Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

Merge pull request #198239 from jacobgreenleaf/jacobg-borg-inhibit

nixos/borgbackup: Add option for inhibiting sleep

authored by Ryan Lahfa and committed by GitHub 4428f9f5 810e9ccf

+51 -4
+8
nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
··· 70 </listitem> 71 <listitem> 72 <para> 73 The EC2 image module no longer fetches instance metadata in 74 stage-1. This results in a significantly smaller initramfs, 75 since network drivers no longer need to be included, and
··· 70 </listitem> 71 <listitem> 72 <para> 73 + <literal>borgbackup</literal> module now has an option for 74 + inhibiting system sleep while backups are running, defaulting 75 + to off (not inhibiting sleep), available as 76 + <link linkend="opt-services.borgbackup.jobs._name_.inhibitsSleep"><literal>services.borgbackup.jobs.&lt;name&gt;.inhibitsSleep</literal></link>. 77 + </para> 78 + </listitem> 79 + <listitem> 80 + <para> 81 The EC2 image module no longer fetches instance metadata in 82 stage-1. This results in a significantly smaller initramfs, 83 since network drivers no longer need to be included, and
+2
nixos/doc/manual/release-notes/rl-2305.section.md
··· 28 29 - `carnix` and `cratesIO` has been removed due to being unmaintained, use alternatives such as [naersk](https://github.com/nix-community/naersk) and [crate2nix](https://github.com/kolloch/crate2nix) instead. 30 31 - The EC2 image module no longer fetches instance metadata in stage-1. This results in a significantly smaller initramfs, since network drivers no longer need to be included, and faster boots, since metadata fetching can happen in parallel with startup of other services. 32 This breaks services which rely on metadata being present by the time stage-2 is entered. Anything which reads EC2 metadata from `/etc/ec2-metadata` should now have an `after` dependency on `fetch-ec2-metadata.service` 33
··· 28 29 - `carnix` and `cratesIO` has been removed due to being unmaintained, use alternatives such as [naersk](https://github.com/nix-community/naersk) and [crate2nix](https://github.com/kolloch/crate2nix) instead. 30 31 + - `borgbackup` module now has an option for inhibiting system sleep while backups are running, defaulting to off (not inhibiting sleep), available as [`services.borgbackup.jobs.<name>.inhibitsSleep`](#opt-services.borgbackup.jobs._name_.inhibitsSleep). 32 + 33 - The EC2 image module no longer fetches instance metadata in stage-1. This results in a significantly smaller initramfs, since network drivers no longer need to be included, and faster boots, since metadata fetching can happen in parallel with startup of other services. 34 This breaks services which rely on metadata being present by the time stage-2 is entered. Anything which reads EC2 metadata from `/etc/ec2-metadata` should now have an `after` dependency on `fetch-ec2-metadata.service` 35
+21 -4
nixos/modules/services/backup/borgbackup.nix
··· 19 concatStringsSep " " 20 (mapAttrsToList (x: y: "--keep-${x}=${toString y}") cfg.prune.keep); 21 22 - mkBackupScript = cfg: '' 23 on_exit() 24 { 25 exitStatus=$? ··· 61 ${optionalString (cfg.prune.prefix != null) "--glob-archives ${escapeShellArg "${cfg.prune.prefix}*"}"} \ 62 $extraPruneArgs 63 ${cfg.postPrune} 64 - ''; 65 66 mkPassEnv = cfg: with cfg.encryption; 67 if passCommand != null then ··· 73 mkBackupService = name: cfg: 74 let 75 userHome = config.users.users.${cfg.user}.home; 76 - in nameValuePair "borgbackup-job-${name}" { 77 description = "BorgBackup job ${name}"; 78 path = with pkgs; [ 79 borgbackup openssh 80 ]; 81 - script = mkBackupScript cfg; 82 serviceConfig = { 83 User = cfg.user; 84 Group = cfg.group; ··· 338 {manpage}`systemd.timer(5)` 339 which triggers the backup immediately if the last trigger 340 was missed (e.g. if the system was powered down). 341 ''; 342 }; 343
··· 19 concatStringsSep " " 20 (mapAttrsToList (x: y: "--keep-${x}=${toString y}") cfg.prune.keep); 21 22 + mkBackupScript = name: cfg: pkgs.writeShellScript "${name}-script" ('' 23 + set -e 24 on_exit() 25 { 26 exitStatus=$? ··· 62 ${optionalString (cfg.prune.prefix != null) "--glob-archives ${escapeShellArg "${cfg.prune.prefix}*"}"} \ 63 $extraPruneArgs 64 ${cfg.postPrune} 65 + ''); 66 67 mkPassEnv = cfg: with cfg.encryption; 68 if passCommand != null then ··· 74 mkBackupService = name: cfg: 75 let 76 userHome = config.users.users.${cfg.user}.home; 77 + backupJobName = "borgbackup-job-${name}"; 78 + backupScript = mkBackupScript backupJobName cfg; 79 + in nameValuePair backupJobName { 80 description = "BorgBackup job ${name}"; 81 path = with pkgs; [ 82 borgbackup openssh 83 ]; 84 + script = "exec " + optionalString cfg.inhibitsSleep ''\ 85 + ${pkgs.systemd}/bin/systemd-inhibit \ 86 + --who="borgbackup" \ 87 + --what="sleep" \ 88 + --why="Scheduled backup" \ 89 + '' + backupScript; 90 serviceConfig = { 91 User = cfg.user; 92 Group = cfg.group; ··· 346 {manpage}`systemd.timer(5)` 347 which triggers the backup immediately if the last trigger 348 was missed (e.g. if the system was powered down). 349 + ''; 350 + }; 351 + 352 + inhibitsSleep = mkOption { 353 + default = false; 354 + type = types.bool; 355 + example = true; 356 + description = lib.mdDoc '' 357 + Prevents the system from sleeping while backing up. 358 ''; 359 }; 360
+20
nixos/tests/borgbackup.nix
··· 99 environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519"; 100 }; 101 102 }; 103 }; 104 ··· 204 client.wait_for_unit("network.target") 205 client.systemctl("start --wait borgbackup-job-commandFail") 206 client.succeed("systemctl is-failed borgbackup-job-commandFail") 207 ''; 208 })
··· 99 environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519"; 100 }; 101 102 + sleepInhibited = { 103 + inhibitsSleep = true; 104 + # Blocks indefinitely while "backing up" so that we can try to suspend the local system while it's hung 105 + dumpCommand = pkgs.writeScript "sleepInhibited" '' 106 + cat /dev/zero 107 + ''; 108 + repo = remoteRepo; 109 + encryption.mode = "none"; 110 + startAt = [ ]; 111 + environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519"; 112 + }; 113 + 114 }; 115 }; 116 ··· 216 client.wait_for_unit("network.target") 217 client.systemctl("start --wait borgbackup-job-commandFail") 218 client.succeed("systemctl is-failed borgbackup-job-commandFail") 219 + 220 + with subtest("sleepInhibited"): 221 + server.wait_for_unit("sshd.service") 222 + client.wait_for_unit("network.target") 223 + client.fail("systemd-inhibit --list | grep -q borgbackup") 224 + client.systemctl("start borgbackup-job-sleepInhibited") 225 + client.wait_until_succeeds("systemd-inhibit --list | grep -q borgbackup") 226 + client.systemctl("stop borgbackup-job-sleepInhibited") 227 ''; 228 })