Compare commits

..

No commits in common. "factory" and "devel" have entirely different histories.

7 changed files with 23 additions and 304 deletions

View File

@ -1,24 +0,0 @@
--- cloudinit/atomic_helper.py.orig
+++ cloudinit/atomic_helper.py
@@ -7,6 +7,8 @@ import stat
import tempfile
from base64 import b64decode, b64encode
+from cloudinit import util
+
_DEF_PERMS = 0o644
LOG = logging.getLogger(__name__)
@@ -43,9 +45,9 @@ def write_file(
tf = None
try:
- tf = tempfile.NamedTemporaryFile(
- dir=os.path.dirname(filename), delete=False, mode=omode
- )
+ dirname = os.path.dirname(filename)
+ util.ensure_dir(dirname)
+ tf = tempfile.NamedTemporaryFile(dir=dirname, delete=False, mode=omode)
LOG.debug(
"Atomically writing to file %s (via temporary file %s) - %s: [%o]"
" %d bytes/chars",

View File

@ -1,100 +0,0 @@
From 4060bed98d2637418955fdb33fc43623c8b95235 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 12 Mar 2024 22:20:06 -0600
Subject: [PATCH 1/4] fix: Don't assume ordering of ThreadPoolExecutor
submissions
---
tests/unittests/test_url_helper.py | 52 +++++++++++++++++++++++++++---
1 file changed, 47 insertions(+), 5 deletions(-)
Index: cloud-init-23.3/tests/unittests/test_url_helper.py
===================================================================
--- cloud-init-23.3.orig/tests/unittests/test_url_helper.py
+++ cloud-init-23.3/tests/unittests/test_url_helper.py
@@ -4,6 +4,7 @@ import logging
from functools import partial
from threading import Event
from time import process_time
+from unittest.mock import ANY, call
import pytest
import requests
@@ -465,20 +466,72 @@ class TestDualStack:
"""Assert expected call intervals occur"""
stagger = 0.1
with mock.patch(M_PATH + "_run_func_with_delay") as delay_func:
+
+ def identity_of_first_arg(x, _):
+ return x
+
dual_stack(
- lambda x, _y: x,
+ identity_of_first_arg,
["you", "and", "me", "and", "dog"],
stagger_delay=stagger,
timeout=1,
)
- # ensure that stagger delay for each subsequent call is:
+ # ensure that stagger delay for each call is made with args:
# [ 0 * N, 1 * N, 2 * N, 3 * N, 4 * N, 5 * N] where N = stagger
# it appears that without an explicit wait/join we can't assert
# number of calls
- for delay, call_item in enumerate(delay_func.call_args_list):
- _, kwargs = call_item
- assert stagger * delay == kwargs.get("delay")
+ calls = [
+ call(
+ func=identity_of_first_arg,
+ addr="you",
+ timeout=1,
+ event=ANY,
+ delay=stagger * 0,
+ ),
+ call(
+ func=identity_of_first_arg,
+ addr="and",
+ timeout=1,
+ event=ANY,
+ delay=stagger * 1,
+ ),
+ call(
+ func=identity_of_first_arg,
+ addr="me",
+ timeout=1,
+ event=ANY,
+ delay=stagger * 2,
+ ),
+ call(
+ func=identity_of_first_arg,
+ addr="and",
+ timeout=1,
+ event=ANY,
+ delay=stagger * 3,
+ ),
+ call(
+ func=identity_of_first_arg,
+ addr="dog",
+ timeout=1,
+ event=ANY,
+ delay=stagger * 4,
+ ),
+ ]
+ num_calls = 0
+ for call_instance in calls:
+ if call_instance in delay_func.call_args_list:
+ num_calls += 1
+
+ # we can't know the order of the submitted functions' execution
+ # we can't know how many of the submitted functions get called
+ # in advance
+ #
+ # we _do_ know what the possible arg combinations are
+ # we _do_ know from the mocked function how many got called
+ # assert that all calls that occurred had known valid arguments
+ # by checking for the correct number of matches
+ assert num_calls == len(delay_func.call_args_list)
ADDR1 = "https://addr1/"

View File

@ -1,22 +0,0 @@
From bed5ae7f777e0e4bcb5609622385ee94751c03ce Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 5 Dec 2023 13:41:13 -0700
Subject: [PATCH] fix(python3.13): Fix import error for passlib on Python 3.13
---
cloudinit/sources/DataSourceAzure.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: cloud-init-23.3/cloudinit/sources/DataSourceAzure.py
===================================================================
--- cloud-init-23.3.orig/cloudinit/sources/DataSourceAzure.py
+++ cloud-init-23.3/cloudinit/sources/DataSourceAzure.py
@@ -55,7 +55,7 @@ try:
)
except (ImportError, AttributeError):
try:
- import passlib
+ import passlib.hash
blowfish_hash = passlib.hash.sha512_crypt.hash
except ImportError:

View File

@ -1,36 +0,0 @@
--- cloudinit/sources/helpers/openstack.py.orig
+++ cloudinit/sources/helpers/openstack.py
@@ -736,7 +736,14 @@ def convert_net_json(network_json=None,
if not mac:
raise ValueError("No mac_address or name entry for %s" % d)
if mac not in known_macs:
- raise ValueError("Unable to find a system nic for %s" % d)
+ # Let's give udev a chance to catch up
+ try:
+ util.udevadm_settle()
+ except subp.ProcessExecutionError:
+ pass
+ known_macs = net.get_interfaces_by_mac()
+ if mac not in known_macs:
+ raise ValueError("Unable to find a system nic for %s" % d)
d["name"] = known_macs[mac]
for cfg, key, fmt, targets in link_updates:
--- tests/unittests/sources/test_configdrive.py.orig
+++ tests/unittests/sources/test_configdrive.py
@@ -389,6 +389,7 @@ class TestConfigDriveDataSource(CiTestCa
M_PATH + "util.find_devs_with", "m_find_devs_with", return_value=[]
)
self.tmp = self.tmp_dir()
+ self.allowed_subp = True
def test_ec2_metadata(self):
populate_dir(self.tmp, CFG_DRIVE_FILES_V2)
@@ -869,6 +870,7 @@ class TestConvertNetworkData(CiTestCase)
def setUp(self):
super(TestConvertNetworkData, self).setUp()
self.tmp = self.tmp_dir()
+ self.allowed_subp = True
def _getnames_in_config(self, ncfg):
return set(

View File

@ -1,24 +1,3 @@
-------------------------------------------------------------------
Tue Feb 4 16:44:12 UTC 2025 - Robert Schweikert <rjschwei@suse.com>
- Add cloud-init-direxist.patch (bsc#1236720)
+ Make sure the directory exists, if not create it, before writing in that
location.
-------------------------------------------------------------------
Mon Jan 20 14:21:55 UTC 2025 - Daniel Garcia <daniel.garcia@suse.com>
- Support python 3.13 (bsc#1233649):
+ pep-594-drop-pipes.patch, gh#canonical/cloud-init#4392
+ cloud-init-fix-python313.patch, gh#canonical/cloud-init#4669
+ cloud-init-dont-assume-ordering-of-ThreadPoolExecutor.patch gh#canonical/cloud-init#5052
-------------------------------------------------------------------
Mon Jan 6 13:17:05 UTC 2025 - Robert Schweikert <rjschwei@suse.com>
- Add cloud-init-wait-for-net.patch (bsc#1227237)
+ Wait for udev once if we cannot find the expected MAC
-------------------------------------------------------------------
Fri Jun 14 10:34:54 UTC 2024 - Markéta Machová <mmachova@suse.com>
@ -28,7 +7,7 @@ Fri Jun 14 10:34:54 UTC 2024 - Markéta Machová <mmachova@suse.com>
Mon Jun 3 19:53:46 UTC 2024 - Robert Schweikert <rjschwei@suse.com>
- Add cloud-init-skip-rename.patch (bsc#1219680)
+ Brute force approach to skip renames if the device is already present
+ Brute force appraoch to skip renames if the device is already present
-------------------------------------------------------------------
Mon Apr 29 21:49:48 UTC 2024 - Robert Schweikert <rjschwei@suse.com>

View File

@ -53,16 +53,6 @@ Patch13: cloud-init-no-nmcfg-needed.patch
Patch14: cloud-init-usr-sudoers.patch
# FIXME https://github.com/canonical/cloud-init/issues/5075
Patch15: cloud-init-skip-rename.patch
# FIXME https://github.com/canonical/cloud-init/pull/5947
Patch16: cloud-init-wait-for-net.patch
# FIXME https://github.com/canonical/cloud-init/pull/4392
Patch17: pep-594-drop-pipes.patch
# FIXME https://github.com/canonical/cloud-init/pull/4669
Patch18: cloud-init-fix-python313.patch
# FIXME https://github.com/canonical/cloud-init/pull/5052
Patch19: cloud-init-dont-assume-ordering-of-ThreadPoolExecutor.patch
# FIXME https://github.com/canonical/cloud-init/pull/4938
Patch20: cloud-init-direxist.patch
BuildRequires: fdupes
BuildRequires: filesystem
# pkg-config is needed to find correct systemd unit dir
@ -176,11 +166,6 @@ Documentation and examples for cloud-init tools
%patch -P 13
%patch -P 14
%patch -P 15
%patch -P 16
%patch -p1 -P 17
%patch -p1 -P 18
%patch -p1 -P 19
%patch -P 20
# patch in the full version to version.py
version_pys=$(find . -name version.py -type f)

View File

@ -1,63 +0,0 @@
From c76f9eb0df30ab7c288e5050ed1df85d132c0202 Mon Sep 17 00:00:00 2001
From: Chad Smith <chad.smith@canonical.com>
Date: Mon, 28 Aug 2023 10:22:04 -0600
Subject: [PATCH] pep-594: drop deprecated pipes module import
python3.11 will deprecated pipes module 3.13 will drop it from main.
cloud-init only used the undocumented pipes.quote function,
which is actually only wrapper around shlex.quote[1].
Use shlex.quote instead.
[1] https://github.com/python/cpython/blob/3.11/Lib/pipes.py#L64-L66
---
cloudinit/distros/parsers/sys_conf.py | 6 +++---
tests/unittests/distros/test_sysconfig.py | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/cloudinit/distros/parsers/sys_conf.py b/cloudinit/distros/parsers/sys_conf.py
index cb6e583e789..1d519ce4ef7 100644
--- a/cloudinit/distros/parsers/sys_conf.py
+++ b/cloudinit/distros/parsers/sys_conf.py
@@ -4,8 +4,8 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
-import pipes
import re
+import shlex
from io import StringIO
# This library is used to parse/write
@@ -82,7 +82,7 @@ def _quote(self, value, multiline=False):
if re.search(r"[\t\r\n ]", value):
if _contains_shell_variable(value):
# If it contains shell variables then we likely want to
- # leave it alone since the pipes.quote function likes
+ # leave it alone since the shlex.quote function likes
# to use single quotes which won't get expanded...
if re.search(r"[\n\"']", value):
quot_func = (
@@ -93,7 +93,7 @@ def _quote(self, value, multiline=False):
lambda x: self._get_single_quote(x) % x
) # noqa: E731
else:
- quot_func = pipes.quote
+ quot_func = shlex.quote
if not quot_func:
return value
return quot_func(value)
diff --git a/tests/unittests/distros/test_sysconfig.py b/tests/unittests/distros/test_sysconfig.py
index 9c3a2018edf..9f8d0cc8003 100644
--- a/tests/unittests/distros/test_sysconfig.py
+++ b/tests/unittests/distros/test_sysconfig.py
@@ -65,7 +65,7 @@ def test_parse_adjust(self):
conf["IPV6TO4_ROUTING"] = "blah \tblah"
contents2 = str(conf).strip()
# Should be requoted due to whitespace
- self.assertRegex(contents2, r"IPV6TO4_ROUTING=[\']blah\s+blah[\']")
+ self.assertRegex(contents2, r"IPV6TO4_ROUTING='blah\s+blah'")
def test_parse_no_adjust_shell(self):
conf = SysConf("".splitlines())