From ff7507295db22539aacb2f9a8734eb97f8257e43 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Dec 2018 20:52:03 +0100 Subject: [PATCH 1/5] networkd-test: set right access modes for /run/systemd/netif Otherwise networkd isn't happy. Let's also make addition of the "systemd-network" non-fatal. The user exists on many machines anyway, hence it shouldn't fail if it already exists. --- test/networkd-test.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/networkd-test.py b/test/networkd-test.py index d876f3a9e0..b6fe74e2c6 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -53,6 +53,7 @@ def setUpModule(): if (subprocess.call(['systemctl', 'is-active', '--quiet', 'systemd-networkd.service']) == 0 and subprocess.call(['systemd-detect-virt', '--quiet']) != 0): raise unittest.SkipTest('not virtualized and networkd is already active') + # Ensure we don't mess with an existing networkd config for u in ['systemd-networkd.socket', 'systemd-networkd', 'systemd-resolved']: if subprocess.call(['systemctl', 'is-active', '--quiet', u]) == 0: @@ -60,6 +61,12 @@ def setUpModule(): running_units.append(u) else: stopped_units.append(u) + + # create static systemd-network user for networkd-test-router.service (it + # needs to do some stuff as root and can't start as user; but networkd + # still insists on the user) + subprocess.call(['adduser', '--system', '--no-create-home', 'systemd-network']) + for d in ['/etc/systemd/network', '/run/systemd/network', '/run/systemd/netif', '/run/systemd/resolve']: if os.path.isdir(d): @@ -68,6 +75,9 @@ def setUpModule(): if os.path.isdir('/run/systemd/resolve'): os.chmod('/run/systemd/resolve', 0o755) shutil.chown('/run/systemd/resolve', 'systemd-resolve', 'systemd-resolve') + if os.path.isdir('/run/systemd/netif'): + os.chmod('/run/systemd/netif', 0o755) + shutil.chown('/run/systemd/netif', 'systemd-network', 'systemd-network') # Avoid "Failed to open /dev/tty" errors in containers. os.environ['SYSTEMD_LOG_TARGET'] = 'journal' @@ -75,11 +85,6 @@ def setUpModule(): # Ensure the unit directory exists so tests can dump files into it. os.makedirs(NETWORK_UNITDIR, exist_ok=True) - # create static systemd-network user for networkd-test-router.service (it - # needs to do some stuff as root and can't start as user; but networkd - # still insists on the user) - subprocess.check_call(['adduser', '--system', '--no-create-home', 'systemd-network']) - def tearDownModule(): global tmpmounts From fef740aed354098af505c300bed13fdf0f251064 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Dec 2018 20:53:51 +0100 Subject: [PATCH 2/5] networkd-test: add write_config() The call was removed in ec89276c2ab345b84c2dab4c35826de41aa6fd0f, but is still used. Not sure why noone noticed this. --- test/networkd-test.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/networkd-test.py b/test/networkd-test.py index b6fe74e2c6..3f9d4b4dff 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -111,13 +111,17 @@ class NetworkdTestingUtilities: list(peer_options)) self.addCleanup(subprocess.call, ['ip', 'link', 'del', 'dev', peer]) + def write_config(self, path, contents): + """"Write a configuration file, and queue it to be removed.""" + + with open(path, 'w') as f: + f.write(contents) + + self.addCleanup(os.remove, path) + def write_network(self, unit_name, contents): """Write a network unit file, and queue it to be removed.""" - unit_path = os.path.join(NETWORK_UNITDIR, unit_name) - - with open(unit_path, 'w') as unit: - unit.write(contents) - self.addCleanup(os.remove, unit_path) + self.write_config(os.path.join(NETWORK_UNITDIR, unit_name), contents) def write_network_dropin(self, unit_name, dropin_name, contents): """Write a network unit drop-in, and queue it to be removed.""" @@ -738,7 +742,7 @@ Domains= ~company ~lab''') orig_hostname = socket.gethostname() self.addCleanup(socket.sethostname, orig_hostname) if not os.path.exists('/etc/hostname'): - self.writeConfig('/etc/hostname', orig_hostname) + self.write_config('/etc/hostname', orig_hostname) subprocess.check_call(['systemctl', 'stop', 'systemd-hostnamed.service']) self.create_iface(dnsmasq_opts=['--dhcp-host={},192.168.5.210,testgreen'.format(self.iface_mac)]) From 8e0ba0c984bc39e76d993c64bf6efd427268613d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Dec 2018 21:59:38 +0100 Subject: [PATCH 3/5] networkd-test: restart hostnamed after reverting /etc/hostname too Otherwise hostnamed will not report the right data in the next test --- test/networkd-test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/networkd-test.py b/test/networkd-test.py index 3f9d4b4dff..0dc19a616e 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -709,6 +709,7 @@ Domains= ~company ~lab''') subprocess.check_call(['mount', '--bind', '/dev/null', '/etc/hostname']) self.addCleanup(subprocess.call, ['umount', '/etc/hostname']) subprocess.check_call(['systemctl', 'stop', 'systemd-hostnamed.service']) + self.addCleanup(subprocess.call, ['systemctl', 'stop', 'systemd-hostnamed.service']) self.create_iface(dnsmasq_opts=['--dhcp-host={},192.168.5.210,testgreen'.format(self.iface_mac)]) self.do_test(coldplug=None, extra_opts='IPv6AcceptRA=False', dhcp_mode='ipv4') @@ -744,6 +745,7 @@ Domains= ~company ~lab''') if not os.path.exists('/etc/hostname'): self.write_config('/etc/hostname', orig_hostname) subprocess.check_call(['systemctl', 'stop', 'systemd-hostnamed.service']) + self.addCleanup(subprocess.call, ['systemctl', 'stop', 'systemd-hostnamed.service']) self.create_iface(dnsmasq_opts=['--dhcp-host={},192.168.5.210,testgreen'.format(self.iface_mac)]) self.do_test(coldplug=None, extra_opts='IPv6AcceptRA=False', dhcp_mode='ipv4') From 0373fc5b6f8478aa5d07458a7c2267a5b26daa1d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Dec 2018 22:00:42 +0100 Subject: [PATCH 4/5] networkd-test: change test_transient_hostname_with_static to use an explicit static hostname Previously, the test would use the existing static hostname. However, this woud not work as expected in the static hostname was "localhost" because the transient hostname will override the static one in that case anyway, as the assumption hostnamed makes is that "localhost" is a non-initialized hostname. Hence when testing this, let's first set the static hostname to something specific first (that is not "localhost"). --- test/networkd-test.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/networkd-test.py b/test/networkd-test.py index 0dc19a616e..176d52a028 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -742,8 +742,16 @@ Domains= ~company ~lab''') orig_hostname = socket.gethostname() self.addCleanup(socket.sethostname, orig_hostname) + if not os.path.exists('/etc/hostname'): - self.write_config('/etc/hostname', orig_hostname) + self.write_config('/etc/hostname', "foobarqux") + else: + self.write_config('/run/hostname.tmp', "foobarqux") + subprocess.check_call(['mount', '--bind', '/run/hostname.tmp', '/etc/hostname']) + self.addCleanup(subprocess.call, ['umount', '/etc/hostname']) + + socket.sethostname("foobarqux"); + subprocess.check_call(['systemctl', 'stop', 'systemd-hostnamed.service']) self.addCleanup(subprocess.call, ['systemctl', 'stop', 'systemd-hostnamed.service']) @@ -755,7 +763,7 @@ Domains= ~company ~lab''') out = subprocess.check_output(['ip', '-4', 'a', 'show', 'dev', self.iface]) self.assertRegex(out, b'inet 192.168.5.210/24 .* scope global dynamic') # static hostname wins over transient one, thus *not* applied - self.assertEqual(socket.gethostname(), orig_hostname) + self.assertEqual(socket.gethostname(), "foobarqux") except AssertionError: self.show_journal('systemd-networkd.service') self.show_journal('systemd-hostnamed.service') From bf246ba00ee70b46f6f52483382aad7c383d0c3a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Dec 2018 22:15:43 +0100 Subject: [PATCH 5/5] networkd-test: add mkosi snippet for building and running networkd-tets.py in a network namespaced container This provides us with an easy command line to test this script. Because the test was so difficult to get running noone ever did, hence it broke badly quickly. Let's fix that. --- test/mkosi.build.networkd-test | 24 ++++++++++ test/mkosi.default.networkd-test | 80 ++++++++++++++++++++++++++++++++ test/mkosi.nspawn.networkd-test | 2 + 3 files changed, 106 insertions(+) create mode 100755 test/mkosi.build.networkd-test create mode 100644 test/mkosi.default.networkd-test create mode 100644 test/mkosi.nspawn.networkd-test diff --git a/test/mkosi.build.networkd-test b/test/mkosi.build.networkd-test new file mode 100755 index 0000000000..cdaa4302f7 --- /dev/null +++ b/test/mkosi.build.networkd-test @@ -0,0 +1,24 @@ +#!/bin/sh +set -ex + +# First, source in the main build script +. "$SRCDIR"/mkosi.build + +mkdir -p "$DESTDIR"/usr/local/bin +cp "$SRCDIR"/test/networkd-test.py "$DESTDIR"/usr/local/bin/networkd-test.py + +mkdir -p "$DESTDIR"/etc/systemd/system +cat > "$DESTDIR"/etc/systemd/system/networkd-test.service <