From 22bbdb5f794c9fe2f350f4295b8dcf93438ad011 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Sun, 3 Sep 2017 11:47:58 +0100 Subject: vm: Add support for registering closures to make-iso9660-image. This mimics the functionality in the root-partition-initializer used in creating the QEMU image. This helps when trying to run guix system init from the generated ISO image. * gnu/build/vm.scm (make-iso9660-image): Add support for registering closures. --- gnu/build/vm.scm | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index 727494ad93..606257d8c3 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -366,12 +366,27 @@ SYSTEM-DIRECTORY is the name of the directory of the 'system' derivation." (error "failed to create GRUB EFI image")))) (define* (make-iso9660-image grub config-file os-drv target - #:key (volume-id "GuixSD_image") (volume-uuid #f)) + #:key (volume-id "GuixSD_image") (volume-uuid #f) + register-closures? (closures '())) "Given a GRUB package, creates an iso image as TARGET, using CONFIG-FILE as GRUB configuration and OS-DRV as the stuff in it." - (let ((grub-mkrescue (string-append grub "/bin/grub-mkrescue"))) + (let ((grub-mkrescue (string-append grub "/bin/grub-mkrescue")) + (target-store (string-append "/tmp/root" (%store-directory)))) (mkdir-p "/tmp/root/var/run") (mkdir-p "/tmp/root/run") + + (mkdir-p target-store) + (mount (%store-directory) target-store "" MS_BIND) + + (when register-closures? + (display "registering closures...\n") + (for-each (lambda (closure) + (register-closure + "/tmp/root" + (string-append "/xchg/" closure) + #:deduplicate? #f)) + closures)) + (unless (zero? (apply system* `(,grub-mkrescue "-o" ,target ,(string-append "boot/grub/grub.cfg=" config-file) -- cgit v1.2.3 From 309b8fe7e65c39e04b7a5f89adb5a0a72867cdff Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Sun, 3 Sep 2017 11:48:11 +0100 Subject: vm: Create /mnt in the generated ISO image in make-iso9660-image. This is used in the installation process, as the mountpoint for the target filesystem. * gnu/build/vm.scm (make-iso9660-image): Create /mnt within the generated ISO image. --- gnu/build/vm.scm | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index 606257d8c3..f6228b40bb 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -374,6 +374,7 @@ GRUB configuration and OS-DRV as the stuff in it." (target-store (string-append "/tmp/root" (%store-directory)))) (mkdir-p "/tmp/root/var/run") (mkdir-p "/tmp/root/run") + (mkdir-p "/tmp/root/mnt") (mkdir-p target-store) (mount (%store-directory) target-store "" MS_BIND) @@ -393,6 +394,10 @@ GRUB configuration and OS-DRV as the stuff in it." ,(string-append "gnu/store=" os-drv "/..") "var=/tmp/root/var" "run=/tmp/root/run" + ;; /mnt is used as part of the installation + ;; process, as the mount point for the target + ;; filesystem, so create it. + "mnt=/tmp/root/mnt" "--" ;; Store two copies of the headers. ;; The resulting ISO-9660 image has a DOS MBR and -- cgit v1.2.3 From 13877c34534fc6a1cda25a984007bc0e7d27ebc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 7 Sep 2017 23:31:21 +0200 Subject: marionette: 'wait-for-file' can be passed a read procedure. * gnu/build/marionette.scm (wait-for-file): Add #:read parameter and honor it. * gnu/tests/base.scm (run-basic-test)["login on tty1"]: Use 'wait-for-file' instead of inline code. --- gnu/build/marionette.scm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/marionette.scm b/gnu/build/marionette.scm index f35f0fbca1..7554a710a0 100644 --- a/gnu/build/marionette.scm +++ b/gnu/build/marionette.scm @@ -165,13 +165,14 @@ QEMU monitor and to the guest's backdoor REPL." (newline repl) (read repl)))) -(define* (wait-for-file file marionette #:key (timeout 10)) - "Wait until FILE exists in MARIONETTE; 'read' its content and return it. If +(define* (wait-for-file file marionette + #:key (timeout 10) (read 'read)) + "Wait until FILE exists in MARIONETTE; READ its content and return it. If FILE has not shown up after TIMEOUT seconds, raise an error." (match (marionette-eval `(let loop ((i ,timeout)) (cond ((file-exists? ,file) - (cons 'success (call-with-input-file ,file read))) + (cons 'success (call-with-input-file ,file ,read))) ((> i 0) (sleep 1) (loop (- i 1))) -- cgit v1.2.3 From 575065bd1c3fbe80ee725bbc483aecfc6e870a1c Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Sun, 10 Sep 2017 11:42:51 +0100 Subject: vm: Add comment about deduplication in make-iso9660-image. * gnu/build/vm.scm (make-iso9660-image): Add comment about the use of #:deduplicate #f when calling register-closure. --- gnu/build/vm.scm | 1 + 1 file changed, 1 insertion(+) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index f6228b40bb..466e3daf44 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -385,6 +385,7 @@ GRUB configuration and OS-DRV as the stuff in it." (register-closure "/tmp/root" (string-append "/xchg/" closure) + ;; XXX: Using deduplication causes cross device link errors. #:deduplicate? #f)) closures)) -- cgit v1.2.3 From bae28ccb69d67f0e988a49046ffa29d201d77a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 20 Jul 2017 00:15:43 +0200 Subject: vm: Allow partitions to be initialized with a given UUID. * gnu/build/vm.scm ()[uuid]: New field. (create-ext-file-system): Add #:uuid and honor it. (create-fat-file-system): Add #:uuid. (format-partition): Add #:uuid and honor it. (initialize-partition): Honor the 'uuid' field of PARTITION. --- gnu/build/vm.scm | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index 466e3daf44..ad67a3727f 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -163,6 +163,7 @@ the #:references-graphs parameter of 'derivation'." (size partition-size) (file-system partition-file-system (default "ext4")) (label partition-label (default #f)) + (uuid partition-uuid (default #f)) (flags partition-flags (default '())) (initializer partition-initializer (default (const #t)))) @@ -236,22 +237,26 @@ actual /dev name based on DEVICE." (define MS_BIND 4096) ; again! (define* (create-ext-file-system partition type - #:key label) + #:key label uuid) "Create an ext-family filesystem of TYPE on PARTITION. If LABEL is true, -use that as the volume name." +use that as the volume name. If UUID is true, use it as the partition UUID." (format #t "creating ~a partition...\n" type) (unless (zero? (apply system* (string-append "mkfs." type) "-F" partition - (if label - `("-L" ,label) - '()))) + `(,@(if label + `("-L" ,label) + '()) + ,@(if uuid + `("-U" ,(uuid->string uuid)) + '())))) (error "failed to create partition"))) (define* (create-fat-file-system partition - #:key label) + #:key label uuid) "Create a FAT filesystem on PARTITION. The number of File Allocation Tables will be determined based on filesystem size. If LABEL is true, use that as the volume name." + ;; FIXME: UUID is ignored! (format #t "creating FAT partition...\n") (unless (zero? (apply system* "mkfs.fat" partition (if label @@ -260,13 +265,13 @@ volume name." (error "failed to create FAT partition"))) (define* (format-partition partition type - #:key label) + #:key label uuid) "Create a file system TYPE on PARTITION. If LABEL is true, use that as the volume name." (cond ((string-prefix? "ext" type) - (create-ext-file-system partition type #:label label)) + (create-ext-file-system partition type #:label label #:uuid uuid)) ((or (string-prefix? "fat" type) (string= "vfat" type)) - (create-fat-file-system partition #:label label)) + (create-fat-file-system partition #:label label #:uuid uuid)) (else (error "Unsupported file system.")))) (define (initialize-partition partition) @@ -275,7 +280,8 @@ it, run its initializer, and unmount it." (let ((target "/fs")) (format-partition (partition-device partition) (partition-file-system partition) - #:label (partition-label partition)) + #:label (partition-label partition) + #:uuid (partition-uuid partition)) (mkdir-p target) (mount (partition-device partition) target (partition-file-system partition)) -- cgit v1.2.3 From a8e1247d7d758a0c32d54f8277f40a05711555b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sat, 19 Aug 2017 23:55:10 +0200 Subject: file-systems: Add UUID type dictionaries. * gnu/build/file-systems.scm (uuid->string): Rename to... (dce-uuid->string): ... this. (string->uuid): Rename to... (string->dce-uuid): ... this. (vhashq): New macro. (%uuid-parsers, %uuid-printers): New variables. (uuid->string, string->uuid): New procedures. --- gnu/build/file-systems.scm | 49 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm index 203fbdfffb..fbaf158951 100644 --- a/gnu/build/file-systems.scm +++ b/gnu/build/file-systems.scm @@ -28,6 +28,7 @@ #:use-module (ice-9 rdelim) #:use-module (ice-9 format) #:use-module (ice-9 regex) + #:use-module (ice-9 vlist) #:use-module (system foreign) #:autoload (system repl repl) (start-repl) #:use-module (srfi srfi-1) @@ -42,7 +43,9 @@ canonicalize-device-spec uuid->string + dce-uuid->string string->uuid + string->dce-uuid string->iso9660-uuid string->ext2-uuid string->ext3-uuid @@ -516,7 +519,7 @@ were found." (define-syntax %network-byte-order (identifier-syntax (endianness big))) -(define (uuid->string uuid) +(define (dce-uuid->string uuid) "Convert UUID, a 16-byte bytevector, to its string representation, something like \"6b700d61-5550-48a1-874c-a3d86998990e\"." ;; See . @@ -532,7 +535,7 @@ like \"6b700d61-5550-48a1-874c-a3d86998990e\"." ;; The regexp of a UUID. (make-regexp "^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$")) -(define (string->uuid str) +(define (string->dce-uuid str) "Parse STR as a DCE UUID (see ) and return its contents as a 16-byte bytevector. Return #f if STR is not a valid UUID representation." @@ -562,10 +565,44 @@ UUID representation." (time-low 4) (time-mid 2) (time-hi 2) (clock-seq 2) (node 6))))))) -(define string->ext2-uuid string->uuid) -(define string->ext3-uuid string->uuid) -(define string->ext4-uuid string->uuid) -(define string->btrfs-uuid string->uuid) +(define string->ext2-uuid string->dce-uuid) +(define string->ext3-uuid string->dce-uuid) +(define string->ext4-uuid string->dce-uuid) +(define string->btrfs-uuid string->dce-uuid) + +(define-syntax vhashq + (syntax-rules (=>) + ((_) + vlist-null) + ((_ (key others ... => value) rest ...) + (vhash-consq key value + (vhashq (others ... => value) rest ...))) + ((_ (=> value) rest ...) + (vhashq rest ...)))) + +(define %uuid-parsers + (vhashq + ('dce 'ext2 'ext3 'ext4 'btrfs 'luks => string->dce-uuid) + ('iso9660 => string->iso9660-uuid))) + +(define %uuid-printers + (vhashq + ('dce 'ext2 'ext3 'ext4 'btrfs 'luks => dce-uuid->string) + ('iso9660 => iso9660-uuid->string) + ('fat32 'fat => fat32-uuid->string))) + +(define* (string->uuid str #:key (type 'dce)) + "Parse STR as a UUID of the given TYPE. On success, return the +corresponding bytevector; otherwise return #f." + (match (vhash-assq type %uuid-parsers) + (#f #f) + ((_ . (? procedure? parse)) (parse str)))) + +(define* (uuid->string bv #:key (type 'dce)) + "Convert BV, a bytevector, to the UUID string representation for TYPE." + (match (vhash-assq type %uuid-printers) + (#f #f) + ((_ . (? procedure? unparse)) (unparse bv)))) (define* (canonicalize-device-spec spec #:optional (title 'any)) -- cgit v1.2.3 From 47cef4ecad54d112aa3b4bc509194d3d49a10785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 5 Sep 2017 21:51:12 +0200 Subject: file-systems: Introduce (gnu system uuid). * gnu/build/file-systems.scm (sub-bytevector) (latin1->string, %fat32-endianness, fat32-uuid->string) (%iso9660-uuid-rx, string->iso9660-uuid) (iso9660-uuid->string, %network-byte-order) (dce-uuid->string, %uuid-rx, string->dce-uuid) (string->ext2-uuid, string->ext3-uuid, string->ext4-uuid) (vhashq, %uuid-parsers, %uuid-printers, string->uuid) (uuid->string): Move to... * gnu/system/uuid.scm: ... here. New file. * gnu/system/file-systems.scm (uuid): Move to the above file. * gnu/system/vm.scm: Adjust accordingly. * gnu/local.mk (GNU_SYSTEM_MODULES): Add uuid.scm. --- gnu/build/file-systems.scm | 167 +-------------------------------------------- gnu/build/vm.scm | 2 +- 2 files changed, 2 insertions(+), 167 deletions(-) (limited to 'gnu/build') diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm index fbaf158951..32885f1d2e 100644 --- a/gnu/build/file-systems.scm +++ b/gnu/build/file-systems.scm @@ -19,6 +19,7 @@ ;;; along with GNU Guix. If not, see . (define-module (gnu build file-systems) + #:use-module (gnu system uuid) #:use-module (guix build utils) #:use-module (guix build bournish) #:use-module (guix build syscalls) @@ -26,9 +27,6 @@ #:use-module (rnrs bytevectors) #:use-module (ice-9 match) #:use-module (ice-9 rdelim) - #:use-module (ice-9 format) - #:use-module (ice-9 regex) - #:use-module (ice-9 vlist) #:use-module (system foreign) #:autoload (system repl repl) (start-repl) #:use-module (srfi srfi-1) @@ -42,17 +40,6 @@ find-partition-by-luks-uuid canonicalize-device-spec - uuid->string - dce-uuid->string - string->uuid - string->dce-uuid - string->iso9660-uuid - string->ext2-uuid - string->ext3-uuid - string->ext4-uuid - string->btrfs-uuid - iso9660-uuid->string - bind-mount mount-flags->bit-mask @@ -98,20 +85,6 @@ takes a bytevector and returns #t when it's a valid superblock." (and (magic? block) block))))))))) -(define (sub-bytevector bv start size) - "Return a copy of the SIZE bytes of BV starting from offset START." - (let ((result (make-bytevector size))) - (bytevector-copy! bv start result 0 size) - result)) - -(define (latin1->string bv terminator) - "Return a string of BV, a latin1 bytevector, or #f. TERMINATOR is a predicate -that takes a number and returns #t when a termination character is found." - (let ((bytes (take-while (negate terminator) (bytevector->u8-list bv)))) - (if (null? bytes) - #f - (list->string (map integer->char bytes))))) - (define null-terminated-latin1->string (cut latin1->string <> zero?)) @@ -199,10 +172,6 @@ if DEVICE does not contain a btrfs file system." ;; . -(define-syntax %fat32-endianness - ;; Endianness of fat file systems. - (identifier-syntax (endianness little))) - (define (fat32-superblock? sblock) "Return #t when SBLOCK is a fat32 superblock." (bytevector=? (sub-bytevector sblock 82 8) @@ -217,12 +186,6 @@ if DEVICE does not contain a btrfs file system." "Return the Volume ID of a fat superblock SBLOCK as a 4-byte bytevector." (sub-bytevector sblock 67 4)) -(define (fat32-uuid->string uuid) - "Convert fat32 UUID, a 4-byte bytevector, to its string representation." - (let ((high (bytevector-uint-ref uuid 0 %fat32-endianness 2)) - (low (bytevector-uint-ref uuid 2 %fat32-endianness 2))) - (format #f "~:@(~x-~x~)" low high))) - (define (fat32-superblock-volume-name sblock) "Return the volume name of SBLOCK as a string of at most 11 characters, or #f if SBLOCK has no volume name. The volume name is a latin1 string. @@ -244,27 +207,6 @@ Trailing spaces are trimmed." ;; . -(define %iso9660-uuid-rx - ;; Y m d H M S ss - (make-regexp "^([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})-([[:digit:]]{2})-([[:digit:]]{2})-([[:digit:]]{2})-([[:digit:]]{2})$")) - -(define (string->iso9660-uuid str) - "Parse STR as a ISO9660 UUID (which is really a timestamp - see /dev/disk/by-uuid). -Return its contents as a 16-byte bytevector. Return #f if STR is not a valid -ISO9660 UUID representation." - (and=> (regexp-exec %iso9660-uuid-rx str) - (lambda (match) - (letrec-syntax ((match-numerals - (syntax-rules () - ((_ index (name rest ...) body) - (let ((name (match:substring match index))) - (match-numerals (+ 1 index) (rest ...) body))) - ((_ index () body) - body)))) - (match-numerals 1 (year month day hour minute second hundredths) - (string->utf8 (string-append year month day - hour minute second hundredths))))))) - (define (iso9660-superblock? sblock) "Return #t when SBLOCK is an iso9660 volume descriptor." (bytevector=? (sub-bytevector sblock 1 6) @@ -311,20 +253,6 @@ SBLOCK as a bytevector. If that's not set, returns the creation time." modification-time))) (sub-bytevector time 0 16))) ; strips GMT offset. -(define (iso9660-uuid->string uuid) - "Given an UUID bytevector, return its timestamp string." - (define (digits->string bytes) - (latin1->string bytes (lambda (c) #f))) - (let* ((year (sub-bytevector uuid 0 4)) - (month (sub-bytevector uuid 4 2)) - (day (sub-bytevector uuid 6 2)) - (hour (sub-bytevector uuid 8 2)) - (minute (sub-bytevector uuid 10 2)) - (second (sub-bytevector uuid 12 2)) - (hundredths (sub-bytevector uuid 14 2)) - (parts (list year month day hour minute second hundredths))) - (string-append (string-join (map digits->string parts) "-")))) - (define (iso9660-superblock-volume-name sblock) "Return the volume name of SBLOCK as a string. The volume name is an ASCII string. Trailing spaces are trimmed." @@ -511,99 +439,6 @@ were found." (define find-partition-by-luks-uuid (find-partition luks-partition-uuid-predicate)) - -;;; -;;; UUIDs. -;;; - -(define-syntax %network-byte-order - (identifier-syntax (endianness big))) - -(define (dce-uuid->string uuid) - "Convert UUID, a 16-byte bytevector, to its string representation, something -like \"6b700d61-5550-48a1-874c-a3d86998990e\"." - ;; See . - (let ((time-low (bytevector-uint-ref uuid 0 %network-byte-order 4)) - (time-mid (bytevector-uint-ref uuid 4 %network-byte-order 2)) - (time-hi (bytevector-uint-ref uuid 6 %network-byte-order 2)) - (clock-seq (bytevector-uint-ref uuid 8 %network-byte-order 2)) - (node (bytevector-uint-ref uuid 10 %network-byte-order 6))) - (format #f "~8,'0x-~4,'0x-~4,'0x-~4,'0x-~12,'0x" - time-low time-mid time-hi clock-seq node))) - -(define %uuid-rx - ;; The regexp of a UUID. - (make-regexp "^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$")) - -(define (string->dce-uuid str) - "Parse STR as a DCE UUID (see ) and -return its contents as a 16-byte bytevector. Return #f if STR is not a valid -UUID representation." - (and=> (regexp-exec %uuid-rx str) - (lambda (match) - (letrec-syntax ((hex->number - (syntax-rules () - ((_ index) - (string->number (match:substring match index) - 16)))) - (put! - (syntax-rules () - ((_ bv index (number len) rest ...) - (begin - (bytevector-uint-set! bv index number - (endianness big) len) - (put! bv (+ index len) rest ...))) - ((_ bv index) - bv)))) - (let ((time-low (hex->number 1)) - (time-mid (hex->number 2)) - (time-hi (hex->number 3)) - (clock-seq (hex->number 4)) - (node (hex->number 5)) - (uuid (make-bytevector 16))) - (put! uuid 0 - (time-low 4) (time-mid 2) (time-hi 2) - (clock-seq 2) (node 6))))))) - -(define string->ext2-uuid string->dce-uuid) -(define string->ext3-uuid string->dce-uuid) -(define string->ext4-uuid string->dce-uuid) -(define string->btrfs-uuid string->dce-uuid) - -(define-syntax vhashq - (syntax-rules (=>) - ((_) - vlist-null) - ((_ (key others ... => value) rest ...) - (vhash-consq key value - (vhashq (others ... => value) rest ...))) - ((_ (=> value) rest ...) - (vhashq rest ...)))) - -(define %uuid-parsers - (vhashq - ('dce 'ext2 'ext3 'ext4 'btrfs 'luks => string->dce-uuid) - ('iso9660 => string->iso9660-uuid))) - -(define %uuid-printers - (vhashq - ('dce 'ext2 'ext3 'ext4 'btrfs 'luks => dce-uuid->string) - ('iso9660 => iso9660-uuid->string) - ('fat32 'fat => fat32-uuid->string))) - -(define* (string->uuid str #:key (type 'dce)) - "Parse STR as a UUID of the given TYPE. On success, return the -corresponding bytevector; otherwise return #f." - (match (vhash-assq type %uuid-parsers) - (#f #f) - ((_ . (? procedure? parse)) (parse str)))) - -(define* (uuid->string bv #:key (type 'dce)) - "Convert BV, a bytevector, to the UUID string representation for TYPE." - (match (vhash-assq type %uuid-printers) - (#f #f) - ((_ . (? procedure? unparse)) (unparse bv)))) - (define* (canonicalize-device-spec spec #:optional (title 'any)) "Return the device name corresponding to SPEC. TITLE is a symbol, one of diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm index ad67a3727f..6da4fa654e 100644 --- a/gnu/build/vm.scm +++ b/gnu/build/vm.scm @@ -26,7 +26,7 @@ #:use-module (guix build syscalls) #:use-module (gnu build linux-boot) #:use-module (gnu build install) - #:use-module (gnu build file-systems) + #:use-module (gnu system uuid) #:use-module (guix records) #:use-module ((guix combinators) #:select (fold2)) #:use-module (ice-9 format) -- cgit v1.2.3