Merge pull request #125696 from hercules-ci/postgresql-backup-only-replace-if-successful

nixos/postgresqlBackup: only replace if successful

Changed files
+32 -4
nixos
modules
services
tests
+10 -4
nixos/modules/services/backup/postgresql-backup.nix
···
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 = {
···
})
(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;
+22
nixos/tests/postgresql.nix
···
machine.succeed(
"systemctl start ${backupService}.service",
"zcat /var/backup/postgresql/${backupName}.sql.gz | grep '<test>ok</test>'",
+
"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 '<test>ok</test>'",
+
"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 '<test>ok</test>'",
+
)
+
with subtest("Initdb works"):
machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2")