{ 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.ydns = { description = "update ydns address record"; after = [ "network-online.target" ]; startAt = "*:0/30"; serviceConfig.Type = "oneshot"; serviceConfig.environmentFile = config.secrets.environments.ydns; path = with pkgs; [ curl cacert gawk iproute ]; environment = { YDNS_HOST = config.var.hostname; CURL_CA_BUNDLE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; }; script = '' update() { ret=$(curl -$1 --basic --silent \ -u "$YDNS_USER:$YDNS_PASSWD" \ "https://ydns.io/api/v1/update/?host=$YDNS_HOST&ip=$2" || exit 0) case "$ret" in ok) echo "updated successfully: $YDNS_HOST ($2)" ;; badauth) echo "updated failed: $YDNS_HOST (authentication failed)" ;; *) echo "update failed: $YDNS_HOST ($ret)" ;; esac } update 4 "$(curl -s -4 https://ydns.io/api/v1/ip)" update 6 "$(ip addr show mngtmpaddr | awk '/inet6/{print $2; exit}' | cut -d/ -f1)" ''; }; system.fsPackages = [ pkgs.nfs-utils ]; systemd.mounts = lib.singleton { description = "backup NFS volume"; after = [ "network-online.target" ]; what = "192.168.1.3:/maxwell"; where = "/mnt/backup"; type = "nfs"; options = "nolock"; }; 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"; after = [ "network-online.target" "mnt-backup.mount" ]; bindsTo = [ "mnt-backup.mount" ]; startAt = "*-*-* 03:00"; # every day at 3:00 onFailure = [ "notify-failed@backup.service" ]; serviceConfig = { Type = "oneshot"; PrivateTmp = true; LimitNOFILE = 65536; }; environment.BUP_DIR = "/mnt/backup"; path = with pkgs; [ bup git nfs-utils sudo gzip postgresql ]; script = '' # mount repository mkdir -p "$BUP_DIR" # init backup ! 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" echo done done < "${saved}" # postgresql backup dir=/tmp/postgresql mkdir -p "$dir" echo dumping databases... sudo -u postgres pg_dumpall | gzip > "$dir"/db.bak echo done echo saving... bup index "$dir" bup save -n postgresql "$dir" --strip-path=/tmp 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}"; }; }