summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.lonestar.org>2019-08-15 04:05:57 -0400
committerChristopher Lemmer Webber <cwebber@dustycloud.org>2019-08-15 07:43:09 -0400
commit9c70c460a05b2bc60f3f3602f0a2dba0f79ce86c (patch)
tree5b55aca91aba654177e117e61020b68236b8dc58 /gnu
parent5ea7537b9a650cfa525401c19879080a9cf42e13 (diff)
machine: Implement 'roll-back-machine'.
* gnu/machine.scm (roll-back-machine, &deploy-error, deploy-error?) (deploy-error-should-roll-back) (deploy-error-captured-args): New variable. * gnu/machine/ssh.scm (roll-back-managed-host): New variable. * guix/scripts/deploy.scm (guix-deploy): Roll-back systems when a deployment fails.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/machine.scm27
-rw-r--r--gnu/machine/ssh.scm72
2 files changed, 95 insertions, 4 deletions
diff --git a/gnu/machine.scm b/gnu/machine.scm
index 30ae97f6ecb..05b03b21d49 100644
--- a/gnu/machine.scm
+++ b/gnu/machine.scm
@@ -24,6 +24,7 @@
24 #:use-module (guix records) 24 #:use-module (guix records)
25 #:use-module (guix store) 25 #:use-module (guix store)
26 #:use-module ((guix utils) #:select (source-properties->location)) 26 #:use-module ((guix utils) #:select (source-properties->location))
27 #:use-module (srfi srfi-35)
27 #:export (environment-type 28 #:export (environment-type
28 environment-type? 29 environment-type?
29 environment-type-name 30 environment-type-name
@@ -40,7 +41,13 @@
40 machine-display-name 41 machine-display-name
41 42
42 deploy-machine 43 deploy-machine
43 machine-remote-eval)) 44 roll-back-machine
45 machine-remote-eval
46
47 &deploy-error
48 deploy-error?
49 deploy-error-should-roll-back
50 deploy-error-captured-args))
44 51
45;;; Commentary: 52;;; Commentary:
46;;; 53;;;
@@ -66,6 +73,7 @@
66 ;; of the form '(machine-remote-eval machine exp)'. 73 ;; of the form '(machine-remote-eval machine exp)'.
67 (machine-remote-eval environment-type-machine-remote-eval) ; procedure 74 (machine-remote-eval environment-type-machine-remote-eval) ; procedure
68 (deploy-machine environment-type-deploy-machine) ; procedure 75 (deploy-machine environment-type-deploy-machine) ; procedure
76 (roll-back-machine environment-type-roll-back-machine) ; procedure
69 77
70 ;; Metadata. 78 ;; Metadata.
71 (name environment-type-name) ; symbol 79 (name environment-type-name) ; symbol
@@ -105,3 +113,20 @@ are built and deployed to MACHINE beforehand."
105MACHINE, activating it on MACHINE and switching MACHINE to the new generation." 113MACHINE, activating it on MACHINE and switching MACHINE to the new generation."
106 (let ((environment (machine-environment machine))) 114 (let ((environment (machine-environment machine)))
107 ((environment-type-deploy-machine environment) machine))) 115 ((environment-type-deploy-machine environment) machine)))
116
117(define (roll-back-machine machine)
118 "Monadic procedure rolling back to the previous system generation on
119MACHINE. Return the number of the generation that was current before switching
120and the new generation number."
121 (let ((environment (machine-environment machine)))
122 ((environment-type-roll-back-machine environment) machine)))
123
124
125;;;
126;;; Error types.
127;;;
128
129(define-condition-type &deploy-error &error
130 deploy-error?
131 (should-roll-back deploy-error-should-roll-back)
132 (captured-args deploy-error-captured-args))
diff --git a/gnu/machine/ssh.scm b/gnu/machine/ssh.scm
index fb15d39e610..4b5d5fe3a2f 100644
--- a/gnu/machine/ssh.scm
+++ b/gnu/machine/ssh.scm
@@ -17,6 +17,7 @@
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18 18
19(define-module (gnu machine ssh) 19(define-module (gnu machine ssh)
20 #:use-module (gnu bootloader)
20 #:use-module (gnu machine) 21 #:use-module (gnu machine)
21 #:autoload (gnu packages gnupg) (guile-gcrypt) 22 #:autoload (gnu packages gnupg) (guile-gcrypt)
22 #:use-module (gnu system) 23 #:use-module (gnu system)
@@ -34,6 +35,7 @@
34 #:use-module (guix store) 35 #:use-module (guix store)
35 #:use-module (guix utils) 36 #:use-module (guix utils)
36 #:use-module (ice-9 match) 37 #:use-module (ice-9 match)
38 #:use-module (srfi srfi-1)
37 #:use-module (srfi srfi-19) 39 #:use-module (srfi srfi-19)
38 #:use-module (srfi srfi-26) 40 #:use-module (srfi srfi-26)
39 #:use-module (srfi srfi-34) 41 #:use-module (srfi srfi-34)
@@ -341,6 +343,18 @@ of MACHINE's system profile, ordered from most recent to oldest."
341 (boot-parameters-kernel-arguments params)))))))) 343 (boot-parameters-kernel-arguments params))))))))
342 generations)))) 344 generations))))
343 345
346(define-syntax-rule (with-roll-back should-roll-back? mbody ...)
347 "Catch exceptions that arise when binding MBODY, a monadic expression in
348%STORE-MONAD, and collect their arguments in a &deploy-error condition, with
349the 'should-roll-back' field set to SHOULD-ROLL-BACK?"
350 (catch #t
351 (lambda ()
352 mbody ...)
353 (lambda args
354 (raise (condition (&deploy-error
355 (should-roll-back should-roll-back?)
356 (captured-args args)))))))
357
344(define (deploy-managed-host machine) 358(define (deploy-managed-host machine)
345 "Internal implementation of 'deploy-machine' for MACHINE instances with an 359 "Internal implementation of 'deploy-machine' for MACHINE instances with an
346environment type of 'managed-host." 360environment type of 'managed-host."
@@ -353,9 +367,60 @@ environment type of 'managed-host."
353 (bootloader-configuration (operating-system-bootloader os)) 367 (bootloader-configuration (operating-system-bootloader os))
354 (bootcfg (operating-system-bootcfg os menu-entries))) 368 (bootcfg (operating-system-bootcfg os menu-entries)))
355 (mbegin %store-monad 369 (mbegin %store-monad
356 (switch-to-system eval os) 370 (with-roll-back #f
357 (upgrade-shepherd-services eval os) 371 (switch-to-system eval os))
358 (install-bootloader eval bootloader-configuration bootcfg))))) 372 (with-roll-back #t
373 (mbegin %store-monad
374 (upgrade-shepherd-services eval os)
375 (install-bootloader eval bootloader-configuration bootcfg)))))))
376
377
378;;;
379;;; Roll-back.
380;;;
381
382(define (roll-back-managed-host machine)
383 "Internal implementation of 'roll-back-machine' for MACHINE instances with
384an environment type of 'managed-host."
385 (define remote-exp
386 (with-extensions (list guile-gcrypt)
387 (with-imported-modules (source-module-closure '((guix config)
388 (guix profiles)))
389 #~(begin
390 (use-modules (guix config)
391 (guix profiles))
392
393 (define %system-profile
394 (string-append %state-directory "/profiles/system"))
395
396 (define target-generation
397 (relative-generation %system-profile -1))
398
399 (if target-generation
400 (switch-to-generation %system-profile target-generation)
401 'error)))))
402
403 (define roll-back-failure
404 (condition (&message (message (G_ "could not roll-back machine")))))
405
406 (mlet* %store-monad ((boot-parameters (machine-boot-parameters machine))
407 (_ -> (if (< (length boot-parameters) 2)
408 (raise roll-back-failure)))
409 (entries -> (map boot-parameters->menu-entry
410 (list (second boot-parameters))))
411 (old-entries -> (map boot-parameters->menu-entry
412 (drop boot-parameters 2)))
413 (bootloader -> (operating-system-bootloader
414 (machine-operating-system machine)))
415 (bootcfg (lower-object
416 ((bootloader-configuration-file-generator
417 (bootloader-configuration-bootloader
418 bootloader))
419 bootloader entries
420 #:old-entries old-entries)))
421 (remote-result (machine-remote-eval machine remote-exp)))
422 (when (eqv? 'error remote-result)
423 (raise roll-back-failure))))
359 424
360 425
361;;; 426;;;
@@ -366,6 +431,7 @@ environment type of 'managed-host."
366 (environment-type 431 (environment-type
367 (machine-remote-eval managed-host-remote-eval) 432 (machine-remote-eval managed-host-remote-eval)
368 (deploy-machine deploy-managed-host) 433 (deploy-machine deploy-managed-host)
434 (roll-back-machine roll-back-managed-host)
369 (name 'managed-host-environment-type) 435 (name 'managed-host-environment-type)
370 (description "Provisioning for machines that are accessible over SSH 436 (description "Provisioning for machines that are accessible over SSH
371and have a known host-name. This entails little more than maintaining an SSH 437and have a known host-name. This entails little more than maintaining an SSH