system: De-monadify 'operating-system-bootcfg'.
[jackhill/guix/guix.git] / gnu / system.scm
index 288c1e8..1766c8f 100644 (file)
 ;;;
 ;;; Code:
 
-(define (bootable-kernel-arguments kernel-arguments system.drv root-device)
-  "Prepend extra arguments to KERNEL-ARGUMENTS that allow SYSTEM.DRV to be
-booted from ROOT-DEVICE"
-  (cons* (string-append "--root="
-                        (cond ((uuid? root-device)
-
-                               ;; Note: Always use the DCE format because that's
-                               ;; what (gnu build linux-boot) expects for the
-                               ;; '--root' kernel command-line option.
-                               (uuid->string (uuid-bytevector root-device)
-                                             'dce))
-                              ((file-system-label? root-device)
-                               (file-system-label->string root-device))
-                              (else root-device)))
-         #~(string-append "--system=" #$system.drv)
-         #~(string-append "--load=" #$system.drv "/boot")
-         kernel-arguments))
+(define (bootable-kernel-arguments system root-device)
+  "Return a list of kernel arguments (gexps) to boot SYSTEM from ROOT-DEVICE."
+  (list (string-append "--root="
+                       (cond ((uuid? root-device)
+
+                              ;; Note: Always use the DCE format because that's
+                              ;; what (gnu build linux-boot) expects for the
+                              ;; '--root' kernel command-line option.
+                              (uuid->string (uuid-bytevector root-device)
+                                            'dce))
+                             ((file-system-label? root-device)
+                              (file-system-label->string root-device))
+                             (else root-device)))
+        #~(string-append "--system=" #$system)
+        #~(string-append "--load=" #$system "/boot")))
 
 ;; System-wide configuration.
 ;; TODO: Add per-field docstrings/stexi.
@@ -156,7 +154,7 @@ booted from ROOT-DEVICE"
                     (default '()))                ; list of gexps/strings
   (bootloader operating-system-bootloader)        ; <bootloader-configuration>
 
-  (initrd operating-system-initrd                 ; (list fs) -> M derivation
+  (initrd operating-system-initrd                 ; (list fs) -> file-like
           (default base-initrd))
   (initrd-modules operating-system-initrd-modules ; list of strings
                   (thunked)                       ; it's system-dependent
@@ -209,12 +207,11 @@ booted from ROOT-DEVICE"
   (sudoers-file operating-system-sudoers-file     ; file-like
                 (default %sudoers-specification)))
 
-(define (operating-system-kernel-arguments os system.drv root-device)
+(define (operating-system-kernel-arguments os root-device)
   "Return all the kernel arguments, including the ones not specified
 directly by the user."
-  (bootable-kernel-arguments (operating-system-user-kernel-arguments os)
-                             system.drv
-                             root-device))
+  (append (bootable-kernel-arguments os root-device)
+          (operating-system-user-kernel-arguments os)))
 
 \f
 ;;;
@@ -317,8 +314,8 @@ file system labels."
          (_                                       ;the old format
           "/")))))
     (x                                            ;unsupported format
-     (warning (G_ "unrecognized boot parameters for '~a'~%")
-              system)
+     (warning (G_ "unrecognized boot parameters at '~a'~%")
+              (port-filename port))
      #f)))
 
 (define (read-boot-parameters-file system)
@@ -328,14 +325,11 @@ format is unrecognized.
 The object has its kernel-arguments extended in order to make it bootable."
   (let* ((file (string-append system "/parameters"))
          (params (call-with-input-file file read-boot-parameters))
-         (root (boot-parameters-root-device params))
-         (kernel-arguments (boot-parameters-kernel-arguments params)))
-    (if params
-      (boot-parameters
-        (inherit params)
-        (kernel-arguments (bootable-kernel-arguments kernel-arguments
-                                                     system root)))
-      #f)))
+         (root (boot-parameters-root-device params)))
+    (boot-parameters
+     (inherit params)
+     (kernel-arguments (append (bootable-kernel-arguments system root)
+                               (boot-parameters-kernel-arguments params))))))
 
 (define (boot-parameters->menu-entry conf)
   (menu-entry
@@ -359,6 +353,9 @@ marked as 'needed-for-boot'."
     (remove file-system-needed-for-boot?
             (operating-system-file-systems os)))
 
+  (define mapped-devices-for-boot
+    (operating-system-boot-mapped-devices os))
+
   (define (device-mappings fs)
     (let ((device (file-system-device fs)))
       (if (string? device)                        ;title is 'device
@@ -374,21 +371,23 @@ marked as 'needed-for-boot'."
     (file-system
       (inherit fs)
       (dependencies
-       (delete-duplicates (append (device-mappings fs)
-                                  (file-system-dependencies fs))
-                          eq?))))
+       (delete-duplicates
+        (remove (cut member <> mapped-devices-for-boot)
+                (append (device-mappings fs)
+                        (file-system-dependencies fs)))
+        eq?))))
 
   (service file-system-service-type
            (map add-dependencies file-systems)))
 
-(define (mapped-device-user device file-systems)
-  "Return a file system among FILE-SYSTEMS that uses DEVICE, or #f."
+(define (mapped-device-users device file-systems)
+  "Return the subset of FILE-SYSTEMS that use DEVICE."
   (let ((target (string-append "/dev/mapper/" (mapped-device-target device))))
-    (find (lambda (fs)
-            (or (member device (file-system-dependencies fs))
-                (and (string? (file-system-device fs))
-                     (string=? (file-system-device fs) target))))
-          file-systems)))
+    (filter (lambda (fs)
+              (or (member device (file-system-dependencies fs))
+                  (and (string? (file-system-device fs))
+                       (string=? (file-system-device fs) target))))
+            file-systems)))
 
 (define (operating-system-user-mapped-devices os)
   "Return the subset of mapped devices that can be installed in
@@ -396,9 +395,8 @@ user-land--i.e., those not needed during boot."
   (let ((devices      (operating-system-mapped-devices os))
         (file-systems (operating-system-file-systems os)))
    (filter (lambda (md)
-             (let ((user (mapped-device-user md file-systems)))
-               (or (not user)
-                   (not (file-system-needed-for-boot? user)))))
+             (let ((users (mapped-device-users md file-systems)))
+               (not (any file-system-needed-for-boot? users))))
            devices)))
 
 (define (operating-system-boot-mapped-devices os)
@@ -407,8 +405,8 @@ from the initrd."
   (let ((devices      (operating-system-mapped-devices os))
         (file-systems (operating-system-file-systems os)))
    (filter (lambda (md)
-             (let ((user (mapped-device-user md file-systems)))
-               (and user (file-system-needed-for-boot? user))))
+             (let ((users (mapped-device-users md file-systems)))
+               (any file-system-needed-for-boot? users)))
            devices)))
 
 (define (device-mapping-services os)
@@ -444,7 +442,7 @@ value of the SYSTEM-SERVICE-TYPE service."
           (return `(("locale" ,locale)))
           (mlet %store-monad
               ((kernel  ->  (operating-system-kernel os))
-               (initrd      (operating-system-initrd-file os))
+               (initrd  ->  (operating-system-initrd-file os))
                (params      (operating-system-boot-parameters-file os)))
             (return `(("kernel" ,kernel)
                       ("parameters" ,params)
@@ -470,13 +468,13 @@ a container or that of a \"bare metal\" system."
     (cons* (service system-service-type entries)
            %boot-service
 
-           ;; %SHEPHERD-ROOT-SERVICE must come first so that the gexp that
+           ;; %SHEPHERD-ROOT-SERVICE must come last so that the gexp that
            ;; execs shepherd comes last in the boot script (XXX).  Likewise,
-           ;; the cleanup service must come last so that its gexp runs before
+           ;; the cleanup service must come first so that its gexp runs before
            ;; activation code.
-           %shepherd-root-service
-           %activation-service
            (service cleanup-service-type #f)
+           %activation-service
+           %shepherd-root-service
 
            (pam-root-service (operating-system-pam-services os))
            (account-service (append (operating-system-accounts os)
@@ -497,7 +495,7 @@ a container or that of a \"bare metal\" system."
                    ;; Add the firmware service, unless we are building for a
                    ;; container.
                    (if container?
-                       '()
+                       (list %containerized-shepherd-service)
                        (list %linux-bare-metal-service
                              (service firmware-service-type
                                       (operating-system-firmware os))))))))
@@ -524,8 +522,7 @@ explicitly appear in OS."
   ;; required for basic administrator tasks.
   (cons* procps psmisc which less zile nano
          pciutils usbutils
-         ;; temporary package to fix CVE-2018-7738 without a graft
-         util-linux-2.31.1
+         util-linux
          inetutils isc-dhcp
          (@ (gnu packages admin) shadow)          ;for 'passwd'
 
@@ -617,9 +614,6 @@ unset PATH
 GUIX_PROFILE=/run/current-system/profile ; \\
 . /run/current-system/profile/etc/profile
 
-# Prepend setuid programs.
-export PATH=/run/setuid-programs:$PATH
-
 # Since 'lshd' does not use pam_env, /etc/environment must be explicitly
 # loaded when someone logs in via SSH.  See <http://bugs.gnu.org/22175>.
 # We need 'PATH' to be defined here, for 'cat' and 'cut'.  Do this before
@@ -631,16 +625,26 @@ then
   export `cat /etc/environment | cut -d= -f1`
 fi
 
-if [ -f \"$HOME/.guix-profile/etc/profile\" ]
-then
-  # Load the user profile's settings.
-  GUIX_PROFILE=\"$HOME/.guix-profile\" ; \\
-  . \"$HOME/.guix-profile/etc/profile\"
-else
-  # At least define this one so that basic things just work
-  # when the user installs their first package.
-  export PATH=\"$HOME/.guix-profile/bin:$PATH\"
-fi
+# Arrange so that ~/.config/guix/current comes first.
+for profile in \"$HOME/.guix-profile\" \"$HOME/.config/guix/current\"
+do
+  if [ -f \"$profile/etc/profile\" ]
+  then
+    # Load the user profile's settings.
+    GUIX_PROFILE=\"$profile\" ; \\
+    . \"$profile/etc/profile\"
+  else
+    # At least define this one so that basic things just work
+    # when the user installs their first package.
+    export PATH=\"$profile/bin:$PATH\"
+  fi
+done
+
+# Prepend setuid programs.
+export PATH=/run/setuid-programs:$PATH
+
+# Arrange so that ~/.config/guix/current/share/info comes first.
+export INFOPATH=\"$HOME/.config/guix/current/share/info:$INFOPATH\"
 
 # Set the umask, notably for users logging in via 'lsh'.
 # See <http://bugs.gnu.org/22650>.
@@ -813,7 +817,6 @@ we're running in the final root.  When CONTAINER? is true, skip all
 hardware-related operations as necessary when booting a Linux container."
   (let* ((services (operating-system-services os #:container? container?))
          (boot     (fold-services services #:target-type boot-service-type)))
-    ;; BOOT is the script as a monadic value.
     (service-value boot)))
 
 (define (operating-system-user-accounts os)
@@ -867,12 +870,12 @@ hardware-related operations as necessary when booting a Linux container."
   (define make-initrd
     (operating-system-initrd os))
 
-  (mlet %store-monad ((initrd (make-initrd boot-file-systems
-                                           #:linux (operating-system-kernel os)
-                                           #:linux-modules
-                                           (operating-system-initrd-modules os)
-                                           #:mapped-devices mapped-devices)))
-    (return (file-append initrd "/initrd"))))
+  (let ((initrd (make-initrd boot-file-systems
+                             #:linux (operating-system-kernel os)
+                             #:linux-modules
+                             (operating-system-initrd-modules os)
+                             #:mapped-devices mapped-devices)))
+    (file-append initrd "/initrd")))
 
 (define (locale-name->definition* name)
   "Variant of 'locale-name->definition' that raises an error upon failure."
@@ -930,42 +933,45 @@ listed in OS.  The C library expects to find it under
   (store-file-system (operating-system-file-systems os)))
 
 (define* (operating-system-bootcfg os #:optional (old-entries '()))
-  "Return the bootloader configuration file for OS.  Use OLD-ENTRIES
-(which is a list of <menu-entry>) to populate the \"old entries\" menu."
-  (mlet* %store-monad
-      ((system      (operating-system-derivation os))
-       (root-fs ->  (operating-system-root-file-system os))
-       (root-device -> (file-system-device root-fs))
-       (params (operating-system-boot-parameters os system root-device))
-       (entry -> (boot-parameters->menu-entry params))
-       (bootloader-conf -> (operating-system-bootloader os)))
-    ((bootloader-configuration-file-generator
-      (bootloader-configuration-bootloader bootloader-conf))
-     bootloader-conf (list entry) #:old-entries old-entries)))
-
-(define (operating-system-boot-parameters os system.drv root-device)
-  "Return a monadic <boot-parameters> record that describes the boot parameters
-of OS.  SYSTEM.DRV is either a derivation or #f.  If it's a derivation, adds
-kernel arguments for that derivation to <boot-parameters>."
-  (mlet* %store-monad
-      ((initrd (operating-system-initrd-file os))
-       (store -> (operating-system-store-file-system os))
-       (bootloader  -> (bootloader-configuration-bootloader
-                        (operating-system-bootloader os)))
-       (bootloader-name -> (bootloader-name bootloader))
-       (label -> (kernel->boot-label (operating-system-kernel os))))
-    (return (boot-parameters
-             (label label)
-             (root-device root-device)
-             (kernel (operating-system-kernel-file os))
-             (kernel-arguments
-              (if system.drv
-                (operating-system-kernel-arguments os system.drv root-device)
-                (operating-system-user-kernel-arguments os)))
-             (initrd initrd)
-             (bootloader-name bootloader-name)
-             (store-device (ensure-not-/dev (file-system-device store)))
-             (store-mount-point (file-system-mount-point store))))))
+  "Return the bootloader configuration file for OS.  Use OLD-ENTRIES,
+a list of <menu-entry>, to populate the \"old entries\" menu."
+  (let* ((root-fs         (operating-system-root-file-system os))
+         (root-device     (file-system-device root-fs))
+         (params          (operating-system-boot-parameters
+                           os root-device
+                           #:system-kernel-arguments? #t))
+         (entry           (boot-parameters->menu-entry params))
+         (bootloader-conf (operating-system-bootloader os)))
+    (define generate-config-file
+      (bootloader-configuration-file-generator
+       (bootloader-configuration-bootloader bootloader-conf)))
+
+    (generate-config-file bootloader-conf (list entry)
+                          #:old-entries old-entries)))
+
+(define* (operating-system-boot-parameters os root-device
+                                           #:key system-kernel-arguments?)
+  "Return a monadic <boot-parameters> record that describes the boot
+parameters of OS.  When SYSTEM-KERNEL-ARGUMENTS? is true, add kernel arguments
+such as '--root' and '--load' to <boot-parameters>."
+  (let* ((initrd          (operating-system-initrd-file os))
+         (store           (operating-system-store-file-system os))
+         (bootloader      (bootloader-configuration-bootloader
+                           (operating-system-bootloader os)))
+         (bootloader-name (bootloader-name bootloader))
+         (label           (kernel->boot-label (operating-system-kernel os))))
+    (boot-parameters
+     (label label)
+     (root-device root-device)
+     (kernel (operating-system-kernel-file os))
+     (kernel-arguments
+      (if system-kernel-arguments?
+          (operating-system-kernel-arguments os root-device)
+          (operating-system-user-kernel-arguments os)))
+     (initrd initrd)
+     (bootloader-name bootloader-name)
+     (store-device (ensure-not-/dev (file-system-device store)))
+     (store-mount-point (file-system-mount-point store)))))
 
 (define (device->sexp device)
   "Serialize DEVICE as an sexp (really, as an object with a read syntax.)"
@@ -977,19 +983,22 @@ kernel arguments for that derivation to <boot-parameters>."
     (_
      device)))
 
-(define* (operating-system-boot-parameters-file os #:optional (system.drv #f))
+(define* (operating-system-boot-parameters-file os
+                                                #:key system-kernel-arguments?)
    "Return a file that describes the boot parameters of OS.  The primary use of
 this file is the reconstruction of GRUB menu entries for old configurations.
-SYSTEM.DRV is optional.  If given, adds kernel arguments for that system to the
-returned file (since the returned file is then usually stored into the
-content-addressed \"system\" directory, it's usually not a good idea
-to give it because the content hash would change by the content hash
+
+When SYSTEM-KERNEL-ARGUMENTS? is true, add kernel arguments such as '--root'
+and '--load' to the returned file (since the returned file is then usually
+stored into the content-addressed \"system\" directory, it's usually not a
+good idea to give it because the content hash would change by the content hash
 being stored into the \"parameters\" file)."
-  (mlet* %store-monad ((root -> (operating-system-root-file-system os))
-                       (device -> (file-system-device root))
-                       (params (operating-system-boot-parameters os
-                                                                 system.drv
-                                                                 device)))
+   (let* ((root   (operating-system-root-file-system os))
+          (device (file-system-device root))
+          (params (operating-system-boot-parameters
+                   os device
+                   #:system-kernel-arguments?
+                   system-kernel-arguments?)))
      (gexp->file "parameters"
                  #~(boot-parameters
                     (version 0)