From 12c82794e3e41887e6a1a2608582aff0586df021 Mon Sep 17 00:00:00 2001 From: ibizaman Date: Wed, 22 Apr 2026 23:44:48 +0200 Subject: [PATCH] backup: do not make systemd service wait for backup to complete fixes #421 --- docs/redirects.json | 12 +++++++ modules/blocks/borgbackup.nix | 10 ++++-- modules/blocks/borgbackup/docs/default.md | 31 +++++++++++++++++ modules/blocks/restic.nix | 8 ++++- modules/blocks/restic/docs/default.md | 41 ++++++++++++++++++++--- modules/contracts/backup/test.nix | 2 +- modules/contracts/databasebackup/test.nix | 2 +- test/blocks/borgbackup.nix | 2 +- 8 files changed, 97 insertions(+), 11 deletions(-) diff --git a/docs/redirects.json b/docs/redirects.json index 14683c3..8cb396b 100644 --- a/docs/redirects.json +++ b/docs/redirects.json @@ -347,6 +347,12 @@ "blocks-borgbackup-maintenance": [ "blocks-borgbackup.html#blocks-borgbackup-maintenance" ], + "blocks-borgbackup-maintenance-manuql": [ + "blocks-borgbackup.html#blocks-borgbackup-maintenance-manuql" + ], + "blocks-borgbackup-maintenance-restore": [ + "blocks-borgbackup.html#blocks-borgbackup-maintenance-restore" + ], "blocks-borgbackup-maintenance-troubleshooting": [ "blocks-borgbackup.html#blocks-borgbackup-maintenance-troubleshooting" ], @@ -1373,6 +1379,12 @@ "blocks-restic-maintenance": [ "blocks-restic.html#blocks-restic-maintenance" ], + "blocks-restic-maintenance-manuql": [ + "blocks-restic.html#blocks-restic-maintenance-manuql" + ], + "blocks-restic-maintenance-restore": [ + "blocks-restic.html#blocks-restic-maintenance-restore" + ], "blocks-restic-maintenance-troubleshooting": [ "blocks-restic.html#blocks-restic-maintenance-troubleshooting" ], diff --git a/modules/blocks/borgbackup.nix b/modules/blocks/borgbackup.nix index 087e425..fb83b0f 100644 --- a/modules/blocks/borgbackup.nix +++ b/modules/blocks/borgbackup.nix @@ -386,8 +386,13 @@ in ${serviceName} = mkMerge [ { serviceConfig = { - # Makes the systemd service wait for the backup to be done before changing state to inactive. - Type = "oneshot"; + # Purposely not a oneshot systemd service otherwise + # the service waits on the completion the backup before deactivating. + # This seems like a nice property at first but there is one annoying + # edge case when deploying. If a backup job somehow is started when + # the deploy happens, the deploy will wait on the service to finish + # before considering the deploy done. And worse, it will consider the + # deploy as failed if the backup fails, which is not what you want. Nice = lib.mkForce cfg.performance.niceness; IOSchedulingClass = lib.mkForce cfg.performance.ioSchedulingClass; IOSchedulingPriority = lib.mkForce cfg.performance.ioPriority; @@ -414,6 +419,7 @@ in in { script = script.preStart; + # Makes the systemd service wait for the backup to be done before changing state to inactive. serviceConfig.Type = "oneshot"; serviceConfig.LoadCredential = script.loadCredentials; } diff --git a/modules/blocks/borgbackup/docs/default.md b/modules/blocks/borgbackup/docs/default.md index 0ce2408..8e84989 100644 --- a/modules/blocks/borgbackup/docs/default.md +++ b/modules/blocks/borgbackup/docs/default.md @@ -3,6 +3,7 @@ Defined in [`/modules/blocks/borgbackup.nix`](@REPO@/modules/blocks/borgbackup.nix). This block sets up a backup job using [BorgBackup][]. +It is heavily based on the nixpkgs BorgBackup module. [borgbackup]: https://www.borgbackup.org/ @@ -229,6 +230,36 @@ See [Backups Dashboard and Alert](blocks-monitoring.html#blocks-monitoring-backu ## Maintenance {#blocks-borgbackup-maintenance} +### Manual Backup {#blocks-borgbackup-maintenance-manuql} + +To launch a backup manually, just run: + +```bash +systemctl start +``` + +You can easily discover the systemd service name you need by either listing the units: + +```bash +systemctl list-units 'borgbackup*' +``` + +Or by autocompleting the unit name with ``: + +```bash +systemctl start borgbackup +``` + +Note that the systemd services are of `Type=simple` which means the systemd service +will not wait for the backup completion to terminate. +If you want instead to wait for the backup to complete, use the `--wait` flag: + +```bash +systemctl start --wait +``` + +### Restore {#blocks-borgbackup-maintenance-restore} + One command-line helper is provided per backup instance and repository pair to automatically supply the needed secrets. The restore script has all the secrets needed to access the repo, diff --git a/modules/blocks/restic.nix b/modules/blocks/restic.nix index e508816..6a0f711 100644 --- a/modules/blocks/restic.nix +++ b/modules/blocks/restic.nix @@ -413,7 +413,13 @@ in nameValuePair "${fullName name instance.settings.repository}_restore_gen" { enable = true; wantedBy = [ "multi-user.target" ]; - serviceConfig.Type = "oneshot"; + # Purposely not a oneshot systemd service otherwise + # the service waits on the completion the backup before deactivating. + # This seems like a nice property at first but there is one annoying + # edge case when deploying. If a backup job somehow is started when + # the deploy happens, the deploy will wait on the service to finish + # before considering the deploy done. And worse, it will consider the + # deploy as failed if the backup fails, which is not what you want. script = ( shb.replaceSecrets { userConfig = instance.settings.repository.secrets // { diff --git a/modules/blocks/restic/docs/default.md b/modules/blocks/restic/docs/default.md index 23d7192..9edf6f4 100644 --- a/modules/blocks/restic/docs/default.md +++ b/modules/blocks/restic/docs/default.md @@ -3,12 +3,12 @@ Defined in [`/modules/blocks/restic.nix`](@REPO@/modules/blocks/restic.nix). This block sets up a backup job using [Restic][]. +It is heavily based on the nixpkgs Restic module. [restic]: https://restic.net/ ## Provider Contracts {#blocks-restic-contract-provider} - This block provides the following contracts: - [backup contract](contracts-backup.html) under the [`shb.restic.instances`][instances] option. @@ -26,7 +26,6 @@ a backup Systemd service and a [restore script](#blocks-restic-maintenance) are ## Usage {#blocks-restic-usage} - The following examples assume usage of the [sops block][] to provide secrets although any blocks providing the [secrets contract][] works too. @@ -35,7 +34,6 @@ although any blocks providing the [secrets contract][] works too. ### One folder backed up manually {#blocks-restic-usage-provider-manual} - The following snippet shows how to configure the backup of 1 folder to 1 repository. We assume that the folder `/var/lib/myfolder` of the service `myservice` must be backed up. @@ -232,11 +230,44 @@ See [Backups Dashboard and Alert](blocks-monitoring.html#blocks-monitoring-backu ## Maintenance {#blocks-restic-maintenance} -One command-line helper is provided per backup instance and repository pair to automatically supply the needed secrets. +### Manual Backup {#blocks-restic-maintenance-manuql} + +To launch a backup manually, just run: + +```bash +systemctl start +``` + +You can easily discover the systemd service name you need by either listing the units: + +```bash +systemctl list-units 'restic*' +``` + +Or by autocompleting the unit name with ``: + +```bash +systemctl start restic +``` + +Note that the systemd services are of `Type=simple` which means the systemd service +will not wait for the backup completion to terminate. +If you want instead to wait for the backup to complete, use the `--wait` flag: + +```bash +systemctl start --wait +``` + +### Restore {#blocks-restic-maintenance-restore} + +One command-line helper is provided per backup instance and repository pair which allows to: + +- list snapshots: `