nixos/applications/restic.nix

205 lines
5.1 KiB
Nix
Raw Normal View History

# nodes is all the nodes
{
lib,
config,
nodes,
pkgs,
...
}:
with lib; let
name = "backup";
cfg = config.services.skynet."${name}";
enable_client = cfg.normal.backups != null && cfg.normal.backups != [];
# since they should all have the same config we can do this
base = {
paths = cfg.normal.backups;
exclude = cfg.normal.exclude;
initialize = true;
passwordFile = config.age.secrets.restic.path;
pruneOpts = [
#"--keep-within 0y2m0d0h"
#"--keep-monthly 2"
];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
RandomizedDelaySec = "5h";
};
};
# takes nodes,
# for each check if iut has teh abckup attribute,
# then if the server is enabled,
# then pull relevant dtails
ownServers = builtins.listToAttrs (builtins.concatLists (
lib.attrsets.mapAttrsToList (
key: value: let
backup = value.config.services.skynet.backup;
in
if
(
(builtins.hasAttr "backup" value.config.services.skynet)
&& backup.server.enable
&& backup.host.name != cfg.host.name
&& !backup.server.appendOnly
)
then [
{
name = backup.host.name;
value =
base
// {
repositoryFile = "/etc/skynet/restic/${backup.host.name}";
backupPrepareCommand = ''
#!${pkgs.stdenv.shell}
set -euo pipefail
baseDir="/etc/skynet/restic"
mkdir -p $baseDir
cd $baseDir
echo -n "rest:http://root:password@${backup.host.ip}:${toString backup.server.port}/root/${cfg.host.name}" > ${backup.host.name}
# read in teh password
#PW = `cat ${config.age.secrets.restic.path}`
line=$(head -n 1 ${config.age.secrets.restic.path})
sed -i "s/password/$line/g" ${backup.host.name}
'';
};
}
]
else []
)
nodes
));
in {
imports = [
];
# using https://github.com/greaka/ops/blob/818be4c4dea9129abe0f086d738df4cb0bb38288/apps/restic/options.nix as a base
# https://git.hrnz.li/Ulli/nixos/src/commit/5edca2dfdab3ce52208e4dfd2b92951e500f8418/profiles/server/restic.nix
# will eb enabled on every server
options.services.skynet."${name}" = {
# backup is enabled by default
# enable = mkEnableOption "Skynet backup";
# what folders to backup
normal = {
backups = lib.mkOption {
default = [];
type = lib.types.listOf lib.types.str;
description = ''
A list of paths to backup.
'';
};
exclude = lib.mkOption {
default = [];
type = lib.types.listOf lib.types.str;
description = ''
A list of paths to exclide .
'';
};
};
# append only data so space limited
secure = {
backups = lib.mkOption {
default = [];
type = lib.types.listOf lib.types.str;
description = ''
A list of paths to backup.
'';
};
exclude = lib.mkOption {
default = [];
type = lib.types.listOf lib.types.str;
description = ''
A list of paths to exclide .
'';
};
};
host = {
ip = mkOption {
type = types.str;
};
name = mkOption {
type = types.str;
};
};
server = {
enable = mkEnableOption "Skynet backup Server";
port = mkOption {
type = types.port;
default = 8765;
};
appendOnly = mkOption {
type = types.bool;
default = false;
};
};
};
config =
{
# these values are anabled for every client
environment.systemPackages = with pkgs; [
restic
];
}
// mkIf cfg.server.enable {
networking.firewall.allowedTCPPorts = [
cfg.server.port
];
age.secrets.restic_pw = {
file = ../secrets/backup/restic_pw.age;
path = "${config.services.restic.server.dataDir}/.htpasswd";
symlink = false;
mode = "770";
owner = "restic";
group = "restic";
};
services.restic.server = {
enable = true;
listenAddress = "${cfg.host.ip}:${toString cfg.server.port}";
appendOnly = cfg.server.appendOnly;
privateRepos = true;
};
}
// mkIf enable_client {
# client stuff here
# A list of all login accounts. To create the password hashes, use
# nix-shell -p apacheHttpd
# htpasswd -nbB "" "password" | cut -d: -f2
age.secrets.restic.file = ../secrets/backup/restic.age;
services.restic.backups =
ownServers
// {
# merge teh two configs together
# backblaze = base // {
# # backupos for each server are stored in a folder under their name
# repository = "b2:NixOS-Main2:/${cfg.host.name}";
# #environmentFile = config.age.secrets.backblaze.path;
# };
};
};
}