diff --git a/modules/config/power-management.nix b/modules/config/power-management.nix
new file mode 100644
index 00000000000..dd241e4e815
--- /dev/null
+++ b/modules/config/power-management.nix
@@ -0,0 +1,75 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+ cfg = config.powerManagement;
+
+ sleepHook = pkgs.writeScript "sleep-hook.sh"
+ ''
+ #! ${pkgs.stdenv.shell}
+ action="$1"
+ if [ "$action" = "resume" ]; then
+ ${cfg.resumeCommands}
+ ${cfg.powerUpCommands}
+ fi
+ '';
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ powerManagement = {
+
+ enable = mkOption {
+ default = false;
+ description =
+ ''
+ Whether to enable power management. This includes support
+ for suspend-to-RAM and powersave features on laptops.
+ '';
+ };
+
+ resumeCommands = mkOption {
+ default = "";
+ description = "Commands executed after the system resumes from suspend-to-RAM.";
+ };
+
+ powerUpCommands = mkOption {
+ default = "";
+ example = "${pkgs.hdparm}/sbin/hdparm -B 255 /dev/sda";
+ description =
+ ''
+ Commands executed when the machine powers up. That is,
+ they're executed both when the system first boots and when
+ it resumes from suspend or hibernation.
+ '';
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ # 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";
+ };
+
+ };
+
+}
diff --git a/modules/config/system-path.nix b/modules/config/system-path.nix
index c2605d0963e..50617ec91da 100644
--- a/modules/config/system-path.nix
+++ b/modules/config/system-path.nix
@@ -10,6 +10,7 @@ let
requiredPackages =
[ config.system.sbin.modprobe # must take precedence over module_init_tools
config.system.sbin.mount # must take precedence over util-linux
+ config.system.build.upstart
config.environment.nix
pkgs.acl
pkgs.attr
@@ -53,7 +54,6 @@ let
pkgs.sysvtools
pkgs.time
pkgs.udev
- pkgs.upstart
pkgs.usbutils
pkgs.utillinux
];
diff --git a/modules/installer/cd-dvd/installation-cd-base.nix b/modules/installer/cd-dvd/installation-cd-base.nix
index 3ec4f3a63de..0fb1156dc71 100644
--- a/modules/installer/cd-dvd/installation-cd-base.nix
+++ b/modules/installer/cd-dvd/installation-cd-base.nix
@@ -1,20 +1,22 @@
# This module contains the basic configuration for building a NixOS
# installation CD.
-{config, pkgs, ...}:
+{ config, pkgs, ... }:
+
+with pkgs.lib;
let
options = {
- system.nixosVersion = pkgs.lib.mkOption {
+ system.nixosVersion = mkOption {
default = "${builtins.readFile ../../../VERSION}";
description = ''
NixOS version number.
'';
};
- installer.configModule = pkgs.lib.mkOption {
+ installer.configModule = mkOption {
example = "./nixos/modules/installer/cd-dvd/installation-cd.nix";
description = ''
Filename of the configuration module that builds the CD
@@ -38,10 +40,12 @@ let
'';
# Put the current directory in a tarball.
- nixosTarball = makeTarball "nixos.tar.bz2" (pkgs.lib.cleanSource ../../..);
+ nixosTarball = makeTarball "nixos.tar.bz2" (cleanSource ../../..);
# Put Nixpkgs in a tarball.
- nixpkgsTarball = makeTarball "nixpkgs.tar.bz2" (pkgs.lib.cleanSource pkgs.path);
+ nixpkgsTarball = makeTarball "nixpkgs.tar.bz2" (cleanSource pkgs.path);
+
+ includeSources = true;
# A dummy /etc/nixos/configuration.nix in the booted CD that
@@ -169,12 +173,14 @@ in
# Provide the NixOS/Nixpkgs sources in /etc/nixos. This is required
# for nixos-install.
- echo "unpacking the NixOS/Nixpkgs sources..."
- mkdir -p /etc/nixos/nixos
- tar xjf ${nixosTarball}/nixos.tar.bz2 -C /etc/nixos/nixos
- mkdir -p /etc/nixos/nixpkgs
- tar xjf ${nixpkgsTarball}/nixpkgs.tar.bz2 -C /etc/nixos/nixpkgs
- chown -R root.root /etc/nixos
+ ${optionalString includeSources ''
+ echo "unpacking the NixOS/Nixpkgs sources..."
+ mkdir -p /etc/nixos/nixos
+ tar xjf ${nixosTarball}/nixos.tar.bz2 -C /etc/nixos/nixos
+ mkdir -p /etc/nixos/nixpkgs
+ tar xjf ${nixpkgsTarball}/nixpkgs.tar.bz2 -C /etc/nixos/nixpkgs
+ chown -R root.root /etc/nixos
+ ''}
# Provide a configuration for the CD/DVD itself, to allow users
# to run nixos-rebuild to change the configuration of the
diff --git a/modules/installer/cd-dvd/iso-image.nix b/modules/installer/cd-dvd/iso-image.nix
index 2a0ac4f0e28..6c1151ca217 100644
--- a/modules/installer/cd-dvd/iso-image.nix
+++ b/modules/installer/cd-dvd/iso-image.nix
@@ -2,20 +2,22 @@
# configuration. The derivation for the ISO image will be placed in
# config.system.build.isoImage.
-{config, pkgs, ...}:
+{ config, pkgs, ... }:
+
+with pkgs.lib;
let
options = {
- isoImage.isoName = pkgs.lib.mkOption {
+ isoImage.isoName = mkOption {
default = "cd.iso";
description = ''
Name of the generated ISO image file.
'';
};
- isoImage.compressImage = pkgs.lib.mkOption {
+ isoImage.compressImage = mkOption {
default = false;
description = ''
Whether the ISO image should be compressed using
@@ -23,7 +25,7 @@ let
'';
};
- isoImage.volumeID = pkgs.lib.mkOption {
+ isoImage.volumeID = mkOption {
default = "NIXOS_BOOT_CD";
description = ''
Specifies the label or volume ID of the generated ISO image.
@@ -32,7 +34,7 @@ let
'';
};
- isoImage.contents = pkgs.lib.mkOption {
+ isoImage.contents = mkOption {
example =
[ { source = pkgs.memtest86 + "/memtest.bin";
target = "boot/memtest.bin";
@@ -44,7 +46,7 @@ let
'';
};
- isoImage.storeContents = pkgs.lib.mkOption {
+ isoImage.storeContents = mkOption {
example = [pkgs.stdenv];
description = ''
This option lists additional derivations to be included in the
@@ -55,14 +57,38 @@ let
};
+ # The Grub image.
+ grubImage = pkgs.runCommand "grub_eltorito" {}
+ ''
+ ${pkgs.grub2}/bin/grub-mkimage -o tmp biosdisk iso9660 help linux linux16 sh chain gfxterm vbe png jpeg
+ cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
+ ''; # */
+
+
# The configuration file for Grub.
grubCfg =
''
- default 0
- timeout 10
- splashimage /boot/background.xpm.gz
+ set default=0
+ set timeout=10
- ${config.boot.extraGrubEntries}
+ if loadfont /boot/grub/unicode.pf2; then
+ set gfxmode=640x480
+ insmod gfxterm
+ insmod vbe
+ terminal_output.gfxterm
+
+ insmod png
+ if background_image /boot/grub/splash.png; then
+ set color_normal=white/black
+ set color_highlight=black/white
+ else
+ set menu_color_normal=cyan/blue
+ set menu_color_highlight=white/blue
+ fi
+
+ fi
+
+ ${config.boot.loader.grub.extraEntries}
'';
in
@@ -70,6 +96,17 @@ in
{
require = options;
+ boot.loader.grub.version = 2;
+
+ # Don't build the GRUB menu builder script, since we don't need it
+ # here and it causes a cyclic dependency.
+ boot.loader.grub.enable = false;
+
+ # !!! Hack - attributes expected by other modules.
+ system.build.menuBuilder = "true";
+ system.boot.loader.kernelFile = "vmlinuz";
+ environment.systemPackages = [ pkgs.grub2 ];
+
# In stage 1 of the boot, mount the CD/DVD as the root FS by label
# so that we don't need to know its device.
fileSystems =
@@ -86,7 +123,7 @@ in
# We need squashfs in the initrd to mount the compressed Nix store,
# and aufs to make the root filesystem appear writable.
- boot.extraModulePackages = (pkgs.lib.optional
+ boot.extraModulePackages = (optional
(! config.boot.kernelPackages.kernel.features ? aufs)
config.boot.kernelPackages.aufs);
boot.initrd.extraKernelModules = ["aufs" "squashfs"];
@@ -112,11 +149,11 @@ in
# Individual files to be included on the CD, outside of the Nix
# store on the CD.
isoImage.contents =
- [ { source = "${pkgs.grub}/lib/grub/${if pkgs.stdenv.system == "i686-linux" then "i386-pc" else "x86_64-unknown"}/stage2_eltorito";
- target = "/boot/grub/stage2_eltorito";
+ [ { source = grubImage;
+ target = "/boot/grub/grub_eltorito";
}
- { source = pkgs.writeText "menu.lst" grubCfg;
- target = "/boot/grub/menu.lst";
+ { source = pkgs.writeText "grub.cfg" grubCfg;
+ target = "/boot/grub/grub.cfg";
}
{ source = config.boot.kernelPackages.kernel + "/vmlinuz";
target = "/boot/vmlinuz";
@@ -124,8 +161,11 @@ in
{ source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
- { source = config.boot.grubSplashImage;
- target = "/boot/background.xpm.gz";
+ { source = "${pkgs.grub2}/share/grub/unicode.pf2";
+ target = "/boot/grub/unicode.pf2";
+ }
+ { source = config.boot.loader.grub.splashImage;
+ target = "/boot/grub/splash.png";
}
{ source = config.system.build.squashfsStore;
target = "/nix-store.squashfs";
@@ -134,31 +174,20 @@ in
source = pkgs.runCommand "empty" {} "ensureDir $out";
target = "/nix/store";
}
- { # Another quick hack: the kernel needs a systemConfig
- # parameter in menu.lst, but the system config depends on
- # menu.lst. Break the cyclic dependency by having a /system
- # symlink on the CD, and having menu.lst refer to /system.
- source = pkgs.runCommand "system" {}
- "ln -s ${config.system.build.toplevel} $out";
- target = "/system";
- }
- { # Idem for the stage-2 init script.
- source = pkgs.runCommand "system" {}
- "ln -s ${config.system.build.bootStage2} $out";
- target = "/init";
- }
];
# The Grub menu.
- boot.extraGrubEntries =
+ boot.loader.grub.extraEntries =
''
- title Boot from hard disk
- root (hd0)
+ menuentry "Boot from hard disk" {
+ set root=(hd0)
chainloader +1
+ }
- title NixOS Installer / Rescue
- kernel /boot/vmlinuz init=/init systemConfig=/system ${toString config.boot.kernelParams}
+ menuentry "NixOS Installer / Rescue" {
+ linux /boot/vmlinuz init=${config.system.build.bootStage2} systemConfig=${config.system.build.toplevel} ${toString config.boot.kernelParams}
initrd /boot/initrd
+ }
'';
# Create the ISO image.
@@ -168,7 +197,7 @@ in
inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = true;
- bootImage = "/boot/grub/stage2_eltorito";
+ bootImage = "/boot/grub/grub_eltorito";
};
boot.postBootCommands =
diff --git a/modules/installer/cd-dvd/memtest.nix b/modules/installer/cd-dvd/memtest.nix
index fb3aa817855..2ec35dcc8fb 100644
--- a/modules/installer/cd-dvd/memtest.nix
+++ b/modules/installer/cd-dvd/memtest.nix
@@ -10,10 +10,11 @@ let
in
{
- boot.extraGrubEntries =
+ boot.loader.grub.extraEntries =
''
- title Memtest86+
- kernel ${memtestPath}
+ menuentry "Memtest86+" {
+ linux16 ${memtestPath}
+ }
'';
isoImage.contents =
diff --git a/modules/installer/grub/grub.nix b/modules/installer/grub/grub.nix
index cb716a2a84e..9fe65a7bceb 100644
--- a/modules/installer/grub/grub.nix
+++ b/modules/installer/grub/grub.nix
@@ -98,10 +98,7 @@ in
sha256 = "14kqdx2lfqvh40h6fjjzqgff1mwk74dmbjvmqphi6azzra7z8d59";
}
# GRUB 1.97 doesn't support gzipped XPMs.
- else pkgs.fetchurl {
- url = http://www.gnu.org/graphics/winkler-gnu-blue.png;
- sha256 = "0y8fvxalwxyid4k438k7c21bnv728qjsb92rqfapsmpv2bcj7f6k";
- };
+ else ./winkler-gnu-blue-640x480.png;
example = null;
description = ''
Background image used for GRUB. It must be a 640x480,
diff --git a/modules/installer/grub/winkler-gnu-blue-640x480.png b/modules/installer/grub/winkler-gnu-blue-640x480.png
new file mode 100644
index 00000000000..35bbb57b51e
Binary files /dev/null and b/modules/installer/grub/winkler-gnu-blue-640x480.png differ
diff --git a/modules/installer/grub/winkler-gnu-blue.README b/modules/installer/grub/winkler-gnu-blue.README
new file mode 100644
index 00000000000..9616362dce2
--- /dev/null
+++ b/modules/installer/grub/winkler-gnu-blue.README
@@ -0,0 +1,6 @@
+This is a resized version of
+
+ http://www.gnu.org/graphics/winkler-gnu-blue.png
+
+by Kyle Winkler and released under the Free Art License
+(http://artlibre.org/licence.php/lalgb.html).
diff --git a/modules/module-list.nix b/modules/module-list.nix
index f6480537abf..f80d4d6a586 100644
--- a/modules/module-list.nix
+++ b/modules/module-list.nix
@@ -5,6 +5,7 @@
./config/networking.nix
./config/no-x-libs.nix
./config/nsswitch.nix
+ ./config/power-management.nix
./config/system-path.nix
./config/timezone.nix
./config/unix-odbc-drivers.nix
@@ -128,9 +129,9 @@
./system/boot/stage-1.nix
./system/boot/stage-2.nix
./system/etc/etc.nix
- ./system/upstart-events/ctrl-alt-delete.nix
- ./system/upstart-events/halt.nix
- ./system/upstart-events/maintenance-shell.nix
+ ./system/upstart-events/control-alt-delete.nix
+ ./system/upstart-events/runlevel.nix
+ ./system/upstart-events/shutdown.nix
./system/upstart/upstart.nix
./tasks/filesystems.nix
./tasks/kbd.nix
diff --git a/modules/services/audio/alsa.nix b/modules/services/audio/alsa.nix
index 5f463f8d8cd..78d6a004418 100644
--- a/modules/services/audio/alsa.nix
+++ b/modules/services/audio/alsa.nix
@@ -46,7 +46,7 @@ in
};
jobs.alsa =
- { startOn = "udev";
+ { startOn = "started udev";
preStart =
''
diff --git a/modules/services/audio/pulseaudio.nix b/modules/services/audio/pulseaudio.nix
index 5a8ffbd30a1..f48cdd49c83 100644
--- a/modules/services/audio/pulseaudio.nix
+++ b/modules/services/audio/pulseaudio.nix
@@ -66,7 +66,6 @@ in
{ description = "PulseAudio system-wide server";
startOn = "startup";
- stopOn = "shutdown";
preStart =
''
diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix
index 5d16ebe0af4..31d5676b8d7 100644
--- a/modules/services/databases/mysql.nix
+++ b/modules/services/databases/mysql.nix
@@ -55,7 +55,15 @@ in
default = "/var/run/mysql";
description = "Location of the file which stores the PID of the MySQL server";
};
-
+
+ initialDatabases = mkOption {
+ default = [];
+ description = "List of database names and their initial schemas that should be used to create databases on the first startup of MySQL";
+ example = [
+ { name = "foodatabase"; schema = ./foodatabase.sql; }
+ { name = "bardatabase"; schema = ./bardatabase.sql; }
+ ];
+ };
};
};
@@ -75,8 +83,7 @@ in
jobs.mysql =
{ description = "MySQL server";
- startOn = "filesystems";
- stopOn = "shutdown";
+ startOn = "started network-interfaces";
preStart =
''
@@ -90,14 +97,49 @@ in
chown -R ${cfg.user} ${cfg.pidDir}
'';
- exec = "${mysql}/bin/mysqld ${mysqldOptions}";
+ exec = "${mysql}/libexec/mysqld ${mysqldOptions}";
+
+ postStart =
+ ''
+ # Wait until the MySQL server is available for use
+ count=0
+ while [ ! -e /tmp/mysql.sock ]
+ do
+ if [ $count -eq 30 ]
+ then
+ echo "Tried 30 times, giving up..."
+ exit 1
+ fi
- postStop =
- ''
- pid=$(cat ${pidFile})
- kill "$pid"
- ${mysql}/bin/mysql_waitpid "$pid" 1000
- '';
+ echo "MySQL daemon not yet started. Waiting for 1 second..."
+ count=$((count++))
+ sleep 1
+ done
+
+ # Create initial databases
+
+ ${concatMapStrings (database:
+ ''
+ if ! test -e "${cfg.dataDir}/${database.name}"; then
+ echo "Creating initial database: ${database.name}"
+ ( echo "create database ${database.name};"
+ echo "use ${database.name};"
+ if [ -f "${database.schema}" ]
+ then
+ cat ${database.schema}
+ elif [ -d "${database.schema}" ]
+ then
+ cat ${database.schema}/mysql-databases/*.sql
+ fi
+ ) | ${mysql}/bin/mysql -u root -N
+ fi
+ '') cfg.initialDatabases}
+ '';
+
+ # !!! Need a postStart script to wait until mysqld is ready to
+ # accept connections.
+
+ extraConfig = "kill timeout 60";
};
};
diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix
index b463e39c725..1e96483662e 100644
--- a/modules/services/databases/postgresql.nix
+++ b/modules/services/databases/postgresql.nix
@@ -116,20 +116,40 @@ in
jobs.postgresql =
{ description = "PostgreSQL server";
- startOn = "${startDependency}/started";
- stopOn = "shutdown";
+ startOn = "started ${startDependency}";
+
+ environment =
+ { TZ = config.time.timeZone;
+ PGDATA = cfg.dataDir;
+ };
preStart =
''
+ # Initialise the database.
if ! test -e ${cfg.dataDir}; then
mkdir -m 0700 -p ${cfg.dataDir}
chown -R postgres ${cfg.dataDir}
- ${run} -c '${postgresql}/bin/initdb -D ${cfg.dataDir} -U root'
+ ${run} -c '${postgresql}/bin/initdb -U root'
fi
+
cp -f ${pkgs.writeText "pg_hba.conf" cfg.authentication} ${cfg.dataDir}/pg_hba.conf
+
+ # We'd like to use the `-w' flag here to wait until the
+ # database is up, but it requires a `postgres' user to
+ # exist. And we can't call `createuser' before the
+ # database is running.
+ ${run} -c '${postgresql}/bin/pg_ctl start -o "${toString flags}"'
+
+ # So wait until the server is running.
+ while ! ${run} -c '${postgresql}/bin/pg_ctl status'; do
+ sleep 1
+ done
'';
- exec = "${run} -c '${postgresql}/bin/postgres -D ${cfg.dataDir} ${toString flags}'";
+ postStop =
+ ''
+ ${run} -c '${postgresql}/bin/pg_ctl stop -m fast'
+ '';
};
};
diff --git a/modules/services/hardware/acpid.nix b/modules/services/hardware/acpid.nix
index ebb2f2a6a05..e9fd8e46dc9 100644
--- a/modules/services/hardware/acpid.nix
+++ b/modules/services/hardware/acpid.nix
@@ -60,11 +60,11 @@ in
options = {
- powerManagement = {
+ services.acpid = {
enable = mkOption {
default = false;
- description = "Whether to enable power management (ACPI daemon)";
+ description = "Whether to enable the ACPI daemon.";
};
};
@@ -74,13 +74,12 @@ in
###### implementation
- config = mkIf config.powerManagement.enable {
+ config = mkIf config.services.acpid.enable {
jobs.acpid =
{ description = "ACPI daemon";
- startOn = "udev";
- stopOn = "shutdown";
+ startOn = "started udev";
exec = "${pkgs.acpid}/sbin/acpid --foreground --confdir ${acpiConfDir}";
};
diff --git a/modules/services/hardware/hal.nix b/modules/services/hardware/hal.nix
index 11cda8d4cc4..25a24ce5e34 100644
--- a/modules/services/hardware/hal.nix
+++ b/modules/services/hardware/hal.nix
@@ -48,10 +48,9 @@ in
config = mkIf cfg.enable {
- # !!! move pmutils somewhere else
- environment.systemPackages = [hal pkgs.pmutils];
+ environment.systemPackages = [ hal ];
- services.hal.packages = [hal pkgs.hal_info];
+ services.hal.packages = [ hal pkgs.hal_info ];
users.extraUsers = singleton
{ name = "haldaemon";
@@ -67,10 +66,7 @@ in
jobs.hal =
{ description = "HAL daemon";
- # !!! TODO: make sure that HAL starts after acpid,
- # otherwise hald-addon-acpi will grab /proc/acpi/event.
- startOn = if config.powerManagement.enable then "acpid" else "dbus";
- stopOn = "shutdown";
+ startOn = "started dbus" + optionalString config.services.acpid.enable " and started acpid";
environment =
{ # !!! HACK? These environment variables manipulated inside
@@ -99,23 +95,14 @@ in
mkdir -m 0755 -p /var/run/hald
rm -f /var/cache/hald/fdi-cache
-
- # For some weird reason HAL sometimes fails to start at
- # boot time, which seems to be timing-dependent. As a
- # temporary workaround, sleep for a while here.
- sleep 2
-
- # !!! Hack: start the daemon here to make sure it's
- # running when the Upstart job reaches the "running"
- # state. Should be fixable in Upstart 0.6.
- ${hal}/sbin/hald --use-syslog # --verbose=yes
'';
- postStop =
- ''
- pid=$(cat /var/run/hald/pid || true)
- test -n "$pid" && kill "$pid"
- '';
+ 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];
@@ -125,4 +112,4 @@ in
};
-}
\ No newline at end of file
+}
diff --git a/modules/services/hardware/udev.nix b/modules/services/hardware/udev.nix
index 105f8a2b54f..798b9a4e381 100644
--- a/modules/services/hardware/udev.nix
+++ b/modules/services/hardware/udev.nix
@@ -159,7 +159,6 @@ in
jobs.udev =
{ startOn = "startup";
- stopOn = "shutdown";
environment = { UDEV_CONFIG_FILE = conf; };
@@ -169,9 +168,6 @@ in
mkdir -p /var/lib/udev/rules.d
- # Get rid of possible old udev processes.
- ${procps}/bin/pkill -u root "^udevd$" || true
-
# Do the loading of additional stage 2 kernel modules.
# Maybe this isn't the best place...
for i in ${toString config.boot.kernelModules}; do
@@ -179,32 +175,24 @@ in
${modprobe}/sbin/modprobe $i || true
done
- # Start udev.
mkdir -p /dev/.udev # !!! bug in udev?
- ${udev}/sbin/udevd --daemon
+ '';
+ daemonType = "fork";
+
+ exec = "${udev}/sbin/udevd --daemon";
+
+ postStart =
+ ''
# 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).
${udev}/sbin/udevadm trigger
${udev}/sbin/udevadm settle # wait for udev to finish
- # Kill udev, let Upstart restart and monitor it. (This is nasty,
- # but we have to run `udevadm trigger' first. Maybe we can use
- # Upstart's `binary' keyword, but it isn't implemented yet.)
- if ! ${procps}/bin/pkill -u root "^udevd$"; then
- echo "couldn't stop udevd"
- fi
-
- while ${procps}/bin/pgrep -u root "^udevd$"; do
- sleep 1
- done
-
- initctl emit new-devices
+ initctl emit -n new-devices
'';
-
- exec = "${udev}/sbin/udevd";
-
+
};
};
diff --git a/modules/services/logging/klogd.nix b/modules/services/logging/klogd.nix
index 0b2e3d9ddc7..2b8a6a64d99 100644
--- a/modules/services/logging/klogd.nix
+++ b/modules/services/logging/klogd.nix
@@ -2,28 +2,16 @@
###### implementation
-let
-
- klogdCmd = "${pkgs.sysklogd}/sbin/klogd -c 1 -2 -k $(dirname $(readlink -f /var/run/booted-system/kernel))/System.map";
-
-in
-
{
jobs.klogd =
{ description = "Kernel log daemon";
- startOn = "syslogd";
- stopOn = "shutdown";
+ startOn = "started syslogd";
- preStart =
- ''
- # !!! this hangs for some reason (it blocks reading from
- # /proc/kmsg).
- #${klogdCmd} -o
- '';
-
- exec = "${klogdCmd} -n";
+ exec =
+ "${pkgs.sysklogd}/sbin/klogd -c 1 -2 -n " +
+ "-k $(dirname $(readlink -f /var/run/booted-system/kernel))/System.map";
};
}
diff --git a/modules/services/logging/syslogd.nix b/modules/services/logging/syslogd.nix
index bc6b6eb4389..7c3e54cadb0 100644
--- a/modules/services/logging/syslogd.nix
+++ b/modules/services/logging/syslogd.nix
@@ -50,12 +50,13 @@ in
jobs.syslogd =
{ description = "Syslog daemon";
- startOn = "udev";
- stopOn = "shutdown";
+ startOn = "started udev";
environment = { TZ = config.time.timeZone; };
- exec = "${pkgs.sysklogd}/sbin/syslogd -n -f ${syslogConf}";
+ daemonType = "fork";
+
+ exec = "${pkgs.sysklogd}/sbin/syslogd -f ${syslogConf}";
};
};
diff --git a/modules/services/mail/dovecot.nix b/modules/services/mail/dovecot.nix
index 8ddbe5bfd7b..a41bd9eaad7 100644
--- a/modules/services/mail/dovecot.nix
+++ b/modules/services/mail/dovecot.nix
@@ -116,7 +116,7 @@ in
jobs.dovecot =
{ description = "Dovecot IMAP/POP3 server";
- startOn = "${startingDependency}/started";
+ startOn = "started ${startingDependency}";
preStart =
''
diff --git a/modules/services/mail/postfix.nix b/modules/services/mail/postfix.nix
index b5ed10d957b..ae85dd43f23 100644
--- a/modules/services/mail/postfix.nix
+++ b/modules/services/mail/postfix.nix
@@ -283,7 +283,7 @@ in
# accurate way is unlikely to be better.
{ description = "Postfix mail server";
- startOn = "${startingDependency}/started";
+ startOn = "started ${startingDependency}";
script =
''
diff --git a/modules/services/misc/autofs.nix b/modules/services/misc/autofs.nix
index b9936d0249d..079c684d086 100644
--- a/modules/services/misc/autofs.nix
+++ b/modules/services/misc/autofs.nix
@@ -75,8 +75,8 @@ in
jobs.autofs =
{ description = "Filesystem automounter";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
environment =
{ PATH = "${pkgs.nfsUtils}/sbin:${config.system.sbin.modprobe}/sbin";
diff --git a/modules/services/misc/disnix.nix b/modules/services/misc/disnix.nix
index 225762813ee..886c86e7fab 100644
--- a/modules/services/misc/disnix.nix
+++ b/modules/services/misc/disnix.nix
@@ -39,8 +39,7 @@ in
jobs.disnix =
{ description = "Disnix server";
- startOn = "dbus";
- stopOn = "shutdown";
+ startOn = "started dbus";
script =
''
diff --git a/modules/services/misc/gpsd.nix b/modules/services/misc/gpsd.nix
index 98feef68231..83cc6bae1d5 100644
--- a/modules/services/misc/gpsd.nix
+++ b/modules/services/misc/gpsd.nix
@@ -88,8 +88,8 @@ in
jobs.gpsd =
{ description = "GPSD daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
exec =
''
diff --git a/modules/services/misc/nixos-manual.nix b/modules/services/misc/nixos-manual.nix
index 04fc34c94fa..ed2972e5b5b 100644
--- a/modules/services/misc/nixos-manual.nix
+++ b/modules/services/misc/nixos-manual.nix
@@ -78,8 +78,7 @@ in
description = "NixOS manual";
- startOn = "udev";
- stopOn = "shutdown";
+ startOn = "started udev";
exec =
''
diff --git a/modules/services/misc/rogue.nix b/modules/services/misc/rogue.nix
index 43f43ae5bad..8760ce12510 100644
--- a/modules/services/misc/rogue.nix
+++ b/modules/services/misc/rogue.nix
@@ -43,8 +43,7 @@ in
jobs.rogue =
{ description = "Rogue dungeon crawling game";
- startOn = "udev";
- stopOn = "shutdown";
+ startOn = "started udev";
extraConfig = "chdir /root";
diff --git a/modules/services/misc/synergy.nix b/modules/services/misc/synergy.nix
index 72eaf640ea8..96616fa7a73 100644
--- a/modules/services/misc/synergy.nix
+++ b/modules/services/misc/synergy.nix
@@ -76,8 +76,8 @@ in
description = "Synergy client";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stopped";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
exec = "${pkgs.synergy}/bin/synergyc ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" }";
};
@@ -89,8 +89,8 @@ in
description = "Synergy server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stopped";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
exec =
''
diff --git a/modules/services/monitoring/nagios/default.nix b/modules/services/monitoring/nagios/default.nix
index 78e6a276fc8..6b1b3163d26 100644
--- a/modules/services/monitoring/nagios/default.nix
+++ b/modules/services/monitoring/nagios/default.nix
@@ -166,8 +166,8 @@ in
description = "Nagios monitoring daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/monitoring/zabbix-agent.nix b/modules/services/monitoring/zabbix-agent.nix
index 9fbcad78c68..3691405e1e2 100644
--- a/modules/services/monitoring/zabbix-agent.nix
+++ b/modules/services/monitoring/zabbix-agent.nix
@@ -69,8 +69,8 @@ in
description = "Zabbix agent daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/monitoring/zabbix-server.nix b/modules/services/monitoring/zabbix-server.nix
index 9b006ed8ec2..d38e955ed4f 100644
--- a/modules/services/monitoring/zabbix-server.nix
+++ b/modules/services/monitoring/zabbix-server.nix
@@ -56,8 +56,8 @@ in
description = "Zabbix server daemon";
- startOn = "postgresql";
- stopOn = "shutdown";
+ startOn = "started postgresql";
+ stopOn = "stopping postgresql";
preStart =
''
diff --git a/modules/services/network-filesystems/nfs-kernel.nix b/modules/services/network-filesystems/nfs-kernel.nix
index 1f67d584b89..2f6904457b2 100644
--- a/modules/services/network-filesystems/nfs-kernel.nix
+++ b/modules/services/network-filesystems/nfs-kernel.nix
@@ -81,8 +81,8 @@ in
description = "Kernel NFS server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
@@ -111,8 +111,8 @@ in
description = "Kernel NFS server";
- startOn = "nfs-kernel-exports/started";
- stopOn = "nfs-kernel-exports/stop";
+ startOn = "started nfs-kernel-exports";
+ stopOn = "stopping nfs-kernel-exports";
exec = "${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} ${builtins.toString cfg.nproc}";
};
@@ -122,8 +122,8 @@ in
description = "Kernel NFS server - mount daemon";
- startOn = "nfs-kernel-nfsd/started";
- stopOn = "nfs-kernel-exports/stop";
+ startOn = "started nfs-kernel-nfsd";
+ stopOn = "stopping nfs-kernel-exports";
exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -F -f ${exports}";
};
@@ -133,8 +133,8 @@ in
description = "Kernel NFS server - Network Status Monitor";
- startOn = "nfs-kernel-nfsd/started";
- stopOn = "nfs-kernel-exports/stop";
+ startOn = "started nfs-kernel-nfsd";
+ stopOn = "stopping nfs-kernel-exports";
preStart =
''
diff --git a/modules/services/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix
index 9b7937ac4a1..814ca7e2316 100644
--- a/modules/services/network-filesystems/samba.nix
+++ b/modules/services/network-filesystems/samba.nix
@@ -56,8 +56,8 @@ let
{ name = "samba-${appName}";
description = "Samba Service daemon ${appName}";
- startOn = "samba/started";
- stopOn = "samba-control/stop";
+ startOn = "started samba";
+ stopOn = "stopping samba-control";
exec = "${samba}/sbin/${appName} ${args}";
};
@@ -168,8 +168,8 @@ in
{ name = "samba";
description = "Samba server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart = setupScript;
};
diff --git a/modules/services/networking/avahi-daemon.nix b/modules/services/networking/avahi-daemon.nix
index f3033e8a408..82693c7399e 100644
--- a/modules/services/networking/avahi-daemon.nix
+++ b/modules/services/networking/avahi-daemon.nix
@@ -118,8 +118,8 @@ in
jobs.avahi_daemon =
{ name = "avahi-daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
script =
''
diff --git a/modules/services/networking/bitlbee.nix b/modules/services/networking/bitlbee.nix
index 2aa51603d05..f61227e0984 100644
--- a/modules/services/networking/bitlbee.nix
+++ b/modules/services/networking/bitlbee.nix
@@ -67,8 +67,8 @@ in
jobs.bitlbee =
{ description = "BitlBee IRC to other chat networks gateway";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/networking/ddclient.nix b/modules/services/networking/ddclient.nix
index b5bffa83cd7..575386c8579 100644
--- a/modules/services/networking/ddclient.nix
+++ b/modules/services/networking/ddclient.nix
@@ -114,7 +114,6 @@ in
{ name = "ddclient";
startOn = "startup";
- stopOn = "shutdown";
preStart =
''
diff --git a/modules/services/networking/dhclient.nix b/modules/services/networking/dhclient.nix
index 9696c8b14aa..a714562444e 100644
--- a/modules/services/networking/dhclient.nix
+++ b/modules/services/networking/dhclient.nix
@@ -26,13 +26,13 @@ let
# 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.
- ${pkgs.upstart}/sbin/initctl stop ntpd
+ ${config.system.build.upstart}/sbin/initctl stop ntpd
- ${pkgs.upstart}/sbin/initctl emit ip-up
+ ${config.system.build.upstart}/sbin/initctl emit -n ip-up
fi
if test "$reason" = EXPIRE -o "$reason" = RELEASE; then
- ${pkgs.upstart}/sbin/initctl emit ip-down
+ ${config.system.build.upstart}/sbin/initctl emit -n ip-down
fi
'';
@@ -62,8 +62,8 @@ in
config = mkIf config.networking.useDHCP {
jobs.dhclient =
- { startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ { startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
@@ -103,6 +103,22 @@ in
}
];
+ powerManagement.resumeCommands =
+ ''
+ export PATH=${config.system.build.upstart}/sbin:$PATH
+
+ restart() {
+ local job="$1"
+ if initctl status "$job" 2> /dev/null | grep -q 'running'; then
+ initctl stop "$job"
+ initctl start "$job"
+ fi
+ }
+
+ restart wpa_supplicant
+ restart dhclient
+ '';
+
};
}
diff --git a/modules/services/networking/dhcpd.nix b/modules/services/networking/dhcpd.nix
index 6daa0c073b8..43e0843cb97 100644
--- a/modules/services/networking/dhcpd.nix
+++ b/modules/services/networking/dhcpd.nix
@@ -111,8 +111,8 @@ in
jobs.dhcpd =
{ description = "DHCP server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
script =
''
diff --git a/modules/services/networking/ejabberd.nix b/modules/services/networking/ejabberd.nix
index 4dce0926364..b85dc26d2fc 100644
--- a/modules/services/networking/ejabberd.nix
+++ b/modules/services/networking/ejabberd.nix
@@ -41,6 +41,11 @@ in
description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas";
};
+ loadDumps = mkOption {
+ default = [];
+ description = "Configuration dump that should be loaded on the first startup";
+ example = [ ./myejabberd.dump ];
+ };
};
};
@@ -54,8 +59,12 @@ in
jobs.ejabberd =
{ description = "EJabberd server";
- startOn = "network-interface/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
+
+ environment = {
+ PATH = "$PATH:${pkgs.ejabberd}/sbin:${pkgs.ejabberd}/bin:${pkgs.coreutils}/bin:${pkgs.bash}/bin:${pkgs.gnused}/bin";
+ };
preStart =
''
@@ -64,6 +73,7 @@ in
if ! test -d ${cfg.spoolDir}
then
+ initialize=1
cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib
fi
@@ -73,13 +83,50 @@ in
cp ${pkgs.ejabberd}/etc/ejabberd/* ${cfg.confDir}
sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg
fi
- '';
+
+ ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} start
+
+ ${if cfg.loadDumps == [] then "" else
+ ''
+ if [ "$initialize" = "1" ]
+ then
+ # Wait until the ejabberd server is available for use
+ count=0
+ while ! ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} status
+ do
+ if [ $count -eq 30 ]
+ then
+ echo "Tried 30 times, giving up..."
+ exit 1
+ fi
- exec = "${pkgs.bash}/bin/sh -c 'export PATH=$PATH:${pkgs.ejabberd}/sbin:${pkgs.coreutils}/bin:${pkgs.bash}/bin; ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} start; sleep 1d'";
+ echo "Ejabberd daemon not yet started. Waiting for 1 second..."
+ count=$((count++))
+ sleep 1
+ done
+
+ ${concatMapStrings (dump:
+ ''
+ echo "Importing dump: ${dump}"
+
+ if [ -f ${dump} ]
+ then
+ ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} load ${dump}
+ elif [ -d ${dump} ]
+ then
+ for i in ${dump}/ejabberd-dump/*
+ do
+ ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} load $i
+ done
+ fi
+ '') cfg.loadDumps}
+ fi
+ ''}
+ '';
postStop =
''
- ${pkgs.ejabberd}/sbin/ejabberdctl stop
+ ejabberdctl --config-dir ${cfg.confDir} --logs ${cfg.logsDir} --spool ${cfg.spoolDir} stop
'';
};
diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix
index 0b8a8d93061..28c43ef3370 100644
--- a/modules/services/networking/firewall.nix
+++ b/modules/services/networking/firewall.nix
@@ -79,7 +79,7 @@ in
environment.systemPackages = [pkgs.iptables];
jobs.firewall =
- { startOn = "network-interfaces/started";
+ { startOn = "started network-interfaces";
preStart =
''
diff --git a/modules/services/networking/gnunet.nix b/modules/services/networking/gnunet.nix
index e35dfbcd1a8..53223f1df22 100644
--- a/modules/services/networking/gnunet.nix
+++ b/modules/services/networking/gnunet.nix
@@ -194,8 +194,8 @@ in
jobs.gnunetd =
{ description = "The GNUnet Daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/networking/gvpe.nix b/modules/services/networking/gvpe.nix
index 72b45df26af..102de2bca2d 100644
--- a/modules/services/networking/gvpe.nix
+++ b/modules/services/networking/gvpe.nix
@@ -56,13 +56,13 @@ in
'';
};
startOn = mkOption {
- default = "network-interfaces/started";
+ default = "started network-interfaces";
description = ''
Condition to start GVPE
'';
};
stopOn = mkOption {
- default = "network-interfaces/stop";
+ default = "stopping network-interfaces";
description = ''
Condition to stop GVPE
'';
diff --git a/modules/services/networking/gw6c.nix b/modules/services/networking/gw6c.nix
index 143fe57979a..eaf84c5f70f 100644
--- a/modules/services/networking/gw6c.nix
+++ b/modules/services/networking/gw6c.nix
@@ -6,10 +6,12 @@ let
cfg = config.services.gw6c;
+ # !!! Move this from the services tree to the nixos tree.
gw6cService = import (servicesPath + /gw6c) {
inherit (pkgs) stdenv gw6c coreutils
- procps upstart iputils gnused
+ procps iputils gnused
gnugrep seccure writeScript;
+ upstart = config.system.build.upstart;
username = cfg.username;
password = cfg.password;
server = cfg.server;
@@ -132,8 +134,8 @@ in
jobs.gw6c =
{ description = "Gateway6 client";
- startOn = if cfg.autorun then "network-interfaces/started" else "";
- stopOn = "network-interfaces/stop";
+ startOn = if cfg.autorun then "started network-interfaces" else "";
+ stopOn = "stopping network-interfaces";
exec = "${gw6cService}/bin/control start";
};
diff --git a/modules/services/networking/ifplugd.nix b/modules/services/networking/ifplugd.nix
index 85eda29f5a2..6ec71849ca3 100644
--- a/modules/services/networking/ifplugd.nix
+++ b/modules/services/networking/ifplugd.nix
@@ -16,7 +16,6 @@ let
#! ${pkgs.stdenv.shell}
if test "$2" = up; then
initctl stop dhclient
- sleep 1
initctl start dhclient
fi
'';
@@ -58,8 +57,8 @@ in
jobs.ifplugd =
{ description = "Network interface connectivity monitor";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
exec =
''
diff --git a/modules/services/networking/ircd-hybrid.nix b/modules/services/networking/ircd-hybrid.nix
index aea5fbd6550..34c3b13d82d 100644
--- a/modules/services/networking/ircd-hybrid.nix
+++ b/modules/services/networking/ircd-hybrid.nix
@@ -122,8 +122,8 @@ in
description = "IRCD Hybrid server";
- startOn = "${startingDependency}/started";
- stopOn = "${startingDependency}/stop";
+ startOn = "started ${startingDependency}";
+ stopOn = "stopping ${startingDependency}";
exec = "${ircdService}/bin/control start";
};
diff --git a/modules/services/networking/ntpd.nix b/modules/services/networking/ntpd.nix
index 159c8022442..eaf5b5532ac 100644
--- a/modules/services/networking/ntpd.nix
+++ b/modules/services/networking/ntpd.nix
@@ -82,7 +82,7 @@ in
chown ${ntpUser} ${stateDir}
# Needed to run ntpd as an unprivileged user.
- ${modprobe}/sbin/modprobe capability || true
+ ${modprobe}/sbin/modprobe --quiet capability || true
# !!! This can hang indefinitely if the network is down or
# the servers are unreachable. This is particularly bad
diff --git a/modules/services/networking/openfire.nix b/modules/services/networking/openfire.nix
index 67e2558b22a..a46b4fa4294 100644
--- a/modules/services/networking/openfire.nix
+++ b/modules/services/networking/openfire.nix
@@ -52,8 +52,7 @@ in
jobs.openfire =
{ description = "OpenFire XMPP server";
- startOn = "${startDependency}/started";
- stopOn = "shutdown";
+ startOn = "started ${startDependency}";
script =
''
diff --git a/modules/services/networking/portmap.nix b/modules/services/networking/portmap.nix
index 0fcbf63d799..5a51836efad 100644
--- a/modules/services/networking/portmap.nix
+++ b/modules/services/networking/portmap.nix
@@ -66,8 +66,8 @@ in
jobs.portmap =
{ description = "ONC RPC portmap";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
exec =
''
diff --git a/modules/services/networking/privoxy.nix b/modules/services/networking/privoxy.nix
index f2350f4c462..eee020a1f0e 100644
--- a/modules/services/networking/privoxy.nix
+++ b/modules/services/networking/privoxy.nix
@@ -81,7 +81,6 @@ in
{ name = "privoxy";
startOn = "startup";
- stopOn = "shutdown";
preStart =
''
diff --git a/modules/services/networking/ssh/lshd.nix b/modules/services/networking/ssh/lshd.nix
index c3a14ba17e8..f5d52c82101 100644
--- a/modules/services/networking/ssh/lshd.nix
+++ b/modules/services/networking/ssh/lshd.nix
@@ -119,8 +119,8 @@ in
jobs.lshd =
{ description = "GNU lshd SSH2 daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
environment =
{ LD_LIBRARY_PATH = config.system.nssModules.path; };
diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix
index 8c18a560748..87cb942f2f9 100644
--- a/modules/services/networking/ssh/sshd.nix
+++ b/modules/services/networking/ssh/sshd.nix
@@ -112,8 +112,7 @@ in
description = "OpenSSH server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
environment = { LD_LIBRARY_PATH = nssModulesPath; };
@@ -126,7 +125,9 @@ in
fi
'';
- exec = "${openssh}/sbin/sshd -D -h /etc/ssh/ssh_host_dsa_key -f ${sshdConfig}";
+ daemonType = "fork";
+
+ exec = "${openssh}/sbin/sshd -h /etc/ssh/ssh_host_dsa_key -f ${sshdConfig}";
};
networking.firewall.allowedTCPPorts = [22];
diff --git a/modules/services/networking/vsftpd.nix b/modules/services/networking/vsftpd.nix
index b98a9aa3f7d..4c6b6f411cd 100644
--- a/modules/services/networking/vsftpd.nix
+++ b/modules/services/networking/vsftpd.nix
@@ -102,8 +102,8 @@ in
jobs.vsftpd =
{ description = "vsftpd server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/networking/wpa_supplicant.nix b/modules/services/networking/wpa_supplicant.nix
index 37b5923421f..93450f8eac1 100644
--- a/modules/services/networking/wpa_supplicant.nix
+++ b/modules/services/networking/wpa_supplicant.nix
@@ -38,8 +38,8 @@ in
environment.systemPackages = [pkgs.wpa_supplicant];
jobs.wpa_supplicant =
- { startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ { startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/networking/xinetd.nix b/modules/services/networking/xinetd.nix
index be9e5712e7d..4729ba9d2e4 100644
--- a/modules/services/networking/xinetd.nix
+++ b/modules/services/networking/xinetd.nix
@@ -122,8 +122,8 @@ in
jobs.xinetd =
{ description = "xinetd server";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
exec = "${xinetd}/sbin/xinetd -syslog daemon -dontfork -stayalive -f ${configFile}";
};
diff --git a/modules/services/printing/cupsd.nix b/modules/services/printing/cupsd.nix
index 149055d74c5..546eb7be396 100644
--- a/modules/services/printing/cupsd.nix
+++ b/modules/services/printing/cupsd.nix
@@ -160,8 +160,8 @@ in
jobs.cupsd =
{ description = "CUPS printing daemon";
- startOn = "network-interfaces/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
diff --git a/modules/services/scheduling/atd.nix b/modules/services/scheduling/atd.nix
index fb579dbf0b2..19fda42928a 100644
--- a/modules/services/scheduling/atd.nix
+++ b/modules/services/scheduling/atd.nix
@@ -67,7 +67,6 @@ in
{ description = "at daemon (atd)";
startOn = "startup";
- stopOn = "shutdown";
preStart =
''
@@ -97,12 +96,12 @@ in
chown atd:atd "$jobdir"/.SEQ && \
chmod 600 "$jobdir"/.SEQ
fi
-
- # `atd' doesn't have a no-fork flag, so start it here. !!!
- # Fix this once we have Upstart 0.6.
- ${at}/sbin/atd
'';
+ daemonType = "fork";
+
+ exec = "${at}/sbin/atd";
+
postStop =
''
test -e /var/run/atd.pid && kill $(cat /var/run/atd.pid)
diff --git a/modules/services/scheduling/cron.nix b/modules/services/scheduling/cron.nix
index 8408fe6e003..478a9800c77 100644
--- a/modules/services/scheduling/cron.nix
+++ b/modules/services/scheduling/cron.nix
@@ -70,7 +70,6 @@ in
{ description = "Cron daemon";
startOn = "startup";
- stopOn = "shutdown";
# Needed to interpret times in the local timezone.
environment = { TZ = config.time.timeZone; };
diff --git a/modules/services/scheduling/fcron.nix b/modules/services/scheduling/fcron.nix
index b38a70b932a..fbd1288a55f 100644
--- a/modules/services/scheduling/fcron.nix
+++ b/modules/services/scheduling/fcron.nix
@@ -101,7 +101,6 @@ in
{ description = "fcron daemon";
startOn = "startup";
- stopOn = "shutdown";
environment =
{ PATH = "/var/run/current-system/sw/bin";
diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix
index 8e1d9bd4d10..b0c8dc66ae5 100644
--- a/modules/services/system/dbus.nix
+++ b/modules/services/system/dbus.nix
@@ -113,8 +113,7 @@ in
};
jobs.dbus =
- { startOn = "udev";
- stopOn = "shutdown";
+ { startOn = "started udev";
preStart =
''
@@ -125,24 +124,19 @@ in
${dbus.tools}/bin/dbus-uuidgen --ensure
rm -f ${homeDir}/pid
- # !!! hack - dbus should be running once this job is
- # considered "running"; should be fixable once we have
- # Upstart 0.6.
- ${dbus}/bin/dbus-daemon --config-file=${configDir}/system.conf
'';
+ daemonType = "fork";
+
+ exec = "${dbus}/bin/dbus-daemon --config-file=${configDir}/system.conf";
+
postStop =
''
- pid=$(cat ${homeDir}/pid)
- if test -n "$pid"; then
- kill $pid
- fi
-
# !!! Hack: doesn't belong here.
- pid=$(cat /var/run/ConsoleKit/pid)
+ pid=$(cat /var/run/ConsoleKit/pid || true)
if test -n "$pid"; then
- kill $pid
- rm /var/run/ConsoleKit/pid
+ kill $pid || true
+ rm -f /var/run/ConsoleKit/pid
fi
'';
};
diff --git a/modules/services/system/nscd.nix b/modules/services/system/nscd.nix
index a14215c70d1..1e3a4ff75c9 100644
--- a/modules/services/system/nscd.nix
+++ b/modules/services/system/nscd.nix
@@ -21,7 +21,6 @@ in
{ description = "Name Service Cache Daemon";
startOn = "startup";
- stopOn = "shutdown";
environment = { LD_LIBRARY_PATH = nssModulesPath; };
diff --git a/modules/services/system/uptimed.nix b/modules/services/system/uptimed.nix
index 3749358ac20..fd4c1652bd3 100644
--- a/modules/services/system/uptimed.nix
+++ b/modules/services/system/uptimed.nix
@@ -53,7 +53,6 @@ in
{ description = "Uptimed daemon";
startOn = "startup";
- stopOn = "shutdown";
preStart =
''
diff --git a/modules/services/ttys/gpm.nix b/modules/services/ttys/gpm.nix
index 026ed4a299f..256fe8d2380 100644
--- a/modules/services/ttys/gpm.nix
+++ b/modules/services/ttys/gpm.nix
@@ -41,8 +41,7 @@ in
jobs.gpm =
{ description = "General purpose mouse";
- startOn = "udev";
- stopOn = "shutdown";
+ startOn = "started udev";
exec = "${pkgs.gpm}/sbin/gpm -m /dev/input/mice -t ${cfg.protocol} -D &>/dev/null";
};
diff --git a/modules/services/ttys/mingetty.nix b/modules/services/ttys/mingetty.nix
index 6c793ffa112..5f6b1d0f14c 100644
--- a/modules/services/ttys/mingetty.nix
+++ b/modules/services/ttys/mingetty.nix
@@ -55,7 +55,7 @@ with pkgs.lib;
# Generate a separate job for each tty.
jobs = listToAttrs (map (tty: nameValuePair tty {
- startOn = "udev";
+ startOn = "started udev";
exec = "${pkgs.mingetty}/sbin/mingetty --loginprog=${pkgs.pam_login}/bin/login --noclear ${tty}";
diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix
index 55902f9e5e0..c70d99db964 100644
--- a/modules/services/web-servers/apache-httpd/default.nix
+++ b/modules/services/web-servers/apache-httpd/default.nix
@@ -582,8 +582,7 @@ in
description = "Apache HTTPD";
- startOn = "${startingDependency}/started";
- stopOn = "shutdown";
+ startOn = "started ${startingDependency}";
environment =
{ # !!! This should be added in test-instrumentation.nix. It
@@ -613,7 +612,14 @@ in
done
'';
- exec = "${httpd}/bin/httpd -f ${httpdConf} -DNO_DETACH";
+ daemonType = "fork";
+
+ exec = "${httpd}/bin/httpd -f ${httpdConf}";
+
+ preStop =
+ ''
+ ${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop
+ '';
};
};
diff --git a/modules/services/web-servers/tomcat.nix b/modules/services/web-servers/tomcat.nix
index 331653ba929..ef569a8fedf 100644
--- a/modules/services/web-servers/tomcat.nix
+++ b/modules/services/web-servers/tomcat.nix
@@ -100,12 +100,12 @@ in
description = "Tomcat user";
home = "/homeless-shelter";
};
-
+
jobs.tomcat =
{ description = "Apache Tomcat server";
- startOn = "network-interface/started";
- stopOn = "network-interfaces/stop";
+ startOn = "started network-interfaces";
+ stopOn = "stopping network-interfaces";
preStart =
''
@@ -215,6 +215,7 @@ in
then
for j in $i/conf/Catalina/*
do
+ mkdir -p ${cfg.baseDir}/conf/Catalina/localhost
ln -sfn $j ${cfg.baseDir}/conf/Catalina/localhost/`basename $j`
done
fi
@@ -251,6 +252,7 @@ in
then
for j in $i/conf/Catalina/*
do
+ mkdir -p ${cfg.baseDir}/conf/Catalina/${virtualHost.name}
ln -sfn $j ${cfg.baseDir}/conf/Catalina/${virtualHost.name}/`basename $j`
done
fi
@@ -304,13 +306,10 @@ in
done
''
else ""}
- ''; # */
- exec =
- ''
- ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${pkgs.tomcat6}/bin/startup.sh; sleep 1000d'
+ ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${pkgs.tomcat6}/bin/startup.sh'
'';
-
+
postStop =
''
echo "Stopping tomcat..."
diff --git a/modules/services/x11/display-managers/kdm.nix b/modules/services/x11/display-managers/kdm.nix
index 349fd19adfe..18a6623eb85 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=${pkgs.upstart}/sbin/halt
- RebootCmd=${pkgs.upstart}/sbin/reboot
+ HaltCmd=${config.system.build.upstart}/sbin/halt
+ RebootCmd=${config.system.build.upstart}/sbin/reboot
${optionalString (config.system.boot.loader.id == "grub") ''
BootManager=Grub
''}
@@ -26,6 +26,8 @@ let
[X-:*-Core]
ServerCmd=${dmcfg.xserverBin} ${dmcfg.xserverArgs}
+ # The default timeout (15) is too short in a heavily loaded boot process.
+ ServerTimeout=60
# Needed to prevent the X server from dying on logout and not coming back:
TerminateServer=true
diff --git a/modules/services/x11/display-managers/slim.nix b/modules/services/x11/display-managers/slim.nix
index af15e0df5e6..ad767e199a1 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.bash}/bin/sh ${dmcfg.session.script} "%session"
- halt_cmd ${pkgs.upstart}/sbin/shutdown -h now
- reboot_cmd ${pkgs.upstart}/sbin/shutdown -r now
+ halt_cmd ${config.system.build.upstart}/sbin/shutdown -h now
+ reboot_cmd ${config.system.build.upstart}/sbin/shutdown -r now
${if cfg.defaultUser != "" then "default_user " + cfg.defaultUser else ""}
${if cfg.hideCursor then "hidecursor true" else ""}
'';
diff --git a/modules/services/x11/xfs.nix b/modules/services/x11/xfs.nix
index 860d5823be3..f2b7108debc 100644
--- a/modules/services/x11/xfs.nix
+++ b/modules/services/x11/xfs.nix
@@ -43,8 +43,7 @@ in
jobs.xfs =
{ description = "X Font Server";
- startOn = "${startingDependency}/started";
- stopOn = "shutdown";
+ startOn = "started ${startingDependency}";
exec = "${pkgs.xorg.xfs}/bin/xfs -config ${configFile}";
};
diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix
index 3afad9d7615..4ceb5579533 100644
--- a/modules/services/x11/xserver.nix
+++ b/modules/services/x11/xserver.nix
@@ -385,7 +385,7 @@ in
optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions;
jobs.xserver =
- { startOn = if cfg.autorun then "hal" else "never";
+ { startOn = if cfg.autorun then "started udev and started hal" else "";
environment =
{ FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup
@@ -401,14 +401,6 @@ in
preStart =
''
- # Ugly hack: wait until udev has started since the X server
- # needs various devices. This would more properly be
- # expressed as an Upstart dependency, but AFAIK in "start
- # on" we can't express a logical AND.
- while ! initctl status udev 2>&1 | grep -q running; do
- sleep 1
- done
-
rm -f /var/run/opengl-driver
${# !!! The OpenGL driver depends on what's detected at runtime.
if elem "nvidia" driverNames then ''
diff --git a/modules/system/activation/activation-script.nix b/modules/system/activation/activation-script.nix
index a62120363f2..df3806b834b 100644
--- a/modules/system/activation/activation-script.nix
+++ b/modules/system/activation/activation-script.nix
@@ -84,6 +84,16 @@ let
mkdir -m 0755 -p /var/run/nix/current-load # for distributed builds
mkdir -m 0700 -p /var/run/nix/remote-stores
+ # Use a tmpfs for /var/run/nscd to ensure that / or /var can be
+ # unmounted or at least remounted read-only during shutdown.
+ # (Upstart 0.6 apparently uses nscd to do some name lookups,
+ # resulting in it holding some mmap mapping to deleted files in
+ # /var/run/nscd.)
+ if [ ! -e /var/run/nscd ]; then
+ mkdir -p /var/run/nscd
+ ${pkgs.utillinux}/bin/mount -t tmpfs -o "mode=755" none /var/run/nscd
+ fi
+
mkdir -m 0755 -p /var/log
touch /var/log/wtmp # must exist
diff --git a/modules/system/activation/switch-to-configuration.sh b/modules/system/activation/switch-to-configuration.sh
index 802b57a31af..18a0664daa7 100644
--- a/modules/system/activation/switch-to-configuration.sh
+++ b/modules/system/activation/switch-to-configuration.sh
@@ -54,27 +54,24 @@ EOF
exit 1
fi
- oldEvents=$(readlink -f /etc/event.d || true)
- newEvents=$(readlink -f @out@/etc/event.d)
+ oldJobs=$(readlink -f /etc/static/init)
+ newJobs=$(readlink -f @out@/etc/init)
- #echo "old: $oldEvents"
- #echo "new: $newEvents"
+ echo "old: $oldJobs"
+ echo "new: $newJobs"
stopJob() {
local job=$1
- initctl stop "$job"
- while ! initctl status "$job" 2>&1 | grep -q "(stop) waiting"; do
- echo "waiting for $job to stop..."
- sleep 1
- done
+ initctl stop "$job" || true
}
# Stop all services that are not in the new Upstart
# configuration.
- for event in $(cd $oldEvents && ls); do
- if ! test -e "$newEvents/$event"; then
- echo "stopping $event..."
- stopJob $event
+ for job in $(cd $oldJobs && ls *.conf); do
+ job=$(basename $job .conf)
+ if ! test -e "$newJobs/$job.conf"; then
+ echo "stopping $job..."
+ stopJob $job
fi
done
@@ -83,26 +80,27 @@ EOF
echo "activating the configuration..."
@out@/activate @out@
- # Make Upstart reload its events. !!! Should wait until it has
- # finished processing its stop events.
- kill -TERM 1
+ # Make Upstart reload its jobs.
+ initctl reload-configuration
# Start all new services and restart all changed services.
- for event in $(cd $newEvents && ls); do
+ for job in $(cd $newJobs && ls *.conf); do
- # Hack: skip the sys-* and ctrl-alt-delete events.
+ job=$(basename $job .conf)
+
+ # Hack: skip the shutdown and control-alt-delete jobs.
# Another hack: don't restart the X server (that would kill all the clients).
# And don't restart dbus, since that causes ConsoleKit to
# forget about current sessions.
- if echo "$event" | grep -q "^sys-\|^ctrl-\|^xserver$\|^dbus$"; then continue; fi
-
- if ! test -e "$oldEvents/$event"; then
- echo "starting $event..."
- initctl start "$event"
- elif test "$(readlink "$oldEvents/$event")" != "$(readlink "$newEvents/$event")"; then
- echo "restarting $event..."
- stopJob $event
- initctl start "$event"
+ if echo "$job" | grep -q "^shutdown$\|^control-alt-delete$\|^xserver$\|^dbus$"; then continue; fi
+
+ if ! test -e "$oldJobs/$job.conf"; then
+ echo "starting $job..."
+ initctl start "$job" || true
+ elif test "$(readlink "$oldJobs/$job.conf")" != "$(readlink "$newJobs/$job.conf")"; then
+ echo "restarting $job..."
+ stopJob $job
+ initctl start "$job" || true
fi
done
fi
diff --git a/modules/system/activation/top-level.nix b/modules/system/activation/top-level.nix
index bb1cacfa78a..1d1fef29902 100644
--- a/modules/system/activation/top-level.nix
+++ b/modules/system/activation/top-level.nix
@@ -76,11 +76,11 @@ let
ln -s ${config.system.activationScripts.script} $out/activate
ln -s ${config.system.build.etc}/etc $out/etc
ln -s ${config.system.path} $out/sw
- ln -s ${pkgs.upstart} $out/upstart
+ ln -s ${config.system.build.upstart} $out/upstart
echo "$kernelParams" > $out/kernel-params
echo "$configurationName" > $out/configuration-name
- echo "${toString pkgs.upstart.interfaceVersion}" > $out/upstart-interface-version
+ echo "${toString config.system.build.upstart.interfaceVersion}" > $out/upstart-interface-version
mkdir $out/fine-tune
childCount=0;
@@ -114,7 +114,7 @@ let
pkgs.gnugrep
pkgs.findutils
pkgs.diffutils
- pkgs.upstart # for initctl
+ config.system.build.upstart # for initctl
];
# Boot loaders
diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh
index 58bf218428b..182fe7e98e1 100644
--- a/modules/system/boot/stage-1-init.sh
+++ b/modules/system/boot/stage-1-init.sh
@@ -39,7 +39,7 @@ trap 'fail' ERR
# Print a greeting.
echo
-echo "<<< NixOS Stage 1 >>>"
+echo "[1;32m<<< NixOS Stage 1 >>>[0m"
echo
diff --git a/modules/system/boot/stage-2-init.sh b/modules/system/boot/stage-2-init.sh
index 0cc09caebba..5343aa9eae9 100644
--- a/modules/system/boot/stage-2-init.sh
+++ b/modules/system/boot/stage-2-init.sh
@@ -5,7 +5,7 @@
# Print a greeting.
echo
-echo "<<< NixOS Stage 2 >>>"
+echo -e "\e[1;32m<<< NixOS Stage 2 >>>\e[0m"
echo
@@ -27,7 +27,7 @@ setPath "@path@"
# Mount special file systems.
mkdir -m 0755 -p /etc
test -e /etc/fstab || touch /etc/fstab # to shut up mount
-[ -s /etc/mtab ] && rm /etc/mtab # while installing a symlink is created (see man mount), if it's still there for whateever reason remove it
+test -s /etc/mtab && rm /etc/mtab # while installing a symlink is created (see man mount), if it's still there for whateever reason remove it
rm -f /etc/mtab* # not that we care about stale locks
mkdir -m 0755 -p /proc
mount -n -t proc none /proc
@@ -100,15 +100,12 @@ rm -rf /var/lock
# gone, of course.
rm -rf /nix/var/nix/chroots # recreated in activate-configuration.sh
-if test -n "$safeMode"; then
- mkdir -m 0755 -p /var/run
- touch /var/run/safemode
-fi
-
-# Create the minimal device nodes needed before we run udev.
+# 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
# Clear the resume device.
@@ -136,12 +133,9 @@ export MODULE_DIR=@kernel@/lib/modules/
# Run any user-specified commands.
@shell@ @postBootCommands@
-echo "starting Upstart..."
+# For debugging Upstart.
+#@shell@ --login < /dev/console > /dev/console 2>&1 &
-# Start Upstart's init. We start it through the
-# /var/run/current-system symlink indirection so that we can upgrade
-# init in a running system by changing the symlink and sending init a
-# HUP signal.
-export UPSTART_CFG_DIR=/etc/event.d
-setPath "@upstartPath@"
-exec /var/run/current-system/upstart/sbin/init
+# Start Upstart's init.
+echo "starting Upstart..."
+PATH=/var/run/current-system/upstart/sbin exec init
diff --git a/modules/system/boot/stage-2.nix b/modules/system/boot/stage-2.nix
index 440ff70965f..5c3c3560be3 100644
--- a/modules/system/boot/stage-2.nix
+++ b/modules/system/boot/stage-2.nix
@@ -15,30 +15,25 @@ let
};
- inherit (pkgs) substituteAll writeText coreutils utillinux udev upstart;
+ inherit (pkgs) substituteAll writeText coreutils utillinux udev;
kernel = config.boot.kernelPackages.kernel;
activateConfiguration = config.system.activationScripts.script;
- # Path for Upstart jobs. Should be quite minimal.
- upstartPath =
- [ pkgs.coreutils
- pkgs.findutils
- pkgs.gnugrep
- pkgs.gnused
- pkgs.upstart
- ];
-
bootStage2 = substituteAll {
src = ./stage-2-init.sh;
isExecutable = true;
- inherit kernel upstart activateConfiguration upstartPath;
+ inherit kernel activateConfiguration;
+ upstart = config.system.build.upstart;
path =
[ coreutils
utillinux
udev
- upstart
];
- postBootCommands = writeText "local-cmds" config.boot.postBootCommands;
+ postBootCommands = writeText "local-cmds"
+ ''
+ ${config.boot.postBootCommands}
+ ${config.powerManagement.powerUpCommands}
+ '';
};
in
diff --git a/modules/system/upstart-events/ctrl-alt-delete.nix b/modules/system/upstart-events/control-alt-delete.nix
similarity index 62%
rename from modules/system/upstart-events/ctrl-alt-delete.nix
rename to modules/system/upstart-events/control-alt-delete.nix
index ae1ba2e342e..5fa2bd87eb9 100644
--- a/modules/system/upstart-events/ctrl-alt-delete.nix
+++ b/modules/system/upstart-events/control-alt-delete.nix
@@ -3,10 +3,10 @@
###### implementation
{
- jobs.ctrl_alt_delete =
- { name = "ctrl-alt-delete";
+ jobs.control_alt_delete =
+ { name = "control-alt-delete";
- startOn = "ctrlaltdel";
+ startOn = "control-alt-delete";
task = true;
diff --git a/modules/system/upstart-events/maintenance-shell.nix b/modules/system/upstart-events/maintenance-shell.nix
deleted file mode 100644
index a8eceb93158..00000000000
--- a/modules/system/upstart-events/maintenance-shell.nix
+++ /dev/null
@@ -1,22 +0,0 @@
-{ config, pkgs, ... }:
-
-###### implementation
-
-{
- jobs.maintenance_shell =
- { name = "maintenance-shell";
-
- startOn = [ "maintenance" "stalled" ];
-
- task = true;
-
- script =
- ''
- exec < /dev/tty1 > /dev/tty1 2>&1
- echo \
- echo "<<< MAINTENANCE SHELL >>>"
- echo ""
- exec ${pkgs.bash}/bin/sh
- '';
- };
-}
diff --git a/modules/system/upstart-events/runlevel.nix b/modules/system/upstart-events/runlevel.nix
new file mode 100644
index 00000000000..750d9a07f50
--- /dev/null
+++ b/modules/system/upstart-events/runlevel.nix
@@ -0,0 +1,25 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+{
+
+ jobs.runlevel =
+ { name = "runlevel";
+
+ startOn = "runlevel [0123456S]";
+
+ task = true;
+
+ script =
+ ''
+ case "$RUNLEVEL" in
+ 0) initctl start shutdown MODE=poweroff;;
+ 1) initctl start shutdown MODE=maintenance;;
+ 6) initctl start shutdown MODE=reboot;;
+ *) echo "Unsupported runlevel: $RUNLEVEL";;
+ esac
+ '';
+ };
+
+}
diff --git a/modules/system/upstart-events/halt.nix b/modules/system/upstart-events/shutdown.nix
similarity index 69%
rename from modules/system/upstart-events/halt.nix
rename to modules/system/upstart-events/shutdown.nix
index 36efc3fe2cf..fa264979c6c 100644
--- a/modules/system/upstart-events/halt.nix
+++ b/modules/system/upstart-events/shutdown.nix
@@ -2,29 +2,33 @@
with pkgs.lib;
-###### implementation
+{
-let
-
- inherit (pkgs) bash utillinux;
-
- jobFun = event:
- { startOn = event;
+ jobs.shutdown =
+ { name = "shutdown";
task = true;
+ environment = { MODE = "poweroff"; };
+
script =
''
set +e # continue in case of errors
+
+ ${pkgs.kbd}/bin/chvt 1
- exec < /dev/tty1 > /dev/tty1 2>&1
+ exec < /dev/console > /dev/console 2>&1
echo ""
- echo "<<< SYSTEM SHUTDOWN >>>"
+ if test "$MODE" = maintenance; then
+ echo "[1;32m<<< Entering maintenance mode >>>[0m"
+ else
+ echo "[1;32m<<< System shutdown >>>[0m"
+ fi
echo ""
- export PATH=${utillinux}/bin:${utillinux}/sbin:$PATH
-
+ export PATH=${pkgs.utillinux}/bin:${pkgs.utillinux}/sbin:$PATH
+
# Set the hardware clock to the system time.
echo "setting the hardware clock..."
hwclock --systohc --utc
@@ -32,6 +36,15 @@ let
# Do an initial sync just in case.
sync
+
+
+ # Stop all Upstart jobs.
+ initctl list | while IFS=", " read jobName status rest; do
+ if test "$jobName" != shutdown -a "$status" != "stop/waiting"; then
+ echo "stopping $jobName..."
+ stop "$jobName"
+ fi
+ done
# Kill all remaining processes except init and this one.
@@ -42,7 +55,20 @@ let
echo "sending the KILL signal to all processes..."
kill -KILL -1
-
+
+
+ # 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 "[1;32m<<< Maintenance shell >>>[0m"
+ echo ""
+ while ! ${pkgs.bash}/bin/bash --login; do true; done
+ initctl emit -n startup
+ exit 0
+ fi
+
# Unmount helper functions.
getMountPoints() {
@@ -99,9 +125,8 @@ let
sync
- # Either reboot or power-off the system. Note that the "halt"
- # event also does a power-off.
- if test ${event} = reboot; then
+ # Either reboot or power-off the system.
+ if test "$MODE" = reboot; then
echo "rebooting..."
sleep 1
exec reboot -f
@@ -113,9 +138,4 @@ let
'';
};
-in
-
-{
- jobs = listToAttrs (map (n: nameValuePair "sys-${n}" (jobFun n))
- [ "reboot" "halt" "system-halt" "power-off" ] );
-}
+}
\ No newline at end of file
diff --git a/modules/system/upstart/upstart.nix b/modules/system/upstart/upstart.nix
index bb6a4f9a117..f7c9eaaa6ef 100644
--- a/modules/system/upstart/upstart.nix
+++ b/modules/system/upstart/upstart.nix
@@ -4,6 +4,19 @@ with pkgs.lib;
let
+ upstart = pkgs.upstart06;
+
+
+ # Path for Upstart jobs. Should be quite minimal.
+ upstartPath =
+ [ pkgs.coreutils
+ pkgs.findutils
+ pkgs.gnugrep
+ pkgs.gnused
+ upstart
+ ];
+
+
# From a job description, generate an Upstart job file.
makeJob = job:
@@ -15,23 +28,25 @@ let
description "${job.description}"
+ console output
+
${if isList job.startOn then
- # This is a hack to support or-dependencies on Upstart 0.3.
- concatMapStrings (x: "start on ${x}\n") job.startOn
+ "start on ${concatStringsSep " or " job.startOn}"
else if job.startOn != "" then
"start on ${job.startOn}"
else ""
}
- ${if job.stopOn != "" then "stop on ${job.stopOn}" else ""}
+ ${optionalString (job.stopOn != "") "stop on ${job.stopOn}"}
+ env PATH=${makeSearchPath "bin" upstartPath}:${makeSearchPath "sbin" upstartPath}
${concatMapStrings (n: "env ${n}=${getAttr n job.environment}\n") (attrNames job.environment)}
- ${if job.preStart != "" then ''
- start script
+ ${optionalString (job.preStart != "") ''
+ pre-start script
${job.preStart}
end script
- '' else ""}
+ ''}
${if job.script != "" && job.exec != "" then
abort "Job ${job.name} has both a `script' and `exec' attribute."
@@ -45,189 +60,218 @@ let
''
exec ${job.exec}
''
- else
- # Simulate jobs without a main process (which Upstart 0.3
- # doesn't support) using a semi-infinite sleep.
- ''
- exec sleep 1e100
- ''
+ else ""
}
- ${if job.respawn && !job.task then "respawn" else ""}
+ ${optionalString (job.postStart != "") ''
+ post-start script
+ ${job.postStart}
+ end script
+ ''}
+
+ ${optionalString job.task "task"}
+ ${optionalString job.respawn "respawn"}
- ${if job.postStop != "" then ''
- stop script
+ ${optionalString (job.preStop != "") ''
+ pre-stop script
+ ${job.preStop}
+ end script
+ ''}
+
+ ${optionalString (job.postStop != "") ''
+ post-stop script
${job.postStop}
end script
- '' else ""}
+ ''}
+
+ ${optionalString (!job.task) (
+ 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}'"
+ )}
${job.extraConfig}
'';
in
- pkgs.runCommand ("upstart-" + job.name)
+ pkgs.runCommand ("upstart-" + job.name + ".conf")
{ inherit (job) buildHook; inherit jobText; }
''
eval "$buildHook"
- ensureDir $out/etc/event.d
- echo "$jobText" > $out/etc/event.d/${job.name}
+ echo "$jobText" > $out
'';
- jobs =
- [pkgs.upstart] # for the built-in logd job
- ++ map (job: job.upstartPkg) (attrValues config.jobs);
-
- # Create an etc/event.d directory containing symlinks to the
- # specified list of Upstart job files.
- jobsDir = pkgs.runCommand "upstart-jobs" {inherit jobs;}
- ''
- ensureDir $out/etc/event.d
- for i in $jobs; do
- if ln -s $i . ; then
- if test -d $i; then
- ln -s $i/etc/event.d/* $out/etc/event.d/
- fi
- else
- echo Duplicate entry: $i;
- fi;
- done
- ''; # */
-
- # !! remove extra indentations.
+
jobOptions = {
- name = mkOption {
- # !!! The type should ensure that this could be a filename.
- type = types.string;
- example = "sshd";
- description = ''
- Name of the Upstart job.
- '';
- };
+ name = mkOption {
+ # !!! The type should ensure that this could be a filename.
+ type = types.string;
+ example = "sshd";
+ description = ''
+ Name of the Upstart job.
+ '';
+ };
- 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.
- '';
- };
+ 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 = "(no description given)";
- description = ''
- A short description of this job.
- '';
- };
+ description = mkOption {
+ type = types.string;
+ default = "(no description given)";
+ description = ''
+ A short description of this job.
+ '';
+ };
- startOn = mkOption {
- # !!! Re-enable this once we're on Upstart >= 0.6.
- #type = types.string;
- default = "";
- description = ''
- The Upstart event that triggers this job to be started.
- If empty, the job will not start automatically.
- '';
- };
+ startOn = mkOption {
+ # !!! Re-enable this once we're on Upstart >= 0.6.
+ #type = types.string;
+ default = "";
+ description = ''
+ The Upstart event that triggers this job to be started.
+ If empty, the job will not start automatically.
+ '';
+ };
- stopOn = mkOption {
- type = types.string;
- default = "shutdown";
- description = ''
- The Upstart event that triggers this job to be stopped.
- '';
- };
+ stopOn = mkOption {
+ type = types.string;
+ default = "shutdown";
+ description = ''
+ The Upstart event that triggers this job to be stopped.
+ '';
+ };
- 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).
- '';
- };
+ 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).
+ '';
+ };
- postStop = mkOption {
- type = types.string;
- default = "";
- description = ''
- Shell commands executed after the job has stopped
- (i.e. after the job's main process has terminated).
- '';
- };
+ postStart = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Shell commands executed after the job is started (i.e. after
+ the job's main process is started), but before the job is
+ considered “running”.
+ '';
+ };
- exec = mkOption {
- type = types.string;
- default = "";
- description = ''
- Command to start the job's main process. If empty, the
- job has no main process, but can still have pre/post-start
- and pre/post-stop scripts, and is considered "running"
- until it is stopped.
- '';
- };
+ preStop = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Shell commands executed before the job is stopped
+ (i.e. before Upstart kills the job's main process). This can
+ be used to cleanly shut down a daemon.
+ '';
+ };
- script = mkOption {
- type = types.string;
- default = "";
- description = ''
- Shell commands executed as the job's main process. Can be
- specified instead of the exec attribute.
- '';
- };
+ postStop = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Shell commands executed after the job has stopped
+ (i.e. after the job's main process has terminated).
+ '';
+ };
- respawn = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether to restart the job automatically if its process
- ends unexpectedly.
- '';
- };
+ exec = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Command to start the job's main process. If empty, the
+ job has no main process, but can still have pre/post-start
+ and pre/post-stop scripts, and is considered “running”
+ until it is stopped.
+ '';
+ };
- task = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether this job is a task rather than a service. Tasks
- are executed only once, while services are restarted when
- they exit.
- '';
- };
+ script = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Shell commands executed as the job's main process. Can be
+ specified instead of the exec attribute.
+ '';
+ };
- 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.
- '';
- };
+ respawn = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to restart the job automatically if its process
+ ends unexpectedly.
+ '';
+ };
- extraConfig = mkOption {
- type = types.string;
- default = "";
- example = "limit nofile 4096 4096";
- description = ''
- Additional Upstart stanzas not otherwise supported.
- '';
- };
+ task = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether this job is a task rather than a service. Tasks
+ are executed only once, while services are restarted when
+ they exit.
+ '';
+ };
- };
+ 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";
+ description = ''
+ Determines how Upstart detects when a daemon should be
+ considered “running”. The value none means
+ that the daemon is considered ready immediately. The value
+ fork means that the daemon will fork once.
+ The value daemon means that the daemon will
+ fork twice. The value stop means that the
+ daemon will raise the SIGSTOP signal to indicate readiness.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.string;
+ default = "";
+ example = "limit nofile 4096 4096";
+ description = ''
+ Additional Upstart stanzas not otherwise supported.
+ '';
+ };
+
+ };
+
+
upstartJob = {name, config, ...}: {
options = {
- upstartPkg = mkOption {
+ jobDrv = mkOption {
default = makeJob config;
type = types.uniq types.package;
description = ''
- Upstart package which contains upstart events inside
- /etc/event.d/. The default value is
- generated from other options.
+ Derivation that builds the Upstart job file. The default
+ value is generated from other options.
'';
};
};
@@ -275,19 +319,26 @@ in
config = {
+ system.build.upstart = upstart;
+
environment.etc =
- [ { # The Upstart events defined above.
- source = "${jobsDir}/etc/event.d";
- target = "event.d";
- }
- ];
+ 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 ];
# !!! fix this
+ /*
tests.upstartJobs = { recurseForDerivations = true; } //
builtins.listToAttrs (map (job: {
name = removePrefix "upstart-" job.name;
value = job;
}) jobs);
+ */
};
diff --git a/modules/tasks/kbd.nix b/modules/tasks/kbd.nix
index 9ba7f973cf3..8ed4b44f91b 100644
--- a/modules/tasks/kbd.nix
+++ b/modules/tasks/kbd.nix
@@ -59,9 +59,11 @@ in
jobs.kbd =
{ description = "Keyboard / console initialisation";
- startOn = "udev";
+ startOn = "started udev";
- preStart = ''
+ task = true;
+
+ script = ''
export LANG=${defaultLocale}
export LOCALE_ARCHIVE=/var/run/current-system/sw/lib/locale/locale-archive
export PATH=${pkgs.gzip}/bin:$PATH # Needed by setfont
diff --git a/modules/tasks/lvm.nix b/modules/tasks/lvm.nix
index 4da517deae1..4aebb33767e 100644
--- a/modules/tasks/lvm.nix
+++ b/modules/tasks/lvm.nix
@@ -7,7 +7,7 @@
config = {
jobs.lvm =
- { startOn = " udev"; # !!! or on new-devices
+ { startOn = "started udev or new-devices";
script =
''
@@ -23,7 +23,7 @@
# make them appear in /dev.
${pkgs.lvm2}/sbin/vgchange --available y
- initctl emit new-devices
+ initctl emit -n new-devices
'';
task = true;
diff --git a/modules/tasks/network-interfaces.nix b/modules/tasks/network-interfaces.nix
index 4b53da876da..2868c251fca 100644
--- a/modules/tasks/network-interfaces.nix
+++ b/modules/tasks/network-interfaces.nix
@@ -135,7 +135,7 @@ in
jobs.networkInterfaces =
{ name = "network-interfaces";
- startOn = "udev";
+ startOn = "started udev";
preStart =
''
@@ -178,6 +178,11 @@ in
# Run any user-specified commands.
${pkgs.stdenv.shell} ${pkgs.writeText "local-net-cmds" cfg.localCommands} || true
+
+ # Emit the ip-up event (e.g. to start ntpd).
+ ${optionalString (cfg.interfaces != []) ''
+ initctl emit -n ip-up
+ ''}
'';
postStop =
diff --git a/modules/tasks/swraid.nix b/modules/tasks/swraid.nix
index 6e29062f0a9..b9465822601 100644
--- a/modules/tasks/swraid.nix
+++ b/modules/tasks/swraid.nix
@@ -13,7 +13,7 @@ in
{
jobs.swraid =
- { startOn = "udev"; # !!! or on "new-devices"
+ { startOn = "started udev or new-devices";
script =
''
@@ -25,11 +25,13 @@ in
# Scan /proc/partitions for RAID devices.
${mdadm}/sbin/mdadm --examine --brief --scan -c partitions > ${tempConf}
+
+ if ! test -s ${tempConf}; then exit 0; fi
# Activate each device found.
${mdadm}/sbin/mdadm --assemble -c ${tempConf} --scan
- initctl emit new-devices
+ initctl emit -n new-devices
'';
task = true;
diff --git a/modules/tasks/tty-backgrounds.nix b/modules/tasks/tty-backgrounds.nix
index d15365fab9d..5f557ac7f5c 100644
--- a/modules/tasks/tty-backgrounds.nix
+++ b/modules/tasks/tty-backgrounds.nix
@@ -105,7 +105,7 @@ in
jobs.ttyBackgrounds =
{ name = "tty-backgrounds";
- startOn = "udev";
+ startOn = "started udev";
preStart =
''
diff --git a/modules/virtualisation/qemu-vm.nix b/modules/virtualisation/qemu-vm.nix
index 87138ed5c52..68ba340e6c2 100644
--- a/modules/virtualisation/qemu-vm.nix
+++ b/modules/virtualisation/qemu-vm.nix
@@ -9,6 +9,8 @@
{config, pkgs, ...}:
+with pkgs.lib;
+
let
vmName = config.networking.hostName;
@@ -16,7 +18,7 @@ let
options = {
virtualisation.diskImage =
- pkgs.lib.mkOption {
+ mkOption {
default = "./${vmName}.qcow2";
description =
''
@@ -90,7 +92,7 @@ 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 = pkgs.lib.mkOverride 50 {}
+ fileSystems = mkOverride 50 {}
[ { mountPoint = "/";
device = "/dev/vda";
}
@@ -119,6 +121,13 @@ in
networking.defaultGateway = "10.0.2.2";
+ networking.nameservers = [ "10.0.2.3" ];
+
+ networking.interfaces = singleton
+ { name = "eth0";
+ ipAddress = "10.0.2.15";
+ };
+
system.build.vm = pkgs.runCommand "nixos-vm" {}
''
ensureDir $out/bin
@@ -135,11 +144,11 @@ in
# When building a regular system configuration, override whatever
# video driver the host uses.
- services.xserver.videoDriver = pkgs.lib.mkOverride 50 {} null;
- services.xserver.videoDrivers = pkgs.lib.mkOverride 50 {} [ "cirrus" "vesa" ];
- services.xserver.defaultDepth = pkgs.lib.mkOverride 50 {} 0;
- services.xserver.resolutions = pkgs.lib.mkOverride 50 {} [];
+ services.xserver.videoDriver = mkOverride 50 {} null;
+ services.xserver.videoDrivers = mkOverride 50 {} [ "cirrus" "vesa" ];
+ services.xserver.defaultDepth = mkOverride 50 {} 0;
+ services.xserver.resolutions = mkOverride 50 {} [];
# Wireless won't work in the VM.
- networking.enableWLAN = pkgs.lib.mkOverride 50 {} false;
+ networking.enableWLAN = mkOverride 50 {} false;
}
diff --git a/release.nix b/release.nix
index 8d00c826806..9520ac02698 100644
--- a/release.nix
+++ b/release.nix
@@ -30,10 +30,11 @@ let
description = "NixOS installation CD (${description}) - ISO image for ${system}";
maintainers = map (x: lib.getAttr x lib.maintainers) maintainers;
};
+ inherit iso;
}
''
ensureDir $out/nix-support
- echo "file iso" ${iso}/iso/*.iso* >> $out/nix-support/hydra-build-products
+ echo "file iso" $iso/iso/*.iso* >> $out/nix-support/hydra-build-products
''; # */