Payas Relekar
527e463208
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.
274 lines
11 KiB
Nix
274 lines
11 KiB
Nix
{ 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" ];
|
|
};
|
|
};
|
|
}
|