1{ lib, ... }:
2let
3 execOptions = [
4 "Boot"
5 "ProcessTwo"
6 "Parameters"
7 "Environment"
8 "User"
9 "WorkingDirectory"
10 "PivotRoot"
11 "Capability"
12 "DropCapability"
13 "NoNewPrivileges"
14 "KillSignal"
15 "Personality"
16 "MachineID"
17 "PrivateUsers"
18 "NotifyReady"
19 "SystemCallFilter"
20 "LimitCPU"
21 "LimitFSIZE"
22 "LimitDATA"
23 "LimitSTACK"
24 "LimitCORE"
25 "LimitRSS"
26 "LimitNOFILE"
27 "LimitAS"
28 "LimitNPROC"
29 "LimitMEMLOCK"
30 "LimitLOCKS"
31 "LimitSIGPENDING"
32 "LimitMSGQUEUE"
33 "LimitNICE"
34 "LimitRTPRIO"
35 "LimitRTTIME"
36 "OOMScoreAdjust"
37 "CPUAffinity"
38 "Hostname"
39 "ResolvConf"
40 "Timezone"
41 "LinkJournal"
42 "Ephemeral"
43 "AmbientCapability"
44 ];
45
46 filesOptions = [
47 "ReadOnly"
48 "Volatile"
49 "Bind"
50 "BindReadOnly"
51 "TemporaryFileSystem"
52 "Overlay"
53 "OverlayReadOnly"
54 "PrivateUsersChown"
55 "BindUser"
56 "Inaccessible"
57 "PrivateUsersOwnership"
58 ];
59
60 networkOptions = [
61 "Private"
62 "VirtualEthernet"
63 "VirtualEthernetExtra"
64 "Interface"
65 "MACVLAN"
66 "IPVLAN"
67 "Bridge"
68 "Zone"
69 "Port"
70 ];
71
72 optionsToConfig = opts: builtins.listToAttrs (map (n: lib.nameValuePair n "testdata") opts);
73
74 grepForOptions = opts: ''
75 node.succeed(
76 "for o in ${builtins.concatStringsSep " " opts} ; do grep --quiet $o ${configFile} || exit 1 ; done"
77 )'';
78
79 unitName = "options-test";
80 configFile = "/etc/systemd/nspawn/${unitName}.nspawn";
81
82in
83{
84 name = "systemd-nspawn-configfile";
85
86 nodes = {
87 node =
88 { pkgs, ... }:
89 {
90 systemd.nspawn."${unitName}" = {
91 enable = true;
92
93 execConfig = optionsToConfig execOptions // {
94 Boot = true;
95 ProcessTwo = true;
96 NotifyReady = true;
97 };
98
99 filesConfig = optionsToConfig filesOptions // {
100 ReadOnly = true;
101 Volatile = "state";
102 PrivateUsersChown = true;
103 PrivateUsersOwnership = "auto";
104 };
105
106 networkConfig = optionsToConfig networkOptions // {
107 Private = true;
108 VirtualEthernet = true;
109 };
110 };
111 };
112 };
113
114 testScript = ''
115 start_all()
116
117 node.wait_for_file("${configFile}")
118
119 with subtest("Test for presence of all specified options in config file"):
120 ${grepForOptions execOptions}
121 ${grepForOptions filesOptions}
122 ${grepForOptions networkOptions}
123
124 with subtest("Test for absence of misspelled option 'MachineId' (instead of 'MachineID')"):
125 node.fail("grep --quiet MachineId ${configFile}")
126 '';
127
128 meta.maintainers = [
129 lib.maintainers.zi3m5f
130 ];
131}