diff options
Diffstat (limited to 'gnu/installer')
-rw-r--r-- | gnu/installer/final.scm | 61 | ||||
-rw-r--r-- | gnu/installer/keymap.scm | 17 | ||||
-rw-r--r-- | gnu/installer/newt/network.scm | 21 | ||||
-rw-r--r-- | gnu/installer/newt/partition.scm | 15 | ||||
-rw-r--r-- | gnu/installer/newt/services.scm | 41 | ||||
-rw-r--r-- | gnu/installer/parted.scm | 87 | ||||
-rw-r--r-- | gnu/installer/services.scm | 12 | ||||
-rw-r--r-- | gnu/installer/tests.scm | 11 | ||||
-rw-r--r-- | gnu/installer/utils.scm | 18 |
9 files changed, 181 insertions, 102 deletions
diff --git a/gnu/installer/final.scm b/gnu/installer/final.scm index fc0b7803fa..276af908f7 100644 --- a/gnu/installer/final.scm +++ b/gnu/installer/final.scm @@ -105,36 +105,6 @@ USERS." (write-passwd password (string-append etc "/passwd")) (write-shadow shadow (string-append etc "/shadow"))) -(define* (kill-cow-users cow-path #:key (spare '("udevd"))) - "Kill all processes that have references to the given COW-PATH in their -'maps' file. The process whose names are in SPARE list are spared." - (define %not-nul - (char-set-complement (char-set #\nul))) - - (let ((pids - (filter-map (lambda (pid) - (false-if-exception - (call-with-input-file - (string-append "/proc/" pid "/maps") - (lambda (port) - (and (string-contains (get-string-all port) - cow-path) - (string->number pid)))))) - (scandir "/proc" string->number)))) - (for-each (lambda (pid) - ;; cmdline does not always exist. - (false-if-exception - (call-with-input-file - (string-append "/proc/" (number->string pid) "/cmdline") - (lambda (port) - (match (string-tokenize (read-string port) %not-nul) - ((argv0 _ ...) - (unless (member (basename argv0) spare) - (syslog "Killing process ~a (~a)~%" pid argv0) - (kill pid SIGKILL))) - (_ #f)))))) - pids))) - (define (call-with-mnt-container thunk) "This is a variant of call-with-container. Run THUNK in a new container process, within a separate MNT namespace. The container is not jailed so that @@ -149,6 +119,28 @@ it can interact with the rest of the system." (match (waitpid pid) ((_ . status) status)))) +(define (install-locale locale) + "Install the given LOCALE or the en_US.utf8 locale as a fallback." + (let ((supported? (false-if-exception + (setlocale LC_ALL locale)))) + (if supported? + (begin + (syslog "install supported locale ~a~%." locale) + (setenv "LC_ALL" locale)) + (begin + ;; If the selected locale is not supported, install a default UTF-8 + ;; locale. This is required to copy some files with UTF-8 + ;; characters, in the nss-certs package notably. Set LANGUAGE + ;; anyways, to have translated messages if possible. + (syslog "~a locale is not supported, installating en_US.utf8 \ +locale instead.~%" locale) + (setlocale LC_ALL "en_US.utf8") + (setenv "LC_ALL" "en_US.utf8") + (setenv "LANGUAGE" + (string-take locale + (or (string-index locale #\_) + (string-length locale)))))))) + (define* (install-system locale #:key (users '())) "Create /etc/shadow and /etc/passwd on the installation target for USERS. Start COW-STORE service on target directory and launch guix install command in @@ -199,6 +191,10 @@ or #f. Return #t on success and #f on failure." (lambda () (dynamic-wind (lambda () + ;; Install the locale before mounting the cow-store, otherwise + ;; the loaded cow-store locale files will prevent umounting. + (install-locale locale) + ;; Save the database, so that it can be restored once the ;; cow-store is umounted. (copy-file database-file saved-database) @@ -221,9 +217,8 @@ or #f. Return #t on success and #f on failure." (lambda () (with-error-to-file "/dev/console" (lambda () - (run-command install-command - #:locale locale))))) - (run-command install-command #:locale locale)))) + (run-command install-command))))) + (run-command install-command)))) (lambda () ;; Restart guix-daemon so that it does no keep the MNT namespace ;; alive. diff --git a/gnu/installer/keymap.scm b/gnu/installer/keymap.scm index c42b308009..83b65a0427 100644 --- a/gnu/installer/keymap.scm +++ b/gnu/installer/keymap.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018 Mathieu Othacehe <[email protected]> +;;; Copyright © 2018, 2021 Mathieu Othacehe <[email protected]> ;;; Copyright © 2020 Florian Pelz <[email protected]> ;;; ;;; This file is part of GNU Guix. @@ -79,6 +79,11 @@ "Parse FILE and return two values, the list of supported X11-KEYMAP-MODEL and X11-KEYMAP-LAYOUT records. FILE is an XML file from the X Keyboard Configuration Database, describing possible XKB configurations." + (define maybe-empty + (match-lambda + ((x) x) + (#f ""))) + (define (model m) (sxml-match m [(model @@ -108,7 +113,7 @@ Configuration Database, describing possible XKB configurations." . ,rest-variant)) (x11-keymap-variant (name name) - (description (car + (description (maybe-empty (assoc-ref rest-variant 'description))))])) (define (layout l) @@ -120,9 +125,9 @@ Configuration Database, describing possible XKB configurations." (variantList ,[variant -> v] ...)) (x11-keymap-layout (name name) - (synopsis (car + (synopsis (maybe-empty (assoc-ref rest-layout 'shortDescription))) - (description (car + (description (maybe-empty (assoc-ref rest-layout 'description))) (variants (list v ...)))] [(layout @@ -131,9 +136,9 @@ Configuration Database, describing possible XKB configurations." . ,rest-layout)) (x11-keymap-layout (name name) - (synopsis (car + (synopsis (maybe-empty (assoc-ref rest-layout 'shortDescription))) - (description (car + (description (maybe-empty (assoc-ref rest-layout 'description))) (variants '()))])) diff --git a/gnu/installer/newt/network.scm b/gnu/installer/newt/network.scm index 4af7143d63..fb221483c3 100644 --- a/gnu/installer/newt/network.scm +++ b/gnu/installer/newt/network.scm @@ -30,6 +30,8 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:use-module (ice-9 match) + #:use-module (web client) + #:use-module (web response) #:use-module (newt) #:export (run-network-page)) @@ -119,8 +121,23 @@ network devices were found. Do you want to continue anyway?")) (define (wait-service-online) "Display a newt scale until connman detects an Internet access. Do FULL-VALUE tentatives, spaced by 1 second." + (define (ci-available?) + (dynamic-wind + (lambda () + (sigaction SIGALRM + (lambda _ #f)) + (alarm 3)) + (lambda () + (false-if-exception + (= (response-code + (http-request "https://ci.guix.gnu.org")) + 200))) + (lambda () + (alarm 0)))) + (define (online?) - (or (connman-online?) + (or (and (connman-online?) + (ci-available?)) (file-exists? "/tmp/installer-assume-online"))) (let* ((full-value 5)) @@ -137,7 +154,7 @@ FULL-VALUE tentatives, spaced by 1 second." (unless (online?) (run-error-page (G_ "The selected network does not provide access to the \ -Internet, please try again.") +Internet and the Guix substitute server, please try again.") (G_ "Connection error")) (raise (condition diff --git a/gnu/installer/newt/partition.scm b/gnu/installer/newt/partition.scm index ea524eb4c3..ccc7686906 100644 --- a/gnu/installer/newt/partition.scm +++ b/gnu/installer/newt/partition.scm @@ -83,7 +83,8 @@ DEVICES list." devices)) (let* ((result (run-listbox-selection-page - #:info-text (G_ "Please select a disk.") + #:info-text (G_ "Please select a \ +disk. The installation device as well as the small devices are filtered.") #:title (G_ "Disk") #:listbox-items (device-items) #:listbox-item->text cdr @@ -131,7 +132,11 @@ Be careful, all data on the disk will be lost.") (run-listbox-selection-page #:info-text (G_ "Please select the file-system type for this partition.") #:title (G_ "File-system type") - #:listbox-items '(ext4 btrfs fat16 fat32 jfs ntfs xfs swap) + #:listbox-items '(btrfs ext4 jfs xfs + swap + ;; These lack basic Unix features. Their only use + ;; on GNU is for interoperation, e.g., with UEFI. + fat32 fat16 ntfs) #:listbox-item->text user-fs-type-name #:sort-listbox-items? #f #:button-text (G_ "Exit") @@ -788,13 +793,13 @@ by pressing the Exit button.~%~%"))) result-user-partitions))))) (init-parted) - (let* ((non-install-devices (non-install-devices)) - (user-partitions (run-page non-install-devices)) + (let* ((eligible-devices (eligible-devices)) + (user-partitions (run-page eligible-devices)) (user-partitions-with-pass (prompt-luks-passwords user-partitions)) (form (draw-formatting-page user-partitions))) ;; Make sure the disks are not in use before proceeding to formatting. - (free-parted non-install-devices) + (free-parted eligible-devices) (format-user-partitions user-partitions-with-pass) (syslog "formatted ~a user partitions~%" (length user-partitions-with-pass)) diff --git a/gnu/installer/newt/services.scm b/gnu/installer/newt/services.scm index 1af4e7df2d..c218825813 100644 --- a/gnu/installer/newt/services.scm +++ b/gnu/installer/newt/services.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2019, 2020 Ludovic Courtès <[email protected]> ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <[email protected]> ;;; Copyright © 2021 Tobias Geerinckx-Rice <[email protected]> +;;; Copyright © 2021 Leo Famulari <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -68,18 +69,16 @@ system.") (condition (&installer-step-abort))))))) -(define (run-other-services-cbt-page) - "Run a page allowing the user to select other services." +(define (run-printing-services-cbt-page) + "Run a page allowing the user to select document services such as CUPS." (let ((items (filter (lambda (service) - (not (member (system-service-type service) - '(desktop - network-management - networking)))) + (eq? 'document + (system-service-type service))) %system-services))) (run-checkbox-tree-page - #:info-text (G_ "You can now select other services to run on your \ + #:info-text (G_ "You can now select the CUPS printing service to run on your \ system.") - #:title (G_ "Other services") + #:title (G_ "Printing and document services") #:items items #:selection (map system-service-recommended? items) #:item->text (compose G_ system-service-name) @@ -90,6 +89,27 @@ system.") (condition (&installer-step-abort))))))) +(define (run-console-services-cbt-page) + "Run a page to select various system adminstration services for non-graphical +systems." + (let ((items (filter (lambda (service) + (eq? 'administration + (system-service-type service))) + %system-services))) + (run-checkbox-tree-page + #:title (G_ "Console services") + #:info-text (G_ "Select miscellaneous services to run on your \ +non-graphical system.") + #:items items + #:selection (map system-service-recommended? items) + #:item->text (compose G_ system-service-name) + #:checkbox-tree-height 5 + #:exit-button-callback-procedure + (lambda () + (raise + (condition + (&installer-step-abort))))))) + (define (run-network-management-page) "Run a page to select among several network management methods." (let ((title (G_ "Network management"))) @@ -121,6 +141,7 @@ client may be enough for a server.") (append desktop (run-networking-cbt-page) (if (null? desktop) - (list (run-network-management-page)) + (cons (run-network-management-page) + (run-console-services-cbt-page)) '()) - (run-other-services-cbt-page)))) + (run-printing-services-cbt-page)))) diff --git a/gnu/installer/parted.scm b/gnu/installer/parted.scm index cbe676017b..66e07574c9 100644 --- a/gnu/installer/parted.scm +++ b/gnu/installer/parted.scm @@ -26,6 +26,7 @@ #:use-module ((gnu build file-systems) #:select (canonicalize-device-spec find-partition-by-label + find-partition-by-uuid read-partition-uuid read-luks-partition-uuid)) #:use-module ((gnu build linux-boot) @@ -80,7 +81,7 @@ with-delay-device-in-use? force-device-sync - non-install-devices + eligible-devices partition-user-type user-fs-type-name partition-filesystem-user-type @@ -345,35 +346,59 @@ fail. See rereadpt function in wipefs.c of util-linux for an explanation." (with-null-output-ports (invoke "dmsetup" "remove_all"))) -(define (installation-device) - "Return the installation device path." +(define (installer-root-partition-path) + "Return the root partition path, or #f if it could not be detected." (let* ((cmdline (linux-command-line)) (root (find-long-option "--root" cmdline))) (and root - (canonicalize-device-spec (uuid root))))) - -(define (non-install-devices) - "Return all the available devices, except the install device." - (define (read-only? device) - (dynamic-wind - (lambda () - (device-open device)) - (lambda () - (device-read-only? device)) - (lambda () - (device-close device)))) - - ;; If parted reports that a device is read-only it is probably the - ;; installation device. However, as this detection does not always work, - ;; compare the device path to the installation device path read from the - ;; command line. - (let ((install-device (installation-device))) - (remove (lambda (device) - (let ((file-name (device-path device))) - (or (read-only? device) - (and install-device - (string=? file-name install-device))))) - (devices)))) + (or (and (access? root F_OK) root) + (find-partition-by-label root) + (and=> (uuid root) + find-partition-by-uuid))))) + +;; Minimal installation device size. +(define %min-device-size + (* 2 GIBIBYTE-SIZE)) ;2GiB + +(define (eligible-devices) + "Return all the available devices except the install device and the devices +which are smaller than %MIN-DEVICE-SIZE." + + (define the-installer-root-partition-path + (installer-root-partition-path)) + + (define (small-device? device) + (let ((length (device-length device)) + (sector-size (device-sector-size device))) + (and (< (* length sector-size) %min-device-size) + (syslog "~a is not eligible because it is smaller than ~a.~%" + (device-path device) + (unit-format-custom-byte device + %min-device-size + UNIT-GIGABYTE))))) + + ;; Read partition table of device and compare each path to the one + ;; we're booting from to determine if it is the installation + ;; device. + (define (installation-device? device) + ;; When using CDROM based installation, the root partition path may be the + ;; device path. + (and (or (string=? the-installer-root-partition-path + (device-path device)) + (let ((disk (disk-new device))) + (and disk + (any (lambda (partition) + (string=? the-installer-root-partition-path + (partition-get-path partition))) + (disk-partitions disk))))) + (syslog "~a is not eligible because it is the installation device.~%" + (device-path device)))) + + (remove + (lambda (device) + (or (installation-device? device) + (small-device? device))) + (devices))) ;; @@ -1414,9 +1439,11 @@ USER-PARTITIONS, or return nothing." (let* ((uuids (map (lambda (file) (uuid->string (read-partition-uuid file))) swap-devices))) - `((swap-devices (list ,@(map (lambda (uuid) - `(uuid ,uuid)) - uuids)))))) + `((swap-devices + (list ,@(map (lambda (uuid) + `(swap-space + (target (uuid ,uuid)))) + uuids)))))) ,@(if (null? encrypted-partitions) '() `((mapped-devices diff --git a/gnu/installer/services.scm b/gnu/installer/services.scm index 341d8b69c8..6584fcceec 100644 --- a/gnu/installer/services.scm +++ b/gnu/installer/services.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2019 Ludovic Courtès <[email protected]> ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <[email protected]> ;;; Copyright © 2021 Tobias Geerinckx-Rice <[email protected]> +;;; Copyright © 2021 Leo Famulari <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -104,6 +105,17 @@ (packages '((specification->package "nss-certs"))) (recommended? #t)) + ;; Miscellaneous system administration services. + (system-service + (name (G_ "Network time service (NTP), to set the clock automatically")) + (type 'administration) + (recommended? #t) + (snippet '((service ntp-service-type)))) + (system-service + (name (G_ "GPM mouse daemon, to use the mouse on the console")) + (type 'administration) + (snippet '((service gpm-service-type)))) + ;; Network connectivity management. (system-service (name (G_ "NetworkManager network connection manager")) diff --git a/gnu/installer/tests.scm b/gnu/installer/tests.scm index 12d1d91608..3c049a1c85 100644 --- a/gnu/installer/tests.scm +++ b/gnu/installer/tests.scm @@ -221,7 +221,11 @@ ROOT-PASSWORD, and USERS." (choose-network-management-tool? (lambda (service) (string-contains service "DHCP"))) + (choose-misc-service? + (lambda (service) + (string-contains service "NTP"))) (choose-other-service? (const #f))) + "Converse over PORT to choose services." (define desktop-environments '()) @@ -243,7 +247,12 @@ ROOT-PASSWORD, and USERS." (null? desktop-environments) (find choose-network-management-tool? services)) - ((checkbox-list (title "Other services") (text _) + ((checkbox-list (title "Console services") (text _) + (items ,services)) + (null? desktop-environments) + (filter choose-misc-service? services)) + + ((checkbox-list (title "Printing and document services") (text _) (items ,services)) (filter choose-other-service? services)))) diff --git a/gnu/installer/utils.scm b/gnu/installer/utils.scm index bb97bc5560..9bd41e2ca0 100644 --- a/gnu/installer/utils.scm +++ b/gnu/installer/utils.scm @@ -74,9 +74,9 @@ number. If no percentage is found, return #f" (and result (string->number (match:substring result 1))))) -(define* (run-command command #:key locale) - "Run COMMAND, a list of strings, in the given LOCALE. Return true if -COMMAND exited successfully, #f otherwise." +(define* (run-command command) + "Run COMMAND, a list of strings. Return true if COMMAND exited +successfully, #f otherwise." (define env (environ)) (define (pause) @@ -90,18 +90,6 @@ COMMAND exited successfully, #f otherwise." (setenv "PATH" "/run/current-system/profile/bin") - (when locale - (let ((supported? (false-if-exception - (setlocale LC_ALL locale)))) - ;; If LOCALE is not supported, then set LANGUAGE, which might at - ;; least give us translated messages. - (if supported? - (setenv "LC_ALL" locale) - (setenv "LANGUAGE" - (string-take locale - (or (string-index locale #\_) - (string-length locale))))))) - (guard (c ((invoke-error? c) (newline) (format (current-error-port) |