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

Fix /proc/net/tcp* check in InternalCommandPortListeningCheck t… #2195

Merged
merged 1 commit into from Jan 18, 2020

Conversation

perlun
Copy link
Contributor

@perlun perlun commented Dec 18, 2019

I noted this when running this code locally; the first part of the check didn't work correctly. After looking more closely, it turned out that we use bashisms with /bin/sh which might work but in many cases (e.g. Debian, Ubuntu-based containers) /bin/sh is a dash binary.

Here is the error. The first invocation illustrates how the statement works properly with bash and the second shows how it fails with dash:

$ denter tomcat
root@85217088bde8:/usr/local/tomcat# true &&  (cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :2490)
00000000:2490
root@85217088bde8:/usr/local/tomcat# sh
# true &&  (cat /proc/net/tcp{,6} | awk '{print $2}' | grep -i :2490)
cat: /proc/net/tcp{,6}: No such file or directory

I added a check to ensure that nothing is printed to stderr from this check, since result.getExitCode() == 0 seems to be true even in cases where parts of this command line is failing. Digging deeper, it's the fallback to his part that typically covers scenarios like this.

command += format("/bin/bash -c '</dev/tcp/localhost/%d'", internalPort);

I can consider reverting the if (!result.getStderr().equals("")) part if it's considered too dangerous, but IMHO it's good to have it there to spot errors like this in the future. I'll leave it up to the project maintainers to decide if this is safe or too risky.


I thought more about the stderr part; it will probably not work since I think in the lattermost fallback (/bin/bash -c '</dev/tcp/localhost/%d), an error will actually be printed to stderr if the port is being used. So I'm fine with removing that part, but will wait with doing so until I hear more feedback on the PR in general.

@rnorth
Copy link
Member

rnorth commented Dec 26, 2019

Interesting - out of curiosity is this causing you an actual issue, or have you just noticed this is incorrect? Happy to fix it either way!

The brace expansion does look to be a bash-ism which will fail in sh etc.

However, I'm unsure that changing the entire port check to run under bash is the right thing to do; we don't have bash available in many containers, so this is going to cause the internal port check to always fail. Indeed, it looks like this is exactly what's happening in CI right now.

What if instead we keep things running under sh but avoid the brace expansion?

It would still be good to check both /proc/net/tcp and /proc/net/tcp6, so perhaps we could just change that one line to run cat over /proc/net/tcp*? I could be wrong, but I think this would do the trick with very little effort or risk of regression. WDYT?

@perlun
Copy link
Contributor Author

perlun commented Dec 30, 2019

@rnorth

Interesting - out of curiosity is this causing you an actual issue, or have you just noticed this is incorrect? Happy to fix it either way!

The check works but we were seeing some TCP connections being performed to our (Tomcat-based, Java backend) service which listens to some arbitrary ports inside the container. In our use case, a TCP connection being opened and then just dropped is an error (we expect some data to be transmitted over a connection to our service); we log this as a warning/error.

I presumed this was coming from the port check; the nc part of it will mean that we actually open a connection to the service inside the container. To get rid of this log noise, I started doing my own local copy of InternalCommandPortListeningCheck and noted that the check was actually failing. (Fixing the check also got rid of the noise in the logs)

The cat /proc/net/tcp{,6} part has the advantage in being much more "silent", compared to the netcat approach, which is why I wanted to get it working. But like you say, cat /proc/net/tcp* ought to be a much safer change. I updated the PR in accordance to this now, hopefully it'll pass the tests this time. 🙂

@perlun perlun changed the title Use bash in InternalCommandPortListeningCheck since we depend on bashisms Fix /proc/net/tcp* check in InternalCommandPortListeningCheck to work on non-bash Dec 30, 2019
@perlun
Copy link
Contributor Author

perlun commented Jan 9, 2020

Bump @bsideup or @rnorth, would be great to get this moving forward. #2195 (comment) describes why adding a test for the change isn't straightforward.

Copy link
Member

@rnorth rnorth left a comment

Choose a reason for hiding this comment

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

Sorry for taking a while to respond @perlun, but I'm happy to approve.

@perlun
Copy link
Contributor Author

perlun commented Jan 13, 2020

@rnorth Thanks. Looking forward to see it merged. 🙂

@perlun
Copy link
Contributor Author

perlun commented Jan 15, 2020

Ping @bsideup @kiview

@rnorth rnorth changed the title Fix /proc/net/tcp* check in InternalCommandPortListeningCheck to work on non-bash Fix /proc/net/tcp* check in InternalCommandPortListeningCheck t… Jan 18, 2020
@rnorth rnorth merged commit 23e9718 into testcontainers:master Jan 18, 2020
thldbc added a commit to DBCDK/microservice-pom that referenced this pull request Feb 20, 2020
testcontainers/testcontainers-java#2195
Testcontainer .start() command was unable to connect to docker image otherwise.
quincy pushed a commit to quincy/testcontainers-java that referenced this pull request May 28, 2020
cristianrgreco added a commit to testcontainers/testcontainers-node that referenced this pull request Sep 3, 2020
@perlun perlun deleted the fix/use-bash-for-bashisms branch October 8, 2020 07:37
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.

None yet

3 participants