From cae154a67eb8e0605464896ea53c87d5634020f1 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sat, 21 Oct 2023 19:02:32 +0100 Subject: [PATCH] nixos/systemd-tmpfiles: add settings option --- .../modules/system/boot/systemd/tmpfiles.nix | 104 +++++++++++++++++- nixos/tests/misc.nix | 4 + 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/nixos/modules/system/boot/systemd/tmpfiles.nix b/nixos/modules/system/boot/systemd/tmpfiles.nix index 32b9b275d358..183e2033ecb0 100644 --- a/nixos/modules/system/boot/systemd/tmpfiles.nix +++ b/nixos/modules/system/boot/systemd/tmpfiles.nix @@ -20,6 +20,102 @@ in ''; }; + systemd.tmpfiles.settings = mkOption { + description = lib.mdDoc '' + 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 = lib.mdDoc '' + 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: + + ''; + }; + options.mode = mkOption { + type = types.str; + default = "-"; + example = "0755"; + description = lib.mdDoc '' + The file access mode to use when creating this file or directory. + ''; + }; + options.user = mkOption { + type = types.str; + default = "-"; + example = "root"; + description = lib.mdDoc '' + 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 = lib.mdDoc '' + 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 = lib.mdDoc '' + 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 = lib.mdDoc '' + An argument whose meaning depends on the type of operation. + + Please see the upstream documentation for the meaning of this + parameter in different situations: + + ''; + }; + })))); + }; + systemd.tmpfiles.packages = mkOption { type = types.listOf types.package; default = []; @@ -100,7 +196,13 @@ in ${concatStringsSep "\n" cfg.rules} ''; }) - ]; + ] ++ (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 )) + ) cfg.settings); systemd.tmpfiles.rules = [ "d /nix/var 0755 root root - -" diff --git a/nixos/tests/misc.nix b/nixos/tests/misc.nix index 442b45948c60..e7842debba7a 100644 --- a/nixos/tests/misc.nix +++ b/nixos/tests/misc.nix @@ -13,6 +13,7 @@ in { environment.variables.EDITOR = lib.mkOverride 0 "emacs"; documentation.nixos.enable = lib.mkOverride 0 true; systemd.tmpfiles.rules = [ "d /tmp 1777 root root 10d" ]; + systemd.tmpfiles.settings."10-test"."/tmp/somefile".d = {}; virtualisation.fileSystems = { "/tmp2" = { fsType = "tmpfs"; options = [ "mode=1777" "noauto" ]; @@ -117,6 +118,9 @@ in { ) machine.fail("[ -e /tmp/foo ]") + with subtest("whether systemd-tmpfiles settings works"): + machine.succeed("[ -e /tmp/somefile ]") + with subtest("whether automounting works"): machine.fail("grep '/tmp2 tmpfs' /proc/mounts") machine.succeed("touch /tmp2/x")