at 18.09-beta 4.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4{ 5 options.services.restic.backups = mkOption { 6 description = '' 7 Periodic backups to create with Restic. 8 ''; 9 type = types.attrsOf (types.submodule ({ name, ... }: { 10 options = { 11 passwordFile = mkOption { 12 type = types.str; 13 description = '' 14 Read the repository password from a file. 15 ''; 16 example = "/etc/nixos/restic-password"; 17 }; 18 19 s3CredentialsFile = mkOption { 20 type = with types; nullOr str; 21 default = null; 22 description = '' 23 file containing the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY 24 for an S3-hosted repository, in the format of an EnvironmentFile 25 as described by systemd.exec(5) 26 ''; 27 }; 28 29 repository = mkOption { 30 type = types.str; 31 description = '' 32 repository to backup to. 33 ''; 34 example = "sftp:backup@192.168.1.100:/backups/${name}"; 35 }; 36 37 paths = mkOption { 38 type = types.listOf types.str; 39 default = []; 40 description = '' 41 Which paths to backup. 42 ''; 43 example = [ 44 "/var/lib/postgresql" 45 "/home/user/backup" 46 ]; 47 }; 48 49 timerConfig = mkOption { 50 type = types.attrsOf types.str; 51 default = { 52 OnCalendar = "daily"; 53 }; 54 description = '' 55 When to run the backup. See man systemd.timer for details. 56 ''; 57 example = { 58 OnCalendar = "00:05"; 59 RandomizedDelaySec = "5h"; 60 }; 61 }; 62 63 user = mkOption { 64 type = types.str; 65 default = "root"; 66 description = '' 67 As which user the backup should run. 68 ''; 69 example = "postgresql"; 70 }; 71 72 extraBackupArgs = mkOption { 73 type = types.listOf types.str; 74 default = []; 75 description = '' 76 Extra arguments passed to restic backup. 77 ''; 78 example = [ 79 "--exclude-file=/etc/nixos/restic-ignore" 80 ]; 81 }; 82 83 extraOptions = mkOption { 84 type = types.listOf types.str; 85 default = []; 86 description = '' 87 Extra extended options to be passed to the restic --option flag. 88 ''; 89 example = [ 90 "sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'" 91 ]; 92 }; 93 94 initialize = mkOption { 95 type = types.bool; 96 default = false; 97 description = '' 98 Create the repository if it doesn't exist. 99 ''; 100 }; 101 }; 102 })); 103 default = {}; 104 example = { 105 localbackup = { 106 paths = [ "/home" ]; 107 repository = "/mnt/backup-hdd"; 108 passwordFile = "/etc/nixos/secrets/restic-password"; 109 initialize = true; 110 }; 111 remotebackup = { 112 paths = [ "/home" ]; 113 repository = "sftp:backup@host:/backups/home"; 114 passwordFile = "/etc/nixos/secrets/restic-password"; 115 extraOptions = [ 116 "sftp.command='ssh backup@host -i /etc/nixos/secrets/backup-private-key -s sftp'" 117 ]; 118 timerConfig = { 119 OnCalendar = "00:05"; 120 RandomizedDelaySec = "5h"; 121 }; 122 }; 123 }; 124 }; 125 126 config = { 127 systemd.services = 128 mapAttrs' (name: backup: 129 let 130 extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions; 131 resticCmd = "${pkgs.restic}/bin/restic${extraOptions}"; 132 in nameValuePair "restic-backups-${name}" ({ 133 environment = { 134 RESTIC_PASSWORD_FILE = backup.passwordFile; 135 RESTIC_REPOSITORY = backup.repository; 136 }; 137 path = with pkgs; [ 138 openssh 139 ]; 140 restartIfChanged = false; 141 serviceConfig = { 142 Type = "oneshot"; 143 ExecStart = "${resticCmd} backup ${concatStringsSep " " backup.extraBackupArgs} ${concatStringsSep " " backup.paths}"; 144 User = backup.user; 145 } // optionalAttrs (backup.s3CredentialsFile != null) { 146 EnvironmentFile = backup.s3CredentialsFile; 147 }; 148 } // optionalAttrs backup.initialize { 149 preStart = '' 150 ${resticCmd} snapshots || ${resticCmd} init 151 ''; 152 }) 153 ) config.services.restic.backups; 154 systemd.timers = 155 mapAttrs' (name: backup: nameValuePair "restic-backups-${name}" { 156 wantedBy = [ "timers.target" ]; 157 timerConfig = backup.timerConfig; 158 }) config.services.restic.backups; 159 }; 160}