nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix

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.

+85 -234
+1 -1
nixos/maintainers/scripts/lxd/lxd-image.nix
··· 27 27 networking.useDHCP = false; 28 28 networking.interfaces.eth0.useDHCP = true; 29 29 30 - # As this is intended as a stadalone image, undo some of the minimal profile stuff 30 + # As this is intended as a standalone image, undo some of the minimal profile stuff 31 31 documentation.enable = true; 32 32 documentation.nixos.enable = true; 33 33 environment.noXlibs = false;
-1
nixos/tests/all-tests.nix
··· 284 284 loki = handleTest ./loki.nix {}; 285 285 lvm2 = handleTest ./lvm2 {}; 286 286 lxd = handleTest ./lxd.nix {}; 287 - lxd-image = handleTest ./lxd-image.nix {}; 288 287 lxd-nftables = handleTest ./lxd-nftables.nix {}; 289 288 lxd-image-server = handleTest ./lxd-image-server.nix {}; 290 289 #logstash = handleTest ./logstash.nix {};
+24
nixos/tests/common/lxd/config.yaml
··· 1 + storage_pools: 2 + - name: default 3 + driver: dir 4 + config: 5 + source: /var/lxd-pool 6 + 7 + networks: 8 + - name: lxdbr0 9 + type: bridge 10 + config: 11 + ipv4.address: auto 12 + ipv6.address: none 13 + 14 + profiles: 15 + - name: default 16 + devices: 17 + eth0: 18 + name: eth0 19 + network: lxdbr0 20 + type: nic 21 + root: 22 + path: / 23 + pool: default 24 + type: disk
+15 -48
nixos/tests/lxd-image-server.nix
··· 1 - import ./make-test-python.nix ({ pkgs, ...} : 1 + import ./make-test-python.nix ({ pkgs, lib, ... } : 2 2 3 3 let 4 - # Since we don't have access to the internet during the tests, we have to 5 - # pre-fetch lxd containers beforehand. 6 - # 7 - # I've chosen to import Alpine Linux, because its image is turbo-tiny and, 8 - # generally, sufficient for our tests. 9 - alpine-meta = pkgs.fetchurl { 10 - url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz"; 11 - hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA="; 4 + lxd-image = import ../release.nix { 5 + configuration = { 6 + # Building documentation makes the test unnecessarily take a longer time: 7 + documentation.enable = lib.mkForce false; 8 + }; 12 9 }; 13 10 14 - alpine-rootfs = pkgs.fetchurl { 15 - url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz"; 16 - hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA="; 17 - }; 18 - 19 - lxd-config = pkgs.writeText "config.yaml" '' 20 - storage_pools: 21 - - name: default 22 - driver: dir 23 - config: 24 - source: /var/lxd-pool 25 - 26 - networks: 27 - - name: lxdbr0 28 - type: bridge 29 - config: 30 - ipv4.address: auto 31 - ipv6.address: none 32 - 33 - profiles: 34 - - name: default 35 - devices: 36 - eth0: 37 - name: eth0 38 - network: lxdbr0 39 - type: nic 40 - root: 41 - path: / 42 - pool: default 43 - type: disk 44 - ''; 45 - 11 + lxd-image-metadata = lxd-image.lxdMeta.${pkgs.system}; 12 + lxd-image-rootfs = lxd-image.lxdImage.${pkgs.system}; 46 13 47 14 in { 48 15 name = "lxd-image-server"; 49 16 50 17 meta = with pkgs.lib.maintainers; { 51 - maintainers = [ mkg20001 ]; 18 + maintainers = [ mkg20001 patryk27 ]; 52 19 }; 53 20 54 21 nodes.machine = { lib, ... }: { ··· 67 100 # lxd expects the pool's directory to already exist 68 101 machine.succeed("mkdir /var/lxd-pool") 69 102 70 - 71 103 machine.succeed( 72 - "cat ${lxd-config} | lxd init --preseed" 104 + "cat ${./common/lxd/config.yaml} | lxd init --preseed" 73 105 ) 74 106 75 107 machine.succeed( 76 - "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine" 108 + "lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-rootfs}/*/*.tar.xz --alias nixos" 77 109 ) 78 110 79 - loc = "/var/www/simplestreams/images/iats/alpine/amd64/default/v1" 111 + loc = "/var/www/simplestreams/images/iats/nixos/amd64/default/v1" 80 112 81 113 with subtest("push image to server"): 82 - machine.succeed("lxc launch alpine test") 83 - machine.succeed("lxc stop test") 114 + machine.succeed("lxc launch nixos test") 115 + machine.sleep(5) 116 + machine.succeed("lxc stop -f test") 84 117 machine.succeed("lxc publish --public test --alias=testimg") 85 118 machine.succeed("lxc image export testimg") 86 119 machine.succeed("ls >&2")
-89
nixos/tests/lxd-image.nix
··· 1 - # This test ensures that the nixOS lxd images builds and functions properly 2 - # It has been extracted from `lxd.nix` to seperate failures of just the image and the lxd software 3 - 4 - import ./make-test-python.nix ({ pkgs, ...} : let 5 - release = import ../release.nix { 6 - /* configuration = { 7 - environment.systemPackages = with pkgs; [ stdenv ]; # inject stdenv so rebuild test works 8 - }; */ 9 - }; 10 - 11 - metadata = release.lxdMeta.${pkgs.system}; 12 - image = release.lxdImage.${pkgs.system}; 13 - 14 - lxd-config = pkgs.writeText "config.yaml" '' 15 - storage_pools: 16 - - name: default 17 - driver: dir 18 - config: 19 - source: /var/lxd-pool 20 - 21 - networks: 22 - - name: lxdbr0 23 - type: bridge 24 - config: 25 - ipv4.address: auto 26 - ipv6.address: none 27 - 28 - profiles: 29 - - name: default 30 - devices: 31 - eth0: 32 - name: eth0 33 - network: lxdbr0 34 - type: nic 35 - root: 36 - path: / 37 - pool: default 38 - type: disk 39 - ''; 40 - in { 41 - name = "lxd-image"; 42 - 43 - meta = with pkgs.lib.maintainers; { 44 - maintainers = [ mkg20001 ]; 45 - }; 46 - 47 - nodes.machine = { lib, ... }: { 48 - virtualisation = { 49 - # disk full otherwise 50 - diskSize = 2048; 51 - 52 - lxc.lxcfs.enable = true; 53 - lxd.enable = true; 54 - }; 55 - }; 56 - 57 - testScript = '' 58 - machine.wait_for_unit("sockets.target") 59 - machine.wait_for_unit("lxd.service") 60 - machine.wait_for_file("/var/lib/lxd/unix.socket") 61 - 62 - # It takes additional second for lxd to settle 63 - machine.sleep(1) 64 - 65 - # lxd expects the pool's directory to already exist 66 - machine.succeed("mkdir /var/lxd-pool") 67 - 68 - machine.succeed( 69 - "cat ${lxd-config} | lxd init --preseed" 70 - ) 71 - 72 - # TODO: test custom built container aswell 73 - 74 - with subtest("importing container works"): 75 - machine.succeed("lxc image import ${metadata}/*/*.tar.xz ${image}/*/*.tar.xz --alias nixos") 76 - 77 - with subtest("launching container works"): 78 - machine.succeed("lxc launch nixos machine -c security.nesting=true") 79 - # make sure machine boots up properly 80 - machine.sleep(5) 81 - 82 - with subtest("container shell works"): 83 - machine.succeed("echo true | lxc exec machine /run/current-system/sw/bin/bash -") 84 - machine.succeed("lxc exec machine /run/current-system/sw/bin/true") 85 - 86 - # with subtest("rebuilding works"): 87 - # machine.succeed("lxc exec machine /run/current-system/sw/bin/nixos-rebuild switch") 88 - ''; 89 - })
+40 -94
nixos/tests/lxd.nix
··· 1 - import ./make-test-python.nix ({ pkgs, ...} : 1 + import ./make-test-python.nix ({ pkgs, lib, ... } : 2 2 3 3 let 4 - # Since we don't have access to the internet during the tests, we have to 5 - # pre-fetch lxd containers beforehand. 6 - # 7 - # I've chosen to import Alpine Linux, because its image is turbo-tiny and, 8 - # generally, sufficient for our tests. 9 - alpine-meta-x86 = pkgs.fetchurl { 10 - url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz"; 11 - hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA="; 12 - }; 13 - alpine-meta-for = arch: pkgs.stdenv.mkDerivation { 14 - name = "alpine-meta-${arch}"; 15 - version = "3.12"; 16 - unpackPhase = "true"; 17 - buildPhase = '' 18 - runHook preBuild 4 + lxd-image = import ../release.nix { 5 + configuration = { 6 + # Building documentation makes the test unnecessarily take a longer time: 7 + documentation.enable = lib.mkForce false; 19 8 20 - tar xvf ${alpine-meta-x86} 21 - sed -i 's/architecture: .*/architecture: ${arch}/' metadata.yaml 22 - 23 - runHook postBuild 24 - ''; 25 - installPhase = '' 26 - runHook preInstall 27 - 28 - tar czRf $out * 29 - 30 - runHook postInstall 31 - ''; 9 + # Our tests require `grep` & friends: 10 + environment.systemPackages = with pkgs; [ busybox ]; 11 + }; 32 12 }; 33 13 34 - alpine-meta = { 35 - x86_64-linux = alpine-meta-x86; 36 - aarch64-linux = alpine-meta-for "aarch64"; 37 - }.${pkgs.system} or (throw "Unsupported system: ${pkgs.system}"); 38 - 39 - alpine-rootfs = { 40 - x86_64-linux = pkgs.fetchurl { 41 - url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz"; 42 - hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA="; 43 - }; 44 - aarch64-linux = pkgs.fetchurl { 45 - url = "https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/aarch64/alpine-minirootfs-3.15.4-aarch64.tar.gz"; 46 - hash = "sha256-9kBz8Jwmo8XepJhTMt5zilCaHHpflnUH7y9+0To39Us="; 47 - }; 48 - }.${pkgs.system} or (throw "Unsupported system: ${pkgs.system}"); 49 - 50 - lxd-config = pkgs.writeText "config.yaml" '' 51 - storage_pools: 52 - - name: default 53 - driver: dir 54 - config: 55 - source: /var/lxd-pool 56 - 57 - networks: 58 - - name: lxdbr0 59 - type: bridge 60 - config: 61 - ipv4.address: auto 62 - ipv6.address: none 63 - 64 - profiles: 65 - - name: default 66 - devices: 67 - eth0: 68 - name: eth0 69 - network: lxdbr0 70 - type: nic 71 - root: 72 - path: / 73 - pool: default 74 - type: disk 75 - ''; 76 - 14 + lxd-image-metadata = lxd-image.lxdMeta.${pkgs.system}; 15 + lxd-image-rootfs = lxd-image.lxdImage.${pkgs.system}; 77 16 78 17 in { 79 18 name = "lxd"; ··· 23 84 24 85 nodes.machine = { lib, ... }: { 25 86 virtualisation = { 87 + diskSize = 2048; 88 + 26 89 # Since we're testing `limits.cpu`, we've gotta have a known number of 27 90 # cores to lean on 28 91 cores = 2; ··· 49 108 machine.succeed("mkdir /var/lxd-pool") 50 109 51 110 machine.succeed( 52 - "cat ${lxd-config} | lxd init --preseed" 111 + "cat ${./common/lxd/config.yaml} | lxd init --preseed" 53 112 ) 54 113 55 114 machine.succeed( 56 - "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine" 115 + "lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-rootfs}/*/*.tar.xz --alias nixos" 57 116 ) 58 117 59 - with subtest("Containers can be launched and destroyed"): 60 - machine.succeed("lxc launch alpine test") 61 - machine.succeed("lxc exec test true") 62 - machine.succeed("lxc delete -f test") 118 + with subtest("Container can be managed"): 119 + machine.succeed("lxc launch nixos container") 120 + machine.sleep(5) 121 + machine.succeed("echo true | lxc exec container /run/current-system/sw/bin/bash -") 122 + machine.succeed("lxc exec container true") 123 + machine.succeed("lxc delete -f container") 63 124 64 - with subtest("Containers are being mounted with lxcfs inside"): 65 - machine.succeed("lxc launch alpine test") 125 + with subtest("Container is mounted with lxcfs inside"): 126 + machine.succeed("lxc launch nixos container") 127 + machine.sleep(5) 66 128 67 129 ## ---------- ## 68 130 ## limits.cpu ## 69 131 70 - machine.succeed("lxc config set test limits.cpu 1") 71 - machine.succeed("lxc restart test") 132 + machine.succeed("lxc config set container limits.cpu 1") 133 + machine.succeed("lxc restart container") 134 + machine.sleep(5) 72 135 73 - # Since Alpine doesn't have `nproc` pre-installed, we've gotta resort 74 - # to the primal methods 75 136 assert ( 76 137 "1" 77 - == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip() 138 + == machine.succeed("lxc exec container grep -- -c ^processor /proc/cpuinfo").strip() 78 139 ) 79 140 80 - machine.succeed("lxc config set test limits.cpu 2") 81 - machine.succeed("lxc restart test") 141 + machine.succeed("lxc config set container limits.cpu 2") 142 + machine.succeed("lxc restart container") 143 + machine.sleep(5) 82 144 83 145 assert ( 84 146 "2" 85 - == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip() 147 + == machine.succeed("lxc exec container grep -- -c ^processor /proc/cpuinfo").strip() 86 148 ) 87 149 88 150 ## ------------- ## 89 151 ## limits.memory ## 90 152 91 - machine.succeed("lxc config set test limits.memory 64MB") 92 - machine.succeed("lxc restart test") 153 + machine.succeed("lxc config set container limits.memory 64MB") 154 + machine.succeed("lxc restart container") 155 + machine.sleep(5) 93 156 94 157 assert ( 95 158 "MemTotal: 62500 kB" 96 - == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip() 159 + == machine.succeed("lxc exec container grep -- MemTotal /proc/meminfo").strip() 97 160 ) 98 161 99 - machine.succeed("lxc config set test limits.memory 128MB") 100 - machine.succeed("lxc restart test") 162 + machine.succeed("lxc config set container limits.memory 128MB") 163 + machine.succeed("lxc restart container") 164 + machine.sleep(5) 101 165 102 166 assert ( 103 167 "MemTotal: 125000 kB" 104 - == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip() 168 + == machine.succeed("lxc exec container grep -- MemTotal /proc/meminfo").strip() 105 169 ) 106 170 107 - machine.succeed("lxc delete -f test") 171 + machine.succeed("lxc delete -f container") 108 172 ''; 109 173 })
+1
pkgs/tools/admin/lxd/default.nix
··· 48 48 ''; 49 49 50 50 passthru.tests.lxd = nixosTests.lxd; 51 + passthru.tests.lxd-nftables = nixosTests.lxd-nftables; 51 52 52 53 nativeBuildInputs = [ installShellFiles pkg-config makeWrapper ]; 53 54 buildInputs = [ lxc acl libcap dqlite.dev raft-canonical.dev
+3
pkgs/tools/virtualization/lxd-image-server/default.nix
··· 3 3 , rsync 4 4 , python3 5 5 , fetchFromGitHub 6 + , nixosTests 6 7 }: 7 8 8 9 python3.pkgs.buildPythonApplication rec { ··· 37 36 ]; 38 37 39 38 doCheck = false; 39 + 40 + passthru.tests.lxd-image-server = nixosTests.lxd-image-server; 40 41 41 42 meta = with lib; { 42 43 description = "Creates and manages a simplestreams lxd image server on top of nginx";
+1 -1
pkgs/top-level/release-lib.nix
··· 103 103 forAllSystems = genAttrs supportedSystems; 104 104 105 105 106 - # Generate attributes for all sytems matching at least one of the given 106 + # Generate attributes for all systems matching at least one of the given 107 107 # patterns 108 108 forMatchingSystems = metaPatterns: genAttrs (supportedMatches metaPatterns); 109 109