Sync with stable

This commit is contained in:
eabdullin 2024-01-25 13:23:20 +03:00
parent 38174f94e2
commit 7d5ad63fb9
47 changed files with 3588 additions and 5623 deletions

View File

@ -1,621 +1,61 @@
From 7daf47d1ee60a132244f2a9ec4e89ad496c32c3e Mon Sep 17 00:00:00 2001 From c4d66915520554adedff9be7396f877cd1a5525c Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com> From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Mon, 28 Mar 2022 14:08:05 +0200 Date: Mon, 6 Mar 2023 16:37:20 +0100
Subject: Add initial redhat setup Subject: [PATCH] Add initial redhat changes
Merged patches (22.1): Adding minimal set of changes necessary for successful build of the package
- 70f80f82 Use _systemdgeneratordir macro for cloud-init-generator handling on RHEL/CentOS 9 Stream koji.
- 0f74e7b8 Add dhcp-client as a dependency
- 791eb2b6 Report full specific version with "cloud-init --version" Merged patches (23.1.1):
- 865805d6 source-git: Use dynamic SRPM_NAME 724a80ac Add TargetRelease
- 45ddc666 add the drop-in also in the %files section of cloud-init.spec 967a4405b rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg
- 08d939b2 Add gdisk and openssl as deps to fix UEFI / Azure initialization ^ Merged since it removes hunks added in this commit itself
- 0531cd68 Add netifaces package as a Requires in cloud-init.spec.template
Discarded because not needed anymore (packit):
e3fd7ce12 Configure Packit to ignore the .gitignore file
e18654e9 Fixes for packit support
Discarded because file does not exist anymore and templates are aligned with upstream:
3576b12460bf18557857ee25df6bf530dab66612 Adding _netdev to the default mount configuration
8092b57ab245856ff1fdde1469960608a489c95e Remove rhel specific files
Added the following entry to %files to keep track of the new README file in config/clean.d/README
%doc %{_sysconfdir}/cloud/clean.d/README
ignored
c75e509b0 Revert "Revert "Setting highest autoconnect priority for network-scripts""
0eba5c619 Revert "Setting highest autoconnect priority for network-scripts"
ignored
ba19343c0d9807d0c68a2d8e4ab274f3ca884247 Add Gitlab CI
fe09305a5479a4814d6c46df07a906bafa29d637 Delete .gitlab-ci.yml
Conflicts: Conflicts:
- .gitignore missing rhel/ static files and "" instead of '' in setup.py
- cloudinit/config/cc_chef.py = use double quotes instead of single quotes
- cloudinit/settings.py = use rhel settings
- cloudinit/sources/DataSourceAzure.py = remove temporary_hostname and helper
- requirements.txt = just add netifaces and not jsonschema dep
- setup.py = use double quotes instead of single quotes
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Merged patches (RHEL-9/21.1):
- 5688a1d0 Removing python-nose and python-tox as dependency
- 237d57f9 Removing mock dependency
- d1c2f496 Removing python-jsonschema dependency
- 0d1cd14c Don't override default network configuration
Merged patches (21.1):
- 915d30ad Change gating file to correct rhel version
- 311f318d Removing net-tools dependency
- 74731806 Adding man pages to Red Hat spec file
- 758d333d Removing blocking test from yaml configuration file
- c7e7c59c Changing permission of cloud-init-generator to 755
- 8b85abbb Installing man pages in the correct place with correct permissions
- c6808d8d Fix unit failure of cloud-final.service if NetworkManager was not present.
- 11866ef6 Report full specific version with "cloud-init --version"
Rebase notes (18.5):
- added bash_completition file
- added cloud-id file
Merged patches (20.3):
- 01900d0 changing ds-identify patch from /usr/lib to /usr/libexec
- 7f47ca3 Render the generator from template instead of cp
Merged patches (19.4):
- 4ab5a61 Fix for network configuration not persisting after reboot
- 84cf125 Removing cloud-user from wheel
- 31290ab Adding gating tests for Azure, ESXi and AWS
Merged patches (18.5):
- 2d6b469 add power-state-change module to cloud_final_modules
- 764159f Adding systemd mount options to wait for cloud-init
- da4d99e Adding disk_setup to rhel/cloud.cfg
- f5c6832 Enable cloud-init by default on vmware
Conflicts:
cloudinit/config/cc_chef.py:
- Updated header documentation text
- Replacing double quotes by simple quotes
setup.py:
- Adding missing cmdclass info
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
Changes:
- move redhat to .distro to use new build script structure
- Fixing changelog for RHEL 9
Merged patches (21.1):
- 69bd7f71 DataSourceAzure.py: use hostnamectl to set hostname
- 0407867e Remove race condition between cloud-init and NetworkManager
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--- ---
.distro/.gitignore | 1 + cloudinit/settings.py | 5 +++--
.distro/Makefile | 74 ++++ 1 file changed, 3 insertions(+), 2 deletions(-)
.distro/Makefile.common | 20 +
.distro/cloud-init-tmpfiles.conf | 1 +
.distro/cloud-init.spec.template | 505 ++++++++++++++++++++++++++
.distro/gating.yaml | 8 +
.distro/rpmbuild/BUILD/.gitignore | 3 +
.distro/rpmbuild/RPMS/.gitignore | 3 +
.distro/rpmbuild/SOURCES/.gitignore | 3 +
.distro/rpmbuild/SPECS/.gitignore | 3 +
.distro/rpmbuild/SRPMS/.gitignore | 3 +
.distro/scripts/frh.py | 27 ++
.distro/scripts/git-backport-diff | 327 +++++++++++++++++
.distro/scripts/git-compile-check | 215 +++++++++++
.distro/scripts/process-patches.sh | 88 +++++
.distro/scripts/tarball_checksum.sh | 3 +
.gitignore | 1 +
cloudinit/config/cc_chef.py | 65 +++-
cloudinit/settings.py | 21 +-
requirements.txt | 3 -
rhel/README.rhel | 5 +
rhel/cloud-init-tmpfiles.conf | 1 +
rhel/cloud.cfg | 69 ++++
rhel/systemd/cloud-config.service | 18 +
rhel/systemd/cloud-config.target | 11 +
rhel/systemd/cloud-final.service | 24 ++
rhel/systemd/cloud-init-local.service | 31 ++
rhel/systemd/cloud-init.service | 26 ++
rhel/systemd/cloud-init.target | 7 +
setup.py | 28 +-
tools/read-version | 28 +-
31 files changed, 1557 insertions(+), 65 deletions(-)
create mode 100644 .distro/.gitignore
create mode 100644 .distro/Makefile
create mode 100644 .distro/Makefile.common
create mode 100644 .distro/cloud-init-tmpfiles.conf
create mode 100644 .distro/cloud-init.spec.template
create mode 100644 .distro/gating.yaml
create mode 100644 .distro/rpmbuild/BUILD/.gitignore
create mode 100644 .distro/rpmbuild/RPMS/.gitignore
create mode 100644 .distro/rpmbuild/SOURCES/.gitignore
create mode 100644 .distro/rpmbuild/SPECS/.gitignore
create mode 100644 .distro/rpmbuild/SRPMS/.gitignore
create mode 100755 .distro/scripts/frh.py
create mode 100755 .distro/scripts/git-backport-diff
create mode 100755 .distro/scripts/git-compile-check
create mode 100755 .distro/scripts/process-patches.sh
create mode 100755 .distro/scripts/tarball_checksum.sh
create mode 100644 rhel/README.rhel
create mode 100644 rhel/cloud-init-tmpfiles.conf
create mode 100644 rhel/cloud.cfg
create mode 100644 rhel/systemd/cloud-config.service
create mode 100644 rhel/systemd/cloud-config.target
create mode 100644 rhel/systemd/cloud-final.service
create mode 100644 rhel/systemd/cloud-init-local.service
create mode 100644 rhel/systemd/cloud-init.service
create mode 100644 rhel/systemd/cloud-init.target
diff --git a/cloudinit/config/cc_chef.py b/cloudinit/config/cc_chef.py
index fdb3a6e3..d028c548 100644
--- a/cloudinit/config/cc_chef.py
+++ b/cloudinit/config/cc_chef.py
@@ -6,7 +6,70 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
-"""Chef: module that configures, starts and installs chef."""
+"""
+Chef
+----
+**Summary:** module that configures, starts and installs chef.
+
+This module enables chef to be installed (from packages or
+from gems, or from omnibus). Before this occurs chef configurations are
+written to disk (validation.pem, client.pem, firstboot.json, client.rb),
+and needed chef folders/directories are created (/etc/chef and /var/log/chef
+and so-on). Then once installing proceeds correctly if configured chef will
+be started (in daemon mode or in non-daemon mode) and then once that has
+finished (if ran in non-daemon mode this will be when chef finishes
+converging, if ran in daemon mode then no further actions are possible since
+chef will have forked into its own process) then a post run function can
+run that can do finishing activities (such as removing the validation pem
+file).
+
+**Internal name:** ``cc_chef``
+
+**Module frequency:** per always
+
+**Supported distros:** all
+
+**Config keys**::
+
+ chef:
+ directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,
+ /var/cache/chef, /var/backups/chef, /run/chef)
+ validation_cert: (optional string to be written to file validation_key)
+ special value 'system' means set use existing file
+ validation_key: (optional the path for validation_cert. default
+ /etc/chef/validation.pem)
+ firstboot_path: (path to write run_list and initial_attributes keys that
+ should also be present in this configuration, defaults
+ to /etc/chef/firstboot.json)
+ exec: boolean to run or not run chef (defaults to false, unless
+ a gem installed is requested
+ where this will then default
+ to true)
+
+ chef.rb template keys (if falsey, then will be skipped and not
+ written to /etc/chef/client.rb)
+
+ chef:
+ client_key:
+ encrypted_data_bag_secret:
+ environment:
+ file_backup_path:
+ file_cache_path:
+ json_attribs:
+ log_level:
+ log_location:
+ node_name:
+ omnibus_url:
+ omnibus_url_retries:
+ omnibus_version:
+ pid_file:
+ server_url:
+ show_time:
+ ssl_verify_mode:
+ validation_cert:
+ validation_key:
+ validation_name:
+"""
import itertools
import json
diff --git a/cloudinit/settings.py b/cloudinit/settings.py diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index ecc1403b..a780e21e 100644 index 8684d003..edbb217d 100644
--- a/cloudinit/settings.py --- a/cloudinit/settings.py
+++ b/cloudinit/settings.py +++ b/cloudinit/settings.py
@@ -48,16 +48,19 @@ CFG_BUILTIN = { @@ -53,13 +53,14 @@ CFG_BUILTIN = {
# At the end to act as a 'catch' when none of the above work...
"None",
], ],
- "def_log_file": "/var/log/cloud-init.log", "def_log_file": "/var/log/cloud-init.log",
- "log_cfgs": [], "log_cfgs": [],
- "syslog_fix_perms": ["syslog:adm", "root:adm", "root:wheel", "root:root"], - "syslog_fix_perms": ["syslog:adm", "root:adm", "root:wheel", "root:root"],
- "system_info": { + "mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
- "paths": { + "syslog_fix_perms": [],
- "cloud_dir": "/var/lib/cloud", "system_info": {
- "templates_dir": "/etc/cloud/templates/", "paths": {
+ 'def_log_file': '/var/log/cloud-init.log', "cloud_dir": "/var/lib/cloud",
+ 'log_cfgs': [], "templates_dir": "/etc/cloud/templates/",
+ 'mount_default_fields': [None, None, 'auto', 'defaults,nofail', '0', '2'],
+ 'ssh_deletekeys': False,
+ 'ssh_genkeytypes': [],
+ 'syslog_fix_perms': [],
+ 'system_info': {
+ 'paths': {
+ 'cloud_dir': '/var/lib/cloud',
+ 'templates_dir': '/etc/cloud/templates/',
}, },
- "distro": "ubuntu", - "distro": "ubuntu",
- "network": {"renderers": None}, + "distro": "rhel",
+ 'distro': 'rhel', "network": {"renderers": None},
+ 'network': {'renderers': None},
}, },
"vendor_data": {"enabled": True, "prefix": []}, "vendor_data": {"enabled": True, "prefix": []},
"vendor_data2": {"enabled": True, "prefix": []},
diff --git a/requirements.txt b/requirements.txt
index c4adc455..f77f1d73 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -30,9 +30,6 @@ requests
# For patching pieces of cloud-config together
jsonpatch
-# For validating cloud-config sections per schema definitions
-jsonschema
-
# Used by DataSourceVMware to inspect the host's network configuration during
# the "setup()" function.
#
diff --git a/rhel/README.rhel b/rhel/README.rhel
new file mode 100644
index 00000000..aa29630d
--- /dev/null
+++ b/rhel/README.rhel
@@ -0,0 +1,5 @@
+The following cloud-init modules are currently unsupported on this OS:
+ - apt_update_upgrade ('apt_update', 'apt_upgrade', 'apt_mirror', 'apt_preserve_sources_list', 'apt_old_mirror', 'apt_sources', 'debconf_selections', 'packages' options)
+ - byobu ('byobu_by_default' option)
+ - chef
+ - grub_dpkg
diff --git a/rhel/cloud-init-tmpfiles.conf b/rhel/cloud-init-tmpfiles.conf
new file mode 100644
index 00000000..0c6d2a3b
--- /dev/null
+++ b/rhel/cloud-init-tmpfiles.conf
@@ -0,0 +1 @@
+d /run/cloud-init 0700 root root - -
diff --git a/rhel/cloud.cfg b/rhel/cloud.cfg
new file mode 100644
index 00000000..9ecba215
--- /dev/null
+++ b/rhel/cloud.cfg
@@ -0,0 +1,69 @@
+users:
+ - default
+
+disable_root: 1
+ssh_pwauth: 0
+
+mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']
+resize_rootfs_tmp: /dev
+ssh_deletekeys: 1
+ssh_genkeytypes: ~
+syslog_fix_perms: ~
+disable_vmware_customization: false
+
+cloud_init_modules:
+ - disk_setup
+ - migrator
+ - bootcmd
+ - write-files
+ - growpart
+ - resizefs
+ - set_hostname
+ - update_hostname
+ - update_etc_hosts
+ - rsyslog
+ - users-groups
+ - ssh
+
+cloud_config_modules:
+ - mounts
+ - locale
+ - set-passwords
+ - rh_subscription
+ - yum-add-repo
+ - package-update-upgrade-install
+ - timezone
+ - puppet
+ - chef
+ - salt-minion
+ - mcollective
+ - disable-ec2-metadata
+ - runcmd
+
+cloud_final_modules:
+ - rightscale_userdata
+ - scripts-per-once
+ - scripts-per-boot
+ - scripts-per-instance
+ - scripts-user
+ - ssh-authkey-fingerprints
+ - keys-to-console
+ - phone-home
+ - final-message
+ - power-state-change
+
+system_info:
+ default_user:
+ name: cloud-user
+ lock_passwd: true
+ gecos: Cloud User
+ groups: [adm, systemd-journal]
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/bash
+ distro: rhel
+ paths:
+ cloud_dir: /var/lib/cloud
+ templates_dir: /etc/cloud/templates
+ ssh_svcname: sshd
+
+# vim:syntax=yaml
diff --git a/rhel/systemd/cloud-config.service b/rhel/systemd/cloud-config.service
new file mode 100644
index 00000000..f3dcd4be
--- /dev/null
+++ b/rhel/systemd/cloud-config.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=Apply the settings specified in cloud-config
+After=network-online.target cloud-config.target
+Wants=network-online.target cloud-config.target
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/cloud-init modules --mode=config
+RemainAfterExit=yes
+TimeoutSec=0
+
+# Output needs to appear in instance console output
+StandardOutput=journal+console
+
+[Install]
+WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-config.target b/rhel/systemd/cloud-config.target
new file mode 100644
index 00000000..ae9b7d02
--- /dev/null
+++ b/rhel/systemd/cloud-config.target
@@ -0,0 +1,11 @@
+# cloud-init normally emits a "cloud-config" upstart event to inform third
+# parties that cloud-config is available, which does us no good when we're
+# using systemd. cloud-config.target serves as this synchronization point
+# instead. Services that would "start on cloud-config" with upstart can
+# instead use "After=cloud-config.target" and "Wants=cloud-config.target"
+# as appropriate.
+
+[Unit]
+Description=Cloud-config availability
+Wants=cloud-init-local.service cloud-init.service
+After=cloud-init-local.service cloud-init.service
diff --git a/rhel/systemd/cloud-final.service b/rhel/systemd/cloud-final.service
new file mode 100644
index 00000000..e281c0cf
--- /dev/null
+++ b/rhel/systemd/cloud-final.service
@@ -0,0 +1,24 @@
+[Unit]
+Description=Execute cloud user/final scripts
+After=network-online.target cloud-config.service rc-local.service
+Wants=network-online.target cloud-config.service
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/cloud-init modules --mode=final
+RemainAfterExit=yes
+TimeoutSec=0
+KillMode=process
+# Restart NetworkManager if it is present and running.
+ExecStartPost=/bin/sh -c 'u=NetworkManager.service; \
+ out=$(systemctl show --property=SubState $u) || exit; \
+ [ "$out" = "SubState=running" ] || exit 0; \
+ systemctl reload-or-try-restart $u'
+
+# Output needs to appear in instance console output
+StandardOutput=journal+console
+
+[Install]
+WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-init-local.service b/rhel/systemd/cloud-init-local.service
new file mode 100644
index 00000000..8f9f6c9f
--- /dev/null
+++ b/rhel/systemd/cloud-init-local.service
@@ -0,0 +1,31 @@
+[Unit]
+Description=Initial cloud-init job (pre-networking)
+DefaultDependencies=no
+Wants=network-pre.target
+After=systemd-remount-fs.service
+Requires=dbus.socket
+After=dbus.socket
+Before=NetworkManager.service network.service
+Before=network-pre.target
+Before=shutdown.target
+Before=firewalld.target
+Conflicts=shutdown.target
+RequiresMountsFor=/var/lib/cloud
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+
+[Service]
+Type=oneshot
+ExecStartPre=/bin/mkdir -p /run/cloud-init
+ExecStartPre=/sbin/restorecon /run/cloud-init
+ExecStartPre=/usr/bin/touch /run/cloud-init/enabled
+ExecStart=/usr/bin/cloud-init init --local
+ExecStart=/bin/touch /run/cloud-init/network-config-ready
+RemainAfterExit=yes
+TimeoutSec=0
+
+# Output needs to appear in instance console output
+StandardOutput=journal+console
+
+[Install]
+WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-init.service b/rhel/systemd/cloud-init.service
new file mode 100644
index 00000000..0b3d796d
--- /dev/null
+++ b/rhel/systemd/cloud-init.service
@@ -0,0 +1,26 @@
+[Unit]
+Description=Initial cloud-init job (metadata service crawler)
+Wants=cloud-init-local.service
+Wants=sshd-keygen.service
+Wants=sshd.service
+After=cloud-init-local.service
+After=NetworkManager.service network.service
+After=NetworkManager-wait-online.service
+Before=network-online.target
+Before=sshd-keygen.service
+Before=sshd.service
+Before=systemd-user-sessions.service
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/cloud-init init
+RemainAfterExit=yes
+TimeoutSec=0
+
+# Output needs to appear in instance console output
+StandardOutput=journal+console
+
+[Install]
+WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-init.target b/rhel/systemd/cloud-init.target
new file mode 100644
index 00000000..083c3b6f
--- /dev/null
+++ b/rhel/systemd/cloud-init.target
@@ -0,0 +1,7 @@
+# cloud-init target is enabled by cloud-init-generator
+# To disable it you can either:
+# a.) boot with kernel cmdline of 'cloud-init=disabled'
+# b.) touch a file /etc/cloud/cloud-init.disabled
+[Unit]
+Description=Cloud-init target
+After=multi-user.target
diff --git a/setup.py b/setup.py
index a9132d2c..3c377eaa 100755
--- a/setup.py
+++ b/setup.py
@@ -139,21 +139,6 @@ INITSYS_FILES = {
"sysvinit_deb": [f for f in glob("sysvinit/debian/*") if is_f(f)],
"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")
- + glob("systemd/*.service")
- + glob("systemd/*.socket")
- + glob("systemd/*.target")
- )
- if (is_f(f) and not is_generator(f))
- ],
- "systemd.generators": [
- render_tmpl(f, mode=0o755)
- for f in glob("systemd/*")
- if is_f(f) and is_generator(f)
- ],
"upstart": [f for f in glob("upstart/*") if is_f(f)],
}
INITSYS_ROOTS = {
@@ -163,10 +148,6 @@ INITSYS_ROOTS = {
"sysvinit_deb": "etc/init.d",
"sysvinit_openrc": "etc/init.d",
"sysvinit_suse": "etc/init.d",
- "systemd": pkg_config_read("systemd", "systemdsystemunitdir"),
- "systemd.generators": pkg_config_read(
- "systemd", "systemdsystemgeneratordir"
- ),
"upstart": "etc/init/",
}
INITSYS_TYPES = sorted([f.partition(".")[0] for f in INITSYS_ROOTS.keys()])
@@ -281,15 +262,13 @@ data_files = [
(
USR_LIB_EXEC + "/cloud-init",
[
- "tools/ds-identify",
"tools/hook-hotplug",
"tools/uncloud-init",
"tools/write-ssh-key-fingerprints",
],
),
(
- USR + "/share/bash-completion/completions",
- ["bash_completion/cloud-init"],
+ ETC + "/bash_completion.d", ["bash_completion/cloud-init"],
),
(USR + "/share/doc/cloud-init", [f for f in glob("doc/*") if is_f(f)]),
(
@@ -308,8 +287,7 @@ if not platform.system().endswith("BSD"):
ETC + "/NetworkManager/dispatcher.d/",
["tools/hook-network-manager"],
),
- (ETC + "/dhcp/dhclient-exit-hooks.d/", ["tools/hook-dhclient"]),
- (LIB + "/udev/rules.d", [f for f in glob("udev/*.rules")]),
+ ("/usr/lib/udev/rules.d", [f for f in glob("udev/*.rules")]),
(
ETC + "/systemd/system/sshd-keygen@.service.d/",
["systemd/disable-sshd-keygen-if-cloud-init-active.conf"],
@@ -339,8 +317,6 @@ setuptools.setup(
scripts=["tools/cloud-init-per"],
license="Dual-licensed under GPLv3 or Apache 2.0",
data_files=data_files,
- install_requires=requirements,
- cmdclass=cmdclass,
entry_points={
"console_scripts": [
"cloud-init = cloudinit.cmd.main:main",
diff --git a/tools/read-version b/tools/read-version
index 02c90643..79755f78 100755
--- a/tools/read-version
+++ b/tools/read-version
@@ -71,32 +71,8 @@ version_long = None
is_release_branch_ci = (
os.environ.get("TRAVIS_PULL_REQUEST_BRANCH", "").startswith("upstream/")
)
-if is_gitdir(_tdir) and which("git") and not is_release_branch_ci:
- flags = []
- if use_tags:
- flags = ['--tags']
- cmd = ['git', 'describe', '--abbrev=8', '--match=[0-9]*'] + flags
-
- try:
- version = tiny_p(cmd).strip()
- except RuntimeError:
- version = None
-
- if version is None or not version.startswith(src_version):
- sys.stderr.write("git describe version (%s) differs from "
- "cloudinit.version (%s)\n" % (version, src_version))
- sys.stderr.write(
- "Please get the latest upstream tags.\n"
- "As an example, this can be done with the following:\n"
- "$ git remote add upstream https://git.launchpad.net/cloud-init\n"
- "$ git fetch upstream --tags\n"
- )
- sys.exit(1)
-
- version_long = tiny_p(cmd + ["--long"]).strip()
-else:
- version = src_version
- version_long = None
+version = src_version
+version_long = None
# version is X.Y.Z[+xxx.gHASH]
# version_long is None or X.Y.Z-xxx-gHASH
--
2.31.1

View File

@ -1,7 +1,8 @@
From c521ec2ce5b1d9a7322ce152011b8792f121bf5c Mon Sep 17 00:00:00 2001 From b3b96bff187e9d0bfcbfefd5fca05c61bd50d368 Mon Sep 17 00:00:00 2001
From: Eduardo Otubo <otubo@redhat.com> From: Eduardo Otubo <otubo@redhat.com>
Date: Fri, 7 May 2021 13:36:06 +0200 Date: Fri, 7 May 2021 13:36:06 +0200
Subject: Do not write NM_CONTROLLED=no in generated interface config files Subject: [PATCH] Do not write NM_CONTROLLED=no in generated interface config
files
Conflicts 20.3: Conflicts 20.3:
- Not appplying patch on cloudinit/net/sysconfig.py since it now has a - Not appplying patch on cloudinit/net/sysconfig.py since it now has a
@ -20,10 +21,10 @@ Signed-off-by: Ryan McCabe <rmccabe@redhat.com>
2 files changed, 10 insertions(+), 30 deletions(-) 2 files changed, 10 insertions(+), 30 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index ba85c4f6..d8c53312 100644 index d4daa78f..a7dbe55b 100644
--- a/cloudinit/net/sysconfig.py --- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py +++ b/cloudinit/net/sysconfig.py
@@ -336,7 +336,6 @@ class Renderer(renderer.Renderer): @@ -316,7 +316,6 @@ class Renderer(renderer.Renderer):
"rhel": { "rhel": {
"ONBOOT": True, "ONBOOT": True,
"USERCTL": False, "USERCTL": False,
@ -31,7 +32,7 @@ index ba85c4f6..d8c53312 100644
"BOOTPROTO": "none", "BOOTPROTO": "none",
}, },
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"}, "suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
@@ -1039,7 +1038,16 @@ class Renderer(renderer.Renderer): @@ -1019,7 +1018,16 @@ class Renderer(renderer.Renderer):
# Distros configuring /etc/sysconfig/network as a file e.g. Centos # Distros configuring /etc/sysconfig/network as a file e.g. Centos
if sysconfig_path.endswith("network"): if sysconfig_path.endswith("network"):
util.ensure_dir(os.path.dirname(sysconfig_path)) util.ensure_dir(os.path.dirname(sysconfig_path))
@ -50,10 +51,10 @@ index ba85c4f6..d8c53312 100644
netcfg.append("NETWORKING_IPV6=yes") netcfg.append("NETWORKING_IPV6=yes")
netcfg.append("IPV6_AUTOCONF=no") netcfg.append("IPV6_AUTOCONF=no")
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 47e4ba00..591241b3 100644 index 056aaeb6..0f523ff8 100644
--- a/tests/unittests/test_net.py --- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py +++ b/tests/unittests/test_net.py
@@ -579,7 +579,6 @@ GATEWAY=172.19.3.254 @@ -585,7 +585,6 @@ GATEWAY=172.19.3.254
HWADDR=fa:16:3e:ed:9a:59 HWADDR=fa:16:3e:ed:9a:59
IPADDR=172.19.1.34 IPADDR=172.19.1.34
NETMASK=255.255.252.0 NETMASK=255.255.252.0
@ -61,7 +62,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -712,7 +711,6 @@ IPADDR=172.19.1.34 @@ -749,7 +748,6 @@ IPADDR=172.19.1.34
IPADDR1=10.0.0.10 IPADDR1=10.0.0.10
NETMASK=255.255.252.0 NETMASK=255.255.252.0
NETMASK1=255.255.255.0 NETMASK1=255.255.255.0
@ -69,7 +70,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -874,7 +872,6 @@ IPV6_AUTOCONF=no @@ -911,7 +909,6 @@ IPV6_AUTOCONF=no
IPV6_DEFAULTGW=2001:DB8::1 IPV6_DEFAULTGW=2001:DB8::1
IPV6_FORCE_ACCEPT_RA=no IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.252.0 NETMASK=255.255.252.0
@ -77,7 +78,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -1053,7 +1050,6 @@ NETWORK_CONFIGS = { @@ -1090,7 +1087,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=none BOOTPROTO=none
DEVICE=eth1 DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80 HWADDR=cf:d6:af:48:e8:80
@ -85,7 +86,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -1072,7 +1068,6 @@ NETWORK_CONFIGS = { @@ -1109,7 +1105,6 @@ NETWORK_CONFIGS = {
IPADDR=192.168.21.3 IPADDR=192.168.21.3
NETMASK=255.255.255.0 NETMASK=255.255.255.0
METRIC=10000 METRIC=10000
@ -93,7 +94,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -1244,7 +1239,6 @@ NETWORK_CONFIGS = { @@ -1353,7 +1348,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no IPV6_FORCE_ACCEPT_RA=no
NETMASK=255.255.255.0 NETMASK=255.255.255.0
@ -101,7 +102,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -2093,7 +2087,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2377,7 +2371,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DHCPV6C=yes DHCPV6C=yes
IPV6INIT=yes IPV6INIT=yes
MACADDR=aa:bb:cc:dd:ee:ff MACADDR=aa:bb:cc:dd:ee:ff
@ -109,7 +110,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Bond TYPE=Bond
USERCTL=no""" USERCTL=no"""
@@ -2103,7 +2096,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2387,7 +2380,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BOOTPROTO=dhcp BOOTPROTO=dhcp
DEVICE=bond0.200 DEVICE=bond0.200
DHCLIENT_SET_DEFAULT_ROUTE=no DHCLIENT_SET_DEFAULT_ROUTE=no
@ -117,7 +118,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
PHYSDEV=bond0 PHYSDEV=bond0
USERCTL=no USERCTL=no
@@ -2123,7 +2115,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2407,7 +2399,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 IPV6_DEFAULTGW=2001:4800:78ff:1b::1
MACADDR=bb:bb:bb:bb:bb:aa MACADDR=bb:bb:bb:bb:bb:aa
NETMASK=255.255.255.0 NETMASK=255.255.255.0
@ -125,7 +126,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
PRIO=22 PRIO=22
STP=no STP=no
@@ -2135,7 +2126,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2419,7 +2410,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BOOTPROTO=none BOOTPROTO=none
DEVICE=eth0 DEVICE=eth0
HWADDR=c0:d6:9f:2c:e8:80 HWADDR=c0:d6:9f:2c:e8:80
@ -133,7 +134,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -2154,7 +2144,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2438,7 +2428,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
MTU=1500 MTU=1500
NETMASK=255.255.255.0 NETMASK=255.255.255.0
NETMASK1=255.255.255.0 NETMASK1=255.255.255.0
@ -141,7 +142,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
PHYSDEV=eth0 PHYSDEV=eth0
USERCTL=no USERCTL=no
@@ -2166,7 +2155,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2450,7 +2439,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DEVICE=eth1 DEVICE=eth1
HWADDR=aa:d6:9f:2c:e8:80 HWADDR=aa:d6:9f:2c:e8:80
MASTER=bond0 MASTER=bond0
@ -149,7 +150,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
SLAVE=yes SLAVE=yes
TYPE=Ethernet TYPE=Ethernet
@@ -2178,7 +2166,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2462,7 +2450,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DEVICE=eth2 DEVICE=eth2
HWADDR=c0:bb:9f:2c:e8:80 HWADDR=c0:bb:9f:2c:e8:80
MASTER=bond0 MASTER=bond0
@ -157,7 +158,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
SLAVE=yes SLAVE=yes
TYPE=Ethernet TYPE=Ethernet
@@ -2190,7 +2177,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2474,7 +2461,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BRIDGE=br0 BRIDGE=br0
DEVICE=eth3 DEVICE=eth3
HWADDR=66:bb:9f:2c:e8:80 HWADDR=66:bb:9f:2c:e8:80
@ -165,7 +166,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -2201,7 +2187,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2485,7 +2471,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
BRIDGE=br0 BRIDGE=br0
DEVICE=eth4 DEVICE=eth4
HWADDR=98:bb:9f:2c:e8:80 HWADDR=98:bb:9f:2c:e8:80
@ -173,7 +174,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -2212,7 +2197,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true @@ -2496,7 +2481,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
DEVICE=eth5 DEVICE=eth5
DHCLIENT_SET_DEFAULT_ROUTE=no DHCLIENT_SET_DEFAULT_ROUTE=no
HWADDR=98:bb:9f:2c:e8:8a HWADDR=98:bb:9f:2c:e8:8a
@ -181,7 +182,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=no ONBOOT=no
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -2689,7 +2673,6 @@ iface bond0 inet6 static @@ -3220,7 +3204,6 @@ iface bond0 inet6 static
MTU=9000 MTU=9000
NETMASK=255.255.255.0 NETMASK=255.255.255.0
NETMASK1=255.255.255.0 NETMASK1=255.255.255.0
@ -189,7 +190,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Bond TYPE=Bond
USERCTL=no USERCTL=no
@@ -2701,7 +2684,6 @@ iface bond0 inet6 static @@ -3232,7 +3215,6 @@ iface bond0 inet6 static
DEVICE=bond0s0 DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00 HWADDR=aa:bb:cc:dd:e8:00
MASTER=bond0 MASTER=bond0
@ -197,7 +198,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
SLAVE=yes SLAVE=yes
TYPE=Ethernet TYPE=Ethernet
@@ -2729,7 +2711,6 @@ iface bond0 inet6 static @@ -3260,7 +3242,6 @@ iface bond0 inet6 static
DEVICE=bond0s1 DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01 HWADDR=aa:bb:cc:dd:e8:01
MASTER=bond0 MASTER=bond0
@ -205,7 +206,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
SLAVE=yes SLAVE=yes
TYPE=Ethernet TYPE=Ethernet
@@ -2794,7 +2775,6 @@ iface bond0 inet6 static @@ -3406,7 +3387,6 @@ iface bond0 inet6 static
BOOTPROTO=none BOOTPROTO=none
DEVICE=en0 DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00 HWADDR=aa:bb:cc:dd:e8:00
@ -213,7 +214,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no""" USERCTL=no"""
@@ -2815,7 +2795,6 @@ iface bond0 inet6 static @@ -3427,7 +3407,6 @@ iface bond0 inet6 static
MTU=2222 MTU=2222
NETMASK=255.255.255.0 NETMASK=255.255.255.0
NETMASK1=255.255.255.0 NETMASK1=255.255.255.0
@ -221,7 +222,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
PHYSDEV=en0 PHYSDEV=en0
USERCTL=no USERCTL=no
@@ -2890,7 +2869,6 @@ iface bond0 inet6 static @@ -3553,7 +3532,6 @@ iface bond0 inet6 static
DEVICE=br0 DEVICE=br0
IPADDR=192.168.2.2 IPADDR=192.168.2.2
NETMASK=255.255.255.0 NETMASK=255.255.255.0
@ -229,7 +230,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
PRIO=22 PRIO=22
STP=no STP=no
@@ -3032,7 +3010,6 @@ iface bond0 inet6 static @@ -3769,7 +3747,6 @@ iface bond0 inet6 static
HWADDR=52:54:00:12:34:00 HWADDR=52:54:00:12:34:00
IPADDR=192.168.1.2 IPADDR=192.168.1.2
NETMASK=255.255.255.0 NETMASK=255.255.255.0
@ -237,7 +238,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=no ONBOOT=no
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -3044,7 +3021,6 @@ iface bond0 inet6 static @@ -3781,7 +3758,6 @@ iface bond0 inet6 static
DEVICE=eth1 DEVICE=eth1
HWADDR=52:54:00:12:34:aa HWADDR=52:54:00:12:34:aa
MTU=1480 MTU=1480
@ -245,7 +246,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -3055,7 +3031,6 @@ iface bond0 inet6 static @@ -3792,7 +3768,6 @@ iface bond0 inet6 static
BOOTPROTO=none BOOTPROTO=none
DEVICE=eth2 DEVICE=eth2
HWADDR=52:54:00:12:34:ff HWADDR=52:54:00:12:34:ff
@ -253,7 +254,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=no ONBOOT=no
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -3628,7 +3603,6 @@ class TestRhelSysConfigRendering(CiTestCase): @@ -4469,7 +4444,6 @@ class TestRhelSysConfigRendering(CiTestCase):
BOOTPROTO=dhcp BOOTPROTO=dhcp
DEVICE=eth1000 DEVICE=eth1000
HWADDR=07-1c-c6-75-a4-be HWADDR=07-1c-c6-75-a4-be
@ -261,7 +262,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -3840,7 +3814,6 @@ GATEWAY=10.0.2.2 @@ -4681,7 +4655,6 @@ GATEWAY=10.0.2.2
HWADDR=52:54:00:12:34:00 HWADDR=52:54:00:12:34:00
IPADDR=10.0.2.15 IPADDR=10.0.2.15
NETMASK=255.255.255.0 NETMASK=255.255.255.0
@ -269,7 +270,7 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
@@ -3910,7 +3883,6 @@ USERCTL=no @@ -4751,7 +4724,6 @@ USERCTL=no
# #
BOOTPROTO=dhcp BOOTPROTO=dhcp
DEVICE=eth0 DEVICE=eth0
@ -277,6 +278,3 @@ index 47e4ba00..591241b3 100644
ONBOOT=yes ONBOOT=yes
TYPE=Ethernet TYPE=Ethernet
USERCTL=no USERCTL=no
--
2.31.1

View File

@ -1,42 +0,0 @@
From b952fa472be3f417e0d857c8647a1b930624c247 Mon Sep 17 00:00:00 2001
From: Eduardo Otubo <otubo@redhat.com>
Date: Fri, 25 Feb 2022 05:05:17 -0500
Subject: Adding _netdev to the default mount configuration
RH-Author: Eduardo Otubo <otubo@redhat.com>
RH-MergeRequest: 21: Adding _netdev to the default mount configuration
RH-Commit: [1/1] 250860a24db396a5088d207d6526a0028ac73eb3 (otubo/cloud-init-src)
RH-Bugzilla: 1998445
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Adding _netdev option also to the default configuration for RHEL.
rhbz: 1998445
x-downstream-only: yes
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
patch_name: ci-Adding-_netdev-to-the-default-mount-configuration.patch
present_in_specfile: true
location_in_specfile: 29
---
rhel/cloud.cfg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rhel/cloud.cfg b/rhel/cloud.cfg
index 9ecba215..1ec1a6c6 100644
--- a/rhel/cloud.cfg
+++ b/rhel/cloud.cfg
@@ -4,7 +4,7 @@ users:
disable_root: 1
ssh_pwauth: 0
-mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']
+mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service,_netdev', '0', '2']
resize_rootfs_tmp: /dev
ssh_deletekeys: 1
ssh_genkeytypes: ~
--
2.31.1

View File

@ -1,7 +1,7 @@
From a14df44ffdc880ae16c691901e2671458ab234ff Mon Sep 17 00:00:00 2001 From c589da20eb92231ef08e10c9724e3e6c663e6ce2 Mon Sep 17 00:00:00 2001
From: Eduardo Otubo <otubo@redhat.com> From: Eduardo Otubo <otubo@redhat.com>
Date: Thu, 17 Feb 2022 15:32:35 +0100 Date: Thu, 17 Feb 2022 15:32:35 +0100
Subject: Setting highest autoconnect priority for network-scripts Subject: [PATCH] Setting highest autoconnect priority for network-scripts
RH-Author: Eduardo Otubo <otubo@redhat.com> RH-Author: Eduardo Otubo <otubo@redhat.com>
RH-MergeRequest: 22: Setting highest autoconnect priority for network-scripts RH-MergeRequest: 22: Setting highest autoconnect priority for network-scripts
@ -24,19 +24,15 @@ rhbz: 2036060
x-downstream-only: yes x-downstream-only: yes
Signed-off-by: Eduardo Otubo <otubo@redhat.com> Signed-off-by: Eduardo Otubo <otubo@redhat.com>
patch_name: ci-Setting-highest-autoconnect-priority-for-network-scr.patch
present_in_specfile: true
location_in_specfile: 30
--- ---
cloudinit/net/sysconfig.py | 1 + cloudinit/net/sysconfig.py | 1 +
1 file changed, 1 insertion(+) 1 file changed, 1 insertion(+)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index d8c53312..b50035b5 100644 index a7dbe55b..4262cd48 100644
--- a/cloudinit/net/sysconfig.py --- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py +++ b/cloudinit/net/sysconfig.py
@@ -337,6 +337,7 @@ class Renderer(renderer.Renderer): @@ -317,6 +317,7 @@ class Renderer(renderer.Renderer):
"ONBOOT": True, "ONBOOT": True,
"USERCTL": False, "USERCTL": False,
"BOOTPROTO": "none", "BOOTPROTO": "none",
@ -44,6 +40,3 @@ index d8c53312..b50035b5 100644
}, },
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"}, "suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
} }
--
2.31.1

View File

@ -1,7 +1,7 @@
From 40ad855b883050069393b9c00db2a6d222d949db Mon Sep 17 00:00:00 2001 From dfff374f66904e84fb07ca157ba010fac6b5f1de Mon Sep 17 00:00:00 2001
From: Eduardo Otubo <otubo@redhat.com> From: Eduardo Otubo <otubo@redhat.com>
Date: Fri, 7 May 2021 13:36:08 +0200 Date: Fri, 7 May 2021 13:36:08 +0200
Subject: limit permissions on def_log_file Subject: [PATCH] limit permissions on def_log_file
This sets a default mode of 0600 on def_log_file, and makes this This sets a default mode of 0600 on def_log_file, and makes this
configurable via the def_log_file_mode option in cloud.cfg. configurable via the def_log_file_mode option in cloud.cfg.
@ -13,7 +13,10 @@ X-approved-upstream: true
Conflicts 21.1: Conflicts 21.1:
cloudinit/stages.py: adjusting call of ensure_file() to use more cloudinit/stages.py: adjusting call of ensure_file() to use more
recent version recent version
Confilicts 23.1.1:
use "" instead of ''
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Signed-off-by: Eduardo Otubo <otubo@redhat.com> Signed-off-by: Eduardo Otubo <otubo@redhat.com>
--- ---
cloudinit/settings.py | 1 + cloudinit/settings.py | 1 +
@ -22,22 +25,22 @@ Signed-off-by: Eduardo Otubo <otubo@redhat.com>
3 files changed, 6 insertions(+) 3 files changed, 6 insertions(+)
diff --git a/cloudinit/settings.py b/cloudinit/settings.py diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index a780e21e..aa2d6b95 100644 index edbb217d..3d541141 100644
--- a/cloudinit/settings.py --- a/cloudinit/settings.py
+++ b/cloudinit/settings.py +++ b/cloudinit/settings.py
@@ -49,6 +49,7 @@ CFG_BUILTIN = { @@ -52,6 +52,7 @@ CFG_BUILTIN = {
"None", "None",
], ],
'def_log_file': '/var/log/cloud-init.log', "def_log_file": "/var/log/cloud-init.log",
+ 'def_log_file_mode': 0o600, + "def_log_file_mode": 0o600,
'log_cfgs': [], "log_cfgs": [],
'mount_default_fields': [None, None, 'auto', 'defaults,nofail', '0', '2'], "mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
'ssh_deletekeys': False, "syslog_fix_perms": [],
diff --git a/cloudinit/stages.py b/cloudinit/stages.py diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 3f17294b..61db1dbd 100644 index 9494a0bf..a624a6fb 100644
--- a/cloudinit/stages.py --- a/cloudinit/stages.py
+++ b/cloudinit/stages.py +++ b/cloudinit/stages.py
@@ -205,6 +205,7 @@ class Init(object): @@ -202,6 +202,7 @@ class Init:
def _initialize_filesystem(self): def _initialize_filesystem(self):
util.ensure_dirs(self._initial_subdirs()) util.ensure_dirs(self._initial_subdirs())
log_file = util.get_cfg_option_str(self.cfg, "def_log_file") log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
@ -46,10 +49,10 @@ index 3f17294b..61db1dbd 100644
util.ensure_file(log_file, mode=0o640, preserve_mode=True) util.ensure_file(log_file, mode=0o640, preserve_mode=True)
perms = self.cfg.get("syslog_fix_perms") perms = self.cfg.get("syslog_fix_perms")
diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
index a2b4a3fa..0ccf3147 100644 index 15d788f3..b6d16c9c 100644
--- a/doc/examples/cloud-config.txt --- a/doc/examples/cloud-config.txt
+++ b/doc/examples/cloud-config.txt +++ b/doc/examples/cloud-config.txt
@@ -414,10 +414,14 @@ timezone: US/Eastern @@ -383,10 +383,14 @@ timezone: US/Eastern
# if syslog_fix_perms is a list, it will iterate through and use the # if syslog_fix_perms is a list, it will iterate through and use the
# first pair that does not raise error. # first pair that does not raise error.
# #
@ -64,6 +67,3 @@ index a2b4a3fa..0ccf3147 100644
syslog_fix_perms: syslog:root syslog_fix_perms: syslog:root
# you can set passwords for a user or multiple users # you can set passwords for a user or multiple users
--
2.31.1

View File

@ -0,0 +1,92 @@
From ecae81f98ce230266eb99671b74534a4ede660f0 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Fri, 10 Mar 2023 11:51:48 +0100
Subject: [PATCH] Manual revert "Use Network-Manager and Netplan as default
renderers for RHEL and Fedora (#1465)"
This reverts changes done in commit 7703aa98b.
Done by hand because the doc file affected by that commit has changed.
X-downstream-only: true
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/net/renderers.py | 1 -
config/cloud.cfg.tmpl | 3 ---
doc/rtd/reference/network-config.rst | 16 ++--------------
3 files changed, 2 insertions(+), 18 deletions(-)
diff --git a/cloudinit/net/renderers.py b/cloudinit/net/renderers.py
index fcf7feba..b241683f 100644
--- a/cloudinit/net/renderers.py
+++ b/cloudinit/net/renderers.py
@@ -30,7 +30,6 @@ DEFAULT_PRIORITY = [
"eni",
"sysconfig",
"netplan",
- "network-manager",
"freebsd",
"netbsd",
"openbsd",
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 7238c102..12f32c51 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -381,9 +381,6 @@ system_info:
{% elif variant in ["dragonfly"] %}
network:
renderers: ['freebsd']
-{% elif variant in ["fedora"] or is_rhel %}
- network:
- renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
{% elif variant == "openmandriva" %}
network:
renderers: ['network-manager', 'networkd']
diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst
index ea331f1c..bc52afa5 100644
--- a/doc/rtd/reference/network-config.rst
+++ b/doc/rtd/reference/network-config.rst
@@ -176,16 +176,6 @@ this state, ``cloud-init`` delegates rendering of the configuration to
distro-supported formats. The following ``renderers`` are supported in
``cloud-init``:
-NetworkManager
---------------
-
-`NetworkManager`_ is the standard Linux network configuration tool suite. It
-supports a wide range of networking setups. Configuration is typically stored
-in :file:`/etc/NetworkManager`.
-
-It is the default for a number of Linux distributions; notably Fedora,
-CentOS/RHEL, and their derivatives.
-
ENI
---
@@ -223,7 +213,6 @@ preference) is as follows:
- ENI
- Sysconfig
- Netplan
-- NetworkManager
- FreeBSD
- NetBSD
- OpenBSD
@@ -234,7 +223,6 @@ preference) is as follows:
- **ENI**: using ``ifup``, ``ifdown`` to manage device setup/teardown
- **Netplan**: using ``netplan apply`` to manage device setup/teardown
-- **NetworkManager**: using ``nmcli`` to manage device setup/teardown
- **Networkd**: using ``ip`` to manage device setup/teardown
When applying the policy, ``cloud-init`` checks if the current instance has the
@@ -244,8 +232,8 @@ supplying an updated configuration in cloud-config. ::
system_info:
network:
- renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
- activators: ['eni', 'netplan', 'network-manager', 'networkd']
+ renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
+ activators: ['eni', 'netplan', 'networkd']
Network configuration tools
===========================

View File

@ -1,65 +0,0 @@
From 00f1f910d8d166ebe2913c12549f212c2d666c11 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu, 20 May 2021 08:53:55 +0200
Subject: rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in
cloud.cfg
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 10: rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg
RH-Commit: [1/1] 6da989423b9b6e017afbac2f1af3649b0487310f
RH-Bugzilla: 1957532
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
Currently genkeytypes in cloud.cfg is set to None, so together with
ssh_deletekeys=1 cloudinit on first boot it will just delete the existing
keys and not generate new ones.
Just removing that property in cloud.cfg is not enough, because
settings.py provides another empty default value that will be used
instead, resulting to no key generated even when the property is not defined.
Removing genkeytypes also in settings.py will default to GENERATE_KEY_NAMES,
but since we want only 'rsa', 'ecdsa' and 'ed25519', add back genkeytypes in
cloud.cfg with the above defaults.
Also remove ssh_deletekeys in settings.py as we always need
to 1 (and it also defaults to 1).
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/settings.py | 2 --
rhel/cloud.cfg | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index aa2d6b95..38a90b70 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -52,8 +52,6 @@ CFG_BUILTIN = {
'def_log_file_mode': 0o600,
'log_cfgs': [],
'mount_default_fields': [None, None, 'auto', 'defaults,nofail', '0', '2'],
- 'ssh_deletekeys': False,
- 'ssh_genkeytypes': [],
'syslog_fix_perms': [],
'system_info': {
'paths': {
diff --git a/rhel/cloud.cfg b/rhel/cloud.cfg
index 1ec1a6c6..75d5c84b 100644
--- a/rhel/cloud.cfg
+++ b/rhel/cloud.cfg
@@ -7,7 +7,7 @@ ssh_pwauth: 0
mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service,_netdev', '0', '2']
resize_rootfs_tmp: /dev
ssh_deletekeys: 1
-ssh_genkeytypes: ~
+ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
syslog_fix_perms: ~
disable_vmware_customization: false
--
2.31.1

View File

@ -0,0 +1,54 @@
From ac0cf308318d423162ce3b7be32dcbf88f20ff50 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 4 Apr 2023 19:59:07 +0530
Subject: [PATCH] rhel: make sure previous-hostname file ends with a new line
(#2108)
cloud-init strips new line from "/etc/hostname" on rhel distro when processing
"/var/lib/cloud/data/previous-hostname". Although this does not pose a serious
issue, it is still better if the behavior is similar to other distros like
Ubuntu where /previous-hostname does end with a new line. Fix this issue by
using hostname parser in rhel similar to debian.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 6d42aa8e2c1a5454a658ab4e2b9cead2677c77cd)
---
cloudinit/distros/rhel.py | 5 ++++-
tools/.github-cla-signers | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py
index df7dc3d6..9625709e 100644
--- a/cloudinit/distros/rhel.py
+++ b/cloudinit/distros/rhel.py
@@ -13,6 +13,7 @@ from cloudinit import distros, helpers
from cloudinit import log as logging
from cloudinit import subp, util
from cloudinit.distros import rhel_util
+from cloudinit.distros.parsers.hostname import HostnameConf
from cloudinit.settings import PER_INSTANCE
LOG = logging.getLogger(__name__)
@@ -111,7 +112,9 @@ class Distro(distros.Distro):
# systemd will never update previous-hostname for us, so
# we need to do it ourselves
if self.uses_systemd() and filename.endswith("/previous-hostname"):
- util.write_file(filename, hostname)
+ conf = HostnameConf("")
+ conf.set_hostname(hostname)
+ util.write_file(filename, str(conf), 0o644)
elif self.uses_systemd():
subp.subp(["hostnamectl", "set-hostname", str(hostname)])
else:
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
index d8cca015..457dacf4 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -9,6 +9,7 @@ andgein
andrew-lee-metaswitch
andrewbogott
andrewlukoshko
+ani-sinha
antonyc
aswinrajamannar
beantaxi

View File

@ -0,0 +1,121 @@
From 34ef256dc614c7dcf5b04a431d410030e333d82b Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Mon, 17 Apr 2023 10:20:16 +0200
Subject: [PATCH] Don't change permissions of netrules target (#2076)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2182948
commit 56c88cafd1b3606e814069a79f4ec265fc427c87
Author: James Falcon <james.falcon@canonical.com>
Date: Thu Mar 23 10:21:56 2023 -0500
Don't change permissions of netrules target (#2076)
Set permissions if file doesn't exist. Leave them if it does.
LP: #2011783
Co-authored-by: Chad Smith <chad.smith@canonical.com>
Conflicts:
cloudinit/net/sysconfig.py: enable_ifcfg_rh missing upstream
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/net/eni.py | 4 +++-
cloudinit/net/sysconfig.py | 7 ++++++-
tests/unittests/distros/test_netconfig.py | 20 ++++++++++++++++++--
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
index 53bd35ca..1de3bec2 100644
--- a/cloudinit/net/eni.py
+++ b/cloudinit/net/eni.py
@@ -576,7 +576,9 @@ class Renderer(renderer.Renderer):
netrules = subp.target_path(target, self.netrules_path)
util.ensure_dir(os.path.dirname(netrules))
util.write_file(
- netrules, self._render_persistent_net(network_state)
+ netrules,
+ content=self._render_persistent_net(network_state),
+ preserve_mode=True,
)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 765c248a..e08c0c69 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -1034,7 +1034,12 @@ class Renderer(renderer.Renderer):
if self.netrules_path:
netrules_content = self._render_persistent_net(network_state)
netrules_path = subp.target_path(target, self.netrules_path)
- util.write_file(netrules_path, netrules_content, file_mode)
+ util.write_file(
+ netrules_path,
+ content=netrules_content,
+ mode=file_mode,
+ preserve_mode=True,
+ )
if available_nm(target=target):
enable_ifcfg_rh(subp.target_path(target, path=NM_CFG_FILE))
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index e9fb0591..b1c89ce3 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -458,8 +458,16 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
def eni_path(self):
return "/etc/network/interfaces.d/50-cloud-init.cfg"
+ def rules_path(self):
+ return "/etc/udev/rules.d/70-persistent-net.rules"
+
def _apply_and_verify_eni(
- self, apply_fn, config, expected_cfgs=None, bringup=False
+ self,
+ apply_fn,
+ config,
+ expected_cfgs=None,
+ bringup=False,
+ previous_files=(),
):
if not expected_cfgs:
raise ValueError("expected_cfg must not be None")
@@ -467,7 +475,11 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
tmpd = None
with mock.patch("cloudinit.net.eni.available") as m_avail:
m_avail.return_value = True
+ path_modes = {}
with self.reRooted(tmpd) as tmpd:
+ for previous_path, content, mode in previous_files:
+ util.write_file(previous_path, content, mode=mode)
+ path_modes[previous_path] = mode
apply_fn(config, bringup)
results = dir2dict(tmpd)
@@ -478,7 +490,9 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
print(results[cfgpath])
print("----------")
self.assertEqual(expected, results[cfgpath])
- self.assertEqual(0o644, get_mode(cfgpath, tmpd))
+ self.assertEqual(
+ path_modes.get(cfgpath, 0o644), get_mode(cfgpath, tmpd)
+ )
def test_apply_network_config_and_bringup_filters_priority_eni_ub(self):
"""Network activator search priority can be overridden from config."""
@@ -527,11 +541,13 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
def test_apply_network_config_eni_ub(self):
expected_cfgs = {
self.eni_path(): V1_NET_CFG_OUTPUT,
+ self.rules_path(): "",
}
self._apply_and_verify_eni(
self.distro.apply_network_config,
V1_NET_CFG,
expected_cfgs=expected_cfgs.copy(),
+ previous_files=((self.rules_path(), "something", 0o660),),
)
def test_apply_network_config_ipv6_ub(self):

View File

@ -0,0 +1,295 @@
From d092efe0f437ad149f6d6e3a9f8b816c0f5c1c2a Mon Sep 17 00:00:00 2001
From: James Falcon <james.falcon@canonical.com>
Date: Wed, 26 Apr 2023 15:11:55 -0500
Subject: [PATCH] Make user/vendor data sensitive and remove log permissions
(#2144)
Because user data and vendor data may contain sensitive information,
this commit ensures that any user data or vendor data written to
instance-data.json gets redacted and is only available to root user.
Also, modify the permissions of cloud-init.log to be 640, so that
sensitive data leaked to the log isn't world readable.
Additionally, remove the logging of user data and vendor data to
cloud-init.log from the Vultr datasource.
LP: #2013967
CVE: CVE-2023-1786
(cherry picked from commit a378b7e4f47375458651c0972e7cd813f6fe0a6b)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceLXD.py | 9 ++++++---
cloudinit/sources/DataSourceVultr.py | 14 ++++++--------
cloudinit/sources/__init__.py | 28 +++++++++++++++++++++++++---
cloudinit/stages.py | 4 +++-
tests/unittests/sources/test_init.py | 27 ++++++++++++++++++++++++++-
tests/unittests/test_stages.py | 18 +++++++++++-------
6 files changed, 77 insertions(+), 23 deletions(-)
diff --git a/cloudinit/sources/DataSourceLXD.py b/cloudinit/sources/DataSourceLXD.py
index ab440cc8..e4cae91a 100644
--- a/cloudinit/sources/DataSourceLXD.py
+++ b/cloudinit/sources/DataSourceLXD.py
@@ -14,7 +14,7 @@ import stat
import time
from enum import Flag, auto
from json.decoder import JSONDecodeError
-from typing import Any, Dict, List, Optional, Union, cast
+from typing import Any, Dict, List, Optional, Tuple, Union, cast
import requests
from requests.adapters import HTTPAdapter
@@ -168,11 +168,14 @@ class DataSourceLXD(sources.DataSource):
_network_config: Union[Dict, str] = sources.UNSET
_crawled_metadata: Union[Dict, str] = sources.UNSET
- sensitive_metadata_keys = (
- "merged_cfg",
+ sensitive_metadata_keys: Tuple[
+ str, ...
+ ] = sources.DataSource.sensitive_metadata_keys + (
"user.meta-data",
"user.vendor-data",
"user.user-data",
+ "cloud-init.user-data",
+ "cloud-init.vendor-data",
)
skip_hotplug_detect = True
diff --git a/cloudinit/sources/DataSourceVultr.py b/cloudinit/sources/DataSourceVultr.py
index 9d7c84fb..660e9f14 100644
--- a/cloudinit/sources/DataSourceVultr.py
+++ b/cloudinit/sources/DataSourceVultr.py
@@ -5,6 +5,8 @@
# Vultr Metadata API:
# https://www.vultr.com/metadata/
+from typing import Tuple
+
import cloudinit.sources.helpers.vultr as vultr
from cloudinit import log as log
from cloudinit import sources, util, version
@@ -28,6 +30,10 @@ class DataSourceVultr(sources.DataSource):
dsname = "Vultr"
+ sensitive_metadata_keys: Tuple[
+ str, ...
+ ] = sources.DataSource.sensitive_metadata_keys + ("startup-script",)
+
def __init__(self, sys_cfg, distro, paths):
super(DataSourceVultr, self).__init__(sys_cfg, distro, paths)
self.ds_cfg = util.mergemanydict(
@@ -54,13 +60,8 @@ class DataSourceVultr(sources.DataSource):
self.get_datasource_data(self.metadata)
# Dump some data so diagnosing failures is manageable
- LOG.debug("Vultr Vendor Config:")
- LOG.debug(util.json_dumps(self.metadata["vendor-data"]))
LOG.debug("SUBID: %s", self.metadata["instance-id"])
LOG.debug("Hostname: %s", self.metadata["local-hostname"])
- if self.userdata_raw is not None:
- LOG.debug("User-Data:")
- LOG.debug(self.userdata_raw)
return True
@@ -146,7 +147,4 @@ if __name__ == "__main__":
config = md["vendor-data"]
sysinfo = vultr.get_sysinfo()
- print(util.json_dumps(sysinfo))
- print(util.json_dumps(config))
-
# vi: ts=4 expandtab
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 565e1754..5c6ae8b1 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -110,7 +110,10 @@ def process_instance_metadata(metadata, key_path="", sensitive_keys=()):
sub_key_path = key_path + "/" + key
else:
sub_key_path = key
- if key in sensitive_keys or sub_key_path in sensitive_keys:
+ if (
+ key.lower() in sensitive_keys
+ or sub_key_path.lower() in sensitive_keys
+ ):
sens_keys.append(sub_key_path)
if isinstance(val, str) and val.startswith("ci-b64:"):
base64_encoded_keys.append(sub_key_path)
@@ -132,6 +135,12 @@ def redact_sensitive_keys(metadata, redact_value=REDACT_SENSITIVE_VALUE):
Replace any keys values listed in 'sensitive_keys' with redact_value.
"""
+ # While 'sensitive_keys' should already sanitized to only include what
+ # is in metadata, it is possible keys will overlap. For example, if
+ # "merged_cfg" and "merged_cfg/ds/userdata" both match, it's possible that
+ # "merged_cfg" will get replaced first, meaning "merged_cfg/ds/userdata"
+ # no longer represents a valid key.
+ # Thus, we still need to do membership checks in this function.
if not metadata.get("sensitive_keys", []):
return metadata
md_copy = copy.deepcopy(metadata)
@@ -139,9 +148,14 @@ def redact_sensitive_keys(metadata, redact_value=REDACT_SENSITIVE_VALUE):
path_parts = key_path.split("/")
obj = md_copy
for path in path_parts:
- if isinstance(obj[path], dict) and path != path_parts[-1]:
+ if (
+ path in obj
+ and isinstance(obj[path], dict)
+ and path != path_parts[-1]
+ ):
obj = obj[path]
- obj[path] = redact_value
+ if path in obj:
+ obj[path] = redact_value
return md_copy
@@ -249,6 +263,14 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
sensitive_metadata_keys: Tuple[str, ...] = (
"merged_cfg",
"security-credentials",
+ "userdata",
+ "user-data",
+ "user_data",
+ "vendordata",
+ "vendor-data",
+ # Provide ds/vendor_data to avoid redacting top-level
+ # "vendor_data": {enabled: True}
+ "ds/vendor_data",
)
# True on datasources that may not see hotplugged devices reflected
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index a624a6fb..1326d205 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -204,7 +204,9 @@ class Init:
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
log_file_mode = util.get_cfg_option_int(self.cfg, "def_log_file_mode")
if log_file:
- util.ensure_file(log_file, mode=0o640, preserve_mode=True)
+ # At this point the log file should have already been created
+ # in the setupLogging function of log.py
+ util.ensure_file(log_file, mode=0o640, preserve_mode=False)
perms = self.cfg.get("syslog_fix_perms")
if not perms:
perms = {}
diff --git a/tests/unittests/sources/test_init.py b/tests/unittests/sources/test_init.py
index 0447e02c..eb27198f 100644
--- a/tests/unittests/sources/test_init.py
+++ b/tests/unittests/sources/test_init.py
@@ -458,12 +458,24 @@ class TestDataSource(CiTestCase):
"cred2": "othersekret",
}
},
+ "someother": {
+ "nested": {
+ "userData": "HIDE ME",
+ }
+ },
+ "VENDOR-DAta": "HIDE ME TOO",
},
)
self.assertCountEqual(
(
"merged_cfg",
"security-credentials",
+ "userdata",
+ "user-data",
+ "user_data",
+ "vendordata",
+ "vendor-data",
+ "ds/vendor_data",
),
datasource.sensitive_metadata_keys,
)
@@ -490,7 +502,9 @@ class TestDataSource(CiTestCase):
"base64_encoded_keys": [],
"merged_cfg": REDACT_SENSITIVE_VALUE,
"sensitive_keys": [
+ "ds/meta_data/VENDOR-DAta",
"ds/meta_data/some/security-credentials",
+ "ds/meta_data/someother/nested/userData",
"merged_cfg",
],
"sys_info": sys_info,
@@ -500,6 +514,7 @@ class TestDataSource(CiTestCase):
"availability_zone": "myaz",
"cloud-name": "subclasscloudname",
"cloud_name": "subclasscloudname",
+ "cloud_id": "subclasscloudname",
"distro": "ubuntu",
"distro_release": "focal",
"distro_version": "20.04",
@@ -522,14 +537,18 @@ class TestDataSource(CiTestCase):
"ds": {
"_doc": EXPERIMENTAL_TEXT,
"meta_data": {
+ "VENDOR-DAta": REDACT_SENSITIVE_VALUE,
"availability_zone": "myaz",
"local-hostname": "test-subclass-hostname",
"region": "myregion",
"some": {"security-credentials": REDACT_SENSITIVE_VALUE},
+ "someother": {
+ "nested": {"userData": REDACT_SENSITIVE_VALUE}
+ },
},
},
}
- self.assertCountEqual(expected, redacted)
+ self.assertEqual(expected, redacted)
file_stat = os.stat(json_file)
self.assertEqual(0o644, stat.S_IMODE(file_stat.st_mode))
@@ -574,6 +593,12 @@ class TestDataSource(CiTestCase):
(
"merged_cfg",
"security-credentials",
+ "userdata",
+ "user-data",
+ "user_data",
+ "vendordata",
+ "vendor-data",
+ "ds/vendor_data",
),
datasource.sensitive_metadata_keys,
)
diff --git a/tests/unittests/test_stages.py b/tests/unittests/test_stages.py
index 15a7e973..a61f9df9 100644
--- a/tests/unittests/test_stages.py
+++ b/tests/unittests/test_stages.py
@@ -606,19 +606,23 @@ class TestInit_InitializeFilesystem:
# Assert we create it 0o640 by default if it doesn't already exist
assert 0o640 == stat.S_IMODE(log_file.stat().mode)
- def test_existing_file_permissions_are_not_modified(self, init, tmpdir):
- """If the log file already exists, we should not modify its permissions
+ def test_existing_file_permissions(self, init, tmpdir):
+ """Test file permissions are set as expected.
+
+ CIS Hardening requires 640 permissions. These permissions are
+ currently hardcoded on every boot, but if there's ever a reason
+ to change this, we need to then ensure that they
+ are *not* set every boot.
See https://bugs.launchpad.net/cloud-init/+bug/1900837.
"""
- # Use a mode that will never be made the default so this test will
- # always be valid
- mode = 0o606
log_file = tmpdir.join("cloud-init.log")
log_file.ensure()
- log_file.chmod(mode)
+ # Use a mode that will never be made the default so this test will
+ # always be valid
+ log_file.chmod(0o606)
init._cfg = {"def_log_file": str(log_file)}
init._initialize_filesystem()
- assert mode == stat.S_IMODE(log_file.stat().mode)
+ assert 0o640 == stat.S_IMODE(log_file.stat().mode)

View File

@ -0,0 +1,206 @@
From 6bf6ceab79df97eb1c90b4df61f654bc0b2f598c Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 2 May 2023 20:35:45 +0530
Subject: [PATCH] Do not generate dsa and ed25519 key types when crypto FIPS
mode is enabled (#2142)
DSA and ED25519 key types are not supported when FIPS is enabled in crypto.
Check if FIPS has been enabled on the system and if so, do not generate those
key types. Presently the check is only available on Linux systems.
LP: 2017761
RHBZ: 2187164
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit c53f04aeb2acf9526a2ebf3d3320f149ac46caa6)
---
cloudinit/config/cc_ssh.py | 21 +++++++++++++++-
cloudinit/util.py | 12 +++++++++
tests/unittests/config/test_cc_ssh.py | 36 +++++++++++++++++++++------
tests/unittests/test_util.py | 25 +++++++++++++++++++
4 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/cloudinit/config/cc_ssh.py b/cloudinit/config/cc_ssh.py
index 1ec889f3..5578654a 100644
--- a/cloudinit/config/cc_ssh.py
+++ b/cloudinit/config/cc_ssh.py
@@ -172,6 +172,8 @@ meta: MetaSchema = {
__doc__ = get_meta_doc(meta)
GENERATE_KEY_NAMES = ["rsa", "dsa", "ecdsa", "ed25519"]
+FIPS_UNSUPPORTED_KEY_NAMES = ["dsa", "ed25519"]
+
pattern_unsupported_config_keys = re.compile(
"^(ecdsa-sk|ed25519-sk)_(private|public|certificate)$"
)
@@ -259,9 +261,26 @@ def handle(
genkeys = util.get_cfg_option_list(
cfg, "ssh_genkeytypes", GENERATE_KEY_NAMES
)
+ # remove keys that are not supported in fips mode if its enabled
+ key_names = (
+ genkeys
+ if not util.fips_enabled()
+ else [
+ names
+ for names in genkeys
+ if names not in FIPS_UNSUPPORTED_KEY_NAMES
+ ]
+ )
+ skipped_keys = set(genkeys).difference(key_names)
+ if skipped_keys:
+ log.debug(
+ "skipping keys that are not supported in fips mode: %s",
+ ",".join(skipped_keys),
+ )
+
lang_c = os.environ.copy()
lang_c["LANG"] = "C"
- for keytype in genkeys:
+ for keytype in key_names:
keyfile = KEY_FILE_TPL % (keytype)
if os.path.exists(keyfile):
continue
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 8ba3e2b6..4a8e3d3b 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -1577,6 +1577,18 @@ def get_cmdline():
return _get_cmdline()
+def fips_enabled() -> bool:
+ fips_proc = "/proc/sys/crypto/fips_enabled"
+ try:
+ contents = load_file(fips_proc).strip()
+ return contents == "1"
+ except (IOError, OSError):
+ # for BSD systems and Linux systems where the proc entry is not
+ # available, we assume FIPS is disabled to retain the old behavior
+ # for now.
+ return False
+
+
def pipe_in_out(in_fh, out_fh, chunk_size=1024, chunk_cb=None):
bytes_piped = 0
while True:
diff --git a/tests/unittests/config/test_cc_ssh.py b/tests/unittests/config/test_cc_ssh.py
index 66368d0f..72941a95 100644
--- a/tests/unittests/config/test_cc_ssh.py
+++ b/tests/unittests/config/test_cc_ssh.py
@@ -101,11 +101,16 @@ class TestHandleSsh:
expected_calls = [mock.call(set(keys), user)] + expected_calls
assert expected_calls == m_setup_keys.call_args_list
+ @pytest.mark.parametrize("fips_enabled", (True, False))
@mock.patch(MODPATH + "glob.glob")
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
@mock.patch(MODPATH + "os.path.exists")
- def test_handle_no_cfg(self, m_path_exists, m_nug, m_glob, m_setup_keys):
+ @mock.patch(MODPATH + "util.fips_enabled")
+ def test_handle_no_cfg(
+ self, m_fips, m_path_exists, m_nug, m_glob, m_setup_keys, fips_enabled
+ ):
"""Test handle with no config ignores generating existing keyfiles."""
+ m_fips.return_value = fips_enabled
cfg = {}
keys = ["key1"]
m_glob.return_value = [] # Return no matching keys to prevent removal
@@ -118,12 +123,22 @@ class TestHandleSsh:
options = ssh_util.DISABLE_USER_OPTS.replace("$USER", "NONE")
options = options.replace("$DISABLE_USER", "root")
m_glob.assert_called_once_with("/etc/ssh/ssh_host_*key*")
- assert [
- mock.call("/etc/ssh/ssh_host_rsa_key"),
- mock.call("/etc/ssh/ssh_host_dsa_key"),
- mock.call("/etc/ssh/ssh_host_ecdsa_key"),
- mock.call("/etc/ssh/ssh_host_ed25519_key"),
- ] in m_path_exists.call_args_list
+ m_fips.assert_called_once()
+
+ if not m_fips():
+ expected_calls = [
+ mock.call("/etc/ssh/ssh_host_rsa_key"),
+ mock.call("/etc/ssh/ssh_host_dsa_key"),
+ mock.call("/etc/ssh/ssh_host_ecdsa_key"),
+ mock.call("/etc/ssh/ssh_host_ed25519_key"),
+ ]
+ else:
+ # Enabled fips doesn't generate dsa or ed25519
+ expected_calls = [
+ mock.call("/etc/ssh/ssh_host_rsa_key"),
+ mock.call("/etc/ssh/ssh_host_ecdsa_key"),
+ ]
+ assert expected_calls in m_path_exists.call_args_list
assert [
mock.call(set(keys), "root", options=options)
] == m_setup_keys.call_args_list
@@ -131,8 +146,9 @@ class TestHandleSsh:
@mock.patch(MODPATH + "glob.glob")
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
@mock.patch(MODPATH + "os.path.exists")
+ @mock.patch(MODPATH + "util.fips_enabled", return_value=False)
def test_dont_allow_public_ssh_keys(
- self, m_path_exists, m_nug, m_glob, m_setup_keys
+ self, m_fips, m_path_exists, m_nug, m_glob, m_setup_keys
):
"""Test allow_public_ssh_keys=False ignores ssh public keys from
platform.
@@ -176,8 +192,10 @@ class TestHandleSsh:
@mock.patch(MODPATH + "glob.glob")
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
@mock.patch(MODPATH + "os.path.exists")
+ @mock.patch(MODPATH + "util.fips_enabled", return_value=False)
def test_handle_default_root(
self,
+ m_fips,
m_path_exists,
m_nug,
m_glob,
@@ -241,8 +259,10 @@ class TestHandleSsh:
@mock.patch(MODPATH + "glob.glob")
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
@mock.patch(MODPATH + "os.path.exists")
+ @mock.patch(MODPATH + "util.fips_enabled", return_value=False)
def test_handle_publish_hostkeys(
self,
+ m_fips,
m_path_exists,
m_nug,
m_glob,
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 07142a86..17182d06 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -1945,6 +1945,31 @@ class TestGetCmdline(helpers.TestCase):
self.assertEqual("abcd 123", ret)
+class TestFipsEnabled:
+ @pytest.mark.parametrize(
+ "fips_enabled_content,expected",
+ (
+ pytest.param(None, False, id="false_when_no_fips_enabled_file"),
+ pytest.param("0\n", False, id="false_when_fips_disabled"),
+ pytest.param("1\n", True, id="true_when_fips_enabled"),
+ pytest.param("1", True, id="true_when_fips_enabled_no_newline"),
+ ),
+ )
+ @mock.patch(M_PATH + "load_file")
+ def test_fips_enabled_based_on_proc_crypto(
+ self, load_file, fips_enabled_content, expected, tmpdir
+ ):
+ def fake_load_file(path):
+ assert path == "/proc/sys/crypto/fips_enabled"
+ if fips_enabled_content is None:
+ raise IOError("No file exists Bob")
+ return fips_enabled_content
+
+ load_file.side_effect = fake_load_file
+
+ assert expected is util.fips_enabled()
+
+
class TestLoadYaml(helpers.CiTestCase):
mydefault = "7b03a8ebace993d806255121073fed52"
with_logs = True

View File

@ -0,0 +1,93 @@
From 0b0632f6c084a8ce95b53cb5125dc0f4107e6968 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 4 May 2023 15:34:43 +0530
Subject: [PATCH] Revert "Manual revert "Use Network-Manager and Netplan as
default renderers for RHEL and Fedora (#1465)""
This reverts commit ecae81f98ce230266eb99671b74534a4ede660f0.
This is patch 1 of the two patches that re-enables NM renderer. This change
can be ignored while rebasing to latest upstream.
X-downstream-only: true
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/net/renderers.py | 1 +
config/cloud.cfg.tmpl | 3 +++
doc/rtd/reference/network-config.rst | 16 ++++++++++++++--
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/cloudinit/net/renderers.py b/cloudinit/net/renderers.py
index c92b9dcf..022ff938 100644
--- a/cloudinit/net/renderers.py
+++ b/cloudinit/net/renderers.py
@@ -28,6 +28,7 @@ DEFAULT_PRIORITY = [
"eni",
"sysconfig",
"netplan",
+ "network-manager",
"freebsd",
"netbsd",
"openbsd",
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 12f32c51..7238c102 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -381,6 +381,9 @@ system_info:
{% elif variant in ["dragonfly"] %}
network:
renderers: ['freebsd']
+{% elif variant in ["fedora"] or is_rhel %}
+ network:
+ renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
{% elif variant == "openmandriva" %}
network:
renderers: ['network-manager', 'networkd']
diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst
index bc52afa5..ea331f1c 100644
--- a/doc/rtd/reference/network-config.rst
+++ b/doc/rtd/reference/network-config.rst
@@ -176,6 +176,16 @@ this state, ``cloud-init`` delegates rendering of the configuration to
distro-supported formats. The following ``renderers`` are supported in
``cloud-init``:
+NetworkManager
+--------------
+
+`NetworkManager`_ is the standard Linux network configuration tool suite. It
+supports a wide range of networking setups. Configuration is typically stored
+in :file:`/etc/NetworkManager`.
+
+It is the default for a number of Linux distributions; notably Fedora,
+CentOS/RHEL, and their derivatives.
+
ENI
---
@@ -213,6 +223,7 @@ preference) is as follows:
- ENI
- Sysconfig
- Netplan
+- NetworkManager
- FreeBSD
- NetBSD
- OpenBSD
@@ -223,6 +234,7 @@ preference) is as follows:
- **ENI**: using ``ifup``, ``ifdown`` to manage device setup/teardown
- **Netplan**: using ``netplan apply`` to manage device setup/teardown
+- **NetworkManager**: using ``nmcli`` to manage device setup/teardown
- **Networkd**: using ``ip`` to manage device setup/teardown
When applying the policy, ``cloud-init`` checks if the current instance has the
@@ -232,8 +244,8 @@ supplying an updated configuration in cloud-config. ::
system_info:
network:
- renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
- activators: ['eni', 'netplan', 'networkd']
+ renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
+ activators: ['eni', 'netplan', 'network-manager', 'networkd']
Network configuration tools
===========================

View File

@ -0,0 +1,33 @@
From 0a2c6b6118ffaf29694b3a51aff3a33298419c50 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 15 May 2023 19:15:12 +0530
Subject: [PATCH] net/sysconfig: do not use the highest autoconnect priority
Using the highest priority is a very big hammer that we may not want to use. We
may want users to override the cloud init generated ifcfg files for custom
configuration of interfaces. If cloud init uses the highest priority, nothing
can beat it. Hence lower the priority to 120 allowing values from 121 to 999
to be used by users if they want to use a custom interface nm keyfile.
X-downstream-only: true
Suggested-by: thaller@redhat.com
fixes: c589da20eb92231 ("Setting highest autoconnect priority for network-scripts")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/net/sysconfig.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index b8786fb7..1fe82412 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -317,7 +317,7 @@ class Renderer(renderer.Renderer):
"ONBOOT": True,
"USERCTL": False,
"BOOTPROTO": "none",
- "AUTOCONNECT_PRIORITY": 999
+ "AUTOCONNECT_PRIORITY": 120,
},
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
}

View File

@ -0,0 +1,43 @@
From 603ad38bca7735eeb72217b4f169a4b4c42ac092 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 16 May 2023 16:08:21 +0530
Subject: [PATCH] net/sysconfig: cosmetic - fix tox formatting
recommended cloud-init code formatting was not enforced with an older downstream
only change. This change fixes the formatting issue so that tox -e do_format
does not complain. Changes are cosmetic.
X-downstream-only: true
fixes: b3b96bff187e9d ("Do not write NM_CONTROLLED=no in generated interface config files")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/net/sysconfig.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 1fe82412..fcce3e99 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -1025,15 +1025,15 @@ class Renderer(renderer.Renderer):
if sysconfig_path.endswith("network"):
util.ensure_dir(os.path.dirname(sysconfig_path))
netcfg = []
- for line in util.load_file(sysconfig_path, quiet=True).split('\n'):
- if 'cloud-init' in line:
+ for line in util.load_file(sysconfig_path, quiet=True).split("\n"):
+ if "cloud-init" in line:
break
- if not line.startswith(('NETWORKING=',
- 'IPV6_AUTOCONF=',
- 'NETWORKING_IPV6=')):
+ if not line.startswith(
+ ("NETWORKING=", "IPV6_AUTOCONF=", "NETWORKING_IPV6=")
+ ):
netcfg.append(line)
# Now generate the cloud-init portion of sysconfig/network
- netcfg.extend([_make_header(), 'NETWORKING=yes'])
+ netcfg.extend([_make_header(), "NETWORKING=yes"])
if network_state.use_ipv6:
netcfg.append("NETWORKING_IPV6=yes")
netcfg.append("IPV6_AUTOCONF=no")

View File

@ -0,0 +1,49 @@
From 58d7574bca2b00d05d090c180f1345a2408cc700 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 22 May 2023 21:30:01 +0530
Subject: [PATCH] nm: generate ipv6 stateful dhcp config at par with sysconfig
(#4115)
The sysconfig renderer sets the following in the ifcfg file for IPV6 stateful
DHCP configuration:
BOOTPROTO = "dhcp"
DHCPV6C = True
IPV6INIT = True
IPV6_AUTOCONF = False
This should result in
[ipv6]
method=dhcp
in the network manager generated keyfile as DHCPV6C is set and
IPV6_AUTOCONF is not set. Unfortunately the network manager renderer
deviates from this and generates:
[ipv6]
method=auto
in it's rendered keyfile. This change fixes this deviation and sets the
IPV6 dhcp stateful configuration in alignment with what is generated by the
sysconfig renderer.
RHBZ: 2207716
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit ea573ba6fc25fe49a6a1a322eeb5259b6238d78b)
---
cloudinit/net/network_manager.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 53763d15..744c0cbb 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -72,7 +72,7 @@ class NMConnection:
"dhcp6": "auto",
"ipv6_slaac": "auto",
"ipv6_dhcpv6-stateless": "auto",
- "ipv6_dhcpv6-stateful": "auto",
+ "ipv6_dhcpv6-stateful": "dhcp",
"dhcp4": "auto",
"dhcp": "auto",
}

View File

@ -0,0 +1,31 @@
From 018aa09f049791755dd746b533abb2464b08a92d Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 22 May 2023 21:33:53 +0530
Subject: [PATCH] network_manager: add a method for ipv6 static IP
configuration (#4127)
The static IP configuration for IPv6 in the method_map is missing for
network manager renderer. This is causing cloud-init to generate a keyfile with
IPv6 method as "auto" instead of "manual". This fixes this issue.
fixes: #4126
RHBZ: 2196284
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 5d440856cb6d2b4c908015fe4eb7227615c17c8b)
---
cloudinit/net/network_manager.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 744c0cbb..2752f52f 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -69,6 +69,7 @@ class NMConnection:
method_map = {
"static": "manual",
+ "static6": "manual",
"dhcp6": "auto",
"ipv6_slaac": "auto",
"ipv6_dhcpv6-stateless": "auto",

View File

@ -0,0 +1,62 @@
From 19adc5a0939fc1804b180333af5486e69d6af0ac Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 22 May 2023 22:06:28 +0530
Subject: [PATCH] net/sysconfig: enable sysconfig renderer if network manager
has ifcfg-rh plugin (#4132)
Some distributions like RHEL does not have ifup and ifdown
scripts that traditionally handled ifcfg-eth* files. Instead RHEL
uses network manager with ifcfg-rh plugin to handle ifcfg
scripts. Therefore, the sysconfig should check for the
existence of ifcfg-rh plugin in addition to checking for the
existence of ifup and ifdown scripts in order to determine if it
can handle ifcfg files. If either the plugin or ifup/ifdown scripts
are present, sysconfig renderer can be enabled.
fixes: #4131
RHBZ: 2194050
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit 009dbf85a72a9077b2267d377b2ff46639fb3def)
---
cloudinit/net/sysconfig.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index fcce3e99..f2c7c92c 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -1,6 +1,7 @@
# This file is part of cloud-init. See LICENSE file for license information.
import copy
+import glob
import io
import os
import re
@@ -1059,7 +1060,25 @@ def _supported_vlan_names(rdev, vid):
def available(target=None):
if not util.system_info()["variant"] in KNOWN_DISTROS:
return False
+ if available_sysconfig(target):
+ return True
+ if available_nm_ifcfg_rh(target):
+ return True
+ return False
+
+
+def available_nm_ifcfg_rh(target=None):
+ # The ifcfg-rh plugin of NetworkManager is installed.
+ # NetworkManager can handle the ifcfg files.
+ return glob.glob(
+ subp.target_path(
+ target,
+ "usr/lib*/NetworkManager/*/libnm-settings-plugin-ifcfg-rh.so",
+ )
+ )
+
+def available_sysconfig(target=None):
expected = ["ifup", "ifdown"]
search = ["/sbin", "/usr/sbin"]
for p in expected:

View File

@ -0,0 +1,401 @@
From f0cf9e52fd084c23f0552456e3b780b5c9c3313a Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 23 May 2023 20:38:31 +0530
Subject: [PATCH] network-manager: Set higher autoconnect priority for nm
keyfiles (#3671)
cloud init generated keyfiles by network manager renderer for network
interfaces can sometimes conflict with existing keyfiles that are left as an
artifact of an upgrade process or are old user generated keyfiles. When two
such keyfiles are present, the existing keyfile can take precedence over the
cloud init generated keyfile making the later ineffective. Removing the old
keyfile blindly by cloud init would also not be correct since there would be
no way to enforce a different interface configuration if one needs it.
This change adds an autoconnect-priority value for cloud init generated keyfile
so that the cloud init configuration takes precedence over the existing old
keyfile configuration in the default case. The priority values range from 0
to 999. We set a value of 120 so that it would be high enough in the default
case and result in cloud init keyfile to take precedence but not too high so
that if the user generated keyfile needs to take precedence, the user can do
so by using a higher value than the one used by cloud init key file, between
the values 121 and 999.
RHBZ: 2196231
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit f663e94ac50bc518e694cbd167fdab216fcff029)
---
cloudinit/net/network_manager.py | 1 +
tests/unittests/cmd/devel/test_net_convert.py | 1 +
.../cloud-init-encc000.2653.nmconnection | 1 +
.../cloud-init-encc000.nmconnection | 1 +
.../cloud-init-zz-all-en.nmconnection | 1 +
.../cloud-init-zz-all-eth.nmconnection | 1 +
tests/unittests/test_net.py | 36 +++++++++++++++++++
7 files changed, 42 insertions(+)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index 2752f52f..ca216928 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -43,6 +43,7 @@ class NMConnection:
self.config["connection"] = {
"id": f"cloud-init {con_id}",
"uuid": str(uuid.uuid5(CI_NM_UUID, con_id)),
+ "autoconnect-priority": "120",
}
# This is not actually used anywhere, but may be useful in future
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
index 100aa8de..71654750 100644
--- a/tests/unittests/cmd/devel/test_net_convert.py
+++ b/tests/unittests/cmd/devel/test_net_convert.py
@@ -74,6 +74,7 @@ SAMPLE_NETWORK_MANAGER_CONTENT = """\
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+autoconnect-priority=120
type=ethernet
interface-name=eth0
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection
index 80483d4f..f44485d2 100644
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection
@@ -3,6 +3,7 @@
[connection]
id=cloud-init encc000.2653
uuid=116aaf19-aabc-50ea-b480-e9aee18bda59
+autoconnect-priority=120
type=vlan
interface-name=encc000.2653
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection
index 3368388d..fbdfbc65 100644
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection
@@ -3,6 +3,7 @@
[connection]
id=cloud-init encc000
uuid=f869ebd3-f175-5747-bf02-d0d44d687248
+autoconnect-priority=120
type=ethernet
interface-name=encc000
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection
index 16120bc1..dce56c7d 100644
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection
@@ -3,6 +3,7 @@
[connection]
id=cloud-init zz-all-en
uuid=159daec9-cba3-5101-85e7-46d831857f43
+autoconnect-priority=120
type=ethernet
interface-name=zz-all-en
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection
index df44d546..ee436bf2 100644
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection
@@ -3,6 +3,7 @@
[connection]
id=cloud-init zz-all-eth
uuid=23a83d8a-d7db-5133-a77b-e68a6ac61ec9
+autoconnect-priority=120
type=ethernet
interface-name=zz-all-eth
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 0f523ff8..7abe61b9 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -631,6 +631,7 @@ dns = none
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+autoconnect-priority=120
type=ethernet
[user]
@@ -1118,6 +1119,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init eth1
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
+ autoconnect-priority=120
type=ethernet
[user]
@@ -1135,6 +1137,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init eth99
uuid=b1b88000-1f03-5360-8377-1a2205efffb4
+ autoconnect-priority=120
type=ethernet
[user]
@@ -1234,6 +1237,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -1364,6 +1368,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -1404,6 +1409,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -1504,6 +1510,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -1734,6 +1741,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -1845,6 +1853,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -1967,6 +1976,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -2043,6 +2053,7 @@ NETWORK_CONFIGS = {
[connection]
id=cloud-init iface0
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
+ autoconnect-priority=120
type=ethernet
interface-name=iface0
@@ -2507,6 +2518,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth3
uuid=b7e95dda-7746-5bf8-bf33-6e5f3c926790
+ autoconnect-priority=120
type=ethernet
slave-type=bridge
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
@@ -2526,6 +2538,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth5
uuid=5fda13c7-9942-5e90-a41b-1d043bd725dc
+ autoconnect-priority=120
type=ethernet
[user]
@@ -2547,6 +2560,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init ib0
uuid=11a1dda7-78b4-5529-beba-d9b5f549ad7b
+ autoconnect-priority=120
type=infiniband
[user]
@@ -2571,6 +2585,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init bond0.200
uuid=88984a9c-ff22-5233-9267-86315e0acaa7
+ autoconnect-priority=120
type=vlan
interface-name=bond0.200
@@ -2594,6 +2609,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+ autoconnect-priority=120
type=ethernet
[user]
@@ -2611,6 +2627,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth4
uuid=e27e4959-fb50-5580-b9a4-2073554627b9
+ autoconnect-priority=120
type=ethernet
slave-type=bridge
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
@@ -2630,6 +2647,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth1
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
+ autoconnect-priority=120
type=ethernet
slave-type=bond
master=54317911-f840-516b-a10d-82cb4c1f075c
@@ -2649,6 +2667,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init br0
uuid=dee46ce4-af7a-5e7c-aa08-b25533ae9213
+ autoconnect-priority=120
type=bridge
interface-name=br0
@@ -2680,6 +2699,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth0.101
uuid=b5acec5e-db80-5935-8b02-0d5619fc42bf
+ autoconnect-priority=120
type=vlan
interface-name=eth0.101
@@ -2708,6 +2728,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init bond0
uuid=54317911-f840-516b-a10d-82cb4c1f075c
+ autoconnect-priority=120
type=bond
interface-name=bond0
@@ -2732,6 +2753,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
[connection]
id=cloud-init eth2
uuid=5559a242-3421-5fdd-896e-9cb8313d5804
+ autoconnect-priority=120
type=ethernet
slave-type=bond
master=54317911-f840-516b-a10d-82cb4c1f075c
@@ -3257,6 +3279,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init bond0s0
uuid=09d0b5b9-67e7-5577-a1af-74d1cf17a71e
+ autoconnect-priority=120
type=ethernet
slave-type=bond
master=54317911-f840-516b-a10d-82cb4c1f075c
@@ -3276,6 +3299,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init bond0s1
uuid=4d9aca96-b515-5630-ad83-d13daac7f9d0
+ autoconnect-priority=120
type=ethernet
slave-type=bond
master=54317911-f840-516b-a10d-82cb4c1f075c
@@ -3295,6 +3319,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init bond0
uuid=54317911-f840-516b-a10d-82cb4c1f075c
+ autoconnect-priority=120
type=bond
interface-name=bond0
@@ -3421,6 +3446,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init en0.99
uuid=f594e2ed-f107-51df-b225-1dc530a5356b
+ autoconnect-priority=120
type=vlan
interface-name=en0.99
@@ -3453,6 +3479,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init en0
uuid=e0ca478b-8d84-52ab-8fae-628482c629b5
+ autoconnect-priority=120
type=ethernet
[user]
@@ -3580,6 +3607,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init br0
uuid=dee46ce4-af7a-5e7c-aa08-b25533ae9213
+ autoconnect-priority=120
type=bridge
interface-name=br0
@@ -3604,6 +3632,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+ autoconnect-priority=120
type=ethernet
slave-type=bridge
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
@@ -3628,6 +3657,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init eth1
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
+ autoconnect-priority=120
type=ethernet
slave-type=bridge
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
@@ -3782,6 +3812,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+ autoconnect-priority=120
type=ethernet
[user]
@@ -3804,6 +3835,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init eth1
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
+ autoconnect-priority=120
type=ethernet
[user]
@@ -3826,6 +3858,7 @@ iface bond0 inet6 static
[connection]
id=cloud-init eth2
uuid=5559a242-3421-5fdd-896e-9cb8313d5804
+ autoconnect-priority=120
type=ethernet
[user]
@@ -5688,6 +5721,7 @@ class TestNetworkManagerRendering(CiTestCase):
[connection]
id=cloud-init eth1000
uuid=8c517500-0c95-5308-9c8a-3092eebc44eb
+ autoconnect-priority=120
type=ethernet
[user]
@@ -5742,6 +5776,7 @@ class TestNetworkManagerRendering(CiTestCase):
[connection]
id=cloud-init interface0
uuid=8b6862ed-dbd6-5830-93f7-a91451c13828
+ autoconnect-priority=120
type=ethernet
[user]
@@ -5778,6 +5813,7 @@ class TestNetworkManagerRendering(CiTestCase):
[connection]
id=cloud-init eth0
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
+ autoconnect-priority=120
type=ethernet
interface-name=eth0

View File

@ -0,0 +1,42 @@
From 5394e28e896e9d18db6d359190bfb58dcbdb2646 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 23 May 2023 21:15:30 +0530
Subject: [PATCH] Set default renderer as sysconfig for c9s/RHEL 9
Currently, network manager is disabled on c9s and RHEL 9 and therefore
sysconfig is used as the primary renderer for network configuration on those
distribution flavors. We do not want to change this for c9s or RHEL 9 even when
network-manager renderer is re-enabled. NM was re-enabled with the following
commit:
5822f72230a58d ("Revert "Revert "Add native NetworkManager support (#1224)""")
This change bumps up the priority for sysconfig renderer so that it is used as
the primary renderer on c9s/RHEL 9 and other downstream distributions derived
from them. For c10s or RHEL 10, we might revert this change so that
network-manager again becomes the primary renderer for those distributions.
X-downstream-only: true
fixes: 0b0632f6c0 ("Revert "Manual revert "Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)")
fixes: 7703aa98b89 ("Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)")
RHBZ:2209349
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
config/cloud.cfg.tmpl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 7238c102..22c6654c 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -383,7 +383,7 @@ system_info:
renderers: ['freebsd']
{% elif variant in ["fedora"] or is_rhel %}
network:
- renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
+ renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd']
{% elif variant == "openmandriva" %}
network:
renderers: ['network-manager', 'networkd']

View File

@ -0,0 +1,25 @@
From 86dd9b0e215a40e60a6c48401a9c04215e10cdea Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 8 Jun 2023 10:19:49 +0530
Subject: [PATCH] Revert "Set default renderer as sysconfig for c9s/RHEL 9"
This reverts commit 5394e28e896e9d18db6d359190bfb58dcbdb2646.
Revert this downstream-only patch and replace it with the upstream patch.
---
config/cloud.cfg.tmpl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 22c6654c..7238c102 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -383,7 +383,7 @@ system_info:
renderers: ['freebsd']
{% elif variant in ["fedora"] or is_rhel %}
network:
- renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd']
+ renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
{% elif variant == "openmandriva" %}
network:
renderers: ['network-manager', 'networkd']

View File

@ -0,0 +1,35 @@
From fd4f6d94e09ed97a4dd6aba3284d9156c16c483b Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 8 Jun 2023 03:29:13 +0530
Subject: [PATCH] Set default renderer as sysconfig for centos/rhel (#4165)
Currently, network manager is disabled on c9s and therefore sysconfig is used as the primary renderer for network configuration. We do not want to change this for c9s even when network-manager renderer is re-enabled as it would mean a big behaviour change for cloud-init in the centos 9 stream.
This change bumps up the priority for sysconfig renderer so that it is used as the primary renderer on c9s and other downstream distributions derived from it. In the next major centos stream release, we may use network manager as the default renderer and make changes accordingly.
RHBZ: 2209349
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit a1f375095bd0ac8628c4fdc79538dc177bb9ff99)
---
config/cloud.cfg.tmpl | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 7238c102..020340f9 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -381,9 +381,12 @@ system_info:
{% elif variant in ["dragonfly"] %}
network:
renderers: ['freebsd']
-{% elif variant in ["fedora"] or is_rhel %}
+{% elif variant in ["fedora"] %}
network:
renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
+{% elif is_rhel %}
+ network:
+ renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd' ]
{% elif variant == "openmandriva" %}
network:
renderers: ['network-manager', 'networkd']

View File

@ -0,0 +1,509 @@
From 908387bc0a73ae3431c0ad90f83e6a4a4e902edb Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 23 Jun 2023 15:47:09 +0530
Subject: [PATCH] test fixes: update tests to reflect AUTOCONNECT_PRIORITY
setting
X-downstream-only: true
fixes: 0a2c6b6118ff ("net/sysconfig: do not use the highest autoconnect priority")
fixes: c589da20eb92 ("Setting highest autoconnect priority for network-scripts")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
tests/unittests/cmd/devel/test_net_convert.py | 1 +
tests/unittests/distros/test_netconfig.py | 8 +++
tests/unittests/test_net.py | 51 +++++++++++++++++++
3 files changed, 60 insertions(+)
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
index 71654750..43e879f7 100644
--- a/tests/unittests/cmd/devel/test_net_convert.py
+++ b/tests/unittests/cmd/devel/test_net_convert.py
@@ -60,6 +60,7 @@ DHCP=ipv4
SAMPLE_SYSCONFIG_CONTENT = """\
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth0
NM_CONTROLLED=no
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index b1c89ce3..eaf723c8 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -717,6 +717,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -731,6 +732,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("eth1"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1
NM_CONTROLLED=no
@@ -756,6 +758,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -772,6 +775,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("eth1"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1
NM_CONTROLLED=no
@@ -816,6 +820,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
HWADDR=00:16:3e:60:7c:df
@@ -829,6 +834,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("infra0"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=infra0
IPADDR=10.0.1.2
@@ -865,6 +871,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
expected_cfgs = {
self.ifcfg_path("eth0"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
IPADDR=192.10.1.2
@@ -877,6 +884,7 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
),
self.ifcfg_path("eth0.1001"): dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0.1001
IPADDR=10.0.1.2
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 7abe61b9..1261840b 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -578,6 +578,7 @@ dns = none
"""
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -740,6 +741,7 @@ dns = none
"""
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -897,6 +899,7 @@ dns = none
"""
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -1085,6 +1088,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-eth1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth1
HWADDR=cf:d6:af:48:e8:80
@@ -1094,6 +1098,7 @@ NETWORK_CONFIGS = {
),
"ifcfg-eth99": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEFROUTE=yes
DEVICE=eth99
@@ -1344,6 +1349,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
IPADDR=192.168.14.2
@@ -1490,6 +1496,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1580,6 +1587,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1656,6 +1664,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1721,6 +1730,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
IPV6_AUTOCONF=yes
@@ -1774,6 +1784,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
IPV6ADDR=2001:1::1/64
@@ -1831,6 +1842,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=iface0
DHCPV6C=yes
@@ -1913,6 +1925,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=iface0
DHCPV6C=yes
@@ -1959,6 +1972,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=iface0
NM_CONTROLLED=no
@@ -2035,6 +2049,7 @@ NETWORK_CONFIGS = {
"expected_sysconfig_rhel": {
"ifcfg-iface0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=iface0
ETHTOOL_OPTS="wol g"
@@ -2371,6 +2386,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
"expected_sysconfig_rhel": {
"ifcfg-bond0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup """
"""xmit_hash_policy=layer3+4 """
@@ -2388,6 +2404,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-bond0.200": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=bond0.200
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2399,6 +2416,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
"ifcfg-br0": textwrap.dedent(
"""\
AGEING=250
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=br0
@@ -2418,6 +2436,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
HWADDR=c0:d6:9f:2c:e8:80
@@ -2427,6 +2446,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth0.101": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0.101
@@ -2446,6 +2466,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth1
HWADDR=aa:d6:9f:2c:e8:80
@@ -2457,6 +2478,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth2": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth2
HWADDR=c0:bb:9f:2c:e8:80
@@ -2468,6 +2490,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth3": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth3
@@ -2478,6 +2501,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth4": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth4
@@ -2488,6 +2512,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-eth5": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth5
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -2498,6 +2523,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
),
"ifcfg-ib0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=ib0
HWADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1
@@ -3203,6 +3229,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-bond0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BONDING_OPTS="mode=active-backup xmit_hash_policy=layer3+4 """
"""miimon=100 num_grat_arp=5 """
@@ -3233,6 +3260,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=bond0s0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3260,6 +3288,7 @@ iface bond0 inet6 static
),
"ifcfg-bond0s1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=bond0s1
HWADDR=aa:bb:cc:dd:e8:01
@@ -3409,6 +3438,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-en0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=en0
HWADDR=aa:bb:cc:dd:e8:00
@@ -3418,6 +3448,7 @@ iface bond0 inet6 static
),
"ifcfg-en0.99": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=en0.99
@@ -3555,6 +3586,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-br0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=br0
IPADDR=192.168.2.2
@@ -3568,6 +3600,7 @@ iface bond0 inet6 static
),
"ifcfg-eth0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth0
@@ -3584,6 +3617,7 @@ iface bond0 inet6 static
),
"ifcfg-eth1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
BRIDGE=br0
DEVICE=eth1
@@ -3772,6 +3806,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
HWADDR=52:54:00:12:34:00
@@ -3784,6 +3819,7 @@ iface bond0 inet6 static
),
"ifcfg-eth1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth1
HWADDR=52:54:00:12:34:aa
@@ -3795,6 +3831,7 @@ iface bond0 inet6 static
),
"ifcfg-eth2": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth2
HWADDR=52:54:00:12:34:ff
@@ -3879,6 +3916,7 @@ iface bond0 inet6 static
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
@@ -4474,6 +4512,7 @@ class TestRhelSysConfigRendering(CiTestCase):
expected_content = """
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1000
HWADDR=07-1c-c6-75-a4-be
@@ -4681,6 +4720,7 @@ USERCTL=no
expected = """\
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=interface0
@@ -4710,6 +4750,7 @@ USERCTL=no
expected_i1 = """\
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0
@@ -4727,6 +4768,7 @@ USERCTL=no
expected_i2 = """\
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1
DHCLIENT_SET_DEFAULT_ROUTE=no
@@ -4755,6 +4797,7 @@ USERCTL=no
expected = """\
# Created by cloud-init on instance boot automatically, do not edit.
#
+AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth0
ONBOOT=yes
@@ -4968,6 +5011,7 @@ USERCTL=no
"expected_sysconfig": {
"ifcfg-ens3": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=ens3
@@ -5013,6 +5057,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eno1
NM_CONTROLLED=no
@@ -5023,6 +5068,7 @@ USERCTL=no
),
"ifcfg-eno1.1000": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eno1.1000
IPADDR=192.6.1.9
@@ -5056,6 +5102,7 @@ USERCTL=no
expected = {
"ifcfg-bond0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BONDING_SLAVE0=enp0s0
BONDING_SLAVE1=enp0s1
@@ -5072,6 +5119,7 @@ USERCTL=no
),
"ifcfg-enp0s0": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BOOTPROTO=none
DEVICE=enp0s0
@@ -5085,6 +5133,7 @@ USERCTL=no
),
"ifcfg-enp0s1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BONDING_MASTER=yes
BOOTPROTO=none
DEVICE=enp0s1
@@ -5116,6 +5165,7 @@ USERCTL=no
expected = {
"ifcfg-eno1": textwrap.dedent(
"""\
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
@@ -5195,6 +5245,7 @@ USERCTL=no
"""\
# Created by cloud-init on instance boot automatically, do not edit.
#
+ AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEFROUTE=yes
DEVICE=eth0

View File

@ -0,0 +1,283 @@
From 9eb7ef217eb03131904fb6e0c692130126334f52 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 23 Jun 2023 16:54:24 +0530
Subject: [PATCH] test fixes: remove NM_CONTROLLED=no from tests
X-downstream-only: true
fixes: b3b96bff187e9 ("Do not write NM_CONTROLLED=no in generated interface config files")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
tests/unittests/cmd/devel/test_net_convert.py | 1 -
tests/unittests/distros/test_netconfig.py | 8 -------
tests/unittests/test_net.py | 23 -------------------
3 files changed, 32 deletions(-)
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
index 43e879f7..082e9656 100644
--- a/tests/unittests/cmd/devel/test_net_convert.py
+++ b/tests/unittests/cmd/devel/test_net_convert.py
@@ -63,7 +63,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
index eaf723c8..7ac8182a 100644
--- a/tests/unittests/distros/test_netconfig.py
+++ b/tests/unittests/distros/test_netconfig.py
@@ -724,7 +724,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
GATEWAY=192.168.1.254
IPADDR=192.168.1.5
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -735,7 +734,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -767,7 +765,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
IPV6_AUTOCONF=no
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -778,7 +775,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=eth1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -826,7 +822,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
HWADDR=00:16:3e:60:7c:df
IPADDR=192.10.1.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -839,7 +834,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=infra0
IPADDR=10.0.1.2
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
@@ -876,7 +870,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=eth0
IPADDR=192.10.1.2
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -889,7 +882,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
DEVICE=eth0.1001
IPADDR=10.0.1.2
NETMASK=255.255.0.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eth0
USERCTL=no
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 1261840b..fd656a57 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -1502,7 +1502,6 @@ NETWORK_CONFIGS = {
DHCPV6C=yes
IPV6INIT=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1594,7 +1593,6 @@ NETWORK_CONFIGS = {
IPV6INIT=yes
IPV6_FORCE_ACCEPT_RA=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1671,7 +1669,6 @@ NETWORK_CONFIGS = {
IPV6INIT=yes
IPV6_FORCE_ACCEPT_RA=no
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1736,7 +1733,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=yes
IPV6INIT=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1792,7 +1788,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1850,7 +1845,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=yes
IPV6INIT=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1933,7 +1927,6 @@ NETWORK_CONFIGS = {
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=yes
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -1975,7 +1968,6 @@ NETWORK_CONFIGS = {
AUTOCONNECT_PRIORITY=120
BOOTPROTO=dhcp
DEVICE=iface0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2053,7 +2045,6 @@ NETWORK_CONFIGS = {
BOOTPROTO=dhcp
DEVICE=iface0
ETHTOOL_OPTS="wol g"
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -2530,7 +2521,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
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=InfiniBand
USERCTL=no"""
@@ -3609,7 +3599,6 @@ iface bond0 inet6 static
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -3626,7 +3615,6 @@ iface bond0 inet6 static
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_FORCE_ACCEPT_RA=no
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -3920,7 +3908,6 @@ iface bond0 inet6 static
BOOTPROTO=none
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
@@ -4759,7 +4746,6 @@ HWADDR=fa:16:3e:25:b4:59
IPADDR=51.68.89.122
MTU=1500
NETMASK=255.255.240.0
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -4774,7 +4760,6 @@ DEVICE=eth1
DHCLIENT_SET_DEFAULT_ROUTE=no
HWADDR=fa:16:3e:b1:ca:29
MTU=9000
-NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5027,7 +5012,6 @@ USERCTL=no
IPV6_FORCE_ACCEPT_RA=no
IPV6_DEFAULTGW=2001:db8::1
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5060,7 +5044,6 @@ USERCTL=no
AUTOCONNECT_PRIORITY=120
BOOTPROTO=none
DEVICE=eno1
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5074,7 +5057,6 @@ USERCTL=no
IPADDR=192.6.1.9
MTU=1495
NETMASK=255.255.255.0
- NM_CONTROLLED=no
ONBOOT=yes
PHYSDEV=eno1
USERCTL=no
@@ -5111,7 +5093,6 @@ USERCTL=no
IPADDR=10.101.8.65
MTU=1334
NETMASK=255.255.255.192
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bond
USERCTL=no
@@ -5124,7 +5105,6 @@ USERCTL=no
BOOTPROTO=none
DEVICE=enp0s0
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Bond
@@ -5138,7 +5118,6 @@ USERCTL=no
BOOTPROTO=none
DEVICE=enp0s1
MASTER=bond0
- NM_CONTROLLED=no
ONBOOT=yes
SLAVE=yes
TYPE=Bond
@@ -5170,7 +5149,6 @@ USERCTL=no
DEVICE=eno1
HWADDR=07-1c-c6-75-a4-be
METRIC=100
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
@@ -5262,7 +5240,6 @@ USERCTL=no
IPV6_FORCE_ACCEPT_RA=no
MTU=1400
NETMASK=255.255.248.0
- NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no

View File

@ -0,0 +1,58 @@
From d39cd4de3ce41b1a1727185f2e57ec27190c23cb Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 4 Jul 2023 13:58:27 +0530
Subject: [PATCH] Revert "limit permissions on def_log_file"
This reverts commit dfff374f66904e84fb07ca157ba010fac6b5f1de.
This commit seems useless and does not effectively change permission of the
log file. Remove it.
---
cloudinit/settings.py | 1 -
cloudinit/stages.py | 1 -
doc/examples/cloud-config.txt | 4 ----
3 files changed, 6 deletions(-)
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index 3d541141..edbb217d 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -52,7 +52,6 @@ CFG_BUILTIN = {
"None",
],
"def_log_file": "/var/log/cloud-init.log",
- "def_log_file_mode": 0o600,
"log_cfgs": [],
"mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
"syslog_fix_perms": [],
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 1326d205..21f30a1f 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -202,7 +202,6 @@ class Init:
def _initialize_filesystem(self):
util.ensure_dirs(self._initial_subdirs())
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
- log_file_mode = util.get_cfg_option_int(self.cfg, "def_log_file_mode")
if log_file:
# At this point the log file should have already been created
# in the setupLogging function of log.py
diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
index b6d16c9c..15d788f3 100644
--- a/doc/examples/cloud-config.txt
+++ b/doc/examples/cloud-config.txt
@@ -383,14 +383,10 @@ timezone: US/Eastern
# if syslog_fix_perms is a list, it will iterate through and use the
# first pair that does not raise error.
#
-# 'def_log_file' will be created with mode 'def_log_file_mode', which
-# is specified as a numeric value and defaults to 0600.
-#
# the default values are '/var/log/cloud-init.log' and 'syslog:adm'
# the value of 'def_log_file' should match what is configured in logging
# if either is empty, then no change of ownership will be done
def_log_file: /var/log/my-logging-file.log
-def_log_file_mode: 0600
syslog_fix_perms: syslog:root
# you can set passwords for a user or multiple users

View File

@ -0,0 +1,43 @@
From f1ccdbdb6c662ce67b4af74e0433a59f099d784a Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 23 Jun 2023 17:54:04 +0530
Subject: [PATCH] test fixes: changes to apply RHEL specific config settings to
tests
X-downstream-only: true
fixes: c4d66915520554adedff9b ("Add initial redhat changes")
fixes: dfff374f66904e84fb07ca ("limit permissions on def_log_file")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
tests/unittests/cmd/test_main.py | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
index e9ad0bb8..5d61aa2c 100644
--- a/tests/unittests/cmd/test_main.py
+++ b/tests/unittests/cmd/test_main.py
@@ -119,14 +119,17 @@ class TestMain(FilesystemMockingTestCase):
{
"def_log_file": "/var/log/cloud-init.log",
"log_cfgs": [],
- "syslog_fix_perms": [
- "syslog:adm",
- "root:adm",
- "root:wheel",
- "root:root",
- ],
"vendor_data": {"enabled": True, "prefix": []},
"vendor_data2": {"enabled": True, "prefix": []},
+ "syslog_fix_perms": [],
+ "mount_default_fields": [
+ None,
+ None,
+ "auto",
+ "defaults,nofail",
+ "0",
+ "2",
+ ],
}
)
updated_cfg.pop("system_info")

View File

@ -0,0 +1,90 @@
From 7a530e186e791858bf70accd2fab80dd9b43ee7e Mon Sep 17 00:00:00 2001
From: Robert Schweikert <rjschwei@suse.com>
Date: Thu, 23 Feb 2023 16:43:56 -0500
Subject: [PATCH] Enable SUSE based distros for ca handling (#2036)
CA handling in the configuration module was previously not supported
for SUSE based distros. Enable this functionality by creating the
necessary configuration settings.
Secondly update the test such that it does not bleed through to the
test system.
(cherry picked from commit 46fcd03187d70f405c748f7a6cfdb02ecb8c6ee7)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/config/cc_ca_certs.py | 31 +++++++++++++++++++++-
tests/unittests/config/test_cc_ca_certs.py | 2 ++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
index 169b0e18..51b8577c 100644
--- a/cloudinit/config/cc_ca_certs.py
+++ b/cloudinit/config/cc_ca_certs.py
@@ -32,8 +32,25 @@ DISTRO_OVERRIDES = {
"ca_cert_config": None,
"ca_cert_update_cmd": ["update-ca-trust"],
},
+ "opensuse": {
+ "ca_cert_path": "/etc/pki/trust/",
+ "ca_cert_local_path": "/usr/share/pki/trust/",
+ "ca_cert_filename": "anchors/cloud-init-ca-cert-{cert_index}.crt",
+ "ca_cert_config": None,
+ "ca_cert_update_cmd": ["update-ca-certificates"],
+ },
}
+for distro in (
+ "opensuse-microos",
+ "opensuse-tumbleweed",
+ "opensuse-leap",
+ "sle_hpc",
+ "sle-micro",
+ "sles",
+):
+ DISTRO_OVERRIDES[distro] = DISTRO_OVERRIDES["opensuse"]
+
MODULE_DESCRIPTION = """\
This module adds CA certificates to the system's CA store and updates any
related files using the appropriate OS-specific utility. The default CA
@@ -48,7 +65,19 @@ configuration option ``remove_defaults``.
Alpine Linux requires the ca-certificates package to be installed in
order to provide the ``update-ca-certificates`` command.
"""
-distros = ["alpine", "debian", "rhel", "ubuntu"]
+distros = [
+ "alpine",
+ "debian",
+ "rhel",
+ "opensuse",
+ "opensuse-microos",
+ "opensuse-tumbleweed",
+ "opensuse-leap",
+ "sle_hpc",
+ "sle-micro",
+ "sles",
+ "ubuntu",
+]
meta: MetaSchema = {
"id": "cc_ca_certs",
diff --git a/tests/unittests/config/test_cc_ca_certs.py b/tests/unittests/config/test_cc_ca_certs.py
index 19e5d422..6db17485 100644
--- a/tests/unittests/config/test_cc_ca_certs.py
+++ b/tests/unittests/config/test_cc_ca_certs.py
@@ -311,6 +311,7 @@ class TestRemoveDefaultCaCerts(TestCase):
"cloud_dir": tmpdir,
}
)
+ self.add_patch("cloudinit.config.cc_ca_certs.os.stat", "m_stat")
def test_commands(self):
ca_certs_content = "# line1\nline2\nline3\n"
@@ -318,6 +319,7 @@ class TestRemoveDefaultCaCerts(TestCase):
"# line1\n# Modified by cloud-init to deselect certs due to"
" user-data\n!line2\n!line3\n"
)
+ self.m_stat.return_value.st_size = 1
for distro_name in cc_ca_certs.distros:
conf = cc_ca_certs._distro_ca_certs_configs(distro_name)

View File

@ -0,0 +1,85 @@
From add770c442088c0915bdefad2a7438f9a38596c5 Mon Sep 17 00:00:00 2001
From: Shreenidhi Shedi <53473811+sshedi@users.noreply.github.com>
Date: Fri, 17 Mar 2023 03:01:22 +0530
Subject: [PATCH] Handle non existent ca-cert-config situation (#2073)
Currently if a cert file doesn't exist, cc_ca_certs module crashes
This fix makes it possible to handle it gracefully.
Also, out_lines variable may not be available if os.stat returns 0.
This issue is also taken care of.
Added tests for the same.
(cherry picked from commit 3634678465e7b8f8608bcb9a1f5773ae7837cbe9)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/config/cc_ca_certs.py | 19 +++++++++++++------
tests/unittests/config/test_cc_ca_certs.py | 12 ++++++++++++
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
index 51b8577c..4dc08681 100644
--- a/cloudinit/config/cc_ca_certs.py
+++ b/cloudinit/config/cc_ca_certs.py
@@ -177,14 +177,20 @@ def disable_system_ca_certs(distro_cfg):
@param distro_cfg: A hash providing _distro_ca_certs_configs function.
"""
- if distro_cfg["ca_cert_config"] is None:
+
+ ca_cert_cfg_fn = distro_cfg["ca_cert_config"]
+
+ if not ca_cert_cfg_fn or not os.path.exists(ca_cert_cfg_fn):
return
+
header_comment = (
"# Modified by cloud-init to deselect certs due to user-data"
)
+
added_header = False
- if os.stat(distro_cfg["ca_cert_config"]).st_size != 0:
- orig = util.load_file(distro_cfg["ca_cert_config"])
+
+ if os.stat(ca_cert_cfg_fn).st_size:
+ orig = util.load_file(ca_cert_cfg_fn)
out_lines = []
for line in orig.splitlines():
if line == header_comment:
@@ -197,9 +203,10 @@ def disable_system_ca_certs(distro_cfg):
out_lines.append(header_comment)
added_header = True
out_lines.append("!" + line)
- util.write_file(
- distro_cfg["ca_cert_config"], "\n".join(out_lines) + "\n", omode="wb"
- )
+
+ util.write_file(
+ ca_cert_cfg_fn, "\n".join(out_lines) + "\n", omode="wb"
+ )
def remove_default_ca_certs(distro_cfg):
diff --git a/tests/unittests/config/test_cc_ca_certs.py b/tests/unittests/config/test_cc_ca_certs.py
index 6db17485..5f1894e7 100644
--- a/tests/unittests/config/test_cc_ca_certs.py
+++ b/tests/unittests/config/test_cc_ca_certs.py
@@ -365,6 +365,18 @@ class TestRemoveDefaultCaCerts(TestCase):
else:
assert mock_subp.call_count == 0
+ def test_non_existent_cert_cfg(self):
+ self.m_stat.return_value.st_size = 0
+
+ for distro_name in cc_ca_certs.distros:
+ conf = cc_ca_certs._distro_ca_certs_configs(distro_name)
+ with ExitStack() as mocks:
+ mocks.enter_context(
+ mock.patch.object(util, "delete_dir_contents")
+ )
+ mocks.enter_context(mock.patch.object(subp, "subp"))
+ cc_ca_certs.disable_default_ca_certs(distro_name, conf)
+
class TestCACertsSchema:
"""Directly test schema rather than through handle."""

View File

@ -0,0 +1,172 @@
From 1cecfe4bc3d7e4806d1890615a119e478decd5fd Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 20 Jul 2023 23:56:01 +0530
Subject: [PATCH] logging: keep current file mode of log file if its stricter
than the new mode (#4250)
By default, the cloud init log file is created with mode 0o644 with
`preserve_mode` parameter of `write_file()` set to False. This means that when
an existing log file is found, its mode will be unconditionally reset to the
mode 0o644. It is possible that this might cause the change of the mode of the
log file from the current more stricter mode to a less strict mode
(when the new mode 0o644 is less strict than the existing mode of the file).
In order to mitigate the above issue, check the current mode of the log file
and if the current mode is stricter than the default new mode 0o644, then
preserve the current mode of the file.
Fixes GH-4243
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit a0e4ec15a1adffabd1c539879514eae4807c834c)
Conflicts:
tests/unittests/test_util.py
---
cloudinit/stages.py | 15 ++++++++++++++-
cloudinit/util.py | 23 +++++++++++++++++++++++
tests/unittests/test_stages.py | 23 ++++++++++++++++-------
tests/unittests/test_util.py | 24 ++++++++++++++++++++++++
4 files changed, 77 insertions(+), 8 deletions(-)
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 21f30a1f..979179af 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -200,12 +200,25 @@ class Init:
self._initialize_filesystem()
def _initialize_filesystem(self):
+ mode = 0o640
+ fmode = None
+
util.ensure_dirs(self._initial_subdirs())
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
if log_file:
# At this point the log file should have already been created
# in the setupLogging function of log.py
- util.ensure_file(log_file, mode=0o640, preserve_mode=False)
+
+ try:
+ fmode = util.get_permissions(log_file)
+ except OSError:
+ pass
+
+ # if existing file mode fmode is stricter, do not change it.
+ if fmode and util.compare_permission(fmode, mode) < 0:
+ mode = fmode
+
+ util.ensure_file(log_file, mode, preserve_mode=False)
perms = self.cfg.get("syslog_fix_perms")
if not perms:
perms = {}
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 4a8e3d3b..af617e73 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -2099,6 +2099,29 @@ def safe_int(possible_int):
return None
+def compare_permission(mode1, mode2):
+ """Compare two file modes in octal.
+
+ If mode1 is less restrictive than mode2 return 1
+ If mode1 is more restrictive than mode2 return -1
+ If mode1 is same as mode2, return 0
+
+ The comparison starts from the permission of the
+ set of users in "others" and then works up to the
+ permission of "user" set.
+ """
+ # Convert modes to octal and reverse the last 3 digits
+ # so 0o640 would be become 0o046
+ mode1_oct = oct(mode1)[2:].rjust(3, "0")
+ mode2_oct = oct(mode2)[2:].rjust(3, "0")
+ m1 = int(mode1_oct[:-3] + mode1_oct[-3:][::-1], 8)
+ m2 = int(mode2_oct[:-3] + mode2_oct[-3:][::-1], 8)
+
+ # Then do a traditional cmp()
+ # https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
+ return (m1 > m2) - (m1 < m2)
+
+
def chmod(path, mode):
real_mode = safe_int(mode)
if path and real_mode:
diff --git a/tests/unittests/test_stages.py b/tests/unittests/test_stages.py
index a61f9df9..831ea9f2 100644
--- a/tests/unittests/test_stages.py
+++ b/tests/unittests/test_stages.py
@@ -606,13 +606,22 @@ class TestInit_InitializeFilesystem:
# Assert we create it 0o640 by default if it doesn't already exist
assert 0o640 == stat.S_IMODE(log_file.stat().mode)
- def test_existing_file_permissions(self, init, tmpdir):
+ @pytest.mark.parametrize(
+ "set_perms,expected_perms",
+ [
+ (0o640, 0o640),
+ (0o606, 0o640),
+ (0o600, 0o600),
+ ],
+ )
+ def test_existing_file_permissions(
+ self, init, tmpdir, set_perms, expected_perms
+ ):
"""Test file permissions are set as expected.
- CIS Hardening requires 640 permissions. These permissions are
- currently hardcoded on every boot, but if there's ever a reason
- to change this, we need to then ensure that they
- are *not* set every boot.
+ CIS Hardening requires 640 permissions. If the file has looser
+ permissions, then hard code 640. If the file has tighter
+ permissions, then leave them as they are
See https://bugs.launchpad.net/cloud-init/+bug/1900837.
"""
@@ -620,9 +629,9 @@ class TestInit_InitializeFilesystem:
log_file.ensure()
# Use a mode that will never be made the default so this test will
# always be valid
- log_file.chmod(0o606)
+ log_file.chmod(set_perms)
init._cfg = {"def_log_file": str(log_file)}
init._initialize_filesystem()
- assert 0o640 == stat.S_IMODE(log_file.stat().mode)
+ assert expected_perms == stat.S_IMODE(log_file.stat().mode)
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 17182d06..289a4234 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -3051,3 +3051,27 @@ class TestVersion:
)
def test_from_str(self, str_ver, cls_ver):
assert util.Version.from_str(str_ver) == cls_ver
+
+
+class TestComparePermissions:
+ @pytest.mark.parametrize(
+ "perm1,perm2,expected",
+ [
+ (0o777, 0o777, 0),
+ (0o000, 0o000, 0),
+ (0o421, 0o421, 0),
+ (0o1640, 0o1640, 0),
+ (0o1407, 0o1600, 1),
+ (0o1600, 0o1407, -1),
+ (0o407, 0o600, 1),
+ (0o600, 0o407, -1),
+ (0o007, 0o700, 1),
+ (0o700, 0o007, -1),
+ (0o077, 0o100, 1),
+ (0o644, 0o640, 1),
+ (0o640, 0o600, 1),
+ (0o600, 0o400, 1),
+ ],
+ )
+ def test_compare_permissions(self, perm1, perm2, expected):
+ assert util.compare_permission(perm1, perm2) == expected

View File

@ -0,0 +1,62 @@
From 25ac8bb44af554a040f0dfa9b52e9241a33a4845 Mon Sep 17 00:00:00 2001
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
Date: Tue, 25 Jul 2023 05:21:46 +0800
Subject: [PATCH] DS VMware: modify a few log level (#4284)
Multiple ip addresses are common scenario for modern Linux, so set
debug log level for such cases.
(cherry picked from commit 4a6a9d3f6c8fe213c51f6c1336f1dd378bf4bdca)
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
cloudinit/sources/DataSourceVMware.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
index 07a80222..bc3b5a5f 100644
--- a/cloudinit/sources/DataSourceVMware.py
+++ b/cloudinit/sources/DataSourceVMware.py
@@ -1,6 +1,6 @@
# Cloud-Init DataSource for VMware
#
-# Copyright (c) 2018-2022 VMware, Inc. All Rights Reserved.
+# Copyright (c) 2018-2023 VMware, Inc. All Rights Reserved.
#
# Authors: Anish Swaminathan <anishs@vmware.com>
# Andrew Kutz <akutz@vmware.com>
@@ -719,7 +719,7 @@ def get_default_ip_addrs():
af_inet4 = addr4_fams.get(netifaces.AF_INET)
if af_inet4:
if len(af_inet4) > 1:
- LOG.warning(
+ LOG.debug(
"device %s has more than one ipv4 address: %s",
dev4,
af_inet4,
@@ -737,7 +737,7 @@ def get_default_ip_addrs():
af_inet6 = addr6_fams.get(netifaces.AF_INET6)
if af_inet6:
if len(af_inet6) > 1:
- LOG.warning(
+ LOG.debug(
"device %s has more than one ipv6 address: %s",
dev6,
af_inet6,
@@ -752,7 +752,7 @@ def get_default_ip_addrs():
af_inet6 = addr4_fams.get(netifaces.AF_INET6)
if af_inet6:
if len(af_inet6) > 1:
- LOG.warning(
+ LOG.debug(
"device %s has more than one ipv6 address: %s",
dev4,
af_inet6,
@@ -767,7 +767,7 @@ def get_default_ip_addrs():
af_inet4 = addr6_fams.get(netifaces.AF_INET)
if af_inet4:
if len(af_inet4) > 1:
- LOG.warning(
+ LOG.debug(
"device %s has more than one ipv4 address: %s",
dev6,
af_inet4,

View File

@ -0,0 +1,283 @@
From c720ab9703752535767691a31e4720e11674bb1f Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 4 Aug 2023 08:58:26 +0530
Subject: [PATCH] NM renderer: set default IPv6 addr-gen-mode for all
interfaces to eui64 (#4291)
By default, NetworkManager renderer in cloud-init does not set any specific
method for IPV6 addr-gen-mode in the keyfiles it writes. Hence, implicitly the
mode is set to `eui64` in the absence of any global addr-gen-mode option in
NetworkManager configuration.
Later when other interfaces get added via D-Bus API or by using nmcli commands
without explictly setting an addr-gen-mode, NM auto generates new profiles for
those interfaces with addr-gen-mode set to `stable-privacy`. This introduces
inconsistency of configurations between interfaces based on how they were
added. This can cause problems for the customers.
In this change, cloud-init overrides NetworkManager's preferred default of
`stable-privacy` to use EUI64 using a drop in NetworkManager configuration
file. This setting can be overriden by using global-connection-defaults
setting in /etc/NetworkManager/NetworkManager.conf file.
RHBZ: 2188388
Signed-off-by: Ani Sinha <anisinha@redhat.com>
(cherry picked from commit d41264cb4297a4b143a23f3677d33b81fbfc6e8e)
Conflicts:
tests/unittests/test_net.py
---
cloudinit/net/network_manager.py | 21 ++++++++
tests/unittests/test_net.py | 91 +++++++++++++++++++++++++-------
2 files changed, 94 insertions(+), 18 deletions(-)
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
index ca216928..8047f796 100644
--- a/cloudinit/net/network_manager.py
+++ b/cloudinit/net/network_manager.py
@@ -21,6 +21,15 @@ from cloudinit.net.network_state import NetworkState
NM_RUN_DIR = "/etc/NetworkManager"
NM_LIB_DIR = "/usr/lib/NetworkManager"
NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
+NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit.
+#
+[.config]
+ enable=nm-version-min:1.40
+[connection.30-cloud-init-ip6-addr-gen-mode]
+ # Select EUI64 to be used if the profile does not specify it.
+ ipv6.addr-gen-mode=0
+
+"""
LOG = logging.getLogger(__name__)
@@ -368,6 +377,12 @@ class Renderer(renderer.Renderer):
name = conn_filename(con_id, target)
util.write_file(name, conn.dump(), 0o600)
+ # Select EUI64 to be used by default by NM for creating the address
+ # for use with RFC4862 IPv6 Stateless Address Autoconfiguration.
+ util.write_file(
+ cloud_init_nm_conf_filename(target), NM_IPV6_ADDR_GEN_CONF, 0o600
+ )
+
def conn_filename(con_id, target=None):
target_con_dir = subp.target_path(target, NM_RUN_DIR)
@@ -375,6 +390,12 @@ def conn_filename(con_id, target=None):
return f"{target_con_dir}/system-connections/{con_file}"
+def cloud_init_nm_conf_filename(target=None):
+ target_con_dir = subp.target_path(target, NM_RUN_DIR)
+ conf_file = "30-cloud-init-ip6-addr-gen-mode.conf"
+ return f"{target_con_dir}/conf.d/{conf_file}"
+
+
def available(target=None):
# TODO: Move `uses_systemd` to a more appropriate location
# It is imported here to avoid circular import
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index fd656a57..d49da696 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -5679,9 +5679,25 @@ class TestNetworkManagerRendering(CiTestCase):
with_logs = True
scripts_dir = "/etc/NetworkManager/system-connections"
+ conf_dir = "/etc/NetworkManager/conf.d"
expected_name = "expected_network_manager"
+ expected_conf_d = {
+ "30-cloud-init-ip6-addr-gen-mode.conf": textwrap.dedent(
+ """\
+ # This is generated by cloud-init. Do not edit.
+ #
+ [.config]
+ enable=nm-version-min:1.40
+ [connection.30-cloud-init-ip6-addr-gen-mode]
+ # Select EUI64 to be used if the profile does not specify it.
+ ipv6.addr-gen-mode=0
+
+ """
+ ),
+ }
+
def _get_renderer(self):
return network_manager.Renderer()
@@ -5700,11 +5716,19 @@ class TestNetworkManagerRendering(CiTestCase):
renderer.render_network_state(ns, target=dir)
return dir2dict(dir)
- def _compare_files_to_expected(self, expected, found):
+ def _compare_files_to_expected(
+ self, expected_scripts, expected_conf, found
+ ):
orig_maxdiff = self.maxDiff
- expected_d = dict(
- (os.path.join(self.scripts_dir, k), v) for k, v in expected.items()
+ conf_d = dict(
+ (os.path.join(self.conf_dir, k), v)
+ for k, v in expected_conf.items()
+ )
+ scripts_d = dict(
+ (os.path.join(self.scripts_dir, k), v)
+ for k, v in expected_scripts.items()
)
+ expected_d = {**conf_d, **scripts_d}
try:
self.maxDiff = None
@@ -5765,6 +5789,7 @@ class TestNetworkManagerRendering(CiTestCase):
"""
),
},
+ self.expected_conf_d,
found,
)
@@ -5820,8 +5845,9 @@ class TestNetworkManagerRendering(CiTestCase):
gateway=10.0.2.2
"""
- ),
+ )
},
+ self.expected_conf_d,
found,
)
@@ -5857,33 +5883,44 @@ class TestNetworkManagerRendering(CiTestCase):
"""
),
},
+ self.expected_conf_d,
found,
)
def test_bond_config(self):
entry = NETWORK_CONFIGS["bond"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_vlan_config(self):
entry = NETWORK_CONFIGS["vlan"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_bridge_config(self):
entry = NETWORK_CONFIGS["bridge"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_manual_config(self):
entry = NETWORK_CONFIGS["manual"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_all_config(self):
entry = NETWORK_CONFIGS["all"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
self.assertNotIn(
"WARNING: Network config: ignoring eth0.101 device-level mtu",
self.logs.getvalue(),
@@ -5892,12 +5929,16 @@ class TestNetworkManagerRendering(CiTestCase):
def test_small_config(self):
entry = NETWORK_CONFIGS["small"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_v4_and_v6_static_config(self):
entry = NETWORK_CONFIGS["v4_and_v6_static"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
expected_msg = (
"WARNING: Network config: ignoring iface0 device-level mtu:8999"
" because ipv4 subnet-level mtu:9000 provided."
@@ -5907,41 +5948,55 @@ class TestNetworkManagerRendering(CiTestCase):
def test_dhcpv6_only_config(self):
entry = NETWORK_CONFIGS["dhcpv6_only"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_simple_render_ipv6_slaac(self):
entry = NETWORK_CONFIGS["ipv6_slaac"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_dhcpv6_stateless_config(self):
entry = NETWORK_CONFIGS["dhcpv6_stateless"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_wakeonlan_disabled_config_v2(self):
entry = NETWORK_CONFIGS["wakeonlan_disabled"]
found = self._render_and_read(
network_config=yaml.load(entry["yaml_v2"])
)
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_wakeonlan_enabled_config_v2(self):
entry = NETWORK_CONFIGS["wakeonlan_enabled"]
found = self._render_and_read(
network_config=yaml.load(entry["yaml_v2"])
)
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_render_v4_and_v6(self):
entry = NETWORK_CONFIGS["v4_and_v6"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
def test_render_v6_and_v4(self):
entry = NETWORK_CONFIGS["v6_and_v4"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
- self._compare_files_to_expected(entry[self.expected_name], found)
+ self._compare_files_to_expected(
+ entry[self.expected_name], self.expected_conf_d, found
+ )
@mock.patch(

View File

@ -1,256 +0,0 @@
From 8e599c618ba33f7ed572f752fc9201ca44e41868 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Wed, 18 May 2022 16:21:45 +0200
Subject: [PATCH 4/5] Align rhel custom files with upstream (#1431)
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 26: Align rhel custom files with upstream (#1431)
RH-Commit: [1/2] edac80c4fa3a11d093ee0e7260796566a7eb141e (eesposit/cloud-init-centos-)
RH-Bugzilla: 2088448
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
commit 9624758f91b61f4711e8d7b5c83075b5d23e0c43
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Wed May 18 15:18:04 2022 +0200
Align rhel custom files with upstream (#1431)
So far RHEL had its own custom .service and cloud.cfg files,
that diverged from upstream. We always replaced the generated files
with the ones we had.
This caused only confusion and made it harder to rebase and backport
patches targeting these files.
At the same time, we are going to delete our custom downstream-only files
and use the ones generated by .tmpl.
The mapping is:
config/cloud.cfg.tmpl -> rhel/cloud.cfg
systemd/* -> rhel/systemd/*
Such rhel-specific files are open and available in the Centos repo:
https://gitlab.com/redhat/centos-stream/src/cloud-init
With this commit, we are also introducing modules in cloud.cfg that
were not in the default rhel cfg file, even though they should already
have been there with previous rebases and releases.
Anyways such modules support rhel as distro, and
therefore should cause no harm.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RHBZ: 2082071
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
config/cloud.cfg.tmpl | 23 +++++++++++++++++++++++
systemd/cloud-config.service.tmpl | 4 ++++
systemd/cloud-final.service.tmpl | 13 +++++++++++++
systemd/cloud-init-local.service.tmpl | 22 +++++++++++++++++++++-
systemd/cloud-init.service.tmpl | 6 +++++-
tests/unittests/test_render_cloudcfg.py | 1 +
6 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 86beee3c..f4d2fd14 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -34,7 +34,11 @@ disable_root: true
{% if variant in ["almalinux", "alpine", "amazon", "centos", "cloudlinux", "eurolinux",
"fedora", "miraclelinux", "openEuler", "rhel", "rocky", "virtuozzo"] %}
+{% if variant == "rhel" %}
+mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service,_netdev', '0', '2']
+{% else %}
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
+{% endif %}
{% if variant == "amazon" %}
resize_rootfs: noblock
{% endif %}
@@ -66,6 +70,14 @@ network:
config: disabled
{% endif %}
+{% if variant == "rhel" %}
+# Default redhat settings:
+ssh_deletekeys: true
+ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
+syslog_fix_perms: ~
+disable_vmware_customization: false
+{% endif %}
+
# The modules that run in the 'init' stage
cloud_init_modules:
- migrator
@@ -107,10 +119,15 @@ cloud_config_modules:
{% endif %}
{% if variant not in ["photon"] %}
- ssh-import-id
+{% if variant not in ["rhel"] %}
- keyboard
+{% endif %}
- locale
{% endif %}
- set-passwords
+{% if variant in ["rhel"] %}
+ - rh_subscription
+{% endif %}
{% if variant in ["rhel", "fedora", "photon"] %}
{% if variant not in ["photon"] %}
- spacewalk
@@ -239,6 +256,10 @@ system_info:
name: ec2-user
lock_passwd: True
gecos: EC2 Default User
+{% elif variant == "rhel" %}
+ name: cloud-user
+ lock_passwd: true
+ gecos: Cloud User
{% else %}
name: {{ variant }}
lock_passwd: True
@@ -254,6 +275,8 @@ system_info:
groups: [adm, sudo]
{% elif variant == "arch" %}
groups: [wheel, users]
+{% elif variant == "rhel" %}
+ groups: [adm, systemd-journal]
{% else %}
groups: [wheel, adm, systemd-journal]
{% endif %}
diff --git a/systemd/cloud-config.service.tmpl b/systemd/cloud-config.service.tmpl
index 9d928ca2..d5568a6e 100644
--- a/systemd/cloud-config.service.tmpl
+++ b/systemd/cloud-config.service.tmpl
@@ -4,6 +4,10 @@ Description=Apply the settings specified in cloud-config
After=network-online.target cloud-config.target
After=snapd.seeded.service
Wants=network-online.target cloud-config.target
+{% if variant == "rhel" %}
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
[Service]
Type=oneshot
diff --git a/systemd/cloud-final.service.tmpl b/systemd/cloud-final.service.tmpl
index 8207b18c..85f423ac 100644
--- a/systemd/cloud-final.service.tmpl
+++ b/systemd/cloud-final.service.tmpl
@@ -7,6 +7,10 @@ After=multi-user.target
Before=apt-daily.service
{% endif %}
Wants=network-online.target cloud-config.service
+{% if variant == "rhel" %}
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
[Service]
@@ -15,7 +19,16 @@ ExecStart=/usr/bin/cloud-init modules --mode=final
RemainAfterExit=yes
TimeoutSec=0
KillMode=process
+{% if variant == "rhel" %}
+# Restart NetworkManager if it is present and running.
+ExecStartPost=/bin/sh -c 'u=NetworkManager.service; \
+ out=$(systemctl show --property=SubState $u) || exit; \
+ [ "$out" = "SubState=running" ] || exit 0; \
+ systemctl reload-or-try-restart $u'
+{% else %}
TasksMax=infinity
+{% endif %}
+
# Output needs to appear in instance console output
StandardOutput=journal+console
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
index 7166f640..a6b82650 100644
--- a/systemd/cloud-init-local.service.tmpl
+++ b/systemd/cloud-init-local.service.tmpl
@@ -1,23 +1,43 @@
## template:jinja
[Unit]
Description=Initial cloud-init job (pre-networking)
-{% if variant in ["ubuntu", "unknown", "debian"] %}
+{% if variant in ["ubuntu", "unknown", "debian", "rhel" ] %}
DefaultDependencies=no
{% endif %}
Wants=network-pre.target
After=hv_kvp_daemon.service
After=systemd-remount-fs.service
+{% if variant == "rhel" %}
+Requires=dbus.socket
+After=dbus.socket
+{% endif %}
Before=NetworkManager.service
+{% if variant == "rhel" %}
+Before=network.service
+{% endif %}
Before=network-pre.target
Before=shutdown.target
+{% if variant == "rhel" %}
+Before=firewalld.target
+Conflicts=shutdown.target
+{% endif %}
{% if variant in ["ubuntu", "unknown", "debian"] %}
Before=sysinit.target
Conflicts=shutdown.target
{% endif %}
RequiresMountsFor=/var/lib/cloud
+{% if variant == "rhel" %}
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
[Service]
Type=oneshot
+{% if variant == "rhel" %}
+ExecStartPre=/bin/mkdir -p /run/cloud-init
+ExecStartPre=/sbin/restorecon /run/cloud-init
+ExecStartPre=/usr/bin/touch /run/cloud-init/enabled
+{% endif %}
ExecStart=/usr/bin/cloud-init init --local
ExecStart=/bin/touch /run/cloud-init/network-config-ready
RemainAfterExit=yes
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
index e71e5679..c170aef7 100644
--- a/systemd/cloud-init.service.tmpl
+++ b/systemd/cloud-init.service.tmpl
@@ -1,7 +1,7 @@
## template:jinja
[Unit]
Description=Initial cloud-init job (metadata service crawler)
-{% if variant not in ["photon"] %}
+{% if variant not in ["photon", "rhel"] %}
DefaultDependencies=no
{% endif %}
Wants=cloud-init-local.service
@@ -36,6 +36,10 @@ Before=shutdown.target
Conflicts=shutdown.target
{% endif %}
Before=systemd-user-sessions.service
+{% if variant == "rhel" %}
+ConditionPathExists=!/etc/cloud/cloud-init.disabled
+ConditionKernelCommandLine=!cloud-init=disabled
+{% endif %}
[Service]
Type=oneshot
diff --git a/tests/unittests/test_render_cloudcfg.py b/tests/unittests/test_render_cloudcfg.py
index 30fbd1a4..9f95d448 100644
--- a/tests/unittests/test_render_cloudcfg.py
+++ b/tests/unittests/test_render_cloudcfg.py
@@ -68,6 +68,7 @@ class TestRenderCloudCfg:
default_user_exceptions = {
"amazon": "ec2-user",
"debian": "ubuntu",
+ "rhel": "cloud-user",
"unknown": "ubuntu",
}
default_user = system_cfg["system_info"]["default_user"]["name"]
--
2.31.1

View File

@ -1,516 +0,0 @@
From 1176a788c23697099093b4d8a9a21f10f71ebb12 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Wed, 1 Feb 2023 10:47:07 +0100
Subject: [PATCH] Allow growpart to resize encrypted partitions (#1316)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2166245
commit d95a331d1035d52443c470e0c00765a2c2b271cc
Author: James Falcon <james.falcon@canonical.com>
Date: Tue Apr 26 19:03:13 2022 -0500
Allow growpart to resize encrypted partitions (#1316)
Adds the ability for growpart to resize a LUKS formatted partition.
This involves resizing the underlying partition as well as the
filesystem. 'cryptsetup' is used for resizing.
This relies on a file present at /cc_growpart_keydata containing
json formatted 'key' and 'slot' keys, with the key being
base64 encoded. After resize, cloud-init will destroy
the luks slot used for resizing and remove the key file.
Conflicts:
cloudinit/config/cc_growpart.py (includes only)
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
cloudinit/config/cc_growpart.py | 171 +++++++++++++++-
test-requirements.txt | 1 +
tests/unittests/config/test_cc_growpart.py | 228 +++++++++++++++++++++
tox.ini | 1 +
4 files changed, 400 insertions(+), 1 deletion(-)
diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py
index 43334caa..bdf17aba 100644
--- a/cloudinit/config/cc_growpart.py
+++ b/cloudinit/config/cc_growpart.py
@@ -64,10 +64,16 @@ growpart is::
ignore_growroot_disabled: <true/false>
"""
+import base64
+import copy
+import json
import os
import os.path
import re
import stat
+from contextlib import suppress
+from pathlib import Path
+from typing import Tuple
from cloudinit import log as logging
from cloudinit import subp, temp_utils, util
@@ -81,6 +87,8 @@ DEFAULT_CONFIG = {
"ignore_growroot_disabled": False,
}
+KEYDATA_PATH = Path("/cc_growpart_keydata")
+
class RESIZE(object):
SKIPPED = "SKIPPED"
@@ -289,10 +297,128 @@ def devent2dev(devent):
return dev
+def get_mapped_device(blockdev):
+ """Returns underlying block device for a mapped device.
+
+ If it is mapped, blockdev will usually take the form of
+ /dev/mapper/some_name
+
+ If blockdev is a symlink pointing to a /dev/dm-* device, return
+ the device pointed to. Otherwise, return None.
+ """
+ realpath = os.path.realpath(blockdev)
+ if realpath.startswith("/dev/dm-"):
+ LOG.debug("%s is a mapped device pointing to %s", blockdev, realpath)
+ return realpath
+ return None
+
+
+def is_encrypted(blockdev, partition) -> bool:
+ """
+ Check if a device is an encrypted device. blockdev should have
+ a /dev/dm-* path whereas partition is something like /dev/sda1.
+ """
+ if not subp.which("cryptsetup"):
+ LOG.debug("cryptsetup not found. Assuming no encrypted partitions")
+ return False
+ try:
+ subp.subp(["cryptsetup", "status", blockdev])
+ except subp.ProcessExecutionError as e:
+ if e.exit_code == 4:
+ LOG.debug("Determined that %s is not encrypted", blockdev)
+ else:
+ LOG.warning(
+ "Received unexpected exit code %s from "
+ "cryptsetup status. Assuming no encrypted partitions.",
+ e.exit_code,
+ )
+ return False
+ with suppress(subp.ProcessExecutionError):
+ subp.subp(["cryptsetup", "isLuks", partition])
+ LOG.debug("Determined that %s is encrypted", blockdev)
+ return True
+ return False
+
+
+def get_underlying_partition(blockdev):
+ command = ["dmsetup", "deps", "--options=devname", blockdev]
+ dep: str = subp.subp(command)[0] # type: ignore
+ # Returned result should look something like:
+ # 1 dependencies : (vdb1)
+ if not dep.startswith("1 depend"):
+ raise RuntimeError(
+ f"Expecting '1 dependencies' from 'dmsetup'. Received: {dep}"
+ )
+ try:
+ return f'/dev/{dep.split(": (")[1].split(")")[0]}'
+ except IndexError as e:
+ raise RuntimeError(
+ f"Ran `{command}`, but received unexpected stdout: `{dep}`"
+ ) from e
+
+
+def resize_encrypted(blockdev, partition) -> Tuple[str, str]:
+ """Use 'cryptsetup resize' to resize LUKS volume.
+
+ The loaded keyfile is json formatted with 'key' and 'slot' keys.
+ key is base64 encoded. Example:
+ {"key":"XFmCwX2FHIQp0LBWaLEMiHIyfxt1SGm16VvUAVledlY=","slot":5}
+ """
+ if not KEYDATA_PATH.exists():
+ return (RESIZE.SKIPPED, "No encryption keyfile found")
+ try:
+ with KEYDATA_PATH.open() as f:
+ keydata = json.load(f)
+ key = keydata["key"]
+ decoded_key = base64.b64decode(key)
+ slot = keydata["slot"]
+ except Exception as e:
+ raise RuntimeError(
+ "Could not load encryption key. This is expected if "
+ "the volume has been previously resized."
+ ) from e
+
+ try:
+ subp.subp(
+ ["cryptsetup", "--key-file", "-", "resize", blockdev],
+ data=decoded_key,
+ )
+ finally:
+ try:
+ subp.subp(
+ [
+ "cryptsetup",
+ "luksKillSlot",
+ "--batch-mode",
+ partition,
+ str(slot),
+ ]
+ )
+ except subp.ProcessExecutionError as e:
+ LOG.warning(
+ "Failed to kill luks slot after resizing encrypted volume: %s",
+ e,
+ )
+ try:
+ KEYDATA_PATH.unlink()
+ except Exception:
+ util.logexc(
+ LOG, "Failed to remove keyfile after resizing encrypted volume"
+ )
+
+ return (
+ RESIZE.CHANGED,
+ f"Successfully resized encrypted volume '{blockdev}'",
+ )
+
+
def resize_devices(resizer, devices):
# returns a tuple of tuples containing (entry-in-devices, action, message)
+ devices = copy.copy(devices)
info = []
- for devent in devices:
+
+ while devices:
+ devent = devices.pop(0)
try:
blockdev = devent2dev(devent)
except ValueError as e:
@@ -329,6 +455,49 @@ def resize_devices(resizer, devices):
)
continue
+ underlying_blockdev = get_mapped_device(blockdev)
+ if underlying_blockdev:
+ try:
+ # We need to resize the underlying partition first
+ partition = get_underlying_partition(blockdev)
+ if is_encrypted(underlying_blockdev, partition):
+ if partition not in [x[0] for x in info]:
+ # We shouldn't attempt to resize this mapped partition
+ # until the underlying partition is resized, so re-add
+ # our device to the beginning of the list we're
+ # iterating over, then add our underlying partition
+ # so it can get processed first
+ devices.insert(0, devent)
+ devices.insert(0, partition)
+ continue
+ status, message = resize_encrypted(blockdev, partition)
+ info.append(
+ (
+ devent,
+ status,
+ message,
+ )
+ )
+ else:
+ info.append(
+ (
+ devent,
+ RESIZE.SKIPPED,
+ f"Resizing mapped device ({blockdev}) skipped "
+ "as it is not encrypted.",
+ )
+ )
+ except Exception as e:
+ info.append(
+ (
+ devent,
+ RESIZE.FAILED,
+ f"Resizing encrypted device ({blockdev}) failed: {e}",
+ )
+ )
+ # At this point, we WON'T resize a non-encrypted mapped device
+ # though we should probably grow the ability to
+ continue
try:
(disk, ptnum) = device_part_info(blockdev)
except (TypeError, ValueError) as e:
diff --git a/test-requirements.txt b/test-requirements.txt
index 06dfbbec..7160416a 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,6 +2,7 @@
httpretty>=0.7.1
pytest
pytest-cov
+pytest-mock
# Only really needed on older versions of python
setuptools
diff --git a/tests/unittests/config/test_cc_growpart.py b/tests/unittests/config/test_cc_growpart.py
index ba66f136..7d4e2629 100644
--- a/tests/unittests/config/test_cc_growpart.py
+++ b/tests/unittests/config/test_cc_growpart.py
@@ -8,6 +8,7 @@ import shutil
import stat
import unittest
from contextlib import ExitStack
+from itertools import chain
from unittest import mock
from cloudinit import cloud, subp, temp_utils
@@ -342,6 +343,233 @@ class TestResize(unittest.TestCase):
os.stat = real_stat
+class TestEncrypted:
+ """Attempt end-to-end scenarios using encrypted devices.
+
+ Things are mocked such that:
+ - "/fake_encrypted" is mounted onto "/dev/mapper/fake"
+ - "/dev/mapper/fake" is a LUKS device and symlinked to /dev/dm-1
+ - The partition backing "/dev/mapper/fake" is "/dev/vdx1"
+ - "/" is not encrypted and mounted onto "/dev/vdz1"
+
+ Note that we don't (yet) support non-encrypted mapped drives, such
+ as LVM volumes. If our mount point is /dev/mapper/*, then we will
+ not resize it if it is not encrypted.
+ """
+
+ def _subp_side_effect(self, value, good=True, **kwargs):
+ if value[0] == "dmsetup":
+ return ("1 dependencies : (vdx1)",)
+ return mock.Mock()
+
+ def _device_part_info_side_effect(self, value):
+ if value.startswith("/dev/mapper/"):
+ raise TypeError(f"{value} not a partition")
+ return (1024, 1024)
+
+ def _devent2dev_side_effect(self, value):
+ if value == "/fake_encrypted":
+ return "/dev/mapper/fake"
+ elif value == "/":
+ return "/dev/vdz"
+ elif value.startswith("/dev"):
+ return value
+ raise Exception(f"unexpected value {value}")
+
+ def _realpath_side_effect(self, value):
+ return "/dev/dm-1" if value.startswith("/dev/mapper") else value
+
+ def assert_resize_and_cleanup(self):
+ all_subp_args = list(
+ chain(*[args[0][0] for args in self.m_subp.call_args_list])
+ )
+ assert "resize" in all_subp_args
+ assert "luksKillSlot" in all_subp_args
+ self.m_unlink.assert_called_once()
+
+ def assert_no_resize_or_cleanup(self):
+ all_subp_args = list(
+ chain(*[args[0][0] for args in self.m_subp.call_args_list])
+ )
+ assert "resize" not in all_subp_args
+ assert "luksKillSlot" not in all_subp_args
+ self.m_unlink.assert_not_called()
+
+ @pytest.fixture
+ def common_mocks(self, mocker):
+ # These are all "happy path" mocks which will get overridden
+ # when needed
+ mocker.patch(
+ "cloudinit.config.cc_growpart.device_part_info",
+ side_effect=self._device_part_info_side_effect,
+ )
+ mocker.patch("os.stat")
+ mocker.patch("stat.S_ISBLK")
+ mocker.patch("stat.S_ISCHR")
+ mocker.patch(
+ "cloudinit.config.cc_growpart.devent2dev",
+ side_effect=self._devent2dev_side_effect,
+ )
+ mocker.patch(
+ "os.path.realpath", side_effect=self._realpath_side_effect
+ )
+ # Only place subp.which is used in cc_growpart is for cryptsetup
+ mocker.patch(
+ "cloudinit.config.cc_growpart.subp.which",
+ return_value="/usr/sbin/cryptsetup",
+ )
+ self.m_subp = mocker.patch(
+ "cloudinit.config.cc_growpart.subp.subp",
+ side_effect=self._subp_side_effect,
+ )
+ mocker.patch(
+ "pathlib.Path.open",
+ new_callable=mock.mock_open,
+ read_data=(
+ '{"key":"XFmCwX2FHIQp0LBWaLEMiHIyfxt1SGm16VvUAVledlY=",'
+ '"slot":5}'
+ ),
+ )
+ mocker.patch("pathlib.Path.exists", return_value=True)
+ self.m_unlink = mocker.patch("pathlib.Path.unlink", autospec=True)
+
+ self.resizer = mock.Mock()
+ self.resizer.resize = mock.Mock(return_value=(1024, 1024))
+
+ def test_resize_when_encrypted(self, common_mocks, caplog):
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+ assert len(info) == 2
+ assert info[0][0] == "/dev/vdx1"
+ assert info[0][2].startswith("no change necessary")
+ assert info[1][0] == "/fake_encrypted"
+ assert (
+ info[1][2]
+ == "Successfully resized encrypted volume '/dev/mapper/fake'"
+ )
+ assert (
+ "/dev/mapper/fake is a mapped device pointing to /dev/dm-1"
+ in caplog.text
+ )
+ assert "Determined that /dev/dm-1 is encrypted" in caplog.text
+
+ self.assert_resize_and_cleanup()
+
+ def test_resize_when_unencrypted(self, common_mocks):
+ info = cc_growpart.resize_devices(self.resizer, ["/"])
+ assert len(info) == 1
+ assert info[0][0] == "/"
+ assert "encrypted" not in info[0][2]
+ self.assert_no_resize_or_cleanup()
+
+ def test_encrypted_but_cryptsetup_not_found(
+ self, common_mocks, mocker, caplog
+ ):
+ mocker.patch(
+ "cloudinit.config.cc_growpart.subp.which",
+ return_value=None,
+ )
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+
+ assert len(info) == 1
+ assert "skipped as it is not encrypted" in info[0][2]
+ assert "cryptsetup not found" in caplog.text
+ self.assert_no_resize_or_cleanup()
+
+ def test_dmsetup_not_found(self, common_mocks, mocker, caplog):
+ def _subp_side_effect(value, **kwargs):
+ if value[0] == "dmsetup":
+ raise subp.ProcessExecutionError()
+
+ mocker.patch(
+ "cloudinit.config.cc_growpart.subp.subp",
+ side_effect=_subp_side_effect,
+ )
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+ assert len(info) == 1
+ assert info[0][0] == "/fake_encrypted"
+ assert info[0][1] == "FAILED"
+ assert (
+ "Resizing encrypted device (/dev/mapper/fake) failed" in info[0][2]
+ )
+ self.assert_no_resize_or_cleanup()
+
+ def test_unparsable_dmsetup(self, common_mocks, mocker, caplog):
+ def _subp_side_effect(value, **kwargs):
+ if value[0] == "dmsetup":
+ return ("2 dependencies",)
+ return mock.Mock()
+
+ mocker.patch(
+ "cloudinit.config.cc_growpart.subp.subp",
+ side_effect=_subp_side_effect,
+ )
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+ assert len(info) == 1
+ assert info[0][0] == "/fake_encrypted"
+ assert info[0][1] == "FAILED"
+ assert (
+ "Resizing encrypted device (/dev/mapper/fake) failed" in info[0][2]
+ )
+ self.assert_no_resize_or_cleanup()
+
+ def test_missing_keydata(self, common_mocks, mocker, caplog):
+ # Note that this will be standard behavior after first boot
+ # on a system with an encrypted root partition
+ mocker.patch("pathlib.Path.open", side_effect=FileNotFoundError())
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+ assert len(info) == 2
+ assert info[0][0] == "/dev/vdx1"
+ assert info[0][2].startswith("no change necessary")
+ assert info[1][0] == "/fake_encrypted"
+ assert info[1][1] == "FAILED"
+ assert (
+ info[1][2]
+ == "Resizing encrypted device (/dev/mapper/fake) failed: Could "
+ "not load encryption key. This is expected if the volume has "
+ "been previously resized."
+ )
+ self.assert_no_resize_or_cleanup()
+
+ def test_resize_failed(self, common_mocks, mocker, caplog):
+ def _subp_side_effect(value, **kwargs):
+ if value[0] == "dmsetup":
+ return ("1 dependencies : (vdx1)",)
+ elif value[0] == "cryptsetup" and "resize" in value:
+ raise subp.ProcessExecutionError()
+ return mock.Mock()
+
+ self.m_subp = mocker.patch(
+ "cloudinit.config.cc_growpart.subp.subp",
+ side_effect=_subp_side_effect,
+ )
+
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+ assert len(info) == 2
+ assert info[0][0] == "/dev/vdx1"
+ assert info[0][2].startswith("no change necessary")
+ assert info[1][0] == "/fake_encrypted"
+ assert info[1][1] == "FAILED"
+ assert (
+ "Resizing encrypted device (/dev/mapper/fake) failed" in info[1][2]
+ )
+ # Assert we still cleanup
+ all_subp_args = list(
+ chain(*[args[0][0] for args in self.m_subp.call_args_list])
+ )
+ assert "luksKillSlot" in all_subp_args
+ self.m_unlink.assert_called_once()
+
+ def test_resize_skipped(self, common_mocks, mocker, caplog):
+ mocker.patch("pathlib.Path.exists", return_value=False)
+ info = cc_growpart.resize_devices(self.resizer, ["/fake_encrypted"])
+ assert len(info) == 2
+ assert info[1] == (
+ "/fake_encrypted",
+ "SKIPPED",
+ "No encryption keyfile found",
+ )
+
+
def simple_device_part_info(devpath):
# simple stupid return (/dev/vda, 1) for /dev/vda
ret = re.search("([^0-9]*)([0-9]*)$", devpath)
diff --git a/tox.ini b/tox.ini
index c494cb94..04a206f2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -108,6 +108,7 @@ deps =
# test-requirements
pytest==3.3.2
pytest-cov==2.5.1
+ pytest-mock==1.7.1
# Needed by pytest and default causes failures
attrs==17.4.0
--
2.39.1

View File

@ -1,36 +0,0 @@
From 14d1952c17637b80923d1bfaf3b6b5f8cf032147 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Wed, 14 Dec 2022 09:31:51 +0100
Subject: [PATCH] Ensure network ready before cloud-init service runs on RHEL
(#1893)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2152100
commit 6e725f36647407d201af0603d7db11fc96a93d4d
Author: James Falcon <james.falcon@canonical.com>
Date: Tue Dec 13 10:55:23 2022 -0600
Ensure network ready before cloud-init service runs on RHEL (#1893)
LP: #1998655
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
systemd/cloud-init.service.tmpl | 1 +
1 file changed, 1 insertion(+)
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
index c170aef7..fc984d5c 100644
--- a/systemd/cloud-init.service.tmpl
+++ b/systemd/cloud-init.service.tmpl
@@ -16,6 +16,7 @@ After=networking.service
"miraclelinux", "openEuler", "rhel", "rocky", "virtuozzo"] %}
After=network.service
After=NetworkManager.service
+After=NetworkManager-wait-online.service
{% endif %}
{% if variant in ["suse"] %}
After=wicked.service
--
2.38.1

View File

@ -1,135 +0,0 @@
From 53e3f8ab9008fec8400f96918c2129f7defe6a70 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Fri, 10 Jun 2022 20:51:55 +0200
Subject: [PATCH 1/3] Honor system locale for RHEL (#1355)
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 29: Honor system locale for RHEL (#1355)
RH-Commit: [1/1] d571126fe6add8dc34a22c869d4e1a07a7373d8d (eesposit/cloud-init-centos-)
RH-Bugzilla: 2061604
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
commit 58da7d856274e9ca2b507128d6f186e0e6abfe06
Author: Wei Shi <wshi@redhat.com>
Date: Wed Mar 30 23:55:30 2022 +0800
Honor system locale for RHEL (#1355)
Make sure to use system locale as default on RHEL if locale is not
set in cloud-config.
RHEL has a pre-installed cloud image using C.UTF-8 for system locale
just like ubuntu-minimal cloud image, without this patch, locale
module will set it to en_US.UTF-8 from ds default value during config
stage.
Authored-by: Wei Shi <shi2wei3@hotmail.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/distros/rhel.py | 32 +++++++++++++++++++++++++
tests/unittests/distros/test_generic.py | 10 ++++----
tools/.github-cla-signers | 1 +
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py
index 84744ece..320f4ba1 100644
--- a/cloudinit/distros/rhel.py
+++ b/cloudinit/distros/rhel.py
@@ -7,6 +7,7 @@
# Author: Joshua Harlow <harlowja@yahoo-inc.com>
#
# This file is part of cloud-init. See LICENSE file for license information.
+import os
from cloudinit import distros, helpers
from cloudinit import log as logging
@@ -57,11 +58,25 @@ class Distro(distros.Distro):
# should only happen say once per instance...)
self._runner = helpers.Runners(paths)
self.osfamily = "redhat"
+ self.default_locale = "en_US.UTF-8"
+ self.system_locale = None
cfg["ssh_svcname"] = "sshd"
def install_packages(self, pkglist):
self.package_command("install", pkgs=pkglist)
+ def get_locale(self):
+ """Return the default locale if set, else use system locale"""
+
+ # read system locale value
+ if not self.system_locale:
+ self.system_locale = self._read_system_locale()
+
+ # Return system_locale setting if valid, else use default locale
+ return (
+ self.system_locale if self.system_locale else self.default_locale
+ )
+
def apply_locale(self, locale, out_fn=None):
if self.uses_systemd():
if not out_fn:
@@ -75,6 +90,23 @@ class Distro(distros.Distro):
}
rhel_util.update_sysconfig_file(out_fn, locale_cfg)
+ def _read_system_locale(self, keyname="LANG"):
+ """Read system default locale setting, if present"""
+ if self.uses_systemd():
+ locale_fn = self.systemd_locale_conf_fn
+ else:
+ locale_fn = self.locale_conf_fn
+
+ if not locale_fn:
+ raise ValueError("Invalid path: %s" % locale_fn)
+
+ if os.path.exists(locale_fn):
+ (_exists, contents) = rhel_util.read_sysconfig_file(locale_fn)
+ if keyname in contents:
+ return contents[keyname]
+ else:
+ return None
+
def _write_hostname(self, hostname, filename):
# systemd will never update previous-hostname for us, so
# we need to do it ourselves
diff --git a/tests/unittests/distros/test_generic.py b/tests/unittests/distros/test_generic.py
index 93c5395c..fedc7300 100644
--- a/tests/unittests/distros/test_generic.py
+++ b/tests/unittests/distros/test_generic.py
@@ -187,12 +187,14 @@ class TestGenericDistro(helpers.FilesystemMockingTestCase):
locale = d.get_locale()
self.assertEqual("C.UTF-8", locale)
- def test_get_locale_rhel(self):
- """Test rhel distro returns NotImplementedError exception"""
+ @mock.patch("cloudinit.distros.rhel.Distro._read_system_locale")
+ def test_get_locale_rhel(self, m_locale):
+ """Test rhel distro returns locale set to C.UTF-8"""
+ m_locale.return_value = "C.UTF-8"
cls = distros.fetch("rhel")
d = cls("rhel", {}, None)
- with self.assertRaises(NotImplementedError):
- d.get_locale()
+ locale = d.get_locale()
+ self.assertEqual("C.UTF-8", locale)
def test_expire_passwd_uses_chpasswd(self):
"""Test ubuntu.expire_passwd uses the passwd command."""
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
index 9f71ea0c..9eb2ae38 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -70,6 +70,7 @@ renanrodrigo
rhansen
riedel
sarahwzadara
+shi2wei3
slingamn
slyon
smoser
--
2.35.1

View File

@ -1,370 +0,0 @@
From 0ae221fe8f29555370520d05f6558eb75fe3cd42 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu, 5 May 2022 11:31:33 +0200
Subject: [PATCH 5/5] Remove rhel specific files
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 26: Align rhel custom files with upstream (#1431)
RH-Commit: [2/2] 0b9687ebab4f4039d5bbe05c00806ec7923e898d (eesposit/cloud-init-centos-)
RH-Bugzilla: 2088448
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
Remove all files in rhel/ directory and related commands that copy
and replace them with the generated ones.
Also adjust setup.py, align it with upstream:
- by default, after rhel 8.3 ds-identify is in /usr/libexec, so no need to move it manually
- bash-completions work also in /usr/share, as upstream
- udev also works in /lib/udev
Also remove rhel/README since it is outdated (chef is used in cloud.cfg) and cloud-init-tmpfiles.conf,
as it exists also in .distro.
X-downstream-only: yes
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
rhel/README.rhel | 5 --
rhel/cloud-init-tmpfiles.conf | 1 -
rhel/cloud.cfg | 69 ---------------------------
rhel/systemd/cloud-config.service | 18 -------
rhel/systemd/cloud-config.target | 11 -----
rhel/systemd/cloud-final.service | 24 ----------
rhel/systemd/cloud-init-local.service | 31 ------------
rhel/systemd/cloud-init.service | 26 ----------
rhel/systemd/cloud-init.target | 7 ---
setup.py | 28 ++++++++++-
11 files changed, 31 insertions(+), 210 deletions(-)
delete mode 100644 rhel/README.rhel
delete mode 100644 rhel/cloud-init-tmpfiles.conf
delete mode 100644 rhel/cloud.cfg
delete mode 100644 rhel/systemd/cloud-config.service
delete mode 100644 rhel/systemd/cloud-config.target
delete mode 100644 rhel/systemd/cloud-final.service
delete mode 100644 rhel/systemd/cloud-init-local.service
delete mode 100644 rhel/systemd/cloud-init.service
delete mode 100644 rhel/systemd/cloud-init.target
diff --git a/rhel/README.rhel b/rhel/README.rhel
deleted file mode 100644
index aa29630d..00000000
--- a/rhel/README.rhel
+++ /dev/null
@@ -1,5 +0,0 @@
-The following cloud-init modules are currently unsupported on this OS:
- - apt_update_upgrade ('apt_update', 'apt_upgrade', 'apt_mirror', 'apt_preserve_sources_list', 'apt_old_mirror', 'apt_sources', 'debconf_selections', 'packages' options)
- - byobu ('byobu_by_default' option)
- - chef
- - grub_dpkg
diff --git a/rhel/cloud-init-tmpfiles.conf b/rhel/cloud-init-tmpfiles.conf
deleted file mode 100644
index 0c6d2a3b..00000000
--- a/rhel/cloud-init-tmpfiles.conf
+++ /dev/null
@@ -1 +0,0 @@
-d /run/cloud-init 0700 root root - -
diff --git a/rhel/cloud.cfg b/rhel/cloud.cfg
deleted file mode 100644
index 75d5c84b..00000000
--- a/rhel/cloud.cfg
+++ /dev/null
@@ -1,69 +0,0 @@
-users:
- - default
-
-disable_root: 1
-ssh_pwauth: 0
-
-mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service,_netdev', '0', '2']
-resize_rootfs_tmp: /dev
-ssh_deletekeys: 1
-ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
-syslog_fix_perms: ~
-disable_vmware_customization: false
-
-cloud_init_modules:
- - disk_setup
- - migrator
- - bootcmd
- - write-files
- - growpart
- - resizefs
- - set_hostname
- - update_hostname
- - update_etc_hosts
- - rsyslog
- - users-groups
- - ssh
-
-cloud_config_modules:
- - mounts
- - locale
- - set-passwords
- - rh_subscription
- - yum-add-repo
- - package-update-upgrade-install
- - timezone
- - puppet
- - chef
- - salt-minion
- - mcollective
- - disable-ec2-metadata
- - runcmd
-
-cloud_final_modules:
- - rightscale_userdata
- - scripts-per-once
- - scripts-per-boot
- - scripts-per-instance
- - scripts-user
- - ssh-authkey-fingerprints
- - keys-to-console
- - phone-home
- - final-message
- - power-state-change
-
-system_info:
- default_user:
- name: cloud-user
- lock_passwd: true
- gecos: Cloud User
- groups: [adm, systemd-journal]
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/bash
- distro: rhel
- paths:
- cloud_dir: /var/lib/cloud
- templates_dir: /etc/cloud/templates
- ssh_svcname: sshd
-
-# vim:syntax=yaml
diff --git a/rhel/systemd/cloud-config.service b/rhel/systemd/cloud-config.service
deleted file mode 100644
index f3dcd4be..00000000
--- a/rhel/systemd/cloud-config.service
+++ /dev/null
@@ -1,18 +0,0 @@
-[Unit]
-Description=Apply the settings specified in cloud-config
-After=network-online.target cloud-config.target
-Wants=network-online.target cloud-config.target
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
-ConditionKernelCommandLine=!cloud-init=disabled
-
-[Service]
-Type=oneshot
-ExecStart=/usr/bin/cloud-init modules --mode=config
-RemainAfterExit=yes
-TimeoutSec=0
-
-# Output needs to appear in instance console output
-StandardOutput=journal+console
-
-[Install]
-WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-config.target b/rhel/systemd/cloud-config.target
deleted file mode 100644
index ae9b7d02..00000000
--- a/rhel/systemd/cloud-config.target
+++ /dev/null
@@ -1,11 +0,0 @@
-# cloud-init normally emits a "cloud-config" upstart event to inform third
-# parties that cloud-config is available, which does us no good when we're
-# using systemd. cloud-config.target serves as this synchronization point
-# instead. Services that would "start on cloud-config" with upstart can
-# instead use "After=cloud-config.target" and "Wants=cloud-config.target"
-# as appropriate.
-
-[Unit]
-Description=Cloud-config availability
-Wants=cloud-init-local.service cloud-init.service
-After=cloud-init-local.service cloud-init.service
diff --git a/rhel/systemd/cloud-final.service b/rhel/systemd/cloud-final.service
deleted file mode 100644
index e281c0cf..00000000
--- a/rhel/systemd/cloud-final.service
+++ /dev/null
@@ -1,24 +0,0 @@
-[Unit]
-Description=Execute cloud user/final scripts
-After=network-online.target cloud-config.service rc-local.service
-Wants=network-online.target cloud-config.service
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
-ConditionKernelCommandLine=!cloud-init=disabled
-
-[Service]
-Type=oneshot
-ExecStart=/usr/bin/cloud-init modules --mode=final
-RemainAfterExit=yes
-TimeoutSec=0
-KillMode=process
-# Restart NetworkManager if it is present and running.
-ExecStartPost=/bin/sh -c 'u=NetworkManager.service; \
- out=$(systemctl show --property=SubState $u) || exit; \
- [ "$out" = "SubState=running" ] || exit 0; \
- systemctl reload-or-try-restart $u'
-
-# Output needs to appear in instance console output
-StandardOutput=journal+console
-
-[Install]
-WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-init-local.service b/rhel/systemd/cloud-init-local.service
deleted file mode 100644
index 8f9f6c9f..00000000
--- a/rhel/systemd/cloud-init-local.service
+++ /dev/null
@@ -1,31 +0,0 @@
-[Unit]
-Description=Initial cloud-init job (pre-networking)
-DefaultDependencies=no
-Wants=network-pre.target
-After=systemd-remount-fs.service
-Requires=dbus.socket
-After=dbus.socket
-Before=NetworkManager.service network.service
-Before=network-pre.target
-Before=shutdown.target
-Before=firewalld.target
-Conflicts=shutdown.target
-RequiresMountsFor=/var/lib/cloud
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
-ConditionKernelCommandLine=!cloud-init=disabled
-
-[Service]
-Type=oneshot
-ExecStartPre=/bin/mkdir -p /run/cloud-init
-ExecStartPre=/sbin/restorecon /run/cloud-init
-ExecStartPre=/usr/bin/touch /run/cloud-init/enabled
-ExecStart=/usr/bin/cloud-init init --local
-ExecStart=/bin/touch /run/cloud-init/network-config-ready
-RemainAfterExit=yes
-TimeoutSec=0
-
-# Output needs to appear in instance console output
-StandardOutput=journal+console
-
-[Install]
-WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-init.service b/rhel/systemd/cloud-init.service
deleted file mode 100644
index 0b3d796d..00000000
--- a/rhel/systemd/cloud-init.service
+++ /dev/null
@@ -1,26 +0,0 @@
-[Unit]
-Description=Initial cloud-init job (metadata service crawler)
-Wants=cloud-init-local.service
-Wants=sshd-keygen.service
-Wants=sshd.service
-After=cloud-init-local.service
-After=NetworkManager.service network.service
-After=NetworkManager-wait-online.service
-Before=network-online.target
-Before=sshd-keygen.service
-Before=sshd.service
-Before=systemd-user-sessions.service
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
-ConditionKernelCommandLine=!cloud-init=disabled
-
-[Service]
-Type=oneshot
-ExecStart=/usr/bin/cloud-init init
-RemainAfterExit=yes
-TimeoutSec=0
-
-# Output needs to appear in instance console output
-StandardOutput=journal+console
-
-[Install]
-WantedBy=cloud-init.target
diff --git a/rhel/systemd/cloud-init.target b/rhel/systemd/cloud-init.target
deleted file mode 100644
index 083c3b6f..00000000
--- a/rhel/systemd/cloud-init.target
+++ /dev/null
@@ -1,7 +0,0 @@
-# cloud-init target is enabled by cloud-init-generator
-# To disable it you can either:
-# a.) boot with kernel cmdline of 'cloud-init=disabled'
-# b.) touch a file /etc/cloud/cloud-init.disabled
-[Unit]
-Description=Cloud-init target
-After=multi-user.target
diff --git a/setup.py b/setup.py
index 3c377eaa..a9132d2c 100755
--- a/setup.py
+++ b/setup.py
@@ -139,6 +139,21 @@ INITSYS_FILES = {
"sysvinit_deb": [f for f in glob("sysvinit/debian/*") if is_f(f)],
"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")
+ + glob("systemd/*.service")
+ + glob("systemd/*.socket")
+ + glob("systemd/*.target")
+ )
+ if (is_f(f) and not is_generator(f))
+ ],
+ "systemd.generators": [
+ render_tmpl(f, mode=0o755)
+ for f in glob("systemd/*")
+ if is_f(f) and is_generator(f)
+ ],
"upstart": [f for f in glob("upstart/*") if is_f(f)],
}
INITSYS_ROOTS = {
@@ -148,6 +163,10 @@ INITSYS_ROOTS = {
"sysvinit_deb": "etc/init.d",
"sysvinit_openrc": "etc/init.d",
"sysvinit_suse": "etc/init.d",
+ "systemd": pkg_config_read("systemd", "systemdsystemunitdir"),
+ "systemd.generators": pkg_config_read(
+ "systemd", "systemdsystemgeneratordir"
+ ),
"upstart": "etc/init/",
}
INITSYS_TYPES = sorted([f.partition(".")[0] for f in INITSYS_ROOTS.keys()])
@@ -262,13 +281,15 @@ data_files = [
(
USR_LIB_EXEC + "/cloud-init",
[
+ "tools/ds-identify",
"tools/hook-hotplug",
"tools/uncloud-init",
"tools/write-ssh-key-fingerprints",
],
),
(
- ETC + "/bash_completion.d", ["bash_completion/cloud-init"],
+ USR + "/share/bash-completion/completions",
+ ["bash_completion/cloud-init"],
),
(USR + "/share/doc/cloud-init", [f for f in glob("doc/*") if is_f(f)]),
(
@@ -287,7 +308,8 @@ if not platform.system().endswith("BSD"):
ETC + "/NetworkManager/dispatcher.d/",
["tools/hook-network-manager"],
),
- ("/usr/lib/udev/rules.d", [f for f in glob("udev/*.rules")]),
+ (ETC + "/dhcp/dhclient-exit-hooks.d/", ["tools/hook-dhclient"]),
+ (LIB + "/udev/rules.d", [f for f in glob("udev/*.rules")]),
(
ETC + "/systemd/system/sshd-keygen@.service.d/",
["systemd/disable-sshd-keygen-if-cloud-init-active.conf"],
@@ -317,6 +339,8 @@ setuptools.setup(
scripts=["tools/cloud-init-per"],
license="Dual-licensed under GPLv3 or Apache 2.0",
data_files=data_files,
+ install_requires=requirements,
+ cmdclass=cmdclass,
entry_points={
"console_scripts": [
"cloud-init = cloudinit.cmd.main:main",
--
2.31.1

View File

@ -1,37 +0,0 @@
From c843f5cf7152846da3422185a6ad344dd47604e6 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Mon, 8 Aug 2022 10:02:48 +0200
Subject: [PATCH 3/3] Revert "Revert "Setting highest autoconnect priority for
network-scripts""
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 31: Revert "Revert "Setting highest autoconnect priority for network-scripts""
RH-Commit: [3/3] 09b83fb559675a2fcd4fc5394b251f034b92c1bc (eesposit/cloud-init-centos-)
RH-Bugzilla: 2107463 2104389 2117532 2098501
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
Reverting NM means we also need to restore this patch
This reverts commit 0eba5c6194017ef493a735cb24757c57d8af7b59.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/net/sysconfig.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index d8c53312..b50035b5 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -337,6 +337,7 @@ class Renderer(renderer.Renderer):
"ONBOOT": True,
"USERCTL": False,
"BOOTPROTO": "none",
+ "AUTOCONNECT_PRIORITY": 999
},
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
}
--
2.31.1

View File

@ -1,37 +0,0 @@
From e5e2ba9e21ac40ec7b8fe1c1dcf501eaeb9f66bf Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Mon, 2 May 2022 14:43:17 +0200
Subject: [PATCH 3/5] Revert "Setting highest autoconnect priority for
network-scripts"
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 24: Add native NetworkManager support (#1224)
RH-Commit: [3/3] 06c87581fc42b6827ad9df600f3dd76d51ced0d0 (eesposit/cloud-init-centos-)
RH-Bugzilla: 2056964
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
This reverts commit 0ef0c86350aa5f800f8393a432f431e2818c8938,
since it was a temporary downstream-only patch while we waited for
"Add native NetworkManager support (#1224)".
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/net/sysconfig.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index 2a45a4fa..dc401d78 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -317,7 +317,6 @@ class Renderer(renderer.Renderer):
"ONBOOT": True,
"USERCTL": False,
"BOOTPROTO": "none",
- "AUTOCONNECT_PRIORITY": 999
},
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
}
--
2.31.1

View File

@ -1,75 +0,0 @@
From c063021168dee7937281decd8f9b601f49a7d0f3 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Mon, 8 Aug 2022 10:02:17 +0200
Subject: [PATCH 2/3] Revert "Use Network-Manager and Netplan as default
renderers for RHEL and Fedora (#1465)"
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 31: Revert "Revert "Setting highest autoconnect priority for network-scripts""
RH-Commit: [2/3] bd662b768dc694c748cab9e36bc5ff0eb009e128 (eesposit/cloud-init-centos-)
RH-Bugzilla: 2107463 2104389 2117532 2098501
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
As NM is reverted, remove also documentation and any trace of it.
This reverts commit bbd9f47a7988e15a2823b065cd539d7c9562d77e.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
config/cloud.cfg.tmpl | 3 ---
doc/rtd/topics/network-config.rst | 12 +-----------
2 files changed, 1 insertion(+), 14 deletions(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index f4d2fd14..80ab4f96 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -353,7 +353,4 @@ system_info:
{% elif variant in ["dragonfly"] %}
network:
renderers: ['freebsd']
-{% elif variant in ["rhel", "fedora"] %}
- network:
- renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
{% endif %}
diff --git a/doc/rtd/topics/network-config.rst b/doc/rtd/topics/network-config.rst
index f503caab..c461a3fe 100644
--- a/doc/rtd/topics/network-config.rst
+++ b/doc/rtd/topics/network-config.rst
@@ -188,15 +188,6 @@ generated configuration into an internal network configuration state. From
this state `Cloud-init`_ delegates rendering of the configuration to Distro
supported formats. The following ``renderers`` are supported in cloud-init:
-- **NetworkManager**
-
-`NetworkManager <https://networkmanager.dev>`_ is the standard Linux network
-configuration tool suite. It supports a wide range of networking setups.
-Configuration is typically stored in ``/etc/NetworkManager``.
-
-It is the default for a number of Linux distributions, notably Fedora;
-CentOS/RHEL; and derivatives.
-
- **ENI**
/etc/network/interfaces or ``ENI`` is supported by the ``ifupdown`` package
@@ -224,7 +215,6 @@ is as follows:
- ENI
- Sysconfig
- Netplan
-- NetworkManager
When applying the policy, `Cloud-init`_ checks if the current instance has the
correct binaries and paths to support the renderer. The first renderer that
@@ -233,7 +223,7 @@ supplying an updated configuration in cloud-config. ::
system_info:
network:
- renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
+ renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
Network Configuration Tools
--
2.31.1

View File

@ -1,165 +0,0 @@
From f5e9ed6c698eddd30e8e97d6f71070e7b75b1381 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Mon, 30 May 2022 16:45:08 +0200
Subject: [PATCH 1/2] Support EC2 tags in instance metadata (#1309)
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 27: Support EC2 tags in instance metadata (#1309)
RH-Commit: [1/1] f6a03e1619316959d3cd1806981b0bebf12bd3b0 (eesposit/cloud-init-centos-)
RH-Bugzilla: 2091640
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
commit 40c52ce1f4049449b04f93226721f63af874c5c7
Author: Eduardo Dobay <edudobay@users.noreply.github.com>
Date: Wed Apr 6 01:28:01 2022 -0300
Support EC2 tags in instance metadata (#1309)
Add support for newer EC2 metadata versions (up to 2021-03-23), so that
tags can be retrieved from the `ds.meta_data.tags` field, as well as
with any new fields that might have been added since the 2018-09-24
version.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/sources/DataSourceEc2.py | 5 +++--
doc/rtd/topics/datasources/ec2.rst | 28 ++++++++++++++++++++++------
tests/unittests/sources/test_ec2.py | 26 +++++++++++++++++++++++++-
tools/.github-cla-signers | 1 +
4 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
index 03b3870c..a030b498 100644
--- a/cloudinit/sources/DataSourceEc2.py
+++ b/cloudinit/sources/DataSourceEc2.py
@@ -61,8 +61,9 @@ class DataSourceEc2(sources.DataSource):
min_metadata_version = "2009-04-04"
# Priority ordered list of additional metadata versions which will be tried
- # for extended metadata content. IPv6 support comes in 2016-09-02
- extended_metadata_versions = ["2018-09-24", "2016-09-02"]
+ # for extended metadata content. IPv6 support comes in 2016-09-02.
+ # Tags support comes in 2021-03-23.
+ extended_metadata_versions = ["2021-03-23", "2018-09-24", "2016-09-02"]
# Setup read_url parameters per get_url_params.
url_max_wait = 120
diff --git a/doc/rtd/topics/datasources/ec2.rst b/doc/rtd/topics/datasources/ec2.rst
index 94e4158d..77232269 100644
--- a/doc/rtd/topics/datasources/ec2.rst
+++ b/doc/rtd/topics/datasources/ec2.rst
@@ -38,11 +38,26 @@ Userdata is accessible via the following URL:
GET http://169.254.169.254/2009-04-04/user-data
1234,fred,reboot,true | 4512,jimbo, | 173,,,
-Note that there are multiple versions of this data provided, cloud-init
-by default uses **2009-04-04** but newer versions can be supported with
-relative ease (newer versions have more data exposed, while maintaining
-backward compatibility with the previous versions).
-Version **2016-09-02** is required for secondary IP address support.
+Note that there are multiple EC2 Metadata versions of this data provided
+to instances. cloud-init will attempt to use the most recent API version it
+supports in order to get latest API features and instance-data. If a given
+API version is not exposed to the instance, those API features will be
+unavailable to the instance.
+
+
++----------------+----------------------------------------------------------+
++ EC2 version | supported instance-data/feature |
++================+==========================================================+
++ **2021-03-23** | Required for Instance tag support. This feature must be |
+| | enabled individually on each instance. See the |
+| | `EC2 tags user guide`_. |
++----------------+----------------------------------------------------------+
+| **2016-09-02** | Required for secondary IP address support. |
++----------------+----------------------------------------------------------+
+| **2009-04-04** | Minimum supports EC2 API version for meta-data and |
+| | user-data. |
++----------------+----------------------------------------------------------+
+
To see which versions are supported from your cloud provider use the following
URL:
@@ -71,7 +86,7 @@ configuration (in `/etc/cloud/cloud.cfg` or `/etc/cloud/cloud.cfg.d/`).
The settings that may be configured are:
- * **metadata_urls**: This list of urls will be searched for an Ec2
+ * **metadata_urls**: This list of urls will be searched for an EC2
metadata service. The first entry that successfully returns a 200 response
for <url>/<version>/meta-data/instance-id will be selected.
(default: ['http://169.254.169.254', 'http://instance-data:8773']).
@@ -121,4 +136,5 @@ Notes
For example: the primary NIC will have a DHCP route-metric of 100,
the next NIC will be 200.
+.. _EC2 tags user guide: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#work-with-tags-in-IMDS
.. vi: textwidth=79
diff --git a/tests/unittests/sources/test_ec2.py b/tests/unittests/sources/test_ec2.py
index b376660d..7c8a5ea5 100644
--- a/tests/unittests/sources/test_ec2.py
+++ b/tests/unittests/sources/test_ec2.py
@@ -210,6 +210,17 @@ SECONDARY_IP_METADATA_2018_09_24 = {
M_PATH_NET = "cloudinit.sources.DataSourceEc2.net."
+TAGS_METADATA_2021_03_23 = {
+ **DEFAULT_METADATA,
+ "tags": {
+ "instance": {
+ "Environment": "production",
+ "Application": "test",
+ "TagWithoutValue": "",
+ }
+ },
+}
+
def _register_ssh_keys(rfunc, base_url, keys_data):
"""handle ssh key inconsistencies.
@@ -670,7 +681,7 @@ class TestEc2(test_helpers.HttprettyTestCase):
logs_with_redacted = [log for log in all_logs if REDACT_TOK in log]
logs_with_token = [log for log in all_logs if "API-TOKEN" in log]
self.assertEqual(1, len(logs_with_redacted_ttl))
- self.assertEqual(81, len(logs_with_redacted))
+ self.assertEqual(83, len(logs_with_redacted))
self.assertEqual(0, len(logs_with_token))
@mock.patch("cloudinit.net.dhcp.maybe_perform_dhcp_discovery")
@@ -811,6 +822,19 @@ class TestEc2(test_helpers.HttprettyTestCase):
)
self.assertIn("Crawl of metadata service took", self.logs.getvalue())
+ def test_get_instance_tags(self):
+ ds = self._setup_ds(
+ platform_data=self.valid_platform_data,
+ sys_cfg={"datasource": {"Ec2": {"strict_id": False}}},
+ md={"md": TAGS_METADATA_2021_03_23},
+ )
+ self.assertTrue(ds.get_data())
+ self.assertIn("tags", ds.metadata)
+ self.assertIn("instance", ds.metadata["tags"])
+ instance_tags = ds.metadata["tags"]["instance"]
+ self.assertEqual(instance_tags["Application"], "test")
+ self.assertEqual(instance_tags["Environment"], "production")
+
class TestGetSecondaryAddresses(test_helpers.CiTestCase):
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
index ac157a2f..9f71ea0c 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -26,6 +26,7 @@ dermotbradley
dhensby
eandersson
eb3095
+edudobay
emmanuelthome
eslerm
esposem
--
2.31.1

View File

@ -1,109 +0,0 @@
From 840d6f7ca86fe9822c613f0f2c21f136271ce3b6 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu, 19 May 2022 15:44:03 +0200
Subject: [PATCH 2/5] Use Network-Manager and Netplan as default renderers for
RHEL and Fedora (#1465)
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 24: Add native NetworkManager support (#1224)
RH-Commit: [2/3] e33081b15a8558967bb480ed659116e7e0872840 (eesposit/cloud-init-centos-)
RH-Bugzilla: 2056964
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
commit 7703aa98b89c8daba207c28a0422268ead10019a
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu May 19 15:05:01 2022 +0200
Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)
This is adapted from Neal Gompa's PR:
https://github.com/canonical/cloud-init/pull/1435
The only difference is that we are not modifying renderers.py (thus
modifying the priority of all distros), but just tweaking cloud.cfg to
apply this change to Fedora and RHEL. Other distros can optionally
add themselves afterwards.
net: Prefer Netplan and NetworkManager renderers by default
NetworkManager is used by default on a variety of Linux distributions,
and exists as a cross-distribution network management service.
Additionally, add information about the NetworkManager renderer to
the cloud-init documentation.
Because Netplan can be explicitly used to manage NetworkManager,
it needs to be preferred before NetworkManager.
This change is a follow-up to #1224, which added the native
NetworkManager renderer.
This patch has been deployed on Fedora's cloud-init package throughout
the development of Fedora Linux 36 to verify that it works.
This should also make it tremendously easier for Linux distributions
to use cloud-init because now a standard configuration is supported
by default.
Signed-off-by: Neal Gompa <ngompa13@gmail.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
config/cloud.cfg.tmpl | 3 +++
doc/rtd/topics/network-config.rst | 12 +++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index fb4b456c..86beee3c 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -330,4 +330,7 @@ system_info:
{% elif variant in ["dragonfly"] %}
network:
renderers: ['freebsd']
+{% elif variant in ["rhel", "fedora"] %}
+ network:
+ renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
{% endif %}
diff --git a/doc/rtd/topics/network-config.rst b/doc/rtd/topics/network-config.rst
index c461a3fe..f503caab 100644
--- a/doc/rtd/topics/network-config.rst
+++ b/doc/rtd/topics/network-config.rst
@@ -188,6 +188,15 @@ generated configuration into an internal network configuration state. From
this state `Cloud-init`_ delegates rendering of the configuration to Distro
supported formats. The following ``renderers`` are supported in cloud-init:
+- **NetworkManager**
+
+`NetworkManager <https://networkmanager.dev>`_ is the standard Linux network
+configuration tool suite. It supports a wide range of networking setups.
+Configuration is typically stored in ``/etc/NetworkManager``.
+
+It is the default for a number of Linux distributions, notably Fedora;
+CentOS/RHEL; and derivatives.
+
- **ENI**
/etc/network/interfaces or ``ENI`` is supported by the ``ifupdown`` package
@@ -215,6 +224,7 @@ is as follows:
- ENI
- Sysconfig
- Netplan
+- NetworkManager
When applying the policy, `Cloud-init`_ checks if the current instance has the
correct binaries and paths to support the renderer. The first renderer that
@@ -223,7 +233,7 @@ supplying an updated configuration in cloud-config. ::
system_info:
network:
- renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
+ renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
Network Configuration Tools
--
2.31.1

View File

@ -1,801 +0,0 @@
From d1790e6462e509e3cd87fc449df84fbd02ca1d89 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu, 2 Jun 2022 16:03:43 +0200
Subject: [PATCH 2/2] cc_set_hostname: do not write "localhost" when no
hostname is given (#1453)
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 28: cc_set_hostname: do not write "localhost" when no hostname is given (#1453)
RH-Commit: [1/1] 4370e9149371dc89be82cb05d30d33e4d2638cec (eesposit/cloud-init-centos-)
RH-Bugzilla: 1980403
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
commit 74e43496f353db52e15d96abeb54ad63baac5be9
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Tue May 31 16:03:44 2022 +0200
cc_set_hostname: do not write "localhost" when no hostname is given (#1453)
Systemd used to sometimes ignore localhost in /etc/hostnames, and many programs
like cloud-init used this as a workaround to set a default hostname.
From https://github.com/systemd/systemd/commit/d39079fcaa05e23540d2b1f0270fa31c22a7e9f1:
We would sometimes ignore localhost-style names in /etc/hostname. That is
brittle. If the user configured some hostname, it's most likely because they
want to use that as the hostname. If they don't want to use such a hostname,
they should just not create the config. Everything becomes simples if we just
use the configured hostname as-is.
This behaviour seems to have been a workaround for Anaconda installer and other
tools writing out /etc/hostname with the default of "localhost.localdomain".
Anaconda PR to stop doing that: rhinstaller/anaconda#3040.
That might have been useful as a work-around for other programs misbehaving if
/etc/hostname was not present, but nowadays it's not useful because systemd
mostly controls the hostname and it is perfectly happy without that file.
Apart from making things simpler, this allows users to set a hostname like
"localhost" and have it honoured, if such a whim strikes them.
As also suggested by the Anaconda PR, we need to stop writing default "localhost"
in /etc/hostnames, and let the right service (networking, user) do that if they
need to. Otherwise, "localhost" will permanently stay as hostname and will
prevent other tools like NetworkManager from setting the right one.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RHBZ: 1980403
Conflicts:
cloudinit/config/cc_update_etc_hosts.py
cloudinit/sources/DataSourceCloudSigma.py
cloudinit/util.py
tests/unittests/test_util.py
Additional imports and/or conditionals that are not present in this version
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/cmd/main.py | 2 +-
cloudinit/config/cc_apt_configure.py | 2 +-
cloudinit/config/cc_debug.py | 2 +-
cloudinit/config/cc_phone_home.py | 4 +-
cloudinit/config/cc_set_hostname.py | 6 ++-
cloudinit/config/cc_spacewalk.py | 2 +-
cloudinit/config/cc_update_etc_hosts.py | 4 +-
cloudinit/config/cc_update_hostname.py | 7 +++-
cloudinit/sources/DataSourceAliYun.py | 8 +++-
cloudinit/sources/DataSourceCloudSigma.py | 6 ++-
cloudinit/sources/DataSourceGCE.py | 5 ++-
cloudinit/sources/DataSourceScaleway.py | 3 +-
cloudinit/sources/__init__.py | 28 ++++++++++---
cloudinit/util.py | 29 +++++++++++---
.../unittests/config/test_cc_set_hostname.py | 40 ++++++++++++++++++-
tests/unittests/sources/test_aliyun.py | 2 +-
tests/unittests/sources/test_cloudsigma.py | 8 ++--
tests/unittests/sources/test_digitalocean.py | 2 +-
tests/unittests/sources/test_gce.py | 4 +-
tests/unittests/sources/test_hetzner.py | 2 +-
tests/unittests/sources/test_init.py | 29 +++++++++-----
tests/unittests/sources/test_scaleway.py | 2 +-
tests/unittests/sources/test_vmware.py | 4 +-
tests/unittests/test_util.py | 17 ++++----
tests/unittests/util.py | 3 +-
25 files changed, 166 insertions(+), 55 deletions(-)
diff --git a/cloudinit/cmd/main.py b/cloudinit/cmd/main.py
index c9be41b3..816d31aa 100644
--- a/cloudinit/cmd/main.py
+++ b/cloudinit/cmd/main.py
@@ -813,7 +813,7 @@ def _maybe_set_hostname(init, stage, retry_stage):
@param retry_stage: String represented logs upon error setting hostname.
"""
cloud = init.cloudify()
- (hostname, _fqdn) = util.get_hostname_fqdn(
+ (hostname, _fqdn, _) = util.get_hostname_fqdn(
init.cfg, cloud, metadata_only=True
)
if hostname: # meta-data or user-data hostname content
diff --git a/cloudinit/config/cc_apt_configure.py b/cloudinit/config/cc_apt_configure.py
index c558311a..0e6466ec 100644
--- a/cloudinit/config/cc_apt_configure.py
+++ b/cloudinit/config/cc_apt_configure.py
@@ -753,7 +753,7 @@ def search_for_mirror_dns(configured, mirrortype, cfg, cloud):
raise ValueError("unknown mirror type")
# if we have a fqdn, then search its domain portion first
- (_, fqdn) = util.get_hostname_fqdn(cfg, cloud)
+ fqdn = util.get_hostname_fqdn(cfg, cloud).fqdn
mydom = ".".join(fqdn.split(".")[1:])
if mydom:
doms.append(".%s" % mydom)
diff --git a/cloudinit/config/cc_debug.py b/cloudinit/config/cc_debug.py
index c51818c3..a00f2823 100644
--- a/cloudinit/config/cc_debug.py
+++ b/cloudinit/config/cc_debug.py
@@ -95,7 +95,7 @@ def handle(name, cfg, cloud, log, args):
"Datasource: %s\n" % (type_utils.obj_name(cloud.datasource))
)
to_print.write("Distro: %s\n" % (type_utils.obj_name(cloud.distro)))
- to_print.write("Hostname: %s\n" % (cloud.get_hostname(True)))
+ to_print.write("Hostname: %s\n" % (cloud.get_hostname(True).hostname))
to_print.write("Instance ID: %s\n" % (cloud.get_instance_id()))
to_print.write("Locale: %s\n" % (cloud.get_locale()))
to_print.write("Launch IDX: %s\n" % (cloud.launch_index))
diff --git a/cloudinit/config/cc_phone_home.py b/cloudinit/config/cc_phone_home.py
index a0e1da78..1cf270aa 100644
--- a/cloudinit/config/cc_phone_home.py
+++ b/cloudinit/config/cc_phone_home.py
@@ -119,8 +119,8 @@ def handle(name, cfg, cloud, log, args):
all_keys = {}
all_keys["instance_id"] = cloud.get_instance_id()
- all_keys["hostname"] = cloud.get_hostname()
- all_keys["fqdn"] = cloud.get_hostname(fqdn=True)
+ all_keys["hostname"] = cloud.get_hostname().hostname
+ all_keys["fqdn"] = cloud.get_hostname(fqdn=True).hostname
pubkeys = {
"pub_key_dsa": "/etc/ssh/ssh_host_dsa_key.pub",
diff --git a/cloudinit/config/cc_set_hostname.py b/cloudinit/config/cc_set_hostname.py
index eb0ca328..2674fa20 100644
--- a/cloudinit/config/cc_set_hostname.py
+++ b/cloudinit/config/cc_set_hostname.py
@@ -76,7 +76,7 @@ def handle(name, cfg, cloud, log, _args):
if hostname_fqdn is not None:
cloud.distro.set_option("prefer_fqdn_over_hostname", hostname_fqdn)
- (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
+ (hostname, fqdn, is_default) = util.get_hostname_fqdn(cfg, cloud)
# Check for previous successful invocation of set-hostname
# set-hostname artifact file accounts for both hostname and fqdn
@@ -94,6 +94,10 @@ def handle(name, cfg, cloud, log, _args):
if not hostname_changed:
log.debug("No hostname changes. Skipping set-hostname")
return
+ if is_default and hostname == "localhost":
+ # https://github.com/systemd/systemd/commit/d39079fcaa05e23540d2b1f0270fa31c22a7e9f1
+ log.debug("Hostname is localhost. Let other services handle this.")
+ return
log.debug("Setting the hostname to %s (%s)", fqdn, hostname)
try:
cloud.distro.set_hostname(hostname, fqdn)
diff --git a/cloudinit/config/cc_spacewalk.py b/cloudinit/config/cc_spacewalk.py
index 3fa6c388..419c8b32 100644
--- a/cloudinit/config/cc_spacewalk.py
+++ b/cloudinit/config/cc_spacewalk.py
@@ -89,7 +89,7 @@ def handle(name, cfg, cloud, log, _args):
if not is_registered():
do_register(
spacewalk_server,
- cloud.datasource.get_hostname(fqdn=True),
+ cloud.datasource.get_hostname(fqdn=True).hostname,
proxy=cfg.get("proxy"),
log=log,
activation_key=cfg.get("activation_key"),
diff --git a/cloudinit/config/cc_update_etc_hosts.py b/cloudinit/config/cc_update_etc_hosts.py
index f0aa9b0f..d2ee6f45 100644
--- a/cloudinit/config/cc_update_etc_hosts.py
+++ b/cloudinit/config/cc_update_etc_hosts.py
@@ -62,7 +62,7 @@ def handle(name, cfg, cloud, log, _args):
hosts_fn = cloud.distro.hosts_fn
if util.translate_bool(manage_hosts, addons=["template"]):
- (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
+ (hostname, fqdn, _) = util.get_hostname_fqdn(cfg, cloud)
if not hostname:
log.warning(
"Option 'manage_etc_hosts' was set, but no hostname was found"
@@ -84,7 +84,7 @@ def handle(name, cfg, cloud, log, _args):
)
elif manage_hosts == "localhost":
- (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
+ (hostname, fqdn, _) = util.get_hostname_fqdn(cfg, cloud)
if not hostname:
log.warning(
"Option 'manage_etc_hosts' was set, but no hostname was found"
diff --git a/cloudinit/config/cc_update_hostname.py b/cloudinit/config/cc_update_hostname.py
index 09f6f6da..e2046020 100644
--- a/cloudinit/config/cc_update_hostname.py
+++ b/cloudinit/config/cc_update_hostname.py
@@ -56,7 +56,12 @@ def handle(name, cfg, cloud, log, _args):
if hostname_fqdn is not None:
cloud.distro.set_option("prefer_fqdn_over_hostname", hostname_fqdn)
- (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
+ (hostname, fqdn, is_default) = util.get_hostname_fqdn(cfg, cloud)
+ if is_default and hostname == "localhost":
+ # https://github.com/systemd/systemd/commit/d39079fcaa05e23540d2b1f0270fa31c22a7e9f1
+ log.debug("Hostname is localhost. Let other services handle this.")
+ return
+
try:
prev_fn = os.path.join(cloud.get_cpath("data"), "previous-hostname")
log.debug("Updating hostname to %s (%s)", fqdn, hostname)
diff --git a/cloudinit/sources/DataSourceAliYun.py b/cloudinit/sources/DataSourceAliYun.py
index 37f512e3..b9390aca 100644
--- a/cloudinit/sources/DataSourceAliYun.py
+++ b/cloudinit/sources/DataSourceAliYun.py
@@ -2,6 +2,7 @@
from cloudinit import dmi, sources
from cloudinit.sources import DataSourceEc2 as EC2
+from cloudinit.sources import DataSourceHostname
ALIYUN_PRODUCT = "Alibaba Cloud ECS"
@@ -16,7 +17,12 @@ class DataSourceAliYun(EC2.DataSourceEc2):
extended_metadata_versions = []
def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
- return self.metadata.get("hostname", "localhost.localdomain")
+ hostname = self.metadata.get("hostname")
+ is_default = False
+ if hostname is None:
+ hostname = "localhost.localdomain"
+ is_default = True
+ return DataSourceHostname(hostname, is_default)
def get_public_ssh_keys(self):
return parse_public_keys(self.metadata.get("public-keys", {}))
diff --git a/cloudinit/sources/DataSourceCloudSigma.py b/cloudinit/sources/DataSourceCloudSigma.py
index de71c3e9..91ebb084 100644
--- a/cloudinit/sources/DataSourceCloudSigma.py
+++ b/cloudinit/sources/DataSourceCloudSigma.py
@@ -11,6 +11,7 @@ from cloudinit import dmi
from cloudinit import log as logging
from cloudinit import sources
from cloudinit.cs_utils import SERIAL_PORT, Cepko
+from cloudinit.sources import DataSourceHostname
LOG = logging.getLogger(__name__)
@@ -90,9 +91,10 @@ class DataSourceCloudSigma(sources.DataSource):
the first part from uuid is being used.
"""
if re.match(r"^[A-Za-z0-9 -_\.]+$", self.metadata["name"]):
- return self.metadata["name"][:61]
+ ret = self.metadata["name"][:61]
else:
- return self.metadata["uuid"].split("-")[0]
+ ret = self.metadata["uuid"].split("-")[0]
+ return DataSourceHostname(ret, False)
def get_public_ssh_keys(self):
return [self.ssh_public_key]
diff --git a/cloudinit/sources/DataSourceGCE.py b/cloudinit/sources/DataSourceGCE.py
index c470bea8..f7ec6b52 100644
--- a/cloudinit/sources/DataSourceGCE.py
+++ b/cloudinit/sources/DataSourceGCE.py
@@ -12,6 +12,7 @@ from cloudinit import log as logging
from cloudinit import sources, url_helper, util
from cloudinit.distros import ug_util
from cloudinit.net.dhcp import EphemeralDHCPv4
+from cloudinit.sources import DataSourceHostname
LOG = logging.getLogger(__name__)
@@ -122,7 +123,9 @@ class DataSourceGCE(sources.DataSource):
def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
# GCE has long FDQN's and has asked for short hostnames.
- return self.metadata["local-hostname"].split(".")[0]
+ return DataSourceHostname(
+ self.metadata["local-hostname"].split(".")[0], False
+ )
@property
def availability_zone(self):
diff --git a/cloudinit/sources/DataSourceScaleway.py b/cloudinit/sources/DataSourceScaleway.py
index 8e5dd82c..8f08dc6d 100644
--- a/cloudinit/sources/DataSourceScaleway.py
+++ b/cloudinit/sources/DataSourceScaleway.py
@@ -30,6 +30,7 @@ from cloudinit import log as logging
from cloudinit import net, sources, url_helper, util
from cloudinit.event import EventScope, EventType
from cloudinit.net.dhcp import EphemeralDHCPv4, NoDHCPLeaseError
+from cloudinit.sources import DataSourceHostname
LOG = logging.getLogger(__name__)
@@ -282,7 +283,7 @@ class DataSourceScaleway(sources.DataSource):
return ssh_keys
def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
- return self.metadata["hostname"]
+ return DataSourceHostname(self.metadata["hostname"], False)
@property
def availability_zone(self):
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 88028cfa..77b24fd7 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -148,6 +148,11 @@ URLParams = namedtuple(
],
)
+DataSourceHostname = namedtuple(
+ "DataSourceHostname",
+ ["hostname", "is_default"],
+)
+
class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
@@ -291,7 +296,7 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
def _get_standardized_metadata(self, instance_data):
"""Return a dictionary of standardized metadata keys."""
- local_hostname = self.get_hostname()
+ local_hostname = self.get_hostname().hostname
instance_id = self.get_instance_id()
availability_zone = self.availability_zone
# In the event of upgrade from existing cloudinit, pickled datasource
@@ -697,22 +702,33 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
@param metadata_only: Boolean, set True to avoid looking up hostname
if meta-data doesn't have local-hostname present.
- @return: hostname or qualified hostname. Optionally return None when
+ @return: a DataSourceHostname namedtuple
+ <hostname or qualified hostname>, <is_default> (str, bool).
+ is_default is a bool and
+ it's true only if hostname is localhost and was
+ returned by util.get_hostname() as a default.
+ This is used to differentiate with a user-defined
+ localhost hostname.
+ Optionally return (None, False) when
metadata_only is True and local-hostname data is not available.
"""
defdomain = "localdomain"
defhost = "localhost"
domain = defdomain
+ is_default = False
if not self.metadata or not self.metadata.get("local-hostname"):
if metadata_only:
- return None
+ return DataSourceHostname(None, is_default)
# this is somewhat questionable really.
# the cloud datasource was asked for a hostname
# and didn't have one. raising error might be more appropriate
# but instead, basically look up the existing hostname
toks = []
hostname = util.get_hostname()
+ if hostname == "localhost":
+ # default hostname provided by socket.gethostname()
+ is_default = True
hosts_fqdn = util.get_fqdn_from_hosts(hostname)
if hosts_fqdn and hosts_fqdn.find(".") > 0:
toks = str(hosts_fqdn).split(".")
@@ -745,9 +761,9 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
hostname = toks[0]
if fqdn and domain != defdomain:
- return "%s.%s" % (hostname, domain)
- else:
- return hostname
+ hostname = "%s.%s" % (hostname, domain)
+
+ return DataSourceHostname(hostname, is_default)
def get_package_mirror_info(self):
return self.distro.get_package_mirror_info(data_source=self)
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 569fc215..4cb21551 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -32,7 +32,8 @@ import subprocess
import sys
import time
from base64 import b64decode, b64encode
-from errno import ENOENT
+from collections import deque, namedtuple
+from errno import EACCES, ENOENT
from functools import lru_cache
from typing import List
from urllib import parse
@@ -1072,6 +1073,12 @@ def dos2unix(contents):
return contents.replace("\r\n", "\n")
+HostnameFqdnInfo = namedtuple(
+ "HostnameFqdnInfo",
+ ["hostname", "fqdn", "is_default"],
+)
+
+
def get_hostname_fqdn(cfg, cloud, metadata_only=False):
"""Get hostname and fqdn from config if present and fallback to cloud.
@@ -1079,9 +1086,17 @@ def get_hostname_fqdn(cfg, cloud, metadata_only=False):
@param cloud: Cloud instance from init.cloudify().
@param metadata_only: Boolean, set True to only query cloud meta-data,
returning None if not present in meta-data.
- @return: a Tuple of strings <hostname>, <fqdn>. Values can be none when
+ @return: a namedtuple of
+ <hostname>, <fqdn>, <is_default> (str, str, bool).
+ Values can be none when
metadata_only is True and no cfg or metadata provides hostname info.
+ is_default is a bool and
+ it's true only if hostname is localhost and was
+ returned by util.get_hostname() as a default.
+ This is used to differentiate with a user-defined
+ localhost hostname.
"""
+ is_default = False
if "fqdn" in cfg:
# user specified a fqdn. Default hostname then is based off that
fqdn = cfg["fqdn"]
@@ -1095,12 +1110,16 @@ def get_hostname_fqdn(cfg, cloud, metadata_only=False):
else:
# no fqdn set, get fqdn from cloud.
# get hostname from cfg if available otherwise cloud
- fqdn = cloud.get_hostname(fqdn=True, metadata_only=metadata_only)
+ fqdn = cloud.get_hostname(
+ fqdn=True, metadata_only=metadata_only
+ ).hostname
if "hostname" in cfg:
hostname = cfg["hostname"]
else:
- hostname = cloud.get_hostname(metadata_only=metadata_only)
- return (hostname, fqdn)
+ hostname, is_default = cloud.get_hostname(
+ metadata_only=metadata_only
+ )
+ return HostnameFqdnInfo(hostname, fqdn, is_default)
def get_fqdn_from_hosts(hostname, filename="/etc/hosts"):
diff --git a/tests/unittests/config/test_cc_set_hostname.py b/tests/unittests/config/test_cc_set_hostname.py
index fd994c4e..3d1d86ee 100644
--- a/tests/unittests/config/test_cc_set_hostname.py
+++ b/tests/unittests/config/test_cc_set_hostname.py
@@ -11,6 +11,7 @@ from configobj import ConfigObj
from cloudinit import cloud, distros, helpers, util
from cloudinit.config import cc_set_hostname
+from cloudinit.sources import DataSourceNone
from tests.unittests import helpers as t_help
LOG = logging.getLogger(__name__)
@@ -153,7 +154,8 @@ class TestHostname(t_help.FilesystemMockingTestCase):
)
] not in m_subp.call_args_list
- def test_multiple_calls_skips_unchanged_hostname(self):
+ @mock.patch("cloudinit.util.get_hostname", return_value="localhost")
+ def test_multiple_calls_skips_unchanged_hostname(self, get_hostname):
"""Only new hostname or fqdn values will generate a hostname call."""
distro = self._fetch_distro("debian")
paths = helpers.Paths({"cloud_dir": self.tmp})
@@ -182,6 +184,42 @@ class TestHostname(t_help.FilesystemMockingTestCase):
self.logs.getvalue(),
)
+ @mock.patch("cloudinit.util.get_hostname", return_value="localhost")
+ def test_localhost_default_hostname(self, get_hostname):
+ """
+ No hostname set. Default value returned is localhost,
+ but we shouldn't write it in /etc/hostname
+ """
+ distro = self._fetch_distro("debian")
+ paths = helpers.Paths({"cloud_dir": self.tmp})
+ ds = DataSourceNone.DataSourceNone({}, None, paths)
+ cc = cloud.Cloud(ds, paths, {}, distro, None)
+ self.patchUtils(self.tmp)
+
+ util.write_file("/etc/hostname", "")
+ cc_set_hostname.handle("cc_set_hostname", {}, cc, LOG, [])
+ contents = util.load_file("/etc/hostname")
+ self.assertEqual("", contents.strip())
+
+ @mock.patch("cloudinit.util.get_hostname", return_value="localhost")
+ def test_localhost_user_given_hostname(self, get_hostname):
+ """
+ User set hostname is localhost. We should write it in /etc/hostname
+ """
+ distro = self._fetch_distro("debian")
+ paths = helpers.Paths({"cloud_dir": self.tmp})
+ ds = DataSourceNone.DataSourceNone({}, None, paths)
+ cc = cloud.Cloud(ds, paths, {}, distro, None)
+ self.patchUtils(self.tmp)
+
+ # user-provided localhost should not be ignored
+ util.write_file("/etc/hostname", "")
+ cc_set_hostname.handle(
+ "cc_set_hostname", {"hostname": "localhost"}, cc, LOG, []
+ )
+ contents = util.load_file("/etc/hostname")
+ self.assertEqual("localhost", contents.strip())
+
def test_error_on_distro_set_hostname_errors(self):
"""Raise SetHostnameError on exceptions from distro.set_hostname."""
distro = self._fetch_distro("debian")
diff --git a/tests/unittests/sources/test_aliyun.py b/tests/unittests/sources/test_aliyun.py
index 8a61d5ee..e628dc02 100644
--- a/tests/unittests/sources/test_aliyun.py
+++ b/tests/unittests/sources/test_aliyun.py
@@ -149,7 +149,7 @@ class TestAliYunDatasource(test_helpers.HttprettyTestCase):
def _test_host_name(self):
self.assertEqual(
- self.default_metadata["hostname"], self.ds.get_hostname()
+ self.default_metadata["hostname"], self.ds.get_hostname().hostname
)
@mock.patch("cloudinit.sources.DataSourceAliYun._is_aliyun")
diff --git a/tests/unittests/sources/test_cloudsigma.py b/tests/unittests/sources/test_cloudsigma.py
index a2f26245..3dca7ea8 100644
--- a/tests/unittests/sources/test_cloudsigma.py
+++ b/tests/unittests/sources/test_cloudsigma.py
@@ -58,12 +58,14 @@ class DataSourceCloudSigmaTest(test_helpers.CiTestCase):
def test_get_hostname(self):
self.datasource.get_data()
- self.assertEqual("test_server", self.datasource.get_hostname())
+ self.assertEqual(
+ "test_server", self.datasource.get_hostname().hostname
+ )
self.datasource.metadata["name"] = ""
- self.assertEqual("65b2fb23", self.datasource.get_hostname())
+ self.assertEqual("65b2fb23", self.datasource.get_hostname().hostname)
utf8_hostname = b"\xd1\x82\xd0\xb5\xd1\x81\xd1\x82".decode("utf-8")
self.datasource.metadata["name"] = utf8_hostname
- self.assertEqual("65b2fb23", self.datasource.get_hostname())
+ self.assertEqual("65b2fb23", self.datasource.get_hostname().hostname)
def test_get_public_ssh_keys(self):
self.datasource.get_data()
diff --git a/tests/unittests/sources/test_digitalocean.py b/tests/unittests/sources/test_digitalocean.py
index f3e6224e..47e46c66 100644
--- a/tests/unittests/sources/test_digitalocean.py
+++ b/tests/unittests/sources/test_digitalocean.py
@@ -178,7 +178,7 @@ class TestDataSourceDigitalOcean(CiTestCase):
self.assertEqual(DO_META.get("vendor_data"), ds.get_vendordata_raw())
self.assertEqual(DO_META.get("region"), ds.availability_zone)
self.assertEqual(DO_META.get("droplet_id"), ds.get_instance_id())
- self.assertEqual(DO_META.get("hostname"), ds.get_hostname())
+ self.assertEqual(DO_META.get("hostname"), ds.get_hostname().hostname)
# Single key
self.assertEqual(
diff --git a/tests/unittests/sources/test_gce.py b/tests/unittests/sources/test_gce.py
index e030931b..1ce0c6ec 100644
--- a/tests/unittests/sources/test_gce.py
+++ b/tests/unittests/sources/test_gce.py
@@ -126,7 +126,7 @@ class TestDataSourceGCE(test_helpers.HttprettyTestCase):
self.ds.get_data()
shostname = GCE_META.get("instance/hostname").split(".")[0]
- self.assertEqual(shostname, self.ds.get_hostname())
+ self.assertEqual(shostname, self.ds.get_hostname().hostname)
self.assertEqual(
GCE_META.get("instance/id"), self.ds.get_instance_id()
@@ -147,7 +147,7 @@ class TestDataSourceGCE(test_helpers.HttprettyTestCase):
)
shostname = GCE_META_PARTIAL.get("instance/hostname").split(".")[0]
- self.assertEqual(shostname, self.ds.get_hostname())
+ self.assertEqual(shostname, self.ds.get_hostname().hostname)
def test_userdata_no_encoding(self):
"""check that user-data is read."""
diff --git a/tests/unittests/sources/test_hetzner.py b/tests/unittests/sources/test_hetzner.py
index f80ed45f..193b7e42 100644
--- a/tests/unittests/sources/test_hetzner.py
+++ b/tests/unittests/sources/test_hetzner.py
@@ -116,7 +116,7 @@ class TestDataSourceHetzner(CiTestCase):
self.assertTrue(m_readmd.called)
- self.assertEqual(METADATA.get("hostname"), ds.get_hostname())
+ self.assertEqual(METADATA.get("hostname"), ds.get_hostname().hostname)
self.assertEqual(METADATA.get("public-keys"), ds.get_public_ssh_keys())
diff --git a/tests/unittests/sources/test_init.py b/tests/unittests/sources/test_init.py
index ce8fc970..79fc9c5b 100644
--- a/tests/unittests/sources/test_init.py
+++ b/tests/unittests/sources/test_init.py
@@ -272,9 +272,11 @@ class TestDataSource(CiTestCase):
self.assertEqual(
"test-subclass-hostname", datasource.metadata["local-hostname"]
)
- self.assertEqual("test-subclass-hostname", datasource.get_hostname())
+ self.assertEqual(
+ "test-subclass-hostname", datasource.get_hostname().hostname
+ )
datasource.metadata["local-hostname"] = "hostname.my.domain.com"
- self.assertEqual("hostname", datasource.get_hostname())
+ self.assertEqual("hostname", datasource.get_hostname().hostname)
def test_get_hostname_with_fqdn_returns_local_hostname_with_domain(self):
"""Datasource.get_hostname with fqdn set gets qualified hostname."""
@@ -285,7 +287,8 @@ class TestDataSource(CiTestCase):
self.assertTrue(datasource.get_data())
datasource.metadata["local-hostname"] = "hostname.my.domain.com"
self.assertEqual(
- "hostname.my.domain.com", datasource.get_hostname(fqdn=True)
+ "hostname.my.domain.com",
+ datasource.get_hostname(fqdn=True).hostname,
)
def test_get_hostname_without_metadata_uses_system_hostname(self):
@@ -300,10 +303,12 @@ class TestDataSource(CiTestCase):
with mock.patch(mock_fqdn) as m_fqdn:
m_gethost.return_value = "systemhostname.domain.com"
m_fqdn.return_value = None # No maching fqdn in /etc/hosts
- self.assertEqual("systemhostname", datasource.get_hostname())
+ self.assertEqual(
+ "systemhostname", datasource.get_hostname().hostname
+ )
self.assertEqual(
"systemhostname.domain.com",
- datasource.get_hostname(fqdn=True),
+ datasource.get_hostname(fqdn=True).hostname,
)
def test_get_hostname_without_metadata_returns_none(self):
@@ -316,9 +321,13 @@ class TestDataSource(CiTestCase):
mock_fqdn = "cloudinit.sources.util.get_fqdn_from_hosts"
with mock.patch("cloudinit.sources.util.get_hostname") as m_gethost:
with mock.patch(mock_fqdn) as m_fqdn:
- self.assertIsNone(datasource.get_hostname(metadata_only=True))
self.assertIsNone(
- datasource.get_hostname(fqdn=True, metadata_only=True)
+ datasource.get_hostname(metadata_only=True).hostname
+ )
+ self.assertIsNone(
+ datasource.get_hostname(
+ fqdn=True, metadata_only=True
+ ).hostname
)
self.assertEqual([], m_gethost.call_args_list)
self.assertEqual([], m_fqdn.call_args_list)
@@ -335,10 +344,12 @@ class TestDataSource(CiTestCase):
with mock.patch(mock_fqdn) as m_fqdn:
m_gethost.return_value = "systemhostname.domain.com"
m_fqdn.return_value = "fqdnhostname.domain.com"
- self.assertEqual("fqdnhostname", datasource.get_hostname())
+ self.assertEqual(
+ "fqdnhostname", datasource.get_hostname().hostname
+ )
self.assertEqual(
"fqdnhostname.domain.com",
- datasource.get_hostname(fqdn=True),
+ datasource.get_hostname(fqdn=True).hostname,
)
def test_get_data_does_not_write_instance_data_on_failure(self):
diff --git a/tests/unittests/sources/test_scaleway.py b/tests/unittests/sources/test_scaleway.py
index d7e8b969..56735dd0 100644
--- a/tests/unittests/sources/test_scaleway.py
+++ b/tests/unittests/sources/test_scaleway.py
@@ -236,7 +236,7 @@ class TestDataSourceScaleway(HttprettyTestCase):
].sort(),
)
self.assertEqual(
- self.datasource.get_hostname(),
+ self.datasource.get_hostname().hostname,
MetadataResponses.FAKE_METADATA["hostname"],
)
self.assertEqual(
diff --git a/tests/unittests/sources/test_vmware.py b/tests/unittests/sources/test_vmware.py
index dd331349..753bb774 100644
--- a/tests/unittests/sources/test_vmware.py
+++ b/tests/unittests/sources/test_vmware.py
@@ -368,7 +368,9 @@ class TestDataSourceVMwareGuestInfo_InvalidPlatform(FilesystemMockingTestCase):
def assert_metadata(test_obj, ds, metadata):
test_obj.assertEqual(metadata.get("instance-id"), ds.get_instance_id())
- test_obj.assertEqual(metadata.get("local-hostname"), ds.get_hostname())
+ test_obj.assertEqual(
+ metadata.get("local-hostname"), ds.get_hostname().hostname
+ )
expected_public_keys = metadata.get("public_keys")
if not isinstance(expected_public_keys, list):
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 3765511b..528b7f36 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -19,6 +19,7 @@ import pytest
import yaml
from cloudinit import importer, subp, util
+from cloudinit.sources import DataSourceHostname
from tests.unittests import helpers
from tests.unittests.helpers import CiTestCase
@@ -331,8 +332,8 @@ class FakeCloud(object):
myargs["metadata_only"] = metadata_only
self.calls.append(myargs)
if fqdn:
- return self.fqdn
- return self.hostname
+ return DataSourceHostname(self.fqdn, False)
+ return DataSourceHostname(self.hostname, False)
class TestUtil(CiTestCase):
@@ -420,7 +421,7 @@ class TestShellify(CiTestCase):
class TestGetHostnameFqdn(CiTestCase):
def test_get_hostname_fqdn_from_only_cfg_fqdn(self):
"""When cfg only has the fqdn key, derive hostname and fqdn from it."""
- hostname, fqdn = util.get_hostname_fqdn(
+ hostname, fqdn, _ = util.get_hostname_fqdn(
cfg={"fqdn": "myhost.domain.com"}, cloud=None
)
self.assertEqual("myhost", hostname)
@@ -428,7 +429,7 @@ class TestGetHostnameFqdn(CiTestCase):
def test_get_hostname_fqdn_from_cfg_fqdn_and_hostname(self):
"""When cfg has both fqdn and hostname keys, return them."""
- hostname, fqdn = util.get_hostname_fqdn(
+ hostname, fqdn, _ = util.get_hostname_fqdn(
cfg={"fqdn": "myhost.domain.com", "hostname": "other"}, cloud=None
)
self.assertEqual("other", hostname)
@@ -436,7 +437,7 @@ class TestGetHostnameFqdn(CiTestCase):
def test_get_hostname_fqdn_from_cfg_hostname_with_domain(self):
"""When cfg has only hostname key which represents a fqdn, use that."""
- hostname, fqdn = util.get_hostname_fqdn(
+ hostname, fqdn, _ = util.get_hostname_fqdn(
cfg={"hostname": "myhost.domain.com"}, cloud=None
)
self.assertEqual("myhost", hostname)
@@ -445,7 +446,7 @@ class TestGetHostnameFqdn(CiTestCase):
def test_get_hostname_fqdn_from_cfg_hostname_without_domain(self):
"""When cfg has a hostname without a '.' query cloud.get_hostname."""
mycloud = FakeCloud("cloudhost", "cloudhost.mycloud.com")
- hostname, fqdn = util.get_hostname_fqdn(
+ hostname, fqdn, _ = util.get_hostname_fqdn(
cfg={"hostname": "myhost"}, cloud=mycloud
)
self.assertEqual("myhost", hostname)
@@ -457,7 +458,7 @@ class TestGetHostnameFqdn(CiTestCase):
def test_get_hostname_fqdn_from_without_fqdn_or_hostname(self):
"""When cfg has neither hostname nor fqdn cloud.get_hostname."""
mycloud = FakeCloud("cloudhost", "cloudhost.mycloud.com")
- hostname, fqdn = util.get_hostname_fqdn(cfg={}, cloud=mycloud)
+ hostname, fqdn, _ = util.get_hostname_fqdn(cfg={}, cloud=mycloud)
self.assertEqual("cloudhost", hostname)
self.assertEqual("cloudhost.mycloud.com", fqdn)
self.assertEqual(
@@ -468,7 +469,7 @@ class TestGetHostnameFqdn(CiTestCase):
def test_get_hostname_fqdn_from_passes_metadata_only_to_cloud(self):
"""Calls to cloud.get_hostname pass the metadata_only parameter."""
mycloud = FakeCloud("cloudhost", "cloudhost.mycloud.com")
- _hn, _fqdn = util.get_hostname_fqdn(
+ _hn, _fqdn, _def_hostname = util.get_hostname_fqdn(
cfg={}, cloud=mycloud, metadata_only=True
)
self.assertEqual(
diff --git a/tests/unittests/util.py b/tests/unittests/util.py
index 79a6e1d0..6fb39506 100644
--- a/tests/unittests/util.py
+++ b/tests/unittests/util.py
@@ -1,5 +1,6 @@
# This file is part of cloud-init. See LICENSE file for license information.
from cloudinit import cloud, distros, helpers
+from cloudinit.sources import DataSourceHostname
from cloudinit.sources.DataSourceNone import DataSourceNone
@@ -37,7 +38,7 @@ def abstract_to_concrete(abclass):
class DataSourceTesting(DataSourceNone):
def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
- return "hostname"
+ return DataSourceHostname("hostname", False)
def persist_instance_data(self):
return True
--
2.31.1

View File

@ -1,77 +0,0 @@
From d51546dee17c9abbb9d44fb33cf81be085a46dae Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu, 19 Jan 2023 09:40:10 +0100
Subject: [PATCH 22/22] cc_set_hostname: ignore
/var/lib/cloud/data/set-hostname if it's empty (#1967)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2140893
commit 9c7502a801763520639c66125eb373123d1e4f44
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Wed Jan 18 17:55:16 2023 +0100
cc_set_hostname: ignore /var/lib/cloud/data/set-hostname if it's empty (#1967)
If the file exists but is empty, do nothing.
Otherwise cloud-init will crash because it does not handle the empty file.
RHBZ: 2140893
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
cloudinit/config/cc_set_hostname.py | 2 +-
tests/unittests/config/test_cc_set_hostname.py | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/cloudinit/config/cc_set_hostname.py b/cloudinit/config/cc_set_hostname.py
index 2674fa20..7e3d5b74 100644
--- a/cloudinit/config/cc_set_hostname.py
+++ b/cloudinit/config/cc_set_hostname.py
@@ -86,7 +86,7 @@ def handle(name, cfg, cloud, log, _args):
# distro._read_hostname implementation so we only validate one artifact.
prev_fn = os.path.join(cloud.get_cpath("data"), "set-hostname")
prev_hostname = {}
- if os.path.exists(prev_fn):
+ if os.path.exists(prev_fn) and os.stat(prev_fn).st_size > 0:
prev_hostname = util.load_json(util.load_file(prev_fn))
hostname_changed = hostname != prev_hostname.get(
"hostname"
diff --git a/tests/unittests/config/test_cc_set_hostname.py b/tests/unittests/config/test_cc_set_hostname.py
index 3d1d86ee..2c92949f 100644
--- a/tests/unittests/config/test_cc_set_hostname.py
+++ b/tests/unittests/config/test_cc_set_hostname.py
@@ -5,6 +5,7 @@ import os
import shutil
import tempfile
from io import BytesIO
+from pathlib import Path
from unittest import mock
from configobj import ConfigObj
@@ -242,5 +243,21 @@ class TestHostname(t_help.FilesystemMockingTestCase):
str(ctx_mgr.exception),
)
+ def test_ignore_empty_previous_artifact_file(self):
+ cfg = {
+ "hostname": "blah",
+ "fqdn": "blah.blah.blah.yahoo.com",
+ }
+ distro = self._fetch_distro("debian")
+ paths = helpers.Paths({"cloud_dir": self.tmp})
+ ds = None
+ cc = cloud.Cloud(ds, paths, {}, distro, None)
+ self.patchUtils(self.tmp)
+ prev_fn = Path(cc.get_cpath("data")) / "set-hostname"
+ prev_fn.touch()
+ cc_set_hostname.handle("cc_set_hostname", cfg, cc, LOG, [])
+ contents = util.load_file("/etc/hostname")
+ self.assertEqual("blah", contents.strip())
+
# vi: ts=4 expandtab
--
2.39.1

View File

@ -1,139 +0,0 @@
From dd5ae3081491a2a98bd74e1655b22c9354707630 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu, 8 Sep 2022 17:46:45 +0200
Subject: [PATCH] cloud.cfg.tmpl: make sure "centos" settings are identical to
"rhel" (#1639)
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2115576
commit 7593243a1abe2ccaf4698579720999380a4da73b
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Wed Sep 7 14:53:26 2022 +0200
cloud.cfg.tmpl: make sure "centos" settings are identical to "rhel" (#1639)
We have a couple of bugs where centos does not have the default user as rhel.
This PR makes sure the configuration is exactly the same.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RHBZ: 2115565
RHBZ: 2115576
Conflicts:
config/cloud.cfg.tmpl: "openmandriva" distro added in the options
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
config/cloud.cfg.tmpl | 27 +++++++++++++------------
tests/unittests/test_render_cloudcfg.py | 1 +
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 80ab4f96..08b6efbc 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -2,6 +2,7 @@
# The top level settings are used as module
# and system configuration.
{% set is_bsd = variant in ["dragonfly", "freebsd", "netbsd", "openbsd"] %}
+{% set is_rhel = variant in ["rhel", "centos"] %}
{% if is_bsd %}
syslog_fix_perms: root:wheel
{% elif variant in ["suse"] %}
@@ -32,9 +33,9 @@ disable_root: false
disable_root: true
{% endif %}
-{% if variant in ["almalinux", "alpine", "amazon", "centos", "cloudlinux", "eurolinux",
- "fedora", "miraclelinux", "openEuler", "rhel", "rocky", "virtuozzo"] %}
-{% if variant == "rhel" %}
+{% if variant in ["almalinux", "alpine", "amazon", "cloudlinux", "eurolinux",
+ "fedora", "miraclelinux", "openEuler", "openmandriva", "rocky", "virtuozzo"] or is_rhel %}
+{% if is_rhel %}
mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service,_netdev', '0', '2']
{% else %}
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
@@ -70,7 +71,7 @@ network:
config: disabled
{% endif %}
-{% if variant == "rhel" %}
+{% if is_rhel %}
# Default redhat settings:
ssh_deletekeys: true
ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
@@ -119,16 +120,16 @@ cloud_config_modules:
{% endif %}
{% if variant not in ["photon"] %}
- ssh-import-id
-{% if variant not in ["rhel"] %}
+{% if not is_rhel %}
- keyboard
{% endif %}
- locale
{% endif %}
- set-passwords
-{% if variant in ["rhel"] %}
+{% if is_rhel %}
- rh_subscription
{% endif %}
-{% if variant in ["rhel", "fedora", "photon"] %}
+{% if variant in ["fedora", "openmandriva", "photon"] or is_rhel %}
{% if variant not in ["photon"] %}
- spacewalk
{% endif %}
@@ -193,9 +194,9 @@ cloud_final_modules:
# (not accessible to handlers/transforms)
system_info:
# This will affect which distro class gets used
-{% if variant in ["almalinux", "alpine", "amazon", "arch", "centos", "cloudlinux", "debian",
+{% if variant in ["almalinux", "alpine", "amazon", "arch", "cloudlinux", "debian",
"eurolinux", "fedora", "freebsd", "gentoo", "netbsd", "miraclelinux", "openbsd", "openEuler",
- "photon", "rhel", "rocky", "suse", "ubuntu", "virtuozzo"] %}
+ "openmandriva", "photon", "rocky", "suse", "ubuntu", "virtuozzo"] or is_rhel %}
distro: {{ variant }}
{% elif variant in ["dragonfly"] %}
distro: dragonflybsd
@@ -248,15 +249,15 @@ system_info:
primary: http://ports.ubuntu.com/ubuntu-ports
security: http://ports.ubuntu.com/ubuntu-ports
ssh_svcname: ssh
-{% elif variant in ["almalinux", "alpine", "amazon", "arch", "centos", "cloudlinux", "eurolinux",
- "fedora", "gentoo", "miraclelinux", "openEuler", "rhel", "rocky", "suse", "virtuozzo"] %}
+{% elif variant in ["almalinux", "alpine", "amazon", "arch", "cloudlinux", "eurolinux",
+ "fedora", "gentoo", "miraclelinux", "openEuler", "openmandriva", "rocky", "suse", "virtuozzo"] or is_rhel %}
# Default user name + that default users groups (if added/used)
default_user:
{% if variant == "amazon" %}
name: ec2-user
lock_passwd: True
gecos: EC2 Default User
-{% elif variant == "rhel" %}
+{% elif is_rhel %}
name: cloud-user
lock_passwd: true
gecos: Cloud User
@@ -275,7 +276,7 @@ system_info:
groups: [adm, sudo]
{% elif variant == "arch" %}
groups: [wheel, users]
-{% elif variant == "rhel" %}
+{% elif is_rhel %}
groups: [adm, systemd-journal]
{% else %}
groups: [wheel, adm, systemd-journal]
diff --git a/tests/unittests/test_render_cloudcfg.py b/tests/unittests/test_render_cloudcfg.py
index 9f95d448..1a6e2715 100644
--- a/tests/unittests/test_render_cloudcfg.py
+++ b/tests/unittests/test_render_cloudcfg.py
@@ -69,6 +69,7 @@ class TestRenderCloudCfg:
"amazon": "ec2-user",
"debian": "ubuntu",
"rhel": "cloud-user",
+ "centos": "cloud-user",
"unknown": "ubuntu",
}
default_user = system_cfg["system_info"]["default_user"]["name"]
--
2.37.3

View File

@ -1,57 +0,0 @@
From f771d841dbdef8fbb1c1a3d1b8d51ff101354502 Mon Sep 17 00:00:00 2001
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Fri, 17 Jun 2022 09:41:23 +0200
Subject: [PATCH 3/3] setup.py: adjust udev/rules default path (#1513)
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-MergeRequest: 30: setup.py: adjust udev/rules default path (#1513)
RH-Commit: [2/2] b71362acefa15587b2c72e8981708065d2fcfa07 (eesposit/cloud-init-centos-)
RH-Bugzilla: 2096270
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
commit 70715125f3af118ae242770e61064c24f41e9a02
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Date: Thu Jun 16 20:39:42 2022 +0200
setup.py: adjust udev/rules default path (#1513)
RHEL must put cloudinit .rules files in /usr/lib/udev/rules.d
This place is a rhel standard and since it is used by all packages
cannot be modified.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
setup.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index a9132d2c..fdf27cd7 100755
--- a/setup.py
+++ b/setup.py
@@ -302,6 +302,11 @@ data_files = [
),
]
if not platform.system().endswith("BSD"):
+
+ RULES_PATH = LIB
+ if os.path.isfile("/etc/redhat-release"):
+ RULES_PATH = "/usr/lib"
+
data_files.extend(
[
(
@@ -309,7 +314,7 @@ if not platform.system().endswith("BSD"):
["tools/hook-network-manager"],
),
(ETC + "/dhcp/dhclient-exit-hooks.d/", ["tools/hook-dhclient"]),
- (LIB + "/udev/rules.d", [f for f in glob("udev/*.rules")]),
+ (RULES_PATH + "/udev/rules.d", [f for f in glob("udev/*.rules")]),
(
ETC + "/systemd/system/sshd-keygen@.service.d/",
["systemd/disable-sshd-keygen-if-cloud-init-active.conf"],
--
2.35.1

View File

@ -1,61 +1,43 @@
Name: cloud-init Name: cloud-init
Version: 22.1 Version: 23.1.1
Release: 9%{?dist} Release: 11%{?dist}
Summary: Cloud instance init scripts Summary: Cloud instance init scripts
License: ASL 2.0 or GPLv3 License: ASL 2.0 or GPLv3
URL: http://launchpad.net/cloud-init URL: http://launchpad.net/cloud-init
Source0: https://launchpad.net/cloud-init/trunk/%{version}/+download/%{name}-%{version}.tar.gz Source0: https://github.com/canonical/cloud-init/archive/refs/tags/%{version}.tar.gz
Source1: cloud-init-tmpfiles.conf Source1: cloud-init-tmpfiles.conf
Patch0001: 0001-Add-initial-redhat-changes.patch
Patch0002: 0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
Patch0003: 0003-Adding-_netdev-to-the-default-mount-configuration.patch
Patch0004: 0004-Setting-highest-autoconnect-priority-for-network-scr.patch
Patch0005: 0005-limit-permissions-on-def_log_file.patch
Patch0006: 0006-rhel-cloud.cfg-remove-ssh_genkeytypes-in-settings.py.patch
# For bz#2056964 - [RHEL-9]Rebase cloud-init from Fedora so it can configure networking using NM keyfiles
Patch7: ci-Add-native-NetworkManager-support-1224.patch
# For bz#2056964 - [RHEL-9]Rebase cloud-init from Fedora so it can configure networking using NM keyfiles
Patch8: ci-Use-Network-Manager-and-Netplan-as-default-renderers.patch
# For bz#2056964 - [RHEL-9]Rebase cloud-init from Fedora so it can configure networking using NM keyfiles
Patch9: ci-Revert-Setting-highest-autoconnect-priority-for-netw.patch
# For bz#2088448 - Align cloud.cfg file and systemd with cloud-init upstream .tmpl files
Patch10: ci-Align-rhel-custom-files-with-upstream-1431.patch
# For bz#2088448 - Align cloud.cfg file and systemd with cloud-init upstream .tmpl files
Patch11: ci-Remove-rhel-specific-files.patch
# For bz#2091640 - [cloud][init] Add support for reading tags from instance metadata
Patch12: ci-Support-EC2-tags-in-instance-metadata-1309.patch
# For bz#1980403 - [RHV] RHEL 9 VM with cloud-init without hostname set doesn't result in the FQDN as hostname
Patch13: ci-cc_set_hostname-do-not-write-localhost-when-no-hostn.patch
# For bz#2061604 - cloud-config will change /etc/locale.conf back to en_US.UTF-8 on rhel-guest-image-9.0
Patch14: ci-Honor-system-locale-for-RHEL-1355.patch
# For bz#2096270 - Adjust udev/rules default path[rhel-9]
Patch15: ci-setup.py-adjust-udev-rules-default-path-1513.patch
# For bz#2107463 - [RHEL-9.1] Cannot run sysconfig when changing the priority of network renderers
# For bz#2104389 - [RHEL-9.1]Failed to config static IP and IPv6 according to VMware Customization Config File
# For bz#2117532 - [RHEL9.1] Revert patch of configuring networking by NM keyfiles
# For bz#2098501 - [RHEL-9.1] IPv6 not workable when cloud-init configure network using NM keyfiles
Patch16: ci-Revert-Add-native-NetworkManager-support-1224.patch
# For bz#2107463 - [RHEL-9.1] Cannot run sysconfig when changing the priority of network renderers
# For bz#2104389 - [RHEL-9.1]Failed to config static IP and IPv6 according to VMware Customization Config File
# For bz#2117532 - [RHEL9.1] Revert patch of configuring networking by NM keyfiles
# For bz#2098501 - [RHEL-9.1] IPv6 not workable when cloud-init configure network using NM keyfiles
Patch17: ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch
# For bz#2107463 - [RHEL-9.1] Cannot run sysconfig when changing the priority of network renderers
# For bz#2104389 - [RHEL-9.1]Failed to config static IP and IPv6 according to VMware Customization Config File
# For bz#2117532 - [RHEL9.1] Revert patch of configuring networking by NM keyfiles
# For bz#2098501 - [RHEL-9.1] IPv6 not workable when cloud-init configure network using NM keyfiles
Patch18: ci-Revert-Revert-Setting-highest-autoconnect-priority-f.patch
# For bz#2115565 - cloud-init configures user "centos" or "rhel" instead of "cloud-user" with cloud-init-22.1
Patch19: ci-cloud.cfg.tmpl-make-sure-centos-settings-are-identic.patch
# For bz#2152100 - [RHEL-9] Ensure network ready before cloud-init service runs on RHEL
Patch20: ci-Ensure-network-ready-before-cloud-init-service-runs-.patch
# For bz#2140893 - systemd[1]: Failed to start Initial cloud-init job after reboot system via sysrq 'b'
Patch21: ci-cc_set_hostname-ignore-var-lib-cloud-data-set-hostna.patch
# For bz#2166245 - Add support for resizing encrypted root volume
Patch22: ci-Allow-growpart-to-resize-encrypted-partitions-1316.patch
# Source-git patches # Source-git patches
Patch1: 0001-Add-initial-redhat-changes.patch
Patch2: 0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
Patch3: 0003-Setting-highest-autoconnect-priority-for-network-scr.patch
Patch4: 0004-limit-permissions-on-def_log_file.patch
Patch5: 0005-Manual-revert-Use-Network-Manager-and-Netplan-as-def.patch
Patch6: 0006-Revert-Add-native-NetworkManager-support-1224.patch
Patch7: 0007-rhel-make-sure-previous-hostname-file-ends-with-a-ne.patch
Patch8: 0008-Don-t-change-permissions-of-netrules-target-2076.patch
Patch9: 0009-Make-user-vendor-data-sensitive-and-remove-log-permi.patch
Patch10: 0010-Do-not-generate-dsa-and-ed25519-key-types-when-crypt.patch
Patch11: 0011-Revert-Manual-revert-Use-Network-Manager-and-Netplan.patch
Patch12: 0012-Revert-Revert-Add-native-NetworkManager-support-1224.patch
Patch13: 0013-net-sysconfig-do-not-use-the-highest-autoconnect-pri.patch
Patch14: 0014-net-sysconfig-cosmetic-fix-tox-formatting.patch
Patch15: 0015-nm-generate-ipv6-stateful-dhcp-config-at-par-with-sy.patch
Patch16: 0016-network_manager-add-a-method-for-ipv6-static-IP-conf.patch
Patch17: 0017-net-sysconfig-enable-sysconfig-renderer-if-network-m.patch
Patch18: 0018-network-manager-Set-higher-autoconnect-priority-for-.patch
Patch19: 0019-Set-default-renderer-as-sysconfig-for-c9s-RHEL-9.patch
Patch20: 0020-Revert-Set-default-renderer-as-sysconfig-for-c9s-RHE.patch
Patch21: 0021-Set-default-renderer-as-sysconfig-for-centos-rhel-41.patch
Patch22: 0022-test-fixes-update-tests-to-reflect-AUTOCONNECT_PRIOR.patch
Patch23: 0023-test-fixes-remove-NM_CONTROLLED-no-from-tests.patch
Patch24: 0024-Revert-limit-permissions-on-def_log_file.patch
Patch25: 0025-test-fixes-changes-to-apply-RHEL-specific-config-set.patch
Patch26: 0026-Enable-SUSE-based-distros-for-ca-handling-2036.patch
Patch27: 0027-Handle-non-existent-ca-cert-config-situation-2073.patch
Patch28: 0028-logging-keep-current-file-mode-of-log-file-if-its-st.patch
Patch29: 0029-DS-VMware-modify-a-few-log-level-4284.patch
Patch30: 0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch
BuildArch: noarch BuildArch: noarch
@ -175,7 +157,27 @@ if [ $1 -eq 1 ] ; then
/bin/systemctl enable cloud-init-local.service >/dev/null 2>&1 || : /bin/systemctl enable cloud-init-local.service >/dev/null 2>&1 || :
/bin/systemctl enable cloud-init.target >/dev/null 2>&1 || : /bin/systemctl enable cloud-init.target >/dev/null 2>&1 || :
elif [ $1 -eq 2 ]; then elif [ $1 -eq 2 ]; then
# Upgrade. If the upgrade is from a version older than 0.7.9-8, # Upgrade
# RHBZ 2210012 - check for null ssh_genkeytypes value in cloud.cfg that
# breaks ssh connectivity after upgrade to a newer version of cloud-init.
if [ -f %{_sysconfdir}/cloud/cloud.cfg.rpmnew ] && grep -q '^\s*ssh_genkeytypes:\s*~\s*$' %{_sysconfdir}/cloud/cloud.cfg ; then
echo "***********************************************"
echo "*** WARNING!!!! ***"
echo ""
echo "ssh_genkeytypes set to null in /etc/cloud/cloud.cfg!"
echo "SSH access might be broken after reboot. Please check the following KCS"
echo "for more detailed information:"
echo ""
echo "https://access.redhat.com/solutions/6988034"
echo ""
echo "Please reconcile the differences between /etc/cloud/cloud.cfg and "
echo "/etc/cloud/cloud.cfg.rpmnew and update ssh_genkeytypes configuration in "
echo "/etc/cloud/cloud.cfg to a list of keytype values, something like:"
echo "ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']"
echo ""
echo "************************************************"
fi
# If the upgrade is from a version older than 0.7.9-8,
# there will be stale systemd config # there will be stale systemd config
/bin/systemctl is-enabled cloud-config.service >/dev/null 2>&1 && /bin/systemctl is-enabled cloud-config.service >/dev/null 2>&1 &&
/bin/systemctl reenable cloud-config.service >/dev/null 2>&1 || : /bin/systemctl reenable cloud-config.service >/dev/null 2>&1 || :
@ -207,6 +209,17 @@ fi
%postun %postun
%systemd_postun cloud-config.service cloud-config.target cloud-final.service cloud-init.service cloud-init.target cloud-init-local.service %systemd_postun cloud-config.service cloud-config.target cloud-final.service cloud-init.service cloud-init.target cloud-init-local.service
if [ -f /etc/ssh/sshd_config.d/50-cloud-init.conf ] ; then
echo "/etc/ssh/sshd_config.d/50-cloud-init.conf not removed"
fi
if [ -f /etc/NetworkManager/conf.d/99-cloud-init.conf ] ; then
echo "/etc/NetworkManager/conf.d/99-cloud-init.conf not removed"
fi
if [ -f /etc/NetworkManager/conf.d/30-cloud-init-ip6-addr-gen-mode.conf ] ; then
echo "/etc/NetworkManager/conf.d/30-cloud-init-ip6-addr-gen-mode.conf not removed"
fi
%files %files
%license LICENSE %license LICENSE
@ -214,6 +227,7 @@ fi
%dir %{_sysconfdir}/cloud/cloud.cfg.d %dir %{_sysconfdir}/cloud/cloud.cfg.d
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg %config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
%doc %{_sysconfdir}/cloud/cloud.cfg.d/README %doc %{_sysconfdir}/cloud/cloud.cfg.d/README
%doc %{_sysconfdir}/cloud/clean.d/README
%dir %{_sysconfdir}/cloud/templates %dir %{_sysconfdir}/cloud/templates
%config(noreplace) %{_sysconfdir}/cloud/templates/* %config(noreplace) %{_sysconfdir}/cloud/templates/*
%{_unitdir}/cloud-config.service %{_unitdir}/cloud-config.service
@ -244,6 +258,64 @@ fi
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf %config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
%changelog %changelog
* Thu Aug 17 2023 Miroslav Rezanina <mrezanin@redhat.com> - 23.1.1-11
- Resolves: bz#2232296
* Tue Aug 15 2023 Miroslav Rezanina <6499514-mrezanin@users.noreply.gitlab.com> - 23.1.1-10
- Resolves: bz#2229660 bz#2229952
* Fri Aug 04 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-9
- 0030-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch [bz#2188388]
- Resolves: bz#2188388
* Wed Jul 26 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-8
- 0022-test-fixes-update-tests-to-reflect-AUTOCONNECT_PRIOR.patch [bz#2217865]
- 0023-test-fixes-remove-NM_CONTROLLED-no-from-tests.patch [bz#2217865]
- 0024-Revert-limit-permissions-on-def_log_file.patch [bz#2217865]
- 0025-test-fixes-changes-to-apply-RHEL-specific-config-set.patch [bz#2217865]
- 0026-Enable-SUSE-based-distros-for-ca-handling-2036.patch [bz#2217865]
- 0027-Handle-non-existent-ca-cert-config-situation-2073.patch [bz#2217865]
- 0028-logging-keep-current-file-mode-of-log-file-if-its-st.patch [bz#2222498]
- 0029-DS-VMware-modify-a-few-log-level-4284.patch [bz#2225374]
- Resolves: bz#2217865 bz#2222498 bz#2225374
* Mon Jun 19 2023 Miroslav Rezanina <mrezanin@redhat.com> - 23.1.1-7
- 0020-Revert-Set-default-renderer-as-sysconfig-for-c9s-RHE.patch
- 0021-Set-default-renderer-as-sysconfig-for-centos-rhel-41.patch [bz#2209349]
- Resolves: bz#2209349
* Tue Jun 06 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-6
- 0011-Revert-Manual-revert-Use-Network-Manager-and-Netplan.patch
- 0012-Revert-Revert-Add-native-NetworkManager-support-1224.patch
- 0013-net-sysconfig-do-not-use-the-highest-autoconnect-pri.patch
- 0014-net-sysconfig-cosmetic-fix-tox-formatting.patch
- 0015-nm-generate-ipv6-stateful-dhcp-config-at-par-with-sy.patch [bz#2207716]
- 0016-network_manager-add-a-method-for-ipv6-static-IP-conf.patch [bz#2196284]
- 0017-net-sysconfig-enable-sysconfig-renderer-if-network-m.patch [bz#2194050]
- 0018-network-manager-Set-higher-autoconnect-priority-for-.patch [bz#2196231]
- 0019-Set-default-renderer-as-sysconfig-for-c9s-RHEL-9.patch [bz#2209349]
- Resolves: bz#2118235 bz#2194050 bz#2196231 bz#2196284 bz#2207716 bz#2209349
* Tue May 16 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-5
- 0010-Do-not-generate-dsa-and-ed25519-key-types-when-crypt.patch [bz#2187164]
- Resolves: bz#2187164
* Fri May 05 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-4
- 0009-Make-user-vendor-data-sensitive-and-remove-log-permi.patch [bz#2190083]
- Resolves: bz#2190083
* Thu Apr 27 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-3
- 0008-Don-t-change-permissions-of-netrules-target-2076.patch [bz#2182948]
- Resolves: bz#2182948
* Tue Apr 18 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-2
- 0007-rhel-make-sure-previous-hostname-file-ends-with-a-ne.patch [bz#2184608]
- Resolves: bz#2184608
* Thu Mar 30 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-1
- Rebase to 23.1.1 [bz#2172811]
- Resolves: bz#2172811
* Wed Feb 08 2023 Camilla Conte <cconte@redhat.com> - 22.1-9 * Wed Feb 08 2023 Camilla Conte <cconte@redhat.com> - 22.1-9
- ci-Allow-growpart-to-resize-encrypted-partitions-1316.patch [bz#2166245] - ci-Allow-growpart-to-resize-encrypted-partitions-1316.patch [bz#2166245]
- Resolves: bz#2166245 - Resolves: bz#2166245