-
-
Notifications
You must be signed in to change notification settings - Fork 447
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
(#128) Throw an error when bash is not installed in the target container #129
Conversation
945b298
to
8e056de
Compare
reopening for travis to rebuild |
@@ -88,13 +88,15 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT | |||
//internal check | |||
command := buildInternalCheckCommand(hp.Port.Int()) | |||
for { | |||
exitCode, err := target.Exec(ctx, []string{"/bin/bash", "-c", command}) | |||
exitCode, err := target.Exec(ctx, []string{"/bin/sh", "-c", command}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was a bug, yes, sorry for that
@@ -105,7 +107,7 @@ func buildInternalCheckCommand(internalPort int) string { | |||
command := `( | |||
cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :%x || | |||
nc -vz -w 1 localhost %d || | |||
/bin/bash -c '</dev/tcp/localhost/%d' | |||
/bin/sh -c '</dev/tcp/localhost/%d' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is unnecessary, I believe. External command fix should be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, sorry for the late response. I'll revert this change and resend. TBH, not sure why the travis tests fail tough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmmm, thinking about it, the internal command should be sh
, because it's very likely that bash
is not present in the container (i.e. Alpine-based images)
@mdelapenya are you planning to fix this branch? |
Yes, the thing is I'm not sure why the tests are failing on Travis 🤷♀ I'm debugging locally trying to find the issue |
After debugging this before the The below output comes from debugging exitCode, err := target.Exec(ctx, []string{"/bin/bash", "-c", command}) The generated command is: true && (
cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :50 ||
nc -vz -w 1 localhost 80 ||
/bin/bash -c '</dev/tcp/localhost/80'
) Entering into the created container (
BTW, The weirdest thing here is that running the tests at this point, they all pass. Replacing BASH with SH, then the command exits with errorLevel 2:
@nikolayk812 could you assist me here? Thanks! |
More on this. If I run the container used in tests:
And execute the internal command from my local terminal: With /bin/bash $ docker exec nginx /bin/bash -c "true && (cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :50)"
$ docker exec nginx /bin/bash -c "true && (cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :0050)"
0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 6218691 1 0000000000000000 100 0 0 10 0 With /bin/sh $ docker exec nginx /bin/sh -c "true && (cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :50)"
cat: /proc/net/tcp{,6}: No such file or directory
$ docker exec nginx /bin/sh -c "true && (cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :0050)"
cat: /proc/net/tcp{,6}: No such file or directory I'm going to check how to use /bin/sh properly |
More on this: trying to escape
I see differences in how the Entering the container used in tests: root@8da5c254bfe3:/# /bin/bash -c 'true && (cat /proc/net/tcp{,6} | awk "\"{print $2}"\" | grep -i :0050)'
0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 6218691 1 0000000000000000 100 0 0 10 0
root@8da5c254bfe3:/# echo $?
0
root@8da5c254bfe3:/# /bin/sh -c 'true && (cat /proc/net/tcp{,6} | awk "\"{print $2}"\" | grep -i :0050)'
cat: /proc/net/tcp{,6}: No such file or directory
root@8da5c254bfe3:/# echo $?
1 I see slight differences in how the command behaves. |
As described in https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt the format of /proc/net/tcp is using 4 digits for the hex port: 46: 010310AC:9C4C 030310AC:1770 01 | | | | | |--> connection state | | | | |------> remote TCP port number | | | |-------------> remote IPv4 address | | |--------------------> local TCP port number | |---------------------------> local IPv4 address |----------------------------------> number of entry So this string pattern is more accurate
5ce826e
to
4f128b8
Compare
@@ -109,7 +109,7 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT | |||
|
|||
func buildInternalCheckCommand(internalPort int) string { | |||
command := `( | |||
cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :%04x || | |||
cat /proc/net/tcp* | awk '{print $2}' | grep -i :%04x || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was the clue!! At least, WOMC! Let's 🤞 for Travis :)
Tests fixed! @gianarb please take a look 🙏, this is already fixed BTW, using SH instead of BASH is what the Java impl is doing (https://github.com/testcontainers/testcontainers-java/blob/23e9718a56eeac3ca2ec87c8a2525fa8e4bf76df/core/src/main/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheck.java#L42), so without knowing it before, it turned out we are in the same page 😄 |
Good job!! Thanks @mdelapenya |
What does this PR do?
It throws an error when the evaluation of the '/bin/bash' command used to
check the host/port in the target container fails because 'bash' is not
present in the system (as it happens in most Alpine-based images).
Why is it important?
It will make the checks more reliable, as the implementation will raise an
error that could be handled by client code.
Before this change, the client code waited and a timeout happened. Now a more
accurate error is raised so it's easier to handle.
Related issues
Closes #128