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