From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55218) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eyVKB-0001yi-Gb for guix-patches@gnu.org; Wed, 21 Mar 2018 00:26:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eyVK6-0004Mt-ER for guix-patches@gnu.org; Wed, 21 Mar 2018 00:26:07 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:36805) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eyVK6-0004Md-8n for guix-patches@gnu.org; Wed, 21 Mar 2018 00:26:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1eyVK5-0007XH-UD for guix-patches@gnu.org; Wed, 21 Mar 2018 00:26:01 -0400 Subject: [bug#30572] [PATCH 6/7] system: Add "guix system docker-image" command. Resent-Message-ID: From: Chris Marusich References: <20180222102933.4978-1-cmmarusich@gmail.com> <20180315040915.5556-1-cmmarusich@gmail.com> <20180315040915.5556-7-cmmarusich@gmail.com> <877eqal62w.fsf@gnu.org> <87370u6pw4.fsf@gmail.com> Date: Wed, 21 Mar 2018 05:25:27 +0100 In-Reply-To: <87370u6pw4.fsf@gmail.com> (Chris Marusich's message of "Wed, 21 Mar 2018 04:58:35 +0100") Message-ID: <87k1u65a2w.fsf@gmail.com> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Cc: 30572@debbugs.gnu.org --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Chris Marusich writes: > Is it OK to commit this as-is (with just the guile-json change you > suggested above)? Here's an updated patch which contains the guile-json change. =2D-=20 Chris --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0006-system-Add-guix-system-docker-image-command.patch Content-Transfer-Encoding: quoted-printable From=2035f930186bcdc7863ac6ce19b0dba428b3cfab3a Mon Sep 17 00:00:00 2001 From: Chris Marusich Date: Mon, 19 Feb 2018 05:45:03 +0100 Subject: [PATCH 6/7] system: Add "guix system docker-image" command. * gnu/system/vm.scm (system-docker-image): New procedure. * guix/scripts/system.scm (system-derivation-for-action): Add a case for docker-image, and in that case, call system-docker-image. (show-help): Document docker-image. (guix-system): Parse arguments for docker-image. * doc/guix.texi (Invoking guix system): Document "guix system docker-image". * gnu/system/examples/docker-image.tmpl: New file. =2D-- doc/guix.texi | 36 ++++++++++-- gnu/system/examples/docker-image.tmpl | 47 +++++++++++++++ gnu/system/vm.scm | 105 ++++++++++++++++++++++++++++++= ++++ guix/scripts/system.scm | 12 ++-- 4 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 gnu/system/examples/docker-image.tmpl diff --git a/doc/guix.texi b/doc/guix.texi index 792539a12..8d38c3d4a 100644 =2D-- a/doc/guix.texi +++ b/doc/guix.texi @@ -20361,12 +20361,18 @@ containing at least the kernel, initrd, and bootl= oader data files must be created. The @code{--image-size} option can be used to specify the size of the image. =20 +@cindex System images, creation in various formats +@cindex Creating system images in various formats @item vm-image @itemx disk-image =2DReturn a virtual machine or disk image of the operating system declared =2Din @var{file} that stands alone. By default, @command{guix system} =2Destimates the size of the image needed to store the system, but you can =2Duse the @option{--image-size} option to specify a value. +@itemx docker-image +Return a virtual machine, disk image, or Docker image of the operating +system declared in @var{file} that stands alone. By default, +@command{guix system} estimates the size of the image needed to store +the system, but you can use the @option{--image-size} option to specify +a value. Docker images are built to contain exactly what they need, so +the @option{--image-size} option is ignored in the case of +@code{docker-image}. =20 You can specify the root file system type by using the @option{--file-system-type} option. It defaults to @code{ext4}. @@ -20384,6 +20390,28 @@ using the following command: # dd if=3D$(guix system disk-image my-os.scm) of=3D/dev/sdc @end example =20 +When using @code{docker-image}, a Docker image is produced. Guix builds +the image from scratch, not from a pre-existing Docker base image. As a +result, it contains @emph{exactly} what you define in the operating +system configuration file. You can then load the image and launch a +Docker container using commands like the following: + +@example +image_id=3D"$(docker load < guixsd-docker-image.tar.gz)" +docker run -e GUIX_NEW_SYSTEM=3D/var/guix/profiles/system \\ + --entrypoint /var/guix/profiles/system/profile/bin/guile \\ + $image_id /var/guix/profiles/system/boot +@end example + +This command starts a new Docker container from the specified image. It +will boot the GuixSD system in the usual manner, which means it will +start any services you have defined in the operating system +configuration. Depending on what you run in the Docker container, it +may be necessary to give the container additional permissions. For +example, if you intend to build software using Guix inside of the Docker +container, you may need to pass the @option{--privileged} option to +@code{docker run}. + @item container Return a script to run the operating system declared in @var{file} within a container. Containers are a set of lightweight isolation diff --git a/gnu/system/examples/docker-image.tmpl b/gnu/system/examples/do= cker-image.tmpl new file mode 100644 index 000000000..d73187398 =2D-- /dev/null +++ b/gnu/system/examples/docker-image.tmpl @@ -0,0 +1,47 @@ +;; This is an operating system configuration template for a "Docker image" +;; setup, so it has barely any services at all. + +(use-modules (gnu)) + +(operating-system + (host-name "komputilo") + (timezone "Europe/Berlin") + (locale "en_US.utf8") + + ;; This is where user accounts are specified. The "root" account is + ;; implicit, and is initially created with the empty password. + (users (cons (user-account + (name "alice") + (comment "Bob's sister") + (group "users") + (supplementary-groups '("wheel" + "audio" "video")) + (home-directory "/home/alice")) + %base-user-accounts)) + + ;; Globally-installed packages. + (packages %base-packages) + + ;; Because the system will run in a Docker container, we may omit many + ;; things that would normally be required in an operating system + ;; configuration file. These things include: + ;; + ;; * bootloader + ;; * file-systems + ;; * services such as mingetty, udevd, slim, networking, dhcp + ;; + ;; Either these things are simply not required, or Docker provides + ;; similar services for us. + + ;; This will be ignored. + (bootloader (bootloader-configuration + (bootloader grub-bootloader) + (target "does-not-matter"))) + ;; This will be ignored, too. + (file-systems (list (file-system + (device "does-not-matter") + (mount-point "/") + (type "does-not-matter")))) + + ;; Guix is all you need! + (services (list (guix-service)))) diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm index d239fa56a..af49065f3 100644 =2D-- a/gnu/system/vm.scm +++ b/gnu/system/vm.scm @@ -23,6 +23,7 @@ =20 (define-module (gnu system vm) #:use-module (guix config) + #:use-module (guix docker) #:use-module (guix store) #:use-module (guix gexp) #:use-module (guix derivations) @@ -30,6 +31,7 @@ #:use-module (guix monads) #:use-module (guix records) #:use-module (guix modules) + #:use-module (guix scripts pack) #:use-module (guix utils) #:use-module (guix hash) #:use-module (guix base32) @@ -39,7 +41,9 @@ #:use-module (gnu packages base) #:use-module (gnu packages bootloaders) #:use-module (gnu packages cdrom) + #:use-module (gnu packages compression) #:use-module (gnu packages guile) + #:autoload (gnu packages gnupg) (libgcrypt) #:use-module (gnu packages gawk) #:use-module (gnu packages bash) #:use-module (gnu packages less) @@ -76,6 +80,7 @@ system-qemu-image/shared-store system-qemu-image/shared-store-script system-disk-image + system-docker-image =20 virtual-machine virtual-machine?)) @@ -376,6 +381,106 @@ the image." #:disk-image-format disk-image-format #:references-graphs inputs)) =20 +(define* (system-docker-image os + #:key + (name "guixsd-docker-image") + register-closures?) + "Build a docker image. OS is the desired . NAME is t= he +base name to use for the output file. When REGISTER-CLOSURES? is not #f, +register the closure of OS with Guix in the resulting Docker image. This = only +makes sense when you want to build a GuixSD Docker image that has Guix +installed inside of it. If you don't need Guix (e.g., your GuixSD Docker +image just contains a web server that is started by the Shepherd), then you +should set REGISTER-CLOSURES? to #f." + (define not-config? + (match-lambda + (('guix 'config) #f) + (('guix rest ...) #t) + (('gnu rest ...) #t) + (rest #f))) + + (define config + ;; (guix config) module for consumption by (guix gcrypt). + (scheme-file "gcrypt-config.scm" + #~(begin + (define-module (guix config) + #:export (%libgcrypt)) + + ;; XXX: Work around . + (eval-when (expand load eval) + (define %libgcrypt + #+(file-append libgcrypt "/lib/libgcrypt")))))) + (mlet %store-monad ((os-drv (operating-system-derivation os #:container?= #t)) + (name -> (string-append name ".tar.gz")) + (graph -> "system-graph")) + (define build + (with-imported-modules `(,@(source-module-closure '((guix docker) + (guix build util= s) + (gnu build vm)) + #:select? not-conf= ig?) + (guix build store-copy) + ((guix config) =3D> ,config)) + #~(begin + ;; Guile-JSON is required by (guix docker). + (add-to-load-path + (string-append #+guile-json "/share/guile/site/" + (effective-version))) + (use-modules (guix docker) + (guix build utils) + (gnu build vm) + (srfi srfi-19) + (guix build store-copy)) + + (let* ((inputs '#$(append (list tar) + (if register-closures? + (list guix) + '()))) + ;; This initializer requires elevated privileges that a= re + ;; not normally available in the build environment (e.g= ., + ;; it needs to create device nodes). In order to obtain + ;; such privileges, we run it as root in a VM. + (initialize (root-partition-initializer + #:closures '(#$graph) + #:register-closures? #$register-closures? + #:system-directory #$os-drv + ;; De-duplication would fail due to + ;; cross-device link errors, so don't do i= t. + #:deduplicate? #f)) + ;; Even as root in a VM, the initializer would fail due= to + ;; lack of privileges if we use a root-directory that i= s on + ;; a file system that is shared with the host (e.g., /t= mp). + (root-directory "/guixsd-system-root")) + (set-path-environment-variable "PATH" '("bin" "sbin") inputs) + (mkdir root-directory) + (initialize root-directory) + (build-docker-image + (string-append "/xchg/" #$name) ;; The output file. + (cons* root-directory + (call-with-input-file (string-append "/xchg/" #$grap= h) + read-reference-graph)) + #$os-drv + #:compressor '(#+(file-append gzip "/bin/gzip") "-9n") + #:creation-time (make-time time-utc 0 1) + #:transformations `((,root-directory -> ""))))))) + (expression->derivation-in-linux-vm + name + ;; The VM's initrd Guile doesn't support dlopen, but our "build" gexp + ;; needs to be run by a Guile that can dlopen libgcrypt. The followi= ng + ;; hack works around that problem by putting the "build" gexp into an + ;; executable script (created by program-file) which, when executed, = will + ;; run using a Guile that supports dlopen. That way, the VM's initrd + ;; Guile can just execute it via invoke, without using dlopen. See: + ;; https://lists.gnu.org/archive/html/guix-devel/2017-10/msg00233.html + (with-imported-modules `((guix build utils)) + #~(begin + (use-modules (guix build utils)) + ;; If we use execl instead of invoke here, the VM will crash wi= th a + ;; kernel panic. + (invoke #$(program-file "build-docker-image" build)))) + #:make-disk-image? #f + #:single-file-output? #t + #:references-graphs `((,graph ,os-drv))))) + ;;; ;;; VM and disk images. diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index acfccce96..09f99b300 100644 =2D-- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2014, 2015, 2016, 2017, 2018 Ludovic Court=C3=A8s ;;; Copyright =C2=A9 2016 Alex Kost =2D;;; Copyright =C2=A9 2016, 2017 Chris Marusich +;;; Copyright =C2=A9 2016, 2017, 2018 Chris Marusich ;;; Copyright =C2=A9 2017 Mathieu Othacehe ;;; ;;; This file is part of GNU Guix. @@ -701,7 +701,9 @@ checking this by themselves in their 'check' procedure." ("iso9660" "image.iso") (_ "disk-image")) #:disk-image-size image-size =2D #:file-system-type file-system-type)))) + #:file-system-type file-system-type)) + ((docker-image) + (system-docker-image os #:register-closures? #t)))) =20 (define (maybe-suggest-running-guix-pull) "Suggest running 'guix pull' if this has never been done before." @@ -899,6 +901,8 @@ Some ACTIONS support additional ARGS.\n")) vm-image build a freestanding virtual machine image\n")) (display (G_ "\ disk-image build a disk image, suitable for a USB stick\n")) + (display (G_ "\ + docker-image build a Docker image\n")) (display (G_ "\ init initialize a root file system to run GNU\n")) (display (G_ "\ @@ -1130,7 +1134,7 @@ argument list and OPTS is the option alist." (case action ((build container vm vm-image disk-image reconfigure init extension-graph shepherd-graph list-generations roll-back =2D switch-generation search) + switch-generation search docker-image) (alist-cons 'action action result)) (else (leave (G_ "~a: unknown action~%") action)))))) =20 @@ -1159,7 +1163,7 @@ argument list and OPTS is the option alist." (exit 1)) =20 (case action =2D ((build container vm vm-image disk-image reconfigure) + ((build container vm vm-image disk-image docker-image reconfigure) (unless (or (=3D count 1) (and expr (=3D count 0))) (fail))) =2D-=20 2.15.1 --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEy/WXVcvn5+/vGD+x3UCaFdgiRp0FAlqx3rcACgkQ3UCaFdgi Rp0KQxAAmRGdxpnZx5SqeI//vEhuP9PzgDunZCLX7QvIhiNUKjS9OoQHv76l/naT 5bXh1CXzNpDhCF69eiDaYTprktPXZ1/fKOCZB/5YXT5NqtCPkWvwTNlmbFosaboW 93OwA2jdijEkUS18haVKIV+o+pQZ1DILShlL5nE24N4rijskc7UejDy8+7haDjpn HJl0Ye2UmnRBEowitejH+YRQbQ3K/jOUVoEnO0VMtwYXyedInrlnxe1OWFF96cQE Csf541B8PASdDQ3kvhYXderDlBCGExvWuR3J450d9u7kmdOXRZIrGPMWclavN9mn vv2KEEYRmRhgNgQH3O+2ccNpY+7J9clH38owwrY1jiy75Y6oKlhisPATlKIUvRxb pxVau/IjJBn2yuJwbBE0GwG4whE2ZcAZRAKhAYUqnHuquYSN+oR+kEnRzVcMk5iS q5j4AJ2gulWgcsFHf5uhGvcbIRp7mM1z4GzwXzwINWRdC/GTlu1DIBtyomQWVoAz 8hCAE3riAdPnAizwixwDqPnQvygHWTmuonUEd35sJr0CT5KBI6exmDAjuethhkF4 nkZvnyf2neGXig3Whq5V9M8DPOe15KifM2EUyi4LoKn9ouTauvPMtHkVGVsfcbKA QLI/7uPmpBh6YSAOc0kkNaFsmp5xpvAd2h7aXOkXX7J5qjUDlbc= =Bwaa -----END PGP SIGNATURE----- --==-=-=--