GNU bug report logs - #75414
[PATCH 0/2] Add roll-back action to guix deploy

Previous Next

Package: guix-patches;

Reported by: Arun Isaac <arunisaac <at> systemreboot.net>

Date: Tue, 7 Jan 2025 00:19:02 UTC

Severity: normal

Tags: patch

Done: Arun Isaac <arunisaac <at> systemreboot.net>

Bug is archived. No further changes may be made.

Full log


Message #38 received at 75414 <at> debbugs.gnu.org (full text, mbox):

From: Arun Isaac <arunisaac <at> systemreboot.net>
To: 75414 <at> debbugs.gnu.org
Cc: Arun Isaac <arunisaac <at> systemreboot.net>
Subject: [PATCH v2 1/1] deploy: Add --roll-back option.
Date: Thu, 27 Feb 2025 22:55:50 +0000
* 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
---
 doc/guix.texi           |  8 +++++
 guix/scripts/deploy.scm | 75 +++++++++++++++++++++++++++++++++++------
 2 files changed, 72 insertions(+), 11 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index a036c85c31a..64746c7f925 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -45232,6 +45232,14 @@ Invoking guix deploy
 The @command{guix deploy -x} command returns zero if and only if the
 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.
 
 Below are the data types you need to know about when writing a
diff --git a/guix/scripts/deploy.scm b/guix/scripts/deploy.scm
index 941ee199f01..e2ef0006e06 100644
--- a/guix/scripts/deploy.scm
+++ b/guix/scripts/deploy.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays <at> sdf.org>
 ;;; Copyright © 2020-2022 Ludovic Courtès <ludo <at> gnu.org>
 ;;; Copyright © 2024 Richard Sent <richard <at> freakingpenguin.com>
+;;; Copyright © 2025 Arun Isaac <arunisaac <at> systemreboot.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -63,6 +64,8 @@ (define (show-help)
   -e, --expression=EXPR  deploy the list of machines EXPR evaluates to"))
   (newline)
   (display (G_ "
+  -r, --roll-back        switch to the previous operating system configuration"))
+  (display (G_ "
   -x, --execute          execute the following command on all the machines"))
   (newline)
   (display (G_ "
@@ -84,6 +87,9 @@ (define %options
          (option '(#\n "dry-run") #f #f
                  (lambda (opt name arg 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
                  (lambda (opt name arg result)
                    (alist-cons 'execute-command? #t result)))
@@ -118,20 +124,32 @@ (define (load-source-file file)
                                            environment-modules))))
     (load* file module)))
 
-(define* (show-what-to-deploy machines #:key (dry-run? #f))
-  "Show the list of machines to deploy, MACHINES."
+(define* (show-what-to-deploy machines #:key (dry-run? #f) (roll-back? #f))
+  "Show the list of machines in MACHINES to deploy or roll back."
   (let ((count (length machines)))
     (if dry-run?
-        (format (current-error-port)
-                (N_ "The following ~d machine would be deployed:~%"
-                    "The following ~d machines would be deployed:~%"
+        (if roll-back?
+            (format (current-error-port)
+                (N_ "The following ~d machine would be rolled back:~%"
+                    "The following ~d machines would be rolled back:~%"
                     count)
                 count)
-        (format (current-error-port)
-                (N_ "The following ~d machine will be deployed:~%"
-                    "The following ~d machines will be deployed:~%"
+            (format (current-error-port)
+                    (N_ "The following ~d machine would 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))
+            (format (current-error-port)
+                    (N_ "The following ~d machine will be deployed:~%"
+                        "The following ~d machines will be deployed:~%"
+                        count)
+                    count)))
     (display (indented-string
               (fill-paragraph (string-join (map machine-display-name machines)
                                            ", ")
@@ -175,6 +193,35 @@ (define (deploy-machine* store machine)
     (info (G_ "successfully deployed ~a~%")
           (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)
   "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
@@ -258,6 +305,7 @@ (define-command (guix-deploy . args)
            (machines (or (and file (load-source-file file))
                          (and expression (read/eval expression))))
            (dry-run? (assoc-ref opts 'dry-run?))
+           (roll-back? (assq-ref opts 'roll-back?))
            (execute-command? (assoc-ref opts 'execute-command?)))
       (when (and file expression)
         (leave (G_ "both '--expression' and a deployment file were provided~%")))
@@ -292,8 +340,13 @@ (define-command (guix-deploy . args)
                     (_
                      (leave (G_ "'-x' specified but no command given~%"))))
                   (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?
                       (map/accumulate-builds store
-                                             (cut deploy-machine* store <>)
+                                             (cut (if roll-back?
+                                                      roll-back-machine*
+                                                      deploy-machine*)
+                                                  store <>)
                                              machines)))))))))))
-- 
2.48.1





This bug report was last modified 145 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.