summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Märdian <luk@slyon.de>2022-03-03 09:49:45 +0100
committerLukas Märdian <luk@slyon.de>2022-03-03 09:49:45 +0100
commita4d52186d6a482725a47da4d63669ef7da96ab8f (patch)
tree41be5716300c4b022d9c0e1a3a495aa33ee48544
parent8d1727ff671179f971d6ad00d029356947c930b1 (diff)
parent55463cf4aa567ed064af11843a04be195828b42c (diff)
netplan.io (0.103-4) unstable; urgency=medium
* Fix OVS timeouts in containers where the host is not OVS enabled * d/t/control: Add explicit wpasupplicant test Depends * d/t/control: mark ethernets and bonds tests as flaky [dgit import unpatched netplan.io 0.103-4]
-rw-r--r--debian/changelog158
-rw-r--r--debian/control95
-rw-r--r--debian/copyright27
-rw-r--r--debian/gbp.conf4
-rw-r--r--debian/libnetplan-dev.dirs1
-rw-r--r--debian/libnetplan-dev.install2
-rw-r--r--debian/libnetplan0.install1
-rw-r--r--debian/libnetplan0.symbols51
-rw-r--r--debian/netplan.io.dirs2
-rw-r--r--debian/netplan.io.install4
-rw-r--r--debian/patches/0001-parse-nm-fix-32bit-format-string.patch21
-rw-r--r--debian/patches/autopkgtest-fixes.patch54
-rw-r--r--debian/patches/glib-2.70-compat.patch87
-rw-r--r--debian/patches/nm-1.32.10-compat.patch21
-rw-r--r--debian/patches/ovs-timeout.patch548
-rw-r--r--debian/patches/series5
-rwxr-xr-xdebian/rules11
-rw-r--r--debian/source/format1
-rwxr-xr-xdebian/tests/autostart.sh79
-rwxr-xr-xdebian/tests/cloud-init.sh115
-rw-r--r--debian/tests/control155
-rwxr-xr-xdebian/tests/prepare-testbed.sh16
-rw-r--r--debian/upstream/metadata7
-rw-r--r--debian/watch4
24 files changed, 1469 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..1ea81ae
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,158 @@
+netplan.io (0.103-4) unstable; urgency=medium
+
+ * Fix OVS timeouts in containers where the host is not OVS enabled
+ * d/t/control: Add explicit wpasupplicant test Depends
+ * d/t/control: mark ethernets and bonds tests as flaky
+
+ -- Lukas Märdian <luk@slyon.de> Thu, 03 Mar 2022 09:49:45 +0100
+
+netplan.io (0.103-3) unstable; urgency=medium
+
+ [ Andrej Shadura ]
+ * Explicitly depend on glib 2.70
+
+ [ Lukas Märdian ]
+ * Fix autopkgtests inside a LXC test-runner
+ + d/t/prepare-testbed.sh: enable udevd (inside LXC)
+ + d/tests/control: enable autostart & cloud-init tests in LXC
+ + d/tests/control: mark scenarios test as flaky
+ + d/tests/control: add breaks-testbed restriction
+
+ -- Lukas Märdian <luk@slyon.de> Fri, 22 Oct 2021 09:22:22 +0200
+
+netplan.io (0.103-2) unstable; urgency=medium
+
+ * Allow build-depending on openvswitch on all architectures.
+ Now that #979366 has been fixed, it should not be an issue anymore.
+
+ -- Andrej Shadura <andrewsh@debian.org> Thu, 21 Oct 2021 11:19:25 +0200
+
+netplan.io (0.103-1) unstable; urgency=medium
+
+ * New upstream release: 0.103 (LP: #1938920).
+ - Add YAML generator and Keyfile parser for NetworkManager YAML backend
+ - Add activation-mode parameter, needs systemd v248+ (LP: #1664844)
+ - Make use of systemd-networkd's reload/reconfigure commands
+ - Deprecate gateway4 & gateway6 in favor of default routes (LP: #1756590)
+ - Add io.netplan.Netplan.Generate() DBus method
+ - Changed the way of how unmanaged-devices are handled by NetworkManager
+ - Improve integration test suite (LP: #1922126)
+ * Update build-dep to fix FTCBFS (Closes: #961466).
+ * Bump systemd dependency to >= v248 for the activation-mode feature.
+ * Run some autopkgtests with Restriction: isolation-container.
+ * Bump Standards-Version to 4.6.0.1, no changes needed.
+ * Update debian/watch
+ * Update debian/upstream/metadata
+ * d/control: Add Rules-Requires-Root: no
+
+ -- Lukas Märdian <luk@slyon.de> Wed, 20 Oct 2021 13:22:07 +0200
+
+netplan.io (0.101-4) unstable; urgency=medium
+
+ * Build-depend on ovs on amd64 only due to a bug in its postinst.
+ See #979366 for details.
+ * Drop the custom build profile, nocheck is enough.
+
+ -- Andrej Shadura <andrewsh@debian.org> Tue, 05 Jan 2021 22:01:50 +0100
+
+netplan.io (0.101-3) unstable; urgency=medium
+
+ * Mark the package linux-any.
+ * Skip openvswitch-switch dependency on m68k and ppc64.
+
+ -- Andrej Shadura <andrewsh@debian.org> Tue, 05 Jan 2021 19:28:50 +0100
+
+netplan.io (0.101-2) unstable; urgency=medium
+
+ * Reindent debian/control.
+ * Add build profiles.
+ * Add cloud tests but mark them as flaky and skip-not-installable
+ for now.
+
+ -- Andrej Shadura <andrewsh@debian.org> Tue, 05 Jan 2021 17:40:42 +0100
+
+netplan.io (0.101-1) unstable; urgency=medium
+
+ [ Andrej Shadura ]
+ * New upstream release.
+ * Merge changes from Ubuntu.
+ * Let tests fail.
+ * Remove the hack to fix build with GCC 10 (actually closes: #957603).
+
+ [ Lukas Märdian ]
+ * d/control: fix lintian warning about trailing whitespace
+ * d/p/0001-Fix-changing-of-macaddress-with-systemd-v247-178.patch:
+ Fix MAC address changes with systemd v247 by using a new approach inside
+ systemd's .network file. It also works with older version of systemd.
+ * Add d/p/0002-parse-fix-networkmanager-backend-options-for-modem-c.patch:
+ Allows parsing of networkmanager: backend handlers for modem devices
+ * Update symbols file
+
+ [ Michael Biebl ]
+ * Stop using deprecated systemd-resolve tool (Closes: #979266).
+
+ -- Andrej Shadura <andrewsh@debian.org> Mon, 04 Jan 2021 20:34:58 +0100
+
+netplan.io (0.99-2) experimental; urgency=medium
+
+ * Split libnetplan off into separate packages.
+ * Force -fcommon to enable builds with GCC 10 to work around #957603.
+
+ -- Andrej Shadura <andrewsh@debian.org> Mon, 27 Apr 2020 17:17:54 +0200
+
+netplan.io (0.99-1) unstable; urgency=medium
+
+ [ Andrej Shadura ]
+ * New upstream release.
+ * Drop old upstream patches.
+ * Update the co-maintainer list.
+ * Bump Standards-Version to 4.5.0.
+ * Update copyright years.
+
+ [ Lukas Märdian ]
+ * debian:tests:control: add autopkgtest dependencies.
+
+ -- Andrej Shadura <andrewsh@debian.org> Mon, 27 Apr 2020 11:01:26 +0200
+
+netplan.io (0.98-2) unstable; urgency=medium
+
+ * Cherry-pick upstream commits.
+ * Use debhelper-compat instead of debian/compat.
+ * Bump debhelper from old 11 to 12.
+ * Bump Standards-Version to 4.4.1 (no changes).
+
+ -- Andrej Shadura <andrewsh@debian.org> Fri, 01 Nov 2019 15:21:21 +0100
+
+netplan.io (0.98-1) unstable; urgency=medium
+
+ [ Andrej Shadura ]
+ * New upstream release: 0.98 (LP: #1840832).
+ * Run all autopkgtests with Restriction: isolation-machine (Closes:
+ #919426).
+
+ [ Mathieu Trudel-Lapierre ]
+ * debian/control: Add Build-Depends on libsystemd-dev for the D-Bus feature,
+ and on dbus-x11 for dbus-launch used in tests.
+
+ -- Andrej Shadura <andrewsh@debian.org> Thu, 26 Sep 2019 14:35:32 +0200
+
+netplan.io (0.95-2) unstable; urgency=medium
+
+ * Set Priority to optional (Closes: #920327).
+
+ -- Andrej Shadura <andrewsh@debian.org> Thu, 24 Jan 2019 09:43:13 +0100
+
+netplan.io (0.95-1) unstable; urgency=medium
+
+ * New upstream release.
+ * Update autopkgtests from the upstream.
+ * Add debian/watch following GitHub releases.
+ * Add Homepage (Closes: #917233).
+
+ -- Andrej Shadura <andrewsh@debian.org> Sat, 29 Dec 2018 16:34:23 +0100
+
+netplan.io (0.40.2-1) unstable; urgency=medium
+
+ * Upload to Debian (Closes: #882661).
+
+ -- Andrej Shadura <andrewsh@debian.org> Wed, 14 Nov 2018 16:29:42 -0800
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..e6437ad
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,95 @@
+Source: netplan.io
+Maintainer: Debian netplan Maintainers <team+netplan@tracker.debian.org>
+Uploaders:
+ Andrej Shadura <andrewsh@debian.org>,
+ Mathieu Trudel-Lapierre <mathieu.tl@gmail.com>,
+ Łukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com>,
+ Lukas Märdian <luk@slyon.de>
+Section: net
+Priority: optional
+Standards-Version: 4.6.0.1
+Rules-Requires-Root: no
+Build-Depends:
+ debhelper-compat (= 13),
+ pkg-config,
+ bash-completion,
+ libyaml-dev,
+ libglib2.0-dev (>= 2.70.0~),
+ uuid-dev,
+ python3 (>= 3.1),
+ python3-coverage <!nocheck>,
+ python3-yaml <!nocheck>,
+ python3-netifaces <!nocheck>,
+ libsystemd-dev,
+ systemd,
+ dbus-x11 <!nocheck>,
+ pyflakes3 <!nocheck>,
+ pycodestyle <!nocheck> | pep8 <!nocheck>,
+ python3-nose <!nocheck>,
+ pandoc,
+ openvswitch-switch <!nocheck>,
+Vcs-Git: https://salsa.debian.org/debian/netplan.io.git
+Vcs-Browser: https://salsa.debian.org/debian/netplan.io
+Homepage: https://netplan.io/
+
+Package: netplan.io
+Architecture: linux-any
+Multi-Arch: foreign
+Depends:
+ ${shlibs:Depends},
+ ${misc:Depends},
+ iproute2,
+ libnetplan0 (>= ${binary:Version}),
+ python3,
+ python3-yaml,
+ python3-netifaces,
+ systemd (>= 248~),
+Suggests:
+ network-manager | wpasupplicant,
+ openvswitch-switch,
+Conflicts: netplan
+Breaks: nplan (<< 0.34~), network-manager (<< 1.2.2-1)
+Replaces: nplan (<< 0.34~)
+Provides: nplan
+Description: YAML network configuration abstraction for various backends
+ netplan reads YAML network configuration files which are written
+ by administrators, installers, cloud image instantiations, or other OS
+ deployments. During early boot it then generates backend specific
+ configuration files in /run to hand off control of devices to a particular
+ networking daemon.
+ .
+ Currently supported backends are networkd and NetworkManager.
+
+Package: libnetplan0
+Architecture: linux-any
+Multi-Arch: same
+Depends:
+ ${shlibs:Depends},
+ ${misc:Depends},
+Description: YAML network configuration abstraction runtime library
+ netplan reads YAML network configuration files which are written
+ by administrators, installers, cloud image instantiations, or other OS
+ deployments. During early boot it then generates backend specific
+ configuration files in /run to hand off control of devices to a particular
+ networking daemon.
+ .
+ Currently supported backends are networkd and NetworkManager.
+ .
+ This package contains the necessary runtime library files.
+
+Package: libnetplan-dev
+Architecture: linux-any
+Multi-Arch: same
+Depends: ${misc:Depends},
+ libnetplan0 (= ${binary:Version}),
+Description: Development files for netplan's libnetplan runtime library
+ netplan reads YAML network configuration files which are written
+ by administrators, installers, cloud image instantiations, or other OS
+ deployments. During early boot it then generates backend specific
+ configuration files in /run to hand off control of devices to a particular
+ networking daemon.
+ .
+ Currently supported backends are networkd and NetworkManager.
+ .
+ This package contains development files for developers wanting to use
+ libnetplan in their applications.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..f99d13e
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,27 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: netplan.io
+Upstream-Contact: Łukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com>
+Source: https://github.com/canonical/netplan
+
+Files: *
+Copyright: 2016—2020 Canonical Ltd.
+License: GPL-3
+
+Files: debian/*
+Copyright:
+ 2016—2020 Canonical Ltd.
+ 2018—2020 Andrej Shadura <andrewsh@debian.org>
+License: GPL-3
+
+License: GPL-3
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 3.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ On Debian systems, the complete text of the GNU Lesser General
+ Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
diff --git a/debian/gbp.conf b/debian/gbp.conf
new file mode 100644
index 0000000..55e760f
--- /dev/null
+++ b/debian/gbp.conf
@@ -0,0 +1,4 @@
+[DEFAULT]
+debian-branch=debian/unstable
+upstream-branch=upstream/latest
+upstream-vcs-tag=%(version)s
diff --git a/debian/libnetplan-dev.dirs b/debian/libnetplan-dev.dirs
new file mode 100644
index 0000000..99379cd
--- /dev/null
+++ b/debian/libnetplan-dev.dirs
@@ -0,0 +1 @@
+usr/include/netplan
diff --git a/debian/libnetplan-dev.install b/debian/libnetplan-dev.install
new file mode 100644
index 0000000..911f5de
--- /dev/null
+++ b/debian/libnetplan-dev.install
@@ -0,0 +1,2 @@
+usr/include/netplan/*.h
+usr/lib/*/libnetplan*.so
diff --git a/debian/libnetplan0.install b/debian/libnetplan0.install
new file mode 100644
index 0000000..514ba93
--- /dev/null
+++ b/debian/libnetplan0.install
@@ -0,0 +1 @@
+usr/lib/*/libnetplan*.so.*
diff --git a/debian/libnetplan0.symbols b/debian/libnetplan0.symbols
new file mode 100644
index 0000000..b4c073c
--- /dev/null
+++ b/debian/libnetplan0.symbols
@@ -0,0 +1,51 @@
+libnetplan.so.0.0 libnetplan0 #MINVER#
+ NETPLAN_OPTIONAL_ADDRESS_TYPES@Base 0.99
+ NETPLAN_WIFI_WOWLAN_TYPES@Base 0.99
+ _serialize_yaml@Base 0.103
+ _write_netplan_conf@Base 0.102
+ address_option_handlers@Base 0.100
+ contains_netdef_type@Base 0.103
+ cur_filename@Base 0.102
+ current_file@Base 0.99
+ find_yaml_glob@Base 0.101
+ g_string_free_to_file@Base 0.99
+ get_global_network@Base 0.103
+ is_hostname@Base 0.100
+ is_ip4_address@Base 0.99
+ is_ip6_address@Base 0.99
+ is_wireguard_key@Base 0.100
+ missing_id@Base 0.99
+ missing_ids_found@Base 0.99
+ netdefs@Base 0.99
+ netdefs_ordered@Base 0.99
+ netplan_clear_netdefs@Base 0.101
+ netplan_delete_connection@Base 0.102
+ netplan_finish_parse@Base 0.99
+ netplan_generate@Base 0.102
+ netplan_get_filename_by_id@Base 0.102
+ netplan_get_global_backend@Base 0.99
+ netplan_get_id_from_nm_filename@Base 0.102
+ netplan_netdef_new@Base 0.102
+ netplan_parse_keyfile@Base 0.102
+ netplan_parse_yaml@Base 0.99
+ ovs_settings_global@Base 0.100
+ parser_error@Base 0.99
+ process_input_file@Base 0.102
+ process_yaml_hierarchy@Base 0.102
+ safe_mkdir_p_dir@Base 0.99
+ systemd_escape@Base 0.100
+ tmp@Base 0.103
+ tunnel_mode_to_string@Base 0.99
+ unlink_glob@Base 0.99
+ validate_backend_rules@Base 0.99
+ validate_default_route_consistency@Base 0.103
+ validate_netdef_grammar@Base 0.99
+ validate_ovs_target@Base 0.100
+ wifi_frequency_24@Base 0.99
+ wifi_frequency_5@Base 0.99
+ wifi_get_freq24@Base 0.99
+ wifi_get_freq5@Base 0.99
+ wireguard_peer_handlers@Base 0.100
+ write_netplan_conf@Base 0.102
+ write_netplan_conf_full@Base 0.103
+ yaml_error@Base 0.99
diff --git a/debian/netplan.io.dirs b/debian/netplan.io.dirs
new file mode 100644
index 0000000..3cc4699
--- /dev/null
+++ b/debian/netplan.io.dirs
@@ -0,0 +1,2 @@
+etc/netplan
+lib/netplan
diff --git a/debian/netplan.io.install b/debian/netplan.io.install
new file mode 100644
index 0000000..88c78f1
--- /dev/null
+++ b/debian/netplan.io.install
@@ -0,0 +1,4 @@
+lib/netplan/*
+lib/systemd/system-generators/netplan
+usr/share/*
+usr/sbin/netplan
diff --git a/debian/patches/0001-parse-nm-fix-32bit-format-string.patch b/debian/patches/0001-parse-nm-fix-32bit-format-string.patch
new file mode 100644
index 0000000..3f22152
--- /dev/null
+++ b/debian/patches/0001-parse-nm-fix-32bit-format-string.patch
@@ -0,0 +1,21 @@
+From: =?utf-8?q?Lukas_M=C3=A4rdian?= <slyon@ubuntu.com>
+Date: Wed, 4 Aug 2021 15:15:45 +0200
+Subject: parse-nm: fix 32bit format string
+
+---
+ src/parse-nm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/parse-nm.c b/src/parse-nm.c
+index 9b09e34..532d17a 100644
+--- a/src/parse-nm.c
++++ b/src/parse-nm.c
+@@ -136,7 +136,7 @@ static void
+ handle_bridge_uint(GKeyFile* kf, const gchar* key, NetplanNetDefinition* nd, char** dataptr) {
+ if (g_key_file_get_uint64(kf, "bridge", key, NULL)) {
+ nd->custom_bridging = TRUE;
+- *dataptr = g_strdup_printf("%lu", g_key_file_get_uint64(kf, "bridge", key, NULL));
++ *dataptr = g_strdup_printf("%"G_GUINT64_FORMAT, g_key_file_get_uint64(kf, "bridge", key, NULL));
+ _kf_clear_key(kf, "bridge", key);
+ }
+ }
diff --git a/debian/patches/autopkgtest-fixes.patch b/debian/patches/autopkgtest-fixes.patch
new file mode 100644
index 0000000..328dbad
--- /dev/null
+++ b/debian/patches/autopkgtest-fixes.patch
@@ -0,0 +1,54 @@
+diff --git a/tests/integration/base.py b/tests/integration/base.py
+index 5042bf4..93ee722 100644
+--- a/tests/integration/base.py
++++ b/tests/integration/base.py
+@@ -75,7 +75,7 @@ class IntegrationTestsBase(unittest.TestCase):
+
+ os.makedirs('/etc/NetworkManager/conf.d', exist_ok=True)
+ with open('/etc/NetworkManager/conf.d/99-test-ignore.conf', 'w') as f:
+- f.write('[keyfile]\nunmanaged-devices+=interface-name:eth0,interface-name:en*,interface-name:veth42,interface-name:veth43')
++ f.write('[keyfile]\nunmanaged-devices+=interface-name:en*,eth0,veth42,veth43,nptestsrv')
+ subprocess.check_call(['netplan', 'apply'])
+ subprocess.call(['/lib/systemd/systemd-networkd-wait-online', '--quiet', '--timeout=30'])
+
+@@ -144,12 +144,6 @@ class IntegrationTestsBase(unittest.TestCase):
+ universal_newlines=True)
+ klass.dev_e2_client_mac = out.split()[2]
+
+- os.makedirs('/run/NetworkManager/conf.d', exist_ok=True)
+-
+- # work around https://launchpad.net/bugs/1615044
+- with open('/run/NetworkManager/conf.d/11-globally-managed-devices.conf', 'w') as f:
+- f.write('[keyfile]\nunmanaged-devices=')
+-
+ @classmethod
+ def shutdown_devices(klass):
+ '''Remove test devices'''
+@@ -432,9 +426,10 @@ class IntegrationTestsWifi(IntegrationTestsBase):
+ klass.dev_w_ap = devs[0]
+ klass.dev_w_client = devs[1]
+
++ os.makedirs('/run/NetworkManager/conf.d', exist_ok=True)
+ # don't let NM trample over our fake AP
+ with open('/run/NetworkManager/conf.d/test-blacklist.conf', 'w') as f:
+- f.write('[main]\nplugins=keyfile\n[keyfile]\nunmanaged-devices+=nptestsrv,%s\n' % klass.dev_w_ap)
++ f.write('[main]\nplugins=keyfile\n[keyfile]\nunmanaged-devices+=%s\n' % klass.dev_w_ap)
+
+ @classmethod
+ def shutdown_devices(klass):
+diff --git a/tests/integration/ethernets.py b/tests/integration/ethernets.py
+index ce016da..865c0d4 100644
+--- a/tests/integration/ethernets.py
++++ b/tests/integration/ethernets.py
+@@ -252,9 +252,8 @@ class TestNetworkd(IntegrationTestsBase, _CommonTests):
+ %(ec)s:
+ dhcp6: no
+ accept-ra: yes
+- addresses: [ '192.168.1.100/24' ]
+- %(e2c)s: {}''' % {'r': self.backend, 'ec': self.dev_e_client, 'e2c': self.dev_e2_client})
+- self.generate_and_settle()
++ addresses: [ '192.168.1.100/24' ]''' % {'r': self.backend, 'ec': self.dev_e_client})
++ self.generate_and_settle([self.dev_e_client])
+ self.assert_iface_up(self.dev_e_client, ['inet6 2600:'], [])
+
+ def test_eth_dhcp6_off_no_accept_ra(self):
diff --git a/debian/patches/glib-2.70-compat.patch b/debian/patches/glib-2.70-compat.patch
new file mode 100644
index 0000000..05d23f6
--- /dev/null
+++ b/debian/patches/glib-2.70-compat.patch
@@ -0,0 +1,87 @@
+From: =?utf-8?q?Lukas_M=C3=A4rdian?= <slyon@ubuntu.com>
+Date: Fri, 1 Oct 2021 12:39:40 +0200
+Subject: generate:dbus:util: glib 2.70 compat
+
+g_spawn_check_exit_status is deprecated since libglib 2.70 and replaced
+by g_spawn_check_wait_status
+---
+ src/dbus.c | 10 +++++-----
+ src/generate.c | 2 +-
+ src/util.c | 2 +-
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index f0aa53a..74032dc 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -110,7 +110,7 @@ _try_accept(bool accept, sd_bus_message *m, NetplanData *d, sd_bus_error *ret_er
+ * Check return code/errors. */
+ kill(d->try_pid, signal);
+ waitpid(d->try_pid, &status, 0);
+- g_spawn_check_exit_status(status, &error);
++ g_spawn_check_wait_status(status, &error);
+ if (error != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED, "netplan try failed: %s", error->message); // LCOV_EXCL_LINE
+
+@@ -228,7 +228,7 @@ method_apply(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED,
+ "cannot run netplan apply: %s", err->message);
+- g_spawn_check_exit_status(exit_status, &err);
++ g_spawn_check_wait_status(exit_status, &err);
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED,
+ "netplan apply failed: %s\nstdout: '%s'\nstderr: '%s'",
+@@ -257,7 +257,7 @@ method_generate(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED,
+ "cannot run netplan generate: %s", err->message);
+- g_spawn_check_exit_status(exit_status, &err);
++ g_spawn_check_wait_status(exit_status, &err);
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED,
+ "netplan generate failed: %s\nstdout: '%s'\nstderr: '%s'",
+@@ -334,7 +334,7 @@ method_get(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED, "cannot run netplan get: %s", err->message); // LCOV_EXCL_LINE
+
+- g_spawn_check_exit_status(exit_status, &err);
++ g_spawn_check_wait_status(exit_status, &err);
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED, "netplan get failed: %s\nstdout: '%s'\nstderr: '%s'", err->message, stdout, stderr); // LCOV_EXCL_LINE
+
+@@ -380,7 +380,7 @@ method_set(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED, "cannot run netplan set %s: %s", config_delta, err->message); // LCOV_EXCL_LINE
+
+- g_spawn_check_exit_status(exit_status, &err);
++ g_spawn_check_wait_status(exit_status, &err);
+ if (err != NULL)
+ return sd_bus_error_setf(ret_error, SD_BUS_ERROR_FAILED, "netplan set failed: %s\nstdout: '%s'\nstderr: '%s'", err->message, stdout, stderr); // LCOV_EXCL_LINE
+
+diff --git a/src/generate.c b/src/generate.c
+index cccd47a..24e60a2 100644
+--- a/src/generate.c
++++ b/src/generate.c
+@@ -67,7 +67,7 @@ check_called_just_in_time()
+ gint exit_code = 0;
+ g_spawn_sync(NULL, (gchar**)argv2, NULL, G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL, &exit_code, NULL);
+ /* return TRUE, if network.target is not yet active */
+- return !g_spawn_check_exit_status(exit_code, NULL);
++ return !g_spawn_check_wait_status(exit_code, NULL);
+ }
+ g_free(output);
+ return FALSE;
+diff --git a/src/util.c b/src/util.c
+index a4c0dba..5861e13 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -188,7 +188,7 @@ systemd_escape(char* string)
+
+ gchar *argv[] = {"bin" "/" "systemd-escape", string, NULL};
+ g_spawn_sync("/", argv, NULL, 0, NULL, NULL, &escaped, &stderrh, &exit_status, &err);
+- g_spawn_check_exit_status(exit_status, &err);
++ g_spawn_check_wait_status(exit_status, &err);
+ if (err != NULL) {
+ // LCOV_EXCL_START
+ g_fprintf(stderr, "failed to ask systemd to escape %s; exit %d\nstdout: '%s'\nstderr: '%s'", string, exit_status, escaped, stderrh);
diff --git a/debian/patches/nm-1.32.10-compat.patch b/debian/patches/nm-1.32.10-compat.patch
new file mode 100644
index 0000000..d98f101
--- /dev/null
+++ b/debian/patches/nm-1.32.10-compat.patch
@@ -0,0 +1,21 @@
+Description: Fix ethernets test with network-manage 1.32.10
+ NetworkManager's udev rules are smarter about catching renamed veths now, so
+ the udev rule the integration tests use to manage their veths need to list the
+ names the veths are renamed to too.
+Author: Michael Hudson-Doyle <michael.hudson@ubuntu.com>
+Origin: vendor
+Forwarded: no
+Last-Update: 2021-09-01
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/tests/integration/base.py
++++ b/tests/integration/base.py
+@@ -70,7 +70,7 @@
+ # ensure NM can manage our fake eths
+ os.makedirs('/run/udev/rules.d', exist_ok=True)
+ with open('/run/udev/rules.d/99-nm-veth-test.rules', 'w') as f:
+- f.write('ENV{ID_NET_DRIVER}=="veth", ENV{INTERFACE}=="eth42|eth43", ENV{NM_UNMANAGED}="0"\n')
++ f.write('ENV{ID_NET_DRIVER}=="veth", ENV{INTERFACE}=="eth42|eth43|iface1|iface2", ENV{NM_UNMANAGED}="0"\n')
+ subprocess.check_call(['udevadm', 'control', '--reload'])
+
+ os.makedirs('/etc/NetworkManager/conf.d', exist_ok=True)
diff --git a/debian/patches/ovs-timeout.patch b/debian/patches/ovs-timeout.patch
new file mode 100644
index 0000000..3314b84
--- /dev/null
+++ b/debian/patches/ovs-timeout.patch
@@ -0,0 +1,548 @@
+Description: Time out on ovs-vsctl commands if OVS is not enabled on the host
+Author: Lukas Märdian <slyon@ubuntu.com>
+Forwarded: https://github.com/canonical/netplan/pull/266
+Last-Update: 2022-03-03
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+---
+diff --git a/src/openvswitch.c b/src/openvswitch.c
+index 2088fbe..ae6b494 100644
+--- a/src/openvswitch.c
++++ b/src/openvswitch.c
+@@ -57,7 +57,7 @@ write_ovs_systemd_unit(const char* id, const GString* cmds, const char* rootdir,
+ g_string_append_printf(s, "After=netplan-ovs-%s.service\n", dependency);
+ }
+
+- g_string_append(s, "\n[Service]\nType=oneshot\n");
++ g_string_append(s, "\n[Service]\nType=oneshot\nTimeoutStartSec=10s\n");
+ g_string_append(s, cmds->str);
+
+ g_string_free_to_file(s, rootdir, path, NULL);
+diff --git a/tests/generator/base.py b/tests/generator/base.py
+index d72974b..b5167bc 100644
+--- a/tests/generator/base.py
++++ b/tests/generator/base.py
+@@ -66,9 +66,9 @@ standalone\nExecStart=/usr/bin/ovs-vsctl set Bridge %(iface)s mcast_snooping_ena
+ Bridge %(iface)s external-ids:netplan/mcast_snooping_enable=false\nExecStart=/usr/bin/ovs-vsctl set Bridge %(iface)s \
+ rstp_enable=false\nExecStart=/usr/bin/ovs-vsctl set Bridge %(iface)s external-ids:netplan/rstp_enable=false\n'
+ OVS_BR_EMPTY = _OVS_BASE + 'After=netplan-ovs-cleanup.service\nBefore=network.target\nWants=network.target\n\n[Service]\n\
+-Type=oneshot\nExecStart=/usr/bin/ovs-vsctl --may-exist add-br %(iface)s\n' + OVS_BR_DEFAULT
++Type=oneshot\nTimeoutStartSec=10s\nExecStart=/usr/bin/ovs-vsctl --may-exist add-br %(iface)s\n' + OVS_BR_DEFAULT
+ OVS_CLEANUP = _OVS_BASE + 'ConditionFileIsExecutable=/usr/bin/ovs-vsctl\nBefore=network.target\nWants=network.target\n\n\
+-[Service]\nType=oneshot\nExecStart=/usr/sbin/netplan apply --only-ovs-cleanup\n'
++[Service]\nType=oneshot\nTimeoutStartSec=10s\nExecStart=/usr/sbin/netplan apply --only-ovs-cleanup\n'
+ UDEV_MAC_RULE = 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="%s", ATTR{address}=="%s", NAME="%s"\n'
+ UDEV_NO_MAC_RULE = 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="%s", NAME="%s"\n'
+ UDEV_SRIOV_RULE = 'ACTION=="add", SUBSYSTEM=="net", ATTRS{sriov_totalvfs}=="?*", RUN+="/usr/sbin/netplan apply --sriov-only"\n'
+diff --git a/tests/generator/test_ovs.py b/tests/generator/test_ovs.py
+index e7084a9..4c9dfbe 100644
+--- a/tests/generator/test_ovs.py
++++ b/tests/generator/test_ovs.py
+@@ -50,6 +50,7 @@ class TestOpenVSwitch(TestBase):
+ self.assert_ovs({'ovs0.service': OVS_VIRTUAL % {'iface': 'ovs0', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br ovs0
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port ovs0 eth1
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port ovs0 eth0
+@@ -60,6 +61,7 @@ After=netplan-ovs-ovs0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set Interface eth0 external-ids:iface-id=myhostname
+ ExecStart=/usr/bin/ovs-vsctl set Interface eth0 external-ids:netplan/external-ids/iface-id=myhostname
+ ExecStart=/usr/bin/ovs-vsctl set Interface eth0 other-config:disable-in-band=true
+@@ -71,6 +73,7 @@ After=netplan-ovs-ovs0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set Interface eth1 other-config:disable-in-band=false
+ ExecStart=/usr/bin/ovs-vsctl set Interface eth1 external-ids:netplan/other-config/disable-in-band=false
+ '''},
+@@ -109,6 +112,7 @@ ExecStart=/usr/bin/ovs-vsctl set Interface eth1 external-ids:netplan/other-confi
+ self.assert_ovs({'global.service': OVS_VIRTUAL % {'iface': 'global', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . external-ids:iface-id=myhostname
+ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . external-ids:netplan/external-ids/iface-id=myhostname
+ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . other-config:disable-in-band=true
+@@ -129,6 +133,7 @@ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . external-ids:netplan/other-confi
+ self.assert_ovs({'ovs0.service': OVS_VIRTUAL % {'iface': 'ovs0', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br ovs0
+ ''' + OVS_BR_DEFAULT % {'iface': 'ovs0'} + '''\
+ ExecStart=/usr/bin/ovs-vsctl set Bridge ovs0 protocols=OpenFlow10,OpenFlow11,OpenFlow12
+@@ -185,6 +190,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-bond br0 bond0 eth1 eth2
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan=true
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 lacp=off
+@@ -253,6 +259,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-bond br0 bond0 eth1 eth2
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan=true
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 lacp=active
+@@ -318,6 +325,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-bond br0 bond0 eth1 eth2
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan=true
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 lacp=off
+@@ -357,6 +365,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-bond br0 bond0 eth1 eth2
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan=true
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 lacp=off
+@@ -408,6 +417,7 @@ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan/bond_mode=activ
+ '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br0 eth1
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br0 eth2
+@@ -432,6 +442,7 @@ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br0 eth2
+ self.assert_ovs({'br0.service': OVS_VIRTUAL % {'iface': 'br0', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ''' + OVS_BR_DEFAULT % {'iface': 'br0'} + '''\
+ ExecStart=/usr/bin/ovs-vsctl set Bridge br0 external-ids:iface-id=myhostname
+@@ -462,6 +473,7 @@ ExecStart=/usr/bin/ovs-vsctl set Bridge br0 external-ids:netplan/other-config/di
+ '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br0 eth1
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br0 eth2
+@@ -521,6 +533,7 @@ ExecStart=/usr/bin/ovs-vsctl set Bridge br0 external-ids:netplan/rstp_enable=tru
+ '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ''' + OVS_BR_DEFAULT % {'iface': 'br0'} + '''\
+ ExecStart=/usr/bin/ovs-vsctl set Bridge br0 protocols=OpenFlow10,OpenFlow11,OpenFlow15
+@@ -570,6 +583,7 @@ ExecStart=/usr/bin/ovs-vsctl set Bridge br0 external-ids:netplan/protocols=OpenF
+ '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ''' + OVS_BR_DEFAULT % {'iface': 'br0'} + '''\
+ ExecStart=/usr/bin/ovs-vsctl set-controller br0 ptcp: ptcp:1337 ptcp:1337:[fe80::1234%eth0] pssl:1337:[fe80::1] ssl:10.10.10.1 \
+@@ -583,6 +597,7 @@ ExecStart=/usr/bin/ovs-vsctl set Controller br0 external-ids:netplan/connection-
+ 'global.service': OVS_VIRTUAL % {'iface': 'global', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set-ssl /key/path /some/path /another/path
+ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . external-ids:netplan/global/set-ssl=/key/path,/some/path,/another/path
+ '''},
+@@ -680,6 +695,7 @@ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . external-ids:netplan/global/set-
+ self.assert_ovs({'global.service': OVS_VIRTUAL % {'iface': 'global', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set-ssl /key/path /some/path /another/path
+ ExecStart=/usr/bin/ovs-vsctl set open_vswitch . external-ids:netplan/global/set-ssl=/key/path,/some/path,/another/path
+ '''},
+@@ -784,6 +800,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-bond br0 bond0 eth1 eth2
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan=true
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 lacp=off
+@@ -832,6 +849,7 @@ Bond=bond0
+ 'br1.service': OVS_VIRTUAL % {'iface': 'br1', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br1
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br1 patchx -- set Interface patchx type=patch options:peer=patchy
+ ''' + OVS_BR_DEFAULT % {'iface': 'br1'}},
+@@ -841,6 +859,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-bond br0 bond0 patchy eth0 -- set Interface patchy type=patch options:peer=patchx
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 external-ids:netplan=true
+ ExecStart=/usr/bin/ovs-vsctl set Port bond0 lacp=off
+@@ -852,6 +871,7 @@ After=netplan-ovs-br1.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set Port patchx external-ids:netplan=true
+ '''},
+ 'patchy.service': OVS_VIRTUAL % {'iface': 'patchy', 'extra':
+@@ -860,6 +880,7 @@ After=netplan-ovs-bond0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set Interface patchy external-ids:netplan=true
+ '''},
+ 'cleanup.service': OVS_CLEANUP % {'iface': 'cleanup'}})
+@@ -887,12 +908,14 @@ ExecStart=/usr/bin/ovs-vsctl set Interface patchy external-ids:netplan=true
+ self.assert_ovs({'br0.service': OVS_VIRTUAL % {'iface': 'br0', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br0 patch0-1 -- set Interface patch0-1 type=patch options:peer=patch1-0
+ ''' + OVS_BR_DEFAULT % {'iface': 'br0'}},
+ 'br1.service': OVS_VIRTUAL % {'iface': 'br1', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br1
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port br1 patch1-0 -- set Interface patch1-0 type=patch options:peer=patch0-1
+ ''' + OVS_BR_DEFAULT % {'iface': 'br1'}},
+@@ -902,6 +925,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set Port patch0-1 external-ids:netplan=true
+ '''},
+ 'patch1-0.service': OVS_VIRTUAL % {'iface': 'patch1-0', 'extra':
+@@ -910,6 +934,7 @@ After=netplan-ovs-br1.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl set Port patch1-0 external-ids:netplan=true
+ '''},
+ 'cleanup.service': OVS_CLEANUP % {'iface': 'cleanup'}})
+@@ -934,6 +959,7 @@ ExecStart=/usr/bin/ovs-vsctl set Port patch1-0 external-ids:netplan=true
+ self.assert_ovs({'br0.service': OVS_VIRTUAL % {'iface': 'br0', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0
+ ''' + OVS_BR_DEFAULT % {'iface': 'br0'}},
+ 'br0.100.service': OVS_VIRTUAL % {'iface': 'br0.100', 'extra':
+@@ -942,6 +968,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0.100 br0 100
+ ExecStart=/usr/bin/ovs-vsctl set Interface br0.100 external-ids:netplan=true
+ '''},
+@@ -971,6 +998,7 @@ After=netplan-ovs-br0.service
+
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br br0.100 br0 100
+ ExecStart=/usr/bin/ovs-vsctl set Interface br0.100 external-ids:netplan=true
+ '''},
+@@ -1007,6 +1035,7 @@ ExecStart=/usr/bin/ovs-vsctl set Interface br0.100 external-ids:netplan=true
+ self.assert_ovs({'ovs-br.service': OVS_VIRTUAL % {'iface': 'ovs-br', 'extra': '''
+ [Service]
+ Type=oneshot
++TimeoutStartSec=10s
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-br ovs-br
+ ExecStart=/usr/bin/ovs-vsctl --may-exist add-port ovs-br non-ovs-bond
+ ''' + OVS_BR_DEFAULT % {'iface': 'ovs-br'}},
+diff --git a/tests/integration/ovs.py b/tests/integration/ovs.py
+index 8a6f60d..8f9a550 100644
+--- a/tests/integration/ovs.py
++++ b/tests/integration/ovs.py
+@@ -31,8 +31,8 @@ class _CommonTests():
+
+ def _collect_ovs_settings(self, bridge0):
+ d = {}
+- d['show'] = subprocess.check_output(['ovs-vsctl', 'show'])
+- d['ssl'] = subprocess.check_output(['ovs-vsctl', 'get-ssl'])
++ d['show'] = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
++ d['ssl'] = subprocess.check_output(['ovs-vsctl', '-t', '5', 'get-ssl'])
+ # Get external-ids
+ for tbl in ('Open_vSwitch', 'Controller', 'Bridge', 'Port', 'Interface'):
+ cols = 'name,external-ids'
+@@ -40,37 +40,37 @@ class _CommonTests():
+ cols = 'external-ids'
+ elif tbl == 'Controller':
+ cols = '_uuid,external-ids'
+- d['external-ids-%s' % tbl] = subprocess.check_output(['ovs-vsctl', '--columns=%s' % cols, '-f', 'csv', '-d',
++ d['external-ids-%s' % tbl] = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=%s' % cols, '-f', 'csv', '-d',
+ 'bare', '--no-headings', 'list', tbl])
+ # Get other-config
+ for tbl in ('Open_vSwitch', 'Bridge', 'Port', 'Interface'):
+ cols = 'name,other-config'
+ if tbl == 'Open_vSwitch':
+ cols = 'other-config'
+- d['other-config-%s' % tbl] = subprocess.check_output(['ovs-vsctl', '--columns=%s' % cols, '-f', 'csv', '-d',
++ d['other-config-%s' % tbl] = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=%s' % cols, '-f', 'csv', '-d',
+ 'bare', '--no-headings', 'list', tbl])
+ # Get bond settings
+ for col in ('bond_mode', 'lacp'):
+- d['%s-Bond' % col] = subprocess.check_output(['ovs-vsctl', '--columns=name,%s' % col, '-f', 'csv', '-d', 'bare',
++ d['%s-Bond' % col] = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=name,%s' % col, '-f', 'csv', '-d', 'bare',
+ '--no-headings', 'list', 'Port'])
+ # Get bridge settings
+- d['set-fail-mode-Bridge'] = subprocess.check_output(['ovs-vsctl', 'get-fail-mode', bridge0])
++ d['set-fail-mode-Bridge'] = subprocess.check_output(['ovs-vsctl', '-t', '5', 'get-fail-mode', bridge0])
+ for col in ('mcast_snooping_enable', 'rstp_enable', 'protocols'):
+- d['%s-Bridge' % col] = subprocess.check_output(['ovs-vsctl', '--columns=name,%s' % col, '-f', 'csv', '-d', 'bare',
++ d['%s-Bridge' % col] = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=name,%s' % col, '-f', 'csv', '-d', 'bare',
+ '--no-headings', 'list', 'Bridge'])
+ # Get controller settings
+- d['set-controller-Bridge'] = subprocess.check_output(['ovs-vsctl', 'get-controller', bridge0])
++ d['set-controller-Bridge'] = subprocess.check_output(['ovs-vsctl', '-t', '5', 'get-controller', bridge0])
+ for col in ('connection_mode',):
+- d['%s-Controller' % col] = subprocess.check_output(['ovs-vsctl', '--columns=_uuid,%s' % col, '-f', 'csv', '-d',
++ d['%s-Controller' % col] = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=_uuid,%s' % col, '-f', 'csv', '-d',
+ 'bare', '--no-headings', 'list', 'Controller'])
+ return d
+
+ def test_cleanup_interfaces(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs0'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'patch0-1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'patch1-0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'patch0-1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'patch1-0'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ openvswitch:
+@@ -81,7 +81,7 @@ class _CommonTests():
+ ovs1: {interfaces: [patch1-0]}''')
+ self.generate_and_settle(['ovs0', 'ovs1'])
+ # Basic verification that the bridges/ports/interfaces are there in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge ovs0', out)
+ self.assertIn(b' Port patch0-1', out)
+ self.assertIn(b' Interface patch0-1', out)
+@@ -94,7 +94,7 @@ class _CommonTests():
+ %(ec)s: {addresses: ['1.2.3.4/24']}''' % {'ec': self.dev_e_client})
+ self.generate_and_settle([self.dev_e_client])
+ # Verify that the netplan=true tagged bridges/ports have been cleaned up
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertNotIn(b'Bridge ovs0', out)
+ self.assertNotIn(b'Port patch0-1', out)
+ self.assertNotIn(b'Interface patch0-1', out)
+@@ -105,11 +105,11 @@ class _CommonTests():
+
+ def test_cleanup_patch_ports(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs0'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'patch0-1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'patchy'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'bond0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'patch0-1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'patchy'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'bond0'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ ethernets:
+@@ -122,7 +122,7 @@ class _CommonTests():
+ ovs0: {interfaces: [patch0-1, bond0]}''' % {'ec': self.dev_e_client})
+ self.generate_and_settle([self.dev_e_client, 'ovs0'])
+ # Basic verification that the bridges/ports/interfaces are there in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge ovs0', out)
+ self.assertIn(b' Port patch0-1\n Interface patch0-1\n type: patch', out)
+ self.assertIn(b' Port bond0', out)
+@@ -141,7 +141,7 @@ class _CommonTests():
+ self.generate_and_settle([self.dev_e_client, 'ovs1'])
+ # Verify that the netplan=true tagged patch ports have been cleaned up
+ # even though the containing bond0 port still exists (with new patch ports)
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge ovs1', out)
+ self.assertIn(b' Port patchy\n Interface patchy\n type: patch', out)
+ self.assertIn(b' Port bond0', out)
+@@ -155,9 +155,9 @@ class _CommonTests():
+
+ def test_bridge_vlan(self):
+ self.setup_eth(None, True)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'br-%s' % self.dev_e_client])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'br-data'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'br-%s.100' % self.dev_e_client])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'br-%s' % self.dev_e_client])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'br-data'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'br-%s.100' % self.dev_e_client])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ version: 2
+@@ -183,7 +183,7 @@ class _CommonTests():
+ 'br-data',
+ 'br-eth42.100'])
+ # Basic verification that the interfaces/ports are set up in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge br-%b' % self.dev_e_client.encode(), out)
+ self.assertIn(b''' Port %(ec)b
+ Interface %(ec)b''' % {b'ec': self.dev_e_client.encode()}, out)
+@@ -196,16 +196,16 @@ class _CommonTests():
+ ['inet 192.168.5.[0-9]+/16', 'mtu 9000']) # from DHCP
+ self.assert_iface('br-data', ['inet 192.168.20.1/16'])
+ self.assert_iface(self.dev_e_client, ['mtu 9000', 'master ovs-system'])
+- self.assertIn(b'100', subprocess.check_output(['ovs-vsctl', 'br-to-vlan',
++ self.assertIn(b'100', subprocess.check_output(['ovs-vsctl', '-t', '5', 'br-to-vlan',
+ 'br-%s.100' % self.dev_e_client]))
+ self.assertIn(b'br-%b' % self.dev_e_client.encode(), subprocess.check_output(
+- ['ovs-vsctl', 'br-to-parent', 'br-%s.100' % self.dev_e_client]))
++ ['ovs-vsctl', '-t', '5', 'br-to-parent', 'br-%s.100' % self.dev_e_client]))
+ self.assertIn(b'br-%b' % self.dev_e_client.encode(), out)
+
+ def test_bridge_base(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovsbr'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', 'del-ssl'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovsbr'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', 'del-ssl'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ ethernets:
+@@ -227,7 +227,7 @@ class _CommonTests():
+ ''' % {'ec': self.dev_e_client, 'e2c': self.dev_e2_client})
+ self.generate_and_settle([self.dev_e_client, self.dev_e2_client, 'ovsbr'])
+ # Basic verification that the interfaces/ports are in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge ovsbr', out)
+ self.assertIn(b' Controller "tcp:127.0.0.1"', out)
+ self.assertIn(b' Controller "pssl:1337:[::1]"', out)
+@@ -236,15 +236,15 @@ class _CommonTests():
+ self.assertIn(b' Port %(ec)b\n Interface %(ec)b' % {b'ec': self.dev_e_client.encode()}, out)
+ self.assertIn(b' Port %(e2c)b\n Interface %(e2c)b' % {b'e2c': self.dev_e2_client.encode()}, out)
+ # Verify the bridge was tagged 'netplan:true' correctly
+- out = subprocess.check_output(['ovs-vsctl', '--columns=name,external-ids', '-f', 'csv', '-d', 'bare',
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=name,external-ids', '-f', 'csv', '-d', 'bare',
+ 'list', 'Bridge', 'ovsbr'])
+ self.assertIn(b'netplan=true', out)
+ self.assert_iface('ovsbr', ['inet 192.170.1.1/24'])
+
+ def test_bond_base(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovsbr'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'mybond'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovsbr'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'mybond'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ ethernets:
+@@ -263,13 +263,13 @@ class _CommonTests():
+ interfaces: [mybond]''' % {'ec': self.dev_e_client, 'e2c': self.dev_e2_client})
+ self.generate_and_settle([self.dev_e_client, self.dev_e2_client, 'ovsbr'])
+ # Basic verification that the interfaces/ports are in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge ovsbr', out)
+ self.assertIn(b' Port mybond', out)
+ self.assertIn(b' Interface %b' % self.dev_e_client.encode(), out)
+ self.assertIn(b' Interface %b' % self.dev_e2_client.encode(), out)
+ # Verify the bond was tagged 'netplan:true' correctly
+- out = subprocess.check_output(['ovs-vsctl', '--columns=name,external-ids', '-f', 'csv', '-d', 'bare', 'list', 'Port'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', '--columns=name,external-ids', '-f', 'csv', '-d', 'bare', 'list', 'Port'])
+ self.assertIn(b'mybond,netplan=true', out)
+ # Verify bond params
+ out = subprocess.check_output(['ovs-appctl', 'bond/show', 'mybond'])
+@@ -282,10 +282,10 @@ class _CommonTests():
+
+ def test_bridge_patch_ports(self):
+ self.setup_eth(None)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'br0'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'br1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'patch0-1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'patch1-0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'br0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'br1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'patch0-1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'patch1-0'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ openvswitch:
+@@ -300,7 +300,7 @@ class _CommonTests():
+ interfaces: [patch1-0]''')
+ self.generate_and_settle(['br0', 'br1'])
+ # Basic verification that the interfaces/ports are set up in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'])
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'])
+ self.assertIn(b' Bridge br0', out)
+ self.assertIn(b''' Port patch0-1
+ Interface patch0-1
+@@ -316,7 +316,7 @@ class _CommonTests():
+
+ def test_bridge_non_ovs_bond(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs-br'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs-br'])
+ self.addCleanup(subprocess.call, ['ip', 'link', 'del', 'non-ovs-bond'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+@@ -333,7 +333,7 @@ class _CommonTests():
+ openvswitch: {}''' % {'ec': self.dev_e_client, 'e2c': self.dev_e2_client})
+ self.generate_and_settle([self.dev_e_client, self.dev_e2_client, 'ovs-br', 'non-ovs-bond'])
+ # Basic verification that the interfaces/ports are set up in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'], universal_newlines=True)
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'], universal_newlines=True)
+ self.assertIn(' Bridge ovs-br', out)
+ self.assertIn(''' Port non-ovs-bond
+ Interface non-ovs-bond''', out)
+@@ -346,7 +346,7 @@ class _CommonTests():
+
+ def test_vlan_maas(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs0'])
+ self.addCleanup(subprocess.call, ['ip', 'link', 'delete', '%s.21' % self.dev_e_client], stderr=subprocess.DEVNULL)
+ with open(self.config, 'w') as f:
+ f.write('''network:
+@@ -379,7 +379,7 @@ class _CommonTests():
+ mtu: 1500''' % {'ec': self.dev_e_client})
+ self.generate_and_settle([self.dev_e_client, 'ovs0', 'eth42.21'])
+ # Basic verification that the interfaces/ports are set up in OVS
+- out = subprocess.check_output(['ovs-vsctl', 'show'], universal_newlines=True)
++ out = subprocess.check_output(['ovs-vsctl', '-t', '5', 'show'], universal_newlines=True)
+ self.assertIn(' Bridge ovs0', out)
+ self.assertIn(''' Port %(ec)s.21
+ Interface %(ec)s.21''' % {'ec': self.dev_e_client}, out)
+@@ -411,9 +411,9 @@ class _CommonTests():
+
+ def test_settings_tag_cleanup(self):
+ self.setup_eth(None, False)
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs0'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-br', 'ovs1'])
+- self.addCleanup(subprocess.call, ['ovs-vsctl', '--if-exists', 'del-port', 'bond0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs0'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-br', 'ovs1'])
++ self.addCleanup(subprocess.call, ['ovs-vsctl', '-t', '5', '--if-exists', 'del-port', 'bond0'])
+ with open(self.config, 'w') as f:
+ f.write('''network:
+ version: 2
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..c6a4348
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,5 @@
+0001-parse-nm-fix-32bit-format-string.patch
+autopkgtest-fixes.patch
+nm-1.32.10-compat.patch
+glib-2.70-compat.patch
+ovs-timeout.patch
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..4fd024f
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,11 @@
+#!/usr/bin/make -f
+
+include /usr/share/dpkg/architecture.mk
+
+%:
+ dh $@
+
+override_dh_auto_install:
+ dh_auto_install -- LIBDIR=/usr/lib/${DEB_HOST_MULTIARCH}
+
+.PHOHY: override_dh_auto_install
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/tests/autostart.sh b/debian/tests/autostart.sh
new file mode 100755
index 0000000..f3aee9f
--- /dev/null
+++ b/debian/tests/autostart.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# Check that netplan and systemd/networkd will properly cooperate and run
+# out generator at boot.
+#
+set -eu
+
+if [ ! -x /tmp/autopkgtest-reboot ]; then
+ echo "SKIP: Testbed does not support reboot"
+ exit 0
+fi
+
+trap 'rm -f /etc/netplan/00test.yaml' EXIT INT QUIT PIPE TERM
+
+# parameters: service expect_running
+assert_is_running() {
+ if [ "$2" = 1 ] && ! systemctl --quiet is-active "$1"; then
+ echo "ERROR: expected $1 to have started, but it was not" >&2
+ systemctl --no-pager status "$1"
+ exit 1
+ elif [ "$2" = 0 ] && systemctl --quiet is-active "$1"; then
+ echo "ERROR: expected $1 to not have started, but it was" >&2
+ systemctl --no-pager status "$1"
+ exit 1
+ else
+ systemctl --no-pager status "$1" || true
+ fi
+}
+
+# Always try to keep the management interface up and running
+mkdir -p /etc/systemd/network
+cat <<EOF > /etc/systemd/network/20-mgmt.network
+[Match]
+Name=eth0 en*
+
+[Network]
+DHCP=yes
+EOF
+
+case "${AUTOPKGTEST_REBOOT_MARK:-}" in
+ '')
+ echo "INFO: Doing initial check that there is no existing netplan config."
+ # right after installation systemd-networkd may or may not be started
+ assert_is_running systemd-networkd.service status
+ echo "INFO: systemd-networkd is fine, rebooting..."
+ /tmp/autopkgtest-reboot noconfig
+ ;;
+
+ noconfig)
+ echo "INFO: Verifying that the test bridge is not up and writing config."
+ if ip a show dev brtest00 2>/dev/null; then
+ echo "ERROR: brtest00 bridge unexpectedly exists" >&2
+ exit 1
+ fi
+ mkdir -p /etc/netplan
+ cat <<EOF > /etc/netplan/00test.yaml
+network:
+ version: 2
+ bridges:
+ brtest00:
+ addresses: [10.42.1.1/24]
+EOF
+
+ echo "INFO: Configuration written, rebooting..."
+ /tmp/autopkgtest-reboot config
+ ;;
+
+ config)
+ echo "INFO: Validate that systemd-networkd is running and our test bridge exists..."
+ assert_is_running systemd-networkd.service 1
+ ip a show dev brtest00
+ echo "OK: Test bridge is configured."
+ ;;
+
+ *)
+ echo "INTERNAL ERROR: autopkgtest marker $AUTOPKGTEST_REBOOT_MARK unexpected" >&2
+ exit 1
+ ;;
+esac
diff --git a/debian/tests/cloud-init.sh b/debian/tests/cloud-init.sh
new file mode 100755
index 0000000..031e894
--- /dev/null
+++ b/debian/tests/cloud-init.sh
@@ -0,0 +1,115 @@
+#!/bin/sh
+#
+# Check that netplan, systemd and cloud-init will properly cooperate
+# and run newly generated service units just-in-time.
+#
+set -eu
+
+if [ ! -x /tmp/autopkgtest-reboot ]; then
+ echo "SKIP: Testbed does not support reboot"
+ exit 0
+fi
+
+# parameters: service expect_running
+assert_is_running() {
+ if [ "$2" = 1 ] && ! systemctl --quiet is-active "$1"; then
+ echo "ERROR: expected $1 to have started, but it was not" >&2
+ systemctl --no-pager status "$1"
+ exit 1
+ elif [ "$2" = 0 ] && systemctl --quiet is-active "$1"; then
+ echo "ERROR: expected $1 to not have started, but it was" >&2
+ systemctl --no-pager status "$1"
+ exit 1
+ else
+ systemctl --no-pager status "$1" || true
+ fi
+}
+
+# Always try to keep the management interface up and running
+mkdir -p /etc/systemd/network
+cat <<EOF > /etc/systemd/network/20-mgmt.network
+[Match]
+Name=eth0 en*
+
+[Network]
+DHCP=yes
+EOF
+
+case "${AUTOPKGTEST_REBOOT_MARK:-}" in
+ '')
+ echo "INFO: Preparing configuration"
+ mkdir -p /etc/netplan
+ # Any netplan YAML config
+ cat <<EOF > /etc/netplan/00test.yaml
+network:
+ version: 2
+ bridges:
+ brtest00:
+ addresses: [10.42.1.1/24]
+EOF
+ # Prepare a dummy netplan service unit, which will be moved to /run/systemd/system/
+ # during early boot, as if it would have been created by 'netplan generate'
+ cat <<EOF > /netplan-dummy.service
+[Unit]
+Description=Check if this dummy is properly started by systemd
+
+[Service]
+Type=oneshot
+# Keep it running, so we can verify it was properly started
+RemainAfterExit=yes
+ExecStart=echo "Doing nothing ..."
+EOF
+ # A service simulating cloud-init, calling 'netplan generate' during early boot
+ # at the 'initialization' phase of systemd (before basic.target is reached).
+ cat <<EOF > /etc/systemd/system/cloud-init-dummy.service
+[Unit]
+Description=Simulating cloud-init's 'netplan generate' call during early boot
+DefaultDependencies=no
+Before=basic.target
+Before=network.target
+After=sysinit.target
+
+[Install]
+RequiredBy=basic.target
+
+[Service]
+Type=oneshot
+# Keep it running, so we can verify it was properly started
+RemainAfterExit=yes
+# Simulate creating a new service unit (i.e. netplan-wpa-*.service / netplan-ovs-*.service)
+ExecStart=/bin/cp /netplan-dummy.service /run/systemd/system/
+ExecStart=/usr/sbin/netplan generate
+EOF
+
+ # right after installation systemd-networkd may or may not be started
+ assert_is_running systemd-networkd.service status
+
+ systemctl disable systemd-networkd.service
+ systemctl enable cloud-init-dummy.service
+ echo "INFO: Configuration written, rebooting..."
+ /tmp/autopkgtest-reboot config
+ ;;
+
+ config)
+ sleep 5 # Give some time for systemd to finish the boot transaction
+ echo "INFO: Validate that systemd-networkd, cloud-init-dummy.service and netplan-dummy.service are running and our test bridge exists..."
+ assert_is_running systemd-networkd.service 1
+ assert_is_running cloud-init-dummy.service 1
+ assert_is_running netplan-dummy.service 1
+ ip a show dev brtest00
+ echo "OK: Test bridge is configured and just-in-time services running."
+
+ # Cleanup
+ systemctl enable systemd-networkd.service
+ systemctl disable cloud-init-dummy.service
+ rm /netplan-dummy.service
+ rm /run/systemd/system/netplan-dummy.service
+ rm /etc/systemd/system/cloud-init-dummy.service
+ rm /etc/netplan/00test.yaml
+ ;;
+
+ *)
+ echo "INTERNAL ERROR: autopkgtest marker $AUTOPKGTEST_REBOOT_MARK unexpected" >&2
+ exit 1
+ ;;
+esac
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 0000000..1d4ca6c
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,155 @@
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=ovs
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+ openvswitch-switch,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, skip-not-installable, flaky
+Features: test-name=ovs
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=ethernets
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=ethernets
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=bridges
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=bridges
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=bonds
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=bonds
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=routing
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed
+Features: test-name=routing
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=vlans
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=vlans
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=wifi
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=wifi
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=tunnels
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+ wireguard-tools,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed
+Features: test-name=tunnels
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=scenarios
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=scenarios
+
+Test-Command: ./debian/tests/prepare-testbed.sh && python3 tests/integration/run.py --test=regressions
+Tests-Directory: tests/integration
+Depends: @,
+ systemd,
+ network-manager,
+ hostapd,
+ wpasupplicant,
+ dnsmasq-base,
+ libnm0,
+ python3-gi,
+ gir1.2-nm-1.0,
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed
+Features: test-name=regressions
+
+Test-Command: ./debian/tests/prepare-testbed.sh && ./debian/tests/autostart.sh
+Depends: @,
+ systemd,
+ udev
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed
+Features: test-name=autostart
+
+Test-Command: ./debian/tests/prepare-testbed.sh && ./debian/tests/cloud-init.sh
+Depends: @,
+ systemd,
+ udev
+Restrictions: allow-stderr, needs-root, isolation-container, breaks-testbed, flaky
+Features: test-name=cloud-init
diff --git a/debian/tests/prepare-testbed.sh b/debian/tests/prepare-testbed.sh
new file mode 100755
index 0000000..d69d866
--- /dev/null
+++ b/debian/tests/prepare-testbed.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -xe
+# disable ifupdown
+rm -f /etc/network/interfaces
+# enable systemd-networkd
+systemctl unmask systemd-networkd.service
+systemctl unmask systemd-networkd.socket
+systemctl unmask systemd-networkd-wait-online.service
+systemctl enable --now systemd-networkd.service
+# enable systemd-resolved
+systemctl unmask systemd-resolved.service
+systemctl enable --now systemd-resolved.service
+# enable systemd-udevd
+mount -o remount,rw /sys
+systemctl unmask systemd-udevd.service
+systemctl start systemd-udevd.service
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
new file mode 100644
index 0000000..896543b
--- /dev/null
+++ b/debian/upstream/metadata
@@ -0,0 +1,7 @@
+---
+Bug-Database: https://bugs.launchpad.net/netplan
+Bug-Submit: https://bugs.launchpad.net/netplan/+filebug
+Changelog: https://github.com/canonical/netplan/commits/master
+Other-References: https://netplan.io
+Repository: https://github.com/canonical/netplan.git
+Repository-Browse: https://github.com/canonical/netplan
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..b9ed2d5
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,4 @@
+version=4
+
+opts=filenamemangle=s/.+\/v?@ANY_VERSION@@ARCHIVE_EXT@/@PACKAGE@-$1.tar.gz/,uversionmangle=s/-?rc/~rc/ \
+ https://github.com/canonical/netplan/releases .*/v?@ANY_VERSION@@ARCHIVE_EXT@