Subject: Re: [bug#27661] ISO-9660 image working and ready

From: [email-masked] (Ludovic Courtès)
Date: Tue, 18 Jul 2017 15:08:49 +0200

Hi Danny,

Danny Milosavljevic <[email-masked]> skribis:

>> I also vote for returning the ISO directly, for consistency with what
>> ‘guix system disk-image’ does for the other formats.  WDYT, Danny?  :-)
>
> Sure, I just don't know how to do that.  The other two files are
> "system" and "bootcfg" and contain some kind of list of gnu store
> paths and single-digit numbers.

They are “references graphs” files, describing the closure of the given
store items.

I gave it a stab and ended up with the attached patch, which Works For
Me™ and is not unreasonably ugly to my eye.  :-)

--8<---------------cut here---------------start------------->8---
$ ./pre-inst-env guix system disk-image -t iso9660 gnu/system/install.scm 
/gnu/store/5pk71pmjp2yshkh0xdfgsnmaxfvdsms1-image.iso
ludo@ribbon ~/src/guix/+master$ file /gnu/store/5pk71pmjp2yshkh0xdfgsnmaxfvdsms1-image.iso
/gnu/store/5pk71pmjp2yshkh0xdfgsnmaxfvdsms1-image.iso: DOS/MBR boot sector; GRand Unified Bootloader, stage1 version 0x79, boot drive 0xbb, stage2 address 0x8e70, 1st sector stage2 0xb8db31c3, stage2 segment 0x201 ISO 9660 CD-ROM filesystem data (DOS/MBR boot sector) 'GUIXSD_IMAGE' (bootable)
--8<---------------cut here---------------end--------------->8---

WDYT?

Ludo’.

diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm
index 086f38ade..305df5933 100644
--- a/gnu/build/vm.scm
+++ b/gnu/build/vm.scm
@@ -76,11 +76,13 @@
                            (qemu (qemu-command)) (memory-size 512)
                            linux initrd
                            make-disk-image?
+                           single-file-output?
                            (disk-image-size (* 100 (expt 2 20)))
                            (disk-image-format "qcow2")
                            (references-graphs '()))
   "Run BUILDER, a Scheme file, into a VM running LINUX with INITRD, and copy
-the result to OUTPUT.
+the result to OUTPUT.  Unless SINGLE-FILE-OUTPUT? is true, the result is
+copied recursively to OUTPUT.
 
 When MAKE-DISK-IMAGE? is true, OUTPUT will contain a VM image of
 DISK-IMAGE-SIZE bytes resulting from the execution of BUILDER, which may
@@ -137,8 +139,14 @@ the #:references-graphs parameter of 'derivation'."
 
   ;; When MAKE-DISK-IMAGE? is true, the image is in OUTPUT already.
   (unless make-disk-image?
-    (mkdir output)
-    (copy-recursively "xchg" output)))
+    (if single-file-output?
+        (let ((graph? (lambda (name stat)
+                        (member (basename name) references-graphs))))
+          (copy-file (first (find-files "xchg" (negate graph?)))
+                     output))
+        (begin
+          (mkdir output)
+          (copy-recursively "xchg" output)))))
 
 
 ;;;
@@ -356,7 +364,7 @@ SYSTEM-DIRECTORY is the name of the directory of the 'system' derivation."
 (define* (make-iso9660-image grub config-file os-drv target
                              #:key (volume-id "GuixSD_image") (volume-uuid #f))
   "Given a GRUB package, creates an iso image as TARGET, using CONFIG-FILE as
-Grub configuration and OS-DRV as the stuff in it."
+GRUB configuration and OS-DRV as the stuff in it."
   (let ((grub-mkrescue (string-append grub "/bin/grub-mkrescue")))
     (mkdir-p "/tmp/root/var/run")
     (mkdir-p "/tmp/root/run")
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index ec3fb031a..45006b2ba 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -108,16 +108,18 @@
                                              (guile-for-build
                                               (%guile-for-build))
 
+                                             (single-file-output? #f)
                                              (make-disk-image? #f)
                                              (references-graphs #f)
                                              (memory-size 256)
                                              (disk-image-format "qcow2")
                                              (disk-image-size 'guess))
   "Evaluate EXP in a QEMU virtual machine running LINUX with INITRD (a
-derivation).  In the virtual machine, EXP has access to all its inputs from the
-store; it should put its output files in the `/xchg' directory, which is
-copied to the derivation's output when the VM terminates.  The virtual machine
-runs with MEMORY-SIZE MiB of memory.
+derivation).  In the virtual machine, EXP has access to all its inputs from
+the store; it should put its output files in the `/xchg' directory, which is
+copied to the derivation's output when the VM terminates, recursively, unless
+SINGLE-FILE-OUTPUT? is true.  The virtual machine runs with MEMORY-SIZE MiB of
+memory.
 
 When MAKE-DISK-IMAGE? is true, then create a QEMU disk image of type
 DISK-IMAGE-FORMAT (e.g., 'qcow2' or 'raw'), of DISK-IMAGE-SIZE bytes and
@@ -167,6 +169,7 @@ made available under the /xchg CIFS share."
                                 #:linux linux #:initrd initrd
                                 #:memory-size #$memory-size
                                 #:make-disk-image? #$make-disk-image?
+                                #:single-file-output? #$single-file-output?
                                 #:disk-image-format #$disk-image-format
                                 #:disk-image-size size
                                 #:references-graphs graphs)))))
@@ -222,6 +225,7 @@ INPUTS is a list of inputs (as for packages)."
            (reboot))))
    #:system system
    #:make-disk-image? #f
+   #:single-file-output? #t
    #:references-graphs inputs))
 
 (define* (qemu-image #:key
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 65dd92e8b..0fcb6a9b0 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -579,8 +579,12 @@ PATTERN, a string.  When PATTERN is #f, display all the system generations."
                                                 (* 70 (expt 2 20)))
                                             #:mappings mappings))
     ((disk-image)
-     (system-disk-image os #:disk-image-size image-size
-                           #:file-system-type file-system-type))))
+     (system-disk-image os
+                        #:name (match file-system-type
+                                 ("iso9660" "image.iso")
+                                 (_         "disk-image"))
+                        #:disk-image-size image-size
+                        #:file-system-type file-system-type))))
 
 (define (maybe-suggest-running-guix-pull)
   "Suggest running 'guix pull' if this has never been done before."