[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug#71639] [PATCH WIP 2/5] services: backup: Add password-command suppo
From: |
Richard Sent |
Subject: |
[bug#71639] [PATCH WIP 2/5] services: backup: Add password-command support to restic-service |
Date: |
Tue, 18 Jun 2024 18:08:49 -0400 |
* gnu/services/backup.scm (restic-backup-job): Add password-command.
(verify-restic-backup-job-configuration): Create.
(restic-backup-job-program): Set either RESTIC_PASSWORD or
RESTIC_PASSWORD_COMMAND depending on what is configured.
* doc/guix.texi (Miscellaneous Services): Document it.
Change-Id: Ice9cf85d1ee4485a2737f515c63c969918219df0
---
doc/guix.texi | 7 +++++++
gnu/services/backup.scm | 42 ++++++++++++++++++++++++++++++++++++-----
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 63c9cbd1a7..f22d679023 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -41344,6 +41344,13 @@ Miscellaneous Services
that will be used to set the @env{RESTIC_PASSWORD} environment variable
for the current job.
+@item @code{password-command} (type: file-like)
+String path or file-like object representing the executable file that
+prints password to stdout. If a file-like object is used, it is placed
+in the store globally executable and in plain text. The executable
+should be designed such that it does not compromise the password if an
+unauthorized user runs it.
+
@item @code{schedule} (type: gexp-or-string)
A string or a gexp that will be passed as time specification in the
mcron job specification (@pxref{Syntax, mcron job specifications,,
diff --git a/gnu/services/backup.scm b/gnu/services/backup.scm
index eeef11eae7..2471d0ea7b 100644
--- a/gnu/services/backup.scm
+++ b/gnu/services/backup.scm
@@ -66,6 +66,9 @@ (define (lowerable? value)
(define list-of-lowerables?
(list-of lowerable?))
+(define-maybe/no-serialization string)
+(define-maybe/no-serialization file-like)
+
(define-configuration/no-serialization restic-backup-job
(restic
(package restic)
@@ -80,10 +83,16 @@ (define-configuration/no-serialization restic-backup-job
(string)
"The restic repository target of this job.")
(password-file
- (string)
+ (maybe-string)
"Name of the password file, readable by the configured @code{user}, that
will be used to set the @code{RESTIC_PASSWORD} environment variable for the
current job.")
+ (password-command
+ (maybe-file-like)
+ "Name of the password command that, when run, returns the password over
+stdin. Due to the nature of the store this command will be globally executable
+and should have external protections to ensure other users cannot retrieve the
+password. This overrides password-file.")
(schedule
(gexp-or-string)
"A string or a gexp that will be passed as time specification in the mcron
@@ -104,6 +113,14 @@ (define-configuration/no-serialization restic-backup-job
"A list of values that are lowered to strings. These will be passed as
command-line arguments to the current job @command{restic backup}
invokation."))
+(define (verify-restic-backup-job-configuration config)
+ (unless (or (maybe-value-set? (restic-backup-job-password-file config))
+ (maybe-value-set? (restic-backup-job-password-command config)))
+ (error "either password-file or password-command must be configured."))
+ (when (and (maybe-value-set? (restic-backup-job-password-file config))
+ (maybe-value-set? (restic-backup-job-password-command config)))
+ (error "password-file and password-command can not be configured
simultaneously.")))
+
(define list-of-restic-backup-jobs?
(list-of restic-backup-job?))
@@ -113,12 +130,22 @@ (define-configuration/no-serialization
restic-backup-configuration
"The list of backup jobs for the current system."))
(define (restic-backup-job-program config)
+ (define (maybe-value-or-false maybe)
+ (if (maybe-value-set? maybe)
+ maybe
+ #f))
+
+ ;; TODO: Find a place to also verify restic-backup-configuration. Mainly
that jobs >=1
+ (verify-restic-backup-job-configuration config)
+
(let ((restic
(file-append (restic-backup-job-restic config) "/bin/restic"))
(repository
(restic-backup-job-repository config))
(password-file
- (restic-backup-job-password-file config))
+ (maybe-value-or-false (restic-backup-job-password-file config)))
+ (password-command
+ (maybe-value-or-false (restic-backup-job-password-command config)))
(files
(restic-backup-job-files config))
(extra-flags
@@ -134,9 +161,14 @@ (define (restic-backup-job-program config)
#~(begin
(use-modules (ice-9 popen)
(ice-9 rdelim))
- (setenv "RESTIC_PASSWORD"
- (with-input-from-file #$password-file read-line))
-
+ (or (and=> #$password-file (lambda (x)
+ (setenv "RESTIC_PASSWORD"
+ (with-input-from-file x
read-line))))
+ (and=> #$password-command (lambda (x)
+ (setenv "RESTIC_PASSWORD_COMMAND" x)))
+ ;; Have a backup error message in case
+ ;; verify-restic-backup-job-configuration is messed with
+ (error "Neither password-file or password-command set"))
(when #$init?
;; Check if the repository exists. See
;; https://github.com/restic/restic/issues/1690 and
--
2.45.1