summaryrefslogtreecommitdiff
path: root/tw/services
diff options
context:
space:
mode:
authorTimo Wilken2023-05-20 13:33:18 +0200
committerTimo Wilken2023-05-20 14:48:55 +0200
commite1ac041de9a4660739cda323ef867c5d1d69ae1a (patch)
tree670b85971852e912a70521cc7920e96b7c762f08 /tw/services
parent3c2ee5e5383e4deac893489b4920297f4a4cb7b6 (diff)
Add restic cleanup service
Diffstat (limited to 'tw/services')
-rw-r--r--tw/services/restic.scm64
1 files changed, 53 insertions, 11 deletions
diff --git a/tw/services/restic.scm b/tw/services/restic.scm
index 18c501a9..b3ad79a2 100644
--- a/tw/services/restic.scm
+++ b/tw/services/restic.scm
@@ -13,6 +13,8 @@
#:use-module (srfi srfi-1)
#:export (restic-server-service-type
restic-server-configuration
+ restic-cleanup-service-type
+ restic-cleanup-repository
home-restic-backup-service-type
restic-backup-repository))
@@ -103,24 +105,64 @@ private restic repos.")
;; Restic cleanup cronjobs
(define-configuration/no-serialization restic-cleanup-repository
- (repository-path string "The directory path of the restic repository to clean up.")
- (owner (string %restic-user) "The user that owns the REPOSITORY-PATH.")
- (group (string %restic-group) "The group that owns the REPOSITORY-PATH."))
+ (schedule gexp "An mcron schedule, specified as a gexp
+(@pxref{G-Expressions}), to use for the cleanup job. String, list or lambda
+syntax is fine (@pxref{Syntax, mcron job specifications,, mcron,
+GNU@tie{}mcron}).")
+ (url string "The directory path (or URL) of the restic repository to clean up.")
+ (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.")
+ (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.")
+ (keep-weekly (maybe-integer %unset-value) "Keep the last N weekly snapshots.")
+ (keep-monthly (maybe-integer %unset-value) "Keep the last N monthly snapshots.")
+ (keep-yearly (maybe-integer %unset-value) "Keep the last N yearly snapshots.")
+ (keep-within (maybe-string %unset-value) "Keep snapshots newer than the
+given duration relative to the latest snapshot."))
+
+(define (restic-cleanup-cronjobs repositories)
+ (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))))
-(define-configuration/no-serialization restic-cleanup-configuration
- (restic (package restic) "The restic package to use."))
+ (define (cronjob repo)
+ #~(job #$(restic-cleanup-repository-schedule repo)
+ #$(program-file
+ ;; Make cron commands for different repos easier to distinguish.
+ (format #f "restic-cleanup-~a-command"
+ (string-trim-right (basename (restic-cleanup-repository-url repo)) #\/))
+ #~(begin
+ ;; `setgid' first, while we're still root.
+ (setgid (group:gid (getgr #$%restic-group)))
+ (setuid (passwd:uid (getpw #$%restic-user)))
+ (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"
+ #$@(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))
+ #$@(arg-with-value "--keep-daily" (restic-cleanup-repository-keep-daily repo))
+ #$@(arg-with-value "--keep-weekly" (restic-cleanup-repository-keep-weekly repo))
+ #$@(arg-with-value "--keep-monthly" (restic-cleanup-repository-keep-monthly repo))
+ #$@(arg-with-value "--keep-yearly" (restic-cleanup-repository-keep-yearly repo)))))))
-(define (restic-deletion-service config) #f)
-(define (restic-prune-service config) #f)
+ (map cronjob repositories))
(define-public restic-cleanup-service-type
(service-type
(name 'restic-cleanup)
(extensions
- (list (service-extension mcron-service-type restic-deletion-service)
- (service-extension mcron-service-type restic-prune-service)))
- (description
- "")))
+ (list (service-extension mcron-service-type restic-cleanup-cronjobs)))
+ (compose concatenate)
+ (extend append)
+ (default-value '())
+ (description "Clean up old restic snapshots on a schedule.")))
;; Restic scheduled backup jobs