mirror of
https://codeberg.org/guix/guix.git
synced 2025-10-02 02:15:12 +00:00
deploy: Add --roll-back option.
* guix/scripts/deploy.scm (guix-deploy): Add the --roll-back option. (show-what-to-deploy): Add #:roll-back? argument. (roll-back-machine*): New function. (show-help): Document the --roll-back option. * doc/guix.texi (Invoking guix deploy): Document the --roll-back option. Change-Id: Ic5084f287aefb2d1d28380ca4ba1c6971cb913e7
This commit is contained in:
parent
8b19b14d5c
commit
b0d3a38f4c
2 changed files with 72 additions and 11 deletions
|
@ -45249,6 +45249,14 @@ guix deploy @var{file} -x -- herd restart @var{service}
|
||||||
The @command{guix deploy -x} command returns zero if and only if the
|
The @command{guix deploy -x} command returns zero if and only if the
|
||||||
command succeeded on all the machines.
|
command succeeded on all the machines.
|
||||||
|
|
||||||
|
You may also wish to roll back configurations on machines to a previous
|
||||||
|
generation. You can do that using the @option{--roll-back} or
|
||||||
|
@option{-r} option like so:
|
||||||
|
|
||||||
|
@example
|
||||||
|
guix deploy --roll-back @var{file}
|
||||||
|
@end example
|
||||||
|
|
||||||
@c FIXME/TODO: Separate the API doc from the CLI doc.
|
@c FIXME/TODO: Separate the API doc from the CLI doc.
|
||||||
|
|
||||||
Below are the data types you need to know about when writing a
|
Below are the data types you need to know about when writing a
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
|
;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
|
||||||
;;; Copyright © 2020-2022 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2020-2022 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2024 Richard Sent <richard@freakingpenguin.com>
|
;;; Copyright © 2024 Richard Sent <richard@freakingpenguin.com>
|
||||||
|
;;; Copyright © 2025 Arun Isaac <arunisaac@systemreboot.net>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -63,6 +64,8 @@ Perform the deployment specified by FILE.\n"))
|
||||||
-e, --expression=EXPR deploy the list of machines EXPR evaluates to"))
|
-e, --expression=EXPR deploy the list of machines EXPR evaluates to"))
|
||||||
(newline)
|
(newline)
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
|
-r, --roll-back switch to the previous operating system configuration"))
|
||||||
|
(display (G_ "
|
||||||
-x, --execute execute the following command on all the machines"))
|
-x, --execute execute the following command on all the machines"))
|
||||||
(newline)
|
(newline)
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
|
@ -84,6 +87,9 @@ Perform the deployment specified by FILE.\n"))
|
||||||
(option '(#\n "dry-run") #f #f
|
(option '(#\n "dry-run") #f #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'dry-run? #t result)))
|
(alist-cons 'dry-run? #t result)))
|
||||||
|
(option '(#\r "roll-back") #f #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'roll-back? #t result)))
|
||||||
(option '(#\x "execute") #f #f
|
(option '(#\x "execute") #f #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'execute-command? #t result)))
|
(alist-cons 'execute-command? #t result)))
|
||||||
|
@ -118,20 +124,32 @@ Perform the deployment specified by FILE.\n"))
|
||||||
environment-modules))))
|
environment-modules))))
|
||||||
(load* file module)))
|
(load* file module)))
|
||||||
|
|
||||||
(define* (show-what-to-deploy machines #:key (dry-run? #f))
|
(define* (show-what-to-deploy machines #:key (dry-run? #f) (roll-back? #f))
|
||||||
"Show the list of machines to deploy, MACHINES."
|
"Show the list of machines in MACHINES to deploy or roll back."
|
||||||
(let ((count (length machines)))
|
(let ((count (length machines)))
|
||||||
(if dry-run?
|
(if dry-run?
|
||||||
(format (current-error-port)
|
(if roll-back?
|
||||||
(N_ "The following ~d machine would be deployed:~%"
|
(format (current-error-port)
|
||||||
"The following ~d machines would be deployed:~%"
|
(N_ "The following ~d machine would be rolled back:~%"
|
||||||
|
"The following ~d machines would be rolled back:~%"
|
||||||
count)
|
count)
|
||||||
count)
|
count)
|
||||||
(format (current-error-port)
|
(format (current-error-port)
|
||||||
(N_ "The following ~d machine will be deployed:~%"
|
(N_ "The following ~d machine would be deployed:~%"
|
||||||
"The following ~d machines will be deployed:~%"
|
"The following ~d machines would be deployed:~%"
|
||||||
|
count)
|
||||||
|
count))
|
||||||
|
(if roll-back?
|
||||||
|
(format (current-error-port)
|
||||||
|
(N_ "The following ~d machine will be rolled back:~%"
|
||||||
|
"The following ~d machines will be rolled back:~%"
|
||||||
|
count)
|
||||||
count)
|
count)
|
||||||
count))
|
(format (current-error-port)
|
||||||
|
(N_ "The following ~d machine will be deployed:~%"
|
||||||
|
"The following ~d machines will be deployed:~%"
|
||||||
|
count)
|
||||||
|
count)))
|
||||||
(display (indented-string
|
(display (indented-string
|
||||||
(fill-paragraph (string-join (map machine-display-name machines)
|
(fill-paragraph (string-join (map machine-display-name machines)
|
||||||
", ")
|
", ")
|
||||||
|
@ -175,6 +193,35 @@ Perform the deployment specified by FILE.\n"))
|
||||||
(info (G_ "successfully deployed ~a~%")
|
(info (G_ "successfully deployed ~a~%")
|
||||||
(machine-display-name machine))))
|
(machine-display-name machine))))
|
||||||
|
|
||||||
|
(define (roll-back-machine* store machine)
|
||||||
|
"Roll back MACHINE, taking care of error handling."
|
||||||
|
(info (G_ "rolling back ~a...~%")
|
||||||
|
(machine-display-name machine))
|
||||||
|
|
||||||
|
(guard* (c
|
||||||
|
;; On Guile 3.0, exceptions such as 'unbound-variable' are compound
|
||||||
|
;; and include a '&message'. However, that message only contains
|
||||||
|
;; the format string. Thus, special-case it here to avoid
|
||||||
|
;; displaying a bare format string.
|
||||||
|
(((exception-predicate &exception-with-kind-and-args) c)
|
||||||
|
(raise c))
|
||||||
|
|
||||||
|
((message-condition? c)
|
||||||
|
(leave (G_ "failed to roll back ~a: ~a~%")
|
||||||
|
(machine-display-name machine)
|
||||||
|
(condition-message c)))
|
||||||
|
((formatted-message? c)
|
||||||
|
(leave (G_ "failed to roll back ~a: ~a~%")
|
||||||
|
(machine-display-name machine)
|
||||||
|
(apply format #f
|
||||||
|
(gettext (formatted-message-string c)
|
||||||
|
%gettext-domain)
|
||||||
|
(formatted-message-arguments c)))))
|
||||||
|
(run-with-store store (roll-back-machine machine)))
|
||||||
|
|
||||||
|
(info (G_ "successfully rolled back ~a~%")
|
||||||
|
(machine-display-name machine)))
|
||||||
|
|
||||||
(define (invoke-command store machine command)
|
(define (invoke-command store machine command)
|
||||||
"Invoke COMMAND, a list of strings, on MACHINE. Display its output (if any)
|
"Invoke COMMAND, a list of strings, on MACHINE. Display its output (if any)
|
||||||
and its error code if it's non-zero. Return true if COMMAND succeeded, false
|
and its error code if it's non-zero. Return true if COMMAND succeeded, false
|
||||||
|
@ -258,6 +305,7 @@ otherwise."
|
||||||
(machines (or (and file (load-source-file file))
|
(machines (or (and file (load-source-file file))
|
||||||
(and expression (read/eval expression))))
|
(and expression (read/eval expression))))
|
||||||
(dry-run? (assoc-ref opts 'dry-run?))
|
(dry-run? (assoc-ref opts 'dry-run?))
|
||||||
|
(roll-back? (assq-ref opts 'roll-back?))
|
||||||
(execute-command? (assoc-ref opts 'execute-command?)))
|
(execute-command? (assoc-ref opts 'execute-command?)))
|
||||||
(when (and file expression)
|
(when (and file expression)
|
||||||
(leave (G_ "both '--expression' and a deployment file were provided~%")))
|
(leave (G_ "both '--expression' and a deployment file were provided~%")))
|
||||||
|
@ -292,8 +340,13 @@ otherwise."
|
||||||
(_
|
(_
|
||||||
(leave (G_ "'-x' specified but no command given~%"))))
|
(leave (G_ "'-x' specified but no command given~%"))))
|
||||||
(begin
|
(begin
|
||||||
(show-what-to-deploy machines #:dry-run? dry-run?)
|
(show-what-to-deploy machines
|
||||||
|
#:dry-run? dry-run?
|
||||||
|
#:roll-back? roll-back?)
|
||||||
(unless dry-run?
|
(unless dry-run?
|
||||||
(map/accumulate-builds store
|
(map/accumulate-builds store
|
||||||
(cut deploy-machine* store <>)
|
(cut (if roll-back?
|
||||||
|
roll-back-machine*
|
||||||
|
deploy-machine*)
|
||||||
|
store <>)
|
||||||
machines)))))))))))
|
machines)))))))))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue