mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-06 12:14:40 +00:00
nixos/systemd-tmpfiles: add initrd support
This adds support for declaring tmpfiles rules exclusively for the
systemd initrd. Configuration is possible through the new option
`boot.initrd.systemd.tmpfiles.settings` that shares the same interface as
`systemd.tmpfiles.settings`.
I did intentionally not replicate the `rules` interface here, given that
the settings attribute set is more versatile than the list of strings
used for `rules`. This should also make it unnecessary to implement the
workaround from 1a68e21d47
again.
A self-contained `tmpfiles.d` directory is generated from the new initrd
settings and it is added to the initrd as a content path at
`/etc/tmpfiles.d`.
The stage-1 `systemd-tmpfiles-setup.service` is now altered to no longer
operate under the `/sysroot` prefix, because the `/sysroot` hierarchy
cannot be expected to be available when the default upstream service is
started.
To handle files under `/sysroot` a slightly altered version of the
upstream default service is introduced. This new unit
`systemd-tmpfiles-setup-sysroot.service` operates only under the
`/sysroot` prefix and it is ordered between `initrd-fs.target` and the
nixos activation.
Config related to tmpfiles was moved from initrd.nix to tmpfiles.nix.
This commit is contained in:
parent
7c8b2a22dc
commit
8dd369f524
@ -53,7 +53,6 @@ let
|
||||
"debug-shell.service"
|
||||
|
||||
# Udev.
|
||||
"systemd-tmpfiles-setup-dev-early.service"
|
||||
"systemd-udevd-control.socket"
|
||||
"systemd-udevd-kernel.socket"
|
||||
"systemd-udevd.service"
|
||||
|
@ -67,8 +67,6 @@ let
|
||||
"systemd-poweroff.service"
|
||||
"systemd-reboot.service"
|
||||
"systemd-sysctl.service"
|
||||
"systemd-tmpfiles-setup-dev.service"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
"timers.target"
|
||||
"tpm2.target"
|
||||
"umount.target"
|
||||
@ -506,8 +504,6 @@ in {
|
||||
(v: let n = escapeSystemdPath v.where;
|
||||
in nameValuePair "${n}.automount" (automountToUnit v)) cfg.automounts);
|
||||
|
||||
# make sure all the /dev nodes are set up
|
||||
services.systemd-tmpfiles-setup-dev.wantedBy = ["sysinit.target"];
|
||||
|
||||
services.initrd-nixos-activation = {
|
||||
after = [ "initrd-fs.target" ];
|
||||
|
@ -1,10 +1,121 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.systemd.tmpfiles;
|
||||
initrdCfg = config.boot.initrd.systemd.tmpfiles;
|
||||
systemd = config.systemd.package;
|
||||
|
||||
settingsOption = {
|
||||
description = ''
|
||||
Declare systemd-tmpfiles rules to create, delete, and clean up volatile
|
||||
and temporary files and directories.
|
||||
|
||||
Even though the service is called `*tmp*files` you can also create
|
||||
persistent files.
|
||||
'';
|
||||
example = {
|
||||
"10-mypackage" = {
|
||||
"/var/lib/my-service/statefolder".d = {
|
||||
mode = "0755";
|
||||
user = "root";
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||
options.type = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
example = "d";
|
||||
description = ''
|
||||
The type of operation to perform on the file.
|
||||
|
||||
The type consists of a single letter and optionally one or more
|
||||
modifier characters.
|
||||
|
||||
Please see the upstream documentation for the available types and
|
||||
more details:
|
||||
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
|
||||
'';
|
||||
};
|
||||
options.mode = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "0755";
|
||||
description = ''
|
||||
The file access mode to use when creating this file or directory.
|
||||
'';
|
||||
};
|
||||
options.user = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "root";
|
||||
description = ''
|
||||
The user of the file.
|
||||
|
||||
This may either be a numeric ID or a user/group name.
|
||||
|
||||
If omitted or when set to `"-"`, the user and group of the user who
|
||||
invokes systemd-tmpfiles is used.
|
||||
'';
|
||||
};
|
||||
options.group = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "root";
|
||||
description = ''
|
||||
The group of the file.
|
||||
|
||||
This may either be a numeric ID or a user/group name.
|
||||
|
||||
If omitted or when set to `"-"`, the user and group of the user who
|
||||
invokes systemd-tmpfiles is used.
|
||||
'';
|
||||
};
|
||||
options.age = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "10d";
|
||||
description = ''
|
||||
Delete a file when it reaches a certain age.
|
||||
|
||||
If a file or directory is older than the current time minus the age
|
||||
field, it is deleted.
|
||||
|
||||
If set to `"-"` no automatic clean-up is done.
|
||||
'';
|
||||
};
|
||||
options.argument = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "";
|
||||
description = ''
|
||||
An argument whose meaning depends on the type of operation.
|
||||
|
||||
Please see the upstream documentation for the meaning of this
|
||||
parameter in different situations:
|
||||
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
|
||||
'';
|
||||
};
|
||||
}))));
|
||||
};
|
||||
|
||||
# generates a single entry for a tmpfiles.d rule
|
||||
settingsEntryToRule = path: entry: ''
|
||||
'${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument}
|
||||
'';
|
||||
|
||||
# generates a list of tmpfiles.d rules from the attrs (paths) under tmpfiles.settings.<name>
|
||||
pathsToRules = mapAttrsToList (path: types:
|
||||
concatStrings (
|
||||
mapAttrsToList (_type: settingsEntryToRule path) types
|
||||
)
|
||||
);
|
||||
|
||||
mkRuleFileContent = paths: concatStrings (pathsToRules paths);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@ -20,101 +131,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.tmpfiles.settings = mkOption {
|
||||
systemd.tmpfiles.settings = mkOption settingsOption;
|
||||
|
||||
boot.initrd.systemd.tmpfiles.settings = mkOption (settingsOption // {
|
||||
description = ''
|
||||
Declare systemd-tmpfiles rules to create, delete, and clean up volatile
|
||||
and temporary files and directories.
|
||||
Similar to {option}`systemd.tmpfiles.settings` but the rules are
|
||||
only applied by systemd-tmpfiles before `initrd-switch-root.target`.
|
||||
|
||||
Even though the service is called `*tmp*files` you can also create
|
||||
persistent files.
|
||||
See {manpage}`bootup(7)`.
|
||||
'';
|
||||
example = {
|
||||
"10-mypackage" = {
|
||||
"/var/lib/my-service/statefolder".d = {
|
||||
mode = "0755";
|
||||
user = "root";
|
||||
group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||
options.type = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
example = "d";
|
||||
description = ''
|
||||
The type of operation to perform on the file.
|
||||
|
||||
The type consists of a single letter and optionally one or more
|
||||
modifier characters.
|
||||
|
||||
Please see the upstream documentation for the available types and
|
||||
more details:
|
||||
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
|
||||
'';
|
||||
};
|
||||
options.mode = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "0755";
|
||||
description = ''
|
||||
The file access mode to use when creating this file or directory.
|
||||
'';
|
||||
};
|
||||
options.user = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "root";
|
||||
description = ''
|
||||
The user of the file.
|
||||
|
||||
This may either be a numeric ID or a user/group name.
|
||||
|
||||
If omitted or when set to `"-"`, the user and group of the user who
|
||||
invokes systemd-tmpfiles is used.
|
||||
'';
|
||||
};
|
||||
options.group = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "root";
|
||||
description = ''
|
||||
The group of the file.
|
||||
|
||||
This may either be a numeric ID or a user/group name.
|
||||
|
||||
If omitted or when set to `"-"`, the user and group of the user who
|
||||
invokes systemd-tmpfiles is used.
|
||||
'';
|
||||
};
|
||||
options.age = mkOption {
|
||||
type = types.str;
|
||||
default = "-";
|
||||
example = "10d";
|
||||
description = ''
|
||||
Delete a file when it reaches a certain age.
|
||||
|
||||
If a file or directory is older than the current time minus the age
|
||||
field, it is deleted.
|
||||
|
||||
If set to `"-"` no automatic clean-up is done.
|
||||
'';
|
||||
};
|
||||
options.argument = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "";
|
||||
description = ''
|
||||
An argument whose meaning depends on the type of operation.
|
||||
|
||||
Please see the upstream documentation for the meaning of this
|
||||
parameter in different situations:
|
||||
<https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
|
||||
'';
|
||||
};
|
||||
}))));
|
||||
};
|
||||
});
|
||||
|
||||
systemd.tmpfiles.packages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
@ -140,8 +166,9 @@ in
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-tmpfiles-clean.service"
|
||||
"systemd-tmpfiles-clean.timer"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
"systemd-tmpfiles-setup-dev-early.service"
|
||||
"systemd-tmpfiles-setup-dev.service"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
];
|
||||
|
||||
systemd.additionalUpstreamUserUnits = [
|
||||
@ -232,11 +259,7 @@ in
|
||||
'';
|
||||
})
|
||||
] ++ (mapAttrsToList (name: paths:
|
||||
pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (concatStrings (mapAttrsToList (path: types:
|
||||
concatStrings (mapAttrsToList (_type: entry: ''
|
||||
'${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument}
|
||||
'') types)
|
||||
) paths ))
|
||||
pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (mkRuleFileContent paths)
|
||||
) cfg.settings);
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
@ -254,5 +277,62 @@ in
|
||||
"R! /nix/var/nix/gcroots/tmp - - - - -"
|
||||
"R! /nix/var/nix/temproots - - - - -"
|
||||
];
|
||||
|
||||
boot.initrd.systemd = {
|
||||
additionalUpstreamUnits = [
|
||||
"systemd-tmpfiles-setup-dev-early.service"
|
||||
"systemd-tmpfiles-setup-dev.service"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
];
|
||||
|
||||
# override to exclude the prefix /sysroot, because it is not necessarily set up when the unit starts
|
||||
services.systemd-tmpfiles-setup.serviceConfig = {
|
||||
ExecStart = [
|
||||
""
|
||||
"systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --exclude-prefix=/sysroot"
|
||||
];
|
||||
};
|
||||
|
||||
# sets up files under the prefix /sysroot, after the hierarchy is available and before nixos activation
|
||||
services.systemd-tmpfiles-setup-sysroot = {
|
||||
description = "Create Volatile Files and Directories in the Real Root";
|
||||
after = [ "initrd-fs.target" ];
|
||||
before = [
|
||||
"initrd-nixos-activation.service"
|
||||
"shutdown.target" "initrd-switch-root.target"
|
||||
];
|
||||
conflicts = [ "shutdown.target" "initrd-switch-root.target" ];
|
||||
wantedBy = [ "initrd.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --prefix=/sysroot";
|
||||
SuccessExitStatus = [ "DATAERR CANTCREAT" ];
|
||||
ImportCredential = [
|
||||
"tmpfiles.*"
|
||||
"login.motd"
|
||||
"login.issue"
|
||||
"network.hosts"
|
||||
"ssh.authorized_keys.root"
|
||||
];
|
||||
};
|
||||
unitConfig = {
|
||||
DefaultDependencies = false;
|
||||
RefuseManualStop = true;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
contents."/etc/tmpfiles.d" = mkIf (initrdCfg.settings != { }) {
|
||||
source = pkgs.linkFarm "initrd-tmpfiles.d" (
|
||||
mapAttrsToList
|
||||
(name: paths: {
|
||||
name = "${name}.conf";
|
||||
path = pkgs.writeText "${name}.conf" (mkRuleFileContent paths);
|
||||
}
|
||||
)
|
||||
initrdCfg.settings);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user