# nodes is all the nodes { lib, config, nodes, pkgs, ... }: with lib; let cfg = config.services.skynet_backup; 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 "skynet_backup" value.config.services) && 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_backup = { # 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; # }; }; }; }