backup: restic -> borg

This commit is contained in:
Ingolf Wagner 2020-09-04 00:49:35 +02:00
parent f462f7f91a
commit 0bfbd5c2b8
No known key found for this signature in database
GPG key ID: 76BF5F1928B9618B
24 changed files with 90 additions and 165 deletions

View file

@ -1,22 +0,0 @@
function only_service(){
local service=$1
cat ~/.etc_info/* | jq '.[] | select(has("'${service}'"))'
}
only_service "restic" \
| jq '.restic' | jq --slurp . | jq 'group_by(.from)' \
| jq --raw-output '
.[] |
.[0].from as $hostname |
.[0].folders as $folders |
[.[] | select(.enable) | .to.server ] as $servers |
"
# \($hostname)
## folders
\( $folders | reduce .[] as $item ( ""; . + "* " + $item + "\n" ) )
## to
\( $servers | reduce .[] as $item ( ""; . + "* " + $item + "\n") )
"' | pandoc-from-markdown-to-man | man --local-file -

View file

@ -4,8 +4,6 @@
<system/desktop> <system/desktop>
./hardware-configuration.nix ./hardware-configuration.nix
./restic.nix
./tinc.nix ./tinc.nix
]; ];

View file

@ -1,8 +0,0 @@
{
backup.services.restic = {
"on-pepe.insecure".enable = false;
"on-porani.insecure".enable = false;
"on-workhorse.private".enable = false;
"on-workout.private".enable = false;
};
}

15
configs/pepe/borg.nix Normal file
View file

@ -0,0 +1,15 @@
{ lib, config, pkgs, ... }: {
# provide borg backup repository
services.borgbackup.repos = {
default = {
quota = "100G";
allowSubRepos = true;
authorizedKeys = [
# todo rename
(lib.fileContents <common_secrets/backup/ssh_rsa.pub>)
];
};
};
}

View file

@ -13,6 +13,8 @@
./lan.nix ./lan.nix
./dms.nix ./dms.nix
./borg.nix
]; ];
networking.hostName = "pepe"; networking.hostName = "pepe";

View file

@ -90,6 +90,6 @@ in {
}; };
# add documents to backup # add documents to backup
backup.all.restic.dirs = [ "/home/ftp-upload/db" ]; backup.dirs = [ "/home/ftp-upload/db" ];
} }

View file

@ -12,12 +12,6 @@
networking.hostName = "porani"; networking.hostName = "porani";
backup.services.restic = {
"on-porani.insecure".enable = false;
"on-workhorse.private".enable = false;
"on-workout.private".enable = false;
};
# not needed because not encrypted # not needed because not encrypted
# enable initrd ssh # enable initrd ssh
#configuration.init-ssh = { #configuration.init-ssh = {

View file

@ -58,7 +58,7 @@
users.groups."syncthing".members = [ "mpd" "syncthing" "kodi" "palo" ]; users.groups."syncthing".members = [ "mpd" "syncthing" "kodi" "palo" ];
backup.all.restic.dirs = [ "/var/lib/syncthing/finance" ]; backup.dirs = [ "/var/lib/syncthing/finance" ];
} }

View file

@ -6,9 +6,7 @@
./nginx.nix ./nginx.nix
./tinc.nix ./tinc.nix
./restic.nix
#./syncplay.nix #./syncplay.nix
#./mail-server.nix #./mail-server.nix
]; ];

View file

@ -1,8 +0,0 @@
{
backup.services.restic = {
"on-pepe.private".enable = false;
"on-porani.insecure".enable = false;
"on-workhorse.private".enable = false;
"on-workout.private".enable = false;
};
}

View file

@ -4,9 +4,9 @@
default = { default = {
quota = "100G"; quota = "100G";
allowSubRepos = true; allowSubRepos = true;
authorizedKeysAppendOnly = [ authorizedKeys = [
# todo rename this one # todo rename
(toString <common_secrets/backup/sftp-user_rsa.pub>) (lib.fileContents <common_secrets/backup/ssh_rsa.pub>)
]; ];
}; };
}; };

View file

@ -73,7 +73,7 @@ in {
LEVEL = Warn LEVEL = Warn
''; '';
}; };
backup.all.restic.dirs = [ config.services.gogs.repositoryRoot ]; backup.dirs = [ config.services.gogs.repositoryRoot ];
#services.gitea = { #services.gitea = {
# enable = true; # enable = true;
@ -99,6 +99,6 @@ in {
# LEVEL = Warn # LEVEL = Warn
# ''; # '';
#}; #};
#backup.all.restic.dirs = [ config.services.gitea.repositoryRoot ]; #backup.dirs = [ config.services.gitea.repositoryRoot ];
} }

View file

@ -455,13 +455,14 @@ let
in { in {
backup.all.restic.dirs = [ config.users.users.mailUser.home ]; backup.dirs = [ "/home/mailfetcher" ];
users.users.mailUser = { users.users.mailUser = {
isNormalUser = true; isNormalUser = true;
description = "collects mails for me"; description = "collects mails for me";
hashedPassword = "!"; hashedPassword = "!";
name = "mailfetcher"; name = "mailfetcher";
home = "/home/mailfetcher";
openssh.authorizedKeys.keyFiles = openssh.authorizedKeys.keyFiles =
config.users.users.root.openssh.authorizedKeys.keyFiles; config.users.users.root.openssh.authorizedKeys.keyFiles;
}; };

View file

@ -7,7 +7,7 @@ let
in { in {
# backup mattermost # backup mattermost
backup.all.restic.dirs = [ "/home/mattermost" ]; backup.dirs = [ "/home/mattermost" ];
containers.mattermost = { containers.mattermost = {

View file

@ -116,6 +116,6 @@
after = [ "media.mount" ]; after = [ "media.mount" ];
}; };
backup.all.restic.dirs = [ "/home/syncthing/finance" ]; backup.dirs = [ "/home/syncthing/finance" ];
} }

View file

@ -33,6 +33,6 @@
# otherwise xterm is the only thing that works # otherwise xterm is the only thing that works
environment.systemPackages = [ pkgs.rxvt_unicode ]; environment.systemPackages = [ pkgs.rxvt_unicode ];
backup.all.restic.dirs = [ config.services.weechat.root ]; backup.dirs = [ config.services.weechat.root ];
} }

54
system/all/borg-jobs.nix Normal file
View file

@ -0,0 +1,54 @@
{ config, lib, ... }: {
options = {
backup.dirs = lib.mkOption {
default = [ ];
type = with lib.types; listOf str;
};
};
config = let
servers = [
{
name = "workhorse";
host = "workhorse.private";
}
{
name = "pepe";
host = "pepe.private";
}
];
dirs = config.backup.dirs;
myHostname = config.networking.hostName;
setup = server: {
paths = dirs;
doInit = true;
repo = "borg@${server}:./${myHostname}";
encryption = {
mode = "repokey-blake2";
# todo rename
passCommand = "cat ${toString <secrets/backup/repo>}";
};
environment.BORG_RSH =
"ssh -i ${toString <secrets/backup/ssh_rsa>}";
compression = "auto,lzma";
startAt = "daily";
};
in {
services.borgbackup.jobs = let
setups = map ({ name, host }: { "${name}" = setup host; }) servers;
setupAttrs = lib.zipAttrsWith (_: vals: lib.head vals) setups;
nonEmptySetups =
lib.filterAttrs (_: { paths, ... }: builtins.length paths != 0)
setupAttrs;
in nonEmptySetups;
};
}

View file

@ -17,8 +17,7 @@
./nginx-landingpage.nix ./nginx-landingpage.nix
./nginx.nix ./nginx.nix
./packages.nix ./packages.nix
./restic.nix ./borg-jobs.nix
./sftp-user.nix
./sshd-known-hosts-bootup.nix ./sshd-known-hosts-bootup.nix
./sshd-known-hosts-private.nix ./sshd-known-hosts-private.nix
./sshd-known-hosts-public.nix ./sshd-known-hosts-public.nix

View file

@ -8,9 +8,9 @@
sshd.name = "sshd"; sshd.name = "sshd";
tor.name = "tor"; tor.name = "tor";
dnsmasq.name = "dnsmasq"; dnsmasq.name = "dnsmasq";
backup_on_workhorse.name = "backup.on-workhorse.private"; #backup_on_workhorse.name = "backup.on-workhorse.private";
backup_on_workout.name = "backup.on-workout.private"; #backup_on_workout.name = "backup.on-workout.private";
backup_on_porani.name = "backup.on-porani.private"; #backup_on_porani.name = "backup.on-porani.private";
syncthing.name = "syncthing"; syncthing.name = "syncthing";
}; };
}; };

View file

@ -1,68 +0,0 @@
{ config, lib, ... }: {
options = {
backup.all.restic.dirs = lib.mkOption {
default = [ ];
type = with lib.types; listOf str;
};
};
config = let
servers = [
"porani.insecure"
"workhorse.private"
"workout.private"
"pepe.private"
];
dirs = config.backup.all.restic.dirs;
setup = server: {
enable = lib.mkDefault true;
passwordFile = toString <secrets/backup/restic-repo>;
repo = "sftp::remote/remote-${config.networking.hostName}";
requires = [ ];
extraArguments = [
"sftp.command='ssh backup@${server} -i ${
toString <secrets/backup/sftp-user_rsa>
} -s sftp'"
];
initialize = true;
timerConfig = {
OnCalendar = "daily";
Persistent = "true";
};
dirs = dirs;
};
hostname = config.networking.hostName;
infoEntry = server: {
restic = {
folders = dirs;
from = hostname;
to = {
server = server;
repo = config.backup.services.restic."on-${server}".repo;
};
enable = config.backup.services.restic."on-${server}".enable;
};
};
in {
backup.services.restic = lib.zipAttrsWith (name: vals: lib.head vals)
(map (server: { "on-${server}" = setup server; }) servers);
systemd.services = let
timeoutConfig = server: {
name = "backup.on-${server}";
value = { serviceConfig.TimeoutSec = 30 * 60; };
};
in builtins.listToAttrs (map timeoutConfig servers);
environment.etc."info/restic-${hostname}.json" = {
enable = true;
text = builtins.toJSON (map infoEntry servers);
};
};
}

View file

@ -1,17 +0,0 @@
{ config, pkgs, lib, ... }: {
module.backup.sftpUser = {
# my backup user
"backup" = {
enable = true;
initialize = true;
home = toString /backup/remote;
authorizedKeys.keyFiles =
[ (toString <common_secrets/backup/sftp-user_rsa.pub>) ]
++ config.users.users.root.openssh.authorizedKeys.keyFiles;
};
};
}

View file

@ -16,7 +16,6 @@
./packages.nix ./packages.nix
./pass.nix ./pass.nix
./remote-install.nix ./remote-install.nix
./restic.nix
./size.nix ./size.nix
./sshd.nix ./sshd.nix
./suspend.nix ./suspend.nix
@ -27,6 +26,8 @@
./wtf.nix ./wtf.nix
]; ];
backup.dirs = [ "/home/palo/.password-store" ];
programs.custom = { programs.custom = {
urxvt = { urxvt = {

View file

@ -194,7 +194,7 @@ in {
aspellDicts.es aspellDicts.es
translate-shell translate-shell
restic borgbackup
gpa gpa
gnupg gnupg
@ -322,13 +322,6 @@ in {
(map (host: "rsync -avLz ${host}.private:/etc/info/ ~/.etc_info") (map (host: "rsync -avLz ${host}.private:/etc/info/ ~/.etc_info")
(attrNames config.module.cluster.services.tinc."private".hosts)))) (attrNames config.module.cluster.services.tinc."private".hosts))))
(pkgs.writers.writeBashBin "etc-info-restic"
(lib.fileContents <assets/etc-info/restic.sh>))
#(pkgs.writers.writeDashBin "reddit" ''
#${unstablePkgs.tuir}/bin/tuir "$@"
#'')
] ++ (lib.crossLists pandocScript [ ] ++ (lib.crossLists pandocScript [
[ "man" "markdown" "mediawiki" ] [ "man" "markdown" "mediawiki" ]
[ "mediawiki" "docbook5" "html5" "man" ] [ "mediawiki" "docbook5" "html5" "man" ]

View file

@ -1,7 +0,0 @@
{ lib, ... }: {
backup.services.restic = { "on-porani.insecure".enable = false; };
backup.all.restic.dirs = [ "/home/palo/.password-store" ];
}