Compare commits
No commits in common. "imports/c8-beta/cloud-init-18.5-4.el8" and "c8" have entirely different histories.
imports/c8
...
c8
|
@ -1 +1 @@
|
|||
a862d6618a4c56c79d3fb0e279f6c93d0f0141cd SOURCES/cloud-init-18.5.tar.gz
|
||||
e73116733f5636eb4bc1a5e47e802c3635b9bfa2 SOURCES/23.4.tar.gz
|
||||
|
|
|
@ -1 +1 @@
|
|||
SOURCES/cloud-init-18.5.tar.gz
|
||||
SOURCES/23.4.tar.gz
|
||||
|
|
|
@ -1,502 +0,0 @@
|
|||
From bfdc177f6127043eac555d356403d9e1d5c52243 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Thu, 31 May 2018 16:45:23 +0200
|
||||
Subject: Add initial redhat setup
|
||||
|
||||
Rebase notes (18.5):
|
||||
- added bash_completition file
|
||||
- added cloud-id file
|
||||
|
||||
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
|
||||
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/config/cc_chef.py | 6 +-
|
||||
cloudinit/settings.py | 7 +-
|
||||
redhat/.gitignore | 1 +
|
||||
redhat/Makefile | 71 ++++++
|
||||
redhat/Makefile.common | 35 +++
|
||||
redhat/cloud-init-tmpfiles.conf | 1 +
|
||||
redhat/cloud-init.spec.template | 352 ++++++++++++++++++++++++++
|
||||
redhat/rpmbuild/BUILD/.gitignore | 3 +
|
||||
redhat/rpmbuild/RPMS/.gitignore | 3 +
|
||||
redhat/rpmbuild/SOURCES/.gitignore | 3 +
|
||||
redhat/rpmbuild/SPECS/.gitignore | 3 +
|
||||
redhat/rpmbuild/SRPMS/.gitignore | 3 +
|
||||
redhat/scripts/frh.py | 27 ++
|
||||
redhat/scripts/git-backport-diff | 327 ++++++++++++++++++++++++
|
||||
redhat/scripts/git-compile-check | 215 ++++++++++++++++
|
||||
redhat/scripts/process-patches.sh | 73 ++++++
|
||||
redhat/scripts/tarball_checksum.sh | 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 | 19 ++
|
||||
rhel/systemd/cloud-init-local.service | 31 +++
|
||||
rhel/systemd/cloud-init.service | 25 ++
|
||||
setup.py | 64 +----
|
||||
tools/read-version | 25 +-
|
||||
27 files changed, 1311 insertions(+), 90 deletions(-)
|
||||
create mode 100644 redhat/.gitignore
|
||||
create mode 100644 redhat/Makefile
|
||||
create mode 100644 redhat/Makefile.common
|
||||
create mode 100644 redhat/cloud-init-tmpfiles.conf
|
||||
create mode 100644 redhat/cloud-init.spec.template
|
||||
create mode 100644 redhat/rpmbuild/BUILD/.gitignore
|
||||
create mode 100644 redhat/rpmbuild/RPMS/.gitignore
|
||||
create mode 100644 redhat/rpmbuild/SOURCES/.gitignore
|
||||
create mode 100644 redhat/rpmbuild/SPECS/.gitignore
|
||||
create mode 100644 redhat/rpmbuild/SRPMS/.gitignore
|
||||
create mode 100755 redhat/scripts/frh.py
|
||||
create mode 100755 redhat/scripts/git-backport-diff
|
||||
create mode 100755 redhat/scripts/git-compile-check
|
||||
create mode 100755 redhat/scripts/process-patches.sh
|
||||
create mode 100755 redhat/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
|
||||
|
||||
diff --git a/cloudinit/config/cc_chef.py b/cloudinit/config/cc_chef.py
|
||||
index 46abedd1..fe7bda8c 100644
|
||||
--- a/cloudinit/config/cc_chef.py
|
||||
+++ b/cloudinit/config/cc_chef.py
|
||||
@@ -33,7 +33,7 @@ file).
|
||||
|
||||
chef:
|
||||
directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,
|
||||
- /var/cache/chef, /var/backups/chef, /var/run/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
|
||||
@@ -88,7 +88,7 @@ CHEF_DIRS = tuple([
|
||||
'/var/lib/chef',
|
||||
'/var/cache/chef',
|
||||
'/var/backups/chef',
|
||||
- '/var/run/chef',
|
||||
+ '/run/chef',
|
||||
])
|
||||
REQUIRED_CHEF_DIRS = tuple([
|
||||
'/etc/chef',
|
||||
@@ -112,7 +112,7 @@ CHEF_RB_TPL_DEFAULTS = {
|
||||
'json_attribs': CHEF_FB_PATH,
|
||||
'file_cache_path': "/var/cache/chef",
|
||||
'file_backup_path': "/var/backups/chef",
|
||||
- 'pid_file': "/var/run/chef/client.pid",
|
||||
+ 'pid_file': "/run/chef/client.pid",
|
||||
'show_time': True,
|
||||
}
|
||||
CHEF_RB_TPL_BOOL_KEYS = frozenset(['show_time'])
|
||||
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||
index b1ebaade..c5367687 100644
|
||||
--- a/cloudinit/settings.py
|
||||
+++ b/cloudinit/settings.py
|
||||
@@ -44,13 +44,16 @@ CFG_BUILTIN = {
|
||||
],
|
||||
'def_log_file': '/var/log/cloud-init.log',
|
||||
'log_cfgs': [],
|
||||
- 'syslog_fix_perms': ['syslog:adm', 'root:adm', 'root:wheel', 'root:root'],
|
||||
+ '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': 'rhel',
|
||||
'network': {'renderers': None},
|
||||
},
|
||||
'vendor_data': {'enabled': True, 'prefix': []},
|
||||
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..f0db3c12
|
||||
--- /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: 0
|
||||
+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: [wheel, 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..12ca9dfd
|
||||
--- /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=multi-user.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..32a83d85
|
||||
--- /dev/null
|
||||
+++ b/rhel/systemd/cloud-final.service
|
||||
@@ -0,0 +1,19 @@
|
||||
+[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
|
||||
+
|
||||
+# Output needs to appear in instance console output
|
||||
+StandardOutput=journal+console
|
||||
+
|
||||
+[Install]
|
||||
+WantedBy=multi-user.target
|
||||
diff --git a/rhel/systemd/cloud-init-local.service b/rhel/systemd/cloud-init-local.service
|
||||
new file mode 100644
|
||||
index 00000000..656eddb9
|
||||
--- /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=multi-user.target
|
||||
diff --git a/rhel/systemd/cloud-init.service b/rhel/systemd/cloud-init.service
|
||||
new file mode 100644
|
||||
index 00000000..68fc5f19
|
||||
--- /dev/null
|
||||
+++ b/rhel/systemd/cloud-init.service
|
||||
@@ -0,0 +1,25 @@
|
||||
+[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
|
||||
+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=multi-user.target
|
||||
diff --git a/setup.py b/setup.py
|
||||
index ea37efc3..06ae48a6 100755
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -135,11 +135,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/*.target')) if is_f(f)],
|
||||
- 'systemd.generators': [f for f in glob('systemd/*-generator') if is_f(f)],
|
||||
'upstart': [f for f in glob('upstart/*') if is_f(f)],
|
||||
}
|
||||
INITSYS_ROOTS = {
|
||||
@@ -148,9 +143,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()])
|
||||
@@ -188,47 +180,6 @@ class MyEggInfo(egg_info):
|
||||
return ret
|
||||
|
||||
|
||||
-# TODO: Is there a better way to do this??
|
||||
-class InitsysInstallData(install):
|
||||
- init_system = None
|
||||
- user_options = install.user_options + [
|
||||
- # This will magically show up in member variable 'init_sys'
|
||||
- ('init-system=', None,
|
||||
- ('init system(s) to configure (%s) [default: None]' %
|
||||
- (", ".join(INITSYS_TYPES)))),
|
||||
- ]
|
||||
-
|
||||
- def initialize_options(self):
|
||||
- install.initialize_options(self)
|
||||
- self.init_system = ""
|
||||
-
|
||||
- def finalize_options(self):
|
||||
- install.finalize_options(self)
|
||||
-
|
||||
- if self.init_system and isinstance(self.init_system, str):
|
||||
- self.init_system = self.init_system.split(",")
|
||||
-
|
||||
- if len(self.init_system) == 0:
|
||||
- self.init_system = ['systemd']
|
||||
-
|
||||
- bad = [f for f in self.init_system if f not in INITSYS_TYPES]
|
||||
- if len(bad) != 0:
|
||||
- raise DistutilsArgError(
|
||||
- "Invalid --init-system: %s" % (','.join(bad)))
|
||||
-
|
||||
- for system in self.init_system:
|
||||
- # add data files for anything that starts with '<system>.'
|
||||
- datakeys = [k for k in INITSYS_ROOTS
|
||||
- if k.partition(".")[0] == system]
|
||||
- for k in datakeys:
|
||||
- if not INITSYS_FILES[k]:
|
||||
- continue
|
||||
- self.distribution.data_files.append(
|
||||
- (INITSYS_ROOTS[k], INITSYS_FILES[k]))
|
||||
- # Force that command to reinitalize (with new file list)
|
||||
- self.distribution.reinitialize_command('install_data', True)
|
||||
-
|
||||
-
|
||||
if not in_virtualenv():
|
||||
USR = "/" + USR
|
||||
ETC = "/" + ETC
|
||||
@@ -239,11 +190,9 @@ if not in_virtualenv():
|
||||
|
||||
data_files = [
|
||||
(ETC + '/bash_completion.d', ['bash_completion/cloud-init']),
|
||||
- (ETC + '/cloud', [render_tmpl("config/cloud.cfg.tmpl")]),
|
||||
(ETC + '/cloud/cloud.cfg.d', glob('config/cloud.cfg.d/*')),
|
||||
(ETC + '/cloud/templates', glob('templates/*')),
|
||||
- (USR_LIB_EXEC + '/cloud-init', ['tools/ds-identify',
|
||||
- 'tools/uncloud-init',
|
||||
+ (USR_LIB_EXEC + '/cloud-init', ['tools/uncloud-init',
|
||||
'tools/write-ssh-key-fingerprints']),
|
||||
(USR + '/share/doc/cloud-init', [f for f in glob('doc/*') if is_f(f)]),
|
||||
(USR + '/share/doc/cloud-init/examples',
|
||||
@@ -255,15 +204,8 @@ if os.uname()[0] != 'FreeBSD':
|
||||
data_files.extend([
|
||||
(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')])
|
||||
])
|
||||
-# Use a subclass for install that handles
|
||||
-# adding on the right init system configuration files
|
||||
-cmdclass = {
|
||||
- 'install': InitsysInstallData,
|
||||
- 'egg_info': MyEggInfo,
|
||||
-}
|
||||
|
||||
requirements = read_requires()
|
||||
|
||||
@@ -278,8 +220,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 e69c2ce0..d43cc8f0 100755
|
||||
--- a/tools/read-version
|
||||
+++ b/tools/read-version
|
||||
@@ -65,29 +65,8 @@ output_json = '--json' in sys.argv
|
||||
src_version = ci_version.version_string()
|
||||
version_long = None
|
||||
|
||||
-if is_gitdir(_tdir) and which("git"):
|
||||
- flags = []
|
||||
- if use_tags:
|
||||
- flags = ['--tags']
|
||||
- cmd = ['git', 'describe', '--abbrev=8', '--match=[0-9]*'] + flags
|
||||
-
|
||||
- version = tiny_p(cmd).strip()
|
||||
-
|
||||
- if 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.20.1
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
From 0bff7d73c49043b0820d0231c9a47539287f35e3 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Thu, 31 May 2018 19:37:55 +0200
|
||||
Subject: Do not write NM_CONTROLLED=no in generated interface config files
|
||||
|
||||
X-downstream-only: true
|
||||
Signed-off-by: Ryan McCabe <rmccabe@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 1 -
|
||||
tests/unittests/test_net.py | 30 ------------------------------
|
||||
2 files changed, 31 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index 17293e1d..ae0554ef 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -250,7 +250,6 @@ class Renderer(renderer.Renderer):
|
||||
iface_defaults = tuple([
|
||||
('ONBOOT', True),
|
||||
('USERCTL', False),
|
||||
- ('NM_CONTROLLED', False),
|
||||
('BOOTPROTO', 'none'),
|
||||
])
|
||||
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 195f261c..5f1aa3e7 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -175,7 +175,6 @@ GATEWAY=172.19.3.254
|
||||
HWADDR=fa:16:3e:ed:9a:59
|
||||
IPADDR=172.19.1.34
|
||||
NETMASK=255.255.252.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -279,7 +278,6 @@ IPADDR=172.19.1.34
|
||||
IPADDR1=10.0.0.10
|
||||
NETMASK=255.255.252.0
|
||||
NETMASK1=255.255.255.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -407,7 +405,6 @@ IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64"
|
||||
IPV6INIT=yes
|
||||
IPV6_DEFAULTGW=2001:DB8::1
|
||||
NETMASK=255.255.252.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -523,7 +520,6 @@ NETWORK_CONFIGS = {
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth1
|
||||
HWADDR=cf:d6:af:48:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -539,7 +535,6 @@ NETWORK_CONFIGS = {
|
||||
IPADDR=192.168.21.3
|
||||
NETMASK=255.255.255.0
|
||||
METRIC=10000
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -652,7 +647,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6ADDR=2001:1::1/64
|
||||
IPV6INIT=yes
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -894,14 +888,12 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DHCPV6C=yes
|
||||
IPV6INIT=yes
|
||||
MACADDR=aa:bb:cc:dd:ee:ff
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Bond
|
||||
USERCTL=no"""),
|
||||
'ifcfg-bond0.200': textwrap.dedent("""\
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=bond0.200
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=bond0
|
||||
TYPE=Ethernet
|
||||
@@ -918,7 +910,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
IPV6_DEFAULTGW=2001:4800:78ff:1b::1
|
||||
MACADDR=bb:bb:bb:bb:bb:aa
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PRIO=22
|
||||
STP=no
|
||||
@@ -928,7 +919,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth0
|
||||
HWADDR=c0:d6:9f:2c:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -945,7 +935,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MTU=1500
|
||||
NETMASK=255.255.255.0
|
||||
NETMASK1=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=eth0
|
||||
TYPE=Ethernet
|
||||
@@ -956,7 +945,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=eth1
|
||||
HWADDR=aa:d6:9f:2c:e8:80
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -966,7 +954,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=eth2
|
||||
HWADDR=c0:bb:9f:2c:e8:80
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -976,7 +963,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BRIDGE=br0
|
||||
DEVICE=eth3
|
||||
HWADDR=66:bb:9f:2c:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -985,7 +971,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BRIDGE=br0
|
||||
DEVICE=eth4
|
||||
HWADDR=98:bb:9f:2c:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -993,7 +978,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth5
|
||||
HWADDR=98:bb:9f:2c:e8:8a
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
TYPE=Ethernet
|
||||
USERCTL=no""")
|
||||
@@ -1356,7 +1340,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MTU=9000
|
||||
NETMASK=255.255.255.0
|
||||
NETMASK1=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Bond
|
||||
USERCTL=no
|
||||
@@ -1366,7 +1349,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=bond0s0
|
||||
HWADDR=aa:bb:cc:dd:e8:00
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -1388,7 +1370,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=bond0s1
|
||||
HWADDR=aa:bb:cc:dd:e8:01
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -1426,7 +1407,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=none
|
||||
DEVICE=en0
|
||||
HWADDR=aa:bb:cc:dd:e8:00
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""),
|
||||
@@ -1443,7 +1423,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
MTU=2222
|
||||
NETMASK=255.255.255.0
|
||||
NETMASK1=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=en0
|
||||
TYPE=Ethernet
|
||||
@@ -1484,7 +1463,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=br0
|
||||
IPADDR=192.168.2.2
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PRIO=22
|
||||
STP=no
|
||||
@@ -1498,7 +1476,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=52:54:00:12:34:00
|
||||
IPV6ADDR=2001:1::100/96
|
||||
IPV6INIT=yes
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1510,7 +1487,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=52:54:00:12:34:01
|
||||
IPV6ADDR=2001:1::101/96
|
||||
IPV6INIT=yes
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1584,7 +1560,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
HWADDR=52:54:00:12:34:00
|
||||
IPADDR=192.168.1.2
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1594,7 +1569,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=eth1
|
||||
HWADDR=52:54:00:12:34:aa
|
||||
MTU=1480
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1603,7 +1577,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth2
|
||||
HWADDR=52:54:00:12:34:ff
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1969,7 +1942,6 @@ class TestRhelSysConfigRendering(CiTestCase):
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth1000
|
||||
HWADDR=07-1C-C6-75-A4-BE
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2090,7 +2062,6 @@ GATEWAY=10.0.2.2
|
||||
HWADDR=52:54:00:12:34:00
|
||||
IPADDR=10.0.2.15
|
||||
NETMASK=255.255.255.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2111,7 +2082,6 @@ USERCTL=no
|
||||
#
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
From 2d3a22bd5b36c20b53f1604e9ff6ce05c98753ec Mon Sep 17 00:00:00 2001
|
||||
From: Cathy Avery <cavery@redhat.com>
|
||||
Date: Mon, 18 Dec 2023 12:54:16 -0500
|
||||
Subject: Do not write NM_CONTROLLED=no in generated interface config files
|
||||
|
||||
Squashed from:
|
||||
From 3ee57b044d2b85d8172961258d2edeab82a43772 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Fri, 7 May 2021 13:36:06 +0200
|
||||
Subject: [PATCH 02/12] Do not write NM_CONTROLLED=no in generated interface config files
|
||||
|
||||
From 3a070f23440c9eb6e0e5fb3605e36285e8a5b727 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Fri, 23 Jun 2023 16:54:24 +0530
|
||||
Subject: [PATCH 27/51] test fixes: remove NM_CONTROLLED=no from tests
|
||||
fixes: b3b96bff187e9 ("Do not write NM_CONTROLLED=no in generated interface config files")
|
||||
|
||||
X-downstream-only: true
|
||||
|
||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 1 -
|
||||
tests/unittests/cmd/devel/test_net_convert.py | 1 -
|
||||
tests/unittests/distros/test_netconfig.py | 8 ---
|
||||
tests/unittests/test_net.py | 53 -------------------
|
||||
4 files changed, 63 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index 7570a5e3..3b7a1f93 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -317,7 +317,6 @@ class Renderer(renderer.Renderer):
|
||||
"rhel": {
|
||||
"ONBOOT": True,
|
||||
"USERCTL": False,
|
||||
- "NM_CONTROLLED": False,
|
||||
"BOOTPROTO": "none",
|
||||
},
|
||||
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
|
||||
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
|
||||
index fb72963f..7b9121b2 100644
|
||||
--- a/tests/unittests/cmd/devel/test_net_convert.py
|
||||
+++ b/tests/unittests/cmd/devel/test_net_convert.py
|
||||
@@ -62,7 +62,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
|
||||
#
|
||||
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 7ba430f2..962ff7fb 100644
|
||||
--- a/tests/unittests/distros/test_netconfig.py
|
||||
+++ b/tests/unittests/distros/test_netconfig.py
|
||||
@@ -723,7 +723,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
|
||||
@@ -733,7 +732,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||
"""\
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth1
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -764,7 +762,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
|
||||
@@ -774,7 +771,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||
"""\
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth1
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -821,7 +817,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
|
||||
@@ -833,7 +828,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
|
||||
@@ -869,7 +863,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
|
||||
@@ -881,7 +874,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 c5509536..052b0674 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -585,7 +585,6 @@ GATEWAY=172.19.3.254
|
||||
HWADDR=fa:16:3e:ed:9a:59
|
||||
IPADDR=172.19.1.34
|
||||
NETMASK=255.255.252.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -750,7 +749,6 @@ IPADDR=172.19.1.34
|
||||
IPADDR1=10.0.0.10
|
||||
NETMASK=255.255.252.0
|
||||
NETMASK1=255.255.255.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -912,7 +910,6 @@ IPV6_AUTOCONF=no
|
||||
IPV6_DEFAULTGW=2001:DB8::1
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
NETMASK=255.255.252.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1143,7 +1140,6 @@ NETWORK_CONFIGS = {
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth1
|
||||
HWADDR=cf:d6:af:48:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -1162,7 +1158,6 @@ NETWORK_CONFIGS = {
|
||||
IPADDR=192.168.21.3
|
||||
NETMASK=255.255.255.0
|
||||
METRIC=10000
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -1319,7 +1314,6 @@ NETWORK_CONFIGS = {
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth1
|
||||
HWADDR=cf:d6:af:48:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -1338,7 +1332,6 @@ NETWORK_CONFIGS = {
|
||||
IPADDR=192.168.21.3
|
||||
NETMASK=255.255.255.0
|
||||
METRIC=10000
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -1581,7 +1574,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6_AUTOCONF=no
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1725,7 +1717,6 @@ NETWORK_CONFIGS = {
|
||||
DHCPV6C=yes
|
||||
IPV6INIT=yes
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1816,7 +1807,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6INIT=yes
|
||||
IPV6_FORCE_ACCEPT_RA=yes
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1892,7 +1882,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6INIT=yes
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -1956,7 +1945,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6_AUTOCONF=yes
|
||||
IPV6INIT=yes
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2014,7 +2002,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6_AUTOCONF=no
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2071,7 +2058,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6_AUTOCONF=yes
|
||||
IPV6INIT=yes
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2157,7 +2143,6 @@ NETWORK_CONFIGS = {
|
||||
IPV6_FAILURE_FATAL=yes
|
||||
IPV6_FORCE_ACCEPT_RA=yes
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2198,7 +2183,6 @@ NETWORK_CONFIGS = {
|
||||
"""\
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=iface0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2275,7 +2259,6 @@ NETWORK_CONFIGS = {
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=iface0
|
||||
ETHTOOL_OPTS="wol g"
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -2619,7 +2602,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
DHCPV6C=yes
|
||||
IPV6INIT=yes
|
||||
MACADDR=aa:bb:cc:dd:ee:ff
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Bond
|
||||
USERCTL=no"""
|
||||
@@ -2629,7 +2611,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=bond0.200
|
||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=bond0
|
||||
USERCTL=no
|
||||
@@ -2649,7 +2630,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
IPV6_DEFAULTGW=2001:4800:78ff:1b::1
|
||||
MACADDR=bb:bb:bb:bb:bb:aa
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PRIO=22
|
||||
STP=no
|
||||
@@ -2661,7 +2641,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth0
|
||||
HWADDR=c0:d6:9f:2c:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -2680,7 +2659,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
MTU=1500
|
||||
NETMASK=255.255.255.0
|
||||
NETMASK1=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=eth0
|
||||
USERCTL=no
|
||||
@@ -2692,7 +2670,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=eth1
|
||||
HWADDR=aa:d6:9f:2c:e8:80
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -2704,7 +2681,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=eth2
|
||||
HWADDR=c0:bb:9f:2c:e8:80
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -2716,7 +2692,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
BRIDGE=br0
|
||||
DEVICE=eth3
|
||||
HWADDR=66:bb:9f:2c:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -2727,7 +2702,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
BRIDGE=br0
|
||||
DEVICE=eth4
|
||||
HWADDR=98:bb:9f:2c:e8:80
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -2738,7 +2712,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||
DEVICE=eth5
|
||||
DHCLIENT_SET_DEFAULT_ROUTE=no
|
||||
HWADDR=98:bb:9f:2c:e8:8a
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -2751,7 +2724,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"""
|
||||
@@ -3473,7 +3445,6 @@ iface bond0 inet6 static
|
||||
MTU=9000
|
||||
NETMASK=255.255.255.0
|
||||
NETMASK1=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Bond
|
||||
USERCTL=no
|
||||
@@ -3485,7 +3456,6 @@ iface bond0 inet6 static
|
||||
DEVICE=bond0s0
|
||||
HWADDR=aa:bb:cc:dd:e8:00
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -3513,7 +3483,6 @@ iface bond0 inet6 static
|
||||
DEVICE=bond0s1
|
||||
HWADDR=aa:bb:cc:dd:e8:01
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Ethernet
|
||||
@@ -3662,7 +3631,6 @@ iface bond0 inet6 static
|
||||
BOOTPROTO=none
|
||||
DEVICE=en0
|
||||
HWADDR=aa:bb:cc:dd:e8:00
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no"""
|
||||
@@ -3683,7 +3651,6 @@ iface bond0 inet6 static
|
||||
MTU=2222
|
||||
NETMASK=255.255.255.0
|
||||
NETMASK1=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=en0
|
||||
USERCTL=no
|
||||
@@ -3811,7 +3778,6 @@ iface bond0 inet6 static
|
||||
DEVICE=br0
|
||||
IPADDR=192.168.2.2
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PRIO=22
|
||||
STP=no
|
||||
@@ -3829,7 +3795,6 @@ iface bond0 inet6 static
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=no
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -3845,7 +3810,6 @@ iface bond0 inet6 static
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=no
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -4030,7 +3994,6 @@ iface bond0 inet6 static
|
||||
HWADDR=52:54:00:12:34:00
|
||||
IPADDR=192.168.1.2
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -4042,7 +4005,6 @@ iface bond0 inet6 static
|
||||
DEVICE=eth1
|
||||
HWADDR=52:54:00:12:34:aa
|
||||
MTU=1480
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -4053,7 +4015,6 @@ iface bond0 inet6 static
|
||||
BOOTPROTO=none
|
||||
DEVICE=eth2
|
||||
HWADDR=52:54:00:12:34:ff
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=no
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -4138,7 +4099,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"""
|
||||
@@ -4736,7 +4696,6 @@ class TestRhelSysConfigRendering(CiTestCase):
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth1000
|
||||
HWADDR=07-1c-c6-75-a4-be
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -4948,7 +4907,6 @@ GATEWAY=10.0.2.2
|
||||
HWADDR=52:54:00:12:34:00
|
||||
IPADDR=10.0.2.15
|
||||
NETMASK=255.255.255.0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -4979,7 +4937,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
|
||||
@@ -4993,7 +4950,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
|
||||
@@ -5018,7 +4974,6 @@ USERCTL=no
|
||||
#
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth0
|
||||
-NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -5251,7 +5206,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
|
||||
@@ -5283,7 +5237,6 @@ USERCTL=no
|
||||
"""\
|
||||
BOOTPROTO=none
|
||||
DEVICE=eno1
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -5296,7 +5249,6 @@ USERCTL=no
|
||||
IPADDR=192.6.1.9
|
||||
MTU=1495
|
||||
NETMASK=255.255.255.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
PHYSDEV=eno1
|
||||
USERCTL=no
|
||||
@@ -5332,7 +5284,6 @@ USERCTL=no
|
||||
IPADDR=10.101.8.65
|
||||
MTU=1334
|
||||
NETMASK=255.255.255.192
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Bond
|
||||
USERCTL=no
|
||||
@@ -5344,7 +5295,6 @@ USERCTL=no
|
||||
BOOTPROTO=none
|
||||
DEVICE=enp0s0
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Bond
|
||||
@@ -5357,7 +5307,6 @@ USERCTL=no
|
||||
BOOTPROTO=none
|
||||
DEVICE=enp0s1
|
||||
MASTER=bond0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
SLAVE=yes
|
||||
TYPE=Bond
|
||||
@@ -5388,7 +5337,6 @@ USERCTL=no
|
||||
DEVICE=eno1
|
||||
HWADDR=07-1c-c6-75-a4-be
|
||||
METRIC=100
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -5479,7 +5427,6 @@ USERCTL=no
|
||||
IPV6_FORCE_ACCEPT_RA=no
|
||||
MTU=1400
|
||||
NETMASK=255.255.248.0
|
||||
- NM_CONTROLLED=no
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
From fa8f782f5dd24e81f7072bfc24c75340f0972af5 Mon Sep 17 00:00:00 2001
|
||||
From: Lars Kellogg-Stedman <lars@redhat.com>
|
||||
Date: Fri, 7 Apr 2017 18:50:54 -0400
|
||||
Subject: limit permissions on def_log_file
|
||||
|
||||
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.
|
||||
|
||||
LP: #1541196
|
||||
Resolves: rhbz#1424612
|
||||
X-approved-upstream: true
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/settings.py | 1 +
|
||||
cloudinit/stages.py | 3 ++-
|
||||
doc/examples/cloud-config.txt | 4 ++++
|
||||
3 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||
index c5367687..d982a4d6 100644
|
||||
--- a/cloudinit/settings.py
|
||||
+++ b/cloudinit/settings.py
|
||||
@@ -43,6 +43,7 @@ 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'],
|
||||
'ssh_deletekeys': False,
|
||||
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||
index 8a064124..4f15484d 100644
|
||||
--- a/cloudinit/stages.py
|
||||
+++ b/cloudinit/stages.py
|
||||
@@ -148,8 +148,9 @@ class Init(object):
|
||||
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:
|
||||
- util.ensure_file(log_file)
|
||||
+ util.ensure_file(log_file, mode=log_file_mode)
|
||||
perms = self.cfg.get('syslog_fix_perms')
|
||||
if not perms:
|
||||
perms = {}
|
||||
diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
|
||||
index eb84dcf5..0e82b83e 100644
|
||||
--- a/doc/examples/cloud-config.txt
|
||||
+++ b/doc/examples/cloud-config.txt
|
||||
@@ -413,10 +413,14 @@ 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
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
From 8a8af21fc8fff984f2b4285e9993cfd50cad70c4 Mon Sep 17 00:00:00 2001
|
||||
From: Lars Kellogg-Stedman <lars@redhat.com>
|
||||
Date: Thu, 15 Jun 2017 12:20:39 -0400
|
||||
Subject: azure: ensure that networkmanager hook script runs
|
||||
|
||||
The networkmanager hook script was failing to run due to the changes
|
||||
we made to resolve rhbz#1440831. This corrects the regression by
|
||||
allowing the NM hook script to run regardless of whether or not
|
||||
cloud-init is "enabled".
|
||||
|
||||
Resolves: rhbz#1460206
|
||||
X-downstream-only: true
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
tools/hook-dhclient | 3 +--
|
||||
tools/hook-network-manager | 3 +--
|
||||
tools/hook-rhel.sh | 3 +--
|
||||
3 files changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/hook-dhclient b/tools/hook-dhclient
|
||||
index 02122f37..181cd51e 100755
|
||||
--- a/tools/hook-dhclient
|
||||
+++ b/tools/hook-dhclient
|
||||
@@ -13,8 +13,7 @@ is_azure() {
|
||||
}
|
||||
|
||||
is_enabled() {
|
||||
- # only execute hooks if cloud-init is enabled and on azure
|
||||
- [ -e /run/cloud-init/enabled ] || return 1
|
||||
+ # only execute hooks if cloud-init is running on azure
|
||||
is_azure
|
||||
}
|
||||
|
||||
diff --git a/tools/hook-network-manager b/tools/hook-network-manager
|
||||
index 67d9044a..1d52cad7 100755
|
||||
--- a/tools/hook-network-manager
|
||||
+++ b/tools/hook-network-manager
|
||||
@@ -13,8 +13,7 @@ is_azure() {
|
||||
}
|
||||
|
||||
is_enabled() {
|
||||
- # only execute hooks if cloud-init is enabled and on azure
|
||||
- [ -e /run/cloud-init/enabled ] || return 1
|
||||
+ # only execute hooks if cloud-init running on azure
|
||||
is_azure
|
||||
}
|
||||
|
||||
diff --git a/tools/hook-rhel.sh b/tools/hook-rhel.sh
|
||||
index 513a5515..d75767e2 100755
|
||||
--- a/tools/hook-rhel.sh
|
||||
+++ b/tools/hook-rhel.sh
|
||||
@@ -13,8 +13,7 @@ is_azure() {
|
||||
}
|
||||
|
||||
is_enabled() {
|
||||
- # only execute hooks if cloud-init is enabled and on azure
|
||||
- [ -e /run/cloud-init/enabled ] || return 1
|
||||
+ # only execute hooks if cloud-init is running on azure
|
||||
is_azure
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From fea3e7fc6d23e988cf4a33dc03064ff31bf1d72d Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Fri, 7 May 2021 13:36:13 +0200
|
||||
Subject: include 'NOZEROCONF=yes' in /etc/sysconfig/network
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190320114559.23708-1-otubo@redhat.com>
|
||||
Patchwork-id: 84937
|
||||
O-Subject: [RHEL-7.7 cloud-init PATCH] include 'NOZEROCONF=yes' in /etc/sysconfig/network
|
||||
Bugzilla: 1653131
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
|
||||
The option NOZEROCONF=yes is not included by default in
|
||||
/etc/sysconfig/network, which is required by Overcloud instances. The
|
||||
patch also includes tests for the modifications.
|
||||
|
||||
X-downstream-only: yes
|
||||
Resolves: rhbz#1653131
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
(cherry picked from commit ffa647e83efd4293bd027e9e390274aad8a12d94)
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 11 ++++++++++-
|
||||
redhat/scripts/frh.py | 10 +++++++---
|
||||
2 files changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index 3b7a1f93..f01c4236 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -1029,7 +1029,16 @@ class Renderer(renderer.Renderer):
|
||||
# Distros configuring /etc/sysconfig/network as a file e.g. Centos
|
||||
if sysconfig_path.endswith("network"):
|
||||
util.ensure_dir(os.path.dirname(sysconfig_path))
|
||||
- netcfg = [_make_header(), "NETWORKING=yes"]
|
||||
+ netcfg = []
|
||||
+ 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=")
|
||||
+ ):
|
||||
+ netcfg.append(line)
|
||||
+ # Now generate the cloud-init portion of sysconfig/network
|
||||
+ netcfg.extend([_make_header(), "NETWORKING=yes"])
|
||||
if network_state.use_ipv6:
|
||||
netcfg.append("NETWORKING_IPV6=yes")
|
||||
netcfg.append("IPV6_AUTOCONF=no")
|
|
@ -0,0 +1,83 @@
|
|||
From f7236c817aee8c39223cca88deb8341b4f2b5dfa Mon Sep 17 00:00:00 2001
|
||||
From: Cathy Avery <cavery@redhat.com>
|
||||
Date: Mon, 18 Dec 2023 14:13:19 -0500
|
||||
Subject: settings.py: update settings for rhel
|
||||
|
||||
commit 2bf34313f2e9599e3304b5446411b5ada6ccd7f0
|
||||
Author: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Tue Apr 11 04:20:00 2023 -0400
|
||||
Please see commit 5e1e568d7085fd4443
|
||||
|
||||
(" Add initial redhat setup")
|
||||
from rhel8.8.0 branch for setings.py. Applying the same for the rebased
|
||||
cloud-init.
|
||||
|
||||
X-downstream-only: true
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
Conflicts: "def_log_file_mode": 0o600 as commit
|
||||
130899115 'limit permissions on def_log_file' was not applied.
|
||||
|
||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
||||
---
|
||||
cloudinit/settings.py | 7 +++++--
|
||||
tests/unittests/cmd/test_main.py | 17 +++++++++++------
|
||||
2 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||
index 592e144d..87829ff0 100644
|
||||
--- a/cloudinit/settings.py
|
||||
+++ b/cloudinit/settings.py
|
||||
@@ -54,13 +54,16 @@ CFG_BUILTIN = {
|
||||
],
|
||||
"def_log_file": "/var/log/cloud-init.log",
|
||||
"log_cfgs": [],
|
||||
- "syslog_fix_perms": ["syslog:adm", "root:adm", "root:wheel", "root:root"],
|
||||
+ "syslog_fix_perms": [],
|
||||
+ "mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
|
||||
+ "ssh_deletekeys": False,
|
||||
+ "ssh_genkeytypes": [],
|
||||
"system_info": {
|
||||
"paths": {
|
||||
"cloud_dir": "/var/lib/cloud",
|
||||
"templates_dir": "/etc/cloud/templates/",
|
||||
},
|
||||
- "distro": "ubuntu",
|
||||
+ "distro": "rhel",
|
||||
"network": {"renderers": None},
|
||||
},
|
||||
"vendor_data": {"enabled": True, "prefix": []},
|
||||
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
|
||||
index ab427115..c8c2ae81 100644
|
||||
--- a/tests/unittests/cmd/test_main.py
|
||||
+++ b/tests/unittests/cmd/test_main.py
|
||||
@@ -119,14 +119,19 @@ 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": [],
|
||||
+ "ssh_deletekeys": False,
|
||||
+ "ssh_genkeytypes": [],
|
||||
+ "mount_default_fields": [
|
||||
+ None,
|
||||
+ None,
|
||||
+ "auto",
|
||||
+ "defaults,nofail",
|
||||
+ "0",
|
||||
+ "2",
|
||||
+ ],
|
||||
}
|
||||
)
|
||||
updated_cfg.pop("system_info")
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
From 471353b3c3bf5cba5cab4d1b203b1c259c709fde Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Thu, 31 May 2018 20:00:32 +0200
|
||||
Subject: sysconfig: Don't write BOOTPROTO=dhcp for ipv6 dhcp
|
||||
|
||||
Don't write BOOTPROTO=dhcp for ipv6 dhcp, as BOOTPROTO applies
|
||||
only to ipv4. Explicitly write IPV6_AUTOCONF=no for dhcp on ipv6.
|
||||
|
||||
X-downstream-only: yes
|
||||
|
||||
Resolves: rhbz#1519271
|
||||
Signed-off-by: Ryan McCabe <rmccabe@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 1 +
|
||||
tests/unittests/test_net.py | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index ae0554ef..ec166cf1 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -310,6 +310,7 @@ class Renderer(renderer.Renderer):
|
||||
if subnet_type == 'dhcp6':
|
||||
iface_cfg['IPV6INIT'] = True
|
||||
iface_cfg['DHCPV6C'] = True
|
||||
+ iface_cfg['IPV6_AUTOCONF'] = False
|
||||
elif subnet_type in ['dhcp4', 'dhcp']:
|
||||
iface_cfg['BOOTPROTO'] = 'dhcp'
|
||||
elif subnet_type == 'static':
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 5f1aa3e7..8bcafe08 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -886,6 +886,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=none
|
||||
DEVICE=bond0
|
||||
DHCPV6C=yes
|
||||
+ IPV6_AUTOCONF=no
|
||||
IPV6INIT=yes
|
||||
MACADDR=aa:bb:cc:dd:ee:ff
|
||||
ONBOOT=yes
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From 21ea1cda0055416119edea44de95b5606f0b0e15 Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Tue, 17 Apr 2018 13:07:54 +0200
|
||||
Subject: DataSourceAzure.py: use hostnamectl to set hostname
|
||||
|
||||
RH-Author: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Message-id: <20180417130754.12918-3-vkuznets@redhat.com>
|
||||
Patchwork-id: 79659
|
||||
O-Subject: [RHEL7.6/7.5.z cloud-init PATCH 2/2] DataSourceAzure.py: use hostnamectl to set hostname
|
||||
Bugzilla: 1568717
|
||||
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
|
||||
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
|
||||
The right way to set hostname in RHEL7 is:
|
||||
|
||||
$ hostnamectl set-hostname HOSTNAME
|
||||
|
||||
DataSourceAzure, however, uses:
|
||||
$ hostname HOSTSNAME
|
||||
|
||||
instead and this causes problems. We can't simply change
|
||||
'BUILTIN_DS_CONFIG' in DataSourceAzure.py as 'hostname' is being used
|
||||
for both getting and setting the hostname.
|
||||
|
||||
Long term, this should be fixed in a different way. Cloud-init
|
||||
has distro-specific hostname setting/getting (see
|
||||
cloudinit/distros/rhel.py) and DataSourceAzure.py needs to be switched
|
||||
to use these.
|
||||
|
||||
Resolves: rhbz#1434109
|
||||
|
||||
X-downstream-only: yes
|
||||
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/sources/DataSourceAzure.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
||||
index e076d5dc..7dbeb04c 100644
|
||||
--- a/cloudinit/sources/DataSourceAzure.py
|
||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
||||
@@ -238,7 +238,7 @@ def get_hostname(hostname_command='hostname'):
|
||||
|
||||
|
||||
def set_hostname(hostname, hostname_command='hostname'):
|
||||
- util.subp([hostname_command, hostname])
|
||||
+ util.subp(['hostnamectl', 'set-hostname', str(hostname)])
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From 6444df4c91c611c65bb292e75e2726f767edcf2b Mon Sep 17 00:00:00 2001
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Thu, 26 Apr 2018 09:27:49 +0200
|
||||
Subject: sysconfig: Don't disable IPV6_AUTOCONF
|
||||
|
||||
RH-Author: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Message-id: <20180426092749.7251-2-vkuznets@redhat.com>
|
||||
Patchwork-id: 79904
|
||||
O-Subject: [RHEL7.6/7.5.z cloud-init PATCH 1/1] sysconfig: Don't disable IPV6_AUTOCONF
|
||||
Bugzilla: 1578702
|
||||
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
|
||||
|
||||
Downstream-only commit 118458a3fb ("sysconfig: Don't write BOOTPROTO=dhcp
|
||||
for ipv6 dhcp") did two things:
|
||||
1) Disabled BOOTPROTO='dhcp' for dhcp6 setups. This change seems to be
|
||||
correct as BOOTPROTO is unrelated to IPv6. The change was since merged
|
||||
upstream (commit a57928d3c314d9568712cd190cb1e721e14c108b).
|
||||
2) Explicitly disabled AUTOCONF and this broke many valid configurations
|
||||
using it instead of DHCPV6C. Revert this part of the change. In case
|
||||
DHCPV6C-only support is needed something like a new 'dhcpv6c_only'
|
||||
network type needs to be suggested upstream.
|
||||
|
||||
X-downstream-only: yes
|
||||
|
||||
Resolves: rhbz#1558854
|
||||
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@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 ec166cf1..ae0554ef 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -310,7 +310,6 @@ class Renderer(renderer.Renderer):
|
||||
if subnet_type == 'dhcp6':
|
||||
iface_cfg['IPV6INIT'] = True
|
||||
iface_cfg['DHCPV6C'] = True
|
||||
- iface_cfg['IPV6_AUTOCONF'] = False
|
||||
elif subnet_type in ['dhcp4', 'dhcp']:
|
||||
iface_cfg['BOOTPROTO'] = 'dhcp'
|
||||
elif subnet_type == 'static':
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
From 86bd1e20fc802edfb920fa53bd611d469f83250b Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Fri, 18 Jan 2019 16:55:36 +0100
|
||||
Subject: net: Make sysconfig renderer compatible with Network Manager.
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190118165536.25963-1-otubo@redhat.com>
|
||||
Patchwork-id: 84052
|
||||
O-Subject: [RHEL-8.0 cloud-init PATCH] net: Make sysconfig renderer compatible with Network Manager.
|
||||
Bugzilla: 1602784
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1602784
|
||||
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=19877292
|
||||
Tested by: upstream maintainers and me
|
||||
|
||||
commit 3861102fcaf47a882516d8b6daab518308eb3086
|
||||
Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Fri Jan 18 15:36:19 2019 +0000
|
||||
|
||||
net: Make sysconfig renderer compatible with Network Manager.
|
||||
|
||||
The 'sysconfig' renderer is activated if, and only if, there's ifup and
|
||||
ifdown commands present in its search dictonary or the network-scripts
|
||||
configuration files are found. This patch adds a check for Network-
|
||||
Manager configuration file as well.
|
||||
|
||||
This solution is based on the use of the plugin 'ifcfg-rh' present in
|
||||
Network-Manager and is designed to support Fedora 29 or other
|
||||
distributions that also replaced network-scripts by Network-Manager.
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 36 +++++++++++++++++++
|
||||
tests/unittests/test_net.py | 71 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 107 insertions(+)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index ae0554ef..dc1815d9 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -10,11 +10,14 @@ from cloudinit.distros.parsers import resolv_conf
|
||||
from cloudinit import log as logging
|
||||
from cloudinit import util
|
||||
|
||||
+from configobj import ConfigObj
|
||||
+
|
||||
from . import renderer
|
||||
from .network_state import (
|
||||
is_ipv6_addr, net_prefix_to_ipv4_mask, subnet_is_ipv6)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
+NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
|
||||
|
||||
|
||||
def _make_header(sep='#'):
|
||||
@@ -46,6 +49,24 @@ def _quote_value(value):
|
||||
return value
|
||||
|
||||
|
||||
+def enable_ifcfg_rh(path):
|
||||
+ """Add ifcfg-rh to NetworkManager.cfg plugins if main section is present"""
|
||||
+ config = ConfigObj(path)
|
||||
+ if 'main' in config:
|
||||
+ if 'plugins' in config['main']:
|
||||
+ if 'ifcfg-rh' in config['main']['plugins']:
|
||||
+ return
|
||||
+ else:
|
||||
+ config['main']['plugins'] = []
|
||||
+
|
||||
+ if isinstance(config['main']['plugins'], list):
|
||||
+ config['main']['plugins'].append('ifcfg-rh')
|
||||
+ else:
|
||||
+ config['main']['plugins'] = [config['main']['plugins'], 'ifcfg-rh']
|
||||
+ config.write()
|
||||
+ LOG.debug('Enabled ifcfg-rh NetworkManager plugins')
|
||||
+
|
||||
+
|
||||
class ConfigMap(object):
|
||||
"""Sysconfig like dictionary object."""
|
||||
|
||||
@@ -656,6 +677,8 @@ class Renderer(renderer.Renderer):
|
||||
netrules_content = self._render_persistent_net(network_state)
|
||||
netrules_path = util.target_path(target, self.netrules_path)
|
||||
util.write_file(netrules_path, netrules_content, file_mode)
|
||||
+ if available_nm(target=target):
|
||||
+ enable_ifcfg_rh(util.target_path(target, path=NM_CFG_FILE))
|
||||
|
||||
sysconfig_path = util.target_path(target, templates.get('control'))
|
||||
# Distros configuring /etc/sysconfig/network as a file e.g. Centos
|
||||
@@ -670,6 +693,13 @@ class Renderer(renderer.Renderer):
|
||||
|
||||
|
||||
def available(target=None):
|
||||
+ sysconfig = available_sysconfig(target=target)
|
||||
+ nm = available_nm(target=target)
|
||||
+
|
||||
+ return any([nm, sysconfig])
|
||||
+
|
||||
+
|
||||
+def available_sysconfig(target=None):
|
||||
expected = ['ifup', 'ifdown']
|
||||
search = ['/sbin', '/usr/sbin']
|
||||
for p in expected:
|
||||
@@ -685,4 +715,10 @@ def available(target=None):
|
||||
return True
|
||||
|
||||
|
||||
+def available_nm(target=None):
|
||||
+ if not os.path.isfile(util.target_path(target, path=NM_CFG_FILE)):
|
||||
+ return False
|
||||
+ return True
|
||||
+
|
||||
+
|
||||
# vi: ts=4 expandtab
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 8bcafe08..526a30ed 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -22,6 +22,7 @@ import os
|
||||
import textwrap
|
||||
import yaml
|
||||
|
||||
+
|
||||
DHCP_CONTENT_1 = """
|
||||
DEVICE='eth0'
|
||||
PROTO='dhcp'
|
||||
@@ -1854,6 +1855,7 @@ class TestRhelSysConfigRendering(CiTestCase):
|
||||
|
||||
with_logs = True
|
||||
|
||||
+ nm_cfg_file = "/etc/NetworkManager/NetworkManager.conf"
|
||||
scripts_dir = '/etc/sysconfig/network-scripts'
|
||||
header = ('# Created by cloud-init on instance boot automatically, '
|
||||
'do not edit.\n#\n')
|
||||
@@ -2497,6 +2499,75 @@ iface eth0 inet dhcp
|
||||
self.assertEqual(
|
||||
expected, dir2dict(tmp_dir)['/etc/network/interfaces'])
|
||||
|
||||
+ def test_check_ifcfg_rh(self):
|
||||
+ """ifcfg-rh plugin is added NetworkManager.conf if conf present."""
|
||||
+ render_dir = self.tmp_dir()
|
||||
+ nm_cfg = util.target_path(render_dir, path=self.nm_cfg_file)
|
||||
+ util.ensure_dir(os.path.dirname(nm_cfg))
|
||||
+
|
||||
+ # write a template nm.conf, note plugins is a list here
|
||||
+ with open(nm_cfg, 'w') as fh:
|
||||
+ fh.write('# test_check_ifcfg_rh\n[main]\nplugins=foo,bar\n')
|
||||
+ self.assertTrue(os.path.exists(nm_cfg))
|
||||
+
|
||||
+ # render and read
|
||||
+ entry = NETWORK_CONFIGS['small']
|
||||
+ found = self._render_and_read(network_config=yaml.load(entry['yaml']),
|
||||
+ dir=render_dir)
|
||||
+ self._compare_files_to_expected(entry[self.expected_name], found)
|
||||
+ self._assert_headers(found)
|
||||
+
|
||||
+ # check ifcfg-rh is in the 'plugins' list
|
||||
+ config = sysconfig.ConfigObj(nm_cfg)
|
||||
+ self.assertIn('ifcfg-rh', config['main']['plugins'])
|
||||
+
|
||||
+ def test_check_ifcfg_rh_plugins_string(self):
|
||||
+ """ifcfg-rh plugin is append when plugins is a string."""
|
||||
+ render_dir = self.tmp_path("render")
|
||||
+ os.makedirs(render_dir)
|
||||
+ nm_cfg = util.target_path(render_dir, path=self.nm_cfg_file)
|
||||
+ util.ensure_dir(os.path.dirname(nm_cfg))
|
||||
+
|
||||
+ # write a template nm.conf, note plugins is a value here
|
||||
+ util.write_file(nm_cfg, '# test_check_ifcfg_rh\n[main]\nplugins=foo\n')
|
||||
+
|
||||
+ # render and read
|
||||
+ entry = NETWORK_CONFIGS['small']
|
||||
+ found = self._render_and_read(network_config=yaml.load(entry['yaml']),
|
||||
+ dir=render_dir)
|
||||
+ self._compare_files_to_expected(entry[self.expected_name], found)
|
||||
+ self._assert_headers(found)
|
||||
+
|
||||
+ # check raw content has plugin
|
||||
+ nm_file_content = util.load_file(nm_cfg)
|
||||
+ self.assertIn('ifcfg-rh', nm_file_content)
|
||||
+
|
||||
+ # check ifcfg-rh is in the 'plugins' list
|
||||
+ config = sysconfig.ConfigObj(nm_cfg)
|
||||
+ self.assertIn('ifcfg-rh', config['main']['plugins'])
|
||||
+
|
||||
+ def test_check_ifcfg_rh_plugins_no_plugins(self):
|
||||
+ """enable_ifcfg_plugin creates plugins value if missing."""
|
||||
+ render_dir = self.tmp_path("render")
|
||||
+ os.makedirs(render_dir)
|
||||
+ nm_cfg = util.target_path(render_dir, path=self.nm_cfg_file)
|
||||
+ util.ensure_dir(os.path.dirname(nm_cfg))
|
||||
+
|
||||
+ # write a template nm.conf, note plugins is missing
|
||||
+ util.write_file(nm_cfg, '# test_check_ifcfg_rh\n[main]\n')
|
||||
+ self.assertTrue(os.path.exists(nm_cfg))
|
||||
+
|
||||
+ # render and read
|
||||
+ entry = NETWORK_CONFIGS['small']
|
||||
+ found = self._render_and_read(network_config=yaml.load(entry['yaml']),
|
||||
+ dir=render_dir)
|
||||
+ self._compare_files_to_expected(entry[self.expected_name], found)
|
||||
+ self._assert_headers(found)
|
||||
+
|
||||
+ # check ifcfg-rh is in the 'plugins' list
|
||||
+ config = sysconfig.ConfigObj(nm_cfg)
|
||||
+ self.assertIn('ifcfg-rh', config['main']['plugins'])
|
||||
+
|
||||
|
||||
class TestNetplanNetRendering(CiTestCase):
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
From 2e070086275341dfceb6d5b1e12f06f22e7bbfcd Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 23 Jan 2019 12:30:21 +0100
|
||||
Subject: net: Wait for dhclient to daemonize before reading lease file
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190123123021.32708-1-otubo@redhat.com>
|
||||
Patchwork-id: 84095
|
||||
O-Subject: [RHEL-7.7 cloud-init PATCH] net: Wait for dhclient to daemonize before reading lease file
|
||||
Bugzilla: 1632967
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1632967
|
||||
Brew: https://bugzilla.redhat.com/show_bug.cgi?id=1632967
|
||||
Tested: Me and upstream
|
||||
|
||||
commit fdadcb5fae51f4e6799314ab98e3aec56c79b17c
|
||||
Author: Jason Zions <jasonzio@microsoft.com>
|
||||
Date: Tue Jan 15 21:37:17 2019 +0000
|
||||
|
||||
net: Wait for dhclient to daemonize before reading lease file
|
||||
|
||||
cloud-init uses dhclient to fetch the DHCP lease so it can extract
|
||||
DHCP options. dhclient creates the leasefile, then writes to it;
|
||||
simply waiting for the leasefile to appear creates a race between
|
||||
dhclient and cloud-init. Instead, wait for dhclient to be parented by
|
||||
init. At that point, we know it has written to the leasefile, so it's
|
||||
safe to copy the file and kill the process.
|
||||
|
||||
cloud-init creates a temporary directory in which to execute dhclient,
|
||||
and deletes that directory after it has killed the process. If
|
||||
cloud-init abandons waiting for dhclient to daemonize, it will still
|
||||
attempt to delete the temporary directory, but will not report an
|
||||
exception should that attempt fail.
|
||||
|
||||
LP: #1794399
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/net/dhcp.py | 44 +++++++++++++++++++++---------
|
||||
cloudinit/net/tests/test_dhcp.py | 15 ++++++++--
|
||||
cloudinit/temp_utils.py | 4 +--
|
||||
cloudinit/tests/test_temp_utils.py | 18 +++++++++++-
|
||||
cloudinit/util.py | 16 ++++++++++-
|
||||
tests/unittests/test_util.py | 6 ++++
|
||||
6 files changed, 83 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
|
||||
index 0db991db..c98a97cd 100644
|
||||
--- a/cloudinit/net/dhcp.py
|
||||
+++ b/cloudinit/net/dhcp.py
|
||||
@@ -9,6 +9,7 @@ import logging
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
+import time
|
||||
|
||||
from cloudinit.net import (
|
||||
EphemeralIPv4Network, find_fallback_nic, get_devicelist,
|
||||
@@ -127,7 +128,9 @@ def maybe_perform_dhcp_discovery(nic=None):
|
||||
if not dhclient_path:
|
||||
LOG.debug('Skip dhclient configuration: No dhclient command found.')
|
||||
return []
|
||||
- with temp_utils.tempdir(prefix='cloud-init-dhcp-', needs_exe=True) as tdir:
|
||||
+ with temp_utils.tempdir(rmtree_ignore_errors=True,
|
||||
+ prefix='cloud-init-dhcp-',
|
||||
+ needs_exe=True) as tdir:
|
||||
# Use /var/tmp because /run/cloud-init/tmp is mounted noexec
|
||||
return dhcp_discovery(dhclient_path, nic, tdir)
|
||||
|
||||
@@ -195,24 +198,39 @@ def dhcp_discovery(dhclient_cmd_path, interface, cleandir):
|
||||
'-pf', pid_file, interface, '-sf', '/bin/true']
|
||||
util.subp(cmd, capture=True)
|
||||
|
||||
- # dhclient doesn't write a pid file until after it forks when it gets a
|
||||
- # proper lease response. Since cleandir is a temp directory that gets
|
||||
- # removed, we need to wait for that pidfile creation before the
|
||||
- # cleandir is removed, otherwise we get FileNotFound errors.
|
||||
+ # Wait for pid file and lease file to appear, and for the process
|
||||
+ # named by the pid file to daemonize (have pid 1 as its parent). If we
|
||||
+ # try to read the lease file before daemonization happens, we might try
|
||||
+ # to read it before the dhclient has actually written it. We also have
|
||||
+ # to wait until the dhclient has become a daemon so we can be sure to
|
||||
+ # kill the correct process, thus freeing cleandir to be deleted back
|
||||
+ # up the callstack.
|
||||
missing = util.wait_for_files(
|
||||
[pid_file, lease_file], maxwait=5, naplen=0.01)
|
||||
if missing:
|
||||
LOG.warning("dhclient did not produce expected files: %s",
|
||||
', '.join(os.path.basename(f) for f in missing))
|
||||
return []
|
||||
- pid_content = util.load_file(pid_file).strip()
|
||||
- try:
|
||||
- pid = int(pid_content)
|
||||
- except ValueError:
|
||||
- LOG.debug(
|
||||
- "pid file contains non-integer content '%s'", pid_content)
|
||||
- else:
|
||||
- os.kill(pid, signal.SIGKILL)
|
||||
+
|
||||
+ ppid = 'unknown'
|
||||
+ for _ in range(0, 1000):
|
||||
+ pid_content = util.load_file(pid_file).strip()
|
||||
+ try:
|
||||
+ pid = int(pid_content)
|
||||
+ except ValueError:
|
||||
+ pass
|
||||
+ else:
|
||||
+ ppid = util.get_proc_ppid(pid)
|
||||
+ if ppid == 1:
|
||||
+ LOG.debug('killing dhclient with pid=%s', pid)
|
||||
+ os.kill(pid, signal.SIGKILL)
|
||||
+ return parse_dhcp_lease_file(lease_file)
|
||||
+ time.sleep(0.01)
|
||||
+
|
||||
+ LOG.error(
|
||||
+ 'dhclient(pid=%s, parentpid=%s) failed to daemonize after %s seconds',
|
||||
+ pid_content, ppid, 0.01 * 1000
|
||||
+ )
|
||||
return parse_dhcp_lease_file(lease_file)
|
||||
|
||||
|
||||
diff --git a/cloudinit/net/tests/test_dhcp.py b/cloudinit/net/tests/test_dhcp.py
|
||||
index cd3e7328..79e8842f 100644
|
||||
--- a/cloudinit/net/tests/test_dhcp.py
|
||||
+++ b/cloudinit/net/tests/test_dhcp.py
|
||||
@@ -145,16 +145,20 @@ class TestDHCPDiscoveryClean(CiTestCase):
|
||||
'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1'}],
|
||||
dhcp_discovery(dhclient_script, 'eth9', tmpdir))
|
||||
self.assertIn(
|
||||
- "pid file contains non-integer content ''", self.logs.getvalue())
|
||||
+ "dhclient(pid=, parentpid=unknown) failed "
|
||||
+ "to daemonize after 10.0 seconds",
|
||||
+ self.logs.getvalue())
|
||||
m_kill.assert_not_called()
|
||||
|
||||
+ @mock.patch('cloudinit.net.dhcp.util.get_proc_ppid')
|
||||
@mock.patch('cloudinit.net.dhcp.os.kill')
|
||||
@mock.patch('cloudinit.net.dhcp.util.wait_for_files')
|
||||
@mock.patch('cloudinit.net.dhcp.util.subp')
|
||||
def test_dhcp_discovery_run_in_sandbox_waits_on_lease_and_pid(self,
|
||||
m_subp,
|
||||
m_wait,
|
||||
- m_kill):
|
||||
+ m_kill,
|
||||
+ m_getppid):
|
||||
"""dhcp_discovery waits for the presence of pidfile and dhcp.leases."""
|
||||
tmpdir = self.tmp_dir()
|
||||
dhclient_script = os.path.join(tmpdir, 'dhclient.orig')
|
||||
@@ -164,6 +168,7 @@ class TestDHCPDiscoveryClean(CiTestCase):
|
||||
pidfile = self.tmp_path('dhclient.pid', tmpdir)
|
||||
leasefile = self.tmp_path('dhcp.leases', tmpdir)
|
||||
m_wait.return_value = [pidfile] # Return the missing pidfile wait for
|
||||
+ m_getppid.return_value = 1 # Indicate that dhclient has daemonized
|
||||
self.assertEqual([], dhcp_discovery(dhclient_script, 'eth9', tmpdir))
|
||||
self.assertEqual(
|
||||
mock.call([pidfile, leasefile], maxwait=5, naplen=0.01),
|
||||
@@ -173,9 +178,10 @@ class TestDHCPDiscoveryClean(CiTestCase):
|
||||
self.logs.getvalue())
|
||||
m_kill.assert_not_called()
|
||||
|
||||
+ @mock.patch('cloudinit.net.dhcp.util.get_proc_ppid')
|
||||
@mock.patch('cloudinit.net.dhcp.os.kill')
|
||||
@mock.patch('cloudinit.net.dhcp.util.subp')
|
||||
- def test_dhcp_discovery_run_in_sandbox(self, m_subp, m_kill):
|
||||
+ def test_dhcp_discovery_run_in_sandbox(self, m_subp, m_kill, m_getppid):
|
||||
"""dhcp_discovery brings up the interface and runs dhclient.
|
||||
|
||||
It also returns the parsed dhcp.leases file generated in the sandbox.
|
||||
@@ -197,6 +203,7 @@ class TestDHCPDiscoveryClean(CiTestCase):
|
||||
pid_file = os.path.join(tmpdir, 'dhclient.pid')
|
||||
my_pid = 1
|
||||
write_file(pid_file, "%d\n" % my_pid)
|
||||
+ m_getppid.return_value = 1 # Indicate that dhclient has daemonized
|
||||
|
||||
self.assertItemsEqual(
|
||||
[{'interface': 'eth9', 'fixed-address': '192.168.2.74',
|
||||
@@ -355,3 +362,5 @@ class TestEphemeralDhcpNoNetworkSetup(HttprettyTestCase):
|
||||
self.assertEqual(fake_lease, lease)
|
||||
# Ensure that dhcp discovery occurs
|
||||
m_dhcp.called_once_with()
|
||||
+
|
||||
+# vi: ts=4 expandtab
|
||||
diff --git a/cloudinit/temp_utils.py b/cloudinit/temp_utils.py
|
||||
index c98a1b53..346276ec 100644
|
||||
--- a/cloudinit/temp_utils.py
|
||||
+++ b/cloudinit/temp_utils.py
|
||||
@@ -81,7 +81,7 @@ def ExtendedTemporaryFile(**kwargs):
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
-def tempdir(**kwargs):
|
||||
+def tempdir(rmtree_ignore_errors=False, **kwargs):
|
||||
# This seems like it was only added in python 3.2
|
||||
# Make it since its useful...
|
||||
# See: http://bugs.python.org/file12970/tempdir.patch
|
||||
@@ -89,7 +89,7 @@ def tempdir(**kwargs):
|
||||
try:
|
||||
yield tdir
|
||||
finally:
|
||||
- shutil.rmtree(tdir)
|
||||
+ shutil.rmtree(tdir, ignore_errors=rmtree_ignore_errors)
|
||||
|
||||
|
||||
def mkdtemp(**kwargs):
|
||||
diff --git a/cloudinit/tests/test_temp_utils.py b/cloudinit/tests/test_temp_utils.py
|
||||
index ffbb92cd..4a52ef89 100644
|
||||
--- a/cloudinit/tests/test_temp_utils.py
|
||||
+++ b/cloudinit/tests/test_temp_utils.py
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
"""Tests for cloudinit.temp_utils"""
|
||||
|
||||
-from cloudinit.temp_utils import mkdtemp, mkstemp
|
||||
+from cloudinit.temp_utils import mkdtemp, mkstemp, tempdir
|
||||
from cloudinit.tests.helpers import CiTestCase, wrap_and_call
|
||||
+import os
|
||||
|
||||
|
||||
class TestTempUtils(CiTestCase):
|
||||
@@ -98,4 +99,19 @@ class TestTempUtils(CiTestCase):
|
||||
self.assertEqual('/fake/return/path', retval)
|
||||
self.assertEqual([{'dir': '/run/cloud-init/tmp'}], calls)
|
||||
|
||||
+ def test_tempdir_error_suppression(self):
|
||||
+ """test tempdir suppresses errors during directory removal."""
|
||||
+
|
||||
+ with self.assertRaises(OSError):
|
||||
+ with tempdir(prefix='cloud-init-dhcp-') as tdir:
|
||||
+ os.rmdir(tdir)
|
||||
+ # As a result, the directory is already gone,
|
||||
+ # so shutil.rmtree should raise OSError
|
||||
+
|
||||
+ with tempdir(rmtree_ignore_errors=True,
|
||||
+ prefix='cloud-init-dhcp-') as tdir:
|
||||
+ os.rmdir(tdir)
|
||||
+ # Since the directory is already gone, shutil.rmtree would raise
|
||||
+ # OSError, but we suppress that
|
||||
+
|
||||
# vi: ts=4 expandtab
|
||||
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
||||
index 7800f7bc..a84112a9 100644
|
||||
--- a/cloudinit/util.py
|
||||
+++ b/cloudinit/util.py
|
||||
@@ -2861,7 +2861,6 @@ def mount_is_read_write(mount_point):
|
||||
mount_opts = result[-1].split(',')
|
||||
return mount_opts[0] == 'rw'
|
||||
|
||||
-
|
||||
def udevadm_settle(exists=None, timeout=None):
|
||||
"""Invoke udevadm settle with optional exists and timeout parameters"""
|
||||
settle_cmd = ["udevadm", "settle"]
|
||||
@@ -2875,5 +2874,20 @@ def udevadm_settle(exists=None, timeout=None):
|
||||
|
||||
return subp(settle_cmd)
|
||||
|
||||
+def get_proc_ppid(pid):
|
||||
+ """
|
||||
+ Return the parent pid of a process.
|
||||
+ """
|
||||
+ ppid = 0
|
||||
+ try:
|
||||
+ contents = load_file("/proc/%s/stat" % pid, quiet=True)
|
||||
+ except IOError as e:
|
||||
+ LOG.warning('Failed to load /proc/%s/stat. %s', pid, e)
|
||||
+ if contents:
|
||||
+ parts = contents.split(" ", 4)
|
||||
+ # man proc says
|
||||
+ # ppid %d (4) The PID of the parent.
|
||||
+ ppid = int(parts[3])
|
||||
+ return ppid
|
||||
|
||||
# vi: ts=4 expandtab
|
||||
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
|
||||
index 5a14479a..8aebcd62 100644
|
||||
--- a/tests/unittests/test_util.py
|
||||
+++ b/tests/unittests/test_util.py
|
||||
@@ -1114,6 +1114,12 @@ class TestLoadShellContent(helpers.TestCase):
|
||||
'key3="val3 #tricky"',
|
||||
''])))
|
||||
|
||||
+ def test_get_proc_ppid(self):
|
||||
+ """get_proc_ppid returns correct parent pid value."""
|
||||
+ my_pid = os.getpid()
|
||||
+ my_ppid = os.getppid()
|
||||
+ self.assertEqual(my_ppid, util.get_proc_ppid(my_pid))
|
||||
+
|
||||
|
||||
class TestGetProcEnv(helpers.TestCase):
|
||||
"""test get_proc_env."""
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
From 8a3bf53398f312b46ed4f304df4c66d061e612c7 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Thu, 28 Feb 2019 12:38:36 +0100
|
||||
Subject: cloud-init-per: don't use dashes in sem names
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190228123836.17979-1-otubo@redhat.com>
|
||||
Patchwork-id: 84743
|
||||
O-Subject: [RHEL-7.7 cloud-init PATCH] This is to fix https://bugs.launchpad.net/cloud-init/+bug/1812676
|
||||
Bugzilla: 1664876
|
||||
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
|
||||
From: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
|
||||
It was found that when there is a dash in cloud-init-per command
|
||||
name and cloud-init-per is executed through cloud-init's bootcmd, e.g:
|
||||
|
||||
bootcmd:
|
||||
- cloud-init-per instance mycmd-bootcmd /usr/bin/mycmd
|
||||
|
||||
the command is executed on each boot. However, running the same
|
||||
cloud-init-per command manually after boot doesn't reveal the issue. Turns
|
||||
out the issue comes from 'migrator' cloud-init module which renames all
|
||||
files in /var/lib/cloud/instance/sem/ replacing dashes with underscores. As
|
||||
migrator runs before bootcmd it renames
|
||||
|
||||
/var/lib/cloud/instance/sem/bootper.mycmd-bootcmd.instance
|
||||
to
|
||||
/var/lib/cloud/instance/sem/bootper.mycmd_bootcmd.instance
|
||||
|
||||
so cloud-init-per doesn't see it and thinks that the comment was never ran
|
||||
before. On next boot the sequence repeats.
|
||||
|
||||
There are multiple ways to resolve the issue. This patch takes the
|
||||
following approach: 'canonicalize' sem names by replacing dashes with
|
||||
underscores (this is consistent with post-'migrator' contents of
|
||||
/var/lib/cloud/instance/sem/). We, however, need to be careful: in case
|
||||
someone had a command with dashes before and he had migrator module enables
|
||||
we need to see the old sem file (or the command will run again and this can
|
||||
be as bad as formatting a partition!) so we add a small 'migrator' part to
|
||||
cloud-init-per script itself checking for legacy sem names.
|
||||
|
||||
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
|
||||
commit 9cf9d8cdd3a8fd7d4d425f7051122d0ac8af2bbd
|
||||
Author: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Date: Mon Feb 18 22:55:49 2019 +0000
|
||||
|
||||
This is to fix https://bugs.launchpad.net/cloud-init/+bug/1812676
|
||||
|
||||
Resolves: rhbz#1664876
|
||||
X-downstream-only: false
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
tools/cloud-init-per | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/cloud-init-per b/tools/cloud-init-per
|
||||
index 7d6754b6..eae3e93f 100755
|
||||
--- a/tools/cloud-init-per
|
||||
+++ b/tools/cloud-init-per
|
||||
@@ -38,7 +38,7 @@ fi
|
||||
[ "$1" = "-h" -o "$1" = "--help" ] && { Usage ; exit 0; }
|
||||
[ $# -ge 3 ] || { Usage 1>&2; exit 1; }
|
||||
freq=$1
|
||||
-name=$2
|
||||
+name=${2/-/_}
|
||||
shift 2;
|
||||
|
||||
[ "${name#*/}" = "${name}" ] || fail "name cannot contain a /"
|
||||
@@ -53,6 +53,12 @@ esac
|
||||
[ -d "${sem%/*}" ] || mkdir -p "${sem%/*}" ||
|
||||
fail "failed to make directory for ${sem}"
|
||||
|
||||
+# Rename legacy sem files with dashes in their names. Do not overwrite existing
|
||||
+# sem files to prevent clobbering those which may have been created from calls
|
||||
+# outside of cloud-init.
|
||||
+sem_legacy="${sem/_/-}"
|
||||
+[ "$sem" != "$sem_legacy" -a -e "$sem_legacy" ] && mv -n "$sem_legacy" "$sem"
|
||||
+
|
||||
[ "$freq" != "always" -a -e "$sem" ] && exit 0
|
||||
"$@"
|
||||
ret=$?
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,572 +0,0 @@
|
|||
From 8e168f17b0c138d589f7b3bea4a4b6fcc8e5e03f Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 6 Mar 2019 14:20:18 +0100
|
||||
Subject: azure: Filter list of ssh keys pulled from fabric
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190306142018.8902-1-otubo@redhat.com>
|
||||
Patchwork-id: 84807
|
||||
O-Subject: [RHEL-7.7 cloud-init PATCH] azure: Filter list of ssh keys pulled from fabric
|
||||
Bugzilla: 1684040
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
|
||||
From: "Jason Zions (MSFT)" <jasonzio@microsoft.com>
|
||||
|
||||
commit 34f54360fcc1e0f805002a0b639d0a84eb2cb8ee
|
||||
Author: Jason Zions (MSFT) <jasonzio@microsoft.com>
|
||||
Date: Fri Feb 22 13:26:31 2019 +0000
|
||||
|
||||
azure: Filter list of ssh keys pulled from fabric
|
||||
|
||||
The Azure data source is expected to expose a list of
|
||||
ssh keys for the user-to-be-provisioned in the crawled
|
||||
metadata. When configured to use the __builtin__ agent
|
||||
this list is built by the WALinuxAgentShim. The shim
|
||||
retrieves the full set of certificates and public keys
|
||||
exposed to the VM from the wireserver, extracts any
|
||||
ssh keys it can, and returns that list.
|
||||
|
||||
This fix reduces that list of ssh keys to just the
|
||||
ones whose fingerprints appear in the "administrative
|
||||
user" section of the ovf-env.xml file. The Azure
|
||||
control plane exposes other ssh keys to the VM for
|
||||
other reasons, but those should not be added to the
|
||||
authorized_keys file for the provisioned user.
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/sources/DataSourceAzure.py | 13 +-
|
||||
cloudinit/sources/helpers/azure.py | 109 +++++++++----
|
||||
.../azure/parse_certificates_fingerprints | 4 +
|
||||
tests/data/azure/parse_certificates_pem | 152 ++++++++++++++++++
|
||||
tests/data/azure/pubkey_extract_cert | 13 ++
|
||||
tests/data/azure/pubkey_extract_ssh_key | 1 +
|
||||
.../test_datasource/test_azure_helper.py | 71 +++++++-
|
||||
7 files changed, 322 insertions(+), 41 deletions(-)
|
||||
create mode 100644 tests/data/azure/parse_certificates_fingerprints
|
||||
create mode 100644 tests/data/azure/parse_certificates_pem
|
||||
create mode 100644 tests/data/azure/pubkey_extract_cert
|
||||
create mode 100644 tests/data/azure/pubkey_extract_ssh_key
|
||||
|
||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
||||
index 7dbeb04c..2062ca5d 100644
|
||||
--- a/cloudinit/sources/DataSourceAzure.py
|
||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
||||
@@ -627,9 +627,11 @@ class DataSourceAzure(sources.DataSource):
|
||||
if self.ds_cfg['agent_command'] == AGENT_START_BUILTIN:
|
||||
self.bounce_network_with_azure_hostname()
|
||||
|
||||
+ pubkey_info = self.cfg.get('_pubkeys', None)
|
||||
metadata_func = partial(get_metadata_from_fabric,
|
||||
fallback_lease_file=self.
|
||||
- dhclient_lease_file)
|
||||
+ dhclient_lease_file,
|
||||
+ pubkey_info=pubkey_info)
|
||||
else:
|
||||
metadata_func = self.get_metadata_from_agent
|
||||
|
||||
@@ -642,6 +644,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
"Error communicating with Azure fabric; You may experience."
|
||||
"connectivity issues.", exc_info=True)
|
||||
return False
|
||||
+
|
||||
util.del_file(REPORTED_READY_MARKER_FILE)
|
||||
util.del_file(REPROVISION_MARKER_FILE)
|
||||
return fabric_data
|
||||
@@ -909,13 +912,15 @@ def find_child(node, filter_func):
|
||||
def load_azure_ovf_pubkeys(sshnode):
|
||||
# This parses a 'SSH' node formatted like below, and returns
|
||||
# an array of dicts.
|
||||
- # [{'fp': '6BE7A7C3C8A8F4B123CCA5D0C2F1BE4CA7B63ED7',
|
||||
- # 'path': 'where/to/go'}]
|
||||
+ # [{'fingerprint': '6BE7A7C3C8A8F4B123CCA5D0C2F1BE4CA7B63ED7',
|
||||
+ # 'path': '/where/to/go'}]
|
||||
#
|
||||
# <SSH><PublicKeys>
|
||||
- # <PublicKey><Fingerprint>ABC</FingerPrint><Path>/ABC</Path>
|
||||
+ # <PublicKey><Fingerprint>ABC</FingerPrint><Path>/x/y/z</Path>
|
||||
# ...
|
||||
# </PublicKeys></SSH>
|
||||
+ # Under some circumstances, there may be a <Value> element along with the
|
||||
+ # Fingerprint and Path. Pass those along if they appear.
|
||||
results = find_child(sshnode, lambda n: n.localName == "PublicKeys")
|
||||
if len(results) == 0:
|
||||
return []
|
||||
diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
|
||||
index e5696b1f..2829dd20 100644
|
||||
--- a/cloudinit/sources/helpers/azure.py
|
||||
+++ b/cloudinit/sources/helpers/azure.py
|
||||
@@ -138,9 +138,36 @@ class OpenSSLManager(object):
|
||||
self.certificate = certificate
|
||||
LOG.debug('New certificate generated.')
|
||||
|
||||
- def parse_certificates(self, certificates_xml):
|
||||
- tag = ElementTree.fromstring(certificates_xml).find(
|
||||
- './/Data')
|
||||
+ @staticmethod
|
||||
+ def _run_x509_action(action, cert):
|
||||
+ cmd = ['openssl', 'x509', '-noout', action]
|
||||
+ result, _ = util.subp(cmd, data=cert)
|
||||
+ return result
|
||||
+
|
||||
+ def _get_ssh_key_from_cert(self, certificate):
|
||||
+ pub_key = self._run_x509_action('-pubkey', certificate)
|
||||
+ keygen_cmd = ['ssh-keygen', '-i', '-m', 'PKCS8', '-f', '/dev/stdin']
|
||||
+ ssh_key, _ = util.subp(keygen_cmd, data=pub_key)
|
||||
+ return ssh_key
|
||||
+
|
||||
+ def _get_fingerprint_from_cert(self, certificate):
|
||||
+ """openssl x509 formats fingerprints as so:
|
||||
+ 'SHA1 Fingerprint=07:3E:19:D1:4D:1C:79:92:24:C6:A0:FD:8D:DA:\
|
||||
+ B6:A8:BF:27:D4:73\n'
|
||||
+
|
||||
+ Azure control plane passes that fingerprint as so:
|
||||
+ '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473'
|
||||
+ """
|
||||
+ raw_fp = self._run_x509_action('-fingerprint', certificate)
|
||||
+ eq = raw_fp.find('=')
|
||||
+ octets = raw_fp[eq+1:-1].split(':')
|
||||
+ return ''.join(octets)
|
||||
+
|
||||
+ def _decrypt_certs_from_xml(self, certificates_xml):
|
||||
+ """Decrypt the certificates XML document using the our private key;
|
||||
+ return the list of certs and private keys contained in the doc.
|
||||
+ """
|
||||
+ tag = ElementTree.fromstring(certificates_xml).find('.//Data')
|
||||
certificates_content = tag.text
|
||||
lines = [
|
||||
b'MIME-Version: 1.0',
|
||||
@@ -151,32 +178,30 @@ class OpenSSLManager(object):
|
||||
certificates_content.encode('utf-8'),
|
||||
]
|
||||
with cd(self.tmpdir):
|
||||
- with open('Certificates.p7m', 'wb') as f:
|
||||
- f.write(b'\n'.join(lines))
|
||||
out, _ = util.subp(
|
||||
- 'openssl cms -decrypt -in Certificates.p7m -inkey'
|
||||
+ 'openssl cms -decrypt -in /dev/stdin -inkey'
|
||||
' {private_key} -recip {certificate} | openssl pkcs12 -nodes'
|
||||
' -password pass:'.format(**self.certificate_names),
|
||||
- shell=True)
|
||||
- private_keys, certificates = [], []
|
||||
+ shell=True, data=b'\n'.join(lines))
|
||||
+ return out
|
||||
+
|
||||
+ def parse_certificates(self, certificates_xml):
|
||||
+ """Given the Certificates XML document, return a dictionary of
|
||||
+ fingerprints and associated SSH keys derived from the certs."""
|
||||
+ out = self._decrypt_certs_from_xml(certificates_xml)
|
||||
current = []
|
||||
+ keys = {}
|
||||
for line in out.splitlines():
|
||||
current.append(line)
|
||||
if re.match(r'[-]+END .*?KEY[-]+$', line):
|
||||
- private_keys.append('\n'.join(current))
|
||||
+ # ignore private_keys
|
||||
current = []
|
||||
elif re.match(r'[-]+END .*?CERTIFICATE[-]+$', line):
|
||||
- certificates.append('\n'.join(current))
|
||||
+ certificate = '\n'.join(current)
|
||||
+ ssh_key = self._get_ssh_key_from_cert(certificate)
|
||||
+ fingerprint = self._get_fingerprint_from_cert(certificate)
|
||||
+ keys[fingerprint] = ssh_key
|
||||
current = []
|
||||
- keys = []
|
||||
- for certificate in certificates:
|
||||
- with cd(self.tmpdir):
|
||||
- public_key, _ = util.subp(
|
||||
- 'openssl x509 -noout -pubkey |'
|
||||
- 'ssh-keygen -i -m PKCS8 -f /dev/stdin',
|
||||
- data=certificate,
|
||||
- shell=True)
|
||||
- keys.append(public_key)
|
||||
return keys
|
||||
|
||||
|
||||
@@ -206,7 +231,6 @@ class WALinuxAgentShim(object):
|
||||
self.dhcpoptions = dhcp_options
|
||||
self._endpoint = None
|
||||
self.openssl_manager = None
|
||||
- self.values = {}
|
||||
self.lease_file = fallback_lease_file
|
||||
|
||||
def clean_up(self):
|
||||
@@ -328,8 +352,9 @@ class WALinuxAgentShim(object):
|
||||
LOG.debug('Azure endpoint found at %s', endpoint_ip_address)
|
||||
return endpoint_ip_address
|
||||
|
||||
- def register_with_azure_and_fetch_data(self):
|
||||
- self.openssl_manager = OpenSSLManager()
|
||||
+ def register_with_azure_and_fetch_data(self, pubkey_info=None):
|
||||
+ if self.openssl_manager is None:
|
||||
+ self.openssl_manager = OpenSSLManager()
|
||||
http_client = AzureEndpointHttpClient(self.openssl_manager.certificate)
|
||||
LOG.info('Registering with Azure...')
|
||||
attempts = 0
|
||||
@@ -347,16 +372,37 @@ class WALinuxAgentShim(object):
|
||||
attempts += 1
|
||||
LOG.debug('Successfully fetched GoalState XML.')
|
||||
goal_state = GoalState(response.contents, http_client)
|
||||
- public_keys = []
|
||||
- if goal_state.certificates_xml is not None:
|
||||
+ ssh_keys = []
|
||||
+ if goal_state.certificates_xml is not None and pubkey_info is not None:
|
||||
LOG.debug('Certificate XML found; parsing out public keys.')
|
||||
- public_keys = self.openssl_manager.parse_certificates(
|
||||
+ keys_by_fingerprint = self.openssl_manager.parse_certificates(
|
||||
goal_state.certificates_xml)
|
||||
- data = {
|
||||
- 'public-keys': public_keys,
|
||||
- }
|
||||
+ ssh_keys = self._filter_pubkeys(keys_by_fingerprint, pubkey_info)
|
||||
self._report_ready(goal_state, http_client)
|
||||
- return data
|
||||
+ return {'public-keys': ssh_keys}
|
||||
+
|
||||
+ def _filter_pubkeys(self, keys_by_fingerprint, pubkey_info):
|
||||
+ """cloud-init expects a straightforward array of keys to be dropped
|
||||
+ into the user's authorized_keys file. Azure control plane exposes
|
||||
+ multiple public keys to the VM via wireserver. Select just the
|
||||
+ user's key(s) and return them, ignoring any other certs.
|
||||
+ """
|
||||
+ keys = []
|
||||
+ for pubkey in pubkey_info:
|
||||
+ if 'value' in pubkey and pubkey['value']:
|
||||
+ keys.append(pubkey['value'])
|
||||
+ elif 'fingerprint' in pubkey and pubkey['fingerprint']:
|
||||
+ fingerprint = pubkey['fingerprint']
|
||||
+ if fingerprint in keys_by_fingerprint:
|
||||
+ keys.append(keys_by_fingerprint[fingerprint])
|
||||
+ else:
|
||||
+ LOG.warning("ovf-env.xml specified PublicKey fingerprint "
|
||||
+ "%s not found in goalstate XML", fingerprint)
|
||||
+ else:
|
||||
+ LOG.warning("ovf-env.xml specified PublicKey with neither "
|
||||
+ "value nor fingerprint: %s", pubkey)
|
||||
+
|
||||
+ return keys
|
||||
|
||||
def _report_ready(self, goal_state, http_client):
|
||||
LOG.debug('Reporting ready to Azure fabric.')
|
||||
@@ -373,11 +419,12 @@ class WALinuxAgentShim(object):
|
||||
LOG.info('Reported ready to Azure fabric.')
|
||||
|
||||
|
||||
-def get_metadata_from_fabric(fallback_lease_file=None, dhcp_opts=None):
|
||||
+def get_metadata_from_fabric(fallback_lease_file=None, dhcp_opts=None,
|
||||
+ pubkey_info=None):
|
||||
shim = WALinuxAgentShim(fallback_lease_file=fallback_lease_file,
|
||||
dhcp_options=dhcp_opts)
|
||||
try:
|
||||
- return shim.register_with_azure_and_fetch_data()
|
||||
+ return shim.register_with_azure_and_fetch_data(pubkey_info=pubkey_info)
|
||||
finally:
|
||||
shim.clean_up()
|
||||
|
||||
diff --git a/tests/data/azure/parse_certificates_fingerprints b/tests/data/azure/parse_certificates_fingerprints
|
||||
new file mode 100644
|
||||
index 00000000..f7293c56
|
||||
--- /dev/null
|
||||
+++ b/tests/data/azure/parse_certificates_fingerprints
|
||||
@@ -0,0 +1,4 @@
|
||||
+ECEDEB3B8488D31AF3BC4CCED493F64B7D27D7B1
|
||||
+073E19D14D1C799224C6A0FD8DDAB6A8BF27D473
|
||||
+4C16E7FAD6297D74A9B25EB8F0A12808CEBE293E
|
||||
+929130695289B450FE45DCD5F6EF0CDE69865867
|
||||
diff --git a/tests/data/azure/parse_certificates_pem b/tests/data/azure/parse_certificates_pem
|
||||
new file mode 100644
|
||||
index 00000000..3521ea3a
|
||||
--- /dev/null
|
||||
+++ b/tests/data/azure/parse_certificates_pem
|
||||
@@ -0,0 +1,152 @@
|
||||
+Bag Attributes
|
||||
+ localKeyID: 01 00 00 00
|
||||
+ Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
|
||||
+Key Attributes
|
||||
+ X509v3 Key Usage: 10
|
||||
+-----BEGIN PRIVATE KEY-----
|
||||
+MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDlEe5fUqwdrQTP
|
||||
+W2oVlGK2f31q/8ULT8KmOTyUvL0RPdJQ69vvHOc5Q2CKg2eviHC2LWhF8WmpnZj6
|
||||
+61RL0GeFGizwvU8Moebw5p3oqdcgoGpHVtxf+mr4QcWF58/Fwez0dA4hcsimVNBz
|
||||
+eNpBBUIKNBMTBG+4d6hcQBUAGKUdGRcCGEyTqXLU0MgHjxC9JgVqWJl+X2LcAGj5
|
||||
+7J+tGYGTLzKJmeCeGVNN5ZtJ0T85MYHCKQk1/FElK+Kq5akovXffQHjlnCPcx0NJ
|
||||
+47NBjlPaFp2gjnAChn79bT4iCjOFZ9avWpqRpeU517UCnY7djOr3fuod/MSQyh3L
|
||||
+Wuem1tWBAgMBAAECggEBAM4ZXQRs6Kjmo95BHGiAEnSqrlgX+dycjcBq3QPh8KZT
|
||||
+nifqnf48XhnackENy7tWIjr3DctoUq4mOp8AHt77ijhqfaa4XSg7fwKeK9NLBGC5
|
||||
+lAXNtAey0o2894/sKrd+LMkgphoYIUnuI4LRaGV56potkj/ZDP/GwTcG/R4SDnTn
|
||||
+C1Nb05PNTAPQtPZrgPo7TdM6gGsTnFbVrYHQLyg2Sq/osHfF15YohB01esRLCAwb
|
||||
+EF8JkRC4hWIZoV7BsyQ39232zAJQGGla7+wKFs3kObwh3VnFkQpT94KZnNiZuEfG
|
||||
+x5pW4Pn3gXgNsftscXsaNe/M9mYZqo//Qw7NvUIvAvECgYEA9AVveyK0HOA06fhh
|
||||
++3hUWdvw7Pbrl+e06jO9+bT1RjQMbHKyI60DZyVGuAySN86iChJRoJr5c6xj+iXU
|
||||
+cR6BVJDjGH5t1tyiK2aYf6hEpK9/j8Z54UiVQ486zPP0PGfT2TO4lBLK+8AUmoaH
|
||||
+gk21ul8QeVCeCJa/o+xEoRFvzcUCgYEA8FCbbvInrUtNY+9eKaUYoNodsgBVjm5X
|
||||
+I0YPUL9D4d+1nvupHSV2NVmQl0w1RaJwrNTafrl5LkqjhQbmuWNta6QgfZzSA3LB
|
||||
+lWXo1Mm0azKdcD3qMGbvn0Q3zU+yGNEgmB/Yju3/NtgYRG6tc+FCWRbPbiCnZWT8
|
||||
+v3C2Y0XggI0CgYEA2/jCZBgGkTkzue5kNVJlh5OS/aog+pCvL6hxCtarfBuTT3ed
|
||||
+Sje+p46cz3DVpmUpATc+Si8py7KNdYQAm/BJ2be6X+woi9Xcgo87zWgcaPCjZzId
|
||||
+0I2jsIE/Gl6XvpRCDrxnGWRPgt3GNP4szbPLrDPiH9oie8+Y9eYYf7G+PZkCgYEA
|
||||
+nRSzZOPYV4f/QDF4pVQLMykfe/iH9B/fyWjEHg3He19VQmRReIHCMMEoqBziPXAe
|
||||
+onpHj8oAkeer1wpZyhhZr6CKtFDLXgGm09bXSC/IRMHC81klORovyzU2HHfZfCtG
|
||||
+WOmIDnU2+0xpIGIP8sztJ3qnf97MTJSkOSadsWo9gwkCgYEAh5AQmJQmck88Dff2
|
||||
+qIfJIX8d+BDw47BFJ89OmMFjGV8TNB+JO+AV4Vkodg4hxKpLqTFZTTUFgoYfy5u1
|
||||
+1/BhAjpmCDCrzubCFhx+8VEoM2+2+MmnuQoMAm9+/mD/IidwRaARgXgvEmp7sfdt
|
||||
+RyWd+p2lYvFkC/jORQtDMY4uW1o=
|
||||
+-----END PRIVATE KEY-----
|
||||
+Bag Attributes
|
||||
+ localKeyID: 02 00 00 00
|
||||
+ Microsoft CSP Name: Microsoft Strong Cryptographic Provider
|
||||
+Key Attributes
|
||||
+ X509v3 Key Usage: 10
|
||||
+-----BEGIN PRIVATE KEY-----
|
||||
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDlQhPrZwVQYFV4
|
||||
+FBc0H1iTXYaznMpwZvEITKtXWACzTdguUderEVOkXW3HTi5HvC2rMayt0nqo3zcd
|
||||
+x1eGiqdjpZQ/wMrkz9wNEM/nNMsXntEwxk0jCVNKB/jz6vf+BOtrSI01SritAGZW
|
||||
+dpKoTUyztT8C2mA3X6D8g3m4Dd07ltnzxaDqAQIU5jBHh3f/Q14tlPNZWUIiqVTC
|
||||
+gDxgAe7MDmfs9h3CInTBX1XM5J4UsLTL23/padgeSvP5YF5qr1+0c7Tdftxr2lwA
|
||||
+N3rLkisf5EiLAToVyJJlgP/exo2I8DaIKe7DZzD3Y1CrurOpkcMKYu5kM1Htlbua
|
||||
+tDkAa2oDAgMBAAECggEAOvdueS9DyiMlCKAeQb1IQosdQOh0l0ma+FgEABC2CWhd
|
||||
+0LgjQTBRM6cGO+urcq7/jhdWQ1UuUG4tVn71z7itCi/F/Enhxc2C22d2GhFVpWsn
|
||||
+giSXJYpZ/mIjkdVfWNo6FRuRmmHwMys1p0qTOS+8qUJWhSzW75csqJZGgeUrAI61
|
||||
+LBV5F0SGR7dR2xZfy7PeDs9xpD0QivDt5DpsZWPaPvw4QlhdLgw6/YU1h9vtm6ci
|
||||
+xLjnPRLZ7JMpcQHO8dUDl6FiEI7yQ11BDm253VQAVMddYRPQABn7SpEF8kD/aZVh
|
||||
+2Clvz61Rz80SKjPUthMPLWMCRp7zB0xDMzt3/1i+tQKBgQD6Ar1/oD3eFnRnpi4u
|
||||
+n/hdHJtMuXWNfUA4dspNjP6WGOid9sgIeUUdif1XyVJ+afITzvgpWc7nUWIqG2bQ
|
||||
+WxJ/4q2rjUdvjNXTy1voVungR2jD5WLQ9DKeaTR0yCliWlx4JgdPG7qGI5MMwsr+
|
||||
+R/PUoUUhGeEX+o/sCSieO3iUrQKBgQDqwBEMvIdhAv/CK2sG3fsKYX8rFT55ZNX3
|
||||
+Tix9DbUGY3wQColNuI8U1nDlxE9U6VOfT9RPqKelBLCgbzB23kdEJnjSlnqlTxrx
|
||||
+E+Hkndyf2ckdJAR3XNxoQ6SRLJNBsgoBj/z5tlfZE9/Jc+uh0mYy3e6g6XCVPBcz
|
||||
+MgoIc+ofbwKBgQCGQhZ1hR30N+bHCozeaPW9OvGDIE0qcEqeh9xYDRFilXnF6pK9
|
||||
+SjJ9jG7KR8jPLiHb1VebDSl5O1EV/6UU2vNyTc6pw7LLCryBgkGW4aWy1WZDXNnW
|
||||
+EG1meGS9GghvUss5kmJ2bxOZmV0Mi0brisQ8OWagQf+JGvtS7BAt+Q3l+QKBgAb9
|
||||
+8YQPmXiqPjPqVyW9Ntz4SnFeEJ5NApJ7IZgX8GxgSjGwHqbR+HEGchZl4ncE/Bii
|
||||
+qBA3Vcb0fM5KgYcI19aPzsl28fA6ivLjRLcqfIfGVNcpW3iyq13vpdctHLW4N9QU
|
||||
+FdTaOYOds+ysJziKq8CYG6NvUIshXw+HTgUybqbBAoGBAIIOqcmmtgOClAwipA17
|
||||
+dAHsI9Sjk+J0+d4JU6o+5TsmhUfUKIjXf5+xqJkJcQZMEe5GhxcCuYkgFicvh4Hz
|
||||
+kv2H/EU35LcJTqC6KTKZOWIbGcn1cqsvwm3GQJffYDiO8fRZSwCaif2J3F2lfH4Y
|
||||
+R/fA67HXFSTT+OncdRpY1NOn
|
||||
+-----END PRIVATE KEY-----
|
||||
+Bag Attributes: <Empty Attributes>
|
||||
+subject=/CN=CRP/OU=AzureRT/O=Microsoft Corporation/L=Redmond/ST=WA/C=US
|
||||
+issuer=/CN=Root Agency
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIB+TCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtSb290
|
||||
+IEFnZW5jeTAeFw0xOTAyMTUxOTA0MDRaFw0yOTAyMTUxOTE0MDRaMGwxDDAKBgNV
|
||||
+BAMMA0NSUDEQMA4GA1UECwwHQXp1cmVSVDEeMBwGA1UECgwVTWljcm9zb2Z0IENv
|
||||
+cnBvcmF0aW9uMRAwDgYDVQQHDAdSZWRtb25kMQswCQYDVQQIDAJXQTELMAkGA1UE
|
||||
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIlPjJXzrRih4C
|
||||
+k/XsoI01oqo7IUxH3dA2F7vHGXQoIpKCp8Qe6Z6cFfdD8Uj+s+B1BX6hngwzIwjN
|
||||
+jE/23X3SALVzJVWzX4Y/IEjbgsuao6sOyNyB18wIU9YzZkVGj68fmMlUw3LnhPbe
|
||||
+eWkufZaJCaLyhQOwlRMbOcn48D6Ys8fccOyXNzpq3rH1OzeQpxS2M8zaJYP4/VZ/
|
||||
+sf6KRpI7bP+QwyFvNKfhcaO9/gj4kMo9lVGjvDU20FW6g8UVNJCV9N4GO6mOcyqo
|
||||
+OhuhVfjCNGgW7N1qi0TIVn0/MQM4l4dcT2R7Z/bV9fhMJLjGsy5A4TLAdRrhKUHT
|
||||
+bzi9HyDvAgMBAAEwDQYJKoZIhvcNAQEFBQADAQA=
|
||||
+-----END CERTIFICATE-----
|
||||
+Bag Attributes
|
||||
+ localKeyID: 01 00 00 00
|
||||
+subject=/C=US/ST=WASHINGTON/L=Seattle/O=Microsoft/OU=Azure/CN=AnhVo/emailAddress=redacted@microsoft.com
|
||||
+issuer=/C=US/ST=WASHINGTON/L=Seattle/O=Microsoft/OU=Azure/CN=AnhVo/emailAddress=redacted@microsoft.com
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIID7TCCAtWgAwIBAgIJALQS3yMg3R41MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
|
||||
+VQQGEwJVUzETMBEGA1UECAwKV0FTSElOR1RPTjEQMA4GA1UEBwwHU2VhdHRsZTES
|
||||
+MBAGA1UECgwJTWljcm9zb2Z0MQ4wDAYDVQQLDAVBenVyZTEOMAwGA1UEAwwFQW5o
|
||||
+Vm8xIjAgBgkqhkiG9w0BCQEWE2FuaHZvQG1pY3Jvc29mdC5jb20wHhcNMTkwMjE0
|
||||
+MjMxMjQwWhcNMjExMTEwMjMxMjQwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgM
|
||||
+CldBU0hJTkdUT04xEDAOBgNVBAcMB1NlYXR0bGUxEjAQBgNVBAoMCU1pY3Jvc29m
|
||||
+dDEOMAwGA1UECwwFQXp1cmUxDjAMBgNVBAMMBUFuaFZvMSIwIAYJKoZIhvcNAQkB
|
||||
+FhNhbmh2b0BtaWNyb3NvZnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
+CgKCAQEA5RHuX1KsHa0Ez1tqFZRitn99av/FC0/Cpjk8lLy9ET3SUOvb7xznOUNg
|
||||
+ioNnr4hwti1oRfFpqZ2Y+utUS9BnhRos8L1PDKHm8Oad6KnXIKBqR1bcX/pq+EHF
|
||||
+hefPxcHs9HQOIXLIplTQc3jaQQVCCjQTEwRvuHeoXEAVABilHRkXAhhMk6ly1NDI
|
||||
+B48QvSYFaliZfl9i3ABo+eyfrRmBky8yiZngnhlTTeWbSdE/OTGBwikJNfxRJSvi
|
||||
+quWpKL1330B45Zwj3MdDSeOzQY5T2hadoI5wAoZ+/W0+IgozhWfWr1qakaXlOde1
|
||||
+Ap2O3Yzq937qHfzEkMody1rnptbVgQIDAQABo1AwTjAdBgNVHQ4EFgQUPvdgLiv3
|
||||
+pAk4r0QTPZU3PFOZJvgwHwYDVR0jBBgwFoAUPvdgLiv3pAk4r0QTPZU3PFOZJvgw
|
||||
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVUHZT+h9+uCPLTEl5IDg
|
||||
+kqd9WpzXA7PJd/V+7DeDDTkEd06FIKTWZLfxLVVDjQJnQqubQb//e0zGu1qKbXnX
|
||||
+R7xqWabGU4eyPeUFWddmt1OHhxKLU3HbJNJJdL6XKiQtpGGUQt/mqNQ/DEr6hhNF
|
||||
+im5I79iA8H/dXA2gyZrj5Rxea4mtsaYO0mfp1NrFtJpAh2Djy4B1lBXBIv4DWG9e
|
||||
+mMEwzcLCOZj2cOMA6+mdLMUjYCvIRtnn5MKUHyZX5EmX79wsqMTvVpddlVLB9Kgz
|
||||
+Qnvft9+SBWh9+F3ip7BsL6Q4Q9v8eHRbnP0ya7ddlgh64uwf9VOfZZdKCnwqudJP
|
||||
+3g==
|
||||
+-----END CERTIFICATE-----
|
||||
+Bag Attributes
|
||||
+ localKeyID: 02 00 00 00
|
||||
+subject=/CN=/subscriptions/redacted/resourcegroups/redacted/providers/Microsoft.Compute/virtualMachines/redacted
|
||||
+issuer=/CN=Microsoft.ManagedIdentity
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIDnTCCAoWgAwIBAgIUB2lauSRccvFkoJybUfIwOUqBN7MwDQYJKoZIhvcNAQEL
|
||||
+BQAwJDEiMCAGA1UEAxMZTWljcm9zb2Z0Lk1hbmFnZWRJZGVudGl0eTAeFw0xOTAy
|
||||
+MTUxOTA5MDBaFw0xOTA4MTQxOTA5MDBaMIGUMYGRMIGOBgNVBAMTgYYvc3Vic2Ny
|
||||
+aXB0aW9ucy8yN2I3NTBjZC1lZDQzLTQyZmQtOTA0NC04ZDc1ZTEyNGFlNTUvcmVz
|
||||
+b3VyY2Vncm91cHMvYW5oZXh0cmFzc2gvcHJvdmlkZXJzL01pY3Jvc29mdC5Db21w
|
||||
+dXRlL3ZpcnR1YWxNYWNoaW5lcy9hbmh0ZXN0Y2VydDCCASIwDQYJKoZIhvcNAQEB
|
||||
+BQADggEPADCCAQoCggEBAOVCE+tnBVBgVXgUFzQfWJNdhrOcynBm8QhMq1dYALNN
|
||||
+2C5R16sRU6RdbcdOLke8LasxrK3SeqjfNx3HV4aKp2OllD/AyuTP3A0Qz+c0yxee
|
||||
+0TDGTSMJU0oH+PPq9/4E62tIjTVKuK0AZlZ2kqhNTLO1PwLaYDdfoPyDebgN3TuW
|
||||
+2fPFoOoBAhTmMEeHd/9DXi2U81lZQiKpVMKAPGAB7swOZ+z2HcIidMFfVczknhSw
|
||||
+tMvbf+lp2B5K8/lgXmqvX7RztN1+3GvaXAA3esuSKx/kSIsBOhXIkmWA/97GjYjw
|
||||
+Nogp7sNnMPdjUKu6s6mRwwpi7mQzUe2Vu5q0OQBragMCAwEAAaNWMFQwDgYDVR0P
|
||||
+AQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHwYD
|
||||
+VR0jBBgwFoAUOJvzEsriQWdJBndPrK+Me1bCPjYwDQYJKoZIhvcNAQELBQADggEB
|
||||
+AFGP/g8o7Hv/to11M0UqfzJuW/AyH9RZtSRcNQFLZUndwweQ6fap8lFsA4REUdqe
|
||||
+7Quqp5JNNY1XzKLWXMPoheIDH1A8FFXdsAroArzlNs9tO3TlIHE8A7HxEVZEmR4b
|
||||
+7ZiixmkQPS2RkjEoV/GM6fheBrzuFn7X5kVZyE6cC5sfcebn8xhk3ZcXI0VmpdT0
|
||||
+jFBsf5IvFCIXXLLhJI4KXc8VMoKFU1jT9na/jyaoGmfwovKj4ib8s2aiXGAp7Y38
|
||||
+UCmY+bJapWom6Piy5Jzi/p/kzMVdJcSa+GqpuFxBoQYEVs2XYVl7cGu/wPM+NToC
|
||||
+pkSoWwF1QAnHn0eokR9E1rU=
|
||||
+-----END CERTIFICATE-----
|
||||
+Bag Attributes: <Empty Attributes>
|
||||
+subject=/CN=CRP/OU=AzureRT/O=Microsoft Corporation/L=Redmond/ST=WA/C=US
|
||||
+issuer=/CN=Root Agency
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIB+TCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtSb290
|
||||
+IEFnZW5jeTAeFw0xOTAyMTUxOTA0MDRaFw0yOTAyMTUxOTE0MDRaMGwxDDAKBgNV
|
||||
+BAMMA0NSUDEQMA4GA1UECwwHQXp1cmVSVDEeMBwGA1UECgwVTWljcm9zb2Z0IENv
|
||||
+cnBvcmF0aW9uMRAwDgYDVQQHDAdSZWRtb25kMQswCQYDVQQIDAJXQTELMAkGA1UE
|
||||
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHU9IDclbKVYVb
|
||||
+Yuv0+zViX+wTwlKspslmy/uf3hkWLh7pyzyrq70S7qtSW2EGixUPxZS/R8pOLHoi
|
||||
+nlKF9ILgj0gVTCJsSwnWpXRg3rhZwIVoYMHN50BHS1SqVD0lsWNMXmo76LoJcjmW
|
||||
+vwIznvj5C/gnhU+K7+c3m7AlCyU2wjwpBAEYj7PQs6l/wTqpEiaqC5NytNBd7qp+
|
||||
+lYYysVrpa1PFL0Nj4MMZARIfjkiJtL9qDhy9YZeJRQ6q/Fhz0kjvkZnfxixfKF4y
|
||||
+WzOfhBrAtpF6oOnuYKk3hxjh9KjTTX4/U8zdLojalX09iyHyEjwJKGlGEpzh1aY7
|
||||
+t5btUyvpAgMBAAEwDQYJKoZIhvcNAQEFBQADAQA=
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/tests/data/azure/pubkey_extract_cert b/tests/data/azure/pubkey_extract_cert
|
||||
new file mode 100644
|
||||
index 00000000..ce9b852d
|
||||
--- /dev/null
|
||||
+++ b/tests/data/azure/pubkey_extract_cert
|
||||
@@ -0,0 +1,13 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIB+TCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtSb290
|
||||
+IEFnZW5jeTAeFw0xOTAyMTUxOTA0MDRaFw0yOTAyMTUxOTE0MDRaMGwxDDAKBgNV
|
||||
+BAMMA0NSUDEQMA4GA1UECwwHQXp1cmVSVDEeMBwGA1UECgwVTWljcm9zb2Z0IENv
|
||||
+cnBvcmF0aW9uMRAwDgYDVQQHDAdSZWRtb25kMQswCQYDVQQIDAJXQTELMAkGA1UE
|
||||
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHU9IDclbKVYVb
|
||||
+Yuv0+zViX+wTwlKspslmy/uf3hkWLh7pyzyrq70S7qtSW2EGixUPxZS/R8pOLHoi
|
||||
+nlKF9ILgj0gVTCJsSwnWpXRg3rhZwIVoYMHN50BHS1SqVD0lsWNMXmo76LoJcjmW
|
||||
+vwIznvj5C/gnhU+K7+c3m7AlCyU2wjwpBAEYj7PQs6l/wTqpEiaqC5NytNBd7qp+
|
||||
+lYYysVrpa1PFL0Nj4MMZARIfjkiJtL9qDhy9YZeJRQ6q/Fhz0kjvkZnfxixfKF4y
|
||||
+WzOfhBrAtpF6oOnuYKk3hxjh9KjTTX4/U8zdLojalX09iyHyEjwJKGlGEpzh1aY7
|
||||
+t5btUyvpAgMBAAEwDQYJKoZIhvcNAQEFBQADAQA=
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/tests/data/azure/pubkey_extract_ssh_key b/tests/data/azure/pubkey_extract_ssh_key
|
||||
new file mode 100644
|
||||
index 00000000..54d749ed
|
||||
--- /dev/null
|
||||
+++ b/tests/data/azure/pubkey_extract_ssh_key
|
||||
@@ -0,0 +1 @@
|
||||
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHU9IDclbKVYVbYuv0+zViX+wTwlKspslmy/uf3hkWLh7pyzyrq70S7qtSW2EGixUPxZS/R8pOLHoinlKF9ILgj0gVTCJsSwnWpXRg3rhZwIVoYMHN50BHS1SqVD0lsWNMXmo76LoJcjmWvwIznvj5C/gnhU+K7+c3m7AlCyU2wjwpBAEYj7PQs6l/wTqpEiaqC5NytNBd7qp+lYYysVrpa1PFL0Nj4MMZARIfjkiJtL9qDhy9YZeJRQ6q/Fhz0kjvkZnfxixfKF4yWzOfhBrAtpF6oOnuYKk3hxjh9KjTTX4/U8zdLojalX09iyHyEjwJKGlGEpzh1aY7t5btUyvp
|
||||
diff --git a/tests/unittests/test_datasource/test_azure_helper.py b/tests/unittests/test_datasource/test_azure_helper.py
|
||||
index 26b2b93d..02556165 100644
|
||||
--- a/tests/unittests/test_datasource/test_azure_helper.py
|
||||
+++ b/tests/unittests/test_datasource/test_azure_helper.py
|
||||
@@ -1,11 +1,13 @@
|
||||
# This file is part of cloud-init. See LICENSE file for license information.
|
||||
|
||||
import os
|
||||
+import unittest2
|
||||
from textwrap import dedent
|
||||
|
||||
from cloudinit.sources.helpers import azure as azure_helper
|
||||
from cloudinit.tests.helpers import CiTestCase, ExitStack, mock, populate_dir
|
||||
|
||||
+from cloudinit.util import load_file
|
||||
from cloudinit.sources.helpers.azure import WALinuxAgentShim as wa_shim
|
||||
|
||||
GOAL_STATE_TEMPLATE = """\
|
||||
@@ -289,6 +291,50 @@ class TestOpenSSLManager(CiTestCase):
|
||||
self.assertEqual([mock.call(manager.tmpdir)], del_dir.call_args_list)
|
||||
|
||||
|
||||
+class TestOpenSSLManagerActions(CiTestCase):
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ super(TestOpenSSLManagerActions, self).setUp()
|
||||
+
|
||||
+ self.allowed_subp = True
|
||||
+
|
||||
+ def _data_file(self, name):
|
||||
+ path = 'tests/data/azure'
|
||||
+ return os.path.join(path, name)
|
||||
+
|
||||
+ @unittest2.skip("todo move to cloud_test")
|
||||
+ def test_pubkey_extract(self):
|
||||
+ cert = load_file(self._data_file('pubkey_extract_cert'))
|
||||
+ good_key = load_file(self._data_file('pubkey_extract_ssh_key'))
|
||||
+ sslmgr = azure_helper.OpenSSLManager()
|
||||
+ key = sslmgr._get_ssh_key_from_cert(cert)
|
||||
+ self.assertEqual(good_key, key)
|
||||
+
|
||||
+ good_fingerprint = '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473'
|
||||
+ fingerprint = sslmgr._get_fingerprint_from_cert(cert)
|
||||
+ self.assertEqual(good_fingerprint, fingerprint)
|
||||
+
|
||||
+ @unittest2.skip("todo move to cloud_test")
|
||||
+ @mock.patch.object(azure_helper.OpenSSLManager, '_decrypt_certs_from_xml')
|
||||
+ def test_parse_certificates(self, mock_decrypt_certs):
|
||||
+ """Azure control plane puts private keys as well as certificates
|
||||
+ into the Certificates XML object. Make sure only the public keys
|
||||
+ from certs are extracted and that fingerprints are converted to
|
||||
+ the form specified in the ovf-env.xml file.
|
||||
+ """
|
||||
+ cert_contents = load_file(self._data_file('parse_certificates_pem'))
|
||||
+ fingerprints = load_file(self._data_file(
|
||||
+ 'parse_certificates_fingerprints')
|
||||
+ ).splitlines()
|
||||
+ mock_decrypt_certs.return_value = cert_contents
|
||||
+ sslmgr = azure_helper.OpenSSLManager()
|
||||
+ keys_by_fp = sslmgr.parse_certificates('')
|
||||
+ for fp in keys_by_fp.keys():
|
||||
+ self.assertIn(fp, fingerprints)
|
||||
+ for fp in fingerprints:
|
||||
+ self.assertIn(fp, keys_by_fp)
|
||||
+
|
||||
+
|
||||
class TestWALinuxAgentShim(CiTestCase):
|
||||
|
||||
def setUp(self):
|
||||
@@ -329,18 +375,31 @@ class TestWALinuxAgentShim(CiTestCase):
|
||||
|
||||
def test_certificates_used_to_determine_public_keys(self):
|
||||
shim = wa_shim()
|
||||
- data = shim.register_with_azure_and_fetch_data()
|
||||
+ """if register_with_azure_and_fetch_data() isn't passed some info about
|
||||
+ the user's public keys, there's no point in even trying to parse
|
||||
+ the certificates
|
||||
+ """
|
||||
+ mypk = [{'fingerprint': 'fp1', 'path': 'path1'},
|
||||
+ {'fingerprint': 'fp3', 'path': 'path3', 'value': ''}]
|
||||
+ certs = {'fp1': 'expected-key',
|
||||
+ 'fp2': 'should-not-be-found',
|
||||
+ 'fp3': 'expected-no-value-key',
|
||||
+ }
|
||||
+ sslmgr = self.OpenSSLManager.return_value
|
||||
+ sslmgr.parse_certificates.return_value = certs
|
||||
+ data = shim.register_with_azure_and_fetch_data(pubkey_info=mypk)
|
||||
self.assertEqual(
|
||||
[mock.call(self.GoalState.return_value.certificates_xml)],
|
||||
- self.OpenSSLManager.return_value.parse_certificates.call_args_list)
|
||||
- self.assertEqual(
|
||||
- self.OpenSSLManager.return_value.parse_certificates.return_value,
|
||||
- data['public-keys'])
|
||||
+ sslmgr.parse_certificates.call_args_list)
|
||||
+ self.assertIn('expected-key', data['public-keys'])
|
||||
+ self.assertIn('expected-no-value-key', data['public-keys'])
|
||||
+ self.assertNotIn('should-not-be-found', data['public-keys'])
|
||||
|
||||
def test_absent_certificates_produces_empty_public_keys(self):
|
||||
+ mypk = [{'fingerprint': 'fp1', 'path': 'path1'}]
|
||||
self.GoalState.return_value.certificates_xml = None
|
||||
shim = wa_shim()
|
||||
- data = shim.register_with_azure_and_fetch_data()
|
||||
+ data = shim.register_with_azure_and_fetch_data(pubkey_info=mypk)
|
||||
self.assertEqual([], data['public-keys'])
|
||||
|
||||
def test_correct_url_used_for_report_ready(self):
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
From ffabcbbf0d4e990f04ab755dd87bb24e70c4fe78 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 20 Mar 2019 11:45:59 +0100
|
||||
Subject: include 'NOZEROCONF=yes' in /etc/sysconfig/network
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190320114559.23708-1-otubo@redhat.com>
|
||||
Patchwork-id: 84937
|
||||
O-Subject: [RHEL-7.7 cloud-init PATCH] include 'NOZEROCONF=yes' in /etc/sysconfig/network
|
||||
Bugzilla: 1653131
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
|
||||
The option NOZEROCONF=yes is not included by default in
|
||||
/etc/sysconfig/network, which is required by Overcloud instances. The
|
||||
patch also includes tests for the modifications.
|
||||
|
||||
X-downstream-only: yes
|
||||
Resolves: rhbz#1653131
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
||||
---
|
||||
cloudinit/net/sysconfig.py | 11 ++++++++++-
|
||||
tests/unittests/test_net.py | 1 -
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||
index dc1815d9..52bb8483 100644
|
||||
--- a/cloudinit/net/sysconfig.py
|
||||
+++ b/cloudinit/net/sysconfig.py
|
||||
@@ -684,7 +684,16 @@ class Renderer(renderer.Renderer):
|
||||
# Distros configuring /etc/sysconfig/network as a file e.g. Centos
|
||||
if sysconfig_path.endswith('network'):
|
||||
util.ensure_dir(os.path.dirname(sysconfig_path))
|
||||
- netcfg = [_make_header(), 'NETWORKING=yes']
|
||||
+ netcfg = []
|
||||
+ 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=')):
|
||||
+ netcfg.append(line)
|
||||
+ # Now generate the cloud-init portion of sysconfig/network
|
||||
+ netcfg.extend([_make_header(), 'NETWORKING=yes'])
|
||||
if network_state.use_ipv6:
|
||||
netcfg.append('NETWORKING_IPV6=yes')
|
||||
netcfg.append('IPV6_AUTOCONF=no')
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 526a30ed..012c43b5 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -887,7 +887,6 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
|
||||
BOOTPROTO=none
|
||||
DEVICE=bond0
|
||||
DHCPV6C=yes
|
||||
- IPV6_AUTOCONF=no
|
||||
IPV6INIT=yes
|
||||
MACADDR=aa:bb:cc:dd:ee:ff
|
||||
ONBOOT=yes
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
From 77585bbc6d01399ff88865b55dfb7a47b8640271 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: Ani Sinha <None>
|
||||
RH-MergeRequest: 113: rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg
|
||||
RH-Jira: RHEL-16572
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Commit: [1/1] f506bf58dc5458f50624342ec33bcd390aa0b719 (anisinha/rhel-cloud-init)
|
||||
|
||||
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>
|
||||
(cherry picked from commit b545a0cbabe8924d048b7172b30e7aad59ed32d5)
|
||||
(cherry picked from commit 855dec5dcc0892c0f7cedf06b025a794769a2a8d)
|
||||
|
||||
Fix unit test breakage
|
||||
|
||||
Fix unit test breakage due to the downstream change
|
||||
5d6674508c6478fa2c ("rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg")
|
||||
|
||||
X-downstream-only: true
|
||||
Fixes: 5d6674508c6478fa2c ("rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg")
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
Squashed:
|
||||
commit 1afec9e6008db187d1b675e4473d5a2bf0b3c36b
|
||||
Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
Date: Thu May 20 08:53:55 2021 +0200
|
||||
Subject: [PATCH 49/51] rhel/cloud.cfg: remove ssh_genkeytypes in settings.py
|
||||
and set in cloud.cfg
|
||||
|
||||
From fe6fb1843fe8df75899fe189b9e5f8ce3cd75be1 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Fri, 8 Dec 2023 12:50:15 +0530
|
||||
Subject: [PATCH 51/51] Fix unit test breakage
|
||||
|
||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
||||
---
|
||||
cloudinit/settings.py | 2 --
|
||||
tests/unittests/cmd/test_main.py | 2 --
|
||||
2 files changed, 4 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||
index 87829ff0..3a581e5b 100644
|
||||
--- a/cloudinit/settings.py
|
||||
+++ b/cloudinit/settings.py
|
||||
@@ -56,8 +56,6 @@ CFG_BUILTIN = {
|
||||
"log_cfgs": [],
|
||||
"syslog_fix_perms": [],
|
||||
"mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
|
||||
- "ssh_deletekeys": False,
|
||||
- "ssh_genkeytypes": [],
|
||||
"system_info": {
|
||||
"paths": {
|
||||
"cloud_dir": "/var/lib/cloud",
|
||||
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
|
||||
index c8c2ae81..19d26ebe 100644
|
||||
--- a/tests/unittests/cmd/test_main.py
|
||||
+++ b/tests/unittests/cmd/test_main.py
|
||||
@@ -122,8 +122,6 @@ class TestMain(FilesystemMockingTestCase):
|
||||
"vendor_data": {"enabled": True, "prefix": []},
|
||||
"vendor_data2": {"enabled": True, "prefix": []},
|
||||
"syslog_fix_perms": [],
|
||||
- "ssh_deletekeys": False,
|
||||
- "ssh_genkeytypes": [],
|
||||
"mount_default_fields": [
|
||||
None,
|
||||
None,
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -1,405 +0,0 @@
|
|||
From f919e65e4a462b385a6daa6b7cccc6af1358cbcf Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 29 May 2019 13:41:47 +0200
|
||||
Subject: [PATCH 3/5] Azure: Changes to the Hyper-V KVP Reporter
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190529134149.842-4-otubo@redhat.com>
|
||||
Patchwork-id: 88266
|
||||
O-Subject: [RHEL-8.0.1/RHEL-8.1.0 cloud-init PATCHv2 3/5] Azure: Changes to the Hyper-V KVP Reporter
|
||||
Bugzilla: 1691986
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
|
||||
From: Anh Vo <anhvo@microsoft.com>
|
||||
commit 86674f013dfcea3c075ab41373ffb475881066f6
|
||||
Author: Anh Vo <anhvo@microsoft.com>
|
||||
Date: Mon Apr 29 20:22:16 2019 +0000
|
||||
|
||||
Azure: Changes to the Hyper-V KVP Reporter
|
||||
|
||||
+ Truncate KVP Pool file to prevent stale entries from
|
||||
being processed by the Hyper-V KVP reporter.
|
||||
+ Drop filtering of KVPs as it is no longer needed.
|
||||
+ Batch appending of existing KVP entries.
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
cloudinit/reporting/handlers.py | 117 +++++++++++++++----------------
|
||||
tests/unittests/test_reporting_hyperv.py | 104 +++++++++++++--------------
|
||||
2 files changed, 106 insertions(+), 115 deletions(-)
|
||||
mode change 100644 => 100755 cloudinit/reporting/handlers.py
|
||||
mode change 100644 => 100755 tests/unittests/test_reporting_hyperv.py
|
||||
|
||||
diff --git a/cloudinit/reporting/handlers.py b/cloudinit/reporting/handlers.py
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
index 6d23558..10165ae
|
||||
--- a/cloudinit/reporting/handlers.py
|
||||
+++ b/cloudinit/reporting/handlers.py
|
||||
@@ -5,7 +5,6 @@ import fcntl
|
||||
import json
|
||||
import six
|
||||
import os
|
||||
-import re
|
||||
import struct
|
||||
import threading
|
||||
import time
|
||||
@@ -14,6 +13,7 @@ from cloudinit import log as logging
|
||||
from cloudinit.registry import DictRegistry
|
||||
from cloudinit import (url_helper, util)
|
||||
from datetime import datetime
|
||||
+from six.moves.queue import Empty as QueueEmptyError
|
||||
|
||||
if six.PY2:
|
||||
from multiprocessing.queues import JoinableQueue as JQueue
|
||||
@@ -129,24 +129,50 @@ class HyperVKvpReportingHandler(ReportingHandler):
|
||||
DESC_IDX_KEY = 'msg_i'
|
||||
JSON_SEPARATORS = (',', ':')
|
||||
KVP_POOL_FILE_GUEST = '/var/lib/hyperv/.kvp_pool_1'
|
||||
+ _already_truncated_pool_file = False
|
||||
|
||||
def __init__(self,
|
||||
kvp_file_path=KVP_POOL_FILE_GUEST,
|
||||
event_types=None):
|
||||
super(HyperVKvpReportingHandler, self).__init__()
|
||||
self._kvp_file_path = kvp_file_path
|
||||
+ HyperVKvpReportingHandler._truncate_guest_pool_file(
|
||||
+ self._kvp_file_path)
|
||||
+
|
||||
self._event_types = event_types
|
||||
self.q = JQueue()
|
||||
- self.kvp_file = None
|
||||
self.incarnation_no = self._get_incarnation_no()
|
||||
self.event_key_prefix = u"{0}|{1}".format(self.EVENT_PREFIX,
|
||||
self.incarnation_no)
|
||||
- self._current_offset = 0
|
||||
self.publish_thread = threading.Thread(
|
||||
target=self._publish_event_routine)
|
||||
self.publish_thread.daemon = True
|
||||
self.publish_thread.start()
|
||||
|
||||
+ @classmethod
|
||||
+ def _truncate_guest_pool_file(cls, kvp_file):
|
||||
+ """
|
||||
+ Truncate the pool file if it has not been truncated since boot.
|
||||
+ This should be done exactly once for the file indicated by
|
||||
+ KVP_POOL_FILE_GUEST constant above. This method takes a filename
|
||||
+ so that we can use an arbitrary file during unit testing.
|
||||
+ Since KVP is a best-effort telemetry channel we only attempt to
|
||||
+ truncate the file once and only if the file has not been modified
|
||||
+ since boot. Additional truncation can lead to loss of existing
|
||||
+ KVPs.
|
||||
+ """
|
||||
+ if cls._already_truncated_pool_file:
|
||||
+ return
|
||||
+ boot_time = time.time() - float(util.uptime())
|
||||
+ try:
|
||||
+ if os.path.getmtime(kvp_file) < boot_time:
|
||||
+ with open(kvp_file, "w"):
|
||||
+ pass
|
||||
+ except (OSError, IOError) as e:
|
||||
+ LOG.warning("failed to truncate kvp pool file, %s", e)
|
||||
+ finally:
|
||||
+ cls._already_truncated_pool_file = True
|
||||
+
|
||||
def _get_incarnation_no(self):
|
||||
"""
|
||||
use the time passed as the incarnation number.
|
||||
@@ -162,20 +188,15 @@ class HyperVKvpReportingHandler(ReportingHandler):
|
||||
|
||||
def _iterate_kvps(self, offset):
|
||||
"""iterate the kvp file from the current offset."""
|
||||
- try:
|
||||
- with open(self._kvp_file_path, 'rb+') as f:
|
||||
- self.kvp_file = f
|
||||
- fcntl.flock(f, fcntl.LOCK_EX)
|
||||
- f.seek(offset)
|
||||
+ with open(self._kvp_file_path, 'rb') as f:
|
||||
+ fcntl.flock(f, fcntl.LOCK_EX)
|
||||
+ f.seek(offset)
|
||||
+ record_data = f.read(self.HV_KVP_RECORD_SIZE)
|
||||
+ while len(record_data) == self.HV_KVP_RECORD_SIZE:
|
||||
+ kvp_item = self._decode_kvp_item(record_data)
|
||||
+ yield kvp_item
|
||||
record_data = f.read(self.HV_KVP_RECORD_SIZE)
|
||||
- while len(record_data) == self.HV_KVP_RECORD_SIZE:
|
||||
- self._current_offset += self.HV_KVP_RECORD_SIZE
|
||||
- kvp_item = self._decode_kvp_item(record_data)
|
||||
- yield kvp_item
|
||||
- record_data = f.read(self.HV_KVP_RECORD_SIZE)
|
||||
- fcntl.flock(f, fcntl.LOCK_UN)
|
||||
- finally:
|
||||
- self.kvp_file = None
|
||||
+ fcntl.flock(f, fcntl.LOCK_UN)
|
||||
|
||||
def _event_key(self, event):
|
||||
"""
|
||||
@@ -207,23 +228,13 @@ class HyperVKvpReportingHandler(ReportingHandler):
|
||||
|
||||
return {'key': k, 'value': v}
|
||||
|
||||
- def _update_kvp_item(self, record_data):
|
||||
- if self.kvp_file is None:
|
||||
- raise ReportException(
|
||||
- "kvp file '{0}' not opened."
|
||||
- .format(self._kvp_file_path))
|
||||
- self.kvp_file.seek(-self.HV_KVP_RECORD_SIZE, 1)
|
||||
- self.kvp_file.write(record_data)
|
||||
-
|
||||
def _append_kvp_item(self, record_data):
|
||||
- with open(self._kvp_file_path, 'rb+') as f:
|
||||
+ with open(self._kvp_file_path, 'ab') as f:
|
||||
fcntl.flock(f, fcntl.LOCK_EX)
|
||||
- # seek to end of the file
|
||||
- f.seek(0, 2)
|
||||
- f.write(record_data)
|
||||
+ for data in record_data:
|
||||
+ f.write(data)
|
||||
f.flush()
|
||||
fcntl.flock(f, fcntl.LOCK_UN)
|
||||
- self._current_offset = f.tell()
|
||||
|
||||
def _break_down(self, key, meta_data, description):
|
||||
del meta_data[self.MSG_KEY]
|
||||
@@ -279,40 +290,26 @@ class HyperVKvpReportingHandler(ReportingHandler):
|
||||
|
||||
def _publish_event_routine(self):
|
||||
while True:
|
||||
+ items_from_queue = 0
|
||||
try:
|
||||
event = self.q.get(block=True)
|
||||
- need_append = True
|
||||
+ items_from_queue += 1
|
||||
+ encoded_data = []
|
||||
+ while event is not None:
|
||||
+ encoded_data += self._encode_event(event)
|
||||
+ try:
|
||||
+ # get all the rest of the events in the queue
|
||||
+ event = self.q.get(block=False)
|
||||
+ items_from_queue += 1
|
||||
+ except QueueEmptyError:
|
||||
+ event = None
|
||||
try:
|
||||
- if not os.path.exists(self._kvp_file_path):
|
||||
- LOG.warning(
|
||||
- "skip writing events %s to %s. file not present.",
|
||||
- event.as_string(),
|
||||
- self._kvp_file_path)
|
||||
- encoded_event = self._encode_event(event)
|
||||
- # for each encoded_event
|
||||
- for encoded_data in (encoded_event):
|
||||
- for kvp in self._iterate_kvps(self._current_offset):
|
||||
- match = (
|
||||
- re.match(
|
||||
- r"^{0}\|(\d+)\|.+"
|
||||
- .format(self.EVENT_PREFIX),
|
||||
- kvp['key']
|
||||
- ))
|
||||
- if match:
|
||||
- match_groups = match.groups(0)
|
||||
- if int(match_groups[0]) < self.incarnation_no:
|
||||
- need_append = False
|
||||
- self._update_kvp_item(encoded_data)
|
||||
- continue
|
||||
- if need_append:
|
||||
- self._append_kvp_item(encoded_data)
|
||||
- except IOError as e:
|
||||
- LOG.warning(
|
||||
- "failed posting event to kvp: %s e:%s",
|
||||
- event.as_string(), e)
|
||||
+ self._append_kvp_item(encoded_data)
|
||||
+ except (OSError, IOError) as e:
|
||||
+ LOG.warning("failed posting events to kvp, %s", e)
|
||||
finally:
|
||||
- self.q.task_done()
|
||||
-
|
||||
+ for _ in range(items_from_queue):
|
||||
+ self.q.task_done()
|
||||
# when main process exits, q.get() will through EOFError
|
||||
# indicating we should exit this thread.
|
||||
except EOFError:
|
||||
@@ -322,7 +319,7 @@ class HyperVKvpReportingHandler(ReportingHandler):
|
||||
# if the kvp pool already contains a chunk of data,
|
||||
# so defer it to another thread.
|
||||
def publish_event(self, event):
|
||||
- if (not self._event_types or event.event_type in self._event_types):
|
||||
+ if not self._event_types or event.event_type in self._event_types:
|
||||
self.q.put(event)
|
||||
|
||||
def flush(self):
|
||||
diff --git a/tests/unittests/test_reporting_hyperv.py b/tests/unittests/test_reporting_hyperv.py
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
index 2e64c6c..d01ed5b
|
||||
--- a/tests/unittests/test_reporting_hyperv.py
|
||||
+++ b/tests/unittests/test_reporting_hyperv.py
|
||||
@@ -1,10 +1,12 @@
|
||||
# This file is part of cloud-init. See LICENSE file for license information.
|
||||
|
||||
from cloudinit.reporting import events
|
||||
-from cloudinit.reporting import handlers
|
||||
+from cloudinit.reporting.handlers import HyperVKvpReportingHandler
|
||||
|
||||
import json
|
||||
import os
|
||||
+import struct
|
||||
+import time
|
||||
|
||||
from cloudinit import util
|
||||
from cloudinit.tests.helpers import CiTestCase
|
||||
@@ -13,7 +15,7 @@ from cloudinit.tests.helpers import CiTestCase
|
||||
class TestKvpEncoding(CiTestCase):
|
||||
def test_encode_decode(self):
|
||||
kvp = {'key': 'key1', 'value': 'value1'}
|
||||
- kvp_reporting = handlers.HyperVKvpReportingHandler()
|
||||
+ kvp_reporting = HyperVKvpReportingHandler()
|
||||
data = kvp_reporting._encode_kvp_item(kvp['key'], kvp['value'])
|
||||
self.assertEqual(len(data), kvp_reporting.HV_KVP_RECORD_SIZE)
|
||||
decoded_kvp = kvp_reporting._decode_kvp_item(data)
|
||||
@@ -26,57 +28,9 @@ class TextKvpReporter(CiTestCase):
|
||||
self.tmp_file_path = self.tmp_path('kvp_pool_file')
|
||||
util.ensure_file(self.tmp_file_path)
|
||||
|
||||
- def test_event_type_can_be_filtered(self):
|
||||
- reporter = handlers.HyperVKvpReportingHandler(
|
||||
- kvp_file_path=self.tmp_file_path,
|
||||
- event_types=['foo', 'bar'])
|
||||
-
|
||||
- reporter.publish_event(
|
||||
- events.ReportingEvent('foo', 'name', 'description'))
|
||||
- reporter.publish_event(
|
||||
- events.ReportingEvent('some_other', 'name', 'description3'))
|
||||
- reporter.q.join()
|
||||
-
|
||||
- kvps = list(reporter._iterate_kvps(0))
|
||||
- self.assertEqual(1, len(kvps))
|
||||
-
|
||||
- reporter.publish_event(
|
||||
- events.ReportingEvent('bar', 'name', 'description2'))
|
||||
- reporter.q.join()
|
||||
- kvps = list(reporter._iterate_kvps(0))
|
||||
- self.assertEqual(2, len(kvps))
|
||||
-
|
||||
- self.assertIn('foo', kvps[0]['key'])
|
||||
- self.assertIn('bar', kvps[1]['key'])
|
||||
- self.assertNotIn('some_other', kvps[0]['key'])
|
||||
- self.assertNotIn('some_other', kvps[1]['key'])
|
||||
-
|
||||
- def test_events_are_over_written(self):
|
||||
- reporter = handlers.HyperVKvpReportingHandler(
|
||||
- kvp_file_path=self.tmp_file_path)
|
||||
-
|
||||
- self.assertEqual(0, len(list(reporter._iterate_kvps(0))))
|
||||
-
|
||||
- reporter.publish_event(
|
||||
- events.ReportingEvent('foo', 'name1', 'description'))
|
||||
- reporter.publish_event(
|
||||
- events.ReportingEvent('foo', 'name2', 'description'))
|
||||
- reporter.q.join()
|
||||
- self.assertEqual(2, len(list(reporter._iterate_kvps(0))))
|
||||
-
|
||||
- reporter2 = handlers.HyperVKvpReportingHandler(
|
||||
- kvp_file_path=self.tmp_file_path)
|
||||
- reporter2.incarnation_no = reporter.incarnation_no + 1
|
||||
- reporter2.publish_event(
|
||||
- events.ReportingEvent('foo', 'name3', 'description'))
|
||||
- reporter2.q.join()
|
||||
-
|
||||
- self.assertEqual(2, len(list(reporter2._iterate_kvps(0))))
|
||||
-
|
||||
def test_events_with_higher_incarnation_not_over_written(self):
|
||||
- reporter = handlers.HyperVKvpReportingHandler(
|
||||
+ reporter = HyperVKvpReportingHandler(
|
||||
kvp_file_path=self.tmp_file_path)
|
||||
-
|
||||
self.assertEqual(0, len(list(reporter._iterate_kvps(0))))
|
||||
|
||||
reporter.publish_event(
|
||||
@@ -86,7 +40,7 @@ class TextKvpReporter(CiTestCase):
|
||||
reporter.q.join()
|
||||
self.assertEqual(2, len(list(reporter._iterate_kvps(0))))
|
||||
|
||||
- reporter3 = handlers.HyperVKvpReportingHandler(
|
||||
+ reporter3 = HyperVKvpReportingHandler(
|
||||
kvp_file_path=self.tmp_file_path)
|
||||
reporter3.incarnation_no = reporter.incarnation_no - 1
|
||||
reporter3.publish_event(
|
||||
@@ -95,7 +49,7 @@ class TextKvpReporter(CiTestCase):
|
||||
self.assertEqual(3, len(list(reporter3._iterate_kvps(0))))
|
||||
|
||||
def test_finish_event_result_is_logged(self):
|
||||
- reporter = handlers.HyperVKvpReportingHandler(
|
||||
+ reporter = HyperVKvpReportingHandler(
|
||||
kvp_file_path=self.tmp_file_path)
|
||||
reporter.publish_event(
|
||||
events.FinishReportingEvent('name2', 'description1',
|
||||
@@ -105,7 +59,7 @@ class TextKvpReporter(CiTestCase):
|
||||
|
||||
def test_file_operation_issue(self):
|
||||
os.remove(self.tmp_file_path)
|
||||
- reporter = handlers.HyperVKvpReportingHandler(
|
||||
+ reporter = HyperVKvpReportingHandler(
|
||||
kvp_file_path=self.tmp_file_path)
|
||||
reporter.publish_event(
|
||||
events.FinishReportingEvent('name2', 'description1',
|
||||
@@ -113,7 +67,7 @@ class TextKvpReporter(CiTestCase):
|
||||
reporter.q.join()
|
||||
|
||||
def test_event_very_long(self):
|
||||
- reporter = handlers.HyperVKvpReportingHandler(
|
||||
+ reporter = HyperVKvpReportingHandler(
|
||||
kvp_file_path=self.tmp_file_path)
|
||||
description = 'ab' * reporter.HV_KVP_EXCHANGE_MAX_VALUE_SIZE
|
||||
long_event = events.FinishReportingEvent(
|
||||
@@ -132,3 +86,43 @@ class TextKvpReporter(CiTestCase):
|
||||
self.assertEqual(msg_slice['msg_i'], i)
|
||||
full_description += msg_slice['msg']
|
||||
self.assertEqual(description, full_description)
|
||||
+
|
||||
+ def test_not_truncate_kvp_file_modified_after_boot(self):
|
||||
+ with open(self.tmp_file_path, "wb+") as f:
|
||||
+ kvp = {'key': 'key1', 'value': 'value1'}
|
||||
+ data = (struct.pack("%ds%ds" % (
|
||||
+ HyperVKvpReportingHandler.HV_KVP_EXCHANGE_MAX_KEY_SIZE,
|
||||
+ HyperVKvpReportingHandler.HV_KVP_EXCHANGE_MAX_VALUE_SIZE),
|
||||
+ kvp['key'].encode('utf-8'), kvp['value'].encode('utf-8')))
|
||||
+ f.write(data)
|
||||
+ cur_time = time.time()
|
||||
+ os.utime(self.tmp_file_path, (cur_time, cur_time))
|
||||
+
|
||||
+ # reset this because the unit test framework
|
||||
+ # has already polluted the class variable
|
||||
+ HyperVKvpReportingHandler._already_truncated_pool_file = False
|
||||
+
|
||||
+ reporter = HyperVKvpReportingHandler(kvp_file_path=self.tmp_file_path)
|
||||
+ kvps = list(reporter._iterate_kvps(0))
|
||||
+ self.assertEqual(1, len(kvps))
|
||||
+
|
||||
+ def test_truncate_stale_kvp_file(self):
|
||||
+ with open(self.tmp_file_path, "wb+") as f:
|
||||
+ kvp = {'key': 'key1', 'value': 'value1'}
|
||||
+ data = (struct.pack("%ds%ds" % (
|
||||
+ HyperVKvpReportingHandler.HV_KVP_EXCHANGE_MAX_KEY_SIZE,
|
||||
+ HyperVKvpReportingHandler.HV_KVP_EXCHANGE_MAX_VALUE_SIZE),
|
||||
+ kvp['key'].encode('utf-8'), kvp['value'].encode('utf-8')))
|
||||
+ f.write(data)
|
||||
+
|
||||
+ # set the time ways back to make it look like
|
||||
+ # we had an old kvp file
|
||||
+ os.utime(self.tmp_file_path, (1000000, 1000000))
|
||||
+
|
||||
+ # reset this because the unit test framework
|
||||
+ # has already polluted the class variable
|
||||
+ HyperVKvpReportingHandler._already_truncated_pool_file = False
|
||||
+
|
||||
+ reporter = HyperVKvpReportingHandler(kvp_file_path=self.tmp_file_path)
|
||||
+ kvps = list(reporter._iterate_kvps(0))
|
||||
+ self.assertEqual(0, len(kvps))
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
From ae9b545cef4a68dfb9f9356dd27e43ff71ec26aa Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 29 May 2019 13:41:45 +0200
|
||||
Subject: [PATCH 1/5] Azure: Ensure platform random_seed is always serializable
|
||||
as JSON.
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190529134149.842-2-otubo@redhat.com>
|
||||
Patchwork-id: 88272
|
||||
O-Subject: [RHEL-8.0.1/RHEL-8.1.0 cloud-init PATCHv2 1/5] Azure: Ensure platform random_seed is always serializable as JSON.
|
||||
Bugzilla: 1691986
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
|
||||
From: "Jason Zions (MSFT)" <jasonzio@microsoft.com>
|
||||
commit 0dc3a77f41f4544e4cb5a41637af7693410d4cdf
|
||||
Author: Jason Zions (MSFT) <jasonzio@microsoft.com>
|
||||
Date: Tue Mar 26 18:53:50 2019 +0000
|
||||
|
||||
Azure: Ensure platform random_seed is always serializable as JSON.
|
||||
|
||||
The Azure platform surfaces random bytes into /sys via Hyper-V.
|
||||
Python 2.7 json.dump() raises an exception if asked to convert
|
||||
a str with non-character content, and python 3.0 json.dump()
|
||||
won't serialize a "bytes" value. As a result, c-i instance
|
||||
data is often not written by Azure, making reboots slower (c-i
|
||||
has to repeat work).
|
||||
|
||||
The random data is base64-encoded and then decoded into a string
|
||||
(str or unicode depending on the version of Python in use). The
|
||||
base64 string has just as many bits of entropy, so we're not
|
||||
throwing away useful "information", but we can be certain
|
||||
json.dump() will correctly serialize the bits.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
tests/unittests/test_datasource/test_azure.py
|
||||
Skipped the commit edf052c as it removes support for python-2.6
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
---
|
||||
cloudinit/sources/DataSourceAzure.py | 24 +++++++++++++++++++-----
|
||||
tests/data/azure/non_unicode_random_string | 1 +
|
||||
tests/unittests/test_datasource/test_azure.py | 24 ++++++++++++++++++++++--
|
||||
3 files changed, 42 insertions(+), 7 deletions(-)
|
||||
create mode 100644 tests/data/azure/non_unicode_random_string
|
||||
|
||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
||||
index 2062ca5..a768b2c 100644
|
||||
--- a/cloudinit/sources/DataSourceAzure.py
|
||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
||||
@@ -54,6 +54,7 @@ REPROVISION_MARKER_FILE = "/var/lib/cloud/data/poll_imds"
|
||||
REPORTED_READY_MARKER_FILE = "/var/lib/cloud/data/reported_ready"
|
||||
AGENT_SEED_DIR = '/var/lib/waagent'
|
||||
IMDS_URL = "http://169.254.169.254/metadata/"
|
||||
+PLATFORM_ENTROPY_SOURCE = "/sys/firmware/acpi/tables/OEM0"
|
||||
|
||||
# List of static scripts and network config artifacts created by
|
||||
# stock ubuntu suported images.
|
||||
@@ -195,6 +196,8 @@ if util.is_FreeBSD():
|
||||
RESOURCE_DISK_PATH = "/dev/" + res_disk
|
||||
else:
|
||||
LOG.debug("resource disk is None")
|
||||
+ # TODO Find where platform entropy data is surfaced
|
||||
+ PLATFORM_ENTROPY_SOURCE = None
|
||||
|
||||
BUILTIN_DS_CONFIG = {
|
||||
'agent_command': AGENT_START_BUILTIN,
|
||||
@@ -1100,16 +1103,27 @@ def _check_freebsd_cdrom(cdrom_dev):
|
||||
return False
|
||||
|
||||
|
||||
-def _get_random_seed():
|
||||
+def _get_random_seed(source=PLATFORM_ENTROPY_SOURCE):
|
||||
"""Return content random seed file if available, otherwise,
|
||||
return None."""
|
||||
# azure / hyper-v provides random data here
|
||||
- # TODO. find the seed on FreeBSD platform
|
||||
# now update ds_cfg to reflect contents pass in config
|
||||
- if util.is_FreeBSD():
|
||||
+ if source is None:
|
||||
return None
|
||||
- return util.load_file("/sys/firmware/acpi/tables/OEM0",
|
||||
- quiet=True, decode=False)
|
||||
+ seed = util.load_file(source, quiet=True, decode=False)
|
||||
+
|
||||
+ # The seed generally contains non-Unicode characters. load_file puts
|
||||
+ # them into a str (in python 2) or bytes (in python 3). In python 2,
|
||||
+ # bad octets in a str cause util.json_dumps() to throw an exception. In
|
||||
+ # python 3, bytes is a non-serializable type, and the handler load_file
|
||||
+ # uses applies b64 encoding *again* to handle it. The simplest solution
|
||||
+ # is to just b64encode the data and then decode it to a serializable
|
||||
+ # string. Same number of bits of entropy, just with 25% more zeroes.
|
||||
+ # There's no need to undo this base64-encoding when the random seed is
|
||||
+ # actually used in cc_seed_random.py.
|
||||
+ seed = base64.b64encode(seed).decode()
|
||||
+
|
||||
+ return seed
|
||||
|
||||
|
||||
def list_possible_azure_ds_devs():
|
||||
diff --git a/tests/data/azure/non_unicode_random_string b/tests/data/azure/non_unicode_random_string
|
||||
new file mode 100644
|
||||
index 0000000..b9ecefb
|
||||
--- /dev/null
|
||||
+++ b/tests/data/azure/non_unicode_random_string
|
||||
@@ -0,0 +1 @@
|
||||
+OEM0d\x00\x00\x00\x01\x80VRTUALMICROSFT\x02\x17\x00\x06MSFT\x97\x00\x00\x00C\xb4{V\xf4X%\x061x\x90\x1c\xfen\x86\xbf~\xf5\x8c\x94&\x88\xed\x84\xf9B\xbd\xd3\xf1\xdb\xee:\xd9\x0fc\x0e\x83(\xbd\xe3'\xfc\x85,\xdf\xf4\x13\x99N\xc5\xf3Y\x1e\xe3\x0b\xa4H\x08J\xb9\xdcdb$
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
|
||||
index 417d86a..eacf225 100644
|
||||
--- a/tests/unittests/test_datasource/test_azure.py
|
||||
+++ b/tests/unittests/test_datasource/test_azure.py
|
||||
@@ -7,11 +7,11 @@ from cloudinit.sources import (
|
||||
UNSET, DataSourceAzure as dsaz, InvalidMetaDataException)
|
||||
from cloudinit.util import (b64e, decode_binary, load_file, write_file,
|
||||
find_freebsd_part, get_path_dev_freebsd,
|
||||
- MountFailedError)
|
||||
+ MountFailedError, json_dumps, load_json)
|
||||
from cloudinit.version import version_string as vs
|
||||
from cloudinit.tests.helpers import (
|
||||
HttprettyTestCase, CiTestCase, populate_dir, mock, wrap_and_call,
|
||||
- ExitStack, PY26, SkipTest)
|
||||
+ ExitStack, PY26, SkipTest, resourceLocation)
|
||||
|
||||
import crypt
|
||||
import httpretty
|
||||
@@ -1924,4 +1924,24 @@ class TestWBIsPlatformViable(CiTestCase):
|
||||
self.logs.getvalue())
|
||||
|
||||
|
||||
+class TestRandomSeed(CiTestCase):
|
||||
+ """Test proper handling of random_seed"""
|
||||
+
|
||||
+ def test_non_ascii_seed_is_serializable(self):
|
||||
+ """Pass if a random string from the Azure infrastructure which
|
||||
+ contains at least one non-Unicode character can be converted to/from
|
||||
+ JSON without alteration and without throwing an exception.
|
||||
+ """
|
||||
+ path = resourceLocation("azure/non_unicode_random_string")
|
||||
+ result = dsaz._get_random_seed(path)
|
||||
+
|
||||
+ obj = {'seed': result}
|
||||
+ try:
|
||||
+ serialized = json_dumps(obj)
|
||||
+ deserialized = load_json(serialized)
|
||||
+ except UnicodeDecodeError:
|
||||
+ self.fail("Non-serializable random seed returned")
|
||||
+
|
||||
+ self.assertEqual(deserialized['seed'], result)
|
||||
+
|
||||
# vi: ts=4 expandtab
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
From b2500e258b930479cef36f514fcf9581ba68c976 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 29 May 2019 13:41:48 +0200
|
||||
Subject: [PATCH 4/5] DataSourceAzure: Adjust timeout for polling IMDS
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190529134149.842-5-otubo@redhat.com>
|
||||
Patchwork-id: 88267
|
||||
O-Subject: [RHEL-8.0.1/RHEL-8.1.0 cloud-init PATCHv2 4/5] DataSourceAzure: Adjust timeout for polling IMDS
|
||||
Bugzilla: 1691986
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
|
||||
From: Anh Vo <anhvo@microsoft.com>
|
||||
commit ab6621d849b24bb652243e88c79f6f3b446048d7
|
||||
Author: Anh Vo <anhvo@microsoft.com>
|
||||
Date: Wed May 8 14:54:03 2019 +0000
|
||||
|
||||
DataSourceAzure: Adjust timeout for polling IMDS
|
||||
|
||||
If the IMDS primary server is not available, falling back to the
|
||||
secondary server takes about 1s. The net result is that the
|
||||
expected E2E time is slightly more than 1s. This change increases
|
||||
the timeout to 2s to prevent the infinite loop of timeouts.
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
cloudinit/sources/DataSourceAzure.py | 15 ++++++++++-----
|
||||
tests/unittests/test_datasource/test_azure.py | 10 +++++++---
|
||||
2 files changed, 17 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
||||
index c827816..5baf8da 100755
|
||||
--- a/cloudinit/sources/DataSourceAzure.py
|
||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
||||
@@ -57,7 +57,12 @@ AZURE_CHASSIS_ASSET_TAG = '7783-7084-3265-9085-8269-3286-77'
|
||||
REPROVISION_MARKER_FILE = "/var/lib/cloud/data/poll_imds"
|
||||
REPORTED_READY_MARKER_FILE = "/var/lib/cloud/data/reported_ready"
|
||||
AGENT_SEED_DIR = '/var/lib/waagent'
|
||||
+
|
||||
+# In the event where the IMDS primary server is not
|
||||
+# available, it takes 1s to fallback to the secondary one
|
||||
+IMDS_TIMEOUT_IN_SECONDS = 2
|
||||
IMDS_URL = "http://169.254.169.254/metadata/"
|
||||
+
|
||||
PLATFORM_ENTROPY_SOURCE = "/sys/firmware/acpi/tables/OEM0"
|
||||
|
||||
# List of static scripts and network config artifacts created by
|
||||
@@ -582,9 +587,9 @@ class DataSourceAzure(sources.DataSource):
|
||||
return
|
||||
self._ephemeral_dhcp_ctx.clean_network()
|
||||
else:
|
||||
- return readurl(url, timeout=1, headers=headers,
|
||||
- exception_cb=exc_cb, infinite=True,
|
||||
- log_req_resp=False).contents
|
||||
+ return readurl(url, timeout=IMDS_TIMEOUT_IN_SECONDS,
|
||||
+ headers=headers, exception_cb=exc_cb,
|
||||
+ infinite=True, log_req_resp=False).contents
|
||||
except UrlError:
|
||||
# Teardown our EphemeralDHCPv4 context on failure as we retry
|
||||
self._ephemeral_dhcp_ctx.clean_network()
|
||||
@@ -1291,8 +1296,8 @@ def _get_metadata_from_imds(retries):
|
||||
headers = {"Metadata": "true"}
|
||||
try:
|
||||
response = readurl(
|
||||
- url, timeout=1, headers=headers, retries=retries,
|
||||
- exception_cb=retry_on_url_exc)
|
||||
+ url, timeout=IMDS_TIMEOUT_IN_SECONDS, headers=headers,
|
||||
+ retries=retries, exception_cb=retry_on_url_exc)
|
||||
except Exception as e:
|
||||
LOG.debug('Ignoring IMDS instance metadata: %s', e)
|
||||
return {}
|
||||
diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
|
||||
index eacf225..bc8b42c 100644
|
||||
--- a/tests/unittests/test_datasource/test_azure.py
|
||||
+++ b/tests/unittests/test_datasource/test_azure.py
|
||||
@@ -163,7 +163,8 @@ class TestGetMetadataFromIMDS(HttprettyTestCase):
|
||||
|
||||
m_readurl.assert_called_with(
|
||||
self.network_md_url, exception_cb=mock.ANY,
|
||||
- headers={'Metadata': 'true'}, retries=2, timeout=1)
|
||||
+ headers={'Metadata': 'true'}, retries=2,
|
||||
+ timeout=dsaz.IMDS_TIMEOUT_IN_SECONDS)
|
||||
|
||||
@mock.patch('cloudinit.url_helper.time.sleep')
|
||||
@mock.patch(MOCKPATH + 'net.is_up')
|
||||
@@ -1789,7 +1790,8 @@ class TestAzureDataSourcePreprovisioning(CiTestCase):
|
||||
headers={'Metadata': 'true',
|
||||
'User-Agent':
|
||||
'Cloud-Init/%s' % vs()
|
||||
- }, method='GET', timeout=1,
|
||||
+ }, method='GET',
|
||||
+ timeout=dsaz.IMDS_TIMEOUT_IN_SECONDS,
|
||||
url=full_url)])
|
||||
self.assertEqual(m_dhcp.call_count, 2)
|
||||
m_net.assert_any_call(
|
||||
@@ -1826,7 +1828,9 @@ class TestAzureDataSourcePreprovisioning(CiTestCase):
|
||||
headers={'Metadata': 'true',
|
||||
'User-Agent':
|
||||
'Cloud-Init/%s' % vs()},
|
||||
- method='GET', timeout=1, url=full_url)])
|
||||
+ method='GET',
|
||||
+ timeout=dsaz.IMDS_TIMEOUT_IN_SECONDS,
|
||||
+ url=full_url)])
|
||||
self.assertEqual(m_dhcp.call_count, 2)
|
||||
m_net.assert_any_call(
|
||||
broadcast='192.168.2.255', interface='eth9', ip='192.168.2.9',
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -1,642 +0,0 @@
|
|||
From 4e4e73df5ce7a819f48bed0ae6d2f0b1fb7e243b Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 29 May 2019 13:41:46 +0200
|
||||
Subject: [PATCH 2/5] DatasourceAzure: add additional logging for azure
|
||||
datasource
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190529134149.842-3-otubo@redhat.com>
|
||||
Patchwork-id: 88268
|
||||
O-Subject: [RHEL-8.0.1/RHEL-8.1.0 cloud-init PATCHv2 2/5] DatasourceAzure: add additional logging for azure datasource
|
||||
Bugzilla: 1691986
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
|
||||
From: Anh Vo <anhvo@microsoft.com>
|
||||
commit 0d8c88393b51db6454491a379dcc2e691551217a
|
||||
Author: Anh Vo <anhvo@microsoft.com>
|
||||
Date: Wed Apr 3 18:23:18 2019 +0000
|
||||
|
||||
DatasourceAzure: add additional logging for azure datasource
|
||||
|
||||
Create an Azure logging decorator and use additional ReportEventStack
|
||||
context managers to provide additional logging details.
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
cloudinit/sources/DataSourceAzure.py | 231 ++++++++++++++++++++++-------------
|
||||
cloudinit/sources/helpers/azure.py | 31 +++++
|
||||
2 files changed, 179 insertions(+), 83 deletions(-)
|
||||
mode change 100644 => 100755 cloudinit/sources/DataSourceAzure.py
|
||||
mode change 100644 => 100755 cloudinit/sources/helpers/azure.py
|
||||
|
||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
index a768b2c..c827816
|
||||
--- a/cloudinit/sources/DataSourceAzure.py
|
||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
||||
@@ -21,10 +21,14 @@ from cloudinit import net
|
||||
from cloudinit.event import EventType
|
||||
from cloudinit.net.dhcp import EphemeralDHCPv4
|
||||
from cloudinit import sources
|
||||
-from cloudinit.sources.helpers.azure import get_metadata_from_fabric
|
||||
from cloudinit.sources.helpers import netlink
|
||||
from cloudinit.url_helper import UrlError, readurl, retry_on_url_exc
|
||||
from cloudinit import util
|
||||
+from cloudinit.reporting import events
|
||||
+
|
||||
+from cloudinit.sources.helpers.azure import (azure_ds_reporter,
|
||||
+ azure_ds_telemetry_reporter,
|
||||
+ get_metadata_from_fabric)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@@ -244,6 +248,7 @@ def set_hostname(hostname, hostname_command='hostname'):
|
||||
util.subp(['hostnamectl', 'set-hostname', str(hostname)])
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
@contextlib.contextmanager
|
||||
def temporary_hostname(temp_hostname, cfg, hostname_command='hostname'):
|
||||
"""
|
||||
@@ -290,6 +295,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
root = sources.DataSource.__str__(self)
|
||||
return "%s [seed=%s]" % (root, self.seed)
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def bounce_network_with_azure_hostname(self):
|
||||
# When using cloud-init to provision, we have to set the hostname from
|
||||
# the metadata and "bounce" the network to force DDNS to update via
|
||||
@@ -315,6 +321,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
util.logexc(LOG, "handling set_hostname failed")
|
||||
return False
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def get_metadata_from_agent(self):
|
||||
temp_hostname = self.metadata.get('local-hostname')
|
||||
agent_cmd = self.ds_cfg['agent_command']
|
||||
@@ -344,15 +351,18 @@ class DataSourceAzure(sources.DataSource):
|
||||
LOG.debug("ssh authentication: "
|
||||
"using fingerprint from fabirc")
|
||||
|
||||
- # wait very long for public SSH keys to arrive
|
||||
- # https://bugs.launchpad.net/cloud-init/+bug/1717611
|
||||
- missing = util.log_time(logfunc=LOG.debug,
|
||||
- msg="waiting for SSH public key files",
|
||||
- func=util.wait_for_files,
|
||||
- args=(fp_files, 900))
|
||||
-
|
||||
- if len(missing):
|
||||
- LOG.warning("Did not find files, but going on: %s", missing)
|
||||
+ with events.ReportEventStack(
|
||||
+ name="waiting-for-ssh-public-key",
|
||||
+ description="wait for agents to retrieve ssh keys",
|
||||
+ parent=azure_ds_reporter):
|
||||
+ # wait very long for public SSH keys to arrive
|
||||
+ # https://bugs.launchpad.net/cloud-init/+bug/1717611
|
||||
+ missing = util.log_time(logfunc=LOG.debug,
|
||||
+ msg="waiting for SSH public key files",
|
||||
+ func=util.wait_for_files,
|
||||
+ args=(fp_files, 900))
|
||||
+ if len(missing):
|
||||
+ LOG.warning("Did not find files, but going on: %s", missing)
|
||||
|
||||
metadata = {}
|
||||
metadata['public-keys'] = key_value or pubkeys_from_crt_files(fp_files)
|
||||
@@ -366,6 +376,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
subplatform_type = 'seed-dir'
|
||||
return '%s (%s)' % (subplatform_type, self.seed)
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def crawl_metadata(self):
|
||||
"""Walk all instance metadata sources returning a dict on success.
|
||||
|
||||
@@ -467,6 +478,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
super(DataSourceAzure, self).clear_cached_attrs(attr_defaults)
|
||||
self._metadata_imds = sources.UNSET
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _get_data(self):
|
||||
"""Crawl and process datasource metadata caching metadata as attrs.
|
||||
|
||||
@@ -513,6 +525,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
# quickly (local check only) if self.instance_id is still valid
|
||||
return sources.instance_id_matches_system_uuid(self.get_instance_id())
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def setup(self, is_new_instance):
|
||||
if self._negotiated is False:
|
||||
LOG.debug("negotiating for %s (new_instance=%s)",
|
||||
@@ -580,6 +593,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
if nl_sock:
|
||||
nl_sock.close()
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _report_ready(self, lease):
|
||||
"""Tells the fabric provisioning has completed """
|
||||
try:
|
||||
@@ -617,9 +631,14 @@ class DataSourceAzure(sources.DataSource):
|
||||
def _reprovision(self):
|
||||
"""Initiate the reprovisioning workflow."""
|
||||
contents = self._poll_imds()
|
||||
- md, ud, cfg = read_azure_ovf(contents)
|
||||
- return (md, ud, cfg, {'ovf-env.xml': contents})
|
||||
-
|
||||
+ with events.ReportEventStack(
|
||||
+ name="reprovisioning-read-azure-ovf",
|
||||
+ description="read azure ovf during reprovisioning",
|
||||
+ parent=azure_ds_reporter):
|
||||
+ md, ud, cfg = read_azure_ovf(contents)
|
||||
+ return (md, ud, cfg, {'ovf-env.xml': contents})
|
||||
+
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _negotiate(self):
|
||||
"""Negotiate with fabric and return data from it.
|
||||
|
||||
@@ -652,6 +671,7 @@ class DataSourceAzure(sources.DataSource):
|
||||
util.del_file(REPROVISION_MARKER_FILE)
|
||||
return fabric_data
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def activate(self, cfg, is_new_instance):
|
||||
address_ephemeral_resize(is_new_instance=is_new_instance,
|
||||
preserve_ntfs=self.ds_cfg.get(
|
||||
@@ -690,12 +710,14 @@ def _partitions_on_device(devpath, maxnum=16):
|
||||
return []
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def _has_ntfs_filesystem(devpath):
|
||||
ntfs_devices = util.find_devs_with("TYPE=ntfs", no_cache=True)
|
||||
LOG.debug('ntfs_devices found = %s', ntfs_devices)
|
||||
return os.path.realpath(devpath) in ntfs_devices
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def can_dev_be_reformatted(devpath, preserve_ntfs):
|
||||
"""Determine if the ephemeral drive at devpath should be reformatted.
|
||||
|
||||
@@ -744,43 +766,59 @@ def can_dev_be_reformatted(devpath, preserve_ntfs):
|
||||
(cand_part, cand_path, devpath))
|
||||
return False, msg
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def count_files(mp):
|
||||
ignored = set(['dataloss_warning_readme.txt'])
|
||||
return len([f for f in os.listdir(mp) if f.lower() not in ignored])
|
||||
|
||||
bmsg = ('partition %s (%s) on device %s was ntfs formatted' %
|
||||
(cand_part, cand_path, devpath))
|
||||
- try:
|
||||
- file_count = util.mount_cb(cand_path, count_files, mtype="ntfs",
|
||||
- update_env_for_mount={'LANG': 'C'})
|
||||
- except util.MountFailedError as e:
|
||||
- if "unknown filesystem type 'ntfs'" in str(e):
|
||||
- return True, (bmsg + ' but this system cannot mount NTFS,'
|
||||
- ' assuming there are no important files.'
|
||||
- ' Formatting allowed.')
|
||||
- return False, bmsg + ' but mount of %s failed: %s' % (cand_part, e)
|
||||
-
|
||||
- if file_count != 0:
|
||||
- LOG.warning("it looks like you're using NTFS on the ephemeral disk, "
|
||||
- 'to ensure that filesystem does not get wiped, set '
|
||||
- '%s.%s in config', '.'.join(DS_CFG_PATH),
|
||||
- DS_CFG_KEY_PRESERVE_NTFS)
|
||||
- return False, bmsg + ' but had %d files on it.' % file_count
|
||||
+
|
||||
+ with events.ReportEventStack(
|
||||
+ name="mount-ntfs-and-count",
|
||||
+ description="mount-ntfs-and-count",
|
||||
+ parent=azure_ds_reporter) as evt:
|
||||
+ try:
|
||||
+ file_count = util.mount_cb(cand_path, count_files, mtype="ntfs",
|
||||
+ update_env_for_mount={'LANG': 'C'})
|
||||
+ except util.MountFailedError as e:
|
||||
+ evt.description = "cannot mount ntfs"
|
||||
+ if "unknown filesystem type 'ntfs'" in str(e):
|
||||
+ return True, (bmsg + ' but this system cannot mount NTFS,'
|
||||
+ ' assuming there are no important files.'
|
||||
+ ' Formatting allowed.')
|
||||
+ return False, bmsg + ' but mount of %s failed: %s' % (cand_part, e)
|
||||
+
|
||||
+ if file_count != 0:
|
||||
+ evt.description = "mounted and counted %d files" % file_count
|
||||
+ LOG.warning("it looks like you're using NTFS on the ephemeral"
|
||||
+ " disk, to ensure that filesystem does not get wiped,"
|
||||
+ " set %s.%s in config", '.'.join(DS_CFG_PATH),
|
||||
+ DS_CFG_KEY_PRESERVE_NTFS)
|
||||
+ return False, bmsg + ' but had %d files on it.' % file_count
|
||||
|
||||
return True, bmsg + ' and had no important files. Safe for reformatting.'
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def address_ephemeral_resize(devpath=RESOURCE_DISK_PATH, maxwait=120,
|
||||
is_new_instance=False, preserve_ntfs=False):
|
||||
# wait for ephemeral disk to come up
|
||||
naplen = .2
|
||||
- missing = util.wait_for_files([devpath], maxwait=maxwait, naplen=naplen,
|
||||
- log_pre="Azure ephemeral disk: ")
|
||||
-
|
||||
- if missing:
|
||||
- LOG.warning("ephemeral device '%s' did not appear after %d seconds.",
|
||||
- devpath, maxwait)
|
||||
- return
|
||||
+ with events.ReportEventStack(
|
||||
+ name="wait-for-ephemeral-disk",
|
||||
+ description="wait for ephemeral disk",
|
||||
+ parent=azure_ds_reporter):
|
||||
+ missing = util.wait_for_files([devpath],
|
||||
+ maxwait=maxwait,
|
||||
+ naplen=naplen,
|
||||
+ log_pre="Azure ephemeral disk: ")
|
||||
+
|
||||
+ if missing:
|
||||
+ LOG.warning("ephemeral device '%s' did"
|
||||
+ " not appear after %d seconds.",
|
||||
+ devpath, maxwait)
|
||||
+ return
|
||||
|
||||
result = False
|
||||
msg = None
|
||||
@@ -808,6 +846,7 @@ def address_ephemeral_resize(devpath=RESOURCE_DISK_PATH, maxwait=120,
|
||||
return
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def perform_hostname_bounce(hostname, cfg, prev_hostname):
|
||||
# set the hostname to 'hostname' if it is not already set to that.
|
||||
# then, if policy is not off, bounce the interface using command
|
||||
@@ -843,6 +882,7 @@ def perform_hostname_bounce(hostname, cfg, prev_hostname):
|
||||
return True
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def crtfile_to_pubkey(fname, data=None):
|
||||
pipeline = ('openssl x509 -noout -pubkey < "$0" |'
|
||||
'ssh-keygen -i -m PKCS8 -f /dev/stdin')
|
||||
@@ -851,6 +891,7 @@ def crtfile_to_pubkey(fname, data=None):
|
||||
return out.rstrip()
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def pubkeys_from_crt_files(flist):
|
||||
pubkeys = []
|
||||
errors = []
|
||||
@@ -866,6 +907,7 @@ def pubkeys_from_crt_files(flist):
|
||||
return pubkeys
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def write_files(datadir, files, dirmode=None):
|
||||
|
||||
def _redact_password(cnt, fname):
|
||||
@@ -893,6 +935,7 @@ def write_files(datadir, files, dirmode=None):
|
||||
util.write_file(filename=fname, content=content, mode=0o600)
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def invoke_agent(cmd):
|
||||
# this is a function itself to simplify patching it for test
|
||||
if cmd:
|
||||
@@ -912,6 +955,7 @@ def find_child(node, filter_func):
|
||||
return ret
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def load_azure_ovf_pubkeys(sshnode):
|
||||
# This parses a 'SSH' node formatted like below, and returns
|
||||
# an array of dicts.
|
||||
@@ -964,6 +1008,7 @@ def load_azure_ovf_pubkeys(sshnode):
|
||||
return found
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def read_azure_ovf(contents):
|
||||
try:
|
||||
dom = minidom.parseString(contents)
|
||||
@@ -1064,6 +1109,7 @@ def read_azure_ovf(contents):
|
||||
return (md, ud, cfg)
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def _extract_preprovisioned_vm_setting(dom):
|
||||
"""Read the preprovision flag from the ovf. It should not
|
||||
exist unless true."""
|
||||
@@ -1092,6 +1138,7 @@ def encrypt_pass(password, salt_id="$6$"):
|
||||
return crypt.crypt(password, salt_id + util.rand_str(strlen=16))
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def _check_freebsd_cdrom(cdrom_dev):
|
||||
"""Return boolean indicating path to cdrom device has content."""
|
||||
try:
|
||||
@@ -1103,6 +1150,7 @@ def _check_freebsd_cdrom(cdrom_dev):
|
||||
return False
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def _get_random_seed(source=PLATFORM_ENTROPY_SOURCE):
|
||||
"""Return content random seed file if available, otherwise,
|
||||
return None."""
|
||||
@@ -1126,6 +1174,7 @@ def _get_random_seed(source=PLATFORM_ENTROPY_SOURCE):
|
||||
return seed
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def list_possible_azure_ds_devs():
|
||||
devlist = []
|
||||
if util.is_FreeBSD():
|
||||
@@ -1140,6 +1189,7 @@ def list_possible_azure_ds_devs():
|
||||
return devlist
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def load_azure_ds_dir(source_dir):
|
||||
ovf_file = os.path.join(source_dir, "ovf-env.xml")
|
||||
|
||||
@@ -1162,47 +1212,54 @@ def parse_network_config(imds_metadata):
|
||||
@param: imds_metadata: Dict of content read from IMDS network service.
|
||||
@return: Dictionary containing network version 2 standard configuration.
|
||||
"""
|
||||
- if imds_metadata != sources.UNSET and imds_metadata:
|
||||
- netconfig = {'version': 2, 'ethernets': {}}
|
||||
- LOG.debug('Azure: generating network configuration from IMDS')
|
||||
- network_metadata = imds_metadata['network']
|
||||
- for idx, intf in enumerate(network_metadata['interface']):
|
||||
- nicname = 'eth{idx}'.format(idx=idx)
|
||||
- dev_config = {}
|
||||
- for addr4 in intf['ipv4']['ipAddress']:
|
||||
- privateIpv4 = addr4['privateIpAddress']
|
||||
- if privateIpv4:
|
||||
- if dev_config.get('dhcp4', False):
|
||||
- # Append static address config for nic > 1
|
||||
- netPrefix = intf['ipv4']['subnet'][0].get(
|
||||
- 'prefix', '24')
|
||||
- if not dev_config.get('addresses'):
|
||||
- dev_config['addresses'] = []
|
||||
- dev_config['addresses'].append(
|
||||
- '{ip}/{prefix}'.format(
|
||||
- ip=privateIpv4, prefix=netPrefix))
|
||||
- else:
|
||||
- dev_config['dhcp4'] = True
|
||||
- for addr6 in intf['ipv6']['ipAddress']:
|
||||
- privateIpv6 = addr6['privateIpAddress']
|
||||
- if privateIpv6:
|
||||
- dev_config['dhcp6'] = True
|
||||
- break
|
||||
- if dev_config:
|
||||
- mac = ':'.join(re.findall(r'..', intf['macAddress']))
|
||||
- dev_config.update(
|
||||
- {'match': {'macaddress': mac.lower()},
|
||||
- 'set-name': nicname})
|
||||
- netconfig['ethernets'][nicname] = dev_config
|
||||
- else:
|
||||
- blacklist = ['mlx4_core']
|
||||
- LOG.debug('Azure: generating fallback configuration')
|
||||
- # generate a network config, blacklist picking mlx4_core devs
|
||||
- netconfig = net.generate_fallback_config(
|
||||
- blacklist_drivers=blacklist, config_driver=True)
|
||||
- return netconfig
|
||||
+ with events.ReportEventStack(
|
||||
+ name="parse_network_config",
|
||||
+ description="",
|
||||
+ parent=azure_ds_reporter) as evt:
|
||||
+ if imds_metadata != sources.UNSET and imds_metadata:
|
||||
+ netconfig = {'version': 2, 'ethernets': {}}
|
||||
+ LOG.debug('Azure: generating network configuration from IMDS')
|
||||
+ network_metadata = imds_metadata['network']
|
||||
+ for idx, intf in enumerate(network_metadata['interface']):
|
||||
+ nicname = 'eth{idx}'.format(idx=idx)
|
||||
+ dev_config = {}
|
||||
+ for addr4 in intf['ipv4']['ipAddress']:
|
||||
+ privateIpv4 = addr4['privateIpAddress']
|
||||
+ if privateIpv4:
|
||||
+ if dev_config.get('dhcp4', False):
|
||||
+ # Append static address config for nic > 1
|
||||
+ netPrefix = intf['ipv4']['subnet'][0].get(
|
||||
+ 'prefix', '24')
|
||||
+ if not dev_config.get('addresses'):
|
||||
+ dev_config['addresses'] = []
|
||||
+ dev_config['addresses'].append(
|
||||
+ '{ip}/{prefix}'.format(
|
||||
+ ip=privateIpv4, prefix=netPrefix))
|
||||
+ else:
|
||||
+ dev_config['dhcp4'] = True
|
||||
+ for addr6 in intf['ipv6']['ipAddress']:
|
||||
+ privateIpv6 = addr6['privateIpAddress']
|
||||
+ if privateIpv6:
|
||||
+ dev_config['dhcp6'] = True
|
||||
+ break
|
||||
+ if dev_config:
|
||||
+ mac = ':'.join(re.findall(r'..', intf['macAddress']))
|
||||
+ dev_config.update(
|
||||
+ {'match': {'macaddress': mac.lower()},
|
||||
+ 'set-name': nicname})
|
||||
+ netconfig['ethernets'][nicname] = dev_config
|
||||
+ evt.description = "network config from imds"
|
||||
+ else:
|
||||
+ blacklist = ['mlx4_core']
|
||||
+ LOG.debug('Azure: generating fallback configuration')
|
||||
+ # generate a network config, blacklist picking mlx4_core devs
|
||||
+ netconfig = net.generate_fallback_config(
|
||||
+ blacklist_drivers=blacklist, config_driver=True)
|
||||
+ evt.description = "network config from fallback"
|
||||
+ return netconfig
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def get_metadata_from_imds(fallback_nic, retries):
|
||||
"""Query Azure's network metadata service, returning a dictionary.
|
||||
|
||||
@@ -1227,6 +1284,7 @@ def get_metadata_from_imds(fallback_nic, retries):
|
||||
return util.log_time(**kwargs)
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def _get_metadata_from_imds(retries):
|
||||
|
||||
url = IMDS_URL + "instance?api-version=2017-12-01"
|
||||
@@ -1246,6 +1304,7 @@ def _get_metadata_from_imds(retries):
|
||||
return {}
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def maybe_remove_ubuntu_network_config_scripts(paths=None):
|
||||
"""Remove Azure-specific ubuntu network config for non-primary nics.
|
||||
|
||||
@@ -1283,14 +1342,20 @@ def maybe_remove_ubuntu_network_config_scripts(paths=None):
|
||||
|
||||
|
||||
def _is_platform_viable(seed_dir):
|
||||
- """Check platform environment to report if this datasource may run."""
|
||||
- asset_tag = util.read_dmi_data('chassis-asset-tag')
|
||||
- if asset_tag == AZURE_CHASSIS_ASSET_TAG:
|
||||
- return True
|
||||
- LOG.debug("Non-Azure DMI asset tag '%s' discovered.", asset_tag)
|
||||
- if os.path.exists(os.path.join(seed_dir, 'ovf-env.xml')):
|
||||
- return True
|
||||
- return False
|
||||
+ with events.ReportEventStack(
|
||||
+ name="check-platform-viability",
|
||||
+ description="found azure asset tag",
|
||||
+ parent=azure_ds_reporter) as evt:
|
||||
+
|
||||
+ """Check platform environment to report if this datasource may run."""
|
||||
+ asset_tag = util.read_dmi_data('chassis-asset-tag')
|
||||
+ if asset_tag == AZURE_CHASSIS_ASSET_TAG:
|
||||
+ return True
|
||||
+ LOG.debug("Non-Azure DMI asset tag '%s' discovered.", asset_tag)
|
||||
+ evt.description = "Non-Azure DMI asset tag '%s' discovered.", asset_tag
|
||||
+ if os.path.exists(os.path.join(seed_dir, 'ovf-env.xml')):
|
||||
+ return True
|
||||
+ return False
|
||||
|
||||
|
||||
class BrokenAzureDataSource(Exception):
|
||||
diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
index 2829dd2..d3af05e
|
||||
--- a/cloudinit/sources/helpers/azure.py
|
||||
+++ b/cloudinit/sources/helpers/azure.py
|
||||
@@ -16,10 +16,27 @@ from xml.etree import ElementTree
|
||||
|
||||
from cloudinit import url_helper
|
||||
from cloudinit import util
|
||||
+from cloudinit.reporting import events
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
+azure_ds_reporter = events.ReportEventStack(
|
||||
+ name="azure-ds",
|
||||
+ description="initialize reporter for azure ds",
|
||||
+ reporting_enabled=True)
|
||||
+
|
||||
+
|
||||
+def azure_ds_telemetry_reporter(func):
|
||||
+ def impl(*args, **kwargs):
|
||||
+ with events.ReportEventStack(
|
||||
+ name=func.__name__,
|
||||
+ description=func.__name__,
|
||||
+ parent=azure_ds_reporter):
|
||||
+ return func(*args, **kwargs)
|
||||
+ return impl
|
||||
+
|
||||
+
|
||||
@contextmanager
|
||||
def cd(newdir):
|
||||
prevdir = os.getcwd()
|
||||
@@ -119,6 +136,7 @@ class OpenSSLManager(object):
|
||||
def clean_up(self):
|
||||
util.del_dir(self.tmpdir)
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def generate_certificate(self):
|
||||
LOG.debug('Generating certificate for communication with fabric...')
|
||||
if self.certificate is not None:
|
||||
@@ -139,17 +157,20 @@ class OpenSSLManager(object):
|
||||
LOG.debug('New certificate generated.')
|
||||
|
||||
@staticmethod
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _run_x509_action(action, cert):
|
||||
cmd = ['openssl', 'x509', '-noout', action]
|
||||
result, _ = util.subp(cmd, data=cert)
|
||||
return result
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _get_ssh_key_from_cert(self, certificate):
|
||||
pub_key = self._run_x509_action('-pubkey', certificate)
|
||||
keygen_cmd = ['ssh-keygen', '-i', '-m', 'PKCS8', '-f', '/dev/stdin']
|
||||
ssh_key, _ = util.subp(keygen_cmd, data=pub_key)
|
||||
return ssh_key
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _get_fingerprint_from_cert(self, certificate):
|
||||
"""openssl x509 formats fingerprints as so:
|
||||
'SHA1 Fingerprint=07:3E:19:D1:4D:1C:79:92:24:C6:A0:FD:8D:DA:\
|
||||
@@ -163,6 +184,7 @@ class OpenSSLManager(object):
|
||||
octets = raw_fp[eq+1:-1].split(':')
|
||||
return ''.join(octets)
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _decrypt_certs_from_xml(self, certificates_xml):
|
||||
"""Decrypt the certificates XML document using the our private key;
|
||||
return the list of certs and private keys contained in the doc.
|
||||
@@ -185,6 +207,7 @@ class OpenSSLManager(object):
|
||||
shell=True, data=b'\n'.join(lines))
|
||||
return out
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def parse_certificates(self, certificates_xml):
|
||||
"""Given the Certificates XML document, return a dictionary of
|
||||
fingerprints and associated SSH keys derived from the certs."""
|
||||
@@ -265,11 +288,13 @@ class WALinuxAgentShim(object):
|
||||
return socket.inet_ntoa(packed_bytes)
|
||||
|
||||
@staticmethod
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _networkd_get_value_from_leases(leases_d=None):
|
||||
return dhcp.networkd_get_option_from_leases(
|
||||
'OPTION_245', leases_d=leases_d)
|
||||
|
||||
@staticmethod
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _get_value_from_leases_file(fallback_lease_file):
|
||||
leases = []
|
||||
content = util.load_file(fallback_lease_file)
|
||||
@@ -287,6 +312,7 @@ class WALinuxAgentShim(object):
|
||||
return leases[-1]
|
||||
|
||||
@staticmethod
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _load_dhclient_json():
|
||||
dhcp_options = {}
|
||||
hooks_dir = WALinuxAgentShim._get_hooks_dir()
|
||||
@@ -305,6 +331,7 @@ class WALinuxAgentShim(object):
|
||||
return dhcp_options
|
||||
|
||||
@staticmethod
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _get_value_from_dhcpoptions(dhcp_options):
|
||||
if dhcp_options is None:
|
||||
return None
|
||||
@@ -318,6 +345,7 @@ class WALinuxAgentShim(object):
|
||||
return _value
|
||||
|
||||
@staticmethod
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def find_endpoint(fallback_lease_file=None, dhcp245=None):
|
||||
value = None
|
||||
if dhcp245 is not None:
|
||||
@@ -352,6 +380,7 @@ class WALinuxAgentShim(object):
|
||||
LOG.debug('Azure endpoint found at %s', endpoint_ip_address)
|
||||
return endpoint_ip_address
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def register_with_azure_and_fetch_data(self, pubkey_info=None):
|
||||
if self.openssl_manager is None:
|
||||
self.openssl_manager = OpenSSLManager()
|
||||
@@ -404,6 +433,7 @@ class WALinuxAgentShim(object):
|
||||
|
||||
return keys
|
||||
|
||||
+ @azure_ds_telemetry_reporter
|
||||
def _report_ready(self, goal_state, http_client):
|
||||
LOG.debug('Reporting ready to Azure fabric.')
|
||||
document = self.REPORT_READY_XML_TEMPLATE.format(
|
||||
@@ -419,6 +449,7 @@ class WALinuxAgentShim(object):
|
||||
LOG.info('Reported ready to Azure fabric.')
|
||||
|
||||
|
||||
+@azure_ds_telemetry_reporter
|
||||
def get_metadata_from_fabric(fallback_lease_file=None, dhcp_opts=None,
|
||||
pubkey_info=None):
|
||||
shim = WALinuxAgentShim(fallback_lease_file=fallback_lease_file,
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
From 9da40a7e46e40eb090538f9d8a5aa6049fbbc5b8 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Tue, 12 Mar 2024 12:52:10 +0530
|
||||
Subject: [PATCH] Retain exit code in cloud-init status for recoverable errors
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 126: Retain exit code in cloud-init status for recoverable errors
|
||||
RH-Jira: RHEL-28817
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Commit: [1/1] 8c45ffe77ed8e964c35af4705d65daaf8282038f
|
||||
|
||||
Version 23.4 of cloud-init changed the status code reported by cloud-init for
|
||||
recoverable errors from 0 to 2. Please see the commit
|
||||
70acb7f2a30d58 ("Add support for cloud-init "degraded" state (#4500)")
|
||||
|
||||
This change has the potential to break customers who are expecting a 0 status
|
||||
and where warnings can be expected. Hence, revert the status code from 2 to 0
|
||||
even in case of recoverable errors. This retains the old behavior and hence
|
||||
avoids breaking scripts and software stack that expects 0 on the end user side.
|
||||
|
||||
Cannonical has made a similar change downstream for similar reasons. Please see
|
||||
https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/2048522
|
||||
and the corresponding downstream patch:
|
||||
https://github.com/canonical/cloud-init/pull/4747/commits/adce34bfd214e4eecdf87329486f30f0898dd303
|
||||
|
||||
This patch has limited risk as it narrowly only restores the old status
|
||||
code for recoverable errors and does not modify anything else.
|
||||
|
||||
X-downstream-only: true
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
---
|
||||
cloudinit/cmd/status.py | 2 +-
|
||||
tests/unittests/cmd/test_status.py | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
|
||||
index f5ee9c11..849c80bc 100644
|
||||
--- a/cloudinit/cmd/status.py
|
||||
+++ b/cloudinit/cmd/status.py
|
||||
@@ -225,7 +225,7 @@ def handle_status_args(name, args) -> int:
|
||||
return 1
|
||||
# Recoverable error
|
||||
elif details.status in UXAppStatusDegradedMap.values():
|
||||
- return 2
|
||||
+ return 0
|
||||
return 0
|
||||
|
||||
|
||||
diff --git a/tests/unittests/cmd/test_status.py b/tests/unittests/cmd/test_status.py
|
||||
index 6c85a59a..567b517a 100644
|
||||
--- a/tests/unittests/cmd/test_status.py
|
||||
+++ b/tests/unittests/cmd/test_status.py
|
||||
@@ -636,7 +636,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
|
||||
},
|
||||
None,
|
||||
MyArgs(long=False, wait=False, format="json"),
|
||||
- 2,
|
||||
+ 0,
|
||||
{
|
||||
"boot_status_code": "enabled-by-kernel-cmdline",
|
||||
"datasource": "nocloud",
|
||||
--
|
||||
2.39.3
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
From ce17b057e4bd5dfaa2cc72991736a1b82704488c Mon Sep 17 00:00:00 2001
|
||||
From: Brett Holman <brett.holman@canonical.com>
|
||||
Date: Tue, 23 Jan 2024 11:47:35 -0700
|
||||
Subject: [PATCH] Revert "Use grep for faster parsing of cloud config in
|
||||
ds-identify (#4327)"
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 122: Revert "Use grep for faster parsing of cloud config in ds-identify (#4327)"
|
||||
RH-Jira: RHEL-22248
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-Commit: [1/1] f14ebd0055aad9340249e83381cf976debdbe38d
|
||||
|
||||
This reverts commit 816e05d4830f5e789f1f85ef926e2849156bff3a.
|
||||
|
||||
Reopens LP: 2030729
|
||||
Fixes GH-4794
|
||||
|
||||
(cherry picked from commit 8ff94fe9493ad88344eb8bbf2f023c6ba2db5206)
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
---
|
||||
tests/unittests/test_ds_identify.py | 146 +---------------------------
|
||||
tools/ds-identify | 31 +++---
|
||||
2 files changed, 15 insertions(+), 162 deletions(-)
|
||||
|
||||
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
|
||||
index ca206fb5..ba0bf779 100644
|
||||
--- a/tests/unittests/test_ds_identify.py
|
||||
+++ b/tests/unittests/test_ds_identify.py
|
||||
@@ -57,146 +57,6 @@ BLKID_UEFI_UBUNTU = [
|
||||
]
|
||||
|
||||
|
||||
-DEFAULT_CLOUD_CONFIG = """\
|
||||
-# The top level settings are used as module
|
||||
-# and base configuration.
|
||||
-# A set of users which may be applied and/or used by various modules
|
||||
-# when a 'default' entry is found it will reference the 'default_user'
|
||||
-# from the distro configuration specified below
|
||||
-users:
|
||||
- - default
|
||||
-
|
||||
-# If this is set, 'root' will not be able to ssh in and they
|
||||
-# will get a message to login instead as the default $user
|
||||
-disable_root: true
|
||||
-
|
||||
-# This will cause the set+update hostname module to not operate (if true)
|
||||
-preserve_hostname: false
|
||||
-
|
||||
-# If you use datasource_list array, keep array items in a single line.
|
||||
-# If you use multi line array, ds-identify script won't read array items.
|
||||
-# Example datasource config
|
||||
-# datasource:
|
||||
-# Ec2:
|
||||
-# metadata_urls: [ 'blah.com' ]
|
||||
-# timeout: 5 # (defaults to 50 seconds)
|
||||
-# max_wait: 10 # (defaults to 120 seconds)
|
||||
-
|
||||
-# The modules that run in the 'init' stage
|
||||
-cloud_init_modules:
|
||||
- - migrator
|
||||
- - seed_random
|
||||
- - bootcmd
|
||||
- - write-files
|
||||
- - growpart
|
||||
- - resizefs
|
||||
- - disk_setup
|
||||
- - mounts
|
||||
- - set_hostname
|
||||
- - update_hostname
|
||||
- - update_etc_hosts
|
||||
- - ca-certs
|
||||
- - rsyslog
|
||||
- - users-groups
|
||||
- - ssh
|
||||
-
|
||||
-# The modules that run in the 'config' stage
|
||||
-cloud_config_modules:
|
||||
- - wireguard
|
||||
- - snap
|
||||
- - ubuntu_autoinstall
|
||||
- - ssh-import-id
|
||||
- - keyboard
|
||||
- - locale
|
||||
- - set-passwords
|
||||
- - grub-dpkg
|
||||
- - apt-pipelining
|
||||
- - apt-configure
|
||||
- - ubuntu-advantage
|
||||
- - ntp
|
||||
- - timezone
|
||||
- - disable-ec2-metadata
|
||||
- - runcmd
|
||||
- - byobu
|
||||
-
|
||||
-# The modules that run in the 'final' stage
|
||||
-cloud_final_modules:
|
||||
- - package-update-upgrade-install
|
||||
- - fan
|
||||
- - landscape
|
||||
- - lxd
|
||||
- - ubuntu-drivers
|
||||
- - write-files-deferred
|
||||
- - puppet
|
||||
- - chef
|
||||
- - ansible
|
||||
- - mcollective
|
||||
- - salt-minion
|
||||
- - reset_rmc
|
||||
- - refresh_rmc_and_interface
|
||||
- - rightscale_userdata
|
||||
- - scripts-vendor
|
||||
- - scripts-per-once
|
||||
- - scripts-per-boot
|
||||
- - scripts-per-instance
|
||||
- - scripts-user
|
||||
- - ssh-authkey-fingerprints
|
||||
- - keys-to-console
|
||||
- - install-hotplug
|
||||
- - phone-home
|
||||
- - final-message
|
||||
- - power-state-change
|
||||
-
|
||||
-# System and/or distro specific settings
|
||||
-# (not accessible to handlers/transforms)
|
||||
-system_info:
|
||||
- # This will affect which distro class gets used
|
||||
- distro: ubuntu
|
||||
- # Default user name + that default users groups (if added/used)
|
||||
- default_user:
|
||||
- name: ubuntu
|
||||
- lock_passwd: True
|
||||
- gecos: Ubuntu
|
||||
- groups: [adm, audio, cdrom, floppy, lxd, netdev, plugdev, sudo, video]
|
||||
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
||||
- shell: /bin/bash
|
||||
- network:
|
||||
- renderers: ['netplan', 'eni', 'sysconfig']
|
||||
- activators: ['netplan', 'eni', 'network-manager', 'networkd']
|
||||
- # Automatically discover the best ntp_client
|
||||
- ntp_client: auto
|
||||
- # Other config here will be given to the distro class and/or path classes
|
||||
- paths:
|
||||
- cloud_dir: /var/lib/cloud/
|
||||
- templates_dir: /etc/cloud/templates/
|
||||
- package_mirrors:
|
||||
- - arches: [i386, amd64]
|
||||
- failsafe:
|
||||
- primary: http://archive.ubuntu.com/ubuntu
|
||||
- security: http://security.ubuntu.com/ubuntu
|
||||
- search:
|
||||
- primary:
|
||||
- - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
|
||||
- - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
|
||||
- - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
|
||||
- security: []
|
||||
- - arches: [arm64, armel, armhf]
|
||||
- failsafe:
|
||||
- primary: http://ports.ubuntu.com/ubuntu-ports
|
||||
- security: http://ports.ubuntu.com/ubuntu-ports
|
||||
- search:
|
||||
- primary:
|
||||
- - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/
|
||||
- - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/
|
||||
- - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/
|
||||
- security: []
|
||||
- - arches: [default]
|
||||
- failsafe:
|
||||
- primary: http://ports.ubuntu.com/ubuntu-ports
|
||||
- security: http://ports.ubuntu.com/ubuntu-ports
|
||||
- ssh_svcname: ssh
|
||||
-"""
|
||||
-
|
||||
POLICY_FOUND_ONLY = "search,found=all,maybe=none,notfound=disabled"
|
||||
POLICY_FOUND_OR_MAYBE = "search,found=all,maybe=all,notfound=disabled"
|
||||
DI_DEFAULT_POLICY = "search,found=all,maybe=all,notfound=disabled"
|
||||
@@ -279,10 +139,6 @@ class DsIdentifyBase(CiTestCase):
|
||||
if files is None:
|
||||
files = {}
|
||||
|
||||
- cloudcfg = "etc/cloud/cloud.cfg"
|
||||
- if cloudcfg not in files:
|
||||
- files[cloudcfg] = DEFAULT_CLOUD_CONFIG
|
||||
-
|
||||
if rootd is None:
|
||||
rootd = self.tmp_dir()
|
||||
|
||||
@@ -1305,7 +1161,7 @@ VALID_CFG = {
|
||||
# Also include a datasource list of more than just
|
||||
# [NoCloud, None], because that would automatically select
|
||||
# NoCloud without checking
|
||||
- "etc/cloud/cloud.cfg": dedent(
|
||||
+ "/etc/cloud/cloud.cfg": dedent(
|
||||
"""\
|
||||
datasource_list: [ Azure, Openstack, NoCloud, None ]
|
||||
datasource:
|
||||
diff --git a/tools/ds-identify b/tools/ds-identify
|
||||
index 7a537278..ec2cc18a 100755
|
||||
--- a/tools/ds-identify
|
||||
+++ b/tools/ds-identify
|
||||
@@ -777,24 +777,21 @@ check_config() {
|
||||
if [ "$1" = "$files" -a ! -f "$1" ]; then
|
||||
return 1
|
||||
fi
|
||||
- local line="" ret="" found=0 found_fn="" oifs="$IFS" out=""
|
||||
- out=$(grep "$key\"\?:" "$@" 2>/dev/null)
|
||||
- IFS=${CR}
|
||||
- for line in $out; do
|
||||
- # drop '# comment'
|
||||
- line=${line%%#*}
|
||||
- # if more than one file was 'grep'ed, then grep will output filename:
|
||||
- # but if only one file, line will not be prefixed.
|
||||
- if [ $# -eq 1 ]; then
|
||||
- found_fn="$1"
|
||||
- else
|
||||
- found_fn="${line%%:*}"
|
||||
- line=${line#*:}
|
||||
- fi
|
||||
- ret=${line#*: };
|
||||
- found=$((found+1))
|
||||
+ local fname="" line="" ret="" found=0 found_fn=""
|
||||
+ # shellcheck disable=2094
|
||||
+ for fname in "$@"; do
|
||||
+ [ -f "$fname" ] || continue
|
||||
+ while read line; do
|
||||
+ line=${line%%#*}
|
||||
+ case "$line" in
|
||||
+ $key:\ *|"${key}":)
|
||||
+ ret=${line#*:};
|
||||
+ ret=${ret# };
|
||||
+ found=$((found+1))
|
||||
+ found_fn="$fname";;
|
||||
+ esac
|
||||
+ done <"$fname"
|
||||
done
|
||||
- IFS="$oifs"
|
||||
if [ $found -ne 0 ]; then
|
||||
_RET="$ret"
|
||||
_RET_fname="$found_fn"
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
From 42aad98557bb62ae693f38e5f1e137bcc44f6046 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Tue, 5 Mar 2024 12:42:26 +0530
|
||||
Subject: [PATCH] Revert "systemd: Standardize cloud-init systemd enablement
|
||||
(#4399)"
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 124: Revert "systemd: Standardize cloud-init systemd enablement (#4399)"
|
||||
RH-Jira: RHEL-21290
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Commit: [1/1] 10da53e761e25ff7d254a4cfb8fb1fd18de8b4ed
|
||||
|
||||
This reverts commit ec7dde8041d4023b09324e84abe37dc766ebbaf6.
|
||||
|
||||
'ConditionEnvironment' clause is not available in RHEL 8.10 systemd and adding
|
||||
the feature would be complicated. Hence reverting the patch seems to be the
|
||||
right thing to do as it was a simple enhancement to make sure all distros use
|
||||
systemd's kernel commandline and file conditionals. We only care about RHEL so
|
||||
the change should not affect us.
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
---
|
||||
systemd/cloud-config.service.tmpl | 3 ++-
|
||||
systemd/cloud-final.service.tmpl | 3 ++-
|
||||
systemd/cloud-init-local.service.tmpl | 3 ++-
|
||||
systemd/cloud-init.service.tmpl | 3 ++-
|
||||
systemd/cloud-init.target | 3 ---
|
||||
5 files changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/systemd/cloud-config.service.tmpl b/systemd/cloud-config.service.tmpl
|
||||
index 31d9d983..76e50ae1 100644
|
||||
--- a/systemd/cloud-config.service.tmpl
|
||||
+++ b/systemd/cloud-config.service.tmpl
|
||||
@@ -5,9 +5,10 @@ After=network-online.target cloud-config.target
|
||||
After=snapd.seeded.service
|
||||
Before=systemd-user-sessions.service
|
||||
Wants=network-online.target cloud-config.target
|
||||
+{% if variant == "rhel" %}
|
||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||
ConditionKernelCommandLine=!cloud-init=disabled
|
||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
||||
+{% endif %}
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
diff --git a/systemd/cloud-final.service.tmpl b/systemd/cloud-final.service.tmpl
|
||||
index bcf8b009..85f423ac 100644
|
||||
--- a/systemd/cloud-final.service.tmpl
|
||||
+++ b/systemd/cloud-final.service.tmpl
|
||||
@@ -7,9 +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
|
||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
||||
+{% endif %}
|
||||
|
||||
|
||||
[Service]
|
||||
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
|
||||
index 3a1ca7fa..6f3f9d8d 100644
|
||||
--- a/systemd/cloud-init-local.service.tmpl
|
||||
+++ b/systemd/cloud-init-local.service.tmpl
|
||||
@@ -26,9 +26,10 @@ Before=sysinit.target
|
||||
Conflicts=shutdown.target
|
||||
{% endif %}
|
||||
RequiresMountsFor=/var/lib/cloud
|
||||
+{% if variant == "rhel" %}
|
||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||
ConditionKernelCommandLine=!cloud-init=disabled
|
||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
||||
+{% endif %}
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
|
||||
index bf91164a..26d2e39c 100644
|
||||
--- a/systemd/cloud-init.service.tmpl
|
||||
+++ b/systemd/cloud-init.service.tmpl
|
||||
@@ -38,9 +38,10 @@ Conflicts=shutdown.target
|
||||
Before=shutdown.target
|
||||
Conflicts=shutdown.target
|
||||
{% endif %}
|
||||
+{% if variant == "rhel" %}
|
||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||
ConditionKernelCommandLine=!cloud-init=disabled
|
||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
||||
+{% endif %}
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
diff --git a/systemd/cloud-init.target b/systemd/cloud-init.target
|
||||
index 30450f7f..760dfee5 100644
|
||||
--- a/systemd/cloud-init.target
|
||||
+++ b/systemd/cloud-init.target
|
||||
@@ -10,6 +10,3 @@
|
||||
[Unit]
|
||||
Description=Cloud-init target
|
||||
After=multi-user.target
|
||||
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||
-ConditionKernelCommandLine=!cloud-init=disabled
|
||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
||||
--
|
||||
2.39.3
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
From 2604984fc44dde89dac847de9f95011713d448ff Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Otubo <otubo@redhat.com>
|
||||
Date: Wed, 29 May 2019 13:41:49 +0200
|
||||
Subject: [PATCH 5/5] cc_mounts: check if mount -a on no-change fstab path
|
||||
|
||||
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||
Message-id: <20190529134149.842-6-otubo@redhat.com>
|
||||
Patchwork-id: 88269
|
||||
O-Subject: [RHEL-8.0.1/RHEL-8.1.0 cloud-init PATCHv2 5/5] cc_mounts: check if mount -a on no-change fstab path
|
||||
Bugzilla: 1691986
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
|
||||
From: "Jason Zions (MSFT)" <jasonzio@microsoft.com>
|
||||
commit acc25d8d7d603313059ac35b4253b504efc560a9
|
||||
Author: Jason Zions (MSFT) <jasonzio@microsoft.com>
|
||||
Date: Wed May 8 22:47:07 2019 +0000
|
||||
|
||||
cc_mounts: check if mount -a on no-change fstab path
|
||||
|
||||
Under some circumstances, cc_disk_setup may reformat volumes which
|
||||
already appear in /etc/fstab (e.g. Azure ephemeral drive is reformatted
|
||||
from NTFS to ext4 after service-heal). Normally, cc_mounts only calls
|
||||
mount -a if it altered /etc/fstab. With this change cc_mounts will read
|
||||
/proc/mounts and verify if configured mounts are already mounted and if
|
||||
not raise flag to request a mount -a. This handles the case where no
|
||||
changes to fstab occur but a mount -a is required due to change in
|
||||
underlying device which prevented the .mount unit from running until
|
||||
after disk was reformatted.
|
||||
|
||||
LP: #1825596
|
||||
|
||||
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
cloudinit/config/cc_mounts.py | 11 ++++++++
|
||||
.../unittests/test_handler/test_handler_mounts.py | 30 +++++++++++++++++++++-
|
||||
2 files changed, 40 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
|
||||
index 339baba..123ffb8 100644
|
||||
--- a/cloudinit/config/cc_mounts.py
|
||||
+++ b/cloudinit/config/cc_mounts.py
|
||||
@@ -439,6 +439,7 @@ def handle(_name, cfg, cloud, log, _args):
|
||||
|
||||
cc_lines = []
|
||||
needswap = False
|
||||
+ need_mount_all = False
|
||||
dirs = []
|
||||
for line in actlist:
|
||||
# write 'comment' in the fs_mntops, entry, claiming this
|
||||
@@ -449,11 +450,18 @@ def handle(_name, cfg, cloud, log, _args):
|
||||
dirs.append(line[1])
|
||||
cc_lines.append('\t'.join(line))
|
||||
|
||||
+ mount_points = [v['mountpoint'] for k, v in util.mounts().items()
|
||||
+ if 'mountpoint' in v]
|
||||
for d in dirs:
|
||||
try:
|
||||
util.ensure_dir(d)
|
||||
except Exception:
|
||||
util.logexc(log, "Failed to make '%s' config-mount", d)
|
||||
+ # dirs is list of directories on which a volume should be mounted.
|
||||
+ # If any of them does not already show up in the list of current
|
||||
+ # mount points, we will definitely need to do mount -a.
|
||||
+ if not need_mount_all and d not in mount_points:
|
||||
+ need_mount_all = True
|
||||
|
||||
sadds = [WS.sub(" ", n) for n in cc_lines]
|
||||
sdrops = [WS.sub(" ", n) for n in fstab_removed]
|
||||
@@ -473,6 +481,9 @@ def handle(_name, cfg, cloud, log, _args):
|
||||
log.debug("No changes to /etc/fstab made.")
|
||||
else:
|
||||
log.debug("Changes to fstab: %s", sops)
|
||||
+ need_mount_all = True
|
||||
+
|
||||
+ if need_mount_all:
|
||||
activate_cmds.append(["mount", "-a"])
|
||||
if uses_systemd:
|
||||
activate_cmds.append(["systemctl", "daemon-reload"])
|
||||
diff --git a/tests/unittests/test_handler/test_handler_mounts.py b/tests/unittests/test_handler/test_handler_mounts.py
|
||||
index 8fea6c2..0fb160b 100644
|
||||
--- a/tests/unittests/test_handler/test_handler_mounts.py
|
||||
+++ b/tests/unittests/test_handler/test_handler_mounts.py
|
||||
@@ -154,7 +154,15 @@ class TestFstabHandling(test_helpers.FilesystemMockingTestCase):
|
||||
return_value=True)
|
||||
|
||||
self.add_patch('cloudinit.config.cc_mounts.util.subp',
|
||||
- 'mock_util_subp')
|
||||
+ 'm_util_subp')
|
||||
+
|
||||
+ self.add_patch('cloudinit.config.cc_mounts.util.mounts',
|
||||
+ 'mock_util_mounts',
|
||||
+ return_value={
|
||||
+ '/dev/sda1': {'fstype': 'ext4',
|
||||
+ 'mountpoint': '/',
|
||||
+ 'opts': 'rw,relatime,discard'
|
||||
+ }})
|
||||
|
||||
self.mock_cloud = mock.Mock()
|
||||
self.mock_log = mock.Mock()
|
||||
@@ -230,4 +238,24 @@ class TestFstabHandling(test_helpers.FilesystemMockingTestCase):
|
||||
fstab_new_content = fd.read()
|
||||
self.assertEqual(fstab_expected_content, fstab_new_content)
|
||||
|
||||
+ def test_no_change_fstab_sets_needs_mount_all(self):
|
||||
+ '''verify unchanged fstab entries are mounted if not call mount -a'''
|
||||
+ fstab_original_content = (
|
||||
+ 'LABEL=cloudimg-rootfs / ext4 defaults 0 0\n'
|
||||
+ 'LABEL=UEFI /boot/efi vfat defaults 0 0\n'
|
||||
+ '/dev/vdb /mnt auto defaults,noexec,comment=cloudconfig 0 2\n'
|
||||
+ )
|
||||
+ fstab_expected_content = fstab_original_content
|
||||
+ cc = {'mounts': [
|
||||
+ ['/dev/vdb', '/mnt', 'auto', 'defaults,noexec']]}
|
||||
+ with open(cc_mounts.FSTAB_PATH, 'w') as fd:
|
||||
+ fd.write(fstab_original_content)
|
||||
+ with open(cc_mounts.FSTAB_PATH, 'r') as fd:
|
||||
+ fstab_new_content = fd.read()
|
||||
+ self.assertEqual(fstab_expected_content, fstab_new_content)
|
||||
+ cc_mounts.handle(None, cc, self.mock_cloud, self.mock_log, [])
|
||||
+ self.m_util_subp.assert_has_calls([
|
||||
+ mock.call(['mount', '-a']),
|
||||
+ mock.call(['systemctl', 'daemon-reload'])])
|
||||
+
|
||||
# vi: ts=4 expandtab
|
||||
--
|
||||
1.8.3.1
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 3f138f68a36224dcefd5c16befbc00486b09c8ec Mon Sep 17 00:00:00 2001
|
||||
From: Brett Holman <brett.holman@canonical.com>
|
||||
Date: Mon, 29 Jan 2024 12:03:36 -0700
|
||||
Subject: [PATCH 1/2] ci: Pin pytest<8.0.0. (#4816)
|
||||
|
||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
||||
RH-MergeRequest: 123: fix: Add types to network v1 schema (#4841)
|
||||
RH-Jira: RHEL-21323
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Commit: [1/2] db0348f73893a7bb536e4a3562dc7ef33b2590ad
|
||||
|
||||
The latest pytest release broke some tests in non-obvious ways. Pin
|
||||
the version for now so that CI passes.
|
||||
|
||||
(cherry picked from commit 7c96c9cd9318e816ce4564b58a2c98271363c447)
|
||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
||||
---
|
||||
integration-requirements.txt | 2 +-
|
||||
test-requirements.txt | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/integration-requirements.txt b/integration-requirements.txt
|
||||
index 1f8b54a5..c0792d63 100644
|
||||
--- a/integration-requirements.txt
|
||||
+++ b/integration-requirements.txt
|
||||
@@ -7,7 +7,7 @@ pycloudlib>=5.10.0,<1!6
|
||||
# test/unittests/conftest.py to be loaded by our integration-tests tox env
|
||||
# resulting in an unmet dependency issue:
|
||||
# https://github.com/pytest-dev/pytest/issues/11104
|
||||
-pytest!=7.3.2
|
||||
+pytest!=7.3.2,<8.0.0
|
||||
|
||||
packaging
|
||||
passlib
|
||||
diff --git a/test-requirements.txt b/test-requirements.txt
|
||||
index 46a98b4c..3d2480fd 100644
|
||||
--- a/test-requirements.txt
|
||||
+++ b/test-requirements.txt
|
||||
@@ -4,7 +4,7 @@
|
||||
# test/unittests/conftest.py to be loaded by our integration-tests tox env
|
||||
# resulting in an unmet dependency issue:
|
||||
# https://github.com/pytest-dev/pytest/issues/11104
|
||||
-pytest!=7.3.2
|
||||
+pytest!=7.3.2,<8.0.0
|
||||
|
||||
pytest-cov
|
||||
pytest-mock
|
||||
--
|
||||
2.39.3
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
From 720faf533832ba758dcc8436f144168996508c2a Mon Sep 17 00:00:00 2001
|
||||
From: James Falcon <james.falcon@canonical.com>
|
||||
Date: Tue, 6 Feb 2024 09:24:37 -0600
|
||||
Subject: [PATCH 2/2] fix: Add types to network v1 schema (#4841)
|
||||
|
||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
||||
RH-MergeRequest: 123: fix: Add types to network v1 schema (#4841)
|
||||
RH-Jira: RHEL-21323
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Commit: [2/2] a73a68dff5a6ef54dc4e3b3527fc778400a461cc
|
||||
|
||||
Conflicts:
|
||||
For RHEL no log argument as we are not including commit e168b4a1383b6eae9c1dc81411d7684fcbbf7df9
|
||||
|
||||
Even though it has conflicted with our documentation, we have allowed
|
||||
nameserver address to a be a string, mtu to be empty, and nameserver
|
||||
search to be missing. Since we have allowed these, expand our schema
|
||||
and documentation accordingly.
|
||||
|
||||
Fixes GH-4710
|
||||
|
||||
(cherry picked from commit b08193b376552ede5d162d8283310adc783d81bf)
|
||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
||||
---
|
||||
.../config/schemas/schema-network-config-v1.json | 13 +++++++++----
|
||||
doc/rtd/reference/network-config-format-v1.rst | 4 ++--
|
||||
tests/unittests/config/test_schema.py | 13 +++++++++++++
|
||||
3 files changed, 24 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
|
||||
index c77885ec..56dc27c9 100644
|
||||
--- a/cloudinit/config/schemas/schema-network-config-v1.json
|
||||
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
|
||||
@@ -24,7 +24,10 @@
|
||||
"description": "The lowercase MAC address of the physical device."
|
||||
},
|
||||
"mtu": {
|
||||
- "type": "integer",
|
||||
+ "type": [
|
||||
+ "integer",
|
||||
+ "null"
|
||||
+ ],
|
||||
"description": "The MTU size in bytes. The ``mtu`` key represents a device's Maximum Transmission Unit, which is the largest size packet or frame, specified in octets (eight-bit bytes), that can be sent in a packet- or frame-based network. Specifying ``mtu`` is optional. Values too small or too large for a device may be ignored by that device."
|
||||
},
|
||||
"subnets": {
|
||||
@@ -384,8 +387,7 @@
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type",
|
||||
- "address",
|
||||
- "search"
|
||||
+ "address"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
@@ -396,7 +398,10 @@
|
||||
},
|
||||
"address": {
|
||||
"description": "List of IPv4 or IPv6 address of nameservers.",
|
||||
- "type": "array",
|
||||
+ "type": [
|
||||
+ "array",
|
||||
+ "string"
|
||||
+ ],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
diff --git a/doc/rtd/reference/network-config-format-v1.rst b/doc/rtd/reference/network-config-format-v1.rst
|
||||
index d267eb94..42f2dc22 100644
|
||||
--- a/doc/rtd/reference/network-config-format-v1.rst
|
||||
+++ b/doc/rtd/reference/network-config-format-v1.rst
|
||||
@@ -252,8 +252,8 @@ Users can specify a ``nameserver`` type. Nameserver dictionaries include
|
||||
the following keys:
|
||||
|
||||
- ``address``: List of IPv4 or IPv6 address of nameservers.
|
||||
-- ``search``: List of hostnames to include in the :file:`resolv.conf` search
|
||||
- path.
|
||||
+- ``search``: Optional. List of hostnames to include in the :file:`resolv.conf`
|
||||
+ search path.
|
||||
- ``interface``: Optional. Ties the nameserver definition to the specified
|
||||
interface. The value specified here must match the ``name`` of an interface
|
||||
defined in this config. If unspecified, this nameserver will be considered
|
||||
diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
|
||||
index 28f0b39d..52667332 100644
|
||||
--- a/tests/unittests/config/test_schema.py
|
||||
+++ b/tests/unittests/config/test_schema.py
|
||||
@@ -2048,6 +2048,19 @@ class TestNetworkSchema:
|
||||
does_not_raise(),
|
||||
id="bond_with_all_known_properties",
|
||||
),
|
||||
+ pytest.param(
|
||||
+ {
|
||||
+ "network": {
|
||||
+ "version": 1,
|
||||
+ "config": [
|
||||
+ {"type": "physical", "name": "eth0", "mtu": None},
|
||||
+ {"type": "nameserver", "address": "8.8.8.8"},
|
||||
+ ],
|
||||
+ }
|
||||
+ },
|
||||
+ does_not_raise(),
|
||||
+ id="GH-4710_mtu_none_and_str_address",
|
||||
+ ),
|
||||
),
|
||||
)
|
||||
def test_network_schema(self, src_config, expectation):
|
||||
--
|
||||
2.39.3
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
From a622a094a1f497c87a66932382265c2dbf1b88a2 Mon Sep 17 00:00:00 2001
|
||||
From: d1r3ct0r <calvin.mwadime@canonical.com>
|
||||
Date: Sat, 20 Jan 2024 02:11:47 +0300
|
||||
Subject: [PATCH 1/2] fix(clean): stop warning when running clean command
|
||||
(#4761)
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 121: fix(clean): stop warning when running clean command (#4761)
|
||||
RH-Jira: RHEL-21530
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Commit: [1/2] f7a20c627afabf00db20c80ecd6e7f577053863b
|
||||
|
||||
When the clean command is run, runparts is called and README in
|
||||
/etc/cloud/clean.d is not executable which leads to a warning.
|
||||
|
||||
No longer deliver the README in our deb package, move content
|
||||
to our online docs. Continue to deliver the /etc/cloud/clean.d
|
||||
directory as it is used by installers like subiquity.
|
||||
|
||||
Fixes: GH-4760
|
||||
(cherry picked from commit da08a260965e35fa63def1cd8b8b472f7c354ffe)
|
||||
|
||||
There is a downstream only change that is squashed with the upstream commit.
|
||||
The spec file under `redhat/` has been updated so as to not include
|
||||
`/etc/cloud/clean.d/README` file. Otherwise, we shall see errors like the
|
||||
following during the build process:
|
||||
|
||||
`error: File not found: /builddir/build/.../etc/cloud/clean.d/README`
|
||||
|
||||
After a rebase, we can only maintain the downstream spec file change as
|
||||
the rest of it is clean cherry-pick from upstream.
|
||||
|
||||
X-downstream-only: true
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
---
|
||||
config/clean.d/README | 18 ------------------
|
||||
doc/rtd/reference/cli.rst | 27 +++++++++++++++++++++++++++
|
||||
packages/redhat/cloud-init.spec.in | 1 -
|
||||
packages/suse/cloud-init.spec.in | 1 -
|
||||
4 files changed, 27 insertions(+), 20 deletions(-)
|
||||
delete mode 100644 config/clean.d/README
|
||||
|
||||
diff --git a/config/clean.d/README b/config/clean.d/README
|
||||
deleted file mode 100644
|
||||
index 9b0feebe..00000000
|
||||
--- a/config/clean.d/README
|
||||
+++ /dev/null
|
||||
@@ -1,18 +0,0 @@
|
||||
--- cloud-init's clean.d run-parts directory --
|
||||
-
|
||||
-This directory is provided for third party applications which need
|
||||
-additional configuration artifact cleanup from the filesystem when
|
||||
-the command `cloud-init clean` is invoked.
|
||||
-
|
||||
-The `cloud-init clean` operation is typically performed by image creators
|
||||
-when preparing a golden image for clone and redeployment. The clean command
|
||||
-removes any cloud-init semaphores, allowing cloud-init to treat the next
|
||||
-boot of this image as the "first boot". When the image is next booted
|
||||
-cloud-init will performing all initial configuration based on any valid
|
||||
-datasource meta-data and user-data.
|
||||
-
|
||||
-Any executable scripts in this subdirectory will be invoked in lexicographical
|
||||
-order with run-parts by the command: sudo cloud-init clean.
|
||||
-
|
||||
-Typical format of such scripts would be a ##-<some-app> like the following:
|
||||
- /etc/cloud/clean.d/99-live-installer
|
||||
diff --git a/doc/rtd/reference/cli.rst b/doc/rtd/reference/cli.rst
|
||||
index 04e05c55..c36775a8 100644
|
||||
--- a/doc/rtd/reference/cli.rst
|
||||
+++ b/doc/rtd/reference/cli.rst
|
||||
@@ -83,6 +83,33 @@ re-run all stages as it did on first boot.
|
||||
config files for ssh daemon. Argument `network` removes all generated
|
||||
config files for network. `all` removes config files of all types.
|
||||
|
||||
+.. note::
|
||||
+
|
||||
+ Cloud-init provides the directory :file:`/etc/cloud/clean.d/` for third party
|
||||
+ applications which need additional configuration artifact cleanup from
|
||||
+ the fileystem when the `clean` command is invoked.
|
||||
+
|
||||
+ The :command:`clean` operation is typically performed by image creators
|
||||
+ when preparing a golden image for clone and redeployment. The clean command
|
||||
+ removes any cloud-init semaphores, allowing cloud-init to treat the next
|
||||
+ boot of this image as the "first boot". When the image is next booted
|
||||
+ cloud-init will performing all initial configuration based on any valid
|
||||
+ datasource meta-data and user-data.
|
||||
+
|
||||
+ Any executable scripts in this subdirectory will be invoked in lexicographical
|
||||
+ order with run-parts when running the :command:`clean` command.
|
||||
+
|
||||
+ Typical format of such scripts would be a ##-<some-app> like the following:
|
||||
+ :file:`/etc/cloud/clean.d/99-live-installer`
|
||||
+
|
||||
+ An example of a script is:
|
||||
+
|
||||
+ .. code-block:: bash
|
||||
+
|
||||
+ sudo rm -rf /var/lib/installer_imgs/
|
||||
+ sudo rm -rf /var/log/installer/
|
||||
+
|
||||
+
|
||||
.. _cli_collect_logs:
|
||||
|
||||
:command:`collect-logs`
|
||||
diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in
|
||||
index 97e95096..accfb1b6 100644
|
||||
--- a/packages/redhat/cloud-init.spec.in
|
||||
+++ b/packages/redhat/cloud-init.spec.in
|
||||
@@ -190,7 +190,6 @@ fi
|
||||
# Configs
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
|
||||
%dir %{_sysconfdir}/cloud/clean.d
|
||||
-%config(noreplace) %{_sysconfdir}/cloud/clean.d/README
|
||||
%dir %{_sysconfdir}/cloud/cloud.cfg.d
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/README
|
||||
diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in
|
||||
index 62a9129b..fae3c12b 100644
|
||||
--- a/packages/suse/cloud-init.spec.in
|
||||
+++ b/packages/suse/cloud-init.spec.in
|
||||
@@ -115,7 +115,6 @@ version_pys=$(cd "%{buildroot}" && find . -name version.py -type f)
|
||||
|
||||
# Configs
|
||||
%dir %{_sysconfdir}/cloud/clean.d
|
||||
-%config(noreplace) %{_sysconfdir}/cloud/clean.d/README
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
|
||||
%dir %{_sysconfdir}/cloud/cloud.cfg.d
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
From 2942fb776cd1fc765089ebd0004e01dc2b3a5920 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Tue, 21 Nov 2023 13:57:15 +0530
|
||||
Subject: [PATCH 2/3] net: allow dhcp6 configuration from
|
||||
generate_fallback_configuration()
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 119: net: allow dhcp6 configuration from generate_fallback_configuration()
|
||||
RH-Jira: RHEL-7277
|
||||
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Commit: [2/2] b067c813488dfddc79d8ebd5bb51894ff040c356
|
||||
|
||||
This will make sure on Azure we can use both dhcp4 and dhcp6 when IMDS is not
|
||||
used. This is useful in situations where only ipv6 network is available and
|
||||
there is no dhcp4 running.
|
||||
|
||||
This change is mostly a reversal of commit 29ed5f5b646ee and therefore,
|
||||
re-application of the commit 518047aea9 with some small changes.
|
||||
|
||||
The issue that caused the reversal of 518047aea9 is fixed by the earlier commit:
|
||||
cab0eaf290af7 ("net/network_manager: do not set "may-fail" to False for both ipv4 and ipv6 dhcp")
|
||||
|
||||
Fixes GH-4439
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
(cherry picked from commit 0264e969166846b2f5cf87ccdb051a3a795eca15)
|
||||
---
|
||||
cloudinit/net/__init__.py | 7 ++++++-
|
||||
tests/unittests/net/test_init.py | 4 ++++
|
||||
tests/unittests/test_net.py | 24 +++++++++++++++++++++---
|
||||
3 files changed, 31 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
|
||||
index bf21633b..c0888f52 100644
|
||||
--- a/cloudinit/net/__init__.py
|
||||
+++ b/cloudinit/net/__init__.py
|
||||
@@ -571,7 +571,12 @@ def generate_fallback_config(config_driver=None):
|
||||
match = {
|
||||
"macaddress": read_sys_net_safe(target_name, "address").lower()
|
||||
}
|
||||
- cfg = {"dhcp4": True, "set-name": target_name, "match": match}
|
||||
+ cfg = {
|
||||
+ "dhcp4": True,
|
||||
+ "dhcp6": True,
|
||||
+ "set-name": target_name,
|
||||
+ "match": match,
|
||||
+ }
|
||||
if config_driver:
|
||||
driver = device_driver(target_name)
|
||||
if driver:
|
||||
diff --git a/tests/unittests/net/test_init.py b/tests/unittests/net/test_init.py
|
||||
index 561d5151..60a44186 100644
|
||||
--- a/tests/unittests/net/test_init.py
|
||||
+++ b/tests/unittests/net/test_init.py
|
||||
@@ -261,6 +261,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
||||
"eth1": {
|
||||
"match": {"macaddress": mac},
|
||||
"dhcp4": True,
|
||||
+ "dhcp6": True,
|
||||
"set-name": "eth1",
|
||||
}
|
||||
},
|
||||
@@ -278,6 +279,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
||||
"eth0": {
|
||||
"match": {"macaddress": mac},
|
||||
"dhcp4": True,
|
||||
+ "dhcp6": True,
|
||||
"set-name": "eth0",
|
||||
}
|
||||
},
|
||||
@@ -293,6 +295,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
||||
"ethernets": {
|
||||
"eth0": {
|
||||
"dhcp4": True,
|
||||
+ "dhcp6": True,
|
||||
"match": {"macaddress": mac},
|
||||
"set-name": "eth0",
|
||||
}
|
||||
@@ -359,6 +362,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
||||
"ethernets": {
|
||||
"ens3": {
|
||||
"dhcp4": True,
|
||||
+ "dhcp6": True,
|
||||
"match": {"name": "ens3"},
|
||||
"set-name": "ens3",
|
||||
}
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 54d053f3..e52c2497 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -4299,6 +4299,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
||||
"ethernets": {
|
||||
"eth0": {
|
||||
"dhcp4": True,
|
||||
+ "dhcp6": True,
|
||||
"set-name": "eth0",
|
||||
"match": {
|
||||
"macaddress": "00:11:22:33:44:55",
|
||||
@@ -4383,6 +4384,9 @@ iface lo inet loopback
|
||||
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
+
|
||||
+# control-alias eth0
|
||||
+iface eth0 inet6 dhcp
|
||||
"""
|
||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
||||
|
||||
@@ -4472,6 +4476,9 @@ iface lo inet loopback
|
||||
|
||||
auto eth1
|
||||
iface eth1 inet dhcp
|
||||
+
|
||||
+# control-alias eth1
|
||||
+iface eth1 inet6 dhcp
|
||||
"""
|
||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
||||
|
||||
@@ -4695,7 +4702,9 @@ class TestRhelSysConfigRendering(CiTestCase):
|
||||
#
|
||||
BOOTPROTO=dhcp
|
||||
DEVICE=eth1000
|
||||
+DHCPV6C=yes
|
||||
HWADDR=07-1c-c6-75-a4-be
|
||||
+IPV6INIT=yes
|
||||
ONBOOT=yes
|
||||
TYPE=Ethernet
|
||||
USERCTL=no
|
||||
@@ -5593,7 +5602,8 @@ class TestOpenSuseSysConfigRendering(CiTestCase):
|
||||
expected_content = """
|
||||
# Created by cloud-init automatically, do not edit.
|
||||
#
|
||||
-BOOTPROTO=dhcp4
|
||||
+BOOTPROTO=dhcp
|
||||
+DHCLIENT6_MODE=managed
|
||||
LLADDR=07-1c-c6-75-a4-be
|
||||
STARTMODE=auto
|
||||
""".lstrip()
|
||||
@@ -5979,7 +5989,11 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||
|
||||
[ipv4]
|
||||
method=auto
|
||||
- may-fail=false
|
||||
+ may-fail=true
|
||||
+
|
||||
+ [ipv6]
|
||||
+ method=auto
|
||||
+ may-fail=true
|
||||
|
||||
"""
|
||||
),
|
||||
@@ -6245,6 +6259,9 @@ iface lo inet loopback
|
||||
|
||||
auto eth1000
|
||||
iface eth1000 inet dhcp
|
||||
+
|
||||
+# control-alias eth1000
|
||||
+iface eth1000 inet6 dhcp
|
||||
"""
|
||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
||||
|
||||
@@ -6304,6 +6321,7 @@ class TestNetplanNetRendering:
|
||||
ethernets:
|
||||
eth1000:
|
||||
dhcp4: true
|
||||
+ dhcp6: true
|
||||
match:
|
||||
macaddress: 07-1c-c6-75-a4-be
|
||||
set-name: eth1000
|
||||
@@ -7803,7 +7821,7 @@ class TestNetworkdNetRendering(CiTestCase):
|
||||
Name=eth1000
|
||||
MACAddress=07-1c-c6-75-a4-be
|
||||
[Network]
|
||||
- DHCP=ipv4"""
|
||||
+ DHCP=yes"""
|
||||
).rstrip(" ")
|
||||
|
||||
expected = self.create_conf_dict(expected.splitlines())
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
From 010cd58942c82e902bc02cb5a34074f6083fc890 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Thu, 23 Nov 2023 12:27:51 +0530
|
||||
Subject: [PATCH 1/3] net/network_manager: do not set "may-fail" to False for
|
||||
both ipv4 and ipv6 dhcp
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 119: net: allow dhcp6 configuration from generate_fallback_configuration()
|
||||
RH-Jira: RHEL-7277
|
||||
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Commit: [1/2] be07418f69a4c461e2fa02a72b7b985053af9660
|
||||
|
||||
If "may-fail" is set to False in the Network Manager keyfile for both ipv4
|
||||
and ipv6 for dhcp configuration, it essentially means both ipv4 and ipv6 network
|
||||
initialization using dhcp must succeed for the overall network configuration to
|
||||
succeed. This means, for environments where only ipv4 or ipv6 is available but
|
||||
not both and we need to configure both ipv4 and ipv6 dhcp, the overall
|
||||
network configuration will fail. This is not what we want. When both ipv4
|
||||
and ipv6 dhcp are configured, it is enough for the overall configuration to
|
||||
succeed if any one succeeds.
|
||||
Therefore, set "may-fail" to True for both ipv4 and ipv6 if and only if both
|
||||
ipv4 and ipv6 are configured as dhcp in the Network Manager keyfile and
|
||||
"may-fail" is set to False for both. If both ipv4 and ipv6 are configured
|
||||
in the keyfile and if for any of them "may-fail" is already set to True,then
|
||||
do nothing.
|
||||
All other cases remain same as before.
|
||||
|
||||
Please see discussions in PR #4474.
|
||||
|
||||
Co-authored-by: James Falcon <james.falcon@canonical.com>
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
(cherry picked from commit 29dd5ace73ad60c7452c39b840045fb47fe0711f)
|
||||
---
|
||||
cloudinit/net/network_manager.py | 59 ++++++++++++++++++++++++++++++++
|
||||
tests/unittests/test_net.py | 8 ++---
|
||||
2 files changed, 63 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||
index 8374cfcc..8a99eb3a 100644
|
||||
--- a/cloudinit/net/network_manager.py
|
||||
+++ b/cloudinit/net/network_manager.py
|
||||
@@ -71,6 +71,57 @@ class NMConnection:
|
||||
if not self.config.has_option(section, option):
|
||||
self.config[section][option] = value
|
||||
|
||||
+ def _config_option_is_set(self, section, option):
|
||||
+ """
|
||||
+ Checks if a config option is set. Returns True if it is,
|
||||
+ else returns False.
|
||||
+ """
|
||||
+ return self.config.has_section(section) and self.config.has_option(
|
||||
+ section, option
|
||||
+ )
|
||||
+
|
||||
+ def _get_config_option(self, section, option):
|
||||
+ """
|
||||
+ Returns the value of a config option if its set,
|
||||
+ else returns None.
|
||||
+ """
|
||||
+ if self._config_option_is_set(section, option):
|
||||
+ return self.config[section][option]
|
||||
+ else:
|
||||
+ return None
|
||||
+
|
||||
+ def _change_set_config_option(self, section, option, value):
|
||||
+ """
|
||||
+ Overrides the value of a config option if its already set.
|
||||
+ Else, if the config option is not set, it does nothing.
|
||||
+ """
|
||||
+ if self._config_option_is_set(section, option):
|
||||
+ self.config[section][option] = value
|
||||
+
|
||||
+ def _set_mayfail_true_if_both_false_dhcp(self):
|
||||
+ """
|
||||
+ If for both ipv4 and ipv6, 'may-fail' is set to be False,
|
||||
+ set it to True for both of them.
|
||||
+ """
|
||||
+ for family in ["ipv4", "ipv6"]:
|
||||
+ if self._get_config_option(family, "may-fail") != "false":
|
||||
+ # if either ipv4 or ipv6 sections are not set/configured,
|
||||
+ # or if both are configured but for either ipv4 or ipv6,
|
||||
+ # 'may-fail' is not 'false', do not do anything.
|
||||
+ return
|
||||
+ if self._get_config_option(family, "method") not in [
|
||||
+ "dhcp",
|
||||
+ "auto",
|
||||
+ ]:
|
||||
+ # if both v4 and v6 are not dhcp, do not do anything.
|
||||
+ return
|
||||
+
|
||||
+ # If we landed here, it means both ipv4 and ipv6 are configured
|
||||
+ # with dhcp/auto and both have 'may-fail' set to 'false'. So set
|
||||
+ # both to 'true'.
|
||||
+ for family in ["ipv4", "ipv6"]:
|
||||
+ self._change_set_config_option(family, "may-fail", "true")
|
||||
+
|
||||
def _set_ip_method(self, family, subnet_type):
|
||||
"""
|
||||
Ensures there's appropriate [ipv4]/[ipv6] for given family
|
||||
@@ -271,6 +322,14 @@ class NMConnection:
|
||||
if family == "ipv4" and "mtu" in subnet:
|
||||
ipv4_mtu = subnet["mtu"]
|
||||
|
||||
+ # we do not want to set may-fail to false for both ipv4 and ipv6 dhcp
|
||||
+ # at the at the same time. This will make the network configuration
|
||||
+ # work only when both ipv4 and ipv6 dhcp succeeds. This may not be
|
||||
+ # what we want. If we have configured both ipv4 and ipv6 dhcp, any one
|
||||
+ # succeeding should be enough. Therefore, if "may-fail" is set to
|
||||
+ # False for both ipv4 and ipv6 dhcp, set them both to True.
|
||||
+ self._set_mayfail_true_if_both_false_dhcp()
|
||||
+
|
||||
if ipv4_mtu is None:
|
||||
ipv4_mtu = device_mtu
|
||||
if not ipv4_mtu == device_mtu:
|
||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||
index 052b0674..54d053f3 100644
|
||||
--- a/tests/unittests/test_net.py
|
||||
+++ b/tests/unittests/test_net.py
|
||||
@@ -1470,11 +1470,11 @@ NETWORK_CONFIGS = {
|
||||
|
||||
[ipv4]
|
||||
method=auto
|
||||
- may-fail=false
|
||||
+ may-fail=true
|
||||
|
||||
[ipv6]
|
||||
method=auto
|
||||
- may-fail=false
|
||||
+ may-fail=true
|
||||
|
||||
"""
|
||||
),
|
||||
@@ -1642,11 +1642,11 @@ NETWORK_CONFIGS = {
|
||||
|
||||
[ipv6]
|
||||
method=auto
|
||||
- may-fail=false
|
||||
+ may-fail=true
|
||||
|
||||
[ipv4]
|
||||
method=auto
|
||||
- may-fail=false
|
||||
+ may-fail=true
|
||||
|
||||
"""
|
||||
),
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
From ffc8f3fbb4c8c14a4ef2b6a99a9ea61da4bedde7 Mon Sep 17 00:00:00 2001
|
||||
From: Ani Sinha <anisinha@redhat.com>
|
||||
Date: Thu, 7 Dec 2023 02:39:51 +0530
|
||||
Subject: [PATCH 3/3] net/nm: check for presence of ifcfg files when nm
|
||||
connection files are absent (#4645)
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 120: net/nm: check for presence of ifcfg files when nm connection files are absent (#4645)
|
||||
RH-Jira: RHEL-17610
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-Commit: [1/1] e0647418de8b70724a32500f26f544650d701404
|
||||
|
||||
On systems that use network manager to manage connections and activate network
|
||||
interfaces, they may also use ifcfg files for configuring
|
||||
interfaces using ifcfg-rh network manager plugin. When network manager is used
|
||||
as the activator, we need to also check for the presence of ifcfg interface
|
||||
config file when the network manager connection file is absent and if ifcfg-rh
|
||||
plugin is present.
|
||||
Hence, with this change, network manager activator first tries to use network
|
||||
manager connection files to bring up or bring down the interface. If the
|
||||
connection files are not present and if ifcfg-rh plugin is present, it tries to
|
||||
use ifcfg files for the interface. If the plugin or the ifcfg files are not
|
||||
present, the activator fails to activate or deactivate the interface and it
|
||||
bails out with warning log.
|
||||
|
||||
Fixes: GH-4640
|
||||
|
||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||
(cherry picked from commit d1d5166895da471cff3606c70d4e8ab6eec1c006)
|
||||
---
|
||||
cloudinit/net/activators.py | 7 +++++++
|
||||
cloudinit/net/network_manager.py | 33 ++++++++++++++++++++++++++++++--
|
||||
2 files changed, 38 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py
|
||||
index e69da40d..dd858862 100644
|
||||
--- a/cloudinit/net/activators.py
|
||||
+++ b/cloudinit/net/activators.py
|
||||
@@ -117,6 +117,13 @@ class NetworkManagerActivator(NetworkActivator):
|
||||
from cloudinit.net.network_manager import conn_filename
|
||||
|
||||
filename = conn_filename(device_name)
|
||||
+ if filename is None:
|
||||
+ LOG.warning(
|
||||
+ "Unable to find an interface config file. "
|
||||
+ "Unable to bring up interface."
|
||||
+ )
|
||||
+ return False
|
||||
+
|
||||
cmd = ["nmcli", "connection", "load", filename]
|
||||
if _alter_interface(cmd, device_name):
|
||||
cmd = ["nmcli", "connection", "up", "filename", filename]
|
||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||
index 8a99eb3a..76a0ac15 100644
|
||||
--- a/cloudinit/net/network_manager.py
|
||||
+++ b/cloudinit/net/network_manager.py
|
||||
@@ -17,10 +17,12 @@ from typing import Optional
|
||||
from cloudinit import subp, util
|
||||
from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
|
||||
from cloudinit.net.network_state import NetworkState
|
||||
+from cloudinit.net.sysconfig import available_nm_ifcfg_rh
|
||||
|
||||
NM_RUN_DIR = "/etc/NetworkManager"
|
||||
NM_LIB_DIR = "/usr/lib/NetworkManager"
|
||||
NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
|
||||
+IFCFG_CFG_FILE = "/etc/sysconfig/network-scripts"
|
||||
NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit.
|
||||
#
|
||||
[.config]
|
||||
@@ -442,7 +444,7 @@ class Renderer(renderer.Renderer):
|
||||
for con_id, conn in self.connections.items():
|
||||
if not conn.valid():
|
||||
continue
|
||||
- name = conn_filename(con_id, target)
|
||||
+ name = nm_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
|
||||
@@ -452,12 +454,39 @@ class Renderer(renderer.Renderer):
|
||||
)
|
||||
|
||||
|
||||
-def conn_filename(con_id, target=None):
|
||||
+def nm_conn_filename(con_id, target=None):
|
||||
target_con_dir = subp.target_path(target, NM_RUN_DIR)
|
||||
con_file = f"cloud-init-{con_id}.nmconnection"
|
||||
return f"{target_con_dir}/system-connections/{con_file}"
|
||||
|
||||
|
||||
+def sysconfig_conn_filename(devname, target=None):
|
||||
+ target_con_dir = subp.target_path(target, IFCFG_CFG_FILE)
|
||||
+ con_file = f"ifcfg-{devname}"
|
||||
+ return f"{target_con_dir}/{con_file}"
|
||||
+
|
||||
+
|
||||
+def conn_filename(devname):
|
||||
+ """
|
||||
+ This function returns the name of the interface config file.
|
||||
+ It first checks for presence of network manager connection file.
|
||||
+ If absent and ifcfg-rh plugin for network manager is available,
|
||||
+ it returns the name of the ifcfg file if it is present. If the
|
||||
+ plugin is not present or the plugin is present but ifcfg file is
|
||||
+ not, it returns None.
|
||||
+ This function is called from NetworkManagerActivator class in
|
||||
+ activators.py.
|
||||
+ """
|
||||
+ conn_file = nm_conn_filename(devname)
|
||||
+ # If the network manager connection file is absent, also check for
|
||||
+ # presence of ifcfg files for the same interface (if nm-ifcfg-rh plugin is
|
||||
+ # present, network manager can handle ifcfg files). If both network manager
|
||||
+ # connection file and ifcfg files are absent, return None.
|
||||
+ if not os.path.isfile(conn_file) and available_nm_ifcfg_rh():
|
||||
+ conn_file = sysconfig_conn_filename(devname)
|
||||
+ return conn_file if os.path.isfile(conn_file) else None
|
||||
+
|
||||
+
|
||||
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"
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
From c43791eeb00bc9000abff0125c18aa6a7e8b7160 Mon Sep 17 00:00:00 2001
|
||||
From: Brett Holman <brett.holman@canonical.com>
|
||||
Date: Tue, 16 Jan 2024 12:43:17 -0700
|
||||
Subject: [PATCH 2/2] test(jsonschema): Pin jsonschema version (#4781)
|
||||
|
||||
RH-Author: Ani Sinha <None>
|
||||
RH-MergeRequest: 121: fix(clean): stop warning when running clean command (#4761)
|
||||
RH-Jira: RHEL-21530
|
||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||
RH-Commit: [2/2] f864085d47723b3fb462c3b6fc6e24b90bf040aa
|
||||
|
||||
Release 4.21.0 broke tests
|
||||
|
||||
(cherry picked from commit 034a5cdf10582da0492321f861b2b8b42182a54e)
|
||||
---
|
||||
requirements.txt | 2 +-
|
||||
test-requirements.txt | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/requirements.txt b/requirements.txt
|
||||
index edec46a7..a095de18 100644
|
||||
--- a/requirements.txt
|
||||
+++ b/requirements.txt
|
||||
@@ -28,7 +28,7 @@ requests
|
||||
jsonpatch
|
||||
|
||||
# For validating cloud-config sections per schema definitions
|
||||
-jsonschema
|
||||
+jsonschema<=4.20.0
|
||||
|
||||
# Used by DataSourceVMware to inspect the host's network configuration during
|
||||
# the "setup()" function.
|
||||
diff --git a/test-requirements.txt b/test-requirements.txt
|
||||
index 19488b94..46a98b4c 100644
|
||||
--- a/test-requirements.txt
|
||||
+++ b/test-requirements.txt
|
||||
@@ -9,6 +9,6 @@ pytest!=7.3.2
|
||||
pytest-cov
|
||||
pytest-mock
|
||||
setuptools
|
||||
-jsonschema
|
||||
+jsonschema<=4.20.0
|
||||
responses
|
||||
passlib
|
||||
--
|
||||
2.41.0
|
||||
|
|
@ -5,38 +5,40 @@
|
|||
%global debug_package %{nil}
|
||||
|
||||
Name: cloud-init
|
||||
Version: 18.5
|
||||
Release: 4%{?dist}
|
||||
Version: 23.4
|
||||
Release: 7%{?dist}
|
||||
Summary: Cloud instance init scripts
|
||||
|
||||
Group: System Environment/Base
|
||||
License: GPLv3
|
||||
URL: http://launchpad.net/cloud-init
|
||||
Source0: https://launchpad.net/cloud-init/trunk/%{version}/+download/%{name}-%{version}.tar.gz
|
||||
URL: https://github.com/canonical/cloud-init
|
||||
Source0: https://github.com/canonical/cloud-init/archive/refs/tags/%{version}.tar.gz
|
||||
Source1: cloud-init-tmpfiles.conf
|
||||
|
||||
Patch0001: 0001-Add-initial-redhat-setup.patch
|
||||
Patch0002: 0002-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
|
||||
Patch0003: 0003-limit-permissions-on-def_log_file.patch
|
||||
Patch0004: 0004-azure-ensure-that-networkmanager-hook-script-runs.patch
|
||||
Patch0005: 0005-sysconfig-Don-t-write-BOOTPROTO-dhcp-for-ipv6-dhcp.patch
|
||||
Patch0006: 0006-DataSourceAzure.py-use-hostnamectl-to-set-hostname.patch
|
||||
Patch0007: 0007-sysconfig-Don-t-disable-IPV6_AUTOCONF.patch
|
||||
Patch0008: 0008-net-Make-sysconfig-renderer-compatible-with-Network-.patch
|
||||
Patch0009: 0009-net-Wait-for-dhclient-to-daemonize-before-reading-le.patch
|
||||
Patch0010: 0010-cloud-init-per-don-t-use-dashes-in-sem-names.patch
|
||||
Patch0011: 0011-azure-Filter-list-of-ssh-keys-pulled-from-fabric.patch
|
||||
Patch0012: 0012-include-NOZEROCONF-yes-in-etc-sysconfig-network.patch
|
||||
# For bz#1691986 - [Azure] [RHEL 8.1] Cloud-init fixes to support fast provisioning for Azure
|
||||
Patch13: ci-Azure-Ensure-platform-random_seed-is-always-serializ.patch
|
||||
# For bz#1691986 - [Azure] [RHEL 8.1] Cloud-init fixes to support fast provisioning for Azure
|
||||
Patch14: ci-DatasourceAzure-add-additional-logging-for-azure-dat.patch
|
||||
# For bz#1691986 - [Azure] [RHEL 8.1] Cloud-init fixes to support fast provisioning for Azure
|
||||
Patch15: ci-Azure-Changes-to-the-Hyper-V-KVP-Reporter.patch
|
||||
# For bz#1691986 - [Azure] [RHEL 8.1] Cloud-init fixes to support fast provisioning for Azure
|
||||
Patch16: ci-DataSourceAzure-Adjust-timeout-for-polling-IMDS.patch
|
||||
# For bz#1691986 - [Azure] [RHEL 8.1] Cloud-init fixes to support fast provisioning for Azure
|
||||
Patch17: ci-cc_mounts-check-if-mount-a-on-no-change-fstab-path.patch
|
||||
Patch0003: 0003-Do-not-write-NM_CONTROLLED-no-in-generated-interface.patch
|
||||
Patch0004: 0004-include-NOZEROCONF-yes-in-etc-sysconfig-network.patch
|
||||
Patch0005: 0005-settings.py-update-settings-for-rhel.patch
|
||||
Patch0013: 0013-rhel-cloud.cfg-remove-ssh_genkeytypes-in-settings.py.patch
|
||||
# For RHEL-7277 - [RFE] [Azure][RHEL8][Network][cloud-init] Can not acquire IPv6 address
|
||||
Patch14: ci-net-network_manager-do-not-set-may-fail-to-False-for.patch
|
||||
# For RHEL-7277 - [RFE] [Azure][RHEL8][Network][cloud-init] Can not acquire IPv6 address
|
||||
Patch15: ci-net-allow-dhcp6-configuration-from-generate_fallback.patch
|
||||
# For RHEL-17610 - [RHEL-8] NetworkManagerActivator brings up interface failed when using sysconfig renderer
|
||||
Patch16: ci-net-nm-check-for-presence-of-ifcfg-files-when-nm-con.patch
|
||||
# For RHEL-21530 - [RHEL-8.10]subp.py[WARNING]: skipping /etc/cloud/clean.d/README when do cloud-init clean
|
||||
Patch17: ci-fix-clean-stop-warning-when-running-clean-command-47.patch
|
||||
# For RHEL-21530 - [RHEL-8.10]subp.py[WARNING]: skipping /etc/cloud/clean.d/README when do cloud-init clean
|
||||
Patch18: ci-test-jsonschema-Pin-jsonschema-version-4781.patch
|
||||
# For RHEL-22248 - [Azure][RHEL-8] cloud-init-23.4 cannot read "- Azure" datasource_list format
|
||||
Patch19: ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch
|
||||
# For RHEL-21323 - [rhel-8] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4
|
||||
Patch20: ci-ci-Pin-pytest-8.0.0.-4816.patch
|
||||
# For RHEL-21323 - [rhel-8] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4
|
||||
Patch21: ci-fix-Add-types-to-network-v1-schema-4841.patch
|
||||
# For RHEL-21290 - Unknown lvalue 'ConditionEnvironment' in section 'Unit' for /usr/lib/systemd/system/cloud-init.target,cloud-init.service
|
||||
Patch22: ci-Revert-systemd-Standardize-cloud-init-systemd-enable.patch
|
||||
# For RHEL-28817 - [RHEL 8.10] cloud-init 23.4 returns 2 on recoverable errors instead of 0
|
||||
Patch23: ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch
|
||||
|
||||
BuildArch: noarch
|
||||
|
||||
|
@ -69,7 +71,6 @@ BuildRequires: /usr/bin/dnf
|
|||
Requires: e2fsprogs
|
||||
Requires: iproute
|
||||
Requires: libselinux-python3
|
||||
Requires: net-tools
|
||||
Requires: policycoreutils-python3
|
||||
Requires: procps
|
||||
Requires: python3-configobj
|
||||
|
@ -85,6 +86,11 @@ Requires: python3-six
|
|||
Requires: shadow-utils
|
||||
Requires: util-linux
|
||||
Requires: xfsprogs
|
||||
Requires: dhcp-client
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2039697
|
||||
Requires: gdisk
|
||||
Requires: openssl
|
||||
Requires: python3-netifaces
|
||||
|
||||
%{?systemd_requires}
|
||||
|
||||
|
@ -108,7 +114,7 @@ sed -i -e 's|#!/usr/bin/env python|#!/usr/bin/env python3|' \
|
|||
%install
|
||||
%py3_install --
|
||||
|
||||
python3 tools/render-cloudcfg --variant fedora > $RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg
|
||||
sed -i "s,@@PACKAGED_VERSION@@,%{version}-%{release}," $RPM_BUILD_ROOT/%{python3_sitelib}/cloudinit/version.py
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/cloud
|
||||
|
||||
|
@ -117,20 +123,20 @@ mkdir -p $RPM_BUILD_ROOT/run/cloud-init
|
|||
mkdir -p $RPM_BUILD_ROOT/%{_tmpfilesdir}
|
||||
cp -p %{SOURCE1} $RPM_BUILD_ROOT/%{_tmpfilesdir}/%{name}.conf
|
||||
|
||||
# We supply our own config file since our software differs from Ubuntu's.
|
||||
cp -p rhel/cloud.cfg $RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/rsyslog.d
|
||||
cp -p tools/21-cloudinit.conf $RPM_BUILD_ROOT/%{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||
|
||||
# Make installed NetworkManager hook name less generic
|
||||
mv $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/hook-network-manager \
|
||||
$RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/cloud-init-azure-hook
|
||||
|
||||
# Install our own systemd units (rhbz#1440831)
|
||||
mkdir -p $RPM_BUILD_ROOT%{_unitdir}
|
||||
cp rhel/systemd/* $RPM_BUILD_ROOT%{_unitdir}/
|
||||
[ ! -d $RPM_BUILD_ROOT/usr/lib/systemd/system-generators ] && mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/system-generators
|
||||
python3 tools/render-template --variant rhel systemd/cloud-init-generator.tmpl > $RPM_BUILD_ROOT/usr/lib/systemd/system-generators/cloud-init-generator
|
||||
chmod 755 $RPM_BUILD_ROOT/usr/lib/systemd/system-generators/cloud-init-generator
|
||||
|
||||
# installing man pages
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man1/
|
||||
for man in cloud-id.1 cloud-init.1 cloud-init-per.1; do
|
||||
install -c -m 0644 doc/man/${man} ${RPM_BUILD_ROOT}%{_mandir}/man1/${man}
|
||||
chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/*
|
||||
done
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
@ -144,8 +150,29 @@ if [ $1 -eq 1 ] ; then
|
|||
/bin/systemctl enable cloud-final.service >/dev/null 2>&1 || :
|
||||
/bin/systemctl enable cloud-init.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 || :
|
||||
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
|
||||
/bin/systemctl is-enabled cloud-config.service >/dev/null 2>&1 &&
|
||||
/bin/systemctl reenable cloud-config.service >/dev/null 2>&1 || :
|
||||
|
@ -158,6 +185,9 @@ elif [ $1 -eq 2 ]; then
|
|||
|
||||
/bin/systemctl is-enabled cloud-init-local.service >/dev/null 2>&1 &&
|
||||
/bin/systemctl reenable cloud-init-local.service >/dev/null 2>&1 || :
|
||||
|
||||
/bin/systemctl is-enabled cloud-init.target >/dev/null 2>&1 &&
|
||||
/bin/systemctl reenable cloud-init.target >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%preun
|
||||
|
@ -167,16 +197,30 @@ if [ $1 -eq 0 ] ; then
|
|||
/bin/systemctl --no-reload disable cloud-final.service >/dev/null 2>&1 || :
|
||||
/bin/systemctl --no-reload disable cloud-init.service >/dev/null 2>&1 || :
|
||||
/bin/systemctl --no-reload disable cloud-init-local.service >/dev/null 2>&1 || :
|
||||
/bin/systemctl --no-reload disable cloud-init.target >/dev/null 2>&1 || :
|
||||
# One-shot services -> no need to stop
|
||||
fi
|
||||
|
||||
%postun
|
||||
%systemd_postun
|
||||
%systemd_postun cloud-config.service cloud-config.target cloud-final.service cloud-init.service cloud-init.target cloud-init-local.service
|
||||
|
||||
if [ $1 -eq 0 ] ; then
|
||||
# warn during package removal not upgrade
|
||||
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
|
||||
fi
|
||||
|
||||
%files
|
||||
%license LICENSE
|
||||
%doc ChangeLog rhel/README.rhel
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg
|
||||
%dir %{_sysconfdir}/cloud/cloud.cfg.d
|
||||
%config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/*.cfg
|
||||
|
@ -186,24 +230,484 @@ fi
|
|||
%{_unitdir}/cloud-config.service
|
||||
%{_unitdir}/cloud-config.target
|
||||
%{_unitdir}/cloud-final.service
|
||||
%{_unitdir}/cloud-init-hotplugd.service
|
||||
%{_unitdir}/cloud-init-hotplugd.socket
|
||||
%{_unitdir}/cloud-init-local.service
|
||||
%{_unitdir}/cloud-init.service
|
||||
%{_unitdir}/cloud-init.target
|
||||
%{_tmpfilesdir}/%{name}.conf
|
||||
%{python3_sitelib}/*
|
||||
%{_libexecdir}/%{name}
|
||||
%{_bindir}/cloud-init*
|
||||
%doc %{_datadir}/doc/%{name}
|
||||
%dir /run/cloud-init
|
||||
%{_mandir}/man1/*
|
||||
%dir %verify(not mode) /run/cloud-init
|
||||
%dir /var/lib/cloud
|
||||
/etc/NetworkManager/dispatcher.d/cloud-init-azure-hook
|
||||
%{_udevrulesdir}/66-azure-ephemeral.rules
|
||||
%{_sysconfdir}/bash_completion.d/cloud-init
|
||||
%{_datadir}/bash-completion/completions/cloud-init
|
||||
%{_bindir}/cloud-id
|
||||
/usr/lib/systemd/system-generators/cloud-init-generator
|
||||
%{_sysconfdir}/systemd/system/sshd-keygen@.service.d/disable-sshd-keygen-if-cloud-init-active.conf
|
||||
|
||||
|
||||
%dir %{_sysconfdir}/rsyslog.d
|
||||
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||
|
||||
%changelog
|
||||
* Thu Mar 14 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7
|
||||
- ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch [RHEL-28817]
|
||||
- Resolves: RHEL-28817
|
||||
([RHEL 8.10] cloud-init 23.4 returns 2 on recoverable errors instead of 0)
|
||||
|
||||
* Mon Mar 11 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-6
|
||||
- ci-Revert-systemd-Standardize-cloud-init-systemd-enable.patch [RHEL-21290]
|
||||
- Resolves: RHEL-21290
|
||||
(Unknown lvalue 'ConditionEnvironment' in section 'Unit' for /usr/lib/systemd/system/cloud-init.target,cloud-init.service)
|
||||
|
||||
* Mon Feb 26 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-5
|
||||
- ci-ci-Pin-pytest-8.0.0.-4816.patch [RHEL-21323]
|
||||
- ci-fix-Add-types-to-network-v1-schema-4841.patch [RHEL-21323]
|
||||
- Resolves: RHEL-21323
|
||||
([rhel-8] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4)
|
||||
|
||||
* Fri Feb 02 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-4
|
||||
- ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch [RHEL-22248]
|
||||
- Resolves: RHEL-22248
|
||||
([Azure][RHEL-8] cloud-init-23.4 cannot read "- Azure" datasource_list format)
|
||||
|
||||
* Fri Feb 02 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-3
|
||||
- ci-fix-clean-stop-warning-when-running-clean-command-47.patch [RHEL-21530]
|
||||
- ci-test-jsonschema-Pin-jsonschema-version-4781.patch [RHEL-21530]
|
||||
- Resolves: RHEL-21530
|
||||
([RHEL-8.10]subp.py[WARNING]: skipping /etc/cloud/clean.d/README when do cloud-init clean)
|
||||
|
||||
* Tue Jan 16 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-2
|
||||
- ci-net-network_manager-do-not-set-may-fail-to-False-for.patch [RHEL-7277]
|
||||
- ci-net-allow-dhcp6-configuration-from-generate_fallback.patch [RHEL-7277]
|
||||
- ci-net-nm-check-for-presence-of-ifcfg-files-when-nm-con.patch [RHEL-17610]
|
||||
- Resolves: RHEL-7277
|
||||
([RFE] [Azure][RHEL8][Network][cloud-init] Can not acquire IPv6 address)
|
||||
- Resolves: RHEL-17610
|
||||
([RHEL-8] NetworkManagerActivator brings up interface failed when using sysconfig renderer)
|
||||
|
||||
* Mon Jan 8 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-1
|
||||
- Rebase to 23.4.1 [RHEL-18314]
|
||||
- Resolves: RHEL-18314
|
||||
([RHEL-8]Rebase cloud-init to 23.4)
|
||||
|
||||
* Thu Nov 23 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-12
|
||||
- ci-rhel-cloud.cfg-remove-ssh_genkeytypes-in-settings.py.patch [RHEL-16572]
|
||||
- Resolves: RHEL-16572
|
||||
([cloud-init][rhel-8] Backport the patch "rhel/cloud.cfg: remove ssh_genkeytypes in settings.py and set in cloud.cfg" to fix settings.py)
|
||||
|
||||
* Mon Sep 18 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-11
|
||||
- ci-net-fix-ipv6_dhcpv6_stateful-stateless-slaac-configu.patch [bz#2046491]
|
||||
- Resolves: bz#2046491
|
||||
(cloud-init enable both DHCPv4 and DHCPv6 when network type is ipv6_dhcpv6-stateful/ipv6_dhcpv6-stateless)
|
||||
- Resolves: RHEL-2325
|
||||
([RHEL8.9][cloud-init] Not inform user during upgrade that cloud-init generated config files are left )
|
||||
|
||||
* Fri Aug 25 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-10
|
||||
- Resolves: bz#2233047
|
||||
([RHEL 8.9] Inform user when cloud-init generated config files are left during uninstalling)
|
||||
|
||||
* Wed Aug 09 2023 Jon Maloy <jmaloy@redhat.com> - 23.1.1-9
|
||||
- ci-NM-renderer-set-default-IPv6-addr-gen-mode-for-all-i.patch [bz#2229460]
|
||||
- Resolves: bz#2229460
|
||||
([rhel-8.9] [RFE] Configure "ipv6.addr-gen-mode=eui64' as default in NetworkManager)
|
||||
|
||||
* Thu Jul 27 2023 Camilla Conte <cconte@redhat.com> - 23.1.1-8
|
||||
- ci-DS-VMware-modify-a-few-log-level-4284.patch [bz#2223810]
|
||||
- Resolves: bz#2223810
|
||||
([cloud-init] [RHEL8.9]There are warning logs if dev has more than one IPV6 address on ESXi)
|
||||
|
||||
* Tue Jul 25 2023 Miroslav Rezanina <mrezanin@redhat.com> - 23.1.1-7
|
||||
- ci-logging-keep-current-file-mode-of-log-file-if-its-st.patch [bz#2222501]
|
||||
- Resolves: bz#2222501
|
||||
(Don't change log permissions if they are already more restrictive [rhel-8])
|
||||
|
||||
* Mon Jul 10 2023 Miroslav Rezanina <mrezanin@redhat.com> - 23.1.1-6
|
||||
- ci-Revert-Manual-revert-Use-Network-Manager-and-Netplan.patch [bz#2219528]
|
||||
- ci-Revert-Revert-Add-native-NetworkManager-support-1224.patch [bz#2219528]
|
||||
- ci-nm-generate-ipv6-stateful-dhcp-config-at-par-with-sy.patch [bz#2219528]
|
||||
- ci-network_manager-add-a-method-for-ipv6-static-IP-conf.patch [bz#2219528]
|
||||
- ci-net-sysconfig-enable-sysconfig-renderer-if-network-m.patch [bz#2219528]
|
||||
- ci-network-manager-Set-higher-autoconnect-priority-for-.patch [bz#2219528]
|
||||
- ci-Set-default-renderer-as-sysconfig-for-centos-rhel-41.patch [bz#2219528]
|
||||
- Resolves: bz#2219528
|
||||
([RHEL8] Support configuring network by NM keyfiles)
|
||||
|
||||
* Thu Jun 29 2023 Jon Maloy <jmaloy@redhat.com> - 23.1.1-4
|
||||
- ci-Add-warning-during-upgrade-from-an-old-version-with-.patch [bz#2210012]
|
||||
- Resolves: bz#2210012
|
||||
([cloud-init] System didn't generate ssh host keys and lost ssh connection after cloud-init removed them with updated cloud-init package.)
|
||||
|
||||
* Wed May 03 2023 Jon Maloy <jmaloy@redhat.com> - 23.1.1-3
|
||||
- ci-Don-t-change-permissions-of-netrules-target-2076.patch [bz#2182947]
|
||||
- ci-Make-user-vendor-data-sensitive-and-remove-log-permi.patch [bz#2190081]
|
||||
- Resolves: bz#2182947
|
||||
(Request to backport "Don't change permissions of netrules target (#2076)")
|
||||
- Resolves: bz#2190081
|
||||
(CVE-2023-1786 cloud-init: sensitive data could be exposed in logs [rhel-8])
|
||||
|
||||
* Tue Apr 25 2023 Jon Maloy <jmaloy@redhat.com> - 23.1.1-2
|
||||
- ci-rhel-make-sure-previous-hostname-file-ends-with-a-ne.patch [bz#2182407]
|
||||
- Resolves: bz#2182407
|
||||
(cloud-init strips new line from "/etc/hostname" when processing "/var/lib/cloud/data/previous-hostname")
|
||||
|
||||
* Fri Apr 21 2023 Jon Maloy <jmaloy@redhat.com> - 23.1.1-1
|
||||
- limit-permissions-on-def_log_file.patch
|
||||
- Resolves bz#1424612
|
||||
- include-NOZEROCONF-yes-in-etc-sysconfig-network.patch
|
||||
- Resolves bz#1653131
|
||||
- Rebase to 23.1.1 [bz#2172821]
|
||||
- Resolves: bz#2172821
|
||||
|
||||
* Mon Jan 30 2023 Camilla Conte <cconte@redhat.com> - 22.1-8
|
||||
- ci-cc_set_hostname-ignore-var-lib-cloud-data-set-hostna.patch [bz#2162258]
|
||||
- Resolves: bz#2162258
|
||||
(systemd[1]: Failed to start Initial cloud-init job after reboot system via sysrq 'b' [RHEL-8])
|
||||
|
||||
* Wed Dec 28 2022 Camilla Conte <cconte@redhat.com> - 22.1-7
|
||||
- ci-Ensure-network-ready-before-cloud-init-service-runs-.patch [bz#2151861]
|
||||
- Resolves: bz#2151861
|
||||
([RHEL-8] Ensure network ready before cloud-init service runs on RHEL)
|
||||
|
||||
* Mon Oct 17 2022 Jon Maloy <jmaloy@redhat.com> - 22.1-6
|
||||
- ci-cloud.cfg.tmpl-make-sure-centos-settings-are-identic.patch [bz#2115576]
|
||||
- Resolves: bz#2115576
|
||||
(cloud-init configures user "centos" or "rhel" instead of "cloud-user" with cloud-init-22.1)
|
||||
|
||||
* Wed Aug 17 2022 Jon Maloy <jmaloy@redhat.com> - 22.1-5
|
||||
- ci-Revert-Add-native-NetworkManager-support-1224.patch [bz#2107464 bz#2110066 bz#2117526 bz#2104393 bz#2098624]
|
||||
- ci-Revert-Use-Network-Manager-and-Netplan-as-default-re.patch [bz#2107464 bz#2110066 bz#2117526 bz#2104393 bz#2098624]
|
||||
- Resolves: bz#2107464
|
||||
([RHEL-8.7] Cannot run sysconfig when changing the priority of network renderers)
|
||||
- Resolves: bz#2110066
|
||||
(DNS integration with OpenStack/cloud-init/NetworkManager is not working)
|
||||
- Resolves: bz#2117526
|
||||
([RHEL8.7] Revert patch of configuring networking by NM keyfiles)
|
||||
- Resolves: bz#2104393
|
||||
([RHEL-8.7]Failed to config static IP and IPv6 according to VMware Customization Config File)
|
||||
- Resolves: bz#2098624
|
||||
([RHEL-8.7] IPv6 not workable when cloud-init configure network using NM keyfiles)
|
||||
|
||||
* Tue Jul 12 2022 Miroslav Rezanina <mrezanin@redhat.com> - 22.1-4
|
||||
- ci-cloud-init.spec-adjust-path-for-66-azure-ephemeral.r.patch [bz#2096269]
|
||||
- ci-setup.py-adjust-udev-rules-default-path-1513.patch [bz#2096269]
|
||||
- Resolves: bz#2096269
|
||||
(Adjust udev/rules default path[RHEL-8])
|
||||
|
||||
* Thu Jun 23 2022 Jon Maloy <jmaloy@redhat.com> - 22.1-3
|
||||
- ci-Support-EC2-tags-in-instance-metadata-1309.patch [bz#2082686]
|
||||
- Resolves: bz#2082686
|
||||
([cloud][init] Add support for reading tags from instance metadata)
|
||||
|
||||
* Tue May 31 2022 Jon Maloy <jmaloy@redhat.com> - 22.1-2
|
||||
- ci-Add-native-NetworkManager-support-1224.patch [bz#2059872]
|
||||
- ci-Use-Network-Manager-and-Netplan-as-default-renderers.patch [bz#2059872]
|
||||
- ci-Align-rhel-custom-files-with-upstream-1431.patch [bz#2082071]
|
||||
- ci-Remove-rhel-specific-files.patch [bz#2082071]
|
||||
- Resolves: bz#2059872
|
||||
([RHEL-8]Rebase cloud-init from Fedora so it can configure networking using NM keyfiles)
|
||||
- Resolves: bz#2082071
|
||||
(Align cloud.cfg file and systemd with cloud-init upstream .tmpl files)
|
||||
|
||||
* Mon Apr 25 2022 Amy Chen <xiachen@redhat.com> - 22.1-1
|
||||
- Rebaes to 22.1 [bz#2065544]
|
||||
- Resolves: bz#2065544
|
||||
([RHEL-8.7.0] cloud-init rebase to 22.1)
|
||||
|
||||
* Fri Apr 01 2022 Camilla Conte <cconte@redhat.com> - 21.1-15
|
||||
- ci-Detect-a-Python-version-change-and-clear-the-cache-8.patch [bz#1935826]
|
||||
- ci-Fix-MIME-policy-failure-on-python-version-upgrade-93.patch [bz#1935826]
|
||||
- Resolves: bz#1935826
|
||||
([rhel-8] Cloud-init init stage fails after upgrade from RHEL7 to RHEL8.)
|
||||
|
||||
* Fri Feb 25 2022 Jon Maloy <jmaloy@redhat.com> - 21.1-14
|
||||
- ci-Fix-IPv6-netmask-format-for-sysconfig-1215.patch [bz#2046540]
|
||||
- Resolves: bz#2046540
|
||||
(cloud-init writes route6-$DEVICE config with a HEX netmask. ip route does not like : Error: inet6 prefix is expected rather than "fd00:fd00:fd00::/ffff:ffff:ffff:ffff::".)
|
||||
|
||||
* Tue Jan 25 2022 Jon Maloy <jmaloy@redhat.com> - 21.1-13
|
||||
- ci-Add-flexibility-to-IMDS-api-version-793.patch [bz#2023940]
|
||||
- ci-Azure-helper-Ensure-Azure-http-handler-sleeps-betwee.patch [bz#2023940]
|
||||
- ci-azure-Removing-ability-to-invoke-walinuxagent-799.patch [bz#2023940]
|
||||
- ci-Azure-eject-the-provisioning-iso-before-reporting-re.patch [bz#2023940]
|
||||
- ci-Azure-Retrieve-username-and-hostname-from-IMDS-865.patch [bz#2023940]
|
||||
- ci-Azure-Retry-net-metadata-during-nic-attach-for-non-t.patch [bz#2023940]
|
||||
- ci-Azure-adding-support-for-consuming-userdata-from-IMD.patch [bz#2023940]
|
||||
- Resolves: bz#2023940
|
||||
([RHEL-8] Support for provisioning Azure VM with userdata)
|
||||
|
||||
* Wed Jan 19 2022 Jon Maloy <jmaloy@redhat.com> - 21.1-12
|
||||
- ci-Add-gdisk-and-openssl-as-deps-to-fix-UEFI-Azure-init.patch [bz#2039697]
|
||||
- ci-Datasource-for-VMware-953.patch [bz#2026587]
|
||||
- ci-Change-netifaces-dependency-to-0.10.4-965.patch [bz#2026587]
|
||||
- ci-Update-dscheck_VMware-s-rpctool-check-970.patch [bz#2026587]
|
||||
- ci-Revert-unnecesary-lcase-in-ds-identify-978.patch [bz#2026587]
|
||||
- ci-Add-netifaces-package-as-a-Requires-in-cloud-init.sp.patch [bz#2026587]
|
||||
- Resolves: bz#2039697
|
||||
([RHEL8] [Azure] cloud-init fails to configure the system)
|
||||
- Resolves: bz#2026587
|
||||
([cloud-init][RHEL8] Support for cloud-init datasource 'cloud-init-vmware-guestinfo')
|
||||
|
||||
* Wed Dec 08 2021 Jon Maloy <jmaloy@redhat.com> - 21.1-11
|
||||
- ci-cloudinit-net-handle-two-different-routes-for-the-sa.patch [bz#2028028]
|
||||
- Resolves: bz#2028028
|
||||
([RHEL-8] Above 19.2 of cloud-init fails to configure routes when configuring static and default routes to the same destination IP)
|
||||
|
||||
* Mon Dec 06 2021 Jon Maloy <jmaloy@redhat.com> - 21.1-10
|
||||
- ci-fix-error-on-upgrade-caused-by-new-vendordata2-attri.patch [bz#2021538]
|
||||
- Resolves: bz#2021538
|
||||
(cloud-init.service fails to start after package update)
|
||||
|
||||
* Mon Oct 25 2021 Jon Maloy <jmaloy@redhat.com> - 21.1-9
|
||||
- ci-cc_ssh.py-fix-private-key-group-owner-and-permission.patch [bz#2013644]
|
||||
- Resolves: bz#2013644
|
||||
(cloud-init fails to set host key permissions correctly)
|
||||
|
||||
* Thu Sep 23 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-8
|
||||
- ci-ssh_utils.py-ignore-when-sshd_config-options-are-not.patch [bz#1862933]
|
||||
- Resolves: bz#1862933
|
||||
(cloud-init fails with ValueError: need more than 1 value to unpack[rhel-8])
|
||||
|
||||
* Fri Aug 27 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-7
|
||||
- ci-Fix-home-permissions-modified-by-ssh-module-SC-338-9.patch [bz#1995840]
|
||||
- Resolves: bz#1995840
|
||||
([cloudinit] Fix home permissions modified by ssh module)
|
||||
|
||||
* Wed Aug 11 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-6
|
||||
- ci-Stop-copying-ssh-system-keys-and-check-folder-permis.patch [bz#1862967]
|
||||
- Resolves: bz#1862967
|
||||
([cloud-init]Customize ssh AuthorizedKeysFile causes login failure)
|
||||
|
||||
* Fri Aug 06 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-5
|
||||
- ci-Add-dhcp-client-as-a-dependency.patch [bz#1977385]
|
||||
- Resolves: bz#1977385
|
||||
([Azure][RHEL-8] cloud-init must require dhcp-client on Azure)
|
||||
|
||||
* Mon Jul 19 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-4
|
||||
- ci-ssh-util-allow-cloudinit-to-merge-all-ssh-keys-into-.patch [bz#1862967]
|
||||
- Resolves: bz#1862967
|
||||
([cloud-init]Customize ssh AuthorizedKeysFile causes login failure)
|
||||
|
||||
* Mon Jul 12 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-3
|
||||
- ci-write-passwords-only-to-serial-console-lock-down-clo.patch [bz#1945891]
|
||||
- Resolves: bz#1945891
|
||||
(CVE-2021-3429 cloud-init: randomly generated passwords logged in clear-text to world-readable file [rhel-8])
|
||||
|
||||
* Fri Jun 11 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-2
|
||||
- ci-rhel-cloud.cfg-remove-ssh_genkeytypes-in-settings.py.patch [bz#1957532]
|
||||
- ci-cloud-init.spec.template-update-systemd_postun-param.patch [bz#1952089]
|
||||
- Resolves: bz#1957532
|
||||
([cloud-init] From RHEL 82+ cloud-init no longer displays sshd keys fingerprints from instance launched from a backup image)
|
||||
- Resolves: bz#1952089
|
||||
(cloud-init brew build fails on Fedora 33)
|
||||
|
||||
* Thu May 27 2021 Miroslav Rezanina <mrezanin@redhat.com> - 21.1-1.el8
|
||||
- Rebaes to 21.1 [bz#1958174]
|
||||
- Resolves: bz#1958174
|
||||
([RHEL-8.5.0] Rebase cloud-init to 21.1)
|
||||
|
||||
* Thu May 13 2021 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-10.el8_4.3
|
||||
- ci-get_interfaces-don-t-exclude-Open-vSwitch-bridge-bon.patch [bz#1957135]
|
||||
- ci-net-exclude-OVS-internal-interfaces-in-get_interface.patch [bz#1957135]
|
||||
- Resolves: bz#1957135
|
||||
(Intermittent failure to start cloud-init due to failure to detect macs [rhel-8.4.0.z])
|
||||
|
||||
* Tue Apr 06 2021 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-10.el8_4.1
|
||||
- ci-Fix-requiring-device-number-on-EC2-derivatives-836.patch [bz#1942699]
|
||||
- Resolves: bz#1942699
|
||||
([Aliyun][RHEL8.4][cloud-init] cloud-init service failed to start with Alibaba instance [rhel-8.4.0.z])
|
||||
|
||||
* Tue Feb 02 2021 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-10.el8
|
||||
- ci-fix-a-typo-in-man-page-cloud-init.1-752.patch [bz#1913127]
|
||||
- Resolves: bz#1913127
|
||||
(A typo in cloud-init man page)
|
||||
|
||||
* Tue Jan 26 2021 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-9.el8
|
||||
- ci-DataSourceAzure-update-password-for-defuser-if-exist.patch [bz#1900892]
|
||||
- ci-Revert-ssh_util-handle-non-default-AuthorizedKeysFil.patch [bz#1919972]
|
||||
- Resolves: bz#1900892
|
||||
([Azure] Update existing user password RHEL8x)
|
||||
- Resolves: bz#1919972
|
||||
([RHEL-8.4] ssh keys can be shared across users giving potential root access)
|
||||
|
||||
* Thu Jan 21 2021 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-8.el8
|
||||
- ci-Missing-IPV6_AUTOCONF-no-to-render-sysconfig-dhcp6-s.patch [bz#1859695]
|
||||
- Resolves: bz#1859695
|
||||
([Cloud-init] DHCPv6 assigned address is not added to VM's interface)
|
||||
|
||||
* Tue Jan 05 2021 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-7.el8
|
||||
- ci-Report-full-specific-version-with-cloud-init-version.patch [bz#1898949]
|
||||
- Resolves: bz#1898949
|
||||
(cloud-init should report full specific full version with "cloud-init --version")
|
||||
|
||||
* Mon Dec 14 2020 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-6.el8
|
||||
- ci-Installing-man-pages-in-the-correct-place-with-corre.patch [bz#1612573]
|
||||
- ci-Adding-BOOTPROTO-dhcp-to-render-sysconfig-dhcp6-stat.patch [bz#1859695]
|
||||
- ci-Fix-unit-failure-of-cloud-final.service-if-NetworkMa.patch [bz#1898943]
|
||||
- ci-ssh_util-handle-non-default-AuthorizedKeysFile-confi.patch [bz#1862967]
|
||||
- Resolves: bz#1612573
|
||||
(Man page scan results for cloud-init)
|
||||
- Resolves: bz#1859695
|
||||
([Cloud-init] DHCPv6 assigned address is not added to VM's interface)
|
||||
- Resolves: bz#1898943
|
||||
([rhel-8]cloud-final.service fails if NetworkManager not installed.)
|
||||
- Resolves: bz#1862967
|
||||
([cloud-init]Customize ssh AuthorizedKeysFile causes login failure)
|
||||
|
||||
* Fri Nov 27 2020 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-5.el8
|
||||
- ci-network-Fix-type-and-respect-name-when-rendering-vla.patch [bz#1881462]
|
||||
- Resolves: bz#1881462
|
||||
([rhel8][cloud-init] ifup bond0.504 Error: Connection activation failed: No suitable device found for this connection)
|
||||
|
||||
* Tue Nov 24 2020 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-4.el8
|
||||
- ci-Changing-permission-of-cloud-init-generator-to-755.patch [bz#1897528]
|
||||
- Resolves: bz#1897528
|
||||
(Change permission on ./systemd/cloud-init-generator.tmpl to 755 instead of 771)
|
||||
|
||||
* Fri Nov 13 2020 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-3.el8
|
||||
- ci--Removing-net-tools-dependency.patch [bz#1881871]
|
||||
- ci--Adding-man-pages-to-Red-Hat-spec-file.patch [bz#1612573]
|
||||
- Resolves: bz#1881871
|
||||
(Remove net-tools legacy dependency from spec file)
|
||||
- Resolves: bz#1612573
|
||||
(Man page scan results for cloud-init)
|
||||
|
||||
* Tue Nov 03 2020 Miroslav Rezanina <mrezanin@redhat.com> - 20.3-2.el8
|
||||
- ci-Explicit-set-IPV6_AUTOCONF-and-IPV6_FORCE_ACCEPT_RA-.patch [bz#1889635]
|
||||
- ci-Add-config-modules-for-controlling-IBM-PowerVM-RMC.-.patch [bz#1886430]
|
||||
- Resolves: bz#1886430
|
||||
(Support for cloud-init config modules for PowerVM Hypervisor in Red Hat cloud-init)
|
||||
- Resolves: bz#1889635
|
||||
(Add support for ipv6_autoconf on cloud-init-20.3)
|
||||
|
||||
* Fri Oct 23 2020 Eduardo Otubo <otubo@redhat.com> - 20.3-1.el8
|
||||
- Rebase to cloud-init 20.3 [bz#1885185]
|
||||
- Resolves: bz#1885185
|
||||
([RHEL-8.4.0] cloud-init rebase to 20.3)
|
||||
|
||||
* Wed Sep 02 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-11.el8
|
||||
- ci-cc_mounts-fix-incorrect-format-specifiers-316.patch [bz#1794664]
|
||||
- Resolves: bz#1794664
|
||||
([RHEL8] swapon fails with "swapfile has holes" when created on a xfs filesystem by cloud-init)
|
||||
|
||||
* Mon Aug 31 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-10.el8
|
||||
- ci-Changing-notation-of-subp-call.patch [bz#1839662]
|
||||
- Resolves: bz#1839662
|
||||
([ESXi][RHEL8.3][cloud-init]ERROR log in cloud-init.log after clone VM on ESXi platform)
|
||||
|
||||
* Mon Aug 24 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-9.el8
|
||||
- ci-Do-not-use-fallocate-in-swap-file-creation-on-xfs.-7.patch [bz#1794664]
|
||||
- ci-swap-file-size-being-used-before-checked-if-str-315.patch [bz#1794664]
|
||||
- ci-Detect-kernel-version-before-swap-file-creation-428.patch [bz#1794664]
|
||||
- Resolves: bz#1794664
|
||||
([RHEL8] swapon fails with "swapfile has holes" when created on a xfs filesystem by cloud-init)
|
||||
|
||||
* Mon Aug 17 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-8.el8
|
||||
- ci-When-tools.conf-does-not-exist-running-cmd-vmware-to.patch [bz#1839662]
|
||||
- ci-ssh-exit-with-non-zero-status-on-disabled-user-472.patch [bz#1833874]
|
||||
- Resolves: bz#1833874
|
||||
([rhel-8.3]using root user error should cause a non-zero exit code)
|
||||
- Resolves: bz#1839662
|
||||
([ESXi][RHEL8.3][cloud-init]ERROR log in cloud-init.log after clone VM on ESXi platform)
|
||||
|
||||
* Fri Jun 26 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-7.el8
|
||||
- Fixing cloud-init-generator permissions [bz#1834173]
|
||||
- Resolves: bz#1834173
|
||||
([rhel-8.3]Incorrect ds-identify check in cloud-init-generator)
|
||||
|
||||
* Thu Jun 25 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-6.el8
|
||||
- ci-ec2-only-redact-token-request-headers-in-logs-avoid-.patch [bz#1822343]
|
||||
- Resolves: bz#1822343
|
||||
([RHEL8.3] Do not log IMDSv2 token values into cloud-init.log)
|
||||
|
||||
* Wed Jun 24 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-5.el8
|
||||
- ci-ec2-Do-not-log-IMDSv2-token-values-instead-use-REDAC.patch [bz#1822343]
|
||||
- ci-Render-the-generator-from-template-instead-of-cp.patch [bz#1834173]
|
||||
- ci-Change-from-redhat-to-rhel-in-systemd-generator-tmpl.patch [bz#1834173]
|
||||
- ci-cloud-init.service.tmpl-use-rhel-instead-of-redhat-4.patch [bz#1834173]
|
||||
- Resolves: bz#1822343
|
||||
([RHEL8.3] Do not log IMDSv2 token values into cloud-init.log)
|
||||
- Resolves: bz#1834173
|
||||
([rhel-8.3]Incorrect ds-identify check in cloud-init-generator)
|
||||
|
||||
* Tue Jun 09 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-4.el8
|
||||
- ci-changing-ds-identify-patch-from-usr-lib-to-usr-libex.patch [bz#1834173]
|
||||
- Resolves: bz#1834173
|
||||
([rhel-8.3]Incorrect ds-identify check in cloud-init-generator)
|
||||
|
||||
* Mon Jun 01 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-3.el8
|
||||
- ci-Make-cloud-init.service-execute-after-network-is-up.patch [bz#1803928]
|
||||
- Resolves: bz#1803928
|
||||
([RHEL8.3] Race condition of starting cloud-init and NetworkManager)
|
||||
|
||||
* Thu May 28 2020 Miroslav Rezanina <mrezanin@redhat.com> - 19.4-2.el8
|
||||
- ci-cc_set_password-increase-random-pwlength-from-9-to-2.patch [bz#1812171]
|
||||
- ci-utils-use-SystemRandom-when-generating-random-passwo.patch [bz#1812174]
|
||||
- ci-Enable-ssh_deletekeys-by-default.patch [bz#1814152]
|
||||
- ci-Remove-race-condition-between-cloud-init-and-Network.patch [bz#1840648]
|
||||
- Resolves: bz#1812171
|
||||
(CVE-2020-8632 cloud-init: Too short random password length in cc_set_password in config/cc_set_passwords.py [rhel-8])
|
||||
- Resolves: bz#1812174
|
||||
(CVE-2020-8631 cloud-init: Use of random.choice when generating random password [rhel-8])
|
||||
- Resolves: bz#1814152
|
||||
(CVE-2018-10896 cloud-init: default configuration disabled deletion of SSH host keys [rhel-8])
|
||||
- Resolves: bz#1840648
|
||||
([cloud-init][RHEL-8.2.0] /etc/resolv.conf lose config after reboot (initial instance is ok))
|
||||
|
||||
* Mon Apr 20 2020 Miroslav Rezanina <mrezanin@redhat.coM> - 19.4-1.el8.1
|
||||
- Rebase to cloud-init 19.4 [bz#1811912]
|
||||
- Resolves: bz#1811912
|
||||
([RHEL-8.2.1] cloud-init rebase to 19.4)
|
||||
|
||||
* Tue Mar 10 2020 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-12.el8
|
||||
- ci-Remove-race-condition-between-cloud-init-and-Network.patch [bz#1807797]
|
||||
- Resolves: bz#1807797
|
||||
([cloud-init][RHEL-8.2.0] /etc/resolv.conf lose config after reboot (initial instance is ok))
|
||||
|
||||
* Thu Feb 20 2020 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-11.el8
|
||||
- ci-azure-avoid-re-running-cloud-init-when-instance-id-i.patch [bz#1788684]
|
||||
- ci-net-skip-bond-interfaces-in-get_interfaces.patch [bz#1768770]
|
||||
- ci-net-add-is_master-check-for-filtering-device-list.patch [bz#1768770]
|
||||
- Resolves: bz#1768770
|
||||
(cloud-init complaining about enslaved mac)
|
||||
- Resolves: bz#1788684
|
||||
([RHEL-8] cloud-init Azure byte swap (hyperV Gen2 Only))
|
||||
|
||||
* Thu Feb 13 2020 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-10.el8
|
||||
- ci-cmd-main.py-Fix-missing-modules-init-key-in-modes-di.patch [bz#1802140]
|
||||
- Resolves: bz#1802140
|
||||
([cloud-init][RHEL8.2]cloud-init cloud-final.service fail with KeyError: 'modules-init' after upgrade to version 18.2-1.el7_6.1 in RHV)
|
||||
|
||||
* Tue Jan 28 2020 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-9.el8
|
||||
- ci-Removing-cloud-user-from-wheel.patch [bz#1785648]
|
||||
- Resolves: bz#1785648
|
||||
([RHEL8]cloud-user added to wheel group and sudoers.d causes 'sudo -v' prompts for passphrase)
|
||||
|
||||
* Fri Nov 22 2019 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-8.el8
|
||||
- ci-Fix-for-network-configuration-not-persisting-after-r.patch [bz#1706482]
|
||||
- ci-util-json.dumps-on-python-2.7-will-handle-UnicodeDec.patch [bz#1744718]
|
||||
- Resolves: bz#1706482
|
||||
([cloud-init][RHVM]cloud-init network configuration does not persist reboot [RHEL 8.2.0])
|
||||
- Resolves: bz#1744718
|
||||
([cloud-init][RHEL8][OpenStack] cloud-init can't persist instance-data.json)
|
||||
|
||||
* Mon Jul 15 2019 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-7.el8
|
||||
- Fixing TPS [bz#1729864]
|
||||
- Resolves: bz#1729864
|
||||
(cloud-init tps fail)
|
||||
|
||||
* Thu Jul 04 2019 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-6.el8
|
||||
- ci-Revert-azure-ensure-that-networkmanager-hook-script-.patch [bz#1692914]
|
||||
- ci-Azure-Return-static-fallback-address-as-if-failed-to.patch [bz#1691986]
|
||||
- Resolves: bz#1691986
|
||||
([Azure] [RHEL 8.1] Cloud-init fixes to support fast provisioning for Azure)
|
||||
- Resolves: bz#1692914
|
||||
([8.1] [WALA][cloud] cloud-init dhclient-hook script has some unexpected side-effects on Azure)
|
||||
|
||||
* Mon Jun 03 2019 Miroslav Rezanina <mrezanin@redhat.com> - 18.5-4.el8
|
||||
- ci-Azure-Ensure-platform-random_seed-is-always-serializ.patch [bz#1691986]
|
||||
- ci-DatasourceAzure-add-additional-logging-for-azure-dat.patch [bz#1691986]
|
||||
|
@ -223,6 +727,7 @@ fi
|
|||
- Resolves: rhbz#1682786
|
||||
(cloud-init changes blocked until gating tests are added)
|
||||
|
||||
|
||||
* Wed Apr 10 2019 Danilo de Paula <ddepaula@redhat.com: - 18.5-1.el8
|
||||
- Rebase to cloud-init 18.5
|
||||
- Resolves: bz#1687563
|
||||
|
|
Loading…
Reference in New Issue