Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23...

45
Code Staging in GNU Guix Ludovic Court ` es GPCE 23 October 2017, Vancouver, Canada

Transcript of Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23...

Page 1: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Code Staging in GNU Guix

Ludovic Courtes

GPCE23 October 2017, Vancouver, Canada

Page 2: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Functional software deployment.

Page 3: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

$ guix package -i emacs ocaml idris ghc

...

$ guix package -r emacs -i vim

...

$ guix package --roll-back

...

Page 4: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

$ guix package -i emacs ocaml idris ghc

...

$ guix package -r emacs -i vim

...

$ guix package --roll-back

...

Page 5: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

(operating-system

(host-name "gastown")

(timezone "Canada/Pacific")

(locale "fr_CA.utf8")

(bootloader (grub-configuration (device "/dev/sda")))

(file-systems (cons (file-system

(device "my-root")

(title ’label)

(mount-point "/")

(type "ext4"))

%base-file-systems))

(users (cons (user-account

(name "alice")

(group "users")

(home-directory "/home/alice"))

%base-user-accounts))

(services (cons (service openssh-service-type)

%base-services)))

Page 6: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

$ guix system vm config.scm

...

$ guix system reconfigure config.scm

...

$ guix system roll-back

...

Page 7: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Functional software deployment paradigm:

1. build process = pure function2. built software = persistent graph

Imposing a Memory Management Discipline on Software Deployment, Dolstra et al., 2004(Nix package manager)

Page 8: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

(define hello

(package

(name "hello")

(version "2.10")

(source (origin

(method url-fetch)

(uri (string-append "https://ftp.gnu.org/.../hello-"version ".tar.gz"))

(sha256 (base32 "0wqd...dz6"))))(build-system gnu-build-system)

(synopsis "An example GNU package")

(description "Produce a friendly greeting.")

(home-page "https://gnu.org/software/hello/")

(license gpl3+)))

Functional Package Management with Guix, Courtes, 2013

Page 9: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

$ guix build hello

/gnu/store/ sp4wxa09zxfcs4vchm6as014msa5yi22 -hello-2.10

Page 10: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

$ guix build hello

/gnu/store/ sp4wxa09zxfcs4vchm6as014msa5yi22 -hello-2.10

hash of all the dependencies;

Page 11: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

build processeschroot, separate UIDs

Gui

le,m

ake,

etc.

Gui

le,m

ake,

etc.

Gui

le,m

ake,

etc. Guile Scheme

(define hello (package ...))

build daemon

Page 12: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

build processeschroot, separate UIDs

Gui

le,m

ake,

etc.

Gui

le,m

ake,

etc.

Gui

le,m

ake,

etc. Guile Scheme

(define hello (package ...))

build daemonRPCs

Page 13: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

build processeschroot, separate UIDs

Gui

le,m

ake,

etc.

Gui

le,m

ake,

etc.

Gui

le,m

ake,

etc. Guile Scheme

(define hello (package ...))

build daemonRPCs

Page 14: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Code staging.

Page 15: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Staging: take #1(define build-exp

;; Build-side code.

’(symlink "/gnu/store/123...-coreutils-8.25""/gnu/store/abc...-result"))

;; ... with unhygienic global variable:

;; (define %build-inputs

;; ’())

(define inputs

;; What goes into the chroot.

‘(("coreutils" ,coreutils)))

(build-expression->derivation store "symlink-to-coreutils"

build-exp

#:inputs inputs

)

Page 16: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Staging: take #1(define build-exp

;; Build-side code.

’(symlink (assoc-ref %build-inputs "coreutils")

%output))

;; ... with unhygienic global variable:

;; (define %build-inputs

;; ’(("coreutils" . "/gnu/store/...-coreutils-8.25")))

(define inputs

;; What goes into the chroot.

‘(("coreutils" ,coreutils)))

(build-expression->derivation store "symlink-to-coreutils"

build-exp

#:inputs inputs)

Page 17: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Staging: take #1(define build-exp

;; Build-side code.

’(symlink (assoc-ref %build-inputs "coreutils")

%output))

;; ... with unhygienic global variable:

;; (define %build-inputs

;; ’())

(define inputs

;; What goes into the chroot.

‘(("coreutils" ,coreutils)))

(build-expression->derivation store "symlink-to-coreutils"

build-exp

#:inputs inputs

)

Page 18: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

I Nix: generates Bash code through string interpolationI Writing Hygienic Macros in Scheme with Syntax-Case,

(Dybvig, 1992)I A Multi-Tier Semantics for Hop (Serrano & Queinnec,

2010)

Page 19: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Take #2: G-expressions

(define build-exp

;; First-class object that carries info

;; about its dependencies.

(gexp (symlink (ungexp coreutils)

(ungexp output))))

;; Leads to a build script like:

;; (symlink "/gnu/store/123...-coreutils-8.25";; (getenv "out"))

(gexp->derivation "symlink-to-coreutils" build-exp)

Page 20: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Take #2: G-expressions

(define build-exp

;; First-class object that carries info

;; about its dependencies.

#~(symlink #$coreutils #$output))

;; Leads to a build script like:

;; (symlink "/gnu/store/123...-coreutils-8.25";; (getenv "out"))

(gexp->derivation "symlink-to-coreutils" build-exp)

Page 21: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Take #2: G-expressions

(define build-exp

;; First-class object that carries info

;; about its dependencies.

#~(symlink #$coreutils #$output))

;; Leads to a build script like:

;; (symlink "/gnu/store/h8a...-coreutils-8.25";; (getenv "out"))

(gexp->derivation "symlink-to-coreutils" build-exp

#:system "i686-linux")

Page 22: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Modules

(define build-exp

;; Compile (guix build utils) and add it

;; to the chroot.

(with-imported-modules ’((guix build utils))

#~(begin

(use-modules (guix build utils))

(mkdir-p (string-append #$output "/bin"))

(gexp->derivation "empty-bin-dir" build-exp)

;; ERROR: (guix build utils) not found!

Page 23: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Modules

(define build-exp

;; Compile (guix build utils) and add it

;; to the chroot.

(with-imported-modules ’((guix build utils))

#~(begin

(use-modules (guix build utils))

(mkdir-p (string-append #$output "/bin")))

(gexp->derivation "empty-bin-dir" build-exp)

Page 24: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Initial RAM Disk

(expression->initrd

(with-imported-modules (source-module-closure

’((gnu build linux-boot)

(guix build utils)))

#~(begin

(use-modules (gnu build linux-boot)

(guix build utils))

(boot-system #:mounts ’#$file-systems

#:linux-modules ’#$linux-modules

#:linux-module-directory ’#$kodir)))

Page 25: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Towards More Use Cases...

(eval-remotely #~(system* #$(file-append ffmpeg "/bin/ffmpeg") ...)(open-ssh-session "example.org"))

(eval-in-vm #~(uname) vm)

...

Page 26: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Scope Preservation

(let ((gen-body (lambda (x)

#~(let ((x 40))

(+ x #$x)))))

#~(let ((x 2))

#$(gen-body #~x))

(let ((x-1bd8-0 2))

(let ((x-4f05-0 40))

(+ x-4f05-0 x-1bd8-0)))

Dybvig 1992, Kiselyov 2008, Rhiger 2012

Page 27: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Scope Preservation

(let ((gen-body (lambda (x)

#~(let ((x 40))

(+ x #$x)))))

#~(let ((x 2))

#$(gen-body #~x))

(let ((x-1bd8-0 2))

(let ((x-4f05-0 40))

(+ x-4f05-0 x-1bd8-0)))

Dybvig 1992, Kiselyov 2008, Rhiger 2012

Page 28: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Limitations

I hygiene vs. macro-introduced bindings?I modules in scope?I serialization of non-primitive data types?I cross-stage debugging info a la Hop?

Page 29: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Summary.

Page 30: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

I G-exps tie staging to software deploymentI used at scale in GuixI entirely implemented as a macro

Page 31: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

[email protected] https://gnu.org/software/guix/

Page 32: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Ghost track!

Page 33: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Cross-Compilation(gexp->derivation "vi"

#~(begin

(mkdir #$output)

(system* (string-append #+coreutils "/bin/ln")

"-s"

(string-append #$emacs "/bin/emacs")

(string-append #$output "/bin/vi")))

)

;; Yields:

;; (begin

;; (mkdir (getenv "out"))

;; (system* (string-append "/gnu/store/123..." "/bin/ln")

;; "-s"

;; (string-append "/gnu/store/345..." ...);; (string-append "/gnu/store/567..." ...)))

Page 34: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Cross-Compilation(gexp->derivation "vi"

#~(begin

(mkdir #$output)

(system* (string-append #+coreutils "/bin/ln")

"-s"

(string-append #$emacs "/bin/emacs")

(string-append #$output "/bin/vi")))

#:target "mips64el-linux-gnu")

;; Yields:

;; (begin

;; (mkdir (getenv "out"))

;; (system* (string-append "/gnu/store/123..." "/bin/ln")

;; "-s"

;; (string-append "/gnu/store/9ab..." ...);; (string-append "/gnu/store/fc2..." ...)))

Page 35: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Defining “Compilers”

(define-gexp-compiler (package-compiler (package <package>)

system target)

;; Return a derivation to build PACKAGE.

(if target

(package->cross-derivation package target system)

(package->derivation package system)))

(define-record-type <plain-file>

(plain-file name content)

...)

(define-gexp-compiler (plain-file-compiler (file <plain-file>)

system target)

;; "Compile" FILE by adding it to the store.

(match file

(($ <plain-file> name content)

(text-file name content))))

Page 36: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Defining “Compilers”

(define-gexp-compiler (package-compiler (package <package>)

system target)

;; Return a derivation to build PACKAGE.

(if target

(package->cross-derivation package target system)

(package->derivation package system)))

(define-record-type <plain-file>

(plain-file name content)

...)

(define-gexp-compiler (plain-file-compiler (file <plain-file>)

system target)

;; "Compile" FILE by adding it to the store.

(match file

(($ <plain-file> name content)

(text-file name content))))

Page 37: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Compilers & “Expanders”

#~(string-append #$coreutils "/bin/ls")

;; Yields:

;; (string-append "/gnu/store/..." "/bin/ls")

(file-append coreutils "/bin/ls")

;; Yields:

;; "/gnu/store/.../bin/ls"

Page 38: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Compilers & “Expanders”

#~(string-append #$coreutils "/bin/ls")

;; Yields:

;; (string-append "/gnu/store/..." "/bin/ls")

(file-append coreutils "/bin/ls")

;; Yields:

;; "/gnu/store/.../bin/ls"

Page 39: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Linux-libre

Page 40: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Linux-libre

initial RAM disk

Page 41: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Linux-libre

initial RAM disk Guile

Page 42: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Linux-libre

initial RAM disk

PID 1: GNU Shepherdservices...

Guile

Page 43: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Linux-libre

initial RAM disk

PID 1: GNU Shepherdservices...

Guile

Guile

Page 44: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Linux-libre

initial RAM disk

PID 1: GNU Shepherdservices...

applications

Guile

Guile

Page 45: Code Staging in GNU Guix · 23/10/2017  · Code Staging in GNU Guix Ludovic Courtes` GPCE 23 October 2017, Vancouver, Canada

Copyright c© 2010, 2012–2017 Ludovic Courtes [email protected].

GNU GuixSD logo, CC-BY-SA 4.0, https://gnu.org/s/guix/graphicsCopyright of other images included in this document is held by their respective owners.

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 License. To view a copy of this license, visithttp://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300,San Francisco, California, 94105, USA.

At your option, you may instead copy, distribute and/or modify this document under the terms of the GNU Free DocumentationLicense, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, noFront-Cover Texts, and no Back-Cover Texts. A copy of the license is available at http://www.gnu.org/licenses/gfdl.html.

The source of this document is available from http://git.sv.gnu.org/cgit/guix/maintenance.git.