From 8430708d0b8b6e773cf45e430b37d7e5daffd319 Mon Sep 17 00:00:00 2001
From: sivertism <10866270+sivertism@users.noreply.github.com>
Date: Wed, 2 Oct 2024 15:42:42 +0200
Subject: [PATCH] initial attempt

---
 modules/blocks/postgresql.nix | 43 +++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/modules/blocks/postgresql.nix b/modules/blocks/postgresql.nix
index 1c2bfd0..bc3b755 100644
--- a/modules/blocks/postgresql.nix
+++ b/modules/blocks/postgresql.nix
@@ -1,6 +1,7 @@
 { config, lib, pkgs, ... }:
 let
   cfg = config.shb.postgresql;
+  contracts = pkgs.callPackage ../contracts {};
 
   upgrade-script = old: new:
     let
@@ -49,6 +50,48 @@ in
       default = false;
     };
 
+    backup = lib.mkOption {
+      type = contracts.backup;
+      description = ''
+        Backup configuration. This is an output option.
+
+        Use it to initialize a block implementing the "backup" contract.
+        For example, with the restic block:
+
+        ```
+        shb.restic.instances."postgresql" = {
+          enable = true;
+
+          # Options specific to Restic.
+        } // config.shb.nextcloud.backup;
+        ```
+      '';
+      readOnly = true;
+      default = {
+        user = "postgresql";
+        sourceDirectories = [
+          /tmp/postgresql_backup
+        ];
+        excludePatterns = [ ];
+
+        hooks.before_backup = [''
+          set -e -o pipefail
+
+          umask 077 # Ensure backup is only readable by postgres user
+
+          rm -rf /tmp/postgresql_backup # Clean up in case after_backup hook wasn't run.
+          mkdir /tmp/postgresql_backup
+
+          ${pkgs.psql}/bin/pg_dumpall | ${pkgs.gzip}/bin/gzip --rsyncable > /tmp/postgresql_backup/pg_dumpall.sql.gz
+        ''];
+
+        hooks.after_backup = [''
+          set -e -o pipefail
+          rm -rf /tmp/postgresql_backup
+        ''];
+      };
+    };
+
     ensures = lib.mkOption {
       description = "List of username, database and/or passwords that should be created.";
       type = lib.types.listOf (lib.types.submodule {