[PATCH 2/8] nixos: consume nixos-qemu modules via a per-node default.nix
Daniel Gomez <[email protected]> Thu, 23 Apr 2026 00:48:40 +0200
| Newsgroups | dev.linux.lists.kdevops |
|---|---|
| Message-ID | <20260423-kdevops-series-b-nixos-qemu-v1-2-209154ae54f8@samsung.com> |
From: Daniel Gomez <[email protected]> Collapse every kdevops-owned jinja template that carried inline NixOS configuration into a single per-node default.nix.j2 that imports modules from scripts/nixos-qemu. The library becomes the single source of truth for what a NixOS guest looks like; kdevops only renders per-node overrides (hostname, SSH keys, workflow enablement, cache mirror, optional 9p share). The Generate NixOS configurations play creates one directory per guest, copies the subtree's libvirt template flake, rewrites its nixos-qemu.url to resolve at the checked-in subtree, and renders default.nix.j2 alongside. Generated-by: Claude AI Signed-off-by: Daniel Gomez <[email protected]> (cherry picked from commit eb20b00dd5161197aea3490803cd97a06e8fb81d) --- kconfigs/Kconfig.nixos | 7 +- playbooks/nixos.yml | 61 +++++---- playbooks/templates/nixos/configuration.nix.j2 | 138 --------------------- playbooks/templates/nixos/default.nix.j2 | 69 +++++++++++ playbooks/templates/nixos/flake.nix.j2 | 38 ------ .../templates/nixos/hardware-configuration.nix.j2 | 42 ------- playbooks/templates/nixos/vms.nix.j2 | 45 ------- playbooks/templates/nixos/workflow-deps.nix.j2 | 127 ------------------- 8 files changed, 100 insertions(+), 427 deletions(-) diff --git a/kconfigs/Kconfig.nixos b/kconfigs/Kconfig.nixos index 196bdafd..622b4492 100644 --- a/kconfigs/Kconfig.nixos +++ b/kconfigs/Kconfig.nixos @@ -10,12 +10,7 @@ config NIXOS_STORAGE_DIR config NIXOS_CONFIG_DIR string output yaml - default "{{ topdir_path }}/nixos" - -config NIXOS_GENERATION_DIR - string - output yaml - default "{{ nixos_config_dir }}/generated" + default "{{ topdir_path }}/scripts/nixos-qemu/configurations" config NIXOS_USE_FLAKES bool "Use Nix flakes for configuration" diff --git a/playbooks/nixos.yml b/playbooks/nixos.yml index d6aa2283..007c9033 100644 --- a/playbooks/nixos.yml +++ b/playbooks/nixos.yml @@ -57,16 +57,22 @@ - "{{ playbook_dir }}/../extra_vars.yaml" tags: generate-configs tasks: - - name: Create NixOS directories + - name: Create top-level NixOS directories ansible.builtin.file: path: "{{ item }}" state: directory mode: '0755' loop: - "{{ nixos_config_dir }}" - - "{{ nixos_generation_dir }}" - "{{ nixos_storage_dir }}" + - name: Create per-node configuration directories + ansible.builtin.file: + path: "{{ nixos_config_dir }}/{{ item }}" + state: directory + mode: '0755' + loop: "{{ groups['all'] | reject('equalto', 'localhost') | list }}" + - name: Ensure SSH key exists for configuration block: - name: Determine SSH key path based on directory @@ -110,41 +116,33 @@ - detected_mirror_url.stdout is defined - detected_mirror_url.stdout | trim != "" - - name: Template base NixOS configuration - ansible.builtin.template: - src: nixos/configuration.nix.j2 - dest: "{{ nixos_generation_dir }}/configuration.nix" - mode: '0644' - - - name: Template hardware configuration - ansible.builtin.template: - src: nixos/hardware-configuration.nix.j2 - dest: "{{ nixos_generation_dir }}/hardware-configuration.nix" - mode: '0644' - - - name: Generate workflow dependencies configuration - ansible.builtin.template: - src: nixos/workflow-deps.nix.j2 - dest: "{{ nixos_generation_dir }}/workflow-deps.nix" - mode: '0644' - when: nixos_enable_workflow_deps | bool - - name: Debug SSH key path ansible.builtin.debug: msg: "Using SSH key: {{ hostvars['localhost']['nixos_ssh_key_path'] | default('NOT SET') }}" - - name: Generate VM definitions - ansible.builtin.template: - src: nixos/vms.nix.j2 - dest: "{{ nixos_generation_dir }}/vms.nix" + - name: Copy nixos-qemu libvirt template flake to each per-node directory + ansible.builtin.copy: + src: "{{ topdir_path }}/scripts/nixos-qemu/templates/libvirt/flake.nix" + dest: "{{ nixos_config_dir }}/{{ item }}/flake.nix" + remote_src: true mode: '0644' + loop: "{{ groups['all'] | reject('equalto', 'localhost') | list }}" - - name: Generate flake.nix if enabled + - name: Point nixos-qemu input at the local subtree in each per-node flake + ansible.builtin.replace: + path: "{{ nixos_config_dir }}/{{ item }}/flake.nix" + regexp: '^(\s*)nixos-qemu\.url = "path:/path/to/nixos-qemu";' + replace: '\1nixos-qemu.url = "path:{{ topdir_path }}/scripts/nixos-qemu";' + loop: "{{ groups['all'] | reject('equalto', 'localhost') | list }}" + + - name: Render per-node default.nix ansible.builtin.template: - src: nixos/flake.nix.j2 - dest: "{{ nixos_config_dir }}/flake.nix" + src: nixos/default.nix.j2 + dest: "{{ nixos_config_dir }}/{{ item }}/default.nix" mode: '0644' - when: nixos_use_flakes | bool + loop: "{{ groups['all'] | reject('equalto', 'localhost') | list }}" + vars: + vm_name: "{{ item }}" # The setup phase is integrated into generate-configs to ensure SSH keys are available @@ -528,10 +526,11 @@ path: "{{ nixos_storage_dir }}/extra-drives" state: absent - - name: Clean up generated NixOS configuration + - name: Clean up per-node generated NixOS configurations ansible.builtin.file: - path: "{{ nixos_generation_dir }}" + path: "{{ nixos_config_dir }}/{{ item }}" state: absent + loop: "{{ groups['all'] | reject('equalto', 'localhost') | list }}" - name: Garbage collect cached NixOS disk images from Nix store ansible.builtin.shell: | diff --git a/playbooks/templates/nixos/configuration.nix.j2 b/playbooks/templates/nixos/configuration.nix.j2 deleted file mode 100644 index d5c00fc3..00000000 --- a/playbooks/templates/nixos/configuration.nix.j2 +++ /dev/null @@ -1,138 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - imports = [ - ./hardware-configuration.nix -{% if nixos_enable_workflow_deps %} - ./workflow-deps.nix -{% endif %} -{% if nixos_custom_config_path != "" %} - {{ nixos_custom_config_path }} -{% endif %} - ]; - - # Nix configuration -{% if nixos_use_local_mirror is defined and nixos_use_local_mirror and nixos_mirror_url is defined and nixos_mirror_url != "" %} - nix.settings = { - substituters = [ - "{{ nixos_mirror_url }}" - "https://cache.nixos.org" - ]; - trusted-substituters = [ - "{{ nixos_mirror_url }}" - "https://cache.nixos.org" - ]; - # Prefer local mirror - extra-substituters = [ "{{ nixos_mirror_url }}" ]; - }; -{% endif %} - - # Boot configuration - boot.loader.grub.enable = true; - boot.loader.grub.device = "/dev/vda"; - boot.loader.timeout = 1; - - # Kernel - boot.kernelPackages = pkgs.linuxPackages_latest; - - # Enable 9p support if configured -{% if bootlinux_9p is defined and bootlinux_9p %} - boot.kernelModules = [ "9p" "9pnet_virtio" ]; - boot.initrd.kernelModules = [ "9p" "9pnet_virtio" ]; -{% endif %} - - # Networking - networking.useDHCP = lib.mkDefault true; - - # Enable SSH - services.openssh = { - enable = true; - settings = { - PermitRootLogin = "yes"; - PasswordAuthentication = false; - PubkeyAuthentication = true; - }; - }; - - # Users - users.users.root = { - openssh.authorizedKeys.keys = [ -{% if nixos_ssh_authorized_key is defined %} - "{{ nixos_ssh_authorized_key }}" -{% else %} - # SSH key will be generated during provisioning -{% endif %} - ]; - }; - - users.users.kdevops = { - isNormalUser = true; - extraGroups = [ "wheel" "libvirt" "kvm" ]; - openssh.authorizedKeys.keys = [ -{% if nixos_ssh_authorized_key is defined %} - "{{ nixos_ssh_authorized_key }}" -{% else %} - # SSH key will be generated during provisioning -{% endif %} - ]; - }; - - # Sudo without password for kdevops user - security.sudo.wheelNeedsPassword = false; - - # Basic packages - environment.systemPackages = with pkgs; [ - vim - git - tmux - htop - wget - curl - rsync - python3 - gcc - gnumake - binutils - coreutils - findutils - procps - util-linux - ]; - - # Enable libvirt for nested virtualization if needed - virtualisation.libvirtd.enable = false; - - # Filesystems - fileSystems."/" = { - device = "/dev/vda1"; - fsType = "ext4"; - }; - -{% if bootlinux_9p is defined and bootlinux_9p %} - # 9P mount for shared kernel source - fileSystems."/mnt/linux" = { - device = "linux_source"; - fsType = "9p"; - options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ]; - }; -{% endif %} - - # Time zone - time.timeZone = "UTC"; - - # Locale - i18n.defaultLocale = "en_US.UTF-8"; - - # State version - system.stateVersion = "24.05"; - - # Enable nix flakes - nix.settings.experimental-features = [ "nix-command" "flakes" ]; - - # Optimize storage - nix.gc = { - automatic = true; - dates = "weekly"; - options = "--delete-older-than 7d"; - }; -} diff --git a/playbooks/templates/nixos/default.nix.j2 b/playbooks/templates/nixos/default.nix.j2 new file mode 100644 index 00000000..64c8871c --- /dev/null +++ b/playbooks/templates/nixos/default.nix.j2 @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: copyleft-next-0.3.1 +# +# Per-node overrides for {{ vm_name }}. Generated by kdevops. +# +# The flake that imports this module (copied from +# scripts/nixos-qemu/templates/libvirt/flake.nix) passes `nixos-qemu` +# and the flake inputs through specialArgs, so workflow modules are +# imported directly and mirror substituters attach to nixos-qemu's +# overlay through plain nixpkgs config. +{ config, lib, pkgs, nixos-qemu, inputs, ... }: { + imports = [ + nixos-qemu.nixosModules.devel + nixos-qemu.nixosModules.build-tools +{% if kdevops_workflow_enable_blktests is defined and kdevops_workflow_enable_blktests %} + nixos-qemu.nixosModules.workflows.blktests +{% endif %} +{% if kdevops_workflow_enable_fstests is defined and kdevops_workflow_enable_fstests %} + nixos-qemu.nixosModules.workflows.fstests +{% endif %} +{% if kdevops_workflow_enable_gitr is defined and kdevops_workflow_enable_gitr %} + nixos-qemu.nixosModules.workflows.gitr +{% endif %} +{% if kdevops_workflow_enable_ltp is defined and kdevops_workflow_enable_ltp %} + nixos-qemu.nixosModules.workflows.ltp +{% endif %} +{% if kdevops_workflow_enable_mmtests is defined and kdevops_workflow_enable_mmtests %} + nixos-qemu.nixosModules.workflows.mmtests +{% endif %} +{% if kdevops_workflow_enable_pynfs is defined and kdevops_workflow_enable_pynfs %} + nixos-qemu.nixosModules.workflows.pynfs +{% endif %} +{% if kdevops_workflow_enable_selftests is defined and kdevops_workflow_enable_selftests %} + nixos-qemu.nixosModules.workflows.selftests +{% endif %} +{% if kdevops_workflow_enable_sysbench is defined and kdevops_workflow_enable_sysbench %} + nixos-qemu.nixosModules.workflows.sysbench +{% endif %} + ]; + + networking.hostName = "{{ vm_name }}"; + + nixos-qemu.user.name = "kdevops"; + +{% if nixos_ssh_authorized_key is defined %} + users.users.root.openssh.authorizedKeys.keys = [ "{{ nixos_ssh_authorized_key }}" ]; + users.users.kdevops.openssh.authorizedKeys.keys = [ "{{ nixos_ssh_authorized_key }}" ]; +{% endif %} + +{% if nixos_use_local_mirror is defined and nixos_use_local_mirror and nixos_mirror_url is defined and nixos_mirror_url != "" %} + nix.settings = { + substituters = [ + "{{ nixos_mirror_url }}" + "https://cache.nixos.org" + ]; + extra-substituters = [ "{{ nixos_mirror_url }}" ]; + }; +{% endif %} + +{% if bootlinux_9p is defined and bootlinux_9p %} + # 9P mount for shared kernel source + boot.kernelModules = [ "9p" "9pnet_virtio" ]; + boot.initrd.kernelModules = [ "9p" "9pnet_virtio" ]; + fileSystems."/mnt/linux" = { + device = "linux_source"; + fsType = "9p"; + options = [ "trans=virtio" "version=9p2000.L" "cache=loose" ]; + }; +{% endif %} +} diff --git a/playbooks/templates/nixos/flake.nix.j2 b/playbooks/templates/nixos/flake.nix.j2 deleted file mode 100644 index 52b5b680..00000000 --- a/playbooks/templates/nixos/flake.nix.j2 +++ /dev/null @@ -1,38 +0,0 @@ -{ - description = "kdevops NixOS VMs"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/{{ nixos_channel }}"; - }; - - outputs = { self, nixpkgs }: { - nixosConfigurations = { -{% for node in groups['all'] if node != 'localhost' %} - "{{ node }}" = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - ./generated/configuration.nix - ./generated/hardware-configuration.nix -{% if nixos_enable_workflow_deps %} - ./generated/workflow-deps.nix -{% endif %} - ({ ... }: { - networking.hostName = "{{ node }}"; - }) - ]; - }; -{% endfor %} - }; - - # Build all VMs - defaultPackage.x86_64-linux = - nixpkgs.legacyPackages.x86_64-linux.writeShellScriptBin "build-vms" '' - echo "Building NixOS VMs..." -{% for node in groups['all'] if node != 'localhost' %} - echo "Building {{ node }}..." - nix build .#nixosConfigurations.{{ node }}.config.system.build.vm -{% endfor %} - echo "All VMs built successfully!" - ''; - }; -} diff --git a/playbooks/templates/nixos/hardware-configuration.nix.j2 b/playbooks/templates/nixos/hardware-configuration.nix.j2 deleted file mode 100644 index bb91bba4..00000000 --- a/playbooks/templates/nixos/hardware-configuration.nix.j2 +++ /dev/null @@ -1,42 +0,0 @@ -{ config, lib, pkgs, modulesPath, ... }: - -{ - imports = [ - (modulesPath + "/profiles/qemu-guest.nix") - ]; - - boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ]; - boot.initrd.kernelModules = [ ]; - boot.kernelModules = [ "kvm-intel" "kvm-amd" ]; - boot.extraModulePackages = [ ]; - - # Root filesystem - fileSystems."/" = { - device = "/dev/disk/by-label/nixos"; - fsType = "ext4"; - }; - - # Boot partition (if UEFI is enabled) -{% if guestfs_requires_uefi is defined and guestfs_requires_uefi %} - fileSystems."/boot" = { - device = "/dev/disk/by-label/boot"; - fsType = "vfat"; - }; -{% endif %} - - # Swap - swapDevices = [ ]; - - # Networking - networking.useDHCP = lib.mkDefault true; - networking.interfaces.eth0.useDHCP = lib.mkDefault true; - - # Hardware configuration - nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - - # Virtualization features - virtualisation.hypervGuest.enable = false; - virtualisation.vmware.guest.enable = false; -} diff --git a/playbooks/templates/nixos/vms.nix.j2 b/playbooks/templates/nixos/vms.nix.j2 deleted file mode 100644 index f2af2b96..00000000 --- a/playbooks/templates/nixos/vms.nix.j2 +++ /dev/null @@ -1,45 +0,0 @@ -# NixOS VM configurations for kdevops -{ config, pkgs, ... }: - -{ - # VM-specific configurations - virtualisation.memorySize = {{ nixos_vm_memory_mb }}; - virtualisation.diskSize = {{ nixos_vm_disk_size_gb * 1024 }}; # Convert GB to MB - virtualisation.cores = {{ nixos_vm_vcpus }}; - - # Enable virtio for better performance - virtualisation.qemu.options = [ - "-machine q35,accel=kvm" - "-cpu host" - "-smp {{ nixos_vm_vcpus }}" - "-m {{ nixos_vm_memory_mb }}M" - ]; - - # Network configuration for VMs - networking.useDHCP = true; - networking.nameservers = [ "8.8.8.8" "8.8.4.4" ]; - - # VM-specific services - services.qemuGuest.enable = true; - - # Enable console access - services.getty.autologinUser = "kdevops"; - boot.kernelParams = [ "console=ttyS0,115200n8" "console=tty0" ]; - - # Additional VM optimizations - boot.initrd.availableKernelModules = [ "virtio_net" "virtio_pci" "virtio_blk" "virtio_scsi" "9p" "9pnet_virtio" ]; - boot.kernelModules = [ "virtio_balloon" "virtio_rng" ]; - -{% if bootlinux_9p is defined and bootlinux_9p %} - # 9P filesystem support for kernel development - fileSystems."/mnt/linux" = { - device = "linux_source"; - fsType = "9p"; - options = [ "trans=virtio" "version=9p2000.L" "rw" ]; - }; -{% endif %} - - # Ensure VM can be reached via SSH - services.openssh.permitRootLogin = "yes"; - services.openssh.passwordAuthentication = false; -} diff --git a/playbooks/templates/nixos/workflow-deps.nix.j2 b/playbooks/templates/nixos/workflow-deps.nix.j2 deleted file mode 100644 index d01aac08..00000000 --- a/playbooks/templates/nixos/workflow-deps.nix.j2 +++ /dev/null @@ -1,127 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - # Workflow-specific dependencies based on enabled kdevops workflows - environment.systemPackages = with pkgs; [ -{% if kdevops_workflow_enable_fstests is defined and kdevops_workflow_enable_fstests %} - # fstests dependencies - xfsprogs - btrfs-progs - e2fsprogs - f2fs-tools - fio - dbench - stress-ng - attr - acl - quota - nfs-utils - cifs-utils -{% endif %} - -{% if kdevops_workflow_enable_blktests is defined and kdevops_workflow_enable_blktests %} - # blktests dependencies - nvme-cli - sg3_utils - targetcli - multipath-tools - dmraid - lvm2 - mdadm -{% endif %} - -{% if kdevops_workflow_enable_selftests is defined and kdevops_workflow_enable_selftests %} - # selftests dependencies - perf-tools - numactl - libcap - libseccomp - keyutils - iproute2 - ethtool - tc -{% endif %} - -{% if kdevops_workflow_enable_mmtests is defined and kdevops_workflow_enable_mmtests %} - # mmtests dependencies - gnuplot - perl - cpupower - dmidecode - sysstat - iotop - powertop -{% endif %} - -{% if kdevops_workflow_enable_pynfs is defined and kdevops_workflow_enable_pynfs %} - # pynfs dependencies - python3 - python3Packages.ply - nfs-utils -{% endif %} - -{% if kdevops_workflow_enable_ltp is defined and kdevops_workflow_enable_ltp %} - # LTP dependencies - autoconf - automake - m4 - libtool - pkg-config - flex - bison - libacl - libcap - libaio - libnuma - libsepol - libselinux - libssl -{% endif %} - -{% if kdevops_workflow_enable_sysbench is defined and kdevops_workflow_enable_sysbench %} - # sysbench dependencies - sysbench - mysql - postgresql -{% endif %} - -{% if kdevops_workflow_enable_gitr is defined and kdevops_workflow_enable_gitr %} - # git regression testing dependencies - git - gitFull - perl - subversion - mercurial -{% endif %} - - # Common build tools often needed - autoconf - automake - libtool - pkg-config - flex - bison - bc - openssl - elfutils - libelf - ]; - -{% if kdevops_workflow_enable_fstests is defined and kdevops_workflow_enable_fstests %} - # Enable required services for fstests - services.nfs.server.enable = true; - services.rpcbind.enable = true; -{% endif %} - -{% if kdevops_workflow_enable_sysbench is defined and kdevops_workflow_enable_sysbench %} - # Database services for sysbench - services.mysql = { - enable = true; - package = pkgs.mariadb; - }; - - services.postgresql = { - enable = true; - }; -{% endif %} -} -- 2.53.0