Compare commits
No commits in common. "c8" and "c8-beta" have entirely different histories.
@ -1,65 +0,0 @@
|
|||||||
From 9da40a7e46e40eb090538f9d8a5aa6049fbbc5b8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Tue, 12 Mar 2024 12:52:10 +0530
|
|
||||||
Subject: [PATCH] Retain exit code in cloud-init status for recoverable errors
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <None>
|
|
||||||
RH-MergeRequest: 126: Retain exit code in cloud-init status for recoverable errors
|
|
||||||
RH-Jira: RHEL-28817
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 8c45ffe77ed8e964c35af4705d65daaf8282038f
|
|
||||||
|
|
||||||
Version 23.4 of cloud-init changed the status code reported by cloud-init for
|
|
||||||
recoverable errors from 0 to 2. Please see the commit
|
|
||||||
70acb7f2a30d58 ("Add support for cloud-init "degraded" state (#4500)")
|
|
||||||
|
|
||||||
This change has the potential to break customers who are expecting a 0 status
|
|
||||||
and where warnings can be expected. Hence, revert the status code from 2 to 0
|
|
||||||
even in case of recoverable errors. This retains the old behavior and hence
|
|
||||||
avoids breaking scripts and software stack that expects 0 on the end user side.
|
|
||||||
|
|
||||||
Cannonical has made a similar change downstream for similar reasons. Please see
|
|
||||||
https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/2048522
|
|
||||||
and the corresponding downstream patch:
|
|
||||||
https://github.com/canonical/cloud-init/pull/4747/commits/adce34bfd214e4eecdf87329486f30f0898dd303
|
|
||||||
|
|
||||||
This patch has limited risk as it narrowly only restores the old status
|
|
||||||
code for recoverable errors and does not modify anything else.
|
|
||||||
|
|
||||||
X-downstream-only: true
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
cloudinit/cmd/status.py | 2 +-
|
|
||||||
tests/unittests/cmd/test_status.py | 2 +-
|
|
||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/cmd/status.py b/cloudinit/cmd/status.py
|
|
||||||
index f5ee9c11..849c80bc 100644
|
|
||||||
--- a/cloudinit/cmd/status.py
|
|
||||||
+++ b/cloudinit/cmd/status.py
|
|
||||||
@@ -225,7 +225,7 @@ def handle_status_args(name, args) -> int:
|
|
||||||
return 1
|
|
||||||
# Recoverable error
|
|
||||||
elif details.status in UXAppStatusDegradedMap.values():
|
|
||||||
- return 2
|
|
||||||
+ return 0
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/tests/unittests/cmd/test_status.py b/tests/unittests/cmd/test_status.py
|
|
||||||
index 6c85a59a..567b517a 100644
|
|
||||||
--- a/tests/unittests/cmd/test_status.py
|
|
||||||
+++ b/tests/unittests/cmd/test_status.py
|
|
||||||
@@ -636,7 +636,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
MyArgs(long=False, wait=False, format="json"),
|
|
||||||
- 2,
|
|
||||||
+ 0,
|
|
||||||
{
|
|
||||||
"boot_status_code": "enabled-by-kernel-cmdline",
|
|
||||||
"datasource": "nocloud",
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
|||||||
From 42aad98557bb62ae693f38e5f1e137bcc44f6046 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Tue, 5 Mar 2024 12:42:26 +0530
|
|
||||||
Subject: [PATCH] Revert "systemd: Standardize cloud-init systemd enablement
|
|
||||||
(#4399)"
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <None>
|
|
||||||
RH-MergeRequest: 124: Revert "systemd: Standardize cloud-init systemd enablement (#4399)"
|
|
||||||
RH-Jira: RHEL-21290
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 10da53e761e25ff7d254a4cfb8fb1fd18de8b4ed
|
|
||||||
|
|
||||||
This reverts commit ec7dde8041d4023b09324e84abe37dc766ebbaf6.
|
|
||||||
|
|
||||||
'ConditionEnvironment' clause is not available in RHEL 8.10 systemd and adding
|
|
||||||
the feature would be complicated. Hence reverting the patch seems to be the
|
|
||||||
right thing to do as it was a simple enhancement to make sure all distros use
|
|
||||||
systemd's kernel commandline and file conditionals. We only care about RHEL so
|
|
||||||
the change should not affect us.
|
|
||||||
|
|
||||||
Signed-off-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
---
|
|
||||||
systemd/cloud-config.service.tmpl | 3 ++-
|
|
||||||
systemd/cloud-final.service.tmpl | 3 ++-
|
|
||||||
systemd/cloud-init-local.service.tmpl | 3 ++-
|
|
||||||
systemd/cloud-init.service.tmpl | 3 ++-
|
|
||||||
systemd/cloud-init.target | 3 ---
|
|
||||||
5 files changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/systemd/cloud-config.service.tmpl b/systemd/cloud-config.service.tmpl
|
|
||||||
index 31d9d983..76e50ae1 100644
|
|
||||||
--- a/systemd/cloud-config.service.tmpl
|
|
||||||
+++ b/systemd/cloud-config.service.tmpl
|
|
||||||
@@ -5,9 +5,10 @@ After=network-online.target cloud-config.target
|
|
||||||
After=snapd.seeded.service
|
|
||||||
Before=systemd-user-sessions.service
|
|
||||||
Wants=network-online.target cloud-config.target
|
|
||||||
+{% if variant == "rhel" %}
|
|
||||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
|
||||||
ConditionKernelCommandLine=!cloud-init=disabled
|
|
||||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
|
||||||
+{% endif %}
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
diff --git a/systemd/cloud-final.service.tmpl b/systemd/cloud-final.service.tmpl
|
|
||||||
index bcf8b009..85f423ac 100644
|
|
||||||
--- a/systemd/cloud-final.service.tmpl
|
|
||||||
+++ b/systemd/cloud-final.service.tmpl
|
|
||||||
@@ -7,9 +7,10 @@ After=multi-user.target
|
|
||||||
Before=apt-daily.service
|
|
||||||
{% endif %}
|
|
||||||
Wants=network-online.target cloud-config.service
|
|
||||||
+{% if variant == "rhel" %}
|
|
||||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
|
||||||
ConditionKernelCommandLine=!cloud-init=disabled
|
|
||||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
|
||||||
+{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl
|
|
||||||
index 3a1ca7fa..6f3f9d8d 100644
|
|
||||||
--- a/systemd/cloud-init-local.service.tmpl
|
|
||||||
+++ b/systemd/cloud-init-local.service.tmpl
|
|
||||||
@@ -26,9 +26,10 @@ Before=sysinit.target
|
|
||||||
Conflicts=shutdown.target
|
|
||||||
{% endif %}
|
|
||||||
RequiresMountsFor=/var/lib/cloud
|
|
||||||
+{% if variant == "rhel" %}
|
|
||||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
|
||||||
ConditionKernelCommandLine=!cloud-init=disabled
|
|
||||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
|
||||||
+{% endif %}
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl
|
|
||||||
index bf91164a..26d2e39c 100644
|
|
||||||
--- a/systemd/cloud-init.service.tmpl
|
|
||||||
+++ b/systemd/cloud-init.service.tmpl
|
|
||||||
@@ -38,9 +38,10 @@ Conflicts=shutdown.target
|
|
||||||
Before=shutdown.target
|
|
||||||
Conflicts=shutdown.target
|
|
||||||
{% endif %}
|
|
||||||
+{% if variant == "rhel" %}
|
|
||||||
ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
|
||||||
ConditionKernelCommandLine=!cloud-init=disabled
|
|
||||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
|
||||||
+{% endif %}
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
diff --git a/systemd/cloud-init.target b/systemd/cloud-init.target
|
|
||||||
index 30450f7f..760dfee5 100644
|
|
||||||
--- a/systemd/cloud-init.target
|
|
||||||
+++ b/systemd/cloud-init.target
|
|
||||||
@@ -10,6 +10,3 @@
|
|
||||||
[Unit]
|
|
||||||
Description=Cloud-init target
|
|
||||||
After=multi-user.target
|
|
||||||
-ConditionPathExists=!/etc/cloud/cloud-init.disabled
|
|
||||||
-ConditionKernelCommandLine=!cloud-init=disabled
|
|
||||||
-ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled
|
|
||||||
--
|
|
||||||
2.39.3
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
|||||||
From 1024e43b58ce84bb6c6d8bd89785704e04560b2a 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: 128: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
RH-Jira: RHEL-27134
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [2/2] 73d27116735e853fbaa38942390721dd78bc6241
|
|
||||||
|
|
||||||
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 678ec39b..e010eb6b 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -645,6 +645,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(),
|
|
||||||
),
|
|
||||||
@@ -2769,6 +2770,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;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2794,6 +2797,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;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2818,6 +2823,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;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2902,12 +2909,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;
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -2962,6 +2972,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.41.0
|
|
||||||
|
|
@ -1,350 +0,0 @@
|
|||||||
From 773501c6d2b52a5623b5fed3c5534d41aa6488fa Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ani Sinha <anisinha@redhat.com>
|
|
||||||
Date: Thu, 20 Jun 2024 22:27:03 +0530
|
|
||||||
Subject: [PATCH] feat(sysconfig): Add DNS from interface config to resolv.conf
|
|
||||||
(#5401)
|
|
||||||
|
|
||||||
RH-Author: xiachen <xiachen@redhat.com>
|
|
||||||
RH-MergeRequest: 140: feat(sysconfig): Add DNS from interface config to resolv.conf (#5401)
|
|
||||||
RH-Jira: RHEL-46013
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] b9f492627cdae3bf356f388eb0870241793a7f99
|
|
||||||
|
|
||||||
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 | 183 +++++++++++++++++++++++++++++++++++-
|
|
||||||
2 files changed, 229 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
|
|
||||||
index f01c4236..42eb2be3 100644
|
|
||||||
--- a/cloudinit/net/sysconfig.py
|
|
||||||
+++ b/cloudinit/net/sysconfig.py
|
|
||||||
@@ -824,20 +824,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 e010eb6b..86ba398d 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(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
@@ -581,6 +585,8 @@ dns = none
|
|
||||||
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
|
|
||||||
@@ -595,7 +601,173 @@ 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.
|
|
||||||
+#
|
|
||||||
+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(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
@@ -646,6 +818,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(),
|
|
||||||
),
|
|
||||||
@@ -653,7 +826,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",
|
|
||||||
@@ -714,6 +893,7 @@ STARTMODE=auto
|
|
||||||
; Created by cloud-init automatically, do not edit.
|
|
||||||
;
|
|
||||||
nameserver 172.19.0.12
|
|
||||||
+search example.com
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
@@ -761,6 +941,7 @@ USERCTL=no
|
|
||||||
; Created by cloud-init automatically, do not edit.
|
|
||||||
;
|
|
||||||
nameserver 172.19.0.12
|
|
||||||
+search example.com
|
|
||||||
""".lstrip(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
--
|
|
||||||
2.45.1
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
From b424877c0e7673466e7bd354c1eed4db908ebab3 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: 143: fix: Add subnet ipv4/ipv6 to network schema (#5191)
|
|
||||||
RH-Jira: RHEL-54155
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] d4c7beb80b8c67df6b6fc04db8d3b93ed82dd067
|
|
||||||
|
|
||||||
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.45.1
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From 4e5b1ed68014b81ca2ef2f07675f2a43cf03c5c3 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: 135: fix: Always use single datasource if specified (#5098)
|
|
||||||
RH-Jira: RHEL-36701
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] 491f053f7d758f1a0ca8918d1449cc2f7838291f
|
|
||||||
|
|
||||||
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.45.1
|
|
||||||
|
|
@ -1,247 +0,0 @@
|
|||||||
From cfbe83d4a869ab20d385b5058031df0364483bda 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] fix: Clean cache if no datasource fallback (#5499)
|
|
||||||
|
|
||||||
RH-Author: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-MergeRequest: 141: fix: Clean cache if no datasource fallback (#5499)
|
|
||||||
RH-Jira: RHEL-49742
|
|
||||||
RH-Acked-by: xiachen <xiachen@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/1] 64a79c1a6bd06c280aed85032bb55cc60ec1fc2e
|
|
||||||
|
|
||||||
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 65207b6778fa97ff450a9200c28e4770c9128854 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: 128: Fixes for cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
RH-Jira: RHEL-27134
|
|
||||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Commit: [1/2] abfebdde6b8b914d5a7de8853beca1fe206a5b23
|
|
||||||
|
|
||||||
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 e52c2497..678ec39b 100644
|
|
||||||
--- a/tests/unittests/test_net.py
|
|
||||||
+++ b/tests/unittests/test_net.py
|
|
||||||
@@ -2934,9 +2934,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
|
|
||||||
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
@@ -4114,6 +4114,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"]
|
|
||||||
+ """
|
|
||||||
+ ),
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6214,6 +6356,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.41.0
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
|||||||
From d17e05b1709e3b7148e889512282603f7399c857 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: 133: fix: Fall back to cached local ds if no valid ds found (#4997)
|
|
||||||
RH-Jira: RHEL-32841
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
||||||
RH-Commit: [1/1] df9c6fda66dee9622725ff2d52e64999796324b8
|
|
||||||
|
|
||||||
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,42 +0,0 @@
|
|||||||
From 8a83f1e6077cea9dc9ebc909e1332e15c8cbadac 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: 129: fix: Undeprecate 'network' in schema route definition (#5072)
|
|
||||||
RH-Jira: RHEL-29710
|
|
||||||
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Commit: [1/1] c482c3e11720f01daa7b0d37035157b062b35213
|
|
||||||
|
|
||||||
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.41.0
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From 6e3c351b013dc2ac01035853229ffdfdafa3afa8 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: 137: fix(cloudstack): Use parsed lease file for virtual router in cloudstack
|
|
||||||
RH-Jira: RHEL-40418
|
|
||||||
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
||||||
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
|
||||||
RH-Commit: [1/1] 77f97c04432fffff125dc1725d66b33ae0ab4af8
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Name: cloud-init
|
Name: cloud-init
|
||||||
Version: 23.4
|
Version: 23.4
|
||||||
Release: 7%{?dist}.8
|
Release: 5%{?dist}
|
||||||
Summary: Cloud instance init scripts
|
Summary: Cloud instance init scripts
|
||||||
|
|
||||||
Group: System Environment/Base
|
Group: System Environment/Base
|
||||||
@ -35,28 +35,6 @@ Patch19: ci-Revert-Use-grep-for-faster-parsing-of-cloud-config-i.patch
|
|||||||
Patch20: ci-ci-Pin-pytest-8.0.0.-4816.patch
|
Patch20: ci-ci-Pin-pytest-8.0.0.-4816.patch
|
||||||
# For RHEL-21323 - [rhel-8] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4
|
# For RHEL-21323 - [rhel-8] The schema WARNING info for network-config.json is not suitable in cloud-init-23.4
|
||||||
Patch21: ci-fix-Add-types-to-network-v1-schema-4841.patch
|
Patch21: ci-fix-Add-types-to-network-v1-schema-4841.patch
|
||||||
# For RHEL-21290 - Unknown lvalue 'ConditionEnvironment' in section 'Unit' for /usr/lib/systemd/system/cloud-init.target,cloud-init.service
|
|
||||||
Patch22: ci-Revert-systemd-Standardize-cloud-init-systemd-enable.patch
|
|
||||||
# For RHEL-28817 - [RHEL 8.10] cloud-init 23.4 returns 2 on recoverable errors instead of 0
|
|
||||||
Patch23: ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch
|
|
||||||
# For RHEL-27134 - [rhel-8]cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
Patch24: ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch
|
|
||||||
# For RHEL-27134 - [rhel-8]cloud-init fails to configure DNS/search domains for network-config v1
|
|
||||||
Patch25: ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch
|
|
||||||
# For RHEL-29710 - Suggest to backport patch ff40d1a to undeprecate 'network' in schema route definition [rhel-8.10.0.z]
|
|
||||||
Patch26: ci-fix-Undeprecate-network-in-schema-route-definition-5.patch
|
|
||||||
# For RHEL-32841 - [cloud-init][ESXi]VMware datasource resets on every boot causing it to lose network configuration [rhel-8.10.z]
|
|
||||||
Patch27: ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch
|
|
||||||
# For RHEL-36701 - DataSourceNoCloudNet not configurable via config files [rhel-8.10.z]
|
|
||||||
Patch28: ci-fix-Always-use-single-datasource-if-specified-5098.patch
|
|
||||||
# For RHEL-40418 - [Cloud-init] CloudstackDataSource cannot work with NetworkManager [rhel-8.10.z]
|
|
||||||
Patch29: ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch
|
|
||||||
# For RHEL-46013 - [RHEL-8] cloud-init fails to configure DNS search domains [rhel-8.10.z]
|
|
||||||
Patch30: ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch
|
|
||||||
# For RHEL-49742 - [Cloud-init] [RHEL-8.10] Password reset feature broken with CloudstackDataSource
|
|
||||||
Patch31: ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch
|
|
||||||
# For RHEL-54155 - [RHEL 8.10] cloud-init schema validation fails.
|
|
||||||
Patch32: ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch
|
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
|
|
||||||
@ -272,55 +250,6 @@ fi
|
|||||||
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
%config(noreplace) %{_sysconfdir}/rsyslog.d/21-cloudinit.conf
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue Aug 20 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-7.el8_10.8
|
|
||||||
- ci-fix-Add-subnet-ipv4-ipv6-to-network-schema-5191.patch [RHEL-54155]
|
|
||||||
- Resolves: RHEL-54155
|
|
||||||
([RHEL 8.10] cloud-init schema validation fails.)
|
|
||||||
|
|
||||||
* Thu Jul 25 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.el8_10.7
|
|
||||||
- ci-fix-Clean-cache-if-no-datasource-fallback-5499.patch [RHEL-49742]
|
|
||||||
- Resolves: RHEL-49742
|
|
||||||
([Cloud-init] [RHEL-8.10] Password reset feature broken with CloudstackDataSource)
|
|
||||||
|
|
||||||
* Tue Jul 09 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-7.el8_10.6
|
|
||||||
- ci-feat-sysconfig-Add-DNS-from-interface-config-to-reso.patch [RHEL-46013]
|
|
||||||
- Resolves: RHEL-46013
|
|
||||||
([RHEL-8] cloud-init fails to configure DNS search domains [rhel-8.10.z])
|
|
||||||
|
|
||||||
* Tue Jul 09 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.el8_10.5
|
|
||||||
- ci-fix-cloudstack-Use-parsed-lease-file-for-virtual-rou.patch [RHEL-40418]
|
|
||||||
- Resolves: RHEL-40418
|
|
||||||
([Cloud-init] CloudstackDataSource cannot work with NetworkManager [rhel-8.10.z])
|
|
||||||
|
|
||||||
* Wed May 29 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-7.el8.3
|
|
||||||
- ci-fix-Always-use-single-datasource-if-specified-5098.patch [RHEL-36701]
|
|
||||||
- Resolves: RHEL-36701
|
|
||||||
(DataSourceNoCloudNet not configurable via config files [rhel-8.10.z])
|
|
||||||
|
|
||||||
* Tue Apr 23 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7.el8_10.2
|
|
||||||
- ci-fix-Fall-back-to-cached-local-ds-if-no-valid-ds-foun.patch [RHEL-32841]
|
|
||||||
- Resolves: RHEL-32841
|
|
||||||
([cloud-init][ESXi]VMware datasource resets on every boot causing it to lose network configuration [rhel-8.10.z])
|
|
||||||
|
|
||||||
* Fri Apr 05 2024 Jon Maloy <jmaloy@redhat.com> - 23.4-7.el8.1
|
|
||||||
- ci-fix-Correct-v2-NetworkManager-route-rendering-4637.patch [RHEL-27134]
|
|
||||||
- ci-feat-apply-global-DNS-to-interfaces-in-network-manag.patch [RHEL-27134]
|
|
||||||
- ci-fix-Undeprecate-network-in-schema-route-definition-5.patch [RHEL-29710]
|
|
||||||
- Resolves: RHEL-27134
|
|
||||||
([rhel-8]cloud-init fails to configure DNS/search domains for network-config v1)
|
|
||||||
- Resolves: RHEL-29710
|
|
||||||
(Suggest to backport patch ff40d1a to undeprecate 'network' in schema route definition [rhel-8.10.0.z])
|
|
||||||
|
|
||||||
* Thu Mar 14 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-7
|
|
||||||
- ci-Retain-exit-code-in-cloud-init-status-for-recoverabl.patch [RHEL-28817]
|
|
||||||
- Resolves: RHEL-28817
|
|
||||||
([RHEL 8.10] cloud-init 23.4 returns 2 on recoverable errors instead of 0)
|
|
||||||
|
|
||||||
* Mon Mar 11 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-6
|
|
||||||
- ci-Revert-systemd-Standardize-cloud-init-systemd-enable.patch [RHEL-21290]
|
|
||||||
- Resolves: RHEL-21290
|
|
||||||
(Unknown lvalue 'ConditionEnvironment' in section 'Unit' for /usr/lib/systemd/system/cloud-init.target,cloud-init.service)
|
|
||||||
|
|
||||||
* Mon Feb 26 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-5
|
* Mon Feb 26 2024 Miroslav Rezanina <mrezanin@redhat.com> - 23.4-5
|
||||||
- ci-ci-Pin-pytest-8.0.0.-4816.patch [RHEL-21323]
|
- ci-ci-Pin-pytest-8.0.0.-4816.patch [RHEL-21323]
|
||||||
- ci-fix-Add-types-to-network-v1-schema-4841.patch [RHEL-21323]
|
- ci-fix-Add-types-to-network-v1-schema-4841.patch [RHEL-21323]
|
||||||
|
Loading…
Reference in New Issue
Block a user