Historically, Guix System is centered around an
structure. This structure contains various fields ranging from the
bootloader and kernel declaration to the services to install.
Depending on the target machine, that can go from a standard
x86_64 machine to a small ARM single board computer such as the
Pine64, the image constraints can vary a lot. The hardware
manufacturers will impose different image formats with various partition
sizes and offsets.
To create images suitable for all those machines, a new abstraction is
necessary: that’s the goal of the
image record. This record
contains all the required information to be transformed into a
standalone image, that can be directly booted on any target machine.
(define-record-type* <image> image make-image image? (name image-name ;symbol (default #f)) (format image-format) ;symbol (target image-target (default #f)) (size image-size ;size in bytes as integer (default 'guess)) (operating-system image-operating-system ;<operating-system> (default #f)) (partitions image-partitions ;list of <partition> (default '())) (compression? image-compression? ;boolean (default #t)) (volatile-root? image-volatile-root? ;boolean (default #t)) (substitutable? image-substitutable? ;boolean (default #t)))
This record contains the operating-system to instantiate. The
format field defines the image type and can be
iso9660 for instance. In the future, it could be
docker or other image types.
A new directory in the Guix sources is dedicated to images definition. For now there are four files:
Let’s have a look to pine64.scm. It contains the
pine64-barebones-os variable which is a minimal definition of an
operating-system dedicated to the Pine A64 LTS board.
(define pine64-barebones-os (operating-system (host-name "vignemale") (timezone "Europe/Paris") (locale "en_US.utf8") (bootloader (bootloader-configuration (bootloader u-boot-pine64-lts-bootloader) (targets '("/dev/vda")))) (initrd-modules '()) (kernel linux-libre-arm64-generic) (file-systems (cons (file-system (device (file-system-label "my-root")) (mount-point "/") (type "ext4")) %base-file-systems)) (services (cons (service agetty-service-type (agetty-configuration (extra-options '("-L")) ; no carrier detect (baud-rate "115200") (term "vt100") (tty "ttyS0"))) %base-services))))
bootloader fields are pointing to packages
dedicated to this board.
Right below, the
pine64-image-type variable is also defined.
(define pine64-image-type (image-type (name 'pine64-raw) (constructor (cut image-with-os arm64-disk-image <>))))
It’s using a record we haven’t talked about yet, the
defined this way:
(define-record-type* <image-type> image-type make-image-type image-type? (name image-type-name) ;symbol (constructor image-type-constructor)) ;<operating-system> -> <image>
The main purpose of this record is to associate a name to a procedure
operating-system to an image. To understand why
it is necessary, let’s have a look to the command producing an image
operating-system configuration file:
guix system image my-os.scm
This command expects an
operating-system configuration but how
should we indicate that we want an image targeting a Pine64 board? We
need to provide an extra information, the
image-type, by passing
-t flag, this way:
guix system image --image-type=pine64-raw my-os.scm
image-type parameter points to the
defined above. Hence, the
operating-system declared in
my-os.scm will be applied the
arm64-disk-image <>) procedure to turn it into an image.
The resulting image looks like:
(image (format 'disk-image) (target "aarch64-linux-gnu") (operating-system my-os) (partitions (list (partition (inherit root-partition) (offset root-offset)))))
which is the aggregation of the
operating-system defined in
my-os.scm to the
But enough Scheme madness. What does this image API bring to the Guix user?
One can run:
mathieu@cervin:~$ guix system --list-image-types The available image types are: - pinebook-pro-raw - pine64-raw - novena-raw - hurd-raw - hurd-qcow2 - qcow2 - uncompressed-iso9660 - efi-raw - arm64-raw - arm32-raw - iso9660
and by writing an
operating-system file based on
pine64-barebones-os, you can customize your image to your
preferences in a file (my-pine-os.scm) like this:
(use-modules (gnu services linux) (gnu system images pine64)) (let ((base-os pine64-barebones-os)) (operating-system (inherit base-os) (timezone "America/Indiana/Indianapolis") (services (cons (service earlyoom-service-type (earlyoom-configuration (prefer-regexp "icecat|chromium"))) (operating-system-user-services base-os)))))
guix system image --image-type=pine64-raw my-pine-os.scm
guix system image --image-type=hurd-raw my-hurd-os.scm
to get an image that can be written directly to a hard drive and booted from.
Without changing anything to
guix system image --image-type=hurd-qcow2 my-hurd-os.scm
will instead produce a Hurd QEMU image.