summaryrefslogtreecommitdiff
path: root/gnu/build/install.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-09-10 21:39:47 +0200
committerLudovic Courtès <ludo@gnu.org>2014-09-10 21:39:47 +0200
commita4888e2e0fb010836930f09a3822580a04fd7e82 (patch)
tree4f7676810b8136a778970c3f3bc1c38ed1a46722 /gnu/build/install.scm
parent6e4532e8fec5b31fad38be82ada46b5a70952b91 (diff)
downloadguix-patches-a4888e2e0fb010836930f09a3822580a04fd7e82.tar
guix-patches-a4888e2e0fb010836930f09a3822580a04fd7e82.tar.gz
install: Gracefully handle corner cases with 'guix system init foo /'.
* gnu/build/install.scm (evaluate-populate-directive): Wrap body in "catch 'system-error", and report clear errors. In the symlink case, retry up EEXIST. (populate-root-file-system): Remove /var/guix/profiles/system-1-link before attempting to create it.
Diffstat (limited to 'gnu/build/install.scm')
-rw-r--r--gnu/build/install.scm45
1 files changed, 33 insertions, 12 deletions
diff --git a/gnu/build/install.scm b/gnu/build/install.scm
index e16896f8b8..7c4a7b7753 100644
--- a/gnu/build/install.scm
+++ b/gnu/build/install.scm
@@ -56,18 +56,38 @@ MOUNT-POINT."
"Evaluate DIRECTIVE, an sexp describing a file or directory to create under
directory TARGET."
(let loop ((directive directive))
- (match directive
- (('directory name)
- (mkdir-p (string-append target name)))
- (('directory name uid gid)
- (let ((dir (string-append target name)))
- (mkdir-p dir)
- (chown dir uid gid)))
- (('directory name uid gid mode)
- (loop `(directory ,name ,uid ,gid))
- (chmod (string-append target name) mode))
- ((new '-> old)
- (symlink old (string-append target new))))))
+ (catch 'system-error
+ (lambda ()
+ (match directive
+ (('directory name)
+ (mkdir-p (string-append target name)))
+ (('directory name uid gid)
+ (let ((dir (string-append target name)))
+ (mkdir-p dir)
+ (chown dir uid gid)))
+ (('directory name uid gid mode)
+ (loop `(directory ,name ,uid ,gid))
+ (chmod (string-append target name) mode))
+ ((new '-> old)
+ (let try ()
+ (catch 'system-error
+ (lambda ()
+ (symlink old (string-append target new)))
+ (lambda args
+ ;; When doing 'guix system init' on the current '/', some
+ ;; symlinks may already exists. Override them.
+ (if (= EEXIST (system-error-errno args))
+ (begin
+ (delete-file (string-append target new))
+ (try))
+ (apply throw args))))))))
+ (lambda args
+ ;; Usually we can only get here when installing to an existing root,
+ ;; as with 'guix system init foo.scm /'.
+ (format (current-error-port)
+ "error: failed to evaluate directive: ~s~%"
+ directive)
+ (apply throw args)))))
(define (directives store)
"Return a list of directives to populate the root file system that will host
@@ -106,6 +126,7 @@ includes /etc, /var, /run, /bin/sh, etc., and all the symlinks to SYSTEM."
(directives (%store-directory)))
;; Add system generation 1.
+ (false-if-exception (delete-file "/var/guix/profiles/system-1-link"))
(symlink system
(string-append target "/var/guix/profiles/system-1-link")))