1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.postgresqlBackup;
8
9 postgresqlBackupService = db: dumpCmd:
10 {
11 enable = true;
12
13 description = "Backup of ${db} database(s)";
14
15 requires = [ "postgresql.service" ];
16
17 script = ''
18 umask 0077 # ensure backup is only readable by postgres user
19
20 if [ -e ${cfg.location}/${db}.sql.gz ]; then
21 ${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
22 fi
23
24 ${dumpCmd} | \
25 ${pkgs.gzip}/bin/gzip -c > ${cfg.location}/${db}.sql.gz
26 '';
27
28 serviceConfig = {
29 Type = "oneshot";
30 User = "postgres";
31 };
32
33 startAt = cfg.startAt;
34 };
35
36in {
37
38 imports = [
39 (mkRemovedOptionModule [ "services" "postgresqlBackup" "period" ] ''
40 A systemd timer is now used instead of cron.
41 The starting time can be configured via <literal>services.postgresqlBackup.startAt</literal>.
42 '')
43 ];
44
45 options = {
46 services.postgresqlBackup = {
47 enable = mkEnableOption "PostgreSQL dumps";
48
49 startAt = mkOption {
50 default = "*-*-* 01:15:00";
51 type = with types; either (listOf str) str;
52 description = ''
53 This option defines (see <literal>systemd.time</literal> for format) when the
54 databases should be dumped.
55 The default is to update at 01:15 (at night) every day.
56 '';
57 };
58
59 backupAll = mkOption {
60 default = cfg.databases == [];
61 defaultText = "services.postgresqlBackup.databases == []";
62 type = lib.types.bool;
63 description = ''
64 Backup all databases using pg_dumpall.
65 This option is mutual exclusive to
66 <literal>services.postgresqlBackup.databases</literal>.
67 The resulting backup dump will have the name all.sql.gz.
68 This option is the default if no databases are specified.
69 '';
70 };
71
72 databases = mkOption {
73 default = [];
74 type = types.listOf types.str;
75 description = ''
76 List of database names to dump.
77 '';
78 };
79
80 location = mkOption {
81 default = "/var/backup/postgresql";
82 type = types.path;
83 description = ''
84 Location to put the gzipped PostgreSQL database dumps.
85 '';
86 };
87
88 pgdumpOptions = mkOption {
89 type = types.separatedString " ";
90 default = "-C";
91 description = ''
92 Command line options for pg_dump. This options is not used
93 if <literal>config.services.postgresqlBackup.backupAll</literal> is enabled.
94 Note that config.services.postgresqlBackup.backupAll is also active,
95 when no databases where specified.
96 '';
97 };
98 };
99
100 };
101
102 config = mkMerge [
103 {
104 assertions = [{
105 assertion = cfg.backupAll -> cfg.databases == [];
106 message = "config.services.postgresqlBackup.backupAll cannot be used together with config.services.postgresqlBackup.databases";
107 }];
108 }
109 (mkIf cfg.enable {
110 systemd.tmpfiles.rules = [
111 "d '${cfg.location}' 0700 postgres - - -"
112 ];
113 })
114 (mkIf (cfg.enable && cfg.backupAll) {
115 systemd.services.postgresqlBackup =
116 postgresqlBackupService "all" "${config.services.postgresql.package}/bin/pg_dumpall";
117 })
118 (mkIf (cfg.enable && !cfg.backupAll) {
119 systemd.services = listToAttrs (map (db:
120 let
121 cmd = "${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db}";
122 in {
123 name = "postgresqlBackup-${db}";
124 value = postgresqlBackupService db cmd;
125 }) cfg.databases);
126 })
127 ];
128
129}