diff --git a/boot/boot-stage-1-init.sh b/boot/boot-stage-1-init.sh index c6d7214028ca..b3b2292beaac 100644 --- a/boot/boot-stage-1-init.sh +++ b/boot/boot-stage-1-init.sh @@ -1,7 +1,9 @@ -#! @staticShell@ +#! @shell@ targetRoot=/mnt/root +export LD_LIBRARY_PATH=@extraUtils@/lib + errorDialog() { timeout=15 @@ -14,13 +16,13 @@ errorDialog() { read -t $timeout reply case $reply in f) - exec @staticShell@;; + exec @shell@;; i) echo echo "Quit interactive shell with exit status of" echo " 0 : to continue" echo " non-zero : to get this dialog again" - @staticShell@ || fail + @shell@ || fail ;; *) echo continuing ignoring error;; @@ -140,24 +142,69 @@ if test -n "$debug1devices"; then fail; fi # Return true if the machine is on AC power, or if we can't determine # whether it's on AC power. -onACPower () { +onACPower() { if test -d "/proc/acpi/battery"; then - if ls /proc/acpi/battery/BAT[0-9]* > /dev/null 2>&1; then - if cat /proc/acpi/battery/BAT*/state \ - | grep "^charging state" \ - | grep -q "discharg" ; then - false - else - true - fi - else - true - fi + if ls /proc/acpi/battery/BAT[0-9]* > /dev/null 2>&1; then + if cat /proc/acpi/battery/BAT*/state \ + | grep "^charging state" \ + | grep -q "discharg" ; then + false + else + true + fi + else + true + fi else - true + true fi } + +# Check the specified file system, if appropriate. +checkFS() { + # Only check block devices. + if ! test -b "$device"; then return 0; fi + + # For unclean ext3 file systems, fsck.ext3 should just replay the + # journal and exit, but in practice this takes *much* longer than + # letting the kernel recover the FS. So, don't run fsck on + # journalling file systems. + eval $(fstype "$device") + if test "$FSTYPE" = ext3 -o "$FSTYPE" = ext4 -o "$FSTYPE" = reiserfs -o "$FSTYPE" = xfs -o "$FSTYPE" = jfs; then + return 0; + fi + + # Don't run `fsck' if the machine is on battery power. !!! Is + # this a good idea? + if ! onACPower; then + echo "on battery power, so \`fsck' not run on \`$device'" + return 0 + fi + + FSTAB_FILE="/etc/mtab" fsck -V -v -C -a "$device" + fsckResult=$? + + if test $(($fsckResult | 2)) = $fsckResult; then + echo "fsck finished, rebooting..." + sleep 3 + reboot + fi + + if test $(($fsckResult | 4)) = $fsckResult; then + echo "$device has unrepaired errors, please fix them manually." + fail + fi + + if test $fsckResult -ge 8; then + echo "fsck on $device failed." + fail + fi + + return 0 +} + + # Function for mounting a file system. mountFS() { local device="$1" @@ -165,44 +212,8 @@ mountFS() { local options="$3" local fsType="$4" - # Check the root device, if . - mustCheck= - if test -b "$device"; then - mustCheck=1 - else - case $device in - LABEL=*) - mustCheck=1 - ;; - esac - fi - - if test -n "$mustCheck"; then - if onACPower; then - FSTAB_FILE="/etc/mtab" fsck -V -v -C -a "$device" - fsckResult=$? - - if test $(($fsckResult | 2)) = $fsckResult; then - echo "fsck finished, rebooting..." - sleep 3 - reboot - fi - - if test $(($fsckResult | 4)) = $fsckResult; then - echo "$device has unrepaired errors, please fix them manually." - fail - fi - - if test $fsckResult -ge 8; then - echo "fsck on $device failed." - fail - fi - else - # Don't run `fsck' if the machine is on battery power. - echo "on battery power, so \`fsck' not run on \`$device'" - fi - fi - + checkFS "$device" + # Mount read-writable. mount -t "$fsType" -o "$options" "$device" /mnt-root$mountPoint || fail } @@ -224,8 +235,8 @@ for ((n = 0; n < ${#mountPoints[*]}; n++)); do # !!! Really quick hack to support bind mounts, i.e., where the # "device" should be taken relative to /mnt-root, not /. Assume - # that every device that start with / but doesn't start with /dev - # or LABEL= is a bind mount. + # that every device that starts with / but doesn't start with /dev + # is a bind mount. case $device in /dev/*) ;; @@ -290,7 +301,6 @@ umount /proc exec run-init "$targetRoot" "$stage2Init" echo -echo $1 failed running "$stage2Init" -echo "It's your last chance to fix things manually without rebooting" -echo "finally switching to interactive shell pid 1" -export $stage2Init; exec @staticShell@ +echo "$1: failed running $stage2Init" +echo "Dropping into a root shell..." +export $stage2Init; exec @shell@ diff --git a/boot/boot-stage-1.nix b/boot/boot-stage-1.nix index 8a5b0a76a3a2..7b7f5503d0b7 100644 --- a/boot/boot-stage-1.nix +++ b/boot/boot-stage-1.nix @@ -13,26 +13,6 @@ in rec { - pkgsDiet = import "${pkgs.path}/top-level/all-packages.nix" { - system = pkgs.stdenv.system; - bootStdenv = pkgs.useDietLibC pkgs.stdenv; - }; - - pkgsKlibc = import "${pkgs.path}/top-level/all-packages.nix" { - system = pkgs.stdenv.system; - bootStdenv = pkgs.useKlibc pkgs.stdenv kernelPackages.klibc; - }; - - pkgsStatic = import "${pkgs.path}/top-level/all-packages.nix" { - system = pkgs.stdenv.system; - bootStdenv = pkgs.makeStaticBinaries pkgs.stdenv; - }; - - stdenvLinuxStuff = import "${pkgs.path}/stdenv/linux" { - system = pkgs.stdenv.system; - allPackages = import "${pkgs.path}/top-level/all-packages.nix"; - }; - # Determine the set of modules that we need to mount the root FS. modulesClosure = pkgs.makeModulesClosure { @@ -44,38 +24,82 @@ rec { }; - udev = pkgsKlibc.udev; - - - # Some additional utilities needed in stage 1, notably mount. We - # don't want to bring in all of util-linux, so we just copy what we - # need. + # Some additional utilities needed in stage 1, like mount, lvm, fsck + # etc. We don't want to bring in all of those packages, so we just + # copy what we need. Instead of using statically linked binaries, + # we just copy what we need from Glibc and use patchelf to make it + # work. extraUtils = pkgs.runCommand "extra-utils" { buildInputs = [pkgs.nukeReferences]; - inherit (pkgsStatic) utillinux; - inherit udev; - e2fsprogs = pkgsDiet.e2fsprogs; - devicemapper = - if config.boot.initrd.lvm - then assert pkgs.devicemapper.enableStatic; pkgs.devicemapper - else null; - lvm2 = - if config.boot.initrd.lvm - then assert pkgs.lvm2.enableStatic; pkgs.lvm2 - else null; - allowedReferences = []; # prevent accidents like glibc being included in the initrd + devicemapper = if config.boot.initrd.lvm then pkgs.devicemapper else null; + lvm2 = if config.boot.initrd.lvm then pkgs.lvm2 else null; + allowedReferences = ["out"]; # prevent accidents like glibc being included in the initrd } '' ensureDir $out/bin + ensureDir $out/lib + + # Copy what we need from Glibc. + cp -p ${pkgs.glibc}/lib/ld-linux*.so.2 $out/lib + cp -p ${pkgs.glibc}/lib/libc.so.* $out/lib + cp -p ${pkgs.glibc}/lib/libpthread.so.* $out/lib + cp -p ${pkgs.glibc}/lib/librt.so.* $out/lib + cp -p ${pkgs.glibc}/lib/libdl.so.* $out/lib + + # Copy some utillinux stuff. + cp ${pkgs.utillinux}/bin/mount ${pkgs.utillinux}/bin/umount ${pkgs.utillinux}/sbin/pivot_root $out/bin + + # Copy e2fsck and friends. + cp ${pkgs.e2fsprogs}/sbin/e2fsck $out/bin + cp ${pkgs.e2fsprogs}/sbin/tune2fs $out/bin + cp ${pkgs.e2fsprogs}/sbin/fsck $out/bin + ln -s e2fsck $out/bin/fsck.ext2 + ln -s e2fsck $out/bin/fsck.ext3 + ln -s e2fsck $out/bin/fsck.ext4 + + cp -pd ${pkgs.e2fsprogs}/lib/lib*.so.* $out/lib + + # Copy devicemapper and lvm, if we need it. if test -n "$devicemapper"; then - cp $devicemapper/sbin/dmsetup.static $out/bin/dmsetup - cp $lvm2/sbin/lvm.static $out/bin/lvm + cp $devicemapper/sbin/dmsetup $out/bin/dmsetup + cp $devicemapper/lib/libdevmapper.so.*.* $out/lib + cp $lvm2/sbin/lvm $out/bin/lvm + fi + + # Copy udev. + cp ${pkgs.udev}/sbin/udevd ${pkgs.udev}/sbin/udevadm $out/bin + cp ${pkgs.udev}/lib/udev/*_id $out/bin + cp ${pkgs.udev}/lib/libvolume_id.so.* $out/lib + + # Copy bash. + cp ${pkgs.bash}/bin/bash $out/bin + ln -s bash $out/bin/sh + + # Run patchelf to make the programs refer to the copied libraries. + for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done + + for i in $out/bin/*; do + if ! test -L $i; then + echo "patching $i..." + patchelf --set-interpreter $out/lib/ld-linux*.so.2 --set-rpath $out/lib $i || true + fi + done + + # Make sure that the patchelf'ed binaries still work. + echo "testing patched programs..." + $out/bin/bash --version + export LD_LIBRARY_PATH=$out/lib + $out/bin/mount --version + $out/bin/umount --version + $out/bin/e2fsck -V + $out/bin/tune2fs 2> /dev/null | grep "tune2fs " + $out/bin/fsck -N + $out/bin/udevadm --version + $out/bin/vol_id 2>&1 | grep "no device" + if test -n "$devicemapper"; then + $out/bin/dmsetup --version | grep "version:" + LVM_SYSTEM_DIR=$out $out/bin/lvm 2>&1 | grep "LVM" fi - cp $utillinux/bin/mount $utillinux/bin/umount $utillinux/sbin/pivot_root $out/bin - cp -p $e2fsprogs/sbin/fsck* $e2fsprogs/sbin/e2fsck $out/bin - cp $udev/sbin/udevd $udev/sbin/udevadm $out/bin - cp $udev/lib/udev/*_id $out/bin - nuke-refs $out/bin/* ''; # */ @@ -91,7 +115,7 @@ rec { name = "udev-rules"; buildCommand = '' ensureDir $out - cp ${udev}/*/udev/rules.d/60-persistent-storage.rules $out/ + cp ${pkgs.udev}/*/udev/rules.d/60-persistent-storage.rules $out/ substituteInPlace $out/60-persistent-storage.rules \ --replace ata_id ${extraUtils}/bin/ata_id \ --replace usb_id ${extraUtils}/bin/usb_id \ @@ -114,11 +138,11 @@ rec { bootStage1 = pkgs.substituteAll { src = ./boot-stage-1-init.sh; + shell = "${extraUtils}/bin/bash"; + isExecutable = true; - staticShell = stdenvLinuxStuff.bootstrapTools.bash; - - inherit modulesClosure udevConf; + inherit modulesClosure udevConf extraUtils; inherit (config.boot) isLiveCD resumeDevice; @@ -136,7 +160,7 @@ rec { # command provided by klibc (which isn't capable of # auto-detecting FS types). extraUtils - kernelPackages.klibcShrunk + pkgs.klibcShrunk ]; }; diff --git a/boot/boot-stage-2-init.sh b/boot/boot-stage-2-init.sh index f5fd818d3c7e..a5f94bf2ad2d 100644 --- a/boot/boot-stage-2-init.sh +++ b/boot/boot-stage-2-init.sh @@ -30,8 +30,9 @@ test -e /etc/fstab || touch /etc/fstab # to shut up mount mkdir -m 0755 -p /proc mount -n -t proc none /proc [ -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 cat /proc/mounts > /etc/mtab -mkdir -m 0755 -p /etc/nixos # Process the kernel command line. @@ -69,6 +70,8 @@ mkdir -m 0755 -p /sys mount -t sysfs none /sys mkdir -m 0755 -p /dev mount -t tmpfs -o "mode=0755" none /dev +mkdir -m 0777 /dev/shm +mount -t tmpfs -o "rw,nosuid,nodev" tmpfs /dev/shm mkdir -m 0755 -p /dev/pts mount -t devpts none /dev/pts [ -e /proc/bus/usb ] && mount -t usbfs none /proc/bus/usb # uml doesn't have usb by default @@ -78,10 +81,12 @@ mkdir -m 0755 -p /nix/var mkdir -m 0700 -p /root mkdir -m 0755 -p /bin # for the /bin/sh symlink mkdir -m 0755 -p /home +mkdir -m 0755 -p /etc/nixos # Miscellaneous boot time cleanup. rm -rf /var/run +rm -rf /var/lock #echo -n "cleaning \`/tmp'..." #rm -rf --one-file-system /tmp/* diff --git a/doc/manual/default.nix b/doc/manual/default.nix index a7f51adf287b..c46e89d0fa14 100644 --- a/doc/manual/default.nix +++ b/doc/manual/default.nix @@ -1,8 +1,10 @@ -{nixpkgsPath ? ../../../nixpkgs}: +{nixpkgsPath ? ../../../nixpkgs, nixpkgs ? null}: let - pkgs = import "${nixpkgsPath}/pkgs/top-level/all-packages.nix" {}; + pkgs = if nixpkgs == null then + import "${nixpkgsPath}/pkgs/top-level/all-packages.nix" {} + else nixpkgs; options = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML (pkgs.lib.optionAttrSetToDocList "" diff --git a/etc/bashrc.sh b/etc/bashrc.sh index 4ec3b4ab4158..20b78b21c632 100644 --- a/etc/bashrc.sh +++ b/etc/bashrc.sh @@ -15,7 +15,9 @@ export LANG=@defaultLocale@ export EDITOR=nano export INFOPATH=/var/run/current-system/sw/info:/var/run/current-system/sw/share/info export LOCATE_PATH=/var/cache/locatedb - +export KDEDIRS=/var/run/current-system/sw +export XDG_CONFIG_DIRS=/var/run/current-system/sw/etc/xdg +export XDG_DATA_DIRS=/var/run/current-system/sw/share # Set up secure multi-user builds: non-root users build through the # Nix daemon. @@ -41,7 +43,7 @@ for i in $NIX_PROFILES; do # !!! reverse export PKG_CONFIG_PATH="$i/lib/pkgconfig:$PKG_CONFIG_PATH" # Automake's `aclocal' bails out if it finds non-existent directories - # in its path. + # in its path. !!! We should fix aclocal instead. if [ -d "$i/share/aclocal" ] then export ACLOCAL_PATH="$i/share/aclocal:$ACLOCAL_PATH" @@ -50,6 +52,11 @@ for i in $NIX_PROFILES; do # !!! reverse # GStreamer. export GST_PLUGIN_PATH="$i/lib/gstreamer-0.10:$GST_PLUGIN_PATH" + + # KDE/Gnome stuff. + export KDEDIRS=$i:$KDEDIRS + export XDG_CONFIG_DIRS=$i/etc/xdg:$XDG_CONFIG_DIRS + export XDG_DATA_DIRS=$i/share:$XDG_DATA_DIRS done diff --git a/helpers/info-wrapper.nix b/helpers/info-wrapper.nix new file mode 100644 index 000000000000..0f482dd4c276 --- /dev/null +++ b/helpers/info-wrapper.nix @@ -0,0 +1,29 @@ +# Quick hack to make the `info' command work properly. `info' needs a +# "dir" file containing all the installed Info files, which we don't +# have (it would be impure to have a package installation update some +# global "dir" file). So this wrapper script around "info" builds a +# temporary "dir" file on the fly. This is a bit slow (on a cold +# cache) but not unacceptably so. + +{bash, texinfo, writeScriptBin}: + +writeScriptBin "info" + '' + #! ${bash}/bin/sh + + dir=$(mktemp --tmpdir -d "info.dir.XXXXXX") + + if test -z "$dir"; then exit 1; fi + + trap 'rm -rf "$dir"' EXIT + + shopt -s nullglob + + for i in $(IFS=:; echo $INFOPATH); do + for j in $i/*.info; do + ${texinfo}/bin/install-info --quiet $j $dir/dir + done + done + + INFOPATH=$dir:$INFOPATH ${texinfo}/bin/info "$@" + '' diff --git a/installer/cd-dvd/rescue-cd.nix b/installer/cd-dvd/rescue-cd.nix index 66c707c77a72..2b82df15fe36 100644 --- a/installer/cd-dvd/rescue-cd.nix +++ b/installer/cd-dvd/rescue-cd.nix @@ -148,12 +148,14 @@ rec { sha256 = "0sdykpziij1f3w4braq8r8nqg4lnsd7i7gi1k5d7c31m2q3b9a7r"; }; } + /* url is broken { tty = 8; theme = pkgs.fetchurl { url = http://www.bootsplash.de/files/themes/Theme-GNU.tar.bz2; md5 = "61969309d23c631e57b0a311102ef034"; }; } + */ ]; }; @@ -188,6 +190,9 @@ rec { pkgs.gdb # for debugging Nix pkgs.testdisk # useful for repairing boot problems pkgs.mssys # for writing Microsoft boot sectors / MBRs + + pkgs.sshfsFuse + pkgs.screen ]; }; diff --git a/installer/nixos-install.sh b/installer/nixos-install.sh index 1288304cbe0f..1784b4357f19 100644 --- a/installer/nixos-install.sh +++ b/installer/nixos-install.sh @@ -131,7 +131,7 @@ export NIX_OTHER_STORES=/mnt/nix:$NIX_OTHER_STORES # Do a nix-pull to speed up building. -if test -n "@nixpkgsURL@"; then +if test -n "@nixpkgsURL@" -a ${NIXOS_PULL:-1} != 0; then chroot $mountPoint @nix@/bin/nix-pull @nixpkgsURL@/MANIFEST || true fi diff --git a/release.nix b/release.nix index 4612e94ded91..d291e21b8dd3 100644 --- a/release.nix +++ b/release.nix @@ -54,6 +54,7 @@ let platform = system; compressImage = true; nixpkgsPath = nixpkgs.path; + relName = "nixos-${builtins.readFile ./VERSION}${if !officialRelease then "pre${toString nixosSrc.rev}" else ""}"; }).rescueCD; in diff --git a/system/ids.nix b/system/ids.nix index 3838f7138f22..a950ec84db12 100644 --- a/system/ids.nix +++ b/system/ids.nix @@ -19,6 +19,7 @@ dovecot = 15; tomcat = 16; gnunetd = 17; + pulseaudio = 22; # must match `pulseaudio' GID nixbld = 30000; # start of range of uids nobody = 65534; @@ -45,6 +46,7 @@ uucp = 19; lp = 20; tomcat = 21; + pulseaudio = 22; # must match `pulseaudio' UID users = 100; nixbld = 30000; diff --git a/system/options.nix b/system/options.nix index 7c4b5def367b..34ae64a3c51b 100644 --- a/system/options.nix +++ b/system/options.nix @@ -34,7 +34,7 @@ in example = "0:0"; description = " Device for manual resume attempt during boot. Looks like - major:minor . + major:minor. ls -l /dev/SWAP_PARTION shows them. "; }; @@ -1933,6 +1933,16 @@ in on the remote machine. "; }; + + proxy = mkOption { + default = ""; + description = " + This option specifies the proxy to use for fetchurl. The real effect + is just exporting http_proxy, https_proxy and ftp_proxy with that + value. + "; + example = "http://127.0.0.1:3128"; + }; # Environment variables for running Nix. envVars = mkOption { @@ -1962,7 +1972,16 @@ in export NIX_REMOTE_SYSTEMS=/etc/nix.machines export NIX_CURRENT_LOAD=/var/run/nix/current-load '' - else "") + conf; + else "") + + + (if config.nix.proxy != "" then + '' + export http_proxy=${config.nix.proxy} + export https_proxy=${config.nix.proxy} + export ftp_proxy=${config.nix.proxy} + '' + else "") + + conf; }; }; @@ -2108,7 +2127,7 @@ in environment = { pathsToLink = mkOption { - default = ["/bin" "/sbin" "/lib" "/share" "/man" "/info"]; + default = ["/bin" "/sbin" "/lib" "/share" "/man" "/info" "/etc"]; example = ["/"]; description = " Lists directories to be symlinked in `/var/run/current-system/sw'. @@ -2167,7 +2186,20 @@ in }; }; + + + powerManagement = { + + enable = mkOption { + default = false; + description = " + Whether to enable power management. + "; + }; + + }; + nesting = { children = mkOption { default = []; @@ -2177,6 +2209,7 @@ in }; }; + passthru = mkOption { default = {}; description = " @@ -2226,6 +2259,10 @@ in (import ../upstart-jobs/cron.nix) (import ../upstart-jobs/fcron.nix) (import ../upstart-jobs/cron/locate.nix) + (import ../upstart-jobs/manual.nix) + (import ../upstart-jobs/rogue.nix) + (import ../upstart-jobs/guest-users.nix) + (import ../upstart-jobs/pulseaudio.nix) # fonts (import ../system/fonts.nix) diff --git a/system/system-options.nix b/system/system-options.nix index b1688cdda805..fdbd57a79f04 100644 --- a/system/system-options.nix +++ b/system/system-options.nix @@ -64,6 +64,16 @@ let inherit (config.environment) pathsToLink; ignoreCollisions = true; + + # TODO: move this to upstart-jobs/xserver/desktopManager/kde4.nix + postBuild = + if config.services.xserver.desktopManager.kde4.enable then + # Rebuild the MIME database. Otherwise KDE won't be able to + # find many MIME types. + '' + ${pkgs.shared_mime_info}/bin/update-mime-database $out/share/mime + '' + else ""; }; }; diff --git a/system/system.nix b/system/system.nix index 78b6a0a6deee..570ba91c96f9 100644 --- a/system/system.nix +++ b/system/system.nix @@ -1,6 +1,7 @@ { platform ? __currentSystem , configuration , nixpkgsPath ? ../../nixpkgs +, nixpkgs ? null }: rec { @@ -24,7 +25,9 @@ rec { pkgs configComponents config; - pkgs = import "${nixpkgsPath}/pkgs/top-level/all-packages.nix" {system = platform;}; + pkgs = if nixpkgs == null then + import "${nixpkgsPath}/pkgs/top-level/all-packages.nix" {system = platform;} + else nixpkgs; manifests = config.installer.manifests; # exported here because nixos-rebuild uses it @@ -150,6 +153,7 @@ rec { pkgs.usbutils pkgs.utillinux pkgs.wirelesstools + (import ../helpers/info-wrapper.nix {inherit (pkgs) bash texinfo writeScriptBin;}) ] ++ pkgs.lib.optional config.services.bitlbee.enable pkgs.bitlbee ++ pkgs.lib.optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp diff --git a/upstart-jobs/acpid.nix b/upstart-jobs/acpid.nix new file mode 100644 index 000000000000..e2eb702bcd43 --- /dev/null +++ b/upstart-jobs/acpid.nix @@ -0,0 +1,83 @@ +{pkgs, config, ...}: + +let + + acpiConfDir = pkgs.runCommand "acpi-events" {} + '' + ensureDir $out + ${ + # Generate a .conf file for each event. (You can't have + # multiple events in one config file...) + let f = event: + '' + fn=$out/${event.name}.conf + echo "event=${event.event}" > $fn + echo "action=${pkgs.writeScript "${event.name}.sh" event.action}" >> $fn + ''; + in pkgs.lib.concatMapStrings f events + } + ''; + + events = [powerEvent lidEvent acEvent]; + + # Called when the power button is pressed. + powerEvent = + { name = "power-button"; + event = "button/power.*"; + action = + '' + #! ${pkgs.bash}/bin/sh + ''; + }; + + # Called when the laptop lid is opened/closed. + lidEvent = + { name = "lid"; + event = "button/lid.*"; + action = + '' + #! ${pkgs.bash}/bin/sh + + # Suspend to RAM if the lid is closed. (We also get this event + # when the lid just opened, in which case we obviously don't + # want to suspend again.) + if grep -q closed /proc/acpi/button/lid/LID/state; then + sync + echo mem > /sys/power/state + fi + ''; + }; + + # Called when the AC power is connected or disconnected. + acEvent = + { name = "ac-power"; + event = "ac_adapter.*"; + action = + '' + #! ${pkgs.bash}/bin/sh + + if grep -q "state:.*on-line" /proc/acpi/ac_adapter/AC/state; then + echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor + elif grep -q "state:.*off-line" /proc/acpi/ac_adapter/AC/state; then + echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor + fi + ''; + }; + +in + +{ + name = "acpid"; + + extraPath = [pkgs.acpid]; + + job = '' + description "ACPI daemon" + + start on udev + stop on shutdown + + respawn ${pkgs.acpid}/sbin/acpid --foreground --confdir ${acpiConfDir} + ''; + +} diff --git a/upstart-jobs/apache-httpd/tomcat-connector.nix b/upstart-jobs/apache-httpd/tomcat-connector.nix new file mode 100644 index 000000000000..f7662c9513f2 --- /dev/null +++ b/upstart-jobs/apache-httpd/tomcat-connector.nix @@ -0,0 +1,91 @@ +{config, pkgs, serverInfo}: + +let + workersProperties = pkgs.writeText "workers.properties" '' +# Define list of workers that will be used +# for mapping requests +# The configuration directives are valid +# for the mod_jk version 1.2.18 and later +# +worker.list=loadbalancer,status + +# Define Node1 +# modify the host as your host IP or DNS name. +worker.node1.port=8009 +worker.node1.host=localhost +worker.node1.type=ajp13 +worker.node1.lbfactor=1 + +# Load-balancing behaviour +worker.loadbalancer.type=lb +worker.loadbalancer.balance_workers=node1 + +# Status worker for managing load balancer +worker.status.type=status + ''; +in +{ + extraModules = [ + { name = "jk"; path = "${pkgs.tomcat_connectors}/modules/mod_jk.so"; } + ]; + + extraConfig = '' +# Where to find workers.properties +JkWorkersFile ${workersProperties} + +# Where to put jk logs +JkLogFile ${config.logDir}/mod_jk.log + +# Set the jk log level [debug/error/info] +JkLogLevel info + +# Select the log format +JkLogStampFormat "[%a %b %d %H:%M:%S %Y]" + +# JkOptions indicates to send SSK KEY SIZE +# Note: Changed from +ForwardURICompat. +# See http://tomcat.apache.org/security-jk.html +JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories + +# JkRequestLogFormat +JkRequestLogFormat "%w %V %T" + +# Mount your applications +JkMount /__application__/* loadbalancer + +# You can use external file for mount points. +# It will be checked for updates each 60 seconds. +# The format of the file is: /url=worker +# /examples/*=loadbalancer +#JkMountFile uriworkermap.properties + +# Add shared memory. +# This directive is present with 1.2.10 and +# later versions of mod_jk, and is needed for +# for load balancing to work properly +# Note: Replaced JkShmFile logs/jk.shm due to SELinux issues. Refer to +# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=225452 +JkShmFile ${config.stateDir}/jk.shm + +# Static files in all Tomcat webapp context directories are served by apache +JkAutoAlias /var/tomcat/webapps + +# All requests go to worker by default +JkMount /* loadbalancer +# Serve some static files using httpd +#JkUnMount /*.html loadbalancer +#JkUnMount /*.jpg loadbalancer +#JkUnMount /*.gif loadbalancer +#JkUnMount /*.css loadbalancer +#JkUnMount /*.png loadbalancer +#JkUnMount /*.js loadbalancer + +# Add jkstatus for managing runtime data + +JkMount status +Order deny,allow +Deny from all +Allow from 127.0.0.1 + + ''; +} diff --git a/upstart-jobs/cupsd.nix b/upstart-jobs/cupsd.nix index 1afd9aae4c28..ced164a13088 100644 --- a/upstart-jobs/cupsd.nix +++ b/upstart-jobs/cupsd.nix @@ -1,4 +1,4 @@ -{config, pkgs}: +{config, pkgs, modprobe}: let @@ -16,23 +16,34 @@ let bindir = pkgs.runCommand "cups-progs" {} '' ensureDir $out/lib/cups ln -s ${cups}/lib/cups/* $out/lib/cups/ - + + # Provide support for printing via SMB. rm $out/lib/cups/backend ensureDir $out/lib/cups/backend ln -s ${cups}/lib/cups/backend/* $out/lib/cups/backend/ ln -s ${pkgs.samba}/bin/smbspool $out/lib/cups/backend/smb + + # Provide Ghostscript rasterisation, necessary for non-Postscript + # printers. + rm $out/lib/cups/filter + ensureDir $out/lib/cups/filter + ln -s ${cups}/lib/cups/filter/* $out/lib/cups/filter/ + ln -s ${pkgs.ghostscript}/lib/cups/filter/* $out/lib/cups/filter/ ''; # */ cupsdConfig = pkgs.writeText "cupsd.conf" '' - LogLevel info + LogLevel debug SystemGroup root Listen localhost:631 Listen /var/run/cups/cups.sock - ServerRoot ${cups}/etc/cups + # Note: we can't use ${cups}/etc/cups as the ServerRoot, since + # CUPS will write in the ServerRoot when e.g. adding new printers + # through the web interface. + ServerRoot /etc/cups ServerBin ${bindir}/lib/cups @@ -93,8 +104,16 @@ in { name = "cupsd"; - extraPath = [ - cups + extraPath = [cups]; + + extraEtc = [ + # CUPS expects the following files in its ServerRoot. + { source = "${cups}/etc/cups/mime.convs"; + target = "cups/mime.convs"; + } + { source = "${cups}/etc/cups/mime.types"; + target = "cups/mime.types"; + } ]; job = '' @@ -107,6 +126,9 @@ in mkdir -m 0755 -p ${logDir} mkdir -m 0700 -p /var/cache/cups mkdir -m 0700 -p /var/spool/cups + + # Make USB printers show up. + ${modprobe}/sbin/modprobe usblp || true end script respawn ${cups}/sbin/cupsd -c ${cupsdConfig} -F diff --git a/upstart-jobs/default.nix b/upstart-jobs/default.nix index f66d11066229..ea5d8fcdbe02 100644 --- a/upstart-jobs/default.nix +++ b/upstart-jobs/default.nix @@ -326,7 +326,7 @@ let # CUPS (printing) daemon. ++ optional config.services.printing.enable (import ../upstart-jobs/cupsd.nix { - inherit config pkgs; + inherit config pkgs modprobe; }) # Gateway6 @@ -360,6 +360,12 @@ let inherit (config.services.bitlbee) portNumber interface; }) + # ACPI daemon. + ++ optional config.powerManagement.enable + (import ../upstart-jobs/acpid.nix { + inherit config pkgs; + }) + # Postfix mail server. ++ optional config.services.postfix.enable (import ../upstart-jobs/postfix.nix { diff --git a/upstart-jobs/guest-users.nix b/upstart-jobs/guest-users.nix new file mode 100644 index 000000000000..bfd83619c0e6 --- /dev/null +++ b/upstart-jobs/guest-users.nix @@ -0,0 +1,76 @@ +{pkgs, config, ...}: +let + inherit(pkgs.lib) mkOption; + + options = { + services = { + guestUsers = { + enable = mkOption { + default = false; + description = " + Whether to enable automatic addition of users with empty passwords + "; + }; + users = mkOption { + default = ["guest"]; + description = " + List of usernames to add + "; + }; + includeRoot = mkOption { + default = false; + description = " + LEAVE THAT ALONE; whether to reset root password + "; + }; + extraGroups = mkOption { + default = ["audio"]; + description = " + Extra groups to grant + "; + }; + }; + }; + }; + inherit (pkgs.lib) concatStringsSep optional optionalString; + + inherit (config.services.guestUsers) enable users includeRoot extraGroups; + + userEntry = user: + { + name = user; + description = "NixOS guest user"; + home = "/home/${user}"; + createHome = true; + group = "users"; + extraGroups = extraGroups; + shell = "/bin/sh"; + }; + + nameString = (concatStringsSep " " users) + optionalString includeRoot " root"; + +in + +{ + require = options; + services = { + extraJobs = optional enable { + name = "clear-passwords"; + job = '' + description "Clear guest passwords" + start on startup + script + for i in ${nameString}; do + echo | ${pkgs.pwdutils}/bin/passwd --stdin $i + done + end script + ''; + }; + mingetty = { + helpLine = optionalString enable "\nThis users have empty passwords: ${nameString}"; + }; + }; + users = { + extraUsers = map userEntry users; + }; +} diff --git a/upstart-jobs/hal.nix b/upstart-jobs/hal.nix index 181341fdcf4c..e510120a04de 100644 --- a/upstart-jobs/hal.nix +++ b/upstart-jobs/hal.nix @@ -44,7 +44,9 @@ let job = '' description "HAL daemon" - start on dbus + # !!! TODO: make sure that HAL starts after acpid, + # otherwise hald-addon-acpi will grab /proc/acpi/event. + start on ${if config.powerManagement.enable then "acpid" else "dbus"} stop on shutdown start script diff --git a/upstart-jobs/manual.nix b/upstart-jobs/manual.nix new file mode 100644 index 000000000000..c515e95d3ddf --- /dev/null +++ b/upstart-jobs/manual.nix @@ -0,0 +1,87 @@ +{pkgs, config, ...}: + +# Show the NixOS manual on tty7 +# Originally used only by installation CD + +let + inherit (pkgs.lib) mkOption; + options = { + services = { + showManual = { + enable = mkOption { + default = false; + description = " + Whether to show the NixOS manual on the tty7 + "; + }; + ttyNumber = mkOption { + default = "7"; + description = " + TTY number name to show the manual on + "; + }; + browserPackage = mkOption { + default = pkgs.w3m; + description = " + Package containing the browser to be used + "; + }; + browserCommand = mkOption { + default = "bin/w3m"; + description = " + Command (command path is relative to browserPackage) to run the browser + "; + }; + manualFile = mkOption { + default = null; + description = " + NixOS manual HTML file + "; + }; + }; + }; + }; + +inherit(pkgs.lib) optional; + +inherit (config.services.showManual) enable ttyNumber browserPackage browserCommand + manualFile; + +realManualFile = if manualFile == null then + (import ../doc/manual {nixpkgs = pkgs;})+"/manual.html" +else manualFile; + +in + +{ + require = [ + options + ]; + + boot = { + extraTTYs = optional enable ttyNumber; + }; + + services = { + extraJobs = optional enable { + name = "showManual"; + + job = '' + description "NixOS manual" + + start on udev + stop on shutdown + respawn ${browserPackage}/${browserCommand} ${realManualFile} < /dev/tty${toString ttyNumber} > /dev/tty${toString ttyNumber} 2>&1 + ''; + }; + ttyBackgrounds = { + specificThemes = optional enable { + tty = ttyNumber; + theme = pkgs.themes "green"; + }; + }; + mingetty = { + helpLine = if enable then "\nPress for NixOS manual." else ""; + }; + }; +} diff --git a/upstart-jobs/mingetty.nix b/upstart-jobs/mingetty.nix index 1d821e789b76..8f50ea5c9db2 100644 --- a/upstart-jobs/mingetty.nix +++ b/upstart-jobs/mingetty.nix @@ -3,7 +3,7 @@ { name = "tty" + toString ttyNumber; job = " - start on startup + start on udev stop on shutdown respawn ${mingetty}/sbin/mingetty --loginprog=${loginProgram} --noclear tty${toString ttyNumber} "; diff --git a/upstart-jobs/pulseaudio.nix b/upstart-jobs/pulseaudio.nix new file mode 100644 index 000000000000..173f96db7fc4 --- /dev/null +++ b/upstart-jobs/pulseaudio.nix @@ -0,0 +1,94 @@ +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + uid = (import ../system/ids.nix).uids.pulseaudio; + gid = (import ../system/ids.nix).gids.pulseaudio; + + options = { + services = { + pulseaudio = { + enable = mkOption { + default = false; + description = '' + Whether to enable the PulseAudio system-wide audio server. + Note that the documentation recommends running PulseAudio + daemons per-user rather than system-wide on desktop machines. + ''; + }; + + logLevel = mkOption { + default = "notice"; + example = "debug"; + description = '' + A string denoting the log level: one of + error, warn, + notice, info, + or debug. + ''; + }; + }; + }; + }; +in + +###### implementation + +# For some reason, PulseAudio wants UID == GID. +assert uid == gid; + +mkIf config.services.pulseaudio.enable { + require = [ + options + ]; + + environment = { + + extraPackages = + pkgs.lib.optional + (!config.environment.cleanStart) + pkgs.pulseaudio; + }; + + users = { + extraUsers = [ + { name = "pulse"; + inherit uid; + group = "pulse"; + description = "PulseAudio system-wide daemon"; + home = "/var/run/pulse"; + } + ]; + + extraGroups = [ + { name = "pulse"; + inherit gid; + } + ]; + }; + + services = { + extraJobs = [{ + name = "pulseaudio"; + + job = '' + description "PulseAudio system-wide server" + + start on startup + stop on shutdown + + start script + test -d /var/run/pulse || \ + ( mkdir -p --mode 755 /var/run/pulse && \ + chown pulse:pulse /var/run/pulse ) + end script + + respawn ${pkgs.pulseaudio}/bin/pulseaudio \ + --system --daemonize \ + --log-level="${config.services.pulseaudio.logLevel}" + ''; + }]; + }; +} diff --git a/upstart-jobs/rogue.nix b/upstart-jobs/rogue.nix new file mode 100644 index 000000000000..0306033adc0b --- /dev/null +++ b/upstart-jobs/rogue.nix @@ -0,0 +1,64 @@ +{pkgs, config, ...}: + +# Show rogue game on tty8 +# Originally used only by installation CD + +let + inherit (pkgs.lib) mkOption; + options = { + services = { + rogue = { + enable = mkOption { + default = false; + description = " + Whether to run rogue + "; + }; + ttyNumber = mkOption { + default = "8"; + description = " + TTY number name to show the manual on + "; + }; + }; + }; + }; + +inherit (pkgs.lib) optional; + +inherit (config.services.rogue) enable ttyNumber; + +in + +{ + require = [ + options + ]; + + boot = { + extraTTYs = optional enable ttyNumber; + }; + + services = { + extraJobs = optional enable { + name = "rogue"; + + job = '' + description "rogue game" + + start on udev + stop on shutdown + respawn ${pkgs.rogue}/bin/rogue < /dev/tty${toString ttyNumber} > /dev/tty${toString ttyNumber} 2>&1 + ''; + }; + ttyBackgrounds = { + specificThemes = optional enable { + tty = ttyNumber; + theme = pkgs.themes "theme-gnu"; + }; + }; + mingetty = { + helpLine = if enable then "\nPress to play rogue." else ""; + }; + }; +} diff --git a/upstart-jobs/tomcat.nix b/upstart-jobs/tomcat.nix index ad4736386d9a..233da6abe384 100644 --- a/upstart-jobs/tomcat.nix +++ b/upstart-jobs/tomcat.nix @@ -99,7 +99,7 @@ in end script - respawn ${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 1d' + respawn ${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' stop script echo "Stopping tomcat..." diff --git a/upstart-jobs/xserver/default.nix b/upstart-jobs/xserver/default.nix index 0a7a70c71750..501597c12f21 100644 --- a/upstart-jobs/xserver/default.nix +++ b/upstart-jobs/xserver/default.nix @@ -297,6 +297,7 @@ let intel = { modules = [xorg.xf86videointel]; }; nv = { modules = [xorg.xf86videonv]; }; ati = { modules = [xorg.xf86videoati]; }; + via = { modules = [xorg.xf86videovia]; }; }; # Get a bunch of user settings. @@ -545,7 +546,9 @@ mkIf cfg.enable { } ${cfg.displayManager.job.beforeScript} - + + rm -f /tmp/.X0-lock + end script ${cfg.displayManager.job.env} diff --git a/upstart-jobs/xserver/desktopManager/default.nix b/upstart-jobs/xserver/desktopManager/default.nix index ab1271e69aed..7ea495716984 100644 --- a/upstart-jobs/xserver/desktopManager/default.nix +++ b/upstart-jobs/xserver/desktopManager/default.nix @@ -10,6 +10,7 @@ in { require = [ (import ./kde.nix) + (import ./kde4.nix) (import ./gnome.nix) (import ./xterm.nix) (import ./none.nix) diff --git a/upstart-jobs/xserver/desktopManager/kde4.nix b/upstart-jobs/xserver/desktopManager/kde4.nix new file mode 100644 index 000000000000..d7d91812a5da --- /dev/null +++ b/upstart-jobs/xserver/desktopManager/kde4.nix @@ -0,0 +1,68 @@ +{pkgs, config, ...}: + +let + inherit (pkgs.lib) mkOption mkIf; + cfg = config.services.xserver.desktopManager.kde; + xorg = config.services.xserver.package; + + options = { services = { xserver = { desktopManager = { + + kde4 = { + enable = mkOption { + default = false; + example = true; + description = "Enable the kde 4 desktop manager."; + }; + }; + + }; }; }; }; +in + +mkIf cfg.enable { + require = options; + + services = { + xserver = { + + desktopManager = { + session = [{ + name = "kde4"; + start = '' + # Start KDE. + exec ${pkgs.kde42.kdebase_workspace}/bin/startkde + ''; + }]; + }; + + }; + }; + + security = { + extraSetuidPrograms = [ + "kcheckpass" + ]; + }; + + environment = { + extraPackages = [ + xorg.xmessage # so that startkde can show error messages + pkgs.qt4 # needed for qdbus + pkgs.kde42.kdelibs + pkgs.kde42.kdebase + pkgs.kde42.kdebase_runtime + pkgs.kde42.kdebase_workspace + pkgs.kde42.kdegames + pkgs.shared_mime_info + xorg.xset # used by startkde, non-essential + ]; + + etc = [ + { source = ../../../etc/pam.d/kde; + target = "pam.d/kde"; + } + { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + target = "X11/xkb"; + } + ]; + }; +}