aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tw/services/restic.scm34
-rw-r--r--tw/system/vin.scm38
2 files changed, 64 insertions, 8 deletions
diff --git a/tw/services/restic.scm b/tw/services/restic.scm
index b3ad79a2..62764750 100644
--- a/tw/services/restic.scm
+++ b/tw/services/restic.scm
@@ -18,8 +18,8 @@
home-restic-backup-service-type
restic-backup-repository))
-(define-public %restic-user "restic")
-(define-public %restic-group "restic")
+(define %restic-user "restic")
+(define %restic-group "restic")
;; Restic REST server
@@ -104,6 +104,8 @@ private restic repos.")
;; Restic cleanup cronjobs
+(define-maybe list-of-strings)
+
(define-configuration/no-serialization restic-cleanup-repository
(schedule gexp "An mcron schedule, specified as a gexp
(@pxref{G-Expressions}), to use for the cleanup job. String, list or lambda
@@ -113,6 +115,9 @@ GNU@tie{}mcron}).")
(password-file string "The file name containing the repository password.
Must be readable by the @code{%restic-user}.")
(restic (package restic) "The restic package to use.")
+ (snapshot-paths (maybe-list-of-strings %unset-value) "Only consider
+snapshots which include these paths.")
+ (prune? (boolean #t) "Immediately prune the repo after deleting snapshots.")
(keep-last (maybe-integer %unset-value) "Keep the last N snapshots.")
(keep-hourly (maybe-integer %unset-value) "Keep the last N hourly snapshots.")
(keep-daily (maybe-integer %unset-value) "Keep the last N daily snapshots.")
@@ -126,9 +131,22 @@ given duration relative to the latest snapshot."))
(define (arg-with-value arg value)
"Produce a list for the given command-line argument with optional value.
The result is inteded to be substituted into a `gexp' using `#$@', e.g. into
-an `execl' call. Values are converted to strings as if by `display'."
- (if (eq? %unset-value value) '()
- (list arg (format #f "~a" value))))
+an `execl' call. Numbers are converted to strings as if by `display'. Lists
+are turned into multiple arguments. For booleans, ARG is returned if VALUE is
+true."
+ (define (to-string thing)
+ (format #f "~a" thing))
+ (cond
+ ((eq? %unset-value value)
+ '())
+ ((boolean? value)
+ (if value (list arg) '()))
+ ((list? value)
+ (append-map (lambda (item)
+ (list arg (to-string item)))
+ value))
+ (else
+ (list arg (to-string value)))))
(define (cronjob repo)
#~(job #$(restic-cleanup-repository-schedule repo)
@@ -143,7 +161,9 @@ an `execl' call. Values are converted to strings as if by `display'."
(setenv "RESTIC_REPOSITORY" '#$(restic-cleanup-repository-url repo))
(setenv "RESTIC_PASSWORD_FILE" '#$(restic-cleanup-repository-password-file repo))
(execl #$(file-append (restic-cleanup-repository-restic repo) "/bin/restic")
- "restic" "forget" "--no-cache" "--prune"
+ "restic" "forget" "--no-cache"
+ #$@(arg-with-value "--prune" (restic-cleanup-repository-prune? repo))
+ #$@(arg-with-value "--path" (restic-cleanup-repository-snapshot-paths repo))
#$@(arg-with-value "--keep-within" (restic-cleanup-repository-keep-within repo))
#$@(arg-with-value "--keep-last" (restic-cleanup-repository-keep-last repo))
#$@(arg-with-value "--keep-hourly" (restic-cleanup-repository-keep-hourly repo))
@@ -154,7 +174,7 @@ an `execl' call. Values are converted to strings as if by `display'."
(map cronjob repositories))
-(define-public restic-cleanup-service-type
+(define restic-cleanup-service-type
(service-type
(name 'restic-cleanup)
(extensions
diff --git a/tw/system/vin.scm b/tw/system/vin.scm
index 3076fd8f..41842b4e 100644
--- a/tw/system/vin.scm
+++ b/tw/system/vin.scm
@@ -56,11 +56,47 @@
(service restic-cleanup-service-type
(list (restic-cleanup-repository
;; Laptop backups run at "0 */2 * * *".
- (schedule #~"10 5 * * *") ; daily at 05:10
+ (schedule #~"0 5 * * *")
(url "/var/backups/restic/timo/laptop")
(password-file "/etc/restic/timo-laptop")
(keep-within "14d")
(keep-weekly 52)
+ (keep-monthly -1))
+
+ ;; Phone backups run with a new version of restic, which creates
+ ;; v2 repos by default. Guix' older restic version can't read
+ ;; these, so create the repo on the server before pushing to it.
+ ;; Restic doesn't automatically upgrade the repo version.
+ ;;
+ ;; Phone backups run "hourly" (modulo Android's throttling of
+ ;; the Restic app), but the underlying data changes at most once
+ ;; a day, so use `keep-daily' instead of `keep-within'.
+
+ (restic-cleanup-repository
+ (schedule #~"0 3 * * *")
+ (url "/var/backups/restic/timo/phone")
+ (password-file "/etc/restic/timo-phone")
+ (snapshot-paths '("/storage/FF37-F8E6/SignalBackup"))
+ ;; We only really care about the last signal backup, but guard
+ ;; against accidental deletion by keeping more.
+ (keep-daily 7))
+
+ (restic-cleanup-repository
+ (schedule #~"0 4 * * *")
+ (url "/var/backups/restic/timo/phone")
+ (password-file "/etc/restic/timo-phone")
+ (snapshot-paths '("/storage/emulated/0/Backups"))
+ (keep-daily 14)
+ (keep-monthly -1))
+
+ (restic-cleanup-repository
+ ;; OAndBackupX/NeoBackup backups can run until the early-ish
+ ;; morning; cleanup once they're all done and pushed.
+ (schedule #~"0 9 * * *")
+ (url "/var/backups/restic/timo/phone")
+ (password-file "/etc/restic/timo-phone")
+ (snapshot-paths '("/storage/FF37-F8E6/OAndBackupX"))
+ (keep-daily 14)
(keep-monthly -1))))
(server-base-services host-name)))