def healthcheck_start [ url: record ] { if not ($env | get -i HEALTHCHECK_URL | is-empty ) { http get --full --max-time 10 ($url | update path $"($in.path)/start" | url join) | ignore } } def healthcheck_log [ url: record log: string ] { if not ($url | is-empty ) { http post --max-time 10 ($url | update path $"($in.path)/log" | url join) $log | ignore } } def healthcheck_fail [ url: record log: string ] { if not ($url | is-empty ) { http post --full --max-time 10 ($url | update path $"($in.path)/fail" | url join) $log | ignore } } def healthcheck_stop [ url: record ] { if not ($url | is-empty ) { http get --full --max-time 10 ($url | url join) | ignore } } def main [ --rclone: string # path to rclone binary --restic: string # path to restic binary --cache-dir: string # path to cache dir ] { let rid = (random uuid) let healthcheck_url = if not ($env | get -i HEALTHCHECK_URL | is-empty) { $env.HEALTHCHECK_URL | url parse | update params ($in | get params | insert rid $rid) } else { {} } healthcheck_start $healthcheck_url alias rclone = ^$rclone alias restic = ^$restic --cache-dir $cache_dir --option "b2.connections=128" if ($env | get -i BACKUP_PATHS | is-empty) { print "BACKUP_PATHS not set." healthcheck_fail $healthcheck_url "BACKUP_PATHS not set." exit 1 } let paths = ($env.BACKUP_PATHS | split row " ") let not_exists = ($paths | path exists | enumerate | filter { |r| not $r.item }) if ($not_exists | length ) > 0 { let error = ("error: some backup paths do not exist:\n\n" + ($not_exists | each { |r| ($paths | get $r.index) } | str join "\n") + "\n") print ($error | str trim --right) healthcheck_fail $healthcheck_url $error exit 1 } $paths | each { |r| print $"BACKUP_PATH: ($r)" } if ($env | get -i B2_ACCOUNT_ID | is-empty) { print "B2_ACCOUNT_ID not set." healthcheck_fail $healthcheck_url "B2_ACCOUNT_ID not set." exit 1 } if ($env | get -i B2_ACCOUNT_KEY | is-empty) { print "B2_ACCOUNT_KEY not set." healthcheck_fail $healthcheck_url "B2_ACCOUNT_KEY not set." exit 1 } if ($env | get -i B2_BUCKET | is-empty) { print "B2_BUCKET not set." healthcheck_fail $healthcheck_url "B2_BUCKET not set." exit 1 } print $"B2_BUCKET: ($env.B2_BUCKET)" if ($env | get -i HOSTNAME | is-empty) { print "HOSTNAME not set." healthcheck_fail $healthcheck_url "HOSTNAME not set." exit 1 } print $"HOSTNAME: ($env.HOSTNAME)" if ($env | get -i RESTIC_PASSWORD_FILE | is-empty) and ($env | get -i RESTIC_PASSWORD_COMMAND | is-empty) { print "Must set either RESTIC_PASSWORD_FILE or RESTIC_PASSWORD_COMMAND." healthcheck_fail $healthcheck_url "Must set either RESTIC_PASSWORD_FILE or RESTIC_PASSWORD_COMMAND." exit 1 } $env.RESTIC_REPOSITORY = $"b2:($env.B2_BUCKET):($env.HOSTNAME)" $env.RCLONE_CONFIG = "/dev/null" $env.RCLONE_CONFIG_B2_TYPE = "b2" $env.RCLONE_CONFIG_B2_ACCOUNT = $env.B2_ACCOUNT_ID $env.RCLONE_CONFIG_B2_KEY = $env.B2_ACCOUNT_KEY if (rclone lsjson $"b2:($env.B2_BUCKET)/($env.HOSTNAME)/config" | from json | length | $in == 0) { let result = (do {restic init} | complete) if $result.exit_code != 0 { print "restic init failed" print ($result.stderr | str trim --right) healthcheck_fail $healthcheck_url $result.stderr exit 1 } else { healthcheck_log $healthcheck_url "restic repository initialized" } } let result = (do {restic backup --host $env.HOSTNAME $paths} | complete) if $result.exit_code == 1 { print "restic backup failed" print ($result.stderr | str trim --right) healthcheck_fail $healthcheck_url $result.stderr exit 1 } else if $result.exit_code == 3 { print "restic backup incomplete" print ($result.stderr | str trim --right) healthcheck_log $healthcheck_url $result.stderr } else { print ($result.stdout | str trim --right) healthcheck_log $healthcheck_url $result.stdout } let result = (do {restic forget --host $env.HOSTNAME --prune --keep-within 14d} | complete) if $result.exit_code != 0 { print "restic forget failed" print ($result.stderr | str trim --right) healthcheck_fail $healthcheck_url $result.stderr exit 1 } print ($result.stdout | str trim --right) healthcheck_log $healthcheck_url $result.stdout let result = (do {restic check} | complete) if $result.exit_code != 0 { print "restic check failed" print ($result.stderr | str trim --right) healthcheck_fail $healthcheck_url $result.stderr exit 1 } print ($result.stdout | str trim --right) healthcheck_log $healthcheck_url $result.stdout let result = (do {restic cache --cleanup} | complete) if $result.exit_code != 0 { print "restic cache failed" print ($result.stderr | str trim) healthcheck_fail $healthcheck_url $result.stderr exit 1 } print ($result.stdout | str trim --right) healthcheck_log $healthcheck_url $result.stdout healthcheck_stop $healthcheck_url }