Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
52c98fc
nixos: systemd: Split unit types into separate module
ElvishJerricco Mar 19, 2022
d193ef8
make-initrd-ng: init
ElvishJerricco Nov 21, 2021
2511374
nixos: systemd-lib: Make generateUnits general with default args
ElvishJerricco Mar 20, 2022
2d4ebf1
initrd: Optional systemd-based initrd
ElvishJerricco Mar 20, 2022
be10e86
systemd-initrd: Partially fix qemu-vm
ElvishJerricco Mar 20, 2022
1abf154
systemd-initrd: Add PATH to everything
ElvishJerricco Mar 20, 2022
213de9b
systemd-initrd: autoFormat and autoResize in initrd
ElvishJerricco Mar 20, 2022
3365666
systemd-initrd: Basic test case
ElvishJerricco Mar 20, 2022
9828446
systemd-initrd: Fix Environment= and PATH
ElvishJerricco Mar 21, 2022
2431347
systemd-initrd: Test autoResize
ElvishJerricco Mar 21, 2022
5bfe213
Clarify suppressed units description
ElvishJerricco Mar 22, 2022
76d05df
fakeNss: move to toplevel
flokli Mar 24, 2022
74bae06
systemd-initrd: use pkgs.fakeNss, document why we need libnss_files.so
flokli Mar 24, 2022
e3083de
systemd-initrd, systemd-lib: drop initrdServiceToUnit
flokli Mar 24, 2022
fc91cdb
nixos/lib/systemd-lib.nix: move comment back down to packages
flokli Mar 24, 2022
1e5261f
nixos/systemd-lib: Use module composition
dasJ Apr 1, 2022
b7c62b8
nixos/systemd-initrd: Remove unit options that don't work
dasJ Apr 1, 2022
c465c8d
nixos/systemd-initrd: Make emergency access more flexible
dasJ Apr 1, 2022
5653209
nixos/systemd-initrd: Redo object specifications
dasJ Apr 1, 2022
7ebb4eb
nixos/systemd-stage-1: Append (Initrd) to /etc/initrd-release
dasJ Apr 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 34 additions & 50 deletions nixos/lib/systemd-lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,23 @@ in rec {
(if isList value then value else [value]))
as));

generateUnits = generateUnits' true;

generateUnits' = allowCollisions: type: units: upstreamUnits: upstreamWants:
pkgs.runCommand "${type}-units"
generateUnits = { allowCollisions ? true, type, units, upstreamUnits, upstreamWants, packages ? cfg.packages, package ? cfg.package }:
let
typeDir = ({
system = "system";
initrd = "system";
user = "user";
nspawn = "nspawn";
}).${type};
in pkgs.runCommand "${type}-units"
{ preferLocalBuild = true;
allowSubstitutes = false;
} ''
mkdir -p $out

# Copy the upstream systemd units we're interested in.
for i in ${toString upstreamUnits}; do
fn=${cfg.package}/example/systemd/${type}/$i
fn=${package}/example/systemd/${typeDir}/$i
if ! [ -e $fn ]; then echo "missing $fn"; false; fi
if [ -L $fn ]; then
target="$(readlink "$fn")"
Expand All @@ -148,7 +153,7 @@ in rec {
# Copy .wants links, but only those that point to units that
# we're interested in.
for i in ${toString upstreamWants}; do
fn=${cfg.package}/example/systemd/${type}/$i
fn=${package}/example/systemd/${typeDir}/$i
if ! [ -e $fn ]; then echo "missing $fn"; false; fi
x=$out/$(basename $fn)
mkdir $x
Expand All @@ -160,14 +165,14 @@ in rec {
done

# Symlink all units provided listed in systemd.packages.
packages="${toString cfg.packages}"
packages="${toString packages}"

# Filter duplicate directories
declare -A unique_packages
for k in $packages ; do unique_packages[$k]=1 ; done

for i in ''${!unique_packages[@]}; do
for fn in $i/etc/systemd/${type}/* $i/lib/systemd/${type}/*; do
for fn in $i/etc/systemd/${typeDir}/* $i/lib/systemd/${typeDir}/*; do
if ! [[ "$fn" =~ .wants$ ]]; then
if [[ -d "$fn" ]]; then
targetDir="$out/$(basename "$fn")"
Expand Down Expand Up @@ -268,9 +273,9 @@ in rec {
{ Conflicts = toString config.conflicts; }
// optionalAttrs (config.requisite != [])
{ Requisite = toString config.requisite; }
// optionalAttrs (config.restartTriggers != [])
// optionalAttrs (config ? restartTriggers && config.restartTriggers != [])
{ X-Restart-Triggers = toString config.restartTriggers; }
// optionalAttrs (config.reloadTriggers != [])
// optionalAttrs (config ? reloadTriggers && config.reloadTriggers != [])
{ X-Reload-Triggers = toString config.reloadTriggers; }
// optionalAttrs (config.description != "") {
Description = config.description; }
Expand All @@ -286,45 +291,24 @@ in rec {
};
};

serviceConfig = { name, config, ... }: {
config = mkMerge
[ { # Default path for systemd services. Should be quite minimal.
path = mkAfter
[ pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
systemd
];
environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
}
(mkIf (config.preStart != "")
{ serviceConfig.ExecStartPre =
[ (makeJobScript "${name}-pre-start" config.preStart) ];
})
(mkIf (config.script != "")
{ serviceConfig.ExecStart =
makeJobScript "${name}-start" config.script + " " + config.scriptArgs;
})
(mkIf (config.postStart != "")
{ serviceConfig.ExecStartPost =
[ (makeJobScript "${name}-post-start" config.postStart) ];
})
(mkIf (config.reload != "")
{ serviceConfig.ExecReload =
makeJobScript "${name}-reload" config.reload;
})
(mkIf (config.preStop != "")
{ serviceConfig.ExecStop =
makeJobScript "${name}-pre-stop" config.preStop;
})
(mkIf (config.postStop != "")
{ serviceConfig.ExecStopPost =
makeJobScript "${name}-post-stop" config.postStop;
})
];
serviceConfig = { config, ... }: {
config.environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
};

stage2ServiceConfig = {
imports = [ serviceConfig ];
# Default path for systemd services. Should be quite minimal.
config.path = mkAfter [
pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
systemd
];
};

stage1ServiceConfig = serviceConfig;

mountConfig = { config, ... }: {
config = {
mountConfig =
Expand Down Expand Up @@ -372,12 +356,12 @@ in rec {
# systemd max line length is now 1MiB
# https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af
in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)}
${if def.reloadIfChanged then ''
${if def ? reloadIfChanged && def.reloadIfChanged then ''
X-ReloadIfChanged=true
'' else if !def.restartIfChanged then ''
'' else if (def ? restartIfChanged && !def.restartIfChanged) then ''
X-RestartIfChanged=false
'' else ""}
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
${optionalString (def ? stopIfChanged && !def.stopIfChanged) "X-StopIfChanged=false"}
${attrsToSection def.serviceConfig}
'';
};
Expand Down
37 changes: 37 additions & 0 deletions nixos/lib/systemd-types.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{ lib, systemdUtils }:

with systemdUtils.lib;
with systemdUtils.unitOptions;
with lib;

rec {
units = with types;
attrsOf (submodule ({ name, config, ... }: {
options = concreteUnitOptions;
config = { unit = mkDefault (systemdUtils.lib.makeUnit name config); };
}));

services = with types; attrsOf (submodule [ stage2ServiceOptions unitConfig stage2ServiceConfig ]);
initrdServices = with types; attrsOf (submodule [ stage1ServiceOptions unitConfig stage1ServiceConfig ]);

targets = with types; attrsOf (submodule [ stage2CommonUnitOptions unitConfig ]);
initrdTargets = with types; attrsOf (submodule [ stage1CommonUnitOptions unitConfig ]);

sockets = with types; attrsOf (submodule [ stage2SocketOptions unitConfig ]);
initrdSockets = with types; attrsOf (submodule [ stage1SocketOptions unitConfig ]);

timers = with types; attrsOf (submodule [ stage2TimerOptions unitConfig ]);
initrdTimers = with types; attrsOf (submodule [ stage1TimerOptions unitConfig ]);

paths = with types; attrsOf (submodule [ stage2PathOptions unitConfig ]);
initrdPaths = with types; attrsOf (submodule [ stage1PathOptions unitConfig ]);

slices = with types; attrsOf (submodule [ stage2SliceOptions unitConfig ]);
initrdSlices = with types; attrsOf (submodule [ stage1SliceOptions unitConfig ]);

mounts = with types; listOf (submodule [ stage2MountOptions unitConfig mountConfig ]);
initrdMounts = with types; listOf (submodule [ stage1MountOptions unitConfig mountConfig ]);

automounts = with types; listOf (submodule [ stage2AutomountOptions unitConfig automountConfig ]);
initrdAutomounts = with types; attrsOf (submodule [ stage1AutomountOptions unitConfig automountConfig ]);
}
Loading