1{ config, lib , pkgs, ...}:
2
3with lib;
4with import ./systemd-unit-options.nix { inherit config lib; };
5with import ./systemd-lib.nix { inherit config lib pkgs; };
6
7let
8 cfg = config.systemd.nspawn;
9
10 checkExec = checkUnitConfig "Exec" [
11 (assertOnlyFields [
12 "Boot" "ProcessTwo" "Parameters" "Environment" "User" "WorkingDirectory"
13 "Capability" "DropCapability" "KillSignal" "Personality" "MachineId"
14 "PrivateUsers" "NotifyReady"
15 ])
16 (assertValueOneOf "Boot" boolValues)
17 (assertValueOneOf "ProcessTwo" boolValues)
18 (assertValueOneOf "NotifyReady" boolValues)
19 ];
20
21 checkFiles = checkUnitConfig "Files" [
22 (assertOnlyFields [
23 "ReadOnly" "Volatile" "Bind" "BindReadOnly" "TemporaryFileSystems"
24 "PrivateUsersChown"
25 ])
26 (assertValueOneOf "ReadOnly" boolValues)
27 (assertValueOneOf "Volatile" (boolValues ++ [ "state" ]))
28 (assertValueOneOf "PrivateUsersChown" boolValues)
29 ];
30
31 checkNetwork = checkUnitConfig "Network" [
32 (assertOnlyFields [
33 "Private" "VirtualEthernet" "VirtualEthernetExtra" "Interface" "MACVLAN"
34 "IPVLAN" "Bridge" "Zone" "Port"
35 ])
36 (assertValueOneOf "Private" boolValues)
37 (assertValueOneOf "VirtualEthernet" boolValues)
38 ];
39
40 instanceOptions = {
41 options = sharedOptions // {
42 execConfig = mkOption {
43 default = {};
44 example = { Parameters = "/bin/sh"; };
45 type = types.addCheck (types.attrsOf unitOption) checkExec;
46 description = ''
47 Each attribute in this set specifies an option in the
48 <literal>[Exec]</literal> section of this unit. See
49 <citerefentry><refentrytitle>systemd.nspawn</refentrytitle>
50 <manvolnum>5</manvolnum></citerefentry> for details.
51 '';
52 };
53
54 filesConfig = mkOption {
55 default = {};
56 example = { Bind = [ "/home/alice" ]; };
57 type = types.addCheck (types.attrsOf unitOption) checkFiles;
58 description = ''
59 Each attribute in this set specifies an option in the
60 <literal>[Files]</literal> section of this unit. See
61 <citerefentry><refentrytitle>systemd.nspawn</refentrytitle>
62 <manvolnum>5</manvolnum></citerefentry> for details.
63 '';
64 };
65
66 networkConfig = mkOption {
67 default = {};
68 example = { Private = false; };
69 type = types.addCheck (types.attrsOf unitOption) checkNetwork;
70 description = ''
71 Each attribute in this set specifies an option in the
72 <literal>[Network]</literal> section of this unit. See
73 <citerefentry><refentrytitle>systemd.nspawn</refentrytitle>
74 <manvolnum>5</manvolnum></citerefentry> for details.
75 '';
76 };
77 };
78
79 };
80
81 instanceToUnit = name: def:
82 let base = {
83 text = ''
84 [Exec]
85 ${attrsToSection def.execConfig}
86
87 [Files]
88 ${attrsToSection def.filesConfig}
89
90 [Network]
91 ${attrsToSection def.networkConfig}
92 '';
93 } // def;
94 in base // { unit = makeUnit name base; };
95
96in {
97
98 options = {
99
100 systemd.nspawn = mkOption {
101 default = {};
102 type = with types; attrsOf (submodule instanceOptions);
103 description = "Definition of systemd-nspawn configurations.";
104 };
105
106 };
107
108 config =
109 let
110 units = mapAttrs' (n: v: let nspawnFile = "${n}.nspawn"; in nameValuePair nspawnFile (instanceToUnit nspawnFile v)) cfg;
111 in mkIf (cfg != {}) {
112
113 environment.etc."systemd/nspawn".source = generateUnits "nspawn" units [] [];
114
115 systemd.services."systemd-nspawn@" = {
116 wantedBy = [ "machine.target" ];
117 };
118 };
119
120}