Compare commits
No commits in common. 'c9' and 'i9-beta' have entirely different histories.
@ -1 +1 @@
|
|||||||
e73116733f5636eb4bc1a5e47e802c3635b9bfa2 SOURCES/23.4.tar.gz
|
0b491818abcdce5ba6c1b30c75dd680d6ee3983e SOURCES/23.1.1.tar.gz
|
||||||
|
@ -1 +1 @@
|
|||||||
SOURCES/23.4.tar.gz
|
SOURCES/23.1.1.tar.gz
|
||||||
|
@ -0,0 +1,685 @@
|
|||||||
|
From 4849336bdd183b8e712b0d44b0be3745561dc907 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sergey Cherevko <s.cherevko@msvsphere-os.ru>
|
||||||
|
Date: Fri, 6 Oct 2023 16:54:42 +0300
|
||||||
|
Subject: [PATCH] Add MSVSphere support
|
||||||
|
|
||||||
|
---
|
||||||
|
README.md | 2 +-
|
||||||
|
cloudinit/config/cc_ca_certs.py | 8 ++++
|
||||||
|
cloudinit/config/cc_ntp.py | 9 ++++
|
||||||
|
cloudinit/config/cc_yum_add_repo.py | 1 +
|
||||||
|
cloudinit/distros/__init__.py | 1 +
|
||||||
|
cloudinit/distros/msvsphere.py | 10 ++++
|
||||||
|
cloudinit/net/sysconfig.py | 1 +
|
||||||
|
cloudinit/settings.py | 2 +-
|
||||||
|
cloudinit/sources/DataSourceRbxCloud.py | 2 +-
|
||||||
|
cloudinit/util.py | 1 +
|
||||||
|
config/cloud.cfg.tmpl | 2 +-
|
||||||
|
doc/rtd/reference/availability.rst | 2 +-
|
||||||
|
doc/rtd/reference/network-config.rst | 4 +-
|
||||||
|
packages/pkg-deps.json | 14 ++++++
|
||||||
|
systemd/cloud-config.service.tmpl | 2 +-
|
||||||
|
systemd/cloud-final.service.tmpl | 4 +-
|
||||||
|
systemd/cloud-init-generator.tmpl | 2 +-
|
||||||
|
systemd/cloud-init-local.service.tmpl | 12 ++---
|
||||||
|
systemd/cloud-init.service.tmpl | 6 +--
|
||||||
|
templates/chrony.conf.msvsphere.tmpl | 45 ++++++++++++++++++
|
||||||
|
templates/ntp.conf.msvsphere.tmpl | 61 +++++++++++++++++++++++++
|
||||||
|
tests/unittests/test_net.py | 1 +
|
||||||
|
tests/unittests/test_render_cloudcfg.py | 1 +
|
||||||
|
tests/unittests/test_util.py | 44 ++++++++++++++++++
|
||||||
|
tools/read-dependencies | 5 +-
|
||||||
|
tools/render-cloudcfg | 1 +
|
||||||
|
tools/run-container | 4 +-
|
||||||
|
27 files changed, 224 insertions(+), 23 deletions(-)
|
||||||
|
create mode 100644 cloudinit/distros/msvsphere.py
|
||||||
|
create mode 100644 templates/chrony.conf.msvsphere.tmpl
|
||||||
|
create mode 100644 templates/ntp.conf.msvsphere.tmpl
|
||||||
|
|
||||||
|
diff --git a/README.md b/README.md
|
||||||
|
index 45a5bd9..fff93c9 100644
|
||||||
|
--- a/README.md
|
||||||
|
+++ b/README.md
|
||||||
|
@@ -39,7 +39,7 @@ get in contact with that distribution and send them our way!
|
||||||
|
|
||||||
|
| Supported OSes | Supported Public Clouds | Supported Private Clouds |
|
||||||
|
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- | --- |
|
||||||
|
-| Alpine Linux<br />Arch Linux<br />Container-Optimized OS<br />Debian<br />DragonFlyBSD<br />Fedora<br />FreeBSD<br />Gentoo Linux<br />NetBSD<br />OpenBSD<br />openEuler<br />OpenCloudOS<br />OpenMandriva<br />RHEL/CentOS/AlmaLinux/Rocky/PhotonOS/Virtuozzo/EuroLinux/CloudLinux/MIRACLE LINUX/MarinerOS<br />SLES/openSUSE<br />TencentOS<br />Ubuntu<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | Amazon Web Services<br />Microsoft Azure<br />Google Cloud Platform<br />Oracle Cloud Infrastructure<br />Softlayer<br />Rackspace Public Cloud<br />IBM Cloud<br />DigitalOcean<br />Bigstep<br />Hetzner<br />Joyent<br />CloudSigma<br />Alibaba Cloud<br />Huawei Cloud<br />OVH<br />OpenNebula<br />Exoscale<br />Scaleway<br />CloudStack<br />AltCloud<br />SmartOS<br />HyperOne<br />Vultr<br />Rootbox<br /> | Bare metal installs<br />OpenStack<br />LXD<br />KVM<br />Metal-as-a-Service (MAAS)<br />VMware<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />|
|
||||||
|
+| Alpine Linux<br />Arch Linux<br />Container-Optimized OS<br />Debian<br />DragonFlyBSD<br />Fedora<br />FreeBSD<br />Gentoo Linux<br />NetBSD<br />OpenBSD<br />openEuler<br />OpenCloudOS<br />OpenMandriva<br />RHEL/CentOS/AlmaLinux/Rocky/PhotonOS/Virtuozzo/EuroLinux/CloudLinux/MIRACLE LINUX/MarinerOS/MSVSphere<br />SLES/openSUSE<br />TencentOS<br />Ubuntu<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | Amazon Web Services<br />Microsoft Azure<br />Google Cloud Platform<br />Oracle Cloud Infrastructure<br />Softlayer<br />Rackspace Public Cloud<br />IBM Cloud<br />DigitalOcean<br />Bigstep<br />Hetzner<br />Joyent<br />CloudSigma<br />Alibaba Cloud<br />Huawei Cloud<br />OVH<br />OpenNebula<br />Exoscale<br />Scaleway<br />CloudStack<br />AltCloud<br />SmartOS<br />HyperOne<br />Vultr<br />Rootbox<br /> | Bare metal installs<br />OpenStack<br />LXD<br />KVM<br />Metal-as-a-Service (MAAS)<br />VMware<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />|
|
||||||
|
|
||||||
|
## To start developing cloud-init
|
||||||
|
|
||||||
|
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
|
||||||
|
index 4dc0868..e6e9a56 100644
|
||||||
|
--- a/cloudinit/config/cc_ca_certs.py
|
||||||
|
+++ b/cloudinit/config/cc_ca_certs.py
|
||||||
|
@@ -32,6 +32,13 @@ DISTRO_OVERRIDES = {
|
||||||
|
"ca_cert_config": None,
|
||||||
|
"ca_cert_update_cmd": ["update-ca-trust"],
|
||||||
|
},
|
||||||
|
+ "msvsphere": {
|
||||||
|
+ "ca_cert_path": "/usr/share/pki/ca-trust-source/",
|
||||||
|
+ "ca_cert_filename": "anchors/cloud-init-ca-certs.crt",
|
||||||
|
+ "ca_cert_config": None,
|
||||||
|
+ "ca_cert_system_path": "/etc/pki/ca-trust/",
|
||||||
|
+ "ca_cert_update_cmd": ["update-ca-trust"],
|
||||||
|
+ },
|
||||||
|
"opensuse": {
|
||||||
|
"ca_cert_path": "/etc/pki/trust/",
|
||||||
|
"ca_cert_local_path": "/usr/share/pki/trust/",
|
||||||
|
@@ -68,6 +75,7 @@ configuration option ``remove_defaults``.
|
||||||
|
distros = [
|
||||||
|
"alpine",
|
||||||
|
"debian",
|
||||||
|
+ "msvsphere",
|
||||||
|
"rhel",
|
||||||
|
"opensuse",
|
||||||
|
"opensuse-microos",
|
||||||
|
diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py
|
||||||
|
index b5620f3..e5e685c 100644
|
||||||
|
--- a/cloudinit/config/cc_ntp.py
|
||||||
|
+++ b/cloudinit/config/cc_ntp.py
|
||||||
|
@@ -35,6 +35,7 @@ distros = [
|
||||||
|
"freebsd",
|
||||||
|
"mariner",
|
||||||
|
"miraclelinux",
|
||||||
|
+ "msvsphere",
|
||||||
|
"openbsd",
|
||||||
|
"openEuler",
|
||||||
|
"OpenCloudOS",
|
||||||
|
@@ -173,6 +174,14 @@ DISTRO_CLIENT_CONFIG = {
|
||||||
|
"check_exe": "/lib/systemd/systemd-timesyncd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
+ "msvsphere": {
|
||||||
|
+ "chrony": {
|
||||||
|
+ "service_name": "chronyd",
|
||||||
|
+ },
|
||||||
|
+ "ntp": {
|
||||||
|
+ "service_name": "ntpd",
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
"opensuse": {
|
||||||
|
"chrony": {
|
||||||
|
"service_name": "chronyd",
|
||||||
|
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
|
||||||
|
index 3087b22..12e678b 100644
|
||||||
|
--- a/cloudinit/config/cc_yum_add_repo.py
|
||||||
|
+++ b/cloudinit/config/cc_yum_add_repo.py
|
||||||
|
@@ -31,6 +31,7 @@ distros = [
|
||||||
|
"cloudlinux",
|
||||||
|
"eurolinux",
|
||||||
|
"fedora",
|
||||||
|
+ "msvsphere",
|
||||||
|
"mariner",
|
||||||
|
"openEuler",
|
||||||
|
"OpenCloudOS",
|
||||||
|
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
|
||||||
|
index 12fae0a..30c5845 100644
|
||||||
|
--- a/cloudinit/distros/__init__.py
|
||||||
|
+++ b/cloudinit/distros/__init__.py
|
||||||
|
@@ -57,6 +57,7 @@ OSFAMILIES = {
|
||||||
|
"fedora",
|
||||||
|
"mariner",
|
||||||
|
"miraclelinux",
|
||||||
|
+ "msvsphere",
|
||||||
|
"openmandriva",
|
||||||
|
"photon",
|
||||||
|
"rhel",
|
||||||
|
diff --git a/cloudinit/distros/msvsphere.py b/cloudinit/distros/msvsphere.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3dc0a34
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/cloudinit/distros/msvsphere.py
|
||||||
|
@@ -0,0 +1,10 @@
|
||||||
|
+# This file is part of cloud-init. See LICENSE file for license information.
|
||||||
|
+
|
||||||
|
+from cloudinit.distros import rhel
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class Distro(rhel.Distro):
|
||||||
|
+ pass
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+# vi: ts=4 expandtab
|
||||||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
|
index f2c7c92..9468a34 100644
|
||||||
|
--- a/cloudinit/net/sysconfig.py
|
||||||
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
|
@@ -27,6 +27,7 @@ KNOWN_DISTROS = [
|
||||||
|
"eurolinux",
|
||||||
|
"fedora",
|
||||||
|
"miraclelinux",
|
||||||
|
+ "msvsphere",
|
||||||
|
"openEuler",
|
||||||
|
"OpenCloudOS",
|
||||||
|
"openmandriva",
|
||||||
|
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||||
|
index edbb217..b6e5623 100644
|
||||||
|
--- a/cloudinit/settings.py
|
||||||
|
+++ b/cloudinit/settings.py
|
||||||
|
@@ -60,7 +60,7 @@ CFG_BUILTIN = {
|
||||||
|
"cloud_dir": "/var/lib/cloud",
|
||||||
|
"templates_dir": "/etc/cloud/templates/",
|
||||||
|
},
|
||||||
|
- "distro": "rhel",
|
||||||
|
+ "distro": "msvsphere",
|
||||||
|
"network": {"renderers": None},
|
||||||
|
},
|
||||||
|
"vendor_data": {"enabled": True, "prefix": []},
|
||||||
|
diff --git a/cloudinit/sources/DataSourceRbxCloud.py b/cloudinit/sources/DataSourceRbxCloud.py
|
||||||
|
index 6890562..e0ba46a 100644
|
||||||
|
--- a/cloudinit/sources/DataSourceRbxCloud.py
|
||||||
|
+++ b/cloudinit/sources/DataSourceRbxCloud.py
|
||||||
|
@@ -60,7 +60,7 @@ def _sub_arp(cmd):
|
||||||
|
|
||||||
|
def gratuitous_arp(items, distro):
|
||||||
|
source_param = "-S"
|
||||||
|
- if distro.name in ["fedora", "centos", "rhel"]:
|
||||||
|
+ if distro.name in ["fedora", "centos", "msvsphere","rhel"]:
|
||||||
|
source_param = "-s"
|
||||||
|
for item in items:
|
||||||
|
try:
|
||||||
|
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
||||||
|
index af617e7..470c185 100644
|
||||||
|
--- a/cloudinit/util.py
|
||||||
|
+++ b/cloudinit/util.py
|
||||||
|
@@ -639,6 +639,7 @@ def _get_variant(info):
|
||||||
|
"fedora",
|
||||||
|
"mariner",
|
||||||
|
"miraclelinux",
|
||||||
|
+ "msvsphere",
|
||||||
|
"openeuler",
|
||||||
|
"opencloudos",
|
||||||
|
"openmandriva",
|
||||||
|
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
|
||||||
|
index 020340f..7cd3336 100644
|
||||||
|
--- a/config/cloud.cfg.tmpl
|
||||||
|
+++ b/config/cloud.cfg.tmpl
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
# and base configuration.
|
||||||
|
{% set is_bsd = variant in ["dragonfly", "freebsd", "netbsd", "openbsd"] %}
|
||||||
|
{% set is_rhel = variant in ["almalinux", "centos", "cloudlinux", "eurolinux",
|
||||||
|
- "miraclelinux", "rhel", "rocky", "virtuozzo" ] %}
|
||||||
|
+ "miraclelinux", "msvsphere", "rhel", "rocky", "virtuozzo" ] %}
|
||||||
|
{% if is_bsd %}
|
||||||
|
syslog_fix_perms: root:wheel
|
||||||
|
{% elif variant in ["suse"] %}
|
||||||
|
diff --git a/doc/rtd/reference/availability.rst b/doc/rtd/reference/availability.rst
|
||||||
|
index b70342a..8137508 100644
|
||||||
|
--- a/doc/rtd/reference/availability.rst
|
||||||
|
+++ b/doc/rtd/reference/availability.rst
|
||||||
|
@@ -27,7 +27,7 @@ NetBSD, OpenBSD and DragonFlyBSD:
|
||||||
|
- NetBSD
|
||||||
|
- OpenBSD
|
||||||
|
- Photon OS
|
||||||
|
-- RHEL/CentOS/AlmaLinux/Rocky Linux/EuroLinux
|
||||||
|
+- RHEL/CentOS/AlmaLinux/Rocky Linux/EuroLinux/MSVSphere
|
||||||
|
- SLES/openSUSE
|
||||||
|
- Ubuntu
|
||||||
|
|
||||||
|
diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst
|
||||||
|
index ea331f1..08dcca9 100644
|
||||||
|
--- a/doc/rtd/reference/network-config.rst
|
||||||
|
+++ b/doc/rtd/reference/network-config.rst
|
||||||
|
@@ -267,7 +267,7 @@ Example output:
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
usage: /usr/bin/cloud-init devel net-convert [-h] -p PATH -k {eni,network_data.json,yaml,azure-imds,vmware-imc} -d PATH -D
|
||||||
|
- {alpine,arch,debian,ubuntu,freebsd,dragonfly,gentoo,cos,netbsd,openbsd,almalinux,amazon,centos,cloudlinux,eurolinux,fedora,mariner,miraclelinux,openmandriva,photon,rhel,rocky,virtuozzo,opensuse,sles,openEuler}
|
||||||
|
+ {alpine,arch,debian,ubuntu,freebsd,dragonfly,gentoo,cos,netbsd,openbsd,almalinux,amazon,centos,cloudlinux,eurolinux,fedora,mariner,miraclelinux,msvsphere,openmandriva,photon,rhel,rocky,virtuozzo,opensuse,sles,openEuler}
|
||||||
|
[-m name,mac] [--debug] -O {eni,netplan,networkd,sysconfig,network-manager}
|
||||||
|
|
||||||
|
options:
|
||||||
|
@@ -278,7 +278,7 @@ Example output:
|
||||||
|
The format of the given network config
|
||||||
|
-d PATH, --directory PATH
|
||||||
|
directory to place output in
|
||||||
|
- -D {alpine,arch,debian,ubuntu,freebsd,dragonfly,gentoo,cos,netbsd,openbsd,almalinux,amazon,centos,cloudlinux,eurolinux,fedora,mariner,miraclelinux,openmandriva,photon,rhel,rocky,virtuozzo,opensuse,sles,openEuler}, --distro {alpine,arch,debian,ubuntu,freebsd,dragonfly,gentoo,cos,netbsd,openbsd,almalinux,amazon,centos,cloudlinux,eurolinux,fedora,mariner,miraclelinux,openmandriva,photon,rhel,rocky,virtuozzo,opensuse,sles,openEuler}
|
||||||
|
+ -D {alpine,arch,debian,ubuntu,freebsd,dragonfly,gentoo,cos,netbsd,openbsd,almalinux,amazon,centos,cloudlinux,eurolinux,fedora,mariner,miraclelinux,msvsphere,openmandriva,photon,rhel,rocky,virtuozzo,opensuse,sles,openEuler}, --distro {alpine,arch,debian,ubuntu,freebsd,dragonfly,gentoo,cos,netbsd,openbsd,almalinux,amazon,centos,cloudlinux,eurolinux,fedora,mariner,miraclelinux,msvsphere,openmandriva,photon,rhel,rocky,virtuozzo,opensuse,sles,openEuler}
|
||||||
|
-m name,mac, --mac name,mac
|
||||||
|
interface name to mac mapping
|
||||||
|
--debug enable debug logging to stderr.
|
||||||
|
diff --git a/packages/pkg-deps.json b/packages/pkg-deps.json
|
||||||
|
index 4ee0982..df7596c 100644
|
||||||
|
--- a/packages/pkg-deps.json
|
||||||
|
+++ b/packages/pkg-deps.json
|
||||||
|
@@ -41,6 +41,20 @@
|
||||||
|
"sudo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
+ "msvsphere" : {
|
||||||
|
+ "build-requires" : [
|
||||||
|
+ "python3-devel"
|
||||||
|
+ ],
|
||||||
|
+ "requires" : [
|
||||||
|
+ "e2fsprogs",
|
||||||
|
+ "iproute",
|
||||||
|
+ "net-tools",
|
||||||
|
+ "procps",
|
||||||
|
+ "rsyslog",
|
||||||
|
+ "shadow-utils",
|
||||||
|
+ "sudo"
|
||||||
|
+ ]
|
||||||
|
+ },
|
||||||
|
"redhat" : {
|
||||||
|
"build-requires" : [
|
||||||
|
"python3-devel"
|
||||||
|
diff --git a/systemd/cloud-config.service.tmpl b/systemd/cloud-config.service.tmpl
|
||||||
|
index d5568a6..3e416a4 100644
|
||||||
|
--- a/systemd/cloud-config.service.tmpl
|
||||||
|
+++ b/systemd/cloud-config.service.tmpl
|
||||||
|
@@ -4,7 +4,7 @@ Description=Apply the settings specified in cloud-config
|
||||||
|
After=network-online.target cloud-config.target
|
||||||
|
After=snapd.seeded.service
|
||||||
|
Wants=network-online.target cloud-config.target
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||||
|
ConditionKernelCommandLine=!cloud-init=disabled
|
||||||
|
{% endif %}
|
||||||
|
diff --git a/systemd/cloud-final.service.tmpl b/systemd/cloud-final.service.tmpl
|
||||||
|
index 85f423a..10b7e72 100644
|
||||||
|
--- a/systemd/cloud-final.service.tmpl
|
||||||
|
+++ b/systemd/cloud-final.service.tmpl
|
||||||
|
@@ -7,7 +7,7 @@ After=multi-user.target
|
||||||
|
Before=apt-daily.service
|
||||||
|
{% endif %}
|
||||||
|
Wants=network-online.target cloud-config.service
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||||
|
ConditionKernelCommandLine=!cloud-init=disabled
|
||||||
|
{% endif %}
|
||||||
|
@@ -19,7 +19,7 @@ ExecStart=/usr/bin/cloud-init modules --mode=final
|
||||||
|
RemainAfterExit=yes
|
||||||
|
TimeoutSec=0
|
||||||
|
KillMode=process
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
# Restart NetworkManager if it is present and running.
|
||||||
|
ExecStartPost=/bin/sh -c 'u=NetworkManager.service; \
|
||||||
|
out=$(systemctl show --property=SubState $u) || exit; \
|
||||||
|
diff --git a/systemd/cloud-init-generator.tmpl b/systemd/cloud-init-generator.tmpl
|
||||||
|
index d71e3b8..e9ca226 100644
|
||||||
|
--- a/systemd/cloud-init-generator.tmpl
|
||||||
|
+++ b/systemd/cloud-init-generator.tmpl
|
||||||
|
@@ -21,7 +21,7 @@ CLOUD_SYSTEM_TARGET="/usr/lib/systemd/system/cloud-init.target"
|
||||||
|
CLOUD_SYSTEM_TARGET="/lib/systemd/system/cloud-init.target"
|
||||||
|
{% endif %}
|
||||||
|
{% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora",
|
||||||
|
- "miraclelinux", "openEuler", "OpenCloudOS", "openmandriva", "rhel", "rocky", "TencentOS", "virtuozzo"] %}
|
||||||
|
+ "miraclelinux", "openEuler", "OpenCloudOS", "openmandriva", "msvsphere", "rhel", "rocky", "TencentOS", "virtuozzo"] %}
|
||||||
|
dsidentify="/usr/libexec/cloud-init/ds-identify"
|
||||||
|
{% else %}
|
||||||
|
dsidentify="/usr/lib/cloud-init/ds-identify"
|
||||||
|
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
|
||||||
|
index 6f3f9d8..b371ca4 100644
|
||||||
|
--- a/systemd/cloud-init-local.service.tmpl
|
||||||
|
+++ b/systemd/cloud-init-local.service.tmpl
|
||||||
|
@@ -1,23 +1,23 @@
|
||||||
|
## template:jinja
|
||||||
|
[Unit]
|
||||||
|
Description=Initial cloud-init job (pre-networking)
|
||||||
|
-{% if variant in ["ubuntu", "unknown", "debian", "rhel" ] %}
|
||||||
|
+{% if variant in ["ubuntu", "unknown", "debian", "msvsphere", "rhel" ] %}
|
||||||
|
DefaultDependencies=no
|
||||||
|
{% endif %}
|
||||||
|
Wants=network-pre.target
|
||||||
|
After=hv_kvp_daemon.service
|
||||||
|
After=systemd-remount-fs.service
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
Requires=dbus.socket
|
||||||
|
After=dbus.socket
|
||||||
|
{% endif %}
|
||||||
|
Before=NetworkManager.service
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
Before=network.service
|
||||||
|
{% endif %}
|
||||||
|
Before=network-pre.target
|
||||||
|
Before=shutdown.target
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
Before=firewalld.target
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
{% endif %}
|
||||||
|
@@ -26,14 +26,14 @@ Before=sysinit.target
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
{% endif %}
|
||||||
|
RequiresMountsFor=/var/lib/cloud
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||||
|
ConditionKernelCommandLine=!cloud-init=disabled
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
ExecStartPre=/bin/mkdir -p /run/cloud-init
|
||||||
|
ExecStartPre=/sbin/restorecon /run/cloud-init
|
||||||
|
ExecStartPre=/usr/bin/touch /run/cloud-init/enabled
|
||||||
|
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
|
||||||
|
index 1b1f9a8..be5c6f6 100644
|
||||||
|
--- a/systemd/cloud-init.service.tmpl
|
||||||
|
+++ b/systemd/cloud-init.service.tmpl
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
## template:jinja
|
||||||
|
[Unit]
|
||||||
|
Description=Initial cloud-init job (metadata service crawler)
|
||||||
|
-{% if variant not in ["photon", "rhel"] %}
|
||||||
|
+{% if variant not in ["photon", "msvsphere", "rhel"] %}
|
||||||
|
DefaultDependencies=no
|
||||||
|
{% endif %}
|
||||||
|
Wants=cloud-init-local.service
|
||||||
|
@@ -13,7 +13,7 @@ After=systemd-networkd-wait-online.service
|
||||||
|
After=networking.service
|
||||||
|
{% endif %}
|
||||||
|
{% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora",
|
||||||
|
- "miraclelinux", "openEuler", "OpenCloudOS", "openmandriva", "rhel", "rocky",
|
||||||
|
+ "miraclelinux", "msvsphere", "openEuler", "OpenCloudOS", "openmandriva", "rhel", "rocky",
|
||||||
|
"suse", "TencentOS", "virtuozzo"] %}
|
||||||
|
|
||||||
|
After=network.service
|
||||||
|
@@ -39,7 +39,7 @@ Before=shutdown.target
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
{% endif %}
|
||||||
|
Before=systemd-user-sessions.service
|
||||||
|
-{% if variant == "rhel" %}
|
||||||
|
+{% if variant in ["msvsphere", "rhel"] %}
|
||||||
|
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
||||||
|
ConditionKernelCommandLine=!cloud-init=disabled
|
||||||
|
{% endif %}
|
||||||
|
diff --git a/templates/chrony.conf.msvsphere.tmpl b/templates/chrony.conf.msvsphere.tmpl
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..5b3542e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/templates/chrony.conf.msvsphere.tmpl
|
||||||
|
@@ -0,0 +1,45 @@
|
||||||
|
+## template:jinja
|
||||||
|
+# Use public servers from the pool.ntp.org project.
|
||||||
|
+# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
||||||
|
+{% if pools %}# pools
|
||||||
|
+{% endif %}
|
||||||
|
+{% for pool in pools -%}
|
||||||
|
+pool {{pool}} iburst
|
||||||
|
+{% endfor %}
|
||||||
|
+{%- if servers %}# servers
|
||||||
|
+{% endif %}
|
||||||
|
+{% for server in servers -%}
|
||||||
|
+server {{server}} iburst
|
||||||
|
+{% endfor %}
|
||||||
|
+
|
||||||
|
+# Record the rate at which the system clock gains/losses time.
|
||||||
|
+driftfile /var/lib/chrony/drift
|
||||||
|
+
|
||||||
|
+# Allow the system clock to be stepped in the first three updates
|
||||||
|
+# if its offset is larger than 1 second.
|
||||||
|
+makestep 1.0 3
|
||||||
|
+
|
||||||
|
+# Enable kernel synchronization of the real-time clock (RTC).
|
||||||
|
+rtcsync
|
||||||
|
+
|
||||||
|
+# Enable hardware timestamping on all interfaces that support it.
|
||||||
|
+#hwtimestamp *
|
||||||
|
+
|
||||||
|
+# Increase the minimum number of selectable sources required to adjust
|
||||||
|
+# the system clock.
|
||||||
|
+#minsources 2
|
||||||
|
+
|
||||||
|
+# Allow NTP client access from local network.
|
||||||
|
+#allow 192.168.0.0/16
|
||||||
|
+
|
||||||
|
+# Serve time even if not synchronized to a time source.
|
||||||
|
+#local stratum 10
|
||||||
|
+
|
||||||
|
+# Specify file containing keys for NTP authentication.
|
||||||
|
+#keyfile /etc/chrony.keys
|
||||||
|
+
|
||||||
|
+# Specify directory for log files.
|
||||||
|
+logdir /var/log/chrony
|
||||||
|
+
|
||||||
|
+# Select which information is logged.
|
||||||
|
+#log measurements statistics tracking
|
||||||
|
diff --git a/templates/ntp.conf.msvsphere.tmpl b/templates/ntp.conf.msvsphere.tmpl
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..62b4776
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/templates/ntp.conf.msvsphere.tmpl
|
||||||
|
@@ -0,0 +1,61 @@
|
||||||
|
+## template:jinja
|
||||||
|
+
|
||||||
|
+# For more information about this file, see the man pages
|
||||||
|
+# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).
|
||||||
|
+
|
||||||
|
+driftfile /var/lib/ntp/drift
|
||||||
|
+
|
||||||
|
+# Permit time synchronization with our time source, but do not
|
||||||
|
+# permit the source to query or modify the service on this system.
|
||||||
|
+restrict default kod nomodify notrap nopeer noquery
|
||||||
|
+restrict -6 default kod nomodify notrap nopeer noquery
|
||||||
|
+
|
||||||
|
+# Permit all access over the loopback interface. This could
|
||||||
|
+# be tightened as well, but to do so would effect some of
|
||||||
|
+# the administrative functions.
|
||||||
|
+restrict 127.0.0.1
|
||||||
|
+restrict -6 ::1
|
||||||
|
+
|
||||||
|
+# Hosts on local network are less restricted.
|
||||||
|
+#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
|
||||||
|
+
|
||||||
|
+# Use public servers from the pool.ntp.org project.
|
||||||
|
+# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
||||||
|
+{% if pools %}# pools
|
||||||
|
+{% endif %}
|
||||||
|
+{% for pool in pools -%}
|
||||||
|
+pool {{pool}} iburst
|
||||||
|
+{% endfor %}
|
||||||
|
+{%- if servers %}# servers
|
||||||
|
+{% endif %}
|
||||||
|
+{% for server in servers -%}
|
||||||
|
+server {{server}} iburst
|
||||||
|
+{% endfor %}
|
||||||
|
+
|
||||||
|
+#broadcast 192.168.1.255 autokey # broadcast server
|
||||||
|
+#broadcastclient # broadcast client
|
||||||
|
+#broadcast 224.0.1.1 autokey # multicast server
|
||||||
|
+#multicastclient 224.0.1.1 # multicast client
|
||||||
|
+#manycastserver 239.255.254.254 # manycast server
|
||||||
|
+#manycastclient 239.255.254.254 autokey # manycast client
|
||||||
|
+
|
||||||
|
+# Enable public key cryptography.
|
||||||
|
+#crypto
|
||||||
|
+
|
||||||
|
+includefile /etc/ntp/crypto/pw
|
||||||
|
+
|
||||||
|
+# Key file containing the keys and key identifiers used when operating
|
||||||
|
+# with symmetric key cryptography.
|
||||||
|
+keys /etc/ntp/keys
|
||||||
|
+
|
||||||
|
+# Specify the key identifiers which are trusted.
|
||||||
|
+#trustedkey 4 8 42
|
||||||
|
+
|
||||||
|
+# Specify the key identifier to use with the ntpdc utility.
|
||||||
|
+#requestkey 8
|
||||||
|
+
|
||||||
|
+# Specify the key identifier to use with the ntpq utility.
|
||||||
|
+#controlkey 8
|
||||||
|
+
|
||||||
|
+# Enable writing of statistics records.
|
||||||
|
+#statistics clockstats cryptostats loopstats peerstats
|
||||||
|
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||||
|
index d49da69..8249f48 100644
|
||||||
|
--- a/tests/unittests/test_net.py
|
||||||
|
+++ b/tests/unittests/test_net.py
|
||||||
|
@@ -7892,6 +7892,7 @@ class TestNetRenderers(CiTestCase):
|
||||||
|
"eurolinux",
|
||||||
|
"fedora",
|
||||||
|
"rhel",
|
||||||
|
+ "msvsphere",
|
||||||
|
]
|
||||||
|
for distro_name in variants:
|
||||||
|
m_info.return_value = {"variant": distro_name}
|
||||||
|
diff --git a/tests/unittests/test_render_cloudcfg.py b/tests/unittests/test_render_cloudcfg.py
|
||||||
|
index d3aeb1b..51cd167 100644
|
||||||
|
--- a/tests/unittests/test_render_cloudcfg.py
|
||||||
|
+++ b/tests/unittests/test_render_cloudcfg.py
|
||||||
|
@@ -17,6 +17,7 @@ DISTRO_VARIANTS = [
|
||||||
|
"fedora",
|
||||||
|
"freebsd",
|
||||||
|
"gentoo",
|
||||||
|
+ "msvsphere",
|
||||||
|
"mariner",
|
||||||
|
"netbsd",
|
||||||
|
"openbsd",
|
||||||
|
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
|
||||||
|
index 289a423..58856a4 100644
|
||||||
|
--- a/tests/unittests/test_util.py
|
||||||
|
+++ b/tests/unittests/test_util.py
|
||||||
|
@@ -209,6 +209,28 @@ OS_RELEASE_MIRACLELINUX_8 = dedent(
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
+OS_RELEASE_MSVSPHERE_9 = dedent(
|
||||||
|
+ """\
|
||||||
|
+ NAME="MSVSphere"
|
||||||
|
+ VERSION="9.3 (Inferit)"
|
||||||
|
+ ID="msvsphere"
|
||||||
|
+ ID_LIKE="rhel centos fedora"
|
||||||
|
+ VERSION_ID="9.3"
|
||||||
|
+ PLATFORM_ID="platform:el9"
|
||||||
|
+ PRETTY_NAME="MSVSphere 9.3 (Inferit)"
|
||||||
|
+ ANSI_COLOR="0;34"
|
||||||
|
+ LOGO="fedora-logo-icon"
|
||||||
|
+ CPE_NAME="cpe:/o:ncsd:msvsphere:9::baseos"
|
||||||
|
+ HOME_URL="https://msvsphere-os.ru/"
|
||||||
|
+ BUG_REPORT_URL="https://bugs.msvsphere-os.ru/"
|
||||||
|
+
|
||||||
|
+ MSVSPHERE_MANTISBT_PROJECT="MSVSphere-9"
|
||||||
|
+ MSVSPHERE_MANTISBT_PROJECT_VERSION="9.3"
|
||||||
|
+ REDHAT_SUPPORT_PRODUCT="MSVSphere"
|
||||||
|
+ REDHAT_SUPPORT_PRODUCT_VERSION="9.3"
|
||||||
|
+"""
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
OS_RELEASE_ROCKY_8 = dedent(
|
||||||
|
"""\
|
||||||
|
NAME="Rocky Linux"
|
||||||
|
@@ -310,6 +332,7 @@ REDHAT_RELEASE_ALMALINUX_8 = "AlmaLinux release 8.3 (Purple Manul)"
|
||||||
|
REDHAT_RELEASE_EUROLINUX_7 = "EuroLinux release 7.9 (Minsk)"
|
||||||
|
REDHAT_RELEASE_EUROLINUX_8 = "EuroLinux release 8.4 (Vaduz)"
|
||||||
|
REDHAT_RELEASE_MIRACLELINUX_8 = "MIRACLE LINUX release 8.4 (Peony)"
|
||||||
|
+REDHAT_RELEASE_MSVSPHERE_9 = "MSVSphere release 9.3 (Inferit)"
|
||||||
|
REDHAT_RELEASE_ROCKY_8 = "Rocky Linux release 8.3 (Green Obsidian)"
|
||||||
|
REDHAT_RELEASE_VIRTUOZZO_8 = "Virtuozzo Linux release 8"
|
||||||
|
REDHAT_RELEASE_CLOUDLINUX_8 = "CloudLinux release 8.4 (Valery Rozhdestvensky)"
|
||||||
|
@@ -1096,6 +1119,26 @@ class TestGetLinuxDistro(CiTestCase):
|
||||||
|
dist = util.get_linux_distro()
|
||||||
|
self.assertEqual(("miraclelinux", "8", "Peony"), dist)
|
||||||
|
|
||||||
|
+ @mock.patch("cloudinit.util.load_file")
|
||||||
|
+ def test_get_linux_msvsphere9_rhrelease(
|
||||||
|
+ self, m_os_release, m_path_exists
|
||||||
|
+ ):
|
||||||
|
+ """Verify msvsphere 9 read from redhat-release."""
|
||||||
|
+ m_os_release.return_value = REDHAT_RELEASE_MSVSPHERE_9
|
||||||
|
+ m_path_exists.side_effect = TestGetLinuxDistro.redhat_release_exists
|
||||||
|
+ dist = util.get_linux_distro()
|
||||||
|
+ self.assertEqual(("msvsphere", "9.3", "Inferit"), dist)
|
||||||
|
+
|
||||||
|
+ @mock.patch("cloudinit.util.load_file")
|
||||||
|
+ def test_get_linux_msvsphere9_osrelease(
|
||||||
|
+ self, m_os_release, m_path_exists
|
||||||
|
+ ):
|
||||||
|
+ """Verify msvsphere 9 read from os-release."""
|
||||||
|
+ m_os_release.return_value = OS_RELEASE_MSVSPHERE_9
|
||||||
|
+ m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists
|
||||||
|
+ dist = util.get_linux_distro()
|
||||||
|
+ self.assertEqual(("msvsphere", "9.3", "Inferit"), dist)
|
||||||
|
+
|
||||||
|
@mock.patch(M_PATH + "load_file")
|
||||||
|
def test_get_linux_rocky8_rhrelease(self, m_os_release, m_path_exists):
|
||||||
|
"""Verify rocky linux 8 read from redhat-release."""
|
||||||
|
@@ -1302,6 +1345,7 @@ class TestGetVariant:
|
||||||
|
({"system": "linux", "dist": ("ubuntu",)}, "ubuntu"),
|
||||||
|
({"system": "linux", "dist": ("linuxmint",)}, "ubuntu"),
|
||||||
|
({"system": "linux", "dist": ("mint",)}, "ubuntu"),
|
||||||
|
+ ({"system": "linux", "dist": ("msvsphere",)}, "msvsphere"),
|
||||||
|
({"system": "linux", "dist": ("redhat",)}, "rhel"),
|
||||||
|
({"system": "linux", "dist": ("opensuse",)}, "suse"),
|
||||||
|
({"system": "linux", "dist": ("opensuse-tumbleweed",)}, "suse"),
|
||||||
|
diff --git a/tools/read-dependencies b/tools/read-dependencies
|
||||||
|
index 87485c2..db9f495 100755
|
||||||
|
--- a/tools/read-dependencies
|
||||||
|
+++ b/tools/read-dependencies
|
||||||
|
@@ -26,6 +26,7 @@ DISTRO_PKG_TYPE_MAP = {
|
||||||
|
"centos": "redhat",
|
||||||
|
"eurolinux": "redhat",
|
||||||
|
"miraclelinux": "redhat",
|
||||||
|
+ "msvsphere": "redhat",
|
||||||
|
"rocky": "redhat",
|
||||||
|
"redhat": "redhat",
|
||||||
|
"debian": "debian",
|
||||||
|
@@ -95,6 +96,7 @@ CI_SYSTEM_BASE_PKGS = {
|
||||||
|
"common": ["make", "sudo", "tar"],
|
||||||
|
"eurolinux": ["python3-tox"],
|
||||||
|
"miraclelinux": ["python3-tox"],
|
||||||
|
+ "msvsphere": ["python3-tox"],
|
||||||
|
"redhat": ["python3-tox"],
|
||||||
|
"centos": ["python3-tox"],
|
||||||
|
"ubuntu": ["devscripts", "python3-dev", "libssl-dev", "tox", "sbuild"],
|
||||||
|
@@ -333,12 +335,13 @@ def pkg_install(pkg_list, distro, test_distro=False, dry_run=False):
|
||||||
|
cmd = DISTRO_INSTALL_PKG_CMD[distro_family]
|
||||||
|
install_cmd.extend(cmd)
|
||||||
|
|
||||||
|
- if distro in ["centos", "redhat", "rocky", "eurolinux"]:
|
||||||
|
+ if distro in ["centos", "redhat", "rocky", "eurolinux", "msvsphere"]:
|
||||||
|
# CentOS and Redhat need epel-release to access oauthlib and jsonschema
|
||||||
|
subprocess.check_call(install_cmd + ["epel-release"])
|
||||||
|
if distro in [
|
||||||
|
"suse",
|
||||||
|
"opensuse",
|
||||||
|
+ "msvsphere",
|
||||||
|
"redhat",
|
||||||
|
"rocky",
|
||||||
|
"centos",
|
||||||
|
diff --git a/tools/render-cloudcfg b/tools/render-cloudcfg
|
||||||
|
index 3cd394f..df48076 100755
|
||||||
|
--- a/tools/render-cloudcfg
|
||||||
|
+++ b/tools/render-cloudcfg
|
||||||
|
@@ -23,6 +23,7 @@ def main():
|
||||||
|
"gentoo",
|
||||||
|
"mariner",
|
||||||
|
"miraclelinux",
|
||||||
|
+ "msvsphere",
|
||||||
|
"netbsd",
|
||||||
|
"openbsd",
|
||||||
|
"openEuler",
|
||||||
|
diff --git a/tools/run-container b/tools/run-container
|
||||||
|
index 328ed93..284d607 100755
|
||||||
|
--- a/tools/run-container
|
||||||
|
+++ b/tools/run-container
|
||||||
|
@@ -248,7 +248,7 @@ apt_install() {
|
||||||
|
install_packages() {
|
||||||
|
get_os_info || return
|
||||||
|
case "$OS_NAME" in
|
||||||
|
- centos|rocky*) yum_install "$@";;
|
||||||
|
+ centos|msvsphere|rocky*) yum_install "$@";;
|
||||||
|
opensuse*) zypper_install "$@";;
|
||||||
|
debian|ubuntu) apt_install "$@";;
|
||||||
|
*) error "Do not know how to install packages on ${OS_NAME}";
|
||||||
|
@@ -497,7 +497,7 @@ main() {
|
||||||
|
|
||||||
|
local build_pkg="" build_srcpkg="" pkg_ext="" distflag=""
|
||||||
|
case "$OS_NAME" in
|
||||||
|
- centos|rocky*) distflag="--distro=redhat";;
|
||||||
|
+ centos|msvsphere|rocky*) distflag="--distro=redhat";;
|
||||||
|
opensuse*) distflag="--distro=suse";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From c589da20eb92231ef08e10c9724e3e6c663e6ce2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eduardo Otubo <otubo@redhat.com>
|
||||||
|
Date: Thu, 17 Feb 2022 15:32:35 +0100
|
||||||
|
Subject: [PATCH] Setting highest autoconnect priority for network-scripts
|
||||||
|
|
||||||
|
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
||||||
|
RH-MergeRequest: 22: Setting highest autoconnect priority for network-scripts
|
||||||
|
RH-Commit: [1/1] 34f1d62f8934a983a124df95b861a1e448681d3b (otubo/cloud-init-src)
|
||||||
|
RH-Bugzilla: 2036060
|
||||||
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||||
|
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
|
|
||||||
|
Set the highest autoconnect priority for network-scripts which is
|
||||||
|
loaded by NetworkManager ifcfg-rh plugin. Note that keyfile is the only
|
||||||
|
and default existing plugin on RHEL9, by setting the highest autoconnect
|
||||||
|
priority for network-scripts, NetworkManager will activate
|
||||||
|
network-scripts but keyfile. Network-scripts path:
|
||||||
|
|
||||||
|
Since this is a blocking issue, we decided to have this one-liner
|
||||||
|
downstream-only patch so we can move forward and have a better
|
||||||
|
NetworkManager support later on the release.
|
||||||
|
|
||||||
|
rhbz: 2036060
|
||||||
|
x-downstream-only: yes
|
||||||
|
|
||||||
|
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/net/sysconfig.py | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
|
index a7dbe55b..4262cd48 100644
|
||||||
|
--- a/cloudinit/net/sysconfig.py
|
||||||
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
|
@@ -317,6 +317,7 @@ class Renderer(renderer.Renderer):
|
||||||
|
"ONBOOT": True,
|
||||||
|
"USERCTL": False,
|
||||||
|
"BOOTPROTO": "none",
|
||||||
|
+ "AUTOCONNECT_PRIORITY": 999
|
||||||
|
},
|
||||||
|
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
From dfff374f66904e84fb07ca157ba010fac6b5f1de Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eduardo Otubo <otubo@redhat.com>
|
||||||
|
Date: Fri, 7 May 2021 13:36:08 +0200
|
||||||
|
Subject: [PATCH] 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
|
||||||
|
|
||||||
|
Conflicts 21.1:
|
||||||
|
cloudinit/stages.py: adjusting call of ensure_file() to use more
|
||||||
|
recent version
|
||||||
|
Confilicts 23.1.1:
|
||||||
|
use "" instead of ''
|
||||||
|
|
||||||
|
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
|
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/settings.py | 1 +
|
||||||
|
cloudinit/stages.py | 1 +
|
||||||
|
doc/examples/cloud-config.txt | 4 ++++
|
||||||
|
3 files changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||||
|
index edbb217d..3d541141 100644
|
||||||
|
--- a/cloudinit/settings.py
|
||||||
|
+++ b/cloudinit/settings.py
|
||||||
|
@@ -52,6 +52,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"],
|
||||||
|
"syslog_fix_perms": [],
|
||||||
|
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||||
|
index 9494a0bf..a624a6fb 100644
|
||||||
|
--- a/cloudinit/stages.py
|
||||||
|
+++ b/cloudinit/stages.py
|
||||||
|
@@ -202,6 +202,7 @@ class Init:
|
||||||
|
def _initialize_filesystem(self):
|
||||||
|
util.ensure_dirs(self._initial_subdirs())
|
||||||
|
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
|
||||||
|
+ log_file_mode = util.get_cfg_option_int(self.cfg, "def_log_file_mode")
|
||||||
|
if log_file:
|
||||||
|
util.ensure_file(log_file, mode=0o640, preserve_mode=True)
|
||||||
|
perms = self.cfg.get("syslog_fix_perms")
|
||||||
|
diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
|
||||||
|
index 15d788f3..b6d16c9c 100644
|
||||||
|
--- a/doc/examples/cloud-config.txt
|
||||||
|
+++ b/doc/examples/cloud-config.txt
|
||||||
|
@@ -383,10 +383,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
|
@ -1,140 +0,0 @@
|
|||||||
From 5fa8113a9efaa90f293b95477c4fa44e3d4b6537 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 23 Nov 2023 12:27:51 +0530
|
|
||||||
Subject: [PATCH] net/network_manager: do not set "may-fail" to False for both
|
|
||||||
ipv4 and ipv6 dhcp
|
|
||||||
|
|
||||||
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 cef4fa2d..fb4c863c 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -1477,11 +1477,11 @@ NETWORK_CONFIGS = {
|
|
||||||
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
[ipv6]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -1650,11 +1650,11 @@ NETWORK_CONFIGS = {
|
|
||||||
|
|
||||||
[ipv6]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
@ -0,0 +1,92 @@
|
|||||||
|
From ecae81f98ce230266eb99671b74534a4ede660f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
|
Date: Fri, 10 Mar 2023 11:51:48 +0100
|
||||||
|
Subject: [PATCH] Manual revert "Use Network-Manager and Netplan as default
|
||||||
|
renderers for RHEL and Fedora (#1465)"
|
||||||
|
|
||||||
|
This reverts changes done in commit 7703aa98b.
|
||||||
|
Done by hand because the doc file affected by that commit has changed.
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
|
||||||
|
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/net/renderers.py | 1 -
|
||||||
|
config/cloud.cfg.tmpl | 3 ---
|
||||||
|
doc/rtd/reference/network-config.rst | 16 ++--------------
|
||||||
|
3 files changed, 2 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/renderers.py b/cloudinit/net/renderers.py
|
||||||
|
index fcf7feba..b241683f 100644
|
||||||
|
--- a/cloudinit/net/renderers.py
|
||||||
|
+++ b/cloudinit/net/renderers.py
|
||||||
|
@@ -30,7 +30,6 @@ DEFAULT_PRIORITY = [
|
||||||
|
"eni",
|
||||||
|
"sysconfig",
|
||||||
|
"netplan",
|
||||||
|
- "network-manager",
|
||||||
|
"freebsd",
|
||||||
|
"netbsd",
|
||||||
|
"openbsd",
|
||||||
|
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
|
||||||
|
index 7238c102..12f32c51 100644
|
||||||
|
--- a/config/cloud.cfg.tmpl
|
||||||
|
+++ b/config/cloud.cfg.tmpl
|
||||||
|
@@ -381,9 +381,6 @@ system_info:
|
||||||
|
{% elif variant in ["dragonfly"] %}
|
||||||
|
network:
|
||||||
|
renderers: ['freebsd']
|
||||||
|
-{% elif variant in ["fedora"] or is_rhel %}
|
||||||
|
- network:
|
||||||
|
- renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
|
||||||
|
{% elif variant == "openmandriva" %}
|
||||||
|
network:
|
||||||
|
renderers: ['network-manager', 'networkd']
|
||||||
|
diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst
|
||||||
|
index ea331f1c..bc52afa5 100644
|
||||||
|
--- a/doc/rtd/reference/network-config.rst
|
||||||
|
+++ b/doc/rtd/reference/network-config.rst
|
||||||
|
@@ -176,16 +176,6 @@ this state, ``cloud-init`` delegates rendering of the configuration to
|
||||||
|
distro-supported formats. The following ``renderers`` are supported in
|
||||||
|
``cloud-init``:
|
||||||
|
|
||||||
|
-NetworkManager
|
||||||
|
---------------
|
||||||
|
-
|
||||||
|
-`NetworkManager`_ is the standard Linux network configuration tool suite. It
|
||||||
|
-supports a wide range of networking setups. Configuration is typically stored
|
||||||
|
-in :file:`/etc/NetworkManager`.
|
||||||
|
-
|
||||||
|
-It is the default for a number of Linux distributions; notably Fedora,
|
||||||
|
-CentOS/RHEL, and their derivatives.
|
||||||
|
-
|
||||||
|
ENI
|
||||||
|
---
|
||||||
|
|
||||||
|
@@ -223,7 +213,6 @@ preference) is as follows:
|
||||||
|
- ENI
|
||||||
|
- Sysconfig
|
||||||
|
- Netplan
|
||||||
|
-- NetworkManager
|
||||||
|
- FreeBSD
|
||||||
|
- NetBSD
|
||||||
|
- OpenBSD
|
||||||
|
@@ -234,7 +223,6 @@ preference) is as follows:
|
||||||
|
|
||||||
|
- **ENI**: using ``ifup``, ``ifdown`` to manage device setup/teardown
|
||||||
|
- **Netplan**: using ``netplan apply`` to manage device setup/teardown
|
||||||
|
-- **NetworkManager**: using ``nmcli`` to manage device setup/teardown
|
||||||
|
- **Networkd**: using ``ip`` to manage device setup/teardown
|
||||||
|
|
||||||
|
When applying the policy, ``cloud-init`` checks if the current instance has the
|
||||||
|
@@ -244,8 +232,8 @@ supplying an updated configuration in cloud-config. ::
|
||||||
|
|
||||||
|
system_info:
|
||||||
|
network:
|
||||||
|
- renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
|
||||||
|
- activators: ['eni', 'netplan', 'network-manager', 'networkd']
|
||||||
|
+ renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
|
||||||
|
+ activators: ['eni', 'netplan', 'networkd']
|
||||||
|
|
||||||
|
Network configuration tools
|
||||||
|
===========================
|
@ -1,172 +0,0 @@
|
|||||||
From 54e87eaad7841270e530beff2dcfe68292ae87ef Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Tue, 21 Nov 2023 13:57:15 +0530
|
|
||||||
Subject: [PATCH] net: allow dhcp6 configuration from
|
|
||||||
generate_fallback_configuration()
|
|
||||||
|
|
||||||
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 fb4c863c..d9ef493b 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -4339,6 +4339,7 @@ class TestGenerateFallbackConfig(CiTestCase):
|
|
||||||
"ethernets": {
|
|
||||||
"eth0": {
|
|
||||||
"dhcp4": True,
|
|
||||||
+ "dhcp6": True,
|
|
||||||
"set-name": "eth0",
|
|
||||||
"match": {
|
|
||||||
"macaddress": "00:11:22:33:44:55",
|
|
||||||
@@ -4423,6 +4424,9 @@ iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth0
|
|
||||||
iface eth0 inet dhcp
|
|
||||||
+
|
|
||||||
+# control-alias eth0
|
|
||||||
+iface eth0 inet6 dhcp
|
|
||||||
"""
|
|
||||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
|
||||||
|
|
||||||
@@ -4512,6 +4516,9 @@ iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth1
|
|
||||||
iface eth1 inet dhcp
|
|
||||||
+
|
|
||||||
+# control-alias eth1
|
|
||||||
+iface eth1 inet6 dhcp
|
|
||||||
"""
|
|
||||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
|
||||||
|
|
||||||
@@ -4736,7 +4743,9 @@ class TestRhelSysConfigRendering(CiTestCase):
|
|
||||||
AUTOCONNECT_PRIORITY=120
|
|
||||||
BOOTPROTO=dhcp
|
|
||||||
DEVICE=eth1000
|
|
||||||
+DHCPV6C=yes
|
|
||||||
HWADDR=07-1c-c6-75-a4-be
|
|
||||||
+IPV6INIT=yes
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no
|
|
||||||
@@ -5646,7 +5655,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()
|
|
||||||
@@ -6032,7 +6042,11 @@ class TestNetworkManagerRendering(CiTestCase):
|
|
||||||
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
- may-fail=false
|
|
||||||
+ may-fail=true
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -6298,6 +6312,9 @@ iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth1000
|
|
||||||
iface eth1000 inet dhcp
|
|
||||||
+
|
|
||||||
+# control-alias eth1000
|
|
||||||
+iface eth1000 inet6 dhcp
|
|
||||||
"""
|
|
||||||
self.assertEqual(expected.lstrip(), contents.lstrip())
|
|
||||||
|
|
||||||
@@ -6357,6 +6374,7 @@ class TestNetplanNetRendering:
|
|
||||||
ethernets:
|
|
||||||
eth1000:
|
|
||||||
dhcp4: true
|
|
||||||
+ dhcp6: true
|
|
||||||
match:
|
|
||||||
macaddress: 07-1c-c6-75-a4-be
|
|
||||||
set-name: eth1000
|
|
||||||
@@ -7856,7 +7874,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())
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
|||||||
|
From ac0cf308318d423162ce3b7be32dcbf88f20ff50 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Tue, 4 Apr 2023 19:59:07 +0530
|
||||||
|
Subject: [PATCH] rhel: make sure previous-hostname file ends with a new line
|
||||||
|
(#2108)
|
||||||
|
|
||||||
|
cloud-init strips new line from "/etc/hostname" on rhel distro when processing
|
||||||
|
"/var/lib/cloud/data/previous-hostname". Although this does not pose a serious
|
||||||
|
issue, it is still better if the behavior is similar to other distros like
|
||||||
|
Ubuntu where /previous-hostname does end with a new line. Fix this issue by
|
||||||
|
using hostname parser in rhel similar to debian.
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit 6d42aa8e2c1a5454a658ab4e2b9cead2677c77cd)
|
||||||
|
---
|
||||||
|
cloudinit/distros/rhel.py | 5 ++++-
|
||||||
|
tools/.github-cla-signers | 1 +
|
||||||
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/distros/rhel.py b/cloudinit/distros/rhel.py
|
||||||
|
index df7dc3d6..9625709e 100644
|
||||||
|
--- a/cloudinit/distros/rhel.py
|
||||||
|
+++ b/cloudinit/distros/rhel.py
|
||||||
|
@@ -13,6 +13,7 @@ from cloudinit import distros, helpers
|
||||||
|
from cloudinit import log as logging
|
||||||
|
from cloudinit import subp, util
|
||||||
|
from cloudinit.distros import rhel_util
|
||||||
|
+from cloudinit.distros.parsers.hostname import HostnameConf
|
||||||
|
from cloudinit.settings import PER_INSTANCE
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
@@ -111,7 +112,9 @@ class Distro(distros.Distro):
|
||||||
|
# systemd will never update previous-hostname for us, so
|
||||||
|
# we need to do it ourselves
|
||||||
|
if self.uses_systemd() and filename.endswith("/previous-hostname"):
|
||||||
|
- util.write_file(filename, hostname)
|
||||||
|
+ conf = HostnameConf("")
|
||||||
|
+ conf.set_hostname(hostname)
|
||||||
|
+ util.write_file(filename, str(conf), 0o644)
|
||||||
|
elif self.uses_systemd():
|
||||||
|
subp.subp(["hostnamectl", "set-hostname", str(hostname)])
|
||||||
|
else:
|
||||||
|
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
|
||||||
|
index d8cca015..457dacf4 100644
|
||||||
|
--- a/tools/.github-cla-signers
|
||||||
|
+++ b/tools/.github-cla-signers
|
||||||
|
@@ -9,6 +9,7 @@ andgein
|
||||||
|
andrew-lee-metaswitch
|
||||||
|
andrewbogott
|
||||||
|
andrewlukoshko
|
||||||
|
+ani-sinha
|
||||||
|
antonyc
|
||||||
|
aswinrajamannar
|
||||||
|
beantaxi
|
@ -1,38 +0,0 @@
|
|||||||
From e5258b60a3dbf44ef1faac91db2b45dab09de0b5 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] test(jsonschema): Pin jsonschema version (#4781)
|
|
||||||
|
|
||||||
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
|
|
@ -0,0 +1,121 @@
|
|||||||
|
From 34ef256dc614c7dcf5b04a431d410030e333d82b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
|
Date: Mon, 17 Apr 2023 10:20:16 +0200
|
||||||
|
Subject: [PATCH] Don't change permissions of netrules target (#2076)
|
||||||
|
|
||||||
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2182948
|
||||||
|
|
||||||
|
commit 56c88cafd1b3606e814069a79f4ec265fc427c87
|
||||||
|
Author: James Falcon <james.falcon@canonical.com>
|
||||||
|
Date: Thu Mar 23 10:21:56 2023 -0500
|
||||||
|
|
||||||
|
Don't change permissions of netrules target (#2076)
|
||||||
|
|
||||||
|
Set permissions if file doesn't exist. Leave them if it does.
|
||||||
|
|
||||||
|
LP: #2011783
|
||||||
|
|
||||||
|
Co-authored-by: Chad Smith <chad.smith@canonical.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
cloudinit/net/sysconfig.py: enable_ifcfg_rh missing upstream
|
||||||
|
|
||||||
|
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/net/eni.py | 4 +++-
|
||||||
|
cloudinit/net/sysconfig.py | 7 ++++++-
|
||||||
|
tests/unittests/distros/test_netconfig.py | 20 ++++++++++++++++++--
|
||||||
|
3 files changed, 27 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
|
||||||
|
index 53bd35ca..1de3bec2 100644
|
||||||
|
--- a/cloudinit/net/eni.py
|
||||||
|
+++ b/cloudinit/net/eni.py
|
||||||
|
@@ -576,7 +576,9 @@ class Renderer(renderer.Renderer):
|
||||||
|
netrules = subp.target_path(target, self.netrules_path)
|
||||||
|
util.ensure_dir(os.path.dirname(netrules))
|
||||||
|
util.write_file(
|
||||||
|
- netrules, self._render_persistent_net(network_state)
|
||||||
|
+ netrules,
|
||||||
|
+ content=self._render_persistent_net(network_state),
|
||||||
|
+ preserve_mode=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
|
index 765c248a..e08c0c69 100644
|
||||||
|
--- a/cloudinit/net/sysconfig.py
|
||||||
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
|
@@ -1034,7 +1034,12 @@ class Renderer(renderer.Renderer):
|
||||||
|
if self.netrules_path:
|
||||||
|
netrules_content = self._render_persistent_net(network_state)
|
||||||
|
netrules_path = subp.target_path(target, self.netrules_path)
|
||||||
|
- util.write_file(netrules_path, netrules_content, file_mode)
|
||||||
|
+ util.write_file(
|
||||||
|
+ netrules_path,
|
||||||
|
+ content=netrules_content,
|
||||||
|
+ mode=file_mode,
|
||||||
|
+ preserve_mode=True,
|
||||||
|
+ )
|
||||||
|
if available_nm(target=target):
|
||||||
|
enable_ifcfg_rh(subp.target_path(target, path=NM_CFG_FILE))
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
|
||||||
|
index e9fb0591..b1c89ce3 100644
|
||||||
|
--- a/tests/unittests/distros/test_netconfig.py
|
||||||
|
+++ b/tests/unittests/distros/test_netconfig.py
|
||||||
|
@@ -458,8 +458,16 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
|
||||||
|
def eni_path(self):
|
||||||
|
return "/etc/network/interfaces.d/50-cloud-init.cfg"
|
||||||
|
|
||||||
|
+ def rules_path(self):
|
||||||
|
+ return "/etc/udev/rules.d/70-persistent-net.rules"
|
||||||
|
+
|
||||||
|
def _apply_and_verify_eni(
|
||||||
|
- self, apply_fn, config, expected_cfgs=None, bringup=False
|
||||||
|
+ self,
|
||||||
|
+ apply_fn,
|
||||||
|
+ config,
|
||||||
|
+ expected_cfgs=None,
|
||||||
|
+ bringup=False,
|
||||||
|
+ previous_files=(),
|
||||||
|
):
|
||||||
|
if not expected_cfgs:
|
||||||
|
raise ValueError("expected_cfg must not be None")
|
||||||
|
@@ -467,7 +475,11 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
|
||||||
|
tmpd = None
|
||||||
|
with mock.patch("cloudinit.net.eni.available") as m_avail:
|
||||||
|
m_avail.return_value = True
|
||||||
|
+ path_modes = {}
|
||||||
|
with self.reRooted(tmpd) as tmpd:
|
||||||
|
+ for previous_path, content, mode in previous_files:
|
||||||
|
+ util.write_file(previous_path, content, mode=mode)
|
||||||
|
+ path_modes[previous_path] = mode
|
||||||
|
apply_fn(config, bringup)
|
||||||
|
|
||||||
|
results = dir2dict(tmpd)
|
||||||
|
@@ -478,7 +490,9 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
|
||||||
|
print(results[cfgpath])
|
||||||
|
print("----------")
|
||||||
|
self.assertEqual(expected, results[cfgpath])
|
||||||
|
- self.assertEqual(0o644, get_mode(cfgpath, tmpd))
|
||||||
|
+ self.assertEqual(
|
||||||
|
+ path_modes.get(cfgpath, 0o644), get_mode(cfgpath, tmpd)
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_apply_network_config_and_bringup_filters_priority_eni_ub(self):
|
||||||
|
"""Network activator search priority can be overridden from config."""
|
||||||
|
@@ -527,11 +541,13 @@ class TestNetCfgDistroUbuntuEni(TestNetCfgDistroBase):
|
||||||
|
def test_apply_network_config_eni_ub(self):
|
||||||
|
expected_cfgs = {
|
||||||
|
self.eni_path(): V1_NET_CFG_OUTPUT,
|
||||||
|
+ self.rules_path(): "",
|
||||||
|
}
|
||||||
|
self._apply_and_verify_eni(
|
||||||
|
self.distro.apply_network_config,
|
||||||
|
V1_NET_CFG,
|
||||||
|
expected_cfgs=expected_cfgs.copy(),
|
||||||
|
+ previous_files=((self.rules_path(), "something", 0o660),),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_apply_network_config_ipv6_ub(self):
|
@ -1,121 +0,0 @@
|
|||||||
From 9e8fbb736d5e8db8bcf0fbc35a76bdad9251990a Mon Sep 17 00:00:00 2001
|
|
||||||
From: d1r3ct0r <calvin.mwadime@canonical.com>
|
|
||||||
Date: Sat, 20 Jan 2024 02:11:47 +0300
|
|
||||||
Subject: [PATCH] fix(clean): stop warning when running clean command (#4761)
|
|
||||||
|
|
||||||
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 .distro/ 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
|
|
@ -0,0 +1,295 @@
|
|||||||
|
From d092efe0f437ad149f6d6e3a9f8b816c0f5c1c2a Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Falcon <james.falcon@canonical.com>
|
||||||
|
Date: Wed, 26 Apr 2023 15:11:55 -0500
|
||||||
|
Subject: [PATCH] Make user/vendor data sensitive and remove log permissions
|
||||||
|
(#2144)
|
||||||
|
|
||||||
|
Because user data and vendor data may contain sensitive information,
|
||||||
|
this commit ensures that any user data or vendor data written to
|
||||||
|
instance-data.json gets redacted and is only available to root user.
|
||||||
|
|
||||||
|
Also, modify the permissions of cloud-init.log to be 640, so that
|
||||||
|
sensitive data leaked to the log isn't world readable.
|
||||||
|
Additionally, remove the logging of user data and vendor data to
|
||||||
|
cloud-init.log from the Vultr datasource.
|
||||||
|
|
||||||
|
LP: #2013967
|
||||||
|
CVE: CVE-2023-1786
|
||||||
|
(cherry picked from commit a378b7e4f47375458651c0972e7cd813f6fe0a6b)
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/sources/DataSourceLXD.py | 9 ++++++---
|
||||||
|
cloudinit/sources/DataSourceVultr.py | 14 ++++++--------
|
||||||
|
cloudinit/sources/__init__.py | 28 +++++++++++++++++++++++++---
|
||||||
|
cloudinit/stages.py | 4 +++-
|
||||||
|
tests/unittests/sources/test_init.py | 27 ++++++++++++++++++++++++++-
|
||||||
|
tests/unittests/test_stages.py | 18 +++++++++++-------
|
||||||
|
6 files changed, 77 insertions(+), 23 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/sources/DataSourceLXD.py b/cloudinit/sources/DataSourceLXD.py
|
||||||
|
index ab440cc8..e4cae91a 100644
|
||||||
|
--- a/cloudinit/sources/DataSourceLXD.py
|
||||||
|
+++ b/cloudinit/sources/DataSourceLXD.py
|
||||||
|
@@ -14,7 +14,7 @@ import stat
|
||||||
|
import time
|
||||||
|
from enum import Flag, auto
|
||||||
|
from json.decoder import JSONDecodeError
|
||||||
|
-from typing import Any, Dict, List, Optional, Union, cast
|
||||||
|
+from typing import Any, Dict, List, Optional, Tuple, Union, cast
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from requests.adapters import HTTPAdapter
|
||||||
|
@@ -168,11 +168,14 @@ class DataSourceLXD(sources.DataSource):
|
||||||
|
_network_config: Union[Dict, str] = sources.UNSET
|
||||||
|
_crawled_metadata: Union[Dict, str] = sources.UNSET
|
||||||
|
|
||||||
|
- sensitive_metadata_keys = (
|
||||||
|
- "merged_cfg",
|
||||||
|
+ sensitive_metadata_keys: Tuple[
|
||||||
|
+ str, ...
|
||||||
|
+ ] = sources.DataSource.sensitive_metadata_keys + (
|
||||||
|
"user.meta-data",
|
||||||
|
"user.vendor-data",
|
||||||
|
"user.user-data",
|
||||||
|
+ "cloud-init.user-data",
|
||||||
|
+ "cloud-init.vendor-data",
|
||||||
|
)
|
||||||
|
|
||||||
|
skip_hotplug_detect = True
|
||||||
|
diff --git a/cloudinit/sources/DataSourceVultr.py b/cloudinit/sources/DataSourceVultr.py
|
||||||
|
index 9d7c84fb..660e9f14 100644
|
||||||
|
--- a/cloudinit/sources/DataSourceVultr.py
|
||||||
|
+++ b/cloudinit/sources/DataSourceVultr.py
|
||||||
|
@@ -5,6 +5,8 @@
|
||||||
|
# Vultr Metadata API:
|
||||||
|
# https://www.vultr.com/metadata/
|
||||||
|
|
||||||
|
+from typing import Tuple
|
||||||
|
+
|
||||||
|
import cloudinit.sources.helpers.vultr as vultr
|
||||||
|
from cloudinit import log as log
|
||||||
|
from cloudinit import sources, util, version
|
||||||
|
@@ -28,6 +30,10 @@ class DataSourceVultr(sources.DataSource):
|
||||||
|
|
||||||
|
dsname = "Vultr"
|
||||||
|
|
||||||
|
+ sensitive_metadata_keys: Tuple[
|
||||||
|
+ str, ...
|
||||||
|
+ ] = sources.DataSource.sensitive_metadata_keys + ("startup-script",)
|
||||||
|
+
|
||||||
|
def __init__(self, sys_cfg, distro, paths):
|
||||||
|
super(DataSourceVultr, self).__init__(sys_cfg, distro, paths)
|
||||||
|
self.ds_cfg = util.mergemanydict(
|
||||||
|
@@ -54,13 +60,8 @@ class DataSourceVultr(sources.DataSource):
|
||||||
|
self.get_datasource_data(self.metadata)
|
||||||
|
|
||||||
|
# Dump some data so diagnosing failures is manageable
|
||||||
|
- LOG.debug("Vultr Vendor Config:")
|
||||||
|
- LOG.debug(util.json_dumps(self.metadata["vendor-data"]))
|
||||||
|
LOG.debug("SUBID: %s", self.metadata["instance-id"])
|
||||||
|
LOG.debug("Hostname: %s", self.metadata["local-hostname"])
|
||||||
|
- if self.userdata_raw is not None:
|
||||||
|
- LOG.debug("User-Data:")
|
||||||
|
- LOG.debug(self.userdata_raw)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
@@ -146,7 +147,4 @@ if __name__ == "__main__":
|
||||||
|
config = md["vendor-data"]
|
||||||
|
sysinfo = vultr.get_sysinfo()
|
||||||
|
|
||||||
|
- print(util.json_dumps(sysinfo))
|
||||||
|
- print(util.json_dumps(config))
|
||||||
|
-
|
||||||
|
# vi: ts=4 expandtab
|
||||||
|
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
|
||||||
|
index 565e1754..5c6ae8b1 100644
|
||||||
|
--- a/cloudinit/sources/__init__.py
|
||||||
|
+++ b/cloudinit/sources/__init__.py
|
||||||
|
@@ -110,7 +110,10 @@ def process_instance_metadata(metadata, key_path="", sensitive_keys=()):
|
||||||
|
sub_key_path = key_path + "/" + key
|
||||||
|
else:
|
||||||
|
sub_key_path = key
|
||||||
|
- if key in sensitive_keys or sub_key_path in sensitive_keys:
|
||||||
|
+ if (
|
||||||
|
+ key.lower() in sensitive_keys
|
||||||
|
+ or sub_key_path.lower() in sensitive_keys
|
||||||
|
+ ):
|
||||||
|
sens_keys.append(sub_key_path)
|
||||||
|
if isinstance(val, str) and val.startswith("ci-b64:"):
|
||||||
|
base64_encoded_keys.append(sub_key_path)
|
||||||
|
@@ -132,6 +135,12 @@ def redact_sensitive_keys(metadata, redact_value=REDACT_SENSITIVE_VALUE):
|
||||||
|
|
||||||
|
Replace any keys values listed in 'sensitive_keys' with redact_value.
|
||||||
|
"""
|
||||||
|
+ # While 'sensitive_keys' should already sanitized to only include what
|
||||||
|
+ # is in metadata, it is possible keys will overlap. For example, if
|
||||||
|
+ # "merged_cfg" and "merged_cfg/ds/userdata" both match, it's possible that
|
||||||
|
+ # "merged_cfg" will get replaced first, meaning "merged_cfg/ds/userdata"
|
||||||
|
+ # no longer represents a valid key.
|
||||||
|
+ # Thus, we still need to do membership checks in this function.
|
||||||
|
if not metadata.get("sensitive_keys", []):
|
||||||
|
return metadata
|
||||||
|
md_copy = copy.deepcopy(metadata)
|
||||||
|
@@ -139,9 +148,14 @@ def redact_sensitive_keys(metadata, redact_value=REDACT_SENSITIVE_VALUE):
|
||||||
|
path_parts = key_path.split("/")
|
||||||
|
obj = md_copy
|
||||||
|
for path in path_parts:
|
||||||
|
- if isinstance(obj[path], dict) and path != path_parts[-1]:
|
||||||
|
+ if (
|
||||||
|
+ path in obj
|
||||||
|
+ and isinstance(obj[path], dict)
|
||||||
|
+ and path != path_parts[-1]
|
||||||
|
+ ):
|
||||||
|
obj = obj[path]
|
||||||
|
- obj[path] = redact_value
|
||||||
|
+ if path in obj:
|
||||||
|
+ obj[path] = redact_value
|
||||||
|
return md_copy
|
||||||
|
|
||||||
|
|
||||||
|
@@ -249,6 +263,14 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
|
||||||
|
sensitive_metadata_keys: Tuple[str, ...] = (
|
||||||
|
"merged_cfg",
|
||||||
|
"security-credentials",
|
||||||
|
+ "userdata",
|
||||||
|
+ "user-data",
|
||||||
|
+ "user_data",
|
||||||
|
+ "vendordata",
|
||||||
|
+ "vendor-data",
|
||||||
|
+ # Provide ds/vendor_data to avoid redacting top-level
|
||||||
|
+ # "vendor_data": {enabled: True}
|
||||||
|
+ "ds/vendor_data",
|
||||||
|
)
|
||||||
|
|
||||||
|
# True on datasources that may not see hotplugged devices reflected
|
||||||
|
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||||
|
index a624a6fb..1326d205 100644
|
||||||
|
--- a/cloudinit/stages.py
|
||||||
|
+++ b/cloudinit/stages.py
|
||||||
|
@@ -204,7 +204,9 @@ class Init:
|
||||||
|
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
|
||||||
|
log_file_mode = util.get_cfg_option_int(self.cfg, "def_log_file_mode")
|
||||||
|
if log_file:
|
||||||
|
- util.ensure_file(log_file, mode=0o640, preserve_mode=True)
|
||||||
|
+ # At this point the log file should have already been created
|
||||||
|
+ # in the setupLogging function of log.py
|
||||||
|
+ util.ensure_file(log_file, mode=0o640, preserve_mode=False)
|
||||||
|
perms = self.cfg.get("syslog_fix_perms")
|
||||||
|
if not perms:
|
||||||
|
perms = {}
|
||||||
|
diff --git a/tests/unittests/sources/test_init.py b/tests/unittests/sources/test_init.py
|
||||||
|
index 0447e02c..eb27198f 100644
|
||||||
|
--- a/tests/unittests/sources/test_init.py
|
||||||
|
+++ b/tests/unittests/sources/test_init.py
|
||||||
|
@@ -458,12 +458,24 @@ class TestDataSource(CiTestCase):
|
||||||
|
"cred2": "othersekret",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
+ "someother": {
|
||||||
|
+ "nested": {
|
||||||
|
+ "userData": "HIDE ME",
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ "VENDOR-DAta": "HIDE ME TOO",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertCountEqual(
|
||||||
|
(
|
||||||
|
"merged_cfg",
|
||||||
|
"security-credentials",
|
||||||
|
+ "userdata",
|
||||||
|
+ "user-data",
|
||||||
|
+ "user_data",
|
||||||
|
+ "vendordata",
|
||||||
|
+ "vendor-data",
|
||||||
|
+ "ds/vendor_data",
|
||||||
|
),
|
||||||
|
datasource.sensitive_metadata_keys,
|
||||||
|
)
|
||||||
|
@@ -490,7 +502,9 @@ class TestDataSource(CiTestCase):
|
||||||
|
"base64_encoded_keys": [],
|
||||||
|
"merged_cfg": REDACT_SENSITIVE_VALUE,
|
||||||
|
"sensitive_keys": [
|
||||||
|
+ "ds/meta_data/VENDOR-DAta",
|
||||||
|
"ds/meta_data/some/security-credentials",
|
||||||
|
+ "ds/meta_data/someother/nested/userData",
|
||||||
|
"merged_cfg",
|
||||||
|
],
|
||||||
|
"sys_info": sys_info,
|
||||||
|
@@ -500,6 +514,7 @@ class TestDataSource(CiTestCase):
|
||||||
|
"availability_zone": "myaz",
|
||||||
|
"cloud-name": "subclasscloudname",
|
||||||
|
"cloud_name": "subclasscloudname",
|
||||||
|
+ "cloud_id": "subclasscloudname",
|
||||||
|
"distro": "ubuntu",
|
||||||
|
"distro_release": "focal",
|
||||||
|
"distro_version": "20.04",
|
||||||
|
@@ -522,14 +537,18 @@ class TestDataSource(CiTestCase):
|
||||||
|
"ds": {
|
||||||
|
"_doc": EXPERIMENTAL_TEXT,
|
||||||
|
"meta_data": {
|
||||||
|
+ "VENDOR-DAta": REDACT_SENSITIVE_VALUE,
|
||||||
|
"availability_zone": "myaz",
|
||||||
|
"local-hostname": "test-subclass-hostname",
|
||||||
|
"region": "myregion",
|
||||||
|
"some": {"security-credentials": REDACT_SENSITIVE_VALUE},
|
||||||
|
+ "someother": {
|
||||||
|
+ "nested": {"userData": REDACT_SENSITIVE_VALUE}
|
||||||
|
+ },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
- self.assertCountEqual(expected, redacted)
|
||||||
|
+ self.assertEqual(expected, redacted)
|
||||||
|
file_stat = os.stat(json_file)
|
||||||
|
self.assertEqual(0o644, stat.S_IMODE(file_stat.st_mode))
|
||||||
|
|
||||||
|
@@ -574,6 +593,12 @@ class TestDataSource(CiTestCase):
|
||||||
|
(
|
||||||
|
"merged_cfg",
|
||||||
|
"security-credentials",
|
||||||
|
+ "userdata",
|
||||||
|
+ "user-data",
|
||||||
|
+ "user_data",
|
||||||
|
+ "vendordata",
|
||||||
|
+ "vendor-data",
|
||||||
|
+ "ds/vendor_data",
|
||||||
|
),
|
||||||
|
datasource.sensitive_metadata_keys,
|
||||||
|
)
|
||||||
|
diff --git a/tests/unittests/test_stages.py b/tests/unittests/test_stages.py
|
||||||
|
index 15a7e973..a61f9df9 100644
|
||||||
|
--- a/tests/unittests/test_stages.py
|
||||||
|
+++ b/tests/unittests/test_stages.py
|
||||||
|
@@ -606,19 +606,23 @@ class TestInit_InitializeFilesystem:
|
||||||
|
# Assert we create it 0o640 by default if it doesn't already exist
|
||||||
|
assert 0o640 == stat.S_IMODE(log_file.stat().mode)
|
||||||
|
|
||||||
|
- def test_existing_file_permissions_are_not_modified(self, init, tmpdir):
|
||||||
|
- """If the log file already exists, we should not modify its permissions
|
||||||
|
+ def test_existing_file_permissions(self, init, tmpdir):
|
||||||
|
+ """Test file permissions are set as expected.
|
||||||
|
+
|
||||||
|
+ CIS Hardening requires 640 permissions. These permissions are
|
||||||
|
+ currently hardcoded on every boot, but if there's ever a reason
|
||||||
|
+ to change this, we need to then ensure that they
|
||||||
|
+ are *not* set every boot.
|
||||||
|
|
||||||
|
See https://bugs.launchpad.net/cloud-init/+bug/1900837.
|
||||||
|
"""
|
||||||
|
- # Use a mode that will never be made the default so this test will
|
||||||
|
- # always be valid
|
||||||
|
- mode = 0o606
|
||||||
|
log_file = tmpdir.join("cloud-init.log")
|
||||||
|
log_file.ensure()
|
||||||
|
- log_file.chmod(mode)
|
||||||
|
+ # Use a mode that will never be made the default so this test will
|
||||||
|
+ # always be valid
|
||||||
|
+ log_file.chmod(0o606)
|
||||||
|
init._cfg = {"def_log_file": str(log_file)}
|
||||||
|
|
||||||
|
init._initialize_filesystem()
|
||||||
|
|
||||||
|
- assert mode == stat.S_IMODE(log_file.stat().mode)
|
||||||
|
+ assert 0o640 == stat.S_IMODE(log_file.stat().mode)
|
@ -0,0 +1,206 @@
|
|||||||
|
From 6bf6ceab79df97eb1c90b4df61f654bc0b2f598c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Tue, 2 May 2023 20:35:45 +0530
|
||||||
|
Subject: [PATCH] Do not generate dsa and ed25519 key types when crypto FIPS
|
||||||
|
mode is enabled (#2142)
|
||||||
|
|
||||||
|
DSA and ED25519 key types are not supported when FIPS is enabled in crypto.
|
||||||
|
Check if FIPS has been enabled on the system and if so, do not generate those
|
||||||
|
key types. Presently the check is only available on Linux systems.
|
||||||
|
|
||||||
|
LP: 2017761
|
||||||
|
RHBZ: 2187164
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit c53f04aeb2acf9526a2ebf3d3320f149ac46caa6)
|
||||||
|
---
|
||||||
|
cloudinit/config/cc_ssh.py | 21 +++++++++++++++-
|
||||||
|
cloudinit/util.py | 12 +++++++++
|
||||||
|
tests/unittests/config/test_cc_ssh.py | 36 +++++++++++++++++++++------
|
||||||
|
tests/unittests/test_util.py | 25 +++++++++++++++++++
|
||||||
|
4 files changed, 85 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/config/cc_ssh.py b/cloudinit/config/cc_ssh.py
|
||||||
|
index 1ec889f3..5578654a 100644
|
||||||
|
--- a/cloudinit/config/cc_ssh.py
|
||||||
|
+++ b/cloudinit/config/cc_ssh.py
|
||||||
|
@@ -172,6 +172,8 @@ meta: MetaSchema = {
|
||||||
|
__doc__ = get_meta_doc(meta)
|
||||||
|
|
||||||
|
GENERATE_KEY_NAMES = ["rsa", "dsa", "ecdsa", "ed25519"]
|
||||||
|
+FIPS_UNSUPPORTED_KEY_NAMES = ["dsa", "ed25519"]
|
||||||
|
+
|
||||||
|
pattern_unsupported_config_keys = re.compile(
|
||||||
|
"^(ecdsa-sk|ed25519-sk)_(private|public|certificate)$"
|
||||||
|
)
|
||||||
|
@@ -259,9 +261,26 @@ def handle(
|
||||||
|
genkeys = util.get_cfg_option_list(
|
||||||
|
cfg, "ssh_genkeytypes", GENERATE_KEY_NAMES
|
||||||
|
)
|
||||||
|
+ # remove keys that are not supported in fips mode if its enabled
|
||||||
|
+ key_names = (
|
||||||
|
+ genkeys
|
||||||
|
+ if not util.fips_enabled()
|
||||||
|
+ else [
|
||||||
|
+ names
|
||||||
|
+ for names in genkeys
|
||||||
|
+ if names not in FIPS_UNSUPPORTED_KEY_NAMES
|
||||||
|
+ ]
|
||||||
|
+ )
|
||||||
|
+ skipped_keys = set(genkeys).difference(key_names)
|
||||||
|
+ if skipped_keys:
|
||||||
|
+ log.debug(
|
||||||
|
+ "skipping keys that are not supported in fips mode: %s",
|
||||||
|
+ ",".join(skipped_keys),
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
lang_c = os.environ.copy()
|
||||||
|
lang_c["LANG"] = "C"
|
||||||
|
- for keytype in genkeys:
|
||||||
|
+ for keytype in key_names:
|
||||||
|
keyfile = KEY_FILE_TPL % (keytype)
|
||||||
|
if os.path.exists(keyfile):
|
||||||
|
continue
|
||||||
|
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
||||||
|
index 8ba3e2b6..4a8e3d3b 100644
|
||||||
|
--- a/cloudinit/util.py
|
||||||
|
+++ b/cloudinit/util.py
|
||||||
|
@@ -1577,6 +1577,18 @@ def get_cmdline():
|
||||||
|
return _get_cmdline()
|
||||||
|
|
||||||
|
|
||||||
|
+def fips_enabled() -> bool:
|
||||||
|
+ fips_proc = "/proc/sys/crypto/fips_enabled"
|
||||||
|
+ try:
|
||||||
|
+ contents = load_file(fips_proc).strip()
|
||||||
|
+ return contents == "1"
|
||||||
|
+ except (IOError, OSError):
|
||||||
|
+ # for BSD systems and Linux systems where the proc entry is not
|
||||||
|
+ # available, we assume FIPS is disabled to retain the old behavior
|
||||||
|
+ # for now.
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def pipe_in_out(in_fh, out_fh, chunk_size=1024, chunk_cb=None):
|
||||||
|
bytes_piped = 0
|
||||||
|
while True:
|
||||||
|
diff --git a/tests/unittests/config/test_cc_ssh.py b/tests/unittests/config/test_cc_ssh.py
|
||||||
|
index 66368d0f..72941a95 100644
|
||||||
|
--- a/tests/unittests/config/test_cc_ssh.py
|
||||||
|
+++ b/tests/unittests/config/test_cc_ssh.py
|
||||||
|
@@ -101,11 +101,16 @@ class TestHandleSsh:
|
||||||
|
expected_calls = [mock.call(set(keys), user)] + expected_calls
|
||||||
|
assert expected_calls == m_setup_keys.call_args_list
|
||||||
|
|
||||||
|
+ @pytest.mark.parametrize("fips_enabled", (True, False))
|
||||||
|
@mock.patch(MODPATH + "glob.glob")
|
||||||
|
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
|
||||||
|
@mock.patch(MODPATH + "os.path.exists")
|
||||||
|
- def test_handle_no_cfg(self, m_path_exists, m_nug, m_glob, m_setup_keys):
|
||||||
|
+ @mock.patch(MODPATH + "util.fips_enabled")
|
||||||
|
+ def test_handle_no_cfg(
|
||||||
|
+ self, m_fips, m_path_exists, m_nug, m_glob, m_setup_keys, fips_enabled
|
||||||
|
+ ):
|
||||||
|
"""Test handle with no config ignores generating existing keyfiles."""
|
||||||
|
+ m_fips.return_value = fips_enabled
|
||||||
|
cfg = {}
|
||||||
|
keys = ["key1"]
|
||||||
|
m_glob.return_value = [] # Return no matching keys to prevent removal
|
||||||
|
@@ -118,12 +123,22 @@ class TestHandleSsh:
|
||||||
|
options = ssh_util.DISABLE_USER_OPTS.replace("$USER", "NONE")
|
||||||
|
options = options.replace("$DISABLE_USER", "root")
|
||||||
|
m_glob.assert_called_once_with("/etc/ssh/ssh_host_*key*")
|
||||||
|
- assert [
|
||||||
|
- mock.call("/etc/ssh/ssh_host_rsa_key"),
|
||||||
|
- mock.call("/etc/ssh/ssh_host_dsa_key"),
|
||||||
|
- mock.call("/etc/ssh/ssh_host_ecdsa_key"),
|
||||||
|
- mock.call("/etc/ssh/ssh_host_ed25519_key"),
|
||||||
|
- ] in m_path_exists.call_args_list
|
||||||
|
+ m_fips.assert_called_once()
|
||||||
|
+
|
||||||
|
+ if not m_fips():
|
||||||
|
+ expected_calls = [
|
||||||
|
+ mock.call("/etc/ssh/ssh_host_rsa_key"),
|
||||||
|
+ mock.call("/etc/ssh/ssh_host_dsa_key"),
|
||||||
|
+ mock.call("/etc/ssh/ssh_host_ecdsa_key"),
|
||||||
|
+ mock.call("/etc/ssh/ssh_host_ed25519_key"),
|
||||||
|
+ ]
|
||||||
|
+ else:
|
||||||
|
+ # Enabled fips doesn't generate dsa or ed25519
|
||||||
|
+ expected_calls = [
|
||||||
|
+ mock.call("/etc/ssh/ssh_host_rsa_key"),
|
||||||
|
+ mock.call("/etc/ssh/ssh_host_ecdsa_key"),
|
||||||
|
+ ]
|
||||||
|
+ assert expected_calls in m_path_exists.call_args_list
|
||||||
|
assert [
|
||||||
|
mock.call(set(keys), "root", options=options)
|
||||||
|
] == m_setup_keys.call_args_list
|
||||||
|
@@ -131,8 +146,9 @@ class TestHandleSsh:
|
||||||
|
@mock.patch(MODPATH + "glob.glob")
|
||||||
|
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
|
||||||
|
@mock.patch(MODPATH + "os.path.exists")
|
||||||
|
+ @mock.patch(MODPATH + "util.fips_enabled", return_value=False)
|
||||||
|
def test_dont_allow_public_ssh_keys(
|
||||||
|
- self, m_path_exists, m_nug, m_glob, m_setup_keys
|
||||||
|
+ self, m_fips, m_path_exists, m_nug, m_glob, m_setup_keys
|
||||||
|
):
|
||||||
|
"""Test allow_public_ssh_keys=False ignores ssh public keys from
|
||||||
|
platform.
|
||||||
|
@@ -176,8 +192,10 @@ class TestHandleSsh:
|
||||||
|
@mock.patch(MODPATH + "glob.glob")
|
||||||
|
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
|
||||||
|
@mock.patch(MODPATH + "os.path.exists")
|
||||||
|
+ @mock.patch(MODPATH + "util.fips_enabled", return_value=False)
|
||||||
|
def test_handle_default_root(
|
||||||
|
self,
|
||||||
|
+ m_fips,
|
||||||
|
m_path_exists,
|
||||||
|
m_nug,
|
||||||
|
m_glob,
|
||||||
|
@@ -241,8 +259,10 @@ class TestHandleSsh:
|
||||||
|
@mock.patch(MODPATH + "glob.glob")
|
||||||
|
@mock.patch(MODPATH + "ug_util.normalize_users_groups")
|
||||||
|
@mock.patch(MODPATH + "os.path.exists")
|
||||||
|
+ @mock.patch(MODPATH + "util.fips_enabled", return_value=False)
|
||||||
|
def test_handle_publish_hostkeys(
|
||||||
|
self,
|
||||||
|
+ m_fips,
|
||||||
|
m_path_exists,
|
||||||
|
m_nug,
|
||||||
|
m_glob,
|
||||||
|
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
|
||||||
|
index 07142a86..17182d06 100644
|
||||||
|
--- a/tests/unittests/test_util.py
|
||||||
|
+++ b/tests/unittests/test_util.py
|
||||||
|
@@ -1945,6 +1945,31 @@ class TestGetCmdline(helpers.TestCase):
|
||||||
|
self.assertEqual("abcd 123", ret)
|
||||||
|
|
||||||
|
|
||||||
|
+class TestFipsEnabled:
|
||||||
|
+ @pytest.mark.parametrize(
|
||||||
|
+ "fips_enabled_content,expected",
|
||||||
|
+ (
|
||||||
|
+ pytest.param(None, False, id="false_when_no_fips_enabled_file"),
|
||||||
|
+ pytest.param("0\n", False, id="false_when_fips_disabled"),
|
||||||
|
+ pytest.param("1\n", True, id="true_when_fips_enabled"),
|
||||||
|
+ pytest.param("1", True, id="true_when_fips_enabled_no_newline"),
|
||||||
|
+ ),
|
||||||
|
+ )
|
||||||
|
+ @mock.patch(M_PATH + "load_file")
|
||||||
|
+ def test_fips_enabled_based_on_proc_crypto(
|
||||||
|
+ self, load_file, fips_enabled_content, expected, tmpdir
|
||||||
|
+ ):
|
||||||
|
+ def fake_load_file(path):
|
||||||
|
+ assert path == "/proc/sys/crypto/fips_enabled"
|
||||||
|
+ if fips_enabled_content is None:
|
||||||
|
+ raise IOError("No file exists Bob")
|
||||||
|
+ return fips_enabled_content
|
||||||
|
+
|
||||||
|
+ load_file.side_effect = fake_load_file
|
||||||
|
+
|
||||||
|
+ assert expected is util.fips_enabled()
|
||||||
|
+
|
||||||
|
+
|
||||||
|
class TestLoadYaml(helpers.CiTestCase):
|
||||||
|
mydefault = "7b03a8ebace993d806255121073fed52"
|
||||||
|
with_logs = True
|
@ -0,0 +1,93 @@
|
|||||||
|
From 0b0632f6c084a8ce95b53cb5125dc0f4107e6968 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 4 May 2023 15:34:43 +0530
|
||||||
|
Subject: [PATCH] Revert "Manual revert "Use Network-Manager and Netplan as
|
||||||
|
default renderers for RHEL and Fedora (#1465)""
|
||||||
|
|
||||||
|
This reverts commit ecae81f98ce230266eb99671b74534a4ede660f0.
|
||||||
|
|
||||||
|
This is patch 1 of the two patches that re-enables NM renderer. This change
|
||||||
|
can be ignored while rebasing to latest upstream.
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/net/renderers.py | 1 +
|
||||||
|
config/cloud.cfg.tmpl | 3 +++
|
||||||
|
doc/rtd/reference/network-config.rst | 16 ++++++++++++++--
|
||||||
|
3 files changed, 18 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/renderers.py b/cloudinit/net/renderers.py
|
||||||
|
index c92b9dcf..022ff938 100644
|
||||||
|
--- a/cloudinit/net/renderers.py
|
||||||
|
+++ b/cloudinit/net/renderers.py
|
||||||
|
@@ -28,6 +28,7 @@ DEFAULT_PRIORITY = [
|
||||||
|
"eni",
|
||||||
|
"sysconfig",
|
||||||
|
"netplan",
|
||||||
|
+ "network-manager",
|
||||||
|
"freebsd",
|
||||||
|
"netbsd",
|
||||||
|
"openbsd",
|
||||||
|
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
|
||||||
|
index 12f32c51..7238c102 100644
|
||||||
|
--- a/config/cloud.cfg.tmpl
|
||||||
|
+++ b/config/cloud.cfg.tmpl
|
||||||
|
@@ -381,6 +381,9 @@ system_info:
|
||||||
|
{% elif variant in ["dragonfly"] %}
|
||||||
|
network:
|
||||||
|
renderers: ['freebsd']
|
||||||
|
+{% elif variant in ["fedora"] or is_rhel %}
|
||||||
|
+ network:
|
||||||
|
+ renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
|
||||||
|
{% elif variant == "openmandriva" %}
|
||||||
|
network:
|
||||||
|
renderers: ['network-manager', 'networkd']
|
||||||
|
diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst
|
||||||
|
index bc52afa5..ea331f1c 100644
|
||||||
|
--- a/doc/rtd/reference/network-config.rst
|
||||||
|
+++ b/doc/rtd/reference/network-config.rst
|
||||||
|
@@ -176,6 +176,16 @@ this state, ``cloud-init`` delegates rendering of the configuration to
|
||||||
|
distro-supported formats. The following ``renderers`` are supported in
|
||||||
|
``cloud-init``:
|
||||||
|
|
||||||
|
+NetworkManager
|
||||||
|
+--------------
|
||||||
|
+
|
||||||
|
+`NetworkManager`_ is the standard Linux network configuration tool suite. It
|
||||||
|
+supports a wide range of networking setups. Configuration is typically stored
|
||||||
|
+in :file:`/etc/NetworkManager`.
|
||||||
|
+
|
||||||
|
+It is the default for a number of Linux distributions; notably Fedora,
|
||||||
|
+CentOS/RHEL, and their derivatives.
|
||||||
|
+
|
||||||
|
ENI
|
||||||
|
---
|
||||||
|
|
||||||
|
@@ -213,6 +223,7 @@ preference) is as follows:
|
||||||
|
- ENI
|
||||||
|
- Sysconfig
|
||||||
|
- Netplan
|
||||||
|
+- NetworkManager
|
||||||
|
- FreeBSD
|
||||||
|
- NetBSD
|
||||||
|
- OpenBSD
|
||||||
|
@@ -223,6 +234,7 @@ preference) is as follows:
|
||||||
|
|
||||||
|
- **ENI**: using ``ifup``, ``ifdown`` to manage device setup/teardown
|
||||||
|
- **Netplan**: using ``netplan apply`` to manage device setup/teardown
|
||||||
|
+- **NetworkManager**: using ``nmcli`` to manage device setup/teardown
|
||||||
|
- **Networkd**: using ``ip`` to manage device setup/teardown
|
||||||
|
|
||||||
|
When applying the policy, ``cloud-init`` checks if the current instance has the
|
||||||
|
@@ -232,8 +244,8 @@ supplying an updated configuration in cloud-config. ::
|
||||||
|
|
||||||
|
system_info:
|
||||||
|
network:
|
||||||
|
- renderers: ['netplan', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
|
||||||
|
- activators: ['eni', 'netplan', 'networkd']
|
||||||
|
+ renderers: ['netplan', 'network-manager', 'eni', 'sysconfig', 'freebsd', 'netbsd', 'openbsd']
|
||||||
|
+ activators: ['eni', 'netplan', 'network-manager', 'networkd']
|
||||||
|
|
||||||
|
Network configuration tools
|
||||||
|
===========================
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@
|
|||||||
|
From 0a2c6b6118ffaf29694b3a51aff3a33298419c50 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Mon, 15 May 2023 19:15:12 +0530
|
||||||
|
Subject: [PATCH] net/sysconfig: do not use the highest autoconnect priority
|
||||||
|
|
||||||
|
Using the highest priority is a very big hammer that we may not want to use. We
|
||||||
|
may want users to override the cloud init generated ifcfg files for custom
|
||||||
|
configuration of interfaces. If cloud init uses the highest priority, nothing
|
||||||
|
can beat it. Hence lower the priority to 120 allowing values from 121 to 999
|
||||||
|
to be used by users if they want to use a custom interface nm keyfile.
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
|
||||||
|
Suggested-by: thaller@redhat.com
|
||||||
|
fixes: c589da20eb92231 ("Setting highest autoconnect priority for network-scripts")
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/net/sysconfig.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
|
index b8786fb7..1fe82412 100644
|
||||||
|
--- a/cloudinit/net/sysconfig.py
|
||||||
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
|
@@ -317,7 +317,7 @@ class Renderer(renderer.Renderer):
|
||||||
|
"ONBOOT": True,
|
||||||
|
"USERCTL": False,
|
||||||
|
"BOOTPROTO": "none",
|
||||||
|
- "AUTOCONNECT_PRIORITY": 999
|
||||||
|
+ "AUTOCONNECT_PRIORITY": 120,
|
||||||
|
},
|
||||||
|
"suse": {"BOOTPROTO": "static", "STARTMODE": "auto"},
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
From 603ad38bca7735eeb72217b4f169a4b4c42ac092 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Tue, 16 May 2023 16:08:21 +0530
|
||||||
|
Subject: [PATCH] net/sysconfig: cosmetic - fix tox formatting
|
||||||
|
|
||||||
|
recommended cloud-init code formatting was not enforced with an older downstream
|
||||||
|
only change. This change fixes the formatting issue so that tox -e do_format
|
||||||
|
does not complain. Changes are cosmetic.
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
|
||||||
|
fixes: b3b96bff187e9d ("Do not write NM_CONTROLLED=no in generated interface config files")
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/net/sysconfig.py | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
|
index 1fe82412..fcce3e99 100644
|
||||||
|
--- a/cloudinit/net/sysconfig.py
|
||||||
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
|
@@ -1025,15 +1025,15 @@ class Renderer(renderer.Renderer):
|
||||||
|
if sysconfig_path.endswith("network"):
|
||||||
|
util.ensure_dir(os.path.dirname(sysconfig_path))
|
||||||
|
netcfg = []
|
||||||
|
- for line in util.load_file(sysconfig_path, quiet=True).split('\n'):
|
||||||
|
- if 'cloud-init' in line:
|
||||||
|
+ for line in util.load_file(sysconfig_path, quiet=True).split("\n"):
|
||||||
|
+ if "cloud-init" in line:
|
||||||
|
break
|
||||||
|
- if not line.startswith(('NETWORKING=',
|
||||||
|
- 'IPV6_AUTOCONF=',
|
||||||
|
- 'NETWORKING_IPV6=')):
|
||||||
|
+ if not line.startswith(
|
||||||
|
+ ("NETWORKING=", "IPV6_AUTOCONF=", "NETWORKING_IPV6=")
|
||||||
|
+ ):
|
||||||
|
netcfg.append(line)
|
||||||
|
# Now generate the cloud-init portion of sysconfig/network
|
||||||
|
- netcfg.extend([_make_header(), 'NETWORKING=yes'])
|
||||||
|
+ netcfg.extend([_make_header(), "NETWORKING=yes"])
|
||||||
|
if network_state.use_ipv6:
|
||||||
|
netcfg.append("NETWORKING_IPV6=yes")
|
||||||
|
netcfg.append("IPV6_AUTOCONF=no")
|
@ -0,0 +1,49 @@
|
|||||||
|
From 58d7574bca2b00d05d090c180f1345a2408cc700 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Mon, 22 May 2023 21:30:01 +0530
|
||||||
|
Subject: [PATCH] nm: generate ipv6 stateful dhcp config at par with sysconfig
|
||||||
|
(#4115)
|
||||||
|
|
||||||
|
The sysconfig renderer sets the following in the ifcfg file for IPV6 stateful
|
||||||
|
DHCP configuration:
|
||||||
|
|
||||||
|
BOOTPROTO = "dhcp"
|
||||||
|
DHCPV6C = True
|
||||||
|
IPV6INIT = True
|
||||||
|
IPV6_AUTOCONF = False
|
||||||
|
|
||||||
|
This should result in
|
||||||
|
[ipv6]
|
||||||
|
method=dhcp
|
||||||
|
|
||||||
|
in the network manager generated keyfile as DHCPV6C is set and
|
||||||
|
IPV6_AUTOCONF is not set. Unfortunately the network manager renderer
|
||||||
|
deviates from this and generates:
|
||||||
|
[ipv6]
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
in it's rendered keyfile. This change fixes this deviation and sets the
|
||||||
|
IPV6 dhcp stateful configuration in alignment with what is generated by the
|
||||||
|
sysconfig renderer.
|
||||||
|
|
||||||
|
RHBZ: 2207716
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit ea573ba6fc25fe49a6a1a322eeb5259b6238d78b)
|
||||||
|
---
|
||||||
|
cloudinit/net/network_manager.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||||
|
index 53763d15..744c0cbb 100644
|
||||||
|
--- a/cloudinit/net/network_manager.py
|
||||||
|
+++ b/cloudinit/net/network_manager.py
|
||||||
|
@@ -72,7 +72,7 @@ class NMConnection:
|
||||||
|
"dhcp6": "auto",
|
||||||
|
"ipv6_slaac": "auto",
|
||||||
|
"ipv6_dhcpv6-stateless": "auto",
|
||||||
|
- "ipv6_dhcpv6-stateful": "auto",
|
||||||
|
+ "ipv6_dhcpv6-stateful": "dhcp",
|
||||||
|
"dhcp4": "auto",
|
||||||
|
"dhcp": "auto",
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
From 018aa09f049791755dd746b533abb2464b08a92d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Mon, 22 May 2023 21:33:53 +0530
|
||||||
|
Subject: [PATCH] network_manager: add a method for ipv6 static IP
|
||||||
|
configuration (#4127)
|
||||||
|
|
||||||
|
The static IP configuration for IPv6 in the method_map is missing for
|
||||||
|
network manager renderer. This is causing cloud-init to generate a keyfile with
|
||||||
|
IPv6 method as "auto" instead of "manual". This fixes this issue.
|
||||||
|
|
||||||
|
fixes: #4126
|
||||||
|
RHBZ: 2196284
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit 5d440856cb6d2b4c908015fe4eb7227615c17c8b)
|
||||||
|
---
|
||||||
|
cloudinit/net/network_manager.py | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||||
|
index 744c0cbb..2752f52f 100644
|
||||||
|
--- a/cloudinit/net/network_manager.py
|
||||||
|
+++ b/cloudinit/net/network_manager.py
|
||||||
|
@@ -69,6 +69,7 @@ class NMConnection:
|
||||||
|
|
||||||
|
method_map = {
|
||||||
|
"static": "manual",
|
||||||
|
+ "static6": "manual",
|
||||||
|
"dhcp6": "auto",
|
||||||
|
"ipv6_slaac": "auto",
|
||||||
|
"ipv6_dhcpv6-stateless": "auto",
|
@ -0,0 +1,62 @@
|
|||||||
|
From 19adc5a0939fc1804b180333af5486e69d6af0ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Mon, 22 May 2023 22:06:28 +0530
|
||||||
|
Subject: [PATCH] net/sysconfig: enable sysconfig renderer if network manager
|
||||||
|
has ifcfg-rh plugin (#4132)
|
||||||
|
|
||||||
|
Some distributions like RHEL does not have ifup and ifdown
|
||||||
|
scripts that traditionally handled ifcfg-eth* files. Instead RHEL
|
||||||
|
uses network manager with ifcfg-rh plugin to handle ifcfg
|
||||||
|
scripts. Therefore, the sysconfig should check for the
|
||||||
|
existence of ifcfg-rh plugin in addition to checking for the
|
||||||
|
existence of ifup and ifdown scripts in order to determine if it
|
||||||
|
can handle ifcfg files. If either the plugin or ifup/ifdown scripts
|
||||||
|
are present, sysconfig renderer can be enabled.
|
||||||
|
|
||||||
|
fixes: #4131
|
||||||
|
RHBZ: 2194050
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit 009dbf85a72a9077b2267d377b2ff46639fb3def)
|
||||||
|
---
|
||||||
|
cloudinit/net/sysconfig.py | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
||||||
|
index fcce3e99..f2c7c92c 100644
|
||||||
|
--- a/cloudinit/net/sysconfig.py
|
||||||
|
+++ b/cloudinit/net/sysconfig.py
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
# This file is part of cloud-init. See LICENSE file for license information.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
+import glob
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
@@ -1059,7 +1060,25 @@ def _supported_vlan_names(rdev, vid):
|
||||||
|
def available(target=None):
|
||||||
|
if not util.system_info()["variant"] in KNOWN_DISTROS:
|
||||||
|
return False
|
||||||
|
+ if available_sysconfig(target):
|
||||||
|
+ return True
|
||||||
|
+ if available_nm_ifcfg_rh(target):
|
||||||
|
+ return True
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def available_nm_ifcfg_rh(target=None):
|
||||||
|
+ # The ifcfg-rh plugin of NetworkManager is installed.
|
||||||
|
+ # NetworkManager can handle the ifcfg files.
|
||||||
|
+ return glob.glob(
|
||||||
|
+ subp.target_path(
|
||||||
|
+ target,
|
||||||
|
+ "usr/lib*/NetworkManager/*/libnm-settings-plugin-ifcfg-rh.so",
|
||||||
|
+ )
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
|
||||||
|
+def available_sysconfig(target=None):
|
||||||
|
expected = ["ifup", "ifdown"]
|
||||||
|
search = ["/sbin", "/usr/sbin"]
|
||||||
|
for p in expected:
|
@ -0,0 +1,401 @@
|
|||||||
|
From f0cf9e52fd084c23f0552456e3b780b5c9c3313a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Tue, 23 May 2023 20:38:31 +0530
|
||||||
|
Subject: [PATCH] network-manager: Set higher autoconnect priority for nm
|
||||||
|
keyfiles (#3671)
|
||||||
|
|
||||||
|
cloud init generated keyfiles by network manager renderer for network
|
||||||
|
interfaces can sometimes conflict with existing keyfiles that are left as an
|
||||||
|
artifact of an upgrade process or are old user generated keyfiles. When two
|
||||||
|
such keyfiles are present, the existing keyfile can take precedence over the
|
||||||
|
cloud init generated keyfile making the later ineffective. Removing the old
|
||||||
|
keyfile blindly by cloud init would also not be correct since there would be
|
||||||
|
no way to enforce a different interface configuration if one needs it.
|
||||||
|
|
||||||
|
This change adds an autoconnect-priority value for cloud init generated keyfile
|
||||||
|
so that the cloud init configuration takes precedence over the existing old
|
||||||
|
keyfile configuration in the default case. The priority values range from 0
|
||||||
|
to 999. We set a value of 120 so that it would be high enough in the default
|
||||||
|
case and result in cloud init keyfile to take precedence but not too high so
|
||||||
|
that if the user generated keyfile needs to take precedence, the user can do
|
||||||
|
so by using a higher value than the one used by cloud init key file, between
|
||||||
|
the values 121 and 999.
|
||||||
|
|
||||||
|
RHBZ: 2196231
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit f663e94ac50bc518e694cbd167fdab216fcff029)
|
||||||
|
---
|
||||||
|
cloudinit/net/network_manager.py | 1 +
|
||||||
|
tests/unittests/cmd/devel/test_net_convert.py | 1 +
|
||||||
|
.../cloud-init-encc000.2653.nmconnection | 1 +
|
||||||
|
.../cloud-init-encc000.nmconnection | 1 +
|
||||||
|
.../cloud-init-zz-all-en.nmconnection | 1 +
|
||||||
|
.../cloud-init-zz-all-eth.nmconnection | 1 +
|
||||||
|
tests/unittests/test_net.py | 36 +++++++++++++++++++
|
||||||
|
7 files changed, 42 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||||
|
index 2752f52f..ca216928 100644
|
||||||
|
--- a/cloudinit/net/network_manager.py
|
||||||
|
+++ b/cloudinit/net/network_manager.py
|
||||||
|
@@ -43,6 +43,7 @@ class NMConnection:
|
||||||
|
self.config["connection"] = {
|
||||||
|
"id": f"cloud-init {con_id}",
|
||||||
|
"uuid": str(uuid.uuid5(CI_NM_UUID, con_id)),
|
||||||
|
+ "autoconnect-priority": "120",
|
||||||
|
}
|
||||||
|
|
||||||
|
# This is not actually used anywhere, but may be useful in future
|
||||||
|
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
|
index 100aa8de..71654750 100644
|
||||||
|
--- a/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
|
+++ b/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
|
@@ -74,6 +74,7 @@ SAMPLE_NETWORK_MANAGER_CONTENT = """\
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0
|
||||||
|
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||||
|
+autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=eth0
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection
|
||||||
|
index 80483d4f..f44485d2 100644
|
||||||
|
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection
|
||||||
|
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.2653.nmconnection
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
[connection]
|
||||||
|
id=cloud-init encc000.2653
|
||||||
|
uuid=116aaf19-aabc-50ea-b480-e9aee18bda59
|
||||||
|
+autoconnect-priority=120
|
||||||
|
type=vlan
|
||||||
|
interface-name=encc000.2653
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection
|
||||||
|
index 3368388d..fbdfbc65 100644
|
||||||
|
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection
|
||||||
|
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-encc000.nmconnection
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
[connection]
|
||||||
|
id=cloud-init encc000
|
||||||
|
uuid=f869ebd3-f175-5747-bf02-d0d44d687248
|
||||||
|
+autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=encc000
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection
|
||||||
|
index 16120bc1..dce56c7d 100644
|
||||||
|
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection
|
||||||
|
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-en.nmconnection
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
[connection]
|
||||||
|
id=cloud-init zz-all-en
|
||||||
|
uuid=159daec9-cba3-5101-85e7-46d831857f43
|
||||||
|
+autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=zz-all-en
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection
|
||||||
|
index df44d546..ee436bf2 100644
|
||||||
|
--- a/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection
|
||||||
|
+++ b/tests/unittests/net/artifacts/no_matching_mac/etc/NetworkManager/system-connections/cloud-init-zz-all-eth.nmconnection
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
[connection]
|
||||||
|
id=cloud-init zz-all-eth
|
||||||
|
uuid=23a83d8a-d7db-5133-a77b-e68a6ac61ec9
|
||||||
|
+autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=zz-all-eth
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||||
|
index 0f523ff8..7abe61b9 100644
|
||||||
|
--- a/tests/unittests/test_net.py
|
||||||
|
+++ b/tests/unittests/test_net.py
|
||||||
|
@@ -631,6 +631,7 @@ dns = none
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0
|
||||||
|
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||||
|
+autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -1118,6 +1119,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth1
|
||||||
|
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -1135,6 +1137,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth99
|
||||||
|
uuid=b1b88000-1f03-5360-8377-1a2205efffb4
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -1234,6 +1237,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -1364,6 +1368,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -1404,6 +1409,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -1504,6 +1510,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -1734,6 +1741,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -1845,6 +1853,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -1967,6 +1976,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -2043,6 +2053,7 @@ NETWORK_CONFIGS = {
|
||||||
|
[connection]
|
||||||
|
id=cloud-init iface0
|
||||||
|
uuid=8ddfba48-857c-5e86-ac09-1b43eae0bf70
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=iface0
|
||||||
|
|
||||||
|
@@ -2507,6 +2518,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth3
|
||||||
|
uuid=b7e95dda-7746-5bf8-bf33-6e5f3c926790
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bridge
|
||||||
|
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
|
||||||
|
@@ -2526,6 +2538,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth5
|
||||||
|
uuid=5fda13c7-9942-5e90-a41b-1d043bd725dc
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -2547,6 +2560,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init ib0
|
||||||
|
uuid=11a1dda7-78b4-5529-beba-d9b5f549ad7b
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=infiniband
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -2571,6 +2585,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init bond0.200
|
||||||
|
uuid=88984a9c-ff22-5233-9267-86315e0acaa7
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=vlan
|
||||||
|
interface-name=bond0.200
|
||||||
|
|
||||||
|
@@ -2594,6 +2609,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0
|
||||||
|
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -2611,6 +2627,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth4
|
||||||
|
uuid=e27e4959-fb50-5580-b9a4-2073554627b9
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bridge
|
||||||
|
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
|
||||||
|
@@ -2630,6 +2647,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth1
|
||||||
|
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bond
|
||||||
|
master=54317911-f840-516b-a10d-82cb4c1f075c
|
||||||
|
@@ -2649,6 +2667,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init br0
|
||||||
|
uuid=dee46ce4-af7a-5e7c-aa08-b25533ae9213
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=bridge
|
||||||
|
interface-name=br0
|
||||||
|
|
||||||
|
@@ -2680,6 +2699,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0.101
|
||||||
|
uuid=b5acec5e-db80-5935-8b02-0d5619fc42bf
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=vlan
|
||||||
|
interface-name=eth0.101
|
||||||
|
|
||||||
|
@@ -2708,6 +2728,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init bond0
|
||||||
|
uuid=54317911-f840-516b-a10d-82cb4c1f075c
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=bond
|
||||||
|
interface-name=bond0
|
||||||
|
|
||||||
|
@@ -2732,6 +2753,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth2
|
||||||
|
uuid=5559a242-3421-5fdd-896e-9cb8313d5804
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bond
|
||||||
|
master=54317911-f840-516b-a10d-82cb4c1f075c
|
||||||
|
@@ -3257,6 +3279,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init bond0s0
|
||||||
|
uuid=09d0b5b9-67e7-5577-a1af-74d1cf17a71e
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bond
|
||||||
|
master=54317911-f840-516b-a10d-82cb4c1f075c
|
||||||
|
@@ -3276,6 +3299,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init bond0s1
|
||||||
|
uuid=4d9aca96-b515-5630-ad83-d13daac7f9d0
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bond
|
||||||
|
master=54317911-f840-516b-a10d-82cb4c1f075c
|
||||||
|
@@ -3295,6 +3319,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init bond0
|
||||||
|
uuid=54317911-f840-516b-a10d-82cb4c1f075c
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=bond
|
||||||
|
interface-name=bond0
|
||||||
|
|
||||||
|
@@ -3421,6 +3446,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init en0.99
|
||||||
|
uuid=f594e2ed-f107-51df-b225-1dc530a5356b
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=vlan
|
||||||
|
interface-name=en0.99
|
||||||
|
|
||||||
|
@@ -3453,6 +3479,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init en0
|
||||||
|
uuid=e0ca478b-8d84-52ab-8fae-628482c629b5
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -3580,6 +3607,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init br0
|
||||||
|
uuid=dee46ce4-af7a-5e7c-aa08-b25533ae9213
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=bridge
|
||||||
|
interface-name=br0
|
||||||
|
|
||||||
|
@@ -3604,6 +3632,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0
|
||||||
|
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bridge
|
||||||
|
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
|
||||||
|
@@ -3628,6 +3657,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth1
|
||||||
|
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
slave-type=bridge
|
||||||
|
master=dee46ce4-af7a-5e7c-aa08-b25533ae9213
|
||||||
|
@@ -3782,6 +3812,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0
|
||||||
|
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -3804,6 +3835,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth1
|
||||||
|
uuid=3c50eb47-7260-5a6d-801d-bd4f587d6b58
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -3826,6 +3858,7 @@ iface bond0 inet6 static
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth2
|
||||||
|
uuid=5559a242-3421-5fdd-896e-9cb8313d5804
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -5688,6 +5721,7 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth1000
|
||||||
|
uuid=8c517500-0c95-5308-9c8a-3092eebc44eb
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -5742,6 +5776,7 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
[connection]
|
||||||
|
id=cloud-init interface0
|
||||||
|
uuid=8b6862ed-dbd6-5830-93f7-a91451c13828
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[user]
|
||||||
|
@@ -5778,6 +5813,7 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
[connection]
|
||||||
|
id=cloud-init eth0
|
||||||
|
uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
||||||
|
+ autoconnect-priority=120
|
||||||
|
type=ethernet
|
||||||
|
interface-name=eth0
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From 5394e28e896e9d18db6d359190bfb58dcbdb2646 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Tue, 23 May 2023 21:15:30 +0530
|
||||||
|
Subject: [PATCH] Set default renderer as sysconfig for c9s/RHEL 9
|
||||||
|
|
||||||
|
Currently, network manager is disabled on c9s and RHEL 9 and therefore
|
||||||
|
sysconfig is used as the primary renderer for network configuration on those
|
||||||
|
distribution flavors. We do not want to change this for c9s or RHEL 9 even when
|
||||||
|
network-manager renderer is re-enabled. NM was re-enabled with the following
|
||||||
|
commit:
|
||||||
|
5822f72230a58d ("Revert "Revert "Add native NetworkManager support (#1224)""")
|
||||||
|
|
||||||
|
This change bumps up the priority for sysconfig renderer so that it is used as
|
||||||
|
the primary renderer on c9s/RHEL 9 and other downstream distributions derived
|
||||||
|
from them. For c10s or RHEL 10, we might revert this change so that
|
||||||
|
network-manager again becomes the primary renderer for those distributions.
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
|
||||||
|
fixes: 0b0632f6c0 ("Revert "Manual revert "Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)")
|
||||||
|
fixes: 7703aa98b89 ("Use Network-Manager and Netplan as default renderers for RHEL and Fedora (#1465)")
|
||||||
|
|
||||||
|
RHBZ:2209349
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
config/cloud.cfg.tmpl | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
|
||||||
|
index 7238c102..22c6654c 100644
|
||||||
|
--- a/config/cloud.cfg.tmpl
|
||||||
|
+++ b/config/cloud.cfg.tmpl
|
||||||
|
@@ -383,7 +383,7 @@ system_info:
|
||||||
|
renderers: ['freebsd']
|
||||||
|
{% elif variant in ["fedora"] or is_rhel %}
|
||||||
|
network:
|
||||||
|
- renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
|
||||||
|
+ renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd']
|
||||||
|
{% elif variant == "openmandriva" %}
|
||||||
|
network:
|
||||||
|
renderers: ['network-manager', 'networkd']
|
@ -0,0 +1,25 @@
|
|||||||
|
From 86dd9b0e215a40e60a6c48401a9c04215e10cdea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 8 Jun 2023 10:19:49 +0530
|
||||||
|
Subject: [PATCH] Revert "Set default renderer as sysconfig for c9s/RHEL 9"
|
||||||
|
|
||||||
|
This reverts commit 5394e28e896e9d18db6d359190bfb58dcbdb2646.
|
||||||
|
|
||||||
|
Revert this downstream-only patch and replace it with the upstream patch.
|
||||||
|
---
|
||||||
|
config/cloud.cfg.tmpl | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
|
||||||
|
index 22c6654c..7238c102 100644
|
||||||
|
--- a/config/cloud.cfg.tmpl
|
||||||
|
+++ b/config/cloud.cfg.tmpl
|
||||||
|
@@ -383,7 +383,7 @@ system_info:
|
||||||
|
renderers: ['freebsd']
|
||||||
|
{% elif variant in ["fedora"] or is_rhel %}
|
||||||
|
network:
|
||||||
|
- renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd']
|
||||||
|
+ renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
|
||||||
|
{% elif variant == "openmandriva" %}
|
||||||
|
network:
|
||||||
|
renderers: ['network-manager', 'networkd']
|
@ -0,0 +1,35 @@
|
|||||||
|
From fd4f6d94e09ed97a4dd6aba3284d9156c16c483b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 8 Jun 2023 03:29:13 +0530
|
||||||
|
Subject: [PATCH] Set default renderer as sysconfig for centos/rhel (#4165)
|
||||||
|
|
||||||
|
Currently, network manager is disabled on c9s and therefore sysconfig is used as the primary renderer for network configuration. We do not want to change this for c9s even when network-manager renderer is re-enabled as it would mean a big behaviour change for cloud-init in the centos 9 stream.
|
||||||
|
|
||||||
|
This change bumps up the priority for sysconfig renderer so that it is used as the primary renderer on c9s and other downstream distributions derived from it. In the next major centos stream release, we may use network manager as the default renderer and make changes accordingly.
|
||||||
|
|
||||||
|
RHBZ: 2209349
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit a1f375095bd0ac8628c4fdc79538dc177bb9ff99)
|
||||||
|
---
|
||||||
|
config/cloud.cfg.tmpl | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
|
||||||
|
index 7238c102..020340f9 100644
|
||||||
|
--- a/config/cloud.cfg.tmpl
|
||||||
|
+++ b/config/cloud.cfg.tmpl
|
||||||
|
@@ -381,9 +381,12 @@ system_info:
|
||||||
|
{% elif variant in ["dragonfly"] %}
|
||||||
|
network:
|
||||||
|
renderers: ['freebsd']
|
||||||
|
-{% elif variant in ["fedora"] or is_rhel %}
|
||||||
|
+{% elif variant in ["fedora"] %}
|
||||||
|
network:
|
||||||
|
renderers: ['netplan', 'network-manager', 'networkd', 'sysconfig', 'eni']
|
||||||
|
+{% elif is_rhel %}
|
||||||
|
+ network:
|
||||||
|
+ renderers: ['sysconfig', 'eni', 'netplan', 'network-manager', 'networkd' ]
|
||||||
|
{% elif variant == "openmandriva" %}
|
||||||
|
network:
|
||||||
|
renderers: ['network-manager', 'networkd']
|
@ -0,0 +1,283 @@
|
|||||||
|
From 9eb7ef217eb03131904fb6e0c692130126334f52 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Fri, 23 Jun 2023 16:54:24 +0530
|
||||||
|
Subject: [PATCH] test fixes: remove NM_CONTROLLED=no from tests
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
fixes: b3b96bff187e9 ("Do not write NM_CONTROLLED=no in generated interface config files")
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
tests/unittests/cmd/devel/test_net_convert.py | 1 -
|
||||||
|
tests/unittests/distros/test_netconfig.py | 8 -------
|
||||||
|
tests/unittests/test_net.py | 23 -------------------
|
||||||
|
3 files changed, 32 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/cmd/devel/test_net_convert.py b/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
|
index 43e879f7..082e9656 100644
|
||||||
|
--- a/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
|
+++ b/tests/unittests/cmd/devel/test_net_convert.py
|
||||||
|
@@ -63,7 +63,6 @@ SAMPLE_SYSCONFIG_CONTENT = """\
|
||||||
|
AUTOCONNECT_PRIORITY=120
|
||||||
|
BOOTPROTO=dhcp
|
||||||
|
DEVICE=eth0
|
||||||
|
-NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py
|
||||||
|
index eaf723c8..7ac8182a 100644
|
||||||
|
--- a/tests/unittests/distros/test_netconfig.py
|
||||||
|
+++ b/tests/unittests/distros/test_netconfig.py
|
||||||
|
@@ -724,7 +724,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
GATEWAY=192.168.1.254
|
||||||
|
IPADDR=192.168.1.5
|
||||||
|
NETMASK=255.255.255.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -735,7 +734,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
AUTOCONNECT_PRIORITY=120
|
||||||
|
BOOTPROTO=dhcp
|
||||||
|
DEVICE=eth1
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -767,7 +765,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
IPV6_AUTOCONF=no
|
||||||
|
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -778,7 +775,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
AUTOCONNECT_PRIORITY=120
|
||||||
|
BOOTPROTO=dhcp
|
||||||
|
DEVICE=eth1
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -826,7 +822,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
HWADDR=00:16:3e:60:7c:df
|
||||||
|
IPADDR=192.10.1.2
|
||||||
|
NETMASK=255.255.255.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -839,7 +834,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
DEVICE=infra0
|
||||||
|
IPADDR=10.0.1.2
|
||||||
|
NETMASK=255.255.0.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
PHYSDEV=eth0
|
||||||
|
USERCTL=no
|
||||||
|
@@ -876,7 +870,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
DEVICE=eth0
|
||||||
|
IPADDR=192.10.1.2
|
||||||
|
NETMASK=255.255.255.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -889,7 +882,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase):
|
||||||
|
DEVICE=eth0.1001
|
||||||
|
IPADDR=10.0.1.2
|
||||||
|
NETMASK=255.255.0.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
PHYSDEV=eth0
|
||||||
|
USERCTL=no
|
||||||
|
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||||
|
index 1261840b..fd656a57 100644
|
||||||
|
--- a/tests/unittests/test_net.py
|
||||||
|
+++ b/tests/unittests/test_net.py
|
||||||
|
@@ -1502,7 +1502,6 @@ NETWORK_CONFIGS = {
|
||||||
|
DHCPV6C=yes
|
||||||
|
IPV6INIT=yes
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1594,7 +1593,6 @@ NETWORK_CONFIGS = {
|
||||||
|
IPV6INIT=yes
|
||||||
|
IPV6_FORCE_ACCEPT_RA=yes
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1671,7 +1669,6 @@ NETWORK_CONFIGS = {
|
||||||
|
IPV6INIT=yes
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1736,7 +1733,6 @@ NETWORK_CONFIGS = {
|
||||||
|
IPV6_AUTOCONF=yes
|
||||||
|
IPV6INIT=yes
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1792,7 +1788,6 @@ NETWORK_CONFIGS = {
|
||||||
|
IPV6_AUTOCONF=no
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1850,7 +1845,6 @@ NETWORK_CONFIGS = {
|
||||||
|
IPV6_AUTOCONF=yes
|
||||||
|
IPV6INIT=yes
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1933,7 +1927,6 @@ NETWORK_CONFIGS = {
|
||||||
|
IPV6_AUTOCONF=no
|
||||||
|
IPV6_FORCE_ACCEPT_RA=yes
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -1975,7 +1968,6 @@ NETWORK_CONFIGS = {
|
||||||
|
AUTOCONNECT_PRIORITY=120
|
||||||
|
BOOTPROTO=dhcp
|
||||||
|
DEVICE=iface0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -2053,7 +2045,6 @@ NETWORK_CONFIGS = {
|
||||||
|
BOOTPROTO=dhcp
|
||||||
|
DEVICE=iface0
|
||||||
|
ETHTOOL_OPTS="wol g"
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -2530,7 +2521,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
||||||
|
IPADDR=192.168.200.7
|
||||||
|
MTU=9000
|
||||||
|
NETMASK=255.255.255.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=InfiniBand
|
||||||
|
USERCTL=no"""
|
||||||
|
@@ -3609,7 +3599,6 @@ iface bond0 inet6 static
|
||||||
|
IPV6INIT=yes
|
||||||
|
IPV6_AUTOCONF=no
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -3626,7 +3615,6 @@ iface bond0 inet6 static
|
||||||
|
IPV6INIT=yes
|
||||||
|
IPV6_AUTOCONF=no
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -3920,7 +3908,6 @@ iface bond0 inet6 static
|
||||||
|
BOOTPROTO=none
|
||||||
|
DEVICE=eth0
|
||||||
|
HWADDR=cf:d6:af:48:e8:80
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no"""
|
||||||
|
@@ -4759,7 +4746,6 @@ HWADDR=fa:16:3e:25:b4:59
|
||||||
|
IPADDR=51.68.89.122
|
||||||
|
MTU=1500
|
||||||
|
NETMASK=255.255.240.0
|
||||||
|
-NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -4774,7 +4760,6 @@ DEVICE=eth1
|
||||||
|
DHCLIENT_SET_DEFAULT_ROUTE=no
|
||||||
|
HWADDR=fa:16:3e:b1:ca:29
|
||||||
|
MTU=9000
|
||||||
|
-NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -5027,7 +5012,6 @@ USERCTL=no
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
IPV6_DEFAULTGW=2001:db8::1
|
||||||
|
NETMASK=255.255.255.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -5060,7 +5044,6 @@ USERCTL=no
|
||||||
|
AUTOCONNECT_PRIORITY=120
|
||||||
|
BOOTPROTO=none
|
||||||
|
DEVICE=eno1
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -5074,7 +5057,6 @@ USERCTL=no
|
||||||
|
IPADDR=192.6.1.9
|
||||||
|
MTU=1495
|
||||||
|
NETMASK=255.255.255.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
PHYSDEV=eno1
|
||||||
|
USERCTL=no
|
||||||
|
@@ -5111,7 +5093,6 @@ USERCTL=no
|
||||||
|
IPADDR=10.101.8.65
|
||||||
|
MTU=1334
|
||||||
|
NETMASK=255.255.255.192
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Bond
|
||||||
|
USERCTL=no
|
||||||
|
@@ -5124,7 +5105,6 @@ USERCTL=no
|
||||||
|
BOOTPROTO=none
|
||||||
|
DEVICE=enp0s0
|
||||||
|
MASTER=bond0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
SLAVE=yes
|
||||||
|
TYPE=Bond
|
||||||
|
@@ -5138,7 +5118,6 @@ USERCTL=no
|
||||||
|
BOOTPROTO=none
|
||||||
|
DEVICE=enp0s1
|
||||||
|
MASTER=bond0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
SLAVE=yes
|
||||||
|
TYPE=Bond
|
||||||
|
@@ -5170,7 +5149,6 @@ USERCTL=no
|
||||||
|
DEVICE=eno1
|
||||||
|
HWADDR=07-1c-c6-75-a4-be
|
||||||
|
METRIC=100
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
||||||
|
@@ -5262,7 +5240,6 @@ USERCTL=no
|
||||||
|
IPV6_FORCE_ACCEPT_RA=no
|
||||||
|
MTU=1400
|
||||||
|
NETMASK=255.255.248.0
|
||||||
|
- NM_CONTROLLED=no
|
||||||
|
ONBOOT=yes
|
||||||
|
TYPE=Ethernet
|
||||||
|
USERCTL=no
|
@ -0,0 +1,58 @@
|
|||||||
|
From d39cd4de3ce41b1a1727185f2e57ec27190c23cb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Tue, 4 Jul 2023 13:58:27 +0530
|
||||||
|
Subject: [PATCH] Revert "limit permissions on def_log_file"
|
||||||
|
|
||||||
|
This reverts commit dfff374f66904e84fb07ca157ba010fac6b5f1de.
|
||||||
|
|
||||||
|
This commit seems useless and does not effectively change permission of the
|
||||||
|
log file. Remove it.
|
||||||
|
---
|
||||||
|
cloudinit/settings.py | 1 -
|
||||||
|
cloudinit/stages.py | 1 -
|
||||||
|
doc/examples/cloud-config.txt | 4 ----
|
||||||
|
3 files changed, 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
|
||||||
|
index 3d541141..edbb217d 100644
|
||||||
|
--- a/cloudinit/settings.py
|
||||||
|
+++ b/cloudinit/settings.py
|
||||||
|
@@ -52,7 +52,6 @@ CFG_BUILTIN = {
|
||||||
|
"None",
|
||||||
|
],
|
||||||
|
"def_log_file": "/var/log/cloud-init.log",
|
||||||
|
- "def_log_file_mode": 0o600,
|
||||||
|
"log_cfgs": [],
|
||||||
|
"mount_default_fields": [None, None, "auto", "defaults,nofail", "0", "2"],
|
||||||
|
"syslog_fix_perms": [],
|
||||||
|
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||||
|
index 1326d205..21f30a1f 100644
|
||||||
|
--- a/cloudinit/stages.py
|
||||||
|
+++ b/cloudinit/stages.py
|
||||||
|
@@ -202,7 +202,6 @@ class Init:
|
||||||
|
def _initialize_filesystem(self):
|
||||||
|
util.ensure_dirs(self._initial_subdirs())
|
||||||
|
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
|
||||||
|
- log_file_mode = util.get_cfg_option_int(self.cfg, "def_log_file_mode")
|
||||||
|
if log_file:
|
||||||
|
# At this point the log file should have already been created
|
||||||
|
# in the setupLogging function of log.py
|
||||||
|
diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt
|
||||||
|
index b6d16c9c..15d788f3 100644
|
||||||
|
--- a/doc/examples/cloud-config.txt
|
||||||
|
+++ b/doc/examples/cloud-config.txt
|
||||||
|
@@ -383,14 +383,10 @@ timezone: US/Eastern
|
||||||
|
# if syslog_fix_perms is a list, it will iterate through and use the
|
||||||
|
# first pair that does not raise error.
|
||||||
|
#
|
||||||
|
-# 'def_log_file' will be created with mode 'def_log_file_mode', which
|
||||||
|
-# is specified as a numeric value and defaults to 0600.
|
||||||
|
-#
|
||||||
|
# the default values are '/var/log/cloud-init.log' and 'syslog:adm'
|
||||||
|
# the value of 'def_log_file' should match what is configured in logging
|
||||||
|
# if either is empty, then no change of ownership will be done
|
||||||
|
def_log_file: /var/log/my-logging-file.log
|
||||||
|
-def_log_file_mode: 0600
|
||||||
|
syslog_fix_perms: syslog:root
|
||||||
|
|
||||||
|
# you can set passwords for a user or multiple users
|
@ -0,0 +1,43 @@
|
|||||||
|
From f1ccdbdb6c662ce67b4af74e0433a59f099d784a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Fri, 23 Jun 2023 17:54:04 +0530
|
||||||
|
Subject: [PATCH] test fixes: changes to apply RHEL specific config settings to
|
||||||
|
tests
|
||||||
|
|
||||||
|
X-downstream-only: true
|
||||||
|
fixes: c4d66915520554adedff9b ("Add initial redhat changes")
|
||||||
|
fixes: dfff374f66904e84fb07ca ("limit permissions on def_log_file")
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
tests/unittests/cmd/test_main.py | 15 +++++++++------
|
||||||
|
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/cmd/test_main.py b/tests/unittests/cmd/test_main.py
|
||||||
|
index e9ad0bb8..5d61aa2c 100644
|
||||||
|
--- a/tests/unittests/cmd/test_main.py
|
||||||
|
+++ b/tests/unittests/cmd/test_main.py
|
||||||
|
@@ -119,14 +119,17 @@ class TestMain(FilesystemMockingTestCase):
|
||||||
|
{
|
||||||
|
"def_log_file": "/var/log/cloud-init.log",
|
||||||
|
"log_cfgs": [],
|
||||||
|
- "syslog_fix_perms": [
|
||||||
|
- "syslog:adm",
|
||||||
|
- "root:adm",
|
||||||
|
- "root:wheel",
|
||||||
|
- "root:root",
|
||||||
|
- ],
|
||||||
|
"vendor_data": {"enabled": True, "prefix": []},
|
||||||
|
"vendor_data2": {"enabled": True, "prefix": []},
|
||||||
|
+ "syslog_fix_perms": [],
|
||||||
|
+ "mount_default_fields": [
|
||||||
|
+ None,
|
||||||
|
+ None,
|
||||||
|
+ "auto",
|
||||||
|
+ "defaults,nofail",
|
||||||
|
+ "0",
|
||||||
|
+ "2",
|
||||||
|
+ ],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
updated_cfg.pop("system_info")
|
@ -0,0 +1,90 @@
|
|||||||
|
From 7a530e186e791858bf70accd2fab80dd9b43ee7e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Robert Schweikert <rjschwei@suse.com>
|
||||||
|
Date: Thu, 23 Feb 2023 16:43:56 -0500
|
||||||
|
Subject: [PATCH] Enable SUSE based distros for ca handling (#2036)
|
||||||
|
|
||||||
|
CA handling in the configuration module was previously not supported
|
||||||
|
for SUSE based distros. Enable this functionality by creating the
|
||||||
|
necessary configuration settings.
|
||||||
|
|
||||||
|
Secondly update the test such that it does not bleed through to the
|
||||||
|
test system.
|
||||||
|
|
||||||
|
(cherry picked from commit 46fcd03187d70f405c748f7a6cfdb02ecb8c6ee7)
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/config/cc_ca_certs.py | 31 +++++++++++++++++++++-
|
||||||
|
tests/unittests/config/test_cc_ca_certs.py | 2 ++
|
||||||
|
2 files changed, 32 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
|
||||||
|
index 169b0e18..51b8577c 100644
|
||||||
|
--- a/cloudinit/config/cc_ca_certs.py
|
||||||
|
+++ b/cloudinit/config/cc_ca_certs.py
|
||||||
|
@@ -32,8 +32,25 @@ DISTRO_OVERRIDES = {
|
||||||
|
"ca_cert_config": None,
|
||||||
|
"ca_cert_update_cmd": ["update-ca-trust"],
|
||||||
|
},
|
||||||
|
+ "opensuse": {
|
||||||
|
+ "ca_cert_path": "/etc/pki/trust/",
|
||||||
|
+ "ca_cert_local_path": "/usr/share/pki/trust/",
|
||||||
|
+ "ca_cert_filename": "anchors/cloud-init-ca-cert-{cert_index}.crt",
|
||||||
|
+ "ca_cert_config": None,
|
||||||
|
+ "ca_cert_update_cmd": ["update-ca-certificates"],
|
||||||
|
+ },
|
||||||
|
}
|
||||||
|
|
||||||
|
+for distro in (
|
||||||
|
+ "opensuse-microos",
|
||||||
|
+ "opensuse-tumbleweed",
|
||||||
|
+ "opensuse-leap",
|
||||||
|
+ "sle_hpc",
|
||||||
|
+ "sle-micro",
|
||||||
|
+ "sles",
|
||||||
|
+):
|
||||||
|
+ DISTRO_OVERRIDES[distro] = DISTRO_OVERRIDES["opensuse"]
|
||||||
|
+
|
||||||
|
MODULE_DESCRIPTION = """\
|
||||||
|
This module adds CA certificates to the system's CA store and updates any
|
||||||
|
related files using the appropriate OS-specific utility. The default CA
|
||||||
|
@@ -48,7 +65,19 @@ configuration option ``remove_defaults``.
|
||||||
|
Alpine Linux requires the ca-certificates package to be installed in
|
||||||
|
order to provide the ``update-ca-certificates`` command.
|
||||||
|
"""
|
||||||
|
-distros = ["alpine", "debian", "rhel", "ubuntu"]
|
||||||
|
+distros = [
|
||||||
|
+ "alpine",
|
||||||
|
+ "debian",
|
||||||
|
+ "rhel",
|
||||||
|
+ "opensuse",
|
||||||
|
+ "opensuse-microos",
|
||||||
|
+ "opensuse-tumbleweed",
|
||||||
|
+ "opensuse-leap",
|
||||||
|
+ "sle_hpc",
|
||||||
|
+ "sle-micro",
|
||||||
|
+ "sles",
|
||||||
|
+ "ubuntu",
|
||||||
|
+]
|
||||||
|
|
||||||
|
meta: MetaSchema = {
|
||||||
|
"id": "cc_ca_certs",
|
||||||
|
diff --git a/tests/unittests/config/test_cc_ca_certs.py b/tests/unittests/config/test_cc_ca_certs.py
|
||||||
|
index 19e5d422..6db17485 100644
|
||||||
|
--- a/tests/unittests/config/test_cc_ca_certs.py
|
||||||
|
+++ b/tests/unittests/config/test_cc_ca_certs.py
|
||||||
|
@@ -311,6 +311,7 @@ class TestRemoveDefaultCaCerts(TestCase):
|
||||||
|
"cloud_dir": tmpdir,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
+ self.add_patch("cloudinit.config.cc_ca_certs.os.stat", "m_stat")
|
||||||
|
|
||||||
|
def test_commands(self):
|
||||||
|
ca_certs_content = "# line1\nline2\nline3\n"
|
||||||
|
@@ -318,6 +319,7 @@ class TestRemoveDefaultCaCerts(TestCase):
|
||||||
|
"# line1\n# Modified by cloud-init to deselect certs due to"
|
||||||
|
" user-data\n!line2\n!line3\n"
|
||||||
|
)
|
||||||
|
+ self.m_stat.return_value.st_size = 1
|
||||||
|
|
||||||
|
for distro_name in cc_ca_certs.distros:
|
||||||
|
conf = cc_ca_certs._distro_ca_certs_configs(distro_name)
|
@ -0,0 +1,85 @@
|
|||||||
|
From add770c442088c0915bdefad2a7438f9a38596c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Shreenidhi Shedi <53473811+sshedi@users.noreply.github.com>
|
||||||
|
Date: Fri, 17 Mar 2023 03:01:22 +0530
|
||||||
|
Subject: [PATCH] Handle non existent ca-cert-config situation (#2073)
|
||||||
|
|
||||||
|
Currently if a cert file doesn't exist, cc_ca_certs module crashes
|
||||||
|
This fix makes it possible to handle it gracefully.
|
||||||
|
|
||||||
|
Also, out_lines variable may not be available if os.stat returns 0.
|
||||||
|
This issue is also taken care of.
|
||||||
|
|
||||||
|
Added tests for the same.
|
||||||
|
|
||||||
|
(cherry picked from commit 3634678465e7b8f8608bcb9a1f5773ae7837cbe9)
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/config/cc_ca_certs.py | 19 +++++++++++++------
|
||||||
|
tests/unittests/config/test_cc_ca_certs.py | 12 ++++++++++++
|
||||||
|
2 files changed, 25 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/config/cc_ca_certs.py b/cloudinit/config/cc_ca_certs.py
|
||||||
|
index 51b8577c..4dc08681 100644
|
||||||
|
--- a/cloudinit/config/cc_ca_certs.py
|
||||||
|
+++ b/cloudinit/config/cc_ca_certs.py
|
||||||
|
@@ -177,14 +177,20 @@ def disable_system_ca_certs(distro_cfg):
|
||||||
|
|
||||||
|
@param distro_cfg: A hash providing _distro_ca_certs_configs function.
|
||||||
|
"""
|
||||||
|
- if distro_cfg["ca_cert_config"] is None:
|
||||||
|
+
|
||||||
|
+ ca_cert_cfg_fn = distro_cfg["ca_cert_config"]
|
||||||
|
+
|
||||||
|
+ if not ca_cert_cfg_fn or not os.path.exists(ca_cert_cfg_fn):
|
||||||
|
return
|
||||||
|
+
|
||||||
|
header_comment = (
|
||||||
|
"# Modified by cloud-init to deselect certs due to user-data"
|
||||||
|
)
|
||||||
|
+
|
||||||
|
added_header = False
|
||||||
|
- if os.stat(distro_cfg["ca_cert_config"]).st_size != 0:
|
||||||
|
- orig = util.load_file(distro_cfg["ca_cert_config"])
|
||||||
|
+
|
||||||
|
+ if os.stat(ca_cert_cfg_fn).st_size:
|
||||||
|
+ orig = util.load_file(ca_cert_cfg_fn)
|
||||||
|
out_lines = []
|
||||||
|
for line in orig.splitlines():
|
||||||
|
if line == header_comment:
|
||||||
|
@@ -197,9 +203,10 @@ def disable_system_ca_certs(distro_cfg):
|
||||||
|
out_lines.append(header_comment)
|
||||||
|
added_header = True
|
||||||
|
out_lines.append("!" + line)
|
||||||
|
- util.write_file(
|
||||||
|
- distro_cfg["ca_cert_config"], "\n".join(out_lines) + "\n", omode="wb"
|
||||||
|
- )
|
||||||
|
+
|
||||||
|
+ util.write_file(
|
||||||
|
+ ca_cert_cfg_fn, "\n".join(out_lines) + "\n", omode="wb"
|
||||||
|
+ )
|
||||||
|
|
||||||
|
|
||||||
|
def remove_default_ca_certs(distro_cfg):
|
||||||
|
diff --git a/tests/unittests/config/test_cc_ca_certs.py b/tests/unittests/config/test_cc_ca_certs.py
|
||||||
|
index 6db17485..5f1894e7 100644
|
||||||
|
--- a/tests/unittests/config/test_cc_ca_certs.py
|
||||||
|
+++ b/tests/unittests/config/test_cc_ca_certs.py
|
||||||
|
@@ -365,6 +365,18 @@ class TestRemoveDefaultCaCerts(TestCase):
|
||||||
|
else:
|
||||||
|
assert mock_subp.call_count == 0
|
||||||
|
|
||||||
|
+ def test_non_existent_cert_cfg(self):
|
||||||
|
+ self.m_stat.return_value.st_size = 0
|
||||||
|
+
|
||||||
|
+ for distro_name in cc_ca_certs.distros:
|
||||||
|
+ conf = cc_ca_certs._distro_ca_certs_configs(distro_name)
|
||||||
|
+ with ExitStack() as mocks:
|
||||||
|
+ mocks.enter_context(
|
||||||
|
+ mock.patch.object(util, "delete_dir_contents")
|
||||||
|
+ )
|
||||||
|
+ mocks.enter_context(mock.patch.object(subp, "subp"))
|
||||||
|
+ cc_ca_certs.disable_default_ca_certs(distro_name, conf)
|
||||||
|
+
|
||||||
|
|
||||||
|
class TestCACertsSchema:
|
||||||
|
"""Directly test schema rather than through handle."""
|
@ -0,0 +1,172 @@
|
|||||||
|
From 1cecfe4bc3d7e4806d1890615a119e478decd5fd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 20 Jul 2023 23:56:01 +0530
|
||||||
|
Subject: [PATCH] logging: keep current file mode of log file if its stricter
|
||||||
|
than the new mode (#4250)
|
||||||
|
|
||||||
|
By default, the cloud init log file is created with mode 0o644 with
|
||||||
|
`preserve_mode` parameter of `write_file()` set to False. This means that when
|
||||||
|
an existing log file is found, its mode will be unconditionally reset to the
|
||||||
|
mode 0o644. It is possible that this might cause the change of the mode of the
|
||||||
|
log file from the current more stricter mode to a less strict mode
|
||||||
|
(when the new mode 0o644 is less strict than the existing mode of the file).
|
||||||
|
|
||||||
|
In order to mitigate the above issue, check the current mode of the log file
|
||||||
|
and if the current mode is stricter than the default new mode 0o644, then
|
||||||
|
preserve the current mode of the file.
|
||||||
|
|
||||||
|
Fixes GH-4243
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit a0e4ec15a1adffabd1c539879514eae4807c834c)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
tests/unittests/test_util.py
|
||||||
|
---
|
||||||
|
cloudinit/stages.py | 15 ++++++++++++++-
|
||||||
|
cloudinit/util.py | 23 +++++++++++++++++++++++
|
||||||
|
tests/unittests/test_stages.py | 23 ++++++++++++++++-------
|
||||||
|
tests/unittests/test_util.py | 24 ++++++++++++++++++++++++
|
||||||
|
4 files changed, 77 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
||||||
|
index 21f30a1f..979179af 100644
|
||||||
|
--- a/cloudinit/stages.py
|
||||||
|
+++ b/cloudinit/stages.py
|
||||||
|
@@ -200,12 +200,25 @@ class Init:
|
||||||
|
self._initialize_filesystem()
|
||||||
|
|
||||||
|
def _initialize_filesystem(self):
|
||||||
|
+ mode = 0o640
|
||||||
|
+ fmode = None
|
||||||
|
+
|
||||||
|
util.ensure_dirs(self._initial_subdirs())
|
||||||
|
log_file = util.get_cfg_option_str(self.cfg, "def_log_file")
|
||||||
|
if log_file:
|
||||||
|
# At this point the log file should have already been created
|
||||||
|
# in the setupLogging function of log.py
|
||||||
|
- util.ensure_file(log_file, mode=0o640, preserve_mode=False)
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ fmode = util.get_permissions(log_file)
|
||||||
|
+ except OSError:
|
||||||
|
+ pass
|
||||||
|
+
|
||||||
|
+ # if existing file mode fmode is stricter, do not change it.
|
||||||
|
+ if fmode and util.compare_permission(fmode, mode) < 0:
|
||||||
|
+ mode = fmode
|
||||||
|
+
|
||||||
|
+ util.ensure_file(log_file, mode, preserve_mode=False)
|
||||||
|
perms = self.cfg.get("syslog_fix_perms")
|
||||||
|
if not perms:
|
||||||
|
perms = {}
|
||||||
|
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
||||||
|
index 4a8e3d3b..af617e73 100644
|
||||||
|
--- a/cloudinit/util.py
|
||||||
|
+++ b/cloudinit/util.py
|
||||||
|
@@ -2099,6 +2099,29 @@ def safe_int(possible_int):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
+def compare_permission(mode1, mode2):
|
||||||
|
+ """Compare two file modes in octal.
|
||||||
|
+
|
||||||
|
+ If mode1 is less restrictive than mode2 return 1
|
||||||
|
+ If mode1 is more restrictive than mode2 return -1
|
||||||
|
+ If mode1 is same as mode2, return 0
|
||||||
|
+
|
||||||
|
+ The comparison starts from the permission of the
|
||||||
|
+ set of users in "others" and then works up to the
|
||||||
|
+ permission of "user" set.
|
||||||
|
+ """
|
||||||
|
+ # Convert modes to octal and reverse the last 3 digits
|
||||||
|
+ # so 0o640 would be become 0o046
|
||||||
|
+ mode1_oct = oct(mode1)[2:].rjust(3, "0")
|
||||||
|
+ mode2_oct = oct(mode2)[2:].rjust(3, "0")
|
||||||
|
+ m1 = int(mode1_oct[:-3] + mode1_oct[-3:][::-1], 8)
|
||||||
|
+ m2 = int(mode2_oct[:-3] + mode2_oct[-3:][::-1], 8)
|
||||||
|
+
|
||||||
|
+ # Then do a traditional cmp()
|
||||||
|
+ # https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
|
||||||
|
+ return (m1 > m2) - (m1 < m2)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def chmod(path, mode):
|
||||||
|
real_mode = safe_int(mode)
|
||||||
|
if path and real_mode:
|
||||||
|
diff --git a/tests/unittests/test_stages.py b/tests/unittests/test_stages.py
|
||||||
|
index a61f9df9..831ea9f2 100644
|
||||||
|
--- a/tests/unittests/test_stages.py
|
||||||
|
+++ b/tests/unittests/test_stages.py
|
||||||
|
@@ -606,13 +606,22 @@ class TestInit_InitializeFilesystem:
|
||||||
|
# Assert we create it 0o640 by default if it doesn't already exist
|
||||||
|
assert 0o640 == stat.S_IMODE(log_file.stat().mode)
|
||||||
|
|
||||||
|
- def test_existing_file_permissions(self, init, tmpdir):
|
||||||
|
+ @pytest.mark.parametrize(
|
||||||
|
+ "set_perms,expected_perms",
|
||||||
|
+ [
|
||||||
|
+ (0o640, 0o640),
|
||||||
|
+ (0o606, 0o640),
|
||||||
|
+ (0o600, 0o600),
|
||||||
|
+ ],
|
||||||
|
+ )
|
||||||
|
+ def test_existing_file_permissions(
|
||||||
|
+ self, init, tmpdir, set_perms, expected_perms
|
||||||
|
+ ):
|
||||||
|
"""Test file permissions are set as expected.
|
||||||
|
|
||||||
|
- CIS Hardening requires 640 permissions. These permissions are
|
||||||
|
- currently hardcoded on every boot, but if there's ever a reason
|
||||||
|
- to change this, we need to then ensure that they
|
||||||
|
- are *not* set every boot.
|
||||||
|
+ CIS Hardening requires 640 permissions. If the file has looser
|
||||||
|
+ permissions, then hard code 640. If the file has tighter
|
||||||
|
+ permissions, then leave them as they are
|
||||||
|
|
||||||
|
See https://bugs.launchpad.net/cloud-init/+bug/1900837.
|
||||||
|
"""
|
||||||
|
@@ -620,9 +629,9 @@ class TestInit_InitializeFilesystem:
|
||||||
|
log_file.ensure()
|
||||||
|
# Use a mode that will never be made the default so this test will
|
||||||
|
# always be valid
|
||||||
|
- log_file.chmod(0o606)
|
||||||
|
+ log_file.chmod(set_perms)
|
||||||
|
init._cfg = {"def_log_file": str(log_file)}
|
||||||
|
|
||||||
|
init._initialize_filesystem()
|
||||||
|
|
||||||
|
- assert 0o640 == stat.S_IMODE(log_file.stat().mode)
|
||||||
|
+ assert expected_perms == stat.S_IMODE(log_file.stat().mode)
|
||||||
|
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
|
||||||
|
index 17182d06..289a4234 100644
|
||||||
|
--- a/tests/unittests/test_util.py
|
||||||
|
+++ b/tests/unittests/test_util.py
|
||||||
|
@@ -3051,3 +3051,27 @@ class TestVersion:
|
||||||
|
)
|
||||||
|
def test_from_str(self, str_ver, cls_ver):
|
||||||
|
assert util.Version.from_str(str_ver) == cls_ver
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestComparePermissions:
|
||||||
|
+ @pytest.mark.parametrize(
|
||||||
|
+ "perm1,perm2,expected",
|
||||||
|
+ [
|
||||||
|
+ (0o777, 0o777, 0),
|
||||||
|
+ (0o000, 0o000, 0),
|
||||||
|
+ (0o421, 0o421, 0),
|
||||||
|
+ (0o1640, 0o1640, 0),
|
||||||
|
+ (0o1407, 0o1600, 1),
|
||||||
|
+ (0o1600, 0o1407, -1),
|
||||||
|
+ (0o407, 0o600, 1),
|
||||||
|
+ (0o600, 0o407, -1),
|
||||||
|
+ (0o007, 0o700, 1),
|
||||||
|
+ (0o700, 0o007, -1),
|
||||||
|
+ (0o077, 0o100, 1),
|
||||||
|
+ (0o644, 0o640, 1),
|
||||||
|
+ (0o640, 0o600, 1),
|
||||||
|
+ (0o600, 0o400, 1),
|
||||||
|
+ ],
|
||||||
|
+ )
|
||||||
|
+ def test_compare_permissions(self, perm1, perm2, expected):
|
||||||
|
+ assert util.compare_permission(perm1, perm2) == expected
|
@ -0,0 +1,62 @@
|
|||||||
|
From 25ac8bb44af554a040f0dfa9b52e9241a33a4845 Mon Sep 17 00:00:00 2001
|
||||||
|
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
||||||
|
Date: Tue, 25 Jul 2023 05:21:46 +0800
|
||||||
|
Subject: [PATCH] DS VMware: modify a few log level (#4284)
|
||||||
|
|
||||||
|
Multiple ip addresses are common scenario for modern Linux, so set
|
||||||
|
debug log level for such cases.
|
||||||
|
|
||||||
|
(cherry picked from commit 4a6a9d3f6c8fe213c51f6c1336f1dd378bf4bdca)
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
---
|
||||||
|
cloudinit/sources/DataSourceVMware.py | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
|
||||||
|
index 07a80222..bc3b5a5f 100644
|
||||||
|
--- a/cloudinit/sources/DataSourceVMware.py
|
||||||
|
+++ b/cloudinit/sources/DataSourceVMware.py
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
# Cloud-Init DataSource for VMware
|
||||||
|
#
|
||||||
|
-# Copyright (c) 2018-2022 VMware, Inc. All Rights Reserved.
|
||||||
|
+# Copyright (c) 2018-2023 VMware, Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Authors: Anish Swaminathan <anishs@vmware.com>
|
||||||
|
# Andrew Kutz <akutz@vmware.com>
|
||||||
|
@@ -719,7 +719,7 @@ def get_default_ip_addrs():
|
||||||
|
af_inet4 = addr4_fams.get(netifaces.AF_INET)
|
||||||
|
if af_inet4:
|
||||||
|
if len(af_inet4) > 1:
|
||||||
|
- LOG.warning(
|
||||||
|
+ LOG.debug(
|
||||||
|
"device %s has more than one ipv4 address: %s",
|
||||||
|
dev4,
|
||||||
|
af_inet4,
|
||||||
|
@@ -737,7 +737,7 @@ def get_default_ip_addrs():
|
||||||
|
af_inet6 = addr6_fams.get(netifaces.AF_INET6)
|
||||||
|
if af_inet6:
|
||||||
|
if len(af_inet6) > 1:
|
||||||
|
- LOG.warning(
|
||||||
|
+ LOG.debug(
|
||||||
|
"device %s has more than one ipv6 address: %s",
|
||||||
|
dev6,
|
||||||
|
af_inet6,
|
||||||
|
@@ -752,7 +752,7 @@ def get_default_ip_addrs():
|
||||||
|
af_inet6 = addr4_fams.get(netifaces.AF_INET6)
|
||||||
|
if af_inet6:
|
||||||
|
if len(af_inet6) > 1:
|
||||||
|
- LOG.warning(
|
||||||
|
+ LOG.debug(
|
||||||
|
"device %s has more than one ipv6 address: %s",
|
||||||
|
dev4,
|
||||||
|
af_inet6,
|
||||||
|
@@ -767,7 +767,7 @@ def get_default_ip_addrs():
|
||||||
|
af_inet4 = addr6_fams.get(netifaces.AF_INET)
|
||||||
|
if af_inet4:
|
||||||
|
if len(af_inet4) > 1:
|
||||||
|
- LOG.warning(
|
||||||
|
+ LOG.debug(
|
||||||
|
"device %s has more than one ipv4 address: %s",
|
||||||
|
dev6,
|
||||||
|
af_inet4,
|
@ -0,0 +1,283 @@
|
|||||||
|
From c720ab9703752535767691a31e4720e11674bb1f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Fri, 4 Aug 2023 08:58:26 +0530
|
||||||
|
Subject: [PATCH] NM renderer: set default IPv6 addr-gen-mode for all
|
||||||
|
interfaces to eui64 (#4291)
|
||||||
|
|
||||||
|
By default, NetworkManager renderer in cloud-init does not set any specific
|
||||||
|
method for IPV6 addr-gen-mode in the keyfiles it writes. Hence, implicitly the
|
||||||
|
mode is set to `eui64` in the absence of any global addr-gen-mode option in
|
||||||
|
NetworkManager configuration.
|
||||||
|
Later when other interfaces get added via D-Bus API or by using nmcli commands
|
||||||
|
without explictly setting an addr-gen-mode, NM auto generates new profiles for
|
||||||
|
those interfaces with addr-gen-mode set to `stable-privacy`. This introduces
|
||||||
|
inconsistency of configurations between interfaces based on how they were
|
||||||
|
added. This can cause problems for the customers.
|
||||||
|
|
||||||
|
In this change, cloud-init overrides NetworkManager's preferred default of
|
||||||
|
`stable-privacy` to use EUI64 using a drop in NetworkManager configuration
|
||||||
|
file. This setting can be overriden by using global-connection-defaults
|
||||||
|
setting in /etc/NetworkManager/NetworkManager.conf file.
|
||||||
|
|
||||||
|
RHBZ: 2188388
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit d41264cb4297a4b143a23f3677d33b81fbfc6e8e)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
tests/unittests/test_net.py
|
||||||
|
---
|
||||||
|
cloudinit/net/network_manager.py | 21 ++++++++
|
||||||
|
tests/unittests/test_net.py | 91 +++++++++++++++++++++++++-------
|
||||||
|
2 files changed, 94 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
||||||
|
index ca216928..8047f796 100644
|
||||||
|
--- a/cloudinit/net/network_manager.py
|
||||||
|
+++ b/cloudinit/net/network_manager.py
|
||||||
|
@@ -21,6 +21,15 @@ from cloudinit.net.network_state import NetworkState
|
||||||
|
NM_RUN_DIR = "/etc/NetworkManager"
|
||||||
|
NM_LIB_DIR = "/usr/lib/NetworkManager"
|
||||||
|
NM_CFG_FILE = "/etc/NetworkManager/NetworkManager.conf"
|
||||||
|
+NM_IPV6_ADDR_GEN_CONF = """# This is generated by cloud-init. Do not edit.
|
||||||
|
+#
|
||||||
|
+[.config]
|
||||||
|
+ enable=nm-version-min:1.40
|
||||||
|
+[connection.30-cloud-init-ip6-addr-gen-mode]
|
||||||
|
+ # Select EUI64 to be used if the profile does not specify it.
|
||||||
|
+ ipv6.addr-gen-mode=0
|
||||||
|
+
|
||||||
|
+"""
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -368,6 +377,12 @@ class Renderer(renderer.Renderer):
|
||||||
|
name = conn_filename(con_id, target)
|
||||||
|
util.write_file(name, conn.dump(), 0o600)
|
||||||
|
|
||||||
|
+ # Select EUI64 to be used by default by NM for creating the address
|
||||||
|
+ # for use with RFC4862 IPv6 Stateless Address Autoconfiguration.
|
||||||
|
+ util.write_file(
|
||||||
|
+ cloud_init_nm_conf_filename(target), NM_IPV6_ADDR_GEN_CONF, 0o600
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
|
||||||
|
def conn_filename(con_id, target=None):
|
||||||
|
target_con_dir = subp.target_path(target, NM_RUN_DIR)
|
||||||
|
@@ -375,6 +390,12 @@ def conn_filename(con_id, target=None):
|
||||||
|
return f"{target_con_dir}/system-connections/{con_file}"
|
||||||
|
|
||||||
|
|
||||||
|
+def cloud_init_nm_conf_filename(target=None):
|
||||||
|
+ target_con_dir = subp.target_path(target, NM_RUN_DIR)
|
||||||
|
+ conf_file = "30-cloud-init-ip6-addr-gen-mode.conf"
|
||||||
|
+ return f"{target_con_dir}/conf.d/{conf_file}"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def available(target=None):
|
||||||
|
# TODO: Move `uses_systemd` to a more appropriate location
|
||||||
|
# It is imported here to avoid circular import
|
||||||
|
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
||||||
|
index fd656a57..d49da696 100644
|
||||||
|
--- a/tests/unittests/test_net.py
|
||||||
|
+++ b/tests/unittests/test_net.py
|
||||||
|
@@ -5679,9 +5679,25 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
with_logs = True
|
||||||
|
|
||||||
|
scripts_dir = "/etc/NetworkManager/system-connections"
|
||||||
|
+ conf_dir = "/etc/NetworkManager/conf.d"
|
||||||
|
|
||||||
|
expected_name = "expected_network_manager"
|
||||||
|
|
||||||
|
+ expected_conf_d = {
|
||||||
|
+ "30-cloud-init-ip6-addr-gen-mode.conf": textwrap.dedent(
|
||||||
|
+ """\
|
||||||
|
+ # This is generated by cloud-init. Do not edit.
|
||||||
|
+ #
|
||||||
|
+ [.config]
|
||||||
|
+ enable=nm-version-min:1.40
|
||||||
|
+ [connection.30-cloud-init-ip6-addr-gen-mode]
|
||||||
|
+ # Select EUI64 to be used if the profile does not specify it.
|
||||||
|
+ ipv6.addr-gen-mode=0
|
||||||
|
+
|
||||||
|
+ """
|
||||||
|
+ ),
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
def _get_renderer(self):
|
||||||
|
return network_manager.Renderer()
|
||||||
|
|
||||||
|
@@ -5700,11 +5716,19 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
renderer.render_network_state(ns, target=dir)
|
||||||
|
return dir2dict(dir)
|
||||||
|
|
||||||
|
- def _compare_files_to_expected(self, expected, found):
|
||||||
|
+ def _compare_files_to_expected(
|
||||||
|
+ self, expected_scripts, expected_conf, found
|
||||||
|
+ ):
|
||||||
|
orig_maxdiff = self.maxDiff
|
||||||
|
- expected_d = dict(
|
||||||
|
- (os.path.join(self.scripts_dir, k), v) for k, v in expected.items()
|
||||||
|
+ conf_d = dict(
|
||||||
|
+ (os.path.join(self.conf_dir, k), v)
|
||||||
|
+ for k, v in expected_conf.items()
|
||||||
|
+ )
|
||||||
|
+ scripts_d = dict(
|
||||||
|
+ (os.path.join(self.scripts_dir, k), v)
|
||||||
|
+ for k, v in expected_scripts.items()
|
||||||
|
)
|
||||||
|
+ expected_d = {**conf_d, **scripts_d}
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.maxDiff = None
|
||||||
|
@@ -5765,6 +5789,7 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
},
|
||||||
|
+ self.expected_conf_d,
|
||||||
|
found,
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -5820,8 +5845,9 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
gateway=10.0.2.2
|
||||||
|
|
||||||
|
"""
|
||||||
|
- ),
|
||||||
|
+ )
|
||||||
|
},
|
||||||
|
+ self.expected_conf_d,
|
||||||
|
found,
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -5857,33 +5883,44 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
},
|
||||||
|
+ self.expected_conf_d,
|
||||||
|
found,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_bond_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["bond"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_vlan_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["vlan"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_bridge_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["bridge"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_manual_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["manual"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_all_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["all"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
self.assertNotIn(
|
||||||
|
"WARNING: Network config: ignoring eth0.101 device-level mtu",
|
||||||
|
self.logs.getvalue(),
|
||||||
|
@@ -5892,12 +5929,16 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
def test_small_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["small"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_v4_and_v6_static_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["v4_and_v6_static"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
expected_msg = (
|
||||||
|
"WARNING: Network config: ignoring iface0 device-level mtu:8999"
|
||||||
|
" because ipv4 subnet-level mtu:9000 provided."
|
||||||
|
@@ -5907,41 +5948,55 @@ class TestNetworkManagerRendering(CiTestCase):
|
||||||
|
def test_dhcpv6_only_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["dhcpv6_only"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_simple_render_ipv6_slaac(self):
|
||||||
|
entry = NETWORK_CONFIGS["ipv6_slaac"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_dhcpv6_stateless_config(self):
|
||||||
|
entry = NETWORK_CONFIGS["dhcpv6_stateless"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_wakeonlan_disabled_config_v2(self):
|
||||||
|
entry = NETWORK_CONFIGS["wakeonlan_disabled"]
|
||||||
|
found = self._render_and_read(
|
||||||
|
network_config=yaml.load(entry["yaml_v2"])
|
||||||
|
)
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_wakeonlan_enabled_config_v2(self):
|
||||||
|
entry = NETWORK_CONFIGS["wakeonlan_enabled"]
|
||||||
|
found = self._render_and_read(
|
||||||
|
network_config=yaml.load(entry["yaml_v2"])
|
||||||
|
)
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_render_v4_and_v6(self):
|
||||||
|
entry = NETWORK_CONFIGS["v4_and_v6"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
def test_render_v6_and_v4(self):
|
||||||
|
entry = NETWORK_CONFIGS["v6_and_v4"]
|
||||||
|
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
||||||
|
- self._compare_files_to_expected(entry[self.expected_name], found)
|
||||||
|
+ self._compare_files_to_expected(
|
||||||
|
+ entry[self.expected_name], self.expected_conf_d, found
|
||||||
|
+ )
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch(
|
@ -0,0 +1,121 @@
|
|||||||
|
From d5d350b8259a9fb55fdd119459442c9f5ac69596 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Falcon <james.falcon@canonical.com>
|
||||||
|
Date: Mon, 27 Mar 2023 15:02:41 -0500
|
||||||
|
Subject: [PATCH] Fix Python 3.12 unit test failures (#2099)
|
||||||
|
|
||||||
|
(cherry picked from commit e3f1ec3f57cc1f5eacff9506d285007966414481)
|
||||||
|
---
|
||||||
|
tests/unittests/net/test_dhcp.py | 2 +-
|
||||||
|
tests/unittests/test_util.py | 38 +++++++++++++++++---------------
|
||||||
|
2 files changed, 21 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py
|
||||||
|
index 40340553..1e43ec14 100644
|
||||||
|
--- a/tests/unittests/net/test_dhcp.py
|
||||||
|
+++ b/tests/unittests/net/test_dhcp.py
|
||||||
|
@@ -705,7 +705,7 @@ class TestEphemeralDhcpNoNetworkSetup(ResponsesTestCase):
|
||||||
|
) as lease:
|
||||||
|
self.assertEqual(fake_lease, lease)
|
||||||
|
# Ensure that dhcp discovery occurs
|
||||||
|
- m_dhcp.called_once_with()
|
||||||
|
+ m_dhcp.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
|
||||||
|
index 289a4234..7b61ec3d 100644
|
||||||
|
--- a/tests/unittests/test_util.py
|
||||||
|
+++ b/tests/unittests/test_util.py
|
||||||
|
@@ -854,64 +854,66 @@ class TestBlkid(CiTestCase):
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-@mock.patch("cloudinit.subp.which")
|
||||||
|
-@mock.patch("cloudinit.subp.subp")
|
||||||
|
+@mock.patch("cloudinit.util.subp.which")
|
||||||
|
+@mock.patch("cloudinit.util.subp.subp")
|
||||||
|
class TestUdevadmSettle(CiTestCase):
|
||||||
|
- def test_with_no_params(self, m_which, m_subp):
|
||||||
|
+ def test_with_no_params(self, m_subp, m_which):
|
||||||
|
"""called with no parameters."""
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
util.udevadm_settle()
|
||||||
|
- m_subp.called_once_with(mock.call(["udevadm", "settle"]))
|
||||||
|
+ m_subp.assert_called_once_with(["udevadm", "settle"])
|
||||||
|
|
||||||
|
- def test_udevadm_not_present(self, m_which, m_subp):
|
||||||
|
+ def test_udevadm_not_present(self, m_subp, m_which):
|
||||||
|
"""where udevadm program does not exist should not invoke subp."""
|
||||||
|
m_which.side_effect = lambda m: m in ("",)
|
||||||
|
util.udevadm_settle()
|
||||||
|
- m_subp.called_once_with(["which", "udevadm"])
|
||||||
|
+ m_which.assert_called_once_with("udevadm")
|
||||||
|
+ m_subp.assert_not_called()
|
||||||
|
|
||||||
|
- def test_with_exists_and_not_exists(self, m_which, m_subp):
|
||||||
|
+ def test_with_exists_and_not_exists(self, m_subp, m_which):
|
||||||
|
"""with exists=file where file does not exist should invoke subp."""
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
mydev = self.tmp_path("mydev")
|
||||||
|
util.udevadm_settle(exists=mydev)
|
||||||
|
- m_subp.called_once_with(
|
||||||
|
+ m_subp.assert_called_once_with(
|
||||||
|
["udevadm", "settle", "--exit-if-exists=%s" % mydev]
|
||||||
|
)
|
||||||
|
|
||||||
|
- def test_with_exists_and_file_exists(self, m_which, m_subp):
|
||||||
|
+ def test_with_exists_and_file_exists(self, m_subp, m_which):
|
||||||
|
"""with exists=file where file does exist should only invoke subp
|
||||||
|
once for 'which' call."""
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
mydev = self.tmp_path("mydev")
|
||||||
|
util.write_file(mydev, "foo\n")
|
||||||
|
util.udevadm_settle(exists=mydev)
|
||||||
|
- m_subp.called_once_with(["which", "udevadm"])
|
||||||
|
+ m_which.assert_called_once_with("udevadm")
|
||||||
|
+ m_subp.assert_not_called()
|
||||||
|
|
||||||
|
- def test_with_timeout_int(self, m_which, m_subp):
|
||||||
|
+ def test_with_timeout_int(self, m_subp, m_which):
|
||||||
|
"""timeout can be an integer."""
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
timeout = 9
|
||||||
|
util.udevadm_settle(timeout=timeout)
|
||||||
|
- m_subp.called_once_with(
|
||||||
|
+ m_subp.assert_called_once_with(
|
||||||
|
["udevadm", "settle", "--timeout=%s" % timeout]
|
||||||
|
)
|
||||||
|
|
||||||
|
- def test_with_timeout_string(self, m_which, m_subp):
|
||||||
|
+ def test_with_timeout_string(self, m_subp, m_which):
|
||||||
|
"""timeout can be a string."""
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
timeout = "555"
|
||||||
|
util.udevadm_settle(timeout=timeout)
|
||||||
|
- m_subp.called_once_with(
|
||||||
|
+ m_subp.assert_called_once_with(
|
||||||
|
["udevadm", "settle", "--timeout=%s" % timeout]
|
||||||
|
)
|
||||||
|
|
||||||
|
- def test_with_exists_and_timeout(self, m_which, m_subp):
|
||||||
|
+ def test_with_exists_and_timeout(self, m_subp, m_which):
|
||||||
|
"""test call with both exists and timeout."""
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
mydev = self.tmp_path("mydev")
|
||||||
|
timeout = "3"
|
||||||
|
- util.udevadm_settle(exists=mydev)
|
||||||
|
- m_subp.called_once_with(
|
||||||
|
+ util.udevadm_settle(exists=mydev, timeout=timeout)
|
||||||
|
+ m_subp.assert_called_once_with(
|
||||||
|
[
|
||||||
|
"udevadm",
|
||||||
|
"settle",
|
||||||
|
@@ -920,7 +922,7 @@ class TestUdevadmSettle(CiTestCase):
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
- def test_subp_exception_raises_to_caller(self, m_which, m_subp):
|
||||||
|
+ def test_subp_exception_raises_to_caller(self, m_subp, m_which):
|
||||||
|
m_which.side_effect = lambda m: m in ("udevadm",)
|
||||||
|
m_subp.side_effect = subp.ProcessExecutionError("BOOM")
|
||||||
|
self.assertRaises(subp.ProcessExecutionError, util.udevadm_settle)
|
@ -0,0 +1,131 @@
|
|||||||
|
From 83cb6de08a3b2dc72aabc16c5603f5d570d9a232 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ani Sinha <anisinha@redhat.com>
|
||||||
|
Date: Thu, 7 Dec 2023 21:03:13 +0530
|
||||||
|
Subject: [PATCH] tests/unittests: add a new unit test for network manager net
|
||||||
|
activator (#4672)
|
||||||
|
|
||||||
|
Some changes in behavior in network manager net activator was brought in with
|
||||||
|
the commit
|
||||||
|
d1d5166895da ("net/nm: check for presence of ifcfg files when nm connection files are absent")
|
||||||
|
|
||||||
|
This change adds some unit tests that exercizes network manager activator's
|
||||||
|
bring_up_interface() method that tests failure scenarios as well as cases
|
||||||
|
where an ifcfg file is used to bring the interface up.
|
||||||
|
|
||||||
|
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
||||||
|
(cherry picked from commit bb474df78bfe45ea5f05907eb710e8d5de764fc8)
|
||||||
|
---
|
||||||
|
tests/unittests/test_net_activators.py | 103 +++++++++++++++++++++++++
|
||||||
|
1 file changed, 103 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tests/unittests/test_net_activators.py b/tests/unittests/test_net_activators.py
|
||||||
|
index afd9056a..bc410d16 100644
|
||||||
|
--- a/tests/unittests/test_net_activators.py
|
||||||
|
+++ b/tests/unittests/test_net_activators.py
|
||||||
|
@@ -347,3 +347,106 @@ class TestActivatorsBringDown:
|
||||||
|
activator.bring_down_all_interfaces(network_state)
|
||||||
|
for call in m_subp.call_args_list:
|
||||||
|
assert call in expected_call_list
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class TestNetworkManagerActivatorBringUp:
|
||||||
|
+ @patch("cloudinit.subp.subp", return_value=("", ""))
|
||||||
|
+ @patch(
|
||||||
|
+ "cloudinit.net.network_manager.available_nm_ifcfg_rh",
|
||||||
|
+ return_value=True,
|
||||||
|
+ )
|
||||||
|
+ @patch("os.path.isfile")
|
||||||
|
+ @patch("os.path.exists", return_value=True)
|
||||||
|
+ def test_bring_up_interface_no_nm_conn(
|
||||||
|
+ self, m_exists, m_isfile, m_plugin, m_subp
|
||||||
|
+ ):
|
||||||
|
+ """
|
||||||
|
+ There is no network manager connection file but ifcfg-rh plugin is
|
||||||
|
+ present and ifcfg interface config files are also present. In this
|
||||||
|
+ case, we should use ifcfg files.
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ def fake_isfile_no_nmconn(filename):
|
||||||
|
+ return False if filename.endswith(".nmconnection") else True
|
||||||
|
+
|
||||||
|
+ m_isfile.side_effect = fake_isfile_no_nmconn
|
||||||
|
+
|
||||||
|
+ expected_call_list = [
|
||||||
|
+ (
|
||||||
|
+ (
|
||||||
|
+ [
|
||||||
|
+ "nmcli",
|
||||||
|
+ "connection",
|
||||||
|
+ "load",
|
||||||
|
+ "".join(
|
||||||
|
+ [
|
||||||
|
+ "/etc/sysconfig/network-scripts/ifcfg-eth0",
|
||||||
|
+ ]
|
||||||
|
+ ),
|
||||||
|
+ ],
|
||||||
|
+ ),
|
||||||
|
+ {},
|
||||||
|
+ ),
|
||||||
|
+ (
|
||||||
|
+ (
|
||||||
|
+ [
|
||||||
|
+ "nmcli",
|
||||||
|
+ "connection",
|
||||||
|
+ "up",
|
||||||
|
+ "filename",
|
||||||
|
+ "".join(
|
||||||
|
+ [
|
||||||
|
+ "/etc/sysconfig/network-scripts/ifcfg-eth0",
|
||||||
|
+ ]
|
||||||
|
+ ),
|
||||||
|
+ ],
|
||||||
|
+ ),
|
||||||
|
+ {},
|
||||||
|
+ ),
|
||||||
|
+ ]
|
||||||
|
+
|
||||||
|
+ index = 0
|
||||||
|
+ assert NetworkManagerActivator.bring_up_interface("eth0")
|
||||||
|
+ for call in m_subp.call_args_list:
|
||||||
|
+ assert call == expected_call_list[index]
|
||||||
|
+ index += 1
|
||||||
|
+
|
||||||
|
+ @patch("cloudinit.subp.subp", return_value=("", ""))
|
||||||
|
+ @patch(
|
||||||
|
+ "cloudinit.net.network_manager.available_nm_ifcfg_rh",
|
||||||
|
+ return_value=False,
|
||||||
|
+ )
|
||||||
|
+ @patch("os.path.isfile")
|
||||||
|
+ @patch("os.path.exists", return_value=True)
|
||||||
|
+ def test_bring_up_interface_no_plugin_no_nm_conn(
|
||||||
|
+ self, m_exists, m_isfile, m_plugin, m_subp
|
||||||
|
+ ):
|
||||||
|
+ """
|
||||||
|
+ The ifcfg-rh plugin is absent and nmconnection file is also
|
||||||
|
+ not present. In this case, we can't use ifcfg file and the
|
||||||
|
+ interface bring up should fail.
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ def fake_isfile_no_nmconn(filename):
|
||||||
|
+ return False if filename.endswith(".nmconnection") else True
|
||||||
|
+
|
||||||
|
+ m_isfile.side_effect = fake_isfile_no_nmconn
|
||||||
|
+ assert not NetworkManagerActivator.bring_up_interface("eth0")
|
||||||
|
+
|
||||||
|
+ @patch("cloudinit.subp.subp", return_value=("", ""))
|
||||||
|
+ @patch(
|
||||||
|
+ "cloudinit.net.network_manager.available_nm_ifcfg_rh",
|
||||||
|
+ return_value=True,
|
||||||
|
+ )
|
||||||
|
+ @patch("os.path.isfile", return_value=False)
|
||||||
|
+ @patch("os.path.exists", return_value=True)
|
||||||
|
+ def test_bring_up_interface_no_conn_file(
|
||||||
|
+ self, m_exists, m_isfile, m_plugin, m_subp
|
||||||
|
+ ):
|
||||||
|
+ """
|
||||||
|
+ Neither network manager connection files are present nor
|
||||||
|
+ ifcfg files are present. Even if ifcfg-rh plugin is present,
|
||||||
|
+ we can not bring up the interface. So bring_up_interface()
|
||||||
|
+ should fail.
|
||||||
|
+ """
|
||||||
|
+ assert not NetworkManagerActivator.bring_up_interface("eth0")
|
@ -1,108 +0,0 @@
|
|||||||
From 808cd6f434a4ede1441cc1f5781abf59f53c4153 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Anders=20Bj=C3=B6rklund?= <anders.f.bjorklund@gmail.com>
|
|
||||||
Date: Mon, 22 Apr 2024 17:52:44 +0200
|
|
||||||
Subject: [PATCH 1/3] Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
RH-Jira: RHEL-45262
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/3] 27d6f99519a28ae91037fe47f9ef654b7fbd6236 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Deprecate the users ssh-authorized-keys property
|
|
||||||
|
|
||||||
Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
|
|
||||||
(cherry picked from commit 5205b4dd74eb2168ebbeba56579b6f116a272937)
|
|
||||||
---
|
|
||||||
.../schemas/schema-cloud-config-v1.json | 16 ++++++++++
|
|
||||||
.../unittests/config/test_cc_users_groups.py | 30 +++++++++++++++++++
|
|
||||||
tools/.github-cla-signers | 1 +
|
|
||||||
3 files changed, 47 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 8b10fe70..670ef4c2 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -272,6 +272,22 @@
|
|
||||||
},
|
|
||||||
"minItems": 1
|
|
||||||
},
|
|
||||||
+ "ssh-authorized-keys": {
|
|
||||||
+ "allOf": [
|
|
||||||
+ {
|
|
||||||
+ "type": "array",
|
|
||||||
+ "items": {
|
|
||||||
+ "type": "string"
|
|
||||||
+ },
|
|
||||||
+ "minItems": 1
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "18.3",
|
|
||||||
+ "deprecated_description": "Use ``ssh_authorized_keys`` instead."
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
"ssh_import_id": {
|
|
||||||
"description": "List of SSH IDs to import for user. Can not be combined with ``ssh_redirect_user``.",
|
|
||||||
"type": "array",
|
|
||||||
diff --git a/tests/unittests/config/test_cc_users_groups.py b/tests/unittests/config/test_cc_users_groups.py
|
|
||||||
index 3300b77b..53e231e1 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_users_groups.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_users_groups.py
|
|
||||||
@@ -503,6 +503,36 @@ class TestUsersGroupsSchema:
|
|
||||||
),
|
|
||||||
True,
|
|
||||||
),
|
|
||||||
+ (
|
|
||||||
+ {
|
|
||||||
+ "users": [
|
|
||||||
+ {
|
|
||||||
+ "name": "lima",
|
|
||||||
+ "uid": "1000",
|
|
||||||
+ "homedir": "/home/lima.linux",
|
|
||||||
+ "shell": "/bin/bash",
|
|
||||||
+ "sudo": "ALL=(ALL) NOPASSWD:ALL",
|
|
||||||
+ "lock_passwd": True,
|
|
||||||
+ "ssh-authorized-keys": ["ssh-ed25519 ..."],
|
|
||||||
+ }
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ pytest.raises(
|
|
||||||
+ SchemaValidationError,
|
|
||||||
+ match=(
|
|
||||||
+ "Cloud config schema deprecations: "
|
|
||||||
+ "users.0.ssh-authorized-keys: "
|
|
||||||
+ " Deprecated in version 18.3."
|
|
||||||
+ " Use ``ssh_authorized_keys`` instead."
|
|
||||||
+ ", "
|
|
||||||
+ "users.0.uid: "
|
|
||||||
+ " Changed in version 22.3."
|
|
||||||
+ " The use of ``string`` type is deprecated."
|
|
||||||
+ " Use an ``integer`` instead."
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+ False,
|
|
||||||
+ ),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@skipUnlessJsonSchema()
|
|
||||||
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
|
|
||||||
index f4da0989..8b119025 100644
|
|
||||||
--- a/tools/.github-cla-signers
|
|
||||||
+++ b/tools/.github-cla-signers
|
|
||||||
@@ -3,6 +3,7 @@ aciba90
|
|
||||||
acourdavAkamai
|
|
||||||
ader1990
|
|
||||||
adobley
|
|
||||||
+afbjorklund
|
|
||||||
ajmyyra
|
|
||||||
akutz
|
|
||||||
AlexBaranowski
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
|||||||
From 94c0cd9c656877250f7e5cfe05325a42bbdec182 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Fri, 4 Oct 2024 02:38:23 +0530
|
|
||||||
Subject: [PATCH 1/2] Fix metric setting for ifcfg network connections for rhel
|
|
||||||
(#5777)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 145: Fix metric setting for ifcfg network connections for rhel (#5777)
|
|
||||||
RH-Jira: RHEL-65018
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Commit: [1/2] a18205f1ffa455a2ccd836ba6baa12b7da0afbde (xiachen/cloud-init)
|
|
||||||
|
|
||||||
Most RHEL systems use Network manager to bring up manage network connections.
|
|
||||||
Network manager does not recognize "METRIC" option for network connections.
|
|
||||||
It uses IPV4_ROUTE_METRIC and IPV6_ROUTE_METRIC options. Please see
|
|
||||||
https://people.freedesktop.org/~lkundrak/nm-docs/nm-settings-ifcfg-rh.html
|
|
||||||
|
|
||||||
This change ensures that cloud-init generates ifcfg network connection files
|
|
||||||
with IPV{4/6}_ROUTE_METRIC options that are compatible with RHEL and
|
|
||||||
network manager.
|
|
||||||
|
|
||||||
Fixes GH-5776
|
|
||||||
|
|
||||||
(cherry picked from commit a399f4b0815234e3fe11255178c737902b2d243d)
|
|
||||||
|
|
||||||
Signed-off-by: Amy Chen <xiachen@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/sysconfig.py | 21 ++++++++++++++++++---
|
|
||||||
tests/unittests/test_net.py | 37 ++++++++++++++++++++-----------------
|
|
||||||
2 files changed, 38 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index 7eb430ed1..b50a6a8a0 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -205,7 +205,7 @@ class Route(ConfigMap):
|
|
||||||
)
|
|
||||||
metric_key = "METRIC" + index
|
|
||||||
if metric_key in self._conf:
|
|
||||||
- metric_value = str(self._conf["METRIC" + index])
|
|
||||||
+ metric_value = str(self._conf[metric_key])
|
|
||||||
buf.write(
|
|
||||||
"%s=%s\n"
|
|
||||||
% ("METRIC" + str(reindex), _quote_value(metric_value))
|
|
||||||
@@ -549,7 +549,12 @@ class Renderer(renderer.Renderer):
|
|
||||||
subnet_type = subnet.get("type")
|
|
||||||
# metric may apply to both dhcp and static config
|
|
||||||
if "metric" in subnet:
|
|
||||||
- if flavor != "suse":
|
|
||||||
+ if flavor == "rhel":
|
|
||||||
+ if subnet_is_ipv6(subnet):
|
|
||||||
+ iface_cfg["IPV6_ROUTE_METRIC"] = subnet["metric"]
|
|
||||||
+ else:
|
|
||||||
+ iface_cfg["IPV4_ROUTE_METRIC"] = subnet["metric"]
|
|
||||||
+ elif flavor != "suse":
|
|
||||||
iface_cfg["METRIC"] = subnet["metric"]
|
|
||||||
if subnet_type in ["dhcp", "dhcp4"]:
|
|
||||||
# On SUSE distros 'DHCLIENT_SET_DEFAULT_ROUTE' is a global
|
|
||||||
@@ -656,7 +661,17 @@ class Renderer(renderer.Renderer):
|
|
||||||
iface_cfg["GATEWAY"] = route["gateway"]
|
|
||||||
route_cfg.has_set_default_ipv4 = True
|
|
||||||
if "metric" in route:
|
|
||||||
- iface_cfg["METRIC"] = route["metric"]
|
|
||||||
+ if flavor == "rhel":
|
|
||||||
+ if subnet_is_ipv6(subnet):
|
|
||||||
+ iface_cfg["IPV6_ROUTE_METRIC"] = route[
|
|
||||||
+ "metric"
|
|
||||||
+ ]
|
|
||||||
+ else:
|
|
||||||
+ iface_cfg["IPV4_ROUTE_METRIC"] = route[
|
|
||||||
+ "metric"
|
|
||||||
+ ]
|
|
||||||
+ else:
|
|
||||||
+ iface_cfg["METRIC"] = route["metric"]
|
|
||||||
|
|
||||||
else:
|
|
||||||
# add default routes only to ifcfg files, not
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index 2d716f4b5..4673e4eaf 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -1345,7 +1345,7 @@ NETWORK_CONFIGS = {
|
|
||||||
HWADDR=c0:d6:9f:2c:e8:80
|
|
||||||
IPADDR=192.168.21.3
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- METRIC=10000
|
|
||||||
+ IPV4_ROUTE_METRIC=10000
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -1521,7 +1521,7 @@ NETWORK_CONFIGS = {
|
|
||||||
HWADDR=c0:d6:9f:2c:e8:80
|
|
||||||
IPADDR=192.168.21.3
|
|
||||||
NETMASK=255.255.255.0
|
|
||||||
- METRIC=10000
|
|
||||||
+ IPV4_ROUTE_METRIC=10000
|
|
||||||
ONBOOT=yes
|
|
||||||
TYPE=Ethernet
|
|
||||||
USERCTL=no"""
|
|
||||||
@@ -5725,24 +5725,27 @@ USERCTL=no
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
- expected = {
|
|
||||||
- "ifcfg-eno1": textwrap.dedent(
|
|
||||||
- """\
|
|
||||||
- AUTOCONNECT_PRIORITY=120
|
|
||||||
- BOOTPROTO=dhcp
|
|
||||||
- DEVICE=eno1
|
|
||||||
- HWADDR=07-1c-c6-75-a4-be
|
|
||||||
- METRIC=100
|
|
||||||
- ONBOOT=yes
|
|
||||||
- TYPE=Ethernet
|
|
||||||
- USERCTL=no
|
|
||||||
- """
|
|
||||||
- ),
|
|
||||||
- }
|
|
||||||
for dhcp_ver in ("dhcp4", "dhcp6"):
|
|
||||||
+ expected = {
|
|
||||||
+ "ifcfg-eno1": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
|
||||||
+ BOOTPROTO=dhcp
|
|
||||||
+ DEVICE=eno1
|
|
||||||
+ HWADDR=07-1c-c6-75-a4-be
|
|
||||||
+ ONBOOT=yes
|
|
||||||
+ TYPE=Ethernet
|
|
||||||
+ USERCTL=no
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ }
|
|
||||||
v2data = copy.deepcopy(v2base)
|
|
||||||
if dhcp_ver == "dhcp6":
|
|
||||||
- expected["ifcfg-eno1"] += "IPV6INIT=yes\nDHCPV6C=yes\n"
|
|
||||||
+ expected[
|
|
||||||
+ "ifcfg-eno1"
|
|
||||||
+ ] += "IPV6INIT=yes\nDHCPV6C=yes\nIPV6_ROUTE_METRIC=100\n"
|
|
||||||
+ else:
|
|
||||||
+ expected["ifcfg-eno1"] += "IPV4_ROUTE_METRIC=100\n"
|
|
||||||
v2data["ethernets"]["eno1"].update(
|
|
||||||
{dhcp_ver: True, "{0}-overrides".format(dhcp_ver): overrides}
|
|
||||||
)
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
From 7f3b0ff968409a880596e04aece4e4c504fb9c64 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] ci: Pin pytest<8.0.0. (#4816)
|
|
||||||
|
|
||||||
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: Ani Sinha <anisinha@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
|
|
||||||
|
|
@ -1,248 +0,0 @@
|
|||||||
From 038a391b7016f16a7336d67965762a7dbf3ba662 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Tue, 5 Nov 2024 04:07:36 +0530
|
|
||||||
Subject: [PATCH] Prevent NM from handling DNS when network interfaces have DNS
|
|
||||||
config (#5846)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 150: Prevent NM from handling DNS when network interfaces have DNS config (#5846)
|
|
||||||
RH-Jira: RHEL-65778
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] b464ef219eba1a0c718dda5ed96b6f88e1273f99
|
|
||||||
|
|
||||||
In the change under PR #5401, we use global DNS configuration as well as
|
|
||||||
DNS and search domain information from interface config and use it to populate
|
|
||||||
/etc/resolv.conf. Therefore, if either or both global DNS/search domain config
|
|
||||||
is present along with per-interface DNS/search domain information, we should add
|
|
||||||
a network manager configuration to prevent network manager from manipulating
|
|
||||||
/etc/resolv.conf.
|
|
||||||
This is in addition to what we already do when only global DNS data is
|
|
||||||
configured.
|
|
||||||
|
|
||||||
Fixes bug added in 1b8030e0 .
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 2df49b652471999434f06d9d83ed9db8b4055895)
|
|
||||||
---
|
|
||||||
cloudinit/net/sysconfig.py | 28 +++++--
|
|
||||||
tests/unittests/test_net.py | 158 ++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 181 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index e4a65187f..4898a2fd1 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -905,17 +905,35 @@ class Renderer(renderer.Renderer):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _render_networkmanager_conf(network_state, templates=None):
|
|
||||||
+ iface_dns = False
|
|
||||||
content = networkmanager_conf.NetworkManagerConf("")
|
|
||||||
-
|
|
||||||
- # If DNS server information is provided, configure
|
|
||||||
- # NetworkManager to not manage dns, so that /etc/resolv.conf
|
|
||||||
- # does not get clobbered.
|
|
||||||
+ # check if there is interface specific DNS information configured
|
|
||||||
+ for iface in network_state.iter_interfaces():
|
|
||||||
+ for subnet in iface["subnets"]:
|
|
||||||
+ if "dns_nameservers" in subnet or "dns_search" in subnet:
|
|
||||||
+ iface_dns = True
|
|
||||||
+ break
|
|
||||||
+ if (
|
|
||||||
+ not iface_dns
|
|
||||||
+ and "dns" in iface
|
|
||||||
+ and (iface["dns"]["nameservers"] or iface["dns"]["search"])
|
|
||||||
+ ):
|
|
||||||
+ iface_dns = True
|
|
||||||
+ break
|
|
||||||
+
|
|
||||||
+ # If DNS server and/or dns search information is provided either
|
|
||||||
+ # globally or per interface basis, configure NetworkManager to
|
|
||||||
+ # not manage dns, so that /etc/resolv.conf does not get clobbered.
|
|
||||||
# This is not required for NetworkManager renderer as it
|
|
||||||
# does not write /etc/resolv.conf directly. DNS information is
|
|
||||||
# written to the interface keyfile and NetworkManager is then
|
|
||||||
# responsible for using the DNS information from the keyfile,
|
|
||||||
# including managing /etc/resolv.conf.
|
|
||||||
- if network_state.dns_nameservers:
|
|
||||||
+ if (
|
|
||||||
+ network_state.dns_nameservers
|
|
||||||
+ or network_state.dns_searchdomains
|
|
||||||
+ or iface_dns
|
|
||||||
+ ):
|
|
||||||
content.set_section_keypair("main", "dns", "none")
|
|
||||||
|
|
||||||
if len(content) == 0:
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index ddb45dc69..47b36d052 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -967,6 +967,164 @@ dns = none
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ "in_data": {
|
|
||||||
+ "networks": [
|
|
||||||
+ {
|
|
||||||
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
|
|
||||||
+ "type": "ipv4",
|
|
||||||
+ "netmask": "255.255.252.0",
|
|
||||||
+ "link": "eth0",
|
|
||||||
+ "routes": [
|
|
||||||
+ {
|
|
||||||
+ "netmask": "0.0.0.0",
|
|
||||||
+ "network": "0.0.0.0",
|
|
||||||
+ "gateway": "172.19.3.254",
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ "ip_address": "172.19.1.34",
|
|
||||||
+ "dns_search": ["example3.com"],
|
|
||||||
+ "dns_nameservers": ["172.19.0.12"],
|
|
||||||
+ "id": "network0",
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ "links": [
|
|
||||||
+ {
|
|
||||||
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
|
|
||||||
+ "mtu": None,
|
|
||||||
+ "type": "physical",
|
|
||||||
+ "id": "eth0",
|
|
||||||
+ },
|
|
||||||
+ ],
|
|
||||||
+ },
|
|
||||||
+ "in_macs": {
|
|
||||||
+ "fa:16:3e:ed:9a:59": "eth0",
|
|
||||||
+ },
|
|
||||||
+ "out_sysconfig_opensuse": [
|
|
||||||
+ (
|
|
||||||
+ "etc/sysconfig/network/ifcfg-eth0",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+BOOTPROTO=static
|
|
||||||
+IPADDR=172.19.1.34
|
|
||||||
+LLADDR=fa:16:3e:ed:9a:59
|
|
||||||
+NETMASK=255.255.252.0
|
|
||||||
+STARTMODE=auto
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/resolv.conf",
|
|
||||||
+ """
|
|
||||||
+; Created by cloud-init automatically, do not edit.
|
|
||||||
+;
|
|
||||||
+nameserver 172.19.0.12
|
|
||||||
+search example3.com
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+[main]
|
|
||||||
+dns = none
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
|
|
||||||
+ "".join(
|
|
||||||
+ [
|
|
||||||
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
|
|
||||||
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
|
|
||||||
+ ]
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ "out_sysconfig_rhel": [
|
|
||||||
+ (
|
|
||||||
+ "etc/sysconfig/network-scripts/ifcfg-eth0",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+AUTOCONNECT_PRIORITY=120
|
|
||||||
+BOOTPROTO=none
|
|
||||||
+DEFROUTE=yes
|
|
||||||
+DEVICE=eth0
|
|
||||||
+DNS1=172.19.0.12
|
|
||||||
+DOMAIN=example3.com
|
|
||||||
+GATEWAY=172.19.3.254
|
|
||||||
+HWADDR=fa:16:3e:ed:9a:59
|
|
||||||
+IPADDR=172.19.1.34
|
|
||||||
+NETMASK=255.255.252.0
|
|
||||||
+ONBOOT=yes
|
|
||||||
+TYPE=Ethernet
|
|
||||||
+USERCTL=no
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/resolv.conf",
|
|
||||||
+ """
|
|
||||||
+; Created by cloud-init automatically, do not edit.
|
|
||||||
+;
|
|
||||||
+nameserver 172.19.0.12
|
|
||||||
+search example3.com
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+[main]
|
|
||||||
+dns = none
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/udev/rules.d/70-persistent-net.rules",
|
|
||||||
+ "".join(
|
|
||||||
+ [
|
|
||||||
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
|
|
||||||
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
|
|
||||||
+ ]
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ "expected_network_manager": [
|
|
||||||
+ (
|
|
||||||
+ "".join(
|
|
||||||
+ [
|
|
||||||
+ "etc/NetworkManager/system-connections",
|
|
||||||
+ "/cloud-init-eth0.nmconnection",
|
|
||||||
+ ]
|
|
||||||
+ ),
|
|
||||||
+ """
|
|
||||||
+# Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+[connection]
|
|
||||||
+id=cloud-init eth0
|
|
||||||
+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+autoconnect-priority=120
|
|
||||||
+type=ethernet
|
|
||||||
+
|
|
||||||
+[user]
|
|
||||||
+org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+[ethernet]
|
|
||||||
+mac-address=FA:16:3E:ED:9A:59
|
|
||||||
+
|
|
||||||
+[ipv4]
|
|
||||||
+method=manual
|
|
||||||
+may-fail=false
|
|
||||||
+address1=172.19.1.34/22
|
|
||||||
+route1=0.0.0.0/0,172.19.3.254
|
|
||||||
+dns=172.19.0.12;
|
|
||||||
+dns-search=example3.com;
|
|
||||||
+
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
"in_data": {
|
|
||||||
"services": [{"type": "dns", "address": "172.19.0.12"}],
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
From cc31dc321ae35995ceff93e67aaf0b0c660aa890 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: 71: Retain exit code in cloud-init status for recoverable errors
|
|
||||||
RH-Jira: RHEL-28549
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 00934ade88c481c012bc1947fa44e5ed59f82858 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
@ -1,242 +0,0 @@
|
|||||||
From 72b2deeafd9276d15f20831f01b2f8c44616f33d 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: 67: Revert "Use grep for faster parsing of cloud config in ds-identify (#4327)"
|
|
||||||
RH-Jira: RHEL-22255
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 5997598254cd16ea7f26d87212b0f09920fcdf50 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
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.39.3
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
|||||||
From 87db4f8680222d2579d0ffb5fe507231f88d8aa5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
|
||||||
Date: Sat, 10 Aug 2024 03:32:40 +0800
|
|
||||||
Subject: [PATCH] Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6
|
|
||||||
addr (#5471)" (#5596)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 108: Revert "fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)" (#5596)
|
|
||||||
RH-Jira: RHEL-54373
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 96cccfca3d29c95d9c491d5995b7aa96adec4621 (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
This reverts commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0.
|
|
||||||
|
|
||||||
When there is no IPv6 set to dhcp explicitly, NetworkManager keyfile
|
|
||||||
defaults to method=auto, may-fail=true. When there is Ipv6 set to dhcp
|
|
||||||
explictily, NetworkManager keyfile will be set to
|
|
||||||
method=auto, may-fail=false. The default settings are what we want, so
|
|
||||||
revert the previous change to keep IPv6 not set explicitly.
|
|
||||||
|
|
||||||
(cherry picked from commit 65014b97420b41dcb6e7ea17c66bb2539f9b09fc)
|
|
||||||
Signed-off-by: Amy Chen <xiachen@redhat.com>
|
|
||||||
---
|
|
||||||
.../sources/helpers/vmware/imc/config_nic.py | 2 +-
|
|
||||||
.../sources/vmware/test_vmware_config_file.py | 68 +++++--------------
|
|
||||||
2 files changed, 18 insertions(+), 52 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py
|
|
||||||
index 254518af..b07214a2 100644
|
|
||||||
--- a/cloudinit/sources/helpers/vmware/imc/config_nic.py
|
|
||||||
+++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py
|
|
||||||
@@ -207,7 +207,7 @@ class NicConfigurator:
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not nic.staticIpv6:
|
|
||||||
- return ([{"type": "dhcp6"}], [])
|
|
||||||
+ return ([], [])
|
|
||||||
|
|
||||||
subnet_list = []
|
|
||||||
# Static Ipv6
|
|
||||||
diff --git a/tests/unittests/sources/vmware/test_vmware_config_file.py b/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
index 25d3b093..b53ea96c 100644
|
|
||||||
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
@@ -240,45 +240,27 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
elif cfg.get("name") == nic2.get("name"):
|
|
||||||
nic2.update(cfg)
|
|
||||||
|
|
||||||
- # Test NIC1
|
|
||||||
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
|
|
||||||
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
|
|
||||||
self.assertEqual(
|
|
||||||
"00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1"
|
|
||||||
)
|
|
||||||
subnets = nic1.get("subnets")
|
|
||||||
- self.assertEqual(2, len(subnets), "number of subnets for NIC1")
|
|
||||||
- subnet_ipv4 = subnets[0]
|
|
||||||
- self.assertEqual(
|
|
||||||
- "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC1"
|
|
||||||
- )
|
|
||||||
- self.assertEqual(
|
|
||||||
- "auto", subnet_ipv4.get("control"), "NIC1 Control type"
|
|
||||||
- )
|
|
||||||
- subnet_ipv6 = subnets[1]
|
|
||||||
- self.assertEqual(
|
|
||||||
- "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC1"
|
|
||||||
- )
|
|
||||||
+ self.assertEqual(1, len(subnets), "number of subnets for NIC1")
|
|
||||||
+ subnet = subnets[0]
|
|
||||||
+ self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1")
|
|
||||||
+ self.assertEqual("auto", subnet.get("control"), "NIC1 Control type")
|
|
||||||
|
|
||||||
- # Test NIC2
|
|
||||||
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
|
|
||||||
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
|
|
||||||
self.assertEqual(
|
|
||||||
"00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2"
|
|
||||||
)
|
|
||||||
subnets = nic2.get("subnets")
|
|
||||||
- self.assertEqual(2, len(subnets), "number of subnets for NIC2")
|
|
||||||
- subnet_ipv4 = subnets[0]
|
|
||||||
- self.assertEqual(
|
|
||||||
- "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC2"
|
|
||||||
- )
|
|
||||||
- self.assertEqual(
|
|
||||||
- "auto", subnet_ipv4.get("control"), "NIC2 Control type"
|
|
||||||
- )
|
|
||||||
- subnet_ipv6 = subnets[1]
|
|
||||||
- self.assertEqual(
|
|
||||||
- "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC2"
|
|
||||||
- )
|
|
||||||
+ self.assertEqual(1, len(subnets), "number of subnets for NIC2")
|
|
||||||
+ subnet = subnets[0]
|
|
||||||
+ self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2")
|
|
||||||
+ self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
|
|
||||||
|
|
||||||
def test_get_nics_list_static(self):
|
|
||||||
"""Tests if NicConfigurator properly calculates network subnets
|
|
||||||
@@ -303,7 +285,6 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
elif cfg.get("name") == nic2.get("name"):
|
|
||||||
nic2.update(cfg)
|
|
||||||
|
|
||||||
- # Test NIC1
|
|
||||||
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
|
|
||||||
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
|
|
||||||
self.assertEqual(
|
|
||||||
@@ -363,7 +344,6 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
else:
|
|
||||||
self.assertEqual(True, False, "invalid gateway %s" % (gateway))
|
|
||||||
|
|
||||||
- # Test NIC2
|
|
||||||
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
|
|
||||||
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
|
|
||||||
self.assertEqual(
|
|
||||||
@@ -371,18 +351,16 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
subnets = nic2.get("subnets")
|
|
||||||
- self.assertEqual(2, len(subnets), "Number of subnets for NIC2")
|
|
||||||
+ self.assertEqual(1, len(subnets), "Number of subnets for NIC2")
|
|
||||||
|
|
||||||
- subnet_ipv4 = subnets[0]
|
|
||||||
- self.assertEqual("static", subnet_ipv4.get("type"), "Subnet type")
|
|
||||||
+ subnet = subnets[0]
|
|
||||||
+ self.assertEqual("static", subnet.get("type"), "Subnet type")
|
|
||||||
self.assertEqual(
|
|
||||||
- "192.168.6.102", subnet_ipv4.get("address"), "Subnet address"
|
|
||||||
+ "192.168.6.102", subnet.get("address"), "Subnet address"
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
- "255.255.0.0", subnet_ipv4.get("netmask"), "Subnet netmask"
|
|
||||||
+ "255.255.0.0", subnet.get("netmask"), "Subnet netmask"
|
|
||||||
)
|
|
||||||
- subnet_ipv6 = subnets[1]
|
|
||||||
- self.assertEqual("dhcp6", subnet_ipv6.get("type"), "Subnet type")
|
|
||||||
|
|
||||||
def test_custom_script(self):
|
|
||||||
cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
|
|
||||||
@@ -469,10 +447,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"type": "static",
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -523,10 +498,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -586,10 +558,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -634,10 +603,7 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
"gateway": "10.20.87.253",
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "type": "dhcp6",
|
|
||||||
- },
|
|
||||||
+ }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
|||||||
From 96b10adc942f5117e35584d28ba88071849e8e29 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 27 Jun 2024 18:38:22 +0530
|
|
||||||
Subject: [PATCH 1/2] Support metalink in yum repository config (#5444)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 97: Support metalink in yum repository config (#5444)
|
|
||||||
RH-Jira: RHEL-44916
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 4671fd3a3f6842f1f590d5a89a429facd0d8bb4d (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
'metalink' config can be specified instead or along with 'baseurl' in the yum
|
|
||||||
repository config. Add support for specifying metalink instead of 'baseurl'.
|
|
||||||
|
|
||||||
Fixes GH-5359
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Co-authored-by: Ben Gray <ben.gray@clearcapital.com>
|
|
||||||
(cherry picked from commit 525026061404ef09baebb85631d9af3b0a4d8930)
|
|
||||||
---
|
|
||||||
cloudinit/config/cc_yum_add_repo.py | 24 ++++++------
|
|
||||||
doc/examples/cloud-config-yum-repo.txt | 3 +-
|
|
||||||
.../unittests/config/test_cc_yum_add_repo.py | 38 +++++++++++++++++++
|
|
||||||
3 files changed, 51 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
|
|
||||||
index 1ab5008f..4fd66250 100644
|
|
||||||
--- a/cloudinit/config/cc_yum_add_repo.py
|
|
||||||
+++ b/cloudinit/config/cc_yum_add_repo.py
|
|
||||||
@@ -210,24 +210,22 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
|
|
||||||
n_repo_config[k] = v
|
|
||||||
repo_config = n_repo_config
|
|
||||||
missing_required = 0
|
|
||||||
- for req_field in ["baseurl"]:
|
|
||||||
+ req_fields = ["baseurl", "metalink"]
|
|
||||||
+ for req_field in req_fields:
|
|
||||||
if req_field not in repo_config:
|
|
||||||
- LOG.warning(
|
|
||||||
- "Repository %s does not contain a %s"
|
|
||||||
- " configuration 'required' entry",
|
|
||||||
- repo_id,
|
|
||||||
- req_field,
|
|
||||||
- )
|
|
||||||
missing_required += 1
|
|
||||||
- if not missing_required:
|
|
||||||
- repo_configs[canon_repo_id] = repo_config
|
|
||||||
- repo_locations[canon_repo_id] = repo_fn_pth
|
|
||||||
- else:
|
|
||||||
+
|
|
||||||
+ if missing_required == len(req_fields):
|
|
||||||
LOG.warning(
|
|
||||||
- "Repository %s is missing %s required fields, skipping!",
|
|
||||||
+ "Repository %s should contain atleast one of the"
|
|
||||||
+ " following configuration entries: %s, skipping!",
|
|
||||||
repo_id,
|
|
||||||
- missing_required,
|
|
||||||
+ ", ".join(req_fields),
|
|
||||||
)
|
|
||||||
+ else:
|
|
||||||
+ repo_configs[canon_repo_id] = repo_config
|
|
||||||
+ repo_locations[canon_repo_id] = repo_fn_pth
|
|
||||||
+
|
|
||||||
for (c_repo_id, path) in repo_locations.items():
|
|
||||||
repo_blob = _format_repository_config(
|
|
||||||
c_repo_id, repo_configs.get(c_repo_id)
|
|
||||||
diff --git a/doc/examples/cloud-config-yum-repo.txt b/doc/examples/cloud-config-yum-repo.txt
|
|
||||||
index e8f2bbb4..6a4037e2 100644
|
|
||||||
--- a/doc/examples/cloud-config-yum-repo.txt
|
|
||||||
+++ b/doc/examples/cloud-config-yum-repo.txt
|
|
||||||
@@ -11,8 +11,9 @@ yum_repos:
|
|
||||||
# Any repository configuration options
|
|
||||||
# See: man yum.conf
|
|
||||||
#
|
|
||||||
- # This one is required!
|
|
||||||
+ # At least one of 'baseurl' or 'metalink' is required!
|
|
||||||
baseurl: http://download.fedoraproject.org/pub/epel/testing/5/$basearch
|
|
||||||
+ metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
|
|
||||||
enabled: false
|
|
||||||
failovermethod: priority
|
|
||||||
gpgcheck: true
|
|
||||||
diff --git a/tests/unittests/config/test_cc_yum_add_repo.py b/tests/unittests/config/test_cc_yum_add_repo.py
|
|
||||||
index d2c2912f..1f27d1fb 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_yum_add_repo.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_yum_add_repo.py
|
|
||||||
@@ -31,6 +31,7 @@ class TestConfig(helpers.FilesystemMockingTestCase):
|
|
||||||
"yum_repos": {
|
|
||||||
"epel-testing": {
|
|
||||||
"name": "Extra Packages for Enterprise Linux 5 - Testing",
|
|
||||||
+ # At least one of baseurl or metalink must be present.
|
|
||||||
# Missing this should cause the repo not to be written
|
|
||||||
# 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
|
|
||||||
"enabled": False,
|
|
||||||
@@ -46,6 +47,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
|
|
||||||
IOError, util.load_file, "/etc/yum.repos.d/epel_testing.repo"
|
|
||||||
)
|
|
||||||
|
|
||||||
+ def test_metalink_config(self):
|
|
||||||
+ cfg = {
|
|
||||||
+ "yum_repos": {
|
|
||||||
+ "epel-testing": {
|
|
||||||
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
|
|
||||||
+ "metalink": "http://blah.org/pub/epel/testing/5/$basearch",
|
|
||||||
+ "enabled": False,
|
|
||||||
+ "gpgcheck": True,
|
|
||||||
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
|
|
||||||
+ "failovermethod": "priority",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ self.patchUtils(self.tmp)
|
|
||||||
+ self.patchOS(self.tmp)
|
|
||||||
+ cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
|
|
||||||
+ contents = util.load_file("/etc/yum.repos.d/epel-testing.repo")
|
|
||||||
+ parser = configparser.ConfigParser()
|
|
||||||
+ parser.read_string(contents)
|
|
||||||
+ expected = {
|
|
||||||
+ "epel-testing": {
|
|
||||||
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
|
|
||||||
+ "failovermethod": "priority",
|
|
||||||
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
|
|
||||||
+ "enabled": "0",
|
|
||||||
+ "metalink": "http://blah.org/pub/epel/testing/5/$basearch",
|
|
||||||
+ "gpgcheck": "1",
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ for section in expected:
|
|
||||||
+ self.assertTrue(
|
|
||||||
+ parser.has_section(section),
|
|
||||||
+ "Contains section {0}".format(section),
|
|
||||||
+ )
|
|
||||||
+ for k, v in expected[section].items():
|
|
||||||
+ self.assertEqual(parser.get(section, k), v)
|
|
||||||
+
|
|
||||||
def test_write_config(self):
|
|
||||||
cfg = {
|
|
||||||
"yum_repos": {
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,145 +0,0 @@
|
|||||||
From d27ac077dac3474fea3c7bb1a19afe50ecbcc64d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 18 Jul 2024 13:36:39 +0530
|
|
||||||
Subject: [PATCH 2/2] Support setting mirrorlist in yum repository config
|
|
||||||
(#5522)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 104: Support setting mirrorlist in yum repository config (#5522)
|
|
||||||
RH-Jira: RHEL-49674
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 4605a0304c6bed6614990b7194465230afa79778 (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
'mirrorlist' config can be specified instead or along with 'baseurl' in the yum
|
|
||||||
repository config. Add support for specifying mirrorlist instead of 'baseurl'.
|
|
||||||
|
|
||||||
Fixes GH-5520
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 0b4084374440d2a5a9968129e0460a1a009d9830)
|
|
||||||
Signed-off-by: Amy Chen <xiachen@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/config/cc_yum_add_repo.py | 2 +-
|
|
||||||
.../schemas/schema-cloud-config-v1.json | 10 +++++
|
|
||||||
doc/examples/cloud-config-yum-repo.txt | 3 +-
|
|
||||||
.../unittests/config/test_cc_yum_add_repo.py | 40 ++++++++++++++++++-
|
|
||||||
4 files changed, 52 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py
|
|
||||||
index 4fd66250..3870d24e 100644
|
|
||||||
--- a/cloudinit/config/cc_yum_add_repo.py
|
|
||||||
+++ b/cloudinit/config/cc_yum_add_repo.py
|
|
||||||
@@ -210,7 +210,7 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
|
|
||||||
n_repo_config[k] = v
|
|
||||||
repo_config = n_repo_config
|
|
||||||
missing_required = 0
|
|
||||||
- req_fields = ["baseurl", "metalink"]
|
|
||||||
+ req_fields = ["baseurl", "metalink", "mirrorlist"]
|
|
||||||
for req_field in req_fields:
|
|
||||||
if req_field not in repo_config:
|
|
||||||
missing_required += 1
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 4fb7fd93..c5f46f37 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -3447,6 +3447,11 @@
|
|
||||||
"format": "uri",
|
|
||||||
"description": "Specifies a URL to a metalink file for the repomd.xml"
|
|
||||||
},
|
|
||||||
+ "mirrorlist": {
|
|
||||||
+ "type": "string",
|
|
||||||
+ "format": "uri",
|
|
||||||
+ "description": "Specifies a URL to a file containing a baseurls list"
|
|
||||||
+ },
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Optional human-readable name of the yum repo."
|
|
||||||
@@ -3484,6 +3489,11 @@
|
|
||||||
"required": [
|
|
||||||
"metalink"
|
|
||||||
]
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "required": [
|
|
||||||
+ "mirrorlist"
|
|
||||||
+ ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
diff --git a/doc/examples/cloud-config-yum-repo.txt b/doc/examples/cloud-config-yum-repo.txt
|
|
||||||
index 6a4037e2..cee26677 100644
|
|
||||||
--- a/doc/examples/cloud-config-yum-repo.txt
|
|
||||||
+++ b/doc/examples/cloud-config-yum-repo.txt
|
|
||||||
@@ -11,9 +11,10 @@ yum_repos:
|
|
||||||
# Any repository configuration options
|
|
||||||
# See: man yum.conf
|
|
||||||
#
|
|
||||||
- # At least one of 'baseurl' or 'metalink' is required!
|
|
||||||
+ # At least one of 'baseurl' or 'metalink' or 'mirrorlist' is required!
|
|
||||||
baseurl: http://download.fedoraproject.org/pub/epel/testing/5/$basearch
|
|
||||||
metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
|
|
||||||
+ mirrorlist: https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&
|
|
||||||
enabled: false
|
|
||||||
failovermethod: priority
|
|
||||||
gpgcheck: true
|
|
||||||
diff --git a/tests/unittests/config/test_cc_yum_add_repo.py b/tests/unittests/config/test_cc_yum_add_repo.py
|
|
||||||
index 1f27d1fb..000792b4 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_yum_add_repo.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_yum_add_repo.py
|
|
||||||
@@ -31,7 +31,8 @@ class TestConfig(helpers.FilesystemMockingTestCase):
|
|
||||||
"yum_repos": {
|
|
||||||
"epel-testing": {
|
|
||||||
"name": "Extra Packages for Enterprise Linux 5 - Testing",
|
|
||||||
- # At least one of baseurl or metalink must be present.
|
|
||||||
+ # At least one of baseurl or metalink or mirrorlist
|
|
||||||
+ # must be present.
|
|
||||||
# Missing this should cause the repo not to be written
|
|
||||||
# 'baseurl': 'http://blah.org/pub/epel/testing/5/$barch',
|
|
||||||
"enabled": False,
|
|
||||||
@@ -84,6 +85,43 @@ class TestConfig(helpers.FilesystemMockingTestCase):
|
|
||||||
for k, v in expected[section].items():
|
|
||||||
self.assertEqual(parser.get(section, k), v)
|
|
||||||
|
|
||||||
+ def test_mirrorlist_config(self):
|
|
||||||
+ cfg = {
|
|
||||||
+ "yum_repos": {
|
|
||||||
+ "epel-testing": {
|
|
||||||
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
|
|
||||||
+ "mirrorlist": "http://mirrors.blah.org/metalink?repo=rhel-$releasever",
|
|
||||||
+ "enabled": False,
|
|
||||||
+ "gpgcheck": True,
|
|
||||||
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
|
|
||||||
+ "failovermethod": "priority",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ self.patchUtils(self.tmp)
|
|
||||||
+ self.patchOS(self.tmp)
|
|
||||||
+ cc_yum_add_repo.handle("yum_add_repo", cfg, None, [])
|
|
||||||
+ contents = util.load_file("/etc/yum.repos.d/epel-testing.repo")
|
|
||||||
+ parser = configparser.ConfigParser()
|
|
||||||
+ parser.read_string(contents)
|
|
||||||
+ expected = {
|
|
||||||
+ "epel-testing": {
|
|
||||||
+ "name": "Extra Packages for Enterprise Linux 5 - Testing",
|
|
||||||
+ "failovermethod": "priority",
|
|
||||||
+ "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL",
|
|
||||||
+ "enabled": "0",
|
|
||||||
+ "mirrorlist": "http://mirrors.blah.org/metalink?repo=rhel-$releasever",
|
|
||||||
+ "gpgcheck": "1",
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ for section in expected:
|
|
||||||
+ self.assertTrue(
|
|
||||||
+ parser.has_section(section),
|
|
||||||
+ "Contains section {0}".format(section),
|
|
||||||
+ )
|
|
||||||
+ for k, v in expected[section].items():
|
|
||||||
+ self.assertEqual(parser.get(section, k), v)
|
|
||||||
+
|
|
||||||
def test_write_config(self):
|
|
||||||
cfg = {
|
|
||||||
"yum_repos": {
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,235 +0,0 @@
|
|||||||
From c34f5c4275c3ef7bee9a99e87bf6e37c5886b160 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Wed, 29 May 2024 03:34:38 +0530
|
|
||||||
Subject: [PATCH 6/6] Update pylint version to support python 3.12 (#5338)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 92: Update pylint version to support python 3.12
|
|
||||||
RH-Jira: RHEL-44598
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [3/3] d6185e0a126e1589260ee59709fe933b5a780b78 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Fedora 39 and above comes with python version 3.12. When running `tox -e pylint`
|
|
||||||
on cloud-init, we may experience issue such as the one reported here:
|
|
||||||
https://github.com/pylint-dev/pylint/issues/8782
|
|
||||||
|
|
||||||
Minimum version of pylint required in order to support python 3.12 is 3.0.2.
|
|
||||||
Please see https://github.com/pylint-dev/astroid/issues/2201 . Upon further
|
|
||||||
experimentation, it is seen that we need minimum pylint version 3.2.0 for
|
|
||||||
cloud-init. Update tox.ini in order to use this pylint version.
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 5ad609ffdf4bb76c5665e12e34e1867b72bd4435)
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
cloudinit/sources/DataSourceWSL.py (does not exist)
|
|
||||||
cloudinit/util.py (doc added upstream)
|
|
||||||
---
|
|
||||||
cloudinit/config/cc_mounts.py | 4 ++++
|
|
||||||
cloudinit/distros/bsd.py | 2 ++
|
|
||||||
cloudinit/distros/netbsd.py | 2 +-
|
|
||||||
cloudinit/sources/DataSourceAzure.py | 2 +-
|
|
||||||
cloudinit/sources/DataSourceEc2.py | 3 ++-
|
|
||||||
cloudinit/sources/DataSourceLXD.py | 2 +-
|
|
||||||
tests/integration_tests/conftest.py | 6 +++---
|
|
||||||
tests/integration_tests/util.py | 2 +-
|
|
||||||
tests/unittests/config/test_cc_ntp.py | 2 ++
|
|
||||||
tests/unittests/sources/test_gce.py | 1 +
|
|
||||||
tests/unittests/test_util.py | 2 ++
|
|
||||||
tox.ini | 2 +-
|
|
||||||
12 files changed, 21 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/cc_mounts.py b/cloudinit/config/cc_mounts.py
|
|
||||||
index 4efa2a29..d445b440 100644
|
|
||||||
--- a/cloudinit/config/cc_mounts.py
|
|
||||||
+++ b/cloudinit/config/cc_mounts.py
|
|
||||||
@@ -304,6 +304,10 @@ def create_swapfile(fname: str, size: str) -> None:
|
|
||||||
"bs=1M",
|
|
||||||
"count=%s" % size,
|
|
||||||
]
|
|
||||||
+ else:
|
|
||||||
+ raise subp.ProcessExecutionError(
|
|
||||||
+ "Missing dependency: 'dd' and 'fallocate' are not available"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
try:
|
|
||||||
subp.subp(cmd, capture=True)
|
|
||||||
diff --git a/cloudinit/distros/bsd.py b/cloudinit/distros/bsd.py
|
|
||||||
index 761cf5c4..77e0385f 100644
|
|
||||||
--- a/cloudinit/distros/bsd.py
|
|
||||||
+++ b/cloudinit/distros/bsd.py
|
|
||||||
@@ -120,6 +120,8 @@ class BSD(distros.Distro):
|
|
||||||
if not self.pkg_cmd_upgrade_prefix:
|
|
||||||
return
|
|
||||||
cmd = self.pkg_cmd_upgrade_prefix
|
|
||||||
+ else:
|
|
||||||
+ cmd = []
|
|
||||||
|
|
||||||
if args and isinstance(args, str):
|
|
||||||
cmd.append(args)
|
|
||||||
diff --git a/cloudinit/distros/netbsd.py b/cloudinit/distros/netbsd.py
|
|
||||||
index a5678907..b7f3f3d8 100644
|
|
||||||
--- a/cloudinit/distros/netbsd.py
|
|
||||||
+++ b/cloudinit/distros/netbsd.py
|
|
||||||
@@ -12,7 +12,7 @@ import cloudinit.distros.bsd
|
|
||||||
from cloudinit import subp, util
|
|
||||||
|
|
||||||
try:
|
|
||||||
- import crypt
|
|
||||||
+ import crypt # pylint: disable=W4901
|
|
||||||
|
|
||||||
salt = crypt.METHOD_BLOWFISH # pylint: disable=E1101
|
|
||||||
blowfish_hash: Any = functools.partial(
|
|
||||||
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
|
||||||
index 11c14e20..eb0304c3 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceAzure.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
|
||||||
@@ -51,7 +51,7 @@ from cloudinit.sources.helpers.azure import (
|
|
||||||
from cloudinit.url_helper import UrlError
|
|
||||||
|
|
||||||
try:
|
|
||||||
- import crypt
|
|
||||||
+ import crypt # pylint: disable=W4901
|
|
||||||
|
|
||||||
blowfish_hash: Any = functools.partial(
|
|
||||||
crypt.crypt, salt=f"$6${util.rand_str(strlen=16)}"
|
|
||||||
diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py
|
|
||||||
index 9e6bfbd1..384e4074 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceEc2.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceEc2.py
|
|
||||||
@@ -312,6 +312,8 @@ class DataSourceEc2(sources.DataSource):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def wait_for_metadata_service(self):
|
|
||||||
+ urls = []
|
|
||||||
+ start_time = 0
|
|
||||||
mcfg = self.ds_cfg
|
|
||||||
|
|
||||||
url_params = self.get_url_params()
|
|
||||||
@@ -345,7 +347,6 @@ class DataSourceEc2(sources.DataSource):
|
|
||||||
and self.cloud_name not in IDMSV2_SUPPORTED_CLOUD_PLATFORMS
|
|
||||||
):
|
|
||||||
# if we can't get a token, use instance-id path
|
|
||||||
- urls = []
|
|
||||||
url2base = {}
|
|
||||||
url_path = "{ver}/meta-data/instance-id".format(
|
|
||||||
ver=self.min_metadata_version
|
|
||||||
diff --git a/cloudinit/sources/DataSourceLXD.py b/cloudinit/sources/DataSourceLXD.py
|
|
||||||
index cd316101..4c95b907 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceLXD.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceLXD.py
|
|
||||||
@@ -331,7 +331,7 @@ class MetaDataKeys(Flag):
|
|
||||||
CONFIG = auto()
|
|
||||||
DEVICES = auto()
|
|
||||||
META_DATA = auto()
|
|
||||||
- ALL = CONFIG | DEVICES | META_DATA
|
|
||||||
+ ALL = CONFIG | DEVICES | META_DATA # pylint: disable=E1131
|
|
||||||
|
|
||||||
|
|
||||||
class _MetaDataReader:
|
|
||||||
diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py
|
|
||||||
index fa729b7d..ec211a00 100644
|
|
||||||
--- a/tests/integration_tests/conftest.py
|
|
||||||
+++ b/tests/integration_tests/conftest.py
|
|
||||||
@@ -241,7 +241,7 @@ def _client(
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
-def client(
|
|
||||||
+def client( # pylint: disable=W0135
|
|
||||||
request, fixture_utils, session_cloud, setup_image
|
|
||||||
) -> Iterator[IntegrationInstance]:
|
|
||||||
"""Provide a client that runs for every test."""
|
|
||||||
@@ -250,7 +250,7 @@ def client(
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
-def module_client(
|
|
||||||
+def module_client( # pylint: disable=W0135
|
|
||||||
request, fixture_utils, session_cloud, setup_image
|
|
||||||
) -> Iterator[IntegrationInstance]:
|
|
||||||
"""Provide a client that runs once per module."""
|
|
||||||
@@ -259,7 +259,7 @@ def module_client(
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="class")
|
|
||||||
-def class_client(
|
|
||||||
+def class_client( # pylint: disable=W0135
|
|
||||||
request, fixture_utils, session_cloud, setup_image
|
|
||||||
) -> Iterator[IntegrationInstance]:
|
|
||||||
"""Provide a client that runs once per class."""
|
|
||||||
diff --git a/tests/integration_tests/util.py b/tests/integration_tests/util.py
|
|
||||||
index 0a15203c..e26e466c 100644
|
|
||||||
--- a/tests/integration_tests/util.py
|
|
||||||
+++ b/tests/integration_tests/util.py
|
|
||||||
@@ -182,7 +182,7 @@ def wait_for_cloud_init(client: IntegrationInstance, num_retries: int = 30):
|
|
||||||
except Exception as e:
|
|
||||||
last_exception = e
|
|
||||||
time.sleep(1)
|
|
||||||
- raise Exception(
|
|
||||||
+ raise Exception( # pylint: disable=W0719
|
|
||||||
"cloud-init status did not return successfully."
|
|
||||||
) from last_exception
|
|
||||||
|
|
||||||
diff --git a/tests/unittests/config/test_cc_ntp.py b/tests/unittests/config/test_cc_ntp.py
|
|
||||||
index a9444ec5..c9ce5daa 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_ntp.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_ntp.py
|
|
||||||
@@ -248,6 +248,7 @@ class TestNtp(FilesystemMockingTestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
def _get_expected_pools(self, pools, distro, client):
|
|
||||||
+ expected_pools = None
|
|
||||||
if client in ["ntp", "chrony"]:
|
|
||||||
if client == "ntp" and distro == "alpine":
|
|
||||||
# NTP for Alpine Linux is Busybox's ntp which does not
|
|
||||||
@@ -263,6 +264,7 @@ class TestNtp(FilesystemMockingTestCase):
|
|
||||||
return expected_pools
|
|
||||||
|
|
||||||
def _get_expected_servers(self, servers, distro, client):
|
|
||||||
+ expected_servers = None
|
|
||||||
if client in ["ntp", "chrony"]:
|
|
||||||
if client == "ntp" and distro == "alpine":
|
|
||||||
# NTP for Alpine Linux is Busybox's ntp which only supports
|
|
||||||
diff --git a/tests/unittests/sources/test_gce.py b/tests/unittests/sources/test_gce.py
|
|
||||||
index c0b19d3c..30a50236 100644
|
|
||||||
--- a/tests/unittests/sources/test_gce.py
|
|
||||||
+++ b/tests/unittests/sources/test_gce.py
|
|
||||||
@@ -101,6 +101,7 @@ class TestDataSourceGCE(test_helpers.ResponsesTestCase):
|
|
||||||
gce_meta = GCE_META
|
|
||||||
|
|
||||||
def _request_callback(request):
|
|
||||||
+ recursive = False
|
|
||||||
url_path = urlparse(request.url).path
|
|
||||||
if url_path.startswith("/computeMetadata/v1/"):
|
|
||||||
path = url_path.split("/computeMetadata/v1/")[1:][0]
|
|
||||||
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
|
|
||||||
index 519ef63c..de1326d4 100644
|
|
||||||
--- a/tests/unittests/test_util.py
|
|
||||||
+++ b/tests/unittests/test_util.py
|
|
||||||
@@ -1677,6 +1677,8 @@ class TestRedirectOutputPreexecFn:
|
|
||||||
args = (test_string, None)
|
|
||||||
elif request.param == "errfmt":
|
|
||||||
args = (None, test_string)
|
|
||||||
+ else:
|
|
||||||
+ args = (None, None)
|
|
||||||
with mock.patch(M_PATH + "subprocess.Popen") as m_popen:
|
|
||||||
util.redirect_output(*args)
|
|
||||||
|
|
||||||
diff --git a/tox.ini b/tox.ini
|
|
||||||
index 5f01a9a8..5199ca13 100644
|
|
||||||
--- a/tox.ini
|
|
||||||
+++ b/tox.ini
|
|
||||||
@@ -25,7 +25,7 @@ hypothesis==6.31.6
|
|
||||||
hypothesis_jsonschema==0.20.1
|
|
||||||
isort==5.10.1
|
|
||||||
mypy==0.950
|
|
||||||
-pylint==2.13.9
|
|
||||||
+pylint==3.2.0
|
|
||||||
pytest==7.0.1
|
|
||||||
ruff==0.0.285
|
|
||||||
types-jsonschema==4.4.2
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
From 52c04e1a523a450dfce70bc441963eb6a026eb59 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 20 Jun 2024 11:18:40 +0530
|
|
||||||
Subject: [PATCH 3/6] doc: update examples to reflect alternative ways to
|
|
||||||
provide `sudo` option (#5418)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
|
|
||||||
RH-Jira: RHEL-44337
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [2/2] 62eac6d731cb725c32cd0beac0219ecc2b407198 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
For creating users and groups, it is possible to pass a `sudo` option to the
|
|
||||||
config file that accepts a sudo rule. The option can be a sudo rule string,
|
|
||||||
a list of sudo rule strings or `False` to explicitly deny sudo usage. Update
|
|
||||||
examples to show how a list of strings can be used with `sudo` option.
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit cbcb05349e35023ee6e81ccaf13e79adb8f65f63)
|
|
||||||
---
|
|
||||||
doc/examples/cloud-config-user-groups.txt | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
|
|
||||||
index 87fc52e8..56eb674f 100644
|
|
||||||
--- a/doc/examples/cloud-config-user-groups.txt
|
|
||||||
+++ b/doc/examples/cloud-config-user-groups.txt
|
|
||||||
@@ -35,6 +35,10 @@ users:
|
|
||||||
lock_passwd: true
|
|
||||||
ssh_authorized_keys:
|
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSL7uWGj8cgWyIOaspgKdVy0cKJ+UTjfv7jBOjG2H/GN8bJVXy72XAvnhM0dUM+CCs8FOf0YlPX+Frvz2hKInrmRhZVwRSL129PasD12MlI3l44u6IwS1o/W86Q+tkQYEljtqDOo0a+cOsaZkvUNzUyEXUwz/lmYa6G4hMKZH4NBj7nbAAF96wsMCoyNwbWryBnDYUr6wMbjRR1J9Pw7Xh7WRC73wy4Va2YuOgbD3V/5ZrFPLbWZW/7TFXVrql04QVbyei4aiFR5n//GvoqwQDNe58LmbzX/xvxyKJYdny2zXmdAhMxbrpFQsfpkJ9E/H5w0yOdSvnWbUoG5xNGoOB csmith@fringe
|
|
||||||
+ - name: testuser
|
|
||||||
+ gecos: Mr. Test
|
|
||||||
+ homedir: /local/testdir
|
|
||||||
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
|
||||||
- name: cloudy
|
|
||||||
gecos: Magic Cloud App Daemon User
|
|
||||||
inactive: '5'
|
|
||||||
@@ -100,6 +104,8 @@ users:
|
|
||||||
#
|
|
||||||
# Allow a user unrestricted sudo access.
|
|
||||||
# sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
+# or
|
|
||||||
+# sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
|
||||||
#
|
|
||||||
# Adding multiple sudo rule strings.
|
|
||||||
# sudo:
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
|||||||
From c933187af44a5de1d6eafde5dcd48e8ac369cf34 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 18 Apr 2024 20:21:14 -0500
|
|
||||||
Subject: [PATCH 2/3] docs: Add deprecated system_info to schema (#5168)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
RH-Jira: RHEL-45262
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [2/3] c4ea6f45ee0997e2f749c290fb8f2ceb8c05c691 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
In some cases, `system_info` can be passed via user data or vendor data
|
|
||||||
to override the system_info in /etc/cloud/cloud.cfg . While this
|
|
||||||
technically can work, this is a use case we no longer support and should
|
|
||||||
indicate that it is deprecated.
|
|
||||||
|
|
||||||
Also remove/update examples.
|
|
||||||
|
|
||||||
(cherry picked from commit 7c67f7732f04b41600934818f7d5bcb4d085ed7c)
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
- due to change fdefe08ad19cea5eb ("fix: Fix typos (#4850)") not
|
|
||||||
present in downstream.
|
|
||||||
doc/examples/cloud-config-user-groups.txt
|
|
||||||
- due to change 0aa17cd10bdd6 ("docs: set the home directory using homedir, not home (#5101)")
|
|
||||||
not present downstream.
|
|
||||||
tests/unittests/sources/test_vultr.py
|
|
||||||
- due to change 144782a838 ("test: Remove side effects from tests (#5074)") not present
|
|
||||||
downstream.
|
|
||||||
---
|
|
||||||
.../schemas/schema-cloud-config-v1.json | 7 ++++++
|
|
||||||
doc/examples/cloud-config-apt.txt | 23 -------------------
|
|
||||||
doc/examples/cloud-config-user-groups.txt | 12 ++--------
|
|
||||||
tests/data/user_data.1.txt | 10 --------
|
|
||||||
tests/unittests/runs/test_merge_run.py | 16 ++++++++++++-
|
|
||||||
5 files changed, 24 insertions(+), 44 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 670ef4c2..97cf2b74 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -513,6 +513,12 @@
|
|
||||||
},
|
|
||||||
"merge_type": {
|
|
||||||
"$ref": "#/$defs/merge_defintion"
|
|
||||||
+ },
|
|
||||||
+ "system_info": {
|
|
||||||
+ "type": "object",
|
|
||||||
+ "description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data.",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -3905,6 +3911,7 @@
|
|
||||||
"ssh_pwauth": {},
|
|
||||||
"ssh_quiet_keygen": {},
|
|
||||||
"swap": {},
|
|
||||||
+ "system_info": {},
|
|
||||||
"timezone": {},
|
|
||||||
"ubuntu_advantage": {},
|
|
||||||
"updates": {},
|
|
||||||
diff --git a/doc/examples/cloud-config-apt.txt b/doc/examples/cloud-config-apt.txt
|
|
||||||
index dd6a0f6a..04968035 100644
|
|
||||||
--- a/doc/examples/cloud-config-apt.txt
|
|
||||||
+++ b/doc/examples/cloud-config-apt.txt
|
|
||||||
@@ -8,29 +8,6 @@
|
|
||||||
# Number: Set pipelining to some number (not recommended)
|
|
||||||
apt_pipelining: False
|
|
||||||
|
|
||||||
-## apt config via system_info:
|
|
||||||
-# under the 'system_info', you can customize cloud-init's interaction
|
|
||||||
-# with apt.
|
|
||||||
-# system_info:
|
|
||||||
-# apt_get_command: [command, argument, argument]
|
|
||||||
-# apt_get_upgrade_subcommand: dist-upgrade
|
|
||||||
-#
|
|
||||||
-# apt_get_command:
|
|
||||||
-# To specify a different 'apt-get' command, set 'apt_get_command'.
|
|
||||||
-# This must be a list, and the subcommand (update, upgrade) is appended to it.
|
|
||||||
-# default is:
|
|
||||||
-# ['apt-get', '--option=Dpkg::Options::=--force-confold',
|
|
||||||
-# '--option=Dpkg::options::=--force-unsafe-io', '--assume-yes', '--quiet']
|
|
||||||
-#
|
|
||||||
-# apt_get_upgrade_subcommand: "dist-upgrade"
|
|
||||||
-# Specify a different subcommand for 'upgrade. The default is 'dist-upgrade'.
|
|
||||||
-# This is the subcommand that is invoked for package_upgrade.
|
|
||||||
-#
|
|
||||||
-# apt_get_wrapper:
|
|
||||||
-# command: eatmydata
|
|
||||||
-# enabled: [True, False, "auto"]
|
|
||||||
-#
|
|
||||||
-
|
|
||||||
# Install additional packages on first boot
|
|
||||||
#
|
|
||||||
# Default: none
|
|
||||||
diff --git a/doc/examples/cloud-config-user-groups.txt b/doc/examples/cloud-config-user-groups.txt
|
|
||||||
index 56eb674f..2cafef88 100644
|
|
||||||
--- a/doc/examples/cloud-config-user-groups.txt
|
|
||||||
+++ b/doc/examples/cloud-config-user-groups.txt
|
|
||||||
@@ -143,13 +143,5 @@ users:
|
|
||||||
#
|
|
||||||
# users[0] (the first user in users) overrides the user directive.
|
|
||||||
#
|
|
||||||
-# The 'default' user above references the distro's config:
|
|
||||||
-# system_info:
|
|
||||||
-# default_user:
|
|
||||||
-# name: Ubuntu
|
|
||||||
-# plain_text_passwd: 'ubuntu'
|
|
||||||
-# home: /home/ubuntu
|
|
||||||
-# shell: /bin/bash
|
|
||||||
-# lock_passwd: True
|
|
||||||
-# gecos: Ubuntu
|
|
||||||
-# groups: [adm, cdrom, dip, lxd, sudo]
|
|
||||||
+# The 'default' user above references the distro's config set in
|
|
||||||
+# /etc/cloud/cloud.cfg.
|
|
||||||
diff --git a/tests/data/user_data.1.txt b/tests/data/user_data.1.txt
|
|
||||||
index 4c4543de..a1b5aa60 100644
|
|
||||||
--- a/tests/data/user_data.1.txt
|
|
||||||
+++ b/tests/data/user_data.1.txt
|
|
||||||
@@ -3,13 +3,3 @@ write_files:
|
|
||||||
- content: blah
|
|
||||||
path: /etc/blah.ini
|
|
||||||
permissions: 493
|
|
||||||
-
|
|
||||||
-system_info:
|
|
||||||
- package_mirrors:
|
|
||||||
- - arches: [i386, amd64, blah]
|
|
||||||
- failsafe:
|
|
||||||
- primary: http://my.archive.mydomain.com/ubuntu
|
|
||||||
- security: http://my.security.mydomain.com/ubuntu
|
|
||||||
- search:
|
|
||||||
- primary: []
|
|
||||||
- security: []
|
|
||||||
diff --git a/tests/unittests/runs/test_merge_run.py b/tests/unittests/runs/test_merge_run.py
|
|
||||||
index afc256ec..251c5ae5 100644
|
|
||||||
--- a/tests/unittests/runs/test_merge_run.py
|
|
||||||
+++ b/tests/unittests/runs/test_merge_run.py
|
|
||||||
@@ -22,7 +22,21 @@ class TestMergeRun(helpers.FilesystemMockingTestCase):
|
|
||||||
cfg = {
|
|
||||||
"datasource_list": ["None"],
|
|
||||||
"cloud_init_modules": ["write_files"],
|
|
||||||
- "system_info": {"paths": {"run_dir": new_root}},
|
|
||||||
+ "system_info": {
|
|
||||||
+ "paths": {"run_dir": new_root},
|
|
||||||
+ "package_mirrors": [
|
|
||||||
+ {
|
|
||||||
+ "arches": ["i386", "amd64", "blah"],
|
|
||||||
+ "failsafe": {
|
|
||||||
+ "primary": "http://my.archive.mydomain.com/ubuntu",
|
|
||||||
+ "security": (
|
|
||||||
+ "http://my.security.mydomain.com/ubuntu"
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ "search": {"primary": [], "security": []},
|
|
||||||
+ },
|
|
||||||
+ ],
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
ud = helpers.readResource("user_data.1.txt")
|
|
||||||
cloud_cfg = safeyaml.dumps(cfg)
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
|||||||
From c21351ad9da5aebcb252aa36cbfa92ac16fa9746 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Florian Apolloner <florian@apolloner.eu>
|
|
||||||
Date: Fri, 5 Jan 2024 19:07:12 +0100
|
|
||||||
Subject: [PATCH 2/3] feat: apply global DNS to interfaces in network-manager
|
|
||||||
(#4723)
|
|
||||||
|
|
||||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
RH-Jira: RHEL-20964
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [2/2] 1d2b10133ec2558e9665f21f53e4b1a898e283a8 (cavery/cloud-init-c-9-s)
|
|
||||||
|
|
||||||
Sometimes DNS settings in cloud configs are specified globally and
|
|
||||||
not per interface / subnet. This results in a configuration without
|
|
||||||
proper nameservers. This was fixed for netplan in d29eeccd and is
|
|
||||||
now also applied to the network-manager renderer.
|
|
||||||
|
|
||||||
Co-authored-by: James Falcon <james.falcon@canonical.com>
|
|
||||||
(cherry picked from commit 0d787d0a262f70ff848b315633742aa8fc45a1de)
|
|
||||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/network_manager.py | 52 ++++++++++++++---------
|
|
||||||
tests/unittests/net/test_net_rendering.py | 3 ++
|
|
||||||
tests/unittests/test_net.py | 11 +++++
|
|
||||||
tools/.github-cla-signers | 1 +
|
|
||||||
4 files changed, 47 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index bd6e6d75..0ba210b7 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -246,7 +246,7 @@ class NMConnection:
|
|
||||||
"""
|
|
||||||
return addr.replace("-", ":").upper()
|
|
||||||
|
|
||||||
- def render_interface(self, iface, renderer):
|
|
||||||
+ def render_interface(self, iface, network_state, renderer):
|
|
||||||
"""
|
|
||||||
Integrate information from network state interface information
|
|
||||||
into the connection. Most of the work is done here.
|
|
||||||
@@ -311,7 +311,6 @@ class NMConnection:
|
|
||||||
found_dns_search = []
|
|
||||||
|
|
||||||
# Deal with Layer 3 configuration
|
|
||||||
- use_top_level_dns = "dns" in iface
|
|
||||||
for subnet in iface["subnets"]:
|
|
||||||
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
|
|
||||||
|
|
||||||
@@ -322,26 +321,39 @@ class NMConnection:
|
|
||||||
self.config[family]["gateway"] = subnet["gateway"]
|
|
||||||
for route in subnet["routes"]:
|
|
||||||
self._add_route(route)
|
|
||||||
- if not use_top_level_dns and "dns_nameservers" in subnet:
|
|
||||||
- for nameserver in subnet["dns_nameservers"]:
|
|
||||||
- found_nameservers.append(nameserver)
|
|
||||||
- if not use_top_level_dns and "dns_search" in subnet:
|
|
||||||
- found_dns_search.append(subnet["dns_search"])
|
|
||||||
+ # Add subnet-level DNS
|
|
||||||
+ if "dns_nameservers" in subnet:
|
|
||||||
+ found_nameservers.extend(subnet["dns_nameservers"])
|
|
||||||
+ if "dns_search" in subnet:
|
|
||||||
+ found_dns_search.extend(subnet["dns_search"])
|
|
||||||
if family == "ipv4" and "mtu" in subnet:
|
|
||||||
ipv4_mtu = subnet["mtu"]
|
|
||||||
|
|
||||||
- # Now add our DNS search domains. We add them later because we
|
|
||||||
- # only want them if an IP family has already been defined
|
|
||||||
- if use_top_level_dns:
|
|
||||||
- for nameserver in iface["dns"]["nameservers"]:
|
|
||||||
- self._add_nameserver(nameserver)
|
|
||||||
- if iface["dns"]["search"]:
|
|
||||||
- self._add_dns_search(iface["dns"]["search"])
|
|
||||||
- else:
|
|
||||||
- for nameserver in found_nameservers:
|
|
||||||
- self._add_nameserver(nameserver)
|
|
||||||
- for dns_search in found_dns_search:
|
|
||||||
- self._add_dns_search(dns_search)
|
|
||||||
+ # Add interface-level DNS
|
|
||||||
+ if "dns" in iface:
|
|
||||||
+ found_nameservers += [
|
|
||||||
+ dns
|
|
||||||
+ for dns in iface["dns"]["nameservers"]
|
|
||||||
+ if dns not in found_nameservers
|
|
||||||
+ ]
|
|
||||||
+ found_dns_search += [
|
|
||||||
+ search
|
|
||||||
+ for search in iface["dns"]["search"]
|
|
||||||
+ if search not in found_dns_search
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ # We prefer any interface-specific DNS entries, but if we do not
|
|
||||||
+ # have any, add the global DNS to the connection
|
|
||||||
+ if not found_nameservers and network_state.dns_nameservers:
|
|
||||||
+ found_nameservers = network_state.dns_nameservers
|
|
||||||
+ if not found_dns_search and network_state.dns_searchdomains:
|
|
||||||
+ found_dns_search = network_state.dns_searchdomains
|
|
||||||
+
|
|
||||||
+ # Write out all DNS entries to the connection
|
|
||||||
+ for nameserver in found_nameservers:
|
|
||||||
+ self._add_nameserver(nameserver)
|
|
||||||
+ if found_dns_search:
|
|
||||||
+ self._add_dns_search(found_dns_search)
|
|
||||||
|
|
||||||
# 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
|
|
||||||
@@ -457,7 +469,7 @@ class Renderer(renderer.Renderer):
|
|
||||||
# Now render the actual interface configuration
|
|
||||||
for iface in network_state.iter_interfaces():
|
|
||||||
conn = self.connections[iface["name"]]
|
|
||||||
- conn.render_interface(iface, self)
|
|
||||||
+ conn.render_interface(iface, network_state, self)
|
|
||||||
|
|
||||||
# And finally write the files
|
|
||||||
for con_id, conn in self.connections.items():
|
|
||||||
diff --git a/tests/unittests/net/test_net_rendering.py b/tests/unittests/net/test_net_rendering.py
|
|
||||||
index 06feab89..f340ffc1 100644
|
|
||||||
--- a/tests/unittests/net/test_net_rendering.py
|
|
||||||
+++ b/tests/unittests/net/test_net_rendering.py
|
|
||||||
@@ -88,6 +88,9 @@ def _check_network_manager(network_state: NetworkState, tmp_path: Path):
|
|
||||||
"test_name, renderers",
|
|
||||||
[("no_matching_mac_v2", Renderer.Netplan | Renderer.NetworkManager)],
|
|
||||||
)
|
|
||||||
+@pytest.mark.xfail(
|
|
||||||
+ reason="v2 interface-specific DNS errantly gets applied globally"
|
|
||||||
+)
|
|
||||||
def test_convert(test_name, renderers, tmp_path):
|
|
||||||
network_config = safeyaml.load(
|
|
||||||
Path(ARTIFACT_DIR, f"{test_name}.yaml").read_text()
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index 2a99f150..d7c9a414 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -646,6 +646,7 @@ method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=172.19.1.34/22
|
|
||||||
route1=0.0.0.0/0,172.19.3.254
|
|
||||||
+dns=172.19.0.12;
|
|
||||||
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
@@ -2797,6 +2798,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
may-fail=false
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2822,6 +2825,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=192.168.200.7/24
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2846,6 +2851,8 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
[ipv4]
|
|
||||||
method=auto
|
|
||||||
may-fail=false
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2930,12 +2937,15 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=192.168.14.2/24
|
|
||||||
+ dns=8.8.8.8;4.4.4.4;8.8.4.4;
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
[ipv6]
|
|
||||||
method=manual
|
|
||||||
may-fail=false
|
|
||||||
address1=2001:1::1/64
|
|
||||||
route1=::/0,2001:4800:78ff:1b::1
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2990,6 +3000,7 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
[ipv6]
|
|
||||||
method=auto
|
|
||||||
may-fail=false
|
|
||||||
+ dns-search=barley.maas;wark.maas;foobar.maas;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers
|
|
||||||
index dbdb9cfa..f4da0989 100644
|
|
||||||
--- a/tools/.github-cla-signers
|
|
||||||
+++ b/tools/.github-cla-signers
|
|
||||||
@@ -13,6 +13,7 @@ andrewbogott
|
|
||||||
andrewlukoshko
|
|
||||||
ani-sinha
|
|
||||||
antonyc
|
|
||||||
+apollo13
|
|
||||||
aswinrajamannar
|
|
||||||
bdrung
|
|
||||||
beantaxi
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,351 +0,0 @@
|
|||||||
From 6b32b371bfd37759ddce3d7f29d15546500698e6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 20 Jun 2024 22:27:03 +0530
|
|
||||||
Subject: [PATCH 1/6] feat(sysconfig): Add DNS from interface config to
|
|
||||||
resolv.conf (#5401)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 88: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
|
|
||||||
RH-Jira: RHEL-17961
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] f353b73cc0f4bb9e1aee037708a1d3cb23b83cc3 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
sysconfig renderer currently only uses global dns and search domain
|
|
||||||
configuration in order to populate /etc/resolv.conf. This means it ignores
|
|
||||||
interface specific dns configuration completely. This means, when global dns
|
|
||||||
information is absent and only interface specific dns configuration is present,
|
|
||||||
/etc/resolv.conf will not have complete dns information. Fix this so that
|
|
||||||
per interface dns information is also taken into account along with global dns
|
|
||||||
configuration in order to populate /etc/resolv.conf.
|
|
||||||
|
|
||||||
Fixes: GH-5400
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 1b8030e0c7fd6fbff7e38ad1e3e6266ae50c83a5)
|
|
||||||
---
|
|
||||||
cloudinit/net/sysconfig.py | 52 +++++++++-
|
|
||||||
tests/unittests/test_net.py | 184 +++++++++++++++++++++++++++++++++++-
|
|
||||||
2 files changed, 230 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index d39f4fe3..7eb430ed 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -825,20 +825,62 @@ class Renderer(renderer.Renderer):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _render_dns(network_state, existing_dns_path=None):
|
|
||||||
- # skip writing resolv.conf if network_state doesn't include any input.
|
|
||||||
+
|
|
||||||
+ found_nameservers = []
|
|
||||||
+ found_dns_search = []
|
|
||||||
+
|
|
||||||
+ for iface in network_state.iter_interfaces():
|
|
||||||
+ for subnet in iface["subnets"]:
|
|
||||||
+ # Add subnet-level DNS
|
|
||||||
+ if "dns_nameservers" in subnet:
|
|
||||||
+ found_nameservers.extend(subnet["dns_nameservers"])
|
|
||||||
+ if "dns_search" in subnet:
|
|
||||||
+ found_dns_search.extend(subnet["dns_search"])
|
|
||||||
+
|
|
||||||
+ # Add interface-level DNS
|
|
||||||
+ if "dns" in iface:
|
|
||||||
+ found_nameservers += [
|
|
||||||
+ dns
|
|
||||||
+ for dns in iface["dns"]["nameservers"]
|
|
||||||
+ if dns not in found_nameservers
|
|
||||||
+ ]
|
|
||||||
+ found_dns_search += [
|
|
||||||
+ search
|
|
||||||
+ for search in iface["dns"]["search"]
|
|
||||||
+ if search not in found_dns_search
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ # When both global and interface specific entries are present,
|
|
||||||
+ # use them both to generate /etc/resolv.conf eliminating duplicate
|
|
||||||
+ # entries. Otherwise use global or interface specific entries whichever
|
|
||||||
+ # is provided.
|
|
||||||
+ if network_state.dns_nameservers:
|
|
||||||
+ found_nameservers += [
|
|
||||||
+ nameserver
|
|
||||||
+ for nameserver in network_state.dns_nameservers
|
|
||||||
+ if nameserver not in found_nameservers
|
|
||||||
+ ]
|
|
||||||
+ if network_state.dns_searchdomains:
|
|
||||||
+ found_dns_search += [
|
|
||||||
+ search
|
|
||||||
+ for search in network_state.dns_searchdomains
|
|
||||||
+ if search not in found_dns_search
|
|
||||||
+ ]
|
|
||||||
+
|
|
||||||
+ # skip writing resolv.conf if no dns information is provided in conf.
|
|
||||||
if not any(
|
|
||||||
[
|
|
||||||
- len(network_state.dns_nameservers),
|
|
||||||
- len(network_state.dns_searchdomains),
|
|
||||||
+ len(found_nameservers),
|
|
||||||
+ len(found_dns_search),
|
|
||||||
]
|
|
||||||
):
|
|
||||||
return None
|
|
||||||
content = resolv_conf.ResolvConf("")
|
|
||||||
if existing_dns_path and os.path.isfile(existing_dns_path):
|
|
||||||
content = resolv_conf.ResolvConf(util.load_file(existing_dns_path))
|
|
||||||
- for nameserver in network_state.dns_nameservers:
|
|
||||||
+ for nameserver in found_nameservers:
|
|
||||||
content.add_nameserver(nameserver)
|
|
||||||
- for searchdomain in network_state.dns_searchdomains:
|
|
||||||
+ for searchdomain in found_dns_search:
|
|
||||||
content.add_search_domain(searchdomain)
|
|
||||||
header = _make_header(";")
|
|
||||||
content_str = str(content)
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index d7c9a414..2d716f4b 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -516,6 +516,8 @@ OS_SAMPLES = [
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ip_address": "172.19.1.34",
|
|
||||||
+ "dns_search": ["testweb.com"],
|
|
||||||
+ "dns_nameservers": ["172.19.0.13"],
|
|
||||||
"id": "network0",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -550,7 +552,9 @@ STARTMODE=auto
|
|
||||||
"""
|
|
||||||
; Created by cloud-init automatically, do not edit.
|
|
||||||
;
|
|
||||||
+nameserver 172.19.0.13
|
|
||||||
nameserver 172.19.0.12
|
|
||||||
+search testweb.com
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
@@ -582,6 +586,8 @@ AUTOCONNECT_PRIORITY=120
|
|
||||||
BOOTPROTO=none
|
|
||||||
DEFROUTE=yes
|
|
||||||
DEVICE=eth0
|
|
||||||
+DNS1=172.19.0.13
|
|
||||||
+DOMAIN=testweb.com
|
|
||||||
GATEWAY=172.19.3.254
|
|
||||||
HWADDR=fa:16:3e:ed:9a:59
|
|
||||||
IPADDR=172.19.1.34
|
|
||||||
@@ -596,7 +602,174 @@ USERCTL=no
|
|
||||||
"""
|
|
||||||
; Created by cloud-init automatically, do not edit.
|
|
||||||
;
|
|
||||||
+nameserver 172.19.0.13
|
|
||||||
nameserver 172.19.0.12
|
|
||||||
+search testweb.com
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+[main]
|
|
||||||
+dns = none
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/udev/rules.d/70-persistent-net.rules",
|
|
||||||
+ "".join(
|
|
||||||
+ [
|
|
||||||
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
|
|
||||||
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
|
|
||||||
+ ]
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ "expected_network_manager": [
|
|
||||||
+ (
|
|
||||||
+ "".join(
|
|
||||||
+ [
|
|
||||||
+ "etc/NetworkManager/system-connections",
|
|
||||||
+ "/cloud-init-eth0.nmconnection",
|
|
||||||
+ ]
|
|
||||||
+ ),
|
|
||||||
+ """
|
|
||||||
+# Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+[connection]
|
|
||||||
+id=cloud-init eth0
|
|
||||||
+uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+autoconnect-priority=120
|
|
||||||
+type=ethernet
|
|
||||||
+
|
|
||||||
+[user]
|
|
||||||
+org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+[ethernet]
|
|
||||||
+mac-address=FA:16:3E:ED:9A:59
|
|
||||||
+
|
|
||||||
+[ipv4]
|
|
||||||
+method=manual
|
|
||||||
+may-fail=false
|
|
||||||
+address1=172.19.1.34/22
|
|
||||||
+route1=0.0.0.0/0,172.19.3.254
|
|
||||||
+dns=172.19.0.13;
|
|
||||||
+dns-search=testweb.com;
|
|
||||||
+
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "in_data": {
|
|
||||||
+ "services": [
|
|
||||||
+ {
|
|
||||||
+ "type": "dns",
|
|
||||||
+ "address": "172.19.0.12",
|
|
||||||
+ "search": ["example1.com", "example2.com"],
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ "networks": [
|
|
||||||
+ {
|
|
||||||
+ "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
|
|
||||||
+ "type": "ipv4",
|
|
||||||
+ "netmask": "255.255.252.0",
|
|
||||||
+ "link": "eth0",
|
|
||||||
+ "routes": [
|
|
||||||
+ {
|
|
||||||
+ "netmask": "0.0.0.0",
|
|
||||||
+ "network": "0.0.0.0",
|
|
||||||
+ "gateway": "172.19.3.254",
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ "ip_address": "172.19.1.34",
|
|
||||||
+ "dns_search": ["example3.com"],
|
|
||||||
+ "dns_nameservers": ["172.19.0.12"],
|
|
||||||
+ "id": "network0",
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
+ "links": [
|
|
||||||
+ {
|
|
||||||
+ "ethernet_mac_address": "fa:16:3e:ed:9a:59",
|
|
||||||
+ "mtu": None,
|
|
||||||
+ "type": "physical",
|
|
||||||
+ "id": "eth0",
|
|
||||||
+ },
|
|
||||||
+ ],
|
|
||||||
+ },
|
|
||||||
+ "in_macs": {
|
|
||||||
+ "fa:16:3e:ed:9a:59": "eth0",
|
|
||||||
+ },
|
|
||||||
+ "out_sysconfig_opensuse": [
|
|
||||||
+ (
|
|
||||||
+ "etc/sysconfig/network/ifcfg-eth0",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+BOOTPROTO=static
|
|
||||||
+IPADDR=172.19.1.34
|
|
||||||
+LLADDR=fa:16:3e:ed:9a:59
|
|
||||||
+NETMASK=255.255.252.0
|
|
||||||
+STARTMODE=auto
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/resolv.conf",
|
|
||||||
+ """
|
|
||||||
+; Created by cloud-init automatically, do not edit.
|
|
||||||
+;
|
|
||||||
+nameserver 172.19.0.12
|
|
||||||
+search example3.com example1.com example2.com
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/NetworkManager/conf.d/99-cloud-init.conf",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+[main]
|
|
||||||
+dns = none
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/udev/rules.d/85-persistent-net-cloud-init.rules",
|
|
||||||
+ "".join(
|
|
||||||
+ [
|
|
||||||
+ 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
|
|
||||||
+ 'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n',
|
|
||||||
+ ]
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+ ],
|
|
||||||
+ "out_sysconfig_rhel": [
|
|
||||||
+ (
|
|
||||||
+ "etc/sysconfig/network-scripts/ifcfg-eth0",
|
|
||||||
+ """
|
|
||||||
+# Created by cloud-init automatically, do not edit.
|
|
||||||
+#
|
|
||||||
+AUTOCONNECT_PRIORITY=120
|
|
||||||
+BOOTPROTO=none
|
|
||||||
+DEFROUTE=yes
|
|
||||||
+DEVICE=eth0
|
|
||||||
+DNS1=172.19.0.12
|
|
||||||
+DOMAIN=example3.com
|
|
||||||
+GATEWAY=172.19.3.254
|
|
||||||
+HWADDR=fa:16:3e:ed:9a:59
|
|
||||||
+IPADDR=172.19.1.34
|
|
||||||
+NETMASK=255.255.252.0
|
|
||||||
+ONBOOT=yes
|
|
||||||
+TYPE=Ethernet
|
|
||||||
+USERCTL=no
|
|
||||||
+""".lstrip(),
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ "etc/resolv.conf",
|
|
||||||
+ """
|
|
||||||
+; Created by cloud-init automatically, do not edit.
|
|
||||||
+;
|
|
||||||
+nameserver 172.19.0.12
|
|
||||||
+search example3.com example1.com example2.com
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
@@ -647,6 +820,7 @@ may-fail=false
|
|
||||||
address1=172.19.1.34/22
|
|
||||||
route1=0.0.0.0/0,172.19.3.254
|
|
||||||
dns=172.19.0.12;
|
|
||||||
+dns-search=example3.com;
|
|
||||||
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
@@ -654,7 +828,13 @@ dns=172.19.0.12;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in_data": {
|
|
||||||
- "services": [{"type": "dns", "address": "172.19.0.12"}],
|
|
||||||
+ "services": [
|
|
||||||
+ {
|
|
||||||
+ "type": "dns",
|
|
||||||
+ "address": "172.19.0.12",
|
|
||||||
+ "search": "example.com",
|
|
||||||
+ }
|
|
||||||
+ ],
|
|
||||||
"networks": [
|
|
||||||
{
|
|
||||||
"network_id": "public-ipv4",
|
|
||||||
@@ -715,6 +895,7 @@ STARTMODE=auto
|
|
||||||
; Created by cloud-init automatically, do not edit.
|
|
||||||
;
|
|
||||||
nameserver 172.19.0.12
|
|
||||||
+search example.com
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
@@ -763,6 +944,7 @@ USERCTL=no
|
|
||||||
; Created by cloud-init automatically, do not edit.
|
|
||||||
;
|
|
||||||
nameserver 172.19.0.12
|
|
||||||
+search example.com
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
From 6a61ce0f0cde11551bfe92835d0b33c7b1022b68 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 18 Apr 2024 20:27:27 -0500
|
|
||||||
Subject: [PATCH] fix: Add subnet ipv4/ipv6 to network schema (#5191)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 109: fix: Add subnet ipv4/ipv6 to network schema (#5191)
|
|
||||||
RH-Jira: RHEL-54686
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 83692fac8f9af1831970091bdf7c43d0e59f314c (anisinha/cloud-init)
|
|
||||||
|
|
||||||
These are used by our openstack network_data.json parsing code and
|
|
||||||
get used by the sysconfig renderer.
|
|
||||||
|
|
||||||
Fixes GH-4911
|
|
||||||
|
|
||||||
(cherry picked from commit 0b1ca174095e3ad685e6d6649bb08aafb19a95b9)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/config/schemas/schema-network-config-v1.json | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
index 64c492a4..f485c784 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
@@ -523,6 +523,14 @@
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/$defs/anyOf_type_route"
|
|
||||||
}
|
|
||||||
+ },
|
|
||||||
+ "ipv4": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "description": "Indicate if the subnet is IPv4. If not specified, it will be inferred from the subnet type or address. This exists for compatibility with OpenStack's ``network_data.json`` when rendered through sysconfig."
|
|
||||||
+ },
|
|
||||||
+ "ipv6": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "description": "Indicate if the subnet is IPv6. If not specified, it will be inferred from the subnet type or address. This is exists for compatibility with OpenStack's ``network_data.json`` when rendered through sysconfig."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
|||||||
From 2f7f3dc6237ea70825dcb70f71d9718f631a9d95 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] fix: Add types to network v1 schema (#4841)
|
|
||||||
|
|
||||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-MergeRequest: 69: fix: Add types to network v1 schema (#4841)
|
|
||||||
RH-Jira: RHEL-21324
|
|
||||||
RH-Acked-by: Ani Sinha <None>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 59b2b4b07dd9eed956943a22b90af487f18b4cbd (cavery/cloud-init-c-9-s)
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
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
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
|||||||
From 8ead44cb39f7726a695aa21a34820f6d40270829 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Mon, 12 Feb 2024 14:48:01 -0600
|
|
||||||
Subject: [PATCH 5/6] fix: Address TIOBE abstract interpretation issues (#4866)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 92: Update pylint version to support python 3.12
|
|
||||||
RH-Jira: RHEL-44598
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [2/3] 3ca11206fa159ab45b2db21e78c4cfaf358b1e01 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
These involve operations on possibly null variables or impossible logic.
|
|
||||||
|
|
||||||
(cherry picked from commit 5e7ef1032a12267a9a518358fbf89da0a88ddb99)
|
|
||||||
---
|
|
||||||
cloudinit/config/cc_lxd.py | 2 +-
|
|
||||||
cloudinit/distros/parsers/ifconfig.py | 6 ++++++
|
|
||||||
cloudinit/util.py | 1 +
|
|
||||||
3 files changed, 8 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py
|
|
||||||
index cb9fc4f3..9f267b4c 100644
|
|
||||||
--- a/cloudinit/config/cc_lxd.py
|
|
||||||
+++ b/cloudinit/config/cc_lxd.py
|
|
||||||
@@ -432,7 +432,7 @@ def bridge_to_cmd(bridge_cfg):
|
|
||||||
% (bridge_cfg.get("ipv6_address"), bridge_cfg.get("ipv6_netmask"))
|
|
||||||
)
|
|
||||||
|
|
||||||
- if bridge_cfg.get("ipv6_nat", "false") == "true":
|
|
||||||
+ if bridge_cfg.get("ipv6_nat") == "true":
|
|
||||||
cmd_create.append("ipv6.nat=true")
|
|
||||||
|
|
||||||
else:
|
|
||||||
diff --git a/cloudinit/distros/parsers/ifconfig.py b/cloudinit/distros/parsers/ifconfig.py
|
|
||||||
index 516b5eb5..d671df1f 100644
|
|
||||||
--- a/cloudinit/distros/parsers/ifconfig.py
|
|
||||||
+++ b/cloudinit/distros/parsers/ifconfig.py
|
|
||||||
@@ -102,6 +102,7 @@ class Ifconfig:
|
|
||||||
"""
|
|
||||||
ifindex = 0
|
|
||||||
ifs_by_mac = defaultdict(list)
|
|
||||||
+ dev = None
|
|
||||||
for line in text.splitlines():
|
|
||||||
if len(line) == 0:
|
|
||||||
continue
|
|
||||||
@@ -119,6 +120,11 @@ class Ifconfig:
|
|
||||||
dev.index = ifindex
|
|
||||||
self._ifs_by_name[curif] = dev
|
|
||||||
|
|
||||||
+ if not dev:
|
|
||||||
+ # This shouldn't happen with normal ifconfig output, but
|
|
||||||
+ # if it does, ensure we don't Traceback
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
toks = line.lower().strip().split()
|
|
||||||
|
|
||||||
if len(toks) > 1 and toks[1].startswith("flags="):
|
|
||||||
diff --git a/cloudinit/util.py b/cloudinit/util.py
|
|
||||||
index 3295735c..5f787c5c 100644
|
|
||||||
--- a/cloudinit/util.py
|
|
||||||
+++ b/cloudinit/util.py
|
|
||||||
@@ -1417,6 +1417,7 @@ def find_devs_with_netbsd(
|
|
||||||
devlist = []
|
|
||||||
label = None
|
|
||||||
_type = None
|
|
||||||
+ mscdlabel_out = ""
|
|
||||||
if criteria:
|
|
||||||
if criteria.startswith("LABEL="):
|
|
||||||
label = criteria.lstrip("LABEL=")
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From 62cec1e38e117fe6b24888862576ac57be14bbda Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 26 Mar 2024 15:55:50 -0500
|
|
||||||
Subject: [PATCH] fix: Always use single datasource if specified (#5098)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 82: fix: Always use single datasource if specified (#5098)
|
|
||||||
RH-Jira: RHEL-36255
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 068e97fcc18dd99f1112a9109acdb30fe2880f6e (anisinha/cloud-init)
|
|
||||||
|
|
||||||
This change may require a user to add `None` to the `datasource_list`
|
|
||||||
defined in `/etc/cloud/cloud.cfg[.d]` if they have a customized
|
|
||||||
datasource_list and want the DataSourceNone fallback behavior.
|
|
||||||
|
|
||||||
ds-identify would automatically append "None" to the datasource_list
|
|
||||||
if a single entry was provided in /etc/cloud/cloud.cfg[.d].
|
|
||||||
This wasn't a problem in the past as the python code would detect
|
|
||||||
a single datasource along with None as an indication to automatically
|
|
||||||
use that datasource. Since the python code no longer does that,
|
|
||||||
we should ensure that one specified datasource results in one specified
|
|
||||||
datasource after ds-identify has run.
|
|
||||||
|
|
||||||
Fixes GH-5091
|
|
||||||
|
|
||||||
(cherry picked from commit cdbbd17ae400e432d13f674c18a6f5c873fa328b)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
tests/unittests/test_ds_identify.py | 2 +-
|
|
||||||
tools/ds-identify | 6 +++++-
|
|
||||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
|
|
||||||
index ba0bf779..acbf3f03 100644
|
|
||||||
--- a/tests/unittests/test_ds_identify.py
|
|
||||||
+++ b/tests/unittests/test_ds_identify.py
|
|
||||||
@@ -522,7 +522,7 @@ class TestDsIdentify(DsIdentifyBase):
|
|
||||||
mydata = copy.deepcopy(VALID_CFG["Ec2-hvm"])
|
|
||||||
cfgpath = "etc/cloud/cloud.cfg.d/myds.cfg"
|
|
||||||
mydata["files"][cfgpath] = 'datasource_list: ["NoCloud"]\n'
|
|
||||||
- self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud", DS_NONE])
|
|
||||||
+ self._check_via_dict(mydata, rc=RC_FOUND, dslist=["NoCloud"])
|
|
||||||
|
|
||||||
def test_configured_list_with_none(self):
|
|
||||||
"""When datasource_list already contains None, None is not added.
|
|
||||||
diff --git a/tools/ds-identify b/tools/ds-identify
|
|
||||||
index ec2cc18a..6e49ded3 100755
|
|
||||||
--- a/tools/ds-identify
|
|
||||||
+++ b/tools/ds-identify
|
|
||||||
@@ -1865,7 +1865,11 @@ _main() {
|
|
||||||
# if there is only a single entry in $DI_DSLIST
|
|
||||||
if [ $# -eq 1 ] || [ $# -eq 2 -a "$2" = "None" ] ; then
|
|
||||||
debug 1 "single entry in datasource_list ($DI_DSLIST) use that."
|
|
||||||
- found "$@"
|
|
||||||
+ if [ $# -eq 1 ]; then
|
|
||||||
+ write_result "datasource_list: [ $1 ]"
|
|
||||||
+ else
|
|
||||||
+ found "$@"
|
|
||||||
+ fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
|||||||
From 914ac26ebd889b1f5cbb13d55fc011e92fc213c6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 18 Jul 2024 09:04:54 -0400
|
|
||||||
Subject: [PATCH 1/2] fix: Clean cache if no datasource fallback (#5499)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 103: fix: Clean cache if no datasource fallback (#5499)
|
|
||||||
RH-Jira: RHEL-49736
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 37eacd97f5e60fae2f71d401c528d508d3db517e (anisinha/cloud-init)
|
|
||||||
|
|
||||||
9929a00 added the ability to used a cached datasource when none is
|
|
||||||
found. This was supposed to be per-datasource, but the lack of cache
|
|
||||||
cleaning got applied universally. This commit makes it so cache will be
|
|
||||||
cleaned as it was before if fallback isn't implemented in datasource.
|
|
||||||
|
|
||||||
Fixes GH-5486
|
|
||||||
|
|
||||||
(cherry picked from commit 550c685c98551f65c30832b186fe091721b48477)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/stages.py | 1 +
|
|
||||||
.../assets/DataSourceNoCacheNetworkOnly.py | 23 ++++
|
|
||||||
.../assets/DataSourceNoCacheWithFallback.py | 29 +++++
|
|
||||||
.../datasources/test_caching.py | 115 ++++++++++++++++++
|
|
||||||
tests/integration_tests/instances.py | 4 +-
|
|
||||||
5 files changed, 171 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
|
|
||||||
create mode 100644 tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
|
|
||||||
create mode 100644 tests/integration_tests/datasources/test_caching.py
|
|
||||||
|
|
||||||
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
|
||||||
index 0b795624..ace94c9a 100644
|
|
||||||
--- a/cloudinit/stages.py
|
|
||||||
+++ b/cloudinit/stages.py
|
|
||||||
@@ -378,6 +378,7 @@ class Init:
|
|
||||||
ds,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
+ util.del_file(self.paths.instance_link)
|
|
||||||
raise e
|
|
||||||
self.datasource = ds
|
|
||||||
# Ensure we adjust our path members datasource
|
|
||||||
diff --git a/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py b/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000..54a7bab3
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/integration_tests/assets/DataSourceNoCacheNetworkOnly.py
|
|
||||||
@@ -0,0 +1,23 @@
|
|
||||||
+import logging
|
|
||||||
+
|
|
||||||
+from cloudinit import sources
|
|
||||||
+
|
|
||||||
+LOG = logging.getLogger(__name__)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class DataSourceNoCacheNetworkOnly(sources.DataSource):
|
|
||||||
+ def _get_data(self):
|
|
||||||
+ LOG.debug("TEST _get_data called")
|
|
||||||
+ return True
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+datasources = [
|
|
||||||
+ (
|
|
||||||
+ DataSourceNoCacheNetworkOnly,
|
|
||||||
+ (sources.DEP_FILESYSTEM, sources.DEP_NETWORK),
|
|
||||||
+ ),
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def get_datasource_list(depends):
|
|
||||||
+ return sources.list_from_depends(depends, datasources)
|
|
||||||
diff --git a/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py b/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000..fdfc473f
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/integration_tests/assets/DataSourceNoCacheWithFallback.py
|
|
||||||
@@ -0,0 +1,29 @@
|
|
||||||
+import logging
|
|
||||||
+import os
|
|
||||||
+
|
|
||||||
+from cloudinit import sources
|
|
||||||
+
|
|
||||||
+LOG = logging.getLogger(__name__)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class DataSourceNoCacheWithFallback(sources.DataSource):
|
|
||||||
+ def _get_data(self):
|
|
||||||
+ if os.path.exists("/ci-test-firstboot"):
|
|
||||||
+ LOG.debug("TEST _get_data called")
|
|
||||||
+ return True
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ def check_if_fallback_is_allowed(self):
|
|
||||||
+ return True
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+datasources = [
|
|
||||||
+ (
|
|
||||||
+ DataSourceNoCacheWithFallback,
|
|
||||||
+ (sources.DEP_FILESYSTEM,),
|
|
||||||
+ ),
|
|
||||||
+]
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def get_datasource_list(depends):
|
|
||||||
+ return sources.list_from_depends(depends, datasources)
|
|
||||||
diff --git a/tests/integration_tests/datasources/test_caching.py b/tests/integration_tests/datasources/test_caching.py
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000..33e4b671
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/integration_tests/datasources/test_caching.py
|
|
||||||
@@ -0,0 +1,115 @@
|
|
||||||
+import pytest
|
|
||||||
+
|
|
||||||
+from tests.integration_tests import releases, util
|
|
||||||
+from tests.integration_tests.instances import IntegrationInstance
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def setup_custom_datasource(client: IntegrationInstance, datasource_name: str):
|
|
||||||
+ client.write_to_file(
|
|
||||||
+ "/etc/cloud/cloud.cfg.d/99-imds.cfg",
|
|
||||||
+ f"datasource_list: [ {datasource_name}, None ]\n"
|
|
||||||
+ "datasource_pkg_list: [ cisources ]",
|
|
||||||
+ )
|
|
||||||
+ assert client.execute(
|
|
||||||
+ "mkdir -p /usr/lib/python3/dist-packages/cisources"
|
|
||||||
+ )
|
|
||||||
+ client.push_file(
|
|
||||||
+ util.ASSETS_DIR / f"DataSource{datasource_name}.py",
|
|
||||||
+ "/usr/lib/python3/dist-packages/cisources/"
|
|
||||||
+ f"DataSource{datasource_name}.py",
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def verify_no_cache_boot(client: IntegrationInstance):
|
|
||||||
+ log = client.read_from_file("/var/log/cloud-init.log")
|
|
||||||
+ util.verify_ordered_items_in_text(
|
|
||||||
+ [
|
|
||||||
+ "No local datasource found",
|
|
||||||
+ "running 'init'",
|
|
||||||
+ "no cache found",
|
|
||||||
+ "Detected platform",
|
|
||||||
+ "TEST _get_data called",
|
|
||||||
+ ],
|
|
||||||
+ text=log,
|
|
||||||
+ )
|
|
||||||
+ util.verify_clean_boot(client)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+@pytest.mark.skipif(
|
|
||||||
+ not releases.IS_UBUNTU,
|
|
||||||
+ reason="hardcoded dist-packages directory",
|
|
||||||
+)
|
|
||||||
+def test_no_cache_network_only(client: IntegrationInstance):
|
|
||||||
+ """Test cache removal per boot. GH-5486
|
|
||||||
+
|
|
||||||
+ This tests the CloudStack password reset use case. The expectation is:
|
|
||||||
+ - Metadata is fetched in network timeframe only
|
|
||||||
+ - Because `check_instance_id` is not defined, no cached datasource
|
|
||||||
+ is found in the init-local phase, but the cache is used in the
|
|
||||||
+ remaining phases due to existance of /run/cloud-init/.instance-id
|
|
||||||
+ - Because `check_if_fallback_is_allowed` is not defined, cloud-init
|
|
||||||
+ does NOT fall back to the pickled datasource, and will
|
|
||||||
+ instead delete the cache during the init-local phase
|
|
||||||
+ - Metadata is therefore fetched every boot in the network phase
|
|
||||||
+ """
|
|
||||||
+ setup_custom_datasource(client, "NoCacheNetworkOnly")
|
|
||||||
+
|
|
||||||
+ # Run cloud-init as if first boot
|
|
||||||
+ assert client.execute("cloud-init clean --logs")
|
|
||||||
+ client.restart()
|
|
||||||
+
|
|
||||||
+ verify_no_cache_boot(client)
|
|
||||||
+
|
|
||||||
+ # Clear the log without clean and run cloud-init for subsequent boot
|
|
||||||
+ assert client.execute("echo '' > /var/log/cloud-init.log")
|
|
||||||
+ client.restart()
|
|
||||||
+
|
|
||||||
+ verify_no_cache_boot(client)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+@pytest.mark.skipif(
|
|
||||||
+ not releases.IS_UBUNTU,
|
|
||||||
+ reason="hardcoded dist-packages directory",
|
|
||||||
+)
|
|
||||||
+def test_no_cache_with_fallback(client: IntegrationInstance):
|
|
||||||
+ """Test we use fallback when defined and no cache available."""
|
|
||||||
+ setup_custom_datasource(client, "NoCacheWithFallback")
|
|
||||||
+
|
|
||||||
+ # Run cloud-init as if first boot
|
|
||||||
+ assert client.execute("cloud-init clean --logs")
|
|
||||||
+ # Used by custom datasource
|
|
||||||
+ client.execute("touch /ci-test-firstboot")
|
|
||||||
+ client.restart()
|
|
||||||
+
|
|
||||||
+ log = client.read_from_file("/var/log/cloud-init.log")
|
|
||||||
+ util.verify_ordered_items_in_text(
|
|
||||||
+ [
|
|
||||||
+ "no cache found",
|
|
||||||
+ "Detected platform",
|
|
||||||
+ "TEST _get_data called",
|
|
||||||
+ "running 'init'",
|
|
||||||
+ "restored from cache with run check",
|
|
||||||
+ "running 'modules:config'",
|
|
||||||
+ ],
|
|
||||||
+ text=log,
|
|
||||||
+ )
|
|
||||||
+ util.verify_clean_boot(client)
|
|
||||||
+
|
|
||||||
+ # Clear the log without clean and run cloud-init for subsequent boot
|
|
||||||
+ assert client.execute("echo '' > /var/log/cloud-init.log")
|
|
||||||
+ client.execute("rm /ci-test-firstboot")
|
|
||||||
+ client.restart()
|
|
||||||
+
|
|
||||||
+ log = client.read_from_file("/var/log/cloud-init.log")
|
|
||||||
+ util.verify_ordered_items_in_text(
|
|
||||||
+ [
|
|
||||||
+ "cache invalid in datasource",
|
|
||||||
+ "Detected platform",
|
|
||||||
+ "Restored fallback datasource from checked cache",
|
|
||||||
+ "running 'init'",
|
|
||||||
+ "restored from cache with run check",
|
|
||||||
+ "running 'modules:config'",
|
|
||||||
+ ],
|
|
||||||
+ text=log,
|
|
||||||
+ )
|
|
||||||
+ util.verify_clean_boot(client)
|
|
||||||
diff --git a/tests/integration_tests/instances.py b/tests/integration_tests/instances.py
|
|
||||||
index 3fc6558a..23c0dc98 100644
|
|
||||||
--- a/tests/integration_tests/instances.py
|
|
||||||
+++ b/tests/integration_tests/instances.py
|
|
||||||
@@ -88,7 +88,9 @@ class IntegrationInstance:
|
|
||||||
# First push to a temporary directory because of permissions issues
|
|
||||||
tmp_path = _get_tmp_path()
|
|
||||||
self.instance.push_file(str(local_path), tmp_path)
|
|
||||||
- assert self.execute("mv {} {}".format(tmp_path, str(remote_path))).ok
|
|
||||||
+ assert self.execute(
|
|
||||||
+ "mv {} {}".format(tmp_path, str(remote_path))
|
|
||||||
+ ), f"Failed to push {tmp_path} to {remote_path}"
|
|
||||||
|
|
||||||
def read_from_file(self, remote_path) -> str:
|
|
||||||
result = self.execute("cat {}".format(remote_path))
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,391 +0,0 @@
|
|||||||
From aaf1d063f198ce09f0d539a85e1a1a2bb834520b Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 2 Jan 2024 11:29:17 -0600
|
|
||||||
Subject: [PATCH 1/3] fix: Correct v2 NetworkManager route rendering (#4637)
|
|
||||||
|
|
||||||
RH-Author: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-MergeRequest: 72: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
RH-Jira: RHEL-20964
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/2] fb865987dbcf506a674eb9798f9c06859539a696 (cavery/cloud-init-c-9-s)
|
|
||||||
|
|
||||||
fix: Correct v2 NetworkManager route rendering
|
|
||||||
|
|
||||||
Because network v2 route defintions can have mixed v4 and v6 routes, we
|
|
||||||
need to determine the IP family per route rather than per subnet.
|
|
||||||
|
|
||||||
Similar, ensure dns-search is rendered correctly.
|
|
||||||
|
|
||||||
Fixes GH-4518
|
|
||||||
|
|
||||||
(cherry picked from commit c2c100e8c9fd8709539b3ab2b0ee34c66ba3f2f7)
|
|
||||||
Signed-off-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/__init__.py | 2 +
|
|
||||||
cloudinit/net/network_manager.py | 87 +++++++++-------
|
|
||||||
tests/unittests/test_net.py | 165 ++++++++++++++++++++++++++++++-
|
|
||||||
3 files changed, 219 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
|
|
||||||
index c0888f52..65e7ff33 100644
|
|
||||||
--- a/cloudinit/net/__init__.py
|
|
||||||
+++ b/cloudinit/net/__init__.py
|
|
||||||
@@ -1287,6 +1287,8 @@ def subnet_is_ipv6(subnet) -> bool:
|
|
||||||
"""Common helper for checking network_state subnets for ipv6."""
|
|
||||||
# 'static6', 'dhcp6', 'ipv6_dhcpv6-stateful', 'ipv6_dhcpv6-stateless' or
|
|
||||||
# 'ipv6_slaac'
|
|
||||||
+ # This function is inappropriate for v2-based routes as routes defined
|
|
||||||
+ # under v2 subnets can contain ipv4 and ipv6 simultaneously
|
|
||||||
if subnet["type"].endswith("6") or subnet["type"] in IPV6_DYNAMIC_TYPES:
|
|
||||||
# This is a request either static6 type or DHCPv6.
|
|
||||||
return True
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index 76a0ac15..bd6e6d75 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -12,10 +12,15 @@ import itertools
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import uuid
|
|
||||||
-from typing import Optional
|
|
||||||
+from typing import List, Optional
|
|
||||||
|
|
||||||
from cloudinit import subp, util
|
|
||||||
-from cloudinit.net import is_ipv6_address, renderer, subnet_is_ipv6
|
|
||||||
+from cloudinit.net import (
|
|
||||||
+ is_ipv6_address,
|
|
||||||
+ is_ipv6_network,
|
|
||||||
+ renderer,
|
|
||||||
+ subnet_is_ipv6,
|
|
||||||
+)
|
|
||||||
from cloudinit.net.network_state import NetworkState
|
|
||||||
from cloudinit.net.sysconfig import available_nm_ifcfg_rh
|
|
||||||
|
|
||||||
@@ -158,11 +163,11 @@ class NMConnection:
|
|
||||||
if self.config[family]["method"] == "auto" and method == "manual":
|
|
||||||
return
|
|
||||||
|
|
||||||
- if (
|
|
||||||
- subnet_type == "ipv6_dhcpv6-stateful"
|
|
||||||
- or subnet_type == "ipv6_dhcpv6-stateless"
|
|
||||||
- or subnet_type == "ipv6_slaac"
|
|
||||||
- ):
|
|
||||||
+ if subnet_type in [
|
|
||||||
+ "ipv6_dhcpv6-stateful",
|
|
||||||
+ "ipv6_dhcpv6-stateless",
|
|
||||||
+ "ipv6_slaac",
|
|
||||||
+ ]:
|
|
||||||
# set ipv4 method to 'disabled' to align with sysconfig renderer.
|
|
||||||
self._set_default("ipv4", "method", "disabled")
|
|
||||||
|
|
||||||
@@ -174,7 +179,8 @@ class NMConnection:
|
|
||||||
Adds a numbered property, such as address<n> or route<n>, ensuring
|
|
||||||
the appropriate value gets used for <n>.
|
|
||||||
"""
|
|
||||||
-
|
|
||||||
+ if not self.config.has_section(section):
|
|
||||||
+ self.config[section] = {}
|
|
||||||
for index in itertools.count(1):
|
|
||||||
key = f"{key_prefix}{index}"
|
|
||||||
if not self.config.has_option(section, key):
|
|
||||||
@@ -189,40 +195,37 @@ class NMConnection:
|
|
||||||
value = subnet["address"] + "/" + str(subnet["prefix"])
|
|
||||||
self._add_numbered(family, "address", value)
|
|
||||||
|
|
||||||
- def _add_route(self, family, route):
|
|
||||||
- """
|
|
||||||
- Adds a ipv[46].route<n> property.
|
|
||||||
- """
|
|
||||||
-
|
|
||||||
+ def _add_route(self, route):
|
|
||||||
+ """Adds a ipv[46].route<n> property."""
|
|
||||||
+ # Because network v2 route definitions can have mixed v4 and v6
|
|
||||||
+ # routes, determine the family per route based on the gateway
|
|
||||||
+ family = "ipv6" if is_ipv6_network(route["gateway"]) else "ipv4"
|
|
||||||
value = route["network"] + "/" + str(route["prefix"])
|
|
||||||
if "gateway" in route:
|
|
||||||
value = value + "," + route["gateway"]
|
|
||||||
self._add_numbered(family, "route", value)
|
|
||||||
|
|
||||||
- def _add_nameserver(self, dns):
|
|
||||||
+ def _add_nameserver(self, dns: str) -> None:
|
|
||||||
"""
|
|
||||||
Extends the ipv[46].dns property with a name server.
|
|
||||||
"""
|
|
||||||
-
|
|
||||||
- # FIXME: the subnet contains IPv4 and IPv6 name server mixed
|
|
||||||
- # together. We might be getting an IPv6 name server while
|
|
||||||
- # we're dealing with an IPv4 subnet. Sort this out by figuring
|
|
||||||
- # out the correct family and making sure a valid section exist.
|
|
||||||
family = "ipv6" if is_ipv6_address(dns) else "ipv4"
|
|
||||||
- self._set_default(family, "method", "disabled")
|
|
||||||
-
|
|
||||||
- self._set_default(family, "dns", "")
|
|
||||||
- self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
|
|
||||||
+ if self.config.has_section(family):
|
|
||||||
+ self._set_default(family, "dns", "")
|
|
||||||
+ self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
|
|
||||||
|
|
||||||
- def _add_dns_search(self, family, dns_search):
|
|
||||||
+ def _add_dns_search(self, dns_search: List[str]) -> None:
|
|
||||||
"""
|
|
||||||
Extends the ipv[46].dns-search property with a name server.
|
|
||||||
"""
|
|
||||||
-
|
|
||||||
- self._set_default(family, "dns-search", "")
|
|
||||||
- self.config[family]["dns-search"] = (
|
|
||||||
- self.config[family]["dns-search"] + ";".join(dns_search) + ";"
|
|
||||||
- )
|
|
||||||
+ for family in ["ipv4", "ipv6"]:
|
|
||||||
+ if self.config.has_section(family):
|
|
||||||
+ self._set_default(family, "dns-search", "")
|
|
||||||
+ self.config[family]["dns-search"] = (
|
|
||||||
+ self.config[family]["dns-search"]
|
|
||||||
+ + ";".join(dns_search)
|
|
||||||
+ + ";"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def con_uuid(self):
|
|
||||||
"""
|
|
||||||
@@ -304,8 +307,11 @@ class NMConnection:
|
|
||||||
|
|
||||||
device_mtu = iface["mtu"]
|
|
||||||
ipv4_mtu = None
|
|
||||||
+ found_nameservers = []
|
|
||||||
+ found_dns_search = []
|
|
||||||
|
|
||||||
# Deal with Layer 3 configuration
|
|
||||||
+ use_top_level_dns = "dns" in iface
|
|
||||||
for subnet in iface["subnets"]:
|
|
||||||
family = "ipv6" if subnet_is_ipv6(subnet) else "ipv4"
|
|
||||||
|
|
||||||
@@ -315,15 +321,28 @@ class NMConnection:
|
|
||||||
if "gateway" in subnet:
|
|
||||||
self.config[family]["gateway"] = subnet["gateway"]
|
|
||||||
for route in subnet["routes"]:
|
|
||||||
- self._add_route(family, route)
|
|
||||||
- if "dns_nameservers" in subnet:
|
|
||||||
+ self._add_route(route)
|
|
||||||
+ if not use_top_level_dns and "dns_nameservers" in subnet:
|
|
||||||
for nameserver in subnet["dns_nameservers"]:
|
|
||||||
- self._add_nameserver(nameserver)
|
|
||||||
- if "dns_search" in subnet:
|
|
||||||
- self._add_dns_search(family, subnet["dns_search"])
|
|
||||||
+ found_nameservers.append(nameserver)
|
|
||||||
+ if not use_top_level_dns and "dns_search" in subnet:
|
|
||||||
+ found_dns_search.append(subnet["dns_search"])
|
|
||||||
if family == "ipv4" and "mtu" in subnet:
|
|
||||||
ipv4_mtu = subnet["mtu"]
|
|
||||||
|
|
||||||
+ # Now add our DNS search domains. We add them later because we
|
|
||||||
+ # only want them if an IP family has already been defined
|
|
||||||
+ if use_top_level_dns:
|
|
||||||
+ for nameserver in iface["dns"]["nameservers"]:
|
|
||||||
+ self._add_nameserver(nameserver)
|
|
||||||
+ if iface["dns"]["search"]:
|
|
||||||
+ self._add_dns_search(iface["dns"]["search"])
|
|
||||||
+ else:
|
|
||||||
+ for nameserver in found_nameservers:
|
|
||||||
+ self._add_nameserver(nameserver)
|
|
||||||
+ for dns_search in found_dns_search:
|
|
||||||
+ self._add_dns_search(dns_search)
|
|
||||||
+
|
|
||||||
# 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
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index d9ef493b..2a99f150 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -2962,9 +2962,9 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true
|
|
||||||
may-fail=false
|
|
||||||
address1=192.168.0.2/24
|
|
||||||
gateway=192.168.0.1
|
|
||||||
+ address2=192.168.2.10/24
|
|
||||||
dns=192.168.0.10;10.23.23.134;
|
|
||||||
dns-search=barley.maas;sacchromyces.maas;brettanomyces.maas;
|
|
||||||
- address2=192.168.2.10/24
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -4154,6 +4154,148 @@ iface bond0 inet6 static
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
},
|
|
||||||
+ "v2-mixed-routes": {
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-eth0.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init eth0
|
|
||||||
+ uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ interface-name=eth0
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+
|
|
||||||
+ [ipv4]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ route1=169.254.42.42/32,62.210.0.1
|
|
||||||
+ route2=169.254.42.43/32,62.210.0.2
|
|
||||||
+ address1=192.168.1.20/16
|
|
||||||
+ dns=8.8.8.8;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ route1=::/0,fe80::dc00:ff:fe20:186
|
|
||||||
+ route2=fe80::dc00:ff:fe20:188/64,fe80::dc00:ff:fe20:187
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ address1=2001:bc8:1210:232:dc00:ff:fe20:185/64
|
|
||||||
+ dns=FEDC::1;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ )
|
|
||||||
+ },
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ eth0:
|
|
||||||
+ dhcp4: true
|
|
||||||
+ dhcp6: true
|
|
||||||
+ nameservers:
|
|
||||||
+ search: [lab, home]
|
|
||||||
+ addresses: [8.8.8.8, "FEDC::1"]
|
|
||||||
+ routes:
|
|
||||||
+ - to: 169.254.42.42/32
|
|
||||||
+ via: 62.210.0.1
|
|
||||||
+ - via: fe80::dc00:ff:fe20:186
|
|
||||||
+ to: ::/0
|
|
||||||
+ - to: 169.254.42.43/32
|
|
||||||
+ via: 62.210.0.2
|
|
||||||
+ - via: fe80::dc00:ff:fe20:187
|
|
||||||
+ to: fe80::dc00:ff:fe20:188
|
|
||||||
+ addresses:
|
|
||||||
+ - 192.168.1.20/16
|
|
||||||
+ - 2001:bc8:1210:232:dc00:ff:fe20:185/64
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ "v2-dns-no-if-ips": {
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-eth0.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init eth0
|
|
||||||
+ uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ interface-name=eth0
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+
|
|
||||||
+ [ipv4]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ dns=8.8.8.8;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ method=auto
|
|
||||||
+ may-fail=true
|
|
||||||
+ dns=FEDC::1;
|
|
||||||
+ dns-search=lab;home;
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ )
|
|
||||||
+ },
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ eth0:
|
|
||||||
+ dhcp4: true
|
|
||||||
+ dhcp6: true
|
|
||||||
+ nameservers:
|
|
||||||
+ search: [lab, home]
|
|
||||||
+ addresses: [8.8.8.8, "FEDC::1"]
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ "v2-dns-no-dhcp": {
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-eth0.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init eth0
|
|
||||||
+ uuid=1dd9a779-d327-56e1-8454-c65e2556c12c
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ interface-name=eth0
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ )
|
|
||||||
+ },
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ eth0:
|
|
||||||
+ nameservers:
|
|
||||||
+ search: [lab, home]
|
|
||||||
+ addresses: [8.8.8.8, "FEDC::1"]
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6267,6 +6409,27 @@ class TestNetworkManagerRendering(CiTestCase):
|
|
||||||
entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
)
|
|
||||||
|
|
||||||
+ def test_v2_mixed_routes(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-mixed-routes"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def test_v2_dns_no_ips(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-dns-no-if-ips"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def test_v2_dns_no_dhcp(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-dns-no-dhcp"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
|
|
||||||
@mock.patch(
|
|
||||||
"cloudinit.net.is_openvswitch_internal_interface",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
|||||||
From cf35040b46abb66c7239d156bd92c7267d7c40f7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
|
||||||
Date: Fri, 29 Mar 2024 22:39:13 +0800
|
|
||||||
Subject: [PATCH] fix: Fall back to cached local ds if no valid ds found
|
|
||||||
(#4997)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 75: fix: Fall back to cached local ds if no valid ds found (#4997)
|
|
||||||
RH-Jira: RHEL-32846
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 408c41fd8009255d98c31210ef936f2e68dfde75 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Rebooting an instance which has finished VMware guest
|
|
||||||
customization with DataSourceVMware will load
|
|
||||||
DataSourceNone due to metadata is NOT available.
|
|
||||||
|
|
||||||
This is mostly a re-post of PR#229, few differences are:
|
|
||||||
1. Let ds decide if fallback is allowed, not always fall back
|
|
||||||
to previous cached LOCAL ds.
|
|
||||||
2. No comparing instance-id of cached ds with previous instance-id
|
|
||||||
due to I think they are always identical.
|
|
||||||
|
|
||||||
Fixes GH-3402
|
|
||||||
|
|
||||||
(cherry picked from commit 9929a00580d50afc60bf4e0fb9f2f39d4f797b4b)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
cloudinit/sources/__init__.py
|
|
||||||
Conflicts because of changes in upstream source coming from
|
|
||||||
30d5e9a3358f4cbaced ("refactor: Use _unpickle rather than hasattr() in sources")
|
|
||||||
---
|
|
||||||
cloudinit/sources/DataSourceVMware.py | 14 +++++++++-
|
|
||||||
cloudinit/sources/__init__.py | 14 ++++++++++
|
|
||||||
cloudinit/stages.py | 40 +++++++++++++++++----------
|
|
||||||
3 files changed, 53 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/sources/DataSourceVMware.py b/cloudinit/sources/DataSourceVMware.py
|
|
||||||
index 1591121d..2d5d42eb 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceVMware.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceVMware.py
|
|
||||||
@@ -197,7 +197,7 @@ class DataSourceVMware(sources.DataSource):
|
|
||||||
break
|
|
||||||
|
|
||||||
if not self.data_access_method:
|
|
||||||
- LOG.error("failed to find a valid data access method")
|
|
||||||
+ LOG.debug("failed to find a valid data access method")
|
|
||||||
return False
|
|
||||||
|
|
||||||
LOG.info("using data access method %s", self._get_subplatform())
|
|
||||||
@@ -291,6 +291,18 @@ class DataSourceVMware(sources.DataSource):
|
|
||||||
self.metadata["instance-id"] = str(id_file.read()).rstrip().lower()
|
|
||||||
return self.metadata["instance-id"]
|
|
||||||
|
|
||||||
+ def check_if_fallback_is_allowed(self):
|
|
||||||
+ if (
|
|
||||||
+ self.data_access_method
|
|
||||||
+ and self.data_access_method == DATA_ACCESS_METHOD_IMC
|
|
||||||
+ and is_vmware_platform()
|
|
||||||
+ ):
|
|
||||||
+ LOG.debug(
|
|
||||||
+ "Cache fallback is allowed for : %s", self._get_subplatform()
|
|
||||||
+ )
|
|
||||||
+ return True
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
def get_public_ssh_keys(self):
|
|
||||||
for key_name in (
|
|
||||||
"public-keys-data",
|
|
||||||
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
|
|
||||||
index c207b5ed..453801be 100644
|
|
||||||
--- a/cloudinit/sources/__init__.py
|
|
||||||
+++ b/cloudinit/sources/__init__.py
|
|
||||||
@@ -312,6 +312,10 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
|
|
||||||
self.vendordata2_raw = None
|
|
||||||
if not hasattr(self, "skip_hotplug_detect"):
|
|
||||||
self.skip_hotplug_detect = False
|
|
||||||
+
|
|
||||||
+ if not hasattr(self, "check_if_fallback_is_allowed"):
|
|
||||||
+ setattr(self, "check_if_fallback_is_allowed", lambda: False)
|
|
||||||
+
|
|
||||||
if hasattr(self, "userdata") and self.userdata is not None:
|
|
||||||
# If userdata stores MIME data, on < python3.6 it will be
|
|
||||||
# missing the 'policy' attribute that exists on >=python3.6.
|
|
||||||
@@ -914,6 +918,16 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
|
|
||||||
# quickly (local check only) if self.instance_id is still
|
|
||||||
return False
|
|
||||||
|
|
||||||
+ def check_if_fallback_is_allowed(self):
|
|
||||||
+ """check_if_fallback_is_allowed()
|
|
||||||
+ Checks if a cached ds is allowed to be restored when no valid ds is
|
|
||||||
+ found in local mode by checking instance-id and searching valid data
|
|
||||||
+ through ds list.
|
|
||||||
+
|
|
||||||
+ @return True if a ds allows fallback, False otherwise.
|
|
||||||
+ """
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
@staticmethod
|
|
||||||
def _determine_dsmode(candidates, default=None, valid=None):
|
|
||||||
# return the first candidate that is non None, warn if not valid
|
|
||||||
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
|
|
||||||
index 3b6405f5..0b795624 100644
|
|
||||||
--- a/cloudinit/stages.py
|
|
||||||
+++ b/cloudinit/stages.py
|
|
||||||
@@ -353,20 +353,32 @@ class Init:
|
|
||||||
LOG.debug(myrep.description)
|
|
||||||
|
|
||||||
if not ds:
|
|
||||||
- util.del_file(self.paths.instance_link)
|
|
||||||
- (cfg_list, pkg_list) = self._get_datasources()
|
|
||||||
- # Deep copy so that user-data handlers can not modify
|
|
||||||
- # (which will affect user-data handlers down the line...)
|
|
||||||
- (ds, dsname) = sources.find_source(
|
|
||||||
- self.cfg,
|
|
||||||
- self.distro,
|
|
||||||
- self.paths,
|
|
||||||
- copy.deepcopy(self.ds_deps),
|
|
||||||
- cfg_list,
|
|
||||||
- pkg_list,
|
|
||||||
- self.reporter,
|
|
||||||
- )
|
|
||||||
- LOG.info("Loaded datasource %s - %s", dsname, ds)
|
|
||||||
+ try:
|
|
||||||
+ cfg_list, pkg_list = self._get_datasources()
|
|
||||||
+ # Deep copy so that user-data handlers can not modify
|
|
||||||
+ # (which will affect user-data handlers down the line...)
|
|
||||||
+ ds, dsname = sources.find_source(
|
|
||||||
+ self.cfg,
|
|
||||||
+ self.distro,
|
|
||||||
+ self.paths,
|
|
||||||
+ copy.deepcopy(self.ds_deps),
|
|
||||||
+ cfg_list,
|
|
||||||
+ pkg_list,
|
|
||||||
+ self.reporter,
|
|
||||||
+ )
|
|
||||||
+ util.del_file(self.paths.instance_link)
|
|
||||||
+ LOG.info("Loaded datasource %s - %s", dsname, ds)
|
|
||||||
+ except sources.DataSourceNotFoundException as e:
|
|
||||||
+ if existing != "check":
|
|
||||||
+ raise e
|
|
||||||
+ ds = self._restore_from_cache()
|
|
||||||
+ if ds and ds.check_if_fallback_is_allowed():
|
|
||||||
+ LOG.info(
|
|
||||||
+ "Restored fallback datasource from checked cache: %s",
|
|
||||||
+ ds,
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ raise e
|
|
||||||
self.datasource = ds
|
|
||||||
# Ensure we adjust our path members datasource
|
|
||||||
# now that we have one (thus allowing ipath to be used)
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,306 +0,0 @@
|
|||||||
From 1df31428c87f08c790c300ba402318378cea8d65 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Thu, 10 Oct 2024 23:19:28 -0500
|
|
||||||
Subject: [PATCH 1/2] fix: Render bridges correctly for v2 on sysconfig with
|
|
||||||
set-name (#5674)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 147: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
|
|
||||||
RH-Jira: RHEL-65021
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Commit: [1/2] 7f7fce173ee9a3ba719fc36580fbce813c5bfbd0 (xiachen/cloud-init)
|
|
||||||
|
|
||||||
When listing interfaces in v2 format, we should expect to be able to
|
|
||||||
reference other interfaces using the name in the configuration, not
|
|
||||||
the name the interface will eventually take. This was broken when
|
|
||||||
using `set-name`.
|
|
||||||
|
|
||||||
To fix this, we now store the configuration id alongside the eventual
|
|
||||||
name, and reference that instead of the name.
|
|
||||||
|
|
||||||
Fixes GH-5574
|
|
||||||
|
|
||||||
(cherry picked from commit a8f69409e5cebf43767d3bb54fbad7ced1e8fc7b)
|
|
||||||
Signed-off-by: Amy Chen <xiachen@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/eni.py | 6 +++
|
|
||||||
cloudinit/net/network_state.py | 30 ++++-------
|
|
||||||
cloudinit/net/sysconfig.py | 24 ++++++---
|
|
||||||
tests/unittests/test_net.py | 96 ++++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 128 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
|
|
||||||
index 486fa22dc..ac0306d6a 100644
|
|
||||||
--- a/cloudinit/net/eni.py
|
|
||||||
+++ b/cloudinit/net/eni.py
|
|
||||||
@@ -5,6 +5,7 @@ import glob
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
+from contextlib import suppress
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cloudinit import subp, util
|
|
||||||
@@ -421,6 +422,11 @@ class Renderer(renderer.Renderer):
|
|
||||||
return content
|
|
||||||
|
|
||||||
def _render_iface(self, iface, render_hwaddress=False):
|
|
||||||
+ iface = copy.deepcopy(iface)
|
|
||||||
+
|
|
||||||
+ # Remove irrelevant keys
|
|
||||||
+ with suppress(KeyError):
|
|
||||||
+ iface.pop("config_id")
|
|
||||||
sections = []
|
|
||||||
subnets = iface.get("subnets", {})
|
|
||||||
accept_ra = iface.pop("accept-ra", None)
|
|
||||||
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
|
|
||||||
index 14c57cdcc..226421bd0 100644
|
|
||||||
--- a/cloudinit/net/network_state.py
|
|
||||||
+++ b/cloudinit/net/network_state.py
|
|
||||||
@@ -411,6 +411,7 @@ class NetworkStateInterpreter:
|
|
||||||
wakeonlan = util.is_true(wakeonlan)
|
|
||||||
iface.update(
|
|
||||||
{
|
|
||||||
+ "config_id": command.get("config_id"),
|
|
||||||
"name": command.get("name"),
|
|
||||||
"type": command.get("type"),
|
|
||||||
"mac_address": command.get("mac_address"),
|
|
||||||
@@ -424,7 +425,8 @@ class NetworkStateInterpreter:
|
|
||||||
"wakeonlan": wakeonlan,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
- self._network_state["interfaces"].update({command.get("name"): iface})
|
|
||||||
+ iface_key = command.get("config_id", command.get("name"))
|
|
||||||
+ self._network_state["interfaces"].update({iface_key: iface})
|
|
||||||
self.dump_network_state()
|
|
||||||
|
|
||||||
@ensure_command_keys(["name", "vlan_id", "vlan_link"])
|
|
||||||
@@ -712,6 +714,7 @@ class NetworkStateInterpreter:
|
|
||||||
|
|
||||||
for eth, cfg in command.items():
|
|
||||||
phy_cmd = {
|
|
||||||
+ "config_id": eth,
|
|
||||||
"type": "physical",
|
|
||||||
}
|
|
||||||
match = cfg.get("match", {})
|
|
||||||
@@ -800,28 +803,15 @@ class NetworkStateInterpreter:
|
|
||||||
def _v2_common(self, cfg) -> None:
|
|
||||||
LOG.debug("v2_common: handling config:\n%s", cfg)
|
|
||||||
for iface, dev_cfg in cfg.items():
|
|
||||||
- if "set-name" in dev_cfg:
|
|
||||||
- set_name_iface = dev_cfg.get("set-name")
|
|
||||||
- if set_name_iface:
|
|
||||||
- iface = set_name_iface
|
|
||||||
if "nameservers" in dev_cfg:
|
|
||||||
- search = dev_cfg.get("nameservers").get("search", [])
|
|
||||||
- dns = dev_cfg.get("nameservers").get("addresses", [])
|
|
||||||
+ search = dev_cfg.get("nameservers").get("search")
|
|
||||||
+ dns = dev_cfg.get("nameservers").get("addresses")
|
|
||||||
name_cmd = {"type": "nameserver"}
|
|
||||||
- if len(search) > 0:
|
|
||||||
- name_cmd.update({"search": search})
|
|
||||||
- if len(dns) > 0:
|
|
||||||
- name_cmd.update({"address": dns})
|
|
||||||
+ if search:
|
|
||||||
+ name_cmd["search"] = search
|
|
||||||
+ if dns:
|
|
||||||
+ name_cmd["address"] = dns
|
|
||||||
self.handle_nameserver(name_cmd)
|
|
||||||
-
|
|
||||||
- mac_address: Optional[str] = dev_cfg.get("match", {}).get(
|
|
||||||
- "macaddress"
|
|
||||||
- )
|
|
||||||
- if mac_address:
|
|
||||||
- real_if_name = find_interface_name_from_mac(mac_address)
|
|
||||||
- if real_if_name:
|
|
||||||
- iface = real_if_name
|
|
||||||
-
|
|
||||||
self._handle_individual_nameserver(name_cmd, iface)
|
|
||||||
|
|
||||||
def _handle_bond_bridge(self, command, cmd_type=None):
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index b50a6a8a0..e4a65187f 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -6,7 +6,7 @@ import io
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
-from typing import Mapping, Optional
|
|
||||||
+from typing import Dict, Optional
|
|
||||||
|
|
||||||
from cloudinit import subp, util
|
|
||||||
from cloudinit.distros.parsers import networkmanager_conf, resolv_conf
|
|
||||||
@@ -721,7 +721,7 @@ class Renderer(renderer.Renderer):
|
|
||||||
):
|
|
||||||
physical_filter = renderer.filter_by_physical
|
|
||||||
for iface in network_state.iter_interfaces(physical_filter):
|
|
||||||
- iface_name = iface["name"]
|
|
||||||
+ iface_name = iface.get("config_id") or iface["name"]
|
|
||||||
iface_subnets = iface.get("subnets", [])
|
|
||||||
iface_cfg = iface_contents[iface_name]
|
|
||||||
route_cfg = iface_cfg.routes
|
|
||||||
@@ -924,7 +924,9 @@ class Renderer(renderer.Renderer):
|
|
||||||
return out
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
- def _render_bridge_interfaces(cls, network_state, iface_contents, flavor):
|
|
||||||
+ def _render_bridge_interfaces(
|
|
||||||
+ cls, network_state: NetworkState, iface_contents, flavor
|
|
||||||
+ ):
|
|
||||||
bridge_key_map = {
|
|
||||||
old_k: new_k
|
|
||||||
for old_k, new_k in cls.cfg_key_maps[flavor].items()
|
|
||||||
@@ -1005,23 +1007,29 @@ class Renderer(renderer.Renderer):
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _render_sysconfig(
|
|
||||||
- cls, base_sysconf_dir, network_state, flavor, templates=None
|
|
||||||
+ cls,
|
|
||||||
+ base_sysconf_dir,
|
|
||||||
+ network_state: NetworkState,
|
|
||||||
+ flavor,
|
|
||||||
+ templates=None,
|
|
||||||
):
|
|
||||||
"""Given state, return /etc/sysconfig files + contents"""
|
|
||||||
if not templates:
|
|
||||||
templates = cls.templates
|
|
||||||
- iface_contents: Mapping[str, NetInterface] = {}
|
|
||||||
+ iface_contents: Dict[str, NetInterface] = {}
|
|
||||||
for iface in network_state.iter_interfaces():
|
|
||||||
if iface["type"] == "loopback":
|
|
||||||
continue
|
|
||||||
- iface_name = iface["name"]
|
|
||||||
- iface_cfg = NetInterface(iface_name, base_sysconf_dir, templates)
|
|
||||||
+ config_id: str = iface.get("config_id") or iface["name"]
|
|
||||||
+ iface_cfg = NetInterface(
|
|
||||||
+ iface["name"], base_sysconf_dir, templates
|
|
||||||
+ )
|
|
||||||
if flavor == "suse":
|
|
||||||
iface_cfg.drop("DEVICE")
|
|
||||||
# If type detection fails it is considered a bug in SUSE
|
|
||||||
iface_cfg.drop("TYPE")
|
|
||||||
cls._render_iface_shared(iface, iface_cfg, flavor)
|
|
||||||
- iface_contents[iface_name] = iface_cfg
|
|
||||||
+ iface_contents[config_id] = iface_cfg
|
|
||||||
cls._render_physical_interfaces(network_state, iface_contents, flavor)
|
|
||||||
cls._render_bond_interfaces(network_state, iface_contents, flavor)
|
|
||||||
cls._render_vlan_interfaces(network_state, iface_contents, flavor)
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index 4673e4eaf..004da81ab 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -4489,6 +4489,95 @@ iface bond0 inet6 static
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
},
|
|
||||||
+ "v2-bridges-set-name": {
|
|
||||||
+ "yaml": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ version: 2
|
|
||||||
+ ethernets:
|
|
||||||
+ baremetalport:
|
|
||||||
+ match:
|
|
||||||
+ macaddress: 52:54:00:bd:8f:cb
|
|
||||||
+ set-name: baremetal0
|
|
||||||
+ provisioningport:
|
|
||||||
+ match:
|
|
||||||
+ macaddress: 52:54:00:25:ae:12
|
|
||||||
+ set-name: provisioning0
|
|
||||||
+ bridges:
|
|
||||||
+ baremetal:
|
|
||||||
+ addresses:
|
|
||||||
+ - fc00:1:1::2/64
|
|
||||||
+ interfaces:
|
|
||||||
+ - baremetalport
|
|
||||||
+ provisioning:
|
|
||||||
+ addresses:
|
|
||||||
+ - fc00:1:2::2/64
|
|
||||||
+ interfaces:
|
|
||||||
+ - provisioningport
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "expected_sysconfig_rhel": {
|
|
||||||
+ "ifcfg-baremetal": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Created by cloud-init automatically, do not edit.
|
|
||||||
+ #
|
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
|
||||||
+ BOOTPROTO=none
|
|
||||||
+ DEVICE=baremetal
|
|
||||||
+ IPV6ADDR=fc00:1:1::2/64
|
|
||||||
+ IPV6INIT=yes
|
|
||||||
+ IPV6_AUTOCONF=no
|
|
||||||
+ IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
+ ONBOOT=yes
|
|
||||||
+ TYPE=Bridge
|
|
||||||
+ USERCTL=no
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "ifcfg-baremetal0": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Created by cloud-init automatically, do not edit.
|
|
||||||
+ #
|
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
|
||||||
+ BOOTPROTO=none
|
|
||||||
+ BRIDGE=baremetal
|
|
||||||
+ DEVICE=baremetal0
|
|
||||||
+ HWADDR=52:54:00:bd:8f:cb
|
|
||||||
+ ONBOOT=yes
|
|
||||||
+ TYPE=Ethernet
|
|
||||||
+ USERCTL=no
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "ifcfg-provisioning": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Created by cloud-init automatically, do not edit.
|
|
||||||
+ #
|
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
|
||||||
+ BOOTPROTO=none
|
|
||||||
+ DEVICE=provisioning
|
|
||||||
+ IPV6ADDR=fc00:1:2::2/64
|
|
||||||
+ IPV6INIT=yes
|
|
||||||
+ IPV6_AUTOCONF=no
|
|
||||||
+ IPV6_FORCE_ACCEPT_RA=no
|
|
||||||
+ ONBOOT=yes
|
|
||||||
+ TYPE=Bridge
|
|
||||||
+ USERCTL=no
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "ifcfg-provisioning0": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Created by cloud-init automatically, do not edit.
|
|
||||||
+ #
|
|
||||||
+ AUTOCONNECT_PRIORITY=120
|
|
||||||
+ BOOTPROTO=none
|
|
||||||
+ BRIDGE=provisioning
|
|
||||||
+ DEVICE=provisioning0
|
|
||||||
+ HWADDR=52:54:00:25:ae:12
|
|
||||||
+ ONBOOT=yes
|
|
||||||
+ TYPE=Ethernet
|
|
||||||
+ USERCTL=no
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -5558,6 +5647,13 @@ USERCTL=no
|
|
||||||
self._compare_files_to_expected(entry[self.expected_name], found)
|
|
||||||
self._assert_headers(found)
|
|
||||||
|
|
||||||
+ def test_bridges_set_name_config(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-bridges-set-name"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], found)
|
|
||||||
+ self._assert_headers(found)
|
|
||||||
+
|
|
||||||
def test_netplan_dhcp_false_disable_dhcp_in_state(self):
|
|
||||||
"""netplan config with dhcp[46]: False should not add dhcp in state"""
|
|
||||||
net_config = yaml.load(NETPLAN_DHCP_FALSE)
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
|||||||
From 58904df7d689df6e3d1d4ddf47b5cb5a267006da Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Fri, 11 Oct 2024 13:58:19 -0500
|
|
||||||
Subject: [PATCH 2/2] fix: Render v2 bridges correctly on network-manager with
|
|
||||||
set-name (#5740)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 147: fix: Render bridges correctly for v2 on sysconfig with set-name (#5674)
|
|
||||||
RH-Jira: RHEL-65021
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Commit: [2/2] e101d8ff06a379752958a3eb19d209bcb7d1e0ed (xiachen/cloud-init)
|
|
||||||
|
|
||||||
Similar to the recent sysconfig fix, ensure bridges render correctly
|
|
||||||
for configs that contain `set-name`.
|
|
||||||
|
|
||||||
Fixes GH-5717
|
|
||||||
|
|
||||||
(cherry picked from commit 9554338e6ecf49c66324cc637eaf0fa7bf10e407)
|
|
||||||
Signed-off-by: Amy Chen <xiachen@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/network_manager.py | 6 +-
|
|
||||||
tests/unittests/test_net.py | 94 ++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 98 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/network_manager.py b/cloudinit/net/network_manager.py
|
|
||||||
index 0ba210b74..f50fafa39 100644
|
|
||||||
--- a/cloudinit/net/network_manager.py
|
|
||||||
+++ b/cloudinit/net/network_manager.py
|
|
||||||
@@ -464,11 +464,13 @@ class Renderer(renderer.Renderer):
|
|
||||||
# interfaces that have UUIDs that can be linked to from related
|
|
||||||
# interfaces
|
|
||||||
for iface in network_state.iter_interfaces():
|
|
||||||
- self.connections[iface["name"]] = NMConnection(iface["name"])
|
|
||||||
+ conn_key = iface.get("config_id") or iface["name"]
|
|
||||||
+ self.connections[conn_key] = NMConnection(iface["name"])
|
|
||||||
|
|
||||||
# Now render the actual interface configuration
|
|
||||||
for iface in network_state.iter_interfaces():
|
|
||||||
- conn = self.connections[iface["name"]]
|
|
||||||
+ conn_key = iface.get("config_id") or iface["name"]
|
|
||||||
+ conn = self.connections[conn_key]
|
|
||||||
conn.render_interface(iface, network_state, self)
|
|
||||||
|
|
||||||
# And finally write the files
|
|
||||||
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
|
|
||||||
index 004da81ab..ddb45dc69 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -4577,6 +4577,94 @@ iface bond0 inet6 static
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
},
|
|
||||||
+ "expected_network_manager": {
|
|
||||||
+ "cloud-init-baremetal.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init baremetal
|
|
||||||
+ uuid=e63eed9a-cd1c-55de-8d5e-1e80b756a482
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=bridge
|
|
||||||
+ interface-name=baremetal
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [bridge]
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ method=manual
|
|
||||||
+ may-fail=false
|
|
||||||
+ address1=fc00:1:1::2/64
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "cloud-init-baremetalport.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init baremetal0
|
|
||||||
+ uuid=8e326690-51d6-5157-ab84-e4e822b06503
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ slave-type=bridge
|
|
||||||
+ master=e63eed9a-cd1c-55de-8d5e-1e80b756a482
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+ mac-address=52:54:00:BD:8F:CB
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "cloud-init-provisioning.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init provisioning
|
|
||||||
+ uuid=e5bd3f1a-cdcc-55d3-a6d8-88f1ba73bd0e
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=bridge
|
|
||||||
+ interface-name=provisioning
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [bridge]
|
|
||||||
+
|
|
||||||
+ [ipv6]
|
|
||||||
+ method=manual
|
|
||||||
+ may-fail=false
|
|
||||||
+ address1=fc00:1:2::2/64
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ "cloud-init-provisioningport.nmconnection": textwrap.dedent(
|
|
||||||
+ """\
|
|
||||||
+ # Generated by cloud-init. Changes will be lost.
|
|
||||||
+
|
|
||||||
+ [connection]
|
|
||||||
+ id=cloud-init provisioning0
|
|
||||||
+ uuid=d79b7b70-e9df-596f-ace7-89537db45684
|
|
||||||
+ autoconnect-priority=120
|
|
||||||
+ type=ethernet
|
|
||||||
+ slave-type=bridge
|
|
||||||
+ master=e5bd3f1a-cdcc-55d3-a6d8-88f1ba73bd0e
|
|
||||||
+
|
|
||||||
+ [user]
|
|
||||||
+ org.freedesktop.NetworkManager.origin=cloud-init
|
|
||||||
+
|
|
||||||
+ [ethernet]
|
|
||||||
+ mac-address=52:54:00:25:AE:12
|
|
||||||
+
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -6722,6 +6810,12 @@ class TestNetworkManagerRendering(CiTestCase):
|
|
||||||
entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
)
|
|
||||||
|
|
||||||
+ def test_v2_bridges_set_name(self):
|
|
||||||
+ entry = NETWORK_CONFIGS["v2-bridges-set-name"]
|
|
||||||
+ found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
|
|
||||||
+ self._compare_files_to_expected(
|
|
||||||
+ entry[self.expected_name], self.expected_conf_d, found
|
|
||||||
+ )
|
|
||||||
|
|
||||||
@mock.patch(
|
|
||||||
"cloudinit.net.is_openvswitch_internal_interface",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
From 332bb23bcfde801edf792e6c629ec350be07b952 Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 19 Mar 2024 14:24:11 -0500
|
|
||||||
Subject: [PATCH 3/3] fix: Undeprecate 'network' in schema route definition
|
|
||||||
(#5072)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 73: fix: Undeprecate 'network' in schema route definition (#5072)
|
|
||||||
RH-Jira: RHEL-29709
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 61c660be43fd25999bca0cfd66d7b2150fee5a14 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
It is passed through to our v1 schema from OpenStack network_data.json
|
|
||||||
|
|
||||||
Fixes GH-5051
|
|
||||||
|
|
||||||
(cherry picked from commit ff40d1af8a6de3ee27937382ec4ceea931d80a88)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/config/schemas/schema-network-config-v1.json | 5 +----
|
|
||||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-network-config-v1.json b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
index 56dc27c9..64c492a4 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-network-config-v1.json
|
|
||||||
@@ -445,10 +445,7 @@
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
"type": "string",
|
|
||||||
- "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent.",
|
|
||||||
- "deprecated": true,
|
|
||||||
- "deprecated_version": "23.3",
|
|
||||||
- "deprecated_description": "Use ``destination`` instead."
|
|
||||||
+ "description": "IPv4 network address with CIDR netmask notation or IPv6 with prefix length. Alias for ``destination`` and only read when ``destination`` key is absent. This exists for OpenStack support. OpenStack route definitions are passed through to v1 config and OpenStack's ``network_data.json`` uses ``network`` instead of ``destination``."
|
|
||||||
},
|
|
||||||
"destination": {
|
|
||||||
"type": "string",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From ed3c05af60c0d50a4576a63c8638e148e58ebf06 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 11 Jul 2024 00:49:58 +0530
|
|
||||||
Subject: [PATCH] fix: add schema rules for 'baseurl' and 'metalink' in yum
|
|
||||||
repo config (#5501)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 101: fix: add schema rules for 'baseurl' and 'metalink' in yum repo config (#5501)
|
|
||||||
RH-Jira: RHEL-46873
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: xiachen <xiachen@redhat.com>
|
|
||||||
RH-Commit: [1/1] df01c93fde517e66ce71a66f80ee54d3ed504906 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
At least one of (or both) 'baseurl' or 'metalink' should be provided for yum
|
|
||||||
repository specification. Add schema changes to enforce it. Without this,
|
|
||||||
with just 'metalink' property set, one would get the schema validator error
|
|
||||||
|
|
||||||
\---
|
|
||||||
Error: Cloud config schema errors: yum_repos.epel-release: 'baseurl' is a required property
|
|
||||||
\---
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
(cherry picked from commit 7d35664ef8b85840f92f18cc48187f7284d227bc)
|
|
||||||
---
|
|
||||||
.../config/schemas/schema-cloud-config-v1.json | 18 ++++++++++++++++--
|
|
||||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 03e723e2..4fb7fd93 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -3442,6 +3442,11 @@
|
|
||||||
"format": "uri",
|
|
||||||
"description": "URL to the directory where the yum repository's 'repodata' directory lives"
|
|
||||||
},
|
|
||||||
+ "metalink": {
|
|
||||||
+ "type": "string",
|
|
||||||
+ "format": "uri",
|
|
||||||
+ "description": "Specifies a URL to a metalink file for the repomd.xml"
|
|
||||||
+ },
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Optional human-readable name of the yum repo."
|
|
||||||
@@ -3469,8 +3474,17 @@
|
|
||||||
"description": "Any supported yum repository configuration options will be written to the yum repo config file. See: man yum.conf"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
- "required": [
|
|
||||||
- "baseurl"
|
|
||||||
+ "anyOf": [
|
|
||||||
+ {
|
|
||||||
+ "required": [
|
|
||||||
+ "baseurl"
|
|
||||||
+ ]
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "required": [
|
|
||||||
+ "metalink"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From fcaff2e02a07af587d8366f61df1685435e32288 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Wed, 3 Jan 2024 09:11:40 -0700
|
|
||||||
Subject: [PATCH] fix(cloudstack): Use parsed lease file for virtual router in
|
|
||||||
cloudstack
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 85: fix(cloudstack): Use parsed lease file for virtual router in cloudstack
|
|
||||||
RH-Jira: RHEL-40217
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] 9d1353620ee2c773170e424479bb2664116554f4 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Fixes 5942f4023e2581a
|
|
||||||
|
|
||||||
(cherry picked from commit cb36bf38b823f811a3e938ccffc03d7d13190095)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/sources/DataSourceCloudStack.py | 22 +++++++++++-----------
|
|
||||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/sources/DataSourceCloudStack.py b/cloudinit/sources/DataSourceCloudStack.py
|
|
||||||
index fd2482a3..f752765d 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceCloudStack.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceCloudStack.py
|
|
||||||
@@ -229,18 +229,18 @@ def get_vr_address():
|
|
||||||
)
|
|
||||||
return latest_address
|
|
||||||
|
|
||||||
- # Try dhcp lease files next...
|
|
||||||
+ # Try dhcp lease files next
|
|
||||||
lease_file = dhcp.IscDhclient.get_latest_lease()
|
|
||||||
- if not lease_file:
|
|
||||||
- LOG.debug("No lease file found, using default gateway")
|
|
||||||
- return get_default_gateway()
|
|
||||||
-
|
|
||||||
- lease_file = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
|
|
||||||
- if not latest_address:
|
|
||||||
- # No virtual router found, fallback on default gateway
|
|
||||||
- LOG.debug("No DHCP found, using default gateway")
|
|
||||||
- return get_default_gateway()
|
|
||||||
- return latest_address
|
|
||||||
+ if lease_file:
|
|
||||||
+ latest_address = dhcp.IscDhclient.parse_dhcp_server_from_lease_file(
|
|
||||||
+ lease_file
|
|
||||||
+ )
|
|
||||||
+ if latest_address:
|
|
||||||
+ return latest_address
|
|
||||||
+
|
|
||||||
+ # No virtual router found, fallback to default gateway
|
|
||||||
+ LOG.debug("No DHCP found, using default gateway")
|
|
||||||
+ return get_default_gateway()
|
|
||||||
|
|
||||||
|
|
||||||
# Used to match classes to dependencies
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
|||||||
From 2b74b0eb94edfd7caa42bc0d8affc37311ba041b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Wed, 3 Jan 2024 09:11:21 -0700
|
|
||||||
Subject: [PATCH 4/6] fix(dhcp): Guard against FileNotFoundError and NameError
|
|
||||||
exceptions
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 92: Update pylint version to support python 3.12
|
|
||||||
RH-Jira: RHEL-44598
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/3] 730b8de9ceb2c380d3b15573d83691ab95a1487e (anisinha/cloud-init)
|
|
||||||
|
|
||||||
(cherry picked from commit 53eb8555e091474803b724700815adc09aa84f05)
|
|
||||||
---
|
|
||||||
cloudinit/net/dhcp.py | 20 ++++++++++------
|
|
||||||
tests/unittests/net/test_dhcp.py | 40 ++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 53 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
|
|
||||||
index 07c13390..a0aee98c 100644
|
|
||||||
--- a/cloudinit/net/dhcp.py
|
|
||||||
+++ b/cloudinit/net/dhcp.py
|
|
||||||
@@ -5,15 +5,15 @@
|
|
||||||
# This file is part of cloud-init. See LICENSE file for license information.
|
|
||||||
|
|
||||||
import abc
|
|
||||||
-import contextlib
|
|
||||||
import glob
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import signal
|
|
||||||
import time
|
|
||||||
+from contextlib import suppress
|
|
||||||
from io import StringIO
|
|
||||||
-from typing import Any, Dict, List
|
|
||||||
+from typing import Any, Dict, List, Optional
|
|
||||||
|
|
||||||
import configobj
|
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ class IscDhclient(DhcpClient):
|
|
||||||
|
|
||||||
# this function waits for these files to exist, clean previous runs
|
|
||||||
# to avoid false positive in wait_for_files
|
|
||||||
- with contextlib.suppress(FileNotFoundError):
|
|
||||||
+ with suppress(FileNotFoundError):
|
|
||||||
os.remove(pid_file)
|
|
||||||
os.remove(lease_file)
|
|
||||||
|
|
||||||
@@ -514,9 +514,15 @@ class IscDhclient(DhcpClient):
|
|
||||||
return latest_file
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
- def parse_dhcp_server_from_lease_file(lease_file):
|
|
||||||
- with open(lease_file, "r") as fd:
|
|
||||||
- for line in fd:
|
|
||||||
+ def parse_dhcp_server_from_lease_file(lease_file) -> Optional[str]:
|
|
||||||
+ """Parse a lease file for the dhcp server address
|
|
||||||
+
|
|
||||||
+ @param lease_file: Name of a file to be parsed
|
|
||||||
+ @return: An address if found, or None
|
|
||||||
+ """
|
|
||||||
+ latest_address = None
|
|
||||||
+ with suppress(FileNotFoundError), open(lease_file, "r") as file:
|
|
||||||
+ for line in file:
|
|
||||||
if "dhcp-server-identifier" in line:
|
|
||||||
words = line.strip(" ;\r\n").split(" ")
|
|
||||||
if len(words) > 2:
|
|
||||||
@@ -561,7 +567,7 @@ class Udhcpc(DhcpClient):
|
|
||||||
|
|
||||||
tmp_dir = temp_utils.get_tmp_ancestor(needs_exe=True)
|
|
||||||
lease_file = os.path.join(tmp_dir, interface + ".lease.json")
|
|
||||||
- with contextlib.suppress(FileNotFoundError):
|
|
||||||
+ with suppress(FileNotFoundError):
|
|
||||||
os.remove(lease_file)
|
|
||||||
|
|
||||||
# udhcpc needs the interface up to send initial discovery packets
|
|
||||||
diff --git a/tests/unittests/net/test_dhcp.py b/tests/unittests/net/test_dhcp.py
|
|
||||||
index a7b62312..8ec96eef 100644
|
|
||||||
--- a/tests/unittests/net/test_dhcp.py
|
|
||||||
+++ b/tests/unittests/net/test_dhcp.py
|
|
||||||
@@ -32,6 +32,46 @@ LEASE_F = "/run/dhclient.lease"
|
|
||||||
DHCLIENT = "/sbin/dhclient"
|
|
||||||
|
|
||||||
|
|
||||||
+@pytest.mark.parametrize(
|
|
||||||
+ "server_address,lease_file_content",
|
|
||||||
+ (
|
|
||||||
+ pytest.param(None, None, id="no_server_addr_on_absent_lease_file"),
|
|
||||||
+ pytest.param(None, "", id="no_server_addr_on_empty_lease_file"),
|
|
||||||
+ pytest.param(
|
|
||||||
+ None,
|
|
||||||
+ "lease {\n fixed-address: 10.1.2.3;\n}\n",
|
|
||||||
+ id="no_server_addr_when_no_server_ident",
|
|
||||||
+ ),
|
|
||||||
+ pytest.param(
|
|
||||||
+ "10.4.5.6",
|
|
||||||
+ "lease {\n fixed-address: 10.1.2.3;\n"
|
|
||||||
+ " option dhcp-server-identifier 10.4.5.6;\n"
|
|
||||||
+ " option dhcp-renewal-time 1800;\n}\n",
|
|
||||||
+ id="server_addr_found_when_server_ident_present",
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+)
|
|
||||||
+class TestParseDHCPServerFromLeaseFile:
|
|
||||||
+ def test_find_server_address_when_present(
|
|
||||||
+ self, server_address, lease_file_content, tmp_path
|
|
||||||
+ ):
|
|
||||||
+ """Test that we return None in the case of no file or file contains no
|
|
||||||
+ server address, otherwise return the address.
|
|
||||||
+ """
|
|
||||||
+ lease_file = tmp_path / "dhcp.leases"
|
|
||||||
+ if server_address:
|
|
||||||
+ if lease_file_content:
|
|
||||||
+ lease_file.write_text(lease_file_content)
|
|
||||||
+ assert (
|
|
||||||
+ server_address
|
|
||||||
+ == IscDhclient.parse_dhcp_server_from_lease_file(lease_file)
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ assert not IscDhclient.parse_dhcp_server_from_lease_file(
|
|
||||||
+ lease_file
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+
|
|
||||||
class TestParseDHCPLeasesFile(CiTestCase):
|
|
||||||
def test_parse_empty_lease_file_errors(self):
|
|
||||||
"""parse_dhcp_lease_file errors when file content is empty."""
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
|||||||
From b7fddab36d805099639358736dab474d2924906b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Wed, 19 Jun 2024 17:07:56 -0600
|
|
||||||
Subject: [PATCH 2/6] fix(jsonschema): Add missing sudo definition (#5418)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 90: fix(jsonschema): Add missing sudo definition (#5418)
|
|
||||||
RH-Jira: RHEL-44337
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/2] 9e56c7ab35744c6530c8cef2f122ffdcc0480d29 (anisinha/cloud-init)
|
|
||||||
|
|
||||||
This configuration:
|
|
||||||
|
|
||||||
```
|
|
||||||
users:
|
|
||||||
- name: osadmin
|
|
||||||
lock_passwd: false
|
|
||||||
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Is valid syntax but is missing from the jsonschema definition.
|
|
||||||
|
|
||||||
Fixes GH-5399
|
|
||||||
|
|
||||||
(cherry picked from commit b533fa51acb850ed754e2b1925e276ff8e5f3507)
|
|
||||||
---
|
|
||||||
cloudinit/config/schemas/schema-cloud-config-v1.json | 9 +++++++++
|
|
||||||
1 file changed, 9 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index a553c52c..8b10fe70 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -299,6 +299,15 @@
|
|
||||||
],
|
|
||||||
"description": "Sudo rule to use or false. Absence of a sudo value or ``null`` will result in no sudo rules added for this user."
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ "type": "array",
|
|
||||||
+ "items": {
|
|
||||||
+ "type": [
|
|
||||||
+ "string",
|
|
||||||
+ "null"
|
|
||||||
+ ]
|
|
||||||
+ }
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
"type": "boolean",
|
|
||||||
"changed": true,
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
From e6e7c274235d924fde752b228f68ec5773e39029 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Brett Holman <brett.holman@canonical.com>
|
|
||||||
Date: Tue, 5 Dec 2023 16:40:03 -0700
|
|
||||||
Subject: [PATCH 2/2] fix(python3.13): Fix import error for passlib on Python
|
|
||||||
3.13 (#4669)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 145: Fix metric setting for ifcfg network connections for rhel (#5777)
|
|
||||||
RH-Jira: RHEL-65018
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Commit: [2/2] 226ae26a9f903774cb36f8f72b89071ba4545a66 (xiachen/cloud-init)
|
|
||||||
|
|
||||||
(cherry picked from commit 09b70436b3a0aae1fe24fdde6e8cdd7ee98d9c15)
|
|
||||||
Signed-off-by: Amy Chen <xiachen@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 eb0304c3d..939210100 100644
|
|
||||||
--- a/cloudinit/sources/DataSourceAzure.py
|
|
||||||
+++ b/cloudinit/sources/DataSourceAzure.py
|
|
||||||
@@ -58,7 +58,7 @@ try:
|
|
||||||
)
|
|
||||||
except (ImportError, AttributeError):
|
|
||||||
try:
|
|
||||||
- import passlib
|
|
||||||
+ import passlib.hash
|
|
||||||
|
|
||||||
blowfish_hash = passlib.hash.sha512_crypt.hash
|
|
||||||
except ImportError:
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,412 +0,0 @@
|
|||||||
From ce69cd178d9c05827db1ca1654de82dc3f9f521e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Chad Smith <chad.smith@canonical.com>
|
|
||||||
Date: Thu, 27 Jun 2024 18:12:31 -0600
|
|
||||||
Subject: [PATCH 3/3] fix(schema): permit deprecated hyphenated keys under
|
|
||||||
users key (#5456)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 95: Deprecate the users ssh-authorized-keys property (#5162)
|
|
||||||
RH-Jira: RHEL-45262
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [3/3] 76804599a9166796dc52bab2031a706993ad2e3c (anisinha/cloud-init)
|
|
||||||
|
|
||||||
Both hyphenated and underscore delimited key names are permitted
|
|
||||||
by cloudinit/distros/ug_util.py#L114 due to magic replacement
|
|
||||||
of key names.
|
|
||||||
|
|
||||||
Since this is still valid json schema, add the necessary hyphenated
|
|
||||||
aliases for all users/groups keys. Because the goal in the future is
|
|
||||||
to only support one config key for a given configuraion option, add
|
|
||||||
deprecated keys to those schema definitions.
|
|
||||||
|
|
||||||
Also drop the description key from the deprecates lock-passwd schema
|
|
||||||
key.
|
|
||||||
|
|
||||||
Any deprecated schema key which provides a suggested replacement should
|
|
||||||
not provide duplicated key descriptions as the preferred replacement
|
|
||||||
will provided the necessary context.
|
|
||||||
|
|
||||||
Fixes GH-5454
|
|
||||||
|
|
||||||
(cherry picked from commit b3618d44a37ae6345f0c3d935b77ae0ae9dd1c92)
|
|
||||||
---
|
|
||||||
.../schemas/schema-cloud-config-v1.json | 103 +++++++++++++-----
|
|
||||||
tests/unittests/config/test_cc_grub_dpkg.py | 4 +-
|
|
||||||
.../test_cc_package_update_upgrade_install.py | 11 +-
|
|
||||||
.../unittests/config/test_cc_users_groups.py | 33 +++---
|
|
||||||
tests/unittests/config/test_schema.py | 15 ++-
|
|
||||||
5 files changed, 108 insertions(+), 58 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/config/schemas/schema-cloud-config-v1.json b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
index 97cf2b74..03e723e2 100644
|
|
||||||
--- a/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
+++ b/cloudinit/config/schemas/schema-cloud-config-v1.json
|
|
||||||
@@ -178,9 +178,9 @@
|
|
||||||
"patternProperties": {
|
|
||||||
"^.+$": {
|
|
||||||
"label": "<group_name>",
|
|
||||||
- "description": "When providing an object for users.groups the ``<group_name>`` keys are the groups to add this user to",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "23.1",
|
|
||||||
+ "deprecated_description": "The use of ``object`` type is deprecated. Use ``string`` or ``array`` of ``string`` instead.",
|
|
||||||
"type": [
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
@@ -203,9 +203,7 @@
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"lock-passwd": {
|
|
||||||
- "default": true,
|
|
||||||
"type": "boolean",
|
|
||||||
- "description": "Default: ``true``",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.3",
|
|
||||||
"deprecated_description": "Use ``lock_passwd`` instead."
|
|
||||||
@@ -215,16 +213,34 @@
|
|
||||||
"description": "Disable password login. Default: ``true``",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
+ "no-create-home": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``no_create_home`` instead."
|
|
||||||
+ },
|
|
||||||
"no_create_home": {
|
|
||||||
"default": false,
|
|
||||||
"description": "Do not create home directory. Default: ``false``",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
+ "no-log-init": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``no_log_init`` instead."
|
|
||||||
+ },
|
|
||||||
"no_log_init": {
|
|
||||||
"default": false,
|
|
||||||
"description": "Do not initialize lastlog and faillog for user. Default: ``false``",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
+ "no-user-group": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``no_user_group`` instead."
|
|
||||||
+ },
|
|
||||||
"no_user_group": {
|
|
||||||
"default": false,
|
|
||||||
"description": "Do not create group named after user. Default: ``false``",
|
|
||||||
@@ -234,24 +250,54 @@
|
|
||||||
"description": "Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While hashed password is better than plain text, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
+ "hashed-passwd": {
|
|
||||||
+ "type": "string",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``hashed_passwd`` instead."
|
|
||||||
+ },
|
|
||||||
"hashed_passwd": {
|
|
||||||
"description": "Hash of user password to be applied. This will be applied even if the user is pre-existing. To generate this hash, run: mkpasswd --method=SHA-512 --rounds=4096. **Note:** While ``hashed_password`` is better than ``plain_text_passwd``, using ``passwd`` in user-data represents a security risk as user-data could be accessible by third-parties depending on your cloud platform.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
+ "plain-text-passwd": {
|
|
||||||
+ "type": "string",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``plain_text_passwd`` instead."
|
|
||||||
+ },
|
|
||||||
"plain_text_passwd": {
|
|
||||||
"description": "Clear text of user password to be applied. This will be applied even if the user is pre-existing. There are many more secure options than using plain text passwords, such as ``ssh_import_id`` or ``hashed_passwd``. Do not use this in production as user-data and your password can be exposed.",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
+ "create-groups": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``create_groups`` instead."
|
|
||||||
+ },
|
|
||||||
"create_groups": {
|
|
||||||
"default": true,
|
|
||||||
"description": "Boolean set ``false`` to disable creation of specified user ``groups``. Default: ``true``.",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
+ "primary-group": {
|
|
||||||
+ "type": "string",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``primary_group`` instead."
|
|
||||||
+ },
|
|
||||||
"primary_group": {
|
|
||||||
"default": "``<username>``",
|
|
||||||
"description": "Primary group for user. Default: ``<username>``",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
+ "selinux-user": {
|
|
||||||
+ "type": "string",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``selinux_user`` instead."
|
|
||||||
+ },
|
|
||||||
"selinux_user": {
|
|
||||||
"description": "SELinux user for user's login. Default to default SELinux user.",
|
|
||||||
"type": "string"
|
|
||||||
@@ -273,20 +319,24 @@
|
|
||||||
"minItems": 1
|
|
||||||
},
|
|
||||||
"ssh-authorized-keys": {
|
|
||||||
- "allOf": [
|
|
||||||
- {
|
|
||||||
- "type": "array",
|
|
||||||
- "items": {
|
|
||||||
- "type": "string"
|
|
||||||
- },
|
|
||||||
- "minItems": 1
|
|
||||||
- },
|
|
||||||
- {
|
|
||||||
- "deprecated": true,
|
|
||||||
- "deprecated_version": "18.3",
|
|
||||||
- "deprecated_description": "Use ``ssh_authorized_keys`` instead."
|
|
||||||
- }
|
|
||||||
- ]
|
|
||||||
+ "type": "array",
|
|
||||||
+ "items": {
|
|
||||||
+ "type": "string"
|
|
||||||
+ },
|
|
||||||
+ "minItems": 1,
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "18.3",
|
|
||||||
+ "deprecated_description": "Use ``ssh_authorized_keys`` instead."
|
|
||||||
+ },
|
|
||||||
+ "ssh-import-id": {
|
|
||||||
+ "type": "array",
|
|
||||||
+ "items": {
|
|
||||||
+ "type": "string"
|
|
||||||
+ },
|
|
||||||
+ "minItems": 1,
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``ssh_import_id`` instead."
|
|
||||||
},
|
|
||||||
"ssh_import_id": {
|
|
||||||
"description": "List of SSH IDs to import for user. Can not be combined with ``ssh_redirect_user``.",
|
|
||||||
@@ -296,6 +346,12 @@
|
|
||||||
},
|
|
||||||
"minItems": 1
|
|
||||||
},
|
|
||||||
+ "ssh-redirect-user": {
|
|
||||||
+ "type": "boolean",
|
|
||||||
+ "deprecated": true,
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "Use ``ssh_redirect_user`` instead."
|
|
||||||
+ },
|
|
||||||
"ssh_redirect_user": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
@@ -398,7 +454,6 @@
|
|
||||||
"properties": {
|
|
||||||
"remove-defaults": {
|
|
||||||
"type": "boolean",
|
|
||||||
- "default": false,
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.3",
|
|
||||||
"deprecated_description": "Use ``remove_defaults`` instead."
|
|
||||||
@@ -516,9 +571,9 @@
|
|
||||||
},
|
|
||||||
"system_info": {
|
|
||||||
"type": "object",
|
|
||||||
- "description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data.",
|
|
||||||
"deprecated": true,
|
|
||||||
- "deprecated_version": "24.2"
|
|
||||||
+ "deprecated_version": "24.2",
|
|
||||||
+ "deprecated_description": "System and/or distro specific settings. This is not intended to be overridden by user data or vendor data."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -1483,7 +1538,6 @@
|
|
||||||
},
|
|
||||||
"grub-dpkg": {
|
|
||||||
"type": "object",
|
|
||||||
- "description": "An alias for ``grub_dpkg``",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.2",
|
|
||||||
"deprecated_description": "Use ``grub_dpkg`` instead."
|
|
||||||
@@ -2082,24 +2136,18 @@
|
|
||||||
},
|
|
||||||
"apt_update": {
|
|
||||||
"type": "boolean",
|
|
||||||
- "default": false,
|
|
||||||
- "description": "Default: ``false``.",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.2",
|
|
||||||
"deprecated_description": "Use ``package_update`` instead."
|
|
||||||
},
|
|
||||||
"apt_upgrade": {
|
|
||||||
"type": "boolean",
|
|
||||||
- "default": false,
|
|
||||||
- "description": "Default: ``false``.",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.2",
|
|
||||||
"deprecated_description": "Use ``package_upgrade`` instead."
|
|
||||||
},
|
|
||||||
"apt_reboot_if_required": {
|
|
||||||
"type": "boolean",
|
|
||||||
- "default": false,
|
|
||||||
- "description": "Default: ``false``.",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.2",
|
|
||||||
"deprecated_description": "Use ``package_reboot_if_required`` instead."
|
|
||||||
@@ -2798,7 +2846,6 @@
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minItems": 1,
|
|
||||||
- "description": "List of ``username:password`` pairs. Each user will have the corresponding password set. A password can be randomly generated by specifying ``RANDOM`` or ``R`` as a user's password. A hashed password, created by a tool like ``mkpasswd``, can be specified. A regex (``r'\\$(1|2a|2y|5|6)(\\$.+){2}'``) is used to determine if a password value should be treated as a hash.",
|
|
||||||
"deprecated": true,
|
|
||||||
"deprecated_version": "22.2",
|
|
||||||
"deprecated_description": "Use ``users`` instead."
|
|
||||||
diff --git a/tests/unittests/config/test_cc_grub_dpkg.py b/tests/unittests/config/test_cc_grub_dpkg.py
|
|
||||||
index b4bd48df..36ef7fd9 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_grub_dpkg.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_grub_dpkg.py
|
|
||||||
@@ -300,8 +300,8 @@ class TestGrubDpkgSchema:
|
|
||||||
pytest.raises(
|
|
||||||
SchemaValidationError,
|
|
||||||
match=(
|
|
||||||
- "Cloud config schema deprecations: grub-dpkg: An alias"
|
|
||||||
- " for ``grub_dpkg`` Deprecated in version 22.2. Use "
|
|
||||||
+ "Cloud config schema deprecations: grub-dpkg:"
|
|
||||||
+ " Deprecated in version 22.2. Use "
|
|
||||||
"``grub_dpkg`` instead."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
diff --git a/tests/unittests/config/test_cc_package_update_upgrade_install.py b/tests/unittests/config/test_cc_package_update_upgrade_install.py
|
|
||||||
index 9ba7f178..734dbc53 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_package_update_upgrade_install.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_package_update_upgrade_install.py
|
|
||||||
@@ -192,16 +192,16 @@ class TestPackageUpdateUpgradeSchema:
|
|
||||||
(
|
|
||||||
{"apt_update": False},
|
|
||||||
(
|
|
||||||
- "Cloud config schema deprecations: apt_update: "
|
|
||||||
- "Default: ``false``. Deprecated in version 22.2. "
|
|
||||||
+ "Cloud config schema deprecations: apt_update: "
|
|
||||||
+ "Deprecated in version 22.2. "
|
|
||||||
"Use ``package_update`` instead."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
{"apt_upgrade": False},
|
|
||||||
(
|
|
||||||
- "Cloud config schema deprecations: apt_upgrade: "
|
|
||||||
- "Default: ``false``. Deprecated in version 22.2. "
|
|
||||||
+ "Cloud config schema deprecations: apt_upgrade: "
|
|
||||||
+ "Deprecated in version 22.2. "
|
|
||||||
"Use ``package_upgrade`` instead."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
@@ -209,8 +209,7 @@ class TestPackageUpdateUpgradeSchema:
|
|
||||||
{"apt_reboot_if_required": False},
|
|
||||||
(
|
|
||||||
"Cloud config schema deprecations: "
|
|
||||||
- "apt_reboot_if_required: Default: ``false``. "
|
|
||||||
- "Deprecated in version 22.2. Use "
|
|
||||||
+ "apt_reboot_if_required: Deprecated in version 22.2. Use "
|
|
||||||
"``package_reboot_if_required`` instead."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
diff --git a/tests/unittests/config/test_cc_users_groups.py b/tests/unittests/config/test_cc_users_groups.py
|
|
||||||
index 53e231e1..4ca67f77 100644
|
|
||||||
--- a/tests/unittests/config/test_cc_users_groups.py
|
|
||||||
+++ b/tests/unittests/config/test_cc_users_groups.py
|
|
||||||
@@ -371,9 +371,20 @@ class TestUsersGroupsSchema:
|
|
||||||
SchemaValidationError,
|
|
||||||
match=(
|
|
||||||
"Cloud config schema deprecations: "
|
|
||||||
- "users.0.lock-passwd: Default: ``true`` "
|
|
||||||
- "Deprecated in version 22.3. Use "
|
|
||||||
- "``lock_passwd`` instead."
|
|
||||||
+ "users.0.lock-passwd: Deprecated in version 22.3."
|
|
||||||
+ " Use ``lock_passwd`` instead."
|
|
||||||
+ ),
|
|
||||||
+ ),
|
|
||||||
+ False,
|
|
||||||
+ ),
|
|
||||||
+ (
|
|
||||||
+ {"users": [{"name": "bbsw", "no-create-home": True}]},
|
|
||||||
+ pytest.raises(
|
|
||||||
+ SchemaValidationError,
|
|
||||||
+ match=(
|
|
||||||
+ "Cloud config schema deprecations: "
|
|
||||||
+ "users.0.no-create-home: Deprecated in version 24.2."
|
|
||||||
+ " Use ``no_create_home`` instead."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
False,
|
|
||||||
@@ -394,13 +405,10 @@ class TestUsersGroupsSchema:
|
|
||||||
SchemaValidationError,
|
|
||||||
match=(
|
|
||||||
"Cloud config schema deprecations: "
|
|
||||||
- "users.0.groups.adm: When providing an object "
|
|
||||||
- "for users.groups the ``<group_name>`` keys "
|
|
||||||
- "are the groups to add this user to Deprecated"
|
|
||||||
- " in version 23.1., users.0.groups.sudo: When "
|
|
||||||
- "providing an object for users.groups the "
|
|
||||||
- "``<group_name>`` keys are the groups to add "
|
|
||||||
- "this user to Deprecated in version 23.1."
|
|
||||||
+ "users.0.groups.adm: Deprecated in version 23.1. "
|
|
||||||
+ "The use of ``object`` type is deprecated. Use "
|
|
||||||
+ "``string`` or ``array`` of ``string`` instead., "
|
|
||||||
+ "users.0.groups.sudo: Deprecated in version 23.1."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
False,
|
|
||||||
@@ -456,10 +464,7 @@ class TestUsersGroupsSchema:
|
|
||||||
SchemaValidationError,
|
|
||||||
match=(
|
|
||||||
"Cloud config schema deprecations: "
|
|
||||||
- "user.groups.sbuild: When providing an object "
|
|
||||||
- "for users.groups the ``<group_name>`` keys "
|
|
||||||
- "are the groups to add this user to Deprecated"
|
|
||||||
- " in version 23.1."
|
|
||||||
+ "user.groups.sbuild: Deprecated in version 23.1."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
False,
|
|
||||||
diff --git a/tests/unittests/config/test_schema.py b/tests/unittests/config/test_schema.py
|
|
||||||
index 52667332..8208affc 100644
|
|
||||||
--- a/tests/unittests/config/test_schema.py
|
|
||||||
+++ b/tests/unittests/config/test_schema.py
|
|
||||||
@@ -2251,9 +2251,9 @@ class TestHandleSchemaArgs:
|
|
||||||
apt_reboot_if_required: true # D3
|
|
||||||
|
|
||||||
# Deprecations: -------------
|
|
||||||
- # D1: Default: ``false``. Deprecated in version 22.2. Use ``package_update`` instead.
|
|
||||||
- # D2: Default: ``false``. Deprecated in version 22.2. Use ``package_upgrade`` instead.
|
|
||||||
- # D3: Default: ``false``. Deprecated in version 22.2. Use ``package_reboot_if_required`` instead.
|
|
||||||
+ # D1: Deprecated in version 22.2. Use ``package_update`` instead.
|
|
||||||
+ # D2: Deprecated in version 22.2. Use ``package_upgrade`` instead.
|
|
||||||
+ # D3: Deprecated in version 22.2. Use ``package_reboot_if_required`` instead.
|
|
||||||
|
|
||||||
Valid schema {cfg_file}
|
|
||||||
""" # noqa: E501
|
|
||||||
@@ -2264,11 +2264,10 @@ class TestHandleSchemaArgs:
|
|
||||||
dedent(
|
|
||||||
"""\
|
|
||||||
Cloud config schema deprecations: \
|
|
||||||
-apt_reboot_if_required: Default: ``false``. Deprecated in version 22.2.\
|
|
||||||
- Use ``package_reboot_if_required`` instead., apt_update: Default: \
|
|
||||||
-``false``. Deprecated in version 22.2. Use ``package_update`` instead.,\
|
|
||||||
- apt_upgrade: Default: ``false``. Deprecated in version 22.2. Use \
|
|
||||||
-``package_upgrade`` instead.\
|
|
||||||
+apt_reboot_if_required: Deprecated in version 22.2. Use\
|
|
||||||
+ ``package_reboot_if_required`` instead., apt_update: Deprecated in version\
|
|
||||||
+ 22.2. Use ``package_update`` instead., apt_upgrade: Deprecated in version\
|
|
||||||
+ 22.2. Use ``package_upgrade`` instead.\
|
|
||||||
Valid schema {cfg_file}
|
|
||||||
""" # noqa: E501
|
|
||||||
),
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
|||||||
From 9ee9fe608b906fe4e523cbf7fbe4539f0322ba2f Mon Sep 17 00:00:00 2001
|
|
||||||
From: PengpengSun <40026211+PengpengSun@users.noreply.github.com>
|
|
||||||
Date: Thu, 4 Jul 2024 04:06:39 +0800
|
|
||||||
Subject: [PATCH 2/2] fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr
|
|
||||||
(#5471)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 99: fix(vmware): Set IPv6 to dhcp when there is no IPv6 addr (#5471)
|
|
||||||
RH-Jira: RHEL-46194
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] fbae24c7e7f48239200eaf457d260203fb550845 (xiachen/cloud-init-centos)
|
|
||||||
|
|
||||||
When there is no IPv6 addr given in the customization configuration,
|
|
||||||
we shall set IPv6 type to dhcp6, then customized Linux network will be
|
|
||||||
set to dhcp IPv6 explicitly.
|
|
||||||
|
|
||||||
(cherry picked from commit 2b6fe6403db769de14f7c7b7e4aa65f5bea8f3e0)
|
|
||||||
---
|
|
||||||
.../sources/helpers/vmware/imc/config_nic.py | 2 +-
|
|
||||||
.../sources/vmware/test_vmware_config_file.py | 68 ++++++++++++++-----
|
|
||||||
2 files changed, 52 insertions(+), 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/sources/helpers/vmware/imc/config_nic.py b/cloudinit/sources/helpers/vmware/imc/config_nic.py
|
|
||||||
index b07214a2..254518af 100644
|
|
||||||
--- a/cloudinit/sources/helpers/vmware/imc/config_nic.py
|
|
||||||
+++ b/cloudinit/sources/helpers/vmware/imc/config_nic.py
|
|
||||||
@@ -207,7 +207,7 @@ class NicConfigurator:
|
|
||||||
"""
|
|
||||||
|
|
||||||
if not nic.staticIpv6:
|
|
||||||
- return ([], [])
|
|
||||||
+ return ([{"type": "dhcp6"}], [])
|
|
||||||
|
|
||||||
subnet_list = []
|
|
||||||
# Static Ipv6
|
|
||||||
diff --git a/tests/unittests/sources/vmware/test_vmware_config_file.py b/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
index b53ea96c..25d3b093 100644
|
|
||||||
--- a/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
+++ b/tests/unittests/sources/vmware/test_vmware_config_file.py
|
|
||||||
@@ -240,27 +240,45 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
elif cfg.get("name") == nic2.get("name"):
|
|
||||||
nic2.update(cfg)
|
|
||||||
|
|
||||||
+ # Test NIC1
|
|
||||||
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
|
|
||||||
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
|
|
||||||
self.assertEqual(
|
|
||||||
"00:50:56:a6:8c:08", nic1.get("mac_address"), "mac address of NIC1"
|
|
||||||
)
|
|
||||||
subnets = nic1.get("subnets")
|
|
||||||
- self.assertEqual(1, len(subnets), "number of subnets for NIC1")
|
|
||||||
- subnet = subnets[0]
|
|
||||||
- self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC1")
|
|
||||||
- self.assertEqual("auto", subnet.get("control"), "NIC1 Control type")
|
|
||||||
+ self.assertEqual(2, len(subnets), "number of subnets for NIC1")
|
|
||||||
+ subnet_ipv4 = subnets[0]
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC1"
|
|
||||||
+ )
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ "auto", subnet_ipv4.get("control"), "NIC1 Control type"
|
|
||||||
+ )
|
|
||||||
+ subnet_ipv6 = subnets[1]
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC1"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
+ # Test NIC2
|
|
||||||
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
|
|
||||||
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
|
|
||||||
self.assertEqual(
|
|
||||||
"00:50:56:a6:5a:de", nic2.get("mac_address"), "mac address of NIC2"
|
|
||||||
)
|
|
||||||
subnets = nic2.get("subnets")
|
|
||||||
- self.assertEqual(1, len(subnets), "number of subnets for NIC2")
|
|
||||||
- subnet = subnets[0]
|
|
||||||
- self.assertEqual("dhcp", subnet.get("type"), "DHCP type for NIC2")
|
|
||||||
- self.assertEqual("auto", subnet.get("control"), "NIC2 Control type")
|
|
||||||
+ self.assertEqual(2, len(subnets), "number of subnets for NIC2")
|
|
||||||
+ subnet_ipv4 = subnets[0]
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ "dhcp", subnet_ipv4.get("type"), "Ipv4 DHCP type for NIC2"
|
|
||||||
+ )
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ "auto", subnet_ipv4.get("control"), "NIC2 Control type"
|
|
||||||
+ )
|
|
||||||
+ subnet_ipv6 = subnets[1]
|
|
||||||
+ self.assertEqual(
|
|
||||||
+ "dhcp6", subnet_ipv6.get("type"), "Ipv6 DHCP type for NIC2"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_get_nics_list_static(self):
|
|
||||||
"""Tests if NicConfigurator properly calculates network subnets
|
|
||||||
@@ -285,6 +303,7 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
elif cfg.get("name") == nic2.get("name"):
|
|
||||||
nic2.update(cfg)
|
|
||||||
|
|
||||||
+ # Test NIC1
|
|
||||||
self.assertEqual("physical", nic1.get("type"), "type of NIC1")
|
|
||||||
self.assertEqual("NIC1", nic1.get("name"), "name of NIC1")
|
|
||||||
self.assertEqual(
|
|
||||||
@@ -344,6 +363,7 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
else:
|
|
||||||
self.assertEqual(True, False, "invalid gateway %s" % (gateway))
|
|
||||||
|
|
||||||
+ # Test NIC2
|
|
||||||
self.assertEqual("physical", nic2.get("type"), "type of NIC2")
|
|
||||||
self.assertEqual("NIC2", nic2.get("name"), "name of NIC2")
|
|
||||||
self.assertEqual(
|
|
||||||
@@ -351,16 +371,18 @@ class TestVmwareConfigFile(CiTestCase):
|
|
||||||
)
|
|
||||||
|
|
||||||
subnets = nic2.get("subnets")
|
|
||||||
- self.assertEqual(1, len(subnets), "Number of subnets for NIC2")
|
|
||||||
+ self.assertEqual(2, len(subnets), "Number of subnets for NIC2")
|
|
||||||
|
|
||||||
- subnet = subnets[0]
|
|
||||||
- self.assertEqual("static", subnet.get("type"), "Subnet type")
|
|
||||||
+ subnet_ipv4 = subnets[0]
|
|
||||||
+ self.assertEqual("static", subnet_ipv4.get("type"), "Subnet type")
|
|
||||||
self.assertEqual(
|
|
||||||
- "192.168.6.102", subnet.get("address"), "Subnet address"
|
|
||||||
+ "192.168.6.102", subnet_ipv4.get("address"), "Subnet address"
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
- "255.255.0.0", subnet.get("netmask"), "Subnet netmask"
|
|
||||||
+ "255.255.0.0", subnet_ipv4.get("netmask"), "Subnet netmask"
|
|
||||||
)
|
|
||||||
+ subnet_ipv6 = subnets[1]
|
|
||||||
+ self.assertEqual("dhcp6", subnet_ipv6.get("type"), "Subnet type")
|
|
||||||
|
|
||||||
def test_custom_script(self):
|
|
||||||
cf = ConfigFile("tests/data/vmware/cust-dhcp-2nic.cfg")
|
|
||||||
@@ -447,7 +469,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"type": "static",
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -498,7 +523,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -558,7 +586,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"metric": 10000,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
@@ -603,7 +634,10 @@ class TestVmwareNetConfig(CiTestCase):
|
|
||||||
"address": "10.20.87.154",
|
|
||||||
"netmask": "255.255.252.0",
|
|
||||||
"gateway": "10.20.87.253",
|
|
||||||
- }
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ "type": "dhcp6",
|
|
||||||
+ },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
|||||||
From 9a3c16dc89d2813c90df2e57e71ae5df704083be Mon Sep 17 00:00:00 2001
|
|
||||||
From: James Falcon <james.falcon@canonical.com>
|
|
||||||
Date: Tue, 9 Jan 2024 10:32:12 -0600
|
|
||||||
Subject: [PATCH] refactor: Ensure internal DNS state same for v1 and v2
|
|
||||||
(#4756)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 152: refactor: Ensure internal DNS state same for v1 and v2 (#4756)
|
|
||||||
RH-Jira: RHEL-68409
|
|
||||||
RH-Acked-by: xiachen <xiachen@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] f006996f7b418103ffaf73ff9ded5b5d149bedf6
|
|
||||||
|
|
||||||
When defining interface-level DNS on the network state, v1 uses the
|
|
||||||
"nameservers" key whereas v2 was using an "addresses" key.
|
|
||||||
This commit updates the v2 parsing to set the key as "nameservers".
|
|
||||||
|
|
||||||
Also update networkd renderer as this was only renderer using the v2
|
|
||||||
"addresses" key.
|
|
||||||
|
|
||||||
(cherry picked from commit 436e6f5ce3fbb8b391a2158538873644058904e6)
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/net/network_state.py | 2 +-
|
|
||||||
cloudinit/net/networkd.py | 13 ++++---------
|
|
||||||
tests/unittests/net/test_network_state.py | 5 ++++-
|
|
||||||
3 files changed, 9 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
|
|
||||||
index 226421bd0..82c3bf894 100644
|
|
||||||
--- a/cloudinit/net/network_state.py
|
|
||||||
+++ b/cloudinit/net/network_state.py
|
|
||||||
@@ -336,7 +336,7 @@ class NetworkStateInterpreter:
|
|
||||||
if iface:
|
|
||||||
nameservers, search = dns
|
|
||||||
iface["dns"] = {
|
|
||||||
- "addresses": nameservers,
|
|
||||||
+ "nameservers": nameservers,
|
|
||||||
"search": search,
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/networkd.py b/cloudinit/net/networkd.py
|
|
||||||
index 0978849c8..29f466eda 100644
|
|
||||||
--- a/cloudinit/net/networkd.py
|
|
||||||
+++ b/cloudinit/net/networkd.py
|
|
||||||
@@ -221,12 +221,6 @@ class Renderer(renderer.Renderer):
|
|
||||||
def parse_dns(self, iface, cfg: CfgParser, ns: NetworkState):
|
|
||||||
sec = "Network"
|
|
||||||
|
|
||||||
- dns_cfg_map = {
|
|
||||||
- "search": "Domains",
|
|
||||||
- "nameservers": "DNS",
|
|
||||||
- "addresses": "DNS",
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
dns = iface.get("dns")
|
|
||||||
if not dns and ns.version == 1:
|
|
||||||
dns = {
|
|
||||||
@@ -236,9 +230,10 @@ class Renderer(renderer.Renderer):
|
|
||||||
elif not dns and ns.version == 2:
|
|
||||||
return
|
|
||||||
|
|
||||||
- for k, v in dns_cfg_map.items():
|
|
||||||
- if k in dns and dns[k]:
|
|
||||||
- cfg.update_section(sec, v, " ".join(dns[k]))
|
|
||||||
+ if dns.get("search"):
|
|
||||||
+ cfg.update_section(sec, "Domains", " ".join(dns["search"]))
|
|
||||||
+ if dns.get("nameservers"):
|
|
||||||
+ cfg.update_section(sec, "DNS", " ".join(dns["nameservers"]))
|
|
||||||
|
|
||||||
def parse_dhcp_overrides(self, cfg: CfgParser, device, dhcp, version):
|
|
||||||
dhcp_config_maps = {
|
|
||||||
diff --git a/tests/unittests/net/test_network_state.py b/tests/unittests/net/test_network_state.py
|
|
||||||
index 7d304ca3a..74a6bb34c 100644
|
|
||||||
--- a/tests/unittests/net/test_network_state.py
|
|
||||||
+++ b/tests/unittests/net/test_network_state.py
|
|
||||||
@@ -258,7 +258,10 @@ class TestNetworkStateParseNameservers:
|
|
||||||
# If an interface was specified, DNS should be part of the interface
|
|
||||||
for iface in config.iter_interfaces():
|
|
||||||
if iface["name"] == "eth1":
|
|
||||||
- assert iface["dns"]["addresses"] == ["192.168.1.1", "8.8.8.8"]
|
|
||||||
+ assert iface["dns"]["nameservers"] == [
|
|
||||||
+ "192.168.1.1",
|
|
||||||
+ "8.8.8.8",
|
|
||||||
+ ]
|
|
||||||
assert iface["dns"]["search"] == ["spam.local"]
|
|
||||||
else:
|
|
||||||
assert "dns" not in iface
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
Loading…
Reference in new issue