summary refs log tree commit diff
path: root/gnu/installer
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/installer')
-rw-r--r--gnu/installer/final.scm30
-rw-r--r--gnu/installer/newt.scm2
-rw-r--r--gnu/installer/utils.scm26
3 files changed, 39 insertions, 19 deletions
diff --git a/gnu/installer/final.scm b/gnu/installer/final.scm
index 044f79372b..069426a3b8 100644
--- a/gnu/installer/final.scm
+++ b/gnu/installer/final.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
-;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -114,6 +114,8 @@ it can interact with the rest of the system."
     ;; Catch SIGINT and kill the container process.
     (sigaction SIGINT
       (lambda (signum)
+        ;: FIXME: Use of SIGKILL prevents the dynamic-wind exit handler of
+        ;; THUNK to run.
         (false-if-exception
          (kill pid SIGKILL))))
 
@@ -196,14 +198,16 @@ or #f.  Return #t on success and #f on failure."
              ;; the loaded cow-store locale files will prevent umounting.
              (install-locale locale)
 
-             ;; Save the database, so that it can be restored once the
-             ;; cow-store is umounted.
+             ;; Stop the daemon and save the database, so that it can be
+             ;; restored once the cow-store is umounted.
+             (stop-service 'guix-daemon)
              (copy-file database-file saved-database)
+
+             (installer-log-line "mounting copy-on-write store")
              (mount-cow-store (%installer-target-dir) backing-directory))
            (lambda ()
              ;; We need to drag the guix-daemon to the container MNT
              ;; namespace, so that it can operate on the cow-store.
-             (stop-service 'guix-daemon)
              (start-service 'guix-daemon (list (number->string (getpid))))
 
              (setvbuf (current-output-port) 'none)
@@ -213,11 +217,25 @@ or #f.  Return #t on success and #f on failure."
 
              (set! ret (run-command install-command #:tty? #t)))
            (lambda ()
-             ;; Restart guix-daemon so that it does no keep the MNT namespace
+             ;; Stop guix-daemon so that it does no keep the MNT namespace
              ;; alive.
-             (restart-service 'guix-daemon)
+             (stop-service 'guix-daemon)
+
+             ;; Restore the database and restart it.  As part of restoring the
+             ;; database, remove the WAL and shm files in case they were left
+             ;; behind after guix-daemon was stopped.  Failing to do so,
+             ;; sqlite might behave as if transactions that appear in the WAL
+             ;; file were committed.  (See <https://www.sqlite.org/wal.html>.)
+             (installer-log-line "restoring store database from '~a'"
+                                 saved-database)
              (copy-file saved-database database-file)
+             (for-each (lambda (suffix)
+                         (false-if-exception
+                          (delete-file (string-append database-file suffix))))
+                       '("-wal" "-shm"))
+             (start-service 'guix-daemon)
 
              ;; Finally umount the cow-store and exit the container.
+             (installer-log-line "unmounting copy-on-write store")
              (unmount-cow-store (%installer-target-dir) backing-directory)
              (assert-exit ret))))))))
diff --git a/gnu/installer/newt.scm b/gnu/installer/newt.scm
index 798ff53af2..e1c4453168 100644
--- a/gnu/installer/newt.scm
+++ b/gnu/installer/newt.scm
@@ -116,7 +116,7 @@ report it by email to ~a.") uploaded-name %guix-bug-report-address)
   (define command-output "")
   (define (line-accumulator line)
     (set! command-output
-          (string-append/shared command-output line "\n")))
+          (string-append/shared command-output line)))
   (define result (run-external-command-with-line-hooks (list line-accumulator)
                                                        args))
   (define exit-val (status:exit-val result))
diff --git a/gnu/installer/utils.scm b/gnu/installer/utils.scm
index 061493e6a7..6838410166 100644
--- a/gnu/installer/utils.scm
+++ b/gnu/installer/utils.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2018, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
-;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2019, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -159,7 +159,9 @@ COMMAND will be run in a pseudoterminal.  Returns the integer status value of
 the child process as returned by waitpid."
   (define (handler input)
     (and
-     (and=> (get-line input)
+     ;; Lines for progress bars etc. end in \r; treat is as a line ending so
+     ;; those lines are printed right away.
+     (and=> (read-delimited "\r\n" input 'concat)
             (lambda (line)
               (if (eof-object? line)
                   #f
@@ -186,7 +188,7 @@ in a pseudoterminal."
 
   (installer-log-line "running command ~s" command)
   (define result (run-external-command-with-line-hooks
-                  (list %display-line-hook) command
+                  (list display) command
                   #:tty? tty?))
   (define exit-val (status:exit-val result))
   (define term-sig (status:term-sig result))
@@ -264,7 +266,10 @@ values."
       (or port (%make-void-port "w")))))
 
 (define (%syslog-line-hook line)
-  (format (syslog-port) "installer[~d]: ~a~%" (getpid) line))
+  (let ((line (if (string-suffix? "\r" line)
+                  (string-append (string-drop-right line 1) "\n")
+                  line)))
+    (format (syslog-port) "installer[~d]: ~a" (getpid) line)))
 
 (define-syntax syslog
   (lambda (s)
@@ -293,11 +298,7 @@ values."
       port)))
 
 (define (%installer-log-line-hook line)
-  (format (installer-log-port) "~a~%" line))
-
-(define (%display-line-hook line)
-  (display line)
-  (newline))
+  (display line (installer-log-port)))
 
 (define %default-installer-line-hooks
   (list %syslog-line-hook
@@ -309,9 +310,10 @@ values."
     (syntax-case s ()
       ((_ fmt args ...)
        (string? (syntax->datum #'fmt))
-       #'(let ((formatted (format #f fmt args ...)))
-               (for-each (lambda (f) (f formatted))
-                         %default-installer-line-hooks))))))
+       (with-syntax ((fmt (string-append (syntax->datum #'fmt) "\n")))
+         #'(let ((formatted (format #f fmt args ...)))
+             (for-each (lambda (f) (f formatted))
+                       %default-installer-line-hooks)))))))
 
 
 ;;;