From f21aa7d22cc8128f6c60632e3108bacf69351dac Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 1 Jun 2012 20:15:07 -0400 Subject: [PATCH 001/327] First attempt at using systemd Basic booting works. Systemd starts agetty instances on tty1 and tty2. Shutdown and journald also work. --- modules/config/system-path.nix | 1 - modules/module-list.nix | 1 + modules/system/activation/top-level.nix | 6 +- modules/system/boot/stage-2-init.sh | 14 ++- modules/system/boot/systemd.nix | 158 ++++++++++++++++++++++++ 5 files changed, 172 insertions(+), 8 deletions(-) create mode 100644 modules/system/boot/systemd.nix diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix index 9eab8dde473d..2a25cd411a1d 100644 --- a/modules/config/system-path.nix +++ b/modules/config/system-path.nix @@ -17,7 +17,6 @@ let requiredPackages = [ config.system.sbin.modprobe # must take precedence over module_init_tools - config.system.build.upstart config.environment.nix pkgs.acl pkgs.attr diff --git a/modules/module-list.nix b/modules/module-list.nix index 48171f62150c..870d316006fc 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -198,6 +198,7 @@ ./system/boot/stage-1.nix ./system/boot/stage-1-extratools.nix ./system/boot/stage-2.nix + ./system/boot/systemd.nix ./system/etc/etc.nix ./system/upstart-events/control-alt-delete.nix ./system/upstart-events/runlevel.nix diff --git a/modules/system/activation/top-level.nix b/modules/system/activation/top-level.nix index 3edc92d502cc..ef32d991d9d6 100644 --- a/modules/system/activation/top-level.nix +++ b/modules/system/activation/top-level.nix @@ -117,12 +117,12 @@ let ln -s ${config.system.build.etc}/etc $out/etc ln -s ${config.system.path} $out/sw - ln -s ${config.system.build.upstart} $out/upstart + ln -s ${pkgs.systemd} $out/systemd ln -s ${config.hardware.firmware} $out/firmware echo -n "$kernelParams" > $out/kernel-params echo -n "$configurationName" > $out/configuration-name - echo -n "${toString config.system.build.upstart.interfaceVersion}" > $out/upstart-interface-version + #echo -n "${toString config.system.build.upstart.interfaceVersion}" > $out/upstart-interface-version echo -n "$nixosVersion" > $out/nixos-version mkdir $out/fine-tune @@ -173,7 +173,7 @@ let pkgs.gnugrep pkgs.findutils pkgs.diffutils - config.system.build.upstart # for initctl + pkgs.systemd ]; # Boot loaders diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index bd48f463dcd6..33d0a6ad3e81 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -56,7 +56,7 @@ fi mkdir -m 0755 -p /etc test -e /etc/fstab || touch /etc/fstab # to shut up mount rm -f /etc/mtab* # not that we care about stale locks -cat /proc/mounts > /etc/mtab +ln -s /proc/mounts /etc/mtab # Process the kernel command line. @@ -184,6 +184,12 @@ if [ -n "$debug2" ]; then fi -# Start Upstart's init. -echo "starting Upstart..." -PATH=/var/run/current-system/upstart/sbin exec init --no-sessions ${debug2:+--verbose} +# FIXME: auto-loading of kernel modules in systemd doesn't work yet +# because it uses libkmod. +"$(cat /proc/sys/kernel/modprobe)" autofs4 +"$(cat /proc/sys/kernel/modprobe)" ipv6 + + +# Start systemd. +echo "starting systemd..." +PATH=/var/run/current-system/systemd/lib/systemd exec systemd --log-level debug --log-target=console --crash-shell diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix new file mode 100644 index 000000000000..3b51ebf43fc0 --- /dev/null +++ b/modules/system/boot/systemd.nix @@ -0,0 +1,158 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + systemd = pkgs.systemd; + + makeUnit = name: text: + pkgs.writeTextFile { name = "unit"; inherit text; destination = "/${name}"; }; + + defaultTarget = makeUnit "default.target" + '' + [Unit] + Description=Default System + Requires=getty.target + After=getty.target + Conflicts=rescue.target + AllowIsolate=yes + ''; + + gettyTarget = makeUnit "getty.target" + '' + [Unit] + Description=Login Prompts + Requires=getty@tty1.service getty@tty2.service + After=getty@tty1.service getty@tty2.service + ''; + + gettyService = makeUnit "getty@.service" + '' + [Unit] + Description=Getty on %I + #BindTo=dev-%i.device + #After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service + Before=getty.target + + [Service] + Environment=TERM=linux + ExecStart=-${pkgs.utillinux}/sbin/agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 + Restart=always + RestartSec=0 + UtmpIdentifier=%I + TTYPath=/dev/%I + TTYReset=yes + TTYVHangup=yes + TTYVTDisallocate=yes + KillMode=process + IgnoreSIGPIPE=no + + # Unset locale for the console getty since the console has problems + # displaying some internationalized messages. + Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= + + # Some login implementations ignore SIGTERM, so we send SIGHUP + # instead, to ensure that login terminates cleanly. + KillSignal=SIGHUP + ''; + + rescueTarget = makeUnit "rescue.target" + '' + [Unit] + Description=Rescue Mode + Requires=rescue.service + After=rescue.service + AllowIsolate=yes + ''; + + rescueService = makeUnit "rescue.service" + '' + [Unit] + Description=Rescue Shell + DefaultDependencies=no + #After=basic.target + #Before=shutdown.target + + [Service] + Environment=HOME=/root + WorkingDirectory=/root + ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.' + #ExecStart=-/sbin/sulogin + ExecStart=-${pkgs.bashInteractive}/bin/bash --login + ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default + StandardInput=tty-force + StandardOutput=inherit + StandardError=inherit + KillMode=process + + # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash + # terminates cleanly. + KillSignal=SIGHUP + ''; + + upstreamUnits = + [ "systemd-journald.socket" + "systemd-journald.service" + "basic.target" + "sysinit.target" + "sysinit.target.wants" + "sockets.target" + "sockets.target.wants" + + # Filesystems. + "local-fs.target" + "local-fs.target.wants" + "local-fs-pre.target" + "remote-fs.target" + "remote-fs-pre.target" + "swap.target" + "media.mount" + "dev-mqueue.mount" + + # Reboot stuff. + "reboot.target" + "reboot.service" + "poweroff.target" + "poweroff.service" + "halt.target" + "halt.service" + "ctrl-alt-del.target" + "shutdown.target" + "umount.target" + "final.target" + ]; + + systemUnits = pkgs.runCommand "system-units" { } + '' + mkdir -p $out/system + for i in ${toString upstreamUnits}; do + fn=${systemd}/example/systemd/system/$i + echo $fn + [ -e $fn ] + ln -s $fn $out/system + done + for i in ${toString [ defaultTarget gettyTarget gettyService rescueTarget rescueService ]}; do + cp $i/* $out/system + done + ''; # */ + +in + +{ + + ###### implementation + + config = { + + environment.systemPackages = [ systemd ]; + + environment.etc = + [ { source = systemUnits; + target = "systemd"; + } + ]; + + }; + +} From a46894b960c47348eef2a682ea5e0597d8c7b2c5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 14 Jun 2012 18:44:56 -0400 Subject: [PATCH 002/327] Get lots more systemd stuff working MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabled a bunch of units that ship with systemd. Also added an option ‘boot.systemd.units’ that can be used to define additional units (e.g. ‘sshd.service’). --- modules/services/networking/ssh/sshd.nix | 35 ++- modules/services/system/dbus.nix | 26 +++ modules/system/boot/stage-2-init.sh | 5 +- modules/system/boot/stage-2.nix | 1 - modules/system/boot/systemd.nix | 261 +++++++++++++++-------- modules/system/upstart/upstart.nix | 2 + 6 files changed, 234 insertions(+), 96 deletions(-) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 53efc08cfb89..e4ca7f39a568 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -127,6 +127,18 @@ let ${userLoop} ''; + preStart = pkgs.writeScript "openssh-pre-start" + '' + #! ${pkgs.stdenv.shell} + + ${mkAuthkeyScript} + + mkdir -m 0755 -p /etc/ssh + + if ! test -f ${cfg.hostKeyPath}; then + ssh-keygen -t ${hktn} -b ${toString hktb} -f ${cfg.hostKeyPath} -N "" + fi + ''; in @@ -305,9 +317,26 @@ in } ]; - jobs.sshd = { + boot.systemd.units."sshd.service" = + '' + [Unit] + Description=SSH daemon - description = "OpenSSH server"; + [Service] + Environment=PATH=${pkgs.coreutils}/bin:${pkgs.openssh}/bin + ExecStartPre=${preStart} + ExecStart=\ + ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ + -f ${pkgs.writeText "sshd_config" cfg.extraConfig} + Restart=always + RestartSec=5 + Type=forking + KillMode=process + PIDFile=/run/sshd.pid + ''; + + jobs.sshd = + { description = "OpenSSH server"; startOn = "started network-interfaces"; @@ -343,6 +372,8 @@ in services.openssh.extraConfig = '' + PidFile /run/sshd.pid + Protocol 2 UsePAM ${if cfg.usePAM then "yes" else "no"} diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix index f7fbb23d0a78..8659c784483f 100644 --- a/modules/services/system/dbus.nix +++ b/modules/services/system/dbus.nix @@ -116,6 +116,32 @@ in gid = config.ids.gids.messagebus; }; + # FIXME: these are copied verbatim from the dbus source tree. We + # should install and use the originals. + boot.systemd.units."dbus.socket" = + '' + [Unit] + Description=D-Bus System Message Bus Socket + + [Socket] + ListenStream=/var/run/dbus/system_bus_socket + ''; + + boot.systemd.units."dbus.service" = + '' + [Unit] + Description=D-Bus System Message Bus + Requires=dbus.socket + After=syslog.target + + [Service] + ExecStartPre=${pkgs.dbus_tools}/bin/dbus-uuidgen --ensure + ExecStartPre=-${pkgs.coreutils}/bin/rm -f /var/run/dbus/pid + ExecStart=${pkgs.dbus_daemon}/bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation + ExecReload=${pkgs.dbus_tools}/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig + OOMScoreAdjust=-900 + ''; + jobs.dbus = { startOn = "started udev and started syslogd"; diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 9e0ed028d5dd..42dd21b6204d 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -90,12 +90,13 @@ mkdir -m 0755 -p /dev/pts mount -t devpts -o mode=0600,gid=@ttyGid@ none /dev/pts [ -e /proc/bus/usb ] && mount -t usbfs none /proc/bus/usb # UML doesn't have USB by default mkdir -m 01777 -p /tmp -mkdir -m 0755 -p /var +mkdir -m 0755 -p /var /var/log mkdir -m 0755 -p /nix/var mkdir -m 0700 -p /root mkdir -m 0755 -p /bin # for the /bin/sh symlink mkdir -m 0755 -p /home mkdir -m 0755 -p /etc/nixos +mkdir -m 0700 -p /var/log/journal # Miscellaneous boot time cleanup. @@ -195,4 +196,4 @@ fi # Start systemd. echo "starting systemd..." -PATH=/var/run/current-system/systemd/lib/systemd exec systemd --log-level debug --log-target=console --crash-shell +PATH=/var/run/current-system/systemd/lib/systemd exec systemd --log-target journal --log-level debug --crash-shell diff --git a/modules/system/boot/stage-2.nix b/modules/system/boot/stage-2.nix index 02c061dacde2..a5e96cc0f1cf 100644 --- a/modules/system/boot/stage-2.nix +++ b/modules/system/boot/stage-2.nix @@ -61,7 +61,6 @@ let isExecutable = true; inherit (config.boot) devShmSize runSize cleanTmpDir; ttyGid = config.ids.gids.tty; - upstart = config.system.build.upstart; path = [ pkgs.coreutils pkgs.utillinux diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 3b51ebf43fc0..4555b59d2783 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -9,106 +9,71 @@ let makeUnit = name: text: pkgs.writeTextFile { name = "unit"; inherit text; destination = "/${name}"; }; - defaultTarget = makeUnit "default.target" - '' - [Unit] - Description=Default System - Requires=getty.target - After=getty.target - Conflicts=rescue.target - AllowIsolate=yes - ''; - - gettyTarget = makeUnit "getty.target" - '' - [Unit] - Description=Login Prompts - Requires=getty@tty1.service getty@tty2.service - After=getty@tty1.service getty@tty2.service - ''; - - gettyService = makeUnit "getty@.service" - '' - [Unit] - Description=Getty on %I - #BindTo=dev-%i.device - #After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service - Before=getty.target - - [Service] - Environment=TERM=linux - ExecStart=-${pkgs.utillinux}/sbin/agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 - Restart=always - RestartSec=0 - UtmpIdentifier=%I - TTYPath=/dev/%I - TTYReset=yes - TTYVHangup=yes - TTYVTDisallocate=yes - KillMode=process - IgnoreSIGPIPE=no - - # Unset locale for the console getty since the console has problems - # displaying some internationalized messages. - Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= - - # Some login implementations ignore SIGTERM, so we send SIGHUP - # instead, to ensure that login terminates cleanly. - KillSignal=SIGHUP - ''; - - rescueTarget = makeUnit "rescue.target" - '' - [Unit] - Description=Rescue Mode - Requires=rescue.service - After=rescue.service - AllowIsolate=yes - ''; - - rescueService = makeUnit "rescue.service" - '' - [Unit] - Description=Rescue Shell - DefaultDependencies=no - #After=basic.target - #Before=shutdown.target - - [Service] - Environment=HOME=/root - WorkingDirectory=/root - ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.' - #ExecStart=-/sbin/sulogin - ExecStart=-${pkgs.bashInteractive}/bin/bash --login - ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default - StandardInput=tty-force - StandardOutput=inherit - StandardError=inherit - KillMode=process - - # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash - # terminates cleanly. - KillSignal=SIGHUP - ''; - upstreamUnits = - [ "systemd-journald.socket" - "systemd-journald.service" + [ # Targets. "basic.target" "sysinit.target" - "sysinit.target.wants" "sockets.target" - "sockets.target.wants" + "graphical.target" + "multi-user.target" + "getty.target" + "rescue.target" + "network.target" + "nss-lookup.target" + "nss-user-lookup.target" + "syslog.target" + "time-sync.target" + # Login stuff. + "systemd-logind.service" + "autovt@.service" + "systemd-vconsole-setup.service" + "systemd-user-sessions.service" + + # Journal. + "systemd-journald.socket" + "systemd-journald.service" + + # SysV init compatibility. + "systemd-initctl.socket" + "systemd-initctl.service" + "runlevel0.target" + "runlevel1.target" + "runlevel2.target" + "runlevel3.target" + "runlevel4.target" + "runlevel5.target" + "runlevel6.target" + + # Random seed. + "systemd-random-seed-load.service" + "systemd-random-seed-save.service" + + # Utmp maintenance. + "systemd-update-utmp-runlevel.service" + "systemd-update-utmp-shutdown.service" + # Filesystems. + "fsck@.service" + "fsck-root.service" + "systemd-remount-fs.service" "local-fs.target" - "local-fs.target.wants" "local-fs-pre.target" "remote-fs.target" "remote-fs-pre.target" "swap.target" - "media.mount" + "dev-hugepages.mount" "dev-mqueue.mount" + "sys-fs-fuse-connections.mount" + "sys-kernel-config.mount" + "sys-kernel-debug.mount" + + # Hibernate / suspend. + "hibernate.target" + "hibernate.service" + "suspend.target" + "suspend.service" + "sleep.target" # Reboot stuff. "reboot.target" @@ -121,18 +86,46 @@ let "shutdown.target" "umount.target" "final.target" + + # Misc. + "syslog.socket" ]; + upstreamWants = + [ "basic.target.wants" + "sysinit.target.wants" + "sockets.target.wants" + "local-fs.target.wants" + "multi-user.target.wants" + "shutdown.target.wants" + ]; + + nixosUnits = mapAttrsToList makeUnit config.boot.systemd.units; + systemUnits = pkgs.runCommand "system-units" { } '' mkdir -p $out/system for i in ${toString upstreamUnits}; do fn=${systemd}/example/systemd/system/$i - echo $fn [ -e $fn ] - ln -s $fn $out/system + if [ -L $fn ]; then + cp -pd $fn $out/system/ + else + ln -s $fn $out/system + fi done - for i in ${toString [ defaultTarget gettyTarget gettyService rescueTarget rescueService ]}; do + for i in ${toString upstreamWants}; do + fn=${systemd}/example/systemd/system/$i + [ -e $fn ] + x=$out/system/$(basename $fn) + mkdir $x + for i in $fn/*; do + y=$x/$(basename $i) + cp -pd $i $y + if ! [ -e $y ]; then rm -v $y; fi + done + done + for i in ${toString nixosUnits}; do cp $i/* $out/system done ''; # */ @@ -141,6 +134,18 @@ in { + ###### interface + + options = { + + boot.systemd.units = mkOption { + default = {} ; + description = "Systemd units."; + }; + + }; + + ###### implementation config = { @@ -152,7 +157,81 @@ in target = "systemd"; } ]; + + boot.systemd.units."default.target" = + '' + [Unit] + Description=Default System + Requires=multi-user.target + After=multi-user.target + Conflicts=rescue.target + AllowIsolate=yes + Wants=sshd.service autovt@tty1.service # FIXME + ''; + boot.systemd.units."getty@.service" = + '' + [Unit] + Description=Getty on %I + Documentation=man:agetty(8) + After=systemd-user-sessions.service plymouth-quit-wait.service + + # If additional gettys are spawned during boot then we should make + # sure that this is synchronized before getty.target, even though + # getty.target didn't actually pull it in. + Before=getty.target + IgnoreOnIsolate=yes + + [Service] + Environment=TERM=linux + ExecStart=-${pkgs.utillinux}/sbin/agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 + Type=idle + Restart=always + RestartSec=0 + UtmpIdentifier=%I + TTYPath=/dev/%I + TTYReset=yes + TTYVHangup=yes + TTYVTDisallocate=yes + KillMode=process + IgnoreSIGPIPE=no + + # Unset locale for the console getty since the console has problems + # displaying some internationalized messages. + Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= + + # Some login implementations ignore SIGTERM, so we send SIGHUP + # instead, to ensure that login terminates cleanly. + KillSignal=SIGHUP + ''; + + boot.systemd.units."rescue.service" = + '' + [Unit] + Description=Rescue Shell + DefaultDependencies=no + Conflicts=shutdown.target + After=sysinit.target + Before=shutdown.target + + [Service] + Environment=HOME=/root + WorkingDirectory=/root + ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.' + #ExecStart=-/sbin/sulogin + ExecStart=-${pkgs.bashInteractive}/bin/bash --login + ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default + Type=idle + StandardInput=tty-force + StandardOutput=inherit + StandardError=inherit + KillMode=process + + # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash + # terminates cleanly. + KillSignal=SIGHUP + ''; + }; } diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 1bfde9fc60ee..284f1aafd37d 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -476,6 +476,7 @@ in system.build.upstart = upstart; + /* environment.etc = flip map (attrValues config.jobs) (job: { source = job.jobDrv; @@ -492,6 +493,7 @@ in ${optionalString (job.setuid != "") "chown ${job.setuid} /var/log/upstart/${job.name}"} ${optionalString (job.setgid != "") "chown :${job.setgid} /var/log/upstart/${job.name}"} '') (attrValues config.jobs)); + */ }; From 164d6e6ab24669d5d6335fad72e9ec95aa4ccce5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 15 Jun 2012 13:09:22 -0400 Subject: [PATCH 003/327] Use udev from systemd --- modules/services/hardware/udev.nix | 95 +++++------------------------- modules/system/boot/systemd.nix | 10 ++++ 2 files changed, 24 insertions(+), 81 deletions(-) diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix index 0b63d7543ea0..81a9b570127b 100644 --- a/modules/services/hardware/udev.nix +++ b/modules/services/hardware/udev.nix @@ -4,7 +4,9 @@ with pkgs.lib; let - inherit (pkgs) stdenv writeText udev procps; + inherit (pkgs) stdenv writeText procps; + + udev = config.system.build.systemd; cfg = config.services.udev; @@ -18,26 +20,23 @@ let # Miscellaneous devices. KERNEL=="kvm", MODE="0666" KERNEL=="kqemu", MODE="0666" + KERNEL=="null", MODE="0777" ''; # Perform substitutions in all udev rules files. udevRules = stdenv.mkDerivation { name = "udev-rules"; buildCommand = '' - ensureDir $out + mkdir -p $out shopt -s nullglob # Set a reasonable $PATH for programs called by udev rules. echo 'ENV{PATH}="${udevPath}/bin:${udevPath}/sbin"' > $out/00-path.rules - # Set the firmware search path so that the firmware.sh helper - # called by 50-firmware.rules works properly. - echo 'ENV{FIRMWARE_DIRS}="/root/test-firmware ${toString config.hardware.firmware}"' >> $out/00-path.rules - # Add the udev rules from other packages. for i in ${toString cfg.packages}; do echo "Adding rules for package $i" - for j in $i/*/udev/rules.d/*; do + for j in $i/{etc,lib}/udev/rules.d/*; do echo "Copying $j to $out/$(basename $j)" echo "# Copied from $j" > $out/$(basename $j) cat $j >> $out/$(basename $j) @@ -53,11 +52,6 @@ let --replace \"/bin/mount \"${pkgs.utillinux}/bin/mount done - # If auto-configuration is disabled, then remove - # udev's 80-drivers.rules file, which contains rules for - # automatically calling modprobe. - ${if !config.boot.hardwareScan then "rm $out/80-drivers.rules" else ""} - echo -n "Checking that all programs called by relative paths in udev rules exist in ${udev}/lib/udev ... " import_progs=$(grep 'IMPORT{program}="[^/$]' $out/* | sed -e 's/.*IMPORT{program}="\([^ "]*\)[ "].*/\1/' | uniq) @@ -72,7 +66,7 @@ let done echo "OK" - echo -n "Checking that all programs call by absolute paths in udev rules exist ... " + echo -n "Checking that all programs called by absolute paths in udev rules exist ... " import_progs=$(grep 'IMPORT{program}="/' $out/* | sed -e 's/.*IMPORT{program}="\([^ "]*\)[ "].*/\1/' | uniq) run_progs=$(grep -v '^[[:space:]]*#' $out/* | grep 'RUN+="/' | @@ -90,24 +84,9 @@ let for i in ${toString cfg.packages}; do grep -l '\(RUN+\|IMPORT{program}\)="\(/usr\)\?/s\?bin' $i/*/udev/rules.d/* || true done - - # Use the persistent device rules (naming for CD/DVD and - # network devices) stored in - # /var/lib/udev/rules.d/70-persistent-{cd,net}.rules. These are - # modified by the write_{cd,net}_rules helpers called from - # 75-cd-aliases-generator.rules and - # 75-persistent-net-generator.rules. - ln -sv /var/lib/udev/rules.d/70-persistent-cd.rules $out/ - ln -sv /var/lib/udev/rules.d/70-persistent-net.rules $out/ ''; # */ }; - # The udev configuration file. - conf = writeText "udev.conf" '' - udev_rules="${udevRules}" - #udev_log="debug" - ''; - # Udev has a 512-character limit for ENV{PATH}, so create a symlink # tree to work around this. udevPath = pkgs.buildEnv { @@ -207,61 +186,15 @@ in services.udev.extraRules = nixosRules; - services.udev.packages = [ pkgs.udev extraUdevRules ]; + services.udev.packages = [ extraUdevRules ]; - services.udev.path = [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.utillinux pkgs.udev ]; + services.udev.path = [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.utillinux udev ]; - jobs.udev = - { startOn = "startup"; - - environment = { UDEV_CONFIG_FILE = conf; }; - - path = [ udev ]; - - preStart = - '' - echo "" > /proc/sys/kernel/hotplug || true - - mkdir -p /var/lib/udev/rules.d - touch /var/lib/udev/rules.d/70-persistent-cd.rules /var/lib/udev/rules.d/70-persistent-net.rules - - mkdir -p /dev/.udev # !!! bug in udev? - ''; - - daemonType = "fork"; - - exec = "udevd --daemon"; - - postStart = - '' - # Do the loading of additional stage 2 kernel modules. - # This needs to be done while udevd is running, because - # the modules may call upon udev's firmware loading rule. - for i in ${toString config.boot.kernelModules}; do - echo "loading kernel module ‘$i’..." - ${config.system.sbin.modprobe}/sbin/modprobe $i || true - done - ''; - }; - - jobs.udevtrigger = - { startOn = "started udev"; - - task = true; - - path = [ udev ]; - - script = - '' - # Let udev create device nodes for all modules that have already - # been loaded into the kernel (or for which support is built into - # the kernel). - udevadm trigger --action=add - udevadm settle || true # wait for udev to finish - - initctl emit -n new-devices - ''; - }; + environment.etc = + [ { source = udevRules; + target = "udev/rules.d"; + } + ]; }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 4555b59d2783..57bc47bd6d62 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -24,11 +24,19 @@ let "syslog.target" "time-sync.target" + # Udev. + "systemd-udev-control.socket" + "systemd-udev-kernel.socket" + "systemd-udev.service" + "systemd-udev-settle.service" + "systemd-udev-trigger.service" + # Login stuff. "systemd-logind.service" "autovt@.service" "systemd-vconsole-setup.service" "systemd-user-sessions.service" + "dbus-org.freedesktop.login1.service" # Journal. "systemd-journald.socket" @@ -150,6 +158,8 @@ in config = { + system.build.systemd = systemd; + environment.systemPackages = [ systemd ]; environment.etc = From ab86759eb3f0596f2f6940d0a5904bb04785911c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 15 Jun 2012 14:18:26 -0400 Subject: [PATCH 004/327] Use kmod instead of module-init-tools --- modules/config/system-path.nix | 4 +--- modules/system/boot/modprobe.nix | 11 ++++++----- modules/system/boot/stage-2-init.sh | 10 +++------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix index 2a25cd411a1d..d5939db95ac8 100644 --- a/modules/config/system-path.nix +++ b/modules/config/system-path.nix @@ -16,8 +16,7 @@ let ''; requiredPackages = - [ config.system.sbin.modprobe # must take precedence over module_init_tools - config.environment.nix + [ config.environment.nix pkgs.acl pkgs.attr pkgs.bashInteractive # bash with ncurses support @@ -38,7 +37,6 @@ let pkgs.less pkgs.libcap pkgs.man - pkgs.module_init_tools pkgs.nano pkgs.ncurses pkgs.netcat diff --git a/modules/system/boot/modprobe.nix b/modules/system/boot/modprobe.nix index f210ecec26d8..1b34e78ab78c 100644 --- a/modules/system/boot/modprobe.nix +++ b/modules/system/boot/modprobe.nix @@ -9,7 +9,6 @@ with pkgs.lib; options = { system.sbin.modprobe = mkOption { - # should be moved in module-init-tools internal = true; default = pkgs.writeTextFile { name = "modprobe"; @@ -18,8 +17,8 @@ with pkgs.lib; text = '' #! ${pkgs.stdenv.shell} - export MODULE_DIR=${config.system.modulesTree}/lib/modules/ - + export MODULE_DIR=/var/run/current-system/kernel-modules/lib/modules + # Fall back to the kernel modules used at boot time if the # modules in the current configuration don't match the # running kernel. @@ -27,7 +26,7 @@ with pkgs.lib; MODULE_DIR=/var/run/booted-system/kernel-modules/lib/modules/ fi - exec ${pkgs.module_init_tools}/sbin/modprobe "$@" + exec ${pkgs.kmod}/sbin/modprobe "$@" ''; }; description = '' @@ -78,6 +77,8 @@ with pkgs.lib; target = "modprobe.d/nixos.conf"; }; + environment.systemPackages = [ config.system.sbin.modprobe pkgs.kmod ]; + boot.blacklistedKernelModules = [ # This module is for debugging and generates gigantic amounts # of log output, so it should never be loaded automatically. @@ -104,7 +105,7 @@ with pkgs.lib; environment.shellInit = '' - export MODULE_DIR=${config.system.modulesTree}/lib/modules/ + export MODULE_DIR=/var/run/current-system/kernel-modules/lib/modules ''; }; diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 42dd21b6204d..384c9e301cb8 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -188,12 +188,8 @@ if [ -n "$debug2" ]; then fi -# FIXME: auto-loading of kernel modules in systemd doesn't work yet -# because it uses libkmod. -"$(cat /proc/sys/kernel/modprobe)" autofs4 -"$(cat /proc/sys/kernel/modprobe)" ipv6 - - # Start systemd. echo "starting systemd..." -PATH=/var/run/current-system/systemd/lib/systemd exec systemd --log-target journal --log-level debug --crash-shell +PATH=/var/run/current-system/systemd/lib/systemd \ + MODULE_DIR=/var/run/current-system/kernel-modules/lib/modules \ + exec systemd --log-target journal --log-level debug --crash-shell From 66f4d108437e62659e77fe11583ae53a23c54b74 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 15 Jun 2012 14:51:48 -0400 Subject: [PATCH 005/327] Use pam_systemd.so to set up device ownership This removes the need for ConsoleKit, so it's gone. --- modules/module-list.nix | 1 - modules/security/consolekit.nix | 60 --------------------------------- modules/security/pam.nix | 4 +-- modules/system/boot/systemd.nix | 1 + 4 files changed, 3 insertions(+), 63 deletions(-) delete mode 100644 modules/security/consolekit.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 870d316006fc..0b324e7fffd2 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -46,7 +46,6 @@ ./programs/wvdial.nix ./rename.nix ./security/ca.nix - ./security/consolekit.nix ./security/pam.nix ./security/pam_usb.nix ./security/policykit.nix diff --git a/modules/security/consolekit.nix b/modules/security/consolekit.nix deleted file mode 100644 index 28e1fec06010..000000000000 --- a/modules/security/consolekit.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -let - - # `pam_console' maintains the set of locally logged in users in - # /var/run/console. This is obsolete, but D-Bus still uses it for - # its `at_console' feature. So maintain it using a ConsoleKit - # session script. Borrowed from - # http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-auth/consolekit/files/pam-foreground-compat.ck - updateVarRunConsole = pkgs.writeTextFile { - name = "var-run-console.ck"; - destination = "/etc/ConsoleKit/run-session.d/var-run-console.ck"; - executable = true; - - text = - '' - #! ${pkgs.stdenv.shell} -e - PATH=${pkgs.coreutils}/bin:${pkgs.gnused}/bin:${pkgs.glibc}/bin - TAGDIR=/var/run/console - - [ -n "$CK_SESSION_USER_UID" ] || exit 1 - - TAGFILE="$TAGDIR/`getent passwd $CK_SESSION_USER_UID | cut -f 1 -d:`" - - if [ "$1" = "session_added" ]; then - mkdir -p "$TAGDIR" - echo "$CK_SESSION_ID" >> "$TAGFILE" - fi - - if [ "$1" = "session_removed" ] && [ -e "$TAGFILE" ]; then - sed -i "\%^$CK_SESSION_ID\$%d" "$TAGFILE" - [ -s "$TAGFILE" ] || rm -f "$TAGFILE" - fi - ''; - }; - -in - -{ - - config = { - - environment.systemPackages = [ pkgs.consolekit ]; - - services.dbus.packages = [ pkgs.consolekit ]; - - environment.etc = singleton - { source = (pkgs.buildEnv { - name = "consolekit-config"; - pathsToLink = [ "/etc/ConsoleKit" ]; - paths = [ pkgs.consolekit pkgs.udev updateVarRunConsole ]; - }) + "/etc/ConsoleKit"; - target = "ConsoleKit"; - }; - - }; - -} diff --git a/modules/security/pam.nix b/modules/security/pam.nix index 4fab7febc710..09803598db90 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -41,7 +41,7 @@ let # against the keys in the calling user's ~/.ssh/authorized_keys. # This is useful for "sudo" on password-less remote systems. sshAgentAuth ? false - , # If set, use ConsoleKit's PAM connector module to claim + , # If set, use systemd's PAM connector module to claim # ownership of audio devices etc. ownDevices ? false , # Whether to forward XAuth keys between users. Mostly useful @@ -104,7 +104,7 @@ let ${optionalString config.krb5.enable "session optional ${pam_krb5}/lib/security/pam_krb5.so"} ${optionalString ownDevices - "session optional ${pkgs.consolekit}/lib/security/pam_ck_connector.so"} + "session optional ${pkgs.systemd}/lib/security/pam_systemd.so"} ${optionalString forwardXAuth "session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99"} ${optionalString (limits != []) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 57bc47bd6d62..0d4256990e7e 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -37,6 +37,7 @@ let "systemd-vconsole-setup.service" "systemd-user-sessions.service" "dbus-org.freedesktop.login1.service" + "user@.service" # Journal. "systemd-journald.socket" From 4a95f8996b11ca9876e24a37d4b521925a1c33bf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 16 Jun 2012 00:19:43 -0400 Subject: [PATCH 006/327] =?UTF-8?q?To=20ease=20migration=20to=20systemd,?= =?UTF-8?q?=20generate=20units=20from=20the=20=E2=80=98jobs=E2=80=99=20opt?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also get rid of the ‘buildHook’ job option because it wasn't very useful. --- modules/config/networking.nix | 2 +- modules/module-list.nix | 3 - .../services/monitoring/nagios/default.nix | 7 +- modules/services/networking/ssh/sshd.nix | 1 - modules/services/system/nscd.nix | 5 +- modules/services/ttys/mingetty.nix | 2 + .../web-servers/apache-httpd/default.nix | 13 +- modules/system/boot/stage-2-init.sh | 2 +- modules/system/boot/systemd.nix | 8 +- .../upstart-events/control-alt-delete.nix | 26 --- modules/system/upstart-events/runlevel.nix | 38 ----- modules/system/upstart/upstart.nix | 161 ++++++++++-------- modules/tasks/filesystems.nix | 4 +- modules/tasks/kbd.nix | 5 +- modules/tasks/network-interfaces.nix | 3 +- 15 files changed, 108 insertions(+), 172 deletions(-) delete mode 100644 modules/system/upstart-events/control-alt-delete.nix delete mode 100644 modules/system/upstart-events/runlevel.nix diff --git a/modules/config/networking.nix b/modules/config/networking.nix index 5065fc22f2ce..757bb9e85e0c 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -67,7 +67,7 @@ in '' + optionalString config.services.nscd.enable '' # Invalidate the nscd cache whenever resolv.conf is # regenerated. - libc_restart='${pkgs.upstart}/sbin/start invalidate-nscd' + libc_restart='${pkgs.systemd}/bin/systemctl start invalidate-nscd.service' '' ); target = "resolvconf.conf"; } diff --git a/modules/module-list.nix b/modules/module-list.nix index 0b324e7fffd2..04fa9c58ec6c 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -199,9 +199,6 @@ ./system/boot/stage-2.nix ./system/boot/systemd.nix ./system/etc/etc.nix - ./system/upstart-events/control-alt-delete.nix - ./system/upstart-events/runlevel.nix - ./system/upstart-events/shutdown.nix ./system/upstart/upstart.nix ./tasks/cpu-freq.nix ./tasks/filesystems.nix diff --git a/modules/services/monitoring/nagios/default.nix b/modules/services/monitoring/nagios/default.nix index 6d2fe3f2acec..3c32a3c25ec9 100644 --- a/modules/services/monitoring/nagios/default.nix +++ b/modules/services/monitoring/nagios/default.nix @@ -159,12 +159,7 @@ in environment.systemPackages = [ pkgs.nagios ]; jobs.nagios = - { # Run `nagios -v' to check the validity of the configuration file so - # that a nixos-rebuild fails *before* we kill the running Nagios - # daemon. - buildHook = "${pkgs.nagios}/bin/nagios -v ${nagiosCfgFile}"; - - description = "Nagios monitoring daemon"; + { description = "Nagios monitoring daemon"; startOn = "started network-interfaces"; stopOn = "stopping network-interfaces"; diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index e4ca7f39a568..9710082f4207 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -329,7 +329,6 @@ in ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ -f ${pkgs.writeText "sshd_config" cfg.extraConfig} Restart=always - RestartSec=5 Type=forking KillMode=process PIDFile=/run/sshd.pid diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index 6f35cd30f582..b2596dbb4139 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -20,15 +20,14 @@ in enable = mkOption { default = true; - description = " - Whether to enable the Name Service Cache Daemon. - "; + description = "Whether to enable the Name Service Cache Daemon."; }; }; }; + ###### implementation config = mkIf config.services.nscd.enable { diff --git a/modules/services/ttys/mingetty.nix b/modules/services/ttys/mingetty.nix index 85db3f8966e1..8304ca180cb8 100644 --- a/modules/services/ttys/mingetty.nix +++ b/modules/services/ttys/mingetty.nix @@ -56,6 +56,7 @@ with pkgs.lib; config = { # Generate a separate job for each tty. + /* jobs = listToAttrs (map (tty: nameValuePair tty { startOn = @@ -72,6 +73,7 @@ with pkgs.lib; environment.LOCALE_ARCHIVE = "/var/run/current-system/sw/lib/locale/locale-archive"; }) config.services.mingetty.ttys); + */ environment.etc = singleton { # Friendly greeting on the virtual consoles. diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index ce3311a5f598..259847d07261 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -532,18 +532,7 @@ in ''; jobs.httpd = - { # Statically verify the syntactic correctness of the generated - # httpd.conf. !!! this is impure! It doesn't just check for - # syntax, but also whether the Apache user/group exist, - # whether SSL keys exist, etc. - buildHook = - '' - echo - echo '=== Checking the generated Apache configuration file ===' - ${httpd}/bin/httpd -f ${httpdConf} -t || true - ''; - - description = "Apache HTTPD"; + { description = "Apache HTTPD"; startOn = "started networking and filesystem" # Hacky. Some subservices depend on Postgres diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 384c9e301cb8..8238fc1537ea 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -192,4 +192,4 @@ fi echo "starting systemd..." PATH=/var/run/current-system/systemd/lib/systemd \ MODULE_DIR=/var/run/current-system/kernel-modules/lib/modules \ - exec systemd --log-target journal --log-level debug --crash-shell + exec systemd --log-target journal # --log-level debug --crash-shell diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 0d4256990e7e..c5a646208cb0 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -111,7 +111,7 @@ let nixosUnits = mapAttrsToList makeUnit config.boot.systemd.units; - systemUnits = pkgs.runCommand "system-units" { } + units = pkgs.runCommand "units" { preferLocalBuild = true; } '' mkdir -p $out/system for i in ${toString upstreamUnits}; do @@ -161,10 +161,12 @@ in system.build.systemd = systemd; + system.build.units = units; + environment.systemPackages = [ systemd ]; environment.etc = - [ { source = systemUnits; + [ { source = units; target = "systemd"; } ]; @@ -177,7 +179,7 @@ in After=multi-user.target Conflicts=rescue.target AllowIsolate=yes - Wants=sshd.service autovt@tty1.service # FIXME + Wants=sshd.service ''; boot.systemd.units."getty@.service" = diff --git a/modules/system/upstart-events/control-alt-delete.nix b/modules/system/upstart-events/control-alt-delete.nix deleted file mode 100644 index f0f146160e58..000000000000 --- a/modules/system/upstart-events/control-alt-delete.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ config, pkgs, ... }: - -###### implementation - -{ - jobs.control_alt_delete = - { name = "control-alt-delete"; - - startOn = "control-alt-delete"; - - task = true; - - script = - '' - shutdown -r now 'Ctrl-Alt-Delete pressed' - ''; - }; - - system.activationScripts.poweroff = - '' - # Allow the kernel to find the poweroff command. This is used - # (for instance) by Xen's "xm shutdown" command to signal a - # guest to shut down cleanly. - echo ${config.system.build.upstart}/sbin/poweroff > /proc/sys/kernel/poweroff_cmd - ''; -} diff --git a/modules/system/upstart-events/runlevel.nix b/modules/system/upstart-events/runlevel.nix deleted file mode 100644 index 016217ea3a67..000000000000 --- a/modules/system/upstart-events/runlevel.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -{ - - # After booting, go to runlevel 2. (NixOS doesn't really use - # runlevels, but this keeps wtmp happy.) - jobs.boot = - { name = "boot"; - startOn = "startup"; - task = true; - restartIfChanged = false; - script = "telinit 2"; - }; - - jobs.runlevel = - { name = "runlevel"; - - startOn = "runlevel [0123456S]"; - - task = true; - - restartIfChanged = false; - - script = - '' - case "$RUNLEVEL" in - 0) initctl start shutdown --no-wait MODE=poweroff;; - 1) initctl start shutdown --no-wait MODE=maintenance;; - 2) true;; - 6) initctl start shutdown --no-wait MODE=reboot;; - *) echo "Unsupported runlevel: $RUNLEVEL";; - esac - ''; - }; - -} diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 284f1aafd37d..b09fdc7d676f 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -12,19 +12,90 @@ let groupExists = g: (g == "") || any (gg: gg.name == g) (attrValues config.users.extraGroups); - # From a job description, generate an Upstart job file. - makeJob = job: + # From a job description, generate an systemd unit file. + makeUnit = job: let hasMain = job.script != "" || job.exec != ""; env = config.system.upstartEnvironment // job.environment; - jobText = - let log = "/var/log/upstart/${job.name}"; in + preStartScript = pkgs.writeScript "${job.name}-pre-start.sh" '' - # Upstart job `${job.name}'. This is a generated file. Do not edit. + #! ${pkgs.stdenv.shell} -e + ${job.preStart} + ''; + startScript = pkgs.writeScript "${job.name}-start.sh" + '' + #! ${pkgs.stdenv.shell} -e + ${if job.script != "" then job.script else '' + exec ${job.exec} + ''} + ''; + + postStartScript = pkgs.writeScript "${job.name}-post-start.sh" + '' + #! ${pkgs.stdenv.shell} -e + ${job.postStart} + ''; + + preStopScript = pkgs.writeScript "${job.name}-pre-stop.sh" + '' + #! ${pkgs.stdenv.shell} -e + ${job.preStop} + ''; + + postStopScript = pkgs.writeScript "${job.name}-post-stop.sh" + '' + #! ${pkgs.stdenv.shell} -e + ${job.postStop} + ''; + + text = + '' + [Unit] + Description=${job.description} + + [Service] + Environment=PATH=${job.path} + ${concatMapStrings (n: "Environment=${n}=\"${getAttr n env}\"\n") (attrNames env)} + + ${optionalString (job.preStart != "" && (job.script != "" || job.exec != "")) '' + ExecStartPre=${preStartScript} + ''} + + ${optionalString (job.preStart != "" && job.script == "" && job.exec == "") '' + ExecStart=${preStartScript} + ''} + + ${optionalString (job.script != "" || job.exec != "") '' + ExecStart=${startScript} + ''} + + ${optionalString (job.postStart != "") '' + ExecStartPost=${postStartScript} + ''} + + ${optionalString (job.preStop != "") '' + ExecStop=${preStopScript} + ''} + + ${optionalString (job.postStop != "") '' + ExecStopPost=${postStopScript} + ''} + + ${if job.script == "" && job.exec == "" then "Type=oneshot\nRemainAfterExit=true" else + if job.daemonType == "fork" then "Type=forking\nGuessMainPID=true" else + if job.daemonType == "none" then "" else + throw "invalid daemon type `${job.daemonType}'"} + + ${optionalString (!job.task && job.respawn) "Restart=always"} + ''; + + /* + text = + '' ${optionalString (job.description != "") '' description "${job.description}" ''} @@ -45,9 +116,6 @@ let ${optionalString (job.console != "") "console ${job.console}"} pre-start script - ${optionalString (job.console == "") '' - exec >> ${log} 2>&1 - ''} ln -sfn "$(readlink -f "/etc/init/${job.name}.conf")" /var/run/upstart-jobs/${job.name} ${optionalString (job.preStart != "") '' source ${jobHelpers} @@ -60,9 +128,6 @@ let else if job.script != "" then '' script - ${optionalString (job.console == "") '' - exec >> ${log} 2>&1 - ''} source ${jobHelpers} ${job.script} end script @@ -70,7 +135,6 @@ let else if job.exec != "" && job.console == "" then '' script - exec >> ${log} 2>&1 exec ${job.exec} end script '' @@ -83,9 +147,6 @@ let ${optionalString (job.postStart != "") '' post-start script - ${optionalString (job.console == "") '' - exec >> ${log} 2>&1 - ''} source ${jobHelpers} ${job.postStart} end script @@ -98,9 +159,6 @@ let # (upstart 0.6.5, job.c:562) optionalString (job.preStop != "") (assert hasMain; '' pre-stop script - ${optionalString (job.console == "") '' - exec >> ${log} 2>&1 - ''} source ${jobHelpers} ${job.preStop} end script @@ -108,9 +166,6 @@ let ${optionalString (job.postStop != "") '' post-stop script - ${optionalString (job.console == "") '' - exec >> ${log} 2>&1 - ''} source ${jobHelpers} ${job.postStop} end script @@ -132,14 +187,9 @@ let ${job.extraConfig} ''; + */ - in - pkgs.runCommand ("upstart-" + job.name + ".conf") - { inherit (job) buildHook; inherit jobText; preferLocalBuild = true; } - '' - eval "$buildHook" - echo "$jobText" > $out - ''; + in text; # Shell functions for use in Upstart jobs. @@ -199,17 +249,6 @@ let ''; }; - buildHook = mkOption { - type = types.string; - default = "true"; - description = '' - Command run while building the Upstart job. Can be used - to perform simple regression tests (e.g., the Apache - Upstart job uses it to check the syntax of the generated - httpd.conf. - ''; - }; - description = mkOption { type = types.string; default = ""; @@ -401,13 +440,10 @@ let options = { - jobDrv = mkOption { - default = makeJob config; - type = types.uniq types.package; - description = '' - Derivation that builds the Upstart job file. The default - value is generated from other options. - ''; + unitText = mkOption { + default = makeUnit config; + type = types.uniq types.string; + description = "Generated text of the systemd unit corresponding to this job."; }; }; @@ -448,16 +484,6 @@ in options = [ jobOptions upstartJob ]; }; - tests.upstartJobs = mkOption { - internal = true; - default = {}; - description = '' - Make it easier to build individual Upstart jobs. (e.g., - nix-build /etc/nixos/nixos -A - tests.upstartJobs.xserver). - ''; - }; - system.upstartEnvironment = mkOption { type = types.attrs; default = {}; @@ -476,25 +502,10 @@ in system.build.upstart = upstart; - /* - environment.etc = - flip map (attrValues config.jobs) (job: - { source = job.jobDrv; - target = "init/${job.name}.conf"; - } ); - - # Upstart can listen on the system bus, allowing normal users to - # do status queries. - services.dbus.packages = [ upstart ]; - - system.activationScripts.chownJobLogs = stringAfter ["var"] - (concatMapStrings (job: '' - touch /var/log/upstart/${job.name} - ${optionalString (job.setuid != "") "chown ${job.setuid} /var/log/upstart/${job.name}"} - ${optionalString (job.setgid != "") "chown :${job.setgid} /var/log/upstart/${job.name}"} - '') (attrValues config.jobs)); - */ - + boot.systemd.units = + flip mapAttrs' config.jobs (name: job: + nameValuePair "${job.name}.service" job.unitText); + }; } diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 9495cac67855..8eaf77330a3d 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -174,7 +174,7 @@ in system.fsPackages = [ pkgs.dosfstools ]; environment.systemPackages = - [ pkgs.ntfs3g pkgs.cifs_utils pkgs.mountall ] + [ pkgs.ntfs3g pkgs.cifs_utils ] ++ config.system.fsPackages; environment.etc = singleton @@ -182,6 +182,7 @@ in target = "fstab"; }; + /* jobs.mountall = { startOn = "started udev or config-changed"; @@ -309,6 +310,7 @@ in initctl start --no-wait mountall ''; }; + */ }; diff --git a/modules/tasks/kbd.nix b/modules/tasks/kbd.nix index 62c4b92ed094..b563d33dc5b1 100644 --- a/modules/tasks/kbd.nix +++ b/modules/tasks/kbd.nix @@ -54,8 +54,10 @@ in inherit requiredTTYs; # pass it to ./modules/tasks/tty-backgrounds.nix - environment.systemPackages = [pkgs.kbd]; + environment.systemPackages = [ pkgs.kbd ]; + /* FIXME - remove; this is handled by systemd now. + jobs.kbd = { description = "Keyboard / console initialisation"; @@ -120,6 +122,7 @@ in ${pkgs.kbd}/bin/loadkeys '${consoleKeyMap}' ''; }; + */ }; diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index c12f9b28ca91..611de13148a3 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -267,7 +267,8 @@ in ${optionalString (cfg.interfaces != [] || cfg.localCommands != "") '' # Emit the ip-up event (e.g. to start ntpd). - initctl emit -n ip-up + #FIXME + #initctl emit -n ip-up ''} ''; }; From 42ee3b4209264d44cad5514bd96f6aa730287438 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 17 Jun 2012 23:31:21 -0400 Subject: [PATCH 007/327] =?UTF-8?q?Add=20a=20=E2=80=98wantedBy=E2=80=99=20?= =?UTF-8?q?attribute=20to=20unit=20definitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This attribute allows a unit to make itself a dependency of another unit. Also, add an option to set the default target unit. --- modules/services/networking/ssh/sshd.nix | 39 +++-------------- modules/services/system/dbus.nix | 15 ++----- modules/system/boot/systemd.nix | 55 ++++++++++++++++-------- modules/system/upstart/upstart.nix | 17 +++++--- modules/tasks/lvm.nix | 2 - 5 files changed, 57 insertions(+), 71 deletions(-) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 9710082f4207..5a924361761c 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -317,13 +317,15 @@ in } ]; - boot.systemd.units."sshd.service" = + boot.systemd.units."sshd.service".text = '' [Unit] Description=SSH daemon [Service] Environment=PATH=${pkgs.coreutils}/bin:${pkgs.openssh}/bin + Environment=LD_LIBRARY_PATH=${nssModulesPath} + Environment=LOCALE_ARCHIVE=/var/run/current-system/sw/lib/locale/locale-archive ExecStartPre=${preStart} ExecStart=\ ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ @@ -334,39 +336,8 @@ in PIDFile=/run/sshd.pid ''; - jobs.sshd = - { description = "OpenSSH server"; - - startOn = "started network-interfaces"; - - environment = { - LD_LIBRARY_PATH = nssModulesPath; - # Duplicated from bashrc. OpenSSH needs a patch for this. - LOCALE_ARCHIVE = "/var/run/current-system/sw/lib/locale/locale-archive"; - }; - - path = [ pkgs.openssh pkgs.gnused ]; - - preStart = - '' - ${mkAuthkeyScript} - - mkdir -m 0755 -p /etc/ssh - - if ! test -f ${cfg.hostKeyPath}; then - ssh-keygen -t ${hktn} -b ${toString hktb} -f ${cfg.hostKeyPath} -N "" - fi - ''; - - daemonType = "fork"; - - exec = - '' - ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ - -f ${pkgs.writeText "sshd_config" cfg.extraConfig} - ''; - }; - + boot.systemd.units."sshd.service".wantedBy = [ "multi-user.target" ]; + networking.firewall.allowedTCPPorts = cfg.ports; services.openssh.extraConfig = diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix index 8659c784483f..bd5c290d5826 100644 --- a/modules/services/system/dbus.nix +++ b/modules/services/system/dbus.nix @@ -118,7 +118,7 @@ in # FIXME: these are copied verbatim from the dbus source tree. We # should install and use the originals. - boot.systemd.units."dbus.socket" = + boot.systemd.units."dbus.socket".text = '' [Unit] Description=D-Bus System Message Bus Socket @@ -127,7 +127,7 @@ in ListenStream=/var/run/dbus/system_bus_socket ''; - boot.systemd.units."dbus.service" = + boot.systemd.units."dbus.service".text = '' [Unit] Description=D-Bus System Message Bus @@ -142,6 +142,7 @@ in OOMScoreAdjust=-900 ''; + /* jobs.dbus = { startOn = "started udev and started syslogd"; @@ -164,15 +165,6 @@ in exec = "dbus-daemon --system"; - /* - postStart = - '' - # Signal Upstart to connect to the system bus. This - # allows ‘initctl’ to work for non-root users. - kill -USR1 1 - ''; - */ - postStop = '' # !!! Hack: doesn't belong here. @@ -183,6 +175,7 @@ in fi ''; }; + */ security.setuidOwners = singleton { program = "dbus-daemon-launch-helper"; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index c5a646208cb0..d75572b2789d 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -4,10 +4,12 @@ with pkgs.lib; let + cfg = config.boot.systemd; + systemd = pkgs.systemd; - makeUnit = name: text: - pkgs.writeTextFile { name = "unit"; inherit text; destination = "/${name}"; }; + makeUnit = name: unit: + pkgs.writeTextFile { name = "unit"; inherit (unit) text; destination = "/${name}"; }; upstreamUnits = [ # Targets. @@ -109,7 +111,7 @@ let "shutdown.target.wants" ]; - nixosUnits = mapAttrsToList makeUnit config.boot.systemd.units; + nixosUnits = mapAttrsToList makeUnit cfg.units; units = pkgs.runCommand "units" { preferLocalBuild = true; } '' @@ -123,6 +125,7 @@ let ln -s $fn $out/system fi done + for i in ${toString upstreamWants}; do fn=${systemd}/example/systemd/system/$i [ -e $fn ] @@ -134,9 +137,18 @@ let if ! [ -e $y ]; then rm -v $y; fi done done + for i in ${toString nixosUnits}; do cp $i/* $out/system done + + ${concatStrings (mapAttrsToList (name: unit: + concatMapStrings (name2: '' + mkdir -p $out/system/${name2}.wants + ln -sfn ../${name} $out/system/${name2}.wants/ + '') unit.wantedBy) cfg.units)} + + ln -s ${cfg.defaultUnit} $out/system/default.target ''; # */ in @@ -148,10 +160,28 @@ in options = { boot.systemd.units = mkOption { - default = {} ; - description = "Systemd units."; + default = {}; + type = types.attrsOf types.optionSet; + options = { + text = mkOption { + types = types.uniq types.string; + description = "Text of this systemd unit."; + }; + wantedBy = mkOption { + default = []; + types = types.listOf types.string; + description = "Units that want (i.e. depend on) this unit."; + }; + }; + description = "Definition of systemd units."; }; + boot.systemd.defaultUnit = mkOption { + default = "multi-user.target"; + type = types.uniq types.string; + description = "Default unit started when the system boots."; + }; + }; @@ -171,18 +201,7 @@ in } ]; - boot.systemd.units."default.target" = - '' - [Unit] - Description=Default System - Requires=multi-user.target - After=multi-user.target - Conflicts=rescue.target - AllowIsolate=yes - Wants=sshd.service - ''; - - boot.systemd.units."getty@.service" = + boot.systemd.units."getty@.service".text = '' [Unit] Description=Getty on %I @@ -218,7 +237,7 @@ in KillSignal=SIGHUP ''; - boot.systemd.units."rescue.service" = + boot.systemd.units."rescue.service".text = '' [Unit] Description=Rescue Shell diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index b09fdc7d676f..2e57ac358da6 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -51,6 +51,7 @@ let #! ${pkgs.stdenv.shell} -e ${job.postStop} ''; + in { text = '' @@ -93,6 +94,13 @@ let ${optionalString (!job.task && job.respawn) "Restart=always"} ''; + wantedBy = + if job.startOn == "" then [ ] + else if job.startOn == "startup" then [ "basic.target" ] + else [ "multi-user.target" ]; + + }; + /* text = '' @@ -189,8 +197,6 @@ let ''; */ - in text; - # Shell functions for use in Upstart jobs. jobHelpers = pkgs.writeText "job-helpers.sh" @@ -440,10 +446,9 @@ let options = { - unitText = mkOption { + unit = mkOption { default = makeUnit config; - type = types.uniq types.string; - description = "Generated text of the systemd unit corresponding to this job."; + description = "Generated definition of the systemd unit corresponding to this job."; }; }; @@ -504,7 +509,7 @@ in boot.systemd.units = flip mapAttrs' config.jobs (name: job: - nameValuePair "${job.name}.service" job.unitText); + nameValuePair "${job.name}.service" job.unit); }; diff --git a/modules/tasks/lvm.nix b/modules/tasks/lvm.nix index 635146ac889b..7773a2c79e31 100644 --- a/modules/tasks/lvm.nix +++ b/modules/tasks/lvm.nix @@ -14,8 +14,6 @@ # Make all logical volumes on all volume groups available, i.e., # make them appear in /dev. ${pkgs.lvm2}/sbin/vgchange --available y - - initctl emit -n new-devices ''; task = true; From 673bf12b1d4132d815e95c98ad27946ad7486bd3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 00:22:18 -0400 Subject: [PATCH 008/327] Improve the dependencies of units generated by the Upstart emulation --- modules/system/upstart/upstart.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 2e57ac358da6..0f7eb65bf2ff 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -57,6 +57,9 @@ let '' [Unit] Description=${job.description} + ${if job.startOn == "stopped udevtrigger" then "After=systemd-udev-settle.service" else + if job.startOn == "started udev" then "After=systemd-udev.service" + else ""} [Service] Environment=PATH=${job.path} @@ -94,10 +97,7 @@ let ${optionalString (!job.task && job.respawn) "Restart=always"} ''; - wantedBy = - if job.startOn == "" then [ ] - else if job.startOn == "startup" then [ "basic.target" ] - else [ "multi-user.target" ]; + wantedBy = if job.startOn == "" then [ ] else [ "multi-user.target" ]; }; From 352510c2081d48895ebc8d3d1658acc79b43ae9b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 15:28:31 -0400 Subject: [PATCH 009/327] =?UTF-8?q?Add=20an=20option=20=E2=80=98boot.syste?= =?UTF-8?q?md.services=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This option makes it more convenient to define services because it automates stuff like setting $PATH, having a pre-start script, and so on. --- modules/services/networking/ssh/sshd.nix | 76 ++++--- modules/system/boot/systemd.nix | 274 +++++++++++++++++------ 2 files changed, 256 insertions(+), 94 deletions(-) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 5a924361761c..3bf4bf642fa5 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -39,6 +39,7 @@ let ); userOptions = { + openssh.authorizedKeys = { preserveExistingKeys = mkOption { @@ -77,6 +78,7 @@ let }; }; + }; mkAuthkeyScript = @@ -127,19 +129,6 @@ let ${userLoop} ''; - preStart = pkgs.writeScript "openssh-pre-start" - '' - #! ${pkgs.stdenv.shell} - - ${mkAuthkeyScript} - - mkdir -m 0755 -p /etc/ssh - - if ! test -f ${cfg.hostKeyPath}; then - ssh-keygen -t ${hktn} -b ${toString hktb} -f ${cfg.hostKeyPath} -N "" - fi - ''; - in { @@ -317,27 +306,52 @@ in } ]; - boot.systemd.units."sshd.service".text = - '' - [Unit] - Description=SSH daemon + boot.systemd.services."set-ssh-keys.service" = + { description = "Update authorized SSH keys"; - [Service] - Environment=PATH=${pkgs.coreutils}/bin:${pkgs.openssh}/bin - Environment=LD_LIBRARY_PATH=${nssModulesPath} - Environment=LOCALE_ARCHIVE=/var/run/current-system/sw/lib/locale/locale-archive - ExecStartPre=${preStart} - ExecStart=\ - ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ - -f ${pkgs.writeText "sshd_config" cfg.extraConfig} - Restart=always - Type=forking - KillMode=process - PIDFile=/run/sshd.pid - ''; + wantedBy = [ "multi-user.target" ]; - boot.systemd.units."sshd.service".wantedBy = [ "multi-user.target" ]; + script = mkAuthkeyScript; + + serviceConfig = + '' + Type=oneshot + RemainAfterExit=true + ''; + }; + boot.systemd.services."sshd.service" = + { description = "SSH daemon"; + + wantedBy = [ "multi-user.target" ]; + after = [ "set-ssh-keys.service" ]; + + path = [ pkgs.openssh ]; + + environment.LD_LIBRARY_PATH = nssModulesPath; + environment.LOCALE_ARCHIVE = "/var/run/current-system/sw/lib/locale/locale-archive"; + + preStart = + '' + mkdir -m 0755 -p /etc/ssh + + if ! test -f ${cfg.hostKeyPath}; then + ssh-keygen -t ${hktn} -b ${toString hktb} -f ${cfg.hostKeyPath} -N "" + fi + ''; + + serviceConfig = + '' + ExecStart=\ + ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ + -f ${pkgs.writeText "sshd_config" cfg.extraConfig} + Restart=always + Type=forking + KillMode=process + PIDFile=/run/sshd.pid + ''; + }; + networking.firewall.allowedTCPPorts = cfg.ports; services.openssh.extraConfig = diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index d75572b2789d..906558bd6956 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -4,6 +4,102 @@ with pkgs.lib; let + servicesOptions = { + + description = mkOption { + default = ""; + types = types.uniq types.string; + description = "Description of this unit used in systemd messages and progress indicators."; + }; + + after = mkOption { + default = []; + types = types.listOf types.string; + description = '' + If the specified units are started at the same time as + this unit, delay this unit until they have started. + ''; + }; + + before = mkOption { + default = []; + types = types.listOf types.string; + description = '' + If the specified units are started at the same time as + this unit, delay them until this unit has started. + ''; + }; + + wantedBy = mkOption { + default = []; + types = types.listOf types.string; + description = "Units that want (i.e. depend on) this unit."; + }; + + environment = mkOption { + default = {}; + type = types.attrs; + example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; + description = "Environment variables passed to the services's processes."; + }; + + path = mkOption { + default = []; + apply = ps: "${makeSearchPath "bin" ps}:${makeSearchPath "sbin" ps}"; + description = '' + Packages added to the service's PATH + environment variable. Both the bin + and sbin subdirectories of each + package are added. + ''; + }; + + serviceConfig = mkOption { + default = ""; + type = types.string; + description = '' + Contents of the [Service] section of the unit. + See systemd.unit + 5 for details. + ''; + }; + + script = mkOption { + type = types.uniq types.string; + default = ""; + description = "Shell commands executed as the service's main process."; + }; + + preStart = mkOption { + type = types.string; + default = ""; + description = '' + Shell commands executed before the service's main process + is started. + ''; + }; + + }; + + + servicesConfig = { name, config, ... }: { + + config = { + + # Default path for systemd services. Should be quite minimal. + path = + [ pkgs.coreutils + pkgs.findutils + pkgs.gnugrep + pkgs.gnused + systemd + ]; + + }; + + }; + + cfg = config.boot.systemd; systemd = pkgs.systemd; @@ -111,6 +207,103 @@ let "shutdown.target.wants" ]; + rescueService = + '' + [Unit] + Description=Rescue Shell + DefaultDependencies=no + Conflicts=shutdown.target + After=sysinit.target + Before=shutdown.target + + [Service] + Environment=HOME=/root + WorkingDirectory=/root + ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.' + #ExecStart=-/sbin/sulogin + ExecStart=-${pkgs.bashInteractive}/bin/bash --login + ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default + Type=idle + StandardInput=tty-force + StandardOutput=inherit + StandardError=inherit + KillMode=process + + # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash + # terminates cleanly. + KillSignal=SIGHUP + ''; + + gettyService = + '' + [Unit] + Description=Getty on %I + Documentation=man:agetty(8) + After=systemd-user-sessions.service plymouth-quit-wait.service + + # If additional gettys are spawned during boot then we should make + # sure that this is synchronized before getty.target, even though + # getty.target didn't actually pull it in. + Before=getty.target + IgnoreOnIsolate=yes + + [Service] + Environment=TERM=linux + ExecStart=-${pkgs.utillinux}/sbin/agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 + Type=idle + Restart=always + RestartSec=0 + UtmpIdentifier=%I + TTYPath=/dev/%I + TTYReset=yes + TTYVHangup=yes + TTYVTDisallocate=yes + KillMode=process + IgnoreSIGPIPE=no + + # Unset locale for the console getty since the console has problems + # displaying some internationalized messages. + Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= + + # Some login implementations ignore SIGTERM, so we send SIGHUP + # instead, to ensure that login terminates cleanly. + KillSignal=SIGHUP + ''; + + serviceToUnit = name: def: + { inherit (def) wantedBy; + + text = + '' + [Unit] + ${optionalString (def.description != "") '' + Description=${def.description} + ''} + Before=${concatStringsSep " " def.before} + After=${concatStringsSep " " def.after} + + [Service] + Environment=PATH=${def.path} + ${concatMapStrings (n: "Environment=${n}=\"${getAttr n def.environment}\"\n") (attrNames def.environment)} + + ${optionalString (def.preStart != "") '' + ExecStartPre=${pkgs.writeScript "${name}-prestart.sh" '' + #! ${pkgs.stdenv.shell} -e + ${def.preStart} + ''} + ''} + + ${optionalString (def.script != "") '' + ExecStart=${pkgs.writeScript "${name}.sh" '' + #! ${pkgs.stdenv.shell} -e + ${def.script} + ''} + ''} + + ${def.serviceConfig} + ''; + }; + nixosUnits = mapAttrsToList makeUnit cfg.units; units = pkgs.runCommand "units" { preferLocalBuild = true; } @@ -160,20 +353,32 @@ in options = { boot.systemd.units = mkOption { + description = "Definition of systemd units."; default = {}; type = types.attrsOf types.optionSet; + options = { + text = mkOption { types = types.uniq types.string; description = "Text of this systemd unit."; }; + wantedBy = mkOption { default = []; types = types.listOf types.string; description = "Units that want (i.e. depend on) this unit."; }; + }; - description = "Definition of systemd units."; + + }; + + boot.systemd.services = mkOption { + description = "Definition of systemd services."; + default = {}; + type = types.attrsOf types.optionSet; + options = [ servicesOptions servicesConfig ]; }; boot.systemd.defaultUnit = mkOption { @@ -201,68 +406,11 @@ in } ]; - boot.systemd.units."getty@.service".text = - '' - [Unit] - Description=Getty on %I - Documentation=man:agetty(8) - After=systemd-user-sessions.service plymouth-quit-wait.service - - # If additional gettys are spawned during boot then we should make - # sure that this is synchronized before getty.target, even though - # getty.target didn't actually pull it in. - Before=getty.target - IgnoreOnIsolate=yes - - [Service] - Environment=TERM=linux - ExecStart=-${pkgs.utillinux}/sbin/agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 - Type=idle - Restart=always - RestartSec=0 - UtmpIdentifier=%I - TTYPath=/dev/%I - TTYReset=yes - TTYVHangup=yes - TTYVTDisallocate=yes - KillMode=process - IgnoreSIGPIPE=no - - # Unset locale for the console getty since the console has problems - # displaying some internationalized messages. - Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= - - # Some login implementations ignore SIGTERM, so we send SIGHUP - # instead, to ensure that login terminates cleanly. - KillSignal=SIGHUP - ''; - - boot.systemd.units."rescue.service".text = - '' - [Unit] - Description=Rescue Shell - DefaultDependencies=no - Conflicts=shutdown.target - After=sysinit.target - Before=shutdown.target - - [Service] - Environment=HOME=/root - WorkingDirectory=/root - ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.' - #ExecStart=-/sbin/sulogin - ExecStart=-${pkgs.bashInteractive}/bin/bash --login - ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default - Type=idle - StandardInput=tty-force - StandardOutput=inherit - StandardError=inherit - KillMode=process - - # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash - # terminates cleanly. - KillSignal=SIGHUP - ''; + boot.systemd.units = + { "rescue.service".text = rescueService; + "getty@.service".text = gettyService; + } + // mapAttrs serviceToUnit cfg.services; }; From 4c21857ee1173d303b6c1f2964d46b677adc0ee5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 17:42:26 -0400 Subject: [PATCH 010/327] =?UTF-8?q?Upstart=20=E2=80=98boot.systemd.service?= =?UTF-8?q?s=E2=80=99=20for=20the=20Upstart=20compatibility=20layer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/system/upstart/upstart.nix | 171 ++--------------------------- 1 file changed, 12 insertions(+), 159 deletions(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 0f7eb65bf2ff..de60f693e831 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -53,18 +53,17 @@ let ''; in { - text = + inherit (job) description path environment; + + after = + if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else + if job.startOn == "started udev" then [ "systemd-udev.service" ] else + []; + + wantedBy = if job.startOn == "" then [ ] else [ "multi-user.target" ]; + + serviceConfig = '' - [Unit] - Description=${job.description} - ${if job.startOn == "stopped udevtrigger" then "After=systemd-udev-settle.service" else - if job.startOn == "started udev" then "After=systemd-udev.service" - else ""} - - [Service] - Environment=PATH=${job.path} - ${concatMapStrings (n: "Environment=${n}=\"${getAttr n env}\"\n") (attrNames env)} - ${optionalString (job.preStart != "" && (job.script != "" || job.exec != "")) '' ExecStartPre=${preStartScript} ''} @@ -96,153 +95,8 @@ let ${optionalString (!job.task && job.respawn) "Restart=always"} ''; - - wantedBy = if job.startOn == "" then [ ] else [ "multi-user.target" ]; - }; - /* - text = - '' - ${optionalString (job.description != "") '' - description "${job.description}" - ''} - - ${if isList job.startOn then - "start on ${concatStringsSep " or " job.startOn}" - else if job.startOn != "" then - "start on ${job.startOn}" - else "" - } - - ${optionalString (job.stopOn != "") "stop on ${job.stopOn}"} - - env PATH=${job.path} - - ${concatMapStrings (n: "env ${n}=\"${getAttr n env}\"\n") (attrNames env)} - - ${optionalString (job.console != "") "console ${job.console}"} - - pre-start script - ln -sfn "$(readlink -f "/etc/init/${job.name}.conf")" /var/run/upstart-jobs/${job.name} - ${optionalString (job.preStart != "") '' - source ${jobHelpers} - ${job.preStart} - ''} - end script - - ${if job.script != "" && job.exec != "" then - abort "Job ${job.name} has both a `script' and `exec' attribute." - else if job.script != "" then - '' - script - source ${jobHelpers} - ${job.script} - end script - '' - else if job.exec != "" && job.console == "" then - '' - script - exec ${job.exec} - end script - '' - else if job.exec != "" then - '' - exec ${job.exec} - '' - else "" - } - - ${optionalString (job.postStart != "") '' - post-start script - source ${jobHelpers} - ${job.postStart} - end script - ''} - - ${optionalString job.task "task"} - ${optionalString (!job.task && job.respawn) "respawn"} - - ${ # preStop is run only if there is exec or script. - # (upstart 0.6.5, job.c:562) - optionalString (job.preStop != "") (assert hasMain; '' - pre-stop script - source ${jobHelpers} - ${job.preStop} - end script - '')} - - ${optionalString (job.postStop != "") '' - post-stop script - source ${jobHelpers} - ${job.postStop} - end script - ''} - - ${if job.daemonType == "fork" then "expect fork" else - if job.daemonType == "daemon" then "expect daemon" else - if job.daemonType == "stop" then "expect stop" else - if job.daemonType == "none" then "" else - throw "invalid daemon type `${job.daemonType}'"} - - ${optionalString (job.setuid != "") '' - setuid ${job.setuid} - ''} - - ${optionalString (job.setgid != "") '' - setuid ${job.setgid} - ''} - - ${job.extraConfig} - ''; - */ - - - # Shell functions for use in Upstart jobs. - jobHelpers = pkgs.writeText "job-helpers.sh" - '' - # Ensure that an Upstart service is running. - ensure() { - local job="$1" - local status="$(status "$job")" - - # If it's already running, we're happy. - [[ "$status" =~ start/running ]] && return 0 - - # If its current goal is to stop, start it. - [[ "$status" =~ stop/ ]] && { status="$(start "$job")" || true; } - - # The "start" command is synchronous *if* the job is - # not already starting. So if somebody else started - # the job in parallel, the "start" above may return - # while the job is still starting. So wait until it - # is up or has failed. - while true; do - [[ "$status" =~ stop/ ]] && { echo "job $job failed to start"; return 1; } - [[ "$status" =~ start/running ]] && return 0 - echo "waiting for job $job to start..." - sleep 1 - status="$(status "$job")" - done - } - - # Check whether the current job has been stopped. Used in - # post-start jobs to determine if they should continue. - stop_check() { - local status="$(status)" - if [[ "$status" =~ stop/ ]]; then - echo "job asked to stop!" - return 1 - fi - if [[ "$status" =~ respawn/ ]]; then - echo "job respawning unexpectedly!" - stop - return 1 - fi - return 0 - } - ''; - jobOptions = { @@ -418,8 +272,7 @@ let }; path = mkOption { - default = [ ]; - apply = ps: "${makeSearchPath "bin" ps}:${makeSearchPath "sbin" ps}"; + default = []; description = '' Packages added to the job's PATH environment variable. Both the bin and sbin @@ -507,7 +360,7 @@ in system.build.upstart = upstart; - boot.systemd.units = + boot.systemd.services = flip mapAttrs' config.jobs (name: job: nameValuePair "${job.name}.service" job.unit); From 9f5051b76c128987975c1aad3d2f9756fe0ccd03 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 17:55:27 -0400 Subject: [PATCH 011/327] Rename mingetty module to agetty --- modules/module-list.nix | 2 +- .../ttys/{mingetty.nix => agetty.nix} | 49 ++++++++++++------- modules/system/boot/systemd.nix | 40 +-------------- 3 files changed, 34 insertions(+), 57 deletions(-) rename modules/services/ttys/{mingetty.nix => agetty.nix} (57%) diff --git a/modules/module-list.nix b/modules/module-list.nix index 04fa9c58ec6c..2aa34cb205fd 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -165,7 +165,7 @@ ./services/system/nscd.nix ./services/system/uptimed.nix ./services/ttys/gpm.nix - ./services/ttys/mingetty.nix + ./services/ttys/agetty.nix ./services/web-servers/apache-httpd/default.nix ./services/web-servers/jboss/default.nix ./services/web-servers/tomcat.nix diff --git a/modules/services/ttys/mingetty.nix b/modules/services/ttys/agetty.nix similarity index 57% rename from modules/services/ttys/mingetty.nix rename to modules/services/ttys/agetty.nix index 8304ca180cb8..f70cbe74d67b 100644 --- a/modules/services/ttys/mingetty.nix +++ b/modules/services/ttys/agetty.nix @@ -10,6 +10,7 @@ with pkgs.lib; services.mingetty = { + # FIXME ttys = mkOption { default = if pkgs.stdenv.isArm @@ -40,7 +41,7 @@ with pkgs.lib; helpLine = mkOption { default = ""; description = '' - Help line printed by mingetty below the welcome line. + Help line printed by mingetty below the welcome line. Used by the installation CD to give some hints on how to proceed. ''; @@ -56,25 +57,39 @@ with pkgs.lib; config = { # Generate a separate job for each tty. - /* - jobs = listToAttrs (map (tty: nameValuePair tty { + boot.systemd.units."getty@.service".text = + '' + [Unit] + Description=Getty on %I + Documentation=man:agetty(8) + After=systemd-user-sessions.service plymouth-quit-wait.service - startOn = - # On tty1 we should always wait for mountall, since it may - # start an emergency-shell job. - if config.services.mingetty.waitOnMounts || tty == "tty1" - then "stopped udevtrigger and filesystem" - else "stopped udevtrigger"; # !!! should start as soon as the tty device is created + # If additional gettys are spawned during boot then we should make + # sure that this is synchronized before getty.target, even though + # getty.target didn't actually pull it in. + Before=getty.target + IgnoreOnIsolate=yes - path = [ pkgs.mingetty ]; - - exec = "mingetty --loginprog=${pkgs.shadow}/bin/login --noclear ${tty}"; - - environment.LOCALE_ARCHIVE = "/var/run/current-system/sw/lib/locale/locale-archive"; - - }) config.services.mingetty.ttys); - */ + [Service] + Environment=TERM=linux + Environment=LOCALE_ARCHIVE=/var/run/current-system/sw/lib/locale/locale-archive + ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 + Type=idle + Restart=always + RestartSec=0 + UtmpIdentifier=%I + TTYPath=/dev/%I + TTYReset=yes + TTYVHangup=yes + TTYVTDisallocate=yes + KillMode=process + IgnoreSIGPIPE=no + # Some login implementations ignore SIGTERM, so we send SIGHUP + # instead, to ensure that login terminates cleanly. + KillSignal=SIGHUP + ''; + environment.etc = singleton { # Friendly greeting on the virtual consoles. source = pkgs.writeText "issue" '' diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 906558bd6956..f41e471cb1bd 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -234,42 +234,6 @@ let KillSignal=SIGHUP ''; - gettyService = - '' - [Unit] - Description=Getty on %I - Documentation=man:agetty(8) - After=systemd-user-sessions.service plymouth-quit-wait.service - - # If additional gettys are spawned during boot then we should make - # sure that this is synchronized before getty.target, even though - # getty.target didn't actually pull it in. - Before=getty.target - IgnoreOnIsolate=yes - - [Service] - Environment=TERM=linux - ExecStart=-${pkgs.utillinux}/sbin/agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 - Type=idle - Restart=always - RestartSec=0 - UtmpIdentifier=%I - TTYPath=/dev/%I - TTYReset=yes - TTYVHangup=yes - TTYVTDisallocate=yes - KillMode=process - IgnoreSIGPIPE=no - - # Unset locale for the console getty since the console has problems - # displaying some internationalized messages. - Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= - - # Some login implementations ignore SIGTERM, so we send SIGHUP - # instead, to ensure that login terminates cleanly. - KillSignal=SIGHUP - ''; - serviceToUnit = name: def: { inherit (def) wantedBy; @@ -407,9 +371,7 @@ in ]; boot.systemd.units = - { "rescue.service".text = rescueService; - "getty@.service".text = gettyService; - } + { "rescue.service".text = rescueService; } // mapAttrs serviceToUnit cfg.services; }; From ca2bd17f54be0a1ba63b9723e0732bc8b0548af9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 17:58:31 -0400 Subject: [PATCH 012/327] Whitespace --- modules/services/ttys/agetty.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index f70cbe74d67b..43ee81481bff 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -41,7 +41,7 @@ with pkgs.lib; helpLine = mkOption { default = ""; description = '' - Help line printed by mingetty below the welcome line. + Help line printed by mingetty below the welcome line. Used by the installation CD to give some hints on how to proceed. ''; @@ -100,6 +100,7 @@ with pkgs.lib; ''; target = "issue"; }; + }; } From c3fb248bcb3d04b898341c214c348000060a41f1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 18:15:34 -0400 Subject: [PATCH 013/327] Get rid of the Upstart shutdown job The only thing that Upstart's shutdown job did that systemd doesn't do natively is update the hardware clock. So added a service for that. --- modules/module-list.nix | 3 +- modules/system/boot/shutdown.nix | 25 ++++ modules/system/upstart-events/shutdown.nix | 162 --------------------- 3 files changed, 27 insertions(+), 163 deletions(-) create mode 100644 modules/system/boot/shutdown.nix delete mode 100644 modules/system/upstart-events/shutdown.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 2aa34cb205fd..c7820690929e 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -194,8 +194,9 @@ ./system/boot/kernel.nix ./system/boot/luksroot.nix ./system/boot/modprobe.nix - ./system/boot/stage-1.nix + ./system/boot/shutdown.nix ./system/boot/stage-1-extratools.nix + ./system/boot/stage-1.nix ./system/boot/stage-2.nix ./system/boot/systemd.nix ./system/etc/etc.nix diff --git a/modules/system/boot/shutdown.nix b/modules/system/boot/shutdown.nix new file mode 100644 index 000000000000..3af8e3e4b295 --- /dev/null +++ b/modules/system/boot/shutdown.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + + # This unit saves the value of the system clock to the hardware + # clock on shutdown. + boot.systemd.units."save-hwclock.service" = + { wantedBy = [ "shutdown.target" ]; + + text = + '' + [Unit] + Description=Save Hardware Clock + DefaultDependencies=no + Before=shutdown.target + + [Service] + Type=oneshot + ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc --utc + ''; + }; + +} diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix deleted file mode 100644 index 8aa794378ed3..000000000000 --- a/modules/system/upstart-events/shutdown.nix +++ /dev/null @@ -1,162 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -{ - - jobs.shutdown = - { name = "shutdown"; - - task = true; - - stopOn = ""; # must override the default ("starting shutdown") - - environment = { MODE = "poweroff"; }; - - extraConfig = "console owner"; - - script = - '' - set +e # continue in case of errors - - ${pkgs.kbd}/bin/chvt 1 - - exec < /dev/console > /dev/console 2>&1 - echo "" - if test "$MODE" = maintenance; then - echo "<<< Entering maintenance mode >>>" - else - echo "<<< System shutdown >>>" - fi - echo "" - - ${config.powerManagement.powerDownCommands} - - export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH - - - # Do an initial sync just in case. - sync - - - # Kill all remaining processes except init, this one and any - # Upstart jobs that don't stop on the "starting shutdown" - # event, as these are necessary to complete the shutdown. - omittedPids=$(initctl list | sed -e 's/.*process \([0-9]\+\)/-o \1/;t;d') - #echo "saved PIDs: $omittedPids" - - echo "sending the TERM signal to all processes..." - ${pkgs.sysvtools}/bin/killall5 -15 $job $omittedPids - - sleep 1 # wait briefly - - echo "sending the KILL signal to all processes..." - ${pkgs.sysvtools}/bin/killall5 -9 $job $omittedPids - - - # If maintenance mode is requested, start a root shell, and - # afterwards emit the "startup" event to bring everything - # back up. - if test "$MODE" = maintenance; then - echo "" - echo "<<< Maintenance shell >>>" - echo "" - ${pkgs.shadow}/bin/login root - initctl emit -n startup - exit 0 - fi - - - # Write a shutdown record to wtmp while /var/log is still writable. - reboot --wtmp-only - - - # Set the hardware clock to the system time. - echo "setting the hardware clock..." - hwclock --systohc --utc - - - # Stop all swap devices. - swapoff -a - - - # Unmount file systems. We repeat this until no more file systems - # can be unmounted. This is to handle loopback devices, file - # systems mounted on other file systems and so on. - tryAgain=1 - while test -n "$tryAgain"; do - tryAgain= - failed= # list of mount points that couldn't be unmounted/remounted - - # Get rid of loopback devices. - loDevices=$(losetup -a | sed 's#^\(/dev/loop[0-9]\+\).*#\1#') - if [ -n "$loDevices" ]; then - echo "removing loopback devices $loDevices..." - losetup -d $loDevices - fi - - cp /proc/mounts /dev/.mounts # don't read /proc/mounts while it's changing - exec 4< /dev/.mounts - while read -u 4 device mp fstype options rest; do - # Skip various special filesystems. Non-existent - # mount points are typically tmpfs/aufs mounts from - # the initrd. - if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /run -o "$mp" = /var/run -o "$mp" = /var/lock -o ! -e "$mp" ]; then continue; fi - - echo "unmounting $mp..." - - # We need to remount,ro before attempting any - # umount, or bind mounts may get confused, with - # the fs not being properly flushed at the end. - - # `-i' is to workaround a bug in mount.cifs (it - # doesn't recognise the `remount' option, and - # instead mounts the FS again). - success= - if mount -t "$fstype" -n -i -o remount,ro "device" "$mp"; then success=1; fi - - # Note: don't use `umount -f'; it's very buggy. - # (For instance, when applied to a bind-mount it - # unmounts the target of the bind-mount.) !!! But - # we should use `-f' for NFS. - if [ "$mp" != / -a "$mp" != /nix -a "$mp" != /nix/store ]; then - if umount -n "$mp"; then success=1; tryAgain=1; fi - fi - - if [ -z "$success" ]; then failed="$failed $mp"; fi - done - done - - - # Warn about filesystems that could not be unmounted or - # remounted read-only. - if [ -n "$failed" ]; then - echo "warning: the following filesystems could not be unmounted:" - for mp in $failed; do echo " $mp"; done - echo Enter 'i' to launch a shell, or wait 10 seconds to continue. - read -t 10 A - if [ "$A" == "i" ]; then - ${pkgs.bashInteractive}/bin/bash -i < /dev/console &> /dev/console - fi - sleep 5 - fi - - - # Final sync. - sync - - - # Either reboot or power-off the system. - if test "$MODE" = reboot; then - echo "rebooting..." - sleep 1 - exec reboot -f - else - echo "powering off..." - sleep 1 - exec halt -f -p - fi - ''; - }; - -} From 13c690b7213ef6385648d126df9aaf487d9774ae Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 18:16:38 -0400 Subject: [PATCH 014/327] Add a .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..b25c15b81fae --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ From c73d642db24bf6fe91d6c23333461f478a9b2d46 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 23:30:26 -0400 Subject: [PATCH 015/327] Don't put quotes around environment values --- modules/system/boot/systemd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index f41e471cb1bd..652f97630242 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -248,7 +248,7 @@ let [Service] Environment=PATH=${def.path} - ${concatMapStrings (n: "Environment=${n}=\"${getAttr n def.environment}\"\n") (attrNames def.environment)} + ${concatMapStrings (n: "Environment=${n}=${getAttr n def.environment}\n") (attrNames def.environment)} ${optionalString (def.preStart != "") '' ExecStartPre=${pkgs.writeScript "${name}-prestart.sh" '' From 88f94d76bcce27b42c748e6f2a7691d0659e5513 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 18 Jun 2012 23:31:07 -0400 Subject: [PATCH 016/327] Use socket-based activation of the Nix daemon --- modules/services/misc/nix-daemon.nix | 112 ++++++++++++++------------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index 31b81a13e363..ea13def39d60 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -4,6 +4,8 @@ with pkgs.lib; let + cfg = config.nix; + inherit (config.environment) nix; makeNixBuildUser = nr: @@ -74,9 +76,7 @@ in gc-keep-outputs = true gc-keep-derivations = true "; - description = " - This option allows to append lines to nix.conf. - "; + description = "Additional text appended to nix.conf."; }; distributedBuilds = mkOption { @@ -169,11 +169,9 @@ in # actually a shell script. envVars = mkOption { internal = true; - default = ""; - type = types.string; - description = " - Environment variables used by Nix. - "; + default = {}; + type = types.attrs; + description = "Environment variables used by Nix."; }; nrBuildUsers = mkOption { @@ -208,14 +206,14 @@ in # /bin/sh won't work. binshDeps = pkgs.writeReferencesToFile config.system.build.binsh; in - pkgs.runCommand "nix.conf" {extraOptions = config.nix.extraOptions; } '' + pkgs.runCommand "nix.conf" {extraOptions = cfg.extraOptions; } '' extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done) cat > $out < /dev/null 2>&1 - ''; + environment = cfg.envVars; - extraConfig = + serviceConfig = '' - limit nofile 4096 4096 + ExecStart=${nix}/bin/nix-worker --daemon + KillMode=process + PIDFile=/run/sshd.pid + Nice=${toString cfg.daemonNiceLevel} + IOSchedulingPriority=${toString cfg.daemonIONiceLevel} + LimitNOFILE=4096 ''; }; + + nix.envVars = + { NIX_CONF_DIR = "/etc/nix"; + + # Enable the copy-from-other-stores substituter, which allows builds + # to be sped up by copying build results from remote Nix stores. To + # do this, mount the remote file system on a subdirectory of + # /var/run/nix/remote-stores. + NIX_OTHER_STORES = "/var/run/nix/remote-stores/*/nix"; + } + + // optionalAttrs cfg.distributedBuilds { + NIX_BUILD_HOOK = "${config.environment.nix}/libexec/nix/build-remote.pl"; + NIX_REMOTE_SYSTEMS = "/etc/nix.machines"; + NIX_CURRENT_LOAD = "/var/run/nix/current-load"; + } + + # !!! These should not be defined here, but in some general proxy configuration module! + // optionalAttrs (cfg.proxy != "") { + http_proxy = cfg.proxy; + https_proxy = cfg.proxy; + ftp_proxy = cfg.proxy; + }; environment.shellInit = '' # Set up the environment variables for running Nix. - ${config.nix.envVars} + ${concatMapStrings (n: "export ${n}=\"${getAttr n cfg.envVars}\"\n") (attrNames cfg.envVars)} # Set up secure multi-user builds: non-root users build through the # Nix daemon. @@ -274,29 +304,7 @@ in fi ''; - nix.envVars = - '' - export NIX_CONF_DIR=/etc/nix - - # Enable the copy-from-other-stores substituter, which allows builds - # to be sped up by copying build results from remote Nix stores. To - # do this, mount the remote file system on a subdirectory of - # /var/run/nix/remote-stores. - export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix - '' # */ - + optionalString config.nix.distributedBuilds '' - export NIX_BUILD_HOOK=${config.environment.nix}/libexec/nix/build-remote.pl - export NIX_REMOTE_SYSTEMS=/etc/nix.machines - export NIX_CURRENT_LOAD=/var/run/nix/current-load - '' - # !!! These should not be defined here, but in some general proxy configuration module! - + optionalString (config.nix.proxy != "") '' - export http_proxy=${config.nix.proxy} - export https_proxy=${config.nix.proxy} - export ftp_proxy=${config.nix.proxy} - ''; - - users.extraUsers = map makeNixBuildUser (range 1 config.nix.nrBuildUsers); + users.extraUsers = map makeNixBuildUser (range 1 cfg.nrBuildUsers); system.activationScripts.nix = stringAfter [ "etc" "users" ] '' From f213c4ca29b132ce19659af888788e102c7e4171 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 09:28:04 -0400 Subject: [PATCH 017/327] Don't run syslogd and klogd The systemd journal removes the need for running syslogd and klogd, so don't start them. --- modules/config/system-path.nix | 1 - modules/module-list.nix | 2 +- modules/services/logging/syslogd.nix | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix index d5939db95ac8..89524c3f2311 100644 --- a/modules/config/system-path.nix +++ b/modules/config/system-path.nix @@ -47,7 +47,6 @@ let pkgs.procps pkgs.rsync pkgs.strace - pkgs.sysklogd pkgs.sysvtools pkgs.time pkgs.udev diff --git a/modules/module-list.nix b/modules/module-list.nix index c7820690929e..6f65e71be9b0 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -80,7 +80,7 @@ ./services/hardware/udev.nix ./services/hardware/udisks.nix ./services/hardware/upower.nix - ./services/logging/klogd.nix + #./services/logging/klogd.nix ./services/logging/logrotate.nix ./services/logging/syslogd.nix ./services/mail/dovecot.nix diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix index 715cfc0f9e6f..bfe7352122c0 100644 --- a/modules/services/logging/syslogd.nix +++ b/modules/services/logging/syslogd.nix @@ -96,7 +96,7 @@ in jobs.syslogd = { description = "Syslog daemon"; - startOn = "started udev"; + #startOn = "started udev"; environment = { TZ = config.time.timeZone; }; From 2b305d7f294090e31da8e039ffbf90f03c41e526 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 14:50:23 -0400 Subject: [PATCH 018/327] Remove accidentally committed line --- modules/services/hardware/udev.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix index 81a9b570127b..fe1b73233585 100644 --- a/modules/services/hardware/udev.nix +++ b/modules/services/hardware/udev.nix @@ -20,7 +20,6 @@ let # Miscellaneous devices. KERNEL=="kvm", MODE="0666" KERNEL=="kqemu", MODE="0666" - KERNEL=="null", MODE="0777" ''; # Perform substitutions in all udev rules files. From dab6bbe3a691cafac994e1782d9141ddd1861f1b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 14:51:04 -0400 Subject: [PATCH 019/327] Set the default unit to "graphical.target" if X11 is enabled --- modules/services/x11/xserver.nix | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 2ae42f5b41be..61af0459a6bd 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -377,15 +377,13 @@ in environment.pathsToLink = [ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ]; - jobs."xserver-start-check" = - { startOn = if cfg.autorun then "filesystem and stopped udevtrigger" else ""; - stopOn = ""; - task = true; - script = "grep -qv noX11 /proc/cmdline && start xserver || true"; - }; + boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; - jobs.xserver = - { restartIfChanged = false; + boot.systemd.services."xserver.service" = + { wantedBy = [ "graphical.target" ]; + after = [ "systemd-udev-settle.service" ]; + + #restartIfChanged = false; environment = { FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup From cd7872b7587fe0d61480dce79ca8f9c68f3dcf38 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 15:14:54 -0400 Subject: [PATCH 020/327] Drop dependency on the old udev --- modules/config/system-path.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix index 89524c3f2311..7651f4760ca7 100644 --- a/modules/config/system-path.nix +++ b/modules/config/system-path.nix @@ -49,7 +49,6 @@ let pkgs.strace pkgs.sysvtools pkgs.time - pkgs.udev pkgs.usbutils pkgs.utillinux extraManpages From cacd608c37dd0253eb6ef5cda2190e47e9e0717b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 15:15:40 -0400 Subject: [PATCH 021/327] Mount devtmpfs in the initrd It seems that udev now requires devtmpfs, so enable it. --- modules/system/boot/stage-1-init.sh | 13 +------------ modules/system/boot/stage-1.nix | 1 - modules/system/boot/stage-2-init.sh | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 278c68fce992..aeb6a5189065 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -66,17 +66,10 @@ mkdir -p /proc mount -t proc none /proc mkdir -p /sys mount -t sysfs none /sys -mount -t tmpfs -o "mode=0755,size=@devSize@" none /dev +mount -t devtmpfs -o "size=@devSize@" none /dev mkdir -p /run mount -t tmpfs -o "mode=0755,size=@runSize@" none /run -# Some console devices, for the interactivity -mknod /dev/console c 5 1 -mknod /dev/tty c 5 0 -mknod /dev/tty1 c 4 1 -mknod /dev/ttyS0 c 4 64 -mknod /dev/ttyS1 c 4 65 - # Process the kernel command line. export stage2Init=/init for o in $(cat /proc/cmdline); do @@ -127,10 +120,6 @@ for i in @kernelModules@; do done -# Create /dev/null. -mknod /dev/null c 1 3 - - # Create device nodes in /dev. echo "running udev..." export UDEV_CONFIG_FILE=@udevConf@ diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index 75f83a27db9d..355f88cf3857 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -154,7 +154,6 @@ let # Copy some coreutils. cp -v ${pkgs.coreutils}/bin/basename $out/bin cp -v ${pkgs.coreutils}/bin/mkdir $out/bin - cp -v ${pkgs.coreutils}/bin/mknod $out/bin cp -v ${pkgs.coreutils}/bin/chmod $out/bin cp -v ${pkgs.coreutils}/bin/cat $out/bin cp -v ${pkgs.coreutils}/bin/chroot $out/bin diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 8238fc1537ea..a4b966081d64 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -39,7 +39,7 @@ if [ ! -e /proc/1 ]; then mkdir -m 0755 -p /sys mount -t sysfs none /sys mkdir -m 0755 -p /dev - mount -t tmpfs -o "mode=0755" none /dev + mount -t devtmpfs none /dev # Create the minimal device nodes needed for the activation scripts # and Upstart. From d692a0807aa0afc216a76c4da02ae979d3dbcf8f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 15:25:56 -0400 Subject: [PATCH 022/327] Don't mount /dev/pts since systemd does that for us --- modules/system/boot/stage-2-init.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index a4b966081d64..bb9b5c281635 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -36,20 +36,8 @@ mount -n -o remount,rw none / if [ ! -e /proc/1 ]; then mkdir -m 0755 -p /proc mount -n -t proc none /proc - mkdir -m 0755 -p /sys - mount -t sysfs none /sys mkdir -m 0755 -p /dev mount -t devtmpfs none /dev - - # Create the minimal device nodes needed for the activation scripts - # and Upstart. - mknod -m 0666 /dev/null c 1 3 - mknod -m 0644 /dev/urandom c 1 9 # needed for passwd - mknod -m 0644 /dev/console c 5 1 - mknod -m 0644 /dev/ptmx c 5 2 # required by upstart - mknod -m 0644 /dev/tty1 c 4 1 - mknod -m 0644 /dev/ttyS0 c 4 64 - mknod -m 0644 /dev/ttyS1 c 4 65 fi @@ -87,7 +75,6 @@ done mkdir -m 0777 /dev/shm mount -t tmpfs -o "rw,nosuid,nodev,size=@devShmSize@" tmpfs /dev/shm mkdir -m 0755 -p /dev/pts -mount -t devpts -o mode=0600,gid=@ttyGid@ none /dev/pts [ -e /proc/bus/usb ] && mount -t usbfs none /proc/bus/usb # UML doesn't have USB by default mkdir -m 01777 -p /tmp mkdir -m 0755 -p /var /var/log From 2526afb1c7711123a183482f4e2f11637adcb1a9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 16:22:26 -0400 Subject: [PATCH 023/327] Don't use ConsoleKit --- modules/services/x11/display-managers/default.nix | 6 ------ modules/services/x11/display-managers/kdm.nix | 2 +- modules/services/x11/display-managers/slim.nix | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/modules/services/x11/display-managers/default.nix b/modules/services/x11/display-managers/default.nix index cdfd271ee65c..528b3a6f7276 100644 --- a/modules/services/x11/display-managers/default.nix +++ b/modules/services/x11/display-managers/default.nix @@ -53,12 +53,6 @@ let fi ''} - # Start a ConsoleKit session so that we get ownership of various - # devices. - if test -z "$XDG_SESSION_COOKIE"; then - exec ${pkgs.consolekit}/bin/ck-launch-session "$0" "$sessionType" - fi - # Handle being called by kdm. if test "''${1:0:1}" = /; then eval exec "$1"; fi diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index fe7802100b2c..47d9299fb79f 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -111,7 +111,7 @@ in logsXsession = true; }; - security.pam.services = [ { name = "kde"; allowNullPassword = true; } ]; + security.pam.services = [ { name = "kde"; allowNullPassword = true; ownDevices = true; } ]; users.extraUsers = singleton { name = "kdm"; diff --git a/modules/services/x11/display-managers/slim.nix b/modules/services/x11/display-managers/slim.nix index 97c5f1d1b2b8..fc4df80d810a 100644 --- a/modules/services/x11/display-managers/slim.nix +++ b/modules/services/x11/display-managers/slim.nix @@ -115,7 +115,7 @@ in # Allow null passwords so that the user can login as root on the # installation CD. - security.pam.services = [ { name = "slim"; allowNullPassword = true; } ]; + security.pam.services = [ { name = "slim"; allowNullPassword = true; ownDevices = true; } ]; }; From 2fa1ba85c6f4b96a56d8ed0c1ca361ee59dc6d2b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 17:02:54 -0400 Subject: [PATCH 024/327] Enable the systemd password agents --- modules/system/boot/systemd.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 652f97630242..7fafc94a4bba 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -194,6 +194,12 @@ let "umount.target" "final.target" + # Password entry. + "systemd-ask-password-console.path" + "systemd-ask-password-console.service" + "systemd-ask-password-wall.path" + "systemd-ask-password-wall.service" + # Misc. "syslog.socket" ]; From 337423af8e63f6d89cfd5818a27e48163239d6bd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 19 Jun 2012 17:36:02 -0400 Subject: [PATCH 025/327] Backdoor: depend on /dev/hvc0 Systemd is the shit: units can declare a dependency on the appearance of device nodes. Yay! --- modules/system/boot/systemd.nix | 21 ++++++++++++++++++++- modules/testing/test-instrumentation.nix | 15 +++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 7fafc94a4bba..6976a204e7f2 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -12,6 +12,23 @@ let description = "Description of this unit used in systemd messages and progress indicators."; }; + requires = mkOption { + default = []; + types = types.listOf types.string; + description = '' + Start the specified units when this unit is started, and stop + this unit when the specified units are stopped or fail. + ''; + }; + + wants = mkOption { + default = []; + types = types.listOf types.string; + description = '' + Start the specified units when this unit is started. + ''; + }; + after = mkOption { default = []; types = types.listOf types.string; @@ -33,7 +50,7 @@ let wantedBy = mkOption { default = []; types = types.listOf types.string; - description = "Units that want (i.e. depend on) this unit."; + description = "Start this unit when the specified units are started."; }; environment = mkOption { @@ -249,6 +266,8 @@ let ${optionalString (def.description != "") '' Description=${def.description} ''} + Requires=${concatStringsSep " " def.requires} + Wants=${concatStringsSep " " def.wants} Before=${concatStringsSep " " def.before} After=${concatStringsSep " " def.after} diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 5e40cf215b7c..468a3030ca6b 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -21,15 +21,12 @@ in { - config = - # Require a patch to the kernel to increase the 15s CIFS timeout. - mkAssert (config.boot.kernelPackages.kernel.features ? cifsTimeout) " - VM tests require that the kernel has the CIFS timeout patch. - " { + config = { - jobs.backdoor = - { startOn = "started udev"; - stopOn = ""; + boot.systemd.services."backdoor.service" = + { wantedBy = [ "multi-user.target" ]; + requires = [ "dev-hvc0.device" ]; + after = [ "dev-hvc0.device" ]; script = '' @@ -43,8 +40,6 @@ in stty -F /dev/hvc0 raw -echo # prevent nl -> cr/nl conversion ${pkgs.socat}/bin/socat stdio exec:${rootShell} ''; - - respawn = false; }; boot.initrd.postDeviceCommands = From 94daecd90b237625955528c1f20cb4cd4b7dd692 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 16 Jul 2012 17:32:26 -0400 Subject: [PATCH 026/327] save-hwclock.service: support time.hardwareClockInLocalTime --- modules/system/boot/shutdown.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/shutdown.nix b/modules/system/boot/shutdown.nix index 3af8e3e4b295..1335429b6697 100644 --- a/modules/system/boot/shutdown.nix +++ b/modules/system/boot/shutdown.nix @@ -18,7 +18,7 @@ with pkgs.lib; [Service] Type=oneshot - ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc --utc + ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc ${if config.time.hardwareClockInLocalTime then "--localtime" else "--utc"} ''; }; From 917e53a2d255885835814e7ff30708facca4ca88 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 16 Jul 2012 17:47:11 -0400 Subject: [PATCH 027/327] Update units names for systemd-186 --- modules/system/boot/systemd.nix | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 6976a204e7f2..d7684c7ecb26 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -140,9 +140,9 @@ let "time-sync.target" # Udev. - "systemd-udev-control.socket" - "systemd-udev-kernel.socket" - "systemd-udev.service" + "systemd-udevd-control.socket" + "systemd-udevd-kernel.socket" + "systemd-udevd.service" "systemd-udev-settle.service" "systemd-udev-trigger.service" @@ -157,6 +157,7 @@ let # Journal. "systemd-journald.socket" "systemd-journald.service" + "syslog.socket" # SysV init compatibility. "systemd-initctl.socket" @@ -178,8 +179,8 @@ let "systemd-update-utmp-shutdown.service" # Filesystems. - "fsck@.service" - "fsck-root.service" + "systemd-fsck@.service" + "systemd-fsck-root.service" "systemd-remount-fs.service" "local-fs.target" "local-fs-pre.target" @@ -194,18 +195,18 @@ let # Hibernate / suspend. "hibernate.target" - "hibernate.service" + "systemd-hibernate.service" "suspend.target" - "suspend.service" + "systemd-suspend.service" "sleep.target" # Reboot stuff. "reboot.target" - "reboot.service" + "systemd-reboot.service" "poweroff.target" - "poweroff.service" + "systemd-poweroff.service" "halt.target" - "halt.service" + "systemd-halt.service" "ctrl-alt-del.target" "shutdown.target" "umount.target" @@ -216,9 +217,6 @@ let "systemd-ask-password-console.service" "systemd-ask-password-wall.path" "systemd-ask-password-wall.service" - - # Misc. - "syslog.socket" ]; upstreamWants = From 425ec4cb00d09a0803d9cc8cdbc554661c704a8a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 19 Jul 2012 12:48:30 -0400 Subject: [PATCH 028/327] syslogd: Make it work with systemd Also made syslogd optional (and disabled by default). --- modules/services/logging/syslogd.nix | 32 ++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix index bfe7352122c0..2136aaa5586c 100644 --- a/modules/services/logging/syslogd.nix +++ b/modules/services/logging/syslogd.nix @@ -36,6 +36,15 @@ in services.syslogd = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable syslogd. Note that systemd also logs + syslog messages, so you normally don't need to run syslogd. + ''; + }; + tty = mkOption { type = types.uniq types.string; default = "tty10"; @@ -89,22 +98,27 @@ in ###### implementation - config = { + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.sysklogd ]; services.syslogd.extraParams = optional cfg.enableNetworkInput "-r"; - jobs.syslogd = + boot.systemd.services."syslog.service" = { description = "Syslog daemon"; + + requires = [ "syslog.socket" ]; - #startOn = "started udev"; + wantedBy = [ "multi-user.target" "syslog.target" ]; - environment = { TZ = config.time.timeZone; }; + environment.TZ = config.time.timeZone; - daemonType = "fork"; - - path = [ pkgs.sysklogd ]; - - exec = "syslogd ${toString cfg.extraParams} -f ${syslogConf}"; + serviceConfig = + '' + ExecStart=${pkgs.sysklogd}/sbin/syslogd ${toString cfg.extraParams} -f ${syslogConf} -n + # Prevent syslogd output looping back through journald. + StandardOutput=null + ''; }; }; From 6419172bc2c3b07c6769479a7cfc07806143e32b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 19 Jul 2012 17:32:50 -0400 Subject: [PATCH 029/327] journald: enable logging to the console --- modules/system/boot/systemd.nix | 43 +++++++++++++++++++----- modules/testing/test-instrumentation.nix | 11 ++---- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index d7684c7ecb26..2b32c94262ed 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -295,21 +295,21 @@ let units = pkgs.runCommand "units" { preferLocalBuild = true; } '' - mkdir -p $out/system + mkdir -p $out for i in ${toString upstreamUnits}; do fn=${systemd}/example/systemd/system/$i [ -e $fn ] if [ -L $fn ]; then - cp -pd $fn $out/system/ + cp -pd $fn $out/ else - ln -s $fn $out/system + ln -s $fn $out/ fi done for i in ${toString upstreamWants}; do fn=${systemd}/example/systemd/system/$i [ -e $fn ] - x=$out/system/$(basename $fn) + x=$out/$(basename $fn) mkdir $x for i in $fn/*; do y=$x/$(basename $i) @@ -319,16 +319,16 @@ let done for i in ${toString nixosUnits}; do - cp $i/* $out/system + cp $i/* $out/ done ${concatStrings (mapAttrsToList (name: unit: concatMapStrings (name2: '' - mkdir -p $out/system/${name2}.wants - ln -sfn ../${name} $out/system/${name2}.wants/ + mkdir -p $out/${name2}.wants + ln -sfn ../${name} $out/${name2}.wants/ '') unit.wantedBy) cfg.units)} - ln -s ${cfg.defaultUnit} $out/system/default.target + ln -s ${cfg.defaultUnit} $out/default.target ''; # */ in @@ -373,6 +373,18 @@ in type = types.uniq types.string; description = "Default unit started when the system boots."; }; + + services.journald.logKernelMessages = mkOption { + default = true; + type = types.bool; + description = "Whether to log kernel messages."; + }; + + services.journald.console = mkOption { + default = ""; + type = types.uniq types.string; + description = "If non-empty, write log messages to the specified TTY device. Defaults to /dev/console."; + }; }; @@ -389,7 +401,20 @@ in environment.etc = [ { source = units; - target = "systemd"; + target = "systemd/system"; + } + { source = pkgs.writeText "journald.conf" + '' + [Journal] + ${optionalString (config.services.journald.console != "") '' + ForwardToConsole=yes + TTYPath=${config.services.journald.console} + ''} + ${optionalString config.services.journald.logKernelMessages '' + ImportKernel=yes + ''} + ''; + target = "systemd/journald.conf"; } ]; diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index ce9c1cea7431..c81f6eaac65a 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -66,15 +66,8 @@ with pkgs.lib; # `xwininfo' is used by the test driver to query open windows. environment.systemPackages = [ pkgs.xorg.xwininfo ]; - # Send all of /var/log/messages to the serial port. - services.syslogd.extraConfig = "*.* /dev/ttyS0"; - - # Disable "-- MARK --" messages. These prevent hanging tests from - # being killed after 1 hour of silence. - services.syslogd.extraParams = [ "-m 0" ]; - - # Don't run klogd. Kernel messages appear on the serial console anyway. - jobs.klogd.startOn = mkOverride 50 ""; + # Log everything to the serial console. + services.journald.console = "/dev/console"; # Prevent tests from accessing the Internet. networking.defaultGateway = mkOverride 150 ""; From ae62436697d75dff839bbfb12bba2d6b1a8136a1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 19 Jul 2012 17:33:22 -0400 Subject: [PATCH 030/327] Random changes --- modules/services/logging/syslogd.nix | 1 + modules/services/networking/ssh/sshd.nix | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix index 2136aaa5586c..a3aff9a30d3a 100644 --- a/modules/services/logging/syslogd.nix +++ b/modules/services/logging/syslogd.nix @@ -104,6 +104,7 @@ in services.syslogd.extraParams = optional cfg.enableNetworkInput "-r"; + # FIXME: restarting syslog seems to break journal logging. boot.systemd.services."syslog.service" = { description = "Syslog daemon"; diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index d89978a852c0..0ef1f09f4d6c 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -330,7 +330,7 @@ in }; boot.systemd.services."sshd.service" = - { description = "SSH daemon"; + { description = "SSH Daemon"; wantedBy = [ "multi-user.target" ]; after = [ "set-ssh-keys.service" ]; From 02e37ba6b006414e528b53020fee99507e0e4c51 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 19 Jul 2012 17:41:42 -0400 Subject: [PATCH 031/327] Shorten filenames of start scripts to make log messages more readable --- modules/system/boot/systemd.nix | 6 ++++-- modules/system/upstart/upstart.nix | 12 +++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 2b32c94262ed..b41049806186 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -255,6 +255,8 @@ let KillSignal=SIGHUP ''; + makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; + serviceToUnit = name: def: { inherit (def) wantedBy; @@ -274,14 +276,14 @@ let ${concatMapStrings (n: "Environment=${n}=${getAttr n def.environment}\n") (attrNames def.environment)} ${optionalString (def.preStart != "") '' - ExecStartPre=${pkgs.writeScript "${name}-prestart.sh" '' + ExecStartPre=${makeJobScript "${name}-prestart.sh" '' #! ${pkgs.stdenv.shell} -e ${def.preStart} ''} ''} ${optionalString (def.script != "") '' - ExecStart=${pkgs.writeScript "${name}.sh" '' + ExecStart=${makeJobScript "${name}.sh" '' #! ${pkgs.stdenv.shell} -e ${def.script} ''} diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index de60f693e831..cbefad214148 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -12,6 +12,8 @@ let groupExists = g: (g == "") || any (gg: gg.name == g) (attrValues config.users.extraGroups); + makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; + # From a job description, generate an systemd unit file. makeUnit = job: @@ -20,13 +22,13 @@ let env = config.system.upstartEnvironment // job.environment; - preStartScript = pkgs.writeScript "${job.name}-pre-start.sh" + preStartScript = makeJobScript "${job.name}-pre-start.sh" '' #! ${pkgs.stdenv.shell} -e ${job.preStart} ''; - startScript = pkgs.writeScript "${job.name}-start.sh" + startScript = makeJobScript "${job.name}-start.sh" '' #! ${pkgs.stdenv.shell} -e ${if job.script != "" then job.script else '' @@ -34,19 +36,19 @@ let ''} ''; - postStartScript = pkgs.writeScript "${job.name}-post-start.sh" + postStartScript = makeJobScript "${job.name}-post-start.sh" '' #! ${pkgs.stdenv.shell} -e ${job.postStart} ''; - preStopScript = pkgs.writeScript "${job.name}-pre-stop.sh" + preStopScript = makeJobScript "${job.name}-pre-stop.sh" '' #! ${pkgs.stdenv.shell} -e ${job.preStop} ''; - postStopScript = pkgs.writeScript "${job.name}-post-stop.sh" + postStopScript = makeJobScript "${job.name}-post-stop.sh" '' #! ${pkgs.stdenv.shell} -e ${job.postStop} From 41cb04f793d4f54ab131934cfac8ca857d61c352 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 11:36:09 -0400 Subject: [PATCH 032/327] Implement serial-getty@.service --- modules/services/ttys/agetty.nix | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index 42d276c96664..a0e53eeaef46 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -21,6 +21,7 @@ with pkgs.lib; ''; }; + # FIXME: not implemented with systemd waitOnMounts = mkOption { default = false; description = '' @@ -56,6 +57,9 @@ with pkgs.lib; config = { + # FIXME: these are mostly copy/pasted from the systemd sources, + # which some small modifications, which is annoying. + # Generate a separate job for each tty. boot.systemd.units."getty@.service".text = '' @@ -70,6 +74,8 @@ with pkgs.lib; Before=getty.target IgnoreOnIsolate=yes + ConditionPathExists=/dev/tty0 + [Service] Environment=TERM=linux Environment=LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive @@ -90,6 +96,39 @@ with pkgs.lib; KillSignal=SIGHUP ''; + boot.systemd.units."serial-getty@.service".text = + '' + [Unit] + Description=Serial Getty on %I + Documentation=man:agetty(8) man:systemd-getty-generator(8) + BindsTo=dev-%i.device + After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service + + # If additional gettys are spawned during boot then we should make + # sure that this is synchronized before getty.target, even though + # getty.target didn't actually pull it in. + Before=getty.target + IgnoreOnIsolate=yes + + [Service] + Environment=TERM=linux + Environment=LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive + ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --login-program ${pkgs.shadow}/bin/login %I 115200,38400,9600 + Type=idle + Restart=always + RestartSec=0 + UtmpIdentifier=%I + TTYPath=/dev/%I + TTYReset=yes + TTYVHangup=yes + KillMode=process + IgnoreSIGPIPE=no + + # Some login implementations ignore SIGTERM, so we send SIGHUP + # instead, to ensure that login terminates cleanly. + KillSignal=SIGHUP + ''; + environment.etc = singleton { # Friendly greeting on the virtual consoles. source = pkgs.writeText "issue" '' From 1375e7951d73280e08bda26bef0ad9c85d059fe2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 12:02:42 -0400 Subject: [PATCH 033/327] Enable systemd-journal-flush.service (added by systemd 187) --- modules/system/boot/systemd.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index b41049806186..40ff14dda7a7 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -157,6 +157,7 @@ let # Journal. "systemd-journald.socket" "systemd-journald.service" + "systemd-journal-flush.service" "syslog.socket" # SysV init compatibility. From 1cde1bdbe68a989cf8776fb81b3f6ad311a93bd6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 12:03:15 -0400 Subject: [PATCH 034/327] nixos-run-vms: If there is only one VM, attach stdio to its serial console This is useful for interactive testing (quicker than logging in via SSH and more convenient than logging in via a virtual console). --- lib/test-driver/Machine.pm | 11 +++++++---- lib/test-driver/test-driver.pl | 2 +- lib/testing.nix | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index dee1e4f33cb2..f0d5fbc19ead 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -50,6 +50,7 @@ sub new { stateDir => "$tmpDir/vm-state-$name", monitor => undef, log => $args->{log}, + redirectSerial => $args->{redirectSerial} // 1, }; mkdir $self->{stateDir}, 0700; @@ -117,10 +118,12 @@ sub start { close $serialP; close $monitorS; close $shellS; - open NUL, "{redirectSerial}) { + open NUL, "{stateDir}; $ENV{USE_TMPDIR} = 1; $ENV{QEMU_OPTS} = diff --git a/lib/test-driver/test-driver.pl b/lib/test-driver/test-driver.pl index 43f74cf404bb..fc4b7ea05551 100644 --- a/lib/test-driver/test-driver.pl +++ b/lib/test-driver/test-driver.pl @@ -50,7 +50,7 @@ my $context = ""; sub createMachine { my ($args) = @_; - my $vm = Machine->new({%{$args}, log => $log}); + my $vm = Machine->new({%{$args}, log => $log, redirectSerial => ($ENV{USE_SERIAL} // "0") ne "1"}); $vms{$vm->name} = $vm; return $vm; } diff --git a/lib/testing.nix b/lib/testing.nix index 6a39df8c865d..212c478a728b 100644 --- a/lib/testing.nix +++ b/lib/testing.nix @@ -158,7 +158,8 @@ rec { wrapProgram $out/bin/nixos-run-vms \ --add-flags "$vms" \ --set tests '"startAll; joinAll;"' \ - --set VLANS '"${toString vlans}"' + --set VLANS '"${toString vlans}"' \ + ${lib.optionalString (builtins.length vms == 1) "--set USE_SERIAL 1"} ''; # " test = runTests driver; From 1602f8e1625d22531b9d414ec1709c2e715776dd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 14:58:15 -0400 Subject: [PATCH 035/327] Typo --- modules/services/misc/nix-daemon.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index ea13def39d60..35c1ace93d3d 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -76,7 +76,7 @@ in gc-keep-outputs = true gc-keep-derivations = true "; - description = "Additional text appended to nix.conf."; + description = "Additional text appended to nix.conf."; }; distributedBuilds = mkOption { From 5fabcf63a36b9d5032ad04a1daf86edb2c0ff3be Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 15:40:50 -0400 Subject: [PATCH 036/327] Get delayed shutdowns to work --- modules/system/boot/systemd.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 40ff14dda7a7..5f7f62b7866a 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -196,10 +196,12 @@ let # Hibernate / suspend. "hibernate.target" - "systemd-hibernate.service" "suspend.target" - "systemd-suspend.service" "sleep.target" + "systemd-hibernate.service" + "systemd-suspend.service" + "systemd-shutdownd.socket" + "systemd-shutdownd.service" # Reboot stuff. "reboot.target" From 0b865edb16f834684726903c35e946685c5eafdf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 16:23:52 -0400 Subject: [PATCH 037/327] switch-to-configuration: require a reboot going from Upstart to systemd --- .../system/activation/switch-to-configuration.sh | 14 +++++++------- modules/system/activation/top-level.nix | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.sh b/modules/system/activation/switch-to-configuration.sh index 62af63ec39f3..0256100f4ec1 100644 --- a/modules/system/activation/switch-to-configuration.sh +++ b/modules/system/activation/switch-to-configuration.sh @@ -59,16 +59,16 @@ fi # Activate the new configuration. if [ "$action" != switch -a "$action" != test ]; then exit 0; fi -oldVersion=$(cat /run/current-system/upstart-interface-version 2> /dev/null || echo 0) -newVersion=$(cat @out@/upstart-interface-version 2> /dev/null || echo 0) +oldVersion="$(cat /run/current-system/init-interface-version 2> /dev/null || echo "")" +newVersion="$(cat @out@/init-interface-version)" -if test "$oldVersion" -ne "$newVersion"; then +if [ "$oldVersion" != "$newVersion" ]; then cat < $out/kernel-params echo -n "$configurationName" > $out/configuration-name - #echo -n "${toString config.system.build.upstart.interfaceVersion}" > $out/upstart-interface-version + echo -n "systemd ${toString config.system.build.systemd.interfaceVersion}" > $out/init-interface-version echo -n "$nixosVersion" > $out/nixos-version mkdir $out/fine-tune From 77510eaa9917eef42fe73bf3a0c802c0e71bbfe8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 17:38:36 -0400 Subject: [PATCH 038/327] dbus.nix: Fix path to dbus-send --- modules/services/system/dbus.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix index bd5c290d5826..a6544368ea0b 100644 --- a/modules/services/system/dbus.nix +++ b/modules/services/system/dbus.nix @@ -138,7 +138,7 @@ in ExecStartPre=${pkgs.dbus_tools}/bin/dbus-uuidgen --ensure ExecStartPre=-${pkgs.coreutils}/bin/rm -f /var/run/dbus/pid ExecStart=${pkgs.dbus_daemon}/bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation - ExecReload=${pkgs.dbus_tools}/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig + ExecReload=${pkgs.dbus_tools}/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig OOMScoreAdjust=-900 ''; From ee075bdf6b43d7a4bf6f3be2f207556523bbf7d8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 17:39:05 -0400 Subject: [PATCH 039/327] agetty.nix: Add remark --- modules/services/ttys/agetty.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index a0e53eeaef46..1916c13333d4 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -87,7 +87,7 @@ with pkgs.lib; TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes - TTYVTDisallocate=yes + TTYVTDisallocate=yes # set to no to prevent clearing the screen KillMode=process IgnoreSIGPIPE=no From 7a98c884f8aff2f9e5b32e87fe02c759edd49472 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 18:24:55 -0400 Subject: [PATCH 040/327] dhcpcd.nix: Go into the background and restart ntpd --- modules/services/networking/dhcpcd.nix | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 122faf981366..c1cc22f905c5 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -51,20 +51,19 @@ let ''} if [ "$reason" = BOUND -o "$reason" = REBOOT ]; then - # Restart ntpd. (The "ip-up" event below will trigger the - # restart.) We need to restart it to make sure that it will - # actually do something: if ntpd cannot resolve the server - # hostnames in its config file, then it will never do + # Restart ntpd. We need to restart it to make sure that it + # will actually do something: if ntpd cannot resolve the + # server hostnames in its config file, then it will never do # anything ever again ("couldn't resolve ..., giving up on # it"), so we silently lose time synchronisation. - ${config.system.build.upstart}/sbin/initctl stop ntpd + ${config.system.build.systemd}/bin/systemctl restart ntpd.service - ${config.system.build.upstart}/sbin/initctl emit -n ip-up $params + #${config.system.build.upstart}/sbin/initctl emit -n ip-up $params fi - if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then - ${config.system.build.upstart}/sbin/initctl emit -n ip-down $params - fi + #if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then + # ${config.system.build.upstart}/sbin/initctl emit -n ip-down $params + #fi ''; in @@ -97,7 +96,9 @@ in path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; - exec = "dhcpcd --config ${dhcpcdConf} --nobackground"; + daemonType = "fork"; + + exec = "dhcpcd --config ${dhcpcdConf}"; }; environment.systemPackages = [ dhcpcd ]; From fd2cef50cdd55686f5ae467b3eac1729a1d34034 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 18:25:23 -0400 Subject: [PATCH 041/327] Don't pull in Upstart --- modules/system/upstart/upstart.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index cbefad214148..6f76f5d7b1d8 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -360,7 +360,7 @@ in config = { - system.build.upstart = upstart; + system.build.upstart = "/no-upstart"; boot.systemd.services = flip mapAttrs' config.jobs (name: job: From 0edf138fc7884db6be1fab45dd6496c4f239d0c0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 18:25:36 -0400 Subject: [PATCH 042/327] switch-to-configuration: Initial systemd support It reloads the configuration, but doesn't (re)start jobs yet. --- .../activation/switch-to-configuration.sh | 84 +------------------ 1 file changed, 4 insertions(+), 80 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.sh b/modules/system/activation/switch-to-configuration.sh index 0256100f4ec1..cc2f2e9282a0 100644 --- a/modules/system/activation/switch-to-configuration.sh +++ b/modules/system/activation/switch-to-configuration.sh @@ -75,91 +75,15 @@ fi # virtual console 1 and we restart the "tty1" job. trap "" SIGHUP -jobsDir=$(readlink -f @out@/etc/init) - -# Stop all currently running jobs that are not in the new Upstart -# configuration. (Here "running" means all jobs that are not in the -# stop/waiting state.) -for job in $(initctl list | sed -e '/ stop\/waiting/ d; /^[^a-z]/ d; s/^\([^ ]\+\).*/\1/' | sort); do - if ! [ -e "$jobsDir/$job.conf" ] ; then - echo "stopping obsolete job ‘$job’..." - stop --quiet "$job" || true - fi -done - # Activate the new configuration (i.e., update /etc, make accounts, # and so on). echo "activating the configuration..." @out@/activate @out@ -# Make Upstart reload its jobs. -initctl reload-configuration +# FIXME: Re-exec systemd if necessary. -# Allow Upstart jobs to react intelligently to a config change. -initctl emit config-changed - -declare -A tasks=(@tasks@) -declare -A noRestartIfChanged=(@noRestartIfChanged@) - -start_() { - local job="$1" - if start --quiet "$job"; then - # Handle services that cancel themselves. - if ! [ -n "${tasks[$job]}" ]; then - local status=$(status "$job") - [[ "$status" =~ start/running ]] || echo "job ‘$job’ failed to start!" - fi - fi -} - -log() { - echo "$@" >&2 || true -} - -# Restart all running jobs that have changed. (Here "running" means -# all jobs that don't have a "stop" goal.) We use the symlinks in -# /var/run/upstart-jobs (created by each job's pre-start script) to -# determine if a job has changed. -for job in @jobs@; do - status=$(status "$job") - if ! [[ "$status" =~ start/ ]]; then continue; fi - if [ "$(readlink -f "$jobsDir/$job.conf")" = "$(readlink -f "/var/run/upstart-jobs/$job")" ]; then continue; fi - if [ -n "${noRestartIfChanged[$job]}" ]; then - log "not restarting changed service ‘$job’" - continue - fi - log "restarting changed service ‘$job’..." - # Note: can't use "restart" here, since that only restarts the - # job's main process. - stop --quiet "$job" || true - start_ "$job" || true -done - -# Start all jobs that are not running but should be. The "should be" -# criterion is tricky: the intended semantics is that we end up with -# the same jobs as after a reboot. If it's a task, start it if it -# differs from the previous instance of the same task; if it wasn't -# previously run, don't run it. If it's a service, only start it if -# it has a "start on" condition. -for job in @jobs@; do - status=$(status "$job") - if ! [[ "$status" =~ stop/ ]]; then continue; fi - - if [ -n "${tasks[$job]}" ]; then - if [ ! -e "/var/run/upstart-jobs/$job" -o \ - "$(readlink -f "$jobsDir/$job.conf")" = "$(readlink -f "/var/run/upstart-jobs/$job")" ]; - then continue; fi - if [ -n "${noRestartIfChanged[$job]}" ]; then continue; fi - log "starting task ‘$job’..." - start --quiet "$job" || true - else - if ! grep -q "^start on" "$jobsDir/$job.conf"; then continue; fi - log "starting service ‘$job’..." - start_ "$job" || true - fi - -done +# Make systemd reload its jobs. +systemctl daemon-reload # Signal dbus to reload its configuration. -dbusPid=$(initctl status dbus 2> /dev/null | sed -e 's/.*process \([0-9]\+\)/\1/;t;d') -[ -n "$dbusPid" ] && kill -HUP "$dbusPid" +systemctl reload dbus.service || true From 71ca633431590457e4380fb0a53e9a8f30cad9cd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Jul 2012 18:32:24 -0400 Subject: [PATCH 043/327] Start agetty on tty1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ‘logind’ automatically starts agetty on all virtual consoles except tty1. We have to do that ourselves. --- modules/system/boot/systemd.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 5f7f62b7866a..db690901014c 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -334,6 +334,8 @@ let '') unit.wantedBy) cfg.units)} ln -s ${cfg.defaultUnit} $out/default.target + + ln -s ../getty@tty1.service $out/multi-user.target.wants/ ''; # */ in From e4ed2120fd90b138d67f5f5306a7deb020557307 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 24 Jul 2012 13:53:17 -0400 Subject: [PATCH 044/327] Create /etc/locale.conf and /etc/vconsole.conf Systemd's systemd-vconsole-setup.service reads locale and console font/keymap settings from these files. In particular, it sets the virtual console to UTF-8 mode depending on the LANG setting. This removed the need for the kbd job. --- modules/config/i18n.nix | 26 +++++++++----- modules/tasks/kbd.nix | 78 ++++++----------------------------------- 2 files changed, 29 insertions(+), 75 deletions(-) diff --git a/modules/config/i18n.nix b/modules/config/i18n.nix index c53325ed4e6c..dd435d481b70 100644 --- a/modules/config/i18n.nix +++ b/modules/config/i18n.nix @@ -1,8 +1,10 @@ -{pkgs, config, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; ###### interface + let - inherit (pkgs.lib) mkOption mkIf; options = { i18n = { @@ -45,16 +47,15 @@ let The keyboard mapping table for the virtual consoles. "; }; + }; + }; -in - + ###### implementation -let - glibcLocales = pkgs.glibcLocales.override { - allLocales = pkgs.lib.any (x: x == "all") config.i18n.supportedLocales; + allLocales = any (x: x == "all") config.i18n.supportedLocales; locales = config.i18n.supportedLocales; }; @@ -63,10 +64,19 @@ in { require = options; - environment.systemPackages = [glibcLocales]; + environment.systemPackages = [ glibcLocales ]; environment.shellInit = '' export LANG=${config.i18n.defaultLocale} ''; + + # ‘/etc/locale.conf’ is used by systemd. + environment.etc = singleton + { target = "locale.conf"; + source = pkgs.writeText "locale.conf" + '' + LANG=${config.i18n.defaultLocale} + ''; + }; } diff --git a/modules/tasks/kbd.nix b/modules/tasks/kbd.nix index dd4b9f382c09..aa708fb60199 100644 --- a/modules/tasks/kbd.nix +++ b/modules/tasks/kbd.nix @@ -10,7 +10,6 @@ let ++ config.boot.extraTTYs ++ [ config.services.syslogd.tty ]; ttys = map (dev: "/dev/${dev}") requiredTTYs; - defaultLocale = config.i18n.defaultLocale; consoleFont = config.i18n.consoleFont; consoleKeyMap = config.i18n.consoleKeyMap; @@ -23,6 +22,7 @@ in # most options are defined in i18n.nix + # FIXME: still needed? boot.extraTTYs = mkOption { default = []; example = ["tty8" "tty9"]; @@ -56,73 +56,17 @@ in environment.systemPackages = [ pkgs.kbd ]; - /* FIXME - remove; this is handled by systemd now. - - jobs.kbd = - { description = "Keyboard / console initialisation"; - - startOn = "started udev"; - - task = true; - - script = '' - export LANG=${defaultLocale} - export LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive - export PATH=${pkgs.gzip}/bin:$PATH # Needed by setfont - - set +e # continue in case of errors - - - # Enable or disable UTF-8 mode. This is based on - # unicode_{start,stop}. - echo 'Enabling or disabling Unicode mode...' - - charMap=$(${pkgs.glibc}/bin/locale charmap) - - if test "$charMap" = UTF-8; then - - for tty in ${toString ttys}; do - - # Tell the console output driver that the bytes arriving are - # UTF-8 encoded multibyte sequences. - echo -n -e '\033%G' > $tty - - done - - # Set the keyboard driver in UTF-8 mode. - # !!! Commented out because it running this while the X - # server is running kicks the X server out of raw mode. - # UTF-8 mode is the default nowadays anyway. - # ${pkgs.kbd}/bin/kbd_mode -u - - else - - for tty in ${toString ttys}; do - - # Tell the console output driver that the bytes arriving are - # UTF-8 encoded multibyte sequences. - echo -n -e '\033%@' > $tty - - done - - # Set the keyboard driver in ASCII (or any 8-bit character - # set) mode. - ${pkgs.kbd}/bin/kbd_mode -a - - fi - - - # Set the console font. - for tty in ${toString ttys}; do - ${pkgs.kbd}/bin/setfont -C $tty ${consoleFont} - done - - - # Set the keymap. - ${pkgs.kbd}/bin/loadkeys '${consoleKeyMap}' - ''; + # Let systemd-vconsole-setup.service do the work of setting up the + # virtual consoles. FIXME: trigger a restart of + # systemd-vconsole-setup.service if /etc/vconsole.conf changes. + environment.etc = singleton + { target = "vconsole.conf"; + source = pkgs.writeText "vconsole.conf" + '' + KEYMAP=${consoleKeyMap} + FONT=${consoleFont} + ''; }; - */ }; From 0fc68a3d1d2a03da543209f922e75d2fa0a55e28 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 Aug 2012 15:11:29 -0400 Subject: [PATCH 045/327] Rewrite switch-to-configuration in Perl This will make it more efficient to do systemd dependency graph processing (if necessary). --- .../activation/switch-to-configuration.pl | 57 ++++++++++++++++++ .../activation/switch-to-configuration.sh | 59 ------------------- modules/system/activation/top-level.nix | 20 +++---- 3 files changed, 65 insertions(+), 71 deletions(-) create mode 100644 modules/system/activation/switch-to-configuration.pl delete mode 100644 modules/system/activation/switch-to-configuration.sh diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl new file mode 100644 index 000000000000..199c23d8ab0e --- /dev/null +++ b/modules/system/activation/switch-to-configuration.pl @@ -0,0 +1,57 @@ +#! @perl@ + +use strict; +use warnings; +use File::Slurp; + +my $action = shift @ARGV; + +if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test")) { + print STDERR < 'quiet') // ""; +my $newVersion = read_file("@out@/init-interface-version"); + +if ($newVersion ne $oldVersion) { + print STDERR < $out/kernel-params @@ -130,7 +130,7 @@ let done mkdir $out/bin - substituteAll ${./switch-to-configuration.sh} $out/bin/switch-to-configuration + substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration chmod +x $out/bin/switch-to-configuration ${config.system.extraSystemBuilderCmds} @@ -146,6 +146,9 @@ let name = "nixos-${config.system.nixosVersion}"; preferLocalBuild = true; buildCommand = systemBuilder; + + inherit (pkgs) systemd; + inherit children; kernelParams = config.boot.kernelParams ++ config.boot.extraKernelParams; @@ -164,17 +167,10 @@ let # to the activation script. noRestartIfChanged = attrValues (mapAttrs (n: v: if v.restartIfChanged then [] else ["[${v.name}]=1"]) config.jobs); - # Most of these are needed by grub-install. - path = - [ pkgs.coreutils - pkgs.gnused - pkgs.gnugrep - pkgs.findutils - pkgs.diffutils - pkgs.systemd - ]; - configurationName = config.boot.loader.grub.configurationName; + + # Needed by switch-to-configuration. + perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl"; }; From 4d2deff7afcb1e023b118bded2ba4e07a763bec2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 Aug 2012 17:26:23 -0400 Subject: [PATCH 046/327] Stop obsolete units, restart changed units, start new units --- .../activation/switch-to-configuration.pl | 42 +++++++++++++++++++ modules/system/boot/systemd.nix | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 199c23d8ab0e..b9ba9b14e63c 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -2,7 +2,9 @@ use strict; use warnings; +use File::Basename; use File::Slurp; +use Cwd 'abs_path'; my $action = shift @ARGV; @@ -40,6 +42,41 @@ EOF # virtual console 1 and we restart the "tty1" unit. $SIG{PIPE} = "IGNORE"; +sub getActiveUnits { + # FIXME: use D-Bus or whatever to query this, since parsing the + # output of list-units is likely to break. + my $lines = `@systemd@/bin/systemctl list-units --full`; + my $res = {}; + foreach my $line (split '\n', $lines) { + chomp $line; + last if $line eq ""; + $line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s/ or next; + next if $1 eq "UNIT"; + $res->{$1} = { load => $2, state => $3, substate => $4 }; + } + return $res; +} + +# Stop all services that no longer exist or have changed in the new +# configuration. +# FIXME: handle template units (e.g. getty@.service). +my $active = getActiveUnits; +foreach my $unitFile (glob "/etc/systemd/system/*") { + next unless -f "$unitFile"; + my $unit = basename $unitFile; + my $state = $active->{$unit}; + if (defined $state && ($state->{state} eq "active" || $state->{state} eq "activating")) { + my $newUnitFile = "@out@/etc/systemd/system/$unit"; + if (! -e $newUnitFile) { + print STDERR "stopping obsolete unit ‘$unit’...\n"; + system("@systemd@/bin/systemctl", "stop", $unit); # FIXME: ignore errors? + } elsif (abs_path($unitFile) ne abs_path($newUnitFile)) { + print STDERR "stopping changed unit ‘$unit’...\n"; + system("@systemd@/bin/systemctl", "stop", $unit); # FIXME: ignore errors? + } + } +} + # Activate the new configuration (i.e., update /etc, make accounts, # and so on). my $res = 0; @@ -51,6 +88,11 @@ system("@out@/activate", "@out@") == 0 or $res = 2; # Make systemd reload its units. system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; +# Start all units required by the default target. This should start +# all changed units we stopped above as well as any new dependencies. +print STDERR "starting default target...\n"; +system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 3; + # Signal dbus to reload its configuration. system("@systemd@/bin/systemctl", "reload", "dbus.service"); diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index db690901014c..848831a94a29 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -324,7 +324,7 @@ let done for i in ${toString nixosUnits}; do - cp $i/* $out/ + ln -s $i/* $out/ done ${concatStrings (mapAttrsToList (name: unit: From 56ce5614f9c17b84e21783ab3cf69774e954967c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 10:40:01 -0400 Subject: [PATCH 047/327] switch-to-configuration: Print all failed services --- .../activation/switch-to-configuration.pl | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index b9ba9b14e63c..4ff4cf1420fe 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -57,6 +57,9 @@ sub getActiveUnits { return $res; } +# Forget about previously failed services. +system("@systemd@/bin/systemctl", "reset-failed"); + # Stop all services that no longer exist or have changed in the new # configuration. # FIXME: handle template units (e.g. getty@.service). @@ -91,9 +94,24 @@ system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; # Start all units required by the default target. This should start # all changed units we stopped above as well as any new dependencies. print STDERR "starting default target...\n"; -system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 3; +system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 4; # Signal dbus to reload its configuration. system("@systemd@/bin/systemctl", "reload", "dbus.service"); +# Check all the failed services. +$active = getActiveUnits; +my @failed; +while (my ($unit, $state) = each %{$active}) { + push @failed, $unit if $state->{state} eq "failed"; +} +if (scalar @failed > 0) { + print STDERR "warning: the following units failed: ", join(", ", @failed), "\n"; + foreach my $unit (@failed) { + print STDERR "\n"; + system("@systemd@/bin/systemctl status '$unit' >&2"); + } + $res = 4; +} + exit $res; From b6bd0a4f84696ece1da1e437430f0ab6df0df726 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 11:53:14 -0400 Subject: [PATCH 048/327] switch-to-configuration: Restart services that were manually started --- .../activation/switch-to-configuration.pl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 4ff4cf1420fe..fd515341d134 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -6,6 +6,8 @@ use File::Basename; use File::Slurp; use Cwd 'abs_path'; +my $restartListFile = "/run/systemd/restart-list"; + my $action = shift @ARGV; if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test")) { @@ -75,6 +77,10 @@ foreach my $unitFile (glob "/etc/systemd/system/*") { system("@systemd@/bin/systemctl", "stop", $unit); # FIXME: ignore errors? } elsif (abs_path($unitFile) ne abs_path($newUnitFile)) { print STDERR "stopping changed unit ‘$unit’...\n"; + # Record that this unit needs to be started below. We + # write this to a file to ensure that the service gets + # restarted if we're interrupted. + write_file($restartListFile, { append => 1 }, "$unit\n"); system("@systemd@/bin/systemctl", "stop", $unit); # FIXME: ignore errors? } } @@ -92,10 +98,21 @@ system("@out@/activate", "@out@") == 0 or $res = 2; system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; # Start all units required by the default target. This should start -# all changed units we stopped above as well as any new dependencies. +# most changed units we stopped above as well as any new dependencies. print STDERR "starting default target...\n"; system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 4; +# Start changed units we stopped above. This is necessary because +# some may not be dependencies of the default target (i.e., they were +# manually started). +my @stopped = split '\n', read_file($restartListFile, err_mode => 'quiet') // ""; +if (scalar @stopped > 0) { + print STDERR "restarting unit(s) ", join(" ", @stopped), "...\n"; + my %unique = map { $_, 1 } @stopped; + system("@systemd@/bin/systemctl", "start", keys(%unique)) == 0 or $res = 4; + unlink($restartListFile); +} + # Signal dbus to reload its configuration. system("@systemd@/bin/systemctl", "reload", "dbus.service"); From bd3c9febc9672e6f6ff8705b6437e1d8fca1bebb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 13:29:56 -0400 Subject: [PATCH 049/327] switch-to-configuration: Stop units in one call to systemctl --- .../activation/switch-to-configuration.pl | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index fd515341d134..e017098a4111 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -65,27 +65,30 @@ system("@systemd@/bin/systemctl", "reset-failed"); # Stop all services that no longer exist or have changed in the new # configuration. # FIXME: handle template units (e.g. getty@.service). +my @unitsToStop; my $active = getActiveUnits; -foreach my $unitFile (glob "/etc/systemd/system/*") { - next unless -f "$unitFile"; - my $unit = basename $unitFile; +while (my ($unit, $state) = each %{$active}) { my $state = $active->{$unit}; - if (defined $state && ($state->{state} eq "active" || $state->{state} eq "activating")) { + my $curUnitFile = "/etc/systemd/system/$unit"; + if (-e $curUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { my $newUnitFile = "@out@/etc/systemd/system/$unit"; if (! -e $newUnitFile) { print STDERR "stopping obsolete unit ‘$unit’...\n"; - system("@systemd@/bin/systemctl", "stop", $unit); # FIXME: ignore errors? - } elsif (abs_path($unitFile) ne abs_path($newUnitFile)) { + push @unitsToStop, $unit; + } elsif (abs_path($curUnitFile) ne abs_path($newUnitFile)) { print STDERR "stopping changed unit ‘$unit’...\n"; # Record that this unit needs to be started below. We # write this to a file to ensure that the service gets # restarted if we're interrupted. write_file($restartListFile, { append => 1 }, "$unit\n"); - system("@systemd@/bin/systemctl", "stop", $unit); # FIXME: ignore errors? + push @unitsToStop, $unit; } } } +system("@systemd@/bin/systemctl", "stop", @unitsToStop) + if scalar @unitsToStop > 0; # FIXME: ignore errors? + # Activate the new configuration (i.e., update /etc, make accounts, # and so on). my $res = 0; @@ -107,7 +110,7 @@ system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 4; # manually started). my @stopped = split '\n', read_file($restartListFile, err_mode => 'quiet') // ""; if (scalar @stopped > 0) { - print STDERR "restarting unit(s) ", join(" ", @stopped), "...\n"; + print STDERR "restarting the following units: ", join(" ", @stopped), "\n"; my %unique = map { $_, 1 } @stopped; system("@systemd@/bin/systemctl", "start", keys(%unique)) == 0 or $res = 4; unlink($restartListFile); From aa6fd9f8a25fbea1f73869ddcc02fd0aea1f4e91 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 13:47:59 -0400 Subject: [PATCH 050/327] switch-to-configuration: Handle unit template instances --- .../activation/switch-to-configuration.pl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index e017098a4111..4f6a2a14cd15 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -64,19 +64,19 @@ system("@systemd@/bin/systemctl", "reset-failed"); # Stop all services that no longer exist or have changed in the new # configuration. -# FIXME: handle template units (e.g. getty@.service). my @unitsToStop; my $active = getActiveUnits; while (my ($unit, $state) = each %{$active}) { my $state = $active->{$unit}; - my $curUnitFile = "/etc/systemd/system/$unit"; + my $baseUnit = $unit; + # Recognise template instances. + $baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/; + my $curUnitFile = "/etc/systemd/system/$baseUnit"; if (-e $curUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { - my $newUnitFile = "@out@/etc/systemd/system/$unit"; + my $newUnitFile = "@out@/etc/systemd/system/$baseUnit"; if (! -e $newUnitFile) { - print STDERR "stopping obsolete unit ‘$unit’...\n"; push @unitsToStop, $unit; } elsif (abs_path($curUnitFile) ne abs_path($newUnitFile)) { - print STDERR "stopping changed unit ‘$unit’...\n"; # Record that this unit needs to be started below. We # write this to a file to ensure that the service gets # restarted if we're interrupted. @@ -86,6 +86,7 @@ while (my ($unit, $state) = each %{$active}) { } } +print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n"; system("@systemd@/bin/systemctl", "stop", @unitsToStop) if scalar @unitsToStop > 0; # FIXME: ignore errors? @@ -110,9 +111,10 @@ system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 4; # manually started). my @stopped = split '\n', read_file($restartListFile, err_mode => 'quiet') // ""; if (scalar @stopped > 0) { - print STDERR "restarting the following units: ", join(" ", @stopped), "\n"; my %unique = map { $_, 1 } @stopped; - system("@systemd@/bin/systemctl", "start", keys(%unique)) == 0 or $res = 4; + my @unique = sort(keys(%unique)); + print STDERR "restarting the following units: ", join(", ", @unique), "\n"; + system("@systemd@/bin/systemctl", "start", @unique) == 0 or $res = 4; unlink($restartListFile); } @@ -126,7 +128,7 @@ while (my ($unit, $state) = each %{$active}) { push @failed, $unit if $state->{state} eq "failed"; } if (scalar @failed > 0) { - print STDERR "warning: the following units failed: ", join(", ", @failed), "\n"; + print STDERR "warning: the following units failed: ", join(", ", sort(@failed)), "\n"; foreach my $unit (@failed) { print STDERR "\n"; system("@systemd@/bin/systemctl status '$unit' >&2"); From 0d6b96a525c34607745d19debe829ee12f8ca2bb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 14:07:43 -0400 Subject: [PATCH 051/327] switch-to-configuration: Fix the call to install the boot loader --- modules/system/activation/switch-to-configuration.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 4f6a2a14cd15..098c08f97208 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -24,8 +24,10 @@ EOF die "This is not a NixOS installation (/etc/NIXOS is missing)!\n" unless -f "/etc/NIXOS"; # Install or update the bootloader. -#system("@installBootLoader@ @out@") == 0 or exit 1 if $action eq "switch" || $action eq "boot"; -exit 0 if $action eq "boot"; +if ($action eq "switch" || $action eq "boot") { + system("@installBootLoader@ @out@") == 0 or exit 1; + exit 0 if $action eq "boot"; +} # Check if we can activate the new configuration. my $oldVersion = read_file("/run/current-system/init-interface-version", err_mode => 'quiet') // ""; From 320682a558098a419aad7c9f435f2e8c64f0a97c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 14:39:59 -0400 Subject: [PATCH 052/327] switch-to-configuration: Don't ellipsize log output --- modules/system/activation/switch-to-configuration.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 098c08f97208..c7a82da7a7bd 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -133,7 +133,7 @@ if (scalar @failed > 0) { print STDERR "warning: the following units failed: ", join(", ", sort(@failed)), "\n"; foreach my $unit (@failed) { print STDERR "\n"; - system("@systemd@/bin/systemctl status '$unit' >&2"); + system("COLUMNS=1000 @systemd@/bin/systemctl status --no-pager '$unit' >&2"); } $res = 4; } From 2a91bb52825f5bae71ebb8cdded65a0da099a1fa Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 3 Aug 2012 17:13:34 -0400 Subject: [PATCH 053/327] switch-to-configuration: Print new units --- .../activation/switch-to-configuration.pl | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index c7a82da7a7bd..6cedf7f26467 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -67,18 +67,17 @@ system("@systemd@/bin/systemctl", "reset-failed"); # Stop all services that no longer exist or have changed in the new # configuration. my @unitsToStop; -my $active = getActiveUnits; -while (my ($unit, $state) = each %{$active}) { - my $state = $active->{$unit}; +my $activePrev = getActiveUnits; +while (my ($unit, $state) = each %{$activePrev}) { my $baseUnit = $unit; # Recognise template instances. $baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/; - my $curUnitFile = "/etc/systemd/system/$baseUnit"; - if (-e $curUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { + my $prevUnitFile = "/etc/systemd/system/$baseUnit"; + if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { my $newUnitFile = "@out@/etc/systemd/system/$baseUnit"; if (! -e $newUnitFile) { push @unitsToStop, $unit; - } elsif (abs_path($curUnitFile) ne abs_path($newUnitFile)) { + } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { # Record that this unit needs to be started below. We # write this to a file to ensure that the service gets # restarted if we're interrupted. @@ -88,9 +87,10 @@ while (my ($unit, $state) = each %{$active}) { } } -print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n"; -system("@systemd@/bin/systemctl", "stop", @unitsToStop) - if scalar @unitsToStop > 0; # FIXME: ignore errors? +if (scalar @unitsToStop > 0) { + print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n"; + system("@systemd@/bin/systemctl", "stop", @unitsToStop); # FIXME: ignore errors? +} # Activate the new configuration (i.e., update /etc, make accounts, # and so on). @@ -123,12 +123,17 @@ if (scalar @stopped > 0) { # Signal dbus to reload its configuration. system("@systemd@/bin/systemctl", "reload", "dbus.service"); -# Check all the failed services. -$active = getActiveUnits; -my @failed; -while (my ($unit, $state) = each %{$active}) { +# Print failed and new units. +my (@failed, @new); +my $activeNew = getActiveUnits; +while (my ($unit, $state) = each %{$activeNew}) { push @failed, $unit if $state->{state} eq "failed"; + push @new, $unit if $state->{state} ne "failed" && !defined $activePrev->{$unit}; } + +print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n" + if scalar @new > 0; + if (scalar @failed > 0) { print STDERR "warning: the following units failed: ", join(", ", sort(@failed)), "\n"; foreach my $unit (@failed) { From f74ffe355057b5dce8abdcee7e7e517e44260f1f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 10:58:27 -0400 Subject: [PATCH 054/327] Remove obsolete Upstart shutdown job --- modules/system/upstart-events/shutdown.nix | 162 --------------------- 1 file changed, 162 deletions(-) delete mode 100644 modules/system/upstart-events/shutdown.nix diff --git a/modules/system/upstart-events/shutdown.nix b/modules/system/upstart-events/shutdown.nix deleted file mode 100644 index 59fbcc0d878b..000000000000 --- a/modules/system/upstart-events/shutdown.nix +++ /dev/null @@ -1,162 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -{ - - jobs.shutdown = - { name = "shutdown"; - - task = true; - - stopOn = ""; # must override the default ("starting shutdown") - - environment = { MODE = "poweroff"; }; - - extraConfig = "console owner"; - - script = - '' - set +e # continue in case of errors - - ${pkgs.kbd}/bin/chvt 1 - - exec < /dev/console > /dev/console 2>&1 - echo "" - if test "$MODE" = maintenance; then - echo "<<< Entering maintenance mode >>>" - else - echo "<<< System shutdown >>>" - fi - echo "" - - ${config.powerManagement.powerDownCommands} - - export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH - - - # Do an initial sync just in case. - sync - - - # Kill all remaining processes except init, this one and any - # Upstart jobs that don't stop on the "starting shutdown" - # event, as these are necessary to complete the shutdown. - omittedPids=$(initctl list | sed -e 's/.*process \([0-9]\+\)/-o \1/;t;d') - #echo "saved PIDs: $omittedPids" - - echo "sending the TERM signal to all processes..." - ${pkgs.sysvtools}/bin/killall5 -15 $job $omittedPids - - sleep 1 # wait briefly - - echo "sending the KILL signal to all processes..." - ${pkgs.sysvtools}/bin/killall5 -9 $job $omittedPids - - - # If maintenance mode is requested, start a root shell, and - # afterwards emit the "startup" event to bring everything - # back up. - if test "$MODE" = maintenance; then - echo "" - echo "<<< Maintenance shell >>>" - echo "" - ${pkgs.shadow}/bin/login root - initctl emit -n startup - exit 0 - fi - - - # Write a shutdown record to wtmp while /var/log is still writable. - reboot --wtmp-only - - - # Set the hardware clock to the system time. - echo "setting the hardware clock..." - hwclock --systohc ${if config.time.hardwareClockInLocalTime then "--localtime" else "--utc"} - - - # Stop all swap devices. - swapoff -a - - - # Unmount file systems. We repeat this until no more file systems - # can be unmounted. This is to handle loopback devices, file - # systems mounted on other file systems and so on. - tryAgain=1 - while test -n "$tryAgain"; do - tryAgain= - failed= # list of mount points that couldn't be unmounted/remounted - - # Get rid of loopback devices. - loDevices=$(losetup -a | sed 's#^\(/dev/loop[0-9]\+\).*#\1#') - if [ -n "$loDevices" ]; then - echo "removing loopback devices $loDevices..." - losetup -d $loDevices - fi - - cp /proc/mounts /dev/.mounts # don't read /proc/mounts while it's changing - exec 4< /dev/.mounts - while read -u 4 device mp fstype options rest; do - # Skip various special filesystems. Non-existent - # mount points are typically tmpfs/aufs mounts from - # the initrd. - if [ "$mp" = /proc -o "$mp" = /sys -o "$mp" = /dev -o "$device" = "rootfs" -o "$mp" = /run -o "$mp" = /var/run -o "$mp" = /var/lock -o ! -e "$mp" ]; then continue; fi - - echo "unmounting $mp..." - - # We need to remount,ro before attempting any - # umount, or bind mounts may get confused, with - # the fs not being properly flushed at the end. - - # `-i' is to workaround a bug in mount.cifs (it - # doesn't recognise the `remount' option, and - # instead mounts the FS again). - success= - if mount -t "$fstype" -n -i -o remount,ro "device" "$mp"; then success=1; fi - - # Note: don't use `umount -f'; it's very buggy. - # (For instance, when applied to a bind-mount it - # unmounts the target of the bind-mount.) !!! But - # we should use `-f' for NFS. - if [ "$mp" != / -a "$mp" != /nix -a "$mp" != /nix/store ]; then - if umount -n "$mp"; then success=1; tryAgain=1; fi - fi - - if [ -z "$success" ]; then failed="$failed $mp"; fi - done - done - - - # Warn about filesystems that could not be unmounted or - # remounted read-only. - if [ -n "$failed" ]; then - echo "warning: the following filesystems could not be unmounted:" - for mp in $failed; do echo " $mp"; done - echo Enter 'i' to launch a shell, or wait 10 seconds to continue. - read -t 10 A - if [ "$A" == "i" ]; then - ${pkgs.bashInteractive}/bin/bash -i < /dev/console &> /dev/console - fi - sleep 5 - fi - - - # Final sync. - sync - - - # Either reboot or power-off the system. - if test "$MODE" = reboot; then - echo "rebooting..." - sleep 1 - exec reboot -f - else - echo "powering off..." - sleep 1 - exec halt -f -p - fi - ''; - }; - -} From 9f9ae7c7e9aa440db85c924a636d3827dcdb2a0e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 11:45:59 -0400 Subject: [PATCH 055/327] Share option definitions between the systemd and Upstart compatibility modules --- modules/services/databases/postgresql.nix | 15 +- modules/system/boot/systemd-unit-options.nix | 101 ++++++++++++ modules/system/boot/systemd.nix | 154 +++---------------- modules/system/upstart/upstart.nix | 88 ++--------- 4 files changed, 145 insertions(+), 213 deletions(-) create mode 100644 modules/system/boot/systemd-unit-options.nix diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index 1633b9d0fdd0..139a716ae75f 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -36,7 +36,7 @@ let ''; pre84 = versionOlder (builtins.parseDrvName postgresql.name).version "8.4"; - + in { @@ -139,7 +139,7 @@ in host all all 127.0.0.1/32 md5 host all all ::1/128 md5 ''; - + users.extraUsers = singleton { name = "postgres"; description = "PostgreSQL server user"; @@ -181,20 +181,19 @@ in postStart = '' while ! psql postgres -c ""; do - stop_check sleep 1 done ''; - extraConfig = + serviceConfig = '' - # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See + # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See # http://www.postgresql.org/docs/current/static/server-shutdown.html - kill signal INT + KillSignal=SIGINT # Give Postgres a decent amount of time to clean up after - # receiving Upstart's SIGINT. - kill timeout 60 + # receiving systemd's SIGINT. + TimeoutSec=60 ''; }; diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix new file mode 100644 index 000000000000..34b37f4d0ba4 --- /dev/null +++ b/modules/system/boot/systemd-unit-options.nix @@ -0,0 +1,101 @@ +{ config, pkgs }: + +with pkgs.lib; + +{ + + serviceOptions = { + + description = mkOption { + default = ""; + types = types.uniq types.string; + description = "Description of this unit used in systemd messages and progress indicators."; + }; + + requires = mkOption { + default = []; + types = types.listOf types.string; + description = '' + Start the specified units when this unit is started, and stop + this unit when the specified units are stopped or fail. + ''; + }; + + wants = mkOption { + default = []; + types = types.listOf types.string; + description = '' + Start the specified units when this unit is started. + ''; + }; + + after = mkOption { + default = []; + types = types.listOf types.string; + description = '' + If the specified units are started at the same time as + this unit, delay this unit until they have started. + ''; + }; + + before = mkOption { + default = []; + types = types.listOf types.string; + description = '' + If the specified units are started at the same time as + this unit, delay them until this unit has started. + ''; + }; + + wantedBy = mkOption { + default = []; + types = types.listOf types.string; + description = "Units that want (i.e. depend on) this unit."; + }; + + environment = mkOption { + default = {}; + type = types.attrs; + example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; + description = "Environment variables passed to the services's processes."; + }; + + path = mkOption { + default = []; + apply = ps: "${makeSearchPath "bin" ps}:${makeSearchPath "sbin" ps}"; + description = '' + Packages added to the service's PATH + environment variable. Both the bin + and sbin subdirectories of each + package are added. + ''; + }; + + serviceConfig = mkOption { + default = ""; + type = types.string; + description = '' + Contents of the [Service] section of the unit. + See systemd.unit + 5 for details. + ''; + }; + + script = mkOption { + type = types.uniq types.string; + default = ""; + description = "Shell commands executed as the service's main process."; + }; + + preStart = mkOption { + type = types.string; + default = ""; + description = '' + Shell commands executed before the service's main process + is started. + ''; + }; + + }; + +} \ No newline at end of file diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 848831a94a29..10c98116710f 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -1,122 +1,10 @@ { config, pkgs, ... }: with pkgs.lib; +with import ./systemd-unit-options.nix { inherit config pkgs; }; let - servicesOptions = { - - description = mkOption { - default = ""; - types = types.uniq types.string; - description = "Description of this unit used in systemd messages and progress indicators."; - }; - - requires = mkOption { - default = []; - types = types.listOf types.string; - description = '' - Start the specified units when this unit is started, and stop - this unit when the specified units are stopped or fail. - ''; - }; - - wants = mkOption { - default = []; - types = types.listOf types.string; - description = '' - Start the specified units when this unit is started. - ''; - }; - - after = mkOption { - default = []; - types = types.listOf types.string; - description = '' - If the specified units are started at the same time as - this unit, delay this unit until they have started. - ''; - }; - - before = mkOption { - default = []; - types = types.listOf types.string; - description = '' - If the specified units are started at the same time as - this unit, delay them until this unit has started. - ''; - }; - - wantedBy = mkOption { - default = []; - types = types.listOf types.string; - description = "Start this unit when the specified units are started."; - }; - - environment = mkOption { - default = {}; - type = types.attrs; - example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; - description = "Environment variables passed to the services's processes."; - }; - - path = mkOption { - default = []; - apply = ps: "${makeSearchPath "bin" ps}:${makeSearchPath "sbin" ps}"; - description = '' - Packages added to the service's PATH - environment variable. Both the bin - and sbin subdirectories of each - package are added. - ''; - }; - - serviceConfig = mkOption { - default = ""; - type = types.string; - description = '' - Contents of the [Service] section of the unit. - See systemd.unit - 5 for details. - ''; - }; - - script = mkOption { - type = types.uniq types.string; - default = ""; - description = "Shell commands executed as the service's main process."; - }; - - preStart = mkOption { - type = types.string; - default = ""; - description = '' - Shell commands executed before the service's main process - is started. - ''; - }; - - }; - - - servicesConfig = { name, config, ... }: { - - config = { - - # Default path for systemd services. Should be quite minimal. - path = - [ pkgs.coreutils - pkgs.findutils - pkgs.gnugrep - pkgs.gnused - systemd - ]; - - }; - - }; - - cfg = config.boot.systemd; systemd = pkgs.systemd; @@ -178,7 +66,7 @@ let # Utmp maintenance. "systemd-update-utmp-runlevel.service" "systemd-update-utmp-shutdown.service" - + # Filesystems. "systemd-fsck@.service" "systemd-fsck-root.service" @@ -260,6 +148,19 @@ let makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; + serviceConfig = { name, config, ... }: { + config = { + # Default path for systemd services. Should be quite minimal. + path = + [ pkgs.coreutils + pkgs.findutils + pkgs.gnugrep + pkgs.gnused + systemd + ]; + }; + }; + serviceToUnit = name: def: { inherit (def) wantedBy; @@ -277,7 +178,7 @@ let [Service] Environment=PATH=${def.path} ${concatMapStrings (n: "Environment=${n}=${getAttr n def.environment}\n") (attrNames def.environment)} - + ${optionalString (def.preStart != "") '' ExecStartPre=${makeJobScript "${name}-prestart.sh" '' #! ${pkgs.stdenv.shell} -e @@ -297,7 +198,7 @@ let }; nixosUnits = mapAttrsToList makeUnit cfg.units; - + units = pkgs.runCommand "units" { preferLocalBuild = true; } '' mkdir -p $out @@ -310,7 +211,7 @@ let ln -s $fn $out/ fi done - + for i in ${toString upstreamWants}; do fn=${systemd}/example/systemd/system/$i [ -e $fn ] @@ -322,7 +223,7 @@ let if ! [ -e $y ]; then rm -v $y; fi done done - + for i in ${toString nixosUnits}; do ln -s $i/* $out/ done @@ -337,7 +238,7 @@ let ln -s ../getty@tty1.service $out/multi-user.target.wants/ ''; # */ - + in { @@ -350,29 +251,24 @@ in description = "Definition of systemd units."; default = {}; type = types.attrsOf types.optionSet; - options = { - text = mkOption { types = types.uniq types.string; description = "Text of this systemd unit."; }; - wantedBy = mkOption { default = []; types = types.listOf types.string; description = "Units that want (i.e. depend on) this unit."; }; - }; - }; boot.systemd.services = mkOption { description = "Definition of systemd services."; default = {}; type = types.attrsOf types.optionSet; - options = [ servicesOptions servicesConfig ]; + options = [ serviceOptions serviceConfig ]; }; boot.systemd.defaultUnit = mkOption { @@ -386,16 +282,16 @@ in type = types.bool; description = "Whether to log kernel messages."; }; - + services.journald.console = mkOption { default = ""; type = types.uniq types.string; description = "If non-empty, write log messages to the specified TTY device. Defaults to /dev/console."; }; - + }; - + ###### implementation config = { @@ -405,7 +301,7 @@ in system.build.units = units; environment.systemPackages = [ systemd ]; - + environment.etc = [ { source = units; target = "systemd/system"; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 6f76f5d7b1d8..6375289293f8 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -1,11 +1,10 @@ { config, pkgs, ... }: with pkgs.lib; +with import ../boot/systemd-unit-options.nix { inherit config pkgs; }; let - upstart = pkgs.upstart; - userExists = u: (u == "") || any (uu: uu.name == u) (attrValues config.users.extraUsers); @@ -66,6 +65,8 @@ let serviceConfig = '' + ${job.serviceConfig} + ${optionalString (job.preStart != "" && (job.script != "" || job.exec != "")) '' ExecStartPre=${preStartScript} ''} @@ -77,7 +78,7 @@ let ${optionalString (job.script != "" || job.exec != "") '' ExecStart=${startScript} ''} - + ${optionalString (job.postStart != "") '' ExecStartPost=${postStartScript} ''} @@ -85,7 +86,7 @@ let ${optionalString (job.preStop != "") '' ExecStop=${preStopScript} ''} - + ${optionalString (job.postStop != "") '' ExecStopPost=${postStopScript} ''} @@ -100,7 +101,7 @@ let }; - jobOptions = { + jobOptions = serviceOptions // { name = mkOption { # !!! The type should ensure that this could be a filename. @@ -111,14 +112,6 @@ let ''; }; - description = mkOption { - type = types.string; - default = ""; - description = '' - A short description of this job. - ''; - }; - startOn = mkOption { # !!! Re-enable this once we're on Upstart >= 0.6. #type = types.string; @@ -137,15 +130,6 @@ let ''; }; - preStart = mkOption { - type = types.string; - default = ""; - description = '' - Shell commands executed before the job is started - (i.e. before the job's main process is started). - ''; - }; - postStart = mkOption { type = types.string; default = ""; @@ -186,15 +170,6 @@ let ''; }; - script = mkOption { - type = types.string; - default = ""; - description = '' - Shell commands executed as the job's main process. Can be - specified instead of the exec attribute. - ''; - }; - respawn = mkOption { type = types.bool; default = true; @@ -223,15 +198,6 @@ let ''; }; - environment = mkOption { - type = types.attrs; - default = {}; - example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; - description = '' - Environment variables passed to the job's processes. - ''; - }; - daemonType = mkOption { type = types.string; default = "none"; @@ -264,15 +230,6 @@ let ''; }; - extraConfig = mkOption { - type = types.string; - default = ""; - example = "limit nofile 4096 4096"; - description = '' - Additional Upstart stanzas not otherwise supported. - ''; - }; - path = mkOption { default = []; description = '' @@ -282,46 +239,25 @@ let ''; }; - console = mkOption { - default = ""; - example = "console"; - description = '' - If set to output, job output is written to - the console. If it's owner, additionally - the job becomes owner of the console. It it's empty (the - default), output is written to - /var/log/upstart/jobname - ''; - }; - }; - upstartJob = {name, config, ...}: { + upstartJob = { name, config, ... }: { options = { - + unit = mkOption { default = makeUnit config; description = "Generated definition of the systemd unit corresponding to this job."; }; - + }; config = { - + # The default name is the name extracted from the attribute path. name = mkDefaultValue name; - - # Default path for Upstart jobs. Should be quite minimal. - path = - [ pkgs.coreutils - pkgs.findutils - pkgs.gnugrep - pkgs.gnused - upstart - ]; - + }; }; @@ -365,7 +301,7 @@ in boot.systemd.services = flip mapAttrs' config.jobs (name: job: nameValuePair "${job.name}.service" job.unit); - + }; } From b11c5d59911f9549a56839576379e5b2902b4f99 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 12:26:52 -0400 Subject: [PATCH 056/327] nscd: Ensure that invalidate-nscd starts after nscd --- modules/services/system/nscd.nix | 12 +++++++++--- modules/services/ttys/agetty.nix | 23 +++++++++++++++-------- modules/system/upstart/upstart.nix | 11 ++++++----- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index b2596dbb4139..80fa1394aca6 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -27,7 +27,7 @@ in }; - + ###### implementation config = mkIf config.services.nscd.enable { @@ -47,13 +47,18 @@ in preStart = '' - mkdir -m 0755 -p /var/run/nscd + mkdir -m 0755 -p /run/nscd + rm -f /run/nscd/nscd.pid mkdir -m 0755 -p /var/db/nscd ''; path = [ pkgs.glibc ]; - exec = "nscd -f ${./nscd.conf} -d 2> /dev/null"; + exec = "nscd -f ${./nscd.conf}"; + + daemonType = "fork"; + + serviceConfig = "PIDFile=/run/nscd/nscd.pid"; }; # Flush nscd's ‘hosts’ database when the network comes up or the @@ -62,6 +67,7 @@ in { name = "invalidate-nscd"; description = "Invalidate NSCD cache"; startOn = "ip-up or config-changed"; + after = [ "nscd.service" ]; task = true; exec = "${pkgs.glibc}/sbin/nscd --invalidate hosts"; }; diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index 1916c13333d4..92915f9132be 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -2,6 +2,18 @@ with pkgs.lib; +let + + issueFile = pkgs.writeText "issue" '' + + ${config.services.mingetty.greetingLine} + xyzzy6 + ${config.services.mingetty.helpLine} + + ''; + +in + { ###### interface @@ -79,7 +91,7 @@ with pkgs.lib; [Service] Environment=TERM=linux Environment=LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive - ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 + ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --noclear -f ${issueFile} --login-program ${pkgs.shadow}/bin/login %I 38400 Type=idle Restart=always RestartSec=0 @@ -95,7 +107,7 @@ with pkgs.lib; # instead, to ensure that login terminates cleanly. KillSignal=SIGHUP ''; - + boot.systemd.units."serial-getty@.service".text = '' [Unit] @@ -131,12 +143,7 @@ with pkgs.lib; environment.etc = singleton { # Friendly greeting on the virtual consoles. - source = pkgs.writeText "issue" '' - - ${config.services.mingetty.greetingLine} - ${config.services.mingetty.helpLine} - - ''; + source = issueFile; target = "issue"; }; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 6375289293f8..92a7add88eb9 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -54,14 +54,15 @@ let ''; in { - inherit (job) description path environment; + inherit (job) description requires wants before environment path; after = - if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else - if job.startOn == "started udev" then [ "systemd-udev.service" ] else - []; + (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else + if job.startOn == "started udev" then [ "systemd-udev.service" ] else + []) ++ job.after; - wantedBy = if job.startOn == "" then [ ] else [ "multi-user.target" ]; + wantedBy = + (if job.startOn == "" then [ ] else [ "multi-user.target" ]) ++ job.wantedBy; serviceConfig = '' From 27f496c1cebe65e2ab53d8f555d791303ac2dab7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 14:59:58 -0400 Subject: [PATCH 057/327] Make the VirtualBox guest services depend on /dev/vboxguest Systemd #ftw --- modules/virtualisation/virtualbox-guest.nix | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/virtualisation/virtualbox-guest.nix b/modules/virtualisation/virtualbox-guest.nix index 8e09d79e3a48..e864c125176c 100644 --- a/modules/virtualisation/virtualbox-guest.nix +++ b/modules/virtualisation/virtualbox-guest.nix @@ -41,7 +41,9 @@ if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then jobs.virtualbox = { description = "VirtualBox service"; - startOn = "started udev"; + wantedBy = [ "multi-user.target" ]; + requires = [ "dev-vboxguest.device" ]; + after = [ "dev-vboxguest.device" ]; exec = "${kernel.virtualboxGuestAdditions}/sbin/VBoxService --foreground"; }; @@ -60,7 +62,7 @@ if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then '' InputDevice "VBoxMouse" ''; - + services.xserver.displayManager.sessionCommands = '' PATH=${makeSearchPath "bin" [ pkgs.gnugrep pkgs.which pkgs.xorg.xorgserver ]}:$PATH \ @@ -72,9 +74,12 @@ if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then # /dev/vboxuser is necessary for VBoxClient to work. Maybe we # should restrict this to logged-in users. KERNEL=="vboxuser", OWNER="root", GROUP="root", MODE="0666" + + # Allow systemd dependencies on vboxguest. + KERNEL=="vboxguest", TAG+="systemd" ''; - # Make the ACPI Shutdown command to do the right thing. + # Make the ACPI Shutdown command to do the right thing. services.acpid.enable = true; services.acpid.powerEventCommands = "poweroff"; }; From d33fd9a1f8f449b9adbb433c7709383697feba9a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 15:48:46 -0400 Subject: [PATCH 058/327] switch-to-configuration: Assume that services that are auto-restarting are going to fail --- modules/system/activation/switch-to-configuration.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 6cedf7f26467..96b256bc24da 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -124,10 +124,10 @@ if (scalar @stopped > 0) { system("@systemd@/bin/systemctl", "reload", "dbus.service"); # Print failed and new units. -my (@failed, @new); +my (@failed, @new, @restarting); my $activeNew = getActiveUnits; while (my ($unit, $state) = each %{$activeNew}) { - push @failed, $unit if $state->{state} eq "failed"; + push @failed, $unit if $state->{state} eq "failed" || $state->{substate} eq "auto-restart"; push @new, $unit if $state->{state} ne "failed" && !defined $activePrev->{$unit}; } From 23947c26a8f902b946ba3cd3c3d176512e75df9c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 15:53:04 -0400 Subject: [PATCH 059/327] Revert accidental commit --- modules/services/ttys/agetty.nix | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index 92915f9132be..1916c13333d4 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -2,18 +2,6 @@ with pkgs.lib; -let - - issueFile = pkgs.writeText "issue" '' - - ${config.services.mingetty.greetingLine} - xyzzy6 - ${config.services.mingetty.helpLine} - - ''; - -in - { ###### interface @@ -91,7 +79,7 @@ in [Service] Environment=TERM=linux Environment=LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive - ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --noclear -f ${issueFile} --login-program ${pkgs.shadow}/bin/login %I 38400 + ExecStart=@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login %I 38400 Type=idle Restart=always RestartSec=0 @@ -107,7 +95,7 @@ in # instead, to ensure that login terminates cleanly. KillSignal=SIGHUP ''; - + boot.systemd.units."serial-getty@.service".text = '' [Unit] @@ -143,7 +131,12 @@ in environment.etc = singleton { # Friendly greeting on the virtual consoles. - source = issueFile; + source = pkgs.writeText "issue" '' + + ${config.services.mingetty.greetingLine} + ${config.services.mingetty.helpLine} + + ''; target = "issue"; }; From 52b6e1031594012c0d69f8304cc9d828ec78be22 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 6 Aug 2012 16:52:08 -0400 Subject: [PATCH 060/327] Use systemd-modules-load.service to load required kernel modules --- modules/system/boot/kernel.nix | 12 ++++++++++++ modules/system/boot/systemd.nix | 3 +++ 2 files changed, 15 insertions(+) diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 1b247a658908..f3ede5c0d490 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -173,6 +173,18 @@ let kernel = config.boot.kernelPackages.kernel; in # The Linux kernel >= 2.6.27 provides firmware. hardware.firmware = [ "${kernel}/lib/firmware" ]; + # Create /etc/modules-load.d/nixos.conf, which is read by + # systemd-modules-load.service to load required kernel modules. + # FIXME: ensure that systemd-modules-load.service is restarted if + # this file changes. + environment.etc = singleton + { target = "modules-load.d/nixos.conf"; + source = pkgs.writeText "nixos.conf" + '' + ${concatStringsSep "\n" config.boot.kernelModules} + ''; + }; + }; } diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 10c98116710f..2a586090dd1e 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -67,6 +67,9 @@ let "systemd-update-utmp-runlevel.service" "systemd-update-utmp-shutdown.service" + # Kernel module loading. + "systemd-modules-load.service" + # Filesystems. "systemd-fsck@.service" "systemd-fsck-root.service" From ce7ead7bd79e04045fe454f6a1a95e4e34c38935 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Aug 2012 10:56:55 -0400 Subject: [PATCH 061/327] switch-to-configuration: Handle changes to fileSystems We now automatically remount filesystems with changed options, mount new filesystems, and unmount obsolete filesystems. --- .../activation/switch-to-configuration.pl | 108 ++++++++++++++---- 1 file changed, 87 insertions(+), 21 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 96b256bc24da..0b900e3fc168 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -7,6 +7,7 @@ use File::Slurp; use Cwd 'abs_path'; my $restartListFile = "/run/systemd/restart-list"; +my $reloadListFile = "/run/systemd/reload-list"; my $action = shift @ARGV; @@ -61,6 +62,19 @@ sub getActiveUnits { return $res; } +sub parseFstab { + my ($filename) = @_; + my %res; + foreach my $line (read_file($filename, err_mode => 'quiet')) { + chomp $line; + $line =~ s/#.*//; + next if $line =~ /^\s*$/; + my @xs = split / /, $line; + $res{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] }; + } + return %res; +} + # Forget about previously failed services. system("@systemd@/bin/systemctl", "reset-failed"); @@ -73,23 +87,64 @@ while (my ($unit, $state) = each %{$activePrev}) { # Recognise template instances. $baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/; my $prevUnitFile = "/etc/systemd/system/$baseUnit"; + my $newUnitFile = "@out@/etc/systemd/system/$baseUnit"; if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { - my $newUnitFile = "@out@/etc/systemd/system/$baseUnit"; if (! -e $newUnitFile) { push @unitsToStop, $unit; } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { - # Record that this unit needs to be started below. We - # write this to a file to ensure that the service gets - # restarted if we're interrupted. - write_file($restartListFile, { append => 1 }, "$unit\n"); - push @unitsToStop, $unit; + if ($unit =~ /\.target$/) { + write_file($restartListFile, { append => 1 }, "$unit\n"); + } elsif ($unit =~ /\.mount$/) { + # Reload the changed mount unit to force a remount. + write_file($reloadListFile, { append => 1 }, "$unit\n"); + } else { + # Record that this unit needs to be started below. We + # write this to a file to ensure that the service gets + # restarted if we're interrupted. + write_file($restartListFile, { append => 1 }, "$unit\n"); + push @unitsToStop, $unit; + } } } } +sub pathToUnitName { + my ($path) = @_; + die unless substr($path, 0, 1) eq "/"; + return "-" if $path eq "/"; + $path = substr($path, 1); + $path =~ s/\//-/g; + # FIXME: handle - and unprintable characters. + return $path; +} + +# Compare the previous and new fstab to figure out which filesystems +# need a remount or need to be unmounted. New filesystems are mounted +# automatically by starting local-fs.target. FIXME: might be nicer if +# we generated units for all mounts; then we could unify this with the +# unit checking code above. +my %prevFstab = parseFstab "/etc/fstab"; +my %newFstab = parseFstab "@out@/etc/fstab"; +foreach my $mountPoint (keys %prevFstab) { + my $prev = $prevFstab{$mountPoint}; + my $new = $newFstab{$mountPoint}; + my $unit = pathToUnitName($mountPoint). ".mount"; + if (!defined $new) { + # Entry disappeared, so unmount it. + push @unitsToStop, $unit; + } elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) { + # Filesystem type or device changed, so unmount and mount it. + write_file($restartListFile, { append => 1 }, "$unit\n"); + push @unitsToStop, $unit; + } elsif ($prev->{options} ne $new->{options}) { + # Mount options changes, so remount it. + write_file($reloadListFile, { append => 1 }, "$unit\n"); + } +} + if (scalar @unitsToStop > 0) { print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n"; - system("@systemd@/bin/systemctl", "stop", @unitsToStop); # FIXME: ignore errors? + system("@systemd@/bin/systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors? } # Activate the new configuration (i.e., update /etc, make accounts, @@ -103,21 +158,32 @@ system("@out@/activate", "@out@") == 0 or $res = 2; # Make systemd reload its units. system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; -# Start all units required by the default target. This should start -# most changed units we stopped above as well as any new dependencies. -print STDERR "starting default target...\n"; -system("@systemd@/bin/systemctl", "start", "default.target") == 0 or $res = 4; +sub unique { + my %unique = map { $_, 1 } @_; + return sort(keys(%unique)); +} -# Start changed units we stopped above. This is necessary because -# some may not be dependencies of the default target (i.e., they were -# manually started). -my @stopped = split '\n', read_file($restartListFile, err_mode => 'quiet') // ""; -if (scalar @stopped > 0) { - my %unique = map { $_, 1 } @stopped; - my @unique = sort(keys(%unique)); - print STDERR "restarting the following units: ", join(", ", @unique), "\n"; - system("@systemd@/bin/systemctl", "start", @unique) == 0 or $res = 4; - unlink($restartListFile); +# Start the following units: +# - The default target. This should start most changed units we +# stopped above as well as any new dependencies. +# - local-fs.target. This mounts any missing local filesystems. +# - Changed units we stopped above. This is necessary because some +# may not be dependencies of the default target (i.e., they were +# manually started). +my @start = unique( + "default.target", "local-fs.target", + split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); +print STDERR "starting the following units: ", join(", ", @start), "\n"; +system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4; +unlink($restartListFile); + +# Reload units that need it. This includes remounting changed mount +# units. +my @reload = unique(split '\n', read_file($reloadListFile, err_mode => 'quiet') // ""); +if (scalar @reload > 0) { + print STDERR "reloading the following units: ", join(", ", @reload), "\n"; + system("@systemd@/bin/systemctl", "reload", "--", @reload) == 0 or $res = 4; + unlink($reloadListFile); } # Signal dbus to reload its configuration. From a3c75462c19978780f0ea9287763e5ffc9e510fd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Aug 2012 15:15:59 -0400 Subject: [PATCH 062/327] switch-to-configuration: Handle switching all systemd units --- modules/system/activation/switch-to-configuration.pl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 0b900e3fc168..06a6a5bc888c 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -92,11 +92,15 @@ while (my ($unit, $state) = each %{$activePrev}) { if (! -e $newUnitFile) { push @unitsToStop, $unit; } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { - if ($unit =~ /\.target$/) { + if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") { + # Do nothing. These cannot be restarted directly. + } elsif ($unit =~ /\.target$/) { write_file($restartListFile, { append => 1 }, "$unit\n"); } elsif ($unit =~ /\.mount$/) { # Reload the changed mount unit to force a remount. write_file($reloadListFile, { append => 1 }, "$unit\n"); + } elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/) { + # FIXME: do something? } else { # Record that this unit needs to be started below. We # write this to a file to ensure that the service gets @@ -170,6 +174,9 @@ sub unique { # - Changed units we stopped above. This is necessary because some # may not be dependencies of the default target (i.e., they were # manually started). +# FIXME: detect units that are symlinks to other units. We shouldn't +# start both at the same time because we'll get a "Failed to add path +# to set" error from systemd. my @start = unique( "default.target", "local-fs.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); From be5486813b248dfe0a864d9db695130338408dff Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Aug 2012 15:25:04 -0400 Subject: [PATCH 063/327] Add an "adm" group Journald will chown all journal files to the adm group so that users in that group can run "journalctl". --- modules/config/users-groups.nix | 1 + modules/misc/ids.nix | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/config/users-groups.nix b/modules/config/users-groups.nix index 598d68eb91db..b5b692654552 100644 --- a/modules/config/users-groups.nix +++ b/modules/config/users-groups.nix @@ -208,6 +208,7 @@ in users = { }; nixbld = { }; utmp = { }; + adm = { }; # expected by journald }; system.activationScripts.rootPasswd = stringAfter [ "etc" ] diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index 13ebf954f329..cc514fb79c81 100644 --- a/modules/misc/ids.nix +++ b/modules/misc/ids.nix @@ -123,6 +123,7 @@ in mpd = 50; clamav = 51; fprot = 52; + adm = 55; # When adding a gid, make sure it doesn't match an existing uid. From a4a90685eaa601e896a1aaf1eb7c2fcf746f5b03 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Aug 2012 15:52:47 -0400 Subject: [PATCH 064/327] switch-to-configuration: Handle swap devices --- .../activation/switch-to-configuration.pl | 24 ++++++++++++------- modules/system/activation/top-level.nix | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 06a6a5bc888c..df4c440b97a9 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -70,7 +70,7 @@ sub parseFstab { $line =~ s/#.*//; next if $line =~ /^\s*$/; my @xs = split / /, $line; - $res{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] }; + $res{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] // "" }; } return %res; } @@ -124,18 +124,26 @@ sub pathToUnitName { # Compare the previous and new fstab to figure out which filesystems # need a remount or need to be unmounted. New filesystems are mounted -# automatically by starting local-fs.target. FIXME: might be nicer if -# we generated units for all mounts; then we could unify this with the -# unit checking code above. +# automatically by starting local-fs.target. Also handles swap +# devices. FIXME: might be nicer if we generated units for all +# mounts; then we could unify this with the unit checking code above. my %prevFstab = parseFstab "/etc/fstab"; my %newFstab = parseFstab "@out@/etc/fstab"; foreach my $mountPoint (keys %prevFstab) { my $prev = $prevFstab{$mountPoint}; my $new = $newFstab{$mountPoint}; - my $unit = pathToUnitName($mountPoint). ".mount"; + my $unit = pathToUnitName($mountPoint). ".mount" if $prev->{fsType} ne "swap"; if (!defined $new) { - # Entry disappeared, so unmount it. - push @unitsToStop, $unit; + if ($prev->{fsType} eq "swap") { + # Swap entry disappeared, so turn it off. Can't use + # "systemctl stop" here because systemd has lots of alias + # units that prevent a stop from actually calling + # "swapoff". + system("@utillinux@/sbin/swapoff", $prev->{device}); + } else { + # Filesystem entry disappeared, so unmount it. + push @unitsToStop, $unit; + } } elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) { # Filesystem type or device changed, so unmount and mount it. write_file($restartListFile, { append => 1 }, "$unit\n"); @@ -178,7 +186,7 @@ sub unique { # start both at the same time because we'll get a "Failed to add path # to set" error from systemd. my @start = unique( - "default.target", "local-fs.target", + "default.target", "local-fs.target", "swap.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); print STDERR "starting the following units: ", join(", ", @start), "\n"; system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4; diff --git a/modules/system/activation/top-level.nix b/modules/system/activation/top-level.nix index d092fa1d0863..0cc9bf049789 100644 --- a/modules/system/activation/top-level.nix +++ b/modules/system/activation/top-level.nix @@ -147,7 +147,7 @@ let preferLocalBuild = true; buildCommand = systemBuilder; - inherit (pkgs) systemd; + inherit (pkgs) systemd utillinux; inherit children; kernelParams = From e00967a54a9f82ee042aff5c374b4eecc4e8274d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Aug 2012 18:41:20 -0400 Subject: [PATCH 065/327] stage-2-init: Drop udev from the $PATH --- modules/system/boot/stage-2.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/system/boot/stage-2.nix b/modules/system/boot/stage-2.nix index a5e96cc0f1cf..e187219cbd88 100644 --- a/modules/system/boot/stage-2.nix +++ b/modules/system/boot/stage-2.nix @@ -64,7 +64,6 @@ let path = [ pkgs.coreutils pkgs.utillinux - pkgs.udev pkgs.sysvtools ] ++ pkgs.lib.optional config.boot.cleanTmpDir pkgs.findutils; postBootCommands = pkgs.writeText "local-cmds" From 39030211af56d9186821eef7daaa18db486bc028 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Aug 2012 18:56:12 -0400 Subject: [PATCH 066/327] Add a unitConfig option to set the [Unit] section of units --- modules/system/boot/systemd-unit-options.nix | 12 +++++++++++- modules/system/boot/systemd.nix | 10 ++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 34b37f4d0ba4..ec769ad69f99 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -71,12 +71,22 @@ with pkgs.lib; ''; }; + unitConfig = mkOption { + default = ""; + type = types.string; + description = '' + Contents of the [Unit] section of the unit. + See systemd.unit + 5 for details. + ''; + }; + serviceConfig = mkOption { default = ""; type = types.string; description = '' Contents of the [Service] section of the unit. - See systemd.unit + See systemd.service 5 for details. ''; }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 2a586090dd1e..5f7ea7d3c9b5 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -26,6 +26,7 @@ let "nss-user-lookup.target" "syslog.target" "time-sync.target" + #"cryptsetup.target" # Udev. "systemd-udevd-control.socket" @@ -68,7 +69,7 @@ let "systemd-update-utmp-shutdown.service" # Kernel module loading. - "systemd-modules-load.service" + "systemd-modules-load.service" # Filesystems. "systemd-fsck@.service" @@ -177,6 +178,7 @@ let Wants=${concatStringsSep " " def.wants} Before=${concatStringsSep " " def.before} After=${concatStringsSep " " def.after} + ${def.unitConfig} [Service] Environment=PATH=${def.path} @@ -207,7 +209,7 @@ let mkdir -p $out for i in ${toString upstreamUnits}; do fn=${systemd}/example/systemd/system/$i - [ -e $fn ] + if ! [ -e $fn ]; then echo "missing $fn"; false; fi if [ -L $fn ]; then cp -pd $fn $out/ else @@ -217,7 +219,7 @@ let for i in ${toString upstreamWants}; do fn=${systemd}/example/systemd/system/$i - [ -e $fn ] + if ! [ -e $fn ]; then echo "missing $fn"; false; fi x=$out/$(basename $fn) mkdir $x for i in $fn/*; do @@ -239,7 +241,7 @@ let ln -s ${cfg.defaultUnit} $out/default.target - ln -s ../getty@tty1.service $out/multi-user.target.wants/ + #ln -s ../getty@tty1.service $out/multi-user.target.wants/ ''; # */ in From 88bfdca8e02ed93079f8159dcc63ab61372b56dc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 15:31:15 -0400 Subject: [PATCH 067/327] stage-1: Use systemd-udevd instead of the old udevd --- modules/system/boot/stage-1-init.sh | 6 ++--- modules/system/boot/stage-1.nix | 35 ++++++++++++----------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 95e925bbe124..fc97100b135c 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -126,10 +126,10 @@ done # Create device nodes in /dev. echo "running udev..." -export UDEV_CONFIG_FILE=@udevConf@ -mkdir -p /dev/.udev # !!! bug in udev? +mkdir -p /etc/udev +ln -sfn @udevRules@ /etc/udev/rules.d mkdir -p /dev/.mdadm -udevd --daemon +systemd-udevd --daemon udevadm trigger --action=add udevadm settle || true modprobe scsi_wait_scan || true diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index 02a75ae21c46..d2a96a764c74 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -9,6 +9,8 @@ with pkgs.lib; let + udev = config.system.build.systemd; + options = { boot.resumeDevice = mkOption { @@ -153,7 +155,7 @@ let cp -v ${pkgs.utillinux}/sbin/blkid $out/bin cp -pdv ${pkgs.utillinux}/lib/libblkid*.so.* $out/lib cp -pdv ${pkgs.utillinux}/lib/libuuid*.so.* $out/lib - + # Copy dmsetup and lvm. cp -v ${pkgs.lvm2}/sbin/dmsetup $out/bin/dmsetup cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm @@ -163,9 +165,12 @@ let cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm # Copy udev. - cp -v ${pkgs.udev}/sbin/udevd ${pkgs.udev}/sbin/udevadm $out/bin - cp -v ${pkgs.udev}/lib/udev/*_id $out/bin - cp -pdv ${pkgs.udev}/lib/libudev.so.* $out/lib + cp -v ${udev}/lib/systemd/systemd-udevd ${udev}/bin/udevadm $out/bin + cp -v ${udev}/lib/udev/*_id $out/bin + cp -pdv ${udev}/lib/libudev.so.* $out/lib + cp -v ${pkgs.kmod}/lib/libkmod.so.* $out/lib + cp -v ${pkgs.acl}/lib/libacl.so.* $out/lib + cp -v ${pkgs.attr}/lib/libattr.so.* $out/lib # Copy modprobe. cp -v ${pkgs.module_init_tools}/sbin/modprobe $out/bin/modprobe @@ -223,26 +228,21 @@ let echo 'ENV{LD_LIBRARY_PATH}="${extraUtils}/lib"' > $out/00-env.rules - cp -v ${pkgs.udev}/lib/udev/rules.d/60-cdrom_id.rules $out/ - cp -v ${pkgs.udev}/lib/udev/rules.d/60-persistent-storage.rules $out/ - cp -v ${pkgs.udev}/lib/udev/rules.d/80-drivers.rules $out/ + cp -v ${udev}/lib/udev/rules.d/60-cdrom_id.rules $out/ + cp -v ${udev}/lib/udev/rules.d/60-persistent-storage.rules $out/ + cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/ cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/ cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/ for i in $out/*.rules; do substituteInPlace $i \ --replace ata_id ${extraUtils}/bin/ata_id \ - --replace usb_id ${extraUtils}/bin/usb_id \ --replace scsi_id ${extraUtils}/bin/scsi_id \ - --replace path_id ${extraUtils}/bin/path_id \ - --replace vol_id ${extraUtils}/bin/vol_id \ --replace cdrom_id ${extraUtils}/bin/cdrom_id \ --replace /sbin/blkid ${extraUtils}/bin/blkid \ - --replace /sbin/modprobe ${extraUtils}/bin/modprobe \ - --replace 'ENV{DM_SBIN_PATH}="${pkgs.lvm2}/sbin"' 'ENV{DM_SBIN_PATH}="${extraUtils}/bin"' \ + --replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \ --replace /sbin/mdadm ${extraUtils}/bin/mdadm done - # !!! Remove this after merging the x-updates branch: # Work around a bug in QEMU, which doesn't implement the "READ # DISC INFORMATION" SCSI command: @@ -260,13 +260,6 @@ let }; - # The udev configuration file for in the initrd. - udevConf = pkgs.writeText "udev-initrd.conf" '' - udev_rules="${udevRules}" - #udev_log="debug" - ''; - - # The init script of boot stage 1 (loading kernel modules for # mounting the root FS). bootStage1 = pkgs.substituteAll { @@ -276,7 +269,7 @@ let isExecutable = true; - inherit udevConf extraUtils modulesClosure; + inherit udevRules extraUtils modulesClosure; inherit (config.boot) resumeDevice devSize runSize; From 4475294f575865fe7fefb8a8d5c3a94f6141550b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 16:45:50 -0400 Subject: [PATCH 068/327] Fix a hang during shutdown Subtle: dhcpcd.service would call resolvconf during shutdown, which in turn would start invalidate-nscd.service, causing the shutdown to be cancelled. Instead, give nscd.service a proper reload action, and do "systemctl reload --no-block nscd.service". The --no-block is necessary to prevent that command from waiting until a timeout occurs (bug in systemd?). --- modules/config/networking.nix | 2 +- modules/services/networking/dhcpcd.nix | 3 ++- modules/services/system/nscd.nix | 17 +++++------------ modules/system/boot/shutdown.nix | 2 +- modules/system/boot/stage-2-init.sh | 2 +- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/modules/config/networking.nix b/modules/config/networking.nix index a91ce9c59e26..5896e9ec9fd4 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -67,7 +67,7 @@ in '' + optionalString config.services.nscd.enable '' # Invalidate the nscd cache whenever resolv.conf is # regenerated. - libc_restart='${pkgs.systemd}/bin/systemctl start invalidate-nscd.service' + libc_restart='${pkgs.systemd}/bin/systemctl reload --no-block nscd.service' '' + optionalString config.services.bind.enable '' # This hosts runs a full-blown DNS resolver. name_servers='127.0.0.1' diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index c1cc22f905c5..77d4ac6253c7 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -92,7 +92,8 @@ in config = mkIf config.networking.useDHCP { jobs.dhcpcd = - { startOn = "started network-interfaces"; + { wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.service" ]; path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index 80fa1394aca6..d92e4e608b59 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -58,18 +58,11 @@ in daemonType = "fork"; - serviceConfig = "PIDFile=/run/nscd/nscd.pid"; - }; - - # Flush nscd's ‘hosts’ database when the network comes up or the - # system configuration changes to get rid of any negative entries. - jobs.invalidate_nscd = - { name = "invalidate-nscd"; - description = "Invalidate NSCD cache"; - startOn = "ip-up or config-changed"; - after = [ "nscd.service" ]; - task = true; - exec = "${pkgs.glibc}/sbin/nscd --invalidate hosts"; + serviceConfig = + '' + PIDFile=/run/nscd/nscd.pid + ExecReload=${pkgs.glibc}/sbin/nscd --invalidate hosts + ''; }; }; diff --git a/modules/system/boot/shutdown.nix b/modules/system/boot/shutdown.nix index 1335429b6697..3fb9545b33fb 100644 --- a/modules/system/boot/shutdown.nix +++ b/modules/system/boot/shutdown.nix @@ -21,5 +21,5 @@ with pkgs.lib; ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc ${if config.time.hardwareClockInLocalTime then "--localtime" else "--utc"} ''; }; - + } diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index e8b01788900b..80aff11b34b0 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -179,4 +179,4 @@ fi echo "starting systemd..." PATH=/run/current-system/systemd/lib/systemd \ MODULE_DIR=/run/current-system/kernel-modules/lib/modules \ - exec systemd --log-target journal # --log-level debug --crash-shell + exec systemd --log-target=journal # --log-level=debug --log-target=console --crash-shell From 7a7d04af8aa5041eb6c28a4573342b5fbdb7497f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 17:09:44 -0400 Subject: [PATCH 069/327] systemd: Use the kernel modules from /run/booted-system This prevents failures in systemd-modules-load.service like "Failed to lookup alias 'ipv6': Function not implemented". --- modules/system/boot/modprobe.nix | 8 ++++---- modules/system/boot/stage-2-init.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/system/boot/modprobe.nix b/modules/system/boot/modprobe.nix index 03d9222af217..141be71b920f 100644 --- a/modules/system/boot/modprobe.nix +++ b/modules/system/boot/modprobe.nix @@ -17,8 +17,8 @@ with pkgs.lib; text = '' #! ${pkgs.stdenv.shell} - export MODULE_DIR=/var/run/current-system/kernel-modules/lib/modules - + export MODULE_DIR=/run/current-system/kernel-modules/lib/modules + # Fall back to the kernel modules used at boot time if the # modules in the current configuration don't match the # running kernel. @@ -105,8 +105,8 @@ with pkgs.lib; environment.shellInit = '' - export MODULE_DIR=/var/run/current-system/kernel-modules/lib/modules - ''; + export MODULE_DIR=/run/current-system/kernel-modules/lib/modules + ''; }; diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 80aff11b34b0..fd60fa5e59e4 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -178,5 +178,5 @@ fi # Start systemd. echo "starting systemd..." PATH=/run/current-system/systemd/lib/systemd \ - MODULE_DIR=/run/current-system/kernel-modules/lib/modules \ + MODULE_DIR=/run/booted-system/kernel-modules/lib/modules \ exec systemd --log-target=journal # --log-level=debug --log-target=console --crash-shell From 9dce4bd9c558722d9ff226de22485546ab27e16d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 17:22:04 -0400 Subject: [PATCH 070/327] Provide start/stop/status aliases as a convenience for Upstart users --- modules/programs/bash/bashrc.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index 79583a73174d..94680bce8908 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -46,3 +46,6 @@ alias ls="ls --color=tty" alias ll="ls -l" alias l="ls -alh" alias which="type -P" +alias start="systemctl start" +alias stop="systemctl stop" +alias status="systemctl status" From a44a7271a8dd4d1fb92c9ea94b276ae266762463 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 17:30:11 -0400 Subject: [PATCH 071/327] Warn about Upstart modules with an unknown startOn condition --- modules/system/upstart/upstart.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 92a7add88eb9..c31314f10919 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -59,7 +59,9 @@ let after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else if job.startOn == "started udev" then [ "systemd-udev.service" ] else - []) ++ job.after; + if job.startOn == "" || job.startOn == "startup" then [ ] else + builtins.trace "Warning: job ‘${job.name}’ has unknown startOn value ‘${job.startOn}’." [] + ) ++ job.after; wantedBy = (if job.startOn == "" then [ ] else [ "multi-user.target" ]) ++ job.wantedBy; From 11c3219c1c6895e12c682342c2dd7c6abb9b2e99 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 18:12:16 -0400 Subject: [PATCH 072/327] =?UTF-8?q?Remove=20the=20=E2=80=98networking?= =?UTF-8?q?=E2=80=99=20job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Systemd has ‘network.target’ for this purpose. --- modules/tasks/network-interfaces.nix | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 611de13148a3..5ff1a83bc814 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -273,15 +273,6 @@ in ''; }; - jobs.networking = { - name = "networking"; - description = "All required interfaces are up"; - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; - task = true; - exec = "true"; - }; - # Set the host name in the activation script. Don't clear it if # it's not configured in the NixOS configuration, since it may # have been set by dhclient in the meantime. From 55b27365663d6761ea5ece113f5c2c26f299b529 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 18:14:16 -0400 Subject: [PATCH 073/327] =?UTF-8?q?Add=20a=20target=20=E2=80=98fs.target?= =?UTF-8?q?=E2=80=99=20that=20waits=20for=20all=20filesystems?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/system/boot/systemd.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 5f7ea7d3c9b5..6cd8b80f22ad 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -150,6 +150,13 @@ let KillSignal=SIGHUP ''; + fsTarget = + '' + [Unit] + Description=All File Systems + Wants=local-fs.target remote-fs.target + ''; + makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; serviceConfig = { name, config, ... }: { @@ -328,6 +335,7 @@ in boot.systemd.units = { "rescue.service".text = rescueService; } + // { "fs.target" = { text = fsTarget; wantedBy = [ "multi-user.target" ]; }; } // mapAttrs serviceToUnit cfg.services; }; From a133eb5991f9f3bf226366ca30ca65e480d467b2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 18:14:48 -0400 Subject: [PATCH 074/327] Add some missing targets Also make multi-user.target pull in remote-fs.target to mount remote filesystems. --- modules/system/boot/systemd.nix | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 6cd8b80f22ad..51b65812b34c 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -27,6 +27,7 @@ let "syslog.target" "time-sync.target" #"cryptsetup.target" + "sigpwr.target" # Udev. "systemd-udevd-control.socket" @@ -35,6 +36,12 @@ let "systemd-udev-settle.service" "systemd-udev-trigger.service" + # Hardware (started by udev when a relevant device is plugged in). + "sound.target" + "bluetooth.target" + "printer.target" + "smartcard.target" + # Login stuff. "systemd-logind.service" "autovt@.service" @@ -106,6 +113,7 @@ let "shutdown.target" "umount.target" "final.target" + "kexec.target" # Password entry. "systemd-ask-password-console.path" @@ -249,6 +257,7 @@ let ln -s ${cfg.defaultUnit} $out/default.target #ln -s ../getty@tty1.service $out/multi-user.target.wants/ + ln -s ../remote-fs.target $out/multi-user.target.wants/ ''; # */ in From c2b2a3369a000c59e6dba6e29b526eeb2d10ec97 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 Aug 2012 18:15:37 -0400 Subject: [PATCH 075/327] Fix dependencies of Apache and PostgreSQL --- modules/services/databases/postgresql.nix | 3 ++- modules/services/web-servers/apache-httpd/default.nix | 8 ++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index 139a716ae75f..69051c295217 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -153,7 +153,8 @@ in jobs.postgresql = { description = "PostgreSQL server"; - startOn = "started network-interfaces and filesystem"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "fs.target" ]; environment = { TZ = config.time.timeZone; diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 2f90c5156435..7c13fd327524 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -581,12 +581,8 @@ in jobs.httpd = { description = "Apache HTTPD"; - startOn = "started networking and filesystem" - # Hacky. Some subservices depend on Postgres - # (e.g. Mediawiki), but they don't have a way to declare - # that dependency. So just start httpd after postgresql if - # the latter is enabled. - + optionalString config.services.postgresql.enable " and started postgresql"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "fs.target" "postgresql.service" ]; path = [ httpd pkgs.coreutils pkgs.gnugrep ] From 981347429a22c86bdade29409b7204fb2dd20a46 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 15 Aug 2012 15:36:54 -0400 Subject: [PATCH 076/327] Add support for PartOf dependencies --- modules/system/boot/systemd-unit-options.nix | 9 +++++++++ modules/system/boot/systemd.nix | 3 ++- modules/system/upstart/upstart.nix | 9 ++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index ec769ad69f99..9aa9b2b4f3ba 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -47,6 +47,15 @@ with pkgs.lib; ''; }; + partOf = mkOption { + default = []; + types = types.listOf types.string; + description = '' + If the specified units are stopped or restarted, then this + unit is stopped or restarted as well. + ''; + }; + wantedBy = mkOption { default = []; types = types.listOf types.string; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 51b65812b34c..06019fa2a089 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -191,8 +191,9 @@ let ''} Requires=${concatStringsSep " " def.requires} Wants=${concatStringsSep " " def.wants} - Before=${concatStringsSep " " def.before} After=${concatStringsSep " " def.after} + Before=${concatStringsSep " " def.before} + PartOf=${concatStringsSep " " def.partOf} ${def.unitConfig} [Service] diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index c31314f10919..577efe170659 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -54,17 +54,20 @@ let ''; in { - inherit (job) description requires wants before environment path; + inherit (job) description requires wants before partOf environment path; after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else if job.startOn == "started udev" then [ "systemd-udev.service" ] else - if job.startOn == "" || job.startOn == "startup" then [ ] else + if job.startOn == "ip-up" then [] else + if job.startOn == "" || job.startOn == "startup" then [] else builtins.trace "Warning: job ‘${job.name}’ has unknown startOn value ‘${job.startOn}’." [] ) ++ job.after; wantedBy = - (if job.startOn == "" then [ ] else [ "multi-user.target" ]) ++ job.wantedBy; + (if job.startOn == "" then [] else + if job.startOn == "ip-up" then [ "ip-up.target" ] else + [ "multi-user.target" ]) ++ job.wantedBy; serviceConfig = '' From d18c2afc6fa6076274aa8334f8b58e1f4e1cdc8a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 15 Aug 2012 15:38:52 -0400 Subject: [PATCH 077/327] Add an ip-up target for services that require IP connectivity --- modules/config/networking.nix | 6 ++++++ modules/services/networking/dhcpcd.nix | 8 +++++--- modules/services/networking/ntpd.nix | 3 ++- modules/system/boot/systemd.nix | 1 + modules/tasks/network-interfaces.nix | 13 +++++++------ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/modules/config/networking.nix b/modules/config/networking.nix index 5896e9ec9fd4..921972093ce1 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -75,4 +75,10 @@ in target = "resolvconf.conf"; } ]; + + boot.systemd.units."ip-up.target".text = + '' + [Unit] + Description=Services Requiring IP Connectivity + ''; } diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 77d4ac6253c7..2767af7200e1 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -56,9 +56,9 @@ let # server hostnames in its config file, then it will never do # anything ever again ("couldn't resolve ..., giving up on # it"), so we silently lose time synchronisation. - ${config.system.build.systemd}/bin/systemctl restart ntpd.service + ${config.system.build.systemd}/bin/systemctl try-restart ntpd.service - #${config.system.build.upstart}/sbin/initctl emit -n ip-up $params + ${config.system.build.systemd}/bin/systemctl start ip-up.target fi #if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then @@ -92,7 +92,9 @@ in config = mkIf config.networking.useDHCP { jobs.dhcpcd = - { wantedBy = [ "multi-user.target" ]; + { description = "DHCP Client"; + + wantedBy = [ "multi-user.target" ]; after = [ "network-interfaces.service" ]; path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; diff --git a/modules/services/networking/ntpd.nix b/modules/services/networking/ntpd.nix index 7d1db8df0663..e9b27268aa17 100644 --- a/modules/services/networking/ntpd.nix +++ b/modules/services/networking/ntpd.nix @@ -68,7 +68,8 @@ in jobs.ntpd = { description = "NTP daemon"; - startOn = "ip-up"; + wantedBy = [ "ip-up.target" ]; + partOf = [ "ip-up.target" ]; path = [ ntp ]; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 06019fa2a089..992981f0a36e 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -259,6 +259,7 @@ let #ln -s ../getty@tty1.service $out/multi-user.target.wants/ ln -s ../remote-fs.target $out/multi-user.target.wants/ + ln -s ../network.target $out/multi-user.target.wants/ ''; # */ in diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 5ff1a83bc814..5302fa82bd48 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -195,10 +195,12 @@ in security.setuidPrograms = [ "ping" "ping6" ]; - jobs.networkInterfaces = - { name = "network-interfaces"; + jobs."network-interfaces" = + { description = "Static Network Interfaces"; - startOn = "stopped udevtrigger"; + after = [ "systemd-udev-settle.service" ]; + before = [ "network.target" ]; + wantedBy = [ "network.target" ]; path = [ pkgs.iproute ]; @@ -266,9 +268,8 @@ in ${pkgs.stdenv.shell} ${pkgs.writeText "local-net-cmds" cfg.localCommands} ${optionalString (cfg.interfaces != [] || cfg.localCommands != "") '' - # Emit the ip-up event (e.g. to start ntpd). - #FIXME - #initctl emit -n ip-up + # Start the ip-up target (e.g. to start ntpd). + ${config.system.build.systemd}/bin/systemctl start ip-up.target ''} ''; }; From 36f5c97b49281fd1977e301db31dfabd1a0b6914 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 16 Aug 2012 16:34:49 -0400 Subject: [PATCH 078/327] Use systemd-udevd instead of udevd --- modules/misc/nixpkgs.nix | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index 3154c3dd1e7d..504f30a1a8f4 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -70,4 +70,14 @@ in }; }; + + config = { + + # FIXME + nixpkgs.config.packageOverrides = pkgs: { + #udev = pkgs.systemd; + lvm2 = pkgs.lvm2.override { udev = pkgs.systemd; }; + }; + + }; } From 8e8bad96d4ba613aec38f6143ab9e71a056128b0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 11:00:14 -0400 Subject: [PATCH 079/327] alsa.nix: Add job description --- modules/services/audio/alsa.nix | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix index d16a67948327..8212b3f9fd06 100644 --- a/modules/services/audio/alsa.nix +++ b/modules/services/audio/alsa.nix @@ -29,9 +29,9 @@ in enableOSSEmulation = mkOption { default = true; - description = '' - Whether to enable ALSA OSS emulation (with certain cards sound mixing may not work!). - ''; + description = '' + Whether to enable ALSA OSS emulation (with certain cards sound mixing may not work!). + ''; }; }; @@ -48,7 +48,9 @@ in boot.kernelModules = optional config.sound.enableOSSEmulation "snd_pcm_oss"; jobs.alsa = - { startOn = "stopped udevtrigger"; + { description = "ALSA Volume Settings"; + + startOn = "stopped udevtrigger"; preStart = '' From 2ce5abaedf40abc537cc1e96c8292341264a643b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 11:00:33 -0400 Subject: [PATCH 080/327] acpid.nix: Fix dependencies --- modules/services/hardware/acpid.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/services/hardware/acpid.nix b/modules/services/hardware/acpid.nix index 303db3816b5a..2002df6a303c 100644 --- a/modules/services/hardware/acpid.nix +++ b/modules/services/hardware/acpid.nix @@ -95,9 +95,10 @@ in config = mkIf config.services.acpid.enable { jobs.acpid = - { description = "ACPI daemon"; + { description = "ACPI Daemon"; - startOn = "stopped udevtrigger and started syslogd"; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-udev-settle.service" ]; path = [ pkgs.acpid ]; From f903a3dcc80c4bad08dab1474b76c461c7f668a1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 11:01:07 -0400 Subject: [PATCH 081/327] dhcpcd.nix: Add a reload action for rebinding interfaces --- modules/services/networking/dhcpcd.nix | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 2767af7200e1..54fdf7b81cfc 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -62,7 +62,7 @@ let fi #if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then - # ${config.system.build.upstart}/sbin/initctl emit -n ip-down $params + # ${config.system.build.systemd}/bin/systemctl start ip-down.target #fi ''; @@ -102,6 +102,11 @@ in daemonType = "fork"; exec = "dhcpcd --config ${dhcpcdConf}"; + + serviceConfig = + '' + ExecReload=${dhcpcd}/sbin/dhcpcd --rebind + ''; }; environment.systemPackages = [ dhcpcd ]; @@ -115,8 +120,7 @@ in powerManagement.resumeCommands = '' # Tell dhcpcd to rebind its interfaces if it's running. - status="$(${config.system.build.upstart}/sbin/status dhcpcd)" - [[ "$status" =~ start/running ]] && ${dhcpcd}/sbin/dhcpcd --rebind + ${config.system.build.systemctl}/bin/systemctl reload dhcpcd.service ''; }; From 7d958dcdd109f7b9bf1fd0eb335ac2ab3b116fb0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 11:02:12 -0400 Subject: [PATCH 082/327] Drop Upstart references --- modules/services/networking/wpa_supplicant.nix | 6 +++--- modules/services/x11/display-managers/kdm.nix | 4 ++-- modules/services/x11/display-managers/slim.nix | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/services/networking/wpa_supplicant.nix b/modules/services/networking/wpa_supplicant.nix index 5dc203fd177f..c6b7df38fcfc 100644 --- a/modules/services/networking/wpa_supplicant.nix +++ b/modules/services/networking/wpa_supplicant.nix @@ -45,8 +45,8 @@ in description = '' The interfaces wpa_supplicant will use. If empty, it will automatically use all wireless interfaces. (Note that auto-detection is currently - broken on Linux 3.4.x kernels. See http://github.com/NixOS/nixos/issues/10 for - further details.) + broken on Linux 3.4.x kernels. See http://github.com/NixOS/nixos/issues/10 for + further details.) ''; }; @@ -122,7 +122,7 @@ in powerManagement.resumeCommands = '' - ${config.system.build.upstart}/sbin/restart wpa_supplicant + ${config.system.build.systemd}/bin/systemctl try-restart wpa_supplicant ''; assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != []; diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index ec4d033a597f..1699ad6343d3 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -12,8 +12,8 @@ let defaultConfig = '' [Shutdown] - HaltCmd=${config.system.build.upstart}/sbin/halt - RebootCmd=${config.system.build.upstart}/sbin/reboot + HaltCmd=${config.system.build.systemd}/sbin/halt + RebootCmd=${config.system.build.systemd}/sbin/reboot ${optionalString (config.system.boot.loader.id == "grub") '' BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"} ''} diff --git a/modules/services/x11/display-managers/slim.nix b/modules/services/x11/display-managers/slim.nix index fc4df80d810a..fbd899b9a95c 100644 --- a/modules/services/x11/display-managers/slim.nix +++ b/modules/services/x11/display-managers/slim.nix @@ -14,8 +14,8 @@ let xserver_arguments ${dmcfg.xserverArgs} sessions ${pkgs.lib.concatStringsSep "," (dmcfg.session.names ++ ["custom"])} login_cmd exec ${pkgs.stdenv.shell} ${dmcfg.session.script} "%session" - halt_cmd ${config.system.build.upstart}/sbin/shutdown -h now - reboot_cmd ${config.system.build.upstart}/sbin/shutdown -r now + halt_cmd ${config.system.build.systemd}/sbin/shutdown -h now + reboot_cmd ${config.system.build.systemd}/sbin/shutdown -r now ${optionalString (cfg.defaultUser != "") ("default_user " + cfg.defaultUser)} ${optionalString cfg.hideCursor "hidecursor true"} ${optionalString cfg.autoLogin "auto_login yes"} From a44e57519627df094657f73c9e475aead2761919 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 13:14:42 -0400 Subject: [PATCH 083/327] =?UTF-8?q?switch-to-configuration:=20Respect=20th?= =?UTF-8?q?e=20=E2=80=98restartIfChanged=E2=80=99=20attribute?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/services/x11/xserver.nix | 2 +- .../activation/switch-to-configuration.pl | 31 +++++++++++++++---- modules/system/boot/systemd-unit-options.nix | 9 ++++++ modules/system/boot/systemd.nix | 1 + modules/system/upstart/upstart.nix | 13 +------- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 5d795e5d57dc..5b9cb74169e0 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -383,7 +383,7 @@ in { wantedBy = [ "graphical.target" ]; after = [ "systemd-udev-settle.service" ]; - #restartIfChanged = false; + restartIfChanged = false; environment = { FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index df4c440b97a9..a4ca287b420f 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -75,12 +75,23 @@ sub parseFstab { return %res; } +sub parseUnit { + my ($filename) = @_; + my $info = {}; + foreach my $line (read_file($filename)) { + # FIXME: not quite correct. + $line =~ /^([^=]+)=(.*)$/ or next; + $info->{$1} = $2; + } + return $info; +} + # Forget about previously failed services. system("@systemd@/bin/systemctl", "reset-failed"); # Stop all services that no longer exist or have changed in the new # configuration. -my @unitsToStop; +my (@unitsToStop, @unitsToSkip); my $activePrev = getActiveUnits; while (my ($unit, $state) = each %{$activePrev}) { my $baseUnit = $unit; @@ -102,11 +113,16 @@ while (my ($unit, $state) = each %{$activePrev}) { } elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/) { # FIXME: do something? } else { - # Record that this unit needs to be started below. We - # write this to a file to ensure that the service gets - # restarted if we're interrupted. - write_file($restartListFile, { append => 1 }, "$unit\n"); - push @unitsToStop, $unit; + my $unitInfo = parseUnit($newUnitFile); + if ($unitInfo->{'X-RestartIfChanged'} eq "false") { + push @unitsToSkip, $unit; + } else { + # Record that this unit needs to be started below. We + # write this to a file to ensure that the service gets + # restarted if we're interrupted. + write_file($restartListFile, { append => 1 }, "$unit\n"); + push @unitsToStop, $unit; + } } } } @@ -159,6 +175,9 @@ if (scalar @unitsToStop > 0) { system("@systemd@/bin/systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors? } +print STDERR "NOT restarting the following units: ", join(", ", sort(@unitsToSkip)), "\n" + if scalar @unitsToSkip > 0; + # Activate the new configuration (i.e., update /etc, make accounts, # and so on). my $res = 0; diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 9aa9b2b4f3ba..f56ee4fc0d34 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -115,6 +115,15 @@ with pkgs.lib; ''; }; + restartIfChanged = mkOption { + type = types.bool; + default = true; + description = '' + Whether the service should be restarted during a NixOS + configuration switch if its definition has changed. + ''; + }; + }; } \ No newline at end of file diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 992981f0a36e..def5a8bc580d 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -199,6 +199,7 @@ let [Service] Environment=PATH=${def.path} ${concatMapStrings (n: "Environment=${n}=${getAttr n def.environment}\n") (attrNames def.environment)} + ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"} ${optionalString (def.preStart != "") '' ExecStartPre=${makeJobScript "${name}-prestart.sh" '' diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 577efe170659..7a498b85439c 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -54,7 +54,7 @@ let ''; in { - inherit (job) description requires wants before partOf environment path; + inherit (job) description requires wants before partOf environment path restartIfChanged; after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else @@ -185,15 +185,6 @@ let ''; }; - restartIfChanged = mkOption { - type = types.bool; - default = true; - description = '' - Whether the job should be restarted if it has changed after a - NixOS configuration switch. - ''; - }; - task = mkOption { type = types.bool; default = false; @@ -302,8 +293,6 @@ in config = { - system.build.upstart = "/no-upstart"; - boot.systemd.services = flip mapAttrs' config.jobs (name: job: nameValuePair "${job.name}.service" job.unit); From b91aa1599ca6ef40d6deef7ffd736254197c4bea Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 13:32:23 -0400 Subject: [PATCH 084/327] sshd.nix: Disable password logins for root by default --- modules/services/networking/ssh/sshd.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 0ef1f09f4d6c..76e35250a60a 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -173,14 +173,13 @@ in }; permitRootLogin = mkOption { - default = "yes"; + default = "without-password"; check = permitRootLoginCheck; description = '' Whether the root user can login using ssh. Valid values are yes, without-password, forced-commands-only or no. - If without-password doesn't work try yes. ''; }; From 676157f1e7e822e35a576eba87cc126cf8ae84bd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 13:42:52 -0400 Subject: [PATCH 085/327] slim.nix: Remove the hideCursor option because it doesn't work --- modules/services/x11/display-managers/slim.nix | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/services/x11/display-managers/slim.nix b/modules/services/x11/display-managers/slim.nix index fbd899b9a95c..68d8c11f830f 100644 --- a/modules/services/x11/display-managers/slim.nix +++ b/modules/services/x11/display-managers/slim.nix @@ -17,7 +17,6 @@ let halt_cmd ${config.system.build.systemd}/sbin/shutdown -h now reboot_cmd ${config.system.build.systemd}/sbin/shutdown -r now ${optionalString (cfg.defaultUser != "") ("default_user " + cfg.defaultUser)} - ${optionalString cfg.hideCursor "hidecursor true"} ${optionalString cfg.autoLogin "auto_login yes"} ''; @@ -76,14 +75,6 @@ in ''; }; - hideCursor = mkOption { - default = false; - example = true; - description = '' - Hide the mouse cursor on the login screen. - ''; - }; - autoLogin = mkOption { default = false; example = true; From 490ce3a230f96a941e81983cdbc168c613034eae Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 13:48:22 -0400 Subject: [PATCH 086/327] PAM: Rename ownDevices to startSession Logind sessions are more generally useful than for device ownership. For instances, ssh logins can be put in their own session (and thus their own cgroup). --- modules/programs/shadow.nix | 2 +- modules/security/pam.nix | 26 +++++++++---------- modules/services/networking/ssh/sshd.nix | 16 +++++++----- modules/services/x11/display-managers/kdm.nix | 2 +- .../services/x11/display-managers/slim.nix | 2 +- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/modules/programs/shadow.nix b/modules/programs/shadow.nix index a3f837c7367c..4b9be4605487 100644 --- a/modules/programs/shadow.nix +++ b/modules/programs/shadow.nix @@ -90,7 +90,7 @@ in { name = "groupmod"; rootOK = true; } { name = "groupmems"; rootOK = true; } { name = "groupdel"; rootOK = true; } - { name = "login"; ownDevices = true; allowNullPassword = true; } + { name = "login"; startSession = true; allowNullPassword = true; } ]; security.setuidPrograms = [ "passwd" "chfn" "su" "newgrp" ]; diff --git a/modules/security/pam.nix b/modules/security/pam.nix index 9e8bc02ddf41..049df0f9958b 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -41,9 +41,10 @@ let # against the keys in the calling user's ~/.ssh/authorized_keys. # This is useful for "sudo" on password-less remote systems. sshAgentAuth ? false - , # If set, use systemd's PAM connector module to claim - # ownership of audio devices etc. - ownDevices ? false + , # If set, the service will register a new session with systemd's + # login manager. If the service is running locally, this will + # give the user ownership of audio devices etc. + startSession ? false , # Whether to forward XAuth keys between users. Mostly useful # for "su". forwardXAuth ? false @@ -103,7 +104,7 @@ let "session optional ${pam_ldap}/lib/security/pam_ldap.so"} ${optionalString config.krb5.enable "session optional ${pam_krb5}/lib/security/pam_krb5.so"} - ${optionalString ownDevices + ${optionalString startSession "session optional ${pkgs.systemd}/lib/security/pam_systemd.so"} ${optionalString forwardXAuth "session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99"} @@ -150,7 +151,7 @@ in default = []; example = [ { name = "chsh"; rootOK = true; } - { name = "login"; ownDevices = true; allowNullPassword = true; + { name = "login"; startSession = true; allowNullPassword = true; limits = [ { domain = "ftp"; type = "hard"; @@ -171,13 +172,13 @@ in the name of the service. The attribute rootOK specifies whether the root user is allowed to use this service without authentication. The - attribute ownDevices specifies whether - ConsoleKit's PAM connector module should be used to give the - user ownership of devices such as audio and CD-ROM drives. - The attribute forwardXAuth specifies - whether X authentication keys should be passed from the - calling user to the target user (e.g. for - su). + attribute startSession specifies whether + systemd's PAM connector module should be used to start a new + session; for local sessions, this will give the user + ownership of devices such as audio and CD-ROM drives. The + attribute forwardXAuth specifies whether + X authentication keys should be passed from the calling user + to the target user (e.g. for su). The attribute limits defines resource limits that should apply to users or groups for the service. Each item in @@ -235,7 +236,6 @@ in { name = "i3lock"; } { name = "lshd"; } { name = "samba"; } - { name = "sshd"; } { name = "vlock"; } { name = "xlock"; } { name = "xscreensaver"; } diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 76e35250a60a..6ad79ca72a82 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -39,7 +39,7 @@ let ); userOptions = { - + openssh.authorizedKeys = { preserveExistingKeys = mkOption { @@ -78,7 +78,7 @@ let }; }; - + }; mkAuthkeyScript = @@ -256,11 +256,11 @@ in The set of system-wide known SSH hosts. ''; example = [ - { + { hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ]; publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub; } - { + { hostNames = [ "myhost2" ]; publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub; } @@ -327,7 +327,7 @@ in RemainAfterExit=true ''; }; - + boot.systemd.services."sshd.service" = { description = "SSH Daemon"; @@ -335,7 +335,7 @@ in after = [ "set-ssh-keys.service" ]; path = [ pkgs.openssh ]; - + environment.LD_LIBRARY_PATH = nssModulesPath; environment.LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; @@ -362,10 +362,12 @@ in networking.firewall.allowedTCPPorts = cfg.ports; + security.pam.services = optional cfg.usePAM { name = "sshd"; startSession = true; }; + services.openssh.extraConfig = '' PidFile /run/sshd.pid - + Protocol 2 UsePAM ${if cfg.usePAM then "yes" else "no"} diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index 1699ad6343d3..1699f6c65a75 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -111,7 +111,7 @@ in logsXsession = true; }; - security.pam.services = [ { name = "kde"; allowNullPassword = true; ownDevices = true; } ]; + security.pam.services = [ { name = "kde"; allowNullPassword = true; startSession = true; } ]; users.extraUsers = singleton { name = "kdm"; diff --git a/modules/services/x11/display-managers/slim.nix b/modules/services/x11/display-managers/slim.nix index 68d8c11f830f..bc9aef101c7d 100644 --- a/modules/services/x11/display-managers/slim.nix +++ b/modules/services/x11/display-managers/slim.nix @@ -106,7 +106,7 @@ in # Allow null passwords so that the user can login as root on the # installation CD. - security.pam.services = [ { name = "slim"; allowNullPassword = true; ownDevices = true; } ]; + security.pam.services = [ { name = "slim"; allowNullPassword = true; startSession = true; } ]; }; From c60d6caee8b95bd10353ccc20c602c33e27be7f7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 14:43:41 -0400 Subject: [PATCH 087/327] Rename xserver.service to display-manager.service The latter is what graphical.target expects. --- modules/services/x11/xserver.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 5b9cb74169e0..fddffbcf0a61 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -379,9 +379,8 @@ in boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; - boot.systemd.services."xserver.service" = - { wantedBy = [ "graphical.target" ]; - after = [ "systemd-udev-settle.service" ]; + boot.systemd.services."display-manager.service" = + { after = [ "systemd-udev-settle.service" ]; restartIfChanged = false; From 1e5a2bca287f9837d5723b741ca986a211db2f39 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 14:45:43 -0400 Subject: [PATCH 088/327] Remove HAL It's obsolete and we no longer use it. --- modules/config/no-x-libs.nix | 3 +- modules/module-list.nix | 1 - modules/services/hardware/hal.nix | 117 ------------------ .../services/x11/desktop-managers/xfce.nix | 1 - 4 files changed, 1 insertion(+), 121 deletions(-) delete mode 100644 modules/services/hardware/hal.nix diff --git a/modules/config/no-x-libs.nix b/modules/config/no-x-libs.nix index 93635aa667fd..f270a3fa431c 100644 --- a/modules/config/no-x-libs.nix +++ b/modules/config/no-x-libs.nix @@ -7,7 +7,7 @@ example = true; description = '' Switch off the options in the default configuration that require X libraries. - Currently this includes: ssh X11 forwarding, dbus, hal, fonts.enableCoreFonts, + Currently this includes: ssh X11 forwarding, dbus, fonts.enableCoreFonts, fonts.enableFontConfig ''; }; @@ -16,7 +16,6 @@ programs.ssh.setXAuthLocation = false; services = { dbus.enable = false; - hal.enable = false; }; fonts = { enableCoreFonts = false; diff --git a/modules/module-list.nix b/modules/module-list.nix index a5eb506fcdd6..9f3fa0d6fc52 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -70,7 +70,6 @@ ./services/games/ghost-one.nix ./services/hardware/acpid.nix ./services/hardware/bluetooth.nix - ./services/hardware/hal.nix ./services/hardware/nvidia-optimus.nix ./services/hardware/pcscd.nix ./services/hardware/pommed.nix diff --git a/modules/services/hardware/hal.nix b/modules/services/hardware/hal.nix deleted file mode 100644 index f9fb2dfecef5..000000000000 --- a/modules/services/hardware/hal.nix +++ /dev/null @@ -1,117 +0,0 @@ -# HAL daemon. -{ config, pkgs, ... }: - -with pkgs.lib; - -let - - cfg = config.services.hal; - - inherit (pkgs) hal; - - fdi = pkgs.buildEnv { - name = "hal-fdi"; - pathsToLink = [ "/share/hal/fdi" ]; - paths = cfg.packages; - }; - -in - -{ - - ###### interface - - options = { - - services.hal = { - - enable = mkOption { - default = false; - description = '' - Whether to start the HAL daemon. - ''; - }; - - packages = mkOption { - default = []; - description = '' - Packages containing additional HAL configuration data. - ''; - }; - - }; - - }; - - - ###### implementation - - config = mkIf cfg.enable { - - environment.systemPackages = [ hal ]; - - services.hal.packages = [ hal pkgs.hal_info ]; - - security.policykit.enable = true; - - users.extraUsers = singleton - { name = "haldaemon"; - uid = config.ids.uids.haldaemon; - description = "HAL daemon user"; - }; - - users.extraGroups = singleton - { name = "haldaemon"; - gid = config.ids.gids.haldaemon; - }; - - jobs.hal = - { description = "HAL daemon"; - - startOn = "started dbus" + optionalString config.services.acpid.enable " and started acpid"; - - environment = - { # !!! HACK? These environment variables manipulated inside - # 'src'/hald/mmap_cache.c are used for testing the daemon. - HAL_FDI_SOURCE_PREPROBE = "${fdi}/share/hal/fdi/preprobe"; - HAL_FDI_SOURCE_INFORMATION = "${fdi}/share/hal/fdi/information"; - HAL_FDI_SOURCE_POLICY = "${fdi}/share/hal/fdi/policy"; - - # Stuff needed by the shell scripts run by HAL (in particular pm-utils). - HALD_RUNNER_PATH = concatStringsSep ":" - [ "${pkgs.coreutils}/bin" - "${pkgs.gnugrep}/bin" - "${pkgs.dbus_tools}/bin" - "${pkgs.procps}/bin" - "${pkgs.procps}/sbin" - "${config.system.sbin.modprobe}/sbin" - "${pkgs.module_init_tools}/bin" - "${pkgs.module_init_tools}/sbin" - "${pkgs.kbd}/bin" - ]; - }; - - preStart = - '' - mkdir -m 0755 -p /var/cache/hald - mkdir -m 0755 -p /var/run/hald - - rm -f /var/cache/hald/fdi-cache - ''; - - daemonType = "fork"; - - # The `PATH=' works around a bug in HAL: it concatenates - # its libexec directory to $PATH, but using a 512-byte - # buffer. So if $PATH is too long it fails. - script = "PATH= exec ${hal}/sbin/hald --use-syslog"; - }; - - services.udev.packages = [hal]; - - services.dbus.enable = true; - services.dbus.packages = [hal]; - - }; - -} diff --git a/modules/services/x11/desktop-managers/xfce.nix b/modules/services/x11/desktop-managers/xfce.nix index 753bac476274..3fead2e96cb8 100644 --- a/modules/services/x11/desktop-managers/xfce.nix +++ b/modules/services/x11/desktop-managers/xfce.nix @@ -89,7 +89,6 @@ in ''; # Enable helpful DBus services. - services.hal = mkIf (!isXfce48) { enable = true; }; services.udisks = mkIf isXfce48 { enable = true; }; services.upower = mkIf (isXfce48 && config.powerManagement.enable) { enable = true; }; From 6547ecb72f67a1f59d339a3faf91bb403f87cfc2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 17 Aug 2012 14:47:37 -0400 Subject: [PATCH 089/327] Remove policykit.nix (old PolicyKit module) Only the HAL module needed it. --- modules/module-list.nix | 1 - modules/security/policykit.nix | 80 ---------------------------------- 2 files changed, 81 deletions(-) delete mode 100644 modules/security/policykit.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 9f3fa0d6fc52..14cf4f7012c5 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -46,7 +46,6 @@ ./security/ca.nix ./security/pam.nix ./security/pam_usb.nix - ./security/policykit.nix ./security/polkit.nix ./security/rtkit.nix ./security/setuid-wrappers.nix diff --git a/modules/security/policykit.nix b/modules/security/policykit.nix deleted file mode 100644 index 5aa02950f747..000000000000 --- a/modules/security/policykit.nix +++ /dev/null @@ -1,80 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -let - - conf = pkgs.writeText "PolicyKit.conf" - '' - - - - - - - ''; - -in - -{ - - options = { - - security.policykit.enable = mkOption { - default = false; - description = "Enable PolicyKit (obsolete)."; - }; - - }; - - - config = mkIf config.security.policykit.enable { - - environment.systemPackages = [ pkgs.policykit ]; - - services.dbus.packages = [ pkgs.policykit ]; - - security.pam.services = [ { name = "polkit"; } ]; - - users.extraUsers = singleton - { name = "polkituser"; - uid = config.ids.uids.polkituser; - description = "PolicyKit user"; - }; - - users.extraGroups = singleton - { name = "polkituser"; - gid = config.ids.gids.polkituser; - }; - - environment.etc = - [ { source = conf; - target = "PolicyKit/PolicyKit.conf"; - } - { source = (pkgs.buildEnv { - name = "PolicyKit-policies"; - pathsToLink = [ "/share/PolicyKit/policy" ]; - paths = [ pkgs.policykit pkgs.consolekit pkgs.hal ]; - }) + "/share/PolicyKit/policy"; - target = "PolicyKit/policy"; - } - ]; - - system.activationScripts.policyKit = stringAfter [ "users" ] - '' - mkdir -m 0770 -p /var/run/PolicyKit - chown root:polkituser /var/run/PolicyKit - - mkdir -m 0770 -p /var/lib/PolicyKit - chown root:polkituser /var/lib/PolicyKit - - mkdir -p /var/lib/misc - touch /var/lib/misc/PolicyKit.reload - chmod 0664 /var/lib/misc/PolicyKit.reload - chown polkituser:polkituser /var/lib/misc/PolicyKit.reload - ''; - - }; - -} From ebb1781dfc7f961bd5f17b3c827fea085bacc097 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 11:10:19 -0400 Subject: [PATCH 090/327] Fix KDE/kdm --- modules/services/x11/desktop-managers/kde4.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/x11/desktop-managers/kde4.nix b/modules/services/x11/desktop-managers/kde4.nix index 2f7f62ce4160..f4bf0d3f2c64 100644 --- a/modules/services/x11/desktop-managers/kde4.nix +++ b/modules/services/x11/desktop-managers/kde4.nix @@ -158,7 +158,7 @@ in services.udisks.enable = true; services.upower = mkIf config.powerManagement.enable { enable = true; }; - security.pam.services = [ { name = "kde"; allowNullPassword = true; } ]; + security.pam.services = [ { name = "kde"; allowNullPassword = true; startSession = true; } ]; }; From cdc3604a7da4e0ca11a737d986a9ad55e649e117 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 11:11:10 -0400 Subject: [PATCH 091/327] kdm: Do a poweroff, not a halt --- modules/services/x11/display-managers/kdm.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index 1699f6c65a75..08ae667211d4 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -12,8 +12,8 @@ let defaultConfig = '' [Shutdown] - HaltCmd=${config.system.build.systemd}/sbin/halt - RebootCmd=${config.system.build.systemd}/sbin/reboot + HaltCmd=${config.system.build.systemd}/sbin/shutdown -h now + RebootCmd=${config.system.build.systemd}/sbin/shutdown -r now ${optionalString (config.system.boot.loader.id == "grub") '' BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"} ''} From 5408f1ebcd09fa01cddbad02375dd89da8b05bc0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 11:11:25 -0400 Subject: [PATCH 092/327] Build slim without consolekit --- modules/misc/nixpkgs.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index 504f30a1a8f4..069bf8ecd9cf 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -76,6 +76,7 @@ in # FIXME nixpkgs.config.packageOverrides = pkgs: { #udev = pkgs.systemd; + slim = pkgs.slim.override { consolekit = null; }; lvm2 = pkgs.lvm2.override { udev = pkgs.systemd; }; }; From 39ec043aea88715c195ba1a2d8a91343f3806cd2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 11:21:03 -0400 Subject: [PATCH 093/327] Typo --- modules/services/networking/dhcpcd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 54fdf7b81cfc..6eea947f604a 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -120,7 +120,7 @@ in powerManagement.resumeCommands = '' # Tell dhcpcd to rebind its interfaces if it's running. - ${config.system.build.systemctl}/bin/systemctl reload dhcpcd.service + ${config.system.build.systemd}/bin/systemctl reload dhcpcd.service ''; }; From 36e05e8dd25810824403f68cef92e3dfe2202cec Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 11:21:11 -0400 Subject: [PATCH 094/327] Add some more backward compatibility hacks --- modules/system/upstart/upstart.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 7a498b85439c..c00bc03c66f8 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -59,6 +59,8 @@ let after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else if job.startOn == "started udev" then [ "systemd-udev.service" ] else + if job.startOn == "started network-interfaces" then [ "network-interfaces.service" ] else + if job.startOn == "started networking" then [ "network.target" ] else if job.startOn == "ip-up" then [] else if job.startOn == "" || job.startOn == "startup" then [] else builtins.trace "Warning: job ‘${job.name}’ has unknown startOn value ‘${job.startOn}’." [] From 3f4ffffed799730ec7e240575b0e4534a79e17b2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 11:32:50 -0400 Subject: [PATCH 095/327] Fix a Perl warning --- modules/system/activation/switch-to-configuration.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index a4ca287b420f..23fd0d777964 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -114,7 +114,7 @@ while (my ($unit, $state) = each %{$activePrev}) { # FIXME: do something? } else { my $unitInfo = parseUnit($newUnitFile); - if ($unitInfo->{'X-RestartIfChanged'} eq "false") { + if (($unitInfo->{'X-RestartIfChanged'} // "true") eq "false") { push @unitsToSkip, $unit; } else { # Record that this unit needs to be started below. We From f3def8194e183c01ce6fc7bbef2688e212a7b128 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 16:19:03 -0400 Subject: [PATCH 096/327] switch-to-configuration: Restart all active targets --- .../activation/switch-to-configuration.pl | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 23fd0d777964..c70a6159fe3a 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -86,6 +86,11 @@ sub parseUnit { return $info; } +sub boolIsTrue { + my ($s) = @_; + return $s eq "yes" || $s eq "true"; +} + # Forget about previously failed services. system("@systemd@/bin/systemctl", "reset-failed"); @@ -102,11 +107,18 @@ while (my ($unit, $state) = each %{$activePrev}) { if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { if (! -e $newUnitFile) { push @unitsToStop, $unit; + } elsif ($unit =~ /\.target$/) { + # Cause all active target units to be restarted below. + # This should start most changed units we stop here as + # well as any new dependencies (including new mounts and + # swap devices). + my $unitInfo = parseUnit($newUnitFile); + unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) { + write_file($restartListFile, { append => 1 }, "$unit\n"); + } } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") { # Do nothing. These cannot be restarted directly. - } elsif ($unit =~ /\.target$/) { - write_file($restartListFile, { append => 1 }, "$unit\n"); } elsif ($unit =~ /\.mount$/) { # Reload the changed mount unit to force a remount. write_file($reloadListFile, { append => 1 }, "$unit\n"); @@ -114,7 +126,7 @@ while (my ($unit, $state) = each %{$activePrev}) { # FIXME: do something? } else { my $unitInfo = parseUnit($newUnitFile); - if (($unitInfo->{'X-RestartIfChanged'} // "true") eq "false") { + if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true")) { push @unitsToSkip, $unit; } else { # Record that this unit needs to be started below. We @@ -194,19 +206,13 @@ sub unique { return sort(keys(%unique)); } -# Start the following units: -# - The default target. This should start most changed units we -# stopped above as well as any new dependencies. -# - local-fs.target. This mounts any missing local filesystems. -# - Changed units we stopped above. This is necessary because some -# may not be dependencies of the default target (i.e., they were -# manually started). -# FIXME: detect units that are symlinks to other units. We shouldn't -# start both at the same time because we'll get a "Failed to add path -# to set" error from systemd. -my @start = unique( - "default.target", "local-fs.target", "swap.target", - split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); +# Start all active targets, as well as changed units we stopped above. +# The latter is necessary because some may not be dependencies of the +# targets (i.e., they were manually started). FIXME: detect units +# that are symlinks to other units. We shouldn't start both at the +# same time because we'll get a "Failed to add path to set" error from +# systemd. +my @start = unique("default.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); print STDERR "starting the following units: ", join(", ", @start), "\n"; system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4; unlink($restartListFile); From e02b57df9b54380e94a18df7276b1ff3cbe42f06 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 20 Aug 2012 16:19:57 -0400 Subject: [PATCH 097/327] Fix the dependencies of the vboxnet0 service --- modules/programs/virtualbox.nix | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/programs/virtualbox.nix b/modules/programs/virtualbox.nix index cb293563dfdd..27e4ac400da6 100644 --- a/modules/programs/virtualbox.nix +++ b/modules/programs/virtualbox.nix @@ -10,25 +10,32 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in environment.systemPackages = [ virtualbox ]; users.extraGroups = singleton { name = "vboxusers"; }; - + services.udev.extraRules = '' - KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660" - KERNEL=="vboxnetctl", OWNER="root", GROUP="root", MODE="0600" + KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd" + KERNEL=="vboxnetctl", OWNER="root", GROUP="root", MODE="0600", TAG+="systemd" ''; # Since we lack the right setuid binaries, set up a host-only network by default. - - jobs."create-vboxnet0" = - { task = true; + + jobs."vboxnet0" = + { description = "VirtualBox vboxnet0 Interface"; + requires = [ "dev-vboxnetctl.device" ]; + after = [ "dev-vboxnetctl.device" ]; + before = [ "network-interfaces.service" ]; + wantedBy = [ "multi-user.target" ]; path = [ virtualbox ]; - startOn = "starting network-interfaces"; - script = + preStart = '' if ! [ -e /sys/class/net/vboxnet0 ]; then VBoxManage hostonlyif create fi ''; + postStop = + '' + VBoxManage hostonlyif remove vboxnet0 + ''; }; networking.interfaces = [ { name = "vboxnet0"; ipAddress = "192.168.56.1"; subnetMask = "255.255.255.0"; } ]; From 223f04b3caecf2e52a9ad98abefb2a6f44cd811e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Aug 2012 11:28:47 -0400 Subject: [PATCH 098/327] =?UTF-8?q?Add=20option=20=E2=80=98boot.systemd.pa?= =?UTF-8?q?ckages=E2=80=99=20to=20use=20units=20from=20the=20specified=20p?= =?UTF-8?q?ackages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/system/boot/systemd.nix | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index def5a8bc580d..2045e702fe90 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -250,6 +250,10 @@ let ln -s $i/* $out/ done + for i in ${toString cfg.packages}; do + ln -s $i/etc/systemd/system/* $out/ + done + ${concatStrings (mapAttrsToList (name: unit: concatMapStrings (name2: '' mkdir -p $out/${name2}.wants @@ -288,11 +292,17 @@ in }; }; + boot.systemd.packages = mkOption { + default = []; + type = types.listOf types.package; + description = "Packages providing systemd units."; + }; + boot.systemd.services = mkOption { - description = "Definition of systemd services."; default = {}; type = types.attrsOf types.optionSet; options = [ serviceOptions serviceConfig ]; + description = "Definition of systemd services."; }; boot.systemd.defaultUnit = mkOption { From c2da812bd0148d9a2055e93fa74911e05caf7f83 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Aug 2012 11:29:59 -0400 Subject: [PATCH 099/327] Enable upower's systemd unit --- modules/misc/nixpkgs.nix | 2 ++ modules/services/hardware/upower.nix | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index 069bf8ecd9cf..c8ca959d91af 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -78,6 +78,8 @@ in #udev = pkgs.systemd; slim = pkgs.slim.override { consolekit = null; }; lvm2 = pkgs.lvm2.override { udev = pkgs.systemd; }; + upower = pkgs.upower.override { useSystemd = true; }; + polkit = pkgs.polkit.override { useSystemd = true; }; }; }; diff --git a/modules/services/hardware/upower.nix b/modules/services/hardware/upower.nix index 1fdaee202d30..d025276ea8e9 100644 --- a/modules/services/hardware/upower.nix +++ b/modules/services/hardware/upower.nix @@ -35,6 +35,8 @@ with pkgs.lib; services.udev.packages = [ pkgs.upower ]; + boot.systemd.packages = [ pkgs.upower ]; + system.activationScripts.upower = '' mkdir -m 0755 -p /var/lib/upower From 0280aa2dc4c6a3cf9ddd84e93242611d4945320c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 10:23:41 -0400 Subject: [PATCH 100/327] Remove the lvm job There is a generator in lvm2 that takes care of this. --- modules/tasks/lvm.nix | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/modules/tasks/lvm.nix b/modules/tasks/lvm.nix index 7773a2c79e31..0e0272388c76 100644 --- a/modules/tasks/lvm.nix +++ b/modules/tasks/lvm.nix @@ -6,19 +6,6 @@ config = { - jobs.lvm = - { startOn = "started udev or new-devices"; - - script = - '' - # Make all logical volumes on all volume groups available, i.e., - # make them appear in /dev. - ${pkgs.lvm2}/sbin/vgchange --available y - ''; - - task = true; - }; - environment.systemPackages = [ pkgs.lvm2 ]; services.udev.packages = [ pkgs.lvm2 ]; From cce6e48edf97d919b472fd8fb3c29b1e885e3361 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 10:25:15 -0400 Subject: [PATCH 101/327] Don't use consolekit anywhere --- modules/misc/nixpkgs.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index c8ca959d91af..021986bc8959 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -80,6 +80,7 @@ in lvm2 = pkgs.lvm2.override { udev = pkgs.systemd; }; upower = pkgs.upower.override { useSystemd = true; }; polkit = pkgs.polkit.override { useSystemd = true; }; + consolekit = null; }; }; From b02c488fde15f05008e03dc935184e0ed353656e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 10:25:27 -0400 Subject: [PATCH 102/327] Automatically append ".service" to the name of service units --- modules/services/logging/syslogd.nix | 2 +- modules/services/misc/nix-daemon.nix | 2 +- modules/services/networking/ssh/sshd.nix | 4 ++-- modules/services/x11/xserver.nix | 2 +- modules/system/boot/systemd.nix | 2 +- modules/system/upstart/upstart.nix | 2 +- modules/testing/test-instrumentation.nix | 2 +- modules/virtualisation/virtualbox-guest.nix | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix index a3aff9a30d3a..2b7e4a8e44c7 100644 --- a/modules/services/logging/syslogd.nix +++ b/modules/services/logging/syslogd.nix @@ -105,7 +105,7 @@ in services.syslogd.extraParams = optional cfg.enableNetworkInput "-r"; # FIXME: restarting syslog seems to break journal logging. - boot.systemd.services."syslog.service" = + boot.systemd.services.syslog = { description = "Syslog daemon"; requires = [ "syslog.socket" ]; diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index 793232872585..cf2d0f52d860 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -248,7 +248,7 @@ in ''; }; - boot.systemd.services."nix-daemon.service" = + boot.systemd.services."nix-daemon" = { description = "Nix Daemon"; path = [ nix pkgs.openssl pkgs.utillinux ] diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 6ad79ca72a82..242129c355e0 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -314,7 +314,7 @@ in } ]; - boot.systemd.services."set-ssh-keys.service" = + boot.systemd.services."set-ssh-keys" = { description = "Update authorized SSH keys"; wantedBy = [ "multi-user.target" ]; @@ -328,7 +328,7 @@ in ''; }; - boot.systemd.services."sshd.service" = + boot.systemd.services.sshd = { description = "SSH Daemon"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index fddffbcf0a61..992911ca3c4b 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -379,7 +379,7 @@ in boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; - boot.systemd.services."display-manager.service" = + boot.systemd.services."display-manager" = { after = [ "systemd-udev-settle.service" ]; restartIfChanged = false; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 2045e702fe90..918c0571ab48 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -358,7 +358,7 @@ in boot.systemd.units = { "rescue.service".text = rescueService; } // { "fs.target" = { text = fsTarget; wantedBy = [ "multi-user.target" ]; }; } - // mapAttrs serviceToUnit cfg.services; + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services; }; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index c00bc03c66f8..fbbbf72e027e 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -297,7 +297,7 @@ in boot.systemd.services = flip mapAttrs' config.jobs (name: job: - nameValuePair "${job.name}.service" job.unit); + nameValuePair job.name job.unit); }; diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index facfe29a4b0e..efce3153c88e 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -11,7 +11,7 @@ let kernel = config.boot.kernelPackages.kernel; in config = { - boot.systemd.services."backdoor.service" = + boot.systemd.services.backdoor = { wantedBy = [ "multi-user.target" ]; requires = [ "dev-hvc0.device" ]; after = [ "dev-hvc0.device" ]; diff --git a/modules/virtualisation/virtualbox-guest.nix b/modules/virtualisation/virtualbox-guest.nix index e864c125176c..03234fbb82f7 100644 --- a/modules/virtualisation/virtualbox-guest.nix +++ b/modules/virtualisation/virtualbox-guest.nix @@ -39,7 +39,7 @@ if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then boot.extraModulePackages = [ kernel.virtualboxGuestAdditions ]; jobs.virtualbox = - { description = "VirtualBox service"; + { description = "VirtualBox Guest Services"; wantedBy = [ "multi-user.target" ]; requires = [ "dev-vboxguest.device" ]; From 9e5bbee2b108e37a861212b33a8d299a55cd82bd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 11:08:42 -0400 Subject: [PATCH 103/327] Make cpufreq a service instead of a task Otherwise it will be restarted by switch-to-configuration even when it hasn't changed. --- modules/tasks/cpu-freq.nix | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/tasks/cpu-freq.nix b/modules/tasks/cpu-freq.nix index 0e0fd502a01c..cb64f8ca2a35 100644 --- a/modules/tasks/cpu-freq.nix +++ b/modules/tasks/cpu-freq.nix @@ -32,15 +32,12 @@ with pkgs.lib; startOn = "started udev"; - task = true; - - script = '' + preStart = '' for i in $(seq 0 $(($(nproc) - 1))); do ${pkgs.cpufrequtils}/bin/cpufreq-set -g ${config.powerManagement.cpuFreqGovernor} -c $i done ''; }; - }; } From af550048e83c4b3b24e400c53fca06613f393880 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 11:09:44 -0400 Subject: [PATCH 104/327] switch-to-configuration: Don't restart the suspend/hibernate targets Restarting them has the side effect of suspending/hibernating the system again. --- modules/system/activation/switch-to-configuration.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index c70a6159fe3a..1d2da3cbf8e0 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -111,10 +111,14 @@ while (my ($unit, $state) = each %{$activePrev}) { # Cause all active target units to be restarted below. # This should start most changed units we stop here as # well as any new dependencies (including new mounts and - # swap devices). - my $unitInfo = parseUnit($newUnitFile); - unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) { - write_file($restartListFile, { append => 1 }, "$unit\n"); + # swap devices). FIXME: the suspend target is sometimes + # active after the system has resumed, which probably + # should not be the case. Just ignore it. + if ($unit ne "suspend.target" && $unit ne "hibernate.target") { + my $unitInfo = parseUnit($newUnitFile); + unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) { + write_file($restartListFile, { append => 1 }, "$unit\n"); + } } } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") { From dfb6e891b95f0b2d6f446b112c532a95fb629d65 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 11:11:14 -0400 Subject: [PATCH 105/327] switch-to-configuration: Don't restart systemd-user-sessions.service Restarting it causes all user sessions to be killed. --- modules/system/activation/switch-to-configuration.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 1d2da3cbf8e0..eb5a7a690f05 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -130,7 +130,9 @@ while (my ($unit, $state) = each %{$activePrev}) { # FIXME: do something? } else { my $unitInfo = parseUnit($newUnitFile); - if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true")) { + if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true") + || $unit eq "systemd-user-sessions.service") + { push @unitsToSkip, $unit; } else { # Record that this unit needs to be started below. We From 4c65a5d95cc1641a8b19e6496da8578e8c91a693 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 11:13:33 -0400 Subject: [PATCH 106/327] Don't restart agetty --- modules/services/ttys/agetty.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index 1916c13333d4..f79962c13650 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -94,6 +94,8 @@ with pkgs.lib; # Some login implementations ignore SIGTERM, so we send SIGHUP # instead, to ensure that login terminates cleanly. KillSignal=SIGHUP + + X-RestartIfChanged=false ''; boot.systemd.units."serial-getty@.service".text = @@ -127,6 +129,8 @@ with pkgs.lib; # Some login implementations ignore SIGTERM, so we send SIGHUP # instead, to ensure that login terminates cleanly. KillSignal=SIGHUP + + X-RestartIfChanged=false ''; environment.etc = singleton From e194d41b9cb8e8e7e780f05302b973166a8efd1a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 12:12:25 -0400 Subject: [PATCH 107/327] cpufreq: Don't complain if a CPU doesn't support the desired governor --- modules/tasks/cpu-freq.nix | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/tasks/cpu-freq.nix b/modules/tasks/cpu-freq.nix index cb64f8ca2a35..59e74fa66603 100644 --- a/modules/tasks/cpu-freq.nix +++ b/modules/tasks/cpu-freq.nix @@ -6,7 +6,7 @@ with pkgs.lib; ###### interface options = { - + powerManagement.cpuFreqGovernor = mkOption { default = ""; example = "ondemand"; @@ -17,7 +17,7 @@ with pkgs.lib; "userspace". ''; }; - + }; @@ -30,11 +30,19 @@ with pkgs.lib; jobs.cpufreq = { description = "Initialize CPU frequency governor"; - startOn = "started udev"; + after = [ "systemd-modules-load.service" ]; + wantedBy = [ "multi-user.target" ]; + + path = [ pkgs.cpufrequtils ]; preStart = '' for i in $(seq 0 $(($(nproc) - 1))); do - ${pkgs.cpufrequtils}/bin/cpufreq-set -g ${config.powerManagement.cpuFreqGovernor} -c $i + for gov in $(cpufreq-info -c $i -g); do + if [ "$gov" = ${config.powerManagement.cpuFreqGovernor} ]; then + echo "<6>setting governor on CPU $i to ‘$gov’" + cpufreq-set -c $i -g $gov + fi + done done ''; }; From 8adc1ee92e71239a230e269c36010fff814299d8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 23 Aug 2012 12:12:58 -0400 Subject: [PATCH 108/327] switch-to-configuration: Stop sockets corresponding to services If a service has a corresponding socket unit, then stop the socket before stopping the service. This prevents it from being restarted behind our backs. Also, don't restart the service; it will be restarted on demand via the socket. --- .../activation/switch-to-configuration.pl | 56 ++++++++++++++----- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index eb5a7a690f05..ff083156ca2d 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -91,23 +91,27 @@ sub boolIsTrue { return $s eq "yes" || $s eq "true"; } -# Forget about previously failed services. -system("@systemd@/bin/systemctl", "reset-failed"); - # Stop all services that no longer exist or have changed in the new # configuration. my (@unitsToStop, @unitsToSkip); my $activePrev = getActiveUnits; while (my ($unit, $state) = each %{$activePrev}) { my $baseUnit = $unit; + # Recognise template instances. $baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/; my $prevUnitFile = "/etc/systemd/system/$baseUnit"; my $newUnitFile = "@out@/etc/systemd/system/$baseUnit"; + + my $baseName = $baseUnit; + $baseName =~ s/\.[a-z]*$//; + if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) { if (! -e $newUnitFile) { push @unitsToStop, $unit; - } elsif ($unit =~ /\.target$/) { + } + + elsif ($unit =~ /\.target$/) { # Cause all active target units to be restarted below. # This should start most changed units we stop here as # well as any new dependencies (including new mounts and @@ -120,7 +124,9 @@ while (my ($unit, $state) = each %{$activePrev}) { write_file($restartListFile, { append => 1 }, "$unit\n"); } } - } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { + } + + elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") { # Do nothing. These cannot be restarted directly. } elsif ($unit =~ /\.mount$/) { @@ -131,14 +137,26 @@ while (my ($unit, $state) = each %{$activePrev}) { } else { my $unitInfo = parseUnit($newUnitFile); if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true") - || $unit eq "systemd-user-sessions.service") + || $unit eq "systemd-user-sessions.service" + || $unit eq "systemd-journald.service") { push @unitsToSkip, $unit; } else { + # If this unit has a corresponding socket unit, + # then stop the socket unit as well, and restart + # the socket instead of the service. + if ($unit =~ /\.service$/ && defined $activePrev->{"$baseName.socket"}) { + push @unitsToStop, "$baseName.socket"; + write_file($restartListFile, { append => 1 }, "$baseName.socket\n"); + } + # Record that this unit needs to be started below. We # write this to a file to ensure that the service gets # restarted if we're interrupted. - write_file($restartListFile, { append => 1 }, "$unit\n"); + else { + write_file($restartListFile, { append => 1 }, "$unit\n"); + } + push @unitsToStop, $unit; } } @@ -156,6 +174,17 @@ sub pathToUnitName { return $path; } +sub unique { + my %seen; + my @res; + foreach my $name (@_) { + next if $seen{$name}; + $seen{$name} = 1; + push @res, $name; + } + return @res; +} + # Compare the previous and new fstab to figure out which filesystems # need a remount or need to be unmounted. New filesystems are mounted # automatically by starting local-fs.target. Also handles swap @@ -189,6 +218,7 @@ foreach my $mountPoint (keys %prevFstab) { } if (scalar @unitsToStop > 0) { + @unitsToStop = unique(@unitsToStop); print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n"; system("@systemd@/bin/systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors? } @@ -204,14 +234,12 @@ system("@out@/activate", "@out@") == 0 or $res = 2; # FIXME: Re-exec systemd if necessary. +# Forget about previously failed services. +system("@systemd@/bin/systemctl", "reset-failed"); + # Make systemd reload its units. system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; -sub unique { - my %unique = map { $_, 1 } @_; - return sort(keys(%unique)); -} - # Start all active targets, as well as changed units we stopped above. # The latter is necessary because some may not be dependencies of the # targets (i.e., they were manually started). FIXME: detect units @@ -219,7 +247,7 @@ sub unique { # same time because we'll get a "Failed to add path to set" error from # systemd. my @start = unique("default.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); -print STDERR "starting the following units: ", join(", ", @start), "\n"; +print STDERR "starting the following units: ", join(", ", sort(@start)), "\n"; system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4; unlink($restartListFile); @@ -227,7 +255,7 @@ unlink($restartListFile); # units. my @reload = unique(split '\n', read_file($reloadListFile, err_mode => 'quiet') // ""); if (scalar @reload > 0) { - print STDERR "reloading the following units: ", join(", ", @reload), "\n"; + print STDERR "reloading the following units: ", join(", ", sort(@reload)), "\n"; system("@systemd@/bin/systemctl", "reload", "--", @reload) == 0 or $res = 4; unlink($reloadListFile); } From e0e0e57c2624944ab534aba84becef9ae3b5f6ad Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Aug 2012 21:11:36 -0400 Subject: [PATCH 109/327] Fix the OpenVPN jobs --- modules/services/networking/openvpn.nix | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/services/networking/openvpn.nix b/modules/services/networking/openvpn.nix index c057bda5033c..12808e2ee271 100644 --- a/modules/services/networking/openvpn.nix +++ b/modules/services/networking/openvpn.nix @@ -11,8 +11,8 @@ let makeOpenVPNJob = cfg: name: let - path = (getAttr "openvpn-${name}" config.jobs).path; - + path = (getAttr "openvpn-${name}" config.boot.systemd.services).path; + upScript = '' #! /bin/sh exec > /var/log/openvpn-${name}-up 2>&1 @@ -28,17 +28,17 @@ let fi fi done - + ${cfg.up} ''; - + downScript = '' #! /bin/sh exec > /var/log/openvpn-${name}-down 2>&1 export PATH=${path} ${cfg.down} ''; - + configFile = pkgs.writeText "openvpn-config-${name}" '' ${optionalString (cfg.up != "" || cfg.down != "") "script-security 2"} @@ -46,7 +46,7 @@ let ${optionalString (cfg.up != "") "up ${pkgs.writeScript "openvpn-${name}-up" upScript}"} ${optionalString (cfg.down != "") "down ${pkgs.writeScript "openvpn-${name}-down" downScript}"} ''; - + in { description = "OpenVPN instance ‘${name}’"; @@ -76,7 +76,7 @@ in default = {}; example = { - + server = { config = '' # Simplest server configuration: http://openvpn.net/index.php/documentation/miscellaneous/static-key-mini-howto.html. @@ -88,7 +88,7 @@ in up = "ip route add ..."; down = "ip route del ..."; }; - + client = { config = '' client @@ -103,7 +103,7 @@ in up = "echo nameserver $nameserver | ${pkgs.openresolv}/sbin/resolvconf -m 0 -a $dev"; down = "${pkgs.openresolv}/sbin/resolvconf -d $dev"; }; - + }; description = '' @@ -116,7 +116,7 @@ in ''; type = types.attrsOf types.optionSet; - + options = { config = mkOption { @@ -158,9 +158,9 @@ in jobs = listToAttrs (mapAttrsFlatten (name: value: nameValuePair "openvpn-${name}" (makeOpenVPNJob value name)) cfg.servers); environment.systemPackages = [ openvpn ]; - + boot.kernelModules = [ "tun" ]; - + }; } From b53842df3e8fbbc97293bb58d23d8b87dae890fb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 11 Sep 2012 10:55:56 -0400 Subject: [PATCH 110/327] Don't set the passno field for tmpfs and other FSs that have no device If passno is set, then systemd will instantiate a systemd-fsck unit, which in turn will instantiate a .device unit (e.g. "none.device"). Since no such device exists, mounting will fail. So don't set passno. --- modules/tasks/filesystems.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 8eaf77330a3d..ab58c0757b66 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -15,7 +15,7 @@ let + " " + fs.fsType + " " + fs.options + " 0" - + " " + (if fs.fsType == "none" || fs.fsType == "btrfs" || fs.noCheck then "0" else + + " " + (if fs.fsType == "none" || fs.device == "none" || fs.fsType == "btrfs" || fs.fsType == "tmpfs" || fs.noCheck then "0" else if fs.mountPoint == "/" then "1" else "2") + "\n" )} From 83c6b1cf3a4c68c2c15a346bdc17ddb4ebc3f16a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 18 Sep 2012 18:12:39 -0400 Subject: [PATCH 111/327] Set $LOCALE_ARCHIVE in systemd services Systemd sets locale variables like $LANG when running services, so $LOCALE_ARCHIVE should also be set to prevent warnings like "perl: warning: Setting locale failed.". --- modules/system/boot/stage-2-init.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 79d332690b9d..f1eb73a8f88f 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -179,4 +179,5 @@ fi echo "starting systemd..." PATH=/run/current-system/systemd/lib/systemd \ MODULE_DIR=/run/booted-system/kernel-modules/lib/modules \ + LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive \ exec systemd --log-target=journal # --log-level=debug --log-target=console --crash-shell From 4fa9b4b2579566bd17b63c19be3700ba95746a95 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 21 Sep 2012 14:58:28 -0400 Subject: [PATCH 112/327] Restart systemd if necessary --- modules/system/activation/switch-to-configuration.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index ff083156ca2d..6542b48c54e0 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -232,7 +232,11 @@ my $res = 0; print STDERR "activating the configuration...\n"; system("@out@/activate", "@out@") == 0 or $res = 2; -# FIXME: Re-exec systemd if necessary. +# Restart systemd if necessary. +if (abs_path("/proc/1/exe") ne abs_path("@systemd@/lib/systemd/systemd")) { + print STDERR "restarting systemd...\n"; + system("@systemd@/bin/systemctl", "daemon-reexec") == 0 or $res = 2; +} # Forget about previously failed services. system("@systemd@/bin/systemctl", "reset-failed"); From 1ad655bdcf49ac078119ba866e0f6d5977e0320c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 21 Sep 2012 22:56:13 -0400 Subject: [PATCH 113/327] Don't join the cpuset controller with cpu/cpuacct This works around the problem described here: http://lists.freedesktop.org/archives/systemd-devel/2012-September/006648.html --- modules/system/boot/systemd.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 918c0571ab48..d8b5ee45c7e4 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -340,6 +340,13 @@ in [ { source = units; target = "systemd/system"; } + { source = pkgs.writeText "systemd.conf" + '' + [Manager] + JoinControllers=cpu,cpuacct net_cls,netprio + ''; + target = "systemd/system.conf"; + } { source = pkgs.writeText "journald.conf" '' [Journal] From fcebb3f3cde263879d4ea99470ec637e84d4da82 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 25 Sep 2012 15:22:55 -0400 Subject: [PATCH 114/327] Clean up the nscd job --- modules/services/system/nscd.nix | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index d92e4e608b59..620424b94a03 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -38,10 +38,10 @@ in description = "Name service cache daemon user"; }; - jobs.nscd = + boot.systemd.services.nscd = { description = "Name Service Cache Daemon"; - startOn = "startup"; + wantedBy = [ "multi-user.target" ]; environment = { LD_LIBRARY_PATH = nssModulesPath; }; @@ -52,15 +52,12 @@ in mkdir -m 0755 -p /var/db/nscd ''; - path = [ pkgs.glibc ]; - - exec = "nscd -f ${./nscd.conf}"; - - daemonType = "fork"; - serviceConfig = '' + ExecStart=@${pkgs.glibc}/sbin/nscd nscd -f ${./nscd.conf} + Type=forking PIDFile=/run/nscd/nscd.pid + Restart=always ExecReload=${pkgs.glibc}/sbin/nscd --invalidate hosts ''; }; From a139fa14b1764862f5b47eebb0a355da2c0300a1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 25 Sep 2012 16:33:21 -0400 Subject: [PATCH 115/327] Optionally make the Nix store read-only to enforce immutability This will be the default once Nix 1.2 is released. --- modules/services/misc/nix-daemon.nix | 11 +++++++++++ modules/system/boot/stage-2-init.sh | 11 +++++++++++ modules/system/boot/stage-2.nix | 1 + 3 files changed, 23 insertions(+) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index cf2d0f52d860..7e52686f32f7 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -183,6 +183,17 @@ in you should increase this value. ''; }; + + readOnlyStore = mkOption { + default = false; + description = '' + If set, NixOS will enforce the immutability of the Nix store + by making /nix/store a read-only bind + mount. Nix will automatically make the store writable when + needed. + ''; + }; + }; }; diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index f1eb73a8f88f..3aab7a59504b 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -41,6 +41,17 @@ if [ ! -e /proc/1 ]; then fi +# Make /nix/store a read-only bind mount to enforce immutability of +# the Nix store. +if [ -n "@readOnlyStore@" ]; then + if ! mountpoint /nix/store; then + mkdir -p /nix/rw-store + mount --bind /nix/store /nix/store + mount -o remount,ro,bind /nix/store + fi +fi + + # Provide a /etc/mtab. mkdir -m 0755 -p /etc test -e /etc/fstab || touch /etc/fstab # to shut up mount diff --git a/modules/system/boot/stage-2.nix b/modules/system/boot/stage-2.nix index e187219cbd88..3569cfa81139 100644 --- a/modules/system/boot/stage-2.nix +++ b/modules/system/boot/stage-2.nix @@ -60,6 +60,7 @@ let shellDebug = "${pkgs.bashInteractive}/bin/bash"; isExecutable = true; inherit (config.boot) devShmSize runSize cleanTmpDir; + inherit (config.nix) readOnlyStore; ttyGid = config.ids.gids.tty; path = [ pkgs.coreutils From 5ef71c6d221412a16c8bcf5e35c09db241372d8c Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Sun, 23 Sep 2012 00:07:59 +0200 Subject: [PATCH 116/327] smartd: convert service to systemd --- modules/services/monitoring/smartd.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/services/monitoring/smartd.nix b/modules/services/monitoring/smartd.nix index 2427f29020ea..242faa010f29 100644 --- a/modules/services/monitoring/smartd.nix +++ b/modules/services/monitoring/smartd.nix @@ -75,7 +75,8 @@ in environment.TZ = config.time.timeZone; - startOn = "started syslogd"; + wantedBy = [ "multi-user.target" ]; + partOf = [ "multi-user.target" ]; path = [ pkgs.smartmontools ]; From af7c192f2a542f18f4f488fc52104dc8a3297e2d Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Sun, 23 Sep 2012 00:51:50 +0200 Subject: [PATCH 117/327] postfix: convert service to systemd --- modules/services/mail/postfix.nix | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/modules/services/mail/postfix.nix b/modules/services/mail/postfix.nix index 3784ae3d39f6..d4505818e0c0 100644 --- a/modules/services/mail/postfix.nix +++ b/modules/services/mail/postfix.nix @@ -318,22 +318,13 @@ in # accurate way is unlikely to be better. { description = "Postfix mail server"; - startOn = "started networking and filesystem"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; - daemonType = "none"; - - respawn = true; + daemonType = "fork"; environment.TZ = config.time.timeZone; - script = '' - while ${pkgs.procps}/bin/ps `${pkgs.coreutils}/bin/cat /var/postfix/queue/pid/master.pid` | - grep -q postfix - do - ${pkgs.coreutils}/bin/sleep 1m - done - ''; - preStart = '' if ! [ -d /var/spool/postfix ]; then @@ -346,7 +337,7 @@ in ${pkgs.coreutils}/bin/chown root:root /var/spool/mail ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail - ln -sf ${pkgs.postfix}/share/postfix/conf/* /var/postfix/conf + ln -sf "${pkgs.postfix}/share/postfix/conf/"* /var/postfix/conf ln -sf ${aliasesFile} /var/postfix/conf/aliases ln -sf ${virtualFile} /var/postfix/conf/virtual @@ -355,11 +346,11 @@ in ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual - exec ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start - ''; # */ + ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start + ''; preStop = '' - exec ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop + ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop ''; }; From 3e6bb7d1de4fb0e4024161f501dbd7521ff791b4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 28 Sep 2012 10:59:58 -0400 Subject: [PATCH 118/327] Move setting ownership of /nix/store to stage-2-init This is necessary because the store might be bind-mounted read-only. --- modules/services/misc/nix-daemon.nix | 11 ++++------- modules/system/boot/stage-2-init.sh | 2 ++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index 7e52686f32f7..ba970b95bc04 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -319,10 +319,6 @@ in system.activationScripts.nix = stringAfter [ "etc" "users" ] '' - # Set up Nix. - chown root:nixbld /nix/store - chmod 1775 /nix/store - # Nix initialisation. mkdir -m 0755 -p \ /nix/var/nix/gcroots \ @@ -334,9 +330,10 @@ in /nix/var/log/nix/drvs \ /nix/var/nix/channel-cache \ /nix/var/nix/chroots - mkdir -m 1777 -p /nix/var/nix/gcroots/per-user - mkdir -m 1777 -p /nix/var/nix/profiles/per-user - mkdir -m 1777 -p /nix/var/nix/gcroots/tmp + mkdir -m 1777 -p \ + /nix/var/nix/gcroots/per-user \ + /nix/var/nix/profiles/per-user \ + /nix/var/nix/gcroots/tmp ln -sf /nix/var/nix/profiles /nix/var/nix/gcroots/ ln -sf /nix/var/nix/manifests /nix/var/nix/gcroots/ diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 3aab7a59504b..55e61ffb69a5 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -43,6 +43,8 @@ fi # Make /nix/store a read-only bind mount to enforce immutability of # the Nix store. +chown root:nixbld /nix/store +chmod 1775 /nix/store if [ -n "@readOnlyStore@" ]; then if ! mountpoint /nix/store; then mkdir -p /nix/rw-store From fabe06337ed54e72aaa2bdd5a0b40e8bda61e46b Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Sun, 23 Sep 2012 22:26:49 +0200 Subject: [PATCH 119/327] alsa.nix: initialize the sound card before restoring previously stored settings The sound card in my ThinkPad won't work unless "init" is run explicitly. --- modules/services/audio/alsa.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix index 8212b3f9fd06..fa63bc74cfc5 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 = From 03f13a49392b90cdc54d8ff057cef76bf0379913 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Wed, 26 Sep 2012 21:00:55 +0200 Subject: [PATCH 120/327] Tell sshd not to detach into the background. This makes it easier for systemd to track it and avoids race conditions such as this one: systemd[1]: PID file /run/sshd.pid not readable (yet?) after start. systemd[1]: Failed to start SSH Daemon. systemd[1]: Unit sshd.service entered failed state. systemd[1]: sshd.service holdoff time over, scheduling restart. systemd[1]: Stopping SSH Daemon... systemd[1]: Starting SSH Daemon... sshd[2315]: Server listening on 0.0.0.0 port 22. sshd[2315]: Server listening on :: port 22. sshd[2335]: error: Bind to port 22 on 0.0.0.0 failed: Address already in use. sshd[2335]: error: Bind to port 22 on :: failed: Address already in use. sshd[2335]: fatal: Cannot bind any address. systemd[1]: Started SSH Daemon. --- modules/services/networking/ssh/sshd.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 242129c355e0..373b482f85c0 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -351,10 +351,10 @@ in serviceConfig = '' ExecStart=\ - ${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} \ + ${pkgs.openssh}/sbin/sshd -D -h ${cfg.hostKeyPath} \ -f ${pkgs.writeText "sshd_config" cfg.extraConfig} Restart=always - Type=forking + Type=simple KillMode=process PIDFile=/run/sshd.pid ''; From 353522ef79ee628f46b2044085a98f59f05ee248 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 14:33:01 -0400 Subject: [PATCH 121/327] Remove JoinControllers line because upstream reverted joining cpuset --- modules/system/boot/systemd.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index d8b5ee45c7e4..4cb0e1cdf1df 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -343,7 +343,6 @@ in { source = pkgs.writeText "systemd.conf" '' [Manager] - JoinControllers=cpu,cpuacct net_cls,netprio ''; target = "systemd/system.conf"; } From 440b793a5b8fcd5250229ce9821e50a6f1065063 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 14:34:39 -0400 Subject: [PATCH 122/327] =?UTF-8?q?Remove=20=E2=80=98autocreate=E2=80=99?= =?UTF-8?q?=20FS=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Systemd creates missing mountpoints unconditionally. --- modules/tasks/filesystems.nix | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index e81ebd660044..14abe22a2da7 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -64,9 +64,6 @@ in specify a volume label (label) for file systems that support it, such as ext2/ext3 (see mke2fs -L). - - autocreate forces mountPoint to be created with - mkdir -p . ''; type = types.list types.optionSet; @@ -108,15 +105,6 @@ in description = "Options used to mount the file system."; }; - autocreate = mkOption { - default = false; - type = types.bool; - description = '' - Automatically create the mount point defined in - . - ''; - }; - autoFormat = mkOption { default = false; type = types.bool; @@ -219,12 +207,6 @@ in fi '')} - # Create missing mount points. Note that this won't work - # if the mount point is under another mount point. - ${flip concatMapStrings config.fileSystems (fs: optionalString fs.autocreate '' - mkdir -p -m 0755 '${fs.mountPoint}' - '')} - # Create missing swapfiles. # FIXME: support changing the size of existing swapfiles. ${flip concatMapStrings config.swapDevices (sw: optionalString (sw.size != null) '' From 891be375b565d05830ae03f9c5f898858f462991 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 16:27:42 -0400 Subject: [PATCH 123/327] Make unitConfig/serviceConfig attribute sets So instead of: boot.systemd.services."foo".serviceConfig = '' StartLimitInterval=10 CPUShare=500 ''; you can say: boot.systemd.services."foo".serviceConfig.StartLimitInterval = 10; boot.systemd.services."foo".serviceConfig.CPUShare = 500; This way all unit options are available and users can set/override options in configuration.nix. --- modules/services/databases/postgresql.nix | 9 ++-- modules/services/logging/syslogd.nix | 11 ++-- modules/services/misc/nix-daemon.nix | 18 +++---- modules/services/networking/dhcpcd.nix | 14 +++--- modules/services/networking/ssh/sshd.nix | 24 ++++----- modules/services/system/nscd.nix | 19 +++---- modules/system/boot/systemd-unit-options.nix | 23 ++++++--- modules/system/boot/systemd.nix | 34 +++++++++---- modules/system/upstart/upstart.nix | 53 +++++++------------- 9 files changed, 100 insertions(+), 105 deletions(-) diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index 18e72381cdce..a52d241e96c3 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -194,15 +194,14 @@ in ''; serviceConfig = - '' - # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See + { # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See # http://www.postgresql.org/docs/current/static/server-shutdown.html - KillSignal=SIGINT + KillSignal = "SIGINT"; # Give Postgres a decent amount of time to clean up after # receiving systemd's SIGINT. - TimeoutSec=60 - ''; + TimeoutSec = 60; + }; }; }; diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix index 2b7e4a8e44c7..8c815ddf25f8 100644 --- a/modules/services/logging/syslogd.nix +++ b/modules/services/logging/syslogd.nix @@ -106,8 +106,8 @@ in # FIXME: restarting syslog seems to break journal logging. boot.systemd.services.syslog = - { description = "Syslog daemon"; - + { description = "Syslog Daemon"; + requires = [ "syslog.socket" ]; wantedBy = [ "multi-user.target" "syslog.target" ]; @@ -115,11 +115,10 @@ in environment.TZ = config.time.timeZone; serviceConfig = - '' - ExecStart=${pkgs.sysklogd}/sbin/syslogd ${toString cfg.extraParams} -f ${syslogConf} -n + { ExecStart = "${pkgs.sysklogd}/sbin/syslogd ${toString cfg.extraParams} -f ${syslogConf} -n"; # Prevent syslogd output looping back through journald. - StandardOutput=null - ''; + StandardOutput = "null"; + }; }; }; diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index ba970b95bc04..718566ee5b9e 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -258,7 +258,7 @@ in ListenStream=/nix/var/nix/daemon-socket/socket ''; }; - + boot.systemd.services."nix-daemon" = { description = "Nix Daemon"; @@ -268,16 +268,14 @@ in environment = cfg.envVars; serviceConfig = - '' - ExecStart=${nix}/bin/nix-worker --daemon - KillMode=process - PIDFile=/run/sshd.pid - Nice=${toString cfg.daemonNiceLevel} - IOSchedulingPriority=${toString cfg.daemonIONiceLevel} - LimitNOFILE=4096 - ''; + { ExecStart = "${nix}/bin/nix-worker --daemon"; + KillMode = "process"; + Nice = cfg.daemonNiceLevel; + IOSchedulingPriority = cfg.daemonIONiceLevel; + LimitNOFILE = 4096; + }; }; - + nix.envVars = { NIX_CONF_DIR = "/etc/nix"; diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 6eea947f604a..cfbc7ba3679c 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -91,7 +91,7 @@ in config = mkIf config.networking.useDHCP { - jobs.dhcpcd = + boot.systemd.services.dhcpcd = { description = "DHCP Client"; wantedBy = [ "multi-user.target" ]; @@ -99,14 +99,12 @@ in path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; - daemonType = "fork"; - - exec = "dhcpcd --config ${dhcpcdConf}"; - serviceConfig = - '' - ExecReload=${dhcpcd}/sbin/dhcpcd --rebind - ''; + { Type = "forking"; + PIDFile = "/run/dhcpcd.pid"; + ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}"; + ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind"; + }; }; environment.systemPackages = [ dhcpcd ]; diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 373b482f85c0..83b7b5372ec3 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -321,11 +321,8 @@ in script = mkAuthkeyScript; - serviceConfig = - '' - Type=oneshot - RemainAfterExit=true - ''; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; }; boot.systemd.services.sshd = @@ -349,15 +346,14 @@ in ''; serviceConfig = - '' - ExecStart=\ - ${pkgs.openssh}/sbin/sshd -D -h ${cfg.hostKeyPath} \ - -f ${pkgs.writeText "sshd_config" cfg.extraConfig} - Restart=always - Type=simple - KillMode=process - PIDFile=/run/sshd.pid - ''; + { ExecStart = + "${pkgs.openssh}/sbin/sshd -D -h ${cfg.hostKeyPath} " + + "-f ${pkgs.writeText "sshd_config" cfg.extraConfig}"; + Restart = "always"; + Type = "simple"; + KillMode = "process"; + PIDFile = "/run/sshd.pid"; + }; }; networking.firewall.allowedTCPPorts = cfg.ports; diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index 54e661896d94..eecb845d5471 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -53,15 +53,16 @@ in ''; serviceConfig = - '' - ExecStart=@${pkgs.glibc}/sbin/nscd nscd -f ${./nscd.conf} - 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 - ''; + { ExecStart = "@${pkgs.glibc}/sbin/nscd nscd -f ${./nscd.conf}"; + Type = "forking"; + PIDFile = "/run/nscd/nscd.pid"; + Restart = "always"; + ExecReload = + [ "${pkgs.glibc}/sbin/nscd --invalidate passwd" + "${pkgs.glibc}/sbin/nscd --invalidate group" + "${pkgs.glibc}/sbin/nscd --invalidate hosts" + ]; + }; }; }; diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index f56ee4fc0d34..c5fa23b36bb0 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -81,21 +81,28 @@ with pkgs.lib; }; unitConfig = mkOption { - default = ""; - type = types.string; + default = {}; + example = { RequiresMountsFor = "/data"; }; + type = types.attrs; description = '' - Contents of the [Unit] section of the unit. - See systemd.unit + Each attribute in this set specifies an option in the + [Unit] section of the unit. See + systemd.unit 5 for details. ''; }; serviceConfig = mkOption { - default = ""; - type = types.string; + default = {}; + example = + { StartLimitInterval = 10; + RestartSec = 5; + }; + type = types.attrs; description = '' - Contents of the [Service] section of the unit. - See systemd.service + Each attribute in this set specifies an option in the + [Service] section of the unit. See + systemd.service 5 for details. ''; }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 4cb0e1cdf1df..a7a7729bb8b9 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -177,24 +177,38 @@ let pkgs.gnused systemd ]; + unitConfig = + { Requires = concatStringsSep " " config.requires; + Wants = concatStringsSep " " config.wants; + After = concatStringsSep " " config.after; + Before = concatStringsSep " " config.before; + PartOf = concatStringsSep " " config.partOf; + } // optionalAttrs (config.description != "") + { Description = config.description; + }; }; }; + toOption = x: + if x == true then "true" + else if x == false then "false" + else toString x; + + attrsToSection = as: + concatStrings (concatLists (mapAttrsToList (name: value: + map (x: '' + ${name}=${toOption x} + '') + (if isList value then value else [value])) + as)); + serviceToUnit = name: def: { inherit (def) wantedBy; text = '' [Unit] - ${optionalString (def.description != "") '' - Description=${def.description} - ''} - Requires=${concatStringsSep " " def.requires} - Wants=${concatStringsSep " " def.wants} - After=${concatStringsSep " " def.after} - Before=${concatStringsSep " " def.before} - PartOf=${concatStringsSep " " def.partOf} - ${def.unitConfig} + ${attrsToSection def.unitConfig} [Service] Environment=PATH=${def.path} @@ -215,7 +229,7 @@ let ''} ''} - ${def.serviceConfig} + ${attrsToSection def.serviceConfig} ''; }; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index fbbbf72e027e..a32bca8ddd76 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -54,7 +54,7 @@ let ''; in { - inherit (job) description requires wants before partOf environment path restartIfChanged; + inherit (job) description requires wants before partOf environment path restartIfChanged unitConfig; after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else @@ -72,40 +72,23 @@ let [ "multi-user.target" ]) ++ job.wantedBy; serviceConfig = - '' - ${job.serviceConfig} - - ${optionalString (job.preStart != "" && (job.script != "" || job.exec != "")) '' - ExecStartPre=${preStartScript} - ''} - - ${optionalString (job.preStart != "" && job.script == "" && job.exec == "") '' - ExecStart=${preStartScript} - ''} - - ${optionalString (job.script != "" || job.exec != "") '' - ExecStart=${startScript} - ''} - - ${optionalString (job.postStart != "") '' - ExecStartPost=${postStartScript} - ''} - - ${optionalString (job.preStop != "") '' - ExecStop=${preStopScript} - ''} - - ${optionalString (job.postStop != "") '' - ExecStopPost=${postStopScript} - ''} - - ${if job.script == "" && job.exec == "" then "Type=oneshot\nRemainAfterExit=true" else - if job.daemonType == "fork" then "Type=forking\nGuessMainPID=true" else - if job.daemonType == "none" then "" else - throw "invalid daemon type `${job.daemonType}'"} - - ${optionalString (!job.task && job.respawn) "Restart=always"} - ''; + job.serviceConfig + // optionalAttrs (job.preStart != "" && (job.script != "" || job.exec != "")) + { ExecStartPre = preStartScript; } + // optionalAttrs (job.script != "" || job.exec != "") + { ExecStart = startScript; } + // optionalAttrs (job.postStart != "") + { ExecStartPost = postStartScript; } + // optionalAttrs (job.preStop != "") + { ExecStop = preStopScript; } + // optionalAttrs (job.postStop != "") + { ExecStopPost = postStopScript; } + // (if job.script == "" && job.exec == "" then { Type = "oneshot"; RemainAfterExit = true; } else + if job.daemonType == "fork" then { Type = "forking"; GuessMainPID = true; } else + if job.daemonType == "none" then { } else + throw "invalid daemon type `${job.daemonType}'") + // optionalAttrs (!job.task && job.respawn) + { Restart = "always"; }; }; From 13d747c11a6935272a2ebdb861daefbdfde47d15 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 16:45:49 -0400 Subject: [PATCH 124/327] Support postStart scripts in service units --- modules/system/boot/systemd-unit-options.nix | 9 +++++++++ modules/system/boot/systemd.nix | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index c5fa23b36bb0..95506712caca 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -122,6 +122,15 @@ with pkgs.lib; ''; }; + postStart = mkOption { + type = types.string; + default = ""; + description = '' + Shell commands executed after the service's main process + is started. + ''; + }; + restartIfChanged = mkOption { type = types.bool; default = true; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index a7a7729bb8b9..bb2ea087c21c 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -229,6 +229,13 @@ let ''} ''} + ${optionalString (def.postStart != "") '' + ExecStartPost=${makeJobScript "${name}-poststart.sh" '' + #! ${pkgs.stdenv.shell} -e + ${def.postStart} + ''} + ''} + ${attrsToSection def.serviceConfig} ''; }; From 5cf702e1c130483caa13e3bb34df0a715679fd14 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 16:47:54 -0400 Subject: [PATCH 125/327] postgresql.nix: Use User/Group instead of su --- modules/services/databases/postgresql.nix | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index a52d241e96c3..caf9a586eb18 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -22,8 +22,6 @@ let postgresql = postgresqlAndPlugins cfg.package; - run = "su -s ${pkgs.stdenv.shell} postgres"; - flags = optional cfg.enableTCPIP "-i"; # The main PostgreSQL configuration file. @@ -157,7 +155,7 @@ in environment.systemPackages = [postgresql]; - jobs.postgresql = + boot.systemd.services.postgresql = { description = "PostgreSQL server"; wantedBy = [ "multi-user.target" ]; @@ -176,14 +174,27 @@ in if ! test -e ${cfg.dataDir}; then mkdir -m 0700 -p ${cfg.dataDir} chown -R postgres ${cfg.dataDir} - ${run} -c 'initdb -U root' + su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root' rm -f ${cfg.dataDir}/*.conf fi ln -sfn ${configFile} ${cfg.dataDir}/postgresql.conf ''; # */ - exec = "${run} -c 'postgres ${toString flags}'"; + serviceConfig = + { ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}"; + User = "postgres"; + Group = "postgres"; + PermissionsStartOnly = true; + + # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See + # http://www.postgresql.org/docs/current/static/server-shutdown.html + KillSignal = "SIGINT"; + + # Give Postgres a decent amount of time to clean up after + # receiving systemd's SIGINT. + TimeoutSec = 60; + }; # Wait for PostgreSQL to be ready to accept connections. postStart = @@ -192,16 +203,6 @@ in sleep 1 done ''; - - serviceConfig = - { # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See - # http://www.postgresql.org/docs/current/static/server-shutdown.html - KillSignal = "SIGINT"; - - # Give Postgres a decent amount of time to clean up after - # receiving systemd's SIGINT. - TimeoutSec = 60; - }; }; }; From 2326c6da2bd80e6d66846dd814ebb6449469e0c6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 16:53:13 -0400 Subject: [PATCH 126/327] postgresql.nix: Depend on the filesystem containing the database --- modules/services/databases/postgresql.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index caf9a586eb18..66bb722782a9 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -203,6 +203,8 @@ in sleep 1 done ''; + + unitConfig.RequiresMountsFor = "${cfg.dataDir}"; }; }; From 990ec8cc4e0ca8c609b6097eafd3aef31f9c7fb8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 17:32:03 -0400 Subject: [PATCH 127/327] Decrease PostgreSQL start check interval --- modules/services/databases/postgresql.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index 66bb722782a9..c34ae9037f26 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -156,7 +156,7 @@ in environment.systemPackages = [postgresql]; boot.systemd.services.postgresql = - { description = "PostgreSQL server"; + { description = "PostgreSQL"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "fs.target" ]; @@ -200,7 +200,7 @@ in postStart = '' while ! psql postgres -c ""; do - sleep 1 + sleep 0.1 done ''; From ca13a913d9f128616b79df971d76e5dd12132a53 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 18:20:22 -0400 Subject: [PATCH 128/327] Oops, lost some code --- modules/system/upstart/upstart.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index a32bca8ddd76..57a532837f3a 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -75,6 +75,8 @@ let job.serviceConfig // optionalAttrs (job.preStart != "" && (job.script != "" || job.exec != "")) { ExecStartPre = preStartScript; } + // optionalAttrs (job.preStart != "" && job.script == "" && job.exec == "") + { ExecStart = preStartScript; } // optionalAttrs (job.script != "" || job.exec != "") { ExecStart = startScript; } // optionalAttrs (job.postStart != "") From 2cf5e3cb6640ae634c5d7060d0ff6fa3b647ce70 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 1 Oct 2012 18:58:11 -0400 Subject: [PATCH 129/327] =?UTF-8?q?Add=20options=20=E2=80=98boot.systemd.t?= =?UTF-8?q?argets=E2=80=99=20and=20=E2=80=98boot.systemd.sockets=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/services/misc/nix-daemon.nix | 16 ++---- modules/system/boot/systemd-unit-options.nix | 32 +++++++----- modules/system/boot/systemd.nix | 54 ++++++++++++++++++-- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index 718566ee5b9e..eeb26ee5e15f 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -246,17 +246,11 @@ in target = "nix.machines"; }; - boot.systemd.units."nix-daemon.socket" = - { wantedBy = [ "sockets.target" ]; - text = - '' - [Unit] - Description=Nix Daemon Socket - Before=multi-user.target - - [Socket] - ListenStream=/nix/var/nix/daemon-socket/socket - ''; + boot.systemd.sockets."nix-daemon" = + { description = "Nix Daemon Socket"; + wantedBy = [ "sockets.target" ]; + before = [ "multi-user.target" ]; + socketConfig.ListenStream = "/nix/var/nix/daemon-socket/socket"; }; boot.systemd.services."nix-daemon" = diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 95506712caca..276197d24d8f 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -2,9 +2,9 @@ with pkgs.lib; -{ +rec { - serviceOptions = { + unitOptions = { description = mkOption { default = ""; @@ -62,6 +62,22 @@ with pkgs.lib; description = "Units that want (i.e. depend on) this unit."; }; + unitConfig = mkOption { + default = {}; + example = { RequiresMountsFor = "/data"; }; + type = types.attrs; + description = '' + Each attribute in this set specifies an option in the + [Unit] section of the unit. See + systemd.unit + 5 for details. + ''; + }; + + }; + + serviceOptions = unitOptions // { + environment = mkOption { default = {}; type = types.attrs; @@ -80,18 +96,6 @@ with pkgs.lib; ''; }; - unitConfig = mkOption { - default = {}; - example = { RequiresMountsFor = "/data"; }; - type = types.attrs; - description = '' - Each attribute in this set specifies an option in the - [Unit] section of the unit. See - systemd.unit - 5 for details. - ''; - }; - serviceConfig = mkOption { default = {}; example = diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index bb2ea087c21c..23751e2104aa 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -202,9 +202,17 @@ let (if isList value then value else [value])) as)); + targetToUnit = name: def: + { inherit (def) wantedBy; + text = + '' + [Unit] + ${attrsToSection def.unitConfig} + ''; + }; + serviceToUnit = name: def: { inherit (def) wantedBy; - text = '' [Unit] @@ -240,6 +248,18 @@ let ''; }; + socketToUnit = name: def: + { inherit (def) wantedBy; + text = + '' + [Unit] + ${attrsToSection def.unitConfig} + + [Socket] + ${attrsToSection def.socketConfig} + ''; + }; + nixosUnits = mapAttrsToList makeUnit cfg.units; units = pkgs.runCommand "units" { preferLocalBuild = true; } @@ -319,11 +339,37 @@ in description = "Packages providing systemd units."; }; + boot.systemd.targets = mkOption { + default = {}; + type = types.attrsOf types.optionSet; + options = unitOptions; + description = "Definition of systemd target units."; + }; + boot.systemd.services = mkOption { default = {}; type = types.attrsOf types.optionSet; options = [ serviceOptions serviceConfig ]; - description = "Definition of systemd services."; + description = "Definition of systemd service units."; + }; + + boot.systemd.sockets = mkOption { + default = {}; + type = types.attrsOf types.optionSet; + options = unitOptions // { + socketConfig = mkOption { + default = {}; + example = { ListenStream = "/run/my-socket"; }; + type = types.attrs; + description = '' + Each attribute in this set specifies an option in the + [Socket] section of the unit. See + systemd.socket + 5 for details. + ''; + }; + }; + description = "Definition of systemd socket units."; }; boot.systemd.defaultUnit = mkOption { @@ -385,7 +431,9 @@ in boot.systemd.units = { "rescue.service".text = rescueService; } // { "fs.target" = { text = fsTarget; wantedBy = [ "multi-user.target" ]; }; } - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services; + // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets; }; From 793297861726a6c7e589d3ad5d2ab063baaec987 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 2 Oct 2012 10:26:55 -0400 Subject: [PATCH 130/327] Fix Upstart compatibility jobs that depend on "stopped udevtrigger" It's not enough to say "after udev-settle.service" since udev-settle.service is not wanted/required anywhere - we need to say "wants udev-settle.service" as well. This should fix problems with ALSA and X11 initialisation that people have been seeing. --- modules/system/upstart/upstart.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 57a532837f3a..4fbf683c4403 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -54,7 +54,7 @@ let ''; in { - inherit (job) description requires wants before partOf environment path restartIfChanged unitConfig; + inherit (job) description wants before partOf environment path restartIfChanged unitConfig; after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else @@ -66,6 +66,10 @@ let builtins.trace "Warning: job ‘${job.name}’ has unknown startOn value ‘${job.startOn}’." [] ) ++ job.after; + requires = + (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else [] + ) ++ job.requires; + wantedBy = (if job.startOn == "" then [] else if job.startOn == "ip-up" then [ "ip-up.target" ] else From 2044ae785db87ac7adbd1b0b749f106210213c37 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 2 Oct 2012 10:32:29 -0400 Subject: [PATCH 131/327] Use "wants" instead of "requires" --- modules/system/upstart/upstart.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 4fbf683c4403..d6362a0e4ca0 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -54,7 +54,7 @@ let ''; in { - inherit (job) description wants before partOf environment path restartIfChanged unitConfig; + inherit (job) description requires before partOf environment path restartIfChanged unitConfig; after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else @@ -66,9 +66,9 @@ let builtins.trace "Warning: job ‘${job.name}’ has unknown startOn value ‘${job.startOn}’." [] ) ++ job.after; - requires = + wants = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else [] - ) ++ job.requires; + ) ++ job.wants; wantedBy = (if job.startOn == "" then [] else From 666620cdd50a1af57aa9b40faea2bcd828b3281c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 2 Oct 2012 10:32:56 -0400 Subject: [PATCH 132/327] =?UTF-8?q?Use=20=E2=80=98mountpoint=20-q=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/system/boot/stage-2-init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 55e61ffb69a5..f54404ddccea 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -46,7 +46,7 @@ fi chown root:nixbld /nix/store chmod 1775 /nix/store if [ -n "@readOnlyStore@" ]; then - if ! mountpoint /nix/store; then + if ! mountpoint -q /nix/store; then mkdir -p /nix/rw-store mount --bind /nix/store /nix/store mount -o remount,ro,bind /nix/store From 02624758b192c33de951b208a7b159dd6c2856e4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 2 Oct 2012 11:09:54 -0400 Subject: [PATCH 133/327] Use udev to restore ALSA volume settings Alsa-utils provides a udev rule to restore volume settings, so use that instead of restoring them from a systemd service. The "alsa-store" service saves the settings on shutdown. --- modules/services/audio/alsa.nix | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix index fa63bc74cfc5..ff08f21a4857 100644 --- a/modules/services/audio/alsa.nix +++ b/modules/services/audio/alsa.nix @@ -45,29 +45,19 @@ in environment.systemPackages = [ alsaUtils ]; + # ALSA provides a udev rule for restoring volume settings. + services.udev.packages = [ alsaUtils ]; + boot.kernelModules = optional config.sound.enableOSSEmulation "snd_pcm_oss"; - jobs.alsa = - { description = "ALSA Volume Settings"; - - startOn = "stopped udevtrigger"; - - preStart = - '' - mkdir -m 0755 -p $(dirname ${soundState}) - - # Try to restore the sound state. - ${alsaUtils}/sbin/alsactl --ignore init || true - ${alsaUtils}/sbin/alsactl --ignore -f ${soundState} restore || true - ''; - - postStop = - '' - # Save the sound state. - ${alsaUtils}/sbin/alsactl --ignore -f ${soundState} store - ''; + boot.systemd.services."alsa-store" = + { description = "Store Sound Card State"; + wantedBy = [ "shutdown.target" ]; + before = [ "shutdown.target" ]; + unitConfig.DefaultDependencies = "no"; + serviceConfig.Type = "oneshot"; + serviceConfig.ExecStart = "${alsaUtils}/sbin/alsactl store --ignore"; }; - }; } From 13a5ebad32b269e11feb2e039fad26f63b2d2679 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 12:34:44 -0400 Subject: [PATCH 134/327] Update some tests for systemd --- lib/test-driver/Machine.pm | 42 +++++++++++++++++++++++++++----------- tests/login.nix | 32 ++++++++++++++--------------- tests/misc.nix | 2 +- tests/openssh.nix | 2 +- tests/subversion.nix | 2 +- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index 76c736b609dc..c7e0bc102f18 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -352,18 +352,39 @@ sub mustFail { } -# Wait for an Upstart job to reach the "running" state. -sub waitForJob { - my ($self, $jobName) = @_; - $self->nest("waiting for job ‘$jobName’", sub { +sub getUnitInfo { + my ($self, $unit) = @_; + my ($status, $lines) = $self->execute("systemctl --no-pager show '$unit'"); + return undef if $status != 0; + my $info = {}; + foreach my $line (split '\n', $lines) { + $line =~ /^([^=]+)=(.*)$/ or next; + $info->{$1} = $2; + } + return $info; +} + + +# Wait for a systemd unit to reach the "active" state. +sub waitForUnit { + my ($self, $unit) = @_; + $self->nest("waiting for unit ‘$unit’", sub { retry sub { - my ($status, $out) = $self->execute("initctl status $jobName"); - return 1 if $out =~ /start\/running/; + my $info = $self->getUnitInfo($unit); + my $state = $info->{ActiveState}; + die "unit ‘$unit’ reached state ‘$state’\n" if $state eq "failed"; + return 1 if $state eq "active"; }; }); } +sub waitForJob { + my ($self, $jobName) = @_; + return $self->waitForUnit($jobName . ".service"); +} + + # Wait until the specified file exists. sub waitForFile { my ($self, $fileName) = @_; @@ -377,16 +398,13 @@ sub waitForFile { sub startJob { my ($self, $jobName) = @_; - $self->execute("initctl start $jobName"); - my ($status, $out) = $self->execute("initctl status $jobName"); - die "failed to start $jobName" unless $out =~ /start\/running/; + $self->execute("systemctl stop $jobName.service"); + # FIXME: check result } sub stopJob { my ($self, $jobName) = @_; - $self->execute("initctl stop $jobName"); - my ($status, $out) = $self->execute("initctl status $jobName"); - die "failed to stop $jobName" unless $out =~ /stop\/waiting/; + $self->execute("systemctl stop $jobName.service"); } diff --git a/tests/login.nix b/tests/login.nix index 90987782f8ca..cdd6414744a6 100644 --- a/tests/login.nix +++ b/tests/login.nix @@ -6,14 +6,23 @@ testScript = '' + $machine->waitForUnit("default.target"); + $machine->screenshot("postboot"); + subtest "create user", sub { $machine->succeed("useradd -m alice"); $machine->succeed("(echo foobar; echo foobar) | passwd alice"); }; + # Check whether switching VTs works. + subtest "virtual console switching", sub { + $machine->sendKeys("alt-f2"); + $machine->waitUntilSucceeds("[ \$(fgconsole) = 2 ]"); + $machine->waitForUnit('getty@tty2.service'); + }; + # Log in as alice on a virtual console. subtest "virtual console login", sub { - $machine->waitForJob("tty1"); $machine->sleep(2); # urgh: wait for username prompt $machine->sendChars("alice\n"); $machine->waitUntilSucceeds("pgrep login"); @@ -24,28 +33,19 @@ $machine->waitForFile("/home/alice/done"); }; - # Check whether switching VTs works. - subtest "virtual console switching", sub { - $machine->sendKeys("alt-f10"); - $machine->waitUntilSucceeds("[ \$(fgconsole) = 10 ]"); - $machine->sleep(2); # allow fbcondecor to catch up (not important) - $machine->screenshot("syslog"); - }; - - # Check whether ConsoleKit/udev gives and removes device - # ownership as needed. + # Check whether systemd gives and removes device ownership as + # needed. subtest "device permissions", sub { + $machine->succeed("getfacl /dev/snd/timer | grep -q alice"); + $machine->sendKeys("alt-f1"); + $machine->waitUntilSucceeds("[ \$(fgconsole) = 1 ]"); $machine->fail("getfacl /dev/snd/timer | grep -q alice"); - $machine->succeed("chvt 1"); - $machine->waitUntilSucceeds("getfacl /dev/snd/timer | grep -q alice"); $machine->succeed("chvt 2"); - $machine->sleep(2); # urgh - $machine->fail("getfacl /dev/snd/timer | grep -q alice"); + $machine->waitUntilSucceeds("getfacl /dev/snd/timer | grep -q alice"); }; # Log out. subtest "virtual console logout", sub { - $machine->succeed("chvt 1"); $machine->sendChars("exit\n"); $machine->waitUntilFails("pgrep -u alice bash"); $machine->screenshot("mingetty"); diff --git a/tests/misc.nix b/tests/misc.nix index 8501d6a09796..9f85877e8bbd 100644 --- a/tests/misc.nix +++ b/tests/misc.nix @@ -30,7 +30,7 @@ # Test that the swap file got created. subtest "swapfile", sub { - $machine->waitUntilSucceeds("cat /proc/swaps | grep /root/swapfile"); + $machine->waitForUnit("root-swapfile.swap"); $machine->succeed("ls -l /root/swapfile | grep 134217728"); }; ''; diff --git a/tests/openssh.nix b/tests/openssh.nix index 5818c9d6cebb..7a3d789327aa 100644 --- a/tests/openssh.nix +++ b/tests/openssh.nix @@ -30,6 +30,6 @@ $client->mustSucceed("chmod 600 /root/.ssh/id_dsa"); $client->waitForJob("network-interfaces"); - $client->mustSucceed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world'"); + $client->mustSucceed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2"); ''; } diff --git a/tests/subversion.nix b/tests/subversion.nix index fb8bba938062..dc4fe9da4700 100644 --- a/tests/subversion.nix +++ b/tests/subversion.nix @@ -41,7 +41,7 @@ in services.httpd.enable = true; services.httpd.adminAddr = "e.dolstra@tudelft.nl"; services.httpd.extraSubservices = - [ { serviceType = "subversion"; + [ { function = import ; urlPrefix = ""; dataDir = "/data/subversion"; userCreationDomain = "192.168.0.0/16"; From 8dc4f2c3bee30b079c82cce6ddc9f8df6d61ef91 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 15:27:31 -0400 Subject: [PATCH 135/327] Fix the rogue service for systemd --- modules/services/misc/rogue.nix | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/services/misc/rogue.nix b/modules/services/misc/rogue.nix index c313de956fca..059b39cad5e8 100644 --- a/modules/services/misc/rogue.nix +++ b/modules/services/misc/rogue.nix @@ -40,14 +40,17 @@ in boot.extraTTYs = [ cfg.tty ]; - jobs.rogue = + boot.systemd.services.rogue = { description = "Rogue dungeon crawling game"; - - startOn = "started udev"; - - extraConfig = "chdir /root"; - - exec = "${pkgs.rogue}/bin/rogue < /dev/${cfg.tty} > /dev/${cfg.tty} 2>&1"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + { ExecStart = "${pkgs.rogue}/bin/rogue"; + StandardInput = "tty"; + StandardOutput = "tty"; + TTYPath = "/dev/${cfg.tty}"; + TTYReset = true; + TTYVTDisallocate = true; + }; }; services.ttyBackgrounds.specificThemes = singleton From 74be2d9707248ba4c79d86e64f0f5f13868891fd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 16:14:44 -0400 Subject: [PATCH 136/327] ISO image: Fix graphical GRUB menu --- modules/installer/cd-dvd/iso-image.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix index 4f87f29f2e92..be4777356e48 100644 --- a/modules/installer/cd-dvd/iso-image.nix +++ b/modules/installer/cd-dvd/iso-image.nix @@ -87,7 +87,7 @@ let # The Grub image. grubImage = pkgs.runCommand "grub_eltorito" {} '' - ${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain vbe png jpeg echo test normal + ${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out ''; # */ From 6c6134c2d2f2d5f7a37d99c4ff54ae2a29ec1951 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 16:15:10 -0400 Subject: [PATCH 137/327] Fix the manual service on the installation CD --- modules/services/misc/nixos-manual.nix | 26 +++++++++++++------------- modules/services/misc/rogue.nix | 1 + 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/services/misc/nixos-manual.nix b/modules/services/misc/nixos-manual.nix index 84c39101bb6c..2e98d50b0ced 100644 --- a/modules/services/misc/nixos-manual.nix +++ b/modules/services/misc/nixos-manual.nix @@ -73,19 +73,19 @@ in boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"]; - jobs = mkIf cfg.showManual - { nixosManual = - { name = "nixos-manual"; - - description = "NixOS manual"; - - startOn = "started udev"; - - exec = - '' - ${cfg.browser} ${manual.manual}/share/doc/nixos/manual.html \ - < /dev/tty${toString cfg.ttyNumber} > /dev/tty${toString cfg.ttyNumber} 2>&1 - ''; + boot.systemd.services = optionalAttrs cfg.showManual + { "nixos-manual" = + { description = "NixOS Manual"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + { ExecStart = "${cfg.browser} ${manual.manual}/share/doc/nixos/manual.html"; + StandardInput = "tty"; + StandardOutput = "tty"; + TTYPath = "/dev/tty${cfg.ttyNumber}"; + TTYReset = true; + TTYVTDisallocate = true; + Restart = "always"; + }; }; }; diff --git a/modules/services/misc/rogue.nix b/modules/services/misc/rogue.nix index 059b39cad5e8..12d61a8ea9fd 100644 --- a/modules/services/misc/rogue.nix +++ b/modules/services/misc/rogue.nix @@ -50,6 +50,7 @@ in TTYPath = "/dev/${cfg.tty}"; TTYReset = true; TTYVTDisallocate = true; + Restart = "always"; }; }; From fdea3ac3d26e0131b07f59d656bb5433c2adab0f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 16:15:30 -0400 Subject: [PATCH 138/327] stage-2-init: Don't rely on groups being initialised --- modules/system/boot/stage-2-init.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index f54404ddccea..8f1184a5eb36 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -42,8 +42,9 @@ fi # Make /nix/store a read-only bind mount to enforce immutability of -# the Nix store. -chown root:nixbld /nix/store +# the Nix store. Note that we can't use "chown root:nixbld" here +# because users/groups might not exist yet. +chown 0:30000 /nix/store chmod 1775 /nix/store if [ -n "@readOnlyStore@" ]; then if ! mountpoint -q /nix/store; then From 38229da94069b42d1cc95ab715f6046d9fbcbe07 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 16:38:31 -0400 Subject: [PATCH 139/327] upower: Add glib to $PATH The upower daemon needs the gdbus command (which is weird given that upower links against dbus_glib, but ah well...). This fixes suspend in KDE with systemd. --- modules/services/hardware/upower.nix | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/services/hardware/upower.nix b/modules/services/hardware/upower.nix index d025276ea8e9..7cd5cd3ddf88 100644 --- a/modules/services/hardware/upower.nix +++ b/modules/services/hardware/upower.nix @@ -35,7 +35,15 @@ with pkgs.lib; services.udev.packages = [ pkgs.upower ]; - boot.systemd.packages = [ pkgs.upower ]; + boot.systemd.services.upower = + { description = "Power Management Daemon"; + path = [ pkgs.glib ]; # needed for gdbus + serviceConfig = + { Type = "dbus"; + BusName = "org.freedesktop.UPower"; + ExecStart = "@${pkgs.upower}/libexec/upowerd upowerd"; + }; + }; system.activationScripts.upower = '' From c6d12257f1c5ca564dbf71990daa62126e6a17eb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 17:57:10 -0400 Subject: [PATCH 140/327] systemd: Run the powerManagement.* hooks on suspend/resume Also, drop pm-utils. Systemd now takes care of suspend/resume. --- modules/config/power-management.nix | 63 ++++++++++++++++++----------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/modules/config/power-management.nix b/modules/config/power-management.nix index c8e1a62749b8..18bb4fb4d421 100644 --- a/modules/config/power-management.nix +++ b/modules/config/power-management.nix @@ -6,21 +6,6 @@ let cfg = config.powerManagement; - sleepHook = pkgs.writeScript "sleep-hook.sh" - '' - #! ${pkgs.stdenv.shell} - action="$1" - case "$action" in - hibernate|suspend) - ${cfg.powerDownCommands} - ;; - thaw|resume) - ${cfg.resumeCommands} - ${cfg.powerUpCommands} - ;; - esac - ''; - in { @@ -79,13 +64,6 @@ in # Enable the ACPI daemon. Not sure whether this is essential. services.acpid.enable = true; - environment.systemPackages = [ pkgs.pmutils ]; - - environment.etc = singleton - { source = sleepHook; - target = "pm/sleep.d/00sleep-hook"; - }; - boot.kernelModules = [ "acpi_cpufreq" "cpufreq_performance" "cpufreq_powersave" "cpufreq_ondemand" "cpufreq_conservative" @@ -93,7 +71,46 @@ in powerManagement.cpuFreqGovernor = mkDefault "ondemand"; powerManagement.scsiLinkPolicy = mkDefault "min_power"; - + + # Service executed before suspending/hibernating. + boot.systemd.services."pre-sleep" = + { description = "Pre-Sleep Actions"; + wantedBy = [ "sleep.target" ]; + before = [ "sleep.target" ]; + script = + '' + ${cfg.powerDownCommands} + ''; + serviceConfig.Type = "oneshot"; + }; + + # Service executed before suspending/hibernating. There doesn't + # seem to be a good way to hook in a service to be executed after + # both suspend *and* hibernate, so have a separate one for each. + boot.systemd.services."post-suspend" = + { description = "Post-Suspend Actions"; + wantedBy = [ "suspend.target" ]; + after = [ "systemd-suspend.service" ]; + script = + '' + ${cfg.resumeCommands} + ${cfg.powerUpCommands} + ''; + serviceConfig.Type = "oneshot"; + }; + + boot.systemd.services."post-hibernate" = + { description = "Post-Hibernate Actions"; + wantedBy = [ "hibernate.target" ]; + after = [ "systemd-hibernate.service" ]; + script = + '' + ${cfg.resumeCommands} + ${cfg.powerUpCommands} + ''; + serviceConfig.Type = "oneshot"; + }; + }; } From db2a4d144eab5917b95550ca727351cc9bd2c55a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 21:44:24 -0400 Subject: [PATCH 141/327] xsession: Set a inhibitor to prevent systemd from handling the power button and lid --- modules/services/x11/display-managers/default.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/services/x11/display-managers/default.nix b/modules/services/x11/display-managers/default.nix index 528b3a6f7276..b94278d0b0d2 100644 --- a/modules/services/x11/display-managers/default.nix +++ b/modules/services/x11/display-managers/default.nix @@ -31,6 +31,13 @@ let exec > ~/.xsession-errors 2>&1 ''} + # Stop systemd from handling the power button and lid switch, + # since presumably the desktop environment will handle these. + if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then + export _INHIBITION_LOCK_TAKEN=1 + ${config.system.build.systemd}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType" + fi + ${optionalString cfg.startOpenSSHAgent '' if test -z "$SSH_AUTH_SOCK"; then # Restart this script as a child of the SSH agent. (It is From 52483c36bb6023cf4c0ff0da559b5d4b0add7d2f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 21:44:45 -0400 Subject: [PATCH 142/327] Lowercase debug output --- modules/system/etc/make-etc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/system/etc/make-etc.sh b/modules/system/etc/make-etc.sh index 6075bdb26735..7cf68db9ddce 100644 --- a/modules/system/etc/make-etc.sh +++ b/modules/system/etc/make-etc.sh @@ -26,9 +26,9 @@ for ((i = 0; i < ${#targets_[@]}; i++)); do if ! [ -e $out/etc/$target ]; then ln -s $source $out/etc/$target else - echo "Duplicate entry $target -> $source" + echo "duplicate entry $target -> $source" if test "$(readlink $out/etc/$target)" != "$source"; then - echo "Mismatched duplicate entry $(readlink $out/etc/$target) <-> $source" + echo "mismatched duplicate entry $(readlink $out/etc/$target) <-> $source" exit 1 fi fi From 7d26dde69a48b2e3b15dd25b55cbc579a68e9f4e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 21:58:20 -0400 Subject: [PATCH 143/327] Oops, systemd-inhibit should be exec'ed --- modules/services/x11/display-managers/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/x11/display-managers/default.nix b/modules/services/x11/display-managers/default.nix index b94278d0b0d2..86a636c27c70 100644 --- a/modules/services/x11/display-managers/default.nix +++ b/modules/services/x11/display-managers/default.nix @@ -35,7 +35,7 @@ let # since presumably the desktop environment will handle these. if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then export _INHIBITION_LOCK_TAKEN=1 - ${config.system.build.systemd}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType" + exec ${config.system.build.systemd}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType" fi ${optionalString cfg.startOpenSSHAgent '' From 9b431cb24e3de6a601d60b2598014897177f5ab0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 21:58:40 -0400 Subject: [PATCH 144/327] upower: Work around the daemon getting stuck after a suspend --- modules/services/hardware/upower.nix | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/services/hardware/upower.nix b/modules/services/hardware/upower.nix index 7cd5cd3ddf88..58f2610ce067 100644 --- a/modules/services/hardware/upower.nix +++ b/modules/services/hardware/upower.nix @@ -50,6 +50,15 @@ with pkgs.lib; mkdir -m 0755 -p /var/lib/upower ''; + # The upower daemon seems to get stuck after doing a suspend + # (i.e. subsequent suspend requests will say "Sleep has already + # been requested and is pending"). So as a workaround, restart + # the daemon. + powerManagement.resumeCommands = + '' + ${config.system.build.systemd}/bin/systemctl try-restart upower + ''; + }; } From 8f4d8cf6202ffa8069e4a4a984e904d32b74efa8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 22:10:35 -0400 Subject: [PATCH 145/327] Enable the power management module by default After all, we don't want NixOS machines to contribute to global warming more than necessary! --- modules/config/power-management.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/config/power-management.nix b/modules/config/power-management.nix index 18bb4fb4d421..c48451bd5f5c 100644 --- a/modules/config/power-management.nix +++ b/modules/config/power-management.nix @@ -17,7 +17,7 @@ in powerManagement = { enable = mkOption { - default = false; + default = true; description = '' Whether to enable power management. This includes support From 5d9b3ed12b48bad5bf00ed183bde52a102464ca8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 23:25:11 -0400 Subject: [PATCH 146/327] scsi-link-pm: Don't fail if there are no matching SCSI hosts --- modules/tasks/scsi-link-power-management.nix | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/tasks/scsi-link-power-management.nix b/modules/tasks/scsi-link-power-management.nix index 263acb8f3214..13ffbc7a51a4 100644 --- a/modules/tasks/scsi-link-power-management.nix +++ b/modules/tasks/scsi-link-power-management.nix @@ -6,7 +6,7 @@ with pkgs.lib; ###### interface options = { - + powerManagement.scsiLinkPolicy = mkOption { default = ""; example = "min_power"; @@ -16,7 +16,7 @@ with pkgs.lib; the kernel configures "max_performance". ''; }; - + }; @@ -25,19 +25,20 @@ with pkgs.lib; config = mkIf (config.powerManagement.scsiLinkPolicy != "") { jobs."scsi-link-pm" = - { description = "Set SCSI link power management policy"; + { description = "SCSI Link Power Management Policy"; - startOn = "started udev"; + startOn = "stopped udevtrigger"; task = true; script = '' + shopt -s nullglob for x in /sys/class/scsi_host/host*/link_power_management_policy; do echo ${config.powerManagement.scsiLinkPolicy} > $x done ''; }; - + }; } From 0ddd147cfc26d84cb2ff70c3de20c5ece0d2abc2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 23:25:33 -0400 Subject: [PATCH 147/327] headless.nix: Mountall is gone --- modules/profiles/headless.nix | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/modules/profiles/headless.nix b/modules/profiles/headless.nix index 204980e9211b..ac0c4059634e 100644 --- a/modules/profiles/headless.nix +++ b/modules/profiles/headless.nix @@ -14,15 +14,4 @@ with pkgs.lib; # Since we can't manually respond to a panic, just reboot. boot.kernelParams = [ "panic=1" "stage1panic=1" ]; - - # Since we don't have an (interactive) console, disable the - # emergency shell (started if mountall fails). - jobs."mount-failed".script = mkOverride 50 - '' - ${pkgs.utillinux}/bin/logger -p user.emerg -t mountall "filesystem ‘$DEVICE’ could not be mounted on ‘$MOUNTPOINT’" - ''; - - # Likewise, redirect mountall output from the console to the default - # Upstart job log file. - jobs."mountall".console = mkOverride 50 ""; } From 892b3f6ad622e536d75050fd2a3ae5243f4c4bf5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 23:26:01 -0400 Subject: [PATCH 148/327] acpid: Skip (rather than fail) if /proc/acpi doesn't exist E.g. EC2 instances don't have ACPI. --- modules/services/hardware/acpid.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/services/hardware/acpid.nix b/modules/services/hardware/acpid.nix index 2002df6a303c..57dc799ca8c0 100644 --- a/modules/services/hardware/acpid.nix +++ b/modules/services/hardware/acpid.nix @@ -105,6 +105,8 @@ in daemonType = "fork"; exec = "acpid --confdir ${acpiConfDir}"; + + unitConfig.ConditionPathExists = [ "/proc/acpi" ]; }; }; From 98c6c5b730d8b66052b21283c73b1da2429c68fe Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 23:26:19 -0400 Subject: [PATCH 149/327] fetch-ec2-data: Update for systemd --- modules/virtualisation/ec2-data.nix | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix index 65f408262256..2f58a9694921 100644 --- a/modules/virtualisation/ec2-data.nix +++ b/modules/virtualisation/ec2-data.nix @@ -8,21 +8,20 @@ with pkgs.lib; { - jobs.fetchEC2Data = - { name = "fetch-ec2-data"; + boot.systemd.services."fetch-ec2-data" = + { description = "Fetch EC2 Data"; - startOn = "ip-up"; - - task = true; + wantedBy = [ "multi-user.target" ]; + before = [ "sshd.service" ]; path = [ pkgs.curl pkgs.iproute ]; script = '' ip route del blackhole 169.254.169.254/32 || true - + curl="curl --retry 3 --retry-delay 0 --fail" - + echo "setting host name..." ${optionalString (config.networking.hostName == "") '' ${pkgs.nettools}/bin/hostname $($curl http://169.254.169.254/1.0/meta-data/hostname) @@ -60,12 +59,15 @@ with pkgs.lib; # accessed from now on. ip route add blackhole 169.254.169.254/32 ''; + + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; }; - jobs.printHostKey = - { name = "print-host-key"; - task = true; - startOn = "started sshd"; + boot.systemd.services."print-host-key" = + { description = "Print SSH Host Key"; + wantedBy = [ "multi-user.target" ]; + after = [ "sshd.service" ]; script = '' # Print the host public key on the console so that the user @@ -75,10 +77,8 @@ with pkgs.lib; ${pkgs.openssh}/bin/ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub > /dev/console echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console ''; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; }; - # Only start sshd after we've obtained the host key (if given in the - # user data), otherwise the sshd job will generate one itself. - jobs.sshd.startOn = mkOverride 90 "stopped fetch-ec2-data"; - } From a5969634f4da94f85ffbce2ce81f760fd73c67e5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 4 Oct 2012 23:38:27 -0400 Subject: [PATCH 150/327] sshd: Do detach into the background This is necessary to ensure that jobs that need to start after sshd work properly. This reverts 03f13a49392b90cdc54d8ff057cef76bf0379913. --- modules/services/networking/ssh/sshd.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 83b7b5372ec3..163616fdd18e 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -347,10 +347,10 @@ in serviceConfig = { ExecStart = - "${pkgs.openssh}/sbin/sshd -D -h ${cfg.hostKeyPath} " + + "${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} " + "-f ${pkgs.writeText "sshd_config" cfg.extraConfig}"; Restart = "always"; - Type = "simple"; + Type = "forking"; KillMode = "process"; PIDFile = "/run/sshd.pid"; }; From dd1770bf0bb7590635244369ac36c771237aa813 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 5 Oct 2012 13:44:15 -0400 Subject: [PATCH 151/327] Enable klogd on Linux < 3.5 On Linux >= 3.5, systemd takes care of logging kernel messages. --- modules/module-list.nix | 2 +- modules/services/logging/klogd.nix | 43 +++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/modules/module-list.nix b/modules/module-list.nix index c1ab8edce403..06c9f8efca70 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -77,7 +77,7 @@ ./services/hardware/udev.nix ./services/hardware/udisks.nix ./services/hardware/upower.nix - #./services/logging/klogd.nix + ./services/logging/klogd.nix ./services/logging/logcheck.nix ./services/logging/logrotate.nix ./services/logging/logstash.nix diff --git a/modules/services/logging/klogd.nix b/modules/services/logging/klogd.nix index 907d83c7a6ac..d7d0bbf89a54 100644 --- a/modules/services/logging/klogd.nix +++ b/modules/services/logging/klogd.nix @@ -1,19 +1,42 @@ { config, pkgs, ... }: -###### implementation +with pkgs.lib; { + ###### interface - jobs.klogd = - { description = "Kernel log daemon"; + options = { - startOn = "started syslogd"; - - path = [ pkgs.sysklogd ]; - - exec = - "klogd -c 1 -2 -n " + - "-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map"; + services.klogd.enable = mkOption { + type = types.bool; + default = versionOlder (getVersion config.boot.kernelPackages.kernel) "3.5"; + description = '' + Whether to enable klogd, the kernel log message processing + daemon. Since systemd handles logging of kernel messages on + Linux 3.5 and later, this is only useful if you're running an + older kernel. + ''; }; + }; + + + ###### implementation + + config = mkIf config.services.klogd.enable { + + jobs.klogd = + { description = "Kernel Log Daemon"; + + wantedBy = [ "multi-user.target" ]; + + path = [ pkgs.sysklogd ]; + + exec = + "klogd -c 1 -2 -n " + + "-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map"; + }; + + }; + } From f451afea8f3c25913cff1cfb53f046edbf91ee90 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 8 Oct 2012 10:51:17 -0400 Subject: [PATCH 152/327] =?UTF-8?q?Remove=20=E2=80=98services.journald.log?= =?UTF-8?q?KernelMessages=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This option no longer exists in systemd. --- modules/system/boot/systemd.nix | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 23751e2104aa..991e09058e83 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -378,12 +378,6 @@ in description = "Default unit started when the system boots."; }; - services.journald.logKernelMessages = mkOption { - default = true; - type = types.bool; - description = "Whether to log kernel messages."; - }; - services.journald.console = mkOption { default = ""; type = types.uniq types.string; @@ -420,9 +414,6 @@ in ForwardToConsole=yes TTYPath=${config.services.journald.console} ''} - ${optionalString config.services.journald.logKernelMessages '' - ImportKernel=yes - ''} ''; target = "systemd/journald.conf"; } From d71c0bb83436d931436f1ce7c5684e8676678b48 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 9 Oct 2012 15:14:15 -0400 Subject: [PATCH 153/327] Respect partOf etc. for socket and target units --- modules/system/boot/systemd-unit-options.nix | 18 +++++++++ modules/system/boot/systemd.nix | 41 ++++++++------------ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 276197d24d8f..127ab7be3b94 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -76,6 +76,7 @@ rec { }; + serviceOptions = unitOptions // { environment = mkOption { @@ -146,4 +147,21 @@ rec { }; + + socketOptions = unitOptions // { + + socketConfig = mkOption { + default = {}; + example = { ListenStream = "/run/my-socket"; }; + type = types.attrs; + description = '' + Each attribute in this set specifies an option in the + [Socket] section of the unit. See + systemd.socket + 5 for details. + ''; + }; + + }; + } \ No newline at end of file diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 991e09058e83..6603d6126b43 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -167,6 +167,20 @@ let makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; + unitConfig = { name, config, ... }: { + config = { + unitConfig = + { Requires = concatStringsSep " " config.requires; + Wants = concatStringsSep " " config.wants; + After = concatStringsSep " " config.after; + Before = concatStringsSep " " config.before; + PartOf = concatStringsSep " " config.partOf; + } // optionalAttrs (config.description != "") { + Description = config.description; + }; + }; + }; + serviceConfig = { name, config, ... }: { config = { # Default path for systemd services. Should be quite minimal. @@ -177,15 +191,6 @@ let pkgs.gnused systemd ]; - unitConfig = - { Requires = concatStringsSep " " config.requires; - Wants = concatStringsSep " " config.wants; - After = concatStringsSep " " config.after; - Before = concatStringsSep " " config.before; - PartOf = concatStringsSep " " config.partOf; - } // optionalAttrs (config.description != "") - { Description = config.description; - }; }; }; @@ -342,33 +347,21 @@ in boot.systemd.targets = mkOption { default = {}; type = types.attrsOf types.optionSet; - options = unitOptions; + options = [ unitOptions unitConfig ]; description = "Definition of systemd target units."; }; boot.systemd.services = mkOption { default = {}; type = types.attrsOf types.optionSet; - options = [ serviceOptions serviceConfig ]; + options = [ serviceOptions unitConfig serviceConfig ]; description = "Definition of systemd service units."; }; boot.systemd.sockets = mkOption { default = {}; type = types.attrsOf types.optionSet; - options = unitOptions // { - socketConfig = mkOption { - default = {}; - example = { ListenStream = "/run/my-socket"; }; - type = types.attrs; - description = '' - Each attribute in this set specifies an option in the - [Socket] section of the unit. See - systemd.socket - 5 for details. - ''; - }; - }; + options = [ socketOptions unitConfig ]; description = "Definition of systemd socket units."; }; From 69024529011d21a18441eb05d9d3671fab10614a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 9 Oct 2012 15:14:32 -0400 Subject: [PATCH 154/327] Whitespace --- modules/services/audio/alsa.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix index ff08f21a4857..92d0cdd26f32 100644 --- a/modules/services/audio/alsa.nix +++ b/modules/services/audio/alsa.nix @@ -58,6 +58,7 @@ in serviceConfig.Type = "oneshot"; serviceConfig.ExecStart = "${alsaUtils}/sbin/alsactl store --ignore"; }; + }; } From ad94b9e50eeeaf7a70cf49e58c0ee6b8e0413e9f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 16:49:47 -0400 Subject: [PATCH 155/327] Use optionalAttrs --- modules/virtualisation/virtualbox-guest.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/virtualisation/virtualbox-guest.nix b/modules/virtualisation/virtualbox-guest.nix index 03234fbb82f7..410a48152a99 100644 --- a/modules/virtualisation/virtualbox-guest.nix +++ b/modules/virtualisation/virtualbox-guest.nix @@ -11,7 +11,7 @@ let in -if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then +optionalAttrs (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) # ugly... { ###### interface @@ -85,4 +85,3 @@ if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then }; } -else {} From 6b185a131fe589af7fa4a721e170b91a3f279116 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 16:49:59 -0400 Subject: [PATCH 156/327] Use config.system.build.systemd in the toplevel derivation --- modules/system/activation/top-level.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/top-level.nix b/modules/system/activation/top-level.nix index 4e79375ba1c5..48c1c0be1896 100644 --- a/modules/system/activation/top-level.nix +++ b/modules/system/activation/top-level.nix @@ -148,7 +148,8 @@ let preferLocalBuild = true; buildCommand = systemBuilder; - inherit (pkgs) systemd utillinux; + inherit (pkgs) utillinux; + inherit (config.system.build) systemd; inherit children; kernelParams = From 17a7f483641db44e456181ddd430604eb5360f7f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 16:50:41 -0400 Subject: [PATCH 157/327] Add an option for BindsTo dependencies --- modules/system/boot/systemd-unit-options.nix | 9 +++++++++ modules/system/boot/systemd.nix | 1 + 2 files changed, 10 insertions(+) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 127ab7be3b94..46f2a705df8c 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -47,6 +47,15 @@ rec { ''; }; + bindsTo = mkOption { + default = []; + types = types.listOf types.string; + description = '' + Like ‘requires’, but in addition, if the specified units + unexpectedly disappear, this unit will be stopped as well. + ''; + }; + partOf = mkOption { default = []; types = types.listOf types.string; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 6603d6126b43..268e81b10910 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -174,6 +174,7 @@ let Wants = concatStringsSep " " config.wants; After = concatStringsSep " " config.after; Before = concatStringsSep " " config.before; + BindsTo = concatStringsSep " " config.bindsTo; PartOf = concatStringsSep " " config.partOf; } // optionalAttrs (config.description != "") { Description = config.description; From e9b221c2ff08b7b941298c4a17c090442f72c5ed Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 16:51:05 -0400 Subject: [PATCH 158/327] firewall.nix: Don't spam the log --- modules/services/networking/firewall.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index e6ae725f85ff..7601fd1be433 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -178,7 +178,6 @@ in preStart = '' ${helpers} - set -x # Flush the old firewall rules. !!! Ideally, updating the # firewall would be atomic. Apparently that's possible From 62b707de07c4aae4a415bc186bda943c70edd3ac Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 17:55:13 -0400 Subject: [PATCH 159/327] Add support for postStop scripts --- modules/system/boot/systemd-unit-options.nix | 9 +++++++++ modules/system/boot/systemd.nix | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 46f2a705df8c..2efea2fb9e12 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -145,6 +145,15 @@ rec { ''; }; + postStop = mkOption { + type = types.string; + default = ""; + description = '' + Shell commands executed after the service's main process + has exited. + ''; + }; + restartIfChanged = mkOption { type = types.bool; default = true; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 268e81b10910..c166c1cbf031 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -250,6 +250,13 @@ let ''} ''} + ${optionalString (def.postStop != "") '' + ExecStopPost=${makeJobScript "${name}-poststop.sh" '' + #! ${pkgs.stdenv.shell} -e + ${def.postStop} + ''} + ''} + ${attrsToSection def.serviceConfig} ''; }; From d7458b5fc21676f2b1176a416687aa9e5a902c9e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 17:55:42 -0400 Subject: [PATCH 160/327] Split the monolithic network-interface service into multiple units MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For each statically configured interface, we now create a unit ‘-cfg.service’ which gets started as soon as the network device comes up. Similarly, each bridge defined in ‘networking.bridges’ and virtual interface in ‘networking.interfaces’ is created by a service ‘.service’. So if we have networking.bridges.br0.interfaces = [ "eth0" "eth1" ]; networking.interfaces = [ { name = "br0"; ipAddress = "192.168.1.1"; } ]; then there will be a unit ‘br0.service’ that depends on ‘sys-subsystem-net-devices-eth0.device’ and ‘sys-subsystem-net-devices-eth1.device’, and a unit ‘br0-cfg.service’ that depends on ‘sys-subsystem-net-devices-br0.device’. --- modules/services/printing/cupsd.nix | 2 +- modules/system/boot/systemd.nix | 2 +- modules/tasks/network-interfaces.nix | 165 ++++++++++++++++----------- 3 files changed, 102 insertions(+), 67 deletions(-) diff --git a/modules/services/printing/cupsd.nix b/modules/services/printing/cupsd.nix index 6d31c0050aaf..1e532f578a22 100644 --- a/modules/services/printing/cupsd.nix +++ b/modules/services/printing/cupsd.nix @@ -138,7 +138,7 @@ in }; services.printing.drivers = - [ pkgs.cups pkgs.cups_pdf_filter pkgs.ghostscript additionalBackends pkgs.perl pkgs.coreutils pkgs.gnused ]; + [ pkgs.cups /* pkgs.cups_pdf_filter */ pkgs.ghostscript additionalBackends pkgs.perl pkgs.coreutils pkgs.gnused ]; services.printing.cupsdConf = '' diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index c166c1cbf031..31560a4dc171 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -7,7 +7,7 @@ let cfg = config.boot.systemd; - systemd = pkgs.systemd; + systemd = pkgs.systemd_tmp; makeUnit = name: unit: pkgs.writeTextFile { name = "unit"; inherit (unit) text; destination = "/${name}"; }; diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index a6fffce5bf46..c0499c9f94ca 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -248,64 +248,6 @@ in '' set +e # continue in case of errors - # Create virtual network interfaces - ${flip concatMapStrings cfg.interfaces (i: - optionalString i.virtual - '' - echo "Creating virtual network interface ${i.name}..." - ${pkgs.tunctl}/bin/tunctl -t "${i.name}" -u "${i.virtualOwner}" - '') - } - - # Set MAC addresses of interfaces, if desired. - ${flip concatMapStrings cfg.interfaces (i: - optionalString (i.macAddress != "") - '' - echo "Setting MAC address of ${i.name} to ${i.macAddress}..." - ip link set "${i.name}" address "${i.macAddress}" - '') - } - - for i in $(cd /sys/class/net && ls -d *); do - echo "Bringing up network device $i..." - ip link set "$i" up - done - - # Create bridge devices. - ${concatStrings (attrValues (flip mapAttrs cfg.bridges (n: v: '' - echo "Creating bridge ${n}..." - ${pkgs.bridge_utils}/sbin/brctl addbr "${n}" - - # Set bridge's hello time to 0 to avoid startup delays. - ${pkgs.bridge_utils}/sbin/brctl setfd "${n}" 0 - - ${flip concatMapStrings v.interfaces (i: '' - ${pkgs.bridge_utils}/sbin/brctl addif "${n}" "${i}" - ip addr flush dev "${i}" - '')} - - # !!! Should delete (brctl delif) any interfaces that - # no longer belong to the bridge. - '')))} - - # Configure the manually specified interfaces. - ${flip concatMapStrings cfg.interfaces (i: - optionalString (i.ipAddress != "") - '' - echo "Configuring interface ${i.name}..." - ip addr add "${i.ipAddress}""${optionalString (i.subnetMask != "") ("/" + i.subnetMask)}" \ - dev "${i.name}" - '' + - optionalString i.proxyARP - '' - echo 1 > /proc/sys/net/ipv4/conf/${i.name}/proxy_arp - '' + - optionalString (i.proxyARP && cfg.enableIPv6) - '' - echo 1 > /proc/sys/net/ipv6/conf/${i.name}/proxy_ndp - '') - } - # Set the static DNS configuration, if given. cat | ${pkgs.openresolv}/sbin/resolvconf -a static < /proc/sys/net/ipv4/ip_forward ''} # Run any user-specified commands. ${pkgs.stdenv.shell} ${pkgs.writeText "local-net-cmds" cfg.localCommands} - - ${optionalString (cfg.interfaces != [] || cfg.localCommands != "") '' - # Start the ip-up target (e.g. to start ntpd). - ${config.system.build.systemd}/bin/systemctl start ip-up.target - ''} ''; }; + boot.systemd.services = + let + + # For each interface , create a job ‘-cfg.service" + # that performs static configuration. It has a "wants" + # dependency on ‘.service’, which is supposed to create + # the interface and need not exist (i.e. for hardware + # interfaces). It has a binds-to dependency on the actual + # network device, so it only gets started after the interface + # has appeared, and it's stopped when the interface + # disappears. + configureInterface = i: nameValuePair "${i.name}-cfg" + { description = "Configuration of ${i.name}"; + wantedBy = [ "network.target" ]; + wants = [ "${i.name}.service" ]; + bindsTo = [ "sys-subsystem-net-devices-${i.name}.device" ]; + after = [ "${i.name}.service" "sys-subsystem-net-devices-${i.name}.device" ]; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + path = [ pkgs.iproute ]; + script = + '' + echo "bringing up interface..." + ip link set "${i.name}" up + '' + + optionalString (i.macAddress != "") + '' + echo "setting MAC address to ${i.macAddress}..." + ip link set "${i.name}" address "${i.macAddress}" + '' + + optionalString (i.ipAddress != "") + '' + echo "configuring interface..." + ip addr flush dev "${i.name}" + ip addr add "${i.ipAddress}""${optionalString (i.subnetMask != "") ("/" + i.subnetMask)}" \ + dev "${i.name}" + ${config.system.build.systemd}/bin/systemctl start ip-up.target + '' + + optionalString i.proxyARP + '' + echo 1 > /proc/sys/net/ipv4/conf/${i.name}/proxy_arp + '' + + optionalString (i.proxyARP && cfg.enableIPv6) + '' + echo 1 > /proc/sys/net/ipv6/conf/${i.name}/proxy_ndp + ''; + }; + + createTunDevice = i: nameValuePair "${i.name}" + { description = "Virtual Network Interface ${i.name}"; + wantedBy = [ "network.target" ]; + serviceConfig = + { Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.tunctl}/bin/tunctl -t '${i.name}' -u '${i.virtualOwner}'"; + ExecStop = "${pkgs.tunctl}/bin/tunctl -d '${i.name}'"; + }; + }; + + createBridgeDevice = n: v: + let + deps = map (i: "sys-subsystem-net-devices-${i}.device") v.interfaces; + in + { description = "Bridge Interface ${n}"; + wantedBy = [ "network.target" ]; + wants = map (i: "${i}.service") v.interfaces; + bindsTo = deps; + after = deps; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + path = [ pkgs.bridge_utils pkgs.iproute ]; + script = + '' + brctl addbr "${n}" + + # Set bridge's hello time to 0 to avoid startup delays. + brctl setfd "${n}" 0 + + ${flip concatMapStrings v.interfaces (i: '' + brctl addif "${n}" "${i}" + ip addr flush dev "${i}" + '')} + + # !!! Should delete (brctl delif) any interfaces that + # no longer belong to the bridge. + ''; + postStop = + '' + ip link set "${n}" down + brctl delbr "${n}" + ''; + }; + + in listToAttrs ( + map configureInterface cfg.interfaces ++ + map createTunDevice (filter (i: i.virtual) cfg.interfaces)) + // mapAttrs createBridgeDevice cfg.bridges; + # Set the host name in the activation script. Don't clear it if # it's not configured in the NixOS configuration, since it may # have been set by dhclient in the meantime. From bd1071d02bfa422c8137a666c47fa3b7b1ec7ce9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 10 Oct 2012 22:47:50 -0400 Subject: [PATCH 161/327] Remove "wants" dependencies on .service Instead it's enough to depend on sys-subsystem-net-devices-.device, which in turn has a "wants" dependency on the service (if any) that creates the interface. --- modules/programs/virtualbox.nix | 2 +- modules/tasks/network-interfaces.nix | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/programs/virtualbox.nix b/modules/programs/virtualbox.nix index 27e4ac400da6..e62b05bd8969 100644 --- a/modules/programs/virtualbox.nix +++ b/modules/programs/virtualbox.nix @@ -24,7 +24,7 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in requires = [ "dev-vboxnetctl.device" ]; after = [ "dev-vboxnetctl.device" ]; before = [ "network-interfaces.service" ]; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "network.target" "sys-subsystem-net-devices-vboxnet0.device" ]; path = [ virtualbox ]; preStart = '' diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index c0499c9f94ca..65da0610b8fe 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -287,9 +287,8 @@ in configureInterface = i: nameValuePair "${i.name}-cfg" { description = "Configuration of ${i.name}"; wantedBy = [ "network.target" ]; - wants = [ "${i.name}.service" ]; bindsTo = [ "sys-subsystem-net-devices-${i.name}.device" ]; - after = [ "${i.name}.service" "sys-subsystem-net-devices-${i.name}.device" ]; + after = [ "sys-subsystem-net-devices-${i.name}.device" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; path = [ pkgs.iproute ]; @@ -323,7 +322,7 @@ in createTunDevice = i: nameValuePair "${i.name}" { description = "Virtual Network Interface ${i.name}"; - wantedBy = [ "network.target" ]; + wantedBy = [ "network.target" "sys-subsystem-net-devices-${i.name}.device" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; @@ -337,8 +336,7 @@ in deps = map (i: "sys-subsystem-net-devices-${i}.device") v.interfaces; in { description = "Bridge Interface ${n}"; - wantedBy = [ "network.target" ]; - wants = map (i: "${i}.service") v.interfaces; + wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ]; bindsTo = deps; after = deps; serviceConfig.Type = "oneshot"; From 4104f60800d0ec5ff5041b7666bd30d49936d10f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 12:43:08 -0400 Subject: [PATCH 162/327] Fix accidental commit --- modules/system/boot/systemd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 31560a4dc171..c166c1cbf031 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -7,7 +7,7 @@ let cfg = config.boot.systemd; - systemd = pkgs.systemd_tmp; + systemd = pkgs.systemd; makeUnit = name: unit: pkgs.writeTextFile { name = "unit"; inherit (unit) text; destination = "/${name}"; }; From 1c53b2e29986ff399033ef975f22939e93104139 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 15:36:52 -0400 Subject: [PATCH 163/327] Don't flush addresses unless necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flushing is bad if the Nix store is on a remote filesystem accessed over that interface. http://hydra.nixos.org/build/3184162 Also added a interface option ‘prefixLength’ as a better alternative to ‘subnetMask’. --- modules/programs/virtualbox.nix | 2 +- modules/tasks/network-interfaces.nix | 38 ++++++++++++++++++++++------ modules/virtualisation/qemu-vm.nix | 1 + 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/modules/programs/virtualbox.nix b/modules/programs/virtualbox.nix index e62b05bd8969..0fb4a95d30bf 100644 --- a/modules/programs/virtualbox.nix +++ b/modules/programs/virtualbox.nix @@ -38,5 +38,5 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in ''; }; - networking.interfaces = [ { name = "vboxnet0"; ipAddress = "192.168.56.1"; subnetMask = "255.255.255.0"; } ]; + networking.interfaces = [ { name = "vboxnet0"; ipAddress = "192.168.56.1"; prefixLength = 24; } ]; } diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 65da0610b8fe..20e1a0066750 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -101,13 +101,24 @@ in ''; }; + prefixLength = mkOption { + default = null; + example = 24; + type = types.nullOr types.int; + description = '' + Subnet mask of the interface, specified as the number of + bits in the prefix (24). + ''; + }; + subnetMask = mkOption { default = ""; example = "255.255.255.0"; type = types.string; description = '' - Subnet mask of the interface. Leave empty to use the - default subnet mask. + Subnet mask of the interface, specified as a bitmask. + This is deprecated; use + instead. ''; }; @@ -285,13 +296,17 @@ in # has appeared, and it's stopped when the interface # disappears. configureInterface = i: nameValuePair "${i.name}-cfg" + (let mask = + if i.prefixLength != null then toString i.prefixLength else + if i.subnetMask != "" then i.subnetMask else "32"; + in { description = "Configuration of ${i.name}"; wantedBy = [ "network.target" ]; bindsTo = [ "sys-subsystem-net-devices-${i.name}.device" ]; after = [ "sys-subsystem-net-devices-${i.name}.device" ]; serviceConfig.Type = "oneshot"; serviceConfig.RemainAfterExit = true; - path = [ pkgs.iproute ]; + path = [ pkgs.iproute pkgs.gawk ]; script = '' echo "bringing up interface..." @@ -304,10 +319,17 @@ in '' + optionalString (i.ipAddress != "") '' - echo "configuring interface..." - ip addr flush dev "${i.name}" - ip addr add "${i.ipAddress}""${optionalString (i.subnetMask != "") ("/" + i.subnetMask)}" \ - dev "${i.name}" + cur=$(ip -4 -o a show dev "${i.name}" | awk '{print $4}') + # Only do a flush/add if it's necessary. This is + # useful when the Nix store is accessed via this + # interface (e.g. in a QEMU VM test). + if [ "$cur" != "${i.ipAddress}/${mask}" ]; then + echo "configuring interface..." + ip -4 addr flush dev "${i.name}" + ip -4 addr add "${i.ipAddress}/${mask}" dev "${i.name}" + else + echo "skipping configuring interface" + fi ${config.system.build.systemd}/bin/systemctl start ip-up.target '' + optionalString i.proxyARP @@ -318,7 +340,7 @@ in '' echo 1 > /proc/sys/net/ipv6/conf/${i.name}/proxy_ndp ''; - }; + }); createTunDevice = i: nameValuePair "${i.name}" { description = "Virtual Network Interface ${i.name}"; diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index f71e0ba51126..ec11f3604e7d 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -363,6 +363,7 @@ in networking.interfaces = singleton { name = "eth0"; ipAddress = "10.0.2.15"; + prefixLength = 24; }; # Don't run ntpd in the guest. It should get the correct time from KVM. From 2cf9bb929bb577738bf83c950da384b607fc6ff1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 16:18:34 -0400 Subject: [PATCH 164/327] =?UTF-8?q?Add=20a=20=E2=80=98restart=E2=80=99=20a?= =?UTF-8?q?lias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/programs/bash/bashrc.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index e2526c398c7d..5e68eb9e6b6d 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -42,6 +42,9 @@ alias ls="ls --color=tty" alias ll="ls -l" alias l="ls -alh" alias which="type -P" + +# Convenience for people used to Upstart. alias start="systemctl start" alias stop="systemctl stop" +alias restart="systemctl restart" alias status="systemctl status" From 285f58702599d4784b21c2a087a7b2c09ecdbce4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 16:18:48 -0400 Subject: [PATCH 165/327] =?UTF-8?q?Move=20non-interface=20specific=20initi?= =?UTF-8?q?alisation=20to=20=E2=80=98network-setup.service=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unit ‘network-interface.service’ has been replaced by ‘network-interfaces.target’. --- modules/programs/virtualbox.nix | 1 - modules/services/networking/dhcpcd.nix | 2 +- modules/system/upstart/upstart.nix | 2 +- modules/tasks/network-interfaces.nix | 82 ++++++++++++++------------ 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/modules/programs/virtualbox.nix b/modules/programs/virtualbox.nix index 0fb4a95d30bf..7bce11ab8553 100644 --- a/modules/programs/virtualbox.nix +++ b/modules/programs/virtualbox.nix @@ -23,7 +23,6 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in { description = "VirtualBox vboxnet0 Interface"; requires = [ "dev-vboxnetctl.device" ]; after = [ "dev-vboxnetctl.device" ]; - before = [ "network-interfaces.service" ]; wantedBy = [ "network.target" "sys-subsystem-net-devices-vboxnet0.device" ]; path = [ virtualbox ]; preStart = diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index cfbc7ba3679c..4f89f77b12b9 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -95,7 +95,7 @@ in { description = "DHCP Client"; wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.service" ]; + after = [ "network-interfaces.target" ]; path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index d6362a0e4ca0..9d17b352dc88 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -59,7 +59,7 @@ let after = (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else if job.startOn == "started udev" then [ "systemd-udev.service" ] else - if job.startOn == "started network-interfaces" then [ "network-interfaces.service" ] else + if job.startOn == "started network-interfaces" then [ "network-interfaces.target" ] else if job.startOn == "started networking" then [ "network.target" ] else if job.startOn == "ip-up" then [] else if job.startOn == "" || job.startOn == "startup" then [] else diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 20e1a0066750..8c2a3215f2a2 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -246,47 +246,54 @@ in security.setuidPrograms = [ "ping" "ping6" ]; - jobs."network-interfaces" = - { description = "Static Network Interfaces"; - - after = [ "systemd-udev-settle.service" ]; - before = [ "network.target" ]; + boot.systemd.targets."network-interfaces" = + { description = "All Network Interfaces"; wantedBy = [ "network.target" ]; - - path = [ pkgs.iproute ]; - - preStart = - '' - set +e # continue in case of errors - - # Set the static DNS configuration, if given. - cat | ${pkgs.openresolv}/sbin/resolvconf -a static < /proc/sys/net/ipv4/ip_forward - ''} - - # Run any user-specified commands. - ${pkgs.stdenv.shell} ${pkgs.writeText "local-net-cmds" cfg.localCommands} - ''; }; boot.systemd.services = let + networkSetup = + { description = "Networking Setup"; + + after = [ "network-interfaces.target" ]; + before = [ "network.target" ]; + wantedBy = [ "network.target" ]; + + path = [ pkgs.iproute ]; + + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + + script = + '' + # Set the static DNS configuration, if given. + cat | ${pkgs.openresolv}/sbin/resolvconf -a static < /proc/sys/net/ipv4/ip_forward + ''} + + # Run any user-specified commands. + ${cfg.localCommands} + ''; + }; + # For each interface , create a job ‘-cfg.service" # that performs static configuration. It has a "wants" # dependency on ‘.service’, which is supposed to create @@ -301,7 +308,7 @@ in if i.subnetMask != "" then i.subnetMask else "32"; in { description = "Configuration of ${i.name}"; - wantedBy = [ "network.target" ]; + wantedBy = [ "network-interfaces.target" ]; bindsTo = [ "sys-subsystem-net-devices-${i.name}.device" ]; after = [ "sys-subsystem-net-devices-${i.name}.device" ]; serviceConfig.Type = "oneshot"; @@ -389,7 +396,8 @@ in in listToAttrs ( map configureInterface cfg.interfaces ++ map createTunDevice (filter (i: i.virtual) cfg.interfaces)) - // mapAttrs createBridgeDevice cfg.bridges; + // mapAttrs createBridgeDevice cfg.bridges + // { "network-setup" = networkSetup; }; # Set the host name in the activation script. Don't clear it if # it's not configured in the NixOS configuration, since it may From b606165bd9d4c8a1f82160f67bd541f064ed1ddc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 17:54:43 -0400 Subject: [PATCH 166/327] Allow a unit to declare "triggers" that force a restart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The triggers are just arbitrary strings that are included in the unit under X-Restart-Triggers. The idea is that if they change between reconfigurations, switch-to-configuration will restart the unit because its store path changed. This is mostly useful for services that implicitly depend on generated files in /etc. Thus you can say restartTriggers = [ confFile ]; where ‘confFile’ is the derivation that generated the /etc file in question. --- modules/system/boot/systemd-unit-options.nix | 9 +++++++++ modules/system/boot/systemd.nix | 1 + 2 files changed, 10 insertions(+) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 2efea2fb9e12..239c837c6767 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -83,6 +83,15 @@ rec { ''; }; + restartTriggers = mkOption { + default = []; + description = '' + An arbitrary list of items such as derivations. If any item + in the list changes between reconfigurations, the service will + be restarted. + ''; + }; + }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index c166c1cbf031..d88ac652ae0e 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -176,6 +176,7 @@ let Before = concatStringsSep " " config.before; BindsTo = concatStringsSep " " config.bindsTo; PartOf = concatStringsSep " " config.partOf; + "X-Restart-Triggers" = toString config.restartTriggers; } // optionalAttrs (config.description != "") { Description = config.description; }; From 71a541afb6cb83b896396f7b6e563abd0c8af4f5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 17:57:54 -0400 Subject: [PATCH 167/327] dhcpcd: Don't depend on network-interfaces.target Dhcpcd automatically detects new interfaces, so we can start it right away. --- modules/services/networking/dhcpcd.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 4f89f77b12b9..f2300a9529d8 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -94,8 +94,7 @@ in boot.systemd.services.dhcpcd = { description = "DHCP Client"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; + wantedBy = [ "network.target" ]; path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; From d63da5892cf79df5d66cdc76430ccd371bd5fb71 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 17:58:46 -0400 Subject: [PATCH 168/327] Ensure that systemd-modules-load is restarted when boot.kernelModules changes --- modules/system/boot/kernel.nix | 36 ++++++++++++++++++++++++++++----- modules/system/boot/systemd.nix | 2 +- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 8a660b90581b..130adb1110a1 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -2,7 +2,16 @@ with pkgs.lib; -let kernel = config.boot.kernelPackages.kernel; in +let + + kernel = config.boot.kernelPackages.kernel; + + kernelModulesConf = pkgs.writeText "nixos.conf" + '' + ${concatStringsSep "\n" config.boot.kernelModules} + ''; + +in { @@ -197,10 +206,27 @@ let kernel = config.boot.kernelPackages.kernel; in # this file changes. environment.etc = singleton { target = "modules-load.d/nixos.conf"; - source = pkgs.writeText "nixos.conf" - '' - ${concatStringsSep "\n" config.boot.kernelModules} - ''; + source = kernelModulesConf; + }; + + # Sigh. This overrides systemd's systemd-modules-load.service + # just so we can set a restart trigger. Also make + # multi-user.target pull it in so that it gets started if it + # failed earlier. + boot.systemd.services."systemd-modules-load" = + { description = "Load Kernel Modules"; + wantedBy = [ "sysinit.target" "multi-user.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + unitConfig = + { DefaultDependencies = "no"; + Conflicts = "shutdown.target"; + }; + serviceConfig = + { Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${config.system.build.systemd}/lib/systemd/systemd-modules-load"; + }; + restartTriggers = [ kernelModulesConf ]; }; lib.kernelConfig = { diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index d88ac652ae0e..0ccb30eb92f2 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -76,7 +76,7 @@ let "systemd-update-utmp-shutdown.service" # Kernel module loading. - "systemd-modules-load.service" + #"systemd-modules-load.service" # Filesystems. "systemd-fsck@.service" From e3c1865067b5517f6264083863f92bc5beedcd28 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Oct 2012 17:59:41 -0400 Subject: [PATCH 169/327] Let the tun services depend on /dev/net/tun --- modules/tasks/network-interfaces.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 8c2a3215f2a2..7ef548a36b4f 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -351,6 +351,8 @@ in createTunDevice = i: nameValuePair "${i.name}" { description = "Virtual Network Interface ${i.name}"; + requires = [ "dev-net-tun.device" ]; + after = [ "dev-net-tun.device" ]; wantedBy = [ "network.target" "sys-subsystem-net-devices-${i.name}.device" ]; serviceConfig = { Type = "oneshot"; @@ -407,6 +409,11 @@ in hostname "${config.networking.hostName}" ''; + services.udev.extraRules = + '' + KERNEL=="tun", TAG+="systemd" + ''; + }; } From 7ce9893bef53b9bb3c37042557593457fbf3a6b3 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Fri, 12 Oct 2012 18:14:39 +0200 Subject: [PATCH 170/327] network-interfaces.nix: interfaces that are part of a bridge must be brought 'up' for the bridge to function --- modules/tasks/network-interfaces.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 7ef548a36b4f..5c984b9e59cb 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -382,6 +382,7 @@ in ${flip concatMapStrings v.interfaces (i: '' brctl addif "${n}" "${i}" + ip link set "${i}" up ip addr flush dev "${i}" '')} From b968244aa16b0456b4e57f67a8c71e9dad788a2d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 15:08:44 -0400 Subject: [PATCH 171/327] Move fs.target to filesystems.nix --- modules/system/boot/systemd.nix | 8 -------- modules/tasks/filesystems.nix | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 0ccb30eb92f2..248dda60f59d 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -158,13 +158,6 @@ let KillSignal=SIGHUP ''; - fsTarget = - '' - [Unit] - Description=All File Systems - Wants=local-fs.target remote-fs.target - ''; - makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; unitConfig = { name, config, ... }: { @@ -423,7 +416,6 @@ in boot.systemd.units = { "rescue.service".text = rescueService; } - // { "fs.target" = { text = fsTarget; wantedBy = [ "multi-user.target" ]; }; } // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets; diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 14abe22a2da7..8bc0b7531c0a 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -180,6 +180,12 @@ in target = "fstab"; }; + # Provide a target that pulls in all filesystems. + boot.systemd.targets.fs = + { description = "All File Systems"; + wants = [ "local-fs.target" "remote-fs.target" ]; + }; + /* jobs.mountall = { startOn = "started udev or config-changed"; From fd7dbc99ab36915769db8c7311abdbd287555d6e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 16:37:14 -0400 Subject: [PATCH 172/327] switch-to-configuration: Handle multiple swap devices properly --- .../activation/switch-to-configuration.pl | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 6542b48c54e0..2b26801f35f1 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -64,15 +64,19 @@ sub getActiveUnits { sub parseFstab { my ($filename) = @_; - my %res; + my ($fss, $swaps); foreach my $line (read_file($filename, err_mode => 'quiet')) { chomp $line; $line =~ s/#.*//; next if $line =~ /^\s*$/; my @xs = split / /, $line; - $res{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] // "" }; + if ($xs[2] eq "swap") { + $swaps->{$xs[0]} = { options => $xs[3] // "" }; + } else { + $fss->{$xs[1]} = { device => $xs[0], fsType => $xs[2], options => $xs[3] // "" }; + } } - return %res; + return ($fss, $swaps); } sub parseUnit { @@ -187,26 +191,18 @@ sub unique { # Compare the previous and new fstab to figure out which filesystems # need a remount or need to be unmounted. New filesystems are mounted -# automatically by starting local-fs.target. Also handles swap -# devices. FIXME: might be nicer if we generated units for all -# mounts; then we could unify this with the unit checking code above. -my %prevFstab = parseFstab "/etc/fstab"; -my %newFstab = parseFstab "@out@/etc/fstab"; -foreach my $mountPoint (keys %prevFstab) { - my $prev = $prevFstab{$mountPoint}; - my $new = $newFstab{$mountPoint}; - my $unit = pathToUnitName($mountPoint). ".mount" if $prev->{fsType} ne "swap"; +# automatically by starting local-fs.target. FIXME: might be nicer if +# we generated units for all mounts; then we could unify this with the +# unit checking code above. +my ($prevFss, $prevSwaps) = parseFstab "/etc/fstab"; +my ($newFss, $newSwaps) = parseFstab "@out@/etc/fstab"; +foreach my $mountPoint (keys ${prevFss}) { + my $prev = $prevFss->{$mountPoint}; + my $new = $newFss->{$mountPoint}; + my $unit = pathToUnitName($mountPoint) . ".mount"; if (!defined $new) { - if ($prev->{fsType} eq "swap") { - # Swap entry disappeared, so turn it off. Can't use - # "systemctl stop" here because systemd has lots of alias - # units that prevent a stop from actually calling - # "swapoff". - system("@utillinux@/sbin/swapoff", $prev->{device}); - } else { - # Filesystem entry disappeared, so unmount it. - push @unitsToStop, $unit; - } + # Filesystem entry disappeared, so unmount it. + push @unitsToStop, $unit; } elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) { # Filesystem type or device changed, so unmount and mount it. write_file($restartListFile, { append => 1 }, "$unit\n"); @@ -217,6 +213,21 @@ foreach my $mountPoint (keys %prevFstab) { } } +# Also handles swap devices. +foreach my $device (keys ${prevSwaps}) { + my $prev = $prevSwaps->{$device}; + my $new = $newSwaps->{$device}; + if (!defined $new) { + # Swap entry disappeared, so turn it off. Can't use + # "systemctl stop" here because systemd has lots of alias + # units that prevent a stop from actually calling + # "swapoff". + print STDERR "stopping swap device: $device\n"; + system("@utillinux@/sbin/swapoff", $device); + } + # FIXME: update swap options (i.e. its priority). +} + if (scalar @unitsToStop > 0) { @unitsToStop = unique(@unitsToStop); print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n"; From 97a2de983bb53c29520b2b125e70d2fb07fba3b8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 16:38:00 -0400 Subject: [PATCH 173/327] Ensure that swap.target is pulled in by switch-to-configuration even if it failed earlier --- modules/system/boot/systemd.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 248dda60f59d..3de6220e6b95 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -311,8 +311,7 @@ let ln -s ${cfg.defaultUnit} $out/default.target #ln -s ../getty@tty1.service $out/multi-user.target.wants/ - ln -s ../remote-fs.target $out/multi-user.target.wants/ - ln -s ../network.target $out/multi-user.target.wants/ + ln -s ../remote-fs.target ../network.target ../swap.target $out/multi-user.target.wants/ ''; # */ in From e8de4455ab0230d88b39a580a934ace69f5110ca Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 16:47:11 -0400 Subject: [PATCH 174/327] Update automatic swapfile creation for systemd --- modules/config/swap.nix | 31 +++++++++++++++++++++++++++++++ modules/tasks/filesystems.nix | 10 ---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/modules/config/swap.nix b/modules/config/swap.nix index 5b20f657e129..776574bc0168 100644 --- a/modules/config/swap.nix +++ b/modules/config/swap.nix @@ -74,9 +74,40 @@ with pkgs.lib; }; config = mkIf ((length config.swapDevices) != 0) { + system.requiredKernelConfig = with config.lib.kernelConfig; [ (isYes "SWAP") ]; + + # Create missing swapfiles. + # FIXME: support changing the size of existing swapfiles. + boot.systemd.services = + let + + escapePath = s: # FIXME: slow + replaceChars ["/" "-"] ["-" "\\x2d"] (substring 1 (stringLength s) s); + + createSwapDevice = sw: assert sw.device != ""; nameValuePair "mkswap-${escapePath sw.device}" + { description = "Initialisation of Swapfile ${sw.device}"; + wantedBy = [ "${escapePath sw.device}.swap" ]; + before = [ "${escapePath sw.device}.swap" ]; + path = [ pkgs.utillinux ]; + script = + '' + if [ ! -e "${sw.device}" ]; then + fallocate -l ${toString sw.size}M "${sw.device}" || + dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size} + mkswap ${sw.device} + fi + ''; + unitConfig.RequiresMountsFor = "${dirOf sw.device}"; + unitConfig.DefaultDependencies = false; # needed to prevent a cycle + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + }; + + in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices)); + }; } diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 8bc0b7531c0a..6c321b23c7ec 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -213,16 +213,6 @@ in fi '')} - # Create missing swapfiles. - # FIXME: support changing the size of existing swapfiles. - ${flip concatMapStrings config.swapDevices (sw: optionalString (sw.size != null) '' - if [ ! -e "${sw.device}" -a -e "$(dirname "${sw.device}")" ]; then - # FIXME: use ‘fallocate’ on filesystems that support it. - dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size} - mkswap ${sw.device} - fi - '')} - ''; daemonType = "daemon"; From 3f6d53cc972fe8bf34b5cb0184087d95c1130c1d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 17:01:49 -0400 Subject: [PATCH 175/327] Move escapeSystemdPath to lib/utils.nix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new file ‘utils.nix’ is intended for NixOS-specific library functions (i.e. stuff that shouldn't go into Nixpkgs' lib/). --- lib/eval-config.nix | 1 + lib/utils.nix | 10 ++++++++++ modules/config/swap.nix | 15 ++++++++------- 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 lib/utils.nix diff --git a/lib/eval-config.nix b/lib/eval-config.nix index ffc0db1c7ea6..c2bbf036af04 100644 --- a/lib/eval-config.nix +++ b/lib/eval-config.nix @@ -31,6 +31,7 @@ rec { inherit pkgs modules baseModules; modulesPath = ../modules; pkgs_i686 = import { system = "i686-linux"; }; + utils = import ./utils.nix pkgs; }; # Import Nixpkgs, allowing the NixOS option nixpkgs.config to diff --git a/lib/utils.nix b/lib/utils.nix new file mode 100644 index 000000000000..b75e063eaa92 --- /dev/null +++ b/lib/utils.nix @@ -0,0 +1,10 @@ +pkgs: with pkgs.lib; + +rec { + + # Escape a path according to the systemd rules, e.g. /dev/xyzzy + # becomes dev-xyzzy. FIXME: slow. + escapeSystemdPath = s: + replaceChars ["/" "-"] ["-" "\\x2d"] (substring 1 (stringLength s) s); + +} diff --git a/modules/config/swap.nix b/modules/config/swap.nix index 776574bc0168..84185ff3bbd5 100644 --- a/modules/config/swap.nix +++ b/modules/config/swap.nix @@ -1,6 +1,7 @@ -{ config, pkgs, ... }: +{ config, pkgs, utils, ... }: with pkgs.lib; +with utils; { @@ -84,13 +85,13 @@ with pkgs.lib; boot.systemd.services = let - escapePath = s: # FIXME: slow - replaceChars ["/" "-"] ["-" "\\x2d"] (substring 1 (stringLength s) s); - - createSwapDevice = sw: assert sw.device != ""; nameValuePair "mkswap-${escapePath sw.device}" + createSwapDevice = sw: + assert sw.device != ""; + let device' = escapeSystemdPath sw.device; in + nameValuePair "mkswap-${escapeSystemdPath sw.device}" { description = "Initialisation of Swapfile ${sw.device}"; - wantedBy = [ "${escapePath sw.device}.swap" ]; - before = [ "${escapePath sw.device}.swap" ]; + wantedBy = [ "${device'}.swap" ]; + before = [ "${device'}.swap" ]; path = [ pkgs.utillinux ]; script = '' From 12d1cd87ce34095b400c7e8fd62082a743f96a53 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 17:32:05 -0400 Subject: [PATCH 176/327] Systemd unit names can contain Nix-illegal characters, so don't include them --- modules/system/boot/systemd.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 3de6220e6b95..2545eaf7393a 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -224,28 +224,28 @@ let ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"} ${optionalString (def.preStart != "") '' - ExecStartPre=${makeJobScript "${name}-prestart.sh" '' + ExecStartPre=${makeJobScript "prestart.sh" '' #! ${pkgs.stdenv.shell} -e ${def.preStart} ''} ''} ${optionalString (def.script != "") '' - ExecStart=${makeJobScript "${name}.sh" '' + ExecStart=${makeJobScript "start.sh" '' #! ${pkgs.stdenv.shell} -e ${def.script} ''} ''} ${optionalString (def.postStart != "") '' - ExecStartPost=${makeJobScript "${name}-poststart.sh" '' + ExecStartPost=${makeJobScript "poststart.sh" '' #! ${pkgs.stdenv.shell} -e ${def.postStart} ''} ''} ${optionalString (def.postStop != "") '' - ExecStopPost=${makeJobScript "${name}-poststop.sh" '' + ExecStopPost=${makeJobScript "poststop.sh" '' #! ${pkgs.stdenv.shell} -e ${def.postStop} ''} @@ -311,7 +311,7 @@ let ln -s ${cfg.defaultUnit} $out/default.target #ln -s ../getty@tty1.service $out/multi-user.target.wants/ - ln -s ../remote-fs.target ../network.target ../swap.target $out/multi-user.target.wants/ + ln -s ../local-fs.target ../remote-fs.target ../network.target ../swap.target $out/multi-user.target.wants/ ''; # */ in From 161c837c49fdaed2c59738f466a265b85bbd0f19 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 17:32:36 -0400 Subject: [PATCH 177/327] Port automatic filesystem creation to systemd --- modules/config/swap.nix | 3 +- modules/tasks/filesystems.nix | 137 +++++++--------------------------- 2 files changed, 29 insertions(+), 111 deletions(-) diff --git a/modules/config/swap.nix b/modules/config/swap.nix index 84185ff3bbd5..8a2f58d7dcd2 100644 --- a/modules/config/swap.nix +++ b/modules/config/swap.nix @@ -101,10 +101,9 @@ with utils; mkswap ${sw.device} fi ''; - unitConfig.RequiresMountsFor = "${dirOf sw.device}"; + unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ]; unitConfig.DefaultDependencies = false; # needed to prevent a cycle serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; }; in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices)); diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 6c321b23c7ec..77a43ed15dba 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -1,6 +1,7 @@ -{ config, pkgs, ... }: +{ config, pkgs, utils, ... }: with pkgs.lib; +with utils; let @@ -27,7 +28,7 @@ let ''; in - + { ###### interface @@ -170,7 +171,7 @@ in # Add the mount helpers to the system path so that `mount' can find them. system.fsPackages = [ pkgs.dosfstools ]; - + environment.systemPackages = [ pkgs.ntfs3g pkgs.cifs_utils ] ++ config.system.fsPackages; @@ -186,119 +187,37 @@ in wants = [ "local-fs.target" "remote-fs.target" ]; }; - /* - jobs.mountall = - { startOn = "started udev or config-changed"; + # Emit systemd services to format requested filesystems. + boot.systemd.services = + let - task = true; - - path = [ pkgs.utillinux pkgs.mountall ] ++ config.system.fsPackages; - - console = "output"; - - preStart = - '' - # Ensure that this job is restarted when fstab changed: - # ${fstab} - echo "mounting filesystems..." - - # Format devices. - ${flip concatMapStrings config.fileSystems (fs: optionalString fs.autoFormat '' - if [ -e "${fs.device}" ]; then + formatDevice = fs: + let + mountPoint' = escapeSystemdPath fs.mountPoint; + device' = escapeSystemdPath fs.device; + in nameValuePair "mkfs-${device'}" + { description = "Initialisation of Filesystem ${fs.device}"; + wantedBy = [ "${mountPoint'}.mount" ]; + before = [ "${mountPoint'}.mount" ]; + require = [ "${device'}.device" ]; + after = [ "${device'}.device" ]; + path = [ pkgs.utillinux ] ++ config.system.fsPackages; + script = + '' + if ! [ -e "${fs.device}" ]; then exit 1; fi + # FIXME: this is scary. The test could be more robust. type=$(blkid -p -s TYPE -o value "${fs.device}" || true) if [ -z "$type" ]; then echo "creating ${fs.fsType} filesystem on ${fs.device}..." mkfs.${fs.fsType} "${fs.device}" fi - fi - '')} + ''; + unitConfig.RequiresMountsFor = [ "${dirOf fs.device}" ]; + unitConfig.DefaultDependencies = false; # needed to prevent a cycle + serviceConfig.Type = "oneshot"; + }; - ''; - - daemonType = "daemon"; - - exec = "mountall --daemon"; - }; - - # The `mount-failed' event is emitted synchronously, but we don't - # want `mountall' to wait for the emergency shell. So use this - # intermediate job to make the event asynchronous. - jobs."mount-failed" = - { task = true; - startOn = "mount-failed"; - restartIfChanged = false; - script = - '' - # Don't start the emergency shell if the X server is - # running. The user won't see it, and the "console owner" - # stanza breaks VT switching and causes the X server to go - # to 100% CPU time. - status="$(status xserver || true)" - [[ "$status" =~ start/ ]] && exit 0 - - stop ${config.boot.ttyEmergency} || true - - start --no-wait emergency-shell \ - DEVICE="$DEVICE" MOUNTPOINT="$MOUNTPOINT" - ''; - }; - - # On an `ip-up' event, notify mountall so that it retries mounting - # remote filesystems. - jobs."mountall-ip-up" = - { - task = true; - startOn = "ip-up"; - restartIfChanged = false; - script = - '' - # Send USR1 to the mountall process. Can't use "pkill - # mountall" here because that has a race condition: we may - # accidentally send USR1 to children of mountall (such as - # fsck) just before they do execve(). - status="$(status mountall)" - if [[ "$status" =~ "start/running, process "([0-9]+) ]]; then - pid=''${BASH_REMATCH[1]} - echo "sending USR1 to $pid..." - kill -USR1 "$pid" - fi - ''; - }; - - jobs."emergency-shell" = - { task = true; - - restartIfChanged = false; - - console = "owner"; - - script = - '' - cat <>> - - The filesystem \`$DEVICE' could not be mounted on \`$MOUNTPOINT'. - - Please do one of the following: - - - Repair the filesystem (\`fsck $DEVICE') and exit the emergency - shell to resume booting. - - - Ignore any failed filesystems and continue booting by running - \`initctl emit filesystem'. - - - Remove the failed filesystem from the system configuration in - /etc/nixos/configuration.nix and run \`nixos-rebuild switch'. - - EOF - - ${pkgs.shadow}/bin/login root || false - - initctl start --no-wait mountall - ''; - }; - */ + in listToAttrs (map formatDevice (filter (fs: fs.autoFormat) config.fileSystems)); }; From 53f216885faf480ad4d1e2c57fce2335bda30958 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Oct 2012 17:39:06 -0400 Subject: [PATCH 178/327] Ignore systemd-modules-load errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On NixOS, ‘boot.kernelModules’ has historically contained modules that may not exist or load everywhere, so don't barf on those. --- modules/system/boot/kernel.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 130adb1110a1..4b6436a77f76 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -225,6 +225,11 @@ in { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${config.system.build.systemd}/lib/systemd/systemd-modules-load"; + # Ignore failed module loads. Typically some of the + # modules in ‘boot.kernelModules’ are "nice to have but + # not required" (e.g. acpi-cpufreq), so we don't want to + # barf on those. + SuccessExitStatus = "0 1"; }; restartTriggers = [ kernelModulesConf ]; }; From 10ac80115b9c2c760dcd3f1c1beb1390b5cd2e21 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 14 Oct 2012 21:12:11 -0400 Subject: [PATCH 179/327] switch-to-configuration: Fix bad Perl --- modules/system/activation/switch-to-configuration.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 2b26801f35f1..41487de9745e 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -196,7 +196,7 @@ sub unique { # unit checking code above. my ($prevFss, $prevSwaps) = parseFstab "/etc/fstab"; my ($newFss, $newSwaps) = parseFstab "@out@/etc/fstab"; -foreach my $mountPoint (keys ${prevFss}) { +foreach my $mountPoint (keys %$prevFss) { my $prev = $prevFss->{$mountPoint}; my $new = $newFss->{$mountPoint}; my $unit = pathToUnitName($mountPoint) . ".mount"; @@ -214,7 +214,7 @@ foreach my $mountPoint (keys ${prevFss}) { } # Also handles swap devices. -foreach my $device (keys ${prevSwaps}) { +foreach my $device (keys %$prevSwaps) { my $prev = $prevSwaps->{$device}; my $new = $newSwaps->{$device}; if (!defined $new) { From 4ca0617f4a4664eff5936179eaa18a37a0453816 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Tue, 16 Oct 2012 18:23:28 +0200 Subject: [PATCH 180/327] modules/programs/bash: improve bash completion support The new configuration.nix option 'environment.enableBashCompletion' determines whether bash completion is automatically enabled system-wide for all interactive shells or not. The default setting is 'off'. --- modules/programs/bash/bash.nix | 31 ++++++++++++++++++++++++++++++- modules/programs/bash/bashrc.sh | 10 +--------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 51654b164a07..9eefb8e686f6 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -7,6 +7,25 @@ with pkgs.lib; let + initBashCompletion = optionalString config.environment.enableBashCompletion '' + # Check whether we're running a version of Bash that has support for + # programmable completion. If we do, enable all modules installed in + # the system (and user profile). + if shopt -q progcomp &>/dev/null; then + . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh" + nullglobStatus=$(shopt -p nullglob) + shopt -s nullglob + for p in $NIX_PROFILES /run/current-system/sw; do + for m in "$p/etc/bash_completion.d/"*; do + echo enable bash completion module $m + . $m + done + done + eval "$nullglobStatus" + fi + ''; + + options = { environment.shellInit = mkOption { @@ -18,6 +37,12 @@ let type = with pkgs.lib.types; string; }; + environment.enableBashCompletion = mkOption { + default = false; + description = "Enable bash-completion for all interactive shells."; + type = with pkgs.lib.types; bool; + }; + }; in @@ -38,7 +63,10 @@ in { # /etc/bashrc: executed every time a bash starts. Sources # /etc/profile to ensure that the system environment is # configured properly. - source = ./bashrc.sh; + source = pkgs.substituteAll { + src = ./bashrc.sh; + inherit initBashCompletion; + }; target = "bashrc"; } @@ -59,4 +87,5 @@ in mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh ''; + environment.pathsToLink = optional config.environment.enableBashCompletion "/etc/bash_completion.d"; } diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index 5e68eb9e6b6d..10a36ede2a38 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -27,15 +27,7 @@ if test "$TERM" = "xterm"; then PS1="\[\033]2;\h:\u:\w\007\]$PS1" fi -# Check whether we're running a version of Bash that has support for -# programmable completion. If we do, and if the current user has -# installed the package 'bash-completion' in her $HOME/.nix-profile, -# then completion is enabled automatically. -if [ -f "$HOME/.nix-profile/etc/profile.d/bash_completion.sh" ]; then - if shopt -q progcomp &>/dev/null; then - . "$HOME/.nix-profile/etc/profile.d/bash_completion.sh" - fi -fi +@initBashCompletion@ # Some aliases. alias ls="ls --color=tty" From c7fb0defe678c1a160d9d0f8a2d25800b95ae7b5 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Tue, 16 Oct 2012 18:41:20 +0200 Subject: [PATCH 181/327] modules/programs/bash: clean-up variables used in initialization of bash-completion --- modules/programs/bash/bash.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 9eefb8e686f6..ca825d7ab946 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -17,11 +17,11 @@ let shopt -s nullglob for p in $NIX_PROFILES /run/current-system/sw; do for m in "$p/etc/bash_completion.d/"*; do - echo enable bash completion module $m . $m done done eval "$nullglobStatus" + unset nullglobStatus p m fi ''; From 6a9b85541200fb9691693f4a8c2a017b8b449cd5 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Tue, 16 Oct 2012 19:07:19 +0200 Subject: [PATCH 182/327] modules/programs/bash: '/run/current-system/sw' is already a part of $NIX_PROFILES --- modules/programs/bash/bash.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index ca825d7ab946..441d30f1e9fa 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -15,7 +15,7 @@ let . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh" nullglobStatus=$(shopt -p nullglob) shopt -s nullglob - for p in $NIX_PROFILES /run/current-system/sw; do + for p in $NIX_PROFILES; do for m in "$p/etc/bash_completion.d/"*; do . $m done From a4cad32c3d13908303f480677b189844a70705bf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Oct 2012 16:01:30 -0400 Subject: [PATCH 183/327] Generate more user-friendly script filenames This is primarily important in journal entries. --- modules/system/boot/systemd.nix | 12 +++++++----- modules/system/upstart/upstart.nix | 10 +++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 2545eaf7393a..66cc048d9c09 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -158,7 +158,9 @@ let KillSignal=SIGHUP ''; - makeJobScript = name: content: "${pkgs.writeScriptBin name content}/bin/${name}"; + makeJobScript = name: text: + let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${name}"; inherit text; }; + in "${x}/bin/${name}"; unitConfig = { name, config, ... }: { config = { @@ -224,28 +226,28 @@ let ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"} ${optionalString (def.preStart != "") '' - ExecStartPre=${makeJobScript "prestart.sh" '' + ExecStartPre=${makeJobScript "${name}-pre-start" '' #! ${pkgs.stdenv.shell} -e ${def.preStart} ''} ''} ${optionalString (def.script != "") '' - ExecStart=${makeJobScript "start.sh" '' + ExecStart=${makeJobScript "${name}-start" '' #! ${pkgs.stdenv.shell} -e ${def.script} ''} ''} ${optionalString (def.postStart != "") '' - ExecStartPost=${makeJobScript "poststart.sh" '' + ExecStartPost=${makeJobScript "${name}-post-start" '' #! ${pkgs.stdenv.shell} -e ${def.postStart} ''} ''} ${optionalString (def.postStop != "") '' - ExecStopPost=${makeJobScript "poststop.sh" '' + ExecStopPost=${makeJobScript "${name}-post-stop" '' #! ${pkgs.stdenv.shell} -e ${def.postStop} ''} diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 9d17b352dc88..5761ed4c5a41 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -21,13 +21,13 @@ let env = config.system.upstartEnvironment // job.environment; - preStartScript = makeJobScript "${job.name}-pre-start.sh" + preStartScript = makeJobScript "${job.name}-pre-start" '' #! ${pkgs.stdenv.shell} -e ${job.preStart} ''; - startScript = makeJobScript "${job.name}-start.sh" + startScript = makeJobScript "${job.name}-start" '' #! ${pkgs.stdenv.shell} -e ${if job.script != "" then job.script else '' @@ -35,19 +35,19 @@ let ''} ''; - postStartScript = makeJobScript "${job.name}-post-start.sh" + postStartScript = makeJobScript "${job.name}-post-start" '' #! ${pkgs.stdenv.shell} -e ${job.postStart} ''; - preStopScript = makeJobScript "${job.name}-pre-stop.sh" + preStopScript = makeJobScript "${job.name}-pre-stop" '' #! ${pkgs.stdenv.shell} -e ${job.preStop} ''; - postStopScript = makeJobScript "${job.name}-post-stop.sh" + postStopScript = makeJobScript "${job.name}-post-stop" '' #! ${pkgs.stdenv.shell} -e ${job.postStop} From b4a1893cddcad7cc406b388a2ef4d5888ffb0971 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 18 Oct 2012 11:54:07 -0400 Subject: [PATCH 184/327] systemd-vconsole-setup: Don't put the X server in non-raw mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ‘systemd-vconsole-setup’ by default operates on /dev/tty0, the currently active tty. Since it puts /dev/tty0 in Unicode or ASCII mode, if the X server is currently active when it runs, keys such as Alt-F4 won't reach the X server anymore. So use /dev/tty1 instead. --- modules/config/i18n.nix | 6 +++--- modules/system/boot/systemd.nix | 2 +- modules/tasks/kbd.nix | 32 +++++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/modules/config/i18n.nix b/modules/config/i18n.nix index dd435d481b70..e964b9bfb1d8 100644 --- a/modules/config/i18n.nix +++ b/modules/config/i18n.nix @@ -47,11 +47,11 @@ let The keyboard mapping table for the virtual consoles. "; }; - + }; - + }; - + ###### implementation glibcLocales = pkgs.glibcLocales.override { diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 66cc048d9c09..dc0c2ba4504b 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -45,7 +45,7 @@ let # Login stuff. "systemd-logind.service" "autovt@.service" - "systemd-vconsole-setup.service" + #"systemd-vconsole-setup.service" "systemd-user-sessions.service" "dbus-org.freedesktop.login1.service" "user@.service" diff --git a/modules/tasks/kbd.nix b/modules/tasks/kbd.nix index aa708fb60199..7867b3c19126 100644 --- a/modules/tasks/kbd.nix +++ b/modules/tasks/kbd.nix @@ -13,6 +13,12 @@ let consoleFont = config.i18n.consoleFont; consoleKeyMap = config.i18n.consoleKeyMap; + vconsoleConf = pkgs.writeText "vconsole.conf" + '' + KEYMAP=${consoleKeyMap} + FONT=${consoleFont} + ''; + in { @@ -61,11 +67,27 @@ in # systemd-vconsole-setup.service if /etc/vconsole.conf changes. environment.etc = singleton { target = "vconsole.conf"; - source = pkgs.writeText "vconsole.conf" - '' - KEYMAP=${consoleKeyMap} - FONT=${consoleFont} - ''; + source = vconsoleConf; + }; + + # This is identical to the systemd-vconsole-setup.service unit + # shipped with systemd, except that it uses /dev/tty1 instead of + # /dev/tty0 to prevent putting the X server in non-raw mode, and + # it has a restart trigger. + boot.systemd.services."systemd-vconsole-setup" = + { description = "Setup Virtual Console"; + before = [ "sysinit.target" "shutdown.target" ]; + unitConfig = + { DefaultDependencies = "no"; + Conflicts = "shutdown.target"; + ConditionPathExists = "/dev/tty1"; + }; + serviceConfig = + { Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${config.system.build.systemd}/lib/systemd/systemd-vconsole-setup /dev/tty1"; + }; + restartTriggers = [ vconsoleConf ]; }; }; From 06cbe6253788b4be2d5a3f2b3d36820cfc1b2b1b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 18 Oct 2012 13:26:47 -0400 Subject: [PATCH 185/327] switch-to-configuration: Support services activated by multiple sockets --- .../activation/switch-to-configuration.pl | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 41487de9745e..b085778f0994 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -146,18 +146,29 @@ while (my ($unit, $state) = each %{$activePrev}) { { push @unitsToSkip, $unit; } else { - # If this unit has a corresponding socket unit, - # then stop the socket unit as well, and restart - # the socket instead of the service. - if ($unit =~ /\.service$/ && defined $activePrev->{"$baseName.socket"}) { - push @unitsToStop, "$baseName.socket"; - write_file($restartListFile, { append => 1 }, "$baseName.socket\n"); + # If this unit is socket-activated, then stop the + # socket unit(s) as well, and restart the + # socket(s) instead of the service. + my $socketActivated = 0; + if ($unit =~ /\.service$/) { + my @sockets = split / /, ($unitInfo->{Sockets} // ""); + if (scalar @sockets == 0) { + @sockets = ("$baseName.socket"); + } + foreach my $socket (@sockets) { + if (defined $activePrev->{$socket}) { + push @unitsToStop, $socket; + write_file($restartListFile, { append => 1 }, "$socket\n"); + $socketActivated = 1; + } + } } - # Record that this unit needs to be started below. We - # write this to a file to ensure that the service gets - # restarted if we're interrupted. - else { + # Otherwise, record that this unit needs to be + # started below. We write this to a file to + # ensure that the service gets restarted if we're + # interrupted. + if (!$socketActivated) { write_file($restartListFile, { append => 1 }, "$unit\n"); } From 3d6824feaa90bebf9fa2b378e52e340584e3bd84 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 19 Oct 2012 10:32:09 -0400 Subject: [PATCH 186/327] Machine.pm: Don't add .service implicitly Systemd will add .service anyway if no unit type is given. --- lib/test-driver/Machine.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index c7e0bc102f18..d376bd404b97 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -381,7 +381,7 @@ sub waitForUnit { sub waitForJob { my ($self, $jobName) = @_; - return $self->waitForUnit($jobName . ".service"); + return $self->waitForUnit($jobName); } @@ -398,13 +398,13 @@ sub waitForFile { sub startJob { my ($self, $jobName) = @_; - $self->execute("systemctl stop $jobName.service"); + $self->execute("systemctl stop $jobName"); # FIXME: check result } sub stopJob { my ($self, $jobName) = @_; - $self->execute("systemctl stop $jobName.service"); + $self->execute("systemctl stop $jobName"); } From ac8db6fd339fa50d5ad189e305c8e1647cbc934b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 19 Oct 2012 15:21:06 -0400 Subject: [PATCH 187/327] firewall.nix: Don't fail if IPv6 is disabled --- modules/services/networking/firewall.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index 7601fd1be433..d0119c56fce5 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -268,9 +268,11 @@ in # Accept all ICMPv6 messages except redirects and node # information queries (type 139). See RFC 4890, section # 4.4. - ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP - ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP - ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept + ${optionalString config.networking.enableIPv6 '' + ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP + ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP + ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept + ''} ${cfg.extraCommands} From c8628e0293a5fcd1e705f658a9a4d7a4861dcc05 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 19 Oct 2012 15:41:01 -0400 Subject: [PATCH 188/327] Don't let interfaces get IPv6 addresses if networking.enableIPv6 is false --- modules/config/networking.nix | 6 +++++- modules/tasks/network-interfaces.nix | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/config/networking.nix b/modules/config/networking.nix index 3ea86d2f9cf4..5fc06c341ad2 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -3,7 +3,9 @@ {config, pkgs, ...}: with pkgs.lib; + let + cfg = config.networking; options = { @@ -43,7 +45,9 @@ in source = pkgs.writeText "hosts" '' 127.0.0.1 localhost - ::1 localhost + ${optionalString cfg.enableIPv6 '' + ::1 localhost + ''} ${cfg.extraHosts} ''; target = "hosts"; diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 5c984b9e59cb..d36a1081de5f 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -278,6 +278,9 @@ in '')} EOF + # Disable or enable IPv6. + echo ${if cfg.enableIPv6 then "0" else "1"} > /proc/sys/net/ipv6/conf/all/disable_ipv6 + # Set the default gateway. ${optionalString (cfg.defaultGateway != "") '' # FIXME: get rid of "|| true" (necessary to make it idempotent). From 7efde0740e1c86e2c7d68c413ff2adc1087dfe2d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 23 Oct 2012 13:35:06 +0200 Subject: [PATCH 189/327] =?UTF-8?q?Add=20user=20option=20=E2=80=98isAlias?= =?UTF-8?q?=E2=80=99=20to=20allow=20one=20user=20account=20to=20alias=20an?= =?UTF-8?q?other?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/config/users-groups.nix | 58 +++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/modules/config/users-groups.nix b/modules/config/users-groups.nix index ee65991ed52f..928391067621 100644 --- a/modules/config/users-groups.nix +++ b/modules/config/users-groups.nix @@ -8,74 +8,74 @@ let users = config.users; userOpts = { name, config, ... }: { - + options = { - + name = mkOption { type = with types; uniq string; description = "The name of the user account. If undefined, the name of the attribute set will be used."; }; - + description = mkOption { type = with types; uniq string; default = ""; description = "A short description of the user account."; }; - + uid = mkOption { type = with types; uniq (nullOr int); default = null; description = "The account UID. If undefined, NixOS will select a free UID."; }; - + group = mkOption { type = with types; uniq string; default = "nogroup"; description = "The user's primary group."; }; - + extraGroups = mkOption { type = types.listOf types.string; default = []; description = "The user's auxiliary groups."; }; - + home = mkOption { type = with types; uniq string; default = "/var/empty"; description = "The user's home directory."; }; - + shell = mkOption { type = with types; uniq string; default = "/run/current-system/sw/sbin/nologin"; description = "The path to the user's shell."; }; - + createHome = mkOption { type = types.bool; default = false; description = "If true, the home directory will be created automatically."; }; - + useDefaultShell = mkOption { type = types.bool; default = false; description = "If true, the user's shell will be set to users.defaultUserShell."; }; - + password = mkOption { type = with types; uniq (nullOr string); default = null; description = "The user's password. If undefined, no password is set for the user. Warning: do not set confidential information here because this data would be readable by all. This option should only be used for public account such as guest."; }; - + isSystemUser = mkOption { type = types.bool; default = true; description = "Indicates if the user is a system user or not."; }; - + createUser = mkOption { type = types.bool; default = true; @@ -85,7 +85,13 @@ let then not modify any of the basic properties for the user account. "; }; - + + isAlias = mkOption { + type = types.bool; + default = false; + description = "If true, the UID of this user is not required to be unique and can thus alias another user."; + }; + }; config = { @@ -93,41 +99,41 @@ let uid = mkDefault (attrByPath [name] null ids.uids); shell = mkIf config.useDefaultShell (mkDefault users.defaultUserShell); }; - + }; groupOpts = { name, config, ... }: { - + options = { - + name = mkOption { type = with types; uniq string; description = "The name of the group. If undefined, the name of the attribute set will be used."; }; - + gid = mkOption { type = with types; uniq (nullOr int); default = null; description = "The GID of the group. If undefined, NixOS will select a free GID."; }; - + }; config = { name = mkDefault name; gid = mkDefault (attrByPath [name] null ids.gids); }; - + }; # Note: the 'X' in front of the password is to distinguish between # having an empty password, and not having a password. - serializedUser = userName: let u = getAttr userName config.users.extraUsers; in "${u.name}\n${u.description}\n${if u.uid != null then toString u.uid else ""}\n${u.group}\n${toString (concatStringsSep "," u.extraGroups)}\n${u.home}\n${u.shell}\n${toString u.createHome}\n${if u.password != null then "X" + u.password else ""}\n${toString u.isSystemUser}\n${if u.createUser then "yes" else "no"}\n"; + serializedUser = u: "${u.name}\n${u.description}\n${if u.uid != null then toString u.uid else ""}\n${u.group}\n${toString (concatStringsSep "," u.extraGroups)}\n${u.home}\n${u.shell}\n${toString u.createHome}\n${if u.password != null then "X" + u.password else ""}\n${toString u.isSystemUser}\n${toString u.createUser}\n${toString u.isAlias}\n"; - # keep this extra file so that cat can be used to pass special chars such as "`" which is used in the avahi daemon usersFile = pkgs.writeText "users" ( - concatMapStrings serializedUser (attrNames config.users.extraUsers) - ); + let + p = partition (u: u.isAlias) (attrValues config.users.extraUsers); + in concatStrings (map serializedUser p.wrong ++ map serializedUser p.right)); in @@ -243,8 +249,9 @@ in read password read isSystemUser read createUser + read isAlias - if ! test "$createUser" = "yes"; then + if [ -z "$createUser" ]; then continue fi @@ -257,6 +264,7 @@ in --home "$home" \ --shell "$shell" \ ''${createHome:+--create-home} \ + ''${isAlias:+--non-unique} \ "$name" if test "''${password:0:1}" = 'X'; then (echo "''${password:1}"; echo "''${password:1}") | ${pkgs.shadow}/bin/passwd "$name" From e5fa3f108efa10c585c3c91fbe39b96066fc4d6d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 23 Oct 2012 07:50:23 -0400 Subject: [PATCH 190/327] Set uniqueness constraint on boot.devShmSize etc. --- modules/system/boot/stage-2.nix | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/system/boot/stage-2.nix b/modules/system/boot/stage-2.nix index 3569cfa81139..c8ea322eb17a 100644 --- a/modules/system/boot/stage-2.nix +++ b/modules/system/boot/stage-2.nix @@ -1,53 +1,60 @@ { config, pkgs, ... }: +with pkgs.lib; + let options = { boot = { - postBootCommands = pkgs.lib.mkOption { + + postBootCommands = mkOption { default = ""; example = "rm -f /var/log/messages"; - type = with pkgs.lib.types; string; + type = types.string; description = '' Shell commands to be executed just before Upstart is started. ''; }; - devSize = pkgs.lib.mkOption { + devSize = mkOption { default = "5%"; example = "32m"; + type = types.uniq types.string; description = '' Size limit for the /dev tmpfs. Look at mount(8), tmpfs size option, for the accepted syntax. ''; }; - devShmSize = pkgs.lib.mkOption { + devShmSize = mkOption { default = "50%"; example = "256m"; + type = types.uniq types.string; description = '' Size limit for the /dev/shm tmpfs. Look at mount(8), tmpfs size option, for the accepted syntax. ''; }; - runSize = pkgs.lib.mkOption { + runSize = mkOption { default = "25%"; example = "256m"; + type = types.uniq types.string; description = '' Size limit for the /run tmpfs. Look at mount(8), tmpfs size option, for the accepted syntax. ''; }; - cleanTmpDir = pkgs.lib.mkOption { + cleanTmpDir = mkOption { default = false; example = true; description = '' Delete all files in /tmp/ during boot. ''; }; + }; }; @@ -66,7 +73,7 @@ let [ pkgs.coreutils pkgs.utillinux pkgs.sysvtools - ] ++ pkgs.lib.optional config.boot.cleanTmpDir pkgs.findutils; + ] ++ optional config.boot.cleanTmpDir pkgs.findutils; postBootCommands = pkgs.writeText "local-cmds" '' ${config.boot.postBootCommands} From c980faebe2cb7592fad47aa2684d10c4ee0a509c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 23 Oct 2012 08:30:50 -0400 Subject: [PATCH 191/327] =?UTF-8?q?upstart.nix:=20Set=20=E2=80=98Type?= =?UTF-8?q?=E2=80=99=20to=20=E2=80=98oneshot=E2=80=99=20for=20Upstart=20ta?= =?UTF-8?q?sks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way the service will only reach the "started" state when the task has finished. --- modules/system/upstart/upstart.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 5761ed4c5a41..33f2775b496d 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -94,7 +94,9 @@ let if job.daemonType == "none" then { } else throw "invalid daemon type `${job.daemonType}'") // optionalAttrs (!job.task && job.respawn) - { Restart = "always"; }; + { Restart = "always"; } + // optionalAttrs job.task + { Type = "oneshot"; RemainAfterExit = false; }; }; From 224c825a36bf8fb161c25845b1cc0bae6866f075 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 23 Oct 2012 09:10:48 -0400 Subject: [PATCH 192/327] =?UTF-8?q?Add=20option=20=E2=80=98users.motd?= =?UTF-8?q?=E2=80=99=20for=20setting=20a=20message=20of=20the=20day=20show?= =?UTF-8?q?n=20on=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that this uses pam_motd. --- modules/programs/shadow.nix | 5 +++-- modules/security/pam.nix | 13 +++++++++++++ modules/services/networking/ssh/sshd.nix | 5 ++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/modules/programs/shadow.nix b/modules/programs/shadow.nix index 4b9be4605487..39359ac4293b 100644 --- a/modules/programs/shadow.nix +++ b/modules/programs/shadow.nix @@ -1,6 +1,6 @@ # Configuration for the pwdutils suite of tools: passwd, useradd, etc. -{config, pkgs, ...}: +{ config, pkgs, ... }: let @@ -27,6 +27,7 @@ let # Uncomment this to allow non-root users to change their account #information. This should be made configurable. #CHFN_RESTRICT frwh + ''; in @@ -90,7 +91,7 @@ in { name = "groupmod"; rootOK = true; } { name = "groupmems"; rootOK = true; } { name = "groupdel"; rootOK = true; } - { name = "login"; startSession = true; allowNullPassword = true; } + { name = "login"; startSession = true; allowNullPassword = true; showMotd = true; } ]; security.setuidPrograms = [ "passwd" "chfn" "su" "newgrp" ]; diff --git a/modules/security/pam.nix b/modules/security/pam.nix index 049df0f9958b..7293f207ed02 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -29,6 +29,8 @@ let concatStringsSep " " [ domain type item value ]) limits)); + motd = pkgs.writeText "motd" config.users.motd; + makePAMService = { name , # If set, root doesn't need to authenticate (e.g. for the "chsh" @@ -58,6 +60,8 @@ let allowNullPassword ? false , # The limits, as per limits.conf(5). limits ? config.security.pam.loginLimits + , # Whether to show the message of the day. + showMotd ? false }: { source = pkgs.writeText "${name}.pam" @@ -110,6 +114,8 @@ let "session optional pam_xauth.so xauthpath=${pkgs.xorg.xauth}/bin/xauth systemuser=99"} ${optionalString (limits != []) "session required ${pkgs.pam}/lib/security/pam_limits.so conf=${makeLimitsConf limits}"} + ${optionalString (showMotd && config.users.motd != null) + "session optional ${pkgs.pam}/lib/security/pam_motd.so motd=${motd}"} ''; target = "pam.d/${name}"; }; @@ -201,6 +207,13 @@ in ''; }; + users.motd = mkOption { + default = null; + example = "Today is Sweetmorn, the 4th day of The Aftermath in the YOLD 3178."; + type = types.nullOr types.string; + description = "Message of the day shown to users when they log in."; + }; + }; diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 163616fdd18e..90e0ea2f0298 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -358,7 +358,7 @@ in networking.firewall.allowedTCPPorts = cfg.ports; - security.pam.services = optional cfg.usePAM { name = "sshd"; startSession = true; }; + security.pam.services = optional cfg.usePAM { name = "sshd"; startSession = true; showMotd = true; }; services.openssh.extraConfig = '' @@ -390,10 +390,13 @@ in GatewayPorts ${cfg.gatewayPorts} PasswordAuthentication ${if cfg.passwordAuthentication then "yes" else "no"} ChallengeResponseAuthentication ${if cfg.challengeResponseAuthentication then "yes" else "no"} + + PrintMotd no # handled by pam_motd ''; assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true; message = "cannot enable X11 forwarding without setting xauth location";}]; + }; } From 2d9258da6705182388fc8e6472a49d2b0fee7b90 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 24 Oct 2012 12:31:02 +0200 Subject: [PATCH 193/327] auto.nix: Use SLiM to implement auto-logins --- modules/services/x11/display-managers/auto.nix | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/modules/services/x11/display-managers/auto.nix b/modules/services/x11/display-managers/auto.nix index cccc6e62a153..33d97e0e07a9 100644 --- a/modules/services/x11/display-managers/auto.nix +++ b/modules/services/x11/display-managers/auto.nix @@ -41,16 +41,11 @@ in config = mkIf cfg.enable { - services.xserver.displayManager.slim.enable = false; - - services.xserver.displayManager.job = - { execCmd = - '' - exec ${pkgs.xorg.xinit}/bin/xinit \ - ${pkgs.su}/bin/su -c ${dmcfg.session.script} ${cfg.user} \ - -- ${dmcfg.xserverBin} ${dmcfg.xserverArgs} - ''; - }; + services.xserver.displayManager.slim = { + enable = true; + autoLogin = true; + defaultUser = cfg.user; + }; }; From 719aeb36caf764eb969dc2cc6fbee8fd14eb47cc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 24 Oct 2012 12:58:58 +0200 Subject: [PATCH 194/327] =?UTF-8?q?Tests:=20Depend=20on=20=E2=80=98network?= =?UTF-8?q?.target=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/avahi.nix | 4 ++-- tests/bittorrent.nix | 6 +++--- tests/firewall.nix | 2 +- tests/installer.nix | 11 +++++------ tests/ipv6.nix | 4 ++-- tests/nat.nix | 4 ++-- tests/openssh.nix | 2 +- tests/tomcat.nix | 2 +- 8 files changed, 17 insertions(+), 18 deletions(-) diff --git a/tests/avahi.nix b/tests/avahi.nix index d29e0ff77c60..f1536f2eafa7 100644 --- a/tests/avahi.nix +++ b/tests/avahi.nix @@ -22,13 +22,13 @@ with pkgs; '' startAll; # mDNS. - $one->waitForJob("network-interfaces"); + $one->waitForJob("network.target"); $one->mustSucceed("avahi-resolve-host-name one.local | tee out >&2"); $one->mustSucceed("test \"`cut -f1 < out`\" = one.local"); $one->mustSucceed("avahi-resolve-host-name two.local | tee out >&2"); $one->mustSucceed("test \"`cut -f1 < out`\" = two.local"); - $two->waitForJob("network-interfaces"); + $two->waitForJob("network.target"); $two->mustSucceed("avahi-resolve-host-name one.local | tee out >&2"); $two->mustSucceed("test \"`cut -f1 < out`\" = one.local"); $two->mustSucceed("avahi-resolve-host-name two.local | tee out >&2"); diff --git a/tests/bittorrent.nix b/tests/bittorrent.nix index 8951e5bad1b3..c0cd7cd18437 100644 --- a/tests/bittorrent.nix +++ b/tests/bittorrent.nix @@ -79,7 +79,7 @@ in $tracker->succeed("chmod 644 /tmp/test.torrent"); # Start the tracker. !!! use a less crappy tracker - $tracker->waitForJob("network-interfaces"); + $tracker->waitForJob("network.target"); $tracker->succeed("bittorrent-tracker --port 6969 --dfile /tmp/dstate >&2 &"); $tracker->waitForOpenPort(6969); @@ -88,7 +88,7 @@ in # Now we should be able to download from the client behind the NAT. $tracker->waitForJob("httpd"); - $client1->waitForJob("network-interfaces"); + $client1->waitForJob("network.target"); $client1->succeed("transmission-cli http://tracker/test.torrent -w /tmp >&2 &"); $client1->waitForFile("/tmp/test.tar.bz2"); $client1->succeed("cmp /tmp/test.tar.bz2 ${file}"); @@ -98,7 +98,7 @@ in # Now download from the second client. This can only succeed if # the first client created a NAT hole in the router. - $client2->waitForJob("network-interfaces"); + $client2->waitForJob("network.target"); $client2->succeed("transmission-cli http://tracker/test.torrent -M -w /tmp >&2 &"); $client2->waitForFile("/tmp/test.tar.bz2"); $client2->succeed("cmp /tmp/test.tar.bz2 ${file}"); diff --git a/tests/firewall.nix b/tests/firewall.nix index b38cd988b769..060dbb6082c5 100644 --- a/tests/firewall.nix +++ b/tests/firewall.nix @@ -27,7 +27,7 @@ $walled->waitForJob("firewall"); $walled->waitForJob("httpd"); - $attacker->waitForJob("network-interfaces"); + $attacker->waitForJob("network.target"); # Local connections should still work. $walled->succeed("curl -v http://localhost/ >&2"); diff --git a/tests/installer.nix b/tests/installer.nix index 65542ae862eb..09c51c1e19e9 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -169,13 +169,12 @@ let my $machine = createMachine({ hda => "harddisk", hdaInterface => "${iface}" }); # Did /boot get mounted, if appropriate? - # !!! There is currently no good way to wait for the - # `filesystems' task to finish. - $machine->waitForFile("/boot/grub"); + $machine->waitForUnit("local-fs.target"); + $machine->succeed("test -e /boot/grub"); # Did the swap device get activated? - # !!! Idem. - $machine->waitUntilSucceeds("cat /proc/swaps | grep -q /dev"); + $machine->waitForUnit("swap.target"); + $machine->succeed("cat /proc/swaps | grep -q /dev"); $machine->mustSucceed("nix-env -i coreutils >&2"); $machine->mustSucceed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/ @@ -188,7 +187,7 @@ let # And just to be sure, check that the machine still boots after # "nixos-rebuild switch". my $machine = createMachine({ hda => "harddisk", hdaInterface => "${iface}" }); - $machine->waitForJob("network-interfaces"); + $machine->waitForJob("network.target"); $machine->shutdown; ''; diff --git a/tests/ipv6.nix b/tests/ipv6.nix index 4a308416aeff..a5f1a65a73d8 100644 --- a/tests/ipv6.nix +++ b/tests/ipv6.nix @@ -35,8 +35,8 @@ startAll; - $client->waitForJob("network-interfaces"); - $server->waitForJob("network-interfaces"); + $client->waitForJob("network.target"); + $server->waitForJob("network.target"); # Wait until the given interface has a non-tentative address of # the desired scope (i.e. has completed Duplicate Address diff --git a/tests/nat.nix b/tests/nat.nix index 5adbf3ce57da..24f390f24cbb 100644 --- a/tests/nat.nix +++ b/tests/nat.nix @@ -41,12 +41,12 @@ # The router should have access to the server. $server->waitForJob("httpd"); - $router->waitForJob("network-interfaces"); + $router->waitForJob("network.target"); $router->succeed("curl --fail http://server/ >&2"); # The client should be also able to connect via the NAT router. $router->waitForJob("nat"); - $client->waitForJob("network-interfaces"); + $client->waitForJob("network.target"); $client->succeed("curl --fail http://server/ >&2"); $client->succeed("ping -c 1 server >&2"); diff --git a/tests/openssh.nix b/tests/openssh.nix index 7a3d789327aa..734925989a37 100644 --- a/tests/openssh.nix +++ b/tests/openssh.nix @@ -29,7 +29,7 @@ $client->copyFileFromHost("key", "/root/.ssh/id_dsa"); $client->mustSucceed("chmod 600 /root/.ssh/id_dsa"); - $client->waitForJob("network-interfaces"); + $client->waitForJob("network.target"); $client->mustSucceed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2"); ''; } diff --git a/tests/tomcat.nix b/tests/tomcat.nix index 0726a7822500..3fd99da413c5 100644 --- a/tests/tomcat.nix +++ b/tests/tomcat.nix @@ -25,7 +25,7 @@ $server->waitForJob("tomcat"); $server->sleep(30); # Dirty, but it takes a while before Tomcat handles to requests properly - $client->waitForJob("network-interfaces"); + $client->waitForJob("network.target"); $client->succeed("curl --fail http://server/examples/servlets/servlet/HelloWorldExample"); $client->succeed("curl --fail http://server/examples/jsp/jsp2/simpletag/hello.jsp"); ''; From c6abc572e8ce4572b6f4aa5306c3487d76147a02 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 24 Oct 2012 12:59:19 +0200 Subject: [PATCH 195/327] Run all tests on both 32 and 64 bit --- release.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/release.nix b/release.nix index b32ce233ec05..4c29fce29f29 100644 --- a/release.nix +++ b/release.nix @@ -193,10 +193,9 @@ let */ - tests = + tests = { system ? "x86_64-linux" }: let - t = import ./tests { system = "i686-linux"; }; - t_64 = import ./tests { system = "x86_64-linux"; }; + t = import ./tests { inherit system; }; in { avahi = t.avahi.test; bittorrent = t.bittorrent.test; @@ -207,7 +206,6 @@ let installer.rebuildCD = t.installer.rebuildCD.test; installer.separateBoot = t.installer.separateBoot.test; installer.simple = t.installer.simple.test; - installer.simple_64 = t_64.installer.simple.test; installer.swraid = t.installer.swraid.test; ipv6 = t.ipv6.test; kde4 = t.kde4.test; From b6f9e0526995d3d571cb4ee0819fb51a23571019 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 24 Oct 2012 18:10:58 +0200 Subject: [PATCH 196/327] Update NFS client/server modules for systemd --- modules/services/network-filesystems/nfsd.nix | 40 ++++++++--------- modules/services/networking/rpcbind.nix | 22 ++++----- modules/tasks/filesystems/nfs.nix | 45 +++++++++---------- tests/nfs.nix | 11 ++--- tests/trac.nix | 3 +- 5 files changed, 61 insertions(+), 60 deletions(-) diff --git a/modules/services/network-filesystems/nfsd.nix b/modules/services/network-filesystems/nfsd.nix index b4dc014d68ed..995e9bba6030 100644 --- a/modules/services/network-filesystems/nfsd.nix +++ b/modules/services/network-filesystems/nfsd.nix @@ -80,44 +80,44 @@ in boot.kernelModules = [ "nfsd" ]; - jobs.nfsd = - { description = "Kernel NFS server"; + boot.systemd.services.nfsd = + { description = "NFS Server"; - startOn = "started networking"; + wantedBy = [ "multi-user.target" ]; + + requires = [ "rpcbind.service" "mountd.service" ]; + after = [ "rpcbind.service" "mountd.service" "statd.service" ]; path = [ pkgs.nfsUtils ]; - preStart = + script = '' - ensure rpcbind - ensure mountd - # Create a state directory required by NFSv4. mkdir -p /var/lib/nfs/v4recovery rpc.nfsd \ ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} \ ${builtins.toString cfg.nproc} + + sm-notify -d ''; postStop = "rpc.nfsd 0"; - postStart = - '' - ensure statd - ensure idmapd - ''; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; }; - jobs.mountd = - { description = "Kernel NFS server - mount daemon"; + boot.systemd.services.mountd = + { description = "NFSv3 Mount Daemon"; + + requires = [ "rpcbind.service" ]; + after = [ "rpcbind.service" ]; path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; preStart = '' - ensure rpcbind - mkdir -p /var/lib/nfs touch /var/lib/nfs/rmtab @@ -133,14 +133,14 @@ in '' } - # exports file is ${exports} - # keep this comment so that this job is restarted whenever exports changes! exportfs -ra ''; - daemonType = "fork"; + restartTriggers = [ exports ]; - exec = "rpc.mountd -f /etc/exports"; + serviceConfig.Type = "forking"; + serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.mountd rpc.mountd -f /etc/exports"; + serviceConfig.Restart = "always"; }; }; diff --git a/modules/services/networking/rpcbind.nix b/modules/services/networking/rpcbind.nix index 5437d221c1e4..8e3e86a515c1 100644 --- a/modules/services/networking/rpcbind.nix +++ b/modules/services/networking/rpcbind.nix @@ -59,20 +59,22 @@ in config = mkIf config.services.rpcbind.enable { - environment.etc = [netconfigFile]; + environment.systemPackages = [ pkgs.rpcbind ]; - jobs.rpcbind = - { description = "ONC RPC rpcbind"; + environment.etc = [ netconfigFile ]; - startOn = "started network-interfaces"; - stopOn = ""; + boot.systemd.services.rpcbind = + { description = "ONC RPC Directory Service"; - daemonType = "fork"; + wantedBy = [ "multi-user.target" ]; - exec = - '' - ${pkgs.rpcbind}/bin/rpcbind - ''; + requires = [ "basic.target" ]; + after = [ "basic.target" ]; + + unitConfig.DefaultDependencies = false; # don't stop during shutdown + + serviceConfig.Type = "forking"; + serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind"; }; }; diff --git a/modules/tasks/filesystems/nfs.nix b/modules/tasks/filesystems/nfs.nix index 491d2de8f24e..055733e456a8 100644 --- a/modules/tasks/filesystems/nfs.nix +++ b/modules/tasks/filesystems/nfs.nix @@ -33,50 +33,49 @@ in config = mkIf (any (fs: fs == "nfs" || fs == "nfs4") config.boot.supportedFilesystems) { services.rpcbind.enable = true; - + system.fsPackages = [ pkgs.nfsUtils ]; boot.kernelModules = [ "sunrpc" ]; boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; - # Ensure that statd and idmapd are started before mountall. - jobs.mountall.preStart = - '' - ensure statd || true - ensure idmapd || true - ''; - - jobs.statd = - { description = "Kernel NFS server - Network Status Monitor"; + boot.systemd.services.statd = + { description = "NFSv3 Network Status Monitor"; path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; - stopOn = ""; # needed during shutdown + wantedBy = [ "remote-fs-pre.target" "multi-user.target" ]; + before = [ "remote-fs-pre.target" ]; + requires = [ "basic.target" "rpcbind.service" ]; + after = [ "basic.target" "rpcbind.service" "network.target" ]; + + unitConfig.DefaultDependencies = false; # don't stop during shutdown preStart = '' - ensure rpcbind mkdir -p ${nfsStateDir}/sm mkdir -p ${nfsStateDir}/sm.bak sm-notify -d ''; - daemonType = "fork"; - - exec = "rpc.statd --no-notify"; + serviceConfig.Type = "forking"; + serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.statd rpc.statd --no-notify"; + serviceConfig.Restart = "always"; }; - jobs.idmapd = - { description = "NFS ID mapping daemon"; + boot.systemd.services.idmapd = + { description = "NFSv4 ID Mapping Daemon"; - path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; + path = [ pkgs.sysvtools pkgs.utillinux ]; - startOn = "started udev"; + wantedBy = [ "remote-fs-pre.target" "multi-user.target" ]; + before = [ "remote-fs-pre.target" ]; + requires = [ "rpcbind.service" ]; + after = [ "rpcbind.service" ]; preStart = '' - ensure rpcbind mkdir -p ${rpcMountpoint} mount -t rpc_pipefs rpc_pipefs ${rpcMountpoint} ''; @@ -86,9 +85,9 @@ in umount ${rpcMountpoint} ''; - daemonType = "fork"; - - exec = "rpc.idmapd -v -c ${idmapdConfFile}"; + serviceConfig.Type = "forking"; + serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}"; + serviceConfig.Restart = "always"; }; }; diff --git a/tests/nfs.nix b/tests/nfs.nix index 7c1ff5e92122..d5b6fc0a692d 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -8,7 +8,7 @@ let [ { mountPoint = "/data"; device = "server:/data"; fsType = "nfs"; - options = "bootwait,vers=3"; + options = "vers=3"; } ]; }; @@ -35,19 +35,20 @@ in testScript = '' $server->waitForJob("nfsd"); + $server->waitForJob("network.target"); startAll; - $client1->waitForJob("tty1"); # depends on filesystems + $client1->waitForJob("data.mount"); $client1->succeed("echo bla > /data/foo"); $server->succeed("test -e /data/foo"); - $client2->waitForJob("tty1"); # depends on filesystems + $client2->waitForJob("data.mount"); $client2->succeed("echo bla > /data/bar"); $server->succeed("test -e /data/bar"); # Test whether restarting ‘nfsd’ works correctly. - $server->succeed("stop nfsd; start nfsd"); + $server->succeed("systemctl restart nfsd"); $client2->succeed("echo bla >> /data/bar"); # will take 90 seconds due to the NFS grace period # Test whether we can get a lock. @@ -66,7 +67,7 @@ in $client2->waitForFile("locked"); # Test whether locks survive a reboot of the server. - $client1->waitForJob("tty1"); # depends on filesystems + $client1->waitForJob("data.mount"); $server->shutdown; $server->start; $client1->succeed("touch /data/xyzzy"); diff --git a/tests/trac.nix b/tests/trac.nix index 254996c24407..a35058a1992f 100644 --- a/tests/trac.nix +++ b/tests/trac.nix @@ -33,8 +33,7 @@ fileSystems = pkgs.lib.mkOverride 50 [ { mountPoint = "/repos"; device = "storage:/repos"; - fsType = "nfs"; - options = "bootwait"; + fsType = "nfs"; } ]; From d380152f39450070d9cd7e7a8272b2b1b8bd6b12 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 24 Oct 2012 18:11:21 +0200 Subject: [PATCH 197/327] Update some tests for systemd --- tests/firewall.nix | 2 +- tests/nat.nix | 2 +- tests/quake3.nix | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/firewall.nix b/tests/firewall.nix index 060dbb6082c5..316ee439b454 100644 --- a/tests/firewall.nix +++ b/tests/firewall.nix @@ -41,7 +41,7 @@ $walled->succeed("ping -c 1 attacker >&2"); # If we stop the firewall, then connections should succeed. - $walled->succeed("stop firewall"); + $walled->stopJob("firewall"); $attacker->succeed("curl -v http://walled/ >&2"); ''; diff --git a/tests/nat.nix b/tests/nat.nix index 24f390f24cbb..ca02fa137d49 100644 --- a/tests/nat.nix +++ b/tests/nat.nix @@ -63,7 +63,7 @@ $router->succeed("ping -c 1 client >&2"); # If we turn off NAT, the client shouldn't be able to reach the server. - $router->succeed("stop nat"); + $router->stopJob("nat"); $client->fail("curl --fail --connect-timeout 5 http://server/ >&2"); $client->fail("ping -c 1 server >&2"); diff --git a/tests/quake3.nix b/tests/quake3.nix index fbd0adab2fac..796c300423d6 100644 --- a/tests/quake3.nix +++ b/tests/quake3.nix @@ -28,9 +28,8 @@ rec { { server = { config, pkgs, ... }: - { jobs.quake3Server = - { name = "quake3-server"; - startOn = "startup"; + { jobs."quake3-server" = + { startOn = "startup"; exec = "${pkgs.quake3demo}/bin/quake3-server '+set g_gametype 0' " + "'+map q3dm7' '+addbot grunt' '+addbot daemia' 2> /tmp/log"; @@ -74,7 +73,7 @@ rec { $client1->shutdown(); $client2->shutdown(); - $server->succeed("stop quake3-server"); + $server->stopJob("quake3-server"); ''; } From ecd7bc931002fca2ea6508765a548dff382ebc10 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 24 Oct 2012 18:22:53 +0200 Subject: [PATCH 198/327] Tests: global search/replace of obsolete functions --- tests/avahi.nix | 40 ++++++++++++------------- tests/bittorrent.nix | 10 +++---- tests/check-filesystems.nix | 20 ++++++------- tests/firewall.nix | 6 ++-- tests/installer.nix | 60 ++++++++++++++++++------------------- tests/ipv6.nix | 6 ++-- tests/kde4.nix | 2 +- tests/mpich.nix | 18 +++++------ tests/mysql-replication.nix | 8 ++--- tests/mysql.nix | 4 +-- tests/nat.nix | 10 +++---- tests/nfs.nix | 10 +++---- tests/openssh.nix | 12 ++++---- tests/portmap.nix | 2 +- tests/proxy.nix | 18 +++++------ tests/quake3.nix | 2 +- tests/subversion.nix | 34 ++++++++++----------- tests/tomcat.nix | 4 +-- tests/trac.nix | 12 ++++---- 19 files changed, 139 insertions(+), 139 deletions(-) diff --git a/tests/avahi.nix b/tests/avahi.nix index f1536f2eafa7..d95361dcd83d 100644 --- a/tests/avahi.nix +++ b/tests/avahi.nix @@ -22,34 +22,34 @@ with pkgs; '' startAll; # mDNS. - $one->waitForJob("network.target"); - $one->mustSucceed("avahi-resolve-host-name one.local | tee out >&2"); - $one->mustSucceed("test \"`cut -f1 < out`\" = one.local"); - $one->mustSucceed("avahi-resolve-host-name two.local | tee out >&2"); - $one->mustSucceed("test \"`cut -f1 < out`\" = two.local"); + $one->waitForUnit("network.target"); + $one->succeed("avahi-resolve-host-name one.local | tee out >&2"); + $one->succeed("test \"`cut -f1 < out`\" = one.local"); + $one->succeed("avahi-resolve-host-name two.local | tee out >&2"); + $one->succeed("test \"`cut -f1 < out`\" = two.local"); - $two->waitForJob("network.target"); - $two->mustSucceed("avahi-resolve-host-name one.local | tee out >&2"); - $two->mustSucceed("test \"`cut -f1 < out`\" = one.local"); - $two->mustSucceed("avahi-resolve-host-name two.local | tee out >&2"); - $two->mustSucceed("test \"`cut -f1 < out`\" = two.local"); + $two->waitForUnit("network.target"); + $two->succeed("avahi-resolve-host-name one.local | tee out >&2"); + $two->succeed("test \"`cut -f1 < out`\" = one.local"); + $two->succeed("avahi-resolve-host-name two.local | tee out >&2"); + $two->succeed("test \"`cut -f1 < out`\" = two.local"); # Basic DNS-SD. - $one->mustSucceed("avahi-browse -r -t _workstation._tcp | tee out >&2"); - $one->mustSucceed("test `wc -l < out` -gt 0"); - $two->mustSucceed("avahi-browse -r -t _workstation._tcp | tee out >&2"); - $two->mustSucceed("test `wc -l < out` -gt 0"); + $one->succeed("avahi-browse -r -t _workstation._tcp | tee out >&2"); + $one->succeed("test `wc -l < out` -gt 0"); + $two->succeed("avahi-browse -r -t _workstation._tcp | tee out >&2"); + $two->succeed("test `wc -l < out` -gt 0"); # More DNS-SD. $one->execute("avahi-publish -s \"This is a test\" _test._tcp 123 one=1 &"); $one->sleep(5); - $two->mustSucceed("avahi-browse -r -t _test._tcp | tee out >&2"); - $two->mustSucceed("test `wc -l < out` -gt 0"); + $two->succeed("avahi-browse -r -t _test._tcp | tee out >&2"); + $two->succeed("test `wc -l < out` -gt 0"); # NSS-mDNS. - $one->mustSucceed("getent hosts one.local >&2"); - $one->mustSucceed("getent hosts two.local >&2"); - $two->mustSucceed("getent hosts one.local >&2"); - $two->mustSucceed("getent hosts two.local >&2"); + $one->succeed("getent hosts one.local >&2"); + $one->succeed("getent hosts two.local >&2"); + $two->succeed("getent hosts one.local >&2"); + $two->succeed("getent hosts two.local >&2"); ''; } diff --git a/tests/bittorrent.nix b/tests/bittorrent.nix index c0cd7cd18437..9e4ee2e06350 100644 --- a/tests/bittorrent.nix +++ b/tests/bittorrent.nix @@ -64,7 +64,7 @@ in startAll; # Enable NAT on the router and start miniupnpd. - $router->waitForJob("nat"); + $router->waitForUnit("nat"); $router->succeed( "iptables -t nat -N MINIUPNPD", "iptables -t nat -A PREROUTING -i eth1 -j MINIUPNPD", @@ -79,7 +79,7 @@ in $tracker->succeed("chmod 644 /tmp/test.torrent"); # Start the tracker. !!! use a less crappy tracker - $tracker->waitForJob("network.target"); + $tracker->waitForUnit("network.target"); $tracker->succeed("bittorrent-tracker --port 6969 --dfile /tmp/dstate >&2 &"); $tracker->waitForOpenPort(6969); @@ -87,8 +87,8 @@ in my $pid = $tracker->succeed("transmission-cli /tmp/test.torrent -M -w /tmp/data >&2 & echo \$!"); # Now we should be able to download from the client behind the NAT. - $tracker->waitForJob("httpd"); - $client1->waitForJob("network.target"); + $tracker->waitForUnit("httpd"); + $client1->waitForUnit("network.target"); $client1->succeed("transmission-cli http://tracker/test.torrent -w /tmp >&2 &"); $client1->waitForFile("/tmp/test.tar.bz2"); $client1->succeed("cmp /tmp/test.tar.bz2 ${file}"); @@ -98,7 +98,7 @@ in # Now download from the second client. This can only succeed if # the first client created a NAT hole in the router. - $client2->waitForJob("network.target"); + $client2->waitForUnit("network.target"); $client2->succeed("transmission-cli http://tracker/test.torrent -M -w /tmp >&2 &"); $client2->waitForFile("/tmp/test.tar.bz2"); $client2->succeed("cmp /tmp/test.tar.bz2 ${file}"); diff --git a/tests/check-filesystems.nix b/tests/check-filesystems.nix index ed4b365b901f..39e8883ee598 100644 --- a/tests/check-filesystems.nix +++ b/tests/check-filesystems.nix @@ -59,22 +59,22 @@ rec { '' startAll; - $share->waitForJob("checkable"); - $fsCheck->waitForJob("checkable"); + $share->waitForUnit("checkable"); + $fsCheck->waitForUnit("checkable"); # check repos1 - $fsCheck->mustSucceed("test -d /repos1"); - $share->mustSucceed("touch /repos1/test1"); - $fsCheck->mustSucceed("test -e /repos1/test1"); + $fsCheck->succeed("test -d /repos1"); + $share->succeed("touch /repos1/test1"); + $fsCheck->succeed("test -e /repos1/test1"); # check repos2 (check after remount) - $fsCheck->mustSucceed("test -d /repos2"); - $share->mustSucceed("touch /repos2/test2"); - $fsCheck->mustSucceed("test -e /repos2/test2"); + $fsCheck->succeed("test -d /repos2"); + $share->succeed("touch /repos2/test2"); + $fsCheck->succeed("test -e /repos2/test2"); # check without network $share->block(); - $fsCheck->mustFail("test -e /repos1/test1"); - $fsCheck->mustFail("test -e /repos2/test2"); + $fsCheck->fail("test -e /repos1/test1"); + $fsCheck->fail("test -e /repos2/test2"); ''; } diff --git a/tests/firewall.nix b/tests/firewall.nix index 316ee439b454..de32b98e5d2f 100644 --- a/tests/firewall.nix +++ b/tests/firewall.nix @@ -25,9 +25,9 @@ '' startAll; - $walled->waitForJob("firewall"); - $walled->waitForJob("httpd"); - $attacker->waitForJob("network.target"); + $walled->waitForUnit("firewall"); + $walled->waitForUnit("httpd"); + $attacker->waitForUnit("network.target"); # Local connections should still work. $walled->succeed("curl -v http://localhost/ >&2"); diff --git a/tests/installer.nix b/tests/installer.nix index 09c51c1e19e9..7e63454dd70c 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -110,24 +110,24 @@ let # Create a channel on the web server containing a few packages # to simulate the Nixpkgs channel. $webserver->start; - $webserver->waitForJob("httpd"); - $webserver->mustSucceed("mkdir /tmp/channel"); - $webserver->mustSucceed( + $webserver->waitForUnit("httpd"); + $webserver->succeed("mkdir /tmp/channel"); + $webserver->succeed( "nix-push file:///tmp/channel " . "http://nixos.org/releases/nixos/channels/nixos-unstable " . "file:///tmp/channel/MANIFEST ${toString channelContents} >&2"); ''} # Make sure that we get a login prompt etc. - $machine->mustSucceed("echo hello"); - $machine->waitForJob("tty1"); - $machine->waitForJob("rogue"); - $machine->waitForJob("nixos-manual"); - $machine->waitForJob("dhcpcd"); + $machine->succeed("echo hello"); + $machine->waitForUnit("tty1"); + $machine->waitForUnit("rogue"); + $machine->waitForUnit("nixos-manual"); + $machine->waitForUnit("dhcpcd"); ${optionalString testChannel '' # Allow the machine to talk to the fake nixos.org. - $machine->mustSucceed( + $machine->succeed( "rm /etc/hosts", "echo 192.168.1.1 nixos.org > /etc/hosts", "ifconfig eth1 up 192.168.1.2", @@ -135,9 +135,9 @@ let ); # Test nix-env. - $machine->mustFail("hello"); - $machine->mustSucceed("nix-env -i hello"); - $machine->mustSucceed("hello") =~ /Hello, world/ + $machine->fail("hello"); + $machine->succeed("nix-env -i hello"); + $machine->succeed("hello") =~ /Hello, world/ or die "bad `hello' output"; ''} @@ -145,12 +145,12 @@ let ${createPartitions} # Create the NixOS configuration. - $machine->mustSucceed( + $machine->succeed( "mkdir -p /mnt/etc/nixos", "nixos-hardware-scan > /mnt/etc/nixos/hardware.nix", ); - my $cfg = $machine->mustSucceed("cat /mnt/etc/nixos/hardware.nix"); + my $cfg = $machine->succeed("cat /mnt/etc/nixos/hardware.nix"); print STDERR "Result of the hardware scan:\n$cfg\n"; $machine->copyFileFromHost( @@ -158,10 +158,10 @@ let "/mnt/etc/nixos/configuration.nix"); # Perform the installation. - $machine->mustSucceed("nixos-install >&2"); + $machine->succeed("nixos-install >&2"); # Do it again to make sure it's idempotent. - $machine->mustSucceed("nixos-install >&2"); + $machine->succeed("nixos-install >&2"); $machine->shutdown; @@ -176,18 +176,18 @@ let $machine->waitForUnit("swap.target"); $machine->succeed("cat /proc/swaps | grep -q /dev"); - $machine->mustSucceed("nix-env -i coreutils >&2"); - $machine->mustSucceed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/ + $machine->succeed("nix-env -i coreutils >&2"); + $machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/ or die "nix-env failed"; - $machine->mustSucceed("nixos-rebuild switch >&2"); + $machine->succeed("nixos-rebuild switch >&2"); $machine->shutdown; # And just to be sure, check that the machine still boots after # "nixos-rebuild switch". my $machine = createMachine({ hda => "harddisk", hdaInterface => "${iface}" }); - $machine->waitForJob("network.target"); + $machine->waitForUnit("network.target"); $machine->shutdown; ''; @@ -211,7 +211,7 @@ in { simple = makeTest { createPartitions = '' - $machine->mustSucceed( + $machine->succeed( "parted /dev/vda mklabel msdos", "parted /dev/vda -- mkpart primary linux-swap 1M 1024M", "parted /dev/vda -- mkpart primary ext2 1024M -1s", @@ -230,7 +230,7 @@ in { separateBoot = makeTest { createPartitions = '' - $machine->mustSucceed( + $machine->succeed( "parted /dev/vda mklabel msdos", "parted /dev/vda -- mkpart primary ext2 1M 50MB", # /boot "parted /dev/vda -- mkpart primary linux-swap 50MB 1024M", @@ -253,7 +253,7 @@ in { lvm = makeTest { createPartitions = '' - $machine->mustSucceed( + $machine->succeed( "parted /dev/vda mklabel msdos", "parted /dev/vda -- mkpart primary 1M 2048M", # first PV "parted /dev/vda -- set 1 lvm on", @@ -276,7 +276,7 @@ in { swraid = makeTest { createPartitions = '' - $machine->mustSucceed( + $machine->succeed( "parted /dev/vda --" . " mklabel msdos" . " mkpart primary ext2 1M 30MB" # /boot @@ -310,7 +310,7 @@ in { grub1 = makeTest { createPartitions = '' - $machine->mustSucceed( + $machine->succeed( "parted /dev/sda mklabel msdos", "parted /dev/sda -- mkpart primary linux-swap 1M 1024M", "parted /dev/sda -- mkpart primary ext2 1024M -1s", @@ -337,19 +337,19 @@ in { $machine->start; # Enable sshd service. - $machine->mustSucceed( + $machine->succeed( "sed -i 's,^}\$,jobs.sshd.startOn = pkgs.lib.mkOverride 0 \"startup\"; },' /etc/nixos/configuration.nix" ); - my $cfg = $machine->mustSucceed("cat /etc/nixos/configuration.nix"); + my $cfg = $machine->succeed("cat /etc/nixos/configuration.nix"); print STDERR "New CD config:\n$cfg\n"; # Apply the new CD configuration. - $machine->mustSucceed("nixos-rebuild test"); + $machine->succeed("nixos-rebuild test"); # Connect to it-self. - #$machine->waitForJob("sshd"); - #$machine->mustSucceed("ssh root@127.0.0.1 echo hello"); + #$machine->waitForUnit("sshd"); + #$machine->succeed("ssh root@127.0.0.1 echo hello"); $machine->shutdown; ''; diff --git a/tests/ipv6.nix b/tests/ipv6.nix index a5f1a65a73d8..29d675e180a3 100644 --- a/tests/ipv6.nix +++ b/tests/ipv6.nix @@ -31,12 +31,12 @@ testScript = '' # Start the router first so that it respond to router solicitations. - $router->waitForJob("radvd"); + $router->waitForUnit("radvd"); startAll; - $client->waitForJob("network.target"); - $server->waitForJob("network.target"); + $client->waitForUnit("network.target"); + $server->waitForUnit("network.target"); # Wait until the given interface has a non-tentative address of # the desired scope (i.e. has completed Duplicate Address diff --git a/tests/kde4.nix b/tests/kde4.nix index afdf1754942b..f435d983791a 100644 --- a/tests/kde4.nix +++ b/tests/kde4.nix @@ -31,7 +31,7 @@ $machine->waitForWindow(qr/plasma-desktop/); # Check that logging in has given the user ownership of devices. - $machine->mustSucceed("getfacl /dev/snd/timer | grep -q alice"); + $machine->succeed("getfacl /dev/snd/timer | grep -q alice"); $machine->execute("su - alice -c 'DISPLAY=:0.0 kwrite /var/log/messages &'"); $machine->execute("su - alice -c 'DISPLAY=:0.0 konqueror http://localhost/ &'"); diff --git a/tests/mpich.nix b/tests/mpich.nix index 0b81bc1d0de0..d57512ebdfed 100644 --- a/tests/mpich.nix +++ b/tests/mpich.nix @@ -24,17 +24,17 @@ with pkgs; '' startAll; - $master->mustSucceed("echo 'MPD_SECRETWORD=secret' > /etc/mpd.conf"); - $master->mustSucceed("chmod 600 /etc/mpd.conf"); - $master->mustSucceed("mpd --daemon --ifhn=master --listenport=4444"); + $master->succeed("echo 'MPD_SECRETWORD=secret' > /etc/mpd.conf"); + $master->succeed("chmod 600 /etc/mpd.conf"); + $master->succeed("mpd --daemon --ifhn=master --listenport=4444"); - $slave->mustSucceed("echo 'MPD_SECRETWORD=secret' > /etc/mpd.conf"); - $slave->mustSucceed("chmod 600 /etc/mpd.conf"); - $slave->mustSucceed("mpd --daemon --host=master --port=4444"); + $slave->succeed("echo 'MPD_SECRETWORD=secret' > /etc/mpd.conf"); + $slave->succeed("chmod 600 /etc/mpd.conf"); + $slave->succeed("mpd --daemon --host=master --port=4444"); - $master->mustSucceed("mpicc -o example -Wall ${./mpich-example.c}"); - $slave->mustSucceed("mpicc -o example -Wall ${./mpich-example.c}"); + $master->succeed("mpicc -o example -Wall ${./mpich-example.c}"); + $slave->succeed("mpicc -o example -Wall ${./mpich-example.c}"); - $master->mustSucceed("mpiexec -n 2 ./example >&2"); + $master->succeed("mpiexec -n 2 ./example >&2"); ''; } diff --git a/tests/mysql-replication.nix b/tests/mysql-replication.nix index 5ac7f0a50978..28a1187dd184 100644 --- a/tests/mysql-replication.nix +++ b/tests/mysql-replication.nix @@ -48,10 +48,10 @@ in testScript = '' startAll; - $master->waitForJob("mysql"); - $master->waitForJob("mysql"); - $slave2->waitForJob("mysql"); + $master->waitForUnit("mysql"); + $master->waitForUnit("mysql"); + $slave2->waitForUnit("mysql"); $slave2->sleep(100); # Hopefully this is long enough!! - $slave2->mustSucceed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); + $slave2->succeed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); ''; } diff --git a/tests/mysql.nix b/tests/mysql.nix index 65785c8fdb50..b48850738b72 100644 --- a/tests/mysql.nix +++ b/tests/mysql.nix @@ -15,8 +15,8 @@ testScript = '' startAll; - $master->waitForJob("mysql"); + $master->waitForUnit("mysql"); $master->sleep(10); # Hopefully this is long enough!! - $master->mustSucceed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); + $master->succeed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); ''; } diff --git a/tests/nat.nix b/tests/nat.nix index ca02fa137d49..e2f01e71b263 100644 --- a/tests/nat.nix +++ b/tests/nat.nix @@ -40,18 +40,18 @@ startAll; # The router should have access to the server. - $server->waitForJob("httpd"); - $router->waitForJob("network.target"); + $server->waitForUnit("httpd"); + $router->waitForUnit("network.target"); $router->succeed("curl --fail http://server/ >&2"); # The client should be also able to connect via the NAT router. - $router->waitForJob("nat"); - $client->waitForJob("network.target"); + $router->waitForUnit("nat"); + $client->waitForUnit("network.target"); $client->succeed("curl --fail http://server/ >&2"); $client->succeed("ping -c 1 server >&2"); # Test whether passive FTP works. - $server->waitForJob("vsftpd"); + $server->waitForUnit("vsftpd"); $server->succeed("echo Hello World > /home/ftp/foo.txt"); $client->succeed("curl -v ftp://server/foo.txt >&2"); diff --git a/tests/nfs.nix b/tests/nfs.nix index d5b6fc0a692d..7c10eec310c1 100644 --- a/tests/nfs.nix +++ b/tests/nfs.nix @@ -34,16 +34,16 @@ in testScript = '' - $server->waitForJob("nfsd"); - $server->waitForJob("network.target"); + $server->waitForUnit("nfsd"); + $server->waitForUnit("network.target"); startAll; - $client1->waitForJob("data.mount"); + $client1->waitForUnit("data.mount"); $client1->succeed("echo bla > /data/foo"); $server->succeed("test -e /data/foo"); - $client2->waitForJob("data.mount"); + $client2->waitForUnit("data.mount"); $client2->succeed("echo bla > /data/bar"); $server->succeed("test -e /data/bar"); @@ -67,7 +67,7 @@ in $client2->waitForFile("locked"); # Test whether locks survive a reboot of the server. - $client1->waitForJob("data.mount"); + $client1->waitForUnit("data.mount"); $server->shutdown; $server->start; $client1->succeed("touch /data/xyzzy"); diff --git a/tests/openssh.nix b/tests/openssh.nix index 734925989a37..16757cf9098e 100644 --- a/tests/openssh.nix +++ b/tests/openssh.nix @@ -20,16 +20,16 @@ my $key=`${pkgs.openssh}/bin/ssh-keygen -t dsa -f key -N ""`; - $server->waitForJob("sshd"); + $server->waitForUnit("sshd"); - $server->mustSucceed("mkdir -m 700 /root/.ssh"); + $server->succeed("mkdir -m 700 /root/.ssh"); $server->copyFileFromHost("key.pub", "/root/.ssh/authorized_keys"); - $client->mustSucceed("mkdir -m 700 /root/.ssh"); + $client->succeed("mkdir -m 700 /root/.ssh"); $client->copyFileFromHost("key", "/root/.ssh/id_dsa"); - $client->mustSucceed("chmod 600 /root/.ssh/id_dsa"); + $client->succeed("chmod 600 /root/.ssh/id_dsa"); - $client->waitForJob("network.target"); - $client->mustSucceed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2"); + $client->waitForUnit("network.target"); + $client->succeed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2"); ''; } diff --git a/tests/portmap.nix b/tests/portmap.nix index 4ee4eb028906..0d2bf1536853 100644 --- a/tests/portmap.nix +++ b/tests/portmap.nix @@ -11,7 +11,7 @@ '' # The `portmap' service must be registered once for TCP and once for # UDP. - $machine->mustSucceed("test `rpcinfo -p | grep portmapper | wc -l` -eq 2"); + $machine->succeed("test `rpcinfo -p | grep portmapper | wc -l` -eq 2"); ''; } diff --git a/tests/proxy.nix b/tests/proxy.nix index 323b548de749..3b79c16ea2c4 100644 --- a/tests/proxy.nix +++ b/tests/proxy.nix @@ -62,33 +62,33 @@ in '' startAll; - $proxy->waitForJob("httpd"); - $backend1->waitForJob("httpd"); - $backend2->waitForJob("httpd"); + $proxy->waitForUnit("httpd"); + $backend1->waitForUnit("httpd"); + $backend2->waitForUnit("httpd"); # With the back-ends up, the proxy should work. - $client->mustSucceed("curl --fail http://proxy/"); + $client->succeed("curl --fail http://proxy/"); - $client->mustSucceed("curl --fail http://proxy/server-status"); + $client->succeed("curl --fail http://proxy/server-status"); # Block the first back-end. $backend1->block; # The proxy should still work. - $client->mustSucceed("curl --fail http://proxy/"); + $client->succeed("curl --fail http://proxy/"); - $client->mustSucceed("curl --fail http://proxy/"); + $client->succeed("curl --fail http://proxy/"); # Block the second back-end. $backend2->block; # Now the proxy should fail as well. - $client->mustFail("curl --fail http://proxy/"); + $client->fail("curl --fail http://proxy/"); # But if the second back-end comes back, the proxy should start # working again. $backend2->unblock; - $client->mustSucceed("curl --fail http://proxy/"); + $client->succeed("curl --fail http://proxy/"); ''; } diff --git a/tests/quake3.nix b/tests/quake3.nix index 796c300423d6..041cfdb29ae4 100644 --- a/tests/quake3.nix +++ b/tests/quake3.nix @@ -45,7 +45,7 @@ rec { '' startAll; - $server->waitForJob("quake3-server"); + $server->waitForUnit("quake3-server"); $client1->waitForX; $client2->waitForX; diff --git a/tests/subversion.nix b/tests/subversion.nix index dc4fe9da4700..309da90c5df1 100644 --- a/tests/subversion.nix +++ b/tests/subversion.nix @@ -66,33 +66,33 @@ in $webserver->waitForOpenPort(80); - print STDERR $client->mustSucceed("svn --version"); + print STDERR $client->succeed("svn --version"); - print STDERR $client->mustSucceed("curl --fail http://webserver/"); + print STDERR $client->succeed("curl --fail http://webserver/"); # Create a new user through the web interface. - $client->mustSucceed("curl --fail -F username=alice -F fullname='Alice Lastname' -F address=alice\@example.org -F password=foobar -F password_again=foobar http://webserver/repoman/adduser"); + $client->succeed("curl --fail -F username=alice -F fullname='Alice Lastname' -F address=alice\@example.org -F password=foobar -F password_again=foobar http://webserver/repoman/adduser"); # Let Alice create a new repository. - $client->mustSucceed("curl --fail -u alice:foobar --form repo=xyzzy --form description=Xyzzy http://webserver/repoman/create"); + $client->succeed("curl --fail -u alice:foobar --form repo=xyzzy --form description=Xyzzy http://webserver/repoman/create"); - $client->mustSucceed("curl --fail http://webserver/") =~ /alice/ or die; + $client->succeed("curl --fail http://webserver/") =~ /alice/ or die; # Let Alice do a checkout. my $svnFlags = "--non-interactive --username alice --password foobar"; - $client->mustSucceed("svn co $svnFlags http://webserver/repos/xyzzy wc"); - $client->mustSucceed("echo hello > wc/world"); - $client->mustSucceed("svn add wc/world"); - $client->mustSucceed("svn ci $svnFlags -m 'Added world.' wc/world"); + $client->succeed("svn co $svnFlags http://webserver/repos/xyzzy wc"); + $client->succeed("echo hello > wc/world"); + $client->succeed("svn add wc/world"); + $client->succeed("svn ci $svnFlags -m 'Added world.' wc/world"); # Create a new user on the server through the create-user.pl script. $webserver->execute("svn-server-create-user.pl bob bob\@example.org Bob"); - $webserver->mustSucceed("svn-server-resetpw.pl bob fnord"); - $client->mustSucceed("curl --fail http://webserver/") =~ /bob/ or die; + $webserver->succeed("svn-server-resetpw.pl bob fnord"); + $client->succeed("curl --fail http://webserver/") =~ /bob/ or die; # Bob should not have access to the repo. my $svnFlagsBob = "--non-interactive --username bob --password fnord"; - $client->mustFail("svn co $svnFlagsBob http://webserver/repos/xyzzy wc2"); + $client->fail("svn co $svnFlagsBob http://webserver/repos/xyzzy wc2"); # Bob should not be able change the ACLs of the repo. # !!! Repoman should really return a 403 here. @@ -100,15 +100,15 @@ in =~ /not authorised/ or die; # Give Bob access. - $client->mustSucceed("curl --fail -u alice:foobar -F description=Xyzzy -F readers=alice,bob -F writers=alice -F watchers= -F tardirs= http://webserver/repoman/update/xyzzy"); + $client->succeed("curl --fail -u alice:foobar -F description=Xyzzy -F readers=alice,bob -F writers=alice -F watchers= -F tardirs= http://webserver/repoman/update/xyzzy"); # So now his checkout should succeed. - $client->mustSucceed("svn co $svnFlagsBob http://webserver/repos/xyzzy wc2"); + $client->succeed("svn co $svnFlagsBob http://webserver/repos/xyzzy wc2"); # Test ViewVC and WebSVN - $client->mustSucceed("curl --fail -u alice:foobar http://webserver/viewvc/xyzzy"); - $client->mustSucceed("curl --fail -u alice:foobar http://webserver/websvn/xyzzy"); - $client->mustSucceed("curl --fail -u alice:foobar http://webserver/repos-xml/xyzzy"); + $client->succeed("curl --fail -u alice:foobar http://webserver/viewvc/xyzzy"); + $client->succeed("curl --fail -u alice:foobar http://webserver/websvn/xyzzy"); + $client->succeed("curl --fail -u alice:foobar http://webserver/repos-xml/xyzzy"); # Stop Apache to gather all the coverage data. $webserver->stopJob("httpd"); diff --git a/tests/tomcat.nix b/tests/tomcat.nix index 3fd99da413c5..c25276aa424e 100644 --- a/tests/tomcat.nix +++ b/tests/tomcat.nix @@ -23,9 +23,9 @@ testScript = '' startAll; - $server->waitForJob("tomcat"); + $server->waitForUnit("tomcat"); $server->sleep(30); # Dirty, but it takes a while before Tomcat handles to requests properly - $client->waitForJob("network.target"); + $client->waitForUnit("network.target"); $client->succeed("curl --fail http://server/examples/servlets/servlet/HelloWorldExample"); $client->succeed("curl --fail http://server/examples/jsp/jsp2/simpletag/hello.jsp"); ''; diff --git a/tests/trac.nix b/tests/trac.nix index a35058a1992f..335d94737047 100644 --- a/tests/trac.nix +++ b/tests/trac.nix @@ -55,15 +55,15 @@ '' startAll; - $postgresql->waitForJob("postgresql"); - $postgresql->mustSucceed("createdb trac"); + $postgresql->waitForUnit("postgresql"); + $postgresql->succeed("createdb trac"); - $webserver->mustSucceed("mkdir -p /repos/trac"); - $webserver->mustSucceed("svnadmin create /repos/trac"); + $webserver->succeed("mkdir -p /repos/trac"); + $webserver->succeed("svnadmin create /repos/trac"); $webserver->waitForFile("/var/trac"); - $webserver->mustSucceed("mkdir -p /var/trac/projects/test"); - $webserver->mustSucceed("PYTHONPATH=${pkgs.pythonPackages.psycopg2}/lib/${pkgs.python.libPrefix}/site-packages trac-admin /var/trac/projects/test initenv Test postgres://root\@postgresql/trac svn /repos/trac"); + $webserver->succeed("mkdir -p /var/trac/projects/test"); + $webserver->succeed("PYTHONPATH=${pkgs.pythonPackages.psycopg2}/lib/${pkgs.python.libPrefix}/site-packages trac-admin /var/trac/projects/test initenv Test postgres://root\@postgresql/trac svn /repos/trac"); $client->waitForX; $client->execute("konqueror http://webserver/projects/test &"); From b43e219aeb42266571797f980c4120ec8960ab1a Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Wed, 24 Oct 2012 19:01:27 +0200 Subject: [PATCH 199/327] modules/services/networking/ssh/sshd.nix: configure AddressFamily properly Explicitly restrict sshd to use of IPv4 addresses if IPv6 support is not enabled. --- modules/services/networking/ssh/sshd.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 90e0ea2f0298..858261bd33e2 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -368,6 +368,7 @@ in UsePAM ${if cfg.usePAM then "yes" else "no"} + AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} ${concatMapStrings (port: '' Port ${toString port} '') cfg.ports} From b3c5d42b1d9881ac9d30aacf2f3a335b60146f48 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 26 Oct 2012 15:15:08 +0200 Subject: [PATCH 200/327] Don't create /var/log/upstart --- modules/system/activation/activation-script.nix | 3 +-- modules/system/boot/stage-2-init.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/system/activation/activation-script.nix b/modules/system/activation/activation-script.nix index 41c3ced1bc27..8d9dcaa17c16 100644 --- a/modules/system/activation/activation-script.nix +++ b/modules/system/activation/activation-script.nix @@ -116,9 +116,8 @@ in # jobs. Used to determine which jobs need to be restarted # when switching to a new configuration. mkdir -m 0700 -p /var/run/upstart-jobs - + mkdir -m 0755 -p /var/log - mkdir -m 0755 -p /var/log/upstart touch /var/log/wtmp # must exist chmod 644 /var/log/wtmp diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 8f1184a5eb36..5168028c1191 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -101,7 +101,7 @@ mkdir -m 0700 -p /var/log/journal # Miscellaneous boot time cleanup. -rm -rf /var/run /var/lock /var/log/upstart +rm -rf /var/run /var/lock rm -f /etc/resolv.conf if test -n "@cleanTmpDir@"; then From 6705358edecde94b14f5bcd0b7ef78dc66daf3bf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 26 Oct 2012 15:15:26 +0200 Subject: [PATCH 201/327] Convert Zabbix agent/server to systemd Note all the crap systemd doesn't need :-) --- modules/services/monitoring/zabbix-agent.nix | 39 ++++--------------- modules/services/monitoring/zabbix-server.nix | 38 +++++------------- 2 files changed, 17 insertions(+), 60 deletions(-) diff --git a/modules/services/monitoring/zabbix-agent.nix b/modules/services/monitoring/zabbix-agent.nix index ce8e1843d4c8..e5e27bb0c9a0 100644 --- a/modules/services/monitoring/zabbix-agent.nix +++ b/modules/services/monitoring/zabbix-agent.nix @@ -73,15 +73,12 @@ in description = "Zabbix daemon user"; }; - jobs.zabbix_agent = - { name = "zabbix-agent"; + boot.systemd.services."zabbix-agent" = + { description = "Zabbix Agent"; - description = "Zabbix agent daemon"; + wantedBy = [ "multi-user.target" ]; - startOn = "ip-up"; - stopOn = "stopping network-interfaces"; - - path = [ pkgs.zabbix.agent ]; + path = [ pkgs.nettools ]; preStart = '' @@ -89,30 +86,10 @@ in chown zabbix ${stateDir} ${logDir} ''; - # Zabbix doesn't have an option not to daemonize, and doesn't - # daemonize in a way that allows Upstart to track it. So to - # make sure that we notice when it goes down, we start Zabbix - # with an open connection to a fifo, with a `cat' on the other - # side. If Zabbix dies, then `cat' will exit as well, so we - # just monitor `cat'. - script = - '' - export PATH=${pkgs.nettools}/bin:$PATH - rm -f ${stateDir}/dummy2 - mkfifo ${stateDir}/dummy2 - cat ${stateDir}/dummy2 & - pid=$! - zabbix_agentd --config ${configFile} 100>${stateDir}/dummy2 - wait "$pid" - ''; - - postStop = - '' - pid=$(cat ${pidFile} 2> /dev/null || true) - (test -n "$pid" && kill "$pid") || true - # Wait until they're really gone. - while ${pkgs.procps}/bin/pgrep -u zabbix zabbix_agentd > /dev/null; do sleep 1; done - ''; + serviceConfig.ExecStart = "@${pkgs.zabbix.agent}/sbin/zabbix_agentd zabbix_agentd --config ${configFile}"; + serviceConfig.Type = "forking"; + serviceConfig.Restart = "always"; + serviceConfig.RestartSec = 2; }; environment.systemPackages = [ pkgs.zabbix.agent ]; diff --git a/modules/services/monitoring/zabbix-server.nix b/modules/services/monitoring/zabbix-server.nix index 57fc69b32709..085fb022c1c9 100644 --- a/modules/services/monitoring/zabbix-server.nix +++ b/modules/services/monitoring/zabbix-server.nix @@ -73,12 +73,11 @@ in description = "Zabbix daemon user"; }; - jobs.zabbix_server = - { name = "zabbix-server"; + boot.systemd.services."zabbix-server" = + { description = "Zabbix Server"; - description = "Zabbix server daemon"; - - startOn = "filesystem"; + wantedBy = [ "multi-user.target" ]; + after = optional (cfg.dbServer == "localhost") "postgresql.service"; preStart = '' @@ -95,31 +94,12 @@ in fi ''; - path = [ pkgs.nettools pkgs.zabbix.server ]; + path = [ pkgs.nettools ]; - # Zabbix doesn't have an option not to daemonize, and doesn't - # daemonize in a way that allows Upstart to track it. So to - # make sure that we notice when it goes down, we start Zabbix - # with an open connection to a fifo, with a `cat' on the other - # side. If Zabbix dies, then `cat' will exit as well, so we - # just monitor `cat'. - script = - '' - rm -f ${stateDir}/dummy - mkfifo ${stateDir}/dummy - cat ${stateDir}/dummy & - pid=$! - zabbix_server --config ${configFile} 100>${stateDir}/dummy - wait "$pid" - ''; - - postStop = - '' - pid=$(cat ${pidFile} 2> /dev/null || true) - (test -n "$pid" && kill "$pid") || true - # Wait until they're really gone. - while ${pkgs.procps}/bin/pkill -u zabbix zabbix_server; do true; done - ''; + serviceConfig.ExecStart = "@${pkgs.zabbix.server}/sbin/zabbix_server zabbix_server --config ${configFile}"; + serviceConfig.Type = "forking"; + serviceConfig.Restart = "always"; + serviceConfig.RestartSec = 2; }; }; From 23390147ea77f30fd4181a48eaca5fb4400bab74 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 26 Oct 2012 16:21:01 +0200 Subject: [PATCH 202/327] upstart.nix: Treat "daemon" as "forking" --- modules/system/upstart/upstart.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 33f2775b496d..cfde1cc07538 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -90,7 +90,7 @@ let // optionalAttrs (job.postStop != "") { ExecStopPost = postStopScript; } // (if job.script == "" && job.exec == "" then { Type = "oneshot"; RemainAfterExit = true; } else - if job.daemonType == "fork" then { Type = "forking"; GuessMainPID = true; } else + if job.daemonType == "fork" || job.daemonType == "daemon" then { Type = "forking"; GuessMainPID = true; } else if job.daemonType == "none" then { } else throw "invalid daemon type `${job.daemonType}'") // optionalAttrs (!job.task && job.respawn) From 65eae4dd34a397237885f7239432297e3ddcd9dc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 26 Oct 2012 16:21:35 +0200 Subject: [PATCH 203/327] Update libvirt for systemd --- modules/virtualisation/libvirtd.nix | 38 +++++++++++------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/modules/virtualisation/libvirtd.nix b/modules/virtualisation/libvirtd.nix index 66bbb757c705..89c4512095db 100644 --- a/modules/virtualisation/libvirtd.nix +++ b/modules/virtualisation/libvirtd.nix @@ -49,11 +49,11 @@ in boot.kernelModules = [ "tun" ]; - jobs.libvirtd = - { description = "Libvirtd virtual machine management daemon"; + boot.systemd.services.libvirtd = + { description = "Libvirt Virtual Machine Management Daemon"; - startOn = "stopped udevtrigger"; - stopOn = ""; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-udev-settle.service" ]; path = [ pkgs.bridge_utils pkgs.dmidecode pkgs.dnsmasq @@ -83,7 +83,9 @@ in done ''; # */ - exec = "${pkgs.libvirt}/sbin/libvirtd --daemon --verbose"; + serviceConfig.ExecStart = "@${pkgs.libvirt}/sbin/libvirtd libvirtd --daemon --verbose"; + serviceConfig.Type = "forking"; + serviceConfig.KillMode = "process"; # when stopping, leave the VMs alone # Wait until libvirtd is ready to accept requests. postStart = @@ -94,18 +96,17 @@ in done exit 1 # !!! seems to be ignored ''; - - daemonType = "daemon"; }; - # !!! Split this into save and restore tasks. jobs."libvirt-guests" = - { description = "Job to save/restore libvirtd VMs"; + { description = "Libvirt Virtual Machines"; - startOn = "started libvirtd"; + wantedBy = [ "multi-user.target" ]; + wants = [ "libvirtd.service" ]; + after = [ "libvirtd.service" ]; # We want to suspend VMs only on shutdown, but Upstart is broken. - stopOn = ""; + #stopOn = ""; restartIfChanged = false; @@ -119,19 +120,8 @@ in postStop = "${pkgs.libvirt}/etc/rc.d/init.d/libvirt-guests stop"; - respawn = false; - }; - - jobs."stop-libvirt" = - { description = "Helper task to stop libvirtd and libvirt-guests on shutdown"; - task = true; - restartIfChanged = false; - startOn = "starting shutdown"; - script = - '' - stop libvirt-guests || true - stop libvirtd || true - ''; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; }; }; From 390f5f7376cad5551f99963bfca1159712e81501 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 26 Oct 2012 19:36:59 +0200 Subject: [PATCH 204/327] Remove the cgroups module Cgroups are handled by systemd now. Systemd's cgroup support does not do all the things that cgrulesengd does, but they're likely to interact poorly with each other. --- modules/module-list.nix | 1 - modules/services/system/cgroups.nix | 146 ---------------------------- 2 files changed, 147 deletions(-) delete mode 100644 modules/services/system/cgroups.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 06c9f8efca70..1f25f2aa1e0b 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -160,7 +160,6 @@ ./services/security/frandom.nix ./services/security/tor.nix ./services/security/torsocks.nix - ./services/system/cgroups.nix ./services/system/dbus.nix ./services/system/kerberos.nix ./services/system/nscd.nix diff --git a/modules/services/system/cgroups.nix b/modules/services/system/cgroups.nix deleted file mode 100644 index 5d5777909e92..000000000000 --- a/modules/services/system/cgroups.nix +++ /dev/null @@ -1,146 +0,0 @@ -{ config, pkgs, ... }: - -with pkgs.lib; - -let - - cfg = config.services.cgroups; - - cgconfigConf = pkgs.writeText "cgconfig.conf" cfg.groups; - - cgrulesConf = pkgs.writeText "cgrules.conf" cfg.rules; - -in - -{ - - ###### interface - - options = { - - services.cgroups.enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable support for control groups, a Linux kernel - feature for resource management. It allows you to assign - processes to groups that share certain resource limits (e.g., - CPU or memory). The cgrulesengd daemon - automatically assigns processes to the right cgroup depending - on the rules defined in - . - ''; - }; - - services.cgroups.groups = mkOption { - type = types.string; - default = - '' - mount { - cpu = /sys/fs/cgroup/cpu; - } - ''; - example = - '' - mount { - cpu = /sys/fs/cgroup/cpu; - cpuacct = /sys/fs/cgroup/cpuacct; - } - - # Create a "www" cgroup with a lower share of the CPU (the - # default is 1024). - group www { - cpu { - cpu.shares = "500"; - } - } - ''; - description = '' - The contents of the cgconfig.conf - configuration file, which defines the cgroups. - ''; - }; - - services.cgroups.rules = mkOption { - type = types.string; - default = ""; - example = - '' - # All processes executed by the "wwwrun" uid should be - # assigned to the "www" CPU cgroup. - wwwrun cpu www - ''; - description = '' - The contents of the cgrules.conf - configuration file, which determines to which cgroups - processes should be assigned by the - cgrulesengd daemon. - ''; - }; - - }; - - - ###### implementation - - config = mkIf cfg.enable { - - environment.systemPackages = [ pkgs.libcgroup ]; - - environment.etc = - [ { source = cgconfigConf; - target = "cgconfig.conf"; - } - { source = cgrulesConf; - target = "cgrules.conf"; - } - ]; - - # The daemon requires the userspace<->kernelspace netlink - # connector. - boot.kernelModules = [ "cn" ]; - - jobs.cgroups = - { startOn = "startup"; - - description = "Control groups daemon"; - - path = [ pkgs.libcgroup pkgs.procps pkgs.utillinux ]; - - preStart = - '' - if [ -d /sys/fs/cgroup ]; then - if ! mountpoint -q /sys/fs/cgroup; then - mount -t tmpfs -o mode=755 /dev/cgroup /sys/fs/cgroup - fi - fi - - cgclear || true - - # Mount the cgroup hierarchies. Note: we refer to the - # store path of cgconfig.conf here to ensure that the job - # gets reloaded if the configuration changes. - cgconfigparser -l ${cgconfigConf} - - # Move existing processes to the right cgroup. - cgclassify --cancel-sticky $(ps --no-headers -eL o tid) || true - - # Force a restart if the rules change: - # ${cgrulesConf} - ''; - - # Run the daemon that moves new processes to the right cgroup. - exec = "cgrulesengd"; - - daemonType = "fork"; - - postStop = - '' - cgclear - ''; - }; - - - }; - -} From ae861c8e336cb7b4e1bb696e95be35c8835c81e4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 29 Oct 2012 12:44:38 +0100 Subject: [PATCH 205/327] Undo accidental commit --- modules/services/printing/cupsd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/printing/cupsd.nix b/modules/services/printing/cupsd.nix index 1e532f578a22..6d31c0050aaf 100644 --- a/modules/services/printing/cupsd.nix +++ b/modules/services/printing/cupsd.nix @@ -138,7 +138,7 @@ in }; services.printing.drivers = - [ pkgs.cups /* pkgs.cups_pdf_filter */ pkgs.ghostscript additionalBackends pkgs.perl pkgs.coreutils pkgs.gnused ]; + [ pkgs.cups pkgs.cups_pdf_filter pkgs.ghostscript additionalBackends pkgs.perl pkgs.coreutils pkgs.gnused ]; services.printing.cupsdConf = '' From 9c74f9a51ba8dbd27de4d36453950997ff551dec Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 29 Oct 2012 17:10:17 +0100 Subject: [PATCH 206/327] modules/programs/ssh.nix: configure AddressFamily properly Explicitly restrict ssh clients to use of IPv4 addresses if IPv6 support is not enabled. --- modules/programs/ssh.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index 5c4b8c3a9a15..123ef3c02567 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -42,6 +42,7 @@ in [ { # SSH configuration. Slight duplication of the sshd_config # generation in the sshd service. source = pkgs.writeText "ssh_config" '' + AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} ${optionalString cfg.setXAuthLocation '' XAuthLocation ${pkgs.xorg.xauth}/bin/xauth ''} From 307644e3b0987cd747fa7869a3f26dfabd642b15 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 29 Oct 2012 17:10:37 +0100 Subject: [PATCH 207/327] modules/programs/ssh.nix: simplify expression that generates 'ForwardX11' entry --- modules/programs/ssh.nix | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index 123ef3c02567..5bbe3a000167 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -46,11 +46,7 @@ in ${optionalString cfg.setXAuthLocation '' XAuthLocation ${pkgs.xorg.xauth}/bin/xauth ''} - ${if cfg.forwardX11 then '' - ForwardX11 yes - '' else '' - ForwardX11 no - ''} + ForwardX11 ${if cfg.forwardX11 then "yes" else "no"} ''; target = "ssh/ssh_config"; } From b1fefb8834f94132106423298079ff66775c1278 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 29 Oct 2012 17:10:46 +0100 Subject: [PATCH 208/327] modules/programs/ssh.nix: strip trailing whitespace --- modules/programs/ssh.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index 5bbe3a000167..fc9ba9a92806 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -34,7 +34,7 @@ in }; }; - assertions = [{ assertion = if cfg.forwardX11 then cfg.setXAuthLocation else true; + assertions = [{ assertion = if cfg.forwardX11 then cfg.setXAuthLocation else true; message = "cannot enable X11 forwarding without setting xauth location";}]; config = { From 47648483141c16efb9887d8af27871cee20d25ad Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 29 Oct 2012 20:29:25 +0100 Subject: [PATCH 209/327] Remove some obsolete options --- modules/services/ttys/agetty.nix | 22 ---------------------- modules/tasks/filesystems.nix | 10 ---------- modules/virtualisation/qemu-vm.nix | 2 -- 3 files changed, 34 deletions(-) diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index f79962c13650..444d04564a97 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -10,28 +10,6 @@ with pkgs.lib; services.mingetty = { - # FIXME - ttys = mkOption { - default = - if pkgs.stdenv.isArm - then [ "ttyS0" ] # presumably an embedded platform such as a plug - else [ "tty1" "tty2" "tty3" "tty4" "tty5" "tty6" ]; - description = '' - The list of tty devices on which to start a login prompt. - ''; - }; - - # FIXME: not implemented with systemd - waitOnMounts = mkOption { - default = false; - description = '' - Whether the login prompts on the virtual consoles will be - started before or after all file systems have been mounted. By - default we don't wait, but if for example your /home is on a - separate partition, you may want to turn this on. - ''; - }; - greetingLine = mkOption { default = ''<<< Welcome to NixOS ${config.system.nixosVersion} (\m) - \l >>>''; description = '' diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 77a43ed15dba..774021d0d865 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -145,16 +145,6 @@ 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. - ''; - }; }; diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index ec11f3604e7d..e3927442821e 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -396,8 +396,6 @@ in VertRefresh 50-160 ''; - services.mingetty.ttys = ttys ++ optional (!cfg.graphics) "ttyS0"; - # Wireless won't work in the VM. networking.wireless.enable = mkOverride 50 false; From 1a82024dd868970143a85e3148d3504dfd8dce61 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 29 Oct 2012 21:01:36 +0100 Subject: [PATCH 210/327] In the tests, don't start agetty on /dev/ttyS0 Running agetty on ttyS0 interferes with the backdoor, which uses ttyS0 as its standard error. After agetty starts, writes to the stderr file descriptor will return EIO (though doing "exec 2>/proc/self/fd/2" will miracuously fix this). http://hydra.nixos.org/build/3252782 --- modules/system/boot/systemd-unit-options.nix | 11 +++++++++ modules/system/boot/systemd.nix | 25 ++++++++++++++++---- modules/testing/test-instrumentation.nix | 12 ++++++---- tests/nat.nix | 3 ++- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 239c837c6767..5707fb6f87e9 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -6,6 +6,17 @@ rec { unitOptions = { + enable = mkOption { + default = true; + types = types.bool; + description = '' + If set to false, this unit will be a symlink to + /dev/null. This is primarily useful to prevent specific + template instances (e.g. serial-getty@ttyS0) + from being started. + ''; + }; + description = mkOption { default = ""; types = types.uniq types.string; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index dc0c2ba4504b..aa0b679ea2f5 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -10,7 +10,14 @@ let systemd = pkgs.systemd; makeUnit = name: unit: - pkgs.writeTextFile { name = "unit"; inherit (unit) text; destination = "/${name}"; }; + pkgs.runCommand "unit" { inherit (unit) text; } + (if unit.enable then '' + mkdir -p $out + echo -n "$text" > $out/${name} + '' else '' + mkdir -p $out + ln -s /dev/null $out/${name} + ''); upstreamUnits = [ # Targets. @@ -205,7 +212,7 @@ let as)); targetToUnit = name: def: - { inherit (def) wantedBy; + { inherit (def) wantedBy enable; text = '' [Unit] @@ -214,7 +221,7 @@ let }; serviceToUnit = name: def: - { inherit (def) wantedBy; + { inherit (def) wantedBy enable; text = '' [Unit] @@ -258,7 +265,7 @@ let }; socketToUnit = name: def: - { inherit (def) wantedBy; + { inherit (def) wantedBy enable; text = '' [Unit] @@ -333,6 +340,16 @@ in types = types.uniq types.string; description = "Text of this systemd unit."; }; + enable = mkOption { + default = true; + types = types.bool; + description = '' + If set to false, this unit will be a symlink to + /dev/null. This is primarily useful to prevent specific + template instances (e.g. serial-getty@ttyS0) + from being started. + ''; + }; wantedBy = mkOption { default = []; types = types.listOf types.string; diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index efce3153c88e..222a10a00435 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -13,9 +13,8 @@ let kernel = config.boot.kernelPackages.kernel; in boot.systemd.services.backdoor = { wantedBy = [ "multi-user.target" ]; - requires = [ "dev-hvc0.device" ]; - after = [ "dev-hvc0.device" ]; - + requires = [ "dev-hvc0.device" "dev-ttyS0.device" ]; + after = [ "dev-hvc0.device" "dev-ttyS0.device" ]; script = '' export USER=root @@ -27,10 +26,15 @@ let kernel = config.boot.kernelPackages.kernel; in echo "connecting to host..." >&2 stty -F /dev/hvc0 raw -echo # prevent nl -> cr/nl conversion echo - PS1= /bin/sh + PS1= exec /bin/sh ''; }; + # Prevent agetty from being instantiated on ttyS0, since it + # interferes with the backdoor (writes to ttyS0 will randomly fail + # with EIO). + boot.systemd.services."serial-getty@ttyS0".enable = false; + boot.initrd.postDeviceCommands = '' # Using acpi_pm as a clock source causes the guest clock to diff --git a/tests/nat.nix b/tests/nat.nix index e2f01e71b263..7b03739a9bc4 100644 --- a/tests/nat.nix +++ b/tests/nat.nix @@ -40,6 +40,7 @@ startAll; # The router should have access to the server. + $server->waitForUnit("network.target"); $server->waitForUnit("httpd"); $router->waitForUnit("network.target"); $router->succeed("curl --fail http://server/ >&2"); @@ -68,7 +69,7 @@ $client->fail("ping -c 1 server >&2"); # And make sure that restarting the NAT job works. - $router->succeed("start nat"); + $router->succeed("systemctl start nat"); $client->succeed("curl --fail http://server/ >&2"); $client->succeed("ping -c 1 server >&2"); ''; From 88a9d7a9ca476ba8d686a6e7427d0f176ebf13b1 Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Tue, 30 Oct 2012 13:33:37 +0100 Subject: [PATCH 211/327] Added environment.promptInit to allow PS1 overriding. Would be nicer to be able to allow overriding via shellInit, however could not get that to work. For now this is a temporary solution which will not break anything. --- modules/programs/bash/bash.nix | 18 +++++++++++++++++- modules/programs/bash/bashrc.sh | 9 +-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 441d30f1e9fa..135d99ec437f 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -25,9 +25,24 @@ let fi ''; - options = { + environment.promptInit = mkOption { + default = '' + # Provide a nice prompt. + PROMPT_COLOR="1;31m" + let $UID && PROMPT_COLOR="1;32m" + PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " + if test "$TERM" = "xterm"; then + PS1="\[\033]2;\h:\u:\w\007\]$PS1" + fi + ''; + description = " + Script used to initialized shell prompt. + "; + type = with pkgs.lib.types; string; + }; + environment.shellInit = mkOption { default = ""; example = ''export PATH=/godi/bin/:$PATH''; @@ -65,6 +80,7 @@ in # configured properly. source = pkgs.substituteAll { src = ./bashrc.sh; + inherit (config.environment) promptInit; inherit initBashCompletion; }; target = "bashrc"; diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index 10a36ede2a38..3542b5f9fd49 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -19,14 +19,7 @@ if [ -z "$PS1" ]; then return; fi # Check the window size after every command. shopt -s checkwinsize -# Provide a nice prompt. -PROMPT_COLOR="1;31m" -let $UID && PROMPT_COLOR="1;32m" -PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " -if test "$TERM" = "xterm"; then - PS1="\[\033]2;\h:\u:\w\007\]$PS1" -fi - +@promptInit@ @initBashCompletion@ # Some aliases. From 4143ff228055022289b837a42ac50ccbff0d18c4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 30 Oct 2012 13:52:12 +0100 Subject: [PATCH 212/327] In headless deployments, don't start agetty on the console --- modules/profiles/headless.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/profiles/headless.nix b/modules/profiles/headless.nix index ac0c4059634e..3446654bc6f5 100644 --- a/modules/profiles/headless.nix +++ b/modules/profiles/headless.nix @@ -10,7 +10,10 @@ with pkgs.lib; boot.vesa = false; boot.initrd.enableSplashScreen = false; services.ttyBackgrounds.enable = false; - services.mingetty.ttys = [ ]; + + # Don't start a tty on the serial consoles. + boot.systemd.services."serial-getty@ttyS0".enable = false; + boot.systemd.services."serial-getty@hvc0".enable = false; # Since we can't manually respond to a panic, just reboot. boot.kernelParams = [ "panic=1" "stage1panic=1" ]; From 2b19856f40917b6a14f9f03aed7f2ae92ffdf99a Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Tue, 30 Oct 2012 14:09:30 +0100 Subject: [PATCH 213/327] Logstash: do not always log to stdout --- modules/services/logging/logstash.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/services/logging/logstash.nix b/modules/services/logging/logstash.nix index f4c226ac3498..641520ad98d9 100644 --- a/modules/services/logging/logstash.nix +++ b/modules/services/logging/logstash.nix @@ -136,9 +136,6 @@ in mkNameValuePairs = mergeConfigs; }; } ( mkIf cfg.enable { - # Always log to stdout - services.logstash.outputConfig = { stdout = {}; }; - jobs.logstash = with pkgs; { description = "Logstash daemon"; startOn = "started networking and filesystem"; From 631fce3c6f46a3fbc8ed69e01cb45a3197f220cd Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Tue, 30 Oct 2012 14:18:51 +0100 Subject: [PATCH 214/327] Logstash: pass TZ, redirect log output to prevent recursion when using syslogd. --- modules/services/logging/logstash.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/services/logging/logstash.nix b/modules/services/logging/logstash.nix index 641520ad98d9..2f6c6dba9431 100644 --- a/modules/services/logging/logstash.nix +++ b/modules/services/logging/logstash.nix @@ -136,13 +136,15 @@ in mkNameValuePairs = mergeConfigs; }; } ( mkIf cfg.enable { - jobs.logstash = with pkgs; { + boot.systemd.services.logstash = with pkgs; { description = "Logstash daemon"; - startOn = "started networking and filesystem"; + + wantedBy = [ "multi-user.target" ]; + environment.TZ = config.time.timeZone; path = [ jre ]; - script = "cd /tmp && exec java -jar ${logstash} agent -f ${writeText "logstash.conf" '' + script = "cd /tmp && exec java -jar ${logstash} agent -f ${writeText "logstash.conf" &> /var/log/logstash.log '' input { ${exprToConfig cfg.inputConfig} } From 8caceffae8b09d07b88ef1fb9e3f47235b2ff524 Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Tue, 30 Oct 2012 14:22:14 +0100 Subject: [PATCH 215/327] Logstash: fix typo, should have tested. --- modules/services/logging/logstash.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/services/logging/logstash.nix b/modules/services/logging/logstash.nix index 2f6c6dba9431..bc44620d6442 100644 --- a/modules/services/logging/logstash.nix +++ b/modules/services/logging/logstash.nix @@ -144,7 +144,7 @@ in path = [ jre ]; - script = "cd /tmp && exec java -jar ${logstash} agent -f ${writeText "logstash.conf" &> /var/log/logstash.log '' + script = "cd /tmp && exec java -jar ${logstash} agent -f ${writeText "logstash.conf" '' input { ${exprToConfig cfg.inputConfig} } @@ -156,7 +156,7 @@ in output { ${exprToConfig cfg.outputConfig} } - ''}"; + ''} &> /var/log/logstash.log"; }; })]; } From 7a76bcd72aa078680e8890269d7d29603b250988 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 30 Oct 2012 14:39:00 +0100 Subject: [PATCH 216/327] Fix the installer test http://hydra.nixos.org/build/3253038 --- tests/installer.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/installer.nix b/tests/installer.nix index 7e63454dd70c..7952e295794d 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -120,7 +120,7 @@ let # Make sure that we get a login prompt etc. $machine->succeed("echo hello"); - $machine->waitForUnit("tty1"); + $machine->waitForUnit('getty@tty2'); $machine->waitForUnit("rogue"); $machine->waitForUnit("nixos-manual"); $machine->waitForUnit("dhcpcd"); From bcdc71ddaed97c2b7e627c7c9d601c262bce9e4e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 30 Oct 2012 16:42:05 +0100 Subject: [PATCH 217/327] Kill the backdoor more forcefully Otherwise it hangs until the 90 second timeout expires. http://hydra.nixos.org/build/3253068 --- modules/testing/test-instrumentation.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 222a10a00435..c6c95e63af1b 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -28,6 +28,7 @@ let kernel = config.boot.kernelPackages.kernel; in echo PS1= exec /bin/sh ''; + serviceConfig.KillSignal = "SIGHUP"; }; # Prevent agetty from being instantiated on ttyS0, since it From e5d4524dda10b50f42c0c3350567170dcd67f3aa Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 30 Oct 2012 17:01:21 +0100 Subject: [PATCH 218/327] Test driver: Don't wait for a reply after issuing "poweroff" --- lib/test-driver/Machine.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm index d376bd404b97..1f7533f22f8f 100644 --- a/lib/test-driver/Machine.pm +++ b/lib/test-driver/Machine.pm @@ -434,7 +434,7 @@ sub shutdown { my ($self) = @_; return unless $self->{booted}; - $self->execute("poweroff"); + print { $self->{socket} } ("poweroff\n"); $self->waitForShutdown; } From 1da362b34b0dbe3245273a56a3152230484089b0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 30 Oct 2012 17:27:14 +0100 Subject: [PATCH 219/327] Fix coverage data collection http://hydra.nixos.org/build/3253046 --- modules/system/boot/systemd.nix | 12 +++++++++++- modules/system/upstart/upstart.nix | 11 +---------- modules/testing/test-instrumentation.nix | 6 +----- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index aa0b679ea2f5..2413509790d3 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -229,7 +229,8 @@ let [Service] Environment=PATH=${def.path} - ${concatMapStrings (n: "Environment=${n}=${getAttr n def.environment}\n") (attrNames def.environment)} + ${let env = cfg.globalEnvironment // def.environment; + in concatMapStrings (n: "Environment=${n}=${getAttr n env}\n") (attrNames env)} ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"} ${optionalString (def.preStart != "") '' @@ -391,6 +392,15 @@ in description = "Default unit started when the system boots."; }; + boot.systemd.globalEnvironment = mkOption { + type = types.attrs; + default = {}; + example = { TZ = "CET"; }; + description = '' + Environment variables passed to all systemd units. + ''; + }; + services.journald.console = mkOption { default = ""; type = types.uniq types.string; diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index cfde1cc07538..44e6e8bb63b5 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -19,7 +19,7 @@ let let hasMain = job.script != "" || job.exec != ""; - env = config.system.upstartEnvironment // job.environment; + env = job.environment; preStartScript = makeJobScript "${job.name}-pre-start" '' @@ -270,15 +270,6 @@ in options = [ jobOptions upstartJob ]; }; - system.upstartEnvironment = mkOption { - type = types.attrs; - default = {}; - example = { TZ = "CET"; }; - description = '' - Environment variables passed to all Upstart jobs. - ''; - }; - }; diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index c6c95e63af1b..8ceffbcb9ec6 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -55,10 +55,6 @@ let kernel = config.boot.kernelPackages.kernel; in # Coverage data is written into /tmp/coverage-data. mkdir -p /tmp/xchg/coverage-data - - # Mount debugfs to gain access to the kernel coverage data (if - # available). - mount -t debugfs none /sys/kernel/debug || true ''; # If the kernel has been built with coverage instrumentation, make @@ -80,7 +76,7 @@ let kernel = config.boot.kernelPackages.kernel; in networking.defaultGateway = mkOverride 150 ""; networking.nameservers = mkOverride 150 [ ]; - system.upstartEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data"; + boot.systemd.globalEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data"; system.requiredKernelConfig = with config.lib.kernelConfig; [ (isYes "SERIAL_8250_CONSOLE") From f293455474b0144cf9821244cc44a550670aea01 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 31 Oct 2012 14:24:22 +0100 Subject: [PATCH 220/327] dhcpcd: Don't duplicate log messages Dhcpcd writes log messages to both syslog and stderr. So ignore stderr. --- modules/services/networking/dhcpcd.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index f2300a9529d8..3abd77c8eeb0 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -103,6 +103,7 @@ in PIDFile = "/run/dhcpcd.pid"; ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}"; ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind"; + StandardError = "null"; }; }; From 1860badbebe7b230f0bff78ecd2ddddb39daecf8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 31 Oct 2012 14:24:51 +0100 Subject: [PATCH 221/327] dhcpcd: Go into the background immediately --- modules/services/networking/dhcpcd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 3abd77c8eeb0..f9d588ea5483 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -101,7 +101,7 @@ in serviceConfig = { Type = "forking"; PIDFile = "/run/dhcpcd.pid"; - ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}"; + ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf} --background"; ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind"; StandardError = "null"; }; From dd7edefb2ce74ce6543b183f22ecb803600e33d5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 31 Oct 2012 14:49:09 +0100 Subject: [PATCH 222/327] Order mkfs services before the corresponding fsck services --- modules/tasks/filesystems.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 774021d0d865..66c97c5fd112 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -188,7 +188,7 @@ in in nameValuePair "mkfs-${device'}" { description = "Initialisation of Filesystem ${fs.device}"; wantedBy = [ "${mountPoint'}.mount" ]; - before = [ "${mountPoint'}.mount" ]; + before = [ "${mountPoint'}.mount" "systemd-fsck@${device'}.service" ]; require = [ "${device'}.device" ]; after = [ "${device'}.device" ]; path = [ pkgs.utillinux ] ++ config.system.fsPackages; From 48a0ea0513146b8696fa9ef2fd65752336bf1a7c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 1 Nov 2012 23:32:12 +0100 Subject: [PATCH 223/327] =?UTF-8?q?Make=20Apache=20wait=20for=20=E2=80=98c?= =?UTF-8?q?haron=20send-keys=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (This is a no-op on non-Charon deployments since the ‘keys.target’ unit won't have any dependencies.) --- .../web-servers/apache-httpd/default.nix | 16 ++++++---------- modules/system/boot/systemd.nix | 5 +++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index ab55e43405ba..8e4a516ea134 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -580,11 +580,12 @@ in date.timezone = "${config.time.timeZone}" ''; - jobs.httpd = + boot.systemd.services.httpd = { description = "Apache HTTPD"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" "fs.target" "postgresql.service" ]; + requires = [ "keys.target" ]; + after = [ "network.target" "fs.target" "postgresql.service" "keys.target" ]; path = [ httpd pkgs.coreutils pkgs.gnugrep ] @@ -596,9 +597,7 @@ in environment = { PHPRC = if enablePHP then phpIni else ""; - TZ = config.time.timeZone; - } // (listToAttrs (concatMap (svc: svc.globalEnvVars) allSubservices)); preStart = @@ -628,12 +627,9 @@ in done ''; - exec = "httpd -f ${httpdConf} -DNO_DETACH"; - - preStop = - '' - ${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop - ''; + serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf} -DNO_DETACH"; + serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop"; + serviceConfig.Restart = "always"; }; }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 2413509790d3..6992299cc88c 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -442,6 +442,11 @@ in } ]; + # Target for ‘charon send-keys’ to hook into. + boot.systemd.targets.keys = + { description = "Security Keys"; + }; + boot.systemd.units = { "rescue.service".text = rescueService; } // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets From af4e176c12f62a88bddc880b770a67d861af243a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Nov 2012 14:10:06 +0100 Subject: [PATCH 224/327] Fix description --- modules/system/boot/systemd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 6992299cc88c..340a6d80c1c7 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -404,7 +404,7 @@ in services.journald.console = mkOption { default = ""; type = types.uniq types.string; - description = "If non-empty, write log messages to the specified TTY device. Defaults to /dev/console."; + description = "If non-empty, write log messages to the specified TTY device."; }; }; From 6ae0b3beed250f014d0d499d04ab59fa2ea3eb76 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Nov 2012 14:20:05 +0100 Subject: [PATCH 225/327] dhcpcd: Don't use --background so that fetch-ec2-data can be ordered after it --- modules/services/networking/dhcpcd.nix | 2 +- modules/virtualisation/ec2-data.nix | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index f9d588ea5483..3abd77c8eeb0 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -101,7 +101,7 @@ in serviceConfig = { Type = "forking"; PIDFile = "/run/dhcpcd.pid"; - ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf} --background"; + ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}"; ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind"; StandardError = "null"; }; diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix index 2f58a9694921..3f005d6eb2d5 100644 --- a/modules/virtualisation/ec2-data.nix +++ b/modules/virtualisation/ec2-data.nix @@ -13,6 +13,7 @@ with pkgs.lib; wantedBy = [ "multi-user.target" ]; before = [ "sshd.service" ]; + after = [ "dhcpcd.service" ]; path = [ pkgs.curl pkgs.iproute ]; From 67de234e1ca96eda70114a90b399230837363548 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Nov 2012 17:05:30 +0100 Subject: [PATCH 226/327] wpa_supplicant.nix: Slightly improve descriptions --- modules/services/networking/wpa_supplicant.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/services/networking/wpa_supplicant.nix b/modules/services/networking/wpa_supplicant.nix index c6b7df38fcfc..b338e08113e5 100644 --- a/modules/services/networking/wpa_supplicant.nix +++ b/modules/services/networking/wpa_supplicant.nix @@ -53,7 +53,7 @@ in driver = mkOption { default = ""; example = "nl80211"; - description = "force a specific wpa_supplicant driver"; + description = "Force a specific wpa_supplicant driver."; }; userControlled = { @@ -66,7 +66,7 @@ in When you want to use this, make sure ${configFile} doesn't exist. It will be created for you. - Currently it is also necesarry to explicitly specify networking.wireless.interfaces + Currently it is also necessary to explicitly specify networking.wireless.interfaces. ''; }; @@ -74,7 +74,7 @@ in default = "wheel"; example = "network"; type = types.string; - description = "members of this group can control wpa_supplicant"; + description = "Members of this group can control wpa_supplicant."; }; }; }; From 93f82dfeefe2d13d83acd4a70f1c7c1f20054931 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Nov 2012 17:07:53 +0100 Subject: [PATCH 227/327] Remove outdated comment about EC2 booting into stage-2 directly --- modules/system/boot/stage-2-init.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 5168028c1191..67a4e0ed16d0 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -25,9 +25,8 @@ setPath "@path@" # Normally, stage 1 mounts the root filesystem read/writable. -# However, in some environments (such as Amazon EC2), stage 2 is -# executed directly, and the root is read-only. So make it writable -# here. +# However, in some environments, stage 2 is executed directly, and the +# root is read-only. So make it writable here. mount -n -o remount,rw / From 97f087cd447ef773cd15c6750df5aa24c633ea25 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Nov 2012 17:08:11 +0100 Subject: [PATCH 228/327] Turn networking.interfaces into an attribute set Thus networking.interfaces = [ { name = "eth0"; ipAddress = "192.168.15.1"; } ]; can now be written as networking.interfaces.eth0.ipAddress = "192.168.15.1"; The old notation still works though. --- lib/build-vms.nix | 40 +++-- modules/programs/virtualbox.nix | 2 +- modules/services/networking/dhcpcd.nix | 3 +- modules/tasks/network-interfaces.nix | 228 ++++++++++++------------- modules/virtualisation/ec2-data.nix | 2 +- tests/bittorrent.nix | 4 +- tests/nat.nix | 2 +- 7 files changed, 138 insertions(+), 143 deletions(-) diff --git a/lib/build-vms.nix b/lib/build-vms.nix index aacd0e99cb18..59f05bfd1043 100644 --- a/lib/build-vms.nix +++ b/lib/build-vms.nix @@ -2,7 +2,7 @@ let pkgs = import { config = {}; inherit system; }; in -with pkgs; +with pkgs.lib; with import ../lib/qemu-flags.nix; rec { @@ -15,7 +15,7 @@ rec { # hostname and `configX' is a NixOS system configuration. Each # machine is given an arbitrary IP address in the virtual network. buildVirtualNetwork = - nodes: let nodesOut = lib.mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut; + nodes: let nodesOut = mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut; buildVM = @@ -27,7 +27,7 @@ rec { [ ../modules/virtualisation/qemu-vm.nix ../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs { key = "no-manual"; services.nixosManual.enable = false; } - ] ++ lib.optional minimal ../modules/testing/minimal-kernel.nix; + ] ++ optional minimal ../modules/testing/minimal-kernel.nix; extraArgs = { inherit nodes; }; }; @@ -39,51 +39,49 @@ rec { let - machines = lib.attrNames nodes; + machines = attrNames nodes; - machinesNumbered = lib.zipTwoLists machines (lib.range 1 254); + machinesNumbered = zipTwoLists machines (range 1 254); - nodes_ = lib.flip map machinesNumbered (m: lib.nameValuePair m.first + nodes_ = flip map machinesNumbered (m: nameValuePair m.first [ ( { config, pkgs, nodes, ... }: let - interfacesNumbered = lib.zipTwoLists config.virtualisation.vlans (lib.range 1 255); - interfaces = - lib.flip map interfacesNumbered ({ first, second }: - { name = "eth${toString second}"; - ipAddress = "192.168.${toString first}.${toString m.second}"; + interfacesNumbered = zipTwoLists config.virtualisation.vlans (range 1 255); + interfaces = flip map interfacesNumbered ({ first, second }: + nameValuePair "eth${toString second}" + { ipAddress = "192.168.${toString first}.${toString m.second}"; subnetMask = "255.255.255.0"; - } - ); + }); in { key = "ip-address"; config = { networking.hostName = m.first; - networking.interfaces = interfaces; + networking.interfaces = listToAttrs interfaces; networking.primaryIPAddress = - lib.optionalString (interfaces != []) (lib.head interfaces).ipAddress; + optionalString (interfaces != []) (head interfaces).value.ipAddress; # Put the IP addresses of all VMs in this machine's # /etc/hosts file. If a machine has multiple # interfaces, use the IP address corresponding to # the first interface (i.e. the first network in its # virtualisation.vlans option). - networking.extraHosts = lib.flip lib.concatMapStrings machines - (m: let config = (lib.getAttr m nodes).config; in - lib.optionalString (config.networking.primaryIPAddress != "") + networking.extraHosts = flip concatMapStrings machines + (m: let config = (getAttr m nodes).config; in + optionalString (config.networking.primaryIPAddress != "") ("${config.networking.primaryIPAddress} " + "${config.networking.hostName}\n")); virtualisation.qemu.options = - lib.flip map interfacesNumbered + flip map interfacesNumbered ({ first, second }: qemuNICFlags second first m.second); }; } ) - (lib.getAttr m.first nodes) + (getAttr m.first nodes) ] ); - in lib.listToAttrs nodes_; + in listToAttrs nodes_; } diff --git a/modules/programs/virtualbox.nix b/modules/programs/virtualbox.nix index 7bce11ab8553..a7c41d915ecd 100644 --- a/modules/programs/virtualbox.nix +++ b/modules/programs/virtualbox.nix @@ -37,5 +37,5 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in ''; }; - networking.interfaces = [ { name = "vboxnet0"; ipAddress = "192.168.56.1"; prefixLength = 24; } ]; + networking.interfaces.vboxnet0 = { ipAddress = "192.168.56.1"; prefixLength = 24; }; } diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 3abd77c8eeb0..6c8194f09719 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -9,7 +9,7 @@ let # Don't start dhclient on explicitly configured interfaces or on # interfaces that are part of a bridge. ignoredInterfaces = - map (i: i.name) (filter (i: i ? ipAddress && i.ipAddress != "" ) config.networking.interfaces) + map (i: i.name) (filter (i: i.ipAddress != null) (attrValues config.networking.interfaces)) ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges)) ++ config.networking.dhcpcd.denyInterfaces; @@ -104,6 +104,7 @@ in ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}"; ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind"; StandardError = "null"; + Restart = "always"; }; }; diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index d36a1081de5f..412e62bfe80c 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -5,7 +5,104 @@ with pkgs.lib; let cfg = config.networking; - hasVirtuals = any (i: i.virtual) cfg.interfaces; + interfaces = attrValues cfg.interfaces; + hasVirtuals = any (i: i.virtual) interfaces; + + interfaceOpts = { name, ... }: { + + options = { + + name = mkOption { + example = "eth0"; + type = types.string; + description = "Name of the interface."; + }; + + ipAddress = mkOption { + default = null; + example = "10.0.0.1"; + type = types.nullOr types.string; + description = '' + IP address of the interface. Leave empty to configure the + interface using DHCP. + ''; + }; + + prefixLength = mkOption { + default = null; + example = 24; + type = types.nullOr types.int; + description = '' + Subnet mask of the interface, specified as the number of + bits in the prefix (24). + ''; + }; + + subnetMask = mkOption { + default = ""; + example = "255.255.255.0"; + type = types.string; + description = '' + Subnet mask of the interface, specified as a bitmask. + This is deprecated; use + instead. + ''; + }; + + macAddress = mkOption { + default = null; + example = "00:11:22:33:44:55"; + type = types.nullOr types.string; + description = '' + MAC address of the interface. Leave empty to use the default. + ''; + }; + + virtual = mkOption { + default = false; + type = types.bool; + description = '' + Whether this interface is virtual and should be created by tunctl. + This is mainly useful for creating bridges between a host a virtual + network such as VPN or a virtual machine. + + Defaults to tap device, unless interface contains "tun" in its name. + ''; + }; + + virtualOwner = mkOption { + default = "root"; + type = types.uniq types.string; + description = '' + In case of a virtual device, the user who owns it. + ''; + }; + + proxyARP = mkOption { + default = false; + type = types.bool; + description = '' + Turn on proxy_arp for this device (and proxy_ndp for ipv6). + This is mainly useful for creating pseudo-bridges between a real + interface and a virtual network such as VPN or a virtual machine for + interfaces that don't support real bridging (most wlan interfaces). + As ARP proxying acts slightly above the link-layer, below-ip traffic + isn't bridged, so things like DHCP won't work. The advantage above + using NAT lies in the fact that no IP addresses are shared, so all + hosts are reachable/routeable. + + WARNING: turns on ip-routing, so if you have multiple interfaces, you + should think of the consequence and setup firewall rules to limit this. + ''; + }; + + }; + + config = { + name = mkDefault name; + }; + + }; in @@ -66,121 +163,20 @@ in }; networking.interfaces = mkOption { - default = []; - example = [ - { name = "eth0"; - ipAddress = "131.211.84.78"; - subnetMask = "255.255.255.128"; - } - ]; + default = {}; + example = + { eth0 = { + ipAddress = "131.211.84.78"; + subnetMask = "255.255.255.128"; + }; + }; description = '' The configuration for each network interface. If is true, then every interface not listed here will be configured using DHCP. ''; - - type = types.list types.optionSet; - - options = { - - name = mkOption { - example = "eth0"; - type = types.string; - description = '' - Name of the interface. - ''; - }; - - ipAddress = mkOption { - default = ""; - example = "10.0.0.1"; - type = types.string; - description = '' - IP address of the interface. Leave empty to configure the - interface using DHCP. - ''; - }; - - prefixLength = mkOption { - default = null; - example = 24; - type = types.nullOr types.int; - description = '' - Subnet mask of the interface, specified as the number of - bits in the prefix (24). - ''; - }; - - subnetMask = mkOption { - default = ""; - example = "255.255.255.0"; - type = types.string; - description = '' - Subnet mask of the interface, specified as a bitmask. - This is deprecated; use - instead. - ''; - }; - - macAddress = mkOption { - default = ""; - example = "00:11:22:33:44:55"; - type = types.string; - description = '' - MAC address of the interface. Leave empty to use the default. - ''; - }; - - virtual = mkOption { - default = false; - type = types.bool; - description = '' - Whether this interface is virtual and should be created by tunctl. - This is mainly useful for creating bridges between a host a virtual - network such as VPN or a virtual machine. - - Defaults to tap device, unless interface contains "tun" in its name. - ''; - }; - - virtualOwner = mkOption { - default = "root"; - type = types.uniq types.string; - description = '' - In case of a virtual device, the user who owns it. - ''; - }; - - proxyARP = mkOption { - default = false; - type = types.bool; - description = '' - Turn on proxy_arp for this device (and proxy_ndp for ipv6). - This is mainly useful for creating pseudo-bridges between a real - interface and a virtual network such as VPN or a virtual machine for - interfaces that don't support real bridging (most wlan interfaces). - As ARP proxying acts slightly above the link-layer, below-ip traffic - isn't bridged, so things like DHCP won't work. The advantage above - using NAT lies in the fact that no IP addresses are shared, so all - hosts are reachable/routeable. - - WARNING: turns on ip-routing, so if you have multiple interfaces, you - should think of the consequence and setup firewall rules to limit this. - ''; - }; - - }; - - }; - - networking.ifaces = mkOption { - default = listToAttrs - (map (iface: { name = iface.name; value = iface; }) config.networking.interfaces); - internal = true; - description = '' - The network interfaces in - as an attribute set keyed on the interface name. - ''; + type = types.loaOf types.optionSet; + options = [ interfaceOpts ]; }; networking.bridges = mkOption { @@ -288,7 +284,7 @@ in ''} # Turn on forwarding if any interface has enabled proxy_arp. - ${optionalString (any (i: i.proxyARP) cfg.interfaces) '' + ${optionalString (any (i: i.proxyARP) interfaces) '' echo 1 > /proc/sys/net/ipv4/ip_forward ''} @@ -322,12 +318,12 @@ in echo "bringing up interface..." ip link set "${i.name}" up '' - + optionalString (i.macAddress != "") + + optionalString (i.macAddress != null) '' echo "setting MAC address to ${i.macAddress}..." ip link set "${i.name}" address "${i.macAddress}" '' - + optionalString (i.ipAddress != "") + + optionalString (i.ipAddress != null) '' cur=$(ip -4 -o a show dev "${i.name}" | awk '{print $4}') # Only do a flush/add if it's necessary. This is @@ -400,8 +396,8 @@ in }; in listToAttrs ( - map configureInterface cfg.interfaces ++ - map createTunDevice (filter (i: i.virtual) cfg.interfaces)) + map configureInterface interfaces ++ + map createTunDevice (filter (i: i.virtual) interfaces)) // mapAttrs createBridgeDevice cfg.bridges // { "network-setup" = networkSetup; }; diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix index 3f005d6eb2d5..6ca89dd7ac5b 100644 --- a/modules/virtualisation/ec2-data.nix +++ b/modules/virtualisation/ec2-data.nix @@ -13,7 +13,7 @@ with pkgs.lib; wantedBy = [ "multi-user.target" ]; before = [ "sshd.service" ]; - after = [ "dhcpcd.service" ]; + after = [ "network.target" ]; path = [ pkgs.curl pkgs.iproute ]; diff --git a/tests/bittorrent.nix b/tests/bittorrent.nix index 9e4ee2e06350..180da8267e0f 100644 --- a/tests/bittorrent.nix +++ b/tests/bittorrent.nix @@ -16,7 +16,7 @@ let miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf" '' ext_ifname=eth1 - listening_ip=${nodes.router.config.networking.ifaces.eth2.ipAddress}/24 + listening_ip=${nodes.router.config.networking.interfaces.eth2.ipAddress}/24 allow 1024-65535 192.168.2.0/24 1024-65535 ''; @@ -49,7 +49,7 @@ in { environment.systemPackages = [ pkgs.transmission ]; virtualisation.vlans = [ 2 ]; networking.defaultGateway = - nodes.router.config.networking.ifaces.eth2.ipAddress; + nodes.router.config.networking.interfaces.eth2.ipAddress; }; client2 = diff --git a/tests/nat.nix b/tests/nat.nix index 7b03739a9bc4..55d87ed4fa14 100644 --- a/tests/nat.nix +++ b/tests/nat.nix @@ -13,7 +13,7 @@ { config, pkgs, nodes, ... }: { virtualisation.vlans = [ 1 ]; networking.defaultGateway = - nodes.router.config.networking.ifaces.eth2.ipAddress; + nodes.router.config.networking.interfaces.eth2.ipAddress; }; router = From 458f36f5f11170dead59ad4adda8146784d98208 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 2 Nov 2012 18:02:12 +0100 Subject: [PATCH 229/327] Turn fileSystems into an attribute set So now you can write fileSystems = [ { mountPoint = "/"; device = "/dev/sda1"; } ]; as fileSystems."/".device = "/dev/sda1"; --- doc/manual/installation.xml | 6 +- modules/installer/cd-dvd/iso-image.nix | 18 +-- modules/installer/tools/nixos-option.sh | 17 +-- modules/system/boot/stage-1.nix | 13 +- modules/tasks/filesystems.nix | 151 ++++++++++---------- modules/virtualisation/amazon-image.nix | 6 +- modules/virtualisation/nova-image.nix | 6 +- modules/virtualisation/qemu-vm.nix | 56 ++++---- modules/virtualisation/virtualbox-image.nix | 6 +- 9 files changed, 131 insertions(+), 148 deletions(-) diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index 0a69ce0ecba8..ed5348829c8b 100644 --- a/doc/manual/installation.xml +++ b/doc/manual/installation.xml @@ -230,11 +230,7 @@ $ reboot { boot.loader.grub.device = "/dev/sda"; - fileSystems = - [ { mountPoint = "/"; - device = "/dev/disk/by-label/nixos"; - } - ]; + fileSystems."/".device = "/dev/disk/by-label/nixos"; swapDevices = [ { device = "/dev/disk/by-label/swap"; } ]; diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix index be4777356e48..96fc8a31dca2 100644 --- a/modules/installer/cd-dvd/iso-image.nix +++ b/modules/installer/cd-dvd/iso-image.nix @@ -184,17 +184,13 @@ in # Note that /dev/root is a symlink to the actual root device # specified on the kernel command line, created in the stage 1 init # script. - fileSystems = - [ { mountPoint = "/"; - device = "/dev/root"; - } - { mountPoint = "/nix/store"; - fsType = "squashfs"; - device = "/nix-store.squashfs"; - options = "loop"; - neededForBoot = true; - } - ]; + fileSystems."/".device = "/dev/root"; + + fileSystems."/nix/store" = + { fsType = "squashfs"; + device = "/nix-store.squashfs"; + options = "loop"; + }; # We need squashfs in the initrd to mount the compressed Nix store, # and aufs to make the root filesystem appear writable. diff --git a/modules/installer/tools/nixos-option.sh b/modules/installer/tools/nixos-option.sh index 656f2a874033..47abac7fddd0 100644 --- a/modules/installer/tools/nixos-option.sh +++ b/modules/installer/tools/nixos-option.sh @@ -239,17 +239,14 @@ if $generate; then # Add filesystem entries for each partition that you want to see # mounted at boot time. This should include at least the root # filesystem. - fileSystems = - [ # { mountPoint = "/"; - # device = "/dev/disk/by-label/nixos"; - # } - # { mountPoint = "/data"; # where you want to mount the device - # device = "/dev/sdb"; # the device - # fsType = "ext3"; # the type of the partition - # options = "data=journal"; - # } - ]; + # fileSystems."/".device = "/dev/disk/by-label/nixos"; + + # fileSystems."/data" = # where you want to mount the device + # { device = "/dev/sdb"; # the device + # fsType = "ext3"; # the type of the partition + # options = "data=journal"; + # }; # List swap partitions activated at boot time. swapDevices = diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index 18d11e2d4025..ac8a3ccc2386 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -99,9 +99,12 @@ let options.neededForBoot = mkOption { default = false; type = types.bool; - description = " - Mount this file system to boot on NixOS. - "; + description = '' + If set, this file system will be mounted in the initial + ramdisk. By default, this applies to the root file system + and to the file system containing + /nix/store. + ''; }; }; @@ -236,8 +239,8 @@ let # booting (such as the FS containing /nix/store, or an FS needed for # mounting /, like / on a loopback). fileSystems = filter - (fs: fs.mountPoint == "/" || fs.neededForBoot) - config.fileSystems; + (fs: fs.mountPoint == "/" || fs.mountPoint == "/nix" || fs.mountPoint == "/nix/store" || fs.neededForBoot) + (attrValues config.fileSystems); udevRules = pkgs.stdenv.mkDerivation { diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 66c97c5fd112..00d711eecd31 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -5,12 +5,14 @@ with utils; let + fileSystems = attrValues config.fileSystems; + fstab = pkgs.writeText "fstab" '' # This is a generated file. Do not edit! # Filesystems. - ${flip concatMapStrings config.fileSystems (fs: + ${flip concatMapStrings fileSystems (fs: (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") + " " + fs.mountPoint + " " + fs.fsType @@ -27,6 +29,70 @@ let )} ''; + fileSystemOpts = { name, ... }: { + + options = { + + mountPoint = mkOption { + example = "/mnt/usb"; + type = types.uniq types.string; + description = "Location of the mounted the file system."; + }; + + device = mkOption { + default = null; + example = "/dev/sda"; + type = types.uniq (types.nullOr types.string); + description = "Location of the device."; + }; + + label = mkOption { + default = null; + example = "root-partition"; + type = types.uniq (types.nullOr types.string); + description = "Label of the device (if any)."; + }; + + fsType = mkOption { + default = "auto"; + example = "ext3"; + type = types.uniq types.string; + description = "Type of the file system."; + }; + + options = mkOption { + default = "defaults,relatime"; + example = "data=journal"; + type = types.string; + merge = pkgs.lib.concatStringsSep ","; + description = "Options used to mount the file system."; + }; + + autoFormat = mkOption { + default = false; + type = types.bool; + description = '' + If the device does not currently contain a filesystem (as + determined by blkid, then automatically + format it with the filesystem type specified in + . Use with caution. + ''; + }; + + noCheck = mkOption { + default = false; + type = types.bool; + description = "Disable running fsck on this filesystem."; + }; + + }; + + config = { + mountPoint = mkDefault name; + }; + + }; + in { @@ -36,20 +102,17 @@ in options = { fileSystems = mkOption { - example = [ - { mountPoint = "/"; - device = "/dev/hda1"; - } - { mountPoint = "/data"; + example = { + "/".device = "/dev/hda1"; + "/data" = { device = "/dev/hda2"; fsType = "ext3"; options = "data=journal"; - } - { mountPoint = "/bigdisk"; - label = "bigdisk"; - } - ]; - + }; + "/bigdisk".label = "bigdisk"; + }; + type = types.loaOf types.optionSet; + options = [ fileSystemOpts ]; description = '' The file systems to be mounted. It must include an entry for the root directory (mountPoint = \"/\"). Each @@ -66,63 +129,6 @@ in systems that support it, such as ext2/ext3 (see mke2fs -L). ''; - - type = types.list types.optionSet; - - options = { - - mountPoint = mkOption { - example = "/mnt/usb"; - type = types.uniq types.string; - description = "Location of the mounted the file system."; - }; - - device = mkOption { - default = null; - example = "/dev/sda"; - type = types.uniq (types.nullOr types.string); - description = "Location of the device."; - }; - - label = mkOption { - default = null; - example = "root-partition"; - type = types.uniq (types.nullOr types.string); - description = "Label of the device (if any)."; - }; - - fsType = mkOption { - default = "auto"; - example = "ext3"; - type = types.uniq types.string; - description = "Type of the file system."; - }; - - options = mkOption { - default = "defaults,relatime"; - example = "data=journal"; - type = types.string; - merge = pkgs.lib.concatStringsSep ","; - description = "Options used to mount the file system."; - }; - - autoFormat = mkOption { - default = false; - type = types.bool; - description = '' - If the device does not currently contain a filesystem (as - determined by blkid, then automatically - format it with the filesystem type specified in - . Use with caution. - ''; - }; - - noCheck = mkOption { - default = false; - type = types.bool; - description = "Disable running fsck on this filesystem."; - }; - }; }; system.fsPackages = mkOption { @@ -152,12 +158,11 @@ in config = { - boot.supportedFilesystems = - map (fs: fs.fsType) config.fileSystems; + boot.supportedFilesystems = map (fs: fs.fsType) fileSystems; boot.initrd.supportedFilesystems = map (fs: fs.fsType) - (filter (fs: fs.mountPoint == "/" || fs.neededForBoot) config.fileSystems); + (filter (fs: fs.mountPoint == "/" || fs.neededForBoot) fileSystems); # Add the mount helpers to the system path so that `mount' can find them. system.fsPackages = [ pkgs.dosfstools ]; @@ -207,7 +212,7 @@ in serviceConfig.Type = "oneshot"; }; - in listToAttrs (map formatDevice (filter (fs: fs.autoFormat) config.fileSystems)); + in listToAttrs (map formatDevice (filter (fs: fs.autoFormat) fileSystems)); }; diff --git a/modules/virtualisation/amazon-image.nix b/modules/virtualisation/amazon-image.nix index 9ada2b176fe3..da6f6d3afc92 100644 --- a/modules/virtualisation/amazon-image.nix +++ b/modules/virtualisation/amazon-image.nix @@ -62,11 +62,7 @@ with pkgs.lib; '' ); - fileSystems = - [ { mountPoint = "/"; - device = "/dev/disk/by-label/nixos"; - } - ]; + fileSystems."/".device = "/dev/disk/by-label/nixos"; boot.initrd.kernelModules = [ "xen-blkfront" "aufs" ]; boot.kernelModules = [ "xen-netfront" ]; diff --git a/modules/virtualisation/nova-image.nix b/modules/virtualisation/nova-image.nix index ea4dbcc4dd4c..2aa78aeaddab 100644 --- a/modules/virtualisation/nova-image.nix +++ b/modules/virtualisation/nova-image.nix @@ -68,11 +68,7 @@ with pkgs.lib; '' ); - fileSystems = - [ { mountPoint = "/"; - device = "/dev/disk/by-label/nixos"; - } - ]; + fileSystems."/".device = "/dev/disk/by-label/nixos"; boot.kernelParams = [ "console=ttyS0" ]; diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index e3927442821e..22e5017d7c08 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -320,35 +320,33 @@ in # where the regular value for the `fileSystems' attribute should be # disregarded for the purpose of building a VM test image (since # those filesystems don't exist in the VM). - fileSystems = mkOverride 50 ( - [ { mountPoint = "/"; - device = "/dev/vda"; - } - { mountPoint = "/nix/store"; - device = "//10.0.2.4/store"; - fsType = "cifs"; - options = "guest,sec=none,noperm,noacl"; - neededForBoot = true; - } - { mountPoint = "/tmp/xchg"; - device = "//10.0.2.4/xchg"; - fsType = "cifs"; - options = "guest,sec=none,noperm,noacl"; - neededForBoot = true; - } - { mountPoint = "/tmp/shared"; - device = "//10.0.2.4/shared"; - fsType = "cifs"; - options = "guest,sec=none,noperm,noacl"; - neededForBoot = true; - } - ] ++ optional cfg.useBootLoader - { mountPoint = "/boot"; - device = "/dev/disk/by-label/boot"; - fsType = "ext4"; - options = "ro"; - noCheck = true; # fsck fails on a r/o filesystem - }); + fileSystems = + { "/".device = "/dev/vda"; + "/nix/store" = + { device = "//10.0.2.4/store"; + fsType = "cifs"; + options = "guest,sec=none,noperm,noacl"; + }; + "/tmp/xchg" = + { device = "//10.0.2.4/xchg"; + fsType = "cifs"; + options = "guest,sec=none,noperm,noacl"; + neededForBoot = true; + }; + "/tmp/shared" = + { device = "//10.0.2.4/shared"; + fsType = "cifs"; + options = "guest,sec=none,noperm,noacl"; + neededForBoot = true; + }; + } // optionalAttrs cfg.useBootLoader + { "/boot" = + { device = "/dev/disk/by-label/boot"; + fsType = "ext4"; + options = "ro"; + noCheck = true; # fsck fails on a r/o filesystem + }; + }; swapDevices = mkOverride 50 [ ]; diff --git a/modules/virtualisation/virtualbox-image.nix b/modules/virtualisation/virtualbox-image.nix index f049c5eb348a..8fe0030946a6 100644 --- a/modules/virtualisation/virtualbox-image.nix +++ b/modules/virtualisation/virtualbox-image.nix @@ -71,11 +71,7 @@ with pkgs.lib; '' ); - fileSystems = - [ { mountPoint = "/"; - device = "/dev/disk/by-label/nixos"; - } - ]; + fileSystems."/".device = "/dev/disk/by-label/nixos"; boot.loader.grub.version = 2; boot.loader.grub.device = "/dev/sda"; From 70e6e19f545244a1a5cb55efb6b396e80cb435d8 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 5 Nov 2012 23:07:53 +0100 Subject: [PATCH 230/327] xsession: source /etc/profile at the beginning of the script The xsession script runs services that depend on a sane environment. Gpg-agent, for example, runs the program "pinentry-gtk-2" to obtain the password to unlock GnuPG and SSH keys. That program will display only gibberish unless $FONTCONFIG_FILE is configured properly. Instead of configuring these variables explicitly one by one, we just source /etc/profile, which contains the appropriate @shellInit@ code. --- modules/services/x11/display-managers/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/x11/display-managers/default.nix b/modules/services/x11/display-managers/default.nix index 86a636c27c70..396311be49e1 100644 --- a/modules/services/x11/display-managers/default.nix +++ b/modules/services/x11/display-managers/default.nix @@ -21,6 +21,7 @@ let '' #! /bin/sh + . /etc/profile cd "$HOME" # The first argument of this script is the session type. From a333f7212e4a079a5c6d26bfcb7c933e02ce01b1 Mon Sep 17 00:00:00 2001 From: aszlig Date: Sat, 3 Nov 2012 05:41:46 +0100 Subject: [PATCH 231/327] systemd: Fail if kernel features are missing. This has rendered my system unbootable, because I forgot to enable AUTOFS4 in my custom kernel. In addition to AUTOFS4, this includes (hopefully) all other kernel features needed by systemd, as listed in the README: REQUIREMENTS: Linux kernel >= 2.6.39 with devtmpfs with cgroups (but it's OK to disable all controllers) optional but strongly recommended: autofs4, ipv6 Autofs4 is not a requirement here, but in our case it turns out that the system is not able to boot properly with a LUKS-enabled system (or at least not on _my_ system). Signed-off-by: aszlig --- modules/system/boot/systemd.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 340a6d80c1c7..e76d35fa9f27 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -453,6 +453,8 @@ in // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets; + system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [ + "CGROUPS" "AUTOFS4_FS" "DEVTMPFS" + ]; }; - } From 04ba5de70a6ec3746fdcc74919587a024b553a3c Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Sun, 11 Nov 2012 21:29:33 +0100 Subject: [PATCH 232/327] modules/programs/bash/bash.nix: cosmetic indention fix --- modules/programs/bash/bash.nix | 50 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 135d99ec437f..f2b0ac46b06a 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -28,35 +28,35 @@ let options = { environment.promptInit = mkOption { - default = '' - # Provide a nice prompt. - PROMPT_COLOR="1;31m" - let $UID && PROMPT_COLOR="1;32m" - PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " - if test "$TERM" = "xterm"; then - PS1="\[\033]2;\h:\u:\w\007\]$PS1" - fi - ''; - description = " - Script used to initialized shell prompt. - "; - type = with pkgs.lib.types; string; - }; + default = '' + # Provide a nice prompt. + PROMPT_COLOR="1;31m" + let $UID && PROMPT_COLOR="1;32m" + PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " + if test "$TERM" = "xterm"; then + PS1="\[\033]2;\h:\u:\w\007\]$PS1" + fi + ''; + description = " + Script used to initialized shell prompt. + "; + type = with pkgs.lib.types; string; + }; environment.shellInit = mkOption { - default = ""; - example = ''export PATH=/godi/bin/:$PATH''; - description = " - Script used to initialized user shell environments. - "; - type = with pkgs.lib.types; string; - }; + default = ""; + example = ''export PATH=/godi/bin/:$PATH''; + description = " + Script used to initialized user shell environments. + "; + type = with pkgs.lib.types; string; + }; environment.enableBashCompletion = mkOption { - default = false; - description = "Enable bash-completion for all interactive shells."; - type = with pkgs.lib.types; bool; - }; + default = false; + description = "Enable bash-completion for all interactive shells."; + type = with pkgs.lib.types; bool; + }; }; From 622a652411bd5d0c611416adcf60b6eb8e8ce04b Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Sun, 11 Nov 2012 21:46:25 +0100 Subject: [PATCH 233/327] Add option "environment.binsh" to configure the shell executable used to create the global /bin/sh symlink. --- modules/programs/bash/bash.nix | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index f2b0ac46b06a..9d52eeebf8e9 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -58,6 +58,18 @@ let type = with pkgs.lib.types; bool; }; + environment.binsh = mkOption { + default = "${config.system.build.binsh}/bin/sh"; + example = "\${pkgs.dash}/bin/dash"; + type = with pkgs.lib.types; path; + description = '' + Select the shell executable that is linked system-wide to + /bin/sh. Please note that NixOS assumes all + over the place that shell to be Bash, so override the default + setting only if you know exactly what you're doing. + ''; + }; + }; in @@ -99,7 +111,7 @@ in # Create the required /bin/sh symlink; otherwise lots of things # (notably the system() function) won't work. mkdir -m 0755 -p /bin - ln -sfn ${config.system.build.binsh}/bin/sh /bin/.sh.tmp + ln -sfn "${config.environment.binsh}" /bin/.sh.tmp mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh ''; From 1350816199b95927273ca17b3ec867a16382d0ee Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 9 Nov 2012 11:45:37 +0100 Subject: [PATCH 234/327] test-instrumentation.nix: Don't start agetty on hvc0 --- modules/testing/test-instrumentation.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 8ceffbcb9ec6..0ee3ad65a3d2 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -33,8 +33,9 @@ let kernel = config.boot.kernelPackages.kernel; in # Prevent agetty from being instantiated on ttyS0, since it # interferes with the backdoor (writes to ttyS0 will randomly fail - # with EIO). + # with EIO). Likewise for hvc0. boot.systemd.services."serial-getty@ttyS0".enable = false; + boot.systemd.services."serial-getty@hvc0".enable = false; boot.initrd.postDeviceCommands = '' From d5aae18587efe15d278e45c38029b6be7cccad12 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 9 Nov 2012 11:45:57 +0100 Subject: [PATCH 235/327] installer test: Don't wait for getty@tty2 because it's started lazily --- tests/installer.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/installer.nix b/tests/installer.nix index 7952e295794d..ad126c128b59 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -120,7 +120,7 @@ let # Make sure that we get a login prompt etc. $machine->succeed("echo hello"); - $machine->waitForUnit('getty@tty2'); + #$machine->waitForUnit('getty@tty2'); $machine->waitForUnit("rogue"); $machine->waitForUnit("nixos-manual"); $machine->waitForUnit("dhcpcd"); From 08e6c0cb7ca1ecaca67567dbf4eddbccd2d4a621 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 12 Nov 2012 09:18:59 +0100 Subject: [PATCH 236/327] Update channel URLs --- doc/manual/installation.xml | 2 +- maintainers/scripts/ec2/create-ebs-amis.py | 2 +- modules/installer/tools/tools.nix | 10 ++++++---- modules/programs/bash/profile.sh | 2 +- tests/installer.nix | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index ed5348829c8b..8bde2f6e0530 100644 --- a/doc/manual/installation.xml +++ b/doc/manual/installation.xml @@ -322,7 +322,7 @@ packages. some reason this is not the case, just do -$ nix-channel --add http://nixos.org/releases/nixos/channels/nixos-unstable +$ nix-channel --add http://nixos.org/channels/nixos-unstable You can then upgrade NixOS to the latest version in the channel by diff --git a/maintainers/scripts/ec2/create-ebs-amis.py b/maintainers/scripts/ec2/create-ebs-amis.py index 939bd30942dc..4dfaa9f3b129 100755 --- a/maintainers/scripts/ec2/create-ebs-amis.py +++ b/maintainers/scripts/ec2/create-ebs-amis.py @@ -52,7 +52,7 @@ m.run_command("mkdir -p /mnt") m.run_command("mount {0} /mnt".format(device)) m.run_command("touch /mnt/.ebs") m.run_command("mkdir -p /mnt/etc/nixos") -m.run_command("nix-channel --add http://nixos.org/releases/nixos/channels/nixos-unstable") +m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable") m.run_command("nix-channel --update") m.run_command("nixos-rebuild switch") version = m.run_command("nixos-version", capture_stdout=True).replace('"', '').rstrip() diff --git a/modules/installer/tools/tools.nix b/modules/installer/tools/tools.nix index d7b8766143ac..c3bbfd953f39 100644 --- a/modules/installer/tools/tools.nix +++ b/modules/installer/tools/tools.nix @@ -84,8 +84,9 @@ in { options = { + # FIXME: remove this option once we're using Nix 1.2. installer.nixosURL = pkgs.lib.mkOption { - default = http://nixos.org/releases/nixos/channels/nixos-unstable; + default = http://nixos.org/channels/nixos-unstable; example = http://nixos.org/releases/nixos/nixos-0.1pre1234; description = '' URL of the Nixpkgs distribution to use when building the @@ -93,11 +94,12 @@ in ''; }; + # FIXME: idem. installer.manifests = pkgs.lib.mkOption { - default = [ http://nixos.org/releases/nixos/channels/nixos-unstable/MANIFEST ]; + default = [ http://nixos.org/channels/nixos-unstable/MANIFEST ]; example = - [ http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/MANIFEST - http://nixos.org/releases/nixos/channels/nixos-stable/MANIFEST + [ http://nixos.org/channels/nixpkgs-unstable/MANIFEST + http://nixos.org/channels/nixos-stable/MANIFEST ]; description = '' URLs of manifests to be downloaded when you run diff --git a/modules/programs/bash/profile.sh b/modules/programs/bash/profile.sh index 1eef2a9e84a8..5393a88d5ffe 100644 --- a/modules/programs/bash/profile.sh +++ b/modules/programs/bash/profile.sh @@ -87,7 +87,7 @@ fi # Subscribe the root user to the NixOS channel by default. if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then - echo "http://nixos.org/releases/nixos/channels/nixos-unstable nixos" > $HOME/.nix-channels + echo "http://nixos.org/channels/nixos-unstable nixos" > $HOME/.nix-channels fi # Create the per-user garbage collector roots directory. diff --git a/tests/installer.nix b/tests/installer.nix index ad126c128b59..8b695ae5a180 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -79,7 +79,7 @@ let { services.httpd.enable = true; services.httpd.adminAddr = "foo@example.org"; services.httpd.servedDirs = singleton - { urlPath = "/releases/nixos/channels/nixos-unstable"; + { urlPath = "/channels/nixos-unstable"; dir = "/tmp/channel"; }; @@ -114,7 +114,7 @@ let $webserver->succeed("mkdir /tmp/channel"); $webserver->succeed( "nix-push file:///tmp/channel " . - "http://nixos.org/releases/nixos/channels/nixos-unstable " . + "http://nixos.org/channels/nixos-unstable " . "file:///tmp/channel/MANIFEST ${toString channelContents} >&2"); ''} From f44d27a96c6ff7c12a6c85a2d7d2069070f550c1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Nov 2012 22:53:57 +0100 Subject: [PATCH 237/327] Make the installer work on systemd Systemd mounts the root filesystem as a shared subtree, which breaks recursive bind mounts. --- modules/installer/tools/nixos-install.sh | 37 +++++++++++++++--------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/modules/installer/tools/nixos-install.sh b/modules/installer/tools/nixos-install.sh index 4e89770cce56..4d3d3db08617 100644 --- a/modules/installer/tools/nixos-install.sh +++ b/modules/installer/tools/nixos-install.sh @@ -17,7 +17,7 @@ if test -z "$mountPoint"; then fi if test -z "$NIXOS_CONFIG"; then - NIXOS_CONFIG=/mnt/etc/nixos/configuration.nix + NIXOS_CONFIG=/etc/nixos/configuration.nix fi if ! test -e "$mountPoint"; then @@ -30,7 +30,7 @@ if ! grep -F -q " $mountPoint " /proc/mounts; then exit 1 fi -if ! test -e "$NIXOS_CONFIG"; then +if ! test -e "$mountPoint/$NIXOS_CONFIG"; then echo "configuration file $NIXOS_CONFIG doesn't exist" exit 1 fi @@ -47,21 +47,30 @@ fi # Mount some stuff in the target root directory. We bind-mount /etc # into the chroot because we need networking and the nixbld user # accounts in /etc/passwd. But we do need the target's /etc/nixos. -mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/mnt $mountPoint/etc -mount --rbind /dev $mountPoint/dev -mount --rbind /proc $mountPoint/proc -mount --rbind /sys $mountPoint/sys -mount --rbind / $mountPoint/mnt +mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/mnt $mountPoint/mnt2 $mountPoint/etc /etc/nixos +mount --make-private / # systemd makes / shared, which is annoying +mount --bind / $mountPoint/mnt +mount --bind /nix/store $mountPoint/mnt/nix/store +mount --bind /dev $mountPoint/dev +mount --bind /dev/shm $mountPoint/dev/shm +mount --bind /proc $mountPoint/proc +mount --bind /sys $mountPoint/sys +mount --bind $mountPoint/etc/nixos $mountPoint/mnt2 mount --bind /etc $mountPoint/etc -mount --bind $mountPoint/mnt/$mountPoint/etc/nixos $mountPoint/etc/nixos +mount --bind $mountPoint/mnt2 $mountPoint/etc/nixos cleanup() { set +e - umount -l $mountPoint/mnt - umount -l $mountPoint/dev - umount -l $mountPoint/proc - umount -l $mountPoint/sys - mountpoint -q $mountPoint/etc && umount -l $mountPoint/etc + mountpoint -q $mountPoint/etc/nixos && umount $mountPoint/etc/nixos + mountpoint -q $mountPoint/etc && umount $mountPoint/etc + umount $mountPoint/mnt2 + umount $mountPoint/sys + umount $mountPoint/proc + umount $mountPoint/dev/shm + umount $mountPoint/dev + umount $mountPoint/mnt/nix/store + umount $mountPoint/mnt + rmdir $mountPoint/mnt $mountPoint/mnt2 } trap "cleanup" EXIT @@ -151,7 +160,7 @@ srcs=$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-nam # Build the specified Nix expression in the target store and install # it into the system configuration profile. echo "building the system configuration..." -NIX_PATH="/mnt$srcs/nixos:nixos-config=/mnt$NIXOS_CONFIG" NIXOS_CONFIG= \ +NIX_PATH="/mnt$srcs/nixos:nixos-config=$NIXOS_CONFIG" NIXOS_CONFIG= \ chroot $mountPoint @nix@/bin/nix-env \ -p /nix/var/nix/profiles/system -f '' --set -A system --show-trace From 1f401a0e353f88595f06265c09cac2f1983cdacb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Nov 2012 22:54:43 +0100 Subject: [PATCH 238/327] Make install-grub.pl work when $PATH is empty --- modules/system/boot/loader/grub/grub.nix | 1 + modules/system/boot/loader/grub/install-grub.pl | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/system/boot/loader/grub/grub.nix b/modules/system/boot/loader/grub/grub.nix index 0a9b374cc60c..384865b867b3 100644 --- a/modules/system/boot/loader/grub/grub.nix +++ b/modules/system/boot/loader/grub/grub.nix @@ -18,6 +18,7 @@ let version extraConfig extraPerEntryConfig extraEntries extraEntriesBeforeNixOS configurationLimit copyKernels timeout default devices; + path = makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.findutils pkgs.gnugrep ]; }); in diff --git a/modules/system/boot/loader/grub/install-grub.pl b/modules/system/boot/loader/grub/install-grub.pl index 5e9f3b4efdad..1d1958a8fe6a 100644 --- a/modules/system/boot/loader/grub/install-grub.pl +++ b/modules/system/boot/loader/grub/install-grub.pl @@ -38,6 +38,7 @@ my $configurationLimit = int(get("configurationLimit")); my $copyKernels = get("copyKernels") eq "true"; my $timeout = int(get("timeout")); my $defaultEntry = int(get("default")); +$ENV{'PATH'} = get("path"); die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2; From 074af5906e7d71e53fe6db5023f17fb3e4d3bda8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Nov 2012 22:55:00 +0100 Subject: [PATCH 239/327] Use new-style fileSystems --- tests/installer.nix | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/installer.nix b/tests/installer.nix index 8b695ae5a180..dd52e817c1d4 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -49,7 +49,7 @@ let boot.loader.grub.extraConfig = "serial; terminal_output.serial"; boot.initrd.kernelModules = [ "ext3" "ext4" "xfs" "virtio_console" ]; - fileSystems = [ ${fileSystems} ]; + ${fileSystems} swapDevices = [ { label = "swap"; } ]; environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ]; @@ -58,16 +58,12 @@ let rootFS = '' - { mountPoint = "/"; - device = "/dev/disk/by-label/nixos"; - } + fileSystems."/".device = "/dev/disk/by-label/nixos"; ''; bootFS = '' - { mountPoint = "/boot"; - device = "/dev/disk/by-label/boot"; - } + fileSystems."/boot".device = "/dev/disk/by-label/boot"; ''; From 35922e61d901676f910b71ffd3e2d662fc62339c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Nov 2012 22:55:36 +0100 Subject: [PATCH 240/327] Systemd requires the latest Nix --- modules/misc/nixpkgs.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index 021986bc8959..aa4066347b5d 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -81,6 +81,7 @@ in upower = pkgs.upower.override { useSystemd = true; }; polkit = pkgs.polkit.override { useSystemd = true; }; consolekit = null; + nix = pkgs.nixUnstable; }; }; From 722a3a7147a3f714b2e2584370fab215733a42a5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Nov 2012 23:07:05 +0100 Subject: [PATCH 241/327] Remove unnecessary (AFAICT) call to toPath --- modules/services/hardware/pommed.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/hardware/pommed.nix b/modules/services/hardware/pommed.nix index 63c783f5c6d0..32599554fc12 100644 --- a/modules/services/hardware/pommed.nix +++ b/modules/services/hardware/pommed.nix @@ -13,7 +13,7 @@ with pkgs.lib; }; configFile = mkOption { - default = builtins.toPath "${pkgs.pommed}/etc/pommed.conf"; + default = "${pkgs.pommed}/etc/pommed.conf"; description = '' The contents of the pommed.conf file. ''; From fe7b3b7f9bdfcc73cd3c3365751ba0d8d5dc08c3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 16 Nov 2012 16:34:22 +0100 Subject: [PATCH 242/327] Installer test: fix nix-push call http://hydra.nixos.org/build/3331147 --- tests/installer.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/installer.nix b/tests/installer.nix index dd52e817c1d4..9f89ad10021e 100644 --- a/tests/installer.nix +++ b/tests/installer.nix @@ -107,11 +107,9 @@ let # to simulate the Nixpkgs channel. $webserver->start; $webserver->waitForUnit("httpd"); - $webserver->succeed("mkdir /tmp/channel"); $webserver->succeed( - "nix-push file:///tmp/channel " . - "http://nixos.org/channels/nixos-unstable " . - "file:///tmp/channel/MANIFEST ${toString channelContents} >&2"); + "nix-push --bzip2 --dest /tmp/channel --manifest --url-prefix http://nixos.org/channels/nixos-unstable " . + "${toString channelContents} >&2"); ''} # Make sure that we get a login prompt etc. From 60bf4c3cd7489f5b627dcd22a4657be8a9eb1cae Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 16 Nov 2012 16:42:45 +0100 Subject: [PATCH 243/327] Add a GRUB 1 dependency http://hydra.nixos.org/build/3331139 --- modules/system/boot/loader/grub/grub.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/loader/grub/grub.nix b/modules/system/boot/loader/grub/grub.nix index 384865b867b3..70cfc87220cf 100644 --- a/modules/system/boot/loader/grub/grub.nix +++ b/modules/system/boot/loader/grub/grub.nix @@ -18,7 +18,7 @@ let version extraConfig extraPerEntryConfig extraEntries extraEntriesBeforeNixOS configurationLimit copyKernels timeout default devices; - path = makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.findutils pkgs.gnugrep ]; + path = makeSearchPath "bin" [ pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils ]; }); in From cd513482d46c41243934ef5835cda30ca228c474 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Thu, 22 Nov 2012 02:07:25 -0500 Subject: [PATCH 244/327] Add rngd service. Inspired by http://pkgs.fedoraproject.org/cgit/rng-tools.git/tree/rngd.service?id=27b1912b2d9659b6934fd4c887e46c13958e7e3c --- modules/module-list.nix | 1 + modules/security/rngd.nix | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 modules/security/rngd.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 1f25f2aa1e0b..3f66ff917fd4 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -48,6 +48,7 @@ ./security/pam.nix ./security/pam_usb.nix ./security/polkit.nix + ./security/rngd.nix ./security/rtkit.nix ./security/setuid-wrappers.nix ./security/sudo.nix diff --git a/modules/security/rngd.nix b/modules/security/rngd.nix new file mode 100644 index 000000000000..1dfea8ce96f0 --- /dev/null +++ b/modules/security/rngd.nix @@ -0,0 +1,26 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + options = { + security.rngd.enable = mkOption { + default = true; + description = '' + Whether tho enable the rng daemon, which adds entropy from + hardware sources of randomness to the kernel entropy pool when + available. It is strongly recommended to keep this enabled! + ''; + }; + }; + + config = mkIf config.security.rngd.enable { + boot.systemd.services.rngd = { + wantedBy = [ config.boot.systemd.defaultUnit ]; + + description = "Hardware RNG Entropy Gatherer Daemon"; + + serviceConfig.ExecStart = "${pkgs.rng_tools}/sbin/rngd -f"; + }; + }; +} From 77891f8d59adc901eeb64401369c3691db8ed994 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 22 Nov 2012 10:41:54 +0100 Subject: [PATCH 245/327] Typo --- modules/security/rngd.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/security/rngd.nix b/modules/security/rngd.nix index 1dfea8ce96f0..79f16f68c5ca 100644 --- a/modules/security/rngd.nix +++ b/modules/security/rngd.nix @@ -7,7 +7,7 @@ with pkgs.lib; security.rngd.enable = mkOption { default = true; description = '' - Whether tho enable the rng daemon, which adds entropy from + Whether to enable the rng daemon, which adds entropy from hardware sources of randomness to the kernel entropy pool when available. It is strongly recommended to keep this enabled! ''; @@ -16,7 +16,7 @@ with pkgs.lib; config = mkIf config.security.rngd.enable { boot.systemd.services.rngd = { - wantedBy = [ config.boot.systemd.defaultUnit ]; + wantedBy = [ "multi-user.target" ]; description = "Hardware RNG Entropy Gatherer Daemon"; From a4bcb26b1a3894022b08381079c2c402d49d611f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 22 Nov 2012 11:49:47 +0100 Subject: [PATCH 246/327] Add options for specifying binary caches --- modules/services/misc/nix-daemon.nix | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index eeb26ee5e15f..5af2d19a8394 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -194,7 +194,29 @@ in ''; }; + binaryCaches = mkOption { + default = [ http://nixos.org/binary-cache ]; + type = types.list types.string; + description = '' + List of binary cache URLs used to obtain pre-built binaries + of Nix packages. + ''; + }; + + trustedBinaryCaches = mkOption { + default = [ ]; + example = [ http://hydra.nixos.org/ ]; + type = types.list types.string; + description = '' + List of binary cache URLs that non-root users can use (in + addition to those specified using + by passing + --option binary-caches to Nix commands. + ''; + }; + }; + }; @@ -225,6 +247,8 @@ in build-max-jobs = ${toString (cfg.maxJobs)} build-use-chroot = ${if cfg.useChroot then "true" else "false"} build-chroot-dirs = ${toString cfg.chrootDirs} $(echo $extraPaths) + binary-caches = ${toString config.nix.binaryCaches} + trusted-binary-caches = ${toString config.nix.trustedBinaryCaches} $extraOptions END ''; From 994a15bc25d4f63c20a3f8929dbe8950e3390429 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 22 Nov 2012 12:04:00 +0100 Subject: [PATCH 247/327] nixos-rebuild: Handle options with spaces in them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like ‘--option binary-caches "http://foo http://bar"’ --- modules/installer/tools/nixos-install.sh | 4 ++-- modules/installer/tools/nixos-rebuild.sh | 26 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/installer/tools/nixos-install.sh b/modules/installer/tools/nixos-install.sh index 4d3d3db08617..d1fdc5820b15 100644 --- a/modules/installer/tools/nixos-install.sh +++ b/modules/installer/tools/nixos-install.sh @@ -29,12 +29,12 @@ if ! grep -F -q " $mountPoint " /proc/mounts; then echo "$mountPoint doesn't appear to be a mount point" exit 1 fi - + if ! test -e "$mountPoint/$NIXOS_CONFIG"; then echo "configuration file $NIXOS_CONFIG doesn't exist" exit 1 fi - + # Do a nix-pull to speed up building. if test -n "@nixosURL@" -a ${NIXOS_PULL:-1} != 0; then diff --git a/modules/installer/tools/nixos-rebuild.sh b/modules/installer/tools/nixos-rebuild.sh index e21a34f996c1..f7c22b98dd76 100644 --- a/modules/installer/tools/nixos-rebuild.sh +++ b/modules/installer/tools/nixos-rebuild.sh @@ -47,7 +47,7 @@ EOF # Parse the command line. -extraBuildFlags= +extraBuildFlags=() action= pullManifest= buildNix=1 @@ -79,20 +79,20 @@ while test "$#" -gt 0; do upgrade=1 ;; --show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|--fallback) - extraBuildFlags="$extraBuildFlags $i" + extraBuildFlags+=("$i") ;; --max-jobs|-j|--cores|-I) j="$1"; shift 1 - extraBuildFlags="$extraBuildFlags $i $j" + extraBuildFlags+=("$i" "$j") ;; --option) j="$1"; shift 1 k="$1"; shift 1 - extraBuildFlags="$extraBuildFlags $i $j $k" + extraBuildFlags+=("$i" "$j" "$k") ;; --fast) buildNix= - extraBuildFlags="$extraBuildFlags --show-trace" + extraBuildFlags+=(--show-trace) ;; *) echo "$0: unknown option \`$i'" @@ -104,7 +104,7 @@ done if test -z "$action"; then showSyntax; fi if test "$action" = dry-run; then - extraBuildFlags="$extraBuildFlags --dry-run" + extraBuildFlags+=(--dry-run) fi if test -n "$rollback"; then @@ -156,9 +156,9 @@ fi # more conservative. if [ -n "$buildNix" ]; then echo "building Nix..." >&2 - if ! nix-build '' -A config.environment.nix -o $tmpDir/nix $extraBuildFlags > /dev/null; then - if ! nix-build '' -A nixFallback -o $tmpDir/nix $extraBuildFlags > /dev/null; then - nix-build '' -A nixUnstable -o $tmpDir/nix $extraBuildFlags > /dev/null + if ! nix-build '' -A config.environment.nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then + if ! nix-build '' -A nixFallback -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then + nix-build '' -A nixUnstable -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null fi fi PATH=$tmpDir/nix/bin:$PATH @@ -171,16 +171,16 @@ fi if test -z "$rollback"; then echo "building the system configuration..." >&2 if test "$action" = switch -o "$action" = boot; then - nix-env $extraBuildFlags -p /nix/var/nix/profiles/system -f '' --set -A system + nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system -f '' --set -A system pathToConfig=/nix/var/nix/profiles/system elif test "$action" = test -o "$action" = build -o "$action" = dry-run; then - nix-build '' -A system -K -k $extraBuildFlags > /dev/null + nix-build '' -A system -K -k "${extraBuildFlags[@]}" > /dev/null pathToConfig=./result elif [ "$action" = build-vm ]; then - nix-build '' -A vm -K -k $extraBuildFlags > /dev/null + nix-build '' -A vm -K -k "${extraBuildFlags[@]}" > /dev/null pathToConfig=./result elif [ "$action" = build-vm-with-bootloader ]; then - nix-build '' -A vmWithBootLoader -K -k $extraBuildFlags > /dev/null + nix-build '' -A vmWithBootLoader -K -k "${extraBuildFlags[@]}" > /dev/null pathToConfig=./result else showSyntax From e76eb7f1a7864ed36130a6cb8a5d8d98c7d2e40e Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Thu, 22 Nov 2012 10:14:41 -0500 Subject: [PATCH 248/327] Disable rngd by default while I work on some patches to make it more systemd-friendly --- modules/security/rngd.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/security/rngd.nix b/modules/security/rngd.nix index 79f16f68c5ca..a4bf0d1eb2af 100644 --- a/modules/security/rngd.nix +++ b/modules/security/rngd.nix @@ -5,11 +5,11 @@ with pkgs.lib; { options = { security.rngd.enable = mkOption { - default = true; + default = false; description = '' Whether to enable the rng daemon, which adds entropy from hardware sources of randomness to the kernel entropy pool when - available. It is strongly recommended to keep this enabled! + available. ''; }; }; From f3c9c83e040135c0b3a42c9b570729c2c01d35ae Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 23 Nov 2012 15:14:16 +0100 Subject: [PATCH 249/327] Make it easier to append to the default sudo configuration --- modules/security/sudo.nix | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/modules/security/sudo.nix b/modules/security/sudo.nix index 211ff8a96096..d2db9ee993f5 100644 --- a/modules/security/sudo.nix +++ b/modules/security/sudo.nix @@ -37,25 +37,6 @@ in security.sudo.configFile = mkOption { # Note: if syntax errors are detected in this file, the NixOS # configuration will fail to build. - default = - '' - # Don't edit this file. Set the NixOS option ‘security.sudo.configFile’ instead. - - # Environment variables to keep for root and %wheel. - Defaults:root,%wheel env_keep+=LOCALE_ARCHIVE - Defaults:root,%wheel env_keep+=NIX_CONF_DIR - Defaults:root,%wheel env_keep+=NIX_PATH - Defaults:root,%wheel env_keep+=TERMINFO_DIRS - - # Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic. - Defaults env_keep+=SSH_AUTH_SOCK - - # "root" is allowed to do anything. - root ALL=(ALL) SETENV: ALL - - # Users in the "wheel" group can do anything. - %wheel ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL - ''; description = '' This string contains the contents of the @@ -69,6 +50,26 @@ in config = mkIf cfg.enable { + security.sudo.configFile = + '' + # Don't edit this file. Set the NixOS option ‘security.sudo.configFile’ instead. + + # Environment variables to keep for root and %wheel. + Defaults:root,%wheel env_keep+=LOCALE_ARCHIVE + Defaults:root,%wheel env_keep+=NIX_CONF_DIR + Defaults:root,%wheel env_keep+=NIX_PATH + Defaults:root,%wheel env_keep+=TERMINFO_DIRS + + # Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic. + Defaults env_keep+=SSH_AUTH_SOCK + + # "root" is allowed to do anything. + root ALL=(ALL) SETENV: ALL + + # Users in the "wheel" group can do anything. + %wheel ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL + ''; + security.setuidPrograms = [ "sudo" ]; environment.systemPackages = [ sudo ]; From a5ef0ffe120c58ac0ec38ac3d0ec61181e8071e2 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Mon, 26 Nov 2012 08:45:23 -0500 Subject: [PATCH 250/327] rngd: Require /dev/random, only start when a hardware randomness source becomes available --- modules/security/rngd.nix | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/security/rngd.nix b/modules/security/rngd.nix index a4bf0d1eb2af..519fb62133cd 100644 --- a/modules/security/rngd.nix +++ b/modules/security/rngd.nix @@ -5,7 +5,7 @@ with pkgs.lib; { options = { security.rngd.enable = mkOption { - default = false; + default = true; description = '' Whether to enable the rng daemon, which adds entropy from hardware sources of randomness to the kernel entropy pool when @@ -15,12 +15,23 @@ with pkgs.lib; }; config = mkIf config.security.rngd.enable { + services.udev.extraRules = '' + KERNEL=="random", TAG+="systemd" + SUBSYSTEM=="cpu", ENV{MODALIAS}=="x86cpu:*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" + KERNEL=="hw_random", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" + KERNEL=="tmp0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" + ''; + boot.systemd.services.rngd = { - wantedBy = [ "multi-user.target" ]; + bindsTo = [ "dev-random.device" ]; + + after = [ "dev-random.device" ]; description = "Hardware RNG Entropy Gatherer Daemon"; serviceConfig.ExecStart = "${pkgs.rng_tools}/sbin/rngd -f"; + + restartTriggers = [ pkgs.rng_tools ]; }; }; } From 403dc16c51343b70172ae2f1aa85f78235918c9a Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 26 Nov 2012 16:19:45 +0100 Subject: [PATCH 251/327] sane: update name of the snapshot version of the backends --- modules/services/hardware/sane.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/hardware/sane.nix b/modules/services/hardware/sane.nix index e9f32a2662cf..6849b3a7bc8e 100644 --- a/modules/services/hardware/sane.nix +++ b/modules/services/hardware/sane.nix @@ -24,7 +24,7 @@ with pkgs.lib; ###### implementation config = let pkg = if config.hardware.sane.snapshot - then pkgs.saneBackendsSnapshot + then pkgs.saneBackendsGit else pkgs.saneBackends; in mkIf config.hardware.sane.enable { environment.systemPackages = [ pkg ]; From 3c6e0fd594801617d77ce78e01d8b066aeb5982e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 29 Nov 2012 18:51:44 +0100 Subject: [PATCH 252/327] Generate the binary hardware database required by systemd 196 --- modules/system/boot/systemd.nix | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index e76d35fa9f27..86e269e0763a 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -442,6 +442,18 @@ in } ]; + system.activationScripts.systemd = + '' + mkdir -p /var/lib/udev -m 0755 + + # Regenerate the hardware database /var/lib/udev/hwdb.bin + # whenever systemd changes. + if [ ! -e /var/lib/udev/prev-systemd -o "$(readlink /var/lib/udev/prev-systemd)" != ${systemd} ]; then + echo "regenerating udev hardware database..." + ${systemd}/bin/udevadm hwdb --update && ln -sfn ${systemd} /var/lib/udev/prev-systemd + fi + ''; + # Target for ‘charon send-keys’ to hook into. boot.systemd.targets.keys = { description = "Security Keys"; @@ -456,5 +468,6 @@ in system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [ "CGROUPS" "AUTOFS4_FS" "DEVTMPFS" ]; + }; } From 745a2018147efd1bad16ec41bc7eaa55a1678dba Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 11 Dec 2012 13:14:17 +0100 Subject: [PATCH 253/327] Check whether /proc/sys/net/ipv6/conf/all/disable_ipv6 exists --- modules/tasks/network-interfaces.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 412e62bfe80c..64cb4a6749eb 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -275,7 +275,9 @@ in EOF # Disable or enable IPv6. - echo ${if cfg.enableIPv6 then "0" else "1"} > /proc/sys/net/ipv6/conf/all/disable_ipv6 + if [ -e /proc/sys/net/ipv6/conf/all/disable_ipv6 ]; then + echo ${if cfg.enableIPv6 then "0" else "1"} > /proc/sys/net/ipv6/conf/all/disable_ipv6 + fi # Set the default gateway. ${optionalString (cfg.defaultGateway != "") '' From 3224ea8a1e394d9189bed3c073294e20ff1591c9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 11 Dec 2012 13:14:33 +0100 Subject: [PATCH 254/327] Don't require nixUnstable --- modules/misc/nixpkgs.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index aa4066347b5d..021986bc8959 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -81,7 +81,6 @@ in upower = pkgs.upower.override { useSystemd = true; }; polkit = pkgs.polkit.override { useSystemd = true; }; consolekit = null; - nix = pkgs.nixUnstable; }; }; From 859badc9663240f7d3c4279d9e657134f8395f17 Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Tue, 11 Dec 2012 20:54:19 +0100 Subject: [PATCH 255/327] Zabbix agent: RemainAfterExit=true seems to give more reliable restarts, cannot completely figure out why, as Type=forking should be enough. --- modules/services/monitoring/zabbix-agent.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/monitoring/zabbix-agent.nix b/modules/services/monitoring/zabbix-agent.nix index e5e27bb0c9a0..9758bc8cb485 100644 --- a/modules/services/monitoring/zabbix-agent.nix +++ b/modules/services/monitoring/zabbix-agent.nix @@ -88,6 +88,7 @@ in serviceConfig.ExecStart = "@${pkgs.zabbix.agent}/sbin/zabbix_agentd zabbix_agentd --config ${configFile}"; serviceConfig.Type = "forking"; + serviceConfig.RemainAfterExit = true; serviceConfig.Restart = "always"; serviceConfig.RestartSec = 2; }; From 5437424297c067a706081a26146bc1c65590c39a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 13 Dec 2012 15:02:58 +0100 Subject: [PATCH 256/327] Hackery to build against both the nixpkgs master and systemd branch --- modules/misc/nixpkgs.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/misc/nixpkgs.nix b/modules/misc/nixpkgs.nix index 021986bc8959..03979e259bf6 100644 --- a/modules/misc/nixpkgs.nix +++ b/modules/misc/nixpkgs.nix @@ -76,7 +76,7 @@ in # FIXME nixpkgs.config.packageOverrides = pkgs: { #udev = pkgs.systemd; - slim = pkgs.slim.override { consolekit = null; }; + slim = pkgs.slim.override (args: if args ? consolekit then { consolekit = null; } else { }); lvm2 = pkgs.lvm2.override { udev = pkgs.systemd; }; upower = pkgs.upower.override { useSystemd = true; }; polkit = pkgs.polkit.override { useSystemd = true; }; From bd7ea9be5895e3545fbd35450f5d0db521684396 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 14 Dec 2012 17:42:54 +0100 Subject: [PATCH 257/327] sysinit.target: Drop the dependency on local-fs.target and swap.target Having all services with DefaultDependencies=yes depend on local-fs.target is annoying, because some of those services might be necessary to mount local filesystems. For instance, Charon's send-keys feature requires sshd to be running in order to receive LUKS encryption keys, which in turn requires dhcpcd, and so on. So we drop this dependency (and swap.target as well for consistency). If services require a specific mount, they should use RequiresMountsFor in any case. --- modules/system/boot/systemd.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 720c8efc53fa..eee65a3ffe0f 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -22,7 +22,7 @@ let upstreamUnits = [ # Targets. "basic.target" - "sysinit.target" + #"sysinit.target" "sockets.target" "graphical.target" "multi-user.target" @@ -459,6 +459,17 @@ in { description = "Security Keys"; }; + # This is like the upstream sysinit.target, except that it doesn't + # depend on local-fs.target and swap.target. If services need to + # be started after some filesystem (local or otherwise) has been + # mounted, they should use the RequiresMountsFor option. + boot.systemd.targets.sysinit = + { description = "System Initialization"; + after = [ "emergency.service" "emergency.target" ]; + unitConfig.Conflicts = "emergency.service emergency.target"; + unitConfig.RefuseManualStart = true; + }; + boot.systemd.units = { "rescue.service".text = rescueService; } // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets From 90e825481d42aa88ed0bdb553b3a06b40a3cba22 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sat, 15 Dec 2012 14:25:25 -0500 Subject: [PATCH 258/327] Update create-ebs-amis.py to recent charon --- maintainers/scripts/ec2/create-ebs-amis.py | 40 ++++++++++++++++------ 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/maintainers/scripts/ec2/create-ebs-amis.py b/maintainers/scripts/ec2/create-ebs-amis.py index 4dfaa9f3b129..3dd1972c5f22 100755 --- a/maintainers/scripts/ec2/create-ebs-amis.py +++ b/maintainers/scripts/ec2/create-ebs-amis.py @@ -32,10 +32,16 @@ f.write('''{{ '''.format(args.region, key_name, ebs_size)) f.close() -depl = deployment.Deployment("./ebs-creator.json", create=True, nix_exprs=["./ebs-creator.nix", "./ebs-creator-config.nix"]) -depl.load_state() -if not args.keep: depl.destroy_vms() -depl.deploy() +db = deployment.open_database("./ebs-creator.charon") +try: + depl = deployment.open_deployment(db, "ebs-creator") +except Exception: + depl = deployment.create_deployment(db) + depl.name = "ebs-creator" +depl.auto_response = "y" +depl.nix_exprs = ["./ebs-creator.nix", "./ebs-creator-config.nix"] +if not args.keep: depl.destroy_resources() +depl.deploy(allow_reboot=True) m = depl.machines['machine'] @@ -52,8 +58,16 @@ m.run_command("mkdir -p /mnt") m.run_command("mount {0} /mnt".format(device)) m.run_command("touch /mnt/.ebs") m.run_command("mkdir -p /mnt/etc/nixos") -m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable") -m.run_command("nix-channel --update") +# Kind of hacky until the nixos channel is updated to systemd +#m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable") +#m.run_command("nix-channel --update") +m.run_command("mkdir unpack") +m.run_command("cd unpack; (curl -L http://hydra.nixos.org/job/nixos/systemd/channel/latest/download | bzcat | tar xv)") +m.run_command("mkdir nixos") +m.run_command("mv unpack/*/* nixos") +m.run_command("mv nixos unpack/*") +m.run_command("nix-env -p /nix/var/nix/profiles/per-user/root/channels -i $(nix-store --add unpack/*)") +m.run_command("rm -fR unpack") m.run_command("nixos-rebuild switch") version = m.run_command("nixos-version", capture_stdout=True).replace('"', '').rstrip() print >> sys.stderr, "NixOS version is {0}".format(version) @@ -84,7 +98,7 @@ def check(): return status == '100%' m.connect() -volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m._instance_id, 'attachment.device': "/dev/sdg"})[0] +volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0] if args.hvm: instance = m._conn.run_instances( image_id="ami-6a9e4503" , instance_type=instance_type @@ -117,7 +131,7 @@ else: m._conn.create_tags([snapshot.id], {'Name': ami_name}) - if not args.keep: depl.destroy_vms() + if not args.keep: depl.destroy_resources() # Register the image. aki = m._conn.get_all_images(filters={'manifest-location': '*pv-grub-hd0_1.03-x86_64*'})[0] @@ -163,11 +177,15 @@ f.write( '''.format(args.region, ami_id, instance_type, key_name)) f.close() -test_depl = deployment.Deployment("./ebs-test.json", create=True, nix_exprs=["./ebs-test.nix"]) -test_depl.load_state() +test_depl = deployment.create_deployment(db) +test_depl.auto_response = "y" +test_depl.name = "ebs-creator-test" +test_depl.nix_exprs = [ "./ebs-test.nix" ] test_depl.deploy(create_only=True) test_depl.machines['machine'].run_command("nixos-version") -if not args.keep: test_depl.destroy_vms() +if not args.keep: + test_depl.destroy_resources() + test_depl.delete() # Log the AMI ID. f = open("{0}.ebs.ami-id".format(args.region), "w") From be4f69519b38e842ad9df58371a483bb73add908 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 11:31:52 -0500 Subject: [PATCH 259/327] iso-image: Use unionfs-fuse instead of aufs --- modules/installer/cd-dvd/iso-image.nix | 41 +++++++++++++++----------- modules/system/boot/stage-1-init.sh | 4 +-- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix index 96fc8a31dca2..8c0008771bb0 100644 --- a/modules/installer/cd-dvd/iso-image.nix +++ b/modules/installer/cd-dvd/iso-image.nix @@ -192,34 +192,41 @@ in options = "loop"; }; - # We need squashfs in the initrd to mount the compressed Nix store, - # and aufs to make the root filesystem appear writable. - boot.extraModulePackages = - if config.boot.kernelPackages.aufs == null then - abort "This kernel doesn't have aufs enabled" - else - [ config.boot.kernelPackages.aufs ]; + boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ]; - boot.initrd.availableKernelModules = [ "aufs" "squashfs" "iso9660" ]; - - boot.initrd.kernelModules = [ "loop" ]; + boot.initrd.kernelModules = [ "loop" "fuse" ]; boot.kernelModules = pkgs.stdenv.lib.optional config.isoImage.makeEfiBootable "efivars"; + # Need unionfs-fuse + boot.initrd.extraUtilsCommands = '' + cp -v ${pkgs.fuse}/lib/libfuse* $out/lib + cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin + ''; + # In stage 1, mount a tmpfs on top of / (the ISO image) and # /nix/store (the squashfs image) to make this a live CD. boot.initrd.postMountCommands = '' - mkdir /mnt-root-tmpfs - mount -t tmpfs -o "mode=755" none /mnt-root-tmpfs + # Hacky!!! fuse hard-codes the path to mount + mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + + mkdir -p /unionfs-chroot$targetRoot + mount --rbind $targetRoot /unionfs-chroot$targetRoot + + mkdir /unionfs-chroot/mnt-root-tmpfs + mount -t tmpfs -o "mode=755" none /unionfs-chroot/mnt-root-tmpfs mkdir /mnt-root-union - mount -t aufs -o dirs=/mnt-root-tmpfs=rw:$targetRoot=ro none /mnt-root-union + unionfs -o allow_other,cow,chroot=/unionfs-chroot /mnt-root-tmpfs=RW:$targetRoot=RO /mnt-root-union + oldTargetRoot=$targetRoot targetRoot=/mnt-root-union - mkdir /mnt-store-tmpfs - mount -t tmpfs -o "mode=755" none /mnt-store-tmpfs - mkdir -p $targetRoot/nix/store - mount -t aufs -o dirs=/mnt-store-tmpfs=rw:/mnt-root/nix/store=ro none /mnt-root-union/nix/store + mkdir /unionfs-chroot/mnt-store-tmpfs + mount -t tmpfs -o "mode=755" none /unionfs-chroot/mnt-store-tmpfs + mkdir -p $oldTargetRoot/nix/store + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /mnt-store-tmpfs=RW:$oldTargetRoot/nix/store=RO /mnt-root-union/nix/store ''; # Closures to be copied to the Nix store on the CD, namely the init diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 23207babe3fa..778e36cfd36e 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -332,8 +332,8 @@ exec 3>&- udevadm control --exit || true # Kill any remaining processes, just to be sure we're not taking any -# with us into stage 2. -pkill -9 -v 1 +# with us into stage 2. unionfs-fuse mounts require the unionfs process. +pkill -9 -v '(1|unionfs)' if test -n "$debug1mounts"; then fail; fi From 3eb0faf3178b6b16f2b0dc13480ab9da727bee42 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 11:56:49 -0500 Subject: [PATCH 260/327] qemu-vm: Use unionfs-fuse instead of aufs for writableStore --- modules/virtualisation/qemu-vm.nix | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 22e5017d7c08..982a6b6db45b 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -95,7 +95,7 @@ let description = '' If enabled, the Nix store in the VM is made writable by - layering an AUFS/tmpfs filesystem on top of the host's Nix + layering a unionfs-fuse/tmpfs filesystem on top of the host's Nix store. ''; }; @@ -250,16 +250,18 @@ in # CIFS. Also use paravirtualised network and block devices for # performance. boot.initrd.availableKernelModules = - [ "cifs" "nls_utf8" "hmac" "md4" "ecb" "des_generic" ] - ++ optional cfg.writableStore [ "aufs" ]; + [ "cifs" "nls_utf8" "hmac" "md4" "ecb" "des_generic" ]; - boot.extraModulePackages = - optional cfg.writableStore config.boot.kernelPackages.aufs; + # unionfs-fuse expects fuse to be loaded + boot.initrd.kernelModules = optional cfg.writableStore [ "fuse" ]; boot.initrd.extraUtilsCommands = '' # We need mke2fs in the initrd. cp ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin + '' + optionalString cfg.writableStore '' + cp -v ${pkgs.fuse}/lib/libfuse* $out/lib + cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin ''; boot.initrd.postDeviceCommands = @@ -288,9 +290,17 @@ in mkdir -p $targetRoot/boot mount -o remount,ro $targetRoot/nix/store ${optionalString cfg.writableStore '' - mkdir /mnt-store-tmpfs - mount -t tmpfs -o "mode=755" none /mnt-store-tmpfs - mount -t aufs -o dirs=/mnt-store-tmpfs=rw:$targetRoot/nix/store=rr none $targetRoot/nix/store + # Hacky!!! fuse hard-codes the path to mount + mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + + mkdir -p /unionfs-chroot$targetRoot + mount --rbind $targetRoot /unionfs-chroot$targetRoot + + mkdir /unionfs-chroot/mnt-store-tmpfs + mount -t tmpfs -o "mode=755" none /unionfs-chroot/mnt-store-tmpfs + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /mnt-store-tmpfs=RW:$targetRoot/nix/store=RO $targetRoot/nix/store ''} ''; From e34024d998291899f9239ef43c3d74363108417f Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 12:33:36 -0500 Subject: [PATCH 261/327] Refactor common unionfs-fuse initrd prep into a separate module --- modules/installer/cd-dvd/iso-image.nix | 17 +++-------------- modules/module-list.nix | 1 + modules/tasks/filesystems/unionfs-fuse.nix | 19 +++++++++++++++++++ modules/virtualisation/qemu-vm.nix | 11 +---------- 4 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 modules/tasks/filesystems/unionfs-fuse.nix diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix index 8c0008771bb0..c9d443441e36 100644 --- a/modules/installer/cd-dvd/iso-image.nix +++ b/modules/installer/cd-dvd/iso-image.nix @@ -194,25 +194,14 @@ in boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ]; - boot.initrd.kernelModules = [ "loop" "fuse" ]; + boot.initrd.kernelModules = [ "loop" ]; boot.kernelModules = pkgs.stdenv.lib.optional config.isoImage.makeEfiBootable "efivars"; - # Need unionfs-fuse - boot.initrd.extraUtilsCommands = '' - cp -v ${pkgs.fuse}/lib/libfuse* $out/lib - cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin - ''; - # In stage 1, mount a tmpfs on top of / (the ISO image) and # /nix/store (the squashfs image) to make this a live CD. boot.initrd.postMountCommands = '' - # Hacky!!! fuse hard-codes the path to mount - mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin - ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin - ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin - mkdir -p /unionfs-chroot$targetRoot mount --rbind $targetRoot /unionfs-chroot$targetRoot @@ -318,7 +307,7 @@ in ''; # Add vfat support to the initrd to enable people to copy the - # contents of the CD to a bootable USB stick. - boot.initrd.supportedFilesystems = [ "vfat" ]; + # contents of the CD to a bootable USB stick. Need unionfs-fuse for union mounts + boot.initrd.supportedFilesystems = [ "vfat" "unionfs-fuse" ]; } diff --git a/modules/module-list.nix b/modules/module-list.nix index 467eac6e00e4..ae5e5d5c49f6 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -214,6 +214,7 @@ ./tasks/filesystems/ext.nix ./tasks/filesystems/nfs.nix ./tasks/filesystems/reiserfs.nix + ./tasks/filesystems/unionfs-fuse.nix ./tasks/filesystems/vfat.nix ./tasks/filesystems/xfs.nix ./tasks/kbd.nix diff --git a/modules/tasks/filesystems/unionfs-fuse.nix b/modules/tasks/filesystems/unionfs-fuse.nix new file mode 100644 index 000000000000..48cf798c7f0a --- /dev/null +++ b/modules/tasks/filesystems/unionfs-fuse.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +{ + config = pkgs.lib.mkIf (pkgs.lib.any (fs: fs == "unionfs-fuse") config.boot.initrd.supportedFilesystems) { + boot.initrd.kernelModules = [ "fuse" ]; + + boot.initrd.extraUtilsCommands = '' + cp -v ${pkgs.fuse}/lib/libfuse* $out/lib + cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin + ''; + + boot.initrd.postDeviceCommands = '' + # Hacky!!! fuse hard-codes the path to mount + mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin + ''; + }; +} diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 982a6b6db45b..8d50da8296c0 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -252,16 +252,12 @@ in boot.initrd.availableKernelModules = [ "cifs" "nls_utf8" "hmac" "md4" "ecb" "des_generic" ]; - # unionfs-fuse expects fuse to be loaded - boot.initrd.kernelModules = optional cfg.writableStore [ "fuse" ]; + boot.initrd.supportedFilesystems = optional cfg.writableStore "unionfs-fuse"; boot.initrd.extraUtilsCommands = '' # We need mke2fs in the initrd. cp ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin - '' + optionalString cfg.writableStore '' - cp -v ${pkgs.fuse}/lib/libfuse* $out/lib - cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin ''; boot.initrd.postDeviceCommands = @@ -290,11 +286,6 @@ in mkdir -p $targetRoot/boot mount -o remount,ro $targetRoot/nix/store ${optionalString cfg.writableStore '' - # Hacky!!! fuse hard-codes the path to mount - mkdir -p /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin - ln -s $(which mount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin - ln -s $(which umount) /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${pkgs.utillinux.name}/bin - mkdir -p /unionfs-chroot$targetRoot mount --rbind $targetRoot /unionfs-chroot$targetRoot From d19c223ba6285da363e8bb8022e67a52c7bb9e0a Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 13:07:42 -0500 Subject: [PATCH 262/327] Simplify unionfs-chroot bind-mounting --- modules/installer/cd-dvd/iso-image.nix | 16 ++++++++-------- modules/virtualisation/qemu-vm.nix | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix index c9d443441e36..33000a3fbf1d 100644 --- a/modules/installer/cd-dvd/iso-image.nix +++ b/modules/installer/cd-dvd/iso-image.nix @@ -202,20 +202,20 @@ in # /nix/store (the squashfs image) to make this a live CD. boot.initrd.postMountCommands = '' - mkdir -p /unionfs-chroot$targetRoot - mount --rbind $targetRoot /unionfs-chroot$targetRoot + mkdir -p /unionfs-chroot/ro-root + mount --rbind $targetRoot /unionfs-chroot/ro-root - mkdir /unionfs-chroot/mnt-root-tmpfs - mount -t tmpfs -o "mode=755" none /unionfs-chroot/mnt-root-tmpfs + mkdir /unionfs-chroot/rw-root + mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-root mkdir /mnt-root-union - unionfs -o allow_other,cow,chroot=/unionfs-chroot /mnt-root-tmpfs=RW:$targetRoot=RO /mnt-root-union + unionfs -o allow_other,cow,chroot=/unionfs-chroot /rw-root=RW:/ro-root=RO /mnt-root-union oldTargetRoot=$targetRoot targetRoot=/mnt-root-union - mkdir /unionfs-chroot/mnt-store-tmpfs - mount -t tmpfs -o "mode=755" none /unionfs-chroot/mnt-store-tmpfs + mkdir /unionfs-chroot/rw-store + mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store mkdir -p $oldTargetRoot/nix/store - unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /mnt-store-tmpfs=RW:$oldTargetRoot/nix/store=RO /mnt-root-union/nix/store + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /rw-store=RW:/ro-root/nix/store=RO /mnt-root-union/nix/store ''; # Closures to be copied to the Nix store on the CD, namely the init diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix index 8d50da8296c0..0367379b2444 100644 --- a/modules/virtualisation/qemu-vm.nix +++ b/modules/virtualisation/qemu-vm.nix @@ -286,12 +286,12 @@ in mkdir -p $targetRoot/boot mount -o remount,ro $targetRoot/nix/store ${optionalString cfg.writableStore '' - mkdir -p /unionfs-chroot$targetRoot - mount --rbind $targetRoot /unionfs-chroot$targetRoot + mkdir -p /unionfs-chroot/ro-store + mount --rbind $targetRoot/nix/store /unionfs-chroot/ro-store - mkdir /unionfs-chroot/mnt-store-tmpfs - mount -t tmpfs -o "mode=755" none /unionfs-chroot/mnt-store-tmpfs - unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /mnt-store-tmpfs=RW:$targetRoot/nix/store=RO $targetRoot/nix/store + mkdir /unionfs-chroot/rw-store + mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /rw-store=RW:/ro-store=RO $targetRoot/nix/store ''} ''; From ac9002ce1845d14dfaa8af0fdb25c9958729b2b2 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 13:16:17 -0500 Subject: [PATCH 263/327] amazon-image: use unionfs-fuse instead of aufs --- modules/virtualisation/amazon-image.nix | 34 +++++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/modules/virtualisation/amazon-image.nix b/modules/virtualisation/amazon-image.nix index da6f6d3afc92..79fb435db386 100644 --- a/modules/virtualisation/amazon-image.nix +++ b/modules/virtualisation/amazon-image.nix @@ -64,11 +64,9 @@ with pkgs.lib; fileSystems."/".device = "/dev/disk/by-label/nixos"; - boot.initrd.kernelModules = [ "xen-blkfront" "aufs" ]; + boot.initrd.kernelModules = [ "xen-blkfront" ]; boot.kernelModules = [ "xen-netfront" ]; - boot.extraModulePackages = [ config.boot.kernelPackages.aufs ]; - # Generate a GRUB menu. Amazon's pv-grub uses this to boot our kernel/initrd. boot.loader.grub.device = "nodev"; boot.loader.grub.timeout = 0; @@ -89,12 +87,12 @@ with pkgs.lib; # while "m1.large" has two ephemeral filesystems and no swap # devices). Also, put /tmp and /var on /disk0, since it has a lot # more space than the root device. Similarly, "move" /nix to /disk0 - # by layering an AUFS on top of it so we have a lot more space for + # by layering a unionfs-fuse mount on top of it so we have a lot more space for # Nix operations. boot.initrd.postMountCommands = '' diskNr=0 - diskForAufs= + diskForUnionfs= for device in /dev/xvd[abcde]*; do if [ "$device" = /dev/xvda -o "$device" = /dev/xvda1 ]; then continue; fi fsType=$(blkid -o value -s TYPE "$device" || true) @@ -106,25 +104,31 @@ with pkgs.lib; diskNr=$((diskNr + 1)) echo "mounting $device on $mp..." if mountFS "$device" "$mp" "" ext3; then - if [ -z "$diskForAufs" ]; then diskForAufs="$mp"; fi + if [ -z "$diskForUnionfs" ]; then diskForUnionfs="$mp"; fi fi else echo "skipping unknown device type $device" fi done - if [ -n "$diskForAufs" ]; then - mkdir -m 755 -p $targetRoot/$diskForAufs/root + if [ -n "$diskForUnionfs" ]; then + mkdir -m 755 -p $targetRoot/$diskForUnionfs/root - mkdir -m 1777 -p $targetRoot/$diskForAufs/root/tmp $targetRoot/tmp - mount --bind $targetRoot/$diskForAufs/root/tmp $targetRoot/tmp + mkdir -m 1777 -p $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp + mount --bind $targetRoot/$diskForUnionfs/root/tmp $targetRoot/tmp if [ ! -e $targetRoot/.ebs ]; then - mkdir -m 755 -p $targetRoot/$diskForAufs/root/var $targetRoot/var - mount --bind $targetRoot/$diskForAufs/root/var $targetRoot/var + mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/var $targetRoot/var + mount --bind $targetRoot/$diskForUnionfs/root/var $targetRoot/var - mkdir -m 755 -p $targetRoot/$diskForAufs/root/nix - mount -t aufs -o dirs=$targetRoot/$diskForAufs/root/nix=rw:$targetRoot/nix=rr none $targetRoot/nix + mkdir -p /unionfs-chroot/ro-nix + mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix + + mkdir -m 755 -p $targetRoot/$diskForUnionfs/root/nix + mkdir -p /unionfs-chroot/rw-nix + mount --rbind $targetRoot/$diskForUnionfs/root/nix /unionfs-chroot/rw-nix + + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /rw-nix=RW:/ro-nix=RO $targetRoot/nix fi fi ''; @@ -149,4 +153,6 @@ with pkgs.lib; # Always include cryptsetup so that Charon can use it. environment.systemPackages = [ pkgs.cryptsetup ]; + + boot.initrd.supportedFilesystems = [ "unionfs-fuse" ]; } From ae4c8e3e0b6218c1cadd7ee360cd92ec613646b9 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 13:31:44 -0500 Subject: [PATCH 264/327] nova-image.nix: Replace the commented-out aufs mount with a commented-out unionfs-fuse mount --- modules/virtualisation/nova-image.nix | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/virtualisation/nova-image.nix b/modules/virtualisation/nova-image.nix index 2aa78aeaddab..0ce5d218cdb4 100644 --- a/modules/virtualisation/nova-image.nix +++ b/modules/virtualisation/nova-image.nix @@ -72,10 +72,6 @@ with pkgs.lib; boot.kernelParams = [ "console=ttyS0" ]; - boot.initrd.kernelModules = [ "aufs" ]; - - boot.extraModulePackages = [ config.boot.kernelPackages.aufs ]; - boot.loader.grub.version = 2; boot.loader.grub.device = "/dev/vda"; boot.loader.grub.timeout = 0; @@ -83,8 +79,8 @@ with pkgs.lib; # Put /tmp and /var on /ephemeral0, which has a lot more space. # Unfortunately we can't do this with the `fileSystems' option # because it has no support for creating the source of a bind - # mount. Also, "move" /nix to /ephemeral0 by layering an AUFS - # on top of it so we have a lot more space for Nix operations. + # mount. Also, "move" /nix to /ephemeral0 by layering a unionfs-fuse + # mount on top of it so we have a lot more space for Nix operations. /* boot.initrd.postMountCommands = '' @@ -96,9 +92,16 @@ with pkgs.lib; mkdir -m 755 -p $targetRoot/var mount --bind $targetRoot/ephemeral0/var $targetRoot/var + mkdir -p /unionfs-chroot/ro-nix + mount --rbind $targetRoot/nix /unionfs-chroot/ro-nix + + mkdir -p /unionfs-chroot/rw-nix mkdir -m 755 -p $targetRoot/ephemeral0/nix - mount -t aufs -o dirs=$targetRoot/ephemeral0/nix=rw:$targetRoot/nix=rr none $targetRoot/nix + mount --rbind $targetRoot/ephemeral0/nix /unionfs-chroot/rw-nix + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot /rw-nix=RW:/ro-nix=RO $targetRoot/nix ''; + + boot.initrd.supportedFilesystems = [ "unionfs-fuse" ]; */ # Since Nova allows VNC access to instances, it's nice to start to From dfca6b97f1933d41c6e63a0b06eaa3f8dcbf7b88 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 13:33:23 -0500 Subject: [PATCH 265/327] Remove last mention of aufs for completeness --- modules/system/boot/kernel.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 4b6436a77f76..3637378d4d1e 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -64,7 +64,7 @@ in boot.extraModulePackages = mkOption { default = []; - # !!! example = [pkgs.aufs pkgs.nvidia_x11]; + # !!! example = [pkgs.nvidia_x11]; description = "A list of additional packages supplying kernel modules."; }; From 39a6143c6636495dc40b1a5434860a895a4142fe Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Sun, 16 Dec 2012 20:28:45 +0100 Subject: [PATCH 266/327] Add options to control rate limiting behaviour of journald. See 'man journald.conf' for more information. --- modules/system/boot/systemd.nix | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index eee65a3ffe0f..ecd6b07c0fff 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -407,6 +407,30 @@ in description = "If non-empty, write log messages to the specified TTY device."; }; + services.journald.rateLimitInterval = mkOption { + default = "10s"; + type = types.uniq types.string; + description = '' + Configures the rate limiting interval that is applied to all + messages generated on the system. This rate limiting is applied + per-service, so that two services which log do not interfere with + each other's limit. The value may be specified in the following + units: s, min, h, ms, us. To turn off any kind of rate limiting, + set either value to 0. + ''; + }; + + services.journald.rateLimitBurst = mkOption { + default = 100; + type = types.uniq types.int; + description = '' + Configures the rate limiting burst limit (number of messages per + interval) that is applied to all messages generated on the system. + This rate limiting is applied per-service, so that two services + which log do not interfere with each other's limit. + ''; + }; + }; @@ -433,6 +457,8 @@ in { source = pkgs.writeText "journald.conf" '' [Journal] + RateLimitInterval=${config.services.journald.rateLimitInterval} + RateLimitBurst=${toString config.services.journald.rateLimitBurst} ${optionalString (config.services.journald.console != "") '' ForwardToConsole=yes TTYPath=${config.services.journald.console} From dc7a5e99d5399fbb3469597de9488a33d69614e0 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 16 Dec 2012 20:12:39 -0500 Subject: [PATCH 267/327] create-ebs-amis.py: Fix for latest charon --- maintainers/scripts/ec2/create-ebs-amis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maintainers/scripts/ec2/create-ebs-amis.py b/maintainers/scripts/ec2/create-ebs-amis.py index 3dd1972c5f22..31613f089629 100755 --- a/maintainers/scripts/ec2/create-ebs-amis.py +++ b/maintainers/scripts/ec2/create-ebs-amis.py @@ -74,7 +74,7 @@ print >> sys.stderr, "NixOS version is {0}".format(version) m.run_command("cp -f $(nix-instantiate --find-file nixos/modules/virtualisation/amazon-config.nix) /mnt/etc/nixos/configuration.nix") m.run_command("nixos-install") if args.hvm: - m.run_command('cp /nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub') + m.run_command('cp /mnt/nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub') m.run_command('sed -i "s|hd0|hd0,0|" /mnt/boot/grub/menu.lst') m.run_command('echo "(hd1) /dev/xvdg" > device.map') m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch') @@ -103,7 +103,7 @@ if args.hvm: instance = m._conn.run_instances( image_id="ami-6a9e4503" , instance_type=instance_type , key_name=key_name - , placement=m._zone + , placement=m.zone , security_groups=["eelco-test"]).instances[0] charon.util.check_wait(lambda: instance.update() == 'running', max_tries=120) instance.stop() From dd131a0c093aa533a96923ac7bd22cef59eabd23 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Mon, 17 Dec 2012 13:09:05 -0500 Subject: [PATCH 268/327] Revert "Setting the system utillinux to be utillinuxCurses." This reverts commit cba4d20280d286cdcd8d07bb9b721978d2c6f883. --- modules/config/system-path.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix index 32e8717cbd1c..3969be680980 100644 --- a/modules/config/system-path.nix +++ b/modules/config/system-path.nix @@ -50,7 +50,7 @@ let pkgs.sysvtools pkgs.time pkgs.usbutils - pkgs.utillinuxCurses + pkgs.utillinux extraManpages ]; From 251f8546c938e18f6cfa7e073aad32b7f76a11cc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 17 Dec 2012 21:08:29 +0100 Subject: [PATCH 269/327] pam_ssh_agent_auth: Use /etc/ssh/authorized_keys.d --- modules/security/pam.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/security/pam.nix b/modules/security/pam.nix index 940c596e3670..32721205b991 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -82,7 +82,7 @@ let ${optionalString rootOK "auth sufficient pam_rootok.so"} ${optionalString (config.security.pam.enableSSHAgentAuth && sshAgentAuth) - "auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys"} + "auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys:~/.ssh/authorized_keys2:/etc/ssh/authorized_keys.d/%u"} ${optionalString usbAuth "auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"} auth sufficient pam_unix.so ${optionalString allowNullPassword "nullok"} likeauth From 75c67b01946b53c711e775db766f53f334927d63 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 18 Dec 2012 13:40:04 +0100 Subject: [PATCH 270/327] mysql: Port to systemd --- modules/services/databases/mysql.nix | 30 ++++++++++++----------- modules/services/databases/postgresql.nix | 4 +-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix index 2c35c13255e5..ef29d563c72a 100644 --- a/modules/services/databases/mysql.nix +++ b/modules/services/databases/mysql.nix @@ -91,6 +91,7 @@ in description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database"; }; + # FIXME: remove this option; it's a really bad idea. rootPassword = mkOption { default = null; description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty."; @@ -140,10 +141,12 @@ in environment.systemPackages = [mysql]; - jobs.mysql = - { description = "MySQL server"; + boot.systemd.services.mysql = + { description = "MySQL Server"; - startOn = "filesystem"; + wantedBy = [ "multi-user.target" ]; + + unitConfig.RequiresMountsFor = "${cfg.dataDir}"; preStart = '' @@ -156,9 +159,12 @@ in mkdir -m 0700 -p ${cfg.pidDir} chown -R ${cfg.user} ${cfg.pidDir} - - ${mysql}/libexec/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions} & + ''; + serviceConfig.ExecStart = "${mysql}/libexec/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}"; + + postStart = + '' # Wait until the MySQL server is available for use count=0 while [ ! -e /tmp/mysql.sock ] @@ -183,7 +189,7 @@ in echo "Creating initial database: ${database.name}" ( echo "create database ${database.name};" echo "use ${database.name};" - + if [ -f "${database.schema}" ] then cat ${database.schema} @@ -204,7 +210,7 @@ in ${optionalString (cfg.rootPassword != null) '' # Change root password - + ( echo "use mysql;" echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';" echo "flush privileges;" @@ -213,14 +219,10 @@ in rm /tmp/mysql_init fi - ''; + ''; # */ - postStop = "${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown"; - - # !!! Need a postStart script to wait until mysqld is ready to - # accept connections. - - extraConfig = "kill timeout 60"; + serviceConfig.ExecStop = + "${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown"; }; }; diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index c34ae9037f26..a013a3ccc3d6 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -156,10 +156,10 @@ in environment.systemPackages = [postgresql]; boot.systemd.services.postgresql = - { description = "PostgreSQL"; + { description = "PostgreSQL Server"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" "fs.target" ]; + after = [ "network.target" ]; environment = { TZ = config.time.timeZone; From ab18c03685ca47ee0289e4cef0a1d641cf777b54 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 18 Dec 2012 13:43:01 +0100 Subject: [PATCH 271/327] mysql55: Port to systemd Not tested. Seriously tempted to delete mysql55. See issue #47. --- modules/services/databases/mysql55.nix | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/modules/services/databases/mysql55.nix b/modules/services/databases/mysql55.nix index a37f1d388313..51fe37b76846 100644 --- a/modules/services/databases/mysql55.nix +++ b/modules/services/databases/mysql55.nix @@ -84,6 +84,7 @@ in description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database"; }; + # FIXME: remove this option; it's a really bad idea. rootPassword = mkOption { default = null; description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty."; @@ -133,10 +134,12 @@ in environment.systemPackages = [mysql]; - jobs.mysql = - { description = "MySQL server"; + boot.systemd.services.mysql = + { description = "MySQL Server"; - startOn = "filesystem"; + wantedBy = [ "multi-user.target" ]; + + unitConfig.RequiresMountsFor = "${cfg.dataDir}"; preStart = '' @@ -149,9 +152,12 @@ in mkdir -m 0700 -p ${cfg.pidDir} chown -R ${cfg.user} ${cfg.pidDir} - - ${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions} & + ''; + serviceConfig.ExecStart = "${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}"; + + postStart = + '' # Wait until the MySQL server is available for use count=0 while [ ! -e /tmp/mysql.sock ] @@ -176,7 +182,7 @@ in echo "Creating initial database: ${database.name}" ( echo "create database ${database.name};" echo "use ${database.name};" - + if [ -f "${database.schema}" ] then cat ${database.schema} @@ -207,7 +213,7 @@ in ${optionalString (cfg.rootPassword != null) '' # Change root password - + ( echo "use mysql;" echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';" echo "flush privileges;" @@ -216,14 +222,10 @@ in rm /tmp/mysql_init fi - ''; + ''; # */ - postStop = "${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown"; - - # !!! Need a postStart script to wait until mysqld is ready to - # accept connections. - - extraConfig = "kill timeout 60"; + serviceConfig.ExecStop = + "${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown"; }; }; From 3ef1432866f7b35adbd4a8b78b25ad0cf61c2fb4 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Tue, 18 Dec 2012 13:44:47 -0500 Subject: [PATCH 272/327] Update create-s3-amis and amazon-image.nix to recent nixos --- maintainers/scripts/ec2/create-s3-amis.sh | 5 +++-- modules/virtualisation/amazon-image.nix | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/maintainers/scripts/ec2/create-s3-amis.sh b/maintainers/scripts/ec2/create-s3-amis.sh index ac92c69f5bb9..767696cfe55e 100755 --- a/maintainers/scripts/ec2/create-s3-amis.sh +++ b/maintainers/scripts/ec2/create-s3-amis.sh @@ -1,6 +1,7 @@ #! /bin/sh -e -revision=$(svnversion "$NIXOS") +nixos=$(nix-instantiate --find-file nixos) +revision=$(cd $nixos; git rev-parse --short HEAD) echo "NixOS revision is $revision" buildAndUploadFor() { @@ -8,7 +9,7 @@ buildAndUploadFor() { arch="$2" echo "building $system image..." - NIXOS_CONFIG=$NIXOS/modules/virtualisation/amazon-config.nix nix-build "$NIXOS" \ + NIXOS_CONFIG=$nixos/modules/virtualisation/amazon-config.nix nix-build "$nixos" \ -A config.system.build.amazonImage --argstr system "$system" -o ec2-ami ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \ diff --git a/modules/virtualisation/amazon-image.nix b/modules/virtualisation/amazon-image.nix index 79fb435db386..38885d12b35c 100644 --- a/modules/virtualisation/amazon-image.nix +++ b/modules/virtualisation/amazon-image.nix @@ -50,6 +50,10 @@ with pkgs.lib; mkdir -p /mnt/etc touch /mnt/etc/NIXOS + # `switch-to-configuration' requires a /bin/sh + mkdir -p /mnt/bin + ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh + # Install a configuration.nix. mkdir -p /mnt/etc/nixos cp ${./amazon-config.nix} /mnt/etc/nixos/configuration.nix From fb8af2f9b6081338b4a2e2b0c850aba108044897 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 19 Dec 2012 12:59:28 +0100 Subject: [PATCH 273/327] postgresql: Don't wait for ages in post-start if the service has failed --- modules/services/databases/postgresql.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index a013a3ccc3d6..c178a84b1b85 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -199,7 +199,8 @@ in # Wait for PostgreSQL to be ready to accept connections. postStart = '' - while ! psql postgres -c ""; do + while ! psql postgres -c "" 2> /dev/null; do + if ! kill -0 "$MAINPID"; then exit 1; fi sleep 0.1 done ''; From 45f0de21f0118f743e486daa1fa1b311a9355afd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 21 Dec 2012 00:14:13 +0100 Subject: [PATCH 274/327] nixos-rebuild: Fix the check for running nix-daemon --- modules/installer/tools/nixos-rebuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/installer/tools/nixos-rebuild.sh b/modules/installer/tools/nixos-rebuild.sh index 01665e277b6d..66acf9087106 100644 --- a/modules/installer/tools/nixos-rebuild.sh +++ b/modules/installer/tools/nixos-rebuild.sh @@ -115,7 +115,7 @@ trap 'rm -rf "$tmpDir"' EXIT # This matters if the new Nix in Nixpkgs has a schema change. It # would upgrade the schema, which should only happen once we actually # switch to the new configuration. -if initctl status nix-daemon 2>&1 | grep -q 'running'; then +if systemctl show nix-daemon.socket nix-daemon.service | grep -q ActiveState=active; then export NIX_REMOTE=${NIX_REMOTE:-daemon} fi From e9784da0e0e3f51e3fcfa6be39137bb8daad5db1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 21 Dec 2012 00:17:42 +0100 Subject: [PATCH 275/327] Remove obsolete file --- tests/test-upstart-job.sh | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100755 tests/test-upstart-job.sh diff --git a/tests/test-upstart-job.sh b/tests/test-upstart-job.sh deleted file mode 100755 index d0fba23d6258..000000000000 --- a/tests/test-upstart-job.sh +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/sh -e - -for i in $*; do - echo "building job $i..." - nix-build /etc/nixos/nixos -A "config.jobs.$i" -o $tmpDir/.result - # !!! Here we assume that the attribute name equals the Upstart - # job name. - ln -sfn $(readlink -f $tmpDir/.result) /etc/init/"$i".conf -done - -echo "restarting init..." -initctl reload-configuration - -sleep 1 - -for i in $*; do - echo "restarting job $i..." - initctl stop "$i" || true - initctl start "$i" -done From 90fa68cf32f5ef9b5668ba222805355a95536277 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Tue, 18 Dec 2012 20:20:50 +0100 Subject: [PATCH 276/327] systemd: convert mongodb job to service --- modules/services/databases/mongodb.nix | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/services/databases/mongodb.nix b/modules/services/databases/mongodb.nix index c676d3e96e46..9e9e1c7dd8c9 100644 --- a/modules/services/databases/mongodb.nix +++ b/modules/services/databases/mongodb.nix @@ -97,17 +97,16 @@ in users.extraUsers = singleton { name = cfg.user; - shell = "/bin/sh"; description = "MongoDB server user"; }; - environment.systemPackages = [mongodb]; + environment.systemPackages = [ mongodb ]; - jobs.mongodb = + boot.systemd.services.mongodb = { description = "MongoDB server"; - daemonType = "daemon"; - startOn = "filesystem"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; preStart = '' @@ -117,11 +116,10 @@ in fi ''; - path = [mongodb]; - exec = "mongod --config ${mongoCnf} --fork"; - setuid = cfg.user; - - extraConfig = "kill timeout 10"; + serviceConfig = { + ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf}"; + User = cfg.user; + }; }; }; From dc58c2ea3790e449fb6c7ec7932c8a93fe2c4df8 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Thu, 27 Dec 2012 00:54:37 +0100 Subject: [PATCH 277/327] systemd: convert samba jobs to systemd services (samba.target) --- .../services/network-filesystems/samba.nix | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/modules/services/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix index 93c07df7cc60..aa75c4322a00 100644 --- a/modules/services/network-filesystems/samba.nix +++ b/modules/services/network-filesystems/samba.nix @@ -26,18 +26,14 @@ let mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd fi - passwdFile="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})" + passwdFile="$(${pkgs.gnused}/bin/sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})" if [ -n "$passwdFile" ]; then - echo 'INFO: creating directory containing passwd file' + echo 'INFO: [samba] creating directory containing passwd file' mkdir -p "$(dirname "$passwdFile")" fi mkdir -p ${logDir} mkdir -p ${privateDir} - - # The following line is to trigger a restart of the daemons when - # the configuration changes: - # ${configFile} ''; configFile = pkgs.writeText "smb.conf" @@ -60,12 +56,11 @@ let # This may include nss_ldap, needed for samba if it has to use ldap. nssModulesPath = config.system.nssModules.path; - daemonJob = appName: args: - { name = "samba-${appName}"; - description = "Samba Service daemon ${appName}"; + daemonService = appName: args: + { description = "Samba Service daemon ${appName}"; - startOn = "started samba"; - stopOn = "stopping samba"; + wantedBy = [ "samba.target" ]; + partOf = [ "samba.target" ]; environment = { LD_LIBRARY_PATH = nssModulesPath; @@ -73,9 +68,12 @@ let LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive"; }; - daemonType = "fork"; + serviceConfig = { + ExecStart = "${samba}/sbin/${appName} ${args}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; - exec = "${samba}/sbin/${appName} ${args}"; + restartTriggers = [ configFile ]; }; in @@ -202,22 +200,26 @@ in }; - # Dummy job to start the real Samba daemons (nmbd, smbd, winbindd). - jobs.sambaControl = - { name = "samba"; + boot.systemd = { + targets.samba = { description = "Samba server"; - - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; - - preStart = setupScript; + requires = [ "samba-setup.service" ]; + after = [ "samba-setup.service" "network.target" ]; + wantedBy = [ "multi-user.target" ]; }; - jobs.nmbd = daemonJob "nmbd" "-D"; + services = { + "samba-nmbd" = daemonService "nmbd" "-F"; + "samba-smbd" = daemonService "smbd" "-F"; + "samba-winbindd" = daemonService "winbindd" "-F"; + "samba-setup" = { + description = "Samba setup task"; + script = setupScript; + unitConfig.RequiresMountsFor = "/home/smbd /var/samba /var/log/samba"; + }; + }; + }; - jobs.smbd = daemonJob "smbd" "-D"; - - jobs.winbindd = daemonJob "winbindd" "-D"; }) ]; From f61f0c139b85766cff6bd40c304cdbf957ea2b27 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Thu, 27 Dec 2012 09:50:40 +0100 Subject: [PATCH 278/327] systemd: convert smartd job to service --- modules/services/monitoring/smartd.nix | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/services/monitoring/smartd.nix b/modules/services/monitoring/smartd.nix index 7e57f90398b7..72a4495b1f58 100644 --- a/modules/services/monitoring/smartd.nix +++ b/modules/services/monitoring/smartd.nix @@ -57,7 +57,7 @@ in description = '' Additional options for each device that is monitored. The example turns on SMART Automatic Offline Testing on startup, and schedules short - self-tests daily, and long self-tests weekly. + self-tests daily, and long self-tests weekly. ''; }; @@ -81,18 +81,16 @@ in config = mkIf cfg.enable { - jobs.smartd = { - description = "S.M.A.R.T. Daemon"; + boot.systemd.services.smartd = { + description = "S.M.A.R.T. Daemon"; - environment.TZ = config.time.timeZone; + environment.TZ = config.time.timeZone; - wantedBy = [ "multi-user.target" ]; - partOf = [ "multi-user.target" ]; + wantedBy = [ "multi-user.target" ]; + partOf = [ "multi-user.target" ]; - path = [ pkgs.smartmontools ]; - - exec = "smartd --no-fork --pidfile=/var/run/smartd.pid ${smartdFlags}"; - }; + serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}"; + }; }; From 3456f3b2328eddee4e34c5807959bdd32efd70da Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Wed, 26 Dec 2012 23:49:22 +0100 Subject: [PATCH 279/327] systemd: convert gogoclient job to service unit --- modules/services/networking/gogoclient.nix | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/modules/services/networking/gogoclient.nix b/modules/services/networking/gogoclient.nix index 593f2436a393..519c45a385a7 100644 --- a/modules/services/networking/gogoclient.nix +++ b/modules/services/networking/gogoclient.nix @@ -56,22 +56,36 @@ in config = mkIf cfg.enable { boot.kernelModules = [ "tun" ]; - # environment.systemPackages = [pkgs.gogoclient]; - networking.enableIPv6 = true; - jobs.gogoclient = { - name = "gogoclient"; + boot.systemd.services.gogoclient = { + description = "ipv6 tunnel"; - startOn = optionalString cfg.autorun "starting networking"; - stopOn = "stopping network-interfaces"; - preStart = '' - mkdir -p /var/lib/gogoc - chmod 700 /var/lib/gogoc - cat ${pkgs.gogoclient}/share/${pkgs.gogoclient.name}/gogoc.conf.sample | ${pkgs.gnused}/bin/sed -e "s|^userid=|&${cfg.username}|;s|^passwd=|&${if cfg.password == "" then "" else "$(cat ${cfg.password})"}|;s|^server=.*|server=${cfg.server}|;s|^auth_method=.*|auth_method=${if cfg.password == "" then "anonymous" else "any"}|;s|^#log_file=|log_file=1|" > /var/lib/gogoc/gogoc.conf + + after = [ "network.target" ]; + + preStart = let authMethod = if cfg.password == "" then "anonymous" else "any"; in + '' + mkdir -p -m 700 /var/lib/gogoc + cat ${pkgs.gogoclient}/share/${pkgs.gogoclient.name}/gogoc.conf.sample | \ + ${pkgs.gnused}/bin/sed \ + -e "s|^userid=|&${cfg.username}|" \ + -e "s|^passwd=|&${optionalString (cfg.password != "") "$(cat ${cfg.password})"}|" \ + -e "s|^server=.*|server=${cfg.server}|" \ + -e "s|^auth_method=.*|auth_method=${authMethod}|" \ + -e "s|^#log_file=|log_file=1|" > /var/lib/gogoc/gogoc.conf ''; - script = "cd /var/lib/gogoc; exec gogoc -y -f ./gogoc.conf"; - path = [pkgs.gogoclient]; + + serviceConfig.ExecStart = "${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf"; + + restartTriggers = attrValues cfg; + + } // optionalAttrs cfg.autorun { + + wantedBy = [ "ip-up.target" ]; + + partOf = [ "ip-up.target" ]; + }; }; From 244ed6ae710553cb1392b1a5c4538e9e47b44cd6 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Thu, 27 Dec 2012 10:04:05 +0100 Subject: [PATCH 280/327] nscd: use proper systemd.special(7) targets --- modules/services/system/nscd.nix | 2 +- modules/system/boot/systemd.nix | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index eecb845d5471..1843368ba27d 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -41,7 +41,7 @@ in boot.systemd.services.nscd = { description = "Name Service Cache Daemon"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ "nss-lookup.target" "nss-user-lookup.target" ]; environment = { LD_LIBRARY_PATH = nssModulesPath; }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index ecd6b07c0fff..a65c95e60f99 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -321,7 +321,8 @@ let ln -s ${cfg.defaultUnit} $out/default.target #ln -s ../getty@tty1.service $out/multi-user.target.wants/ - ln -s ../local-fs.target ../remote-fs.target ../network.target ../swap.target $out/multi-user.target.wants/ + ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \ + ../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/ ''; # */ in From 183829cf99b629a43e8f6d1033f627f9082b980e Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Thu, 27 Dec 2012 13:38:37 +0100 Subject: [PATCH 281/327] gogoclient: change working dir before starting otherwise state files are placed in / --- modules/services/networking/gogoclient.nix | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/modules/services/networking/gogoclient.nix b/modules/services/networking/gogoclient.nix index 519c45a385a7..7d742df97b0f 100644 --- a/modules/services/networking/gogoclient.nix +++ b/modules/services/networking/gogoclient.nix @@ -59,13 +59,14 @@ in networking.enableIPv6 = true; boot.systemd.services.gogoclient = { - description = "ipv6 tunnel"; after = [ "network.target" ]; + requires = [ "network.target" ]; - preStart = let authMethod = if cfg.password == "" then "anonymous" else "any"; in - '' + unitConfig.RequiresMountsFor = "/var/lib/gogoc"; + + script = let authMethod = if cfg.password == "" then "anonymous" else "any"; in '' mkdir -p -m 700 /var/lib/gogoc cat ${pkgs.gogoclient}/share/${pkgs.gogoclient.name}/gogoc.conf.sample | \ ${pkgs.gnused}/bin/sed \ @@ -74,18 +75,12 @@ in -e "s|^server=.*|server=${cfg.server}|" \ -e "s|^auth_method=.*|auth_method=${authMethod}|" \ -e "s|^#log_file=|log_file=1|" > /var/lib/gogoc/gogoc.conf + cd /var/lib/gogoc + exec ${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf ''; - - serviceConfig.ExecStart = "${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf"; - - restartTriggers = attrValues cfg; - } // optionalAttrs cfg.autorun { - wantedBy = [ "ip-up.target" ]; - partOf = [ "ip-up.target" ]; - }; }; From 19e8ffc43f63016b6cdc910f02d99161e9cbe135 Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Sun, 30 Dec 2012 19:30:06 +0100 Subject: [PATCH 282/327] networkmanager: Use systemctl instead of initctl --- modules/services/networking/networkmanager.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/networking/networkmanager.nix b/modules/services/networking/networkmanager.nix index 591f34ceee75..d8198dd03298 100644 --- a/modules/services/networking/networkmanager.nix +++ b/modules/services/networking/networkmanager.nix @@ -39,7 +39,7 @@ let ipUpScript = pkgs.writeScript "01nixos-ip-up" '' #!/bin/sh if test "$2" = "up"; then - ${pkgs.upstart}/sbin/initctl emit ip-up "IFACE=$1" + ${config.system.build.systemd}/bin/systemctl start ip-up.target fi ''; From 16a9bcfe815a9fe72c41348b4231c619e11da610 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Fri, 28 Dec 2012 13:29:53 +0100 Subject: [PATCH 283/327] add support for systemd mount units This is mainly useful for specifying mounts that depend on other units. For example sshfs or davfs need network (and possibly nameservices). While systemd makes a distinction between local and remote filesystems, this only works for in-kernel filesystems such as nfs and cifs. fuse-based filesystems (such as sshfs and davs) are classified as local, so they fail without networking. By explicitly declaring these mounts as full systemd units (as opposed to having systemd generate them automatically from /etc/fstab), dependencies can be specified as on every other unit. In the future, we can probably port NixOS' filesystems handling to use these native systemd.mount units and skip /etc/fstab altogether, but this probably requires additional changes, such as starting systemd even earlier during boot (stage 1). --- modules/system/boot/systemd-unit-options.nix | 47 ++++++++++++++++++ modules/system/boot/systemd.nix | 52 +++++++++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index 5707fb6f87e9..e3f0ec6f1d91 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -202,4 +202,51 @@ rec { }; + mountOptions = unitOptions // { + + what = mkOption { + default = ""; + example = "/dev/sda1"; + type = types.uniq types.string; + description = "Absolute path of device node, file or other resource. (Mandatory)"; + }; + + where = mkOption { + default = ""; + example = "/mnt"; + type = types.uniq types.string; + description = '' + Absolute path of a directory of the mount point. + Will be created if it doesn't exist. (Mandatory) + ''; + }; + + type = mkOption { + default = ""; + example = "ext4"; + type = types.uniq types.string; + description = "File system type."; + }; + + options = mkOption { + default = ""; + example = "noatime"; + type = types.string; + merge = concatStringsSep ","; + description = "Options used to mount the file system."; + }; + + mountConfig = mkOption { + default = {}; + example = { DirectoryMode = "0775"; }; + type = types.attrs; + description = '' + Each attribute in this set specifies an option in the + [Mount] section of the unit. See + systemd.mount + 5 for details. + ''; + }; + }; + } \ No newline at end of file diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index a65c95e60f99..fbd28e6e836e 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -198,6 +198,19 @@ let }; }; + mountConfig = { name, config, ... }: { + config = { + mountConfig = + { What = config.what; + Where = config.where; + } // optionalAttrs (config.type != "") { + Type = config.type; + } // optionalAttrs (config.options != "") { + Options = config.options; + }; + }; + }; + toOption = x: if x == true then "true" else if x == false then "false" @@ -277,6 +290,29 @@ let ''; }; + # this is by no means the full escaping-logic systemd uses + # so feel free to extend this further. + mountName = path: + let escaped = replaceChars [ "-" " " "/" ] + [ "\x2d" "\x20" "-" ] (toString path); + in if (substring 0 1 escaped == "-") + then substring 1 (sub (stringLength escaped) 1) escaped + else escaped; + + mountToUnit = name: def: + assert def.mountConfig.What != ""; + assert def.mountConfig.Where != ""; + { inherit (def) wantedBy enable; + text = + '' + [Unit] + ${attrsToSection def.unitConfig} + + [Mount] + ${attrsToSection def.mountConfig} + ''; + }; + nixosUnits = mapAttrsToList makeUnit cfg.units; units = pkgs.runCommand "units" { preferLocalBuild = true; } @@ -387,6 +423,17 @@ in description = "Definition of systemd socket units."; }; + boot.systemd.mounts = mkOption { + default = []; + type = types.listOf types.optionSet; + options = [ mountOptions unitConfig mountConfig ]; + description = '' + Definition of systemd mount units. + This is a list instead of an attrSet, because systemd mandates the names to be derived from + the 'where' attribute. + ''; + }; + boot.systemd.defaultUnit = mkOption { default = "multi-user.target"; type = types.uniq types.string; @@ -501,7 +548,10 @@ in { "rescue.service".text = rescueService; } // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets; + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets + // listToAttrs (map + (v: let n = mountName v.where; + in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts); system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [ "CGROUPS" "AUTOFS4_FS" "DEVTMPFS" From ebf48167174a2f3d80560f9a55750e7f304499a2 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Tue, 1 Jan 2013 14:42:43 +0100 Subject: [PATCH 284/327] systemd mount units: use 'escapeSystemdPath' from lib/utils --- lib/utils.nix | 2 +- modules/system/boot/systemd.nix | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/utils.nix b/lib/utils.nix index b75e063eaa92..35c56e8c32bb 100644 --- a/lib/utils.nix +++ b/lib/utils.nix @@ -5,6 +5,6 @@ rec { # Escape a path according to the systemd rules, e.g. /dev/xyzzy # becomes dev-xyzzy. FIXME: slow. escapeSystemdPath = s: - replaceChars ["/" "-"] ["-" "\\x2d"] (substring 1 (stringLength s) s); + replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"] (substring 1 (stringLength s) s); } diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index fbd28e6e836e..f0e94266b17f 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -1,6 +1,7 @@ -{ config, pkgs, ... }: +{ config, pkgs, utils, ... }: with pkgs.lib; +with utils; with import ./systemd-unit-options.nix { inherit config pkgs; }; let @@ -290,15 +291,6 @@ let ''; }; - # this is by no means the full escaping-logic systemd uses - # so feel free to extend this further. - mountName = path: - let escaped = replaceChars [ "-" " " "/" ] - [ "\x2d" "\x20" "-" ] (toString path); - in if (substring 0 1 escaped == "-") - then substring 1 (sub (stringLength escaped) 1) escaped - else escaped; - mountToUnit = name: def: assert def.mountConfig.What != ""; assert def.mountConfig.Where != ""; @@ -550,7 +542,7 @@ in // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets // listToAttrs (map - (v: let n = mountName v.where; + (v: let n = escapeSystemdPath v.where; in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts); system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [ From 7e70cffc45644405a95ccfe39b1dbd54ab132a28 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Tue, 1 Jan 2013 14:49:26 +0100 Subject: [PATCH 285/327] systemd mount units: better handling of mandatory options --- modules/system/boot/systemd-unit-options.nix | 2 -- modules/system/boot/systemd.nix | 2 -- 2 files changed, 4 deletions(-) diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index e3f0ec6f1d91..ad9b5da23164 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -205,14 +205,12 @@ rec { mountOptions = unitOptions // { what = mkOption { - default = ""; example = "/dev/sda1"; type = types.uniq types.string; description = "Absolute path of device node, file or other resource. (Mandatory)"; }; where = mkOption { - default = ""; example = "/mnt"; type = types.uniq types.string; description = '' diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index f0e94266b17f..f4d0655118ea 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -292,8 +292,6 @@ let }; mountToUnit = name: def: - assert def.mountConfig.What != ""; - assert def.mountConfig.Where != ""; { inherit (def) wantedBy enable; text = '' From 9aa69885f04969e5d31dcb8265c327adc908954e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 2 Jan 2013 18:23:19 +0100 Subject: [PATCH 286/327] Don't do readlink() on every mount point when remounting /dev etc. Doing so causes the activation script to hang if (say) an NFS mount point is unreachable. --- modules/system/activation/activation-script.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/system/activation/activation-script.nix b/modules/system/activation/activation-script.nix index 8d9dcaa17c16..dc0175632174 100644 --- a/modules/system/activation/activation-script.nix +++ b/modules/system/activation/activation-script.nix @@ -145,9 +145,9 @@ in system.activationScripts.tmpfs = '' - ${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devSize}" /dev - ${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devShmSize}" /dev/shm - ${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.runSize}" /run + ${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devSize}" none /dev + ${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.devShmSize}" none /dev/shm + ${pkgs.utillinux}/bin/mount -o "remount,size=${config.boot.runSize}" none /run ''; }; From 207d30b6f3b7d3fabfbc312ce06b73c1ce3a7a7c Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Fri, 4 Jan 2013 10:58:56 +0100 Subject: [PATCH 287/327] Fix VirtualBox image generation: switch-to-configuration in chroot needs /bin/sh --- modules/virtualisation/virtualbox-image.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/virtualisation/virtualbox-image.nix b/modules/virtualisation/virtualbox-image.nix index 8fe0030946a6..373195a9d688 100644 --- a/modules/virtualisation/virtualbox-image.nix +++ b/modules/virtualisation/virtualbox-image.nix @@ -63,6 +63,10 @@ with pkgs.lib; mkdir -p /mnt/etc/nixos cp ${./nova-config.nix} /mnt/etc/nixos/configuration.nix + # `switch-to-configuration' requires a /bin/sh + mkdir -p /mnt/bin + ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh + # Generate the GRUB menu. chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot From f701acfac056eb62f227e8a911b30a5bc66a26c9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 4 Jan 2013 13:50:50 +0100 Subject: [PATCH 288/327] nix-daemon: Start "nix-daemon" rather than "nix-worker --daemon" --- modules/services/misc/nix-daemon.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index 49aa8e7931f7..eaea8bd653a3 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -286,7 +286,7 @@ in environment = cfg.envVars; serviceConfig = - { ExecStart = "${nix}/bin/nix-worker --daemon"; + { ExecStart = "@${nix}/bin/nix-daemon nix-daemon"; KillMode = "process"; Nice = cfg.daemonNiceLevel; IOSchedulingPriority = cfg.daemonIONiceLevel; From baac242a1f9ea8f39e9bf00b484f77e490956d7e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 4 Jan 2013 14:04:41 +0100 Subject: [PATCH 289/327] Run the garbage collector as a systemd service Running it from systemd rather than cron has several advantages: systemd ensures that only one instance runs at a time; the GC can be manually started/stopped; and logging goes to the journal. We still need cron to start the service at the right time, but hopefully soon we can get rid of cron entirely (once systemd supports starting a unit at a specific time). --- modules/services/misc/nix-gc.nix | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/modules/services/misc/nix-gc.nix b/modules/services/misc/nix-gc.nix index 942e7996da02..5322e1ff57d8 100644 --- a/modules/services/misc/nix-gc.nix +++ b/modules/services/misc/nix-gc.nix @@ -16,7 +16,7 @@ in automatic = mkOption { default = false; - example = true; + type = types.bool; description = " Automatically run the garbage collector at specified dates. "; @@ -24,6 +24,7 @@ in dates = mkOption { default = "15 03 * * *"; + type = types.string; description = " Run the garbage collector at specified dates to avoid full hard-drives. @@ -33,6 +34,7 @@ in options = mkOption { default = ""; example = "--max-freed $((64 * 1024**3))"; + type = types.string; description = " Options given to nix-collect-garbage when the garbage collector is run automatically. @@ -45,10 +47,17 @@ in ###### implementation - config = mkIf cfg.automatic { - services.cron.systemCronJobs = [ - "${cfg.dates} root ${nix}/bin/nix-collect-garbage ${cfg.options} > /var/log/gc.log 2>&1" - ]; + config = { + + services.cron.systemCronJobs = mkIf cfg.automatic (singleton + "${cfg.dates} root ${config.system.build.systemd}/bin/systemctl start nix-gc.service"); + + boot.systemd.services."nix-gc" = + { description = "Nix Garbage Collector"; + serviceConfig.ExecStart = + "@${nix}/bin/nix-collect-garbage nix-collect-garbage ${cfg.options}"; + }; + }; } From 96ba0ca283607977620d31809d52396232074806 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 5 Jan 2013 01:05:25 +0100 Subject: [PATCH 290/327] For some units, use "systemctl restart" rather than "systemctl stop/start" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During a configuration switch, changed units are stopped in the old configuration, then started in the new configuration (i.e. after running the activation script and running "systemctl daemon-reload"). This ensures that services are stopped using the ExecStop/ExecStopPost commands from the old configuration. However, for some services it's undesirable to stop them; in particular dhcpcd, which deconfigures its network interfaces when it stops. This is dangerous when doing remote upgrades - usually things go right (especially because the switch script ignores SIGHUP), but not always (see 9aa69885f04969e5d31dcb8265c327adc908954e). Likewise, sshd should be kept running for as long as possible to prevent a lock-out if the switch fails. So the new option ‘stopIfChanged = false’ causes "systemctl restart" to be used instead of "systemctl stop" followed by "systemctl start". This is only proper for services that don't have stop commands. (And it might not handle dependencies properly in some cases, but I'm not sure.) --- modules/services/networking/dhcpcd.nix | 5 ++ modules/services/networking/ssh/sshd.nix | 2 + .../activation/switch-to-configuration.pl | 46 +++++++++++++------ modules/system/boot/systemd-unit-options.nix | 15 ++++++ modules/system/boot/systemd.nix | 1 + 5 files changed, 56 insertions(+), 13 deletions(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 2a0d73f60040..cf7f621a85d5 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -97,6 +97,11 @@ in wantedBy = [ "network.target" ]; + # Stopping dhcpcd during a reconfiguration is undesirable + # because it brings down the network interfaces configured by + # dhcpcd. So do a "systemctl restart" instead. + stopIfChanged = false; + path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; serviceConfig = diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 21f81152fa57..8f898ce06a18 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -267,6 +267,8 @@ in wantedBy = [ "multi-user.target" ]; + stopIfChanged = false; + path = [ pkgs.openssh ]; environment.LD_LIBRARY_PATH = nssModulesPath; diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index b085778f0994..28ccc158f726 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -6,6 +6,7 @@ use File::Basename; use File::Slurp; use Cwd 'abs_path'; +my $startListFile = "/run/systemd/start-list"; my $restartListFile = "/run/systemd/restart-list"; my $reloadListFile = "/run/systemd/reload-list"; @@ -125,7 +126,7 @@ while (my ($unit, $state) = each %{$activePrev}) { if ($unit ne "suspend.target" && $unit ne "hibernate.target") { my $unitInfo = parseUnit($newUnitFile); unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) { - write_file($restartListFile, { append => 1 }, "$unit\n"); + write_file($startListFile, { append => 1 }, "$unit\n"); } } } @@ -158,21 +159,31 @@ while (my ($unit, $state) = each %{$activePrev}) { foreach my $socket (@sockets) { if (defined $activePrev->{$socket}) { push @unitsToStop, $socket; - write_file($restartListFile, { append => 1 }, "$socket\n"); + write_file($startListFile, { append => 1 }, "$socket\n"); $socketActivated = 1; } } } - # Otherwise, record that this unit needs to be - # started below. We write this to a file to - # ensure that the service gets restarted if we're - # interrupted. - if (!$socketActivated) { - write_file($restartListFile, { append => 1 }, "$unit\n"); - } + if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "true")) { - push @unitsToStop, $unit; + # This unit should be restarted instead of + # stopped and started. + write_file($restartListFile, { append => 1 }, "$unit\n"); + + } else { + + # If the unit is not socket-activated, record + # that this unit needs to be started below. + # We write this to a file to ensure that the + # service gets restarted if we're interrupted. + if (!$socketActivated) { + write_file($startListFile, { append => 1 }, "$unit\n"); + } + + push @unitsToStop, $unit; + + } } } } @@ -216,7 +227,7 @@ foreach my $mountPoint (keys %$prevFss) { push @unitsToStop, $unit; } elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) { # Filesystem type or device changed, so unmount and mount it. - write_file($restartListFile, { append => 1 }, "$unit\n"); + write_file($startListFile, { append => 1 }, "$unit\n"); push @unitsToStop, $unit; } elsif ($prev->{options} ne $new->{options}) { # Mount options changes, so remount it. @@ -266,16 +277,25 @@ system("@systemd@/bin/systemctl", "reset-failed"); # Make systemd reload its units. system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3; +# Restart changed services (those that have to be restarted rather +# than stopped and started). +my @restart = unique(split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); +if (scalar @restart > 0) { + print STDERR "restarting the following units: ", join(", ", sort(@restart)), "\n"; + system("@systemd@/bin/systemctl", "restart", "--", @restart) == 0 or $res = 4; + unlink($restartListFile); +} + # Start all active targets, as well as changed units we stopped above. # The latter is necessary because some may not be dependencies of the # targets (i.e., they were manually started). FIXME: detect units # that are symlinks to other units. We shouldn't start both at the # same time because we'll get a "Failed to add path to set" error from # systemd. -my @start = unique("default.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // "")); +my @start = unique("default.target", split('\n', read_file($startListFile, err_mode => 'quiet') // "")); print STDERR "starting the following units: ", join(", ", sort(@start)), "\n"; system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4; -unlink($restartListFile); +unlink($startListFile); # Reload units that need it. This includes remounting changed mount # units. diff --git a/modules/system/boot/systemd-unit-options.nix b/modules/system/boot/systemd-unit-options.nix index ad9b5da23164..1f8097ada1c3 100644 --- a/modules/system/boot/systemd-unit-options.nix +++ b/modules/system/boot/systemd-unit-options.nix @@ -183,6 +183,21 @@ rec { ''; }; + stopIfChanged = mkOption { + type = types.bool; + default = true; + description = '' + If set, a changed unit is restarted by calling + systemctl stop in the old configuration, + then systemctl start in the new one. + Otherwise, it is restarted in a single step using + systemctl restart in the new configuration. + The latter is less correct because it runs the + ExecStop commands from the new + configuration. + ''; + }; + }; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index f4d0655118ea..a0462951d005 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -246,6 +246,7 @@ let ${let env = cfg.globalEnvironment // def.environment; in concatMapStrings (n: "Environment=${n}=${getAttr n env}\n") (attrNames env)} ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"} + ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"} ${optionalString (def.preStart != "") '' ExecStartPre=${makeJobScript "${name}-pre-start" '' From 1aea92c4ce311e685a5e9c0e7ab2df1562626ac6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 5 Jan 2013 01:35:26 +0100 Subject: [PATCH 291/327] =?UTF-8?q?Ensure=20that=20=E2=80=98nix.gc.options?= =?UTF-8?q?=E2=80=99=20is=20subject=20to=20shell=20expansion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/services/misc/nix-gc.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/services/misc/nix-gc.nix b/modules/services/misc/nix-gc.nix index 5322e1ff57d8..435326e87fb8 100644 --- a/modules/services/misc/nix-gc.nix +++ b/modules/services/misc/nix-gc.nix @@ -3,7 +3,6 @@ with pkgs.lib; let - nix = config.environment.nix; cfg = config.nix.gc; in @@ -54,8 +53,8 @@ in boot.systemd.services."nix-gc" = { description = "Nix Garbage Collector"; - serviceConfig.ExecStart = - "@${nix}/bin/nix-collect-garbage nix-collect-garbage ${cfg.options}"; + path = [ config.environment.nix ]; + script = "exec nix-collect-garbage ${cfg.options}"; }; }; From 9a81748f2044ccea5e5083e3c8b38c4f6f79cda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Sun, 6 Jan 2013 22:31:13 +0100 Subject: [PATCH 292/327] Adding defaultGatewayWindowSize This allows setting the max tcp window size for the route of the default gateway (usually the internet access). It works only for non-DHCP configurations by now. --- modules/tasks/network-interfaces.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 64cb4a6749eb..740c3b83cda6 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -5,6 +5,10 @@ with pkgs.lib; let cfg = config.networking; + + windowSize = if cfg.defaultGatewayWindowSize != "" then + "window ${cfg.defaultGatewayWindowSize}" else ""; + interfaces = attrValues cfg.interfaces; hasVirtuals = any (i: i.virtual) interfaces; @@ -135,6 +139,15 @@ in ''; }; + networking.defaultGatewayWindowSize = mkOption { + default = ""; + example = "524288"; + description = '' + The window size of the default gateway. It limits maximal data bursts that TCP peers + are allowed to send to us. + ''; + }; + networking.nameservers = mkOption { default = []; example = ["130.161.158.4" "130.161.33.17"]; @@ -282,7 +295,7 @@ in # Set the default gateway. ${optionalString (cfg.defaultGateway != "") '' # FIXME: get rid of "|| true" (necessary to make it idempotent). - ip route add default via "${cfg.defaultGateway}" || true + ip route add default via "${cfg.defaultGateway}" ${windowSize} || true ''} # Turn on forwarding if any interface has enabled proxy_arp. From 38af5986584621921c438c8bee08747f202106c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Sun, 6 Jan 2013 23:20:48 +0100 Subject: [PATCH 293/327] Simplifying defaultGatewayWindowSize according to Eelco suggestions --- modules/tasks/network-interfaces.nix | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 740c3b83cda6..bbc357b1b299 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -5,10 +5,6 @@ with pkgs.lib; let cfg = config.networking; - - windowSize = if cfg.defaultGatewayWindowSize != "" then - "window ${cfg.defaultGatewayWindowSize}" else ""; - interfaces = attrValues cfg.interfaces; hasVirtuals = any (i: i.virtual) interfaces; @@ -140,8 +136,9 @@ in }; networking.defaultGatewayWindowSize = mkOption { - default = ""; - example = "524288"; + default = null; + example = 524288; + type = types.nullOr types.int; description = '' The window size of the default gateway. It limits maximal data bursts that TCP peers are allowed to send to us. @@ -295,7 +292,9 @@ in # Set the default gateway. ${optionalString (cfg.defaultGateway != "") '' # FIXME: get rid of "|| true" (necessary to make it idempotent). - ip route add default via "${cfg.defaultGateway}" ${windowSize} || true + ip route add default via "${cfg.defaultGateway}" ${ + optionalString (cfg.defaultGatewayWindowSize != null) + "window ${cfg.defaultGatewayWindowSize}"} || true ''} # Turn on forwarding if any interface has enabled proxy_arp. From 2e035ae042ab4557c27953c3a1fd04754c89158a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jan 2013 15:04:19 +0100 Subject: [PATCH 294/327] Hack to prevent -cfg.service from breaking the default gateway Restarting -cfg.service may cause the interface's IP addresses to be flushed. If the default gateway goes through that interface, then the default gateway is deleted. So we need to restart network-setup.target. --- modules/tasks/network-interfaces.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index bbc357b1b299..82f4d3da4f11 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -347,6 +347,9 @@ in echo "configuring interface..." ip -4 addr flush dev "${i.name}" ip -4 addr add "${i.ipAddress}/${mask}" dev "${i.name}" + # Ensure that the default gateway remains set. + # (Flushing this interface may have removed it.) + ${config.system.build.systemd}/bin/systemctl try-restart --no-block network-setup.service else echo "skipping configuring interface" fi From da32722ade156ff9b924fb09f1c28792e5d1ecc0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jan 2013 16:00:10 +0100 Subject: [PATCH 295/327] display-manager: Start after local-fs.target We don't want users trying to log in while /home is still being fsck'ed... --- modules/services/x11/xserver.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 1c5a3f75039b..6eec6f88b97d 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -389,7 +389,7 @@ in boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; boot.systemd.services."display-manager" = - { after = [ "systemd-udev-settle.service" ]; + { after = [ "systemd-udev-settle.service" "local-fs.target" ]; restartIfChanged = false; From 74bae63135455282b8d8467573c4bfef4871c39d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jan 2013 16:01:22 +0100 Subject: [PATCH 296/327] smartd: Remove unnecessary PartOf dependency --- modules/services/monitoring/smartd.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/services/monitoring/smartd.nix b/modules/services/monitoring/smartd.nix index 72a4495b1f58..48066856625a 100644 --- a/modules/services/monitoring/smartd.nix +++ b/modules/services/monitoring/smartd.nix @@ -87,7 +87,6 @@ in environment.TZ = config.time.timeZone; wantedBy = [ "multi-user.target" ]; - partOf = [ "multi-user.target" ]; serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}"; }; From 1541311f06a0fd148ace46bb0adaa3f968b36d1e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 7 Jan 2013 16:03:35 +0100 Subject: [PATCH 297/327] switch-to-configuration: Stop some target units to ensure proper dependency ordering This is currently only done for network-interfaces.target, but it should propably be done for most targets. --- .../activation/switch-to-configuration.pl | 18 +++++++++++++++++- modules/tasks/network-interfaces.nix | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 28ccc158f726..44cd261cf983 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -117,6 +117,8 @@ while (my ($unit, $state) = each %{$activePrev}) { } elsif ($unit =~ /\.target$/) { + my $unitInfo = parseUnit($newUnitFile); + # Cause all active target units to be restarted below. # This should start most changed units we stop here as # well as any new dependencies (including new mounts and @@ -124,11 +126,25 @@ while (my ($unit, $state) = each %{$activePrev}) { # active after the system has resumed, which probably # should not be the case. Just ignore it. if ($unit ne "suspend.target" && $unit ne "hibernate.target") { - my $unitInfo = parseUnit($newUnitFile); unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) { write_file($startListFile, { append => 1 }, "$unit\n"); } } + + # Stop targets that have X-StopOnReconfiguration set. + # This is necessary to respect dependency orderings + # involving targets: if unit X starts after target Y and + # target Y starts after unit Z, then if X and Z have both + # changed, then X should be restarted after Z. However, + # if target Y is in the "active" state, X and Z will be + # restarted at the same time because X's dependency on Y + # is already satisfied. Thus, we need to stop Y first. + # Stopping a target generally has no effect on other units + # (unless there is a PartOf dependency), so this is just a + # bookkeeping thing to get systemd to do the right thing. + if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "false")) { + push @unitsToStop, $unit; + } } elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) { diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index 82f4d3da4f11..a002e2b68b2d 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -255,6 +255,7 @@ in boot.systemd.targets."network-interfaces" = { description = "All Network Interfaces"; wantedBy = [ "network.target" ]; + unitConfig.X-StopOnReconfiguration = true; }; boot.systemd.services = From b79c5dc8781611648c728e3650c4b68bfdce231f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 00:35:27 +0100 Subject: [PATCH 298/327] Add section on network configuration topics --- doc/manual/configuration.xml | 169 +++++++++++++++++++++++++++++++++++ doc/manual/installation.xml | 20 ++--- doc/manual/manual.xml | 11 +-- 3 files changed, 185 insertions(+), 15 deletions(-) create mode 100644 doc/manual/configuration.xml diff --git a/doc/manual/configuration.xml b/doc/manual/configuration.xml new file mode 100644 index 000000000000..f73018279a5f --- /dev/null +++ b/doc/manual/configuration.xml @@ -0,0 +1,169 @@ + + +Configuration + +This chapter describes how to configure various aspects of a +NixOS machine through the configuration file +/etc/nixos/configuration.nix. As described in +, changes to that file only take +effect after you run nixos-rebuild. + + + + +
Networking + +
Secure shell access + +Secure shell (SSH) access to your machine can be enabled by +setting: + + +services.openssh.enable = true; + + +By default, root logins using a password are disallowed. They can be +disabled entirely by setting +services.openssh.permitRootLogin to +"no". + +You can declaratively specify authorised RSA/DSA public keys for +a user as follows: + + + +users.extraUsers.alice.openssh.authorizedKeys.keys = + [ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ]; + + + + +
+ + +
IPv4 configuration + +By default, NixOS uses DHCP (specifically, +(dhcpcd)) to automatically configure network +interfaces. However, you can configure an interface manually as +follows: + + +networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; }; + + +(The network prefix can also be specified using the option +subnetMask, +e.g. "255.255.255.0", but this is deprecated.) +Typically you’ll also want to set a default gateway and set of name +servers: + + +networking.defaultGateway = "192.168.1.1"; +networking.nameservers = [ "8.8.8.8" ]; + + + + +Statically configured interfaces are set up by the systemd +service +interface-name-cfg.service. +The default gateway and name server configuration is performed by +network-setup.service. + +The host name is set using : + + +networking.hostName = "cartman"; + + +The default host name is nixos. Set it to the +empty string ("") to allow the DHCP server to +provide the host name. + +
+ + +
IPv6 configuration + +IPv6 is enabled by default. Stateless address autoconfiguration +is used to automatically assign IPv6 addresses to all interfaces. You +can disable IPv6 support globally by setting: + + +networking.enableIPv6 = false; + + + + +
+ + +
Firewall + +NixOS has a simple stateful firewall that blocks incoming +connections and other unexpected packets. The firewall applies to +both IPv4 and IPv6 traffic. It can be enabled as follows: + + +networking.firewall.enable = true; + + +You can open specific TCP ports to the outside world: + + +networking.firewall.allowedTCPPorts = [ 80 443 ]; + + +Note that TCP port 22 (ssh) is opened automatically if the SSH daemon +is enabled (). UDP +ports can be opened through +. Also of +interest is + + +networking.firewall.allowPing = true; + + +to allow the machine to respond to ping requests. (ICMPv6 pings are +always allowed.) + +
+ + +
Wireless networks + +TODO + +
+ + +
Ad-hoc configuration + +You can use to specify +shell commands to be run at the end of +network-setup.service. This is useful for doing +network configuration not covered by the existing NixOS modules. For +instance, to statically configure an IPv6 address: + + +networking.localCommands = + '' + ip -6 addr add 2001:610:685:1::1/64 dev eth0 + ''; + + + + +
+ + + + + +
+ + +
diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index 8bde2f6e0530..55e23691ccb9 100644 --- a/doc/manual/installation.xml +++ b/doc/manual/installation.xml @@ -58,7 +58,7 @@ Wiki. For partitioning: fdisk. - + For initialising Ext4 partitions: mkfs.ext4. It is recommended that you assign a unique symbolic label to the file system using the option @@ -70,13 +70,13 @@ Wiki. mkswap. Again it’s recommended to assign a label to the swap partition: . - + For creating LVM volumes, the LVM commands, e.g., $ pvcreate /dev/sda1 /dev/sdb1 $ vgcreate MyVolGroup /dev/sda1 /dev/sdb1 -$ lvcreate --size 2G --name bigdisk MyVolGroup +$ lvcreate --size 2G --name bigdisk MyVolGroup $ lvcreate --size 1G --name smalldisk MyVolGroup @@ -87,7 +87,7 @@ $ lvcreate --size 1G --name smalldisk MyVolGroup - + Mount the target file system on which NixOS should be installed on /mnt. @@ -138,7 +138,7 @@ $ nixos-option --install xlink:href="https://nixos.org/repos/nix/configurations/trunk/"/>. - + If your machine has a limited amount of memory, you may want to activate swap devices now (swapon device). The installer (or @@ -234,7 +234,7 @@ $ reboot swapDevices = [ { device = "/dev/disk/by-label/swap"; } ]; - + services.sshd.enable = true; } @@ -260,7 +260,7 @@ to build the new configuration, make it the default configuration for booting, and try to realise the configuration in the running system (e.g., by restarting system services). -You can also do +You can also do $ nixos-rebuild test @@ -270,7 +270,7 @@ without making it the boot default. So if (say) the configuration locks up your machine, you can just reboot to get back to a working configuration. -There is also +There is also $ nixos-rebuild boot @@ -279,7 +279,7 @@ to build the configuration and make it the boot default, but not switch to it now (so it will only take effect after the next reboot). -Finally, you can do +Finally, you can do $ nixos-rebuild build @@ -329,7 +329,7 @@ You can then upgrade NixOS to the latest version in the channel by running -$ nix-channel --update +$ nix-channel --update nixos and running the nixos-rebuild command as described diff --git a/doc/manual/manual.xml b/doc/manual/manual.xml index b7e4c6315f9e..9179911f2487 100644 --- a/doc/manual/manual.xml +++ b/doc/manual/manual.xml @@ -24,16 +24,16 @@ 2007-2012 Eelco Dolstra - + - + Preface This manual describes NixOS, a Linux distribution based on the purely functional package management system Nix. - + NixOS is rather bleeding edge, and this manual is correspondingly sketchy and quite possibly out of date. It gives basic information on how to get NixOS up and running, but since @@ -45,11 +45,12 @@ mailing list or on the #nixos channel on Freenode.. - + - + + From f05e5813b556cf8ed5e88f5f605277f893332634 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 02:02:15 +0100 Subject: [PATCH 299/327] Add an overview of systemctl/loginctl/journalctl --- doc/manual/configuration.xml | 6 +- doc/manual/installation.xml | 2 +- doc/manual/manual.xml | 1 + doc/manual/running.xml | 288 +++++++++++++++++++++++++++++++++++ 4 files changed, 295 insertions(+), 2 deletions(-) create mode 100644 doc/manual/running.xml diff --git a/doc/manual/configuration.xml b/doc/manual/configuration.xml index f73018279a5f..f1f99fb70ed9 100644 --- a/doc/manual/configuration.xml +++ b/doc/manual/configuration.xml @@ -2,7 +2,7 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="ch-configuration"> -Configuration +Configuring NixOS This chapter describes how to configure various aspects of a NixOS machine through the configuration file @@ -166,4 +166,8 @@ networking.localCommands = + + + diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index 55e23691ccb9..1c00dd37d337 100644 --- a/doc/manual/installation.xml +++ b/doc/manual/installation.xml @@ -1,7 +1,7 @@ -Installation +Installing NixOS diff --git a/doc/manual/manual.xml b/doc/manual/manual.xml index 9179911f2487..ce4055a753c9 100644 --- a/doc/manual/manual.xml +++ b/doc/manual/manual.xml @@ -51,6 +51,7 @@ + diff --git a/doc/manual/running.xml b/doc/manual/running.xml new file mode 100644 index 000000000000..f9feadbc086e --- /dev/null +++ b/doc/manual/running.xml @@ -0,0 +1,288 @@ + + +Running NixOS + +This chapter describes various aspects of managing a running +NixOS system, such as how to use the systemd +service manager. + + + + +
Service management + +In NixOS, all system services are started and monitored using +the systemd program. Systemd is the “init” process of the system +(i.e. PID 1), the parent of all other processes. It manages a set of +so-called “units”, which can be things like system services +(programs), but also mount points, swap files, devices, targets +(groups of units) and more. Units can have complex dependencies; for +instance, one unit can require that another unit must be succesfully +started before the first unit can be started. When the system boots, +it starts a unit named default.target; the +dependencies of this unit cause all system services to be started, +filesystems to be mounted, swap files to be activated, and so +on. + +The command systemctl is the main way to +interact with systemd. Without any arguments, it +shows the status of active units: + + +$ systemctl +-.mount loaded active mounted / +swapfile.swap loaded active active /swapfile +sshd.service loaded active running SSH Daemon +graphical.target loaded active active Graphical Interface +... + + + + +You can ask for detailed status information about a unit, for +instance, the PostgreSQL database service: + + +$ systemctl status postgresql.service +postgresql.service - PostgreSQL Server + Loaded: loaded (/nix/store/pn3q73mvh75gsrl8w7fdlfk3fq5qm5mw-unit/postgresql.service) + Active: active (running) since Mon, 2013-01-07 15:55:57 CET; 9h ago + Main PID: 2390 (postgres) + CGroup: name=systemd:/system/postgresql.service + ├─2390 postgres + ├─2418 postgres: writer process + ├─2419 postgres: wal writer process + ├─2420 postgres: autovacuum launcher process + ├─2421 postgres: stats collector process + └─2498 postgres: zabbix zabbix [local] idle + +Jan 07 15:55:55 hagbard postgres[2394]: [1-1] LOG: database system was shut down at 2013-01-07 15:55:05 CET +Jan 07 15:55:57 hagbard postgres[2390]: [1-1] LOG: database system is ready to accept connections +Jan 07 15:55:57 hagbard postgres[2420]: [1-1] LOG: autovacuum launcher started +Jan 07 15:55:57 hagbard systemd[1]: Started PostgreSQL Server. + + +Note that this shows the status of the unit (active and running), all +the processes belonging to the service, as well as the most recent log +messages from the service. + + + +Units can be stopped, started or restarted: + + +$ systemctl stop postgresql.service +$ systemctl start postgresql.service +$ systemctl restart postgresql.service + + +These operations are synchronous: they wait until the service has +finished starting or stopping (or has failed). Starting a unit will +cause the dependencies of that unit to be started as well (if +necessary). + + + +
+ + + + +
Rebooting and shutting down + +The system can be shut down (and automatically powered off) by +doing: + + +$ shutdown + + +This is equivalent to running systemctl poweroff. +Likewise, reboot (a.k.a. systemctl +reboot) will reboot the system. + +The machine can be suspended to RAM (if supported) using +systemctl suspend, and suspended to disk using +systemctl hibernate. + +These commands can be run by any user who is logged in locally, +i.e. on a virtual console or in X11; otherwise, the user is asked for +authentication. + +
+ + + + +
User sessions + +Systemd keeps track of all users who are logged into the system +(e.g. on a virtual console or remotely via SSH). The command +loginctl allows quering and manipulating user +sessions. For instance, to list all user sessions: + + +$ loginctl + SESSION UID USER SEAT + c1 500 eelco seat0 + c3 0 root seat0 + c4 500 alice + + +This shows that two users are logged in locally, while another is +logged in remotely. (“Seats” are essentially the combinations of +displays and input devices attached to the system; usually, there is +only one seat.) To get information about a session: + + +$ loginctl session-status c3 +c3 - root (0) + Since: Tue, 2013-01-08 01:17:56 CET; 4min 42s ago + Leader: 2536 (login) + Seat: seat0; vc3 + TTY: /dev/tty3 + Service: login; type tty; class user + State: online + CGroup: name=systemd:/user/root/c3 + ├─ 2536 /nix/store/10mn4xip9n7y9bxqwnsx7xwx2v2g34xn-shadow-4.1.5.1/bin/login -- + ├─10339 -bash + └─10355 w3m nixos.org + + +This shows that the user is logged in on virtual console 3. It also +lists the processes belonging to this session. Since systemd keeps +track of this, you can terminate a session in a way that ensures that +all the session’s processes are gone: + + +$ loginctl terminate-session c3 + + + + +
+ + + + +
Control groups + +To keep track of the processes in a running system, systemd uses +control groups (cgroups). A control group is a +set of processes used to allocate resources such as CPU, memory or I/O +bandwidth. There can be multiple control group hierarchies, allowing +each kind of resource to be managed independently. + +The command systemd-cgls lists all control +groups in the systemd hierarchy, which is what +systemd uses to keep track of the processes belonging to each service +or user session: + + +$ systemd-cgls +├─user +│ └─eelco +│ └─c1 +│ ├─ 2567 -:0 +│ ├─ 2682 kdeinit4: kdeinit4 Running... +│ ├─ ... +│ └─10851 sh -c less -R +└─system + ├─httpd.service + │ ├─2444 httpd -f /nix/store/3pyacby5cpr55a03qwbnndizpciwq161-httpd.conf -DNO_DETACH + │ └─... + ├─dhcpcd.service + │ └─2376 dhcpcd --config /nix/store/f8dif8dsi2yaa70n03xir8r653776ka6-dhcpcd.conf + └─ ... + + +Similarly, systemd-cgls cpu shows the cgroups in +the CPU hierarchy, which allows per-cgroup CPU scheduling priorities. +By default, every systemd service gets its own CPU cgroup, while all +user sessions are in the top-level CPU cgroup. This ensures, for +instance, that a thousand run-away processes in the +httpd.service cgroup cannot starve the CPU for one +process in the postgresql.service cgroup. (By +contrast, it they were in the same cgroup, then the PostgreSQL process +would get 1/1001 of the cgroup’s CPU time.) You can limit a service’s +CPU share in configuration.nix: + + +boot.systemd.services.httpd.serviceConfig.CPUShares = 512; + + +By default, every cgroup has 1024 CPU shares, so this will halve the +CPU allocation of the httpd.service cgroup. + +There also is a memory hierarchy that +controls memory allocation limits; by default, all processes are in +the top-level cgroup, so any service or session can exhaust all +available memory. Per-cgroup memory limits can be specified in +configuration.nix; for instance, to limit +httpd.service to 512 MiB of RAM (excluding swap) +and 640 MiB of RAM (including swap): + + +boot.systemd.services.httpd.serviceConfig.MemoryLimit = "512M"; +boot.systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ]; + + + + +The command systemd-cgtop shows a +continuously updated list of all cgroups with their CPU and memory +usage. + +
+ + + + +
Logging + +System-wide logging is provided by systemd’s +journal, which subsumes traditional logging +daemons such as syslogd and klogd. Log entries are kept in binary +files in /var/log/journal/. The command +journalctl allows you to see the contents of the +journal. For example, + + +$ journalctl -b + + +shows all journal entries since the last reboot. (The output of +journalctl is piped into less by +default.) You can use various options and match operators to restrict +output to messages of interest. For instance, to get all messages +from PostgreSQL: + + +$ journalctl _SYSTEMD_UNIT=postgresql.service +-- Logs begin at Mon, 2013-01-07 13:28:01 CET, end at Tue, 2013-01-08 01:09:57 CET. -- +... +Jan 07 15:44:14 hagbard postgres[2681]: [2-1] LOG: database system is shut down +-- Reboot -- +Jan 07 15:45:10 hagbard postgres[2532]: [1-1] LOG: database system was shut down at 2013-01-07 15:44:14 CET +Jan 07 15:45:13 hagbard postgres[2500]: [1-1] LOG: database system is ready to accept connections + + +Or to get all messages since the last reboot that have at least a +“critical” severity level: + + +$ journalctl -b -p crit +Dec 17 21:08:06 mandark sudo[3673]: pam_unix(sudo:auth): auth could not identify password for [alice] +Dec 29 01:30:22 mandark kernel[6131]: [1053513.909444] CPU6: Core temperature above threshold, cpu clock throttled (total events = 1) + + + + +
+ + +
From 81796c5baf6801718c2e55491baf725bd89c1753 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 02:13:33 +0100 Subject: [PATCH 300/327] =?UTF-8?q?Add=20a=20command=20=E2=80=98nixos-help?= =?UTF-8?q?=E2=80=99=20that=20opens=20the=20NixOS=20manual=20in=20a=20brow?= =?UTF-8?q?ser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/services/misc/nixos-manual.nix | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/services/misc/nixos-manual.nix b/modules/services/misc/nixos-manual.nix index 2e98d50b0ced..1a172904c454 100644 --- a/modules/services/misc/nixos-manual.nix +++ b/modules/services/misc/nixos-manual.nix @@ -16,6 +16,17 @@ let inherit pkgs options; }; + entry = "${manual.manual}/share/doc/nixos/manual.html"; + + help = pkgs.writeScriptBin "nixos-help" + '' + #! ${pkgs.stdenv.shell} -e + if ! ''${BROWSER:-w3m} ${entry}; then + echo "$0: unable to start a web browser; please set \$BROWSER or install ‘w3m’" + exit 1 + fi + ''; + in { @@ -69,7 +80,7 @@ in system.build.manual = manual; - environment.systemPackages = [ manual.manpages ]; + environment.systemPackages = [ manual.manpages help ]; boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"]; @@ -78,7 +89,7 @@ in { description = "NixOS Manual"; wantedBy = [ "multi-user.target" ]; serviceConfig = - { ExecStart = "${cfg.browser} ${manual.manual}/share/doc/nixos/manual.html"; + { ExecStart = "${cfg.browser} ${entry}"; StandardInput = "tty"; StandardOutput = "tty"; TTYPath = "/dev/tty${cfg.ttyNumber}"; From 884f58fa8aeb3dc6696810baf161874f4e3306fe Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 15:35:21 +0100 Subject: [PATCH 301/327] Include libsystemd-daemon.so.* in the initrd since dmsetup needs it Strangely, this is only case after updating systemd to 197, I didn't change lvm2... --- modules/system/boot/stage-1.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index ac8a3ccc2386..b131867966ab 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -177,6 +177,7 @@ let cp -v ${pkgs.lvm2}/sbin/dmsetup $out/bin/dmsetup cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm cp -v ${pkgs.lvm2}/lib/libdevmapper.so.*.* $out/lib + cp -v ${pkgs.systemd}/lib/libsystemd-daemon.so.* $out/lib # Add RAID mdadm tool. cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm From 827e3dadc8abeac591f9e8060ef4da7376079e64 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 17:00:45 +0100 Subject: [PATCH 302/327] Don't special-case systemd-journald.service and systemd-user-sessions.service --- modules/system/activation/switch-to-configuration.pl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/system/activation/switch-to-configuration.pl b/modules/system/activation/switch-to-configuration.pl index 44cd261cf983..032947c3c546 100644 --- a/modules/system/activation/switch-to-configuration.pl +++ b/modules/system/activation/switch-to-configuration.pl @@ -126,7 +126,7 @@ while (my ($unit, $state) = each %{$activePrev}) { # active after the system has resumed, which probably # should not be the case. Just ignore it. if ($unit ne "suspend.target" && $unit ne "hibernate.target") { - unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "false")) { + unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "no")) { write_file($startListFile, { append => 1 }, "$unit\n"); } } @@ -142,7 +142,7 @@ while (my ($unit, $state) = each %{$activePrev}) { # Stopping a target generally has no effect on other units # (unless there is a PartOf dependency), so this is just a # bookkeeping thing to get systemd to do the right thing. - if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "false")) { + if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "no")) { push @unitsToStop, $unit; } } @@ -157,10 +157,7 @@ while (my ($unit, $state) = each %{$activePrev}) { # FIXME: do something? } else { my $unitInfo = parseUnit($newUnitFile); - if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true") - || $unit eq "systemd-user-sessions.service" - || $unit eq "systemd-journald.service") - { + if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes")) { push @unitsToSkip, $unit; } else { # If this unit is socket-activated, then stop the @@ -181,7 +178,7 @@ while (my ($unit, $state) = each %{$activePrev}) { } } - if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "true")) { + if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes")) { # This unit should be restarted instead of # stopped and started. From 948dd8dd1a3403b0a873d53980fcf137cca260a2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 17:26:51 +0100 Subject: [PATCH 303/327] Use the upstream (but patched) sysinit.target --- modules/system/boot/systemd.nix | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index a0462951d005..f72d15d01299 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -23,7 +23,7 @@ let upstreamUnits = [ # Targets. "basic.target" - #"sysinit.target" + "sysinit.target" "sockets.target" "graphical.target" "multi-user.target" @@ -524,17 +524,6 @@ in { description = "Security Keys"; }; - # This is like the upstream sysinit.target, except that it doesn't - # depend on local-fs.target and swap.target. If services need to - # be started after some filesystem (local or otherwise) has been - # mounted, they should use the RequiresMountsFor option. - boot.systemd.targets.sysinit = - { description = "System Initialization"; - after = [ "emergency.service" "emergency.target" ]; - unitConfig.Conflicts = "emergency.service emergency.target"; - unitConfig.RefuseManualStart = true; - }; - boot.systemd.units = { "rescue.service".text = rescueService; } // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets From f4a3bdd6afa31671bfc18fd22417b04914dfa0a8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 18:24:06 +0100 Subject: [PATCH 304/327] Install {rescue,emergency}.{target,service} Also, symlink kbrequest.target to rescue.target as suggested by the systemd.special manpage. This way, you can start a sulogin rescue shell by pressing Alt+Up. --- modules/system/boot/systemd.nix | 39 ++++++++------------------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index f72d15d01299..83911d179fde 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -28,7 +28,6 @@ let "graphical.target" "multi-user.target" "getty.target" - "rescue.target" "network.target" "nss-lookup.target" "nss-user-lookup.target" @@ -37,6 +36,12 @@ let #"cryptsetup.target" "sigpwr.target" + # Rescue/emergency. + "rescue.target" + "rescue.service" + "emergency.target" + "emergency.service" + # Udev. "systemd-udevd-control.socket" "systemd-udevd-kernel.socket" @@ -139,33 +144,6 @@ let "shutdown.target.wants" ]; - rescueService = - '' - [Unit] - Description=Rescue Shell - DefaultDependencies=no - Conflicts=shutdown.target - After=sysinit.target - Before=shutdown.target - - [Service] - Environment=HOME=/root - WorkingDirectory=/root - ExecStartPre=-${pkgs.coreutils}/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to enter default mode.' - #ExecStart=-/sbin/sulogin - ExecStart=-${pkgs.bashInteractive}/bin/bash --login - ExecStopPost=-${systemd}/bin/systemctl --fail --no-block default - Type=idle - StandardInput=tty-force - StandardOutput=inherit - StandardError=inherit - KillMode=process - - # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash - # terminates cleanly. - KillSignal=SIGHUP - ''; - makeJobScript = name: text: let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${name}"; inherit text; }; in "${x}/bin/${name}"; @@ -347,6 +325,8 @@ let ln -s ${cfg.defaultUnit} $out/default.target + ln -s rescue.target $out/kbrequest.target + #ln -s ../getty@tty1.service $out/multi-user.target.wants/ ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \ ../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/ @@ -525,8 +505,7 @@ in }; boot.systemd.units = - { "rescue.service".text = rescueService; } - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets + mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets // listToAttrs (map From ac53b25f167746cff0885ee28c6a172a43b81984 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jan 2013 18:31:46 +0100 Subject: [PATCH 305/327] Remove handling of "debug2" and "S|s|single" kernel command line options The "S|s|single" option is handled by systemd (starting rescue.target). And the rescue target basically removes the need for a special debug shell. (Also, there is "systemd.crash_shell=1" for starting a shell if systemd crashes.) --- modules/system/boot/stage-2-init.sh | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 67a4e0ed16d0..0ad9982e4303 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -62,20 +62,12 @@ ln -s /proc/mounts /etc/mtab # Process the kernel command line. -debug2= for o in $(cat /proc/cmdline); do case $o in debugtrace) # Show each command. set -x ;; - debug2) - debug2=1 - ;; - S|s|single) - # !!! argh, can't pass a startup event to Upstart yet. - exec @shell@ - ;; resume=*) set -- $(IFS==; echo $o) resumeDevice=$2 @@ -168,26 +160,6 @@ ln -sfn /run/booted-system /nix/var/nix/gcroots/booted-system @shell@ @postBootCommands@ -# For debugging Upstart. -if [ -n "$debug2" ]; then - # Get the console from the kernel cmdline - console=tty1 - for o in $(cat /proc/cmdline); do - case $o in - console=*) - set -- $(IFS==; echo $o) - params=$2 - set -- $(IFS=,; echo $params) - console=$1 - ;; - esac - done - - echo "Debug shell called from @out@" - setsid @shellDebug@ < /dev/$console >/dev/$console 2>/dev/$console -fi - - # Start systemd. echo "starting systemd..." PATH=/run/current-system/systemd/lib/systemd \ From 19127aa4165b8aae6ca29dc7a80d21bd0b40dfe4 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Tue, 8 Jan 2013 16:19:51 -0500 Subject: [PATCH 306/327] Add dd-agent module --- modules/module-list.nix | 1 + modules/services/monitoring/dd-agent.nix | 58 ++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 modules/services/monitoring/dd-agent.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index ae5e5d5c49f6..db54f5665a73 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -100,6 +100,7 @@ ./services/misc/rogue.nix ./services/misc/svnserve.nix ./services/misc/synergy.nix + ./services/monitoring/dd-agent.nix ./services/monitoring/monit.nix ./services/monitoring/nagios/default.nix ./services/monitoring/smartd.nix diff --git a/modules/services/monitoring/dd-agent.nix b/modules/services/monitoring/dd-agent.nix new file mode 100644 index 000000000000..c0493557d56d --- /dev/null +++ b/modules/services/monitoring/dd-agent.nix @@ -0,0 +1,58 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + cfg = config.services.dd-agent; + + datadog-conf = pkgs.runCommand "datadog.conf" {} '' + sed -e 's|^api_key:|api_key: ${cfg.api_key}|' ${optionalString (cfg.hostname != null) + "-e 's|^#hostname: mymachine.mydomain|hostname: ${cfg.hostname}|'" + } ${pkgs.dd-agent}/etc/dd-agent/datadog.conf.example > $out + ''; +in { + options.services.dd-agent = { + enable = mkOption { + description = "Whether to enable the dd-agent montioring service"; + + default = false; + + type = types.bool; + }; + + # !!! This gets stored in the store (world-readable), wish we had https://github.com/NixOS/nix/issues/8 + api_key = mkOption { + description = "The Datadog API key to associate the agent with your account"; + + example = "ae0aa6a8f08efa988ba0a17578f009ab"; + + type = types.uniq types.string; + }; + + hostname = mkOption { + description = "The hostname to show in the Datadog dashboard (optional)"; + + default = null; + + example = "mymachine.mydomain"; + + type = types.uniq (types.nullOr types.string); + }; + }; + + config = mkIf cfg.enable { + environment.etc = [ { source = datadog-conf; target = "dd-agent/datadog.conf"; } ]; + + boot.systemd.services.dd-agent = { + description = "Datadog agent monitor"; + + path = [ pkgs.sysstat pkgs.procps ]; + + wantedBy = [ "multi-user.target" ]; + + serviceConfig.ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground"; + + restartTriggers = [ pkgs.dd-agent ]; + }; + }; +} From b5e639dbb10c396e174aa79f5941c727675148d5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jan 2013 13:43:57 +0100 Subject: [PATCH 307/327] Update the troubleshooting section for systemd --- doc/manual/default.nix | 2 +- doc/manual/troubleshooting.xml | 80 +++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/doc/manual/default.nix b/doc/manual/default.nix index d3f554c099ee..e6edb30985c1 100644 --- a/doc/manual/default.nix +++ b/doc/manual/default.nix @@ -59,7 +59,7 @@ in rec { mkdir -p $dst/images/callouts cp ${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/ - + cp ${./style.css} $dst/style.css ensureDir $out/nix-support diff --git a/doc/manual/troubleshooting.xml b/doc/manual/troubleshooting.xml index ff19607844fc..f18ca9f4c5c7 100644 --- a/doc/manual/troubleshooting.xml +++ b/doc/manual/troubleshooting.xml @@ -4,60 +4,70 @@ Troubleshooting -
- -Debugging the boot process +
Boot problems -To get a Stage 1 shell (i.e., a shell in the initial ramdisk), -add debug1 to the kernel command line. The shell -gets started before anything useful has been done. That is, no -modules have been loaded and no file systems have been mounted, except -for /proc and /sys. +If NixOS fails to boot, there are a number of kernel command +line parameters that may help you to identify or fix the issue. You +can add these parameters in the GRUB boot menu by pressing “e” to +modify the selected boot entry and editing the line starting with +linux. The following are some useful kernel command +line parameters that are recognised by the NixOS boot scripts or by +systemd: -To get a Stage 2 shell (i.e., a shell in the actual root file -system), add debug2 to the kernel command -line. This shell is started right after stage 1 calls the stage 2 -init script, so the root file system is there but -no services have been started. + -
+ debug1 + Request an interactive shell in stage 1 of the + boot process (the initial ramdisk). The shell gets started before + anything useful has been done. That is, no modules have been + loaded and no file systems have been mounted, except for + /proc and + /sys. + + single + Boot into rescue mode (a.k.a. single user mode). + This will cause systemd to start nothing but the unit + rescue.target, which runs + sulogin to prompt for the root password and + start a root login shell. Exiting the shell causes the system to + continue with the normal boot process. + + systemd.log_level=debug systemd.log_target=console + Make systemd very verbose and send log messages to + the console instead of the journal. + -
- -Safe mode + -If the hardware autodetection (in -upstart-jobs/hardware-scan) causes problems, add -safemode to the kernel command line. This will -disable auto-loading of modules for your PCI devices. However, you -will probably need to explicitly add modules to - to get network support etc. +For more parameters recognised by systemd, see +systemd1. + +If no login prompts or X11 login screens appear (e.g. due to +hanging dependencies), you can press Alt+ArrowUp. If you’re lucky, +this will start rescue mode (described above). (Also note that since +most units have a 90-second timeout before systemd gives up on them, +the agetty login prompts should appear eventually +unless something is very wrong.)
- + Maintenance mode -You can go to maintenance mode by doing +You can enter rescue mode by running: -$ shutdown now +$ systemctl rescue -This will eventually give you a single-user root shell. - -To get out of maintenance mode, do - - -$ initctl emit startup - - +This will eventually give you a single-user root shell. Systemd will +stop (almost) all system services. To get out of maintenance mode, +just exit from the rescue shell.
- From 91bead9c18416a70651ecb82b26e46d157bd8bb9 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Wed, 9 Jan 2013 22:44:50 +0100 Subject: [PATCH 308/327] modules/system/boot/loader/grub/memtest.nix: use 'memtest86plus' instead of 'memtest86' The 'memtest86' package didn't work on any of my machines. 'memtest86plus', on the other hand, seems to work just fine. Does anyone know why we keep the seemingly older version around still? --- modules/system/boot/loader/grub/memtest.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/boot/loader/grub/memtest.nix b/modules/system/boot/loader/grub/memtest.nix index 4bd4b69101c9..b18ff0512f2a 100644 --- a/modules/system/boot/loader/grub/memtest.nix +++ b/modules/system/boot/loader/grub/memtest.nix @@ -5,7 +5,7 @@ with pkgs.lib; let isEnabled = config.boot.loader.grub.memtest86; - memtest86 = pkgs.memtest86; + memtest86 = pkgs.memtest86plus; in { options = { From 93a7a32babe618a8ae69a1085df78329820c1c85 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jan 2013 22:31:57 +0100 Subject: [PATCH 309/327] initrd: Don't enable the root shell by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting an authenticated root shell is a security hole, so don't do it by default. The kernel command line parameter ‘initrd.shell_on_fail’ restores the original. (Of course, this only improves security if you have a password on GRUB to prevent the kernel command line from being edited by unauthorized users.) --- doc/manual/troubleshooting.xml | 15 ++++++- modules/system/boot/stage-1-init.sh | 63 ++++++++++++++++------------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/doc/manual/troubleshooting.xml b/doc/manual/troubleshooting.xml index f18ca9f4c5c7..4d5c5994fc84 100644 --- a/doc/manual/troubleshooting.xml +++ b/doc/manual/troubleshooting.xml @@ -16,15 +16,26 @@ systemd: + initrd.shell_on_fail + Start a root shell if something goes wrong in + stage 1 of the boot process (the initial ramdisk). This is + disabled by default because there is no authentication for the + root shell. + + debug1 - Request an interactive shell in stage 1 of the - boot process (the initial ramdisk). The shell gets started before + Start an interactive shell in stage 1 before anything useful has been done. That is, no modules have been loaded and no file systems have been mounted, except for /proc and /sys. + debugtrace + Print every shell command executed by the stage 1 + and 2 boot scripts. + + single Boot into rescue mode (a.k.a. single user mode). This will cause systemd to start nothing but the unit diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 778e36cfd36e..c1e46956f6e1 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -1,6 +1,7 @@ #! @shell@ targetRoot=/mnt-root +console=tty1 export LD_LIBRARY_PATH=@extraUtils@/lib export PATH=@extraUtils@/bin:@extraUtils@/sbin @@ -17,37 +18,31 @@ An error occured in stage 1 of the boot process, which must mount the root filesystem on \`$targetRoot' and then start stage 2. Press one of the following keys: - i) to launch an interactive shell; +EOF + if [ -n "$allowShell" ]; then cat </dev/$console 2>/dev/$console" ;; - i) - echo "Starting interactive shell..." - setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail - ;; - *) - echo "Continuing...";; - esac + if [ -n "$allowShell" -a "$reply" = f ]; then + exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" + elif [ -n "$allowShell" -a "$reply" = i ]; then + echo "Starting interactive shell..." + setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail + elif [ "$reply" = r ]; then + echo "Rebooting..." + reboot -f + else + echo "Continuing..." + fi } trap 'fail' 0 @@ -76,6 +71,12 @@ mount -t securityfs none /sys/kernel/security export stage2Init=/init for o in $(cat /proc/cmdline); do case $o in + console=*) + set -- $(IFS==; echo $o) + params=$2 + set -- $(IFS=,; echo $params) + console=$1 + ;; init=*) set -- $(IFS==; echo $o) stage2Init=$2 @@ -84,13 +85,19 @@ for o in $(cat /proc/cmdline); do # Show each command. set -x ;; + initrd.shell_on_fail) + allowShell=1 + ;; debug1) # stop right away + allowShell=1 fail ;; debug1devices) # stop after loading modules and creating device nodes + allowShell=1 debug1devices=1 ;; debug1mounts) # stop after mounting file systems + allowShell=1 debug1mounts=1 ;; stage1panic=1) @@ -180,7 +187,7 @@ onACPower() { checkFS() { local device="$1" local fsType="$2" - + # Only check block devices. if [ ! -b "$device" ]; then return 0; fi @@ -219,7 +226,7 @@ checkFS() { if test $(($fsckResult | 2)) = $fsckResult; then echo "fsck finished, rebooting..." sleep 3 - reboot + reboot -f fi if test $(($fsckResult | 4)) = $fsckResult; then From c7b427fbca9f863e25db64538cf2e74e4f74893c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jan 2013 22:49:26 +0100 Subject: [PATCH 310/327] Give our kernel parameters a common prefix ("boot.*") --- doc/manual/troubleshooting.xml | 6 +++--- modules/profiles/headless.nix | 2 +- modules/system/boot/kernel.nix | 2 +- modules/system/boot/stage-1-init.sh | 12 ++++++------ modules/system/boot/stage-2-init.sh | 2 +- modules/testing/test-instrumentation.nix | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/manual/troubleshooting.xml b/doc/manual/troubleshooting.xml index 4d5c5994fc84..2961f8e1233a 100644 --- a/doc/manual/troubleshooting.xml +++ b/doc/manual/troubleshooting.xml @@ -16,14 +16,14 @@ systemd: - initrd.shell_on_fail + boot.shell_on_fail Start a root shell if something goes wrong in stage 1 of the boot process (the initial ramdisk). This is disabled by default because there is no authentication for the root shell. - debug1 + boot.debug1 Start an interactive shell in stage 1 before anything useful has been done. That is, no modules have been loaded and no file systems have been mounted, except for @@ -31,7 +31,7 @@ systemd: /sys. - debugtrace + boot.trace Print every shell command executed by the stage 1 and 2 boot scripts. diff --git a/modules/profiles/headless.nix b/modules/profiles/headless.nix index 3446654bc6f5..593bd925b006 100644 --- a/modules/profiles/headless.nix +++ b/modules/profiles/headless.nix @@ -16,5 +16,5 @@ with pkgs.lib; boot.systemd.services."serial-getty@hvc0".enable = false; # Since we can't manually respond to a panic, just reboot. - boot.kernelParams = [ "panic=1" "stage1panic=1" ]; + boot.kernelParams = [ "panic=1" "boot.panic_on_fail" ]; } diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 3637378d4d1e..6cf9311e471e 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -50,7 +50,7 @@ in boot.extraKernelParams = mkOption { default = [ ]; - example = [ "debugtrace" ]; + example = [ "boot.trace" ]; description = "Additional user-defined kernel parameters."; }; diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index c1e46956f6e1..9bcbe291aad5 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -81,26 +81,26 @@ for o in $(cat /proc/cmdline); do set -- $(IFS==; echo $o) stage2Init=$2 ;; - debugtrace) + boot.trace|debugtrace) # Show each command. set -x ;; - initrd.shell_on_fail) + boot.shell_on_fail) allowShell=1 ;; - debug1) # stop right away + boot.debug1|debug1) # stop right away allowShell=1 fail ;; - debug1devices) # stop after loading modules and creating device nodes + boot.debug1devices) # stop after loading modules and creating device nodes allowShell=1 debug1devices=1 ;; - debug1mounts) # stop after mounting file systems + boot.debug1mounts) # stop after mounting file systems allowShell=1 debug1mounts=1 ;; - stage1panic=1) + boot.panic_on_fail|stage1panic=1) panicOnFail=1 ;; root=*) diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh index 0ad9982e4303..5447ce0c502e 100644 --- a/modules/system/boot/stage-2-init.sh +++ b/modules/system/boot/stage-2-init.sh @@ -64,7 +64,7 @@ ln -s /proc/mounts /etc/mtab # Process the kernel command line. for o in $(cat /proc/cmdline); do case $o in - debugtrace) + boot.debugtrace) # Show each command. set -x ;; diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 0ee3ad65a3d2..108dcb0ab6db 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -65,7 +65,7 @@ let kernel = config.boot.kernelPackages.kernel; in # Panic if an error occurs in stage 1 (rather than waiting for # user intervention). boot.kernelParams = - [ "console=tty1" "console=ttyS0" "panic=1" "stage1panic=1" ]; + [ "console=tty1" "console=ttyS0" "panic=1" "boot.panic_on_fail" ]; # `xwininfo' is used by the test driver to query open windows. environment.systemPackages = [ pkgs.xorg.xwininfo ]; From 0b3d54d3cd39c54b9dafb83bbbdd37dc631c1c7b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Jan 2013 22:53:11 +0100 Subject: [PATCH 311/327] Guard against portmap and rpcbind both being enabled --- modules/services/networking/rpcbind.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/services/networking/rpcbind.nix b/modules/services/networking/rpcbind.nix index 8e3e86a515c1..f82803e75194 100644 --- a/modules/services/networking/rpcbind.nix +++ b/modules/services/networking/rpcbind.nix @@ -29,6 +29,8 @@ let ''; }; + check = mkAssert (!(config.services.rpcbind.enable && config.services.portmap.enable)) + "Portmap and rpcbind cannot both be enabled."; in @@ -57,7 +59,7 @@ in ###### implementation - config = mkIf config.services.rpcbind.enable { + config = mkIf config.services.rpcbind.enable (check { environment.systemPackages = [ pkgs.rpcbind ]; @@ -77,6 +79,6 @@ in serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind"; }; - }; + }); } From 3bbbd62cbcfca6ba5c907dc6c350ff319037bad9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Jan 2013 13:46:34 +0100 Subject: [PATCH 312/327] Start dhcpcd/wpa_supplicant after systemd-udev-settle This is necessary to prevent a race. Udev 197 has a new naming scheme for network devices, so it will rename (say) eth0 to eno0. This fails with "error changing net interface name eth0 to eno1: Device or resource busy" if another process has opened the interface in the meantime. --- modules/services/networking/dhcpcd.nix | 1 + modules/services/networking/wpa_supplicant.nix | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index cf7f621a85d5..739ba95d5e34 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -96,6 +96,7 @@ in { description = "DHCP Client"; wantedBy = [ "network.target" ]; + after = [ "systemd-udev-settle.service" ]; # Stopping dhcpcd during a reconfiguration is undesirable # because it brings down the network interfaces configured by diff --git a/modules/services/networking/wpa_supplicant.nix b/modules/services/networking/wpa_supplicant.nix index b338e08113e5..4f8ae55d2090 100644 --- a/modules/services/networking/wpa_supplicant.nix +++ b/modules/services/networking/wpa_supplicant.nix @@ -90,8 +90,10 @@ in services.dbus.packages = [ pkgs.wpa_supplicant ]; jobs.wpa_supplicant = - { startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; + { description = "WPA Supplicant"; + + wantedBy = [ "network.target" ]; + after = [ "systemd-udev-settle.service" ]; path = [ pkgs.wpa_supplicant ]; From 5685ee54461a71f35b64bff62c158b9f129dce95 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Jan 2013 13:59:41 +0100 Subject: [PATCH 313/327] Add/fix systemd unit descriptions --- modules/services/networking/firewall.nix | 4 +++- modules/services/networking/ntpd.nix | 2 +- modules/services/printing/cupsd.nix | 2 +- modules/services/scheduling/atd.nix | 2 +- modules/services/scheduling/cron.nix | 2 +- modules/services/x11/xserver.nix | 4 +++- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index d262f1f76cbc..7bc09a7b4044 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -236,7 +236,9 @@ in ]; jobs.firewall = - { startOn = "started network-interfaces"; + { description = "Firewall"; + + startOn = "started network-interfaces"; path = [ pkgs.iptables ]; diff --git a/modules/services/networking/ntpd.nix b/modules/services/networking/ntpd.nix index e9b27268aa17..be3fcbd65433 100644 --- a/modules/services/networking/ntpd.nix +++ b/modules/services/networking/ntpd.nix @@ -66,7 +66,7 @@ in }; jobs.ntpd = - { description = "NTP daemon"; + { description = "NTP Daemon"; wantedBy = [ "ip-up.target" ]; partOf = [ "ip-up.target" ]; diff --git a/modules/services/printing/cupsd.nix b/modules/services/printing/cupsd.nix index 6d31c0050aaf..5a6b85810aaa 100644 --- a/modules/services/printing/cupsd.nix +++ b/modules/services/printing/cupsd.nix @@ -118,7 +118,7 @@ in boot.blacklistedKernelModules = [ "usblp" ]; jobs.cupsd = - { description = "CUPS printing daemon"; + { description = "CUPS Printing Daemon"; startOn = "started network-interfaces"; stopOn = "stopping network-interfaces"; diff --git a/modules/services/scheduling/atd.nix b/modules/services/scheduling/atd.nix index 6e6eaec1db9a..66266e5b5708 100644 --- a/modules/services/scheduling/atd.nix +++ b/modules/services/scheduling/atd.nix @@ -64,7 +64,7 @@ in }; jobs.atd = - { description = "at daemon (atd)"; + { description = "Job Execution Daemon (atd)"; startOn = "stopped udevtrigger"; diff --git a/modules/services/scheduling/cron.nix b/modules/services/scheduling/cron.nix index 350d65b476a6..cf348793a653 100644 --- a/modules/services/scheduling/cron.nix +++ b/modules/services/scheduling/cron.nix @@ -86,7 +86,7 @@ in environment.systemPackages = [ cronNixosPkg ]; jobs.cron = - { description = "Cron daemon"; + { description = "Cron Daemon"; startOn = "startup"; diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 6eec6f88b97d..599f8be226db 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -389,7 +389,9 @@ in boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; boot.systemd.services."display-manager" = - { after = [ "systemd-udev-settle.service" "local-fs.target" ]; + { description = "X11 Server"; + + after = [ "systemd-udev-settle.service" "local-fs.target" ]; restartIfChanged = false; From e32dda4c40db3b2b761b390e1255bbfe6cb500e2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Jan 2013 14:25:13 +0100 Subject: [PATCH 314/327] Bump the NixOS version number to 0.2 A new init system justifies a new version number! --- .version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.version b/.version index ceab6e11ece0..2f4536184bca 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.1 \ No newline at end of file +0.2 \ No newline at end of file From ac8080b83c8bcaaadd35f7430ccc0add0eade15a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Jan 2013 16:53:17 +0100 Subject: [PATCH 315/327] Remove obsolete environment variables --- modules/security/ca.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/security/ca.nix b/modules/security/ca.nix index ef33298f19e2..378fe4e691db 100644 --- a/modules/security/ca.nix +++ b/modules/security/ca.nix @@ -20,10 +20,6 @@ with pkgs.lib; environment.shellInit = '' export OPENSSL_X509_CERT_FILE=/etc/ssl/certs/ca-bundle.crt - - # !!! Remove the following as soon as OpenSSL 1.0.0e is the default. - export CURL_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt - export GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt ''; }; From 0b399d8e49e064842265c0b5f6b4e0346ad097eb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Jan 2013 17:34:01 +0100 Subject: [PATCH 316/327] Revert "Remove obsolete environment variables" This reverts commit ac8080b83c8bcaaadd35f7430ccc0add0eade15a. --- modules/security/ca.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/security/ca.nix b/modules/security/ca.nix index 378fe4e691db..ef33298f19e2 100644 --- a/modules/security/ca.nix +++ b/modules/security/ca.nix @@ -20,6 +20,10 @@ with pkgs.lib; environment.shellInit = '' export OPENSSL_X509_CERT_FILE=/etc/ssl/certs/ca-bundle.crt + + # !!! Remove the following as soon as OpenSSL 1.0.0e is the default. + export CURL_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt + export GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt ''; }; From 61f1df279ff7af94cb1b6e1888d2651a6f174cc7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 15 Jan 2013 17:34:24 +0100 Subject: [PATCH 317/327] Remove bogus comment --- modules/security/ca.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/security/ca.nix b/modules/security/ca.nix index ef33298f19e2..e42f5ffe3b89 100644 --- a/modules/security/ca.nix +++ b/modules/security/ca.nix @@ -21,7 +21,6 @@ with pkgs.lib; '' export OPENSSL_X509_CERT_FILE=/etc/ssl/certs/ca-bundle.crt - # !!! Remove the following as soon as OpenSSL 1.0.0e is the default. export CURL_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt export GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt ''; From ae4e94d9acc510183fab1501bd6e9ed189b31e20 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jan 2013 12:33:18 +0100 Subject: [PATCH 318/327] =?UTF-8?q?Rename=20=E2=80=98boot.systemd=E2=80=99?= =?UTF-8?q?=20to=20=E2=80=98systemd=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested by Mathijs Kwik. ‘boot.systemd’ is a misnomer because systemd affects more than just booting. And it saves some typing. --- doc/manual/running.xml | 6 ++--- modules/config/networking.nix | 2 +- modules/config/power-management.nix | 6 ++--- modules/config/swap.nix | 2 +- modules/profiles/headless.nix | 4 ++-- modules/rename.nix | 5 +++++ modules/security/rngd.nix | 2 +- modules/services/audio/alsa.nix | 2 +- modules/services/databases/mongodb.nix | 2 +- modules/services/databases/mysql.nix | 2 +- modules/services/databases/mysql55.nix | 2 +- modules/services/databases/postgresql.nix | 2 +- modules/services/hardware/upower.nix | 2 +- modules/services/logging/logstash.nix | 2 +- modules/services/logging/syslogd.nix | 2 +- modules/services/misc/nix-daemon.nix | 4 ++-- modules/services/misc/nix-gc.nix | 2 +- modules/services/misc/nixos-manual.nix | 2 +- modules/services/misc/rogue.nix | 2 +- modules/services/monitoring/dd-agent.nix | 2 +- modules/services/monitoring/smartd.nix | 2 +- modules/services/monitoring/zabbix-agent.nix | 2 +- modules/services/monitoring/zabbix-server.nix | 2 +- modules/services/network-filesystems/nfsd.nix | 4 ++-- .../services/network-filesystems/samba.nix | 2 +- modules/services/networking/dhcpcd.nix | 2 +- modules/services/networking/gogoclient.nix | 2 +- modules/services/networking/openvpn.nix | 2 +- modules/services/networking/rpcbind.nix | 2 +- modules/services/networking/ssh/sshd.nix | 2 +- modules/services/system/dbus.nix | 4 ++-- modules/services/system/nscd.nix | 2 +- modules/services/ttys/agetty.nix | 4 ++-- .../web-servers/apache-httpd/default.nix | 2 +- modules/services/x11/xserver.nix | 4 ++-- modules/system/boot/kernel.nix | 2 +- modules/system/boot/shutdown.nix | 2 +- modules/system/boot/systemd.nix | 22 +++++++++---------- modules/system/upstart/upstart.nix | 2 +- modules/tasks/filesystems.nix | 4 ++-- modules/tasks/filesystems/nfs.nix | 4 ++-- modules/tasks/kbd.nix | 2 +- modules/tasks/network-interfaces.nix | 4 ++-- modules/testing/test-instrumentation.nix | 8 +++---- modules/virtualisation/ec2-data.nix | 4 ++-- modules/virtualisation/libvirtd.nix | 2 +- 46 files changed, 77 insertions(+), 72 deletions(-) diff --git a/doc/manual/running.xml b/doc/manual/running.xml index f9feadbc086e..ea4028b6e9b5 100644 --- a/doc/manual/running.xml +++ b/doc/manual/running.xml @@ -212,7 +212,7 @@ would get 1/1001 of the cgroup’s CPU time.) You can limit a service’s CPU share in configuration.nix: -boot.systemd.services.httpd.serviceConfig.CPUShares = 512; +systemd.services.httpd.serviceConfig.CPUShares = 512; By default, every cgroup has 1024 CPU shares, so this will halve the @@ -227,8 +227,8 @@ available memory. Per-cgroup memory limits can be specified in and 640 MiB of RAM (including swap): -boot.systemd.services.httpd.serviceConfig.MemoryLimit = "512M"; -boot.systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ]; +systemd.services.httpd.serviceConfig.MemoryLimit = "512M"; +systemd.services.httpd.serviceConfig.ControlGroupAttribute = [ "memory.memsw.limit_in_bytes 640M" ]; diff --git a/modules/config/networking.nix b/modules/config/networking.nix index e9d04c49904d..6908996db6c9 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -87,7 +87,7 @@ in } ]; - boot.systemd.units."ip-up.target".text = + systemd.units."ip-up.target".text = '' [Unit] Description=Services Requiring IP Connectivity diff --git a/modules/config/power-management.nix b/modules/config/power-management.nix index c48451bd5f5c..4da6cebcb941 100644 --- a/modules/config/power-management.nix +++ b/modules/config/power-management.nix @@ -73,7 +73,7 @@ in powerManagement.scsiLinkPolicy = mkDefault "min_power"; # Service executed before suspending/hibernating. - boot.systemd.services."pre-sleep" = + systemd.services."pre-sleep" = { description = "Pre-Sleep Actions"; wantedBy = [ "sleep.target" ]; before = [ "sleep.target" ]; @@ -87,7 +87,7 @@ in # Service executed before suspending/hibernating. There doesn't # seem to be a good way to hook in a service to be executed after # both suspend *and* hibernate, so have a separate one for each. - boot.systemd.services."post-suspend" = + systemd.services."post-suspend" = { description = "Post-Suspend Actions"; wantedBy = [ "suspend.target" ]; after = [ "systemd-suspend.service" ]; @@ -99,7 +99,7 @@ in serviceConfig.Type = "oneshot"; }; - boot.systemd.services."post-hibernate" = + systemd.services."post-hibernate" = { description = "Post-Hibernate Actions"; wantedBy = [ "hibernate.target" ]; after = [ "systemd-hibernate.service" ]; diff --git a/modules/config/swap.nix b/modules/config/swap.nix index 8a2f58d7dcd2..222c18d3e629 100644 --- a/modules/config/swap.nix +++ b/modules/config/swap.nix @@ -82,7 +82,7 @@ with utils; # Create missing swapfiles. # FIXME: support changing the size of existing swapfiles. - boot.systemd.services = + systemd.services = let createSwapDevice = sw: diff --git a/modules/profiles/headless.nix b/modules/profiles/headless.nix index 593bd925b006..0a2bfa80c47c 100644 --- a/modules/profiles/headless.nix +++ b/modules/profiles/headless.nix @@ -12,8 +12,8 @@ with pkgs.lib; services.ttyBackgrounds.enable = false; # Don't start a tty on the serial consoles. - boot.systemd.services."serial-getty@ttyS0".enable = false; - boot.systemd.services."serial-getty@hvc0".enable = false; + systemd.services."serial-getty@ttyS0".enable = false; + systemd.services."serial-getty@hvc0".enable = false; # Since we can't manually respond to a panic, just reboot. boot.kernelParams = [ "panic=1" "boot.panic_on_fail" ]; diff --git a/modules/rename.nix b/modules/rename.nix index 43566bab22f9..534137d4e091 100644 --- a/modules/rename.nix +++ b/modules/rename.nix @@ -71,6 +71,11 @@ in zipModules ([] ++ rename obsolete "networking.enableWLAN" "networking.wireless.enable" ++ rename obsolete "networking.enableRT73Firmware" "networking.enableRalinkFirmware" +# FIXME: Remove these eventually. +++ rename obsolete "boot.systemd.sockets" "systemd.sockets" +++ rename obsolete "boot.systemd.targets" "systemd.targets" +++ rename obsolete "boot.systemd.services" "systemd.services" + # Old Grub-related options. ++ rename obsolete "boot.copyKernels" "boot.loader.grub.copyKernels" ++ rename obsolete "boot.extraGrubEntries" "boot.loader.grub.extraEntries" diff --git a/modules/security/rngd.nix b/modules/security/rngd.nix index 519fb62133cd..dd251fe69d31 100644 --- a/modules/security/rngd.nix +++ b/modules/security/rngd.nix @@ -22,7 +22,7 @@ with pkgs.lib; KERNEL=="tmp0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" ''; - boot.systemd.services.rngd = { + systemd.services.rngd = { bindsTo = [ "dev-random.device" ]; after = [ "dev-random.device" ]; diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix index 92d0cdd26f32..ead53c3dc3a0 100644 --- a/modules/services/audio/alsa.nix +++ b/modules/services/audio/alsa.nix @@ -50,7 +50,7 @@ in boot.kernelModules = optional config.sound.enableOSSEmulation "snd_pcm_oss"; - boot.systemd.services."alsa-store" = + systemd.services."alsa-store" = { description = "Store Sound Card State"; wantedBy = [ "shutdown.target" ]; before = [ "shutdown.target" ]; diff --git a/modules/services/databases/mongodb.nix b/modules/services/databases/mongodb.nix index 9e9e1c7dd8c9..887f1f0529f1 100644 --- a/modules/services/databases/mongodb.nix +++ b/modules/services/databases/mongodb.nix @@ -102,7 +102,7 @@ in environment.systemPackages = [ mongodb ]; - boot.systemd.services.mongodb = + systemd.services.mongodb = { description = "MongoDB server"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix index ef29d563c72a..7bf7a77aa85d 100644 --- a/modules/services/databases/mysql.nix +++ b/modules/services/databases/mysql.nix @@ -141,7 +141,7 @@ in environment.systemPackages = [mysql]; - boot.systemd.services.mysql = + systemd.services.mysql = { description = "MySQL Server"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/databases/mysql55.nix b/modules/services/databases/mysql55.nix index 51fe37b76846..37cab395677e 100644 --- a/modules/services/databases/mysql55.nix +++ b/modules/services/databases/mysql55.nix @@ -134,7 +134,7 @@ in environment.systemPackages = [mysql]; - boot.systemd.services.mysql = + systemd.services.mysql = { description = "MySQL Server"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix index c178a84b1b85..a33fdaab423e 100644 --- a/modules/services/databases/postgresql.nix +++ b/modules/services/databases/postgresql.nix @@ -155,7 +155,7 @@ in environment.systemPackages = [postgresql]; - boot.systemd.services.postgresql = + systemd.services.postgresql = { description = "PostgreSQL Server"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/hardware/upower.nix b/modules/services/hardware/upower.nix index 58f2610ce067..54f5d03de391 100644 --- a/modules/services/hardware/upower.nix +++ b/modules/services/hardware/upower.nix @@ -35,7 +35,7 @@ with pkgs.lib; services.udev.packages = [ pkgs.upower ]; - boot.systemd.services.upower = + systemd.services.upower = { description = "Power Management Daemon"; path = [ pkgs.glib ]; # needed for gdbus serviceConfig = diff --git a/modules/services/logging/logstash.nix b/modules/services/logging/logstash.nix index bc44620d6442..b535a942a9e8 100644 --- a/modules/services/logging/logstash.nix +++ b/modules/services/logging/logstash.nix @@ -136,7 +136,7 @@ in mkNameValuePairs = mergeConfigs; }; } ( mkIf cfg.enable { - boot.systemd.services.logstash = with pkgs; { + systemd.services.logstash = with pkgs; { description = "Logstash daemon"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix index 8c815ddf25f8..886669606b45 100644 --- a/modules/services/logging/syslogd.nix +++ b/modules/services/logging/syslogd.nix @@ -105,7 +105,7 @@ in services.syslogd.extraParams = optional cfg.enableNetworkInput "-r"; # FIXME: restarting syslog seems to break journal logging. - boot.systemd.services.syslog = + systemd.services.syslog = { description = "Syslog Daemon"; requires = [ "syslog.socket" ]; diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix index eaea8bd653a3..a2ec899a5931 100644 --- a/modules/services/misc/nix-daemon.nix +++ b/modules/services/misc/nix-daemon.nix @@ -270,14 +270,14 @@ in target = "nix.machines"; }; - boot.systemd.sockets."nix-daemon" = + systemd.sockets."nix-daemon" = { description = "Nix Daemon Socket"; wantedBy = [ "sockets.target" ]; before = [ "multi-user.target" ]; socketConfig.ListenStream = "/nix/var/nix/daemon-socket/socket"; }; - boot.systemd.services."nix-daemon" = + systemd.services."nix-daemon" = { description = "Nix Daemon"; path = [ nix pkgs.openssl pkgs.utillinux ] diff --git a/modules/services/misc/nix-gc.nix b/modules/services/misc/nix-gc.nix index 435326e87fb8..dc9fa85cf667 100644 --- a/modules/services/misc/nix-gc.nix +++ b/modules/services/misc/nix-gc.nix @@ -51,7 +51,7 @@ in services.cron.systemCronJobs = mkIf cfg.automatic (singleton "${cfg.dates} root ${config.system.build.systemd}/bin/systemctl start nix-gc.service"); - boot.systemd.services."nix-gc" = + systemd.services."nix-gc" = { description = "Nix Garbage Collector"; path = [ config.environment.nix ]; script = "exec nix-collect-garbage ${cfg.options}"; diff --git a/modules/services/misc/nixos-manual.nix b/modules/services/misc/nixos-manual.nix index 1a172904c454..108ed2911ce0 100644 --- a/modules/services/misc/nixos-manual.nix +++ b/modules/services/misc/nixos-manual.nix @@ -84,7 +84,7 @@ in boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"]; - boot.systemd.services = optionalAttrs cfg.showManual + systemd.services = optionalAttrs cfg.showManual { "nixos-manual" = { description = "NixOS Manual"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/misc/rogue.nix b/modules/services/misc/rogue.nix index 12d61a8ea9fd..c5cc8b4050d7 100644 --- a/modules/services/misc/rogue.nix +++ b/modules/services/misc/rogue.nix @@ -40,7 +40,7 @@ in boot.extraTTYs = [ cfg.tty ]; - boot.systemd.services.rogue = + systemd.services.rogue = { description = "Rogue dungeon crawling game"; wantedBy = [ "multi-user.target" ]; serviceConfig = diff --git a/modules/services/monitoring/dd-agent.nix b/modules/services/monitoring/dd-agent.nix index c0493557d56d..c6ab1ca0a3a0 100644 --- a/modules/services/monitoring/dd-agent.nix +++ b/modules/services/monitoring/dd-agent.nix @@ -43,7 +43,7 @@ in { config = mkIf cfg.enable { environment.etc = [ { source = datadog-conf; target = "dd-agent/datadog.conf"; } ]; - boot.systemd.services.dd-agent = { + systemd.services.dd-agent = { description = "Datadog agent monitor"; path = [ pkgs.sysstat pkgs.procps ]; diff --git a/modules/services/monitoring/smartd.nix b/modules/services/monitoring/smartd.nix index 48066856625a..07acab761d08 100644 --- a/modules/services/monitoring/smartd.nix +++ b/modules/services/monitoring/smartd.nix @@ -81,7 +81,7 @@ in config = mkIf cfg.enable { - boot.systemd.services.smartd = { + systemd.services.smartd = { description = "S.M.A.R.T. Daemon"; environment.TZ = config.time.timeZone; diff --git a/modules/services/monitoring/zabbix-agent.nix b/modules/services/monitoring/zabbix-agent.nix index 9758bc8cb485..229236c1bbd4 100644 --- a/modules/services/monitoring/zabbix-agent.nix +++ b/modules/services/monitoring/zabbix-agent.nix @@ -73,7 +73,7 @@ in description = "Zabbix daemon user"; }; - boot.systemd.services."zabbix-agent" = + systemd.services."zabbix-agent" = { description = "Zabbix Agent"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/monitoring/zabbix-server.nix b/modules/services/monitoring/zabbix-server.nix index 085fb022c1c9..df42071ebba0 100644 --- a/modules/services/monitoring/zabbix-server.nix +++ b/modules/services/monitoring/zabbix-server.nix @@ -73,7 +73,7 @@ in description = "Zabbix daemon user"; }; - boot.systemd.services."zabbix-server" = + systemd.services."zabbix-server" = { description = "Zabbix Server"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/network-filesystems/nfsd.nix b/modules/services/network-filesystems/nfsd.nix index 995e9bba6030..ab8e77e2bad4 100644 --- a/modules/services/network-filesystems/nfsd.nix +++ b/modules/services/network-filesystems/nfsd.nix @@ -80,7 +80,7 @@ in boot.kernelModules = [ "nfsd" ]; - boot.systemd.services.nfsd = + systemd.services.nfsd = { description = "NFS Server"; wantedBy = [ "multi-user.target" ]; @@ -108,7 +108,7 @@ in serviceConfig.RemainAfterExit = true; }; - boot.systemd.services.mountd = + systemd.services.mountd = { description = "NFSv3 Mount Daemon"; requires = [ "rpcbind.service" ]; diff --git a/modules/services/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix index aa75c4322a00..c4157c647c63 100644 --- a/modules/services/network-filesystems/samba.nix +++ b/modules/services/network-filesystems/samba.nix @@ -200,7 +200,7 @@ in }; - boot.systemd = { + systemd = { targets.samba = { description = "Samba server"; requires = [ "samba-setup.service" ]; diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 739ba95d5e34..533b719a6675 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -92,7 +92,7 @@ in config = mkIf config.networking.useDHCP { - boot.systemd.services.dhcpcd = + systemd.services.dhcpcd = { description = "DHCP Client"; wantedBy = [ "network.target" ]; diff --git a/modules/services/networking/gogoclient.nix b/modules/services/networking/gogoclient.nix index 7d742df97b0f..07c35e3cb3d6 100644 --- a/modules/services/networking/gogoclient.nix +++ b/modules/services/networking/gogoclient.nix @@ -58,7 +58,7 @@ in networking.enableIPv6 = true; - boot.systemd.services.gogoclient = { + systemd.services.gogoclient = { description = "ipv6 tunnel"; after = [ "network.target" ]; diff --git a/modules/services/networking/openvpn.nix b/modules/services/networking/openvpn.nix index 12808e2ee271..4ea6fa135b0f 100644 --- a/modules/services/networking/openvpn.nix +++ b/modules/services/networking/openvpn.nix @@ -11,7 +11,7 @@ let makeOpenVPNJob = cfg: name: let - path = (getAttr "openvpn-${name}" config.boot.systemd.services).path; + path = (getAttr "openvpn-${name}" config.systemd.services).path; upScript = '' #! /bin/sh diff --git a/modules/services/networking/rpcbind.nix b/modules/services/networking/rpcbind.nix index f82803e75194..7180b2cfa14f 100644 --- a/modules/services/networking/rpcbind.nix +++ b/modules/services/networking/rpcbind.nix @@ -65,7 +65,7 @@ in environment.etc = [ netconfigFile ]; - boot.systemd.services.rpcbind = + systemd.services.rpcbind = { description = "ONC RPC Directory Service"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index 8f898ce06a18..e9df8dd3cf6b 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -262,7 +262,7 @@ in } ]; - boot.systemd.services.sshd = + systemd.services.sshd = { description = "SSH Daemon"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix index a6544368ea0b..4a9d9a77b575 100644 --- a/modules/services/system/dbus.nix +++ b/modules/services/system/dbus.nix @@ -118,7 +118,7 @@ in # FIXME: these are copied verbatim from the dbus source tree. We # should install and use the originals. - boot.systemd.units."dbus.socket".text = + systemd.units."dbus.socket".text = '' [Unit] Description=D-Bus System Message Bus Socket @@ -127,7 +127,7 @@ in ListenStream=/var/run/dbus/system_bus_socket ''; - boot.systemd.units."dbus.service".text = + systemd.units."dbus.service".text = '' [Unit] Description=D-Bus System Message Bus diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix index 1843368ba27d..22f507f39d74 100644 --- a/modules/services/system/nscd.nix +++ b/modules/services/system/nscd.nix @@ -38,7 +38,7 @@ in description = "Name service cache daemon user"; }; - boot.systemd.services.nscd = + systemd.services.nscd = { description = "Name Service Cache Daemon"; wantedBy = [ "nss-lookup.target" "nss-user-lookup.target" ]; diff --git a/modules/services/ttys/agetty.nix b/modules/services/ttys/agetty.nix index 444d04564a97..f269de6fc2a0 100644 --- a/modules/services/ttys/agetty.nix +++ b/modules/services/ttys/agetty.nix @@ -39,7 +39,7 @@ with pkgs.lib; # which some small modifications, which is annoying. # Generate a separate job for each tty. - boot.systemd.units."getty@.service".text = + systemd.units."getty@.service".text = '' [Unit] Description=Getty on %I @@ -76,7 +76,7 @@ with pkgs.lib; X-RestartIfChanged=false ''; - boot.systemd.units."serial-getty@.service".text = + systemd.units."serial-getty@.service".text = '' [Unit] Description=Serial Getty on %I diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 17a8c8216cad..35afacefa164 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -601,7 +601,7 @@ in date.timezone = "${config.time.timeZone}" ''; - boot.systemd.services.httpd = + systemd.services.httpd = { description = "Apache HTTPD"; wantedBy = [ "multi-user.target" ]; diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 599f8be226db..2e6158bafa11 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -386,9 +386,9 @@ in environment.pathsToLink = [ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ]; - boot.systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; + systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; - boot.systemd.services."display-manager" = + systemd.services."display-manager" = { description = "X11 Server"; after = [ "systemd-udev-settle.service" "local-fs.target" ]; diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 6cf9311e471e..4776f4451f05 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -213,7 +213,7 @@ in # just so we can set a restart trigger. Also make # multi-user.target pull it in so that it gets started if it # failed earlier. - boot.systemd.services."systemd-modules-load" = + systemd.services."systemd-modules-load" = { description = "Load Kernel Modules"; wantedBy = [ "sysinit.target" "multi-user.target" ]; before = [ "sysinit.target" "shutdown.target" ]; diff --git a/modules/system/boot/shutdown.nix b/modules/system/boot/shutdown.nix index 3fb9545b33fb..23ddf6d02024 100644 --- a/modules/system/boot/shutdown.nix +++ b/modules/system/boot/shutdown.nix @@ -6,7 +6,7 @@ with pkgs.lib; # This unit saves the value of the system clock to the hardware # clock on shutdown. - boot.systemd.units."save-hwclock.service" = + systemd.units."save-hwclock.service" = { wantedBy = [ "shutdown.target" ]; text = diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 83911d179fde..80957cd11930 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -6,7 +6,7 @@ with import ./systemd-unit-options.nix { inherit config pkgs; }; let - cfg = config.boot.systemd; + cfg = config.systemd; systemd = pkgs.systemd; @@ -340,7 +340,7 @@ in options = { - boot.systemd.units = mkOption { + systemd.units = mkOption { description = "Definition of systemd units."; default = {}; type = types.attrsOf types.optionSet; @@ -367,34 +367,34 @@ in }; }; - boot.systemd.packages = mkOption { + systemd.packages = mkOption { default = []; type = types.listOf types.package; description = "Packages providing systemd units."; }; - boot.systemd.targets = mkOption { + systemd.targets = mkOption { default = {}; type = types.attrsOf types.optionSet; options = [ unitOptions unitConfig ]; description = "Definition of systemd target units."; }; - boot.systemd.services = mkOption { + systemd.services = mkOption { default = {}; type = types.attrsOf types.optionSet; options = [ serviceOptions unitConfig serviceConfig ]; description = "Definition of systemd service units."; }; - boot.systemd.sockets = mkOption { + systemd.sockets = mkOption { default = {}; type = types.attrsOf types.optionSet; options = [ socketOptions unitConfig ]; description = "Definition of systemd socket units."; }; - boot.systemd.mounts = mkOption { + systemd.mounts = mkOption { default = []; type = types.listOf types.optionSet; options = [ mountOptions unitConfig mountConfig ]; @@ -405,13 +405,13 @@ in ''; }; - boot.systemd.defaultUnit = mkOption { + systemd.defaultUnit = mkOption { default = "multi-user.target"; type = types.uniq types.string; description = "Default unit started when the system boots."; }; - boot.systemd.globalEnvironment = mkOption { + systemd.globalEnvironment = mkOption { type = types.attrs; default = {}; example = { TZ = "CET"; }; @@ -500,11 +500,11 @@ in ''; # Target for ‘charon send-keys’ to hook into. - boot.systemd.targets.keys = + systemd.targets.keys = { description = "Security Keys"; }; - boot.systemd.units = + systemd.units = mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix index 44e6e8bb63b5..5d5139b7a57e 100644 --- a/modules/system/upstart/upstart.nix +++ b/modules/system/upstart/upstart.nix @@ -277,7 +277,7 @@ in config = { - boot.systemd.services = + systemd.services = flip mapAttrs' config.jobs (name: job: nameValuePair job.name job.unit); diff --git a/modules/tasks/filesystems.nix b/modules/tasks/filesystems.nix index 00d711eecd31..8efc96f7fe46 100644 --- a/modules/tasks/filesystems.nix +++ b/modules/tasks/filesystems.nix @@ -177,13 +177,13 @@ in }; # Provide a target that pulls in all filesystems. - boot.systemd.targets.fs = + systemd.targets.fs = { description = "All File Systems"; wants = [ "local-fs.target" "remote-fs.target" ]; }; # Emit systemd services to format requested filesystems. - boot.systemd.services = + systemd.services = let formatDevice = fs: diff --git a/modules/tasks/filesystems/nfs.nix b/modules/tasks/filesystems/nfs.nix index 055733e456a8..3d5e1dd51f50 100644 --- a/modules/tasks/filesystems/nfs.nix +++ b/modules/tasks/filesystems/nfs.nix @@ -40,7 +40,7 @@ in boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; - boot.systemd.services.statd = + systemd.services.statd = { description = "NFSv3 Network Status Monitor"; path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ]; @@ -64,7 +64,7 @@ in serviceConfig.Restart = "always"; }; - boot.systemd.services.idmapd = + systemd.services.idmapd = { description = "NFSv4 ID Mapping Daemon"; path = [ pkgs.sysvtools pkgs.utillinux ]; diff --git a/modules/tasks/kbd.nix b/modules/tasks/kbd.nix index 7867b3c19126..b0e222cd05eb 100644 --- a/modules/tasks/kbd.nix +++ b/modules/tasks/kbd.nix @@ -74,7 +74,7 @@ in # shipped with systemd, except that it uses /dev/tty1 instead of # /dev/tty0 to prevent putting the X server in non-raw mode, and # it has a restart trigger. - boot.systemd.services."systemd-vconsole-setup" = + systemd.services."systemd-vconsole-setup" = { description = "Setup Virtual Console"; before = [ "sysinit.target" "shutdown.target" ]; unitConfig = diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index a002e2b68b2d..e8097e418c8b 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -252,13 +252,13 @@ in security.setuidPrograms = [ "ping" "ping6" ]; - boot.systemd.targets."network-interfaces" = + systemd.targets."network-interfaces" = { description = "All Network Interfaces"; wantedBy = [ "network.target" ]; unitConfig.X-StopOnReconfiguration = true; }; - boot.systemd.services = + systemd.services = let networkSetup = diff --git a/modules/testing/test-instrumentation.nix b/modules/testing/test-instrumentation.nix index 108dcb0ab6db..9c36ac2bbdd4 100644 --- a/modules/testing/test-instrumentation.nix +++ b/modules/testing/test-instrumentation.nix @@ -11,7 +11,7 @@ let kernel = config.boot.kernelPackages.kernel; in config = { - boot.systemd.services.backdoor = + systemd.services.backdoor = { wantedBy = [ "multi-user.target" ]; requires = [ "dev-hvc0.device" "dev-ttyS0.device" ]; after = [ "dev-hvc0.device" "dev-ttyS0.device" ]; @@ -34,8 +34,8 @@ let kernel = config.boot.kernelPackages.kernel; in # Prevent agetty from being instantiated on ttyS0, since it # interferes with the backdoor (writes to ttyS0 will randomly fail # with EIO). Likewise for hvc0. - boot.systemd.services."serial-getty@ttyS0".enable = false; - boot.systemd.services."serial-getty@hvc0".enable = false; + systemd.services."serial-getty@ttyS0".enable = false; + systemd.services."serial-getty@hvc0".enable = false; boot.initrd.postDeviceCommands = '' @@ -77,7 +77,7 @@ let kernel = config.boot.kernelPackages.kernel; in networking.defaultGateway = mkOverride 150 ""; networking.nameservers = mkOverride 150 [ ]; - boot.systemd.globalEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data"; + systemd.globalEnvironment.GCOV_PREFIX = "/tmp/xchg/coverage-data"; system.requiredKernelConfig = with config.lib.kernelConfig; [ (isYes "SERIAL_8250_CONSOLE") diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix index 33b8c1e516dc..42c50d857e42 100644 --- a/modules/virtualisation/ec2-data.nix +++ b/modules/virtualisation/ec2-data.nix @@ -19,7 +19,7 @@ in { require = [options]; - boot.systemd.services."fetch-ec2-data" = + systemd.services."fetch-ec2-data" = { description = "Fetch EC2 Data"; wantedBy = [ "multi-user.target" ]; @@ -78,7 +78,7 @@ in serviceConfig.RemainAfterExit = true; }; - boot.systemd.services."print-host-key" = + systemd.services."print-host-key" = { description = "Print SSH Host Key"; wantedBy = [ "multi-user.target" ]; after = [ "sshd.service" ]; diff --git a/modules/virtualisation/libvirtd.nix b/modules/virtualisation/libvirtd.nix index 89c4512095db..757a20f61648 100644 --- a/modules/virtualisation/libvirtd.nix +++ b/modules/virtualisation/libvirtd.nix @@ -49,7 +49,7 @@ in boot.kernelModules = [ "tun" ]; - boot.systemd.services.libvirtd = + systemd.services.libvirtd = { description = "Libvirt Virtual Machine Management Daemon"; wantedBy = [ "multi-user.target" ]; From 4d983d4955fcb6eb6b633b216ee0e29839b3b4a5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jan 2013 13:17:57 +0100 Subject: [PATCH 319/327] =?UTF-8?q?Rename=20=E2=80=98system.build.systemd?= =?UTF-8?q?=E2=80=99=20to=20=E2=80=98systemd.package=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it cheaper to test a new systemd and is more consistent with other modules. --- modules/services/hardware/udev.nix | 2 +- modules/services/hardware/upower.nix | 2 +- modules/services/misc/nix-gc.nix | 2 +- modules/services/networking/dhcpcd.nix | 8 ++++---- modules/services/networking/networkmanager.nix | 2 +- modules/services/networking/wpa_supplicant.nix | 2 +- modules/services/x11/display-managers/default.nix | 2 +- modules/services/x11/display-managers/kdm.nix | 4 ++-- modules/services/x11/display-managers/slim.nix | 4 ++-- modules/system/activation/top-level.nix | 4 ++-- modules/system/boot/kernel.nix | 2 +- modules/system/boot/stage-1.nix | 2 +- modules/system/boot/systemd.nix | 10 +++++++--- modules/tasks/kbd.nix | 2 +- modules/tasks/network-interfaces.nix | 4 ++-- 15 files changed, 28 insertions(+), 24 deletions(-) diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix index d558d2983cf9..e1a338d6ad8b 100644 --- a/modules/services/hardware/udev.nix +++ b/modules/services/hardware/udev.nix @@ -6,7 +6,7 @@ let inherit (pkgs) stdenv writeText procps; - udev = config.system.build.systemd; + udev = config.systemd.package; cfg = config.services.udev; diff --git a/modules/services/hardware/upower.nix b/modules/services/hardware/upower.nix index 54f5d03de391..5d1658adb75f 100644 --- a/modules/services/hardware/upower.nix +++ b/modules/services/hardware/upower.nix @@ -56,7 +56,7 @@ with pkgs.lib; # the daemon. powerManagement.resumeCommands = '' - ${config.system.build.systemd}/bin/systemctl try-restart upower + ${config.systemd.package}/bin/systemctl try-restart upower ''; }; diff --git a/modules/services/misc/nix-gc.nix b/modules/services/misc/nix-gc.nix index dc9fa85cf667..280450446016 100644 --- a/modules/services/misc/nix-gc.nix +++ b/modules/services/misc/nix-gc.nix @@ -49,7 +49,7 @@ in config = { services.cron.systemCronJobs = mkIf cfg.automatic (singleton - "${cfg.dates} root ${config.system.build.systemd}/bin/systemctl start nix-gc.service"); + "${cfg.dates} root ${config.systemd.package}/bin/systemctl start nix-gc.service"); systemd.services."nix-gc" = { description = "Nix Garbage Collector"; diff --git a/modules/services/networking/dhcpcd.nix b/modules/services/networking/dhcpcd.nix index 533b719a6675..342253bac296 100644 --- a/modules/services/networking/dhcpcd.nix +++ b/modules/services/networking/dhcpcd.nix @@ -57,13 +57,13 @@ let # server hostnames in its config file, then it will never do # anything ever again ("couldn't resolve ..., giving up on # it"), so we silently lose time synchronisation. - ${config.system.build.systemd}/bin/systemctl try-restart ntpd.service + ${config.systemd.package}/bin/systemctl try-restart ntpd.service - ${config.system.build.systemd}/bin/systemctl start ip-up.target + ${config.systemd.package}/bin/systemctl start ip-up.target fi #if [ "$reason" = EXPIRE -o "$reason" = RELEASE -o "$reason" = NOCARRIER ] ; then - # ${config.system.build.systemd}/bin/systemctl start ip-down.target + # ${config.systemd.package}/bin/systemctl start ip-down.target #fi ''; @@ -126,7 +126,7 @@ in powerManagement.resumeCommands = '' # Tell dhcpcd to rebind its interfaces if it's running. - ${config.system.build.systemd}/bin/systemctl reload dhcpcd.service + ${config.systemd.package}/bin/systemctl reload dhcpcd.service ''; }; diff --git a/modules/services/networking/networkmanager.nix b/modules/services/networking/networkmanager.nix index d8198dd03298..0daa945c14ac 100644 --- a/modules/services/networking/networkmanager.nix +++ b/modules/services/networking/networkmanager.nix @@ -39,7 +39,7 @@ let ipUpScript = pkgs.writeScript "01nixos-ip-up" '' #!/bin/sh if test "$2" = "up"; then - ${config.system.build.systemd}/bin/systemctl start ip-up.target + ${config.systemd.package}/bin/systemctl start ip-up.target fi ''; diff --git a/modules/services/networking/wpa_supplicant.nix b/modules/services/networking/wpa_supplicant.nix index 4f8ae55d2090..20752cdee259 100644 --- a/modules/services/networking/wpa_supplicant.nix +++ b/modules/services/networking/wpa_supplicant.nix @@ -124,7 +124,7 @@ in powerManagement.resumeCommands = '' - ${config.system.build.systemd}/bin/systemctl try-restart wpa_supplicant + ${config.systemd.package}/bin/systemctl try-restart wpa_supplicant ''; assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != []; diff --git a/modules/services/x11/display-managers/default.nix b/modules/services/x11/display-managers/default.nix index 396311be49e1..1f842c0c9534 100644 --- a/modules/services/x11/display-managers/default.nix +++ b/modules/services/x11/display-managers/default.nix @@ -36,7 +36,7 @@ let # since presumably the desktop environment will handle these. if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then export _INHIBITION_LOCK_TAKEN=1 - exec ${config.system.build.systemd}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType" + exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType" fi ${optionalString cfg.startOpenSSHAgent '' diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix index 08ae667211d4..6a628ec124f2 100644 --- a/modules/services/x11/display-managers/kdm.nix +++ b/modules/services/x11/display-managers/kdm.nix @@ -12,8 +12,8 @@ let defaultConfig = '' [Shutdown] - HaltCmd=${config.system.build.systemd}/sbin/shutdown -h now - RebootCmd=${config.system.build.systemd}/sbin/shutdown -r now + HaltCmd=${config.systemd.package}/sbin/shutdown -h now + RebootCmd=${config.systemd.package}/sbin/shutdown -r now ${optionalString (config.system.boot.loader.id == "grub") '' BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"} ''} diff --git a/modules/services/x11/display-managers/slim.nix b/modules/services/x11/display-managers/slim.nix index bc9aef101c7d..9e8b9391f45f 100644 --- a/modules/services/x11/display-managers/slim.nix +++ b/modules/services/x11/display-managers/slim.nix @@ -14,8 +14,8 @@ let xserver_arguments ${dmcfg.xserverArgs} sessions ${pkgs.lib.concatStringsSep "," (dmcfg.session.names ++ ["custom"])} login_cmd exec ${pkgs.stdenv.shell} ${dmcfg.session.script} "%session" - halt_cmd ${config.system.build.systemd}/sbin/shutdown -h now - reboot_cmd ${config.system.build.systemd}/sbin/shutdown -r now + halt_cmd ${config.systemd.package}/sbin/shutdown -h now + reboot_cmd ${config.systemd.package}/sbin/shutdown -r now ${optionalString (cfg.defaultUser != "") ("default_user " + cfg.defaultUser)} ${optionalString cfg.autoLogin "auto_login yes"} ''; diff --git a/modules/system/activation/top-level.nix b/modules/system/activation/top-level.nix index 48c1c0be1896..e99b50a0309d 100644 --- a/modules/system/activation/top-level.nix +++ b/modules/system/activation/top-level.nix @@ -120,7 +120,7 @@ let echo -n "$kernelParams" > $out/kernel-params echo -n "$configurationName" > $out/configuration-name - echo -n "systemd ${toString config.system.build.systemd.interfaceVersion}" > $out/init-interface-version + echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version echo -n "$nixosVersion" > $out/nixos-version mkdir $out/fine-tune @@ -149,7 +149,7 @@ let buildCommand = systemBuilder; inherit (pkgs) utillinux; - inherit (config.system.build) systemd; + systemd = config.systemd.package; inherit children; kernelParams = diff --git a/modules/system/boot/kernel.nix b/modules/system/boot/kernel.nix index 4776f4451f05..7744fd94a2c8 100644 --- a/modules/system/boot/kernel.nix +++ b/modules/system/boot/kernel.nix @@ -224,7 +224,7 @@ in serviceConfig = { Type = "oneshot"; RemainAfterExit = true; - ExecStart = "${config.system.build.systemd}/lib/systemd/systemd-modules-load"; + ExecStart = "${config.systemd.package}/lib/systemd/systemd-modules-load"; # Ignore failed module loads. Typically some of the # modules in ‘boot.kernelModules’ are "nice to have but # not required" (e.g. acpi-cpufreq), so we don't want to diff --git a/modules/system/boot/stage-1.nix b/modules/system/boot/stage-1.nix index b131867966ab..9743703ffbe6 100644 --- a/modules/system/boot/stage-1.nix +++ b/modules/system/boot/stage-1.nix @@ -9,7 +9,7 @@ with pkgs.lib; let - udev = config.system.build.systemd; + udev = config.systemd.package; options = { diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 80957cd11930..b76367021206 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -8,7 +8,7 @@ let cfg = config.systemd; - systemd = pkgs.systemd; + systemd = cfg.package; makeUnit = name: unit: pkgs.runCommand "unit" { inherit (unit) text; } @@ -340,6 +340,12 @@ in options = { + systemd.package = mkOption { + default = pkgs.systemd; + type = types.package; + description = "The systemd package."; + }; + systemd.units = mkOption { description = "Definition of systemd units."; default = {}; @@ -457,8 +463,6 @@ in config = { - system.build.systemd = systemd; - system.build.units = units; environment.systemPackages = [ systemd ]; diff --git a/modules/tasks/kbd.nix b/modules/tasks/kbd.nix index b0e222cd05eb..e4d22e94c80c 100644 --- a/modules/tasks/kbd.nix +++ b/modules/tasks/kbd.nix @@ -85,7 +85,7 @@ in serviceConfig = { Type = "oneshot"; RemainAfterExit = true; - ExecStart = "${config.system.build.systemd}/lib/systemd/systemd-vconsole-setup /dev/tty1"; + ExecStart = "${config.systemd.package}/lib/systemd/systemd-vconsole-setup /dev/tty1"; }; restartTriggers = [ vconsoleConf ]; }; diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix index e8097e418c8b..49dd47251e5d 100644 --- a/modules/tasks/network-interfaces.nix +++ b/modules/tasks/network-interfaces.nix @@ -350,11 +350,11 @@ in ip -4 addr add "${i.ipAddress}/${mask}" dev "${i.name}" # Ensure that the default gateway remains set. # (Flushing this interface may have removed it.) - ${config.system.build.systemd}/bin/systemctl try-restart --no-block network-setup.service + ${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service else echo "skipping configuring interface" fi - ${config.system.build.systemd}/bin/systemctl start ip-up.target + ${config.systemd.package}/bin/systemctl start ip-up.target '' + optionalString i.proxyARP '' From ea358b4eae2509722b849c054fdff69cc31ac8c7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jan 2013 13:21:59 +0100 Subject: [PATCH 320/327] =?UTF-8?q?nixos-rebuild:=20Use=20=E2=80=98[=20...?= =?UTF-8?q?=20]=E2=80=99=20instead=20of=20=E2=80=98test=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/installer/tools/nixos-rebuild.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/installer/tools/nixos-rebuild.sh b/modules/installer/tools/nixos-rebuild.sh index 66acf9087106..0b149610e324 100644 --- a/modules/installer/tools/nixos-rebuild.sh +++ b/modules/installer/tools/nixos-rebuild.sh @@ -50,7 +50,7 @@ buildNix=1 rollback= upgrade= -while test "$#" -gt 0; do +while [ "$#" -gt 0 ]; do i="$1"; shift 1 case "$i" in --help) @@ -94,13 +94,13 @@ while test "$#" -gt 0; do esac done -if test -z "$action"; then showSyntax; fi +if [ -z "$action" ]; then showSyntax; fi -if test "$action" = dry-run; then +if [ "$action" = dry-run ]; then extraBuildFlags+=(--dry-run) fi -if test -n "$rollback"; then +if [ -n "$rollback" ]; then buildNix= fi @@ -143,12 +143,12 @@ fi # Either upgrade the configuration in the system profile (for "switch" # or "boot"), or just build it and create a symlink "result" in the # current directory (for "build" and "test"). -if test -z "$rollback"; then +if [ -z "$rollback" ]; then echo "building the system configuration..." >&2 - if test "$action" = switch -o "$action" = boot; then + if [ "$action" = switch -o "$action" = boot ]; then nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system -f '' --set -A system pathToConfig=/nix/var/nix/profiles/system - elif test "$action" = test -o "$action" = build -o "$action" = dry-run; then + elif [ "$action" = test -o "$action" = build -o "$action" = dry-run ]; then nix-build '' -A system -K -k "${extraBuildFlags[@]}" > /dev/null pathToConfig=./result elif [ "$action" = build-vm ]; then @@ -160,11 +160,11 @@ if test -z "$rollback"; then else showSyntax fi -else # test -n "$rollback" - if test "$action" = switch -o "$action" = boot; then +else # [ -n "$rollback" ] + if [ "$action" = switch -o "$action" = boot ]; then nix-env --rollback -p /nix/var/nix/profiles/system pathToConfig=/nix/var/nix/profiles/system - elif test "$action" = test -o "$action" = build; then + elif [ "$action" = test -o "$action" = build ]; then systemNumber=$( nix-env -p /nix/var/nix/profiles/system --list-generations | sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h' @@ -179,7 +179,7 @@ fi # If we're not just building, then make the new configuration the boot # default and/or activate it now. -if test "$action" = switch -o "$action" = boot -o "$action" = test; then +if [ "$action" = switch -o "$action" = boot -o "$action" = test ]; then # Just in case the new configuration hangs the system, do a sync now. sync @@ -187,7 +187,7 @@ if test "$action" = switch -o "$action" = boot -o "$action" = test; then fi -if test "$action" = build-vm; then +if [ "$action" = build-vm ]; then cat >&2 < Date: Wed, 16 Jan 2013 14:40:41 +0100 Subject: [PATCH 321/327] Set the NixOS version to something useful when building from Git --- modules/installer/tools/nixos-rebuild.sh | 10 ++++++++++ modules/misc/version.nix | 17 ++++++++++++----- release.nix | 4 ++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/modules/installer/tools/nixos-rebuild.sh b/modules/installer/tools/nixos-rebuild.sh index 0b149610e324..28a1d2282939 100644 --- a/modules/installer/tools/nixos-rebuild.sh +++ b/modules/installer/tools/nixos-rebuild.sh @@ -140,6 +140,16 @@ if [ -n "$buildNix" ]; then fi +# Update the version suffix if we're building from Git (so that +# nixos-version shows something useful). +if nixos=$(nix-instantiate --find-file nixos "${extraBuildFlags[@]}"); then + suffix=$($SHELL $nixos/modules/installer/tools/get-version-suffix "${extraBuildFlags[@]}") + if [ -n "$suffix" ]; then + echo -n "$suffix" > "$nixos/.version-suffix" + fi +fi + + # Either upgrade the configuration in the system profile (for "switch" # or "boot"), or just build it and create a symlink "result" in the # current directory (for "build" and "test"). diff --git a/modules/misc/version.nix b/modules/misc/version.nix index 319cdcb5f98f..23e96171d1fe 100644 --- a/modules/misc/version.nix +++ b/modules/misc/version.nix @@ -5,18 +5,25 @@ with pkgs.lib; { options = { - + system.nixosVersion = mkOption { - default = - builtins.readFile ../../.version - + (if builtins.pathExists ../../.version-suffix then builtins.readFile ../../.version-suffix else "pre-git"); description = "NixOS version."; }; + system.nixosVersionSuffix = mkOption { + description = "NixOS version suffix."; + }; + }; config = { + system.nixosVersion = + builtins.readFile ../../.version + config.system.nixosVersionSuffix; + + system.nixosVersionSuffix = + if builtins.pathExists ../../.version-suffix then builtins.readFile ../../.version-suffix else "pre-git"; + # Generate /etc/os-release. See # http://0pointer.de/public/systemd-man/os-release.html for the # format. @@ -32,7 +39,7 @@ with pkgs.lib; ''; target = "os-release"; }; - + }; } diff --git a/release.nix b/release.nix index 4c29fce29f29..6caf3b385b16 100644 --- a/release.nix +++ b/release.nix @@ -20,7 +20,7 @@ let let versionModule = - { system.nixosVersion = version + (lib.optionalString (!officialRelease) versionSuffix); + { system.nixosVersionSuffix = lib.optionalString (!officialRelease) versionSuffix; isoImage.isoBaseName = "nixos-${type}"; }; @@ -55,7 +55,7 @@ let with import {inherit system;}; let - versionModule = { system.nixosVersion = version + (lib.optionalString (!officialRelease) versionSuffix); }; + versionModule = { system.nixosVersionSuffix = lib.optionalString (!officialRelease) versionSuffix; }; config = (import lib/eval-config.nix { inherit system; From f2908085099a1ce529843982bfe8cc3d3fd375d6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jan 2013 15:03:54 +0100 Subject: [PATCH 322/327] Set some missing types --- modules/misc/version.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/misc/version.nix b/modules/misc/version.nix index 23e96171d1fe..aa9557d94210 100644 --- a/modules/misc/version.nix +++ b/modules/misc/version.nix @@ -7,10 +7,12 @@ with pkgs.lib; options = { system.nixosVersion = mkOption { + type = types.uniq types.string; description = "NixOS version."; }; system.nixosVersionSuffix = mkOption { + type = types.uniq types.string; description = "NixOS version suffix."; }; @@ -19,10 +21,10 @@ with pkgs.lib; config = { system.nixosVersion = - builtins.readFile ../../.version + config.system.nixosVersionSuffix; + mkDefault (builtins.readFile ../../.version + config.system.nixosVersionSuffix); system.nixosVersionSuffix = - if builtins.pathExists ../../.version-suffix then builtins.readFile ../../.version-suffix else "pre-git"; + mkDefault (if builtins.pathExists ../../.version-suffix then builtins.readFile ../../.version-suffix else "pre-git"); # Generate /etc/os-release. See # http://0pointer.de/public/systemd-man/os-release.html for the From e65a49f00f0b5da866e326e090cb5b9ff48bec6b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jan 2013 16:06:50 +0100 Subject: [PATCH 323/327] Add missing file --- modules/installer/tools/get-version-suffix | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 modules/installer/tools/get-version-suffix diff --git a/modules/installer/tools/get-version-suffix b/modules/installer/tools/get-version-suffix new file mode 100644 index 000000000000..76cec8d5dae3 --- /dev/null +++ b/modules/installer/tools/get-version-suffix @@ -0,0 +1,29 @@ +getVersion() { + local dir="$1" + rev= + if [ -e "$dir/.git" ]; then + if [ -z "$(type -P git)" ]; then + echo "warning: Git not found; cannot figure out revision of $dir" >&2 + return + fi + cd "$dir" + rev=$(git rev-parse --short HEAD) + if git describe --always --dirty | grep -q dirty; then + rev+=M + fi + fi +} + +if nixos=$(nix-instantiate --find-file nixos "$@"); then + getVersion $nixos + if [ -n "$rev" ]; then + suffix="pre-$rev" + if nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then + getVersion $nixpkgs + if [ -n "$rev" ]; then + suffix+="-$rev" + fi + fi + echo $suffix + fi +fi From 6e7b0a0c0e44256ddc28476d926a638947339daf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 Jan 2013 16:11:51 +0100 Subject: [PATCH 324/327] =?UTF-8?q?Fix=20=E2=80=98nixos-rebuikd=20dry-run?= =?UTF-8?q?=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/installer/tools/nixos-rebuild.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/installer/tools/nixos-rebuild.sh b/modules/installer/tools/nixos-rebuild.sh index 28a1d2282939..b9272f31ac6f 100644 --- a/modules/installer/tools/nixos-rebuild.sh +++ b/modules/installer/tools/nixos-rebuild.sh @@ -96,10 +96,6 @@ done if [ -z "$action" ]; then showSyntax; fi -if [ "$action" = dry-run ]; then - extraBuildFlags+=(--dry-run) -fi - if [ -n "$rollback" ]; then buildNix= fi @@ -129,7 +125,7 @@ fi # First build Nix, since NixOS may require a newer version than the # current one. Of course, the same goes for Nixpkgs, but Nixpkgs is # more conservative. -if [ -n "$buildNix" ]; then +if [ "$action" != dry-run -a -n "$buildNix" ]; then echo "building Nix..." >&2 if ! nix-build '' -A config.environment.nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then if ! nix-build '' -A nixFallback -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then @@ -150,6 +146,11 @@ if nixos=$(nix-instantiate --find-file nixos "${extraBuildFlags[@]}"); then fi +if [ "$action" = dry-run ]; then + extraBuildFlags+=(--dry-run) +fi + + # Either upgrade the configuration in the system profile (for "switch" # or "boot"), or just build it and create a symlink "result" in the # current directory (for "build" and "test"). From e89afd7d892fa1b8cff57f1045e27b25366f7475 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Wed, 16 Jan 2013 10:12:15 -0500 Subject: [PATCH 325/327] Ignore .version-suffix file created by nixos-rebuild --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b25c15b81fae..e75fb319980e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *~ +.version-suffix From c6bb091b5bb6989a117149d8d4bfdc533b5cc82c Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Thu, 3 Jan 2013 18:55:56 +0100 Subject: [PATCH 326/327] Rewrite NetworkManager job to systemd service --- .../services/networking/networkmanager.nix | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/modules/services/networking/networkmanager.nix b/modules/services/networking/networkmanager.nix index 0daa945c14ac..bd5ec4bd8f78 100644 --- a/modules/services/networking/networkmanager.nix +++ b/modules/services/networking/networkmanager.nix @@ -1,13 +1,14 @@ { config, pkgs, ... }: with pkgs.lib; +with pkgs; let cfg = config.networking.networkmanager; stateDirs = "/var/lib/NetworkManager /var/lib/dhclient"; - configFile = pkgs.writeText "NetworkManager.conf" '' + configFile = writeText "NetworkManager.conf" '' [main] plugins=keyfile @@ -36,7 +37,7 @@ let ResultActive=yes ''; - ipUpScript = pkgs.writeScript "01nixos-ip-up" '' + ipUpScript = writeScript "01nixos-ip-up" '' #!/bin/sh if test "$2" = "up"; then ${config.systemd.package}/bin/systemctl start ip-up.target @@ -67,7 +68,7 @@ in { Extra packages that provide NetworkManager plugins. ''; merge = mergeListOption; - apply = list: [ pkgs.networkmanager pkgs.modemmanager ] ++ list; + apply = list: [ networkmanager modemmanager wpa_supplicant ] ++ list; }; }; @@ -76,10 +77,14 @@ in { config = mkIf cfg.enable { - environment.etc = singleton { - source = ipUpScript; - target = "NetworkManager/dispatcher.d/01nixos-ip-up"; - }; + environment.etc = [ + { source = ipUpScript; + target = "NetworkManager/dispatcher.d/01nixos-ip-up"; + } + { source = configFile; + target = "NetworkManager/NetworkManager.conf"; + } + ]; environment.systemPackages = cfg.packages; @@ -88,24 +93,31 @@ in { gid = config.ids.gids.networkmanager; }; - jobs.networkmanager = { - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; + systemd.packages = cfg.packages; - path = [ pkgs.networkmanager ]; - - preStart = '' - mkdir -m 755 -p /etc/NetworkManager + # Create an initialisation service that both starts + # NetworkManager when network.target is reached, + # and sets up necessary directories for NM. + systemd.services."NetworkManager-init" = { + description = "NetworkManager initialisation"; + wantedBy = [ "network.target" ]; + partOf = [ "NetworkManager.service" ]; + wants = [ "NetworkManager.service" ]; + before = [ "NetworkManager.service" ]; + script = '' mkdir -m 700 -p /etc/NetworkManager/system-connections mkdir -m 755 -p ${stateDirs} ''; - - exec = "NetworkManager --config=${configFile} --no-daemon"; + serviceConfig = { + Type = "oneshot"; + }; }; - networking.useDHCP = false; - - networking.wireless.enable = true; + # Turn off NixOS' network management + networking = { + useDHCP = false; + wireless.enable = false; + }; security.polkit.permissions = polkitConf; From 1440e92ae8f7a7c3654307bcbf19ddf4c7f51f40 Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Thu, 17 Jan 2013 13:37:54 +0100 Subject: [PATCH 327/327] Rename NetworkManager-init service to networkmanager-init --- modules/services/networking/networkmanager.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/networking/networkmanager.nix b/modules/services/networking/networkmanager.nix index bd5ec4bd8f78..74d9992f770d 100644 --- a/modules/services/networking/networkmanager.nix +++ b/modules/services/networking/networkmanager.nix @@ -98,7 +98,7 @@ in { # Create an initialisation service that both starts # NetworkManager when network.target is reached, # and sets up necessary directories for NM. - systemd.services."NetworkManager-init" = { + systemd.services."networkmanager-init" = { description = "NetworkManager initialisation"; wantedBy = [ "network.target" ]; partOf = [ "NetworkManager.service" ];