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