Personal Nix setup
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update backup paths

+41 -48
+28 -34
modules/server/backup.nix
··· 8 8 rclone = "${pkgs.rclone}/bin/rclone"; 9 9 coreutils = pkgs.coreutils; 10 10 11 - rcloneFlags = "--config ${backup.configPath}"; 11 + rcloneConf = "/etc/rclone-backup.conf"; 12 + rcloneFlags = "--config ${rcloneConf} --skip-links --ignore-errors --fast-list --size-only"; 12 13 13 14 pathType = types.submodule ({ name, ... }: { 14 15 options = { 15 16 name = mkOption { 16 17 default = name; 17 - description = "Name used as the backup subdirectory in the remote. Defaults to the attribute name."; 18 18 type = types.str; 19 + internal = true; 19 20 }; 20 21 21 22 path = mkOption { ··· 29 30 type = types.nullOr types.str; 30 31 }; 31 32 32 - extras = mkOption { 33 + exclude = mkOption { 33 34 default = []; 34 - description = "Additional files/directories within path to copy alongside a sqlite backup."; 35 + description = "Patterns to exclude from sync backups."; 35 36 type = types.listOf types.str; 36 37 }; 38 + 37 39 }; 38 40 }); 39 41 42 + mkSyncBackup = path: let 43 + sqliteExcludes = optionals (path.sqlite != null) 44 + (map (s: "--exclude ${escapeShellArg s}") [ path.sqlite "${path.sqlite}-shm" "${path.sqlite}-wal" ]); 45 + userExcludes = map (p: "--exclude ${escapeShellArg p}") path.exclude; 46 + excludeFlags = concatStringsSep " " (sqliteExcludes ++ userExcludes); 47 + in '' 48 + echo "Syncing ${path.name}..." 49 + ${rclone} ${rcloneFlags} sync ${excludeFlags} "${path.path}" "r2crypt:${path.name}/" 50 + ''; 51 + 40 52 mkSqliteBackup = path: let 41 53 sqlite = "${pkgs.sqlite}/bin/sqlite3"; 42 54 in '' 43 - echo "Backing up ${path.name}..." 55 + echo "Backing up ${path.name} database..." 44 56 ${coreutils}/bin/mkdir -p "$TMP/${path.name}" 45 57 ${sqlite} "${path.path}/${path.sqlite}" ".backup $TMP/${path.name}/${path.sqlite}" 46 - ${concatMapStringsSep "\n" (item: '' 47 - if [ -e "${path.path}/${item}" ]; then 48 - ${coreutils}/bin/cp -a "${path.path}/${item}" "$TMP/${path.name}/" 49 - fi 50 - '') path.extras} 51 - ${rclone} ${rcloneFlags} copy "$TMP/${path.name}" "r2crypt:${path.name}/$DATE/" 58 + ${rclone} ${rcloneFlags} copy "$TMP/${path.name}" "r2crypt:${path.name}-db/$DATE/" 52 59 ''; 53 60 54 61 mkSqlitePrune = path: '' 55 - CUTOFF=$(${coreutils}/bin/date -d '-${toString backup.retention} days' +%Y-%m-%d) 56 - ${rclone} ${rcloneFlags} lsd "r2crypt:${path.name}/" 2>/dev/null | ${coreutils}/bin/awk '{print $NF}' | while read -r dir; do 57 - if [[ "$dir" < "$CUTOFF" ]]; then 58 - ${rclone} ${rcloneFlags} purge "r2crypt:${path.name}/$dir/" || true 59 - fi 60 - done 61 - ''; 62 - 63 - mkSyncBackup = path: '' 64 - echo "Syncing ${path.name}..." 65 - ${rclone} ${rcloneFlags} sync "${path.path}" "r2crypt:${path.name}/" 62 + ${rclone} ${rcloneFlags} delete --min-age ${toString backup.retention}d "r2crypt:${path.name}-db/" 66 63 ''; 67 64 68 65 in helpers.linuxAttrs { ··· 94 91 default = 30; 95 92 description = "Number of days to retain backups."; 96 93 type = types.int; 97 - }; 98 - 99 - configPath = mkOption { 100 - default = "/etc/rclone-backup.conf"; 101 - description = "Path to the rclone configuration file."; 102 - type = types.str; 103 94 }; 104 95 105 96 paths = mkOption { ··· 110 101 }; 111 102 112 103 config = let 113 - sqlitePaths = filter (p: p.sqlite != null) (attrValues backup.paths); 114 - syncPaths = filter (p: p.sqlite == null) (attrValues backup.paths); 104 + allPaths = attrValues backup.paths; 105 + sqlitePaths = filter (p: p.sqlite != null) allPaths; 115 106 in mkIf (cfg.enable && backup.enable) { 107 + 116 108 environment.etc."rclone-backup.conf".text = '' 117 109 [r2] 118 110 type = s3 ··· 123 115 [r2crypt] 124 116 type = crypt 125 117 remote = r2:${backup.bucket} 118 + filename_encryption = off 119 + directory_name_encryption = false 126 120 ''; 127 121 128 122 age.secrets."rclone-backup.env" = { ··· 146 140 trap '${coreutils}/bin/rm -rf "$TMP"' EXIT 147 141 148 142 ${concatMapStringsSep "\n" (p: '' 143 + (set -e; ${mkSyncBackup p}) || FAILED=1 144 + '') allPaths} 145 + 146 + ${concatMapStringsSep "\n" (p: '' 149 147 (set -e; ${mkSqliteBackup p}) || FAILED=1 150 148 '') sqlitePaths} 151 149 152 150 ${concatMapStringsSep "\n" (p: '' 153 151 (set -e; ${mkSqlitePrune p}) || true 154 152 '') sqlitePaths} 155 - 156 - ${concatMapStringsSep "\n" (p: '' 157 - (set -e; ${mkSyncBackup p}) || FAILED=1 158 - '') syncPaths} 159 153 160 154 exit "$FAILED" 161 155 '';
+13 -13
modules/server/tangled.nix
··· 23 23 }; 24 24 }; 25 25 26 - config = mkIf (cfg.enable && cfg.tangled.enable) { 26 + config = let 27 + knot = config.services.tangled.knot; 28 + in mkIf (cfg.enable && cfg.tangled.enable) { 27 29 modules.server = { 28 - sshd.allowUsers = [ config.services.tangled.knot.gitUser ]; 30 + sshd.allowUsers = [ knot.gitUser ]; 29 31 backup.paths.tangled = { 30 - path = "${config.services.tangled.knot.stateDir}/repos"; 32 + path = knot.stateDir; 33 + sqlite = "knotserver.db"; 34 + exclude = [ "motd" ".*/**" ".*" ]; 31 35 }; 32 36 }; 33 37 ··· 94 98 description = "Update Tangled MOTD"; 95 99 serviceConfig = { 96 100 Type = "oneshot"; 97 - User = config.services.tangled.knot.gitUser; 98 - ExecStart = let 99 - stateDir = config.services.tangled.knot.stateDir; 100 - in pkgs.writeShellScript "tangled-motd" '' 101 - ${pkgs.fortune-kind}/bin/fortune-kind | ${pkgs.coreutils}/bin/head -1 > "${stateDir}/motd" 101 + User = knot.gitUser; 102 + ExecStart = pkgs.writeShellScript "tangled-motd" '' 103 + ${pkgs.fortune-kind}/bin/fortune-kind | ${pkgs.coreutils}/bin/head -1 > "${knot.stateDir}/motd" 102 104 ''; 103 105 }; 104 106 }; ··· 111 113 }; 112 114 }; 113 115 114 - age.secrets."gitconfig.private" = let 115 - user = config.services.tangled.knot.gitUser; 116 - in { 116 + age.secrets."gitconfig.private" = { 117 117 symlink = false; 118 118 path = "/etc/gitconfig.private"; 119 119 file = ./encrypt/gitconfig.age; 120 - owner = user; 121 - group = user; 120 + owner = knot.gitUser; 121 + group = knot.gitUser; 122 122 mode = "0444"; 123 123 }; 124 124 };
-1
modules/server/vaultwarden.nix
··· 30 30 modules.server.backup.paths.vaultwarden = { 31 31 path = "/var/lib/vaultwarden"; 32 32 sqlite = "db.sqlite3"; 33 - extras = [ "attachments" "rsa_key.pem" "rsa_key.pub.pem" ]; 34 33 }; 35 34 36 35 age.secrets."vaultwarden" = {