From e591185d8393bfbff2b09c20b9dad415a68973db Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2026 16:07:26 -0400 Subject: [PATCH 01/11] fix(azurelinux): remove some config excluded only from azurelinux (#6874) There is no need to exclude these config selections from azurelinux, so this simplifies the config template. --- config/cloud.cfg.tmpl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index 762d1502a52..3ac2f5879e9 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -178,9 +178,7 @@ cloud_config_modules: {% if variant == "raspberry-pi-os" %} - raspberry_pi {% endif %} -{% if variant not in ["azurelinux"] %} - disable_ec2_metadata -{% endif %} - runcmd {% if variant in ["debian", "ubuntu", "unknown"] %} - byobu @@ -198,17 +196,13 @@ cloud_final_modules: - ubuntu_drivers {% endif %} - write_files_deferred -{% if variant not in ["azurelinux"] %} - puppet - chef -{% endif %} - ansible -{% if variant not in ["azurelinux"] %} - mcollective - salt_minion {% if variant not in ["alpine"] %} - reset_rmc -{% endif %} {% endif %} - scripts_vendor - scripts_per_once From 8ae74678152957e23fda2c670d0f7ec29ec2c5a2 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2026 16:10:43 -0400 Subject: [PATCH 02/11] fix(azurelinux): remove custom azurelinux group config (#6874) Azure Linux 4 is now Fedora-based; this removes the custom group config, allowing azurelinux to use the fallback group list, as Fedora does. --- config/cloud.cfg.tmpl | 1 - 1 file changed, 1 deletion(-) diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index 3ac2f5879e9..b5b6b3c4eab 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -13,7 +13,6 @@ "raspberry-pi-os": "Raspberry Pi OS", "ubuntu": "Ubuntu", "unknown": "Ubuntu"}) %} {% set groups = ({"alpine": "adm, wheel", "aosc": "wheel", "arch": "wheel, users", - "azurelinux": "wheel", "debian": "adm, audio, cdrom, dialout, dip, floppy, netdev, plugdev, sudo, video", "gentoo": "users, wheel", "mariner": "wheel", "photon": "wheel", From 314531fa3c760b86138be26bd7ad51cb03a94f42 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2026 16:12:40 -0400 Subject: [PATCH 03/11] fix(azurelinux): set azurelinux default username to azureuser (#6874) The Azure cloud generally documents the default username as "azureuser", so this sets the default to match. --- config/cloud.cfg.tmpl | 2 +- tests/unittests/test_render_template.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index b5b6b3c4eab..02ae6c87d59 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -24,7 +24,7 @@ {% set shells = ({"alpine": "/bin/ash", "dragonfly": "/bin/sh", "freebsd": "/bin/tcsh", "netbsd": "/bin/sh", "openbsd": "/bin/ksh"}) %} -{% set usernames = ({"amazon": "ec2-user", "centos": "cloud-user", +{% set usernames = ({"amazon": "ec2-user", "azurelinux": "azureuser", "centos": "cloud-user", "openmandriva": "omv", "raspberry-pi-os": "pi", "rhel": "cloud-user", "unknown": "ubuntu"}) %} diff --git a/tests/unittests/test_render_template.py b/tests/unittests/test_render_template.py index 7f8fc944429..32926da1dd2 100644 --- a/tests/unittests/test_render_template.py +++ b/tests/unittests/test_render_template.py @@ -93,6 +93,7 @@ def test_variant_sets_default_user_in_cloud_cfg(self, variant, tmpdir): default_user_exceptions = { "amazon": "ec2-user", + "azurelinux": "azureuser", "rhel": "cloud-user", "centos": "cloud-user", "raspberry-pi-os": "pi", From 8771a379e59e9fa576a43952447e4e50322c173d Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2026 16:31:16 -0400 Subject: [PATCH 04/11] fix(azurelinux): include azurelinux in distro group with fedora (#6874) Azure Linux 4 is Fedora-based, so include it in the same group for the mount_default_fields and ssh_pwauth settings. --- config/cloud.cfg.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index 02ae6c87d59..f5b055bcd6a 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -60,7 +60,7 @@ disable_root: false disable_root: true {% endif %} -{%- if variant in ["alpine", "amazon", "fedora", "OpenCloudOS", "openeuler", +{%- if variant in ["alpine", "amazon", "azurelinux", "fedora", "OpenCloudOS", "openeuler", "openmandriva", "photon", "TencentOS"] or is_rhel %} {% if is_rhel %} From 1fd06a6ef65648aad18309537ff7953e763c27d9 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Thu, 7 May 2026 16:32:40 -0400 Subject: [PATCH 05/11] fix(azurelinux): Set specific list of network renderers for azurelinux (#6874) Azure Linux 4 is no longer in the same group as mariner or photon; the available network renderers are netplan, systemd-networkd, and NetworkManager. --- config/cloud.cfg.tmpl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index f5b055bcd6a..3926ea8b4d5 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -280,6 +280,9 @@ system_info: {% if variant == "alpine" %} network: renderers: ['eni'] +{% elif variant == "azurelinux" %} + network: + renderers: ['netplan', 'networkd', 'network-manager'] {% elif variant == "debian" %} network: renderers: ['netplan', 'eni', 'networkd'] @@ -293,7 +296,7 @@ system_info: {% elif variant in ["freebsd", "netbsd", "openbsd"] %} network: renderers: ['{{ variant }}'] -{% elif variant in ["azurelinux", "mariner", "photon"] %} +{% elif variant in ["mariner", "photon"] %} network: renderers: ['networkd'] {% elif variant == "openmandriva" %} From 9a8656669ec483ce34bb26b1d2817c96bee261ae Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 8 May 2026 12:41:30 -0400 Subject: [PATCH 06/11] fix(azurelinux): use libexec path for ds-identify (#6874) --- systemd/cloud-init-generator.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systemd/cloud-init-generator.tmpl b/systemd/cloud-init-generator.tmpl index e55ece6d276..888bad535ea 100644 --- a/systemd/cloud-init-generator.tmpl +++ b/systemd/cloud-init-generator.tmpl @@ -20,7 +20,7 @@ CLOUD_SYSTEM_TARGET="/usr/lib/systemd/system/cloud-init.target" {% else %} CLOUD_SYSTEM_TARGET="/lib/systemd/system/cloud-init.target" {% endif %} -{% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora", +{% if variant in ["almalinux", "azurelinux", "centos", "cloudlinux", "eurolinux", "fedora", "miraclelinux", "openeuler", "OpenCloudOS", "openmandriva", "rhel", "rocky", "TencentOS", "virtuozzo"] %} dsidentify="/usr/libexec/cloud-init/ds-identify" {% elif variant == "benchmark" %} From fe50391f2eebcc1e31b0b58035d181baf0f319bc Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 8 May 2026 12:53:27 -0400 Subject: [PATCH 07/11] fix(azurelinux): remove overridden package_command() method (#6874) Azure Linux 3.0 used tdnf and needed to override this method; Azure Linux 4.0 does not use tdnf and can use the inherited method. --- cloudinit/distros/azurelinux.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/cloudinit/distros/azurelinux.py b/cloudinit/distros/azurelinux.py index 591b870020e..2b7178a71f0 100644 --- a/cloudinit/distros/azurelinux.py +++ b/cloudinit/distros/azurelinux.py @@ -6,7 +6,6 @@ import logging -from cloudinit import subp, util from cloudinit.distros import rhel from cloudinit.net.netplan import CLOUDINIT_NETPLAN_FILE @@ -45,30 +44,3 @@ def __init__(self, name, cfg, paths): "postcmds": "True", }, } - - def package_command(self, command, args=None, pkgs=None): - if pkgs is None: - pkgs = [] - - if subp.which("dnf"): - LOG.debug("Using DNF for package management") - cmd = ["dnf"] - else: - LOG.debug("Using TDNF for package management") - cmd = ["tdnf"] - # Determines whether or not dnf/tdnf prompts for confirmation - # of critical actions. We don't want to prompt... - cmd.append("-y") - - if args and isinstance(args, str): - cmd.append(args) - elif args and isinstance(args, list): - cmd.extend(args) - - cmd.append(command) - - pkglist = util.expand_package_list("%s-%s", pkgs) - cmd.extend(pkglist) - - # Allow the output of this to flow outwards (ie not be captured) - subp.subp(cmd, capture=False) From 1c634786941717902342e61899c5684bc8360c6e Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 8 May 2026 12:54:42 -0400 Subject: [PATCH 08/11] fix(azurelinux): remove use_lib_exec property override (#6874) Azure Linux 3.0 used /usr/lib, while Azure Linux 4.0 inherits from Fedora and so uses /usr/libexec. --- cloudinit/distros/azurelinux.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cloudinit/distros/azurelinux.py b/cloudinit/distros/azurelinux.py index 2b7178a71f0..e3880548de8 100644 --- a/cloudinit/distros/azurelinux.py +++ b/cloudinit/distros/azurelinux.py @@ -21,8 +21,6 @@ class Distro(rhel.Distro): - usr_lib_exec = "/usr/lib" - def __init__(self, name, cfg, paths): super().__init__(name, cfg, paths) self.osfamily = "azurelinux" From 24bd380d48efc4944ddb0cbd35db089fef36bcaf Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 8 May 2026 13:17:33 -0400 Subject: [PATCH 09/11] fix(azurelinux): update systemd cloud-init-*.service templates (#6874) Add azurelinux into most fedora/rhel conditionals in the templates. --- systemd/cloud-init-local.service.tmpl | 6 +++--- systemd/cloud-init-main.service.tmpl | 6 +++--- systemd/cloud-init-network.service.tmpl | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl index e88b15ca246..ca6dbe0a159 100644 --- a/systemd/cloud-init-local.service.tmpl +++ b/systemd/cloud-init-local.service.tmpl @@ -2,14 +2,14 @@ [Unit] # https://docs.cloud-init.io/en/latest/explanation/boot.html Description=Cloud-init: Local Stage (pre-network) -{% if variant in ["almalinux", "cloudlinux", "ubuntu", "unknown", "debian", "raspberry-pi-os", "rhel"] %} +{% if variant in ["almalinux", "azurelinux", "cloudlinux", "ubuntu", "unknown", "debian", "raspberry-pi-os", "rhel"] %} DefaultDependencies=no {% endif %} Wants=network-pre.target After=hv_kvp_daemon.service Before=network-pre.target Before=shutdown.target -{% if variant in ["almalinux", "cloudlinux", "rhel"] %} +{% if variant in ["almalinux", "azurelinux", "cloudlinux", "rhel"] %} Before=firewalld.target {% endif %} {% if variant in ["ubuntu", "unknown", "debian", "raspberry-pi-os"] %} @@ -22,7 +22,7 @@ ConditionEnvironment=!KERNEL_CMDLINE=cloud-init=disabled [Service] Type=oneshot -{% if variant in ["almalinux", "cloudlinux", "rhel"] %} +{% if variant in ["almalinux", "azurelinux", "cloudlinux", "rhel"] %} ExecStartPre=/sbin/restorecon /run/cloud-init {% endif %} # This service is a shim which preserves systemd ordering while allowing a diff --git a/systemd/cloud-init-main.service.tmpl b/systemd/cloud-init-main.service.tmpl index 2ca6220c24c..a38b2e817cf 100644 --- a/systemd/cloud-init-main.service.tmpl +++ b/systemd/cloud-init-main.service.tmpl @@ -8,10 +8,10 @@ # https://www.freedesktop.org/software/systemd/man/latest/systemd-remount-fs.service.html [Unit] Description=Cloud-init: Single Process -{% if variant in ["almalinux", "cloudlinux", "ubuntu", "unknown", "debian", "raspberry-pi-os", "rhel"] %} +{% if variant in ["almalinux", "azurelinux", "cloudlinux", "ubuntu", "unknown", "debian", "raspberry-pi-os", "rhel"] %} DefaultDependencies=no {% endif %} -{% if variant in ["almalinux", "cloudlinux", "rhel"] %} +{% if variant in ["almalinux", "azurelinux", "cloudlinux", "rhel"] %} Requires=dbus.socket After=dbus.socket {% endif %} @@ -31,7 +31,7 @@ ExecStart=/usr/bin/cloud-init --all-stages KillMode=process TasksMax=infinity TimeoutStartSec=infinity -{% if variant in ["almalinux", "cloudlinux", "rhel"] %} +{% if variant in ["almalinux", "azurelinux", "cloudlinux", "rhel"] %} ExecStartPre=/sbin/restorecon /run/cloud-init {% endif %} diff --git a/systemd/cloud-init-network.service.tmpl b/systemd/cloud-init-network.service.tmpl index c284024be76..58a36f5dfe0 100644 --- a/systemd/cloud-init-network.service.tmpl +++ b/systemd/cloud-init-network.service.tmpl @@ -2,7 +2,7 @@ [Unit] # https://docs.cloud-init.io/en/latest/explanation/boot.html Description=Cloud-init: Network Stage -{% if variant not in ["almalinux", "cloudlinux", "photon", "rhel"] %} +{% if variant not in ["almalinux", "azurelinux", "cloudlinux", "photon", "rhel"] %} DefaultDependencies=no {% endif %} Wants=cloud-init-local.service @@ -15,7 +15,7 @@ After=systemd-networkd-wait-online.service {% if variant in ["ubuntu", "unknown", "debian", "raspberry-pi-os"] %} After=networking.service {% endif %} -{% if variant in ["almalinux", "centos", "cloudlinux", "eurolinux", "fedora", +{% if variant in ["almalinux", "azurelinux", "centos", "cloudlinux", "eurolinux", "fedora", "miraclelinux", "openeuler", "OpenCloudOS", "openmandriva", "rhel", "rocky", "suse", "TencentOS", "virtuozzo"] %} After=NetworkManager.service From 81001c5b2f64938288b78db99860500a35f432ea Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 8 May 2026 15:22:40 -0400 Subject: [PATCH 10/11] fix(azurelinux): update hosts.azurelinux.tmpl (#6874) Azure Linux 4.0 is Fedora-based, so update the hosts template to match the fedora/redhat template. --- templates/hosts.azurelinux.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/hosts.azurelinux.tmpl b/templates/hosts.azurelinux.tmpl index 8e3c23f6f12..9e64e26916e 100644 --- a/templates/hosts.azurelinux.tmpl +++ b/templates/hosts.azurelinux.tmpl @@ -19,4 +19,5 @@ you need to add the following to config: # The following lines are desirable for IPv6 capable hosts ::1 {{fqdn}} {{hostname}} +::1 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 From f2d5f5e7fd1f33e4c105257b97d003b7356ab4a3 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 8 May 2026 15:33:43 -0400 Subject: [PATCH 11/11] fix(azurelinux): update test_util with Azure Linux 4 os-release (#6874) --- tests/unittests/test_util.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index d75fbc4a8ab..fe24962e19b 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -409,15 +409,23 @@ OS_RELEASE_AZURELINUX = dedent( """\ - NAME="Microsoft Azure Linux" - VERSION="3.0.20240206" + NAME="Azure Linux" + VERSION="4.0 (Cloud Variant)" + RELEASE_TYPE=stable ID=azurelinux - VERSION_ID="3.0" - PRETTY_NAME="Microsoft Azure Linux 3.0" - ANSI_COLOR="1;34" + ID_LIKE=fedora + VERSION_ID=4.0 + VERSION_CODENAME="" + PRETTY_NAME="Azure Linux 4.0 (Cloud Variant)" + ANSI_COLOR="0;38;2;60;110;180" + LOGO=azurelinux-logo-icon + CPE_NAME="cpe:/o:microsoft:azurelinux:4.0" HOME_URL="https://aka.ms/azurelinux" - BUG_REPORT_URL="https://aka.ms/azurelinux" + DOCUMENTATION_URL="https://aka.ms/azurelinux" SUPPORT_URL="https://aka.ms/azurelinux" + BUG_REPORT_URL="https://aka.ms/azurelinux" + VARIANT="Cloud Variant" + VARIANT_ID=cloud """ ) @@ -1276,7 +1284,7 @@ def test_get_linux_azurelinux_os_release( m_os_release.return_value = OS_RELEASE_AZURELINUX m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists dist = util.get_linux_distro() - assert ("azurelinux", "3.0", "") == dist + assert ("azurelinux", "4.0", "Cloud Variant") == dist @mock.patch(M_PATH + "load_text_file") def test_get_linux_openmandriva(self, m_os_release, m_path_exists):