{ config, pkgs, lib, ... }: with lib; { systemd.services."notify-failed@" = { description = "notify that %i has failed"; scriptArgs = "%i"; path = [ pkgs.maxwell-notify ]; script = '' unit=$1 notify "$unit: failed. last log lines:" journalctl -u "$unit" -o cat -n 15 | notify ''; }; systemd.services.backup = let saved = pkgs.writeText "backup-saved" '' /etc/lvm /var/lib /home ''; excluded = pkgs.writeText "backup-excluded" '' /var/lib/systemd /var/lib/udisks2 /var/lib/postgresql /var/lib/matrix-synapse/media_store/url_cache /var/lib/matrix-synapse/media_store/url_cache_thumbnails ''; in { description = "system backup"; startAt = "*-*-* 03:00"; # every day at 3:00 onFailure = [ "notify-failed@backup.service" ]; serviceConfig = { Type = "oneshot"; PrivateTmp = true; PrivateMounts = true; LimitNOFILE = 65536; }; environment.BUP_DIR = "/mnt/backup"; path = with pkgs; [ bup git util-linux sudo gzip postgresql ]; script = '' # mount repository mount -m -L backup "$BUP_DIR" # init backup, if empty ! test -e $BUP_DIR/bupindex && bup init # build indices and save while read -r dir; do { name=$(basename "$dir") echo indexing $name... bup index "$dir" --exclude-from="${excluded}" echo done echo saving $name... bup save -n "$name" "$dir" || true echo done } || true done < "${saved}" # postgresql backup dir=/tmp/postgresql mkdir -p "$dir" echo dumping databases... sudo -u postgres pg_dumpall > "$dir"/db.bak echo done echo saving... bup index "$dir" bup save -n postgresql "$dir" --strip-path=/tmp echo done echo generating par2 files... bup fsck -j 8 -g echo done # prune backups every week if test $(( $(date +%s) / 86400 % 7 )) -eq 0; then echo pruning... bup prune-older --keep-all-for 6m --keep-monthlies-for 2y --unsafe echo done fi ''; }; systemd.services.namecoin-update = let userFile = with config.services.namecoind; pkgs.writeText "namecoin.conf" '' rpcbind=${rpc.address} rpcport=${toString rpc.port} rpcuser=${rpc.user} rpcpassword=${rpc.password} ''; in { description = "update namecoin names"; after = [ "namecoind.service" ]; startAt = "hourly"; onFailure = [ "notify-failed@namecoin-update.service" ]; path = [ pkgs.namecoind ]; serviceConfig.Type = "oneshot"; serviceConfig.ExecStart = "${pkgs.haskellPackages.namecoin-update}/bin/namecoin-update ${userFile}"; }; }