nixos/azure: move image-specific configs from azure-common to azure-image, fix console output (#359365)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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" { };
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user