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 @@
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 @@ When AUTO-LOGIN? is true, log in automatically as DEFAULT-USER."
(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 @@
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 @@ explicitly appear in OS."
(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 @@ explicitly appear in OS."
(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 @@ export LC_ALL=\"" locale "\"
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 @@ alias ll='ls -l'
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 @@ we're running in the final root."
;; 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 @@ we're running in the final root."
(_ #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 @@ we're running in the final root."
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 @@ we're running in the final root."
(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 @@ made available under the /xchg CIFS share."
(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 @@ file (GRUB-CONFIGURATION must be the name of a file in the VM.)
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 @@ such as /etc files."
#: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 @@ such as /etc files."
;;; 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 @@ of the GNU system as described by OS."
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 @@ environment with the store shared with the host."
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 @@ exec " #$qemu "/bin/qemu-system-x86_64 -enable-kvm -no-reboot -net nic,model=vir
-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 @@ numeric gid or #f."
(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,15 +47,44 @@ MOUNT-POINT. Return #t on success."
(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."
(match directive (let loop ((directive directive))
(('directory name) (match directive
(mkdir-p (string-append target name))) (('directory name)
(('directory name uid gid) (mkdir-p (string-append target name)))
(let ((dir (string-append target name))) (('directory name uid gid)
(mkdir-p dir) (let ((dir (string-append target name)))
(chown dir uid gid))) (mkdir-p dir)
((new '-> old) (chown dir uid gid)))
(symlink old (string-append target new))))) (('directory name uid gid mode)
(loop `(directory ,name ,uid ,gid))
(chmod (string-append target name) mode))
((new '-> old)
(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 @@ further populate the partition."
;; 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"))