diff --git a/Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch b/Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch index 91064ca6ef565e18f47c49325d2eb3e797b054fa..ad0504cdf3776e81c7811febca5414c708a0cf98 100644 --- a/Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch +++ b/Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch @@ -13,18 +13,18 @@ Reference:https://bugs.almalinux.org/view.php?id=32&nbn=1 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py -index 0a5d481..17ba3c5 100644 +index aa24303..bac1dc4 100644 --- a/cloudinit/net/sysconfig.py +++ b/cloudinit/net/sysconfig.py @@ -19,7 +19,7 @@ from .network_state import ( LOG = logging.getLogger(__name__) + KNOWN_DISTROS = ['almalinux', 'centos', 'cloudlinux', 'eurolinux', 'fedora', +- 'openEuler', 'rhel', 'rocky', 'suse', 'virtuozzo'] ++ 'openeuler', 'rhel', 'rocky', 'suse', 'virtuozzo'] NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf" --KNOWN_DISTROS = ['centos', 'fedora', 'rhel', 'suse'] -+KNOWN_DISTROS = ['centos', 'fedora', 'rhel', 'suse', 'linux'] - def _make_header(sep='#'): -- 1.8.3.1 diff --git a/add-variable-to-forbid-tmp-dir.patch b/add-variable-to-forbid-tmp-dir.patch index 690fea7bbb8683547a35dc7647f455b93824a7d3..7d9ddd678a452187444d6ea70ffd51751c6e784b 100644 --- a/add-variable-to-forbid-tmp-dir.patch +++ b/add-variable-to-forbid-tmp-dir.patch @@ -11,10 +11,10 @@ Signed-off-by: chengquan 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py -index bd02fac..a22737c 100755 +index d332273..4272db3 100755 --- a/setup.py +++ b/setup.py -@@ -75,6 +75,8 @@ def read_requires(): +@@ -78,6 +78,8 @@ def read_requires(): deps = subprocess.check_output(cmd) return deps.decode('utf-8').splitlines() @@ -23,7 +23,7 @@ index bd02fac..a22737c 100755 def render_tmpl(template, mode=None): """render template into a tmpdir under same dir as setup.py -@@ -96,7 +98,10 @@ def render_tmpl(template, mode=None): +@@ -99,7 +101,10 @@ def render_tmpl(template, mode=None): return template topdir = os.path.dirname(sys.argv[0]) @@ -35,26 +35,29 @@ index bd02fac..a22737c 100755 atexit.register(shutil.rmtree, tmpd) bname = os.path.basename(template).rstrip(tmpl_ext) fpath = os.path.join(tmpd, bname) -@@ -111,6 +116,10 @@ def render_tmpl(template, mode=None): +@@ -114,6 +119,9 @@ def render_tmpl(template, mode=None): # return path relative to setup.py return os.path.join(os.path.basename(tmpd), bname) +def sort_files(file_list): + file_list.sort() + return file_list -+ + # User can set the variant for template rendering if '--distro' in sys.argv: - idx = sys.argv.index('--distro') -@@ -126,9 +135,9 @@ INITSYS_FILES = { +@@ -130,10 +138,10 @@ INITSYS_FILES = { 'sysvinit_openrc': [f for f in glob('sysvinit/gentoo/*') if is_f(f)], 'sysvinit_suse': [f for f in glob('sysvinit/suse/*') if is_f(f)], 'systemd': [render_tmpl(f) - for f in (glob('systemd/*.tmpl') + + for f in sort_files((glob('systemd/*.tmpl') + glob('systemd/*.service') + + glob('systemd/*.socket') + - glob('systemd/*.target')) + glob('systemd/*.target'))) if (is_f(f) and not is_generator(f))], 'systemd.generators': [ render_tmpl(f, mode=0o755) +-- +1.8.3.1 + diff --git a/backport-CVE-2021-3429-write-passwords-only-to-serial-console-lock-down-clo.patch b/backport-CVE-2021-3429-write-passwords-only-to-serial-console-lock-down-clo.patch deleted file mode 100644 index 8d26a7c974fdd82fcf2f392d8f35540b66c87843..0000000000000000000000000000000000000000 --- a/backport-CVE-2021-3429-write-passwords-only-to-serial-console-lock-down-clo.patch +++ /dev/null @@ -1,350 +0,0 @@ -From b794d426b9ab43ea9d6371477466070d86e10668 Mon Sep 17 00:00:00 2001 -From: Daniel Watkins -Date: Fri, 19 Mar 2021 10:06:42 -0400 -Subject: [PATCH] write passwords only to serial console, lock down - cloud-init-output.log (#847) - -Prior to this commit, when a user specified configuration which would -generate random passwords for users, cloud-init would cause those -passwords to be written to the serial console by emitting them on -stderr. In the default configuration, any stdout or stderr emitted by -cloud-init is also written to `/var/log/cloud-init-output.log`. This -file is world-readable, meaning that those randomly-generated passwords -were available to be read by any user with access to the system. This -presents an obvious security issue. - -This commit responds to this issue in two ways: - -* We address the direct issue by moving from writing the passwords to - sys.stderr to writing them directly to /dev/console (via - util.multi_log); this means that the passwords will never end up in - cloud-init-output.log -* To avoid future issues like this, we also modify the logging code so - that any files created in a log sink subprocess will only be - owner/group readable and, if it exists, will be owned by the adm - group. This results in `/var/log/cloud-init-output.log` no longer - being world-readable, meaning that if there are other parts of the - codebase that are emitting sensitive data intended for the serial - console, that data is no longer available to all users of the system. - -LP: #1918303 ---- - cloudinit/config/cc_set_passwords.py | 5 +- - cloudinit/config/tests/test_set_passwords.py | 40 +++++++++---- - cloudinit/tests/test_util.py | 56 +++++++++++++++++++ - cloudinit/util.py | 38 +++++++++++-- - tests/integration_tests/test_logging.py | 22 ++++++++ - tests/unittests/test_util.py | 4 ++ - 6 files changed, 173 insertions(+), 16 deletions(-) - create mode 100644 tests/integration_tests/test_logging.py - -diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py -index d6b5682db4..433de751fa 100755 ---- a/cloudinit/config/cc_set_passwords.py -+++ b/cloudinit/config/cc_set_passwords.py -@@ -78,7 +78,6 @@ - """ - - import re --import sys - - from cloudinit.distros import ug_util - from cloudinit import log as logging -@@ -214,7 +213,9 @@ def handle(_name, cfg, cloud, log, args): - if len(randlist): - blurb = ("Set the following 'random' passwords\n", - '\n'.join(randlist)) -- sys.stderr.write("%s\n%s\n" % blurb) -+ util.multi_log( -+ "%s\n%s\n" % blurb, stderr=False, fallback_to_stdout=False -+ ) - - if expire: - expired_users = [] -diff --git a/cloudinit/config/tests/test_set_passwords.py b/cloudinit/config/tests/test_set_passwords.py -index daa1ef518f..bbe2ee8faa 100644 ---- a/cloudinit/config/tests/test_set_passwords.py -+++ b/cloudinit/config/tests/test_set_passwords.py -@@ -74,10 +74,6 @@ class TestSetPasswordsHandle(CiTestCase): - - with_logs = True - -- def setUp(self): -- super(TestSetPasswordsHandle, self).setUp() -- self.add_patch('cloudinit.config.cc_set_passwords.sys.stderr', 'm_err') -- - def test_handle_on_empty_config(self, *args): - """handle logs that no password has changed when config is empty.""" - cloud = self.tmp_cloud(distro='ubuntu') -@@ -129,10 +125,12 @@ def test_bsd_calls_custom_pw_cmds_to_set_and_expire_passwords( - mock.call(['pw', 'usermod', 'ubuntu', '-p', '01-Jan-1970'])], - m_subp.call_args_list) - -+ @mock.patch(MODPATH + "util.multi_log") - @mock.patch(MODPATH + "util.is_BSD") - @mock.patch(MODPATH + "subp.subp") -- def test_handle_on_chpasswd_list_creates_random_passwords(self, m_subp, -- m_is_bsd): -+ def test_handle_on_chpasswd_list_creates_random_passwords( -+ self, m_subp, m_is_bsd, m_multi_log -+ ): - """handle parses command set random passwords.""" - m_is_bsd.return_value = False - cloud = self.tmp_cloud(distro='ubuntu') -@@ -146,10 +144,32 @@ def test_handle_on_chpasswd_list_creates_random_passwords(self, m_subp, - self.assertIn( - 'DEBUG: Handling input for chpasswd as list.', - self.logs.getvalue()) -- self.assertNotEqual( -- [mock.call(['chpasswd'], -- '\n'.join(valid_random_pwds) + '\n')], -- m_subp.call_args_list) -+ -+ self.assertEqual(1, m_subp.call_count) -+ args, _kwargs = m_subp.call_args -+ self.assertEqual(["chpasswd"], args[0]) -+ -+ stdin = args[1] -+ user_pass = { -+ user: password -+ for user, password -+ in (line.split(":") for line in stdin.splitlines()) -+ } -+ -+ self.assertEqual(1, m_multi_log.call_count) -+ self.assertEqual( -+ mock.call(mock.ANY, stderr=False, fallback_to_stdout=False), -+ m_multi_log.call_args -+ ) -+ -+ self.assertEqual(set(["root", "ubuntu"]), set(user_pass.keys())) -+ written_lines = m_multi_log.call_args[0][0].splitlines() -+ for password in user_pass.values(): -+ for line in written_lines: -+ if password in line: -+ break -+ else: -+ self.fail("Password not emitted to console") - - - # vi: ts=4 expandtab -diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py -index b7a302f1cc..e811917e01 100644 ---- a/cloudinit/tests/test_util.py -+++ b/cloudinit/tests/test_util.py -@@ -851,4 +851,60 @@ def test_static_parameters_are_passed(self, m_write_file): - assert "ab" == kwargs["omode"] - - -+@mock.patch("cloudinit.util.grp.getgrnam") -+@mock.patch("cloudinit.util.os.setgid") -+@mock.patch("cloudinit.util.os.umask") -+class TestRedirectOutputPreexecFn: -+ """This tests specifically the preexec_fn used in redirect_output.""" -+ -+ @pytest.fixture(params=["outfmt", "errfmt"]) -+ def preexec_fn(self, request): -+ """A fixture to gather the preexec_fn used by redirect_output. -+ -+ This enables simpler direct testing of it, and parameterises any tests -+ using it to cover both the stdout and stderr code paths. -+ """ -+ test_string = "| piped output to invoke subprocess" -+ if request.param == "outfmt": -+ args = (test_string, None) -+ elif request.param == "errfmt": -+ args = (None, test_string) -+ with mock.patch("cloudinit.util.subprocess.Popen") as m_popen: -+ util.redirect_output(*args) -+ -+ assert 1 == m_popen.call_count -+ _args, kwargs = m_popen.call_args -+ assert "preexec_fn" in kwargs, "preexec_fn not passed to Popen" -+ return kwargs["preexec_fn"] -+ -+ def test_preexec_fn_sets_umask( -+ self, m_os_umask, _m_setgid, _m_getgrnam, preexec_fn -+ ): -+ """preexec_fn should set a mask that avoids world-readable files.""" -+ preexec_fn() -+ -+ assert [mock.call(0o037)] == m_os_umask.call_args_list -+ -+ def test_preexec_fn_sets_group_id_if_adm_group_present( -+ self, _m_os_umask, m_setgid, m_getgrnam, preexec_fn -+ ): -+ """We should setgrp to adm if present, so files are owned by them.""" -+ fake_group = mock.Mock(gr_gid=mock.sentinel.gr_gid) -+ m_getgrnam.return_value = fake_group -+ -+ preexec_fn() -+ -+ assert [mock.call("adm")] == m_getgrnam.call_args_list -+ assert [mock.call(mock.sentinel.gr_gid)] == m_setgid.call_args_list -+ -+ def test_preexec_fn_handles_absent_adm_group_gracefully( -+ self, _m_os_umask, m_setgid, m_getgrnam, preexec_fn -+ ): -+ """We should handle an absent adm group gracefully.""" -+ m_getgrnam.side_effect = KeyError("getgrnam(): name not found: 'adm'") -+ -+ preexec_fn() -+ -+ assert 0 == m_setgid.call_count -+ - # vi: ts=4 expandtab -diff --git a/cloudinit/util.py b/cloudinit/util.py -index 769f3425ee..4e0a72db86 100644 ---- a/cloudinit/util.py -+++ b/cloudinit/util.py -@@ -359,7 +359,7 @@ def find_modules(root_dir): - - - def multi_log(text, console=True, stderr=True, -- log=None, log_level=logging.DEBUG): -+ log=None, log_level=logging.DEBUG, fallback_to_stdout=True): - if stderr: - sys.stderr.write(text) - if console: -@@ -368,7 +368,7 @@ def multi_log(text, console=True, stderr=True, - with open(conpath, 'w') as wfh: - wfh.write(text) - wfh.flush() -- else: -+ elif fallback_to_stdout: - # A container may lack /dev/console (arguably a container bug). If - # it does not exist, then write output to stdout. this will result - # in duplicate stderr and stdout messages if stderr was True. -@@ -623,6 +623,26 @@ def redirect_output(outfmt, errfmt, o_out=None, o_err=None): - if not o_err: - o_err = sys.stderr - -+ # pylint: disable=subprocess-popen-preexec-fn -+ def set_subprocess_umask_and_gid(): -+ """Reconfigure umask and group ID to create output files securely. -+ -+ This is passed to subprocess.Popen as preexec_fn, so it is executed in -+ the context of the newly-created process. It: -+ -+ * sets the umask of the process so created files aren't world-readable -+ * if an adm group exists in the system, sets that as the process' GID -+ (so that the created file(s) are owned by root:adm) -+ """ -+ os.umask(0o037) -+ try: -+ group_id = grp.getgrnam("adm").gr_gid -+ except KeyError: -+ # No adm group, don't set a group -+ pass -+ else: -+ os.setgid(group_id) -+ - if outfmt: - LOG.debug("Redirecting %s to %s", o_out, outfmt) - (mode, arg) = outfmt.split(" ", 1) -@@ -632,7 +652,12 @@ def redirect_output(outfmt, errfmt, o_out=None, o_err=None): - owith = "wb" - new_fp = open(arg, owith) - elif mode == "|": -- proc = subprocess.Popen(arg, shell=True, stdin=subprocess.PIPE) -+ proc = subprocess.Popen( -+ arg, -+ shell=True, -+ stdin=subprocess.PIPE, -+ preexec_fn=set_subprocess_umask_and_gid, -+ ) - new_fp = proc.stdin - else: - raise TypeError("Invalid type for output format: %s" % outfmt) -@@ -654,7 +679,12 @@ def redirect_output(outfmt, errfmt, o_out=None, o_err=None): - owith = "wb" - new_fp = open(arg, owith) - elif mode == "|": -- proc = subprocess.Popen(arg, shell=True, stdin=subprocess.PIPE) -+ proc = subprocess.Popen( -+ arg, -+ shell=True, -+ stdin=subprocess.PIPE, -+ preexec_fn=set_subprocess_umask_and_gid, -+ ) - new_fp = proc.stdin - else: - raise TypeError("Invalid type for error format: %s" % errfmt) -diff --git a/tests/integration_tests/modules/test_set_password.py b/tests/integration_tests/modules/test_set_password.py -index b13f76fbfd..d7cf91a57b 100644 ---- a/tests/integration_tests/modules/test_set_password.py -+++ b/tests/integration_tests/modules/test_set_password.py -@@ -116,6 +116,30 @@ def test_random_passwords_set_correctly(self, class_client): - # Which are not the same - assert shadow_users["harry"] != shadow_users["dick"] - -+ def test_random_passwords_not_stored_in_cloud_init_output_log( -+ self, class_client -+ ): -+ """We should not emit passwords to the in-instance log file. -+ -+ LP: #1918303 -+ """ -+ cloud_init_output = class_client.read_from_file( -+ "/var/log/cloud-init-output.log" -+ ) -+ assert "dick:" not in cloud_init_output -+ assert "harry:" not in cloud_init_output -+ -+ def test_random_passwords_emitted_to_serial_console(self, class_client): -+ """We should emit passwords to the serial console. (LP: #1918303)""" -+ try: -+ console_log = class_client.instance.console_log() -+ except NotImplementedError: -+ # Assume that an exception here means that we can't use the console -+ # log -+ pytest.skip("NotImplementedError when requesting console log") -+ assert "dick:" in console_log -+ assert "harry:" in console_log -+ - def test_explicit_password_set_correctly(self, class_client): - """Test that an explicitly-specified password is set correctly.""" - shadow_users, _ = self._fetch_and_parse_etc_shadow(class_client) -diff --git a/tests/integration_tests/test_logging.py b/tests/integration_tests/test_logging.py -new file mode 100644 -index 0000000000..b31a043482 ---- /dev/null -+++ b/tests/integration_tests/test_logging.py -@@ -0,0 +1,22 @@ -+"""Integration tests relating to cloud-init's logging.""" -+ -+ -+class TestVarLogCloudInitOutput: -+ """Integration tests relating to /var/log/cloud-init-output.log.""" -+ -+ def test_var_log_cloud_init_output_not_world_readable(self, client): -+ """ -+ The log can contain sensitive data, it shouldn't be world-readable. -+ -+ LP: #1918303 -+ """ -+ # Check the file exists -+ assert client.execute("test -f /var/log/cloud-init-output.log").ok -+ -+ # Check its permissions are as we expect -+ perms, user, group = client.execute( -+ "stat -c %a:%U:%G /var/log/cloud-init-output.log" -+ ).split(":") -+ assert "640" == perms -+ assert "root" == user -+ assert "adm" == group -diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py -index 857629f1c4..e52920010a 100644 ---- a/tests/unittests/test_util.py -+++ b/tests/unittests/test_util.py -@@ -572,6 +572,10 @@ def test_logs_go_to_stdout_if_console_does_not_exist(self): - util.multi_log(logged_string) - self.assertEqual(logged_string, self.stdout.getvalue()) - -+ def test_logs_dont_go_to_stdout_if_fallback_to_stdout_is_false(self): -+ util.multi_log('something', fallback_to_stdout=False) -+ self.assertEqual('', self.stdout.getvalue()) -+ - def test_logs_go_to_log_if_given(self): - log = mock.MagicMock() - logged_string = 'something very important' diff --git a/backport-net-exclude-OVS-internal-interfaces-in-get_interface.patch b/backport-net-exclude-OVS-internal-interfaces-in-get_interface.patch deleted file mode 100644 index ac56366d86f6b44c553895a6b45880b7569ecdc4..0000000000000000000000000000000000000000 --- a/backport-net-exclude-OVS-internal-interfaces-in-get_interface.patch +++ /dev/null @@ -1,496 +0,0 @@ -From 121bc04cdf0e6732fe143b7419131dc250c13384 Mon Sep 17 00:00:00 2001 -From: Daniel Watkins -Date: Mon, 8 Mar 2021 12:50:57 -0500 -Subject: [PATCH] net: exclude OVS internal interfaces in get_interfaces (#829) - -`get_interfaces` is used to in two ways, broadly: firstly, to determine -the available interfaces when converting cloud network configuration -formats to cloud-init's network configuration formats; and, secondly, to -ensure that any interfaces which are specified in network configuration -are (a) available, and (b) named correctly. The first of these is -unaffected by this commit, as no clouds support Open vSwitch -configuration in their network configuration formats. - -For the second, we check that MAC addresses of physical devices are -unique. In some OVS configurations, there are OVS-created devices which -have duplicate MAC addresses, either with each other or with physical -devices. As these interfaces are created by OVS, we can be confident -that (a) they will be available when appropriate, and (b) that OVS will -name them correctly. As such, this commit excludes any OVS-internal -interfaces from the set of interfaces returned by `get_interfaces`. - -LP: #1912844 ---- - cloudinit/net/__init__.py | 62 +++++++++++ - cloudinit/net/tests/test_init.py | 119 +++++++++++++++++++++ - cloudinit/sources/helpers/tests/test_openstack.py | 5 + - cloudinit/sources/tests/test_oracle.py | 4 + - tests/integration_tests/bugs/test_lp1912844.py | 103 ++++++++++++++++++ - .../unittests/test_datasource/test_configdrive.py | 8 ++ - tests/unittests/test_net.py | 20 ++++ - 7 files changed, 321 insertions(+) - create mode 100644 tests/integration_tests/bugs/test_lp1912844.py - -diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py -index de65e7a..385b7bc 100644 ---- a/cloudinit/net/__init__.py -+++ b/cloudinit/net/__init__.py -@@ -6,6 +6,7 @@ - # This file is part of cloud-init. See LICENSE file for license information. - - import errno -+import functools - import ipaddress - import logging - import os -@@ -19,6 +20,19 @@ from cloudinit.url_helper import UrlError, readurl - LOG = logging.getLogger(__name__) - SYS_CLASS_NET = "/sys/class/net/" - DEFAULT_PRIMARY_INTERFACE = 'eth0' -+OVS_INTERNAL_INTERFACE_LOOKUP_CMD = [ -+ "ovs-vsctl", -+ "--format", -+ "csv", -+ "--no-headings", -+ "--timeout", -+ "10", -+ "--columns", -+ "name", -+ "find", -+ "interface", -+ "type=internal", -+] - - - def natural_sort_key(s, _nsre=re.compile('([0-9]+)')): -@@ -133,6 +147,52 @@ def master_is_openvswitch(devname): - return os.path.exists(ovs_path) - - -+@functools.lru_cache(maxsize=None) -+def openvswitch_is_installed() -> bool: -+ """Return a bool indicating if Open vSwitch is installed in the system.""" -+ ret = bool(subp.which("ovs-vsctl")) -+ if not ret: -+ LOG.debug( -+ "ovs-vsctl not in PATH; not detecting Open vSwitch interfaces" -+ ) -+ return ret -+ -+ -+@functools.lru_cache(maxsize=None) -+def get_ovs_internal_interfaces() -> list: -+ """Return a list of the names of OVS internal interfaces on the system. -+ -+ These will all be strings, and are used to exclude OVS-specific interface -+ from cloud-init's network configuration handling. -+ """ -+ try: -+ out, _err = subp.subp(OVS_INTERNAL_INTERFACE_LOOKUP_CMD) -+ except subp.ProcessExecutionError as exc: -+ if "database connection failed" in exc.stderr: -+ LOG.info( -+ "Open vSwitch is not yet up; no interfaces will be detected as" -+ " OVS-internal" -+ ) -+ return [] -+ raise -+ else: -+ return out.splitlines() -+ -+ -+def is_openvswitch_internal_interface(devname: str) -> bool: -+ """Returns True if this is an OVS internal interface. -+ -+ If OVS is not installed or not yet running, this will return False. -+ """ -+ if not openvswitch_is_installed(): -+ return False -+ ovs_bridges = get_ovs_internal_interfaces() -+ if devname in ovs_bridges: -+ LOG.debug("Detected %s as an OVS interface", devname) -+ return True -+ return False -+ -+ - def is_netfailover(devname, driver=None): - """ netfailover driver uses 3 nics, master, primary and standby. - this returns True if the device is either the primary or standby -@@ -884,6 +944,8 @@ def get_interfaces(blacklist_drivers=None) -> list: - # skip nics that have no mac (00:00....) - if name != 'lo' and mac == zero_mac[:len(mac)]: - continue -+ if is_openvswitch_internal_interface(name): -+ continue - # skip nics that have drivers blacklisted - driver = device_driver(name) - if driver in blacklist_drivers: -diff --git a/cloudinit/net/tests/test_init.py b/cloudinit/net/tests/test_init.py -index 0535387..946f8ee 100644 ---- a/cloudinit/net/tests/test_init.py -+++ b/cloudinit/net/tests/test_init.py -@@ -391,6 +391,10 @@ class TestGetDeviceList(CiTestCase): - self.assertCountEqual(['eth0', 'eth1'], net.get_devicelist()) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False), -+) - class TestGetInterfaceMAC(CiTestCase): - - def setUp(self): -@@ -1224,6 +1228,121 @@ class TestNetFailOver(CiTestCase): - self.assertFalse(net.is_netfailover(devname, driver)) - - -+class TestOpenvswitchIsInstalled: -+ """Test cloudinit.net.openvswitch_is_installed. -+ -+ Uses the ``clear_lru_cache`` local autouse fixture to allow us to test -+ despite the ``lru_cache`` decorator on the unit under test. -+ """ -+ -+ @pytest.fixture(autouse=True) -+ def clear_lru_cache(self): -+ net.openvswitch_is_installed.cache_clear() -+ -+ @pytest.mark.parametrize( -+ "expected,which_return", [(True, "/some/path"), (False, None)] -+ ) -+ @mock.patch("cloudinit.net.subp.which") -+ def test_mirrors_which_result(self, m_which, expected, which_return): -+ m_which.return_value = which_return -+ assert expected == net.openvswitch_is_installed() -+ -+ @mock.patch("cloudinit.net.subp.which") -+ def test_only_calls_which_once(self, m_which): -+ net.openvswitch_is_installed() -+ net.openvswitch_is_installed() -+ assert 1 == m_which.call_count -+ -+ -+@mock.patch("cloudinit.net.subp.subp", return_value=("", "")) -+class TestGetOVSInternalInterfaces: -+ """Test cloudinit.net.get_ovs_internal_interfaces. -+ -+ Uses the ``clear_lru_cache`` local autouse fixture to allow us to test -+ despite the ``lru_cache`` decorator on the unit under test. -+ """ -+ @pytest.fixture(autouse=True) -+ def clear_lru_cache(self): -+ net.get_ovs_internal_interfaces.cache_clear() -+ -+ def test_command_used(self, m_subp): -+ """Test we use the correct command when we call subp""" -+ net.get_ovs_internal_interfaces() -+ -+ assert [ -+ mock.call(net.OVS_INTERNAL_INTERFACE_LOOKUP_CMD) -+ ] == m_subp.call_args_list -+ -+ def test_subp_contents_split_and_returned(self, m_subp): -+ """Test that the command output is appropriately mangled.""" -+ stdout = "iface1\niface2\niface3\n" -+ m_subp.return_value = (stdout, "") -+ -+ assert [ -+ "iface1", -+ "iface2", -+ "iface3", -+ ] == net.get_ovs_internal_interfaces() -+ -+ def test_database_connection_error_handled_gracefully(self, m_subp): -+ """Test that the error indicating OVS is down is handled gracefully.""" -+ m_subp.side_effect = ProcessExecutionError( -+ stderr="database connection failed" -+ ) -+ -+ assert [] == net.get_ovs_internal_interfaces() -+ -+ def test_other_errors_raised(self, m_subp): -+ """Test that only database connection errors are handled.""" -+ m_subp.side_effect = ProcessExecutionError() -+ -+ with pytest.raises(ProcessExecutionError): -+ net.get_ovs_internal_interfaces() -+ -+ def test_only_runs_once(self, m_subp): -+ """Test that we cache the value.""" -+ net.get_ovs_internal_interfaces() -+ net.get_ovs_internal_interfaces() -+ -+ assert 1 == m_subp.call_count -+ -+ -+@mock.patch("cloudinit.net.get_ovs_internal_interfaces") -+@mock.patch("cloudinit.net.openvswitch_is_installed") -+class TestIsOpenVSwitchInternalInterface: -+ def test_false_if_ovs_not_installed( -+ self, m_openvswitch_is_installed, _m_get_ovs_internal_interfaces -+ ): -+ """Test that OVS' absence returns False.""" -+ m_openvswitch_is_installed.return_value = False -+ -+ assert not net.is_openvswitch_internal_interface("devname") -+ -+ @pytest.mark.parametrize( -+ "detected_interfaces,devname,expected_return", -+ [ -+ ([], "devname", False), -+ (["notdevname"], "devname", False), -+ (["devname"], "devname", True), -+ (["some", "other", "devices", "and", "ours"], "ours", True), -+ ], -+ ) -+ def test_return_value_based_on_detected_interfaces( -+ self, -+ m_openvswitch_is_installed, -+ m_get_ovs_internal_interfaces, -+ detected_interfaces, -+ devname, -+ expected_return, -+ ): -+ """Test that the detected interfaces are used correctly.""" -+ m_openvswitch_is_installed.return_value = True -+ m_get_ovs_internal_interfaces.return_value = detected_interfaces -+ assert expected_return == net.is_openvswitch_internal_interface( -+ devname -+ ) -+ -+ - class TestIsIpAddress: - """Tests for net.is_ip_address. - -diff --git a/cloudinit/sources/helpers/tests/test_openstack.py b/cloudinit/sources/helpers/tests/test_openstack.py -index 2bde1e3..95fb974 100644 ---- a/cloudinit/sources/helpers/tests/test_openstack.py -+++ b/cloudinit/sources/helpers/tests/test_openstack.py -@@ -1,10 +1,15 @@ - # This file is part of cloud-init. See LICENSE file for license information. - # ./cloudinit/sources/helpers/tests/test_openstack.py -+from unittest import mock - - from cloudinit.sources.helpers import openstack - from cloudinit.tests import helpers as test_helpers - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestConvertNetJson(test_helpers.CiTestCase): - - def test_phy_types(self): -diff --git a/cloudinit/sources/tests/test_oracle.py b/cloudinit/sources/tests/test_oracle.py -index a7bbdfd..dcf33b9 100644 ---- a/cloudinit/sources/tests/test_oracle.py -+++ b/cloudinit/sources/tests/test_oracle.py -@@ -173,6 +173,10 @@ class TestIsPlatformViable(test_helpers.CiTestCase): - m_read_dmi_data.assert_has_calls([mock.call('chassis-asset-tag')]) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestNetworkConfigFromOpcImds: - def test_no_secondary_nics_does_not_mutate_input(self, oracle_ds): - oracle_ds._vnics_data = [{}] -diff --git a/tests/integration_tests/bugs/test_lp1912844.py b/tests/integration_tests/bugs/test_lp1912844.py -new file mode 100644 -index 0000000..efafae5 ---- /dev/null -+++ b/tests/integration_tests/bugs/test_lp1912844.py -@@ -0,0 +1,103 @@ -+"""Integration test for LP: #1912844 -+ -+cloud-init should ignore OVS-internal interfaces when performing its own -+interface determination: these interfaces are handled fully by OVS, so -+cloud-init should never need to touch them. -+ -+This test is a semi-synthetic reproducer for the bug. It uses a similar -+network configuration, tweaked slightly to DHCP in a way that will succeed even -+on "failed" boots. The exact bug doesn't reproduce with the NoCloud -+datasource, because it runs at init-local time (whereas the MAAS datasource, -+from the report, runs only at init (network) time): this means that the -+networking code runs before OVS creates its interfaces (which happens after -+init-local but, of course, before networking is up), and so doesn't generate -+the traceback that they cause. We work around this by calling -+``get_interfaces_by_mac` directly in the test code. -+""" -+import pytest -+ -+from tests.integration_tests import random_mac_address -+ -+MAC_ADDRESS = random_mac_address() -+ -+NETWORK_CONFIG = """\ -+bonds: -+ bond0: -+ interfaces: -+ - enp5s0 -+ macaddress: {0} -+ mtu: 1500 -+bridges: -+ ovs-br: -+ interfaces: -+ - bond0 -+ macaddress: {0} -+ mtu: 1500 -+ openvswitch: {{}} -+ dhcp4: true -+ethernets: -+ enp5s0: -+ mtu: 1500 -+ set-name: enp5s0 -+ match: -+ macaddress: {0} -+version: 2 -+vlans: -+ ovs-br.100: -+ id: 100 -+ link: ovs-br -+ mtu: 1500 -+ ovs-br.200: -+ id: 200 -+ link: ovs-br -+ mtu: 1500 -+""".format(MAC_ADDRESS) -+ -+ -+SETUP_USER_DATA = """\ -+#cloud-config -+packages: -+- openvswitch-switch -+""" -+ -+ -+@pytest.fixture -+def ovs_enabled_session_cloud(session_cloud): -+ """A session_cloud wrapper, to use an OVS-enabled image for tests. -+ -+ This implementation is complicated by wanting to use ``session_cloud``s -+ snapshot cleanup/retention logic, to avoid having to reimplement that here. -+ """ -+ old_snapshot_id = session_cloud.snapshot_id -+ with session_cloud.launch( -+ user_data=SETUP_USER_DATA, -+ ) as instance: -+ instance.instance.clean() -+ session_cloud.snapshot_id = instance.snapshot() -+ -+ yield session_cloud -+ -+ try: -+ session_cloud.delete_snapshot() -+ finally: -+ session_cloud.snapshot_id = old_snapshot_id -+ -+ -+@pytest.mark.lxd_vm -+def test_get_interfaces_by_mac_doesnt_traceback(ovs_enabled_session_cloud): -+ """Launch our OVS-enabled image and confirm the bug doesn't reproduce.""" -+ launch_kwargs = { -+ "config_dict": { -+ "user.network-config": NETWORK_CONFIG, -+ "volatile.eth0.hwaddr": MAC_ADDRESS, -+ }, -+ } -+ with ovs_enabled_session_cloud.launch( -+ launch_kwargs=launch_kwargs, -+ ) as client: -+ result = client.execute( -+ "python3 -c" -+ "'from cloudinit.net import get_interfaces_by_mac;" -+ "get_interfaces_by_mac()'" -+ ) -+ assert result.ok -diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py -index 6f830cc..2e2b784 100644 ---- a/tests/unittests/test_datasource/test_configdrive.py -+++ b/tests/unittests/test_datasource/test_configdrive.py -@@ -494,6 +494,10 @@ class TestConfigDriveDataSource(CiTestCase): - self.assertEqual('config-disk (/dev/anything)', cfg_ds.subplatform) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestNetJson(CiTestCase): - def setUp(self): - super(TestNetJson, self).setUp() -@@ -654,6 +658,10 @@ class TestNetJson(CiTestCase): - self.assertEqual(out_data, conv_data) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestConvertNetworkData(CiTestCase): - - with_logs = True -diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py -index 38d934d..cb636f4 100644 ---- a/tests/unittests/test_net.py -+++ b/tests/unittests/test_net.py -@@ -2933,6 +2933,10 @@ iface eth1 inet dhcp - self.assertEqual(0, mock_settle.call_count) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestRhelSysConfigRendering(CiTestCase): - - with_logs = True -@@ -3620,6 +3624,10 @@ USERCTL=no - expected, self._render_and_read(network_config=v2data)) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestOpenSuseSysConfigRendering(CiTestCase): - - with_logs = True -@@ -5037,6 +5045,10 @@ class TestNetRenderers(CiTestCase): - self.assertTrue(result) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestGetInterfaces(CiTestCase): - _data = {'bonds': ['bond1'], - 'bridges': ['bridge1'], -@@ -5186,6 +5198,10 @@ class TestInterfaceHasOwnMac(CiTestCase): - self.assertFalse(interface_has_own_mac("eth0")) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestGetInterfacesByMac(CiTestCase): - _data = {'bonds': ['bond1'], - 'bridges': ['bridge1'], -@@ -5342,6 +5358,10 @@ class TestInterfacesSorting(CiTestCase): - ['enp0s3', 'enp0s8', 'enp0s13', 'enp1s2', 'enp2s0', 'enp2s3']) - - -+@mock.patch( -+ "cloudinit.net.is_openvswitch_internal_interface", -+ mock.Mock(return_value=False) -+) - class TestGetIBHwaddrsByInterface(CiTestCase): - - _ib_addr = '80:00:00:28:fe:80:00:00:00:00:00:00:00:11:22:03:00:33:44:56' --- -1.8.3.1 - diff --git a/bugfix-cloud-init-add-openEuler-os.patch b/bugfix-cloud-init-add-openEuler-os.patch index 7404035306ddb11557158c28cada67e0d4f7b7fd..6f9f21fc406938173aae66266d140b42a13c8b84 100644 --- a/bugfix-cloud-init-add-openEuler-os.patch +++ b/bugfix-cloud-init-add-openEuler-os.patch @@ -1,9 +1,9 @@ From 098429a75ea00df1d8a5670e45df6babfc37f327 Mon Sep 17 00:00:00 2001 From: chengquan Date: Thu, 8 Aug 2019 16:11:58 +0800 -Subject: [PATCH] cloud-init: cloud-init add openEuler os +Subject: [PATCH] cloud-init: cloud-init add openeuler os -reason: add openEuler into distros +reason: add openeuler into distros Signed-off-by: chengquan --- @@ -14,43 +14,44 @@ Signed-off-by: chengquan cloud-init-20.3/cloudinit/config/cc_spacewalk.py | 2 +- .../cloudinit/config/cc_yum_add_repo.py | 2 +- cloud-init-20.3/cloudinit/distros/__init__.py | 2 +- - cloud-init-20.3/cloudinit/distros/openEuler.py | 12 ++++ + cloud-init-20.3/cloudinit/distros/openeuler.py | 12 ++++ cloud-init-20.3/cloudinit/util.py | 2 +- cloud-init-20.3/config/cloud.cfg.tmpl | 8 +-- cloud-init-20.3/systemd/cloud-init.service.tmpl | 2 +- cloud-init-20.3/tests/cloud_tests/util.py | 2 +- cloud-init-20.3/tools/render-cloudcfg | 2 +- - 14 files changed, 95 insertions(+), 15 deletions(-) - create mode 100644 cloud-init-19.4/cloudinit/distros/openEuler.py + cloud-init-20.3/systemd/cloud-init-generator.tmpl | 2 +- + 15 files changed, 96 insertions(+), 16 deletions(-) + create mode 100644 cloud-init-19.4/cloudinit/distros/openeuler.py diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py -index 3d7279d..ae6f06b 100644 +index c3aee79..b107359 100644 --- a/cloudinit/config/cc_ntp.py +++ b/cloudinit/config/cc_ntp.py @@ -25,7 +25,7 @@ frequency = PER_INSTANCE NTP_CONF = '/etc/ntp.conf' NR_POOL_SERVERS = 4 - distros = ['alpine', 'centos', 'debian', 'fedora', 'opensuse', 'rhel', -- 'sles', 'ubuntu'] -+ 'sles', 'ubuntu', 'openEuler'] + distros = ['almalinux', 'alpine', 'centos', 'cloudlinux', 'debian', +- 'eurolinux', 'fedora', 'openEuler', 'opensuse', 'photon', ++ 'eurolinux', 'fedora', 'openeuler', 'opensuse', 'photon', + 'rhel', 'rocky', 'sles', 'ubuntu', 'virtuozzo'] NTP_CLIENT_CONFIG = { - 'chrony': { diff --git a/cloudinit/config/cc_resolv_conf.py b/cloudinit/config/cc_resolv_conf.py -index 519e66e..dc093fb 100644 +index 648935e..8a4efa5 100644 --- a/cloudinit/config/cc_resolv_conf.py +++ b/cloudinit/config/cc_resolv_conf.py @@ -55,7 +55,7 @@ LOG = logging.getLogger(__name__) frequency = PER_INSTANCE --distros = ['alpine', 'fedora', 'opensuse', 'rhel', 'sles'] -+distros = ['alpine', 'fedora', 'opensuse', 'rhel', 'sles', 'openEuler'] +-distros = ['alpine', 'fedora', 'opensuse', 'photon', 'rhel', 'sles'] ++distros = ['alpine', 'fedora', 'opensuse', 'photon', 'rhel', 'sles', 'openeuler'] - - def generate_resolv_conf(template_fn, params, target_fname="/etc/resolv.conf"): + RESOLVE_CONFIG_TEMPLATE_MAP = { + '/etc/resolv.conf': 'resolv.conf', diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py -index 28d62e9..9a25767 100644 +index 693317c..6c1c6b7 100644 --- a/cloudinit/config/cc_rh_subscription.py +++ b/cloudinit/config/cc_rh_subscription.py @@ -44,7 +44,7 @@ from cloudinit import util @@ -58,12 +59,12 @@ index 28d62e9..9a25767 100644 LOG = logging.getLogger(__name__) -distros = ['fedora', 'rhel'] -+distros = ['fedora', 'rhel', 'openEuler'] ++distros = ['fedora', 'rhel', 'openeuler'] def handle(name, cfg, _cloud, log, _args): diff --git a/cloudinit/config/cc_spacewalk.py b/cloudinit/config/cc_spacewalk.py -index 9508360..0cee8a7 100644 +index 9508360..6732979 100644 --- a/cloudinit/config/cc_spacewalk.py +++ b/cloudinit/config/cc_spacewalk.py @@ -30,7 +30,7 @@ For more information about spacewalk see: https://fedorahosted.org/spacewalk/ @@ -71,41 +72,41 @@ index 9508360..0cee8a7 100644 -distros = ['redhat', 'fedora'] -+distros = ['redhat', 'fedora', 'openEuler'] ++distros = ['redhat', 'fedora', 'openeuler'] required_packages = ['rhn-setup'] def_ca_cert_path = "/usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT" diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py -index 01fe683..1b7c783 100644 +index d66d3ae..f4ac969 100644 --- a/cloudinit/config/cc_yum_add_repo.py +++ b/cloudinit/config/cc_yum_add_repo.py -@@ -36,7 +36,7 @@ from configparser import ConfigParser - +@@ -38,7 +38,7 @@ from configparser import ConfigParser from cloudinit import util --distros = ['centos', 'fedora', 'rhel'] -+distros = ['centos', 'fedora', 'rhel', 'openEuler'] + distros = ['almalinux', 'centos', 'cloudlinux', 'eurolinux', 'fedora', +- 'openEuler', 'photon', 'rhel', 'rocky', 'virtuozzo'] ++ 'openeuler', 'photon', 'rhel', 'rocky', 'virtuozzo'] def _canonicalize_id(repo_id): diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py -index 2537608..2492962 100755 +index cf6aad1..d91aab2 100755 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py -@@ -45,7 +45,7 @@ OSFAMILIES = { - 'debian': ['debian', 'ubuntu'], +@@ -50,7 +50,7 @@ OSFAMILIES = { 'freebsd': ['freebsd'], 'gentoo': ['gentoo'], -- 'redhat': ['amazon', 'centos', 'fedora', 'rhel'], -+ 'redhat': ['amazon', 'centos', 'fedora', 'rhel', 'openEuler'], + 'redhat': ['almalinux', 'amazon', 'centos', 'cloudlinux', 'eurolinux', +- 'fedora', 'openEuler', 'photon', 'rhel', 'rocky', 'virtuozzo'], ++ 'fedora', 'openeuler', 'photon', 'rhel', 'rocky', 'virtuozzo'], 'suse': ['opensuse', 'sles'], } -diff --git a/cloudinit/distros/openEuler.py b/cloudinit/distros/openEuler.py +diff --git a/cloudinit/distros/openeuler.py b/cloudinit/distros/openeuler.py new file mode 100644 index 0000000..7505ca4 --- /dev/null -+++ b/cloudinit/distros/openEuler.py ++++ b/cloudinit/distros/openeuler.py @@ -0,0 +1,12 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. +# This file is part of cloud-init. See LICENSE file for license information. @@ -120,94 +121,123 @@ index 0000000..7505ca4 + +# vi: ts=4 expandtab diff --git a/cloudinit/util.py b/cloudinit/util.py -index cf9e349..39a6c50 100644 +index 575a1fe..68c12f9 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -549,7 +549,7 @@ def system_info(): linux_dist = info['dist'][0].lower() if linux_dist in ( - 'alpine', 'arch', 'centos', 'debian', 'fedora', 'rhel', -- 'suse'): -+ 'suse', 'openEuler'): + 'almalinux', 'alpine', 'arch', 'centos', 'cloudlinux', +- 'debian', 'eurolinux', 'fedora', 'openEuler', 'photon', ++ 'debian', 'eurolinux', 'fedora', 'openeuler', 'photon', + 'rhel', 'rocky', 'suse', 'virtuozzo'): var = linux_dist elif linux_dist in ('ubuntu', 'linuxmint', 'mint'): - var = 'ubuntu' diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl -index 2beb9b0..2318741 100644 +index b66bbe6..995ba66 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl -@@ -21,7 +21,7 @@ disable_root: false - disable_root: true +@@ -33,7 +33,7 @@ disable_root: true {% endif %} --{% if variant in ["alpine", "amazon", "centos", "fedora", "rhel"] %} -+{% if variant in ["alpine", "amazon", "centos", "fedora", "rhel", "openEuler"] %} + {% if variant in ["almalinux", "alpine", "amazon", "centos", "cloudlinux", "eurolinux", +- "fedora", "openEuler", "rhel", "rocky", "virtuozzo"] %} ++ "fedora", "openeuler", "rhel", "rocky", "virtuozzo"] %} mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2'] {% if variant == "amazon" %} resize_rootfs: noblock -@@ -92,7 +92,7 @@ cloud_config_modules: - - ssh-import-id +@@ -110,7 +110,7 @@ cloud_config_modules: - locale + {% endif %} - set-passwords --{% if variant in ["rhel", "fedora"] %} -+{% if variant in ["rhel", "fedora", "openEuler"] %} +-{% if variant in ["rhel", "fedora", "photon"] %} ++{% if variant in ["rhel", "fedora", "photon", "openeuler"] %} + {% if variant not in ["photon"] %} - spacewalk - - yum-add-repo {% endif %} -@@ -153,7 +153,7 @@ system_info: +@@ -176,7 +176,7 @@ cloud_final_modules: + system_info: # This will affect which distro class gets used - {% if variant in ["alpine", "amazon", "arch", "centos", "debian", - "fedora", "freebsd", "netbsd", "openbsd", "rhel", -- "suse", "ubuntu"] %} -+ "suse", "ubuntu", "openEuler"] %} + {% if variant in ["almalinux", "alpine", "amazon", "arch", "centos", "cloudlinux", "debian", +- "eurolinux", "fedora", "freebsd", "netbsd", "openbsd", "openEuler", ++ "eurolinux", "fedora", "freebsd", "netbsd", "openbsd", "openeuler", + "photon", "rhel", "rocky", "suse", "ubuntu", "virtuozzo"] %} distro: {{ variant }} - {% else %} - # Unknown/fallback distro. -@@ -205,7 +205,7 @@ system_info: + {% elif variant in ["dragonfly"] %} +@@ -231,7 +231,7 @@ system_info: security: http://ports.ubuntu.com/ubuntu-ports ssh_svcname: ssh - {% elif variant in ["alpine", "amazon", "arch", "centos", "fedora", -- "rhel", "suse"] %} -+ "rhel", "suse", "openEuler"] %} + {% elif variant in ["almalinux", "alpine", "amazon", "arch", "centos", "cloudlinux", "eurolinux", +- "fedora", "openEuler", "rhel", "rocky", "suse", "virtuozzo"] %} ++ "fedora", "openeuler", "rhel", "rocky", "suse", "virtuozzo"] %} # Default user name + that default users groups (if added/used) default_user: {% if variant == "amazon" %} +diff --git a/systemd/cloud-init-generator.tmpl b/systemd/cloud-init-generator.tmpl +index 7d1e725..685c012 100644 +--- a/systemd/cloud-init-generator.tmpl ++++ b/systemd/cloud-init-generator.tmpl +@@ -84,7 +84,7 @@ default() { + check_for_datasource() { + local ds_rc="" + {% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora", +- "openEuler", "rhel", "rocky", "virtuozzo"] %} ++ "openeuler", "rhel", "rocky", "virtuozzo"] %} + local dsidentify="/usr/libexec/cloud-init/ds-identify" + {% else %} + local dsidentify="/usr/lib/cloud-init/ds-identify" diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl -index af6d9a8..fd1babf 100644 +index de3f3d9..25830e0 100644 --- a/systemd/cloud-init.service.tmpl +++ b/systemd/cloud-init.service.tmpl -@@ -10,7 +10,7 @@ After=systemd-networkd-wait-online.service - {% if variant in ["ubuntu", "unknown", "debian"] %} +@@ -13,7 +13,7 @@ After=systemd-networkd-wait-online.service After=networking.service {% endif %} --{% if variant in ["centos", "fedora", "rhel"] %} -+{% if variant in ["centos", "fedora", "rhel", "openEuler"] %} + {% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora", +- "openEuler", "rhel", "rocky", "virtuozzo"] %} ++ "openeuler", "rhel", "rocky", "virtuozzo"] %} After=network.service After=NetworkManager.service {% endif %} -diff --git a/tests/cloud_tests/util.py b/tests/cloud_tests/util.py -index 7dcccbd..87f0e3f 100644 ---- a/tests/cloud_tests/util.py -+++ b/tests/cloud_tests/util.py -@@ -23,7 +23,7 @@ from tests.cloud_tests import LOG - - OS_FAMILY_MAPPING = { - 'debian': ['debian', 'ubuntu'], -- 'redhat': ['centos', 'rhel', 'fedora'], -+ 'redhat': ['centos', 'rhel', 'fedora', 'openEuler'], - 'gentoo': ['gentoo'], - 'freebsd': ['freebsd'], - 'suse': ['sles'], +diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py +index 1459fd9..b888e87 100644 +--- a/tests/unittests/test_cli.py ++++ b/tests/unittests/test_cli.py +@@ -225,7 +225,7 @@ class TestCLI(test_helpers.FilesystemMockingTestCase): + expected_doc_sections = [ + '**Supported distros:** all', + ('**Supported distros:** almalinux, alpine, centos, cloudlinux, ' +- 'debian, eurolinux, fedora, openEuler, opensuse, photon, rhel, ' ++ 'debian, eurolinux, fedora, openeuler, opensuse, photon, rhel, ' + 'rocky, sles, ubuntu, virtuozzo'), + '**Config schema**:\n **resize_rootfs:** (true/false/noblock)', + '**Examples**::\n\n runcmd:\n - [ ls, -l, / ]\n' +diff --git a/tests/unittests/test_render_cloudcfg.py b/tests/unittests/test_render_cloudcfg.py +index 00d50e6..e8680b8 100644 +--- a/tests/unittests/test_render_cloudcfg.py ++++ b/tests/unittests/test_render_cloudcfg.py +@@ -10,7 +10,7 @@ from cloudinit import util + + # TODO(Look to align with tools.render-cloudcfg or cloudinit.distos.OSFAMILIES) + DISTRO_VARIANTS = ["amazon", "arch", "centos", "debian", "eurolinux", "fedora", +- "freebsd", "netbsd", "openbsd", "photon", "rhel", "suse", ++ "freebsd", "netbsd", "openbsd", "openeuler", "photon", "rhel", "suse", + "ubuntu", "unknown"] + + diff --git a/tools/render-cloudcfg b/tools/render-cloudcfg -index ed45484..6d1fa6e 100755 +index 560f591..7751cb6 100755 --- a/tools/render-cloudcfg +++ b/tools/render-cloudcfg -@@ -6,7 +6,7 @@ import sys +@@ -5,7 +5,7 @@ import os + import sys - VARIANTS = ["alpine", "amazon", "arch", "centos", "debian", "fedora", - "freebsd", "netbsd", "openbsd", "rhel", "suse", "ubuntu", -- "unknown"] -+ "unknown", "openEuler"] + VARIANTS = ["almalinux", "alpine", "amazon", "arch", "centos", "cloudlinux", "debian", +- "eurolinux", "fedora", "freebsd", "netbsd", "openbsd", "openEuler", "photon", ++ "eurolinux", "fedora", "freebsd", "netbsd", "openbsd", "openeuler", "photon", + "rhel", "suse","rocky", "ubuntu", "unknown", "virtuozzo"] - if "avoid-pep8-E402-import-not-top-of-file": +-- +1.8.3.1 + diff --git a/cloud-init-20.4-Revert-ssh_util-handle-non-default-AuthorizedKeysFil.patch b/cloud-init-20.4-Revert-ssh_util-handle-non-default-AuthorizedKeysFil.patch deleted file mode 100644 index 49563272f64eb6080e5468dbbb521a837bef6ea1..0000000000000000000000000000000000000000 --- a/cloud-init-20.4-Revert-ssh_util-handle-non-default-AuthorizedKeysFil.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9a4c22ac0b660cd2573b9a88d14a0ef39b61afca Mon Sep 17 00:00:00 2001 -From: Eduardo Otubo -Date: Wed, 3 Feb 2021 10:28:49 +0100 -Subject: [PATCH] Revert "ssh_util: handle non-default AuthorizedKeysFile - config (#586)" (#775) - -This reverts commit b0e73814db4027dba0b7dc0282e295b7f653325c. - -Signed-off-by: Eduardo Otubo ---- - cloudinit/ssh_util.py | 6 +++--- - tests/unittests/test_sshutil.py | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py -index d5113996..c08042d6 100644 ---- a/cloudinit/ssh_util.py -+++ b/cloudinit/ssh_util.py -@@ -262,13 +262,13 @@ def extract_authorized_keys(username, sshd_cfg_file=DEF_SSHD_CFG): - - except (IOError, OSError): - # Give up and use a default key filename -- auth_key_fns.append(default_authorizedkeys_file) -+ auth_key_fns[0] = default_authorizedkeys_file - util.logexc(LOG, "Failed extracting 'AuthorizedKeysFile' in SSH " - "config from %r, using 'AuthorizedKeysFile' file " - "%r instead", DEF_SSHD_CFG, auth_key_fns[0]) - -- # always store all the keys in the first file configured on sshd_config -- return (auth_key_fns[0], parse_authorized_keys(auth_key_fns)) -+ # always store all the keys in the user's private file -+ return (default_authorizedkeys_file, parse_authorized_keys(auth_key_fns)) - - - def setup_user_keys(keys, username, options=None): -diff --git a/tests/unittests/test_sshutil.py b/tests/unittests/test_sshutil.py -index 88a111e3..fd1d1bac 100644 ---- a/tests/unittests/test_sshutil.py -+++ b/tests/unittests/test_sshutil.py -@@ -593,7 +593,7 @@ class TestMultipleSshAuthorizedKeysFile(test_helpers.CiTestCase): - fpw.pw_name, sshd_config) - content = ssh_util.update_authorized_keys(auth_key_entries, []) - -- self.assertEqual(authorized_keys, auth_key_fn) -+ self.assertEqual("%s/.ssh/authorized_keys" % fpw.pw_dir, auth_key_fn) - self.assertTrue(VALID_CONTENT['rsa'] in content) - self.assertTrue(VALID_CONTENT['dsa'] in content) - -@@ -610,7 +610,7 @@ class TestMultipleSshAuthorizedKeysFile(test_helpers.CiTestCase): - sshd_config = self.tmp_path('sshd_config') - util.write_file( - sshd_config, -- "AuthorizedKeysFile %s %s" % (user_keys, authorized_keys) -+ "AuthorizedKeysFile %s %s" % (authorized_keys, user_keys) - ) - - (auth_key_fn, auth_key_entries) = ssh_util.extract_authorized_keys( -@@ -618,7 +618,7 @@ class TestMultipleSshAuthorizedKeysFile(test_helpers.CiTestCase): - ) - content = ssh_util.update_authorized_keys(auth_key_entries, []) - -- self.assertEqual(user_keys, auth_key_fn) -+ self.assertEqual("%s/.ssh/authorized_keys" % fpw.pw_dir, auth_key_fn) - self.assertTrue(VALID_CONTENT['rsa'] in content) - self.assertTrue(VALID_CONTENT['dsa'] in content) - --- -2.27.0 - diff --git a/cloud-init-20.4-disable-lxd-tests.patch b/cloud-init-20.4-disable-lxd-tests.patch deleted file mode 100644 index 4a070634262cbbb6c836cccdadbad2f2a4db7422..0000000000000000000000000000000000000000 --- a/cloud-init-20.4-disable-lxd-tests.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f70a9a0a98c0af5a7b2aea9a8e4b40bbe1668038 Mon Sep 17 00:00:00 2001 -From: Eduardo Otubo -Date: Thu, 3 Dec 2020 12:31:42 +0100 -Subject: [PATCH 1/3] Disable LXD tests - -Signed-off-by: Eduardo Otubo ---- - tests/cloud_tests/platforms/__init__.py | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/tests/cloud_tests/platforms/__init__.py b/tests/cloud_tests/platforms/__init__.py -index e506baa0..e7efcba5 100644 ---- a/tests/cloud_tests/platforms/__init__.py -+++ b/tests/cloud_tests/platforms/__init__.py -@@ -3,7 +3,6 @@ - """Main init.""" - - from .ec2 import platform as ec2 --from .lxd import platform as lxd - from .nocloudkvm import platform as nocloudkvm - from .azurecloud import platform as azurecloud - from ..util import emit_dots_on_travis -@@ -11,7 +10,6 @@ from ..util import emit_dots_on_travis - PLATFORMS = { - 'ec2': ec2.EC2Platform, - 'nocloud-kvm': nocloudkvm.NoCloudKVMPlatform, -- 'lxd': lxd.LXDPlatform, - 'azurecloud': azurecloud.AzureCloudPlatform, - } - --- -2.27.0 - diff --git a/cloud-init-20.4-nm-controlled.patch b/cloud-init-20.4-nm-controlled.patch index 606e7bc3801328bb4b6cc2e0d901cc7f9d26d39d..c42ffc0d907ec1ee2d1855de7fc20c5a7d26061c 100644 --- a/cloud-init-20.4-nm-controlled.patch +++ b/cloud-init-20.4-nm-controlled.patch @@ -19,10 +19,10 @@ Signed-off-by: Ryan McCabe 3 files changed, 1 insertion(+), 58 deletions(-) diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py -index a930e612..9c822c3e 100644 +index ef4543b..13c6ad7 100644 --- a/cloudinit/net/sysconfig.py +++ b/cloudinit/net/sysconfig.py -@@ -289,7 +289,7 @@ class Renderer(renderer.Renderer): +@@ -290,7 +290,7 @@ class Renderer(renderer.Renderer): # details about this) iface_defaults = { @@ -32,10 +32,10 @@ index a930e612..9c822c3e 100644 'suse': {'BOOTPROTO': 'static', 'STARTMODE': 'auto'}, } diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py -index a1df066a..bc167f94 100644 +index d09e46a..3f01c99 100644 --- a/tests/unittests/test_distros/test_netconfig.py +++ b/tests/unittests/test_distros/test_netconfig.py -@@ -484,7 +484,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -503,7 +503,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): GATEWAY=192.168.1.254 IPADDR=192.168.1.5 NETMASK=255.255.255.0 @@ -43,7 +43,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -492,7 +491,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -511,7 +510,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): self.ifcfg_path('eth1'): dedent("""\ BOOTPROTO=dhcp DEVICE=eth1 @@ -51,7 +51,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -517,7 +515,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -536,7 +534,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): IPV6_AUTOCONF=no IPV6_DEFAULTGW=2607:f0d0:1002:0011::1 IPV6_FORCE_ACCEPT_RA=no @@ -59,7 +59,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -525,7 +522,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -544,7 +541,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): self.ifcfg_path('eth1'): dedent("""\ BOOTPROTO=dhcp DEVICE=eth1 @@ -67,7 +67,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -559,7 +555,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -578,7 +574,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): HWADDR=00:16:3e:60:7c:df IPADDR=192.10.1.2 NETMASK=255.255.255.0 @@ -75,7 +75,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -569,7 +564,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -588,7 +583,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): DEVICE=infra0 IPADDR=10.0.1.2 NETMASK=255.255.0.0 @@ -83,7 +83,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes PHYSDEV=eth0 USERCTL=no -@@ -598,7 +592,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -617,7 +611,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): DEVICE=eth0 IPADDR=192.10.1.2 NETMASK=255.255.255.0 @@ -91,7 +91,7 @@ index a1df066a..bc167f94 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -608,7 +601,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): +@@ -627,7 +620,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): DEVICE=eth0.1001 IPADDR=10.0.1.2 NETMASK=255.255.0.0 @@ -100,7 +100,7 @@ index a1df066a..bc167f94 100644 PHYSDEV=eth0 USERCTL=no diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py -index 70453683..47a71964 100644 +index 094450b..6294f4b 100644 --- a/tests/unittests/test_net.py +++ b/tests/unittests/test_net.py @@ -535,7 +535,6 @@ GATEWAY=172.19.3.254 @@ -127,7 +127,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -884,7 +881,6 @@ NETWORK_CONFIGS = { +@@ -910,7 +907,6 @@ NETWORK_CONFIGS = { BOOTPROTO=none DEVICE=eth1 HWADDR=cf:d6:af:48:e8:80 @@ -135,7 +135,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no"""), -@@ -901,7 +897,6 @@ NETWORK_CONFIGS = { +@@ -927,7 +923,6 @@ NETWORK_CONFIGS = { IPADDR=192.168.21.3 NETMASK=255.255.255.0 METRIC=10000 @@ -143,7 +143,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no"""), -@@ -1032,7 +1027,6 @@ NETWORK_CONFIGS = { +@@ -1075,7 +1070,6 @@ NETWORK_CONFIGS = { IPV6_AUTOCONF=no IPV6_FORCE_ACCEPT_RA=no NETMASK=255.255.255.0 @@ -151,7 +151,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1095,7 +1089,6 @@ NETWORK_CONFIGS = { +@@ -1144,7 +1138,6 @@ NETWORK_CONFIGS = { DHCPV6C=yes IPV6INIT=yes DEVICE=iface0 @@ -159,7 +159,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1150,7 +1143,6 @@ NETWORK_CONFIGS = { +@@ -1199,7 +1192,6 @@ NETWORK_CONFIGS = { IPV6INIT=yes IPV6_FORCE_ACCEPT_RA=yes DEVICE=iface0 @@ -167,7 +167,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1205,7 +1197,6 @@ NETWORK_CONFIGS = { +@@ -1261,7 +1253,6 @@ NETWORK_CONFIGS = { IPV6INIT=yes IPV6_FORCE_ACCEPT_RA=no DEVICE=iface0 @@ -175,7 +175,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1250,7 +1241,6 @@ NETWORK_CONFIGS = { +@@ -1313,7 +1304,6 @@ NETWORK_CONFIGS = { IPV6_AUTOCONF=yes IPV6INIT=yes DEVICE=iface0 @@ -183,7 +183,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1277,7 +1267,6 @@ NETWORK_CONFIGS = { +@@ -1340,7 +1330,6 @@ NETWORK_CONFIGS = { IPV6_AUTOCONF=no IPV6_FORCE_ACCEPT_RA=no DEVICE=iface0 @@ -191,7 +191,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1324,7 +1313,6 @@ NETWORK_CONFIGS = { +@@ -1387,7 +1376,6 @@ NETWORK_CONFIGS = { IPV6_AUTOCONF=yes IPV6INIT=yes DEVICE=iface0 @@ -199,15 +199,15 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1371,7 +1359,6 @@ NETWORK_CONFIGS = { - IPV6INIT=yes +@@ -1435,7 +1423,6 @@ NETWORK_CONFIGS = { + IPV6_AUTOCONF=no IPV6_FORCE_ACCEPT_RA=yes DEVICE=iface0 - NM_CONTROLLED=no ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1404,7 +1391,6 @@ NETWORK_CONFIGS = { +@@ -1468,7 +1455,6 @@ NETWORK_CONFIGS = { 'ifcfg-iface0': textwrap.dedent("""\ BOOTPROTO=dhcp DEVICE=iface0 @@ -215,7 +215,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1447,7 +1433,6 @@ NETWORK_CONFIGS = { +@@ -1511,7 +1497,6 @@ NETWORK_CONFIGS = { BOOTPROTO=dhcp DEVICE=iface0 ETHTOOL_OPTS="wol g" @@ -223,7 +223,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -1736,7 +1721,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1800,7 +1785,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DHCPV6C=yes IPV6INIT=yes MACADDR=aa:bb:cc:dd:ee:ff @@ -231,7 +231,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Bond USERCTL=no"""), -@@ -1744,7 +1728,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1808,7 +1792,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BOOTPROTO=dhcp DEVICE=bond0.200 DHCLIENT_SET_DEFAULT_ROUTE=no @@ -239,7 +239,7 @@ index 70453683..47a71964 100644 ONBOOT=yes PHYSDEV=bond0 USERCTL=no -@@ -1762,7 +1745,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1826,7 +1809,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true IPV6_DEFAULTGW=2001:4800:78ff:1b::1 MACADDR=bb:bb:bb:bb:bb:aa NETMASK=255.255.255.0 @@ -247,7 +247,7 @@ index 70453683..47a71964 100644 ONBOOT=yes PRIO=22 STP=no -@@ -1772,7 +1754,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1836,7 +1818,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BOOTPROTO=none DEVICE=eth0 HWADDR=c0:d6:9f:2c:e8:80 @@ -255,7 +255,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no"""), -@@ -1789,7 +1770,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1853,7 +1834,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true MTU=1500 NETMASK=255.255.255.0 NETMASK1=255.255.255.0 @@ -263,7 +263,7 @@ index 70453683..47a71964 100644 ONBOOT=yes PHYSDEV=eth0 USERCTL=no -@@ -1799,7 +1779,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1863,7 +1843,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DEVICE=eth1 HWADDR=aa:d6:9f:2c:e8:80 MASTER=bond0 @@ -271,7 +271,7 @@ index 70453683..47a71964 100644 ONBOOT=yes SLAVE=yes TYPE=Ethernet -@@ -1809,7 +1788,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1873,7 +1852,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DEVICE=eth2 HWADDR=c0:bb:9f:2c:e8:80 MASTER=bond0 @@ -279,7 +279,7 @@ index 70453683..47a71964 100644 ONBOOT=yes SLAVE=yes TYPE=Ethernet -@@ -1819,7 +1797,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1883,7 +1861,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BRIDGE=br0 DEVICE=eth3 HWADDR=66:bb:9f:2c:e8:80 @@ -287,7 +287,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no"""), -@@ -1828,7 +1805,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1892,7 +1869,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BRIDGE=br0 DEVICE=eth4 HWADDR=98:bb:9f:2c:e8:80 @@ -295,7 +295,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no"""), -@@ -1837,7 +1813,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1901,7 +1877,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DEVICE=eth5 DHCLIENT_SET_DEFAULT_ROUTE=no HWADDR=98:bb:9f:2c:e8:8a @@ -303,7 +303,7 @@ index 70453683..47a71964 100644 ONBOOT=no TYPE=Ethernet USERCTL=no"""), -@@ -1848,7 +1823,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true +@@ -1912,7 +1887,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true IPADDR=192.168.200.7 MTU=9000 NETMASK=255.255.255.0 @@ -311,7 +311,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=InfiniBand USERCTL=no"""), -@@ -2293,7 +2267,6 @@ iface bond0 inet6 static +@@ -2357,7 +2331,6 @@ iface bond0 inet6 static MTU=9000 NETMASK=255.255.255.0 NETMASK1=255.255.255.0 @@ -319,7 +319,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Bond USERCTL=no -@@ -2303,7 +2276,6 @@ iface bond0 inet6 static +@@ -2367,7 +2340,6 @@ iface bond0 inet6 static DEVICE=bond0s0 HWADDR=aa:bb:cc:dd:e8:00 MASTER=bond0 @@ -327,7 +327,7 @@ index 70453683..47a71964 100644 ONBOOT=yes SLAVE=yes TYPE=Ethernet -@@ -2325,7 +2297,6 @@ iface bond0 inet6 static +@@ -2389,7 +2361,6 @@ iface bond0 inet6 static DEVICE=bond0s1 HWADDR=aa:bb:cc:dd:e8:01 MASTER=bond0 @@ -335,7 +335,7 @@ index 70453683..47a71964 100644 ONBOOT=yes SLAVE=yes TYPE=Ethernet -@@ -2382,7 +2353,6 @@ iface bond0 inet6 static +@@ -2446,7 +2417,6 @@ iface bond0 inet6 static BOOTPROTO=none DEVICE=en0 HWADDR=aa:bb:cc:dd:e8:00 @@ -343,7 +343,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no"""), -@@ -2401,7 +2371,6 @@ iface bond0 inet6 static +@@ -2465,7 +2435,6 @@ iface bond0 inet6 static MTU=2222 NETMASK=255.255.255.0 NETMASK1=255.255.255.0 @@ -351,7 +351,7 @@ index 70453683..47a71964 100644 ONBOOT=yes PHYSDEV=en0 USERCTL=no -@@ -2466,7 +2435,6 @@ iface bond0 inet6 static +@@ -2530,7 +2499,6 @@ iface bond0 inet6 static DEVICE=br0 IPADDR=192.168.2.2 NETMASK=255.255.255.0 @@ -359,7 +359,7 @@ index 70453683..47a71964 100644 ONBOOT=yes PRIO=22 STP=no -@@ -2482,7 +2450,6 @@ iface bond0 inet6 static +@@ -2546,7 +2514,6 @@ iface bond0 inet6 static IPV6INIT=yes IPV6_AUTOCONF=no IPV6_FORCE_ACCEPT_RA=no @@ -367,7 +367,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -2496,7 +2463,6 @@ iface bond0 inet6 static +@@ -2560,7 +2527,6 @@ iface bond0 inet6 static IPV6INIT=yes IPV6_AUTOCONF=no IPV6_FORCE_ACCEPT_RA=no @@ -375,7 +375,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -2590,7 +2556,6 @@ iface bond0 inet6 static +@@ -2654,7 +2620,6 @@ iface bond0 inet6 static HWADDR=52:54:00:12:34:00 IPADDR=192.168.1.2 NETMASK=255.255.255.0 @@ -383,7 +383,7 @@ index 70453683..47a71964 100644 ONBOOT=no TYPE=Ethernet USERCTL=no -@@ -2600,7 +2565,6 @@ iface bond0 inet6 static +@@ -2664,7 +2629,6 @@ iface bond0 inet6 static DEVICE=eth1 HWADDR=52:54:00:12:34:aa MTU=1480 @@ -391,7 +391,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -2609,7 +2573,6 @@ iface bond0 inet6 static +@@ -2673,7 +2637,6 @@ iface bond0 inet6 static BOOTPROTO=none DEVICE=eth2 HWADDR=52:54:00:12:34:ff @@ -399,7 +399,7 @@ index 70453683..47a71964 100644 ONBOOT=no TYPE=Ethernet USERCTL=no -@@ -3026,7 +2989,6 @@ class TestRhelSysConfigRendering(CiTestCase): +@@ -3094,7 +3057,6 @@ class TestRhelSysConfigRendering(CiTestCase): BOOTPROTO=dhcp DEVICE=eth1000 HWADDR=07-1c-c6-75-a4-be @@ -407,7 +407,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3147,7 +3109,6 @@ GATEWAY=10.0.2.2 +@@ -3215,7 +3177,6 @@ GATEWAY=10.0.2.2 HWADDR=52:54:00:12:34:00 IPADDR=10.0.2.15 NETMASK=255.255.255.0 @@ -415,7 +415,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3178,7 +3139,6 @@ HWADDR=fa:16:3e:25:b4:59 +@@ -3246,7 +3207,6 @@ HWADDR=fa:16:3e:25:b4:59 IPADDR=51.68.89.122 MTU=1500 NETMASK=255.255.240.0 @@ -423,7 +423,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3192,7 +3152,6 @@ DEVICE=eth1 +@@ -3260,7 +3220,6 @@ DEVICE=eth1 DHCLIENT_SET_DEFAULT_ROUTE=no HWADDR=fa:16:3e:b1:ca:29 MTU=9000 @@ -431,7 +431,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3217,7 +3176,6 @@ USERCTL=no +@@ -3285,7 +3244,6 @@ USERCTL=no # BOOTPROTO=dhcp DEVICE=eth0 @@ -439,7 +439,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3492,7 +3450,6 @@ USERCTL=no +@@ -3560,7 +3518,6 @@ USERCTL=no IPV6_FORCE_ACCEPT_RA=no IPV6_DEFAULTGW=2001:db8::1 NETMASK=255.255.255.0 @@ -447,7 +447,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3517,7 +3474,6 @@ USERCTL=no +@@ -3585,7 +3542,6 @@ USERCTL=no 'ifcfg-eno1': textwrap.dedent("""\ BOOTPROTO=none DEVICE=eno1 @@ -455,7 +455,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Ethernet USERCTL=no -@@ -3528,7 +3484,6 @@ USERCTL=no +@@ -3596,7 +3552,6 @@ USERCTL=no IPADDR=192.6.1.9 MTU=1495 NETMASK=255.255.255.0 @@ -463,7 +463,7 @@ index 70453683..47a71964 100644 ONBOOT=yes PHYSDEV=eno1 USERCTL=no -@@ -3558,7 +3513,6 @@ USERCTL=no +@@ -3626,7 +3581,6 @@ USERCTL=no IPADDR=10.101.8.65 MTU=1334 NETMASK=255.255.255.192 @@ -471,7 +471,7 @@ index 70453683..47a71964 100644 ONBOOT=yes TYPE=Bond USERCTL=no -@@ -3568,7 +3522,6 @@ USERCTL=no +@@ -3636,7 +3590,6 @@ USERCTL=no BOOTPROTO=none DEVICE=enp0s0 MASTER=bond0 @@ -479,7 +479,7 @@ index 70453683..47a71964 100644 ONBOOT=yes SLAVE=yes TYPE=Bond -@@ -3579,7 +3532,6 @@ USERCTL=no +@@ -3647,7 +3600,6 @@ USERCTL=no BOOTPROTO=none DEVICE=enp0s1 MASTER=bond0 @@ -487,7 +487,7 @@ index 70453683..47a71964 100644 ONBOOT=yes SLAVE=yes TYPE=Bond -@@ -3603,7 +3555,6 @@ USERCTL=no +@@ -3671,7 +3623,6 @@ USERCTL=no DEVICE=eno1 HWADDR=07-1c-c6-75-a4-be METRIC=100 @@ -496,5 +496,5 @@ index 70453683..47a71964 100644 TYPE=Ethernet USERCTL=no -- -2.27.0 +1.8.3.1 diff --git a/cloud-init-20.4-sandbox-ca_certs-tests-to-avoid-failure.patch b/cloud-init-20.4-sandbox-ca_certs-tests-to-avoid-failure.patch deleted file mode 100644 index 20f27e330c232033f78283f925cefb0ca30c928b..0000000000000000000000000000000000000000 --- a/cloud-init-20.4-sandbox-ca_certs-tests-to-avoid-failure.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f16b18607444cb41e263edfa7fb0c97ba1f7e518 Mon Sep 17 00:00:00 2001 -From: Eduardo Otubo -Date: Fri, 4 Dec 2020 11:05:08 +0100 -Subject: [PATCH] Sandbox ca_certs tests to avoid failure - -Signed-off-by: Eduardo Otubo ---- - .../unittests/test_handler/test_handler_ca_certs.py | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/tests/unittests/test_handler/test_handler_ca_certs.py b/tests/unittests/test_handler/test_handler_ca_certs.py -index e74a0a08..a16430d5 100644 ---- a/tests/unittests/test_handler/test_handler_ca_certs.py -+++ b/tests/unittests/test_handler/test_handler_ca_certs.py -@@ -152,6 +152,7 @@ class TestAddCaCerts(TestCase): - self.paths = helpers.Paths({ - 'cloud_dir': tmpdir, - }) -+ self.add_patch("cloudinit.config.cc_ca_certs.os.stat", "m_stat") - - def test_no_certs_in_list(self): - """Test that no certificate are written if not provided.""" -@@ -215,17 +216,12 @@ class TestAddCaCerts(TestCase): - - expected = "cloud-init-ca-certs.crt\n" - -- with ExitStack() as mocks: -- mock_write = mocks.enter_context( -- mock.patch.object(util, 'write_file', autospec=True)) -- mock_stat = mocks.enter_context( -- mock.patch("cloudinit.config.cc_ca_certs.os.stat") -- ) -- mock_stat.return_value.st_size = 0 -+ with mock.patch.object(util, 'write_file', autospec=True) as m_write: -+ self.m_stat.return_value.st_size = 0 - - cc_ca_certs.add_ca_certs([cert]) - -- mock_write.assert_has_calls([ -+ m_write.assert_has_calls([ - mock.call("/usr/share/ca-certificates/cloud-init-ca-certs.crt", - cert, mode=0o644), - mock.call("/etc/ca-certificates.conf", expected, omode="wb")]) --- -2.27.0 - diff --git a/cloud-init-20.4.tar.gz b/cloud-init-20.4.tar.gz deleted file mode 100644 index 550eb04509c107f2a1dab389bc79bb348f14b231..0000000000000000000000000000000000000000 Binary files a/cloud-init-20.4.tar.gz and /dev/null differ diff --git a/cloud-init-21.4.tar.gz b/cloud-init-21.4.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ef2956aa7b373b5fe057663b06339471779f64b4 Binary files /dev/null and b/cloud-init-21.4.tar.gz differ diff --git a/cloud-init.spec b/cloud-init.spec index 1d4c82da26d22ac77bd31eef3b06391c21d87423..1e3e7f5e290381d016de67964fe7417414867411 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,6 +1,6 @@ Name: cloud-init -Version: 20.4 -Release: 3 +Version: 21.4 +Release: 1 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 @@ -8,25 +8,20 @@ Source0: https://launchpad.net/%{name}/trunk/%{version}/+download/%{name}-%{vers Source1: cloud-init-tmpfiles.conf -Patch0: cloud-init-20.4-disable-lxd-tests.patch -Patch1: cloud-init-20.4-nm-controlled.patch -Patch2: cloud-init-20.4-no-override-default-network.patch -Patch3: bugfix-cloud-init-add-openEuler-os.patch -Patch4: bugfix-sort-requirements.patch -Patch5: add-variable-to-forbid-tmp-dir.patch -Patch6: cloud-init-20.4-sandbox-ca_certs-tests-to-avoid-failure.patch -Patch7: cloud-init-20.4-Revert-ssh_util-handle-non-default-AuthorizedKeysFil.patch -Patch8: backport-net-exclude-OVS-internal-interfaces-in-get_interface.patch -Patch9: backport-CVE-2021-3429-write-passwords-only-to-serial-console-lock-down-clo.patch +Patch0: cloud-init-20.4-nm-controlled.patch +Patch1: cloud-init-20.4-no-override-default-network.patch +Patch2: bugfix-cloud-init-add-openEuler-os.patch +Patch3: bugfix-sort-requirements.patch +Patch4: add-variable-to-forbid-tmp-dir.patch Patch9000: Fix-the-error-level-logs-displayed-for-the-cloud-init-local-service.patch BuildRequires: pkgconfig(systemd) python3-devel python3-setuptools systemd BuildRequires: iproute python3-configobj python3-httpretty >= 0.8.14-2 BuildRequires: python3-jinja2 python3-jsonpatch python3-jsonschema -BuildRequires: python3-mock python3-nose python3-oauthlib python3-prettytable +BuildRequires: python3-mock python3-oauthlib python3-prettytable BuildRequires: python3-pyserial python3-PyYAML python3-requests python3-six -BuildRequires: python3-unittest2 dnf %{_vendor}-release python3-pytest passwd +BuildRequires: python3-unittest2 dnf %{_vendor}-release python3-pytest passwd python3-netifaces Requires: e2fsprogs iproute python3-libselinux net-tools python3-policycoreutils Requires: procps python3-configobj python3-jinja2 python3-jsonpatch xfsprogs @@ -110,6 +105,9 @@ fi %{_unitdir}/cloud-config.target %{_unitdir}/cloud-init.target /usr/lib/systemd/system-generators/cloud-init-generator +%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf +/usr/lib/systemd/system/cloud-init-hotplugd.service +/usr/lib/systemd/system/cloud-init-hotplugd.socket %{_tmpfilesdir}/%{name}.conf %{_libexecdir}/%{name} %{_bindir}/cloud-init* @@ -126,6 +124,12 @@ fi %exclude /usr/share/doc/* %changelog +* Wed Dec 29 2021 yangzhuangzhuang - 21.4-1 +- Type:update +- ID:CVE-2021-3429 +- SUG:NA +- DESC:update version to 21.4 + * Wed Sep 22 2021 yangzhuangzhuang - 20.4-3 - Type:CVE - ID:CVE-2021-3429