diff --git a/nix/modules/tmpfiles.nix b/nix/modules/tmpfiles.nix index 33a9894..787a70c 100644 --- a/nix/modules/tmpfiles.nix +++ b/nix/modules/tmpfiles.nix @@ -1,9 +1,133 @@ { config, lib, ... }: let - inherit (lib) types; + inherit (lib) + types + mkOption + mapAttrsToList + concatStrings + ; + 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: + + ''; + }; + 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: + + ''; + }; + } + ) + ) + ) + ); + }; + + # 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. + pathsToRules = mapAttrsToList ( + path: types: concatStrings (mapAttrsToList (_type: settingsEntryToRule path) types) + ); + + mkRuleFileContent = paths: concatStrings (pathsToRules paths); + in { options = { + systemd.tmpfiles.settings = lib.mkOption settingsOption; + systemd.tmpfiles.rules = lib.mkOption { type = types.listOf types.str; default = [ ]; @@ -18,10 +142,21 @@ in }; config = { - environment.etc."tmpfiles.d/00-system-manager.conf".text = '' - # This file is created automatically and should not be modified. - # Please change the option ‘systemd.tmpfiles.rules’ instead. - ${lib.concatStringsSep "\n" config.systemd.tmpfiles.rules} - ''; + environment.etc."tmpfiles.d/00-system-manager.conf".text = + '' + # This file is created automatically and should not be modified. + # Use 'systemd.tmpfiles.rules' or 'systemd.tmpfiles.settings' to modify this. + ${lib.concatStringsSep "\n" config.systemd.tmpfiles.rules} + '' + + lib.concatStringsSep "\n" ( + lib.mapAttrsToList ( + name: paths: + lib.concatStringsSep "\n" [ + "# ${name}" + (mkRuleFileContent paths) + "" + ] + ) config.systemd.tmpfiles.settings + ); }; }