2023-04-22 18:38:58 -05:00
|
|
|
|
|
|
|
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)"
|
|
|
|
|
2023-04-24 15:14:04 -05:00
|
|
|
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."
|
2023-04-22 18:38:58 -05:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
let-env RESTIC_REPOSITORY = $"b2:($env.B2_BUCKET):($env.HOSTNAME)"
|
|
|
|
|
|
|
|
let-env RCLONE_CONFIG = "/dev/null"
|
|
|
|
let-env RCLONE_CONFIG_B2_TYPE = "b2"
|
|
|
|
let-env RCLONE_CONFIG_B2_ACCOUNT = $env.B2_ACCOUNT_ID
|
|
|
|
let-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
|
|
|
|
}
|