nixos/azure: move image-specific configs from azure-common to azure-image, fix console output (#359365)

This commit is contained in:
Florian Klink
2025-02-02 22:57:49 +02:00
committed by GitHub
6 changed files with 164 additions and 94 deletions
@@ -204,6 +204,8 @@
- Support for CUDA 10 has been dropped, as announced in the 24.11 release notes.
- `virtualisation/azure-common.nix`'s filesystem and grub configurations have been moved to `virtualisation/azure-image.nix`. This makes `azure-common.nix` more generic so it could be used for users who generate Azure image using other methods (e.g. nixos-generators and disko). For existing users depending on these configurations, please also import `azure-image.nix`.
- `zammad` has had its support for MySQL removed, since it was never working correctly and is now deprecated upstream. Check the [migration guide](https://docs.zammad.org/en/latest/appendix/migrate-to-postgresql.html) for how to convert your database to PostgreSQL.
- The `earlyoom` service is now using upstream systemd service, which enables
+54 -51
View File
@@ -1,48 +1,67 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.virtualisation.azure;
mlxDrivers = [ "mlx4_en" "mlx4_core" "mlx5_core" ];
mlxDrivers = [
"mlx4_en"
"mlx4_core"
"mlx5_core"
];
in
{
options.virtualisation.azure = {
acceleratedNetworking = mkOption {
acceleratedNetworking = lib.mkOption {
default = false;
description = "Whether the machine's network interface has enabled accelerated networking.";
};
};
imports = [
../profiles/headless.nix
./azure-agent.nix
];
config = {
virtualisation.azure.agent.enable = true;
services.waagent.enable = true;
boot.kernelParams = [ "console=ttyS0" "earlyprintk=ttyS0" "rootdelay=300" "panic=1" "boot.panic_on_fail" ];
boot.initrd.kernelModules = [ "hv_vmbus" "hv_netvsc" "hv_utils" "hv_storvsc" ];
# Enable cloud-init by default for waagent.
# Otherwise waagent would try manage networking using ifupdown,
# which is currently not availeble in nixpkgs.
services.cloud-init.enable = true;
services.cloud-init.network.enable = true;
systemd.services.cloud-config.serviceConfig.Restart = "on-failure";
# cloud-init.network.enable also enables systemd-networkd
networking.useNetworkd = true;
# Ensure kernel outputs to ttyS0 (Azure Serial Console),
# and reboot machine upon fatal boot issues
boot.kernelParams = [
"console=ttyS0"
"earlyprintk=ttyS0"
"rootdelay=300"
"panic=1"
"boot.panic_on_fail"
];
# Load Hyper-V kernel modules
boot.initrd.kernelModules = [
"hv_vmbus"
"hv_netvsc"
"hv_utils"
"hv_storvsc"
];
# Accelerated networking, configured following:
# https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview
boot.initrd.availableKernelModules = lib.optionals cfg.acceleratedNetworking mlxDrivers;
# Accelerated networking
systemd.network.networks."99-azure-unmanaged-devices.network" = lib.mkIf cfg.acceleratedNetworking {
matchConfig.Driver = mlxDrivers;
linkConfig.Unmanaged = "yes";
};
networking.networkmanager.unmanaged = lib.mkIf cfg.acceleratedNetworking
(builtins.map (drv: "driver:${drv}") mlxDrivers);
# Generate a GRUB menu.
boot.loader.grub.device = "/dev/sda";
boot.growPartition = true;
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
autoResize = true;
};
networking.networkmanager.unmanaged = lib.mkIf cfg.acceleratedNetworking (
builtins.map (drv: "driver:${drv}") mlxDrivers
);
# Allow root logins only using the SSH key that the user specified
# at instance creation time, ping client connections to avoid timeouts
@@ -51,35 +70,19 @@ in
services.openssh.settings.ClientAliveInterval = 180;
# Force getting the hostname from Azure
networking.hostName = mkDefault "";
networking.hostName = lib.mkDefault "";
# Always include cryptsetup so that NixOps can use it.
# sg_scan is needed to finalize disk removal on older kernels
environment.systemPackages = [ pkgs.cryptsetup pkgs.sg3_utils ];
environment.systemPackages = [
pkgs.cryptsetup
pkgs.sg3_utils
];
networking.usePredictableInterfaceNames = false;
services.udev.extraRules = ''
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:0", ATTR{removable}=="0", SYMLINK+="disk/by-lun/0",
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:1", ATTR{removable}=="0", SYMLINK+="disk/by-lun/1",
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:2", ATTR{removable}=="0", SYMLINK+="disk/by-lun/2"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:3", ATTR{removable}=="0", SYMLINK+="disk/by-lun/3"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:4", ATTR{removable}=="0", SYMLINK+="disk/by-lun/4"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:5", ATTR{removable}=="0", SYMLINK+="disk/by-lun/5"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:6", ATTR{removable}=="0", SYMLINK+="disk/by-lun/6"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:7", ATTR{removable}=="0", SYMLINK+="disk/by-lun/7"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:8", ATTR{removable}=="0", SYMLINK+="disk/by-lun/8"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:9", ATTR{removable}=="0", SYMLINK+="disk/by-lun/9"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:10", ATTR{removable}=="0", SYMLINK+="disk/by-lun/10"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:11", ATTR{removable}=="0", SYMLINK+="disk/by-lun/11"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:12", ATTR{removable}=="0", SYMLINK+="disk/by-lun/12"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:13", ATTR{removable}=="0", SYMLINK+="disk/by-lun/13"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:14", ATTR{removable}=="0", SYMLINK+="disk/by-lun/14"
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:15", ATTR{removable}=="0", SYMLINK+="disk/by-lun/15"
'';
services.udev.extraRules = lib.concatMapStrings (i: ''
ENV{DEVTYPE}=="disk", KERNEL!="sda" SUBSYSTEM=="block", SUBSYSTEMS=="scsi", KERNELS=="?:0:0:${toString i}", ATTR{removable}=="0", SYMLINK+="disk/by-lun/${toString i}"
'') (lib.range 1 15);
};
}
@@ -8,5 +8,11 @@
# This configures everything but bootstrap services,
# which only need to be run once and have already finished
# if you are able to see this comment.
imports = [ "${modulesPath}/virtualisation/azure-common.nix" ];
imports = [
"${modulesPath}/virtualisation/azure-common.nix"
"${modulesPath}/virtualisation/azure-image.nix"
];
# Please set the VM Generation to the actual value
# virtualisation.azureImage.vmGeneration = "v1";
}
+47 -3
View File
@@ -46,6 +46,14 @@ in
'';
};
label = mkOption {
type = types.str;
default = "nixos";
description = ''
NixOS partition label.
'';
};
vmGeneration = mkOption {
type =
with types;
@@ -68,19 +76,55 @@ in
system.build.azureImage = import ../../lib/make-disk-image.nix {
name = "azure-image";
inherit (config.image) baseName;
# Azure expects vhd format with fixed size,
# generating raw format and convert with subformat args afterwards
format = "raw";
postVM = ''
${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -o subformat=fixed,force_size -O vpc $diskImage $out/${config.image.fileName}
rm $diskImage
'';
configFile = ./azure-config-user.nix;
format = "raw";
bootSize = "${toString cfg.bootSize}M";
partitionTableType = if cfg.vmGeneration == "v2" then "efi" else "legacy";
partitionTableType = if (cfg.vmGeneration == "v2") then "efi" else "legacy";
inherit (cfg) contents;
inherit (cfg) contents label;
inherit (config.virtualisation) diskSize;
inherit config lib pkgs;
};
boot.growPartition = true;
boot.loader.grub = rec {
efiSupport = (cfg.vmGeneration == "v2");
device = if efiSupport then "nodev" else "/dev/sda";
efiInstallAsRemovable = efiSupport;
# Force grub to run in text mode and output to console
# by disabling font and splash image
font = null;
splashImage = null;
# For Gen 1 VM, configurate grub output to serial_com0.
# Not needed for Gen 2 VM wbere serial_com0 does not exist,
# and outputing to console is enough to make Azure Serial Console working
extraConfig = lib.mkIf (!efiSupport) ''
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal_input --append serial
terminal_output --append serial
'';
};
fileSystems = {
"/" = {
device = "/dev/disk/by-label/${cfg.label}";
inherit (cfg) label;
fsType = "ext4";
autoResize = true;
};
"/boot" = lib.mkIf (cfg.vmGeneration == "v2") {
device = "/dev/disk/by-label/ESP";
fsType = "vfat";
};
};
};
}
+45 -27
View File
@@ -31,7 +31,7 @@ let
attrsOf (
either atom (attrsOf atom)
// {
description = atom.description + "or an attribute set of them";
description = atom.description + " or an attribute set of them";
}
);
generate =
@@ -110,14 +110,18 @@ let
};
ResourceDisk = {
Format = mkEnableOption ''
If set to `true`, waagent formats and mounts the resource disk that the platform provides,
unless the file system type in `ResourceDisk.FileSystem` is set to `ntfs`.
The agent makes a single Linux partition (ID 83) available on the disk.
This partition isn't formatted if it can be successfully mounted.
Format = mkOption {
type = types.bool;
default = false;
description = ''
If set to `true`, waagent formats and mounts the resource disk that the platform provides,
unless the file system type in `ResourceDisk.FileSystem` is set to `ntfs`.
The agent makes a single Linux partition (ID 83) available on the disk.
This partition isn't formatted if it can be successfully mounted.
This configuration has no effect if resource disk is managed by cloud-init.
'';
This configuration has no effect if resource disk is managed by cloud-init.
'';
};
FileSystem = mkOption {
type = types.str;
@@ -155,12 +159,16 @@ let
'';
};
EnableSwap = mkEnableOption ''
If enabled, the agent creates a swap file (`/swapfile`) on the resource disk
and adds it to the system swap space.
EnableSwap = mkOption {
type = types.bool;
default = false;
description = ''
If enabled, the agent creates a swap file (`/swapfile`) on the resource disk
and adds it to the system swap space.
This configuration has no effect if resource disk is managed by cloud-init.
'';
This configuration has no effect if resource disk is managed by cloud-init.
'';
};
SwapSizeMB = mkOption {
type = types.int;
@@ -173,16 +181,24 @@ let
};
};
Logs.Verbose = lib.mkEnableOption ''
If you set this option, log verbosity is boosted.
Waagent logs to `/var/log/waagent.log` and uses the system logrotate functionality to rotate logs.
'';
Logs.Verbose = lib.mkOption {
type = types.bool;
default = false;
description = ''
If you set this option, log verbosity is boosted.
Waagent logs to `/var/log/waagent.log` and uses the system logrotate functionality to rotate logs.
'';
};
OS = {
EnableRDMA = lib.mkEnableOption ''
If enabled, the agent attempts to install and then load an RDMA kernel driver
that matches the version of the firmware on the underlying hardware.
'';
EnableRDMA = lib.mkOption {
type = types.bool;
default = false;
description = ''
If enabled, the agent attempts to install and then load an RDMA kernel driver
that matches the version of the firmware on the underlying hardware.
'';
};
RootDeviceScsiTimeout = lib.mkOption {
type = types.nullOr types.int;
@@ -212,17 +228,19 @@ let
};
};
AutoUpdate.Enable = lib.mkEnableOption ''
Enable or disable autoupdate for goal state processing.
'';
AutoUpdate.Enable = lib.mkOption {
type = types.bool;
default = false;
description = ''
Whether or not to enable autoupdate for goal state processing.
'';
};
};
};
in
{
options.services.waagent = {
enable = lib.mkEnableOption ''
Whether to enable the Windows Azure Linux Agent.
'';
enable = lib.mkEnableOption "Windows Azure Linux Agent";
package = lib.mkPackageOption pkgs "waagent" { };
+9 -12
View File
@@ -4,7 +4,7 @@
lib,
python3,
bash,
gitUpdater,
openssl,
nixosTests,
}:
@@ -31,11 +31,13 @@ python.pkgs.buildPythonApplication rec {
# Replace tools used in udev rules with their full path and ensure they are present.
postPatch = ''
substituteInPlace config/66-azure-storage.rules \
--replace-fail readlink ${coreutils}/bin/readlink \
--replace-fail cut ${coreutils}/bin/cut \
--replace-fail /bin/sh ${bash}/bin/sh
--replace-fail readlink '${coreutils}/bin/readlink' \
--replace-fail cut '${coreutils}/bin/cut' \
--replace-fail '/bin/sh' '${bash}/bin/sh'
substituteInPlace config/99-azure-product-uuid.rules \
--replace-fail "/bin/chmod" "${coreutils}/bin/chmod"
--replace-fail '/bin/chmod' '${coreutils}/bin/chmod'
substituteInPlace azurelinuxagent/common/conf.py \
--replace-fail '/usr/bin/openssl' '${openssl}/bin/openssl'
'';
propagatedBuildInputs = [ python.pkgs.distro ];
@@ -65,13 +67,8 @@ python.pkgs.buildPythonApplication rec {
dontWrapPythonPrograms = false;
passthru = {
tests = {
inherit (nixosTests) waagent;
};
updateScript = gitUpdater {
rev-prefix = "v";
};
passthru.tests = {
inherit (nixosTests) waagent;
};
meta = {