diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index 61cf4be0426..f26501105b1 100644 --- a/modules/misc/ids.nix +++ b/modules/misc/ids.nix @@ -73,7 +73,7 @@ in fprot = 52; bind = 53; wwwrun = 54; - spamd = 55; + spamd = 56; # When adding a uid, make sure it doesn't match an existing gid. @@ -127,6 +127,8 @@ in fprot = 52; wwwrun = 54; adm = 55; + spamd = 56; + networkmanager = 57; # When adding a gid, make sure it doesn't match an existing uid. diff --git a/modules/module-list.nix b/modules/module-list.nix index b56e4acae57..c1ab8edce40 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -83,7 +83,6 @@ ./services/logging/logstash.nix ./services/logging/syslogd.nix ./services/mail/dovecot.nix - ./services/mail/dovecot2.nix ./services/mail/freepops.nix ./services/mail/mail.nix ./services/mail/postfix.nix diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix index 8212b3f9fd0..fa63bc74cfc 100644 --- a/modules/services/audio/alsa.nix +++ b/modules/services/audio/alsa.nix @@ -56,8 +56,9 @@ in '' mkdir -m 0755 -p $(dirname ${soundState}) - # Restore the sound state. - ${alsaUtils}/sbin/alsactl --ignore -f ${soundState} restore + # Try to restore the sound state. + ${alsaUtils}/sbin/alsactl --ignore init || true + ${alsaUtils}/sbin/alsactl --ignore -f ${soundState} restore || true ''; postStop = diff --git a/modules/services/mail/dovecot.nix b/modules/services/mail/dovecot.nix index ff41c8f4302..9a9acf69c51 100644 --- a/modules/services/mail/dovecot.nix +++ b/modules/services/mail/dovecot.nix @@ -4,47 +4,46 @@ with pkgs.lib; let - cfg = config.services.dovecot; + cfg = config.services.dovecot2; dovecotConf = '' - base_dir = /var/run/dovecot/ + base_dir = /var/run/dovecot2/ - protocols = imap imaps pop3 pop3s + protocols = imap pop3 '' + (if cfg.sslServerCert!="" then '' - ssl_cert_file = ${cfg.sslServerCert} - ssl_key_file = ${cfg.sslServerKey} - ssl_ca_file = ${cfg.sslCACert} + ssl_cert = <${cfg.sslServerCert} + ssl_key = <${cfg.sslServerKey} + ssl_ca = <${cfg.sslCACert} + disable_plaintext_auth = yes '' else '' - ssl_disable = yes + ssl = no disable_plaintext_auth = no '') + '' - login_user = ${cfg.user} - login_chroot = no + default_internal_user = ${cfg.user} - mail_location = maildir:/var/spool/mail/%u + mail_location = ${cfg.mailLocation} maildir_copy_with_hardlinks = yes - auth default { - mechanisms = plain login - userdb passwd { - } - passdb pam { - } + auth_mechanisms = plain login + service auth { user = root } - auth_debug = yes - auth_verbose = yes + userdb { + driver = passwd + } + passdb { + driver = pam + args = dovecot2 + } pop3_uidl_format = %08Xv%08Xu - - log_path = /var/log/dovecot.log - ''; + '' + cfg.extraConfig; confFile = pkgs.writeText "dovecot.conf" dovecotConf; @@ -56,23 +55,37 @@ in options = { - services.dovecot = { + services.dovecot2 = { enable = mkOption { default = false; - description = "Whether to enable the Dovecot POP3/IMAP server."; + description = "Whether to enable the Dovecot 2.x POP3/IMAP server."; }; user = mkOption { - default = "dovecot"; + default = "dovecot2"; description = "Dovecot user name."; }; group = mkOption { - default = "dovecot"; + default = "dovecot2"; description = "Dovecot group name."; }; + extraConfig = mkOption { + default = ""; + example = "mail_debug = yes"; + description = "Additional entries to put verbatim into Dovecot's config file."; + }; + + mailLocation = mkOption { + default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */ + example = "maildir:~/mail:INBOX=/var/spool/mail/%u"; + description = '' + Location that dovecot will use for mail folders. Dovecot mail_location option. + ''; + }; + sslServerCert = mkOption { default = ""; description = "Server certificate"; @@ -95,36 +108,44 @@ in ###### implementation - config = mkIf config.services.dovecot.enable { + config = mkIf config.services.dovecot2.enable { - security.pam.services = [ { name = "dovecot"; } ]; + security.pam.services = [ { name = "dovecot2"; } ]; - users.extraUsers = singleton + users.extraUsers = [ { name = cfg.user; - uid = config.ids.uids.dovecot; + uid = config.ids.uids.dovecot2; description = "Dovecot user"; group = cfg.group; - }; + } + { name = "dovenull"; + uid = config.ids.uids.dovenull2; + description = "Dovecot user for untrusted logins"; + group = cfg.group; + } + ]; users.extraGroups = singleton { name = cfg.group; - gid = config.ids.gids.dovecot; + gid = config.ids.gids.dovecot2; }; - jobs.dovecot = + jobs.dovecot2 = { description = "Dovecot IMAP/POP3 server"; startOn = "started networking"; preStart = '' - ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot /var/run/dovecot/login - ${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot + ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot2 /var/run/dovecot2/login + ${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot2 ''; exec = "${pkgs.dovecot}/sbin/dovecot -F -c ${confFile}"; }; + environment.systemPackages = [ pkgs.dovecot ]; + }; } diff --git a/modules/services/mail/dovecot2.nix b/modules/services/mail/dovecot2.nix deleted file mode 100644 index c5f5da41d31..00000000000 --- a/modules/services/mail/dovecot2.nix +++ /dev/null @@ -1,149 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -let - - cfg = config.services.dovecot2; - - dovecotConf = - '' - base_dir = /var/run/dovecot2/ - - protocols = imap pop3 - '' - + (if cfg.sslServerCert!="" then - '' - ssl_cert_file = ${cfg.sslServerCert} - ssl_key_file = ${cfg.sslServerKey} - ssl_ca_file = ${cfg.sslCACert} - '' else '' - ssl = no - disable_plaintext_auth = no - '') - - + '' - default_internal_user = ${cfg.user} - - mail_location = ${cfg.mailLocation} - - maildir_copy_with_hardlinks = yes - - auth_mechanisms = plain login - service auth { - user = root - } - userdb { - driver = passwd - } - passdb { - driver = pam - args = dovecot2 - } - #auth_debug = yes - #auth_verbose = yes - #debug_log_path = /tmp/dovecot2debug.log - - pop3_uidl_format = %08Xv%08Xu - - log_path = /var/log/dovecot2.log - ''; - - confFile = pkgs.writeText "dovecot.conf" dovecotConf; - -in - -{ - - ###### interface - - options = { - - services.dovecot2 = { - - enable = mkOption { - default = false; - description = "Whether to enable the Dovecot 2.x POP3/IMAP server."; - }; - - user = mkOption { - default = "dovecot2"; - description = "Dovecot user name."; - }; - - group = mkOption { - default = "dovecot2"; - description = "Dovecot group name."; - }; - - mailLocation = mkOption { - default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */ - example = "maildir:~/mail:INBOX=/var/spool/mail/%u"; - description = '' - Location that dovecot will use for mail folders. Dovecot mail_location option. - ''; - }; - - sslServerCert = mkOption { - default = ""; - description = "Server certificate"; - }; - - sslCACert = mkOption { - default = ""; - description = "CA certificate used by the server certificate."; - }; - - sslServerKey = mkOption { - default = ""; - description = "Server key."; - }; - - }; - - }; - - - ###### implementation - - config = mkIf config.services.dovecot2.enable { - - security.pam.services = [ { name = "dovecot2"; } ]; - - users.extraUsers = [ - { name = cfg.user; - uid = config.ids.uids.dovecot2; - description = "Dovecot user"; - group = cfg.group; - } - { name = "dovenull"; - uid = config.ids.uids.dovenull2; - description = "Dovecot user for untrusted logins"; - group = cfg.group; - } - ]; - - users.extraGroups = singleton - { name = cfg.group; - gid = config.ids.gids.dovecot2; - }; - - jobs.dovecot2 = - { description = "Dovecot IMAP/POP3 server"; - - startOn = "started networking"; - - preStart = - '' - ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot2 /var/run/dovecot2/login - ${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot2 - ''; - - exec = "${pkgs.dovecot_2_0}/sbin/dovecot -F -c ${confFile}"; - }; - - environment.systemPackages = [ pkgs.dovecot_2_0 ]; - - }; - -} diff --git a/modules/services/mail/postfix.nix b/modules/services/mail/postfix.nix index d4505818e0c..6b141e7e24e 100644 --- a/modules/services/mail/postfix.nix +++ b/modules/services/mail/postfix.nix @@ -85,6 +85,45 @@ let '' + cfg.extraConfig; + masterCf = '' + # ========================================================================== + # service type private unpriv chroot wakeup maxproc command + args + # (yes) (yes) (yes) (never) (100) + # ========================================================================== + smtp inet n - n - - smtpd + #submission inet n - n - - smtpd + # -o smtpd_tls_security_level=encrypt + # -o smtpd_sasl_auth_enable=yes + # -o smtpd_client_restrictions=permit_sasl_authenticated,reject + # -o milter_macro_daemon_name=ORIGINATING + pickup fifo n - n 60 1 pickup + cleanup unix n - n - 0 cleanup + qmgr fifo n - n 300 1 qmgr + tlsmgr unix - - n 1000? 1 tlsmgr + rewrite unix - - n - - trivial-rewrite + bounce unix - - n - 0 bounce + defer unix - - n - 0 bounce + trace unix - - n - 0 bounce + verify unix - - n - 1 verify + flush unix n - n 1000? 0 flush + proxymap unix - - n - - proxymap + proxywrite unix - - n - 1 proxymap + smtp unix - - n - - smtp + relay unix - - n - - smtp + -o smtp_fallback_relay= + # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 + showq unix n - n - - showq + error unix - - n - - error + retry unix - - n - - error + discard unix - - n - - discard + local unix - n n - - local + virtual unix - n n - - virtual + lmtp unix - - n - - lmtp + anvil unix - - n - 1 anvil + scache unix - - n - 1 scache + ${cfg.extraMasterConf} + ''; + aliases = optionalString (cfg.postmasterAlias != "") '' postmaster: ${cfg.postmasterAlias} @@ -98,6 +137,7 @@ let aliasesFile = pkgs.writeText "postfix-aliases" aliases; virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual; mainCfFile = pkgs.writeText "postfix-main.cf" mainCf; + masterCfFile = pkgs.writeText "postfix-master.cf" masterCf; in @@ -232,7 +272,7 @@ in extraConfig = mkOption { default = ""; description = " - Extra configuration, will be added verbatim to the configuration file. + Extra lines to be added verbatim to the main.cf configuration file. "; }; @@ -266,6 +306,12 @@ in "; }; + extraMasterConf = mkOption { + default = ""; + example = "submission inet n - n - - smtpd"; + description = "Extra lines to append to the generated master.cf file."; + }; + }; }; @@ -342,6 +388,7 @@ in ln -sf ${aliasesFile} /var/postfix/conf/aliases ln -sf ${virtualFile} /var/postfix/conf/virtual ln -sf ${mainCfFile} /var/postfix/conf/main.cf + ln -sf ${masterCfFile} /var/postfix/conf/master.cf ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual diff --git a/modules/services/mail/spamassassin.nix b/modules/services/mail/spamassassin.nix index 9b387eb940f..d4dbe8ddbd0 100644 --- a/modules/services/mail/spamassassin.nix +++ b/modules/services/mail/spamassassin.nix @@ -21,6 +21,11 @@ in description = "Whether to run the SpamAssassin daemon."; }; + debug = mkOption { + default = false; + description = "Whether to run the SpamAssassin daemon in debug mode."; + }; + }; }; @@ -33,17 +38,23 @@ in # Allow users to run 'spamc'. environment.systemPackages = [ pkgs.spamassassin ]; - users.extraUsers = singleton - { name = "spamd"; - description = "Spam Assassin Daemon"; - uid = config.ids.uids.spamd; - }; + users.extraUsers = singleton { + name = "spamd"; + description = "Spam Assassin Daemon"; + uid = config.ids.uids.spamd; + group = "spamd"; + }; + + users.extraGroups = singleton { + name = "spamd"; + gid = config.ids.gids.spamd; + }; jobs.spamd = { description = "Spam Assassin Server"; startOn = "started networking and filesystem"; environment.TZ = config.time.timeZone; - exec = "${pkgs.spamassassin}/bin/spamd -C /etc/spamassassin/init.pre --siteconfigpath=/etc/spamassassin --username=spamd --pidfile=/var/run/spamd.pid"; + exec = "${pkgs.spamassassin}/bin/spamd ${optionalString cfg.debug "-D"} --username=spamd --groupname=spamd --nouser-config --virtual-config-dir=/var/lib/spamassassin/user-%u --allow-tell --pidfile=/var/run/spamd.pid"; }; }; diff --git a/modules/services/monitoring/nagios/default.nix b/modules/services/monitoring/nagios/default.nix index 3c32a3c25ec..c809a3b8457 100644 --- a/modules/services/monitoring/nagios/default.nix +++ b/modules/services/monitoring/nagios/default.nix @@ -179,12 +179,7 @@ in ''; }; - services.httpd = mkIf cfg.enableWebInterface { - extraConfig = mkThenElse { - thenPart = extraHttpdConfig; - elsePart = ""; - }; - }; + services.httpd.extraConfig = optionalString cfg.enableWebInterface extraHttpdConfig; }; diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index 64cfcef124a..e6ae725f85f 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -33,7 +33,9 @@ let # Helper command to manipulate both the IPv4 and IPv6 tables. ip46tables() { iptables "$@" - ip6tables "$@" + ${optionalString config.networking.enableIPv6 '' + ip6tables "$@" + ''} } ''; @@ -96,6 +98,15 @@ in ''; }; + networking.firewall.trustedInterfaces = mkOption { + type = types.list types.string; + description = + '' + Traffic coming in from these interfaces will be accepted + unconditionally. + ''; + }; + networking.firewall.allowedTCPPorts = mkOption { default = []; example = [ 22 80 ]; @@ -153,6 +164,8 @@ in # holds). config = mkIf cfg.enable { + networking.firewall.trustedInterfaces = [ "lo" ]; + environment.systemPackages = [ pkgs.iptables ]; boot.kernelModules = [ "nf_conntrack_ftp" ]; @@ -220,8 +233,10 @@ in # The "nixos-fw" chain does the actual work. ip46tables -N nixos-fw - # Accept all traffic on the loopback interface. - ip46tables -A nixos-fw -i lo -j nixos-fw-accept + # Accept all traffic on the trusted interfaces. + ${flip concatMapStrings cfg.trustedInterfaces (iface: '' + ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept + '')} # Accept packets from established or related connections. ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept diff --git a/modules/services/networking/networkmanager.nix b/modules/services/networking/networkmanager.nix index c33bbad83b3..591f34ceee7 100644 --- a/modules/services/networking/networkmanager.nix +++ b/modules/services/networking/networkmanager.nix @@ -3,12 +3,47 @@ with pkgs.lib; let + cfg = config.networking.networkmanager; - stateDir = "/var/lib/NetworkManager"; + stateDirs = "/var/lib/NetworkManager /var/lib/dhclient"; -in + configFile = pkgs.writeText "NetworkManager.conf" '' + [main] + plugins=keyfile -{ + [keyfile] + ${optionalString (config.networking.hostName != "") '' + hostname=${config.networking.hostName} + ''} + + [logging] + level=WARN + ''; + + polkitConf = '' + [network-manager] + Identity=unix-group:networkmanager + Action=org.freedesktop.NetworkManager.* + ResultAny=yes + ResultInactive=no + ResultActive=yes + + [modem-manager] + Identity=unix-group:networkmanager + Action=org.freedesktop.ModemManager.* + ResultAny=yes + ResultInactive=no + ResultActive=yes + ''; + + ipUpScript = pkgs.writeScript "01nixos-ip-up" '' + #!/bin/sh + if test "$2" = "up"; then + ${pkgs.upstart}/sbin/initctl emit ip-up "IFACE=$1" + fi + ''; + +in { ###### interface @@ -20,61 +55,62 @@ in description = '' Whether to use NetworkManager to obtain an IP adress and other configuration for all network interfaces that are not manually - configured. + configured. If enabled, a group networkmanager + will be created. Add all users that should have permission + to change network settings to this group. ''; }; networking.networkmanager.packages = mkOption { - default = [ pkgs.networkmanager ]; - description = - '' - Packages providing NetworkManager plugins. - ''; + default = [ ]; + description = '' + Extra packages that provide NetworkManager plugins. + ''; + merge = mergeListOption; + apply = list: [ pkgs.networkmanager pkgs.modemmanager ] ++ list; }; }; ###### implementation - config = mkIf config.networking.networkmanager.enable { + config = mkIf cfg.enable { - jobs.networkmanager = - { startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; + environment.etc = singleton { + source = ipUpScript; + target = "NetworkManager/dispatcher.d/01nixos-ip-up"; + }; - script = - '' - mkdir -m 755 -p /etc/NetworkManager - mkdir -m 700 -p /etc/NetworkManager/system-connections - mkdir -m 755 -p ${stateDir} + environment.systemPackages = cfg.packages; - if [[ ! -f /etc/NetworkManager/NetworkManager.conf ]]; then - cat <<-EOF > /etc/NetworkManager/NetworkManager.conf - [main] - plugins=keyfile - EOF - fi + users.extraGroups = singleton { + name = "networkmanager"; + gid = config.ids.gids.networkmanager; + }; - exec ${pkgs.networkmanager}/sbin/NetworkManager --no-daemon - ''; - }; + jobs.networkmanager = { + startOn = "started network-interfaces"; + stopOn = "stopping network-interfaces"; + + path = [ pkgs.networkmanager ]; + + preStart = '' + mkdir -m 755 -p /etc/NetworkManager + mkdir -m 700 -p /etc/NetworkManager/system-connections + mkdir -m 755 -p ${stateDirs} + ''; + + exec = "NetworkManager --config=${configFile} --no-daemon"; + }; - environment.systemPackages = config.networking.networkmanager.packages; - services.dbus.packages = config.networking.networkmanager.packages; networking.useDHCP = false; - environment.etc = [ - { - source = pkgs.writeScript "01nixos-ip-up" - '' - #!/bin/sh - if test "$2" = "up"; then - ${pkgs.upstart}/sbin/initctl emit ip-up "IFACE=$1" - fi - ''; - target = "NetworkManager/dispatcher.d/01nixos-ip-up"; - } - ]; + networking.wireless.enable = true; + + security.polkit.permissions = polkitConf; + + services.dbus.packages = cfg.packages; + + services.udev.packages = cfg.packages; }; } - diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index 620424b94a0..54e661896d9 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -58,6 +58,8 @@ in Type=forking PIDFile=/run/nscd/nscd.pid Restart=always + ExecReload=${pkgs.glibc}/sbin/nscd --invalidate passwd + ExecReload=${pkgs.glibc}/sbin/nscd --invalidate group ExecReload=${pkgs.glibc}/sbin/nscd --invalidate hosts ''; }; diff --git a/modules/services/x11/desktop-managers/xfce.nix b/modules/services/x11/desktop-managers/xfce.nix index 3fead2e96cb..d06eb23b8e9 100644 --- a/modules/services/x11/desktop-managers/xfce.nix +++ b/modules/services/x11/desktop-managers/xfce.nix @@ -7,8 +7,6 @@ let xcfg = config.services.xserver; cfg = xcfg.desktopManager.xfce; - isXfce48 = pkgs.xfce ? libxfce4ui; - in { @@ -45,8 +43,7 @@ in }; environment.systemPackages = - [ - pkgs.gtk # To get GTK+'s themes. + [ pkgs.gtk # To get GTK+'s themes. pkgs.hicolor_icon_theme pkgs.shared_mime_info pkgs.which # Needed by the xfce's xinitrc script. @@ -70,8 +67,6 @@ in # "utilities-terminal" and "accessories-text-editor". pkgs.gnome.gnomeicontheme pkgs.desktop_file_utils - ] - ++ optionals isXfce48 [ pkgs.xfce.libxfce4ui pkgs.xfce.garcon pkgs.xfce.thunar_volman @@ -83,14 +78,14 @@ in environment.pathsToLink = [ "/share/xfce4" "/share/themes" "/share/mime" "/share/desktop-directories" ]; - environment.shellInit = optionalString isXfce48 + environment.shellInit = '' export GIO_EXTRA_MODULES=${pkgs.xfce.gvfs}/lib/gio/modules ''; # Enable helpful DBus services. - services.udisks = mkIf isXfce48 { enable = true; }; - services.upower = mkIf (isXfce48 && config.powerManagement.enable) { enable = true; }; + services.udisks.enable = true; + services.upower.enable = config.powerManagement.enable; }; diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index d64a37e6692..9c04757e131 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -136,6 +136,10 @@ modprobe scsi_wait_scan || true udevadm settle || true +# Load boot-time keymap before any LVM/LUKS initialization +@extraUtils@/bin/busybox loadkmap < "@busyboxKeymap@" + + # XXX: Use case usb->lvm will still fail, usb->luks->lvm is covered @preLVMCommands@ diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index 97f1aa516e8..18d11e2d402 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -280,6 +280,15 @@ let }; + # The binary keymap for busybox to load at boot. + busyboxKeymap = pkgs.runCommand "boottime-keymap" + { preferLocalBuild = true; } + '' + ${pkgs.kbd}/bin/loadkeys -qb "${config.i18n.consoleKeyMap}" > $out || + ${pkgs.kbd}/bin/loadkeys -qbu "${config.i18n.consoleKeyMap}" > $out + ''; + + # The init script of boot stage 1 (loading kernel modules for # mounting the root FS). bootStage1 = pkgs.substituteAll { @@ -289,7 +298,7 @@ let isExecutable = true; - inherit udevRules extraUtils modulesClosure; + inherit udevRules extraUtils modulesClosure busyboxKeymap; inherit (config.boot) resumeDevice devSize runSize; diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index ab58c0757b6..e81ebd66004 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -156,6 +156,16 @@ in description = "Names of supported filesystem types in the initial ramdisk."; }; + boot.ttyEmergency = mkOption { + default = + if pkgs.stdenv.isArm + then "ttyS0" # presumably an embedded platform such as a plug + else "tty1"; + description = '' + The tty that will be stopped in case an emergency shell is spawned + at boot. + ''; + }; }; @@ -248,7 +258,7 @@ in status="$(status xserver || true)" [[ "$status" =~ start/ ]] && exit 0 - stop tty1 || true + stop ${config.boot.ttyEmergency} || true start --no-wait emergency-shell \ DEVICE="$DEVICE" MOUNTPOINT="$MOUNTPOINT"