summaryrefslogtreecommitdiff
path: root/gnu/installer
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/installer')
-rw-r--r--gnu/installer/final.scm61
-rw-r--r--gnu/installer/keymap.scm17
-rw-r--r--gnu/installer/newt/network.scm21
-rw-r--r--gnu/installer/newt/partition.scm15
-rw-r--r--gnu/installer/newt/services.scm41
-rw-r--r--gnu/installer/parted.scm87
-rw-r--r--gnu/installer/services.scm12
-rw-r--r--gnu/installer/tests.scm11
-rw-r--r--gnu/installer/utils.scm18
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)