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 9eab8dde473..2a25cd411a1 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 48171f62150..870d316006f 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 3edc92d502c..ef32d991d9d 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 bd48f463dcd..33d0a6ad3e8 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 00000000000..3b51ebf43fc --- /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 53efc08cfb8..e4ca7f39a56 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 f7fbb23d0a7..8659c784483 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 9e0ed028d5d..42dd21b6204 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 02c061dacde..a5e96cc0f1c 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 3b51ebf43fc..4555b59d278 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 1bfde9fc60e..284f1aafd37 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 0b63d7543ea..81a9b570127 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 4555b59d278..57bc47bd6d6 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 2a25cd411a1..d5939db95ac 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 f210ecec26d..1b34e78ab78 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 42dd21b6204..384c9e301cb 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 870d316006f..0b324e7fffd 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 28e1fec0601..00000000000 --- 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 4fab7febc71..09803598db9 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 57bc47bd6d6..0d4256990e7 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 5065fc22f2c..757bb9e85e0 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 0b324e7fffd..04fa9c58ec6 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 6d2fe3f2ace..3c32a3c25ec 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 e4ca7f39a56..9710082f420 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 6f35cd30f58..b2596dbb413 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 85db3f8966e..8304ca180cb 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 ce3311a5f59..259847d0726 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 384c9e301cb..8238fc1537e 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 0d4256990e7..c5a646208cb 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 f0f146160e5..00000000000 --- 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 016217ea3a6..00000000000 --- 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 284f1aafd37..b09fdc7d676 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 9495cac6785..8eaf77330a3 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 62c4b92ed09..b563d33dc5b 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 c12f9b28ca9..611de13148a 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 9710082f420..5a924361761 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 8659c784483..bd5c290d582 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 c5a646208cb..d75572b2789 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 b09fdc7d676..2e57ac358da 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 635146ac889..7773a2c79e3 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 2e57ac358da..0f7eb65bf2f 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 5a924361761..3bf4bf642fa 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 d75572b2789..906558bd695 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 0f7eb65bf2f..de60f693e83 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 04fa9c58ec6..2aa34cb205f 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 8304ca180cb..f70cbe74d67 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 906558bd695..f41e471cb1b 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 f70cbe74d67..43ee81481bf 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 2aa34cb205f..c7820690929 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 00000000000..3af8e3e4b29 --- /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 8aa794378ed..00000000000 --- 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 00000000000..b25c15b81fa --- /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 f41e471cb1b..652f9763024 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 31b81a13e36..ea13def39d6 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 d5939db95ac..89524c3f231 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 c7820690929..6f65e71be9b 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 715cfc0f9e6..bfe7352122c 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 81a9b570127..fe1b7323358 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 2ae42f5b41b..61af0459a6b 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 89524c3f231..7651f4760ca 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 278c68fce99..aeb6a518906 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 75f83a27db9..355f88cf385 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 8238fc1537e..a4b966081d6 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 a4b966081d6..bb9b5c28163 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 cdfd271ee65..528b3a6f727 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 fe7802100b2..47d9299fb79 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 97c5f1d1b2b..fc4df80d810 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 652f9763024..7fafc94a4bb 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 7fafc94a4bb..6976a204e7f 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 5e40cf215b7..468a3030ca6 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 3af8e3e4b29..1335429b669 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 6976a204e7f..d7684c7ecb2 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 bfe7352122c..2136aaa5586 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 d7684c7ecb2..2b32c94262e 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 ce9c1cea743..c81f6eaac65 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 2136aaa5586..a3aff9a30d3 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 d89978a852c..0ef1f09f4d6 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 2b32c94262e..b4104980618 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 de60f693e83..cbefad21414 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 42d276c9666..a0e53eeaef4 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 b4104980618..40ff14dda7a 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 dee1e4f33cb..f0d5fbc19ea 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 43f74cf404b..fc4b7ea0555 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 6a39df8c865..212c478a728 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 ea13def39d6..35c1ace93d3 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 40ff14dda7a..5f7f62b7866 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 62af63ec39f..0256100f4ec 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 bd5c290d582..a6544368ea0 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 a0e53eeaef4..1916c13333d 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 122faf98136..c1cc22f905c 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 cbefad21414..6f76f5d7b1d 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 0256100f4ec..cc2f2e9282a 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 5f7f62b7866..db690901014 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 c53325ed4e6..dd435d481b7 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 dd4b9f382c0..aa708fb6019 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 00000000000..199c23d8ab0 --- /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 199c23d8ab0..b9ba9b14e63 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 db690901014..848831a94a2 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 b9ba9b14e63..4ff4cf1420f 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 4ff4cf1420f..fd515341d13 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 fd515341d13..e017098a411 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 e017098a411..4f6a2a14cd1 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 4f6a2a14cd1..098c08f9720 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 098c08f9720..c7a82da7a7b 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 c7a82da7a7b..6cedf7f2646 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 59fbcc0d878..00000000000 --- 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 1633b9d0fdd..139a716ae75 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 00000000000..34b37f4d0ba --- /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 848831a94a2..10c98116710 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 6f76f5d7b1d..6375289293f 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 b2596dbb413..80fa1394aca 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 1916c13333d..92915f9132b 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 6375289293f..92a7add88eb 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 8e09d79e3a4..e864c125176 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 6cedf7f2646..96b256bc24d 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 92915f9132b..1916c13333d 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 1b247a65890..f3ede5c0d49 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 10c98116710..2a586090dd1 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 96b256bc24d..0b900e3fc16 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 0b900e3fc16..06a6a5bc888 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 598d68eb91d..b5b69265455 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 13ebf954f32..cc514fb79c8 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 06a6a5bc888..df4c440b97a 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 d092fa1d086..0cc9bf04978 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 a5e96cc0f1c..e187219cbd8 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 34b37f4d0ba..ec769ad69f9 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 2a586090dd1..5f7ea7d3c9b 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 95e925bbe12..fc97100b135 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 02a75ae21c4..d2a96a764c7 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 a91ce9c59e2..5896e9ec9fd 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 c1cc22f905c..77d4ac6253c 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 80fa1394aca..d92e4e608b5 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 1335429b669..3fb9545b33f 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 e8b01788900..80aff11b34b 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 03d9222af21..141be71b920 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 80aff11b34b..fd60fa5e59e 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 79583a73174..94680bce890 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 92a7add88eb..c31314f1091 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 611de13148a..5ff1a83bc81 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 5f7ea7d3c9b..6cd8b80f22a 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 6cd8b80f22a..51b65812b34 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 139a716ae75..69051c29521 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 2f90c515643..7c13fd32752 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 ec769ad69f9..9aa9b2b4f3b 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 51b65812b34..06019fa2a08 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 c31314f1091..577efe17065 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 5896e9ec9fd..921972093ce 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 77d4ac6253c..2767af7200e 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 7d1db8df066..e9b27268aa1 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 06019fa2a08..992981f0a36 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 5ff1a83bc81..5302fa82bd4 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 3154c3dd1e7..504f30a1a8f 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 d16a6794832..8212b3f9fd0 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 303db3816b5..2002df6a303 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 2767af7200e..54fdf7b81cf 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 5dc203fd177..c6b7df38fcf 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 ec4d033a597..1699ad6343d 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 fc4df80d810..fbd899b9a95 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 5d795e5d57d..5b9cb74169e 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 df4c440b97a..a4ca287b420 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 9aa9b2b4f3b..f56ee4fc0d3 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 992981f0a36..def5a8bc580 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 577efe17065..7a498b85439 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 0ef1f09f4d6..76e35250a60 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 fbd899b9a95..68d8c11f830 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 a3f837c7367..4b9be460548 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 9e8bc02ddf4..049df0f9958 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 76e35250a60..6ad79ca72a8 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 1699ad6343d..1699f6c65a7 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 68d8c11f830..bc9aef101c7 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 5b9cb74169e..fddffbcf0a6 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 93635aa667f..f270a3fa431 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 a5eb506fcdd..9f3fa0d6fc5 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 f9fb2dfecef..00000000000 --- 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 753bac47627..3fead2e96cb 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 9f3fa0d6fc5..14cf4f7012c 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 5aa02950f74..00000000000 --- 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 2f7f62ce416..f4bf0d3f2c6 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 1699f6c65a7..08ae667211d 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 504f30a1a8f..069bf8ecd9c 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 54fdf7b81cf..6eea947f604 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 7a498b85439..c00bc03c66f 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 a4ca287b420..23fd0d77796 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 23fd0d77796..c70a6159fe3 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 cb293563dfd..27e4ac400da 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 def5a8bc580..2045e702fe9 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 069bf8ecd9c..c8ca959d91a 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 1fdaee202d3..d025276ea8e 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 7773a2c79e3..0e0272388c7 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 c8ca959d91a..021986bc895 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 a3aff9a30d3..2b7e4a8e44c 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 79323287258..cf2d0f52d86 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 6ad79ca72a8..242129c355e 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 fddffbcf0a6..992911ca3c4 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 2045e702fe9..918c0571ab4 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 c00bc03c66f..fbbbf72e027 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 facfe29a4b0..efce3153c88 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 e864c125176..03234fbb82f 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 0e0fd502a01..cb64f8ca2a3 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 c70a6159fe3..1d2da3cbf8e 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 1d2da3cbf8e..eb5a7a690f0 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 1916c13333d..f79962c1365 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 cb64f8ca2a3..59e74fa6660 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 eb5a7a690f0..ff083156ca2 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 c057bda5033..12808e2ee27 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 8eaf77330a3..ab58c0757b6 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 79d332690b9..f1eb73a8f88 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 ff083156ca2..6542b48c54e 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 918c0571ab4..d8b5ee45c7e 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 d92e4e608b5..620424b94a0 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 cf2d0f52d86..7e52686f32f 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 f1eb73a8f88..3aab7a59504 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 e187219cbd8..3569cfa8113 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 2427f29020e..242faa010f2 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 3784ae3d39f..d4505818e0c 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 7e52686f32f..ba970b95bc0 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 3aab7a59504..55e61ffb69a 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 8212b3f9fd0..fa63bc74cfc 100644 --- a/modules/services/audio/alsa.nix +++ b/modules/services/audio/alsa.nix @@ -56,8 +56,9 @@ in '' mkdir -m 0755 -p $(dirname ${soundState}) - # Restore the sound state. - ${alsaUtils}/sbin/alsactl --ignore -f ${soundState} restore + # Try to restore the sound state. + ${alsaUtils}/sbin/alsactl --ignore init || true + ${alsaUtils}/sbin/alsactl --ignore -f ${soundState} restore || true ''; postStop = 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 242129c355e..373b482f85c 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 d8b5ee45c7e..4cb0e1cdf1d 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 e81ebd66004..14abe22a2da 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 18e72381cdc..a52d241e96c 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 2b7e4a8e44c..8c815ddf25f 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 ba970b95bc0..718566ee5b9 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 6eea947f604..cfbc7ba3679 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 373b482f85c..83b7b5372ec 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 54e661896d9..eecb845d547 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 f56ee4fc0d3..c5fa23b36bb 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 4cb0e1cdf1d..a7a7729bb8b 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 fbbbf72e027..a32bca8ddd7 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 c5fa23b36bb..95506712cac 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 a7a7729bb8b..bb2ea087c21 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 a52d241e96c..caf9a586eb1 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 caf9a586eb1..66bb722782a 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 66bb722782a..c34ae9037f2 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 a32bca8ddd7..57a532837f3 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 718566ee5b9..eeb26ee5e15 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 95506712cac..276197d24d8 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 bb2ea087c21..23751e2104a 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 57a532837f3..4fbf683c440 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 4fbf683c440..d6362a0e4ca 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 55e61ffb69a..f54404ddcce 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 fa63bc74cfc..ff08f21a485 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 76c736b609d..c7e0bc102f1 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 90987782f8c..cdd6414744a 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 8501d6a0979..9f85877e8bb 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 5818c9d6ceb..7a3d789327a 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 fb8bba93806..dc4fe9da470 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 c313de956fc..059b39cad5e 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 4f87f29f2e9..be4777356e4 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 84c39101bb6..2e98d50b0ce 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 059b39cad5e..12d61a8ea9f 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 f54404ddcce..8f1184a5eb3 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 d025276ea8e..7cd5cd3ddf8 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 c8e1a62749b..18bb4fb4d42 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 528b3a6f727..b94278d0b0d 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 6075bdb2673..7cf68db9ddc 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 b94278d0b0d..86a636c27c7 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 7cd5cd3ddf8..58f2610ce06 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 18bb4fb4d42..c48451bd5f5 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 263acb8f321..13ffbc7a51a 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 204980e9211..ac0c4059634 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 2002df6a303..57dc799ca8c 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 65f40826225..2f58a969492 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 83b7b5372ec..163616fdd18 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 c1ab8edce40..06c9f8efca7 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 907d83c7a6a..d7d0bbf89a5 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 23751e2104a..991e09058e8 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 276197d24d8..127ab7be3b9 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 991e09058e8..6603d6126b4 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 ff08f21a485..92d0cdd26f3 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 03234fbb82f..410a48152a9 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 4e79375ba1c..48c1c0be189 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 127ab7be3b9..46f2a705df8 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 6603d6126b4..268e81b1091 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 e6ae725f85f..7601fd1be43 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 46f2a705df8..2efea2fb9e1 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 268e81b1091..c166c1cbf03 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 6d31c0050aa..1e532f578a2 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 c166c1cbf03..31560a4dc17 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 a6fffce5bf4..c0499c9f94c 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 27e4ac400da..e62b05bd896 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 c0499c9f94c..65da0610b8f 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 31560a4dc17..c166c1cbf03 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 e62b05bd896..0fb4a95d30b 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 65da0610b8f..20e1a006675 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 f71e0ba5112..ec11f3604e7 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 e2526c398c7..5e68eb9e6b6 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 0fb4a95d30b..7bce11ab855 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 cfbc7ba3679..4f89f77b12b 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 d6362a0e4ca..9d17b352dc8 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 20e1a006675..8c2a3215f2a 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 2efea2fb9e1..239c837c676 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 c166c1cbf03..d88ac652ae0 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 4f89f77b12b..f2300a9529d 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 8a660b90581..130adb1110a 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 d88ac652ae0..0ccb30eb92f 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 8c2a3215f2a..7ef548a36b4 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 7ef548a36b4..5c984b9e59c 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 0ccb30eb92f..248dda60f59 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 14abe22a2da..8bc0b7531c0 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 6542b48c54e..2b26801f35f 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 248dda60f59..3de6220e6b9 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 5b20f657e12..776574bc016 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 8bc0b7531c0..6c321b23c7e 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 ffc0db1c7ea..c2bbf036af0 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 00000000000..b75e063eaa9 --- /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 776574bc016..84185ff3bbd 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 3de6220e6b9..2545eaf7393 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 84185ff3bbd..8a2f58d7dcd 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 6c321b23c7e..77a43ed15db 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 130adb1110a..4b6436a77f7 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 2b26801f35f..41487de9745 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 51654b164a0..9eefb8e686f 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 5e68eb9e6b6..10a36ede2a3 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 9eefb8e686f..ca825d7ab94 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 ca825d7ab94..441d30f1e9f 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 2545eaf7393..66cc048d9c0 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 9d17b352dc8..5761ed4c5a4 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 dd435d481b7..e964b9bfb1d 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 66cc048d9c0..dc0c2ba4504 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 aa708fb6019..7867b3c1912 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 41487de9745..b085778f099 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 c7e0bc102f1..d376bd404b9 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 7601fd1be43..d0119c56fce 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 3ea86d2f9cf..5fc06c341ad 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 5c984b9e59c..d36a1081de5 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 ee65991ed52..92839106762 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 3569cfa8113..c8ea322eb17 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 5761ed4c5a4..33f2775b496 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 4b9be460548..39359ac4293 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 049df0f9958..7293f207ed0 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 163616fdd18..90e0ea2f029 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 cccc6e62a15..33d97e0e07a 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 d29e0ff77c6..f1536f2eafa 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 8951e5bad1b..c0cd7cd1843 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 b38cd988b76..060dbb6082c 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 65542ae862e..09c51c1e19e 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 4a308416aef..a5f1a65a73d 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 5adbf3ce57d..24f390f24cb 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 7a3d789327a..734925989a3 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 0726a782250..3fd99da413c 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 b32ce233ec0..4c29fce29f2 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 b4dc014d68e..995e9bba603 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 5437d221c1e..8e3e86a515c 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 491d2de8f24..055733e456a 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 7c1ff5e9212..d5b6fc0a692 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 254996c2440..a35058a1992 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 060dbb6082c..316ee439b45 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 24f390f24cb..ca02fa137d4 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 fbd0adab2fa..796c300423d 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 f1536f2eafa..d95361dcd83 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 c0cd7cd1843..9e4ee2e0635 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 ed4b365b901..39e8883ee59 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 316ee439b45..de32b98e5d2 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 09c51c1e19e..7e63454dd70 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 a5f1a65a73d..29d675e180a 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 afdf1754942..f435d983791 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 0b81bc1d0de..d57512ebdfe 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 5ac7f0a5097..28a1187dd18 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 65785c8fdb5..b48850738b7 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 ca02fa137d4..e2f01e71b26 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 d5b6fc0a692..7c10eec310c 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 734925989a3..16757cf9098 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 4ee4eb02890..0d2bf153685 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 323b548de74..3b79c16ea2c 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 796c300423d..041cfdb29ae 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 dc4fe9da470..309da90c5df 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 3fd99da413c..c25276aa424 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 a35058a1992..335d9473704 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 90e0ea2f029..858261bd33e 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 41c3ced1bc2..8d9dcaa17c1 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 8f1184a5eb3..5168028c119 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 ce8e1843d4c..e5e27bb0c9a 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 57fc69b3270..085fb022c1c 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 33f2775b496..cfde1cc0753 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 66bbb757c70..89c4512095d 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 06c9f8efca7..1f25f2aa1e0 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 5d5777909e9..00000000000 --- 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 1e532f578a2..6d31c0050aa 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 5c4b8c3a9a1..123ef3c0256 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 123ef3c0256..5bbe3a00016 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 5bbe3a00016..fc9ba9a9280 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 f79962c1365..444d04564a9 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 77a43ed15db..774021d0d86 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 ec11f3604e7..e3927442821 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 239c837c676..5707fb6f87e 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 dc0c2ba4504..aa0b679ea2f 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 efce3153c88..222a10a0043 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 e2f01e71b26..7b03739a9bc 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 441d30f1e9f..135d99ec437 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 10a36ede2a3..3542b5f9fd4 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 ac0c4059634..3446654bc6f 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 f4c226ac349..641520ad98d 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 641520ad98d..2f6c6dba943 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 2f6c6dba943..bc44620d644 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 7e63454dd70..7952e295794 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 222a10a0043..c6c95e63af1 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 d376bd404b9..1f7533f22f8 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 aa0b679ea2f..2413509790d 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 cfde1cc0753..44e6e8bb63b 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 c6c95e63af1..8ceffbcb9ec 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 f2300a9529d..3abd77c8eeb 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 3abd77c8eeb..f9d588ea548 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 774021d0d86..66c97c5fd11 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 ab55e43405b..8e4a516ea13 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 2413509790d..6992299cc88 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 6992299cc88..340a6d80c1c 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 f9d588ea548..3abd77c8eeb 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 2f58a969492..3f005d6eb2d 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 c6b7df38fcf..b338e08113e 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 5168028c119..67a4e0ed16d 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 aacd0e99cb1..59f05bfd104 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 7bce11ab855..a7c41d915ec 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 3abd77c8eeb..6c8194f0971 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 d36a1081de5..412e62bfe80 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 3f005d6eb2d..6ca89dd7ac5 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 9e4ee2e0635..180da8267e0 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 7b03739a9bc..55d87ed4fa1 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 0a69ce0ecba..ed5348829c8 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 be4777356e4..96fc8a31dca 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 656f2a87403..47abac7fddd 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 18d11e2d402..ac8a3ccc238 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 66c97c5fd11..00d711eecd3 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 9ada2b176fe..da6f6d3afc9 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 ea4dbcc4dd4..2aa78aeadda 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 e3927442821..22e5017d7c0 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 f049c5eb348..8fe0030946a 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 86a636c27c7..396311be49e 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 340a6d80c1c..e76d35fa9f2 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 135d99ec437..f2b0ac46b06 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 f2b0ac46b06..9d52eeebf8e 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 8ceffbcb9ec..0ee3ad65a3d 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 7952e295794..ad126c128b5 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 ed5348829c8..8bde2f6e053 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 939bd30942d..4dfaa9f3b12 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 d7b8766143a..c3bbfd953f3 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 1eef2a9e84a..5393a88d5ff 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 ad126c128b5..8b695ae5a18 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 4e89770cce5..4d3d3db0861 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 0a9b374cc60..384865b867b 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 5e9f3b4efda..1d1958a8fe6 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 8b695ae5a18..dd52e817c1d 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 021986bc895..aa4066347b5 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 63c783f5c6d..32599554fc1 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 dd52e817c1d..9f89ad10021 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 384865b867b..70cfc87220c 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 1f25f2aa1e0..3f66ff917fd 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 00000000000..1dfea8ce96f --- /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 1dfea8ce96f..79f16f68c5c 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 eeb26ee5e15..5af2d19a839 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 4d3d3db0861..d1fdc5820b1 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 e21a34f996c..f7c22b98dd7 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 79f16f68c5c..a4bf0d1eb2a 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 211ff8a9609..d2db9ee993f 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 a4bf0d1eb2a..519fb62133c 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 e9f32a2662c..6849b3a7bc8 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 e76d35fa9f2..86e269e0763 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 412e62bfe80..64cb4a6749e 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 aa4066347b5..021986bc895 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 e5e27bb0c9a..9758bc8cb48 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 021986bc895..03979e259bf 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 720c8efc53f..eee65a3ffe0 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 4dfaa9f3b12..3dd1972c5f2 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 96fc8a31dca..8c0008771bb 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 23207babe3f..778e36cfd36 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 22e5017d7c0..982a6b6db45 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 8c0008771bb..c9d443441e3 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 467eac6e00e..ae5e5d5c49f 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 00000000000..48cf798c7f0 --- /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 982a6b6db45..8d50da8296c 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 c9d443441e3..33000a3fbf1 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 8d50da8296c..0367379b244 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 da6f6d3afc9..79fb435db38 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 2aa78aeadda..0ce5d218cdb 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 4b6436a77f7..3637378d4d1 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 eee65a3ffe0..ecd6b07c0ff 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 3dd1972c5f2..31613f08962 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 32e8717cbd1..3969be68098 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 940c596e367..32721205b99 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 2c35c13255e..ef29d563c72 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 c34ae9037f2..a013a3ccc3d 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 a37f1d38831..51fe37b7684 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 ac92c69f5bb..767696cfe55 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 79fb435db38..38885d12b35 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 a013a3ccc3d..c178a84b1b8 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 01665e277b6..66acf908710 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 d0fba23d625..00000000000 --- 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 c676d3e96e4..9e9e1c7dd8c 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 93c07df7cc6..aa75c4322a0 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 7e57f90398b..72a4495b1f5 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 593f2436a39..519c45a385a 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 eecb845d547..1843368ba27 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 ecd6b07c0ff..a65c95e60f9 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 519c45a385a..7d742df97b0 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 591f34ceee7..d8198dd0329 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 5707fb6f87e..e3f0ec6f1d9 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 a65c95e60f9..fbd28e6e836 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 b75e063eaa9..35c56e8c32b 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 fbd28e6e836..f0e94266b17 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 e3f0ec6f1d9..ad9b5da2316 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 f0e94266b17..f4d0655118e 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 8d9dcaa17c1..dc017563217 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 8fe0030946a..373195a9d68 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 49aa8e7931f..eaea8bd653a 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 942e7996da0..5322e1ff57d 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 2a0d73f6004..cf7f621a85d 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 21f81152fa5..8f898ce06a1 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 b085778f099..28ccc158f72 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 ad9b5da2316..1f8097ada1c 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 f4d0655118e..a0462951d00 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 5322e1ff57d..435326e87fb 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 64cb4a6749e..740c3b83cda 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 740c3b83cda..bbc357b1b29 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 bbc357b1b29..82f4d3da4f1 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 1c5a3f75039..6eec6f88b97 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 72a4495b1f5..48066856625 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 28ccc158f72..44cd261cf98 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 82f4d3da4f1..a002e2b68b2 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 00000000000..f73018279a5 --- /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 8bde2f6e053..55e23691ccb 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 b7e4c6315f9..9179911f248 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 f73018279a5..f1f99fb70ed 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 55e23691ccb..1c00dd37d33 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 9179911f248..ce4055a753c 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 00000000000..f9feadbc086 --- /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 2e98d50b0ce..1a172904c45 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 ac8a3ccc238..b131867966a 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 44cd261cf98..032947c3c54 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 a0462951d00..f72d15d0129 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 f72d15d0129..83911d179fd 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 67a4e0ed16d..0ad9982e430 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 ae5e5d5c49f..db54f5665a7 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 00000000000..c0493557d56 --- /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 d3f554c099e..e6edb30985c 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 ff19607844f..f18ca9f4c5c 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 4bd4b69101c..b18ff0512f2 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 f18ca9f4c5c..4d5c5994fc8 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 778e36cfd36..c1e46956f6e 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 4d5c5994fc8..2961f8e1233 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 3446654bc6f..593bd925b00 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 3637378d4d1..6cf9311e471 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 c1e46956f6e..9bcbe291aad 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 0ad9982e430..5447ce0c502 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 0ee3ad65a3d..108dcb0ab6d 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 8e3e86a515c..f82803e7519 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 cf7f621a85d..739ba95d5e3 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 b338e08113e..4f8ae55d209 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 d262f1f76cb..7bc09a7b404 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 e9b27268aa1..be3fcbd6543 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 6d31c0050aa..5a6b85810aa 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 6e6eaec1db9..66266e5b570 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 350d65b476a..cf348793a65 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 6eec6f88b97..599f8be226d 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 ceab6e11ece..2f4536184bc 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 ef33298f19e..378fe4e691d 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 378fe4e691d..ef33298f19e 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 ef33298f19e..e42f5ffe3b8 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 f9feadbc086..ea4028b6e9b 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 e9d04c49904..6908996db6c 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 c48451bd5f5..4da6cebcb94 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 8a2f58d7dcd..222c18d3e62 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 593bd925b00..0a2bfa80c47 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 43566bab22f..534137d4e09 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 519fb62133c..dd251fe69d3 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 92d0cdd26f3..ead53c3dc3a 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 9e9e1c7dd8c..887f1f0529f 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 ef29d563c72..7bf7a77aa85 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 51fe37b7684..37cab395677 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 c178a84b1b8..a33fdaab423 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 58f2610ce06..54f5d03de39 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 bc44620d644..b535a942a9e 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 8c815ddf25f..886669606b4 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 eaea8bd653a..a2ec899a593 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 435326e87fb..dc9fa85cf66 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 1a172904c45..108ed2911ce 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 12d61a8ea9f..c5cc8b4050d 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 c0493557d56..c6ab1ca0a3a 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 48066856625..07acab761d0 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 9758bc8cb48..229236c1bbd 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 085fb022c1c..df42071ebba 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 995e9bba603..ab8e77e2bad 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 aa75c4322a0..c4157c647c6 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 739ba95d5e3..533b719a667 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 7d742df97b0..07c35e3cb3d 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 12808e2ee27..4ea6fa135b0 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 f82803e7519..7180b2cfa14 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 8f898ce06a1..e9df8dd3cf6 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 a6544368ea0..4a9d9a77b57 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 1843368ba27..22f507f39d7 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 444d04564a9..f269de6fc2a 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 17a8c8216ca..35afacefa16 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 599f8be226d..2e6158bafa1 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 6cf9311e471..4776f4451f0 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 3fb9545b33f..23ddf6d0202 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 83911d179fd..80957cd1193 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 44e6e8bb63b..5d5139b7a57 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 00d711eecd3..8efc96f7fe4 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 055733e456a..3d5e1dd51f5 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 7867b3c1912..b0e222cd05e 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 a002e2b68b2..e8097e418c8 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 108dcb0ab6d..9c36ac2bbdd 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 33b8c1e516d..42c50d857e4 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 89c4512095d..757a20f6164 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 d558d2983cf..e1a338d6ad8 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 54f5d03de39..5d1658adb75 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 dc9fa85cf66..28045044601 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 533b719a667..342253bac29 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 d8198dd0329..0daa945c14a 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 4f8ae55d209..20752cdee25 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 396311be49e..1f842c0c953 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 08ae667211d..6a628ec124f 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 bc9aef101c7..9e8b9391f45 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 48c1c0be189..e99b50a0309 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 4776f4451f0..7744fd94a2c 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 b131867966a..9743703ffbe 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 80957cd1193..b7636702120 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 b0e222cd05e..e4d22e94c80 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 e8097e418c8..49dd47251e5 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 66acf908710..0b149610e32 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 0b149610e32..28a1d228293 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 319cdcb5f98..23e96171d1f 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 4c29fce29f2..6caf3b385b1 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 23e96171d1f..aa9557d9421 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 00000000000..76cec8d5dae --- /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 28a1d228293..b9272f31ac6 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 b25c15b81fa..e75fb319980 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 0daa945c14a..bd5ec4bd8f7 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 bd5ec4bd8f7..74d9992f770 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" ];