at 24.11-pre 4.1 kB view raw
1{ config, lib, pkgs, utils, ...}: 2 3with utils.systemdUtils.unitOptions; 4with utils.systemdUtils.lib; 5with lib; 6 7let 8 cfg = config.systemd.nspawn; 9 10 checkExec = checkUnitConfig "Exec" [ 11 (assertOnlyFields [ 12 "Boot" "ProcessTwo" "Parameters" "Environment" "User" "WorkingDirectory" 13 "PivotRoot" "Capability" "DropCapability" "NoNewPrivileges" "KillSignal" 14 "Personality" "MachineID" "PrivateUsers" "NotifyReady" "SystemCallFilter" 15 "LimitCPU" "LimitFSIZE" "LimitDATA" "LimitSTACK" "LimitCORE" "LimitRSS" 16 "LimitNOFILE" "LimitAS" "LimitNPROC" "LimitMEMLOCK" "LimitLOCKS" 17 "LimitSIGPENDING" "LimitMSGQUEUE" "LimitNICE" "LimitRTPRIO" "LimitRTTIME" 18 "OOMScoreAdjust" "CPUAffinity" "Hostname" "ResolvConf" "Timezone" 19 "LinkJournal" "Ephemeral" "AmbientCapability" 20 ]) 21 (assertValueOneOf "Boot" boolValues) 22 (assertValueOneOf "ProcessTwo" boolValues) 23 (assertValueOneOf "NotifyReady" boolValues) 24 ]; 25 26 checkFiles = checkUnitConfig "Files" [ 27 (assertOnlyFields [ 28 "ReadOnly" "Volatile" "Bind" "BindReadOnly" "TemporaryFileSystem" 29 "Overlay" "OverlayReadOnly" "PrivateUsersChown" "BindUser" 30 "Inaccessible" "PrivateUsersOwnership" 31 ]) 32 (assertValueOneOf "ReadOnly" boolValues) 33 (assertValueOneOf "Volatile" (boolValues ++ [ "state" ])) 34 (assertValueOneOf "PrivateUsersChown" boolValues) 35 (assertValueOneOf "PrivateUsersOwnership" [ "off" "chown" "map" "auto" ]) 36 ]; 37 38 checkNetwork = checkUnitConfig "Network" [ 39 (assertOnlyFields [ 40 "Private" "VirtualEthernet" "VirtualEthernetExtra" "Interface" "MACVLAN" 41 "IPVLAN" "Bridge" "Zone" "Port" 42 ]) 43 (assertValueOneOf "Private" boolValues) 44 (assertValueOneOf "VirtualEthernet" boolValues) 45 ]; 46 47 instanceOptions = { 48 options = 49 (getAttrs [ "enable" ] sharedOptions) 50 // { 51 execConfig = mkOption { 52 default = {}; 53 example = { Parameters = "/bin/sh"; }; 54 type = types.addCheck (types.attrsOf unitOption) checkExec; 55 description = '' 56 Each attribute in this set specifies an option in the 57 `[Exec]` section of this unit. See 58 {manpage}`systemd.nspawn(5)` for details. 59 ''; 60 }; 61 62 filesConfig = mkOption { 63 default = {}; 64 example = { Bind = [ "/home/alice" ]; }; 65 type = types.addCheck (types.attrsOf unitOption) checkFiles; 66 description = '' 67 Each attribute in this set specifies an option in the 68 `[Files]` section of this unit. See 69 {manpage}`systemd.nspawn(5)` for details. 70 ''; 71 }; 72 73 networkConfig = mkOption { 74 default = {}; 75 example = { Private = false; }; 76 type = types.addCheck (types.attrsOf unitOption) checkNetwork; 77 description = '' 78 Each attribute in this set specifies an option in the 79 `[Network]` section of this unit. See 80 {manpage}`systemd.nspawn(5)` for details. 81 ''; 82 }; 83 }; 84 85 }; 86 87 instanceToUnit = name: def: 88 let base = { 89 text = '' 90 [Exec] 91 ${attrsToSection def.execConfig} 92 93 [Files] 94 ${attrsToSection def.filesConfig} 95 96 [Network] 97 ${attrsToSection def.networkConfig} 98 ''; 99 } // def; 100 in base // { unit = makeUnit name base; }; 101 102in { 103 104 options = { 105 106 systemd.nspawn = mkOption { 107 default = {}; 108 type = with types; attrsOf (submodule instanceOptions); 109 description = "Definition of systemd-nspawn configurations."; 110 }; 111 112 }; 113 114 config = 115 let 116 units = mapAttrs' (n: v: let nspawnFile = "${n}.nspawn"; in nameValuePair nspawnFile (instanceToUnit nspawnFile v)) cfg; 117 in 118 mkMerge [ 119 (mkIf (cfg != {}) { 120 environment.etc."systemd/nspawn".source = mkIf (cfg != {}) (generateUnits { 121 allowCollisions = false; 122 type = "nspawn"; 123 inherit units; 124 upstreamUnits = []; 125 upstreamWants = []; 126 }); 127 }) 128 { 129 systemd.targets.multi-user.wants = [ "machines.target" ]; 130 } 131 ]; 132}