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

new-chroot: set up new network namespace and add default route in it #118

Closed
wants to merge 1 commit into from
Closed

Conversation

msekletar
Copy link
Contributor

Some software excepts (implicitly or otherwise) that system always has
default route properly configured. For example, you can't bind() UDP
socket to all IP addresses and then join multicast group, w/o having
default route. This is what ruby test-suite does and fails due to
missing default route when building ruby with --new-chroot while network
access is disallowed.

rpmbuild_networking option allows you to configure whether mock should
set up build environment in way that it is possible to access
network. This option affects only mock commands spawned with
--new-chroot. Previously we added --private-network to nspawn command
when rpmbuild_networking was set to False. This commit introduces a
change in this regard. We never add --private-network to nspawn
arguments, instead we setup network namespace ourselves and we also add
default route pointing to loopback interface (only interface in the new
namespace). This should fix build ruby's build failure and provide more
"pleasant" build environment even when network access is disallowed.

Note that this commit introduces new dependency which is pyroute2. We
need pyroute2 in order to setup environment in new network namespace.

Fixes #113

@msekletar
Copy link
Contributor Author

Few caveats,

  • I am not a python programmer, so please check this PR carefully
  • I've tested this only manually using --chroot and --shell and verifying that I have only loopback interface and default route pointing to it (when rpmbuild_networking=False)
  • If setup of network namespace fails due to an exception in condUnshareNet it looks like the exception handler catches the exception, logs about it and continues. Well, this is actually not the case. If exception is raised in child it is also raised in parent process (see https://docs.python.org/3.6/library/subprocess.html#exceptions). Hence we should also catch exception in parent, but there are two problems,
    • Type information is lost, so I don't know what exception I am dealing with, because in parent we get generic SubprocesException
    • I need to know that exception is from child process. According to docs this should be possible to figure out because child process exceptions should have child_traceback attribute set. However, at least with python-3.6.2 subprocess exception never has this attribute, even when it was really raised by child (tested by introducing artificial raise statement to condUnshareNet)

Some software expects (implicitly or otherwise) that system always has
default route properly configured. For example, you can't bind() UDP
socket to all IP addresses and then join multicast group, w/o having
default route. This is what ruby test suite does and fails due to
missing default route when building ruby with --new-chroot while network
access is disallowed.

rpmbuild_networking option allows you to configure whether mock should
set up build environment in way that it is possible to access
network. This option affects only mock commands spawned with
--new-chroot. Previously we added --private-network to nspawn command
when rpmbuild_networking was set to False. This commit introduces a
change in this regard. We never add --private-network to nspawn
arguments, instead we setup network namespace ourselves and we also add
default route pointing to loopback interface (only interface in the new
namespace). This should fix build ruby's build failure and provide more
"pleasant" build environment even when network access is disallowed.

Note that this commit introduces new dependency which is pyroute2. We
need pyroute2 in order to setup environment in new network namespace.

Fixes #113
@msekletar
Copy link
Contributor Author

msekletar commented Sep 13, 2017

If the setup of network namespace fails due to an exception in condUnshareNet it looks like the exception handler catches the exception, logs about it and continues. Well, this is actually not the case. If an exception is raised in the child it is also raised in parent process (see https://docs.python.org/3.6/library/subprocess.html#exceptions). Hence we should also catch exception in parent, but there are two problems,

Above isn't entirely true because only unhandled exceptions are re-raised in a parent. I figured out that exception was raised in parent because actually exception handler from the child raised a new exception. I force pushed my branch where this is now fixed.

Type information is lost, so I don't know what exception I am dealing with because in parent we get generic SubprocesException

This is still true, but we are no longer getting the exception in the parent as it is handled by child's exception handler.

I need to know that exception is from the child process. According to docs, this should be possible to figure out because child process exceptions should have child_traceback attribute set. However, at least with python-3.6.2 subprocess exception never has this attribute, even when it was really raised by child (tested by introducing artificial raise statement to condUnshareNet)

This is most likely a bug that I will report to upstream Python bug tracker.

@xsuchy
Copy link
Member

xsuchy commented Oct 2, 2017

I have done few minor changes.
Merged as a1a3dda

@xsuchy xsuchy closed this Oct 2, 2017
@voxik
Copy link
Contributor

voxik commented Oct 3, 2017

I can't see any documentation of "rpmbuild_networking" config option in this PR :/ What is the default behavior actually?

@xsuchy
Copy link
Member

xsuchy commented Oct 3, 2017

@voxik The behavior has been present there for some time. And it does not change. Previously we just passed option to systemd-nspawn and left nspawn to handle it. Now we do not pass the option to nspawn anymore and we handle the network namespaces ourself.

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.

Add default route to lo in container when network is disabled
3 participants