diff options
author | Minghe Ren <mingheren@microsoft.com> | 2022-11-07 15:01:57 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-07 17:01:57 -0600 |
commit | 699b6a05e20253b3666eb51eb77654741aa7c37d (patch) | |
tree | d9ea336511a531f1f44c56286bccad1364997bb0 | |
parent | e9fccdb7fe66696ca2df455ecdeea177fa70bfc3 (diff) | |
download | cloud-init-git-699b6a05e20253b3666eb51eb77654741aa7c37d.tar.gz |
add mariner support (#1780)
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | cloudinit/config/cc_ntp.py | 10 | ||||
-rw-r--r-- | cloudinit/config/cc_resolv_conf.py | 10 | ||||
-rw-r--r-- | cloudinit/config/cc_yum_add_repo.py | 1 | ||||
-rw-r--r-- | cloudinit/distros/__init__.py | 1 | ||||
-rw-r--r-- | cloudinit/distros/mariner.py | 55 | ||||
-rw-r--r-- | cloudinit/util.py | 1 | ||||
-rw-r--r-- | config/cloud.cfg.tmpl | 22 | ||||
-rw-r--r-- | templates/host.mariner.tmpl | 22 | ||||
-rw-r--r-- | tests/unittests/distros/test_mariner.py | 25 | ||||
-rw-r--r-- | tests/unittests/distros/test_netconfig.py | 125 | ||||
-rw-r--r-- | tests/unittests/test_cli.py | 3 | ||||
-rw-r--r-- | tests/unittests/test_render_cloudcfg.py | 1 | ||||
-rw-r--r-- | tests/unittests/test_util.py | 23 | ||||
-rw-r--r-- | tools/.github-cla-signers | 1 | ||||
-rwxr-xr-x | tools/render-cloudcfg | 1 |
16 files changed, 297 insertions, 6 deletions
@@ -39,7 +39,7 @@ get in contact with that distribution and send them our way! | Supported OSes | Supported Public Clouds | Supported Private Clouds | |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- | --- | -| Alpine Linux<br />Arch Linux<br />Container-Optimized OS<br />Debian<br />DragonFlyBSD<br />Fedora<br />FreeBSD<br />Gentoo Linux<br />NetBSD<br />OpenBSD<br />openEuler<br />OpenMandriva<br />RHEL/CentOS/AlmaLinux/Rocky/PhotonOS/Virtuozzo/EuroLinux/CloudLinux/MIRACLE LINUX<br />SLES/openSUSE<br />Ubuntu<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | Amazon Web Services<br />Microsoft Azure<br />Google Cloud Platform<br />Oracle Cloud Infrastructure<br />Softlayer<br />Rackspace Public Cloud<br />IBM Cloud<br />DigitalOcean<br />Bigstep<br />Hetzner<br />Joyent<br />CloudSigma<br />Alibaba Cloud<br />Huawei Cloud<br />OVH<br />OpenNebula<br />Exoscale<br />Scaleway<br />CloudStack<br />AltCloud<br />SmartOS<br />HyperOne<br />Vultr<br />Rootbox<br /> | Bare metal installs<br />OpenStack<br />LXD<br />KVM<br />Metal-as-a-Service (MAAS)<br />VMware<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />| +| Alpine Linux<br />Arch Linux<br />Container-Optimized OS<br />Debian<br />DragonFlyBSD<br />Fedora<br />FreeBSD<br />Gentoo Linux<br />NetBSD<br />OpenBSD<br />openEuler<br />OpenMandriva<br />RHEL/CentOS/AlmaLinux/Rocky/PhotonOS/Virtuozzo/EuroLinux/CloudLinux/MIRACLE LINUX/MarinerOS<br />SLES/openSUSE<br />Ubuntu<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | Amazon Web Services<br />Microsoft Azure<br />Google Cloud Platform<br />Oracle Cloud Infrastructure<br />Softlayer<br />Rackspace Public Cloud<br />IBM Cloud<br />DigitalOcean<br />Bigstep<br />Hetzner<br />Joyent<br />CloudSigma<br />Alibaba Cloud<br />Huawei Cloud<br />OVH<br />OpenNebula<br />Exoscale<br />Scaleway<br />CloudStack<br />AltCloud<br />SmartOS<br />HyperOne<br />Vultr<br />Rootbox<br /> | Bare metal installs<br />OpenStack<br />LXD<br />KVM<br />Metal-as-a-Service (MAAS)<br />VMware<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />| ## To start developing cloud-init diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py index b1da3761..8ecc4eb8 100644 --- a/cloudinit/config/cc_ntp.py +++ b/cloudinit/config/cc_ntp.py @@ -33,6 +33,7 @@ distros = [ "eurolinux", "fedora", "freebsd", + "mariner", "miraclelinux", "openbsd", "openEuler", @@ -141,6 +142,15 @@ DISTRO_CLIENT_CONFIG = { "template_name": "ntpd.conf.openbsd", }, }, + "mariner": { + "chrony": { + "service_name": "chronyd", + }, + "systemd-timesyncd": { + "check_exe": "/usr/lib/systemd/systemd-timesyncd", + "confpath": "/etc/systemd/timesyncd.conf", + }, + }, "openbsd": { "openntpd": {}, }, diff --git a/cloudinit/config/cc_resolv_conf.py b/cloudinit/config/cc_resolv_conf.py index 3c9ca22e..8dbed71e 100644 --- a/cloudinit/config/cc_resolv_conf.py +++ b/cloudinit/config/cc_resolv_conf.py @@ -55,7 +55,15 @@ meta: MetaSchema = { "name": "Resolv Conf", "title": "Configure resolv.conf", "description": MODULE_DESCRIPTION, - "distros": ["alpine", "fedora", "opensuse", "photon", "rhel", "sles"], + "distros": [ + "alpine", + "fedora", + "mariner", + "opensuse", + "photon", + "rhel", + "sles", + ], "frequency": PER_INSTANCE, "examples": [ dedent( diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py index d570be69..cf81b844 100644 --- a/cloudinit/config/cc_yum_add_repo.py +++ b/cloudinit/config/cc_yum_add_repo.py @@ -31,6 +31,7 @@ distros = [ "cloudlinux", "eurolinux", "fedora", + "mariner", "openEuler", "openmandriva", "photon", diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index 0dd8eb18..1d47c071 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -55,6 +55,7 @@ OSFAMILIES = { "cloudlinux", "eurolinux", "fedora", + "mariner", "miraclelinux", "openEuler", "openmandriva", diff --git a/cloudinit/distros/mariner.py b/cloudinit/distros/mariner.py new file mode 100644 index 00000000..41b0dc75 --- /dev/null +++ b/cloudinit/distros/mariner.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# vi: ts=4 expandtab +# +# Copyright (C) 2021 VMware Inc. +# +# This file is part of cloud-init. See LICENSE file for license information. + +from cloudinit import helpers +from cloudinit import log as logging +from cloudinit.distros import photon + +LOG = logging.getLogger(__name__) + +NETWORK_FILE_HEADER = """\ +# This file is generated from information provided by the datasource. Changes +# to it will not persist across an instance reboot. To disable cloud-init's +# network configuration capabilities, write a file +# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following: +# network: {config: disabled} +""" + + +class Distro(photon.Distro): + systemd_hostname_conf_fn = "/etc/hostname" + network_conf_dir = "/etc/systemd/network/" + systemd_locale_conf_fn = "/etc/locale.conf" + resolve_conf_fn = "/etc/systemd/resolved.conf" + + network_conf_fn = {"netplan": "/etc/netplan/50-cloud-init.yaml"} + renderer_configs = { + "networkd": { + "resolv_conf_fn": resolve_conf_fn, + "network_conf_dir": network_conf_dir, + }, + "netplan": { + "netplan_path": network_conf_fn["netplan"], + "netplan_header": NETWORK_FILE_HEADER, + "postcmds": "True", + }, + } + + # Should be fqdn if we can use it + prefer_fqdn = True + + def __init__(self, name, cfg, paths): + photon.Distro.__init__(self, name, cfg, paths) + # This will be used to restrict certain + # calls from repeatly happening (when they + # should only happen say once per instance...) + self._runner = helpers.Runners(paths) + self.osfamily = "mariner" + self.init_cmd = ["systemctl"] + + def _get_localhost_ip(self): + return "127.0.0.1" diff --git a/cloudinit/util.py b/cloudinit/util.py index ce257c85..1fd2c81b 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -636,6 +636,7 @@ def _get_variant(info): "debian", "eurolinux", "fedora", + "mariner", "miraclelinux", "openeuler", "openmandriva", diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index 94561f42..0f234a7d 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -133,8 +133,8 @@ cloud_config_modules: {% if is_rhel %} - rh_subscription {% endif %} -{% if variant in ["fedora", "openmandriva", "photon"] or is_rhel %} -{% if variant not in ["photon"] %} +{% if variant in ["fedora", "mariner", "openmandriva", "photon"] or is_rhel %} +{% if variant not in ["mariner", "photon"] %} - spacewalk {% endif %} - yum-add-repo @@ -198,7 +198,7 @@ cloud_final_modules: system_info: # This will affect which distro class gets used {% if variant in ["almalinux", "alpine", "amazon", "arch", "cloudlinux", "debian", - "eurolinux", "fedora", "freebsd", "gentoo", "netbsd", "miraclelinux", "openbsd", "openEuler", + "eurolinux", "fedora", "freebsd", "gentoo", "netbsd", "mariner", "miraclelinux", "openbsd", "openEuler", "openmandriva", "photon", "rocky", "suse", "ubuntu", "virtuozzo"] or is_rhel %} distro: {{ variant }} {% elif variant in ["dragonfly"] %} @@ -356,6 +356,22 @@ system_info: # In Photon, we have default network settings, hence if network settings are # not explicitly given in metadata, don't use fallback network config. disable_fallback_netcfg: true +{% elif variant in ["mariner"] %} + default_user: + name: mariner + lock_passwd: True + gecos: MarinerOS + groups: [wheel] + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + shell: /bin/bash + # Other config here will be given to the distro class and/or path classes + paths: + cloud_dir: /var/lib/cloud/ + templates_dir: /etc/cloud/templates/ + network: + renderers: ['networkd'] + + ssh_svcname: sshd {% endif %} {% if variant in ["freebsd", "netbsd", "openbsd"] %} network: diff --git a/templates/host.mariner.tmpl b/templates/host.mariner.tmpl new file mode 100644 index 00000000..7787c367 --- /dev/null +++ b/templates/host.mariner.tmpl @@ -0,0 +1,22 @@ ++## template:jinja ++{# ++This file /etc/cloud/templates/hosts.mariner.tmpl is only utilized ++if enabled in cloud-config. Specifically, in order to enable it ++you need to add the following to config: ++ manage_etc_hosts: True ++-#} ++# Your system has configured 'manage_etc_hosts' as True. ++# As a result, if you wish for changes to this file to persist ++# then you will need to either ++# a.) make changes to the master file in /etc/cloud/templates/hosts.mariner.tmpl ++# b.) change or remove the value of 'manage_etc_hosts' in ++# /etc/cloud/cloud.cfg or cloud-config from user-data ++# ++# The following lines are desirable for IPv4 capable hosts ++127.0.0.1 {{fqdn}} {{hostname}} ++127.0.0.1 localhost.localdomain localhost ++127.0.0.1 localhost4.localdomain4 localhost4 ++ ++# The following lines are desirable for IPv6 capable hosts ++::1 {{fqdn}} {{hostname}} ++::1 localhost6.localdomain6 localhost6 diff --git a/tests/unittests/distros/test_mariner.py b/tests/unittests/distros/test_mariner.py new file mode 100644 index 00000000..57f8d498 --- /dev/null +++ b/tests/unittests/distros/test_mariner.py @@ -0,0 +1,25 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +from tests.unittests.helpers import CiTestCase + +from . import _get_distro + +SYSTEM_INFO = { + "paths": { + "cloud_dir": "/var/lib/cloud/", + "templates_dir": "/etc/cloud/templates/", + }, + "network": {"renderers": "networkd"}, +} + + +class TestMariner(CiTestCase): + with_logs = True + distro = _get_distro("mariner", SYSTEM_INFO) + expected_log_line = "Rely on MarinerOS default network config" + + def test_network_renderer(self): + self.assertEqual(self.distro._cfg["network"]["renderers"], "networkd") + + def test_get_distro(self): + self.assertEqual(self.distro.osfamily, "mariner") diff --git a/tests/unittests/distros/test_netconfig.py b/tests/unittests/distros/test_netconfig.py index 85d17487..f17a5d21 100644 --- a/tests/unittests/distros/test_netconfig.py +++ b/tests/unittests/distros/test_netconfig.py @@ -1119,6 +1119,131 @@ class TestNetCfgDistroPhoton(TestNetCfgDistroBase): ) +class TestNetCfgDistroMariner(TestNetCfgDistroBase): + def setUp(self): + super(TestNetCfgDistroMariner, self).setUp() + self.distro = self._get_distro("mariner", renderers=["networkd"]) + + def create_conf_dict(self, contents): + content_dict = {} + for line in contents: + if line: + line = line.strip() + if line and re.search(r"^\[(.+)\]$", line): + content_dict[line] = [] + key = line + elif line: + assert key + content_dict[key].append(line) + + return content_dict + + def compare_dicts(self, actual, expected): + for k, v in actual.items(): + self.assertEqual(sorted(expected[k]), sorted(v)) + + def _apply_and_verify( + self, apply_fn, config, expected_cfgs=None, bringup=False + ): + if not expected_cfgs: + raise ValueError("expected_cfg must not be None") + + tmpd = None + with mock.patch("cloudinit.net.networkd.available") as m_avail: + m_avail.return_value = True + with self.reRooted(tmpd) as tmpd: + apply_fn(config, bringup) + + results = dir2dict(tmpd) + for cfgpath, expected in expected_cfgs.items(): + actual = self.create_conf_dict(results[cfgpath].splitlines()) + self.compare_dicts(actual, expected) + self.assertEqual(0o644, get_mode(cfgpath, tmpd)) + + def nwk_file_path(self, ifname): + return "/etc/systemd/network/10-cloud-init-%s.network" % ifname + + def net_cfg_1(self, ifname): + ret = ( + """\ + [Match] + Name=%s + [Network] + DHCP=no + [Address] + Address=192.168.1.5/24 + [Route] + Gateway=192.168.1.254""" + % ifname + ) + return ret + + def net_cfg_2(self, ifname): + ret = ( + """\ + [Match] + Name=%s + [Network] + DHCP=ipv4""" + % ifname + ) + return ret + + def test_mariner_network_config_v1(self): + tmp = self.net_cfg_1("eth0").splitlines() + expected_eth0 = self.create_conf_dict(tmp) + + tmp = self.net_cfg_2("eth1").splitlines() + expected_eth1 = self.create_conf_dict(tmp) + + expected_cfgs = { + self.nwk_file_path("eth0"): expected_eth0, + self.nwk_file_path("eth1"): expected_eth1, + } + + self._apply_and_verify( + self.distro.apply_network_config, V1_NET_CFG, expected_cfgs.copy() + ) + + def test_mariner_network_config_v2(self): + tmp = self.net_cfg_1("eth7").splitlines() + expected_eth7 = self.create_conf_dict(tmp) + + tmp = self.net_cfg_2("eth9").splitlines() + expected_eth9 = self.create_conf_dict(tmp) + + expected_cfgs = { + self.nwk_file_path("eth7"): expected_eth7, + self.nwk_file_path("eth9"): expected_eth9, + } + + self._apply_and_verify( + self.distro.apply_network_config, V2_NET_CFG, expected_cfgs.copy() + ) + + def test_mariner_network_config_v1_with_duplicates(self): + expected = """\ + [Match] + Name=eth0 + [Network] + DHCP=no + DNS=1.2.3.4 + Domains=test.com + [Address] + Address=192.168.0.102/24""" + + net_cfg = safeyaml.load(V1_NET_CFG_WITH_DUPS) + + expected = self.create_conf_dict(expected.splitlines()) + expected_cfgs = { + self.nwk_file_path("eth0"): expected, + } + + self._apply_and_verify( + self.distro.apply_network_config, net_cfg, expected_cfgs.copy() + ) + + def get_mode(path, target=None): return os.stat(subp.target_path(target, path)).st_mode & 0o777 diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py index c75ee015..dd85a1c7 100644 --- a/tests/unittests/test_cli.py +++ b/tests/unittests/test_cli.py @@ -248,7 +248,8 @@ class TestCLI: "**Supported distros:** all", "**Supported distros:** almalinux, alpine, centos, " "cloudlinux, cos, debian, eurolinux, fedora, freebsd, " - "miraclelinux, openbsd, openEuler, openmandriva, " + "mariner, miraclelinux, " + "openbsd, openEuler, openmandriva, " "opensuse, photon, rhel, rocky, sles, ubuntu, virtuozzo", "**Config schema**:\n **resize_rootfs:** " "(``true``/``false``/``noblock``)", diff --git a/tests/unittests/test_render_cloudcfg.py b/tests/unittests/test_render_cloudcfg.py index 1a6e2715..d3aeb1b7 100644 --- a/tests/unittests/test_render_cloudcfg.py +++ b/tests/unittests/test_render_cloudcfg.py @@ -17,6 +17,7 @@ DISTRO_VARIANTS = [ "fedora", "freebsd", "gentoo", + "mariner", "netbsd", "openbsd", "photon", diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index 103bb9c0..6dc827c1 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -353,6 +353,20 @@ OS_RELEASE_COS = dedent( """ ) +OS_RELEASE_MARINER = dedent( + """\ + NAME="CBL-Mariner" + VERSION="2.0.20221004" + ID=mariner + VERSION_ID=2.0 + PRETTY_NAME="CBL-Mariner/Linux" + ANSI_COLOR="1;34" + HOME_URL="https://aka.ms/cbl-mariner" + BUG_REPORT_URL="https://aka.ms/cbl-mariner" + SUPPORT_URL="https://aka.ms/cbl-mariner" +""" +) + @pytest.mark.usefixtures("fake_filesystem") class TestUtil: @@ -1139,6 +1153,14 @@ class TestGetLinuxDistro(CiTestCase): dist = util.get_linux_distro() self.assertEqual(("photon", "4.0", "VMware Photon OS/Linux"), dist) + @mock.patch("cloudinit.util.load_file") + def test_get_linux_mariner_os_release(self, m_os_release, m_path_exists): + """Verify we get the correct name and machine arch on MarinerOS""" + m_os_release.return_value = OS_RELEASE_MARINER + m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists + dist = util.get_linux_distro() + self.assertEqual(("mariner", "2.0", ""), dist) + @mock.patch(M_PATH + "load_file") def test_get_linux_openmandriva(self, m_os_release, m_path_exists): """Verify we get the correct name and machine arch on OpenMandriva""" @@ -1205,6 +1227,7 @@ class TestGetVariant: ({"system": "linux", "dist": ("debian",)}, "debian"), ({"system": "linux", "dist": ("eurolinux",)}, "eurolinux"), ({"system": "linux", "dist": ("fedora",)}, "fedora"), + ({"system": "linux", "dist": ("mariner",)}, "mariner"), ({"system": "linux", "dist": ("openEuler",)}, "openeuler"), ({"system": "linux", "dist": ("photon",)}, "photon"), ({"system": "linux", "dist": ("rhel",)}, "rhel"), diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers index db2ec796..2826b9d8 100644 --- a/tools/.github-cla-signers +++ b/tools/.github-cla-signers @@ -94,6 +94,7 @@ RedKrieg renanrodrigo rhansen riedel +rmhsawyer rongz609 s-makin SadeghHayeri diff --git a/tools/render-cloudcfg b/tools/render-cloudcfg index eae83217..c04daead 100755 --- a/tools/render-cloudcfg +++ b/tools/render-cloudcfg @@ -21,6 +21,7 @@ def main(): "fedora", "freebsd", "gentoo", + "mariner", "miraclelinux", "netbsd", "openbsd", |