Unverified Commit 4742e5b1 authored by Florian Klink's avatar Florian Klink Committed by GitHub
Browse files

nixos/azure: move image-specific configs from azure-common to azure-image, fix...

nixos/azure: move image-specific configs from azure-common to azure-image, fix console output (#359365)
parents 7e5f4307 1460db45
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+55 −52
Original line number Diff line number Diff line
{ 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 = {
    services.waagent.enable = true;

    # 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"
    ];

  config = {
    virtualisation.azure.agent.enable = true;
    # Load Hyper-V kernel modules
    boot.initrd.kernelModules = [
      "hv_vmbus"
      "hv_netvsc"
      "hv_utils"
      "hv_storvsc"
    ];

    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" ];
    # 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);
  };
}
+7 −1
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -110,7 +110,10 @@ let
      };

      ResourceDisk = {
        Format = mkEnableOption ''
        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.
@@ -118,6 +121,7 @@ let

            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 ''
        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.
          '';
        };

        SwapSizeMB = mkOption {
          type = types.int;
@@ -173,16 +181,24 @@ let
        };
      };

      Logs.Verbose = lib.mkEnableOption ''
      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 ''
        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" { };

Loading