summaryrefslogtreecommitdiffstats
path: root/modules/by-name/ba/backup/module.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/by-name/ba/backup/module.nix')
-rw-r--r--modules/by-name/ba/backup/module.nix78
1 files changed, 44 insertions, 34 deletions
diff --git a/modules/by-name/ba/backup/module.nix b/modules/by-name/ba/backup/module.nix
index e601d840..ca7a469c 100644
--- a/modules/by-name/ba/backup/module.nix
+++ b/modules/by-name/ba/backup/module.nix
@@ -1,25 +1,30 @@
-# nixos-config - My current NixOS configuration
-#
-# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-# This file is part of my nixos-config.
-#
-# You should have received a copy of the License along with this program.
-# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
{
lib,
config,
pkgs,
- libraries,
...
}: let
- cfg = config.soispha.services.backup;
+ cfg = config.vhack.services.backup;
snapshotDir = "/srv/last_snapshot";
in {
- options.soispha.services.backup = {
- enable = libraries.base.options.mkEnable "backups via restic";
+ options.vhack.services.backup = {
+ exclude = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ description = "Which paths to exclude from the backup. Should be absolute.";
+ example = [
+ "/var/lib/postgresql"
+ ];
+ };
+ backupPrepare = lib.mkOption {
+ type = lib.types.attrsOf lib.types.str;
+ example = ''
+ {
+ postgresql = "pg_dumpall";
+ }
+ '';
+ default = {};
+ };
storagebox = {
enable = lib.mkEnableOption "remote backups";
@@ -32,13 +37,17 @@ in {
sshKey = lib.mkOption {
type = lib.types.path;
description = "The age-encrypted ssh-key, passed to agenix";
- default = ./secrets/storagebox/ssh_key.age;
+ };
+
+ sshHostKey = lib.mkOption {
+ type = lib.types.str;
+ description = "The ssh public host key, to authenticate that the server matches.";
+ example = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
};
repositoryPassword = lib.mkOption {
type = lib.types.path;
description = "The age-encrypted restic password, passed to agenix";
- default = ./secrets/storagebox/repository_password.age;
};
};
@@ -48,7 +57,6 @@ in {
repositoryPassword = lib.mkOption {
type = lib.types.path;
description = "The age-encrypted restic password, passed to agenix";
- default = ./secrets/local/repository_password.age;
};
backupMountPoint = lib.mkOption {
@@ -59,11 +67,15 @@ in {
};
};
- config = lib.mkIf cfg.enable {
- soispha.impermanence.directories = lib.mkMerge [
+ config = lib.mkIf (cfg.local.enable || cfg.storagebox.enable) {
+ vhack.persist.directories = lib.mkMerge [
(lib.mkIf cfg.storagebox.enable [
"/var/cache/restic-backups-storagebox"
+ # TODO: Ideally we would not save the admin cache and normal cache separately, as
+ # they both access the exactly same data. The admin one just also has write
+ # access. But because the `systemd.mounts` thing does not work, they are saved
+ # separately now. <2026-10-31>
# Generate the base systemd.mount from impermanence (we will override this, so it
# points to the non-admin one instead)
"/var/cache/restic-backups-storagebox-admin"
@@ -101,10 +113,10 @@ in {
};
};
- soispha.programs.ssh = lib.mkIf cfg.storagebox.enable {
+ vhack.programs.ssh = lib.mkIf cfg.storagebox.enable {
enable = true;
rootKnownHosts = {
- "[u459143-sub1.your-storagebox.de]:23" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
+ "[${cfg.storagebox.user}.your-storagebox.de]:23" = cfg.storagebox.sshHostKey;
};
};
@@ -120,14 +132,17 @@ in {
serviceConfig = {
ExecStart = lib.getExe (pkgs.writeShellApplication {
name = "prepareBackup";
- text = ''
- set -x
-
- [ -d "${snapshotDir}" ] && btrfs subvolume delete "${snapshotDir}"
+ text =
+ ''
+ set -x
+ ''
+ + builtins.concatStringsSep "\n\n" (builtins.attrValues cfg.backupPrepare)
+ + ''
+ [ -d "${snapshotDir}" ] && btrfs subvolume delete "${snapshotDir}"
- # -r := Make the snapshot read-only
- btrfs subvolume snapshot -r /srv "${snapshotDir}";
- '';
+ # -r := Make the snapshot read-only
+ btrfs subvolume snapshot -r /srv "${snapshotDir}";
+ '';
inheritPath = false;
runtimeInputs = [
@@ -160,16 +175,10 @@ in {
};
services.restic.backups = let
- homeDir = "${snapshotDir}/home";
-
paths = [
snapshotDir
];
- exclude = [
- "${homeDir}/soispha/.cache"
- "${homeDir}/soispha/.local/share/lutris/install"
- "${homeDir}/soispha/.local/share/Steam/steamapps/common"
- ];
+ exclude = lib.map (path: "${snapshotDir}/${path}") cfg.exclude;
extraBackupArgs = [
# Don't scan the filesystem to determine an estimate.
"--no-scan"
@@ -208,6 +217,7 @@ in {
repository = "rclone: ";
timerConfig = {
+ Requires = "network-online.target";
OnActiveSec = "30m";
OnUnitInactiveSec = "2h";
Persistent = true;