diff --git a/backport-Workaround-net_setup_link-race-with-udev-1655.patch b/backport-Workaround-net_setup_link-race-with-udev-1655.patch new file mode 100644 index 0000000000000000000000000000000000000000..54d094c737ce572a7b0c4215c2c43fd8414a9128 --- /dev/null +++ b/backport-Workaround-net_setup_link-race-with-udev-1655.patch @@ -0,0 +1,52 @@ +From 6b3042e91a03dfd5c1c1498d9c00d6ae765381b6 Mon Sep 17 00:00:00 2001 +From: James Falcon +Date: Mon, 15 Aug 2022 16:35:13 -0500 +Subject: [PATCH 3/3] Workaround net_setup_link race with udev (#1655) + +Reference:https://github.com/canonical/cloud-init/commit/7136109df5a7b3c75dfb05a853fc4485fed25b5f +Conflict:NA + +LP: #1983516 +--- + cloudinit/net/netplan.py | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py +index 894b5db..7d6740d 100644 +--- a/cloudinit/net/netplan.py ++++ b/cloudinit/net/netplan.py +@@ -264,10 +264,27 @@ class Renderer(renderer.Renderer): + LOG.debug("netplan net_setup_link postcmd disabled") + return + setup_lnk = ['udevadm', 'test-builtin', 'net_setup_link'] +- for cmd in [setup_lnk + [SYS_CLASS_NET + iface] +- for iface in get_devicelist() if +- os.path.islink(SYS_CLASS_NET + iface)]: +- subp.subp(cmd, capture=True) ++ ++ # It's possible we can race a udev rename and attempt to run ++ # net_setup_link on a device that no longer exists. When this happens, ++ # we don't know what the device was renamed to, so re-gather the ++ # entire list of devices and try again. ++ last_exception = Exception ++ for _ in range(5): ++ try: ++ for iface in get_devicelist(): ++ if os.path.islink(SYS_CLASS_NET + iface): ++ subp.subp( ++ setup_lnk + [SYS_CLASS_NET + iface], capture=True ++ ) ++ break ++ except subp.ProcessExecutionError as e: ++ last_exception = e ++ else: ++ raise RuntimeError( ++ "'udevadm test-builtin net_setup_link' unable to run " ++ "successfully for all devices." ++ ) from last_exception + + def _render_content(self, network_state: NetworkState): + +-- +2.40.0 + diff --git a/backport-util-Fix-error-path-and-parsing-in-get_proc_ppid.patch b/backport-util-Fix-error-path-and-parsing-in-get_proc_ppid.patch new file mode 100644 index 0000000000000000000000000000000000000000..0a886e57f9ed317ced453cbd5cc23f05b877bab8 --- /dev/null +++ b/backport-util-Fix-error-path-and-parsing-in-get_proc_ppid.patch @@ -0,0 +1,98 @@ +From 93b341c7ab968aedd926ed30cfbd3fa29be62fb3 Mon Sep 17 00:00:00 2001 +From: Brett Holman +Date: Fri, 5 Aug 2022 18:11:06 +0200 +Subject: [PATCH 1/3] util: Fix error path and parsing in get_proc_ppid() + +Reference:https://github.com/canonical/cloud-init/commit/668a68fe577368555ea7f71577fc352494a98c25 +Conflict:NA + +If IOError was thrown, the variable "contents" was +unbound and threw a name error exception. + +Parsing /proc//stat was broken in less common +cases. + +Fix both and add parsing tests. +--- + cloudinit/util.py | 10 ++++----- + tests/unittests/test_util.py | 41 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+), 5 deletions(-) + +diff --git a/cloudinit/util.py b/cloudinit/util.py +index 0e0fc04..9e530db 100644 +--- a/cloudinit/util.py ++++ b/cloudinit/util.py +@@ -2761,13 +2761,13 @@ def get_proc_ppid(pid): + ppid = 0 + try: + contents = load_file("/proc/%s/stat" % pid, quiet=True) ++ if contents: ++ # see proc.5 for format ++ m = re.search(r"^\d+ \(.+\) [RSDZTtWXxKWP] (\d+)", str(contents)) ++ if m: ++ ppid = int(m.group(1)) + except IOError as e: + LOG.warning('Failed to load /proc/%s/stat. %s', pid, e) +- if contents: +- parts = contents.split(" ", 4) +- # man proc says +- # ppid %d (4) The PID of the parent. +- ppid = int(parts[3]) + return ppid + + # vi: ts=4 expandtab +diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py +index 1185487..3fa5059 100644 +--- a/tests/unittests/test_util.py ++++ b/tests/unittests/test_util.py +@@ -898,6 +898,47 @@ class TestGetProcEnv(helpers.TestCase): + my_ppid = os.getppid() + self.assertEqual(my_ppid, util.get_proc_ppid(my_pid)) + ++ def test_get_proc_ppid_mocked(self): ++ for ppid, proc_data in ( ++ ( ++ 0, ++ "1 (systemd) S 0 1 1 0 -1 4194560 112664 14612195 153 18014" ++ "274 237 756828 152754 20 0 1 0 3 173809664 3736" ++ "18446744073709551615 1 1 0 0 0 0 671173123 4096 1260 0 0 0 17" ++ "8 0 0 0 0 123974 0 0 0 0 0 0 0 0", ++ ), ++ ( ++ 180771, ++ "180781 ([pytest-xdist r) R 180771 180598 167240 34825 " ++ "180598 4194304 128712 7570 0 0 1061 34 8 1 20 0 2 0 6551540 " ++ "351993856 25173 18446744073709551615 93907896635392 " ++ "93907899455533 140725724279536 0 0 0 0 16781312 17642 0 0 0 " ++ "17 1 0 0 0 0 0 93907901810800 93907902095288 93907928788992 " ++ "140725724288007 140725724288074 140725724288074 " ++ "140725724291047 0", ++ ), ++ ( ++ 5620, ++ "8723 (Utility Process) S 5620 5191 5191 0 -1 4194304 3219 " ++ "0 50 0 1045 431 0 0 20 0 3 0 9007 220585984 8758 " ++ "18446744073709551615 94469734690816 94469735319392 " ++ "140728350183632 0 0 0 0 69634 1073745144 0 0 0 17 10 0 0 0 0 " ++ "0 94469735327152 94469735331056 94469763170304 " ++ "140728350189012 140728350189221 140728350189221 " ++ "140728350195661 0", ++ ), ++ ( ++ 4946, ++ "4947 ((sd-pam)) S 4946 4946 4946 0 -1 1077936448 54 0 0 0 " ++ "0 0 0 0 20 0 1 0 4136 175616000 1394 18446744073709551615 1 1" ++ "0 0 0 0 0 4096 0 0 0 0 17 8 0 0 0 0 0 0 0 0 0 0 0 0 0", ++ ), ++ ): ++ with mock.patch( ++ "cloudinit.util.load_file", return_value=proc_data ++ ): ++ assert ppid == util.get_proc_ppid("mocked") ++ + + class TestKernelVersion(): + """test kernel version function""" +-- +2.40.0 + diff --git a/backport-util-Support-Idle-process-state-in-get_proc_ppid-163.patch b/backport-util-Support-Idle-process-state-in-get_proc_ppid-163.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c4903e84f91a7708afe04fa9706e9451b60d8a4 --- /dev/null +++ b/backport-util-Support-Idle-process-state-in-get_proc_ppid-163.patch @@ -0,0 +1,36 @@ +From 631eecf82a4af3ec46b6f2a257849a80a2299bee Mon Sep 17 00:00:00 2001 +From: Brett Holman +Date: Fri, 5 Aug 2022 22:28:53 +0200 +Subject: [PATCH 2/3] util: Support Idle process state in get_proc_ppid() + (#1637) + +Reference:https://github.com/canonical/cloud-init/commit/f51c352e6c6a7d05a61308c188450a1b818eac45 +Conflict:NA +--- + cloudinit/util.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/cloudinit/util.py b/cloudinit/util.py +index 9e530db..58f6e27 100644 +--- a/cloudinit/util.py ++++ b/cloudinit/util.py +@@ -2763,9 +2763,15 @@ def get_proc_ppid(pid): + contents = load_file("/proc/%s/stat" % pid, quiet=True) + if contents: + # see proc.5 for format +- m = re.search(r"^\d+ \(.+\) [RSDZTtWXxKWP] (\d+)", str(contents)) ++ m = re.search(r"^\d+ \(.+\) [RSDZTtWXxKPI] (\d+)", str(contents)) + if m: + ppid = int(m.group(1)) ++ else: ++ LOG.warning( ++ "Unable to match parent pid of process pid=%s input: %s", ++ pid, ++ contents, ++ ) + except IOError as e: + LOG.warning('Failed to load /proc/%s/stat. %s', pid, e) + return ppid +-- +2.40.0 + diff --git a/cloud-init.spec b/cloud-init.spec index 4408d574f6289e41f2b3c381dc2bfb623e1eaaf8..e98e4dabecadda3775693420567f17adeb9bd94f 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init Version: 21.4 -Release: 17 +Release: 18 Summary: the defacto multi-distribution package that handles early initialization of a cloud instance. License: ASL 2.0 or GPLv3 URL: http://launchpad.net/cloud-init @@ -36,6 +36,9 @@ Patch6005: backport-DataSourceVMware-fix-var-use-before-init-1674.patch Patch6006: backport-cc_set_hostname-ignore-var-lib-cloud-data-set-hostna.patch Patch6007: backport-disk_setup-use-byte-string-when-purging-the-partitio.patch Patch6008: backport-util-atomically-update-sym-links-to-avoid-Suppress-F.patch +Patch6009: backport-Workaround-net_setup_link-race-with-udev-1655.patch +Patch6010: backport-util-Fix-error-path-and-parsing-in-get_proc_ppid.patch +Patch6011: backport-util-Support-Idle-process-state-in-get_proc_ppid-163.patch Patch9000: Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch @@ -147,6 +150,12 @@ fi %exclude /usr/share/doc/* %changelog +* Sat Jul 29 2023 Lv Ying - 21.4-18 +- backport upstream patches: +https://github.com/canonical/cloud-init/commit/7136109df5a7b3c75dfb05a853fc4485fed25b5f +https://github.com/canonical/cloud-init/commit/f51c352e6c6a7d05a61308c188450a1b818eac45 +https://github.com/canonical/cloud-init/commit/668a68fe577368555ea7f71577fc352494a98c25 + * Sat Jul 29 2023 Lv Ying - 21.4-17 - backport upstream patches: https://github.com/canonical/cloud-init/commit/fa53c7f4086f5937bc9bd328dba9f91ca73b6614