# Taken from nixpkgs: nixos/modules/system/boot/systemd/tmpfiles.nix { config, pkgs, lib, unstable-pkgs, ... }: let # TODO: 24.05, year of the types.attrsWith inherit (unstable-pkgs.lib) types mkOption; cfg = config.systemd.user.tmpfiles; attrsWith' = placeholder: elemType: types.attrsWith { inherit elemType; inherit (lib) placeholder; }; escapeArgument = lib.strings.escapeC [ "\t" "\n" "\r" " " "\\" ]; 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 = attrsWith' "config-name" ( attrsWith' "path" ( attrsWith' "tmpfiles-type" ( lib.types.submodule ( { name, config, ... }: { options.type = mkOption { type = types.str; default = name; defaultText = "‹tmpfiles-type›"; 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: {manpage}`tmpfiles.d(5)` ''; }; 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: {manpage}`tmpfiles.d(5)` ''; }; } ) ) ) ); }; # generates a single entry for a tmpfiles.d rule settingsEntryToRule = path: entry: '' '${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${escapeArgument entry.argument} ''; # generates a list of tmpfiles.d rules from the attrs (paths) under tmpfiles.settings.<name> pathsToRules = lib.mapAttrsToList ( path: types: lib.concatStrings (lib.mapAttrsToList (_type: settingsEntryToRule path) types) ); mkRuleFileContent = paths: lib.concatStrings (pathsToRules paths); in { options.systemd.user.tmpfiles.settings = lib.mkOption settingsOption; config = lib.mkIf (cfg.settings != { }) { assertions = [ (lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs lib.platforms.linux) ]; xdg.configFile = { "systemd/user/basic.target.wants/systemd-tmpfiles-setup.service".source = "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service"; "systemd/user/systemd-tmpfiles-setup.service".source = "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service"; "systemd/user/timers.target.wants/systemd-tmpfiles-clean.timer".source = "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.timer"; "systemd/user/systemd-tmpfiles-clean.service".source = "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.service"; } // (lib.mapAttrs' (name: paths: { name = "user-tmpfiles.d/${name}.conf"; value = { text = mkRuleFileContent paths; onChange = "${pkgs.systemd}/bin/systemd-tmpfiles --user --create"; }; }) cfg.settings); }; }