Compare commits

..

7 Commits

4 changed files with 101 additions and 29 deletions

View File

@@ -2,3 +2,20 @@
Small NixOS module to do backups to my NAS.
## Usage example
```nix
# Example uses sops to store repo password
sops.secrets."backup_helper_secret" = { };
backup-helper = {
enable = true;
password-file = "/run/secrets/backup_helper_secret";
# Dirs to backup
backup-dirs = [
"/var/lib/important-data"
"/home/user/stuff"
];
};
```
See [this](https://git.t-juice.club/torjus/backup-helper/src/commit/e84295ad5951fe3eb97113a94c16fbed412734e5/backup.nix#L42-L71) for all options and defaults.

View File

@@ -11,25 +11,7 @@ let
runtimeInputs = [
pkgs.restic
];
text = ''
if [ -z "$BACKUP_HELPER_DIRS" ]; then
echo "BACKUP_HELPER_DIRS is not set"
exit 1;
fi
exit_code=0;
for i in ''${BACKUP_HELPER_DIRS//,/ }; do
echo "Starting backup of $i";
if ! output=$(restic backup "$i"); then
exit_code=1;
echo "Backup of $i failed with exit code $?:"
echo "$output"
else
echo "Backup of $i successful:"
echo "$output"
fi
done
exit "$exit_code";
'';
text = (builtins.readFile ./backup.sh);
};
in
{
@@ -45,6 +27,11 @@ in
default = [ ];
description = "Directories to be backed up.";
};
backup-commands = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Backup the stdout of commands. Format strings like key:command";
};
schedule = lib.mkOption {
type = lib.types.str;
default = "*-*-* 00:00:00";
@@ -60,6 +47,11 @@ in
default = 0;
description = "Randomized delay in seconds to spread out backups.";
};
forget = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Run restic forget after backup.";
};
};
config = lib.mkIf cfg.enable {
systemd.services."backup-helper" = {
@@ -69,9 +61,13 @@ in
{
RESTIC_REPOSITORY = cfg.restic-repository;
BACKUP_HELPER_DIRS = lib.strings.concatStringsSep "," cfg.backup-dirs;
BACKUP_FORGET = if cfg.forget then "1" else "0";
}
// lib.attrsets.optionalAttrs (builtins.hasAttr "password-file" cfg) {
RESTIC_PASSWORD_FILE = cfg.password-file;
}
// lib.attrsets.optionalAttrs (cfg.backup-commands != [ ]) {
BACKUP_HELPER_COMMANDS = lib.strings.concatStringsSep ";" cfg.backup-commands;
};
serviceConfig = {
Type = "oneshot";

51
backup.sh Normal file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# If neither of BACKUP_HELPER_DIRS and BACKUP_HELPER_COMMANDS not set. Exit
if [ -z "$BACKUP_HELPER_DIRS" ] && [ -z "$BACKUP_HELPER_COMMANDS" ]; then
echo "BACKUP_HELPER_DIRS is not set"
exit 1;
fi
exit_code=0;
# Backup directories
if [ -n "$BACKUP_HELPER_DIRS" ]; then
for i in ${BACKUP_HELPER_DIRS//,/ }; do
echo "Starting backup of $i";
if ! output=$(restic backup "$i"); then
exit_code=1;
echo "Backup of $i failed with exit code $?:"
echo "$output"
else
echo "Backup of $i successful:"
echo "$output"
fi
done
fi
# Backup command outputs
if [ -n "$BACKUP_HELPER_COMMANDS" ]; then
IFS=";" read -r -a pairs <<< "$BACKUP_HELPER_COMMANDS"
for pair in "${pairs[@]}"; do
IFS=":" read -r key value <<< "$pair"
# Split value into array of command args
IFS=' ' read -r -a cmd_parts <<< "$value"
if ! output=$(restic backup --stdin-filename "$key" --stdin-from-command -- "${cmd_parts[@]}"); then
exit_code=1;
echo "Backup of $key failed with exit code $?:"
echo "$output"
else
echo "Backup of $key successful:"
echo "$output"
fi
done
fi
if [ "$BACKUP_FORGET" -eq 1 ]; then
echo "Removing old backups"
output=$(restic forget -d 7 -w 4 -m 6 --keep-within 1d --prune)
echo "$output"
fi
exit "$exit_code"

View File

@@ -3,7 +3,8 @@
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
outputs =
{ self, nixpkgs }:
let
allSystems = [
"x86_64-linux"
@@ -11,24 +12,31 @@
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {
forAllSystems =
f:
nixpkgs.lib.genAttrs allSystems (
system:
f {
pkgs = import nixpkgs { inherit system; };
});
}
);
in
{
nixosModules.backup-helper = import ./backup.nix;
nixosModules.default = self.nixosModules.backup-helper;
devShells = forAllSystems ({ pkgs }: {
devShells = forAllSystems (
{ pkgs }:
{
default = pkgs.mkShell {
packages = with pkgs;
[
packages = with pkgs; [
restic
bash
jq
curl
];
};
});
}
);
};
}