Hermes: Enable Backup module
This is admittedly a failure, because restic is a one way street. It takes what is on disk and pushes to backup location. Which means, if I want to restore the backup, I have to restore first, by way of imperatively setting up restic repos in advance and then setting up the backup servies for restic. This is not ideal, and Syncthing has proven to be more suitable solution for my needs. But, considering my possible future requirements, I should start thinking about solving this problem.
This commit is contained in:
parent
9ff1246638
commit
527e463208
2 changed files with 275 additions and 0 deletions
|
@ -98,6 +98,7 @@
|
|||
# ./hosts/enterprise/backup.nix
|
||||
./hosts/hermes/configuration.nix
|
||||
./hosts/hermes/syncthing.nix
|
||||
./hosts/hermes/backup.nix
|
||||
|
||||
# User-specific config : Home-manager
|
||||
home-manager.nixosModules.home-manager
|
||||
|
|
274
hosts/hermes/backup.nix
Normal file
274
hosts/hermes/backup.nix
Normal file
|
@ -0,0 +1,274 @@
|
|||
{ config, pkgs, options, ... }:
|
||||
|
||||
# Automated Backup and backup notification configuration for NixOS
|
||||
# Using:
|
||||
# 1. Restic : encryption, snapshots, dedeuplication
|
||||
# 2. Rclone : access to free storages (Google Drive, OneDrive etc)
|
||||
# 3. Systemd/NixOS : automation, notifications etc
|
||||
# 4. (DBus) : desktop notifications, provided by Plasma desktop
|
||||
let
|
||||
payas = "payas";
|
||||
in
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
restic # It is included in system by restic service, but its useful to have the package in PATH to remove occasional locks
|
||||
rsync
|
||||
rclone
|
||||
];
|
||||
|
||||
# Le Backups!! Test them every month or so, just to be sure
|
||||
services.restic.backups =
|
||||
let
|
||||
defaultPruneOpts = [
|
||||
"--keep-last 10"
|
||||
"--keep-hourly 3"
|
||||
"--keep-daily 4"
|
||||
"--keep-weekly 3"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
defaultBackupFrequency = "hourly";
|
||||
in
|
||||
{
|
||||
# maildir (for one email account, on a shared folder curtosy of family member)
|
||||
maildir_relekarpayas_onedrive_shared = {
|
||||
user = payas;
|
||||
repository = "rclone:relekarpayas_onedrive_shared:/payas_backup/maildir_rpg";
|
||||
initialize = true; # for now, I want to control repo intialization myself
|
||||
passwordFile = config.age.secrets.maildir_relekarpayas_onedrive.path;
|
||||
paths = [ "/home/payas/.mail/" ];
|
||||
# Run our nice little service every hour. If this proves too taxing, increase duration or give out fixed time.
|
||||
timerConfig.OnCalendar = defaultBackupFrequency;
|
||||
pruneOpts = defaultPruneOpts;
|
||||
};
|
||||
|
||||
# Syncthing dir
|
||||
syncthing_googledrive = {
|
||||
user = payas;
|
||||
repository = "rclone:relekarpayas_googledrive:/syncthing";
|
||||
initialize = true; # for now, I want to control repo intialization myself
|
||||
passwordFile = config.age.secrets.syncthing_relekarpayas_googledrive.path;
|
||||
paths = [ "/home/payas/Syncthing/" ];
|
||||
# Ignore Media dir because it contains non-essential and heavy media files
|
||||
extraBackupArgs = [ "--exclude=/home/payas/Syncthing/Media" ];
|
||||
# Run our nice little service every hour. If this proves too taxing, increase duration or give out fixed time.
|
||||
timerConfig.OnCalendar = defaultBackupFrequency;
|
||||
pruneOpts = defaultPruneOpts;
|
||||
};
|
||||
|
||||
syncthing_onedrive_shared = {
|
||||
user = payas;
|
||||
repository = "rclone:relekarpayas_onedrive_shared:/payas_backup/Syncthing";
|
||||
initialize = true; # for now, I want to control repo intialization myself
|
||||
passwordFile = config.age.secrets.syncthing_relekarpayas_onedrive.path;
|
||||
paths = [ "/home/payas/Syncthing/" ];
|
||||
# Ignore Media dir because it contains non-essential and heavy media files
|
||||
extraBackupArgs = [ "--exclude=/home/payas/Syncthing/Media" ];
|
||||
# Run our nice little service every hour. If this proves too taxing, increase duration or give out fixed time.
|
||||
timerConfig.OnCalendar = defaultBackupFrequency;
|
||||
pruneOpts = defaultPruneOpts;
|
||||
};
|
||||
|
||||
# Org-mode notes
|
||||
org_googledrive = {
|
||||
user = payas;
|
||||
repository = "rclone:relekarpayas_googledrive:/org";
|
||||
initialize = true; # for now, I want to control repo intialization myself
|
||||
passwordFile = config.age.secrets.org_relekarpayas_googledrive.path;
|
||||
paths = [ "/home/payas/org/" ];
|
||||
# Run our nice little service every hour. If this proves too taxing, increase duration or give out fixed time.
|
||||
timerConfig.OnCalendar = defaultBackupFrequency;
|
||||
pruneOpts = defaultPruneOpts;
|
||||
};
|
||||
|
||||
org_onedrive_shared = {
|
||||
user = payas;
|
||||
repository = "rclone:relekarpayas_onedrive_shared:/payas_backup/org";
|
||||
initialize = true; # for now, I want to control repo intialization myself
|
||||
passwordFile = config.age.secrets.org_relekarpayas_onedrive.path;
|
||||
paths = [ "/home/payas/org/" ];
|
||||
# Run our nice little service every hour. If this proves too taxing, increase duration or give out fixed time.
|
||||
timerConfig.OnCalendar = defaultBackupFrequency;
|
||||
pruneOpts = defaultPruneOpts;
|
||||
};
|
||||
};
|
||||
|
||||
# Le Backup notifications : So I find out about success/failure of backups without having to check logs every now and then
|
||||
# This generates actual desktop notifications, and integrates nicely (as long as DBus is accessible to service)
|
||||
#
|
||||
# Backup notification idea (for now) is this:
|
||||
# 1. Detect service failure: handled by systemd
|
||||
# 2. Invoke alert service: handled by systemd
|
||||
# 3. touch a BACKUP_Failure file in ~: probably unnecessary, but I intent to delete these files after
|
||||
# investigating/fixing failures so as to have greater visibility and
|
||||
# don't want file-not-exist conflicts
|
||||
# 4. Show desktop notification for exactly which backup failed
|
||||
systemd.services =
|
||||
let
|
||||
defaultBackupServiceEnv = {
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/user/1000/bus";
|
||||
};
|
||||
defaultDescr = "Backup notification";
|
||||
failureDescr = ": Failure: ";
|
||||
orgDescr = "Org";
|
||||
syncthingDescr = "Syncthing";
|
||||
maildirDescr = "Maildir";
|
||||
googDescr = "goog";
|
||||
msDescr = "ms";
|
||||
oneshot = "oneshot";
|
||||
backupFailedPrefix = "/home/payas/BACKUP_FAILED";
|
||||
in
|
||||
{
|
||||
# Syncthing failure notification
|
||||
backup-failure-alert-syncthing-goog = {
|
||||
description = defaultDescr + failureDescr + syncthingDescr;
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/touch '${backupFailedPrefix}_${syncthingDescr}_${googDescr}'"
|
||||
"${pkgs.libnotify}/bin/notify-send --hint='string:desktop-entry:org.kde.konsole' 'Backup failure: Syncthing: Goog'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
|
||||
# Syncthing success: Remove failure indicator file if present
|
||||
backup-success-alert-syncthing-goog = {
|
||||
description = "Syncthing_goog backup success: Remove failure indicator file if present";
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/rm '${backupFailedPrefix}_${syncthingDescr}_${googDescr}'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
# Configure notification services for restic backup service
|
||||
restic-backups-syncthing_googledrive = {
|
||||
onFailure = [ "backup-failure-alert-syncthing-goog.service" ];
|
||||
unitConfig.OnSuccess = [ "backup-success-alert-syncthing-goog.service" ];
|
||||
};
|
||||
|
||||
backup-failure-alert-syncthing-ms = {
|
||||
description = defaultDescr + failureDescr + syncthingDescr;
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/touch '${backupFailedPrefix}_${syncthingDescr}_${msDescr}'"
|
||||
"${pkgs.libnotify}/bin/notify-send --hint='string:desktop-entry:org.kde.konsole' 'Backup failure: Syncthing: MS'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
|
||||
backup-success-alert-syncthing-ms = {
|
||||
description = "Syncthing_ms backup success: Remove failure indicator file if present";
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/rm '${backupFailedPrefix}_${syncthingDescr}_${msDescr}'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
restic-backups-syncthing_onedrive_shared = {
|
||||
onFailure = [ "backup-failure-alert-syncthing-ms.service" ];
|
||||
unitConfig.OnSuccess = [ "backup-success-alert-syncthing-ms.service" ];
|
||||
};
|
||||
|
||||
# Org failure notification
|
||||
backup-failure-alert-org-goog = {
|
||||
description = defaultDescr + failureDescr + orgDescr;
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/touch '${backupFailedPrefix}_${orgDescr}_${googDescr}'"
|
||||
"${pkgs.libnotify}/bin/notify-send --hint='string:desktop-entry:org.kde.konsole' 'Backup failure: Org: Goog'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
|
||||
# Org success: Remove failure indicator file if present
|
||||
backup-success-alert-org-goog = {
|
||||
description = "Org backup success: Remove failure indicator file if present";
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/rm '${backupFailedPrefix}_${orgDescr}_${googDescr}'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
# Configure notification services for restic backup service
|
||||
restic-backups-org_googledrive = {
|
||||
onFailure = [ "backup-failure-alert-org-goog.service" ];
|
||||
unitConfig.OnSuccess = [ "backup-success-alert-org-goog.service" ];
|
||||
};
|
||||
|
||||
backup-failure-alert-org-ms = {
|
||||
description = defaultDescr + failureDescr + syncthingDescr;
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/touch '${backupFailedPrefix}_${orgDescr}_${msDescr}'"
|
||||
"${pkgs.libnotify}/bin/notify-send --hint='string:desktop-entry:org.kde.konsole' 'Backup failure: Org: MS'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
|
||||
backup-success-alert-org-ms = {
|
||||
description = "${orgDescr}_${msDescr} backup success: Remove failure indicator file if present";
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/rm '${backupFailedPrefix}_${orgDescr}_${msDescr}'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
restic-backups-org_onedrive_shared = {
|
||||
onFailure = [ "backup-failure-alert-org-ms.service" ];
|
||||
unitConfig.OnSuccess = [ "backup-success-alert-org-ms.service" ];
|
||||
};
|
||||
|
||||
# Maildir backup failure notification
|
||||
backup-failure-alert-maildir_onedrive = {
|
||||
description = defaultDescr + failureDescr + maildirDescr;
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/touch '${backupFailedPrefix}_${maildirDescr}_${msDescr}'"
|
||||
"${pkgs.libnotify}/bin/notify-send --hint='string:desktop-entry:org.kde.konsole' 'Backup failure: Maildir: MS_shared'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
|
||||
backup-success-alert-maildir-onedrive = {
|
||||
description = "Maildir backup success: Remove failure indicator file if present";
|
||||
environment = defaultBackupServiceEnv;
|
||||
serviceConfig = {
|
||||
Type = oneshot;
|
||||
ExecStart = [
|
||||
"${pkgs.coreutils}/bin/rm '${backupFailedPrefix}_${maildirDescr}_${msDescr}'"
|
||||
];
|
||||
User = payas;
|
||||
};
|
||||
};
|
||||
# Configure notification services for restic backup service
|
||||
restic-backups-maildir_relekarpayas_onedrive_shared = {
|
||||
onFailure = [ "backup-failure-alert-maildir_onedrive.service" ];
|
||||
unitConfig.OnSuccess = [ "backup-success-alert-maildir-onedrive.service" ];
|
||||
};
|
||||
};
|
||||
}
|
Reference in a new issue