File: 0001-config-Support-APT-automated-mirror-selection.patch

package info (click to toggle)
cloud-init 22.4.2-1%2Bdeb12u3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 9,088 kB
  • sloc: python: 108,898; sh: 4,091; makefile: 147; xml: 22
file content (142 lines) | stat: -rw-r--r-- 6,074 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From 8dffe8af24604e1949cc991c1db181a69695d945 Mon Sep 17 00:00:00 2001
From: Bastian Blank <waldi@debian.org>
Date: Tue, 16 Aug 2022 15:45:11 +0200
Subject: [PATCH] config: Support APT automated mirror selection
Forwarded: https://github.com/canonical/cloud-init/pull/1670

---
 cloudinit/config/cc_apt_configure.py          | 22 +++++-
 .../schemas/schema-cloud-config-v1.json       |  5 ++
 .../test_apt_configure_mirrorlists_v3.py      | 68 +++++++++++++++++++
 3 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 tests/unittests/config/test_apt_configure_mirrorlists_v3.py

Index: cloud-init/cloudinit/config/cc_apt_configure.py
===================================================================
--- cloud-init.orig/cloudinit/config/cc_apt_configure.py
+++ cloud-init/cloudinit/config/cc_apt_configure.py
@@ -220,7 +220,10 @@ def apply_apt(cfg, cloud, target):
     mirrors = find_apt_mirror_info(cfg, cloud, arch=arch)
     LOG.debug("Apt Mirror info: %s", mirrors)
 
-    if util.is_false(cfg.get("preserve_sources_list", False)):
+    if util.is_true(cfg.get("generate_mirrorlists", False)):
+        generate_mirrorlists(cfg, mirrors, cloud)
+
+    elif util.is_false(cfg.get("preserve_sources_list", False)):
         add_mirror_keys(cfg, target)
         generate_sources_list(cfg, release, mirrors, cloud)
         rename_apt_lists(mirrors, target, arch)
@@ -485,6 +488,23 @@ def generate_sources_list(cfg, release,
     util.write_file(aptsrc, disabled, mode=0o644)
 
 
+def generate_mirrorlists(cfg, mirrors, cloud):
+    """generate_mirrorlists
+    create one file for every mirror for apt-transport-mirror(1)"""
+    aptmir = pathlib.Path("/etc/apt/mirrors")
+    util.ensure_dir(str(aptmir))
+    util.write_file(
+        str(aptmir / f"{cloud.distro.name}.list"),
+        f"{mirrors['PRIMARY']}\n",
+        mode=0o644,
+    )
+    util.write_file(
+        str(aptmir / f"{cloud.distro.name}-security.list"),
+        f"{mirrors['SECURITY']}\n",
+        mode=0o644,
+    )
+
+
 def add_apt_key_raw(key, file_name, hardened=False, target=None):
     """
     actual adding of a key as defined in key argument
Index: cloud-init/cloudinit/config/schemas/schema-cloud-config-v1.json
===================================================================
--- cloud-init.orig/cloudinit/config/schemas/schema-cloud-config-v1.json
+++ cloud-init/cloudinit/config/schemas/schema-cloud-config-v1.json
@@ -749,6 +749,11 @@
               "default": false,
               "description": "By default, cloud-init will generate a new sources list in ``/etc/apt/sources.list.d`` based on any changes specified in cloud config. To disable this behavior and preserve the sources list from the pristine image, set ``preserve_sources_list`` to ``true``.\n\nThe ``preserve_sources_list`` option overrides all other config keys that would alter ``sources.list`` or ``sources.list.d``, **except** for additional sources to be added to ``sources.list.d``."
             },
+            "generate_mirrorlists": {
+              "type": "boolean",
+              "default": false,
+              "description": "Write lists for APT automated mirror selection (``apt-transport-mirror(1)``). It will write separate lists for both the PRIMARY and SECURITY mirror into ``/etc/apt/mirrors/${DIST}.list`` and ``/etc/apt/mirrors/${DIST}-security.list``.  Those can then be used in the APT source.list as ``mirror+file:///etc/apt/mirrors/${DIST}.list``. No ``/etc/apt/sources.list`` will be writte in this case."
+            },
             "disable_suites": {
               "type": "array",
               "items": {
Index: cloud-init/tests/unittests/config/test_apt_configure_mirrorlists_v3.py
===================================================================
--- /dev/null
+++ cloud-init/tests/unittests/config/test_apt_configure_mirrorlists_v3.py
@@ -0,0 +1,68 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
+""" test_apt_custom_mirrorlists
+Test creation of mirrorlists
+"""
+import logging
+import shutil
+import tempfile
+from contextlib import ExitStack
+from unittest import mock
+from unittest.mock import call
+
+from cloudinit import subp, util
+from cloudinit.config import cc_apt_configure
+from tests.unittests import helpers as t_help
+from tests.unittests.util import get_cloud
+
+LOG = logging.getLogger(__name__)
+
+
+class TestAptSourceConfigMirrorlists(t_help.FilesystemMockingTestCase):
+    """TestAptSourceConfigMirrorlists - Class to test mirrorlists rendering"""
+
+    def setUp(self):
+        super().setUp()
+        self.subp = subp.subp
+        self.new_root = tempfile.mkdtemp()
+        self.addCleanup(shutil.rmtree, self.new_root)
+
+        rpatcher = mock.patch("cloudinit.util.lsb_release")
+        get_rel = rpatcher.start()
+        get_rel.return_value = {"codename": "fakerel"}
+        self.addCleanup(rpatcher.stop)
+        apatcher = mock.patch("cloudinit.util.get_dpkg_architecture")
+        get_arch = apatcher.start()
+        get_arch.return_value = "amd64"
+        self.addCleanup(apatcher.stop)
+
+    def test_apt_v3_mirrors_list(self):
+        """test_apt_v3_mirrors_list"""
+        cfg = {"apt": {"generate_mirrorlists": True}}
+
+        mycloud = get_cloud("ubuntu")
+
+        with ExitStack() as stack:
+            mock_writefile = stack.enter_context(
+                mock.patch.object(util, "write_file")
+            )
+            stack.enter_context(mock.patch.object(util, "ensure_dir"))
+            cc_apt_configure.handle("test", cfg, mycloud, LOG, None)
+
+        mock_writefile.assert_has_calls(
+            [
+                call(
+                    "/etc/apt/mirrors/ubuntu.list",
+                    "http://archive.ubuntu.com/ubuntu/\n",
+                    mode=0o644,
+                ),
+                call(
+                    "/etc/apt/mirrors/ubuntu-security.list",
+                    "http://security.ubuntu.com/ubuntu/\n",
+                    mode=0o644,
+                ),
+            ]
+        )
+
+
+# vi: ts=4 expandtab