From 56ab4f61bc8f9210f76412c615beef64246e50f3 Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Tue, 3 May 2022 12:24:13 +0200 Subject: [PATCH] nixos/lxd: improve tests - Make tests/lxd.nix use NixOS's lxdMeta & lxdImage to avoid relying on 3rd party containers such as Alpine Linux for testing purposes. - Merge tests/lxd-image.nix into tests/lxd.nix, since now both have a similar structure. - Extract duplicated inline LXD configuration into a separate file, - Add passthru.lxd-nftables & passthru.lxd-image-server. --- nixos/maintainers/scripts/lxd/lxd-image.nix | 2 +- nixos/tests/all-tests.nix | 1 - nixos/tests/common/lxd/config.yaml | 24 ++++ nixos/tests/lxd-image-server.nix | 63 ++------ nixos/tests/lxd-image.nix | 89 ------------ nixos/tests/lxd.nix | 134 ++++++------------ pkgs/tools/admin/lxd/default.nix | 1 + .../lxd-image-server/default.nix | 3 + pkgs/top-level/release-lib.nix | 2 +- 9 files changed, 85 insertions(+), 234 deletions(-) create mode 100644 nixos/tests/common/lxd/config.yaml delete mode 100644 nixos/tests/lxd-image.nix diff --git a/nixos/maintainers/scripts/lxd/lxd-image.nix b/nixos/maintainers/scripts/lxd/lxd-image.nix index c76b9fcc7f7..6aa3f2f5584 100644 --- a/nixos/maintainers/scripts/lxd/lxd-image.nix +++ b/nixos/maintainers/scripts/lxd/lxd-image.nix @@ -27,7 +27,7 @@ with lib; networking.useDHCP = false; networking.interfaces.eth0.useDHCP = true; - # As this is intended as a stadalone image, undo some of the minimal profile stuff + # As this is intended as a standalone image, undo some of the minimal profile stuff documentation.enable = true; documentation.nixos.enable = true; environment.noXlibs = false; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 923464a0c9a..dda1c41f969 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -284,7 +284,6 @@ in loki = handleTest ./loki.nix {}; lvm2 = handleTest ./lvm2 {}; lxd = handleTest ./lxd.nix {}; - lxd-image = handleTest ./lxd-image.nix {}; lxd-nftables = handleTest ./lxd-nftables.nix {}; lxd-image-server = handleTest ./lxd-image-server.nix {}; #logstash = handleTest ./logstash.nix {}; diff --git a/nixos/tests/common/lxd/config.yaml b/nixos/tests/common/lxd/config.yaml new file mode 100644 index 00000000000..3bb667ed43f --- /dev/null +++ b/nixos/tests/common/lxd/config.yaml @@ -0,0 +1,24 @@ +storage_pools: + - name: default + driver: dir + config: + source: /var/lxd-pool + +networks: + - name: lxdbr0 + type: bridge + config: + ipv4.address: auto + ipv6.address: none + +profiles: + - name: default + devices: + eth0: + name: eth0 + network: lxdbr0 + type: nic + root: + path: / + pool: default + type: disk diff --git a/nixos/tests/lxd-image-server.nix b/nixos/tests/lxd-image-server.nix index fa40e33e74d..072f4570c2c 100644 --- a/nixos/tests/lxd-image-server.nix +++ b/nixos/tests/lxd-image-server.nix @@ -1,54 +1,21 @@ -import ./make-test-python.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, lib, ... } : let - # Since we don't have access to the internet during the tests, we have to - # pre-fetch lxd containers beforehand. - # - # I've chosen to import Alpine Linux, because its image is turbo-tiny and, - # generally, sufficient for our tests. - alpine-meta = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz"; - hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA="; - }; - - alpine-rootfs = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz"; - hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA="; + lxd-image = import ../release.nix { + configuration = { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; + }; }; - lxd-config = pkgs.writeText "config.yaml" '' - storage_pools: - - name: default - driver: dir - config: - source: /var/lxd-pool - - networks: - - name: lxdbr0 - type: bridge - config: - ipv4.address: auto - ipv6.address: none - - profiles: - - name: default - devices: - eth0: - name: eth0 - network: lxdbr0 - type: nic - root: - path: / - pool: default - type: disk - ''; - + lxd-image-metadata = lxd-image.lxdMeta.${pkgs.system}; + lxd-image-rootfs = lxd-image.lxdImage.${pkgs.system}; in { name = "lxd-image-server"; meta = with pkgs.lib.maintainers; { - maintainers = [ mkg20001 ]; + maintainers = [ mkg20001 patryk27 ]; }; nodes.machine = { lib, ... }: { @@ -100,20 +67,20 @@ in { # lxd expects the pool's directory to already exist machine.succeed("mkdir /var/lxd-pool") - machine.succeed( - "cat ${lxd-config} | lxd init --preseed" + "cat ${./common/lxd/config.yaml} | lxd init --preseed" ) machine.succeed( - "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine" + "lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-rootfs}/*/*.tar.xz --alias nixos" ) - loc = "/var/www/simplestreams/images/iats/alpine/amd64/default/v1" + loc = "/var/www/simplestreams/images/iats/nixos/amd64/default/v1" with subtest("push image to server"): - machine.succeed("lxc launch alpine test") - machine.succeed("lxc stop test") + machine.succeed("lxc launch nixos test") + machine.sleep(5) + machine.succeed("lxc stop -f test") machine.succeed("lxc publish --public test --alias=testimg") machine.succeed("lxc image export testimg") machine.succeed("ls >&2") diff --git a/nixos/tests/lxd-image.nix b/nixos/tests/lxd-image.nix deleted file mode 100644 index 4930b55f190..00000000000 --- a/nixos/tests/lxd-image.nix +++ /dev/null @@ -1,89 +0,0 @@ -# This test ensures that the nixOS lxd images builds and functions properly -# It has been extracted from `lxd.nix` to seperate failures of just the image and the lxd software - -import ./make-test-python.nix ({ pkgs, ...} : let - release = import ../release.nix { - /* configuration = { - environment.systemPackages = with pkgs; [ stdenv ]; # inject stdenv so rebuild test works - }; */ - }; - - metadata = release.lxdMeta.${pkgs.system}; - image = release.lxdImage.${pkgs.system}; - - lxd-config = pkgs.writeText "config.yaml" '' - storage_pools: - - name: default - driver: dir - config: - source: /var/lxd-pool - - networks: - - name: lxdbr0 - type: bridge - config: - ipv4.address: auto - ipv6.address: none - - profiles: - - name: default - devices: - eth0: - name: eth0 - network: lxdbr0 - type: nic - root: - path: / - pool: default - type: disk - ''; -in { - name = "lxd-image"; - - meta = with pkgs.lib.maintainers; { - maintainers = [ mkg20001 ]; - }; - - nodes.machine = { lib, ... }: { - virtualisation = { - # disk full otherwise - diskSize = 2048; - - lxc.lxcfs.enable = true; - lxd.enable = true; - }; - }; - - testScript = '' - machine.wait_for_unit("sockets.target") - machine.wait_for_unit("lxd.service") - machine.wait_for_file("/var/lib/lxd/unix.socket") - - # It takes additional second for lxd to settle - machine.sleep(1) - - # lxd expects the pool's directory to already exist - machine.succeed("mkdir /var/lxd-pool") - - machine.succeed( - "cat ${lxd-config} | lxd init --preseed" - ) - - # TODO: test custom built container aswell - - with subtest("importing container works"): - machine.succeed("lxc image import ${metadata}/*/*.tar.xz ${image}/*/*.tar.xz --alias nixos") - - with subtest("launching container works"): - machine.succeed("lxc launch nixos machine -c security.nesting=true") - # make sure machine boots up properly - machine.sleep(5) - - with subtest("container shell works"): - machine.succeed("echo true | lxc exec machine /run/current-system/sw/bin/bash -") - machine.succeed("lxc exec machine /run/current-system/sw/bin/true") - - # with subtest("rebuilding works"): - # machine.succeed("lxc exec machine /run/current-system/sw/bin/nixos-rebuild switch") - ''; -}) diff --git a/nixos/tests/lxd.nix b/nixos/tests/lxd.nix index 162bbcc47e8..15d16564d64 100644 --- a/nixos/tests/lxd.nix +++ b/nixos/tests/lxd.nix @@ -1,79 +1,18 @@ -import ./make-test-python.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, lib, ... } : let - # Since we don't have access to the internet during the tests, we have to - # pre-fetch lxd containers beforehand. - # - # I've chosen to import Alpine Linux, because its image is turbo-tiny and, - # generally, sufficient for our tests. - alpine-meta-x86 = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz"; - hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA="; - }; - alpine-meta-for = arch: pkgs.stdenv.mkDerivation { - name = "alpine-meta-${arch}"; - version = "3.12"; - unpackPhase = "true"; - buildPhase = '' - runHook preBuild - - tar xvf ${alpine-meta-x86} - sed -i 's/architecture: .*/architecture: ${arch}/' metadata.yaml - - runHook postBuild - ''; - installPhase = '' - runHook preInstall - - tar czRf $out * - - runHook postInstall - ''; - }; + lxd-image = import ../release.nix { + configuration = { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; - alpine-meta = { - x86_64-linux = alpine-meta-x86; - aarch64-linux = alpine-meta-for "aarch64"; - }.${pkgs.system} or (throw "Unsupported system: ${pkgs.system}"); - - alpine-rootfs = { - x86_64-linux = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz"; - hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA="; - }; - aarch64-linux = pkgs.fetchurl { - url = "https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/aarch64/alpine-minirootfs-3.15.4-aarch64.tar.gz"; - hash = "sha256-9kBz8Jwmo8XepJhTMt5zilCaHHpflnUH7y9+0To39Us="; + # Our tests require `grep` & friends: + environment.systemPackages = with pkgs; [ busybox ]; }; - }.${pkgs.system} or (throw "Unsupported system: ${pkgs.system}"); - - lxd-config = pkgs.writeText "config.yaml" '' - storage_pools: - - name: default - driver: dir - config: - source: /var/lxd-pool - - networks: - - name: lxdbr0 - type: bridge - config: - ipv4.address: auto - ipv6.address: none - - profiles: - - name: default - devices: - eth0: - name: eth0 - network: lxdbr0 - type: nic - root: - path: / - pool: default - type: disk - ''; + }; + lxd-image-metadata = lxd-image.lxdMeta.${pkgs.system}; + lxd-image-rootfs = lxd-image.lxdImage.${pkgs.system}; in { name = "lxd"; @@ -84,6 +23,8 @@ in { nodes.machine = { lib, ... }: { virtualisation = { + diskSize = 2048; + # Since we're testing `limits.cpu`, we've gotta have a known number of # cores to lean on cores = 2; @@ -108,61 +49,66 @@ in { machine.succeed("mkdir /var/lxd-pool") machine.succeed( - "cat ${lxd-config} | lxd init --preseed" + "cat ${./common/lxd/config.yaml} | lxd init --preseed" ) machine.succeed( - "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine" + "lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-rootfs}/*/*.tar.xz --alias nixos" ) - with subtest("Containers can be launched and destroyed"): - machine.succeed("lxc launch alpine test") - machine.succeed("lxc exec test true") - machine.succeed("lxc delete -f test") + with subtest("Container can be managed"): + machine.succeed("lxc launch nixos container") + machine.sleep(5) + machine.succeed("echo true | lxc exec container /run/current-system/sw/bin/bash -") + machine.succeed("lxc exec container true") + machine.succeed("lxc delete -f container") - with subtest("Containers are being mounted with lxcfs inside"): - machine.succeed("lxc launch alpine test") + with subtest("Container is mounted with lxcfs inside"): + machine.succeed("lxc launch nixos container") + machine.sleep(5) ## ---------- ## ## limits.cpu ## - machine.succeed("lxc config set test limits.cpu 1") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.cpu 1") + machine.succeed("lxc restart container") + machine.sleep(5) - # Since Alpine doesn't have `nproc` pre-installed, we've gotta resort - # to the primal methods assert ( "1" - == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip() + == machine.succeed("lxc exec container grep -- -c ^processor /proc/cpuinfo").strip() ) - machine.succeed("lxc config set test limits.cpu 2") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.cpu 2") + machine.succeed("lxc restart container") + machine.sleep(5) assert ( "2" - == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip() + == machine.succeed("lxc exec container grep -- -c ^processor /proc/cpuinfo").strip() ) ## ------------- ## ## limits.memory ## - machine.succeed("lxc config set test limits.memory 64MB") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.memory 64MB") + machine.succeed("lxc restart container") + machine.sleep(5) assert ( "MemTotal: 62500 kB" - == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip() + == machine.succeed("lxc exec container grep -- MemTotal /proc/meminfo").strip() ) - machine.succeed("lxc config set test limits.memory 128MB") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.memory 128MB") + machine.succeed("lxc restart container") + machine.sleep(5) assert ( "MemTotal: 125000 kB" - == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip() + == machine.succeed("lxc exec container grep -- MemTotal /proc/meminfo").strip() ) - machine.succeed("lxc delete -f test") + machine.succeed("lxc delete -f container") ''; }) diff --git a/pkgs/tools/admin/lxd/default.nix b/pkgs/tools/admin/lxd/default.nix index 48cb73be831..0b32c23f65a 100644 --- a/pkgs/tools/admin/lxd/default.nix +++ b/pkgs/tools/admin/lxd/default.nix @@ -48,6 +48,7 @@ buildGo118Package rec { ''; passthru.tests.lxd = nixosTests.lxd; + passthru.tests.lxd-nftables = nixosTests.lxd-nftables; nativeBuildInputs = [ installShellFiles pkg-config makeWrapper ]; buildInputs = [ lxc acl libcap dqlite.dev raft-canonical.dev diff --git a/pkgs/tools/virtualization/lxd-image-server/default.nix b/pkgs/tools/virtualization/lxd-image-server/default.nix index 3a1d32247a4..aeb6ac33693 100644 --- a/pkgs/tools/virtualization/lxd-image-server/default.nix +++ b/pkgs/tools/virtualization/lxd-image-server/default.nix @@ -3,6 +3,7 @@ , rsync , python3 , fetchFromGitHub +, nixosTests }: python3.pkgs.buildPythonApplication rec { @@ -37,6 +38,8 @@ python3.pkgs.buildPythonApplication rec { doCheck = false; + passthru.tests.lxd-image-server = nixosTests.lxd-image-server; + meta = with lib; { description = "Creates and manages a simplestreams lxd image server on top of nginx"; homepage = "https://github.com/Avature/lxd-image-server"; diff --git a/pkgs/top-level/release-lib.nix b/pkgs/top-level/release-lib.nix index ceae00baec9..e066d191ef2 100644 --- a/pkgs/top-level/release-lib.nix +++ b/pkgs/top-level/release-lib.nix @@ -103,7 +103,7 @@ rec { forAllSystems = genAttrs supportedSystems; - # Generate attributes for all sytems matching at least one of the given + # Generate attributes for all systems matching at least one of the given # patterns forMatchingSystems = metaPatterns: genAttrs (supportedMatches metaPatterns);