mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
restic: decouple helper script from linux-specific systemd logic
And make platform support explicit.
This commit is contained in:
parent
12bca6d40a
commit
c199de6cd8
1 changed files with 405 additions and 343 deletions
|
|
@ -43,6 +43,40 @@ let
|
|||
gnugrep
|
||||
which
|
||||
];
|
||||
|
||||
# Create the base restic environment variables for both systemd
|
||||
# and the helper script
|
||||
mkEnvironment =
|
||||
backup:
|
||||
lib.flatten [
|
||||
"PATH=${backup.ssh-package}/bin"
|
||||
|
||||
(attrsToEnvs (
|
||||
{
|
||||
RESTIC_PROGRESS_FPS = backup.progressFps;
|
||||
RESTIC_PASSWORD_FILE = backup.passwordFile;
|
||||
RESTIC_REPOSITORY = backup.repository;
|
||||
RESTIC_REPOSITORY_FILE = backup.repositoryFile;
|
||||
}
|
||||
// backup.rcloneOptions
|
||||
))
|
||||
];
|
||||
|
||||
inherit (pkgs.stdenv.hostPlatform) isLinux;
|
||||
|
||||
# Until we have launchd support (#7924), mark the options
|
||||
# not used in the helper script as "linux exclusive"
|
||||
linuxExclusive =
|
||||
option:
|
||||
option
|
||||
// {
|
||||
readOnly = pkgs.stdenv.hostPlatform.isDarwin;
|
||||
|
||||
description = option.description + ''
|
||||
|
||||
This option is only supported on linux.
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
options.services.restic = {
|
||||
|
|
@ -50,7 +84,14 @@ in
|
|||
|
||||
backups = lib.mkOption {
|
||||
description = ''
|
||||
Periodic backups to create with Restic.
|
||||
Backup configurations for Restic.
|
||||
|
||||
On Linux systems, a corresponding systemd user service
|
||||
(and optionally a systemd timer for automatic scheduling)
|
||||
will be created, along with a helper wrapper script.
|
||||
|
||||
On non-Linux platforms, only the helper wrapper script
|
||||
will be created.
|
||||
'';
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
|
|
@ -102,7 +143,8 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
inhibitsSleep = lib.mkOption {
|
||||
inhibitsSleep = linuxExclusive (
|
||||
lib.mkOption {
|
||||
default = false;
|
||||
type = lib.types.bool;
|
||||
example = true;
|
||||
|
|
@ -111,7 +153,8 @@ in
|
|||
to block system idling so you may need to enable polkitd with
|
||||
{option}`security.polkit.enable`.
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
repository = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
|
|
@ -136,7 +179,8 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
paths = lib.mkOption {
|
||||
paths = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
|
|
@ -148,9 +192,11 @@ in
|
|||
"/var/lib/postgresql"
|
||||
"/home/user/backup"
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
exclude = lib.mkOption {
|
||||
exclude = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
|
|
@ -163,9 +209,11 @@ in
|
|||
"/home/*/.cache"
|
||||
".git"
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
timerConfig = lib.mkOption {
|
||||
timerConfig = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = lib.types.nullOr unitType;
|
||||
default = {
|
||||
OnCalendar = "daily";
|
||||
|
|
@ -180,9 +228,11 @@ in
|
|||
RandomizedDelaySec = "5h";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
extraBackupArgs = lib.mkOption {
|
||||
extraBackupArgs = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
|
|
@ -192,7 +242,8 @@ in
|
|||
"--cleanup-cache"
|
||||
"--exclude-file=/etc/nixos/restic-ignore"
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
extraOptions = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
|
|
@ -206,15 +257,18 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
initialize = lib.mkOption {
|
||||
initialize = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Create the repository if it does not already exist.
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
pruneOpts = lib.mkOption {
|
||||
pruneOpts = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
|
|
@ -232,26 +286,32 @@ in
|
|||
"--keep-monthly 12"
|
||||
"--keep-yearly 75"
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
runCheck = lib.mkOption {
|
||||
runCheck = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = lib.length config.checkOpts > 0 || lib.length config.pruneOpts > 0;
|
||||
defaultText = lib.literalExpression "lib.length config.checkOpts > 0 || lib.length config.pruneOpts > 0";
|
||||
description = "Whether to run 'restic check' with the provided `checkOpts` options.";
|
||||
example = true;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
checkOpts = lib.mkOption {
|
||||
checkOpts = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
A list of options for 'restic check'.
|
||||
'';
|
||||
example = [ "--with-cache" ];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
dynamicFilesFrom = lib.mkOption {
|
||||
dynamicFilesFrom = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
|
|
@ -260,23 +320,28 @@ in
|
|||
are given to the '--files-from' option.
|
||||
'';
|
||||
example = "find /home/alice/git -type d -name .git";
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
backupPrepareCommand = lib.mkOption {
|
||||
backupPrepareCommand = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
A script that must run before starting the backup process.
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
backupCleanupCommand = lib.mkOption {
|
||||
backupCleanupCommand = linuxExclusive (
|
||||
lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
A script that must run after finishing the backup process.
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
createWrapper = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
|
|
@ -326,12 +391,16 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
assertions = lib.mapAttrsToList (n: v: {
|
||||
assertion = lib.xor (v.repository == null) (v.repositoryFile == null);
|
||||
message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set";
|
||||
}) cfg.backups;
|
||||
}
|
||||
|
||||
(lib.mkIf isLinux {
|
||||
systemd.user.services = lib.mapAttrs' (
|
||||
name: backup:
|
||||
let
|
||||
|
|
@ -404,19 +473,7 @@ in
|
|||
CacheDirectoryMode = "0700";
|
||||
PrivateTmp = true;
|
||||
|
||||
Environment = [
|
||||
"RESTIC_CACHE_DIR=%C"
|
||||
"PATH=${backup.ssh-package}/bin"
|
||||
]
|
||||
++ attrsToEnvs (
|
||||
{
|
||||
RESTIC_PROGRESS_FPS = backup.progressFps;
|
||||
RESTIC_PASSWORD_FILE = backup.passwordFile;
|
||||
RESTIC_REPOSITORY = backup.repository;
|
||||
RESTIC_REPOSITORY_FILE = backup.repositoryFile;
|
||||
}
|
||||
// backup.rcloneOptions
|
||||
);
|
||||
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C" ];
|
||||
|
||||
ExecStart =
|
||||
lib.optional doBackup backupCmd
|
||||
|
|
@ -476,7 +533,9 @@ in
|
|||
};
|
||||
}
|
||||
) cfg.backups;
|
||||
})
|
||||
|
||||
(lib.mkIf isLinux {
|
||||
systemd.user.timers = lib.mapAttrs' (
|
||||
name: backup:
|
||||
lib.nameValuePair "restic-backups-${name}" {
|
||||
|
|
@ -486,12 +545,14 @@ in
|
|||
Timer = backup.timerConfig;
|
||||
}
|
||||
) (lib.filterAttrs (_: v: v.timerConfig != null) cfg.backups);
|
||||
})
|
||||
|
||||
{
|
||||
home.packages = lib.mapAttrsToList (
|
||||
name: backup:
|
||||
let
|
||||
serviceName = "restic-backups-${name}";
|
||||
backupService = config.systemd.user.services.${serviceName};
|
||||
environment = mkEnvironment backup;
|
||||
notPathVar = x: !(lib.hasPrefix "PATH" x);
|
||||
extraOptions = lib.concatMap (arg: [
|
||||
"-o"
|
||||
|
|
@ -523,16 +584,15 @@ in
|
|||
''}
|
||||
|
||||
# Set same environment variables as the systemd service
|
||||
${lib.pipe backupService.Service.Environment [
|
||||
${lib.pipe environment [
|
||||
(lib.filter notPathVar)
|
||||
lib.concatLines
|
||||
]}
|
||||
|
||||
# Override this as %C will not work
|
||||
RESTIC_CACHE_DIR=$HOME/.cache/${serviceName}
|
||||
|
||||
PATH=${
|
||||
lib.pipe backupService.Service.Environment [
|
||||
lib.pipe environment [
|
||||
(lib.filter (lib.hasPrefix "PATH="))
|
||||
lib.head
|
||||
(lib.removePrefix "PATH=")
|
||||
|
|
@ -543,7 +603,9 @@ in
|
|||
'';
|
||||
}
|
||||
) (lib.filterAttrs (_: v: v.createWrapper) cfg.backups);
|
||||
};
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
meta.maintainers = [ lib.maintainers.jess ];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue