* Merged the Upstart 0.6 branch.

svn path=/nixos/trunk/; revision=18620
This commit is contained in:
Eelco Dolstra 2009-11-25 10:48:36 +00:00
commit 8c134a151c
85 changed files with 831 additions and 557 deletions

View File

@ -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";
};
};
}

View File

@ -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
];

View File

@ -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

View File

@ -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 =

View File

@ -10,10 +10,11 @@ let
in
{
boot.extraGrubEntries =
boot.loader.grub.extraEntries =
''
title Memtest86+
kernel ${memtestPath}
menuentry "Memtest86+" {
linux16 ${memtestPath}
}
'';
isoImage.contents =

View File

@ -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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -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).

View File

@ -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

View File

@ -46,7 +46,7 @@ in
};
jobs.alsa =
{ startOn = "udev";
{ startOn = "started udev";
preStart =
''

View File

@ -66,7 +66,6 @@ in
{ description = "PulseAudio system-wide server";
startOn = "startup";
stopOn = "shutdown";
preStart =
''

View File

@ -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";
};
};

View File

@ -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'
'';
};
};

View File

@ -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}";
};

View File

@ -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
};
}
}

View File

@ -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";
};
};

View File

@ -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";
};
}

View File

@ -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}";
};
};

View File

@ -116,7 +116,7 @@ in
jobs.dovecot =
{ description = "Dovecot IMAP/POP3 server";
startOn = "${startingDependency}/started";
startOn = "started ${startingDependency}";
preStart =
''

View File

@ -283,7 +283,7 @@ in
# accurate way is unlikely to be better.
{ description = "Postfix mail server";
startOn = "${startingDependency}/started";
startOn = "started ${startingDependency}";
script =
''

View File

@ -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";

View File

@ -39,8 +39,7 @@ in
jobs.disnix =
{ description = "Disnix server";
startOn = "dbus";
stopOn = "shutdown";
startOn = "started dbus";
script =
''

View File

@ -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 =
''

View File

@ -78,8 +78,7 @@ in
description = "NixOS manual";
startOn = "udev";
stopOn = "shutdown";
startOn = "started udev";
exec =
''

View File

@ -43,8 +43,7 @@ in
jobs.rogue =
{ description = "Rogue dungeon crawling game";
startOn = "udev";
stopOn = "shutdown";
startOn = "started udev";
extraConfig = "chdir /root";

View File

@ -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 =
''

View File

@ -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 =
''

View File

@ -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 =
''

View File

@ -56,8 +56,8 @@ in
description = "Zabbix server daemon";
startOn = "postgresql";
stopOn = "shutdown";
startOn = "started postgresql";
stopOn = "stopping postgresql";
preStart =
''

View File

@ -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 =
''

View File

@ -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;
};

View File

@ -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 =
''

View File

@ -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 =
''

View File

@ -114,7 +114,6 @@ in
{ name = "ddclient";
startOn = "startup";
stopOn = "shutdown";
preStart =
''

View File

@ -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
'';
};
}

View File

@ -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 =
''

View File

@ -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
'';
};

View File

@ -79,7 +79,7 @@ in
environment.systemPackages = [pkgs.iptables];
jobs.firewall =
{ startOn = "network-interfaces/started";
{ startOn = "started network-interfaces";
preStart =
''

View File

@ -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 =
''

View File

@ -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
'';

View File

@ -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";
};

View File

@ -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 =
''

View File

@ -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";
};

View File

@ -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

View File

@ -52,8 +52,7 @@ in
jobs.openfire =
{ description = "OpenFire XMPP server";
startOn = "${startDependency}/started";
stopOn = "shutdown";
startOn = "started ${startDependency}";
script =
''

View File

@ -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 =
''

View File

@ -81,7 +81,6 @@ in
{ name = "privoxy";
startOn = "startup";
stopOn = "shutdown";
preStart =
''

View File

@ -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; };

View File

@ -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];

View File

@ -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 =
''

View File

@ -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 =
''

View File

@ -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}";
};

View File

@ -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 =
''

View File

@ -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)

View File

@ -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; };

View File

@ -101,7 +101,6 @@ in
{ description = "fcron daemon";
startOn = "startup";
stopOn = "shutdown";
environment =
{ PATH = "/var/run/current-system/sw/bin";

View File

@ -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
'';
};

View File

@ -21,7 +21,6 @@ in
{ description = "Name Service Cache Daemon";
startOn = "startup";
stopOn = "shutdown";
environment = { LD_LIBRARY_PATH = nssModulesPath; };

View File

@ -53,7 +53,6 @@ in
{ description = "Uptimed daemon";
startOn = "startup";
stopOn = "shutdown";
preStart =
''

View File

@ -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";
};

View File

@ -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}";

View File

@ -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
'';
};
};

View File

@ -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..."

View File

@ -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

View File

@ -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 ""}
'';

View File

@ -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}";
};

View File

@ -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 ''

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -39,7 +39,7 @@ trap 'fail' ERR
# Print a greeting.
echo
echo "<<< NixOS Stage 1 >>>"
echo "<<< NixOS Stage 1 >>>"
echo

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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
'';
};
}

View File

@ -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
'';
};
}

View File

@ -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 "<<< Entering maintenance mode >>>"
else
echo "<<< System shutdown >>>"
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 "<<< Maintenance shell >>>"
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" ] );
}
}

View File

@ -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
<filename>httpd.conf</filename>.
'';
};
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
<filename>httpd.conf</filename>.
'';
};
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 <varname>exec</varname> 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 <varname>exec</varname> 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 <literal>none</literal> means
that the daemon is considered ready immediately. The value
<literal>fork</literal> means that the daemon will fork once.
The value <literal>daemon</literal> means that the daemon will
fork twice. The value <literal>stop</literal> 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
<filename>/etc/event.d/</filename>. 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);
*/
};

View File

@ -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

View File

@ -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;

View File

@ -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 =

View File

@ -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;

View File

@ -105,7 +105,7 @@ in
jobs.ttyBackgrounds =
{ name = "tty-backgrounds";
startOn = "udev";
startOn = "started udev";
preStart =
''

View File

@ -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;
}

View File

@ -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
''; # */