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

Add default route to `lo` in container when network is disabled #113

Closed
junaruga opened this issue Aug 28, 2017 · 12 comments

Comments

@junaruga
Copy link

commented Aug 28, 2017

ruby.spec has a test for ipv4 multicast on mock environment.
I want to enable the multicast for enp0s25 (ipv4) network interface in mock.

But when I tested with ip command to check it on mock, the process during check section, enp0s25 multicast was still disabled.
Then when I did mock --shell, the multicast was enabled.
Do you have any idea to enable the multicast for the process of check section?

$ git diff ruby.spec

+BuildRequires: /usr/sbin/ip

-make check TESTS="-v $DISABLE_TESTS"
+sleep 30
+ip maddress
+make test-all TESTS="rinda/test_rinda.rb"
$ fedpkg srpm
$ mock -r fedora-rawhide-x86_64 *.rpm

build.log (https://gist.github.com/junaruga/c6e25d26b09ab89115ad64fa44274763)

+ sleep 30
+ ip maddress <= only lo's multicast is enabled.
1:  lo 
    inet  224.0.0.1
    inet6 ff02::1
    inet6 ff01::1
+ make test-all TESTS=rinda/test_rinda.rb
=> Errror
$ mock -r fedora-rawhide-x86_64 --shell

<mock-chroot> sh-4.4# ip maddress
1:	lo
	inet  224.0.0.1
	inet6 ff02::1
	inet6 ff01::1
2:	enp0s25
	link  01:00:5e:00:00:01
	inet  224.0.0.1
	inet6 ff02::1
	inet6 ff01::1
...
@ignatenkobrain

This comment has been minimized.

Copy link
Member

commented Aug 28, 2017

I guess this problem tightly related to using systemd-nspawn.. cc @msekletar

@junaruga

This comment has been minimized.

Copy link
Author

commented Aug 28, 2017

@ignatenkobrain Maybe that's right.
I could build with mock --old-chroot option (use old chroot instead of systemd-nspawn), and multicast is enabled on the mock.

$ mock -r fedora-rawhide-x86_64 --old-chroot *.rpm
...
+ sleep 30
+ ip maddress
1:  lo
    inet  224.0.0.1
    inet6 ff02::1
    inet6 ff01::1
2:  enp0s25
    link  01:00:5e:00:00:01
    inet  224.0.0.1
    inet6 ff02::1
    inet6 ff01::1
...
+ make test-all TESTS=rinda/test_rinda.rb
...
39 tests, 396 assertions, 0 failures, 0 errors, 0 skips
...

=> Success

@xsuchy

This comment has been minimized.

Copy link
Member

commented Aug 28, 2017

I have no idea how multicasts work in systemd-nspawn. I am trying to avoid any network related tasks in spec files.

@junaruga

This comment has been minimized.

Copy link
Author

commented Aug 29, 2017

@xsuchy okay. As a reference, I am using below systemd-nspawn.

$ rpm -qf /usr/bin/systemd-nspawn
systemd-container-231-17.fc25.x86_64
@junaruga

This comment has been minimized.

Copy link
Author

commented Aug 29, 2017

I tried below both cases, and the situation is same for both.

config_opts['use_host_resolv'] = False or True

However my colleague succeeded to build Fedora ruby for both --old-chroot and --new-chroot without the errors today. So, my local environment might be wrong.

His installed systemd-nspawn is as follows.

$ rpm -qf /usr/bin/systemd-nspawn
systemd-container-234-5.fc27.x86_64
@junaruga

This comment has been minimized.

Copy link
Author

commented Aug 29, 2017

The problem solved by the colleague's help.

I added below option and the build was succeeded.
The multicast was enabled in systemd-nspawn environment.

$ vi ~/.config/mock.cfg 

# To test multicast on mock (systemd-nspawn).
config_opts['rpmbuild_networking'] = True
$ mock -r fedora-rawhide-x86_64 *.rpm

+ DISABLE_TESTS=' -x test_fork.rb'
+ ip maddress
1:  lo 
    inet  224.0.0.1
    inet6 ff02::1
    inet6 ff01::1
2:  enp0s25
    link  01:00:5e:00:00:01
    link  33:33:00:00:00:01
    inet  224.0.0.1
    inet6 ff02::1
    inet6 ff01::1
...
+ make test-all TESTS=rinda/test_rinda.rb
...
39 tests, 396 assertions, 0 failures, 0 errors, 0 skips

I think this option can be set in /etc/mock/*.cfg as initial settings.

Or

We can update document for that.
https://fedoraproject.org/wiki/Using_Mock_to_test_package_builds

Thanks.

@xsuchy

This comment has been minimized.

Copy link
Member

commented Aug 29, 2017

It is already documented here. https://github.com/rpm-software-management/mock/blob/devel/etc/mock/site-defaults.cfg#L59

By default, all rpms should be build without network access (that is Koji default as well). So it is OK to have it disabled by default.

As it is working for you now, I am closing this.

@xsuchy xsuchy closed this Aug 29, 2017
@msekletar

This comment has been minimized.

Copy link
Contributor

commented Aug 29, 2017

FWIW, failing multicast subscription in test_rinda.rb is caused by missing default route in nspawn container.

@junaruga

This comment has been minimized.

Copy link
Author

commented Aug 29, 2017

@xsuchy

It is already documented here. https://github.com/rpm-software-management/mock/blob/devel/etc/mock/site-defaults.cfg#L59

By default, all rpms should be build without network access (that is Koji default as well). So it is OK to have it disabled by default.

As it is working for you now, I am closing this.

I am fine to close this ticket. Thanks.
I could build, enabling multicast by enabling config_opts['rpmbuild_networking'] = True .
But I think this is not a right way.

Because ruby's test should be passed without network access.
Look at below Koji build by "$ fedpkg scratch-build --srpm" that I ran right now.
The build is passing with multicast.

https://koji.fedoraproject.org/koji/taskinfo?taskID=21528597
x86_64: https://kojipkgs.fedoraproject.org//work/tasks/8598/21528598/build.log

+ ip maddress
1:	lo
	inet  224.0.0.1
	inet6 ff02::1
	inet6 ff01::1
2:	eth0
	link  01:00:5e:00:00:01
	link  33:33:00:00:00:01
	link  33:33:ff:dd:ec:96
	inet  224.0.0.1
	inet6 ff02::1:ffdd:ec96
	inet6 ff02::1
	inet6 ff01::1
...
+ make test-all TESTS=rinda/test_rinda.rb
...
39 tests, 396 assertions, 0 failures, 0 errors, 0 skips

@msekletar

FWIW, failing multicast subscription in test_rinda.rb is caused by missing default route in nspawn container.

What is "missing default route in nspawn container"?
Is it my local environment's issue? or the upstream "nspawn container" program's issue?

@xsuchy

This comment has been minimized.

Copy link
Member

commented Aug 29, 2017

After talking to @msekletar I am reopening this issue. The container is missing default route (to loopback device) Therefore kernel does not know which network device to choose to multicast.

We should add the logic: if $container and $network_disabled then ip route add default gw lo

Of course, we need to do that from host using -netns as 'ip' command is not available in the container.

@xsuchy xsuchy reopened this Aug 29, 2017
@xsuchy xsuchy changed the title Testing for ipv4 multicast on mock Add default route to `lo` in container when network is disabled Aug 29, 2017
@voxik

This comment has been minimized.

Copy link
Contributor

commented Sep 4, 2017

I reported this to Ruby upstream [1]. Will see what's their opinion.

@xsuchy

This comment has been minimized.

Copy link
Member

commented Sep 4, 2017

Notes from @msekletar how to add default route

#!/bin/bash
container=$1

# setup
mkdir -p /run/netns
eval $(machinectl show -p Leader ${container})
touch /run/netns/ns-pid-${Leader}
mount --bind /proc/${Leader}/ns/net /run/netns/ns-pid-${Leader}

# add route
ip netns exec ns-pid-${Leader} ip route add default via 127.0.0.1

# clean up
umount /run/netns/ns-pid-${Leader}
rm -f /run/netns/ns-pid-${Leader}
xsuchy added a commit that referenced this issue Sep 6, 2017
Be more consistent. Previously we passed it only for rebuild command and in shell you suddenly have network even
if config disable it and users were confused.

See #113
msekletar added a commit to msekletar/mock that referenced this issue Sep 12, 2017
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.

Fixes rpm-software-management#113
msekletar added a commit to msekletar/mock that referenced this issue Sep 12, 2017
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 rpm-software-management#113
msekletar added a commit to msekletar/mock that referenced this issue Sep 13, 2017
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 rpm-software-management#113
@xsuchy xsuchy closed this in a1a3dda Oct 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.