diff options
| author | Jakob L. Kreuze <zerodaysfordays@sdf.lonestar.org> | 2019-08-15 04:05:57 -0400 |
|---|---|---|
| committer | Christopher Lemmer Webber <cwebber@dustycloud.org> | 2019-08-15 07:43:09 -0400 |
| commit | 9c70c460a05b2bc60f3f3602f0a2dba0f79ce86c (patch) | |
| tree | 5b55aca91aba654177e117e61020b68236b8dc58 /gnu | |
| parent | 5ea7537b9a650cfa525401c19879080a9cf42e13 (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.scm | 27 | ||||
| -rw-r--r-- | gnu/machine/ssh.scm | 72 |
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." | |||
| 105 | MACHINE, activating it on MACHINE and switching MACHINE to the new generation." | 113 | MACHINE, 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 | ||
| 119 | MACHINE. Return the number of the generation that was current before switching | ||
| 120 | and 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 | ||
| 349 | the '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 |
| 346 | environment type of 'managed-host." | 360 | environment 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 | ||
| 384 | an 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 |
| 371 | and have a known host-name. This entails little more than maintaining an SSH | 437 | and have a known host-name. This entails little more than maintaining an SSH |
