From 6817570a1f2beef9d920e1f7aa67b7f442685f7b Mon Sep 17 00:00:00 2001 From: shixuantong Date: Mon, 27 Mar 2023 09:28:30 +0800 Subject: [PATCH] keep custom strict perms when 50-cloud-init.yaml exists --- ...stom-strict-perms-when-50-cloud-init.patch | 178 ++++++++++++++++++ cloud-init.spec | 6 +- 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 backport-netplan-keep-custom-strict-perms-when-50-cloud-init.patch diff --git a/backport-netplan-keep-custom-strict-perms-when-50-cloud-init.patch b/backport-netplan-keep-custom-strict-perms-when-50-cloud-init.patch new file mode 100644 index 0000000..a4e5e0e --- /dev/null +++ b/backport-netplan-keep-custom-strict-perms-when-50-cloud-init.patch @@ -0,0 +1,178 @@ +From 483f79cb3b94c8c7d176e748892a040c71132cb3 Mon Sep 17 00:00:00 2001 +From: Chad Smith +Date: Sat, 4 Feb 2023 13:37:02 -0700 +Subject: [PATCH] netplan: keep custom strict perms when 50-cloud-init.yaml + exists + +Retain existing config file permissions when those permissions are +more strict than the default permissions set on +/etc/netplan/50-cloud-init.yaml. +--- + cloudinit/net/netplan.py | 5 ++ + .../unittests/test_distros/test_netconfig.py | 74 ++++++++++++------- + 2 files changed, 53 insertions(+), 26 deletions(-) + +diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py +index 6bb2cb5..894b5db 100644 +--- a/cloudinit/net/netplan.py ++++ b/cloudinit/net/netplan.py +@@ -237,6 +237,11 @@ class Renderer(renderer.Renderer): + header += "\n" + + mode = 0o600 if features.NETPLAN_CONFIG_ROOT_READ_ONLY else 0o644 ++ if os.path.exists(fpnplan): ++ current_mode = util.get_permissions(fpnplan) ++ if current_mode & mode == current_mode: ++ # preserve mode if existing perms are more strict than default ++ mode = current_mode + util.write_file(fpnplan, header + content, mode=mode) + + if self.clean_default: +diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py +index bae2dc4..97659c4 100644 +--- a/tests/unittests/test_distros/test_netconfig.py ++++ b/tests/unittests/test_distros/test_netconfig.py +@@ -391,7 +391,6 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase): + expected_cfgs = { + self.eni_path(): V1_NET_CFG_OUTPUT, + } +- # ub_distro.apply_network_config(V1_NET_CFG, False) + self._apply_and_verify_eni(self.distro.apply_network_config, + V1_NET_CFG, + expected_cfgs=expected_cfgs.copy()) +@@ -411,8 +410,14 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase): + self.distro = self._get_distro('ubuntu', renderers=['netplan']) + self.devlist = ['eth0', 'lo'] + +- def _apply_and_verify_netplan(self, apply_fn, config, expected_cfgs=None, +- bringup=False): ++ def _apply_and_verify_netplan( ++ self, ++ apply_fn, ++ config, ++ expected_cfgs=None, ++ bringup=False, ++ previous_files=(), ++ ): + if not expected_cfgs: + raise ValueError('expected_cfg must not be None') + +@@ -422,12 +427,12 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase): + with mock.patch("cloudinit.net.netplan.get_devicelist", + return_value=self.devlist): + with self.reRooted(tmpd) as tmpd: ++ for previous_path, content, mode in previous_files: ++ util.write_file(previous_path, content, mode=mode) + apply_fn(config, bringup) + + results = dir2dict(tmpd) +- +- mode = 0o600 if features.NETPLAN_CONFIG_ROOT_READ_ONLY else 0o644 +- for cfgpath, expected in expected_cfgs.items(): ++ for cfgpath, expected, mode in expected_cfgs: + print("----------") + print(expected) + print("^^^^ expected | rendered VVVVVVV") +@@ -440,39 +445,56 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase): + return '/etc/netplan/50-cloud-init.yaml' + + def test_apply_network_config_v1_to_netplan_ub(self): +- expected_cfgs = { +- self.netplan_path(): V1_TO_V2_NET_CFG_OUTPUT, +- } ++ expected_cfgs = ( ++ (self.netplan_path(), V1_TO_V2_NET_CFG_OUTPUT, 0o600), ++ ) + +- # ub_distro.apply_network_config(V1_NET_CFG, False) + self._apply_and_verify_netplan(self.distro.apply_network_config, + V1_NET_CFG, +- expected_cfgs=expected_cfgs.copy()) ++ expected_cfgs=expected_cfgs) + + def test_apply_network_config_v1_ipv6_to_netplan_ub(self): +- expected_cfgs = { +- self.netplan_path(): V1_TO_V2_NET_CFG_IPV6_OUTPUT, +- } ++ expected_cfgs = ( ++ (self.netplan_path(), V1_TO_V2_NET_CFG_IPV6_OUTPUT, 0o600), ++ ) + +- # ub_distro.apply_network_config(V1_NET_CFG_IPV6, False) + self._apply_and_verify_netplan(self.distro.apply_network_config, + V1_NET_CFG_IPV6, +- expected_cfgs=expected_cfgs.copy()) ++ expected_cfgs=expected_cfgs) + + def test_apply_network_config_v2_passthrough_ub(self): +- expected_cfgs = { +- self.netplan_path(): V2_TO_V2_NET_CFG_OUTPUT, +- } +- # ub_distro.apply_network_config(V2_NET_CFG, False) ++ expected_cfgs = ( ++ (self.netplan_path(), V2_TO_V2_NET_CFG_OUTPUT, 0o600), ++ ) + self._apply_and_verify_netplan(self.distro.apply_network_config, + V2_NET_CFG, +- expected_cfgs=expected_cfgs.copy()) ++ expected_cfgs=expected_cfgs) ++ ++ def test_apply_network_config_v2_passthrough_retain_orig_perms(self): ++ """Custom permissions on existing netplan is kept when more strict.""" ++ expected_cfgs = ( ++ (self.netplan_path(), V2_TO_V2_NET_CFG_OUTPUT, 0o640), ++ ) ++ with mock.patch.object( ++ features, "NETPLAN_CONFIG_ROOT_READ_ONLY", False ++ ): ++ # When NETPLAN_CONFIG_ROOT_READ_ONLY is False default perms are 644 ++ # we keep 640 because it's more strict. ++ # 1640 is used to assert sticky bit preserved across write ++ self._apply_and_verify_netplan( ++ self.distro.apply_network_config, ++ V2_NET_CFG, ++ expected_cfgs=expected_cfgs, ++ previous_files=( ++ ("/etc/netplan/50-cloud-init.yaml", "a", 0o640), ++ ), ++ ) + + def test_apply_network_config_v2_passthrough_ub_old_behavior(self): + """Kinetic and earlier have 50-cloud-init.yaml world-readable""" +- expected_cfgs = { +- self.netplan_path(): V2_TO_V2_NET_CFG_OUTPUT, +- } ++ expected_cfgs = ( ++ (self.netplan_path(), V2_TO_V2_NET_CFG_OUTPUT, 0o644), ++ ) + # ub_distro.apply_network_config(V2_NET_CFG, False) + with mock.patch.object( + features, "NETPLAN_CONFIG_ROOT_READ_ONLY", False +@@ -480,7 +502,7 @@ class TestNetCfgDistroUbuntuNetplan(TestNetCfgDistroBase): + self._apply_and_verify_netplan( + self.distro.apply_network_config, + V2_NET_CFG, +- expected_cfgs=expected_cfgs.copy(), ++ expected_cfgs=expected_cfgs, + ) + + class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -771,7 +793,6 @@ class TestNetCfgDistroArch(TestNetCfgDistroBase): + """), + } + +- # ub_distro.apply_network_config(V1_NET_CFG, False) + self._apply_and_verify(self.distro.apply_network_config, + V1_NET_CFG, + expected_cfgs=expected_cfgs.copy(), +@@ -920,6 +941,7 @@ class TestNetCfgDistroPhoton(TestNetCfgDistroBase): + + + def get_mode(path, target=None): ++ # Mask upper st_mode bits like S_IFREG bit preserve sticky and isuid/osgid + return os.stat(subp.target_path(target, path)).st_mode & 0o777 + + # vi: ts=4 expandtab +-- +2.33.0 + diff --git a/cloud-init.spec b/cloud-init.spec index b5c9233..be8cf4a 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init Version: 21.4 -Release: 10 +Release: 11 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 @@ -19,6 +19,7 @@ Patch7: delete-config-nopasswd-all.patch Patch8: backport-net-netplan-config-root-read-only-as-wifi-config-can.patch Patch9: backport-netplan-define-features.NETPLAN_CONFIG_ROOT_READ_ONL.patch Patch10: backport-Fix-the-distro.osfamily-output-problem.patch +Patch11: backport-netplan-keep-custom-strict-perms-when-50-cloud-init.patch Patch9000: Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch @@ -130,6 +131,9 @@ fi %exclude /usr/share/doc/* %changelog +* Mon Mar 27 2023 shixuantong - 21.4-11 +- keep custom strict perms when 50-cloud-init.yaml exists + * Thu Feb 02 2023 shixuantong - 21.4-10 - revert make the same authentication behavior for arm and x86 machine -- Gitee