Merge pull request #244093 from adamcstephens/lxd/vm

lxd: Add VM image and server support for QEMU VMs

authored by

Mario Rodas and committed by
GitHub
4f2c2764 12aaefa7

+365 -232
+2
nixos/doc/manual/release-notes/rl-2311.section.md
··· 6 6 7 7 - Support for WiFi6 (IEEE 802.11ax) and WPA3-SAE-PK was enabled in the `hostapd` package, along with a significant rework of the hostapd module. 8 8 9 + - LXD now supports virtual machine instances to complement the existing container support 10 + 9 11 ## New Services {#sec-release-23.11-new-services} 10 12 11 13 - [MCHPRS](https://github.com/MCHPR/MCHPRS), a multithreaded Minecraft server built for redstone. Available as [services.mchprs](#opt-services.mchprs.enable).
+20
nixos/maintainers/scripts/lxd/lxd-container-image-inner.nix
··· 1 + # Edit this configuration file to define what should be installed on 2 + # your system. Help is available in the configuration.nix(5) man page 3 + # and in the NixOS manual (accessible by running ‘nixos-help’). 4 + 5 + { config, pkgs, lib, ... }: 6 + 7 + { 8 + imports = 9 + [ 10 + # Include the default lxd configuration. 11 + ../../../modules/virtualisation/lxc-container.nix 12 + # Include the container-specific autogenerated configuration. 13 + ./lxd.nix 14 + ]; 15 + 16 + networking.useDHCP = false; 17 + networking.interfaces.eth0.useDHCP = true; 18 + 19 + system.stateVersion = "21.05"; # Did you read the comment? 20 + }
-95
nixos/maintainers/scripts/lxd/lxd-image-inner.nix
··· 1 - # Edit this configuration file to define what should be installed on 2 - # your system. Help is available in the configuration.nix(5) man page 3 - # and in the NixOS manual (accessible by running ‘nixos-help’). 4 - 5 - { config, pkgs, lib, ... }: 6 - 7 - { 8 - imports = 9 - [ # Include the default lxd configuration. 10 - ../../../modules/virtualisation/lxc-container.nix 11 - # Include the container-specific autogenerated configuration. 12 - ./lxd.nix 13 - ]; 14 - 15 - # networking.hostName = mkForce "nixos"; # Overwrite the hostname. 16 - # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. 17 - 18 - # Set your time zone. 19 - # time.timeZone = "Europe/Amsterdam"; 20 - 21 - # The global useDHCP flag is deprecated, therefore explicitly set to false here. 22 - # Per-interface useDHCP will be mandatory in the future, so this generated config 23 - # replicates the default behaviour. 24 - networking.useDHCP = false; 25 - networking.interfaces.eth0.useDHCP = true; 26 - 27 - # Configure network proxy if necessary 28 - # networking.proxy.default = "http://user:password@proxy:port/"; 29 - # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; 30 - 31 - # Select internationalisation properties. 32 - # i18n.defaultLocale = "en_US.UTF-8"; 33 - # console = { 34 - # font = "Lat2-Terminus16"; 35 - # keyMap = "us"; 36 - # }; 37 - 38 - # Enable the X11 windowing system. 39 - # services.xserver.enable = true; 40 - 41 - # Configure keymap in X11 42 - # services.xserver.layout = "us"; 43 - # services.xserver.xkbOptions = "eurosign:e"; 44 - 45 - # Enable CUPS to print documents. 46 - # services.printing.enable = true; 47 - 48 - # Enable sound. 49 - # sound.enable = true; 50 - # hardware.pulseaudio.enable = true; 51 - 52 - # Enable touchpad support (enabled default in most desktopManager). 53 - # services.xserver.libinput.enable = true; 54 - 55 - # Define a user account. Don't forget to set a password with ‘passwd’. 56 - # users.users.alice = { 57 - # isNormalUser = true; 58 - # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. 59 - # }; 60 - 61 - # List packages installed in system profile. To search, run: 62 - # $ nix search wget 63 - # environment.systemPackages = with pkgs; [ 64 - # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. 65 - # wget 66 - # firefox 67 - # ]; 68 - 69 - # Some programs need SUID wrappers, can be configured further or are 70 - # started in user sessions. 71 - # programs.mtr.enable = true; 72 - # programs.gnupg.agent = { 73 - # enable = true; 74 - # enableSSHSupport = true; 75 - # }; 76 - 77 - # List services that you want to enable: 78 - 79 - # Enable the OpenSSH daemon. 80 - # services.openssh.enable = true; 81 - 82 - # Open ports in the firewall. 83 - # networking.firewall.allowedTCPPorts = [ ... ]; 84 - # networking.firewall.allowedUDPPorts = [ ... ]; 85 - # Or disable the firewall altogether. 86 - # networking.firewall.enable = false; 87 - 88 - # This value determines the NixOS release from which the default 89 - # settings for stateful data, like file locations and database versions 90 - # on your system were taken. It’s perfectly fine and recommended to leave 91 - # this value at the release version of the first install of this system. 92 - # Before changing this value read the documentation for this option 93 - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 94 - system.stateVersion = "21.05"; # Did you read the comment? 95 - }
+3 -3
nixos/maintainers/scripts/lxd/lxd-image.nix nixos/maintainers/scripts/lxd/lxd-container-image.nix
··· 1 - { lib, config, pkgs, ... }: 1 + { lib, pkgs, ... }: 2 2 3 3 { 4 4 imports = [ ··· 16 16 system.activationScripts.config = '' 17 17 if [ ! -e /etc/nixos/configuration.nix ]; then 18 18 mkdir -p /etc/nixos 19 - cat ${./lxd-image-inner.nix} > /etc/nixos/configuration.nix 20 - sed 's|../../../modules/virtualisation/lxc-container.nix|<nixpkgs/nixos/modules/virtualisation/lxc-container.nix>|g' -i /etc/nixos/configuration.nix 19 + cat ${./lxd-container-image-inner.nix} > /etc/nixos/configuration.nix 20 + ${lib.getExe pkgs.gnused} 's|../../../modules/virtualisation/lxc-container.nix|<nixpkgs/nixos/modules/virtualisation/lxc-container.nix>|g' -i /etc/nixos/configuration.nix 21 21 fi 22 22 ''; 23 23
+20
nixos/maintainers/scripts/lxd/lxd-virtual-machine-image-inner.nix
··· 1 + # Edit this configuration file to define what should be installed on 2 + # your system. Help is available in the configuration.nix(5) man page 3 + # and in the NixOS manual (accessible by running ‘nixos-help’). 4 + 5 + { config, pkgs, lib, ... }: 6 + 7 + { 8 + imports = 9 + [ 10 + # Include the default lxd configuration. 11 + ../../../modules/virtualisation/lxd-virtual-machine.nix 12 + # Include the container-specific autogenerated configuration. 13 + ./lxd.nix 14 + ]; 15 + 16 + networking.useDHCP = false; 17 + networking.interfaces.eth0.useDHCP = true; 18 + 19 + system.stateVersion = "23.05"; # Did you read the comment? 20 + }
+27
nixos/maintainers/scripts/lxd/lxd-virtual-machine-image.nix
··· 1 + { lib, pkgs, ... }: 2 + 3 + { 4 + imports = [ 5 + ../../../modules/virtualisation/lxd-virtual-machine.nix 6 + ]; 7 + 8 + virtualisation.lxc.templates.nix = { 9 + enable = true; 10 + target = "/etc/nixos/lxd.nix"; 11 + template = ./nix.tpl; 12 + when = ["create" "copy"]; 13 + }; 14 + 15 + # copy the config for nixos-rebuild 16 + system.activationScripts.config = '' 17 + if [ ! -e /etc/nixos/configuration.nix ]; then 18 + mkdir -p /etc/nixos 19 + cat ${./lxd-virtual-machine-image-inner.nix} > /etc/nixos/configuration.nix 20 + ${lib.getExe pkgs.gnused} 's|../../../modules/virtualisation/lxd-virtual-machine.nix|<nixpkgs/nixos/modules/virtualisation/lxd-virtual-machine.nix>|g' -i /etc/nixos/configuration.nix 21 + fi 22 + ''; 23 + 24 + # Network 25 + networking.useDHCP = false; 26 + networking.interfaces.enp5s0.useDHCP = true; 27 + }
+6 -124
nixos/modules/virtualisation/lxc-container.nix
··· 1 1 { lib, config, pkgs, ... }: 2 2 3 - with lib; 4 - 5 3 let 6 - templateSubmodule = { ... }: { 7 - options = { 8 - enable = mkEnableOption (lib.mdDoc "this template"); 9 - 10 - target = mkOption { 11 - description = lib.mdDoc "Path in the container"; 12 - type = types.path; 13 - }; 14 - template = mkOption { 15 - description = lib.mdDoc ".tpl file for rendering the target"; 16 - type = types.path; 17 - }; 18 - when = mkOption { 19 - description = lib.mdDoc "Events which trigger a rewrite (create, copy)"; 20 - type = types.listOf (types.str); 21 - }; 22 - properties = mkOption { 23 - description = lib.mdDoc "Additional properties"; 24 - type = types.attrs; 25 - default = {}; 26 - }; 27 - }; 28 - }; 29 - 30 - toYAML = name: data: pkgs.writeText name (generators.toYAML {} data); 31 - 32 4 cfg = config.virtualisation.lxc; 33 - templates = if cfg.templates != {} then let 34 - list = mapAttrsToList (name: value: { inherit name; } // value) 35 - (filterAttrs (name: value: value.enable) cfg.templates); 36 - in 37 - { 38 - files = map (tpl: { 39 - source = tpl.template; 40 - target = "/templates/${tpl.name}.tpl"; 41 - }) list; 42 - properties = listToAttrs (map (tpl: nameValuePair tpl.target { 43 - when = tpl.when; 44 - template = "${tpl.name}.tpl"; 45 - properties = tpl.properties; 46 - }) list); 47 - } 48 - else { files = []; properties = {}; }; 49 - 50 - in 51 - { 5 + in { 52 6 imports = [ 53 - ../installer/cd-dvd/channel.nix 54 - ../profiles/clone-config.nix 55 - ../profiles/minimal.nix 7 + ./lxc-instance-common.nix 56 8 ]; 57 9 58 10 options = { 59 11 virtualisation.lxc = { 60 - templates = mkOption { 61 - description = lib.mdDoc "Templates for LXD"; 62 - type = types.attrsOf (types.submodule (templateSubmodule)); 63 - default = {}; 64 - example = literalExpression '' 65 - { 66 - # create /etc/hostname on container creation. also requires networking.hostName = "" to be set 67 - "hostname" = { 68 - enable = true; 69 - target = "/etc/hostname"; 70 - template = builtins.toFile "hostname.tpl" "{{ container.name }}"; 71 - when = [ "create" ]; 72 - }; 73 - # create /etc/nixos/hostname.nix with a configuration for keeping the hostname applied 74 - "hostname-nix" = { 75 - enable = true; 76 - target = "/etc/nixos/hostname.nix"; 77 - template = builtins.toFile "hostname-nix.tpl" "{ ... }: { networking.hostName = \"{{ container.name }}\"; }"; 78 - # copy keeps the file updated when the container is changed 79 - when = [ "create" "copy" ]; 80 - }; 81 - # copy allow the user to specify a custom configuration.nix 82 - "configuration-nix" = { 83 - enable = true; 84 - target = "/etc/nixos/configuration.nix"; 85 - template = builtins.toFile "configuration-nix" "{{ config_get(\"user.user-data\", properties.default) }}"; 86 - when = [ "create" ]; 87 - }; 88 - }; 89 - ''; 90 - }; 91 - 92 - privilegedContainer = mkOption { 93 - type = types.bool; 12 + privilegedContainer = lib.mkOption { 13 + type = lib.types.bool; 94 14 default = false; 95 15 description = lib.mdDoc '' 96 16 Whether this LXC container will be running as a privileged container or not. If set to `true` then ··· 116 36 ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system 117 37 ''; 118 38 119 - system.build.metadata = pkgs.callPackage ../../lib/make-system-tarball.nix { 120 - contents = [ 121 - { 122 - source = toYAML "metadata.yaml" { 123 - architecture = builtins.elemAt (builtins.match "^([a-z0-9_]+).+" (toString pkgs.system)) 0; 124 - creation_date = 1; 125 - properties = { 126 - description = "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} ${pkgs.system}"; 127 - os = "${config.system.nixos.distroId}"; 128 - release = "${config.system.nixos.codeName}"; 129 - }; 130 - templates = templates.properties; 131 - }; 132 - target = "/metadata.yaml"; 133 - } 134 - ] ++ templates.files; 135 - }; 136 - 137 39 # TODO: build rootfs as squashfs for faster unpack 138 40 system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix { 139 41 extraArgs = "--owner=0"; ··· 180 82 ProtectKernelTunables=no 181 83 NoNewPrivileges=no 182 84 LoadCredential= 183 - '' + optionalString cfg.privilegedContainer '' 85 + '' + lib.optionalString cfg.privilegedContainer '' 184 86 # Additional settings for privileged containers 185 87 ProtectHome=no 186 88 ProtectSystem=no ··· 193 95 }) 194 96 ]; 195 97 196 - # Allow the user to login as root without password. 197 - users.users.root.initialHashedPassword = mkOverride 150 ""; 198 - 199 - system.activationScripts.installInitScript = mkForce '' 98 + system.activationScripts.installInitScript = lib.mkForce '' 200 99 ln -fs $systemConfig/init /sbin/init 201 100 ''; 202 - 203 - # Some more help text. 204 - services.getty.helpLine = 205 - '' 206 - 207 - Log in as "root" with an empty password. 208 - ''; 209 - 210 - # Containers should be light-weight, so start sshd on demand. 211 - services.openssh.enable = mkDefault true; 212 - services.openssh.startWhenNeeded = mkDefault true; 213 - 214 - # As this is intended as a standalone image, undo some of the minimal profile stuff 215 - environment.noXlibs = false; 216 - documentation.enable = true; 217 - documentation.nixos.enable = true; 218 - services.logrotate.enable = true; 219 101 }; 220 102 }
+104
nixos/modules/virtualisation/lxc-image-metadata.nix
··· 1 + { lib, config, pkgs, ... }: 2 + 3 + let 4 + templateSubmodule = {...}: { 5 + options = { 6 + enable = lib.mkEnableOption "this template"; 7 + 8 + target = lib.mkOption { 9 + description = "Path in the container"; 10 + type = lib.types.path; 11 + }; 12 + template = lib.mkOption { 13 + description = ".tpl file for rendering the target"; 14 + type = lib.types.path; 15 + }; 16 + when = lib.mkOption { 17 + description = "Events which trigger a rewrite (create, copy)"; 18 + type = lib.types.listOf (lib.types.str); 19 + }; 20 + properties = lib.mkOption { 21 + description = "Additional properties"; 22 + type = lib.types.attrs; 23 + default = {}; 24 + }; 25 + }; 26 + }; 27 + 28 + toYAML = name: data: pkgs.writeText name (lib.generators.toYAML {} data); 29 + 30 + cfg = config.virtualisation.lxc; 31 + templates = if cfg.templates != {} then let 32 + list = lib.mapAttrsToList (name: value: { inherit name; } // value) 33 + (lib.filterAttrs (name: value: value.enable) cfg.templates); 34 + in 35 + { 36 + files = map (tpl: { 37 + source = tpl.template; 38 + target = "/templates/${tpl.name}.tpl"; 39 + }) list; 40 + properties = lib.listToAttrs (map (tpl: lib.nameValuePair tpl.target { 41 + when = tpl.when; 42 + template = "${tpl.name}.tpl"; 43 + properties = tpl.properties; 44 + }) list); 45 + } 46 + else { files = []; properties = {}; }; 47 + 48 + in { 49 + options = { 50 + virtualisation.lxc = { 51 + templates = lib.mkOption { 52 + description = "Templates for LXD"; 53 + type = lib.types.attrsOf (lib.types.submodule templateSubmodule); 54 + default = {}; 55 + example = lib.literalExpression '' 56 + { 57 + # create /etc/hostname on container creation 58 + "hostname" = { 59 + enable = true; 60 + target = "/etc/hostname"; 61 + template = builtins.writeFile "hostname.tpl" "{{ container.name }}"; 62 + when = [ "create" ]; 63 + }; 64 + # create /etc/nixos/hostname.nix with a configuration for keeping the hostname applied 65 + "hostname-nix" = { 66 + enable = true; 67 + target = "/etc/nixos/hostname.nix"; 68 + template = builtins.writeFile "hostname-nix.tpl" "{ ... }: { networking.hostName = "{{ container.name }}"; }"; 69 + # copy keeps the file updated when the container is changed 70 + when = [ "create" "copy" ]; 71 + }; 72 + # copy allow the user to specify a custom configuration.nix 73 + "configuration-nix" = { 74 + enable = true; 75 + target = "/etc/nixos/configuration.nix"; 76 + template = builtins.writeFile "configuration-nix" "{{ config_get(\"user.user-data\", properties.default) }}"; 77 + when = [ "create" ]; 78 + }; 79 + }; 80 + ''; 81 + }; 82 + }; 83 + }; 84 + 85 + config = { 86 + system.build.metadata = pkgs.callPackage ../../lib/make-system-tarball.nix { 87 + contents = [ 88 + { 89 + source = toYAML "metadata.yaml" { 90 + architecture = builtins.elemAt (builtins.match "^([a-z0-9_]+).+" (toString pkgs.system)) 0; 91 + creation_date = 1; 92 + properties = { 93 + description = "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} ${pkgs.system}"; 94 + os = "${config.system.nixos.distroId}"; 95 + release = "${config.system.nixos.codeName}"; 96 + }; 97 + templates = templates.properties; 98 + }; 99 + target = "/metadata.yaml"; 100 + } 101 + ] ++ templates.files; 102 + }; 103 + }; 104 + }
+30
nixos/modules/virtualisation/lxc-instance-common.nix
··· 1 + {lib, ...}: 2 + 3 + { 4 + imports = [ 5 + ./lxc-image-metadata.nix 6 + 7 + ../installer/cd-dvd/channel.nix 8 + ../profiles/clone-config.nix 9 + ../profiles/minimal.nix 10 + ]; 11 + 12 + # Allow the user to login as root without password. 13 + users.users.root.initialHashedPassword = lib.mkOverride 150 ""; 14 + 15 + # Some more help text. 16 + services.getty.helpLine = '' 17 + 18 + Log in as "root" with an empty password. 19 + ''; 20 + 21 + # Containers should be light-weight, so start sshd on demand. 22 + services.openssh.enable = lib.mkDefault true; 23 + services.openssh.startWhenNeeded = lib.mkDefault true; 24 + 25 + # As this is intended as a standalone image, undo some of the minimal profile stuff 26 + environment.noXlibs = false; 27 + documentation.enable = true; 28 + documentation.nixos.enable = true; 29 + services.logrotate.enable = true; 30 + }
+46
nixos/modules/virtualisation/lxd-virtual-machine.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + let 4 + serialDevice = 5 + if pkgs.stdenv.hostPlatform.isx86 6 + then "ttyS0" 7 + else "ttyAMA0"; # aarch64 8 + in { 9 + imports = [ 10 + ./lxc-instance-common.nix 11 + 12 + ../profiles/qemu-guest.nix 13 + ]; 14 + 15 + config = { 16 + system.build.qemuImage = import ../../lib/make-disk-image.nix { 17 + inherit pkgs lib config; 18 + 19 + partitionTableType = "efi"; 20 + format = "qcow2-compressed"; 21 + copyChannel = true; 22 + }; 23 + 24 + fileSystems = { 25 + "/" = { 26 + device = "/dev/disk/by-label/nixos"; 27 + autoResize = true; 28 + fsType = "ext4"; 29 + }; 30 + "/boot" = { 31 + device = "/dev/disk/by-label/ESP"; 32 + fsType = "vfat"; 33 + }; 34 + }; 35 + 36 + boot.growPartition = true; 37 + boot.loader.systemd-boot.enable = true; 38 + 39 + # image building needs to know what device to install bootloader on 40 + boot.loader.grub.device = "/dev/vda"; 41 + 42 + boot.kernelParams = ["console=tty1" "console=${serialDevice}"]; 43 + 44 + virtualisation.lxd.agent.enable = lib.mkDefault true; 45 + }; 46 + }
+1 -1
nixos/modules/virtualisation/lxd.nix
··· 196 196 "kernel.keys.maxkeys" = 2000; 197 197 }; 198 198 199 - boot.kernelModules = [ "veth" "xt_comment" "xt_CHECKSUM" "xt_MASQUERADE" ] 199 + boot.kernelModules = [ "veth" "xt_comment" "xt_CHECKSUM" "xt_MASQUERADE" "vhost_vsock" ] 200 200 ++ optionals (!config.networking.nftables.enable) [ "iptable_mangle" ]; 201 201 }; 202 202 }
+36 -4
nixos/release.nix
··· 313 313 ); 314 314 315 315 # An image that can be imported into lxd and used for container creation 316 - lxdImage = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system: 316 + lxdContainerImage = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system: 317 317 318 318 with import ./.. { inherit system; }; 319 319 ··· 322 322 modules = 323 323 [ configuration 324 324 versionModule 325 - ./maintainers/scripts/lxd/lxd-image.nix 325 + ./maintainers/scripts/lxd/lxd-container-image.nix 326 326 ]; 327 327 }).config.system.build.tarball) 328 328 329 329 ); 330 330 331 331 # Metadata for the lxd image 332 - lxdMeta = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system: 332 + lxdContainerMeta = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system: 333 333 334 334 with import ./.. { inherit system; }; 335 335 ··· 338 338 modules = 339 339 [ configuration 340 340 versionModule 341 - ./maintainers/scripts/lxd/lxd-image.nix 341 + ./maintainers/scripts/lxd/lxd-container-image.nix 342 + ]; 343 + }).config.system.build.metadata) 344 + 345 + ); 346 + 347 + # An image that can be imported into lxd and used for container creation 348 + lxdVirtualMachineImage = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system: 349 + 350 + with import ./.. { inherit system; }; 351 + 352 + hydraJob ((import lib/eval-config.nix { 353 + inherit system; 354 + modules = 355 + [ configuration 356 + versionModule 357 + ./maintainers/scripts/lxd/lxd-virtual-machine-image.nix 358 + ]; 359 + }).config.system.build.qemuImage) 360 + 361 + ); 362 + 363 + # Metadata for the lxd image 364 + lxdVirtualMachineImageMeta = forMatchingSystems [ "x86_64-linux" "aarch64-linux" ] (system: 365 + 366 + with import ./.. { inherit system; }; 367 + 368 + hydraJob ((import lib/eval-config.nix { 369 + inherit system; 370 + modules = 371 + [ configuration 372 + versionModule 373 + ./maintainers/scripts/lxd/lxd-virtual-machine-image.nix 342 374 ]; 343 375 }).config.system.build.metadata) 344 376
+5 -5
nixos/tests/lxd/container.nix
··· 1 1 import ../make-test-python.nix ({ pkgs, lib, ... } : 2 2 3 3 let 4 - lxd-image = import ../../release.nix { 4 + releases = import ../../release.nix { 5 5 configuration = { 6 6 # Building documentation makes the test unnecessarily take a longer time: 7 7 documentation.enable = lib.mkForce false; ··· 11 11 }; 12 12 }; 13 13 14 - lxd-image-metadata = lxd-image.lxdMeta.${pkgs.stdenv.hostPlatform.system}; 15 - lxd-image-rootfs = lxd-image.lxdImage.${pkgs.stdenv.hostPlatform.system}; 14 + lxd-image-metadata = releases.lxdContainerMeta.${pkgs.stdenv.hostPlatform.system}; 15 + lxd-image-rootfs = releases.lxdContainerImage.${pkgs.stdenv.hostPlatform.system}; 16 16 17 17 in { 18 - name = "lxd"; 18 + name = "lxd-container"; 19 19 20 20 meta = with pkgs.lib.maintainers; { 21 - maintainers = [ patryk27 ]; 21 + maintainers = [ patryk27 adamcstephens ]; 22 22 }; 23 23 24 24 nodes.machine = { lib, ... }: {
+1
nixos/tests/lxd/default.nix
··· 6 6 container = import ./container.nix {inherit system pkgs;}; 7 7 nftables = import ./nftables.nix {inherit system pkgs;}; 8 8 ui = import ./ui.nix {inherit system pkgs;}; 9 + virtual-machine = import ./virtual-machine.nix { inherit system pkgs; }; 9 10 }
+64
nixos/tests/lxd/virtual-machine.nix
··· 1 + import ../make-test-python.nix ({ pkgs, lib, ... }: 2 + 3 + let 4 + releases = import ../../release.nix { 5 + configuration = { 6 + # Building documentation makes the test unnecessarily take a longer time: 7 + documentation.enable = lib.mkForce false; 8 + 9 + # Our tests require `grep` & friends: 10 + environment.systemPackages = with pkgs; [busybox]; 11 + }; 12 + }; 13 + 14 + lxd-image-metadata = releases.lxdVirtualMachineImageMeta.${pkgs.stdenv.hostPlatform.system}; 15 + lxd-image-disk = releases.lxdVirtualMachineImage.${pkgs.stdenv.hostPlatform.system}; 16 + 17 + instance-name = "instance1"; 18 + in { 19 + name = "lxd-virtual-machine"; 20 + 21 + meta = with pkgs.lib.maintainers; { 22 + maintainers = [adamcstephens]; 23 + }; 24 + 25 + nodes.machine = {lib, ...}: { 26 + virtualisation = { 27 + diskSize = 4096; 28 + 29 + cores = 2; 30 + 31 + # Ensure we have enough memory for the nested virtual machine 32 + memorySize = 1024; 33 + 34 + lxc.lxcfs.enable = true; 35 + lxd.enable = true; 36 + }; 37 + }; 38 + 39 + testScript = '' 40 + def instance_is_up(_) -> bool: 41 + status, _ = machine.execute("lxc exec ${instance-name} --disable-stdin --force-interactive /run/current-system/sw/bin/true") 42 + return status == 0 43 + 44 + machine.wait_for_unit("sockets.target") 45 + machine.wait_for_unit("lxd.service") 46 + machine.wait_for_file("/var/lib/lxd/unix.socket") 47 + 48 + # Wait for lxd to settle 49 + machine.succeed("lxd waitready") 50 + 51 + machine.succeed("lxd init --minimal") 52 + 53 + with subtest("virtual-machine image can be imported"): 54 + machine.succeed("lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-disk}/nixos.qcow2 --alias nixos") 55 + 56 + with subtest("virtual-machine can be launched and become available"): 57 + machine.succeed("lxc launch nixos ${instance-name} --vm --config limits.memory=512MB --config security.secureboot=false") 58 + with machine.nested("Waiting for instance to start and be usable"): 59 + retry(instance_is_up) 60 + 61 + with subtest("lxd-agent is started"): 62 + machine.succeed("lxc exec ${instance-name} systemctl is-active lxd-agent") 63 + ''; 64 + })