1{ lib, pkgs, ... }:
2let
3 inherit (import ../ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
4 backupPath = "/home/backup";
5in
6{
7 name = "pgbackrest-sftp";
8
9 meta = {
10 maintainers = with lib.maintainers; [ wolfgangwalther ];
11 };
12
13 nodes.primary =
14 {
15 pkgs,
16 ...
17 }:
18 {
19 services.postgresql = {
20 enable = true;
21 initialScript = pkgs.writeText "init.sql" ''
22 CREATE TABLE t(c text);
23 INSERT INTO t VALUES ('hello world');
24 '';
25 };
26
27 services.pgbackrest = {
28 enable = true;
29 repos.backup = {
30 type = "sftp";
31 path = "/home/backup";
32 sftp-host-key-check-type = "none";
33 sftp-host-key-hash-type = "sha256";
34 sftp-host-user = "backup";
35 sftp-private-key-file = "/var/lib/pgbackrest/sftp_key";
36 };
37
38 stanzas.default.jobs.future = {
39 schedule = "3000-01-01";
40 type = "diff";
41 };
42 };
43 };
44
45 nodes.backup =
46 {
47 nodes,
48 ...
49 }:
50 {
51 services.openssh.enable = true;
52 users.users.backup = {
53 name = "backup";
54 group = "backup";
55 isNormalUser = true;
56 createHome = true;
57 openssh.authorizedKeys.keys = [
58 snakeOilPublicKey
59 ];
60 };
61 users.groups.backup = { };
62 };
63
64 testScript =
65 { nodes, ... }:
66 ''
67 start_all()
68
69 primary.wait_for_unit("multi-user.target")
70 backup.wait_for_unit("multi-user.target")
71
72 primary.log(primary.succeed("""
73 HOME="/var/lib/pgbackrest"
74 cat ${snakeOilPrivateKey} > ~/sftp_key
75 chown -R pgbackrest:pgbackrest ~/sftp_key
76 chmod 770 ~
77 """))
78
79 with subtest("backup/restore works with local instance/remote repo (SFTP)"):
80 primary.succeed("sudo -u pgbackrest pgbackrest --stanza=default stanza-create", timeout=10)
81 primary.succeed("sudo -u pgbackrest pgbackrest --stanza=default check")
82
83 primary.systemctl("start pgbackrest-default-future")
84
85 # corrupt cluster
86 primary.systemctl("stop postgresql")
87 primary.execute("rm ${nodes.primary.services.postgresql.dataDir}/global/pg_control")
88
89 primary.succeed("sudo -u postgres pgbackrest --stanza=default restore --delta")
90
91 primary.systemctl("start postgresql")
92 primary.wait_for_unit("postgresql.target")
93 assert "hello world" in primary.succeed("sudo -u postgres psql -c 'TABLE t;'")
94 '';
95}