backup: restic -> borg
This commit is contained in:
parent
f462f7f91a
commit
0bfbd5c2b8
24 changed files with 90 additions and 165 deletions
|
@ -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 -
|
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
<system/desktop>
|
<system/desktop>
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
|
|
||||||
./restic.nix
|
|
||||||
./tinc.nix
|
./tinc.nix
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -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
15
configs/pepe/borg.nix
Normal 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>)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -13,6 +13,8 @@
|
||||||
./lan.nix
|
./lan.nix
|
||||||
./dms.nix
|
./dms.nix
|
||||||
|
|
||||||
|
./borg.nix
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "pepe";
|
networking.hostName = "pepe";
|
||||||
|
|
|
@ -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" ];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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" ];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
|
|
||||||
./nginx.nix
|
./nginx.nix
|
||||||
./tinc.nix
|
./tinc.nix
|
||||||
./restic.nix
|
|
||||||
#./syncplay.nix
|
#./syncplay.nix
|
||||||
|
|
||||||
#./mail-server.nix
|
#./mail-server.nix
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -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>)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 ];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,6 @@
|
||||||
after = [ "media.mount" ];
|
after = [ "media.mount" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
backup.all.restic.dirs = [ "/home/syncthing/finance" ];
|
backup.dirs = [ "/home/syncthing/finance" ];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
54
system/all/borg-jobs.nix
Normal 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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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" ]
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
{ lib, ... }: {
|
|
||||||
|
|
||||||
backup.services.restic = { "on-porani.insecure".enable = false; };
|
|
||||||
|
|
||||||
backup.all.restic.dirs = [ "/home/palo/.password-store" ];
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue