Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ryuk): make listen address of exposed port configurable #2809

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

romainlaurent
Copy link

What does this PR do?

Configurable listen address for the ExposedPorts on Ryuk container.

Why is it important?

We run our containers from a gitlab runner where there is a network policy which forbid containers exposing port to listen on 0.0.0.0 .

Related issues

The unit tests should cover the use cases

@romainlaurent romainlaurent requested a review from a team as a code owner October 2, 2024 08:28
Copy link

netlify bot commented Oct 2, 2024

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 5b08390
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/66fec379bfca4600086a326e
😎 Deploy Preview https://deploy-preview-2809--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@romainlaurent romainlaurent changed the title chore(ryuk): make listen address of exposed port configurable feat(ryuk): make listen address of exposed port configurable Oct 2, 2024
Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition, thanks for the PR.

I've made some initial suggestions but we should wait for #2728 to be merged before completing as there's going to be some conflicts and it will be easier to fix here.

We should also look to test that the reaper works as expected using a custom port so a test for that should be added, best to wait for the above PR to land first as that changes quite a bit in that area.

internal/config/config.go Outdated Show resolved Hide resolved
internal/config/config.go Outdated Show resolved Hide resolved
internal/config/config_test.go Outdated Show resolved Hide resolved
internal/config/config_test.go Outdated Show resolved Hide resolved
internal/config/config_test.go Outdated Show resolved Hide resolved
internal/config/config_test.go Outdated Show resolved Hide resolved
reaper.go Outdated Show resolved Hide resolved
@romainlaurent
Copy link
Author

Thanks for your comments!
Waiting patiently for #2728 to be merged

@romainlaurent romainlaurent deleted the chore/ryuk_listen_address branch October 2, 2024 13:59
Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick changes, second round...

Comment on lines 139 to 140
ryukAddress := os.Getenv("TESTCONTAINERS_RYUK_ADDRESS")
if ryukAddress != "" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we could fold this to be a little more idiomatic

Suggested change
ryukAddress := os.Getenv("TESTCONTAINERS_RYUK_ADDRESS")
if ryukAddress != "" {
if ryukAddress := os.Getenv("TESTCONTAINERS_RYUK_ADDRESS"); ryukAddress != "" {

@@ -140,6 +142,15 @@ func TestReadTCConfig(t *testing.T) {
assert.Equal(t, expected, config)
})

t.Run("Invalid IP address", func(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: to my previous set of comments, were working towards simple names with no spaces:

Suggested change
t.Run("Invalid IP address", func(t *testing.T) {
t.Run("invalid-address", func(t *testing.T) {

Comment on lines 147 to 149
t.Cleanup(func() {
os.Unsetenv("TESTCONTAINERS_RYUK_ADDRESS")
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug: this isn't needed t.Setenv already adds a clean up function.

Suggested change
t.Cleanup(func() {
os.Unsetenv("TESTCONTAINERS_RYUK_ADDRESS")
})

reaper.go Outdated
Comment on lines 247 to 249
exposedPort := string(listeningPort)
if tcConfig.RyukAddress != "" {
exposedPort = net.JoinHostPort(tcConfig.RyukAddress, "") + ":" + exposedPort
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug: pretty sure this would result in a double colon, I would expect the following, did I miss something?

Suggested change
exposedPort := string(listeningPort)
if tcConfig.RyukAddress != "" {
exposedPort = net.JoinHostPort(tcConfig.RyukAddress, "") + ":" + exposedPort
exposedPort := config.ReaperDefaultPort
if tcConfig.RyukAddress != "" {
exposedPort = net.JoinHostPort(tcConfig.RyukAddress, exposedPort)

Also note that the other PR has port configurable using the env var RYUK_PORT, not sure if that will land, but just making you aware.

reaper_test.go Outdated
@@ -408,6 +408,22 @@ func Test_NewReaper(t *testing.T) {
"TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX": "registry.mycompany.com/mirror",
},
},
{
name: "Reaper with a custom listen address",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: simple test names

Suggested change
name: "Reaper with a custom listen address",
name: "custom-address",

func parseIP(input string) string {
ip := net.ParseIP(input)
if ip == nil {
panic("invalid IP address: " + input)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: quote so users can see issues like trailing white space

Suggested change
panic("invalid IP address: " + input)
panic(fmt.Sprintf("invalid IP address: %q", input))

@stevenh
Copy link
Collaborator

stevenh commented Oct 2, 2024

@romainlaurent not sure you wanted to delete this branch?

@romainlaurent romainlaurent restored the chore/ryuk_listen_address branch October 3, 2024 07:36
@romainlaurent
Copy link
Author

romainlaurent commented Oct 3, 2024

Indeed, a branch rename had more impact than expected. Unfortunately, this approach hasn't fixed my issue.

The problem I have is that my tests are running in GitLab CI with the Docker executor.
This setup causes my Ryuk container to run alongside the one launching the tests.

I will propose something different where I override the Reaper.Endpoint field here.

We can override the Reaper.Endpoint field by using an environment variable, such as TESTCONTAINERS_RYUK_USE_NAME_ENDPOINT=false.

What do you think about it?

@romainlaurent romainlaurent reopened this Oct 3, 2024
@mdelapenya
Copy link
Member

@romainlaurent You probably read this about Gitlab CI, right? https://golang.testcontainers.org/system_requirements/ci/gitlab_ci/

Isn't it working for you?

@romainlaurent
Copy link
Author

romainlaurent commented Oct 3, 2024

@mdelapenya thanks for your answer!
Yes I have but it's not enough, there is strict network policies on the runner which forbid traffic on container listening on 0.0.0.0
I got this log error
failed waiting for reaper container 8fdba937 port tcp/8080 to be ready: dial tcp 172.17.0.1:33074: connect: network is unreachable: creating reaper failed
Maybe by changing only here
wait.ForListeningPort(listeningPort) by wait.ForLog("Started")

Copy link
Collaborator

@stevenh stevenh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a workable fix I'm afraid as if ForListeningPort doesn't work then the container wont be accessible.

reaper.go Outdated
@@ -249,7 +249,7 @@ func newReaper(ctx context.Context, sessionID string, provider ReaperProvider) (
ExposedPorts: []string{string(listeningPort)},
Labels: core.DefaultLabels(sessionID),
Privileged: tcConfig.RyukPrivileged,
WaitingFor: wait.ForListeningPort(listeningPort),
WaitingFor: wait.ForLog("Started"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug: If the listening for check doesn't work then the reaper wont be accessible so this is not a good fix.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could work by adding TESTCONTAINERS_RYUK_ENDPOINT_OVERRIDE_BY_NAME=true, allowing us to contact the container directly through its name.
I'm not sure it's the most elegant solution, so I'm open to any alternatives you think would be better.

reaper.go Outdated
reaperContainer.ID[:8], port.Proto(), port.Port(), err)
}
}
err = wait.ForLog("Started").WaitUntilReady(ctx, reaperContainer)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug: If the listening for doesn't work the container isn't accessible so wont work.

@romainlaurent romainlaurent marked this pull request as draft October 3, 2024 13:40
@romainlaurent romainlaurent force-pushed the chore/ryuk_listen_address branch 3 times, most recently from b7ecbee to 61e3e59 Compare October 3, 2024 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants