Skip to content

Commit 8ae7ac9

Browse files
committed
lxd: Add tests
1 parent 6c6924b commit 8ae7ac9

3 files changed

Lines changed: 187 additions & 0 deletions

File tree

nixos/tests/all-tests.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ in
178178
limesurvey = handleTest ./limesurvey.nix {};
179179
login = handleTest ./login.nix {};
180180
loki = handleTest ./loki.nix {};
181+
lxd = handleTest ./lxd.nix {};
182+
lxd-nftables = handleTest ./lxd-nftables.nix {};
181183
#logstash = handleTest ./logstash.nix {};
182184
lorri = handleTest ./lorri/default.nix {};
183185
magnetico = handleTest ./magnetico.nix {};

nixos/tests/lxd-nftables.nix

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# This test makes sure that lxd stops implicitly depending on iptables when
2+
# user enabled nftables.
3+
#
4+
# It has been extracted from `lxd.nix` for clarity, and because switching from
5+
# iptables to nftables requires a full reboot, which is a bit hard inside NixOS
6+
# tests.
7+
8+
import ./make-test-python.nix ({ pkgs, ...} : {
9+
name = "lxd-nftables";
10+
meta = with pkgs.stdenv.lib.maintainers; {
11+
maintainers = [ patryk27 ];
12+
};
13+
14+
machine = { lib, ... }: {
15+
virtualisation = {
16+
lxd.enable = true;
17+
};
18+
19+
networking = {
20+
firewall.enable = false;
21+
nftables.enable = true;
22+
nftables.ruleset = ''
23+
table inet filter {
24+
chain incoming {
25+
type filter hook input priority 0;
26+
policy accept;
27+
}
28+
29+
chain forward {
30+
type filter hook forward priority 0;
31+
policy accept;
32+
}
33+
34+
chain output {
35+
type filter hook output priority 0;
36+
policy accept;
37+
}
38+
}
39+
'';
40+
};
41+
};
42+
43+
testScript = ''
44+
machine.wait_for_unit("network.target")
45+
46+
with subtest("When nftables are enabled, lxd doesn't depend on iptables anymore"):
47+
machine.succeed("lsmod | grep nf_tables")
48+
machine.fail("lsmod | grep ip_tables")
49+
'';
50+
})

nixos/tests/lxd.nix

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import ./make-test-python.nix ({ pkgs, ...} :
2+
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+
10+
alpine-meta = pkgs.fetchurl {
11+
url = "https://uk.images.linuxcontainers.org/images/alpine/3.11/i386/default/20200608_13:00/lxd.tar.xz";
12+
sha256 = "1hkvaj3rr333zmx1759njy435lps33gl4ks8zfm7m4nqvipm26a0";
13+
};
14+
15+
alpine-rootfs = pkgs.fetchurl {
16+
url = "https://uk.images.linuxcontainers.org/images/alpine/3.11/i386/default/20200608_13:00/rootfs.tar.xz";
17+
sha256 = "1v82zdra4j5xwsff09qlp7h5vbsg54s0j7rdg4rynichfid3r347";
18+
};
19+
20+
lxd-config = pkgs.writeText "config.yaml" ''
21+
storage_pools:
22+
- name: default
23+
driver: dir
24+
config:
25+
source: /var/lxd-pool
26+
27+
networks:
28+
- name: lxdbr0
29+
type: bridge
30+
config:
31+
ipv4.address: auto
32+
ipv6.address: none
33+
34+
profiles:
35+
- name: default
36+
devices:
37+
eth0:
38+
name: eth0
39+
network: lxdbr0
40+
type: nic
41+
root:
42+
path: /
43+
pool: default
44+
type: disk
45+
'';
46+
47+
in {
48+
name = "lxd";
49+
meta = with pkgs.stdenv.lib.maintainers; {
50+
maintainers = [ patryk27 ];
51+
};
52+
53+
machine = { lib, ... }: {
54+
virtualisation = {
55+
# Since we're testing `limits.cpu`, we've gotta have a known number of
56+
# cores to lay on
57+
cores = 2;
58+
59+
# Ditto, for `limits.memory`
60+
memorySize = 512;
61+
62+
lxc.lxcfs.enable = true;
63+
lxd.enable = true;
64+
};
65+
};
66+
67+
testScript = ''
68+
machine.wait_for_unit("sockets.target")
69+
machine.wait_for_unit("lxd.service")
70+
71+
# It takes additional second for lxd to settle
72+
machine.sleep(1)
73+
74+
# lxd expects the pool's directory to already exist
75+
machine.succeed("mkdir /var/lxd-pool")
76+
77+
machine.succeed(
78+
"cat ${lxd-config} | lxd init --preseed"
79+
)
80+
81+
machine.succeed(
82+
"lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine"
83+
)
84+
85+
with subtest("Containers can be launched and destroyed"):
86+
machine.succeed("lxc launch alpine test")
87+
machine.succeed("lxc exec test true")
88+
machine.succeed("lxc delete -f test")
89+
90+
with subtest("Containers are being mounted with lxcfs inside"):
91+
machine.succeed("lxc launch alpine test")
92+
93+
## ---------- ##
94+
## limits.cpu ##
95+
96+
machine.succeed("lxc config set test limits.cpu 1")
97+
98+
# Since Alpine doesn't have `nproc` pre-installed, we've gotta resort
99+
# to the primal methods
100+
assert (
101+
"1"
102+
== machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip()
103+
)
104+
105+
machine.succeed("lxc config set test limits.cpu 2")
106+
107+
assert (
108+
"2"
109+
== machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip()
110+
)
111+
112+
## ------------- ##
113+
## limits.memory ##
114+
115+
machine.succeed("lxc config set test limits.memory 64MB")
116+
117+
assert (
118+
"MemTotal: 62500 kB"
119+
== machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip()
120+
)
121+
122+
machine.succeed("lxc config set test limits.memory 128MB")
123+
124+
assert (
125+
"MemTotal: 125000 kB"
126+
== machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip()
127+
)
128+
129+
machine.succeed("lxc delete -f test")
130+
131+
with subtest("Unless explicitly changed, lxd leans on iptables"):
132+
machine.succeed("lsmod | grep ip_tables")
133+
machine.fail("lsmod | grep nf_tables")
134+
'';
135+
})

0 commit comments

Comments
 (0)