{ config , hostAddress , localAddress }: let unstablepkgs = import { config = config.nixpkgs.config; }; passwords = import ../../variables/passwords.crypt.nix; bucket = "bkp"; subvolumeParentDir = "/var/lib"; subvolumeDir = "/var/lib/container-volumes"; subvolumeSnapshot = "/var/lib/container-volumes.snapshot"; bkpSource = subvolumeSnapshot; bkpDestination = "/container/backup"; cacheDir = "/var/lib/rclone-cachedir"; wasabiRc = pkgs: pkgs.writeText "rc" '' [wasabi-${bucket}] type = s3 provider = Wasabi env_auth = false #bkp user access_key_id = ${passwords.storage.wasabi.bkp.key} secret_access_key = ${passwords.storage.wasabi.bkp.secret} region = us-east-1 endpoint = s3.wasabisys.com location_constraint = acl = server_side_encryption = storage_class = ''; bkp-mount-rclone-manual = pkgs: { enable = true; description = "bkp-mount-rclone-manual service"; path = with pkgs; [ unstablepkgs.rclone utillinux ]; serviceConfig = { Type = "notify"; }; script = '' export PATH="$PATH:/run/wrappers/bin" exec rclone --config ${wasabiRc pkgs} mount wasabi-${bucket}:${bucket} ${bkpDestination} \ --stats=50m --stats-log-level=NOTICE \ --cache-dir=${cacheDir} \ --vfs-cache-mode=full ''; preStart = '' mkdir -p ${bkpDestination} mkdir -p ${cacheDir} ''; postStop = '' sync umount ${bkpDestination} \ || umount -l ${bkpDestination} \ || : rmdir ${bkpDestination} ''; }; in { config = { pkgs, ... }: { imports = [ ../profiles/containers/configuration.nix ]; environment.systemPackages = with pkgs; [ btrfs-progs rdup rdedup iptraf-ng nethogs rclone ]; networking.firewall.enable = true; systemd.services."bkp-mount-rclone-manual" = bkp-mount-rclone-manual pkgs; systemd.services."bkp-sync-rclone" = { enable = true; description = "bkp-sync-rclone service"; serviceConfig = { Type = "oneshot"; }; after = [ "bkp-run.service" ]; requires = [ "bkp-run.service" ]; path = with pkgs; [ unstablepkgs.rclone utillinux ]; script = '' set -x echo Starting rclone sync... rclone --config ${wasabiRc pkgs} sync \ ${bkpDestination}/rdedup/ wasabi-${bucket}:${bucket}/rdedup/ \ --stats=50m --stats-log-level=WARNING echo Finished rclone sync... ''; }; systemd.services."bkp-run" = { enable = true; description = "bkp-run"; serviceConfig = { Type = "oneshot"; }; partOf = [ "bkp-sync-rclone.service" ]; path = with pkgs; [ btrfs-progs rdup rdedup coreutils ]; preStart = '' echo Creating new btrfs snapshot of ${subvolumeDir} at ${subvolumeSnapshot} btrfs subvolume snapshot -r ${subvolumeDir} ${subvolumeSnapshot} ''; script = '' #! ${pkgs.bash}/bin/bash set -Eeuxo pipefail export RUST_BACKTRACE=1 export TIMESTAMP=$(date +"%Y%m%d.%H%M%S") echo Starting rdup/rdedup backup... for d in `ls -1 ${bkpSource}`; do echo Determining backup source size ${bkpSource}/$d... du -hs ${bkpSource}/$d rdup -x /dev/null ${bkpSource}/$d | rdedup -v -ttt --dir=${bkpDestination}/rdedup store $d-''${TIMESTAMP} done sync echo Finished rdup/rdedup backup... echo Removing all previous backups... rdedup --dir=${bkpDestination}/rdedup list | grep -v ''${TIMESTAMP} | xargs echo rdedup --dir=${bkpDestination}/rdedup remove echo Running rdedup garbage-collector... time rdedup -v -ttt --dir=${bkpDestination}/rdedup gc echo Determining backup destination size ${bkpDestination}/rdedup... du -hs ${bkpDestination}/rdedup ''; postStop = '' btrfs subvolume delete ${subvolumeSnapshot} ''; }; systemd.timers."bkp" = { description = "Timer to trigger bkp periodically"; enable = true; wantedBy = [ "timer.target" "multi-user.target" ]; timerConfig = { # Obtained using `systemd-analyze calendar "Wed 23:00"` # OnCalendar = "Wed *-*-* 23:00:00"; OnStartupSec="2d"; Unit = "bkp-sync-rclone.service"; OnUnitInactiveSec="2d"; Persistent="true"; }; }; }; autoStart = true; bindMounts = { "${subvolumeParentDir}" = { hostPath = "/var/lib/"; isReadOnly = false; }; "/dev/fuse" = { hostPath = "/dev/fuse"; isReadOnly = false; }; }; allowedDevices = [ { node = "/dev/fuse"; modifier = "rw"; } ]; privateNetwork = true; forwardPorts = [ ]; inherit hostAddress localAddress; }