diff options
| author | Rutherther <rutherther@ditigal.xyz> | 2026-01-03 23:02:40 +0100 |
|---|---|---|
| committer | Rutherther <rutherther@ditigal.xyz> | 2026-01-14 09:17:34 +0100 |
| commit | 94f9177cf812971406b48c2c2ecf3f6927373378 (patch) | |
| tree | 1df0369a15b46210598b442cf75014ef5dd79496 /gnu | |
| parent | ab22501915fa57cf3a3f94dcc7fec86b433d85ad (diff) | |
install: Show different motd in headless console.
motd is shown by the pam module, it doesn't support changing what motd gets
displayed easily. The only way to control it is by read permissions on
individual motd files, making files unreadable by the user logging in.
So instead of that, make a custom script that prints different motd,
checking if a temporary file exists. An environment variable would be better
suited for this purpose, but those aren't passed through by PAM.
* gnu/system/install.scm
(%installation-login-pam-service): New variable. Modified login pam service.
(%installation-console-login): New variable. Wrapper around login to create a
file for PAM rule.
(%installation-services): Use new login pam service and wrapper.
Change-Id: I5e05e604b3106390181190559ade62ca5e2db216
Signed-off-by: Rutherther <rutherther@ditigal.xyz>
Diffstat (limited to 'gnu')
| -rw-r--r-- | gnu/system/install.scm | 386 |
1 files changed, 229 insertions, 157 deletions
diff --git a/gnu/system/install.scm b/gnu/system/install.scm index 80332b7b534..1e30e33f7a5 100644 --- a/gnu/system/install.scm +++ b/gnu/system/install.scm | |||
| @@ -336,6 +336,83 @@ templates under @file{/etc/configuration}."))) | |||
| 336 | "Load the @code{uvesafb} kernel module with the right options.") | 336 | "Load the @code{uvesafb} kernel module with the right options.") |
| 337 | (default-value #t))) | 337 | (default-value #t))) |
| 338 | 338 | ||
| 339 | (define %installation-login-pam-service | ||
| 340 | ;; Custom 'login' pam.d rule. It is based on the original one, | ||
| 341 | ;; but includes possibility to print different motd. This motd | ||
| 342 | ;; is useful for headless consoles. | ||
| 343 | (let* ((unix (pam-entry | ||
| 344 | (control "required") | ||
| 345 | (module "pam_unix.so"))) | ||
| 346 | (env (pam-entry ; to honor /etc/environment. | ||
| 347 | (control "required") | ||
| 348 | (module "pam_env.so"))) | ||
| 349 | (motd (plain-file "motd" " | ||
| 350 | \x1b[1;37mWelcome to the installation of GNU Guix!\x1b[0m | ||
| 351 | |||
| 352 | \x1b[2m\ | ||
| 353 | Using this shell, you can carry out the installation process \"manually.\" | ||
| 354 | Access documentation at any time by pressing Alt-F2.\x1b[0m | ||
| 355 | ")) | ||
| 356 | (console-motd (plain-file "console-motd" " | ||
| 357 | \x1b[1;37mWelcome to the installation of GNU Guix!\x1b[0m | ||
| 358 | |||
| 359 | You are in a headless console. If you can use a display, you should see the | ||
| 360 | graphical installer on TTY1, it's opened by default. In case you cannot use a | ||
| 361 | display, you can carry out the installation process in this shell \"manually\" | ||
| 362 | or by starting the installer, using `guix-system-installer` command. | ||
| 363 | |||
| 364 | \x1b[2mYou can access the Guix documentation using `info \"(guix)\"`.\x1b[0m | ||
| 365 | ")) | ||
| 366 | (show-motd (program-file "show-motd" | ||
| 367 | #~(begin | ||
| 368 | (use-modules (ice-9 textual-ports)) | ||
| 369 | |||
| 370 | (call-with-input-file | ||
| 371 | (if (file-exists? | ||
| 372 | (string-append | ||
| 373 | "/tmp/console_" | ||
| 374 | (basename (getenv "PAM_TTY")))) | ||
| 375 | #$console-motd | ||
| 376 | #$motd) | ||
| 377 | (lambda (port) | ||
| 378 | (display (get-string-all port)))))))) | ||
| 379 | (pam-service | ||
| 380 | (name "login") | ||
| 381 | (account (list unix)) | ||
| 382 | (auth (list (pam-entry | ||
| 383 | (control "required") | ||
| 384 | (module "pam_unix.so") | ||
| 385 | (arguments '("nullok"))))) | ||
| 386 | (password (list (pam-entry | ||
| 387 | (control "required") | ||
| 388 | (module "pam_unix.so") | ||
| 389 | (arguments '("sha512" "shadow"))))) | ||
| 390 | (session `(,(pam-entry | ||
| 391 | (control "optional") | ||
| 392 | (module "pam_exec.so") | ||
| 393 | (arguments | ||
| 394 | (list "type=open_session" "stdout" show-motd))) | ||
| 395 | ,(pam-entry ;to fill in /proc/self/loginuid | ||
| 396 | (control "required") | ||
| 397 | (module "pam_loginuid.so")) | ||
| 398 | ,env ,unix))))) | ||
| 399 | |||
| 400 | (define %installation-console-login | ||
| 401 | ;; Make a custom 'login' wrapper for execution in console | ||
| 402 | ;; terminal. It instructs pam.d login rule to print different | ||
| 403 | ;; motd. | ||
| 404 | (program-file | ||
| 405 | "login-with-motd" | ||
| 406 | #~(begin | ||
| 407 | (call-with-output-file | ||
| 408 | (string-append "/tmp/console_" | ||
| 409 | (basename (ttyname (current-output-port)))) | ||
| 410 | (const #t)) | ||
| 411 | |||
| 412 | (apply execlp | ||
| 413 | #$(file-append shadow "/bin/login") | ||
| 414 | (command-line))))) | ||
| 415 | |||
| 339 | (define* (%installation-services | 416 | (define* (%installation-services |
| 340 | #:key | 417 | #:key |
| 341 | (system (or (and=> | 418 | (system (or (and=> |
| @@ -344,163 +421,158 @@ templates under @file{/etc/configuration}."))) | |||
| 344 | (%current-system))) | 421 | (%current-system))) |
| 345 | (guix-for-system (current-guix))) | 422 | (guix-for-system (current-guix))) |
| 346 | ;; List of services of the installation system. | 423 | ;; List of services of the installation system. |
| 347 | (let ((motd (plain-file "motd" " | 424 | (define (normal-tty tty) |
| 348 | \x1b[1;37mWelcome to the installation of GNU Guix!\x1b[0m | 425 | (service mingetty-service-type |
| 349 | 426 | (mingetty-configuration (tty tty) | |
| 350 | \x1b[2m\ | 427 | (auto-login "root") |
| 351 | Using this shell, you can carry out the installation process \"manually.\" | 428 | (login-pause? #t)))) |
| 352 | Access documentation at any time by pressing Alt-F2.\x1b[0m | 429 | |
| 353 | "))) | 430 | (define bare-bones-os |
| 354 | (define (normal-tty tty) | 431 | (load "examples/bare-bones.tmpl")) |
| 355 | (service mingetty-service-type | 432 | |
| 356 | (mingetty-configuration (tty tty) | 433 | (append |
| 357 | (auto-login "root") | 434 | ;; Generic services |
| 358 | (login-pause? #t)))) | 435 | (list (service virtual-terminal-service-type) |
| 359 | 436 | ||
| 360 | (define bare-bones-os | 437 | (service kmscon-service-type |
| 361 | (load "examples/bare-bones.tmpl")) | 438 | (kmscon-configuration |
| 362 | 439 | (virtual-terminal "tty1") | |
| 363 | (append | 440 | (login-program (installer-program |
| 364 | ;; Generic services | 441 | #:guix-for-installer guix-for-system)))) |
| 365 | (list (service virtual-terminal-service-type) | 442 | |
| 366 | 443 | (simple-service 'installer-login | |
| 367 | (service kmscon-service-type | 444 | pam-root-service-type |
| 368 | (kmscon-configuration | 445 | (list %installation-login-pam-service)) |
| 369 | (virtual-terminal "tty1") | 446 | |
| 370 | (login-program (installer-program | 447 | ;; Documentation. The manual is in UTF-8, but |
| 371 | #:guix-for-installer guix-for-system)))) | 448 | ;; 'console-font-service' sets up Unicode support and loads a font |
| 372 | 449 | ;; with all the useful glyphs like em dash and quotation marks. | |
| 373 | (service login-service-type | 450 | (service documentation-service-type "tty2") |
| 374 | (login-configuration | 451 | |
| 375 | (motd motd))) | 452 | ;; Documentation add-on. |
| 376 | 453 | %configuration-template-service | |
| 377 | ;; Documentation. The manual is in UTF-8, but | 454 | |
| 378 | ;; 'console-font-service' sets up Unicode support and loads a font | 455 | ;; A bunch of 'root' ttys. |
| 379 | ;; with all the useful glyphs like em dash and quotation marks. | 456 | (normal-tty "tty3") |
| 380 | (service documentation-service-type "tty2") | 457 | (normal-tty "tty4") |
| 381 | 458 | (normal-tty "tty5") | |
| 382 | ;; Documentation add-on. | 459 | (normal-tty "tty6") |
| 383 | %configuration-template-service | 460 | |
| 384 | 461 | ;; The usual services. | |
| 385 | ;; A bunch of 'root' ttys. | 462 | (service shepherd-system-log-service-type) |
| 386 | (normal-tty "tty3") | 463 | |
| 387 | (normal-tty "tty4") | 464 | ;; Use the Avahi daemon to discover substitute servers on the local |
| 388 | (normal-tty "tty5") | 465 | ;; network. It can be faster than fetching from remote servers. |
| 389 | (normal-tty "tty6") | 466 | (service avahi-service-type) |
| 390 | 467 | ||
| 391 | ;; The usual services. | 468 | ;; The build daemon. |
| 392 | (service shepherd-system-log-service-type) | 469 | (service guix-service-type |
| 393 | 470 | (guix-configuration | |
| 394 | ;; Use the Avahi daemon to discover substitute servers on the local | 471 | ;; Register the default substitute server key(s) as |
| 395 | ;; network. It can be faster than fetching from remote servers. | 472 | ;; trusted to allow the installation process to use |
| 396 | (service avahi-service-type) | 473 | ;; substitutes by default. |
| 397 | 474 | (authorize-key? #t) | |
| 398 | ;; The build daemon. | 475 | |
| 399 | (service guix-service-type | 476 | ;; Install and run the current Guix rather than an older |
| 400 | (guix-configuration | 477 | ;; snapshot. |
| 401 | ;; Register the default substitute server key(s) as | 478 | (guix guix-for-system))) |
| 402 | ;; trusted to allow the installation process to use | 479 | |
| 403 | ;; substitutes by default. | 480 | ;; Start udev so that useful device nodes are available. |
| 404 | (authorize-key? #t) | 481 | ;; Use device-mapper rules for cryptsetup & co; enable the CRDA for |
| 405 | 482 | ;; regulations-compliant WiFi access. | |
| 406 | ;; Install and run the current Guix rather than an older | 483 | (service udev-service-type |
| 407 | ;; snapshot. | 484 | (udev-configuration |
| 408 | (guix guix-for-system))) | 485 | (rules (list lvm2 crda)))) |
| 409 | 486 | ||
| 410 | ;; Start udev so that useful device nodes are available. | 487 | ;; Add the 'cow-store' service, which users have to start manually |
| 411 | ;; Use device-mapper rules for cryptsetup & co; enable the CRDA for | 488 | ;; since it takes the installation directory as an argument. |
| 412 | ;; regulations-compliant WiFi access. | 489 | (cow-store-service) |
| 413 | (service udev-service-type | 490 | |
| 414 | (udev-configuration | 491 | ;; Install Unicode support and a suitable font. |
| 415 | (rules (list lvm2 crda)))) | 492 | (service console-font-service-type |
| 416 | 493 | (map (match-lambda | |
| 417 | ;; Add the 'cow-store' service, which users have to start manually | 494 | ("tty2" |
| 418 | ;; since it takes the installation directory as an argument. | 495 | ;; Use a font that contains characters such as |
| 419 | (cow-store-service) | 496 | ;; curly quotes as found in the manual. |
| 420 | 497 | '("tty2" . "LatGrkCyr-8x16")) | |
| 421 | ;; Install Unicode support and a suitable font. | 498 | (tty |
| 422 | (service console-font-service-type | 499 | ;; Use a font that doesn't have more than 256 |
| 423 | (map (match-lambda | 500 | ;; glyphs so that we can use colors with varying |
| 424 | ("tty2" | 501 | ;; brightness levels (see note in setfont(8)). |
| 425 | ;; Use a font that contains characters such as | 502 | `(,tty . "lat9u-16"))) |
| 426 | ;; curly quotes as found in the manual. | 503 | '("tty1" "tty2" "tty3" "tty4" "tty5" "tty6"))) |
| 427 | '("tty2" . "LatGrkCyr-8x16")) | 504 | |
| 428 | (tty | 505 | ;; To facilitate copy/paste. |
| 429 | ;; Use a font that doesn't have more than 256 | 506 | (service gpm-service-type) |
| 430 | ;; glyphs so that we can use colors with varying | 507 | |
| 431 | ;; brightness levels (see note in setfont(8)). | 508 | ;; Add an SSH server to facilitate remote installs. |
| 432 | `(,tty . "lat9u-16"))) | 509 | (service openssh-service-type |
| 433 | '("tty1" "tty2" "tty3" "tty4" "tty5" "tty6"))) | 510 | (openssh-configuration |
| 434 | 511 | (port-number 22) | |
| 435 | ;; To facilitate copy/paste. | 512 | (permit-root-login #t) |
| 436 | (service gpm-service-type) | 513 | ;; The root account is passwordless, so make sure |
| 437 | 514 | ;; a password is set before allowing logins. | |
| 438 | ;; Add an SSH server to facilitate remote installs. | 515 | (allow-empty-passwords? #f) |
| 439 | (service openssh-service-type | 516 | (password-authentication? #t) |
| 440 | (openssh-configuration | 517 | |
| 441 | (port-number 22) | 518 | ;; Don't start it upfront. |
| 442 | (permit-root-login #t) | 519 | (%auto-start? #f))) |
| 443 | ;; The root account is passwordless, so make sure | 520 | |
| 444 | ;; a password is set before allowing logins. | 521 | ;; Since this is running on a USB stick with a overlayfs as the root |
| 445 | (allow-empty-passwords? #f) | 522 | ;; file system, use an appropriate cache configuration. |
| 446 | (password-authentication? #t) | 523 | (service nscd-service-type |
| 447 | 524 | (nscd-configuration | |
| 448 | ;; Don't start it upfront. | 525 | (caches %nscd-minimal-caches))) |
| 449 | (%auto-start? #f))) | 526 | |
| 450 | 527 | ;; Having /bin/sh is a good idea. In particular it allows Tramp | |
| 451 | ;; Since this is running on a USB stick with a overlayfs as the root | 528 | ;; connections to this system to work. |
| 452 | ;; file system, use an appropriate cache configuration. | 529 | (service special-files-service-type |
| 453 | (service nscd-service-type | 530 | `(("/bin/sh" ,(file-append bash "/bin/sh")))) |
| 454 | (nscd-configuration | 531 | |
| 455 | (caches %nscd-minimal-caches))) | 532 | ;; Loopback device, needed by OpenSSH notably. |
| 456 | 533 | (service static-networking-service-type | |
| 457 | ;; Having /bin/sh is a good idea. In particular it allows Tramp | 534 | (list %loopback-static-networking)) |
| 458 | ;; connections to this system to work. | 535 | |
| 459 | (service special-files-service-type | 536 | (service wpa-supplicant-service-type) |
| 460 | `(("/bin/sh" ,(file-append bash "/bin/sh")))) | 537 | (service dbus-root-service-type) |
| 461 | 538 | (service connman-service-type | |
| 462 | ;; Loopback device, needed by OpenSSH notably. | 539 | (connman-configuration |
| 463 | (service static-networking-service-type | 540 | (disable-vpn? #t))) |
| 464 | (list %loopback-static-networking)) | 541 | |
| 465 | 542 | ;; Keep a reference to BARE-BONES-OS to make sure it can be | |
| 466 | (service wpa-supplicant-service-type) | 543 | ;; installed without downloading/building anything. Also keep the |
| 467 | (service dbus-root-service-type) | 544 | ;; things needed by 'profile-derivation' to minimize the amount of |
| 468 | (service connman-service-type | 545 | ;; download. |
| 469 | (connman-configuration | 546 | (service gc-root-service-type |
| 470 | (disable-vpn? #t))) | 547 | (append |
| 471 | 548 | (list bare-bones-os | |
| 472 | ;; Keep a reference to BARE-BONES-OS to make sure it can be | 549 | (libc-utf8-locales-for-target system) |
| 473 | ;; installed without downloading/building anything. Also keep the | 550 | texinfo |
| 474 | ;; things needed by 'profile-derivation' to minimize the amount of | 551 | guile-3.0) |
| 475 | ;; download. | 552 | %default-locale-libcs))) |
| 476 | (service gc-root-service-type | 553 | |
| 477 | (append | 554 | ;; Specific system services |
| 478 | (list bare-bones-os | 555 | |
| 479 | (libc-utf8-locales-for-target system) | 556 | ;; AArch64 has a better detection of consoles, mainly because device |
| 480 | texinfo | 557 | ;; trees are utilized. On x86_64, the detection is usually done |
| 481 | guile-3.0) | 558 | ;; through BIOS and consoles do not get registered to /proc/console. |
| 482 | %default-locale-libcs))) | 559 | ;; The only way they would is if the user used console linux argument. |
| 483 | 560 | `(,@(if (target-aarch64? system) | |
| 484 | ;; Specific system services | 561 | (list (service agetty-service-type |
| 485 | 562 | (agetty-configuration (tty #f) | |
| 486 | ;; AArch64 has a better detection of consoles, mainly because device | 563 | (auto-login "root") |
| 487 | ;; trees are utilized. On x86_64, the detection is usually done | 564 | (login-pause? #t) |
| 488 | ;; through BIOS and consoles do not get registered to /proc/console. | 565 | (login-program |
| 489 | ;; The only way they would is if the user used console linux argument. | 566 | %installation-console-login)))) |
| 490 | `(,@(if (target-aarch64? system) | 567 | '())) |
| 491 | (list (service agetty-service-type | 568 | |
| 492 | (agetty-configuration (tty #f) | 569 | ;; Machines without Kernel Mode Setting (those with many old and |
| 493 | (auto-login "root") | 570 | ;; current AMD GPUs, SiS GPUs, ...) need uvesafb to show the GUI |
| 494 | (login-pause? #t)))) | 571 | ;; installer. Some may also need a kernel parameter like nomodeset |
| 495 | '())) | 572 | ;; or vga=793, but we leave that for the user to specify in GRUB. |
| 496 | 573 | `(,@(if (supported-package? v86d system) | |
| 497 | ;; Machines without Kernel Mode Setting (those with many old and | 574 | (list (service uvesafb-service-type)) |
| 498 | ;; current AMD GPUs, SiS GPUs, ...) need uvesafb to show the GUI | 575 | '())))) |
| 499 | ;; installer. Some may also need a kernel parameter like nomodeset | ||
| 500 | ;; or vga=793, but we leave that for the user to specify in GRUB. | ||
| 501 | `(,@(if (supported-package? v86d system) | ||
| 502 | (list (service uvesafb-service-type)) | ||
| 503 | '()))))) | ||
| 504 | 576 | ||
| 505 | (define %issue | 577 | (define %issue |
| 506 | ;; Greeting. | 578 | ;; Greeting. |
