diff --git a/nixos/modules/services/backup/postgresql-backup.nix b/nixos/modules/services/backup/postgresql-backup.nix
index 9da2d522a68..f658eb756f7 100644
--- a/nixos/modules/services/backup/postgresql-backup.nix
+++ b/nixos/modules/services/backup/postgresql-backup.nix
@@ -14,15 +14,21 @@ let
requires = [ "postgresql.service" ];
+ path = [ pkgs.coreutils pkgs.gzip config.services.postgresql.package ];
+
script = ''
+ set -e -o pipefail
+
umask 0077 # ensure backup is only readable by postgres user
if [ -e ${cfg.location}/${db}.sql.gz ]; then
- ${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
+ mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
fi
${dumpCmd} | \
- ${pkgs.gzip}/bin/gzip -c > ${cfg.location}/${db}.sql.gz
+ gzip -c > ${cfg.location}/${db}.in-progress.sql.gz
+
+ mv ${cfg.location}/${db}.in-progress.sql.gz ${cfg.location}/${db}.sql.gz
'';
serviceConfig = {
@@ -113,12 +119,12 @@ in {
})
(mkIf (cfg.enable && cfg.backupAll) {
systemd.services.postgresqlBackup =
- postgresqlBackupService "all" "${config.services.postgresql.package}/bin/pg_dumpall";
+ postgresqlBackupService "all" "pg_dumpall";
})
(mkIf (cfg.enable && !cfg.backupAll) {
systemd.services = listToAttrs (map (db:
let
- cmd = "${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db}";
+ cmd = "pg_dump ${cfg.pgdumpOptions} ${db}";
in {
name = "postgresqlBackup-${db}";
value = postgresqlBackupService db cmd;
diff --git a/nixos/tests/postgresql.nix b/nixos/tests/postgresql.nix
index 091e64294ac..0369a070719 100644
--- a/nixos/tests/postgresql.nix
+++ b/nixos/tests/postgresql.nix
@@ -73,8 +73,30 @@ let
machine.succeed(
"systemctl start ${backupService}.service",
"zcat /var/backup/postgresql/${backupName}.sql.gz | grep 'ok'",
+ "ls -hal /var/backup/postgresql/ >/dev/console",
"stat -c '%a' /var/backup/postgresql/${backupName}.sql.gz | grep 600",
)
+ with subtest("Backup service fails gracefully"):
+ # Sabotage the backup process
+ machine.succeed("rm /run/postgresql/.s.PGSQL.5432")
+ machine.fail(
+ "systemctl start ${backupService}.service",
+ )
+ machine.succeed(
+ "ls -hal /var/backup/postgresql/ >/dev/console",
+ "zcat /var/backup/postgresql/${backupName}.prev.sql.gz | grep 'ok'",
+ "stat /var/backup/postgresql/${backupName}.in-progress.sql.gz",
+ )
+ # In a previous version, the second run would overwrite prev.sql.gz,
+ # so we test a second run as well.
+ machine.fail(
+ "systemctl start ${backupService}.service",
+ )
+ machine.succeed(
+ "stat /var/backup/postgresql/${backupName}.in-progress.sql.gz",
+ "zcat /var/backup/postgresql/${backupName}.prev.sql.gz | grep 'ok'",
+ )
+
with subtest("Initdb works"):
machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2")