system: Make /run/current-system at activation time.

* gnu/system.scm (etc-directory): Change default value of #:profile.
  Change contents of SHELLS.  Use /run/current-system/profile/{s,}bin in
  BASHRC.
  (operating-system-boot-script)[%modules]: Add (guix build
  linux-initrd).  Add call to 'activate-current-system' in gexp.
  (operating-system-initrd-file, operating-system-grub.cfg): New
  procedures.
  (operating-system-derivation): Don't build grub.cfg here and remove it
  from the file union.
* gnu/system/vm.scm (qemu-image): Remove #:populate.
  (operating-system-build-gid, operating-system-default-contents):
  Remove.
  (system-qemu-image): Remove call to
  'operating-system-default-contents'.  Use 'operating-system-grub.cfg'
  to get grub.cfg.  Add GRUB.CFG to #:inputs.
  (system-qemu-image/shared-store): Likewise, but don't add GRUB.CFG to
  #:inputs.
  (system-qemu-image/shared-store-script): Pass --system kernel option.
* guix/build/activation.scm (%booted-system, %current-system): New
  variables.
  (boot-time-system, activate-current-system): New procedures.
* guix/build/install.scm (evaluate-populate-directive): Add case
  for ('directory name uid gid mode).
  (directives, populate-root-file-system): New procedures.
* guix/build/vm.scm (initialize-hard-disk): Replace calls to
  'evaluate-populate-directive' by a call to
  'populate-root-file-system'.
* gnu/services/dmd.scm (dmd-configuration-file): Use
  /run/current-system/profile/bin.
* gnu/services/xorg.scm (slim-service): Likewise.
This commit is contained in:
Ludovic Courtès 2014-05-17 17:39:30 +02:00
parent bf43449ace
commit b4140694ac
7 changed files with 118 additions and 87 deletions

View file

@ -64,7 +64,7 @@ (define config
services)) services))
;; guix-daemon 0.6 aborts if 'PATH' is undefined, so work around it. ;; guix-daemon 0.6 aborts if 'PATH' is undefined, so work around it.
(setenv "PATH" "/run/current-system/bin") (setenv "PATH" "/run/current-system/profile/bin")
(format #t "starting services...~%") (format #t "starting services...~%")
(for-each start '#$(append-map service-provision services)))) (for-each start '#$(append-map service-provision services))))

View file

@ -139,7 +139,7 @@ (define (slim.cfg)
(mlet %store-monad ((startx (or startx (xorg-start-command))) (mlet %store-monad ((startx (or startx (xorg-start-command)))
(xinitrc (xinitrc))) (xinitrc (xinitrc)))
(text-file* "slim.cfg" " (text-file* "slim.cfg" "
default_path /run/current-system/bin default_path /run/current-system/profile/bin
default_xserver " startx " default_xserver " startx "
xserver_arguments :0 vt7 xserver_arguments :0 vt7
xauth_path " xauth "/bin/xauth xauth_path " xauth "/bin/xauth

View file

@ -55,6 +55,7 @@ (define-module (gnu system)
operating-system-derivation operating-system-derivation
operating-system-profile operating-system-profile
operating-system-grub.cfg
<file-system> <file-system>
file-system file-system
@ -263,7 +264,7 @@ (define* (etc-directory #:key
(locale "C") (timezone "Europe/Paris") (locale "C") (timezone "Europe/Paris")
(skeletons '()) (skeletons '())
(pam-services '()) (pam-services '())
(profile "/var/run/current-system/profile") (profile "/run/current-system/profile")
(sudoers "")) (sudoers ""))
"Return a derivation that builds the static part of the /etc directory." "Return a derivation that builds the static part of the /etc directory."
(mlet* %store-monad (mlet* %store-monad
@ -273,8 +274,8 @@ (define* (etc-directory #:key
(shells (text-file "shells" ; used by xterm and others (shells (text-file "shells" ; used by xterm and others
"\ "\
/bin/sh /bin/sh
/run/current-system/bin/sh /run/current-system/profile/bin/sh
/run/current-system/bin/bash\n")) /run/current-system/profile/bin/bash\n"))
(issue (text-file "issue" " (issue (text-file "issue" "
This is an alpha preview of the GNU system. Welcome. This is an alpha preview of the GNU system. Welcome.
@ -293,8 +294,8 @@ (define* (etc-directory #:key
export TZ=\"" timezone "\" export TZ=\"" timezone "\"
export TZDIR=\"" tzdata "/share/zoneinfo\" export TZDIR=\"" tzdata "/share/zoneinfo\"
export PATH=$HOME/.guix-profile/bin:" profile "/bin:" profile "/sbin export PATH=/run/setuid-programs:/run/current-system/profile/sbin
export PATH=/run/setuid-programs:$PATH export PATH=$HOME/.guix-profile/bin:/run/current-system/profile/bin:$PATH
export CPATH=$HOME/.guix-profile/include:" profile "/include export CPATH=$HOME/.guix-profile/include:" profile "/include
export LIBRARY_PATH=$HOME/.guix-profile/lib:" profile "/lib export LIBRARY_PATH=$HOME/.guix-profile/lib:" profile "/lib
alias ls='ls -p --color' alias ls='ls -p --color'
@ -402,7 +403,8 @@ (define (operating-system-boot-script os)
we're running in the final root." we're running in the final root."
(define %modules (define %modules
'((guix build activation) '((guix build activation)
(guix build utils))) (guix build utils)
(guix build linux-initrd)))
(mlet* %store-monad ((services (operating-system-services os)) (mlet* %store-monad ((services (operating-system-services os))
(etc (operating-system-etc-directory os)) (etc (operating-system-etc-directory os))
@ -446,6 +448,9 @@ (define group-specs
;; Activate setuid programs. ;; Activate setuid programs.
(activate-setuid-programs (list #$@setuid-progs)) (activate-setuid-programs (list #$@setuid-progs))
;; Set up /run/current-system.
(activate-current-system #:boot? #t)
;; Close any remaining open file descriptors to be on the ;; Close any remaining open file descriptors to be on the
;; safe side. This must be the very last thing we do, ;; safe side. This must be the very last thing we do,
;; because Guile has internal FDs such as 'sleep_pipe' ;; because Guile has internal FDs such as 'sleep_pipe'
@ -466,8 +471,8 @@ (define (operating-system-root-file-system os)
(_ #f)) (_ #f))
(operating-system-file-systems os))) (operating-system-file-systems os)))
(define (operating-system-derivation os) (define (operating-system-initrd-file os)
"Return a derivation that builds OS." "Return a gexp denoting the initrd file of OS."
(define boot-file-systems (define boot-file-systems
(filter (match-lambda (filter (match-lambda
(($ <file-system> device "/") (($ <file-system> device "/")
@ -476,15 +481,16 @@ (define boot-file-systems
boot?)) boot?))
(operating-system-file-systems os))) (operating-system-file-systems os)))
(mlet %store-monad
((initrd ((operating-system-initrd os) boot-file-systems)))
(return #~(string-append #$initrd "/initrd"))))
(define (operating-system-grub.cfg os)
"Return the GRUB configuration file for OS."
(mlet* %store-monad (mlet* %store-monad
((profile (operating-system-profile os)) ((system (operating-system-derivation os))
(etc (operating-system-etc-directory os))
(services (operating-system-services os))
(boot (operating-system-boot-script os))
(kernel -> (operating-system-kernel os))
(initrd ((operating-system-initrd os) boot-file-systems))
(initrd-file -> #~(string-append #$initrd "/initrd"))
(root-fs -> (operating-system-root-file-system os)) (root-fs -> (operating-system-root-file-system os))
(kernel -> (operating-system-kernel os))
(entries -> (list (menu-entry (entries -> (list (menu-entry
(label (string-append (label (string-append
"GNU system with " "GNU system with "
@ -494,15 +500,25 @@ (define boot-file-systems
(linux-arguments (linux-arguments
(list (string-append "--root=" (list (string-append "--root="
(file-system-device root-fs)) (file-system-device root-fs))
#~(string-append "--load=" #$boot))) #~(string-append "--system=" #$system)
(initrd initrd-file)))) #~(string-append "--load=" #$system
(grub.cfg (grub-configuration-file entries))) "/boot")))
(initrd #~(string-append #$system "/initrd"))))))
(grub-configuration-file entries)))
(define (operating-system-derivation os)
"Return a derivation that builds OS."
(mlet* %store-monad
((profile (operating-system-profile os))
(etc (operating-system-etc-directory os))
(boot (operating-system-boot-script os))
(kernel -> (operating-system-kernel os))
(initrd (operating-system-initrd-file os)))
(file-union "system" (file-union "system"
`(("boot" ,#~#$boot) `(("boot" ,#~#$boot)
("kernel" ,#~#$kernel) ("kernel" ,#~#$kernel)
("initrd" ,initrd-file) ("initrd" ,initrd)
("profile" ,#~#$profile) ("profile" ,#~#$profile)
("grub.cfg" ,#~#$grub.cfg)
("etc" ,#~#$etc))))) ("etc" ,#~#$etc)))))
;;; system.scm ends here ;;; system.scm ends here

View file

@ -192,7 +192,6 @@ (define* (qemu-image #:key
(file-system-type "ext4") (file-system-type "ext4")
grub-configuration grub-configuration
(register-closures? #t) (register-closures? #t)
(populate #f)
(inputs '()) (inputs '())
copy-inputs?) copy-inputs?)
"Return a bootable, stand-alone QEMU image, with a root partition of type "Return a bootable, stand-alone QEMU image, with a root partition of type
@ -203,12 +202,7 @@ (define* (qemu-image #:key
INPUTS is a list of inputs (as for packages). When COPY-INPUTS? is true, copy INPUTS is a list of inputs (as for packages). When COPY-INPUTS? is true, copy
all of INPUTS into the image being built. When REGISTER-CLOSURES? is true, all of INPUTS into the image being built. When REGISTER-CLOSURES? is true,
register INPUTS in the store database of the image so that Guix can be used in register INPUTS in the store database of the image so that Guix can be used in
the image. the image."
POPULATE is a list of directives stating directories or symlinks to be created
in the disk image partition. It is evaluated once the image has been
populated with INPUTS-TO-COPY. It can be used to provide additional files,
such as /etc files."
(mlet %store-monad (mlet %store-monad
((graph (sequence %store-monad (map input->name+output inputs)))) ((graph (sequence %store-monad (map input->name+output inputs))))
(expression->derivation-in-linux-vm (expression->derivation-in-linux-vm
@ -241,8 +235,7 @@ (define* (qemu-image #:key
#:copy-closures? #$copy-inputs? #:copy-closures? #$copy-inputs?
#:register-closures? #$register-closures? #:register-closures? #$register-closures?
#:disk-image-size #$disk-image-size #:disk-image-size #$disk-image-size
#:file-system-type #$file-system-type #:file-system-type #$file-system-type)
#:directives '#$populate)
(reboot)))) (reboot))))
#:system system #:system system
#:make-disk-image? #t #:make-disk-image? #t
@ -254,39 +247,6 @@ (define* (qemu-image #:key
;;; Stand-alone VM image. ;;; Stand-alone VM image.
;;; ;;;
(define (operating-system-build-gid os)
"Return as a monadic value the group id for build users of OS, or #f."
(mlet %store-monad ((services (operating-system-services os)))
(return (any (lambda (service)
(and (equal? '(guix-daemon)
(service-provision service))
(match (service-user-groups service)
((group)
(user-group-id group)))))
services))))
(define (operating-system-default-contents os)
"Return a list of directives suitable for 'system-qemu-image' describing the
basic contents of the root file system of OS."
(mlet* %store-monad ((os-drv (operating-system-derivation os))
(build-gid (operating-system-build-gid os))
(profile (operating-system-profile os)))
(return #~((directory #$(%store-prefix) 0 #$(or build-gid 0))
(directory "/etc")
(directory "/var/log") ; for dmd
(directory "/var/run/nscd")
(directory "/var/guix/gcroots")
("/var/guix/gcroots/system" -> #$os-drv)
(directory "/run")
("/run/current-system" -> #$profile)
(directory "/bin")
("/bin/sh" -> "/run/current-system/bin/bash")
(directory "/tmp")
(directory "/var/guix/profiles/per-user/root" 0 0)
(directory "/root" 0 0) ; an exception
(directory "/home" 0 0)))))
(define* (system-qemu-image os (define* (system-qemu-image os
#:key #:key
(file-system-type "ext4") (file-system-type "ext4")
@ -312,14 +272,12 @@ (define file-systems-to-keep
file-systems-to-keep))))) file-systems-to-keep)))))
(mlet* %store-monad (mlet* %store-monad
((os-drv (operating-system-derivation os)) ((os-drv (operating-system-derivation os))
(os-dir -> (derivation->output-path os-drv)) (grub.cfg (operating-system-grub.cfg os)))
(grub.cfg -> (string-append os-dir "/grub.cfg"))
(populate (operating-system-default-contents os)))
(qemu-image #:grub-configuration grub.cfg (qemu-image #:grub-configuration grub.cfg
#:populate populate
#:disk-image-size disk-image-size #:disk-image-size disk-image-size
#:file-system-type file-system-type #:file-system-type file-system-type
#:inputs `(("system" ,os-drv)) #:inputs `(("system" ,os-drv)
("grub.cfg" ,grub.cfg))
#:copy-inputs? #t)))) #:copy-inputs? #t))))
(define (virtualized-operating-system os) (define (virtualized-operating-system os)
@ -356,11 +314,8 @@ (define* (system-qemu-image/shared-store
with the host." with the host."
(mlet* %store-monad (mlet* %store-monad
((os-drv (operating-system-derivation os)) ((os-drv (operating-system-derivation os))
(os-dir -> (derivation->output-path os-drv)) (grub.cfg (operating-system-grub.cfg os)))
(grub.cfg -> (string-append os-dir "/grub.cfg"))
(populate (operating-system-default-contents os)))
(qemu-image #:grub-configuration grub.cfg (qemu-image #:grub-configuration grub.cfg
#:populate populate
#:disk-image-size disk-image-size #:disk-image-size disk-image-size
#:inputs `(("system" ,os-drv)) #:inputs `(("system" ,os-drv))
@ -390,7 +345,7 @@ (define builder
-kernel " #$(operating-system-kernel os) "/bzImage \ -kernel " #$(operating-system-kernel os) "/bzImage \
-initrd " #$os-drv "/initrd \ -initrd " #$os-drv "/initrd \
-append \"" #$(if graphic? "" "console=ttyS0 ") -append \"" #$(if graphic? "" "console=ttyS0 ")
"--load=" #$os-drv "/boot --root=/dev/vda1\" \ "--system=" #$os-drv " --load=" #$os-drv "/boot --root=/dev/vda1\" \
-serial stdio \ -serial stdio \
-drive file=" #$image -drive file=" #$image
",if=virtio,cache=writeback,werror=report,readonly\n") ",if=virtio,cache=writeback,werror=report,readonly\n")

View file

@ -18,13 +18,15 @@
(define-module (guix build activation) (define-module (guix build activation)
#:use-module (guix build utils) #:use-module (guix build utils)
#:use-module (guix build linux-initrd)
#:use-module (ice-9 ftw) #:use-module (ice-9 ftw)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-26) #:use-module (srfi srfi-26)
#:export (activate-users+groups #:export (activate-users+groups
activate-etc activate-etc
activate-setuid-programs)) activate-setuid-programs
activate-current-system))
;;; Commentary: ;;; Commentary:
;;; ;;;
@ -195,4 +197,33 @@ (define (make-setuid-program prog)
(for-each make-setuid-program programs)) (for-each make-setuid-program programs))
(define %booted-system
;; The system we booted in (a symlink.)
"/run/booted-system")
(define %current-system
;; The system that is current (a symlink.) This is not necessarily the same
;; as %BOOTED-SYSTEM, for instance because we can re-build a new system
;; configuration and activate it, without rebooting.
"/run/current-system")
(define (boot-time-system)
"Return the '--system' argument passed on the kernel command line."
(find-long-option "--system" (linux-command-line)))
(define* (activate-current-system #:optional (system (boot-time-system))
#:key boot?)
"Atomically make SYSTEM the current system. When BOOT? is true, also make
it the booted system."
(format #t "making '~a' the current system...~%" system)
(when boot?
(when (file-exists? %booted-system)
(delete-file %booted-system))
(symlink system %booted-system))
;; Atomically make SYSTEM current.
(let ((new (string-append %current-system ".new")))
(symlink system new)
(rename-file new %current-system)))
;;; activation.scm ends here ;;; activation.scm ends here

View file

@ -19,9 +19,10 @@
(define-module (guix build install) (define-module (guix build install)
#:use-module (guix build utils) #:use-module (guix build utils)
#:use-module (guix build install) #:use-module (guix build install)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:export (install-grub #:export (install-grub
evaluate-populate-directive populate-root-file-system
reset-timestamps reset-timestamps
register-closure)) register-closure))
@ -46,6 +47,7 @@ (define* (install-grub grub.cfg device mount-point)
(define (evaluate-populate-directive directive target) (define (evaluate-populate-directive directive target)
"Evaluate DIRECTIVE, an sexp describing a file or directory to create under "Evaluate DIRECTIVE, an sexp describing a file or directory to create under
directory TARGET." directory TARGET."
(let loop ((directive directive))
(match directive (match directive
(('directory name) (('directory name)
(mkdir-p (string-append target name))) (mkdir-p (string-append target name)))
@ -53,8 +55,36 @@ (define (evaluate-populate-directive directive target)
(let ((dir (string-append target name))) (let ((dir (string-append target name)))
(mkdir-p dir) (mkdir-p dir)
(chown dir uid gid))) (chown dir uid gid)))
(('directory name uid gid mode)
(loop `(directory ,name ,uid ,gid))
(chmod (string-append target name) mode))
((new '-> old) ((new '-> old)
(symlink old (string-append target new))))) (symlink old (string-append target new))))))
(define (directives store)
"Return a list of directives to populate the root file system that will host
STORE."
`((directory ,store 0 0)
(directory "/etc")
(directory "/var/log") ; for dmd
(directory "/var/run/nscd")
(directory "/var/guix/gcroots")
(directory "/run")
("/var/guix/gcroots/booted-system" -> "/run/booted-system")
("/var/guix/gcroots/current-system" -> "/run/current-system")
(directory "/bin")
("/bin/sh" -> "/run/current-system/profile/bin/bash")
(directory "/tmp" 0 0 #o1777) ; sticky bit
(directory "/var/guix/profiles/per-user/root" 0 0)
(directory "/root" 0 0) ; an exception
(directory "/home" 0 0)))
(define (populate-root-file-system target)
"Make the essential non-store files and directories on TARGET. This
includes /etc, /var, /run, /bin/sh, etc."
(for-each (cut evaluate-populate-directive <> target)
(directives (%store-directory))))
(define (reset-timestamps directory) (define (reset-timestamps directory)
"Reset the timestamps of all the files under DIRECTORY, so that they appear "Reset the timestamps of all the files under DIRECTORY, so that they appear

View file

@ -206,8 +206,7 @@ (define target-store
;; Evaluate the POPULATE directives. ;; Evaluate the POPULATE directives.
(display "populating...\n") (display "populating...\n")
(for-each (cut evaluate-populate-directive <> target-directory) (populate-root-file-system target-directory)
directives)
(unless (install-grub grub.cfg "/dev/sda" target-directory) (unless (install-grub grub.cfg "/dev/sda" target-directory)
(error "failed to install GRUB")) (error "failed to install GRUB"))