diff --git a/boot/boot-stage-1-init.sh b/boot/boot-stage-1-init.sh index 0ddf6bb7eae..c6d7214028c 100644 --- a/boot/boot-stage-1-init.sh +++ b/boot/boot-stage-1-init.sh @@ -138,6 +138,26 @@ fi 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 () { + 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 + else + true + fi +} + # Function for mounting a file system. mountFS() { local device="$1" @@ -158,24 +178,29 @@ mountFS() { fi if test -n "$mustCheck"; then - FSTAB_FILE="/etc/mtab" fsck -V -v -C -a "$device" - fsckResult=$? + 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 | 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 | 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 + 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 # Mount read-writable. diff --git a/default.nix b/default.nix index 1a621c3457e..86f437d3696 100644 --- a/default.nix +++ b/default.nix @@ -1,6 +1,6 @@ let - fromEnv = name : default : + fromEnv = name: default: let env = builtins.getEnv name; in if env == "" then default else env; configuration = import (fromEnv "NIXOS_CONFIG" /etc/nixos/configuration.nix); diff --git a/doc/manual/default.nix b/doc/manual/default.nix index e6f9b84329f..a7f51adf287 100644 --- a/doc/manual/default.nix +++ b/doc/manual/default.nix @@ -38,6 +38,8 @@ let ${pkgs.docbook5_xsl}/xml/xsl/docbook/html/docbook.xsl \ ./manual.xml cp ${./style.css} $out/style.css + ensureDir $out/nix-support + echo "doc manual $out" >> $out/nix-support/hydra-build-products ''; }; diff --git a/doc/manual/manual.xml b/doc/manual/manual.xml index 55adf3e647d..9f79b6fdb6e 100644 --- a/doc/manual/manual.xml +++ b/doc/manual/manual.xml @@ -15,6 +15,7 @@ 2007 + 2008 Eelco Dolstra diff --git a/etc/default.nix b/etc/default.nix index 731558b67f2..fc07a39f9be 100644 --- a/etc/default.nix +++ b/etc/default.nix @@ -30,13 +30,12 @@ let nssModulesPath = config.system.nssModules.path; wrapperDir = config.system.wrapperDir; systemPath = config.system.path; + binsh = config.system.build.binsh; optional = pkgs.lib.optional; # !!! ugh, these files shouldn't be created here. - - pamConsoleHandlers = pkgs.writeText "console.handlers" '' console consoledevs /dev/tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9] ${pkgs.pam_console}/sbin/pam_console_apply lock logfail wait -t tty -s -c ${pamConsolePerms} @@ -131,14 +130,28 @@ let } { # Nix configuration. - source = pkgs.writeText "nix.conf" '' - # WARNING: this file is generated. - build-users-group = nixbld - build-max-jobs = ${toString (config.nix.maxJobs)} - build-use-chroot = ${if config.nix.useChroot then "true" else "false"} - build-chroot-dirs = /dev /dev/pts /proc /bin - ${config.nix.extraOptions} - ''; + source = + let + # Tricky: if we're using a chroot for builds, then we need + # /bin/sh in the chroot (our own compromise to purity). + # However, since /bin/sh is a symlink to some path in the + # Nix store, which furthermore has runtime dependencies on + # other paths in the store, we need the closure of /bin/sh + # in `build-chroot-dirs' - otherwise any builder that uses + # /bin/sh won't work. + refs = pkgs.writeReferencesToFile binsh; + in + pkgs.runCommand "nix.conf" {} '' + binshDeps=$(for i in $(cat ${refs}); do if test -d $i; then echo $i; fi; done) + cat > $out <> $out/nix-support/hydra-build-products + ''; # */ + + + }; + + +in jobs \ No newline at end of file diff --git a/system/options.nix b/system/options.nix index ad97565bb97..fbb316dc53a 100644 --- a/system/options.nix +++ b/system/options.nix @@ -301,7 +301,6 @@ in kernel = kernelPackages.kernel; in [ kernel ] - ++ pkgs.lib.optional ((config.networking.enableIntel3945ABGFirmware || config.networking.enableIntel4965AGNFirmware) && !kernel.features ? iwlwifi) kernelPackages.iwlwifi ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007 ++ config.boot.extraModulePackages # should only keep this one, other have to be set by the option owners. @@ -818,6 +817,13 @@ in no "; }; + + gatewayPorts = mkOption { + default = "no"; + description = " + Specifies whether remote hosts are allowed to connect to ports forwarded for the client. See man sshd_conf. + "; + }; }; lshd = { @@ -1255,9 +1261,11 @@ in default = []; example = [ "proxy_connect" { name = "php5_module"; path = "${pkgs.php}/modules/libphp5.so"; } ]; description = '' - Loads additional modules either beeing distributed with apache. - If the module is contained in a foreign package (such as php5_module) - kse an attrset as given in the example. + Specifies additional Apache modules. These can be specified + as a string in the case of modules distributed with Apache, + or as an attribute set specifying the + name and path of the + module. ''; }; @@ -1996,25 +2004,29 @@ in example = [ { type = "svn"; url = "https://svn.nixos.org/repos/nix/nixos/branches/stdenv-updates"; target = "/etc/nixos/nixos-stdenv-updates"; } { type = "git"; initialize = ''git clone git://mawercer.de/nixos $target''; update = "git pull origin"; target = "/etc/nixos/nixos-git"; } ]; - description = "The NixOS repository from which the system will be build. - nixos-checkout will update all working copies of the given repositories, - nixos-rebuild will use the first item which has - the attribute default = true falling back to the - first item. The type defines the repository tool added - to the path. It also defines a \"valid\" repository. - If the target directory already exists and it's not - valid it will be moved to the backup location - \${dir}-date. - For svn the default target and repositories are - /etc/nixos/nixos and - https://svn.nixos.org/repos/nix/nixos/trunk. - For git repositories update is called after - initialization when the repo is initialized. - The initialize code is run from working directory - dirname \$target and should create the directory - \$target. (git clone url nixos/nixpkgs/services should do) - For the executables beeing used see - "; + description = '' + The NixOS repository from which the system will be built. + nixos-checkout will update all working + copies of the given repositories, + nixos-rebuild will use the first item + which has the attribute default = true + falling back to the first item. The type defines the + repository tool added to the path. It also defines a "valid" + repository. If the target directory already exists and it's + not valid it will be moved to the backup location + dir-date. + For svn the default target and repositories are + /etc/nixos/nixos and + https://svn.nixos.org/repos/nix/nixos/trunk. + For git repositories update is called after initialization + when the repo is initialized. The initialize code is run + from working directory dirname + target and should create the + directory + dir. (git + clone url nixos/nixpkgs/services should do) For + the executables used see . + ''; }; nixpkgs = mkOption { @@ -2029,12 +2041,17 @@ in }; repoTypes = mkOption { - default = { - svn = { valid = "[ -d .svn ]"; env = [ pkgs.coreutils pkgs.subversion ]; }; - git = { valid = "[ -d .git ]"; env = [ pkgs.coreutils pkgs.git pkgs.gnused /* FIXME: use full path to sed in nix-pull */ ]; }; - }; - description = "defines PATH environment and when directory is considered beeing a valid repository. - If it's not it's moved to a backup directory"; + default = { + svn = { valid = "[ -d .svn ]"; env = [ pkgs.coreutils pkgs.subversion ]; }; + git = { valid = "[ -d .git ]"; env = [ pkgs.coreutils pkgs.git pkgs.gnused /* FIXME: use full path to sed in nix-pull */ ]; }; + }; + description = '' + Defines, for each supported version control system + (e.g. git), the dependencies for the + mechanism, as well as a test used to determine whether a + directory is a checkout created by that version control + system. + ''; }; manifests = mkOption { @@ -2423,6 +2440,7 @@ in (import ../upstart-jobs/zabbix-server.nix) (import ../upstart-jobs/disnix.nix) (import ../upstart-jobs/cron.nix) + (import ../upstart-jobs/fcron.nix) (import ../upstart-jobs/cron/locate.nix) # fonts diff --git a/system/system-options.nix b/system/system-options.nix index 650a08e0a76..97a9e05d4f5 100644 --- a/system/system-options.nix +++ b/system/system-options.nix @@ -88,6 +88,10 @@ in ]; system = { + build = { + binsh = pkgs.bashInteractive; + }; + activationScripts = { systemConfig = noDepEntry '' systemConfig="$1" @@ -122,7 +126,7 @@ in # Create the required /bin/sh symlink; otherwise lots of things # (notably the system() function) won't work. mkdir -m 0755 -p $mountPoint/bin - ln -sfn ${pkgs.bash}/bin/sh $mountPoint/bin/sh + ln -sfn ${config.system.build.binsh}/bin/sh $mountPoint/bin/sh '' [ activateLib.defaultPath # path to ln & mkdir activateLib.stdio # ? diff --git a/system/system.nix b/system/system.nix index 0eb86cc857d..75087708b83 100644 --- a/system/system.nix +++ b/system/system.nix @@ -184,6 +184,9 @@ rec { # at boot time (such as start `init'). activateConfiguration = config.system.activationScripts.script; + # The shell that we want to use for /bin/sh. + binsh = pkgs.bashInteractive; + # The init script of boot stage 2, which is supposed to do # everything else to bring up the system. diff --git a/upstart-jobs/atd.nix b/upstart-jobs/atd.nix index b477a38eee4..cfdbeb67915 100644 --- a/upstart-jobs/atd.nix +++ b/upstart-jobs/atd.nix @@ -19,7 +19,8 @@ let default = false; description = '' Whether to make /var/spool/at{jobs,spool} writeable - by everyone (and sticky). + by everyone (and sticky). This is normally not needed since + the `at' commands are setuid/setgid `atd'. ''; }; }; @@ -74,7 +75,7 @@ start script if [ ! -f "$etcdir"/at.deny ] then touch "$etcdir"/at.deny && \ - chown root:root "$etcdir"/at.deny && \ + chown root:atd "$etcdir"/at.deny && \ chmod 640 "$etcdir"/at.deny fi if [ ! -f "$jobdir"/.SEQ ] @@ -107,9 +108,13 @@ mkIf cfg.enable { ]; security = { - extraSetuidPrograms = [ - "at" "atq" "atrm" - ]; + setuidOwners = map (program: { + inherit program; + owner = "atd"; + group = "atd"; + setuid = true; + setgid = true; + }) [ "at" "atq" "atrm" ]; }; environment = { diff --git a/upstart-jobs/default.nix b/upstart-jobs/default.nix index f0862aaddec..3633dee63e7 100644 --- a/upstart-jobs/default.nix +++ b/upstart-jobs/default.nix @@ -150,7 +150,7 @@ let firmwareDirs = pkgs.lib.optional config.networking.enableIntel2200BGFirmware pkgs.ipw2200fw ++ pkgs.lib.optional config.networking.enableIntel3945ABGFirmware pkgs.iwlwifi3945ucode - ++ pkgs.lib.optional config.networking.enableIntel4965AGNFirmware pkgs.iwlwifi4965ucode + ++ pkgs.lib.optional config.networking.enableIntel4965AGNFirmware kernelPackages.iwlwifi4965ucode ++ pkgs.lib.optional config.networking.enableZydasZD1211Firmware pkgs.zd1211fw ++ pkgs.lib.optional config.hardware.enableGo7007 "${kernelPackages.wis_go7007}/firmware" ++ config.services.udev.addFirmware; @@ -239,9 +239,7 @@ let inherit (pkgs) writeText openssh glibc; inherit (pkgs.xorg) xauth; inherit nssModulesPath; - forwardX11 = config.services.sshd.forwardX11; - allowSFTP = config.services.sshd.allowSFTP; - permitRootLogin = config.services.sshd.permitRootLogin; + inherit (config.services.sshd) forwardX11 allowSFTP permitRootLogin gatewayPorts; }) # GNU lshd SSH2 deamon. diff --git a/upstart-jobs/fcron.nix b/upstart-jobs/fcron.nix new file mode 100644 index 00000000000..97d259c65e1 --- /dev/null +++ b/upstart-jobs/fcron.nix @@ -0,0 +1,138 @@ +{pkgs, config}: + +###### interface +let + inherit (pkgs.lib) mkOption concatStringsSep; + inherit (pkgs) writeText; + + options = { + services = { + fcron = { + enable = mkOption { + default = false; + description = ''Whether to enable the `fcron' daemon. + From its docs: "fcron does both the job of Vixie Cron and anacron, but does even more and better". + It can trigger actions even if the event has passed due to shutdown for example. + TODO: add supoprt for fcron.allow and fcron.deny + Of course on cron daemon is enough.. So if fcron works fine there should be a system option systemCron="fcron or cron" + + There are (or have been) some security issues. + I haven't yet checked wether they have been resolved. + For now you should trust the users registering crontab files. + I think gentoo has them listed. + ''; + }; + allow = mkOption { + default = []; + description = '' + Users allowed to use fcrontab and fcrondyn (one name per line, special name "all" acts for everyone) + nix adds username "root" for you. + ''; + }; + deny = mkOption { + default = []; + description = " same as allow but deny "; + }; + maxSerialJobs = mkOption { + default = 1; + description = "maximum number of serial jobs which can run simultaneously (-m)"; + }; + queuelen = mkOption { + default = ""; + description = "number of jobs the serial queue and the lavg queue can contain - empty to net set this number (-q)"; + }; + systab = mkOption { + default = ""; + description = '' + The "system" crontab contents.. + ''; + }; + }; + }; + }; +in + +###### implementation +let + # Put all the system cronjobs together. + # TODO allow using fcron only.. + #systemCronJobs = + # config.services.cron.systemCronJobs; + cfg = config.services.fcron; + ifEnabled = if cfg.enable then pkgs.lib.id else (x : []); + queuelen = if cfg.queuelen == "" then "" else "-q ${toString cfg.queuelen}"; + + # shell is set to /sh in config.. + # ${pkgs.lib.concatStrings (map (job: job + "\n") systemCronJobs)} + systemCronJobsFile = pkgs.writeText "fcron-systab" '' + SHELL=${pkgs.bash}/bin/sh + PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin + ''; + + allowdeny = target: users : { + source = writeText "fcron.${target}" (concatStringsSep "\n" users); + target = "fcron.${target}"; + mode = "600"; # fcron has some security issues.. So I guess this is most safe + }; + +in + +{ + require = [ + # (import ../upstart-jobs/default.nix) # config.services.extraJobs + # (import ?) # config.time.timeZone + # (import ?) # config.environment.etc + # (import ?) # config.environment.extraPackages + # (import ?) # config.environment.cleanStart + options + ]; + + environment = { + etc = ifEnabled [ + (allowdeny "allow" (["root"] ++ cfg.allow)) + (allowdeny "deny" cfg.deny) + # see man 5 fcron.conf + { source = writeText "fcon.conf" '' + fcrontabs = /var/spool/fcron + pidfile = /var/run/fcron.pid + fifofile = /var/run/fcron.fifo + fcronallow = /etc/fcron.allow + fcrondeny = /etc/fcron.deny + shell = /bin/sh + sendmail = /var/setuid-wrappers/sendmail + editor = /var/run/current-system/sw/bin/vi + ''; + target = "fcron.conf"; + mode = "0600"; # max allowed is 644 + } + ]; + + extraPackages = ifEnabled ( + pkgs.lib.optional + (!config.environment.cleanStart) + pkgs.fcron); + }; + + services = { + extraJobs = ifEnabled [{ + name = "fcron"; + + job = '' + description "fcron daemon" + + start on startup + stop on shutdown + + env PATH=/var/run/current-system/sw/bin + + start script + ${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron + # load system crontab file + ${pkgs.fcron}/bin/fcrontab -u systab ${writeText "systab" cfg.systab} + end script + + respawn ${pkgs.fcron}/sbin/fcron -f -m ${toString cfg.maxSerialJobs} ${queuelen} + ''; + }]; + }; +} diff --git a/upstart-jobs/lshd.nix b/upstart-jobs/lshd.nix index e2a61eed387..0a13d9ba7ee 100644 --- a/upstart-jobs/lshd.nix +++ b/upstart-jobs/lshd.nix @@ -31,6 +31,7 @@ start script end script respawn ${lsh}/sbin/lshd --daemonic \ + --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ -p ${toString portNumber} \ ${if interfaces == [] then "" else (concatStrings (map (i: "--interface=\"${i}\"") diff --git a/upstart-jobs/sshd.nix b/upstart-jobs/sshd.nix index c64c4eb49a5..e9b916e81d3 100644 --- a/upstart-jobs/sshd.nix +++ b/upstart-jobs/sshd.nix @@ -1,6 +1,6 @@ { writeText, openssh, glibc, xauth , nssModulesPath -, forwardX11, allowSFTP, permitRootLogin +, forwardX11, allowSFTP, permitRootLogin, gatewayPorts }: assert permitRootLogin == "yes" || @@ -29,6 +29,7 @@ let "} PermitRootLogin ${permitRootLogin} + GatewayPorts ${gatewayPorts} ''; diff --git a/upstart-jobs/xserver.nix b/upstart-jobs/xserver.nix index 231bcd943ad..0e204282c14 100644 --- a/upstart-jobs/xserver.nix +++ b/upstart-jobs/xserver.nix @@ -183,6 +183,10 @@ let default = "0.12"; description = "Cursor speed factor for highest-speed finger motion"; }; + twoFingerScroll = mkOption { + default = false; + description = "Whether to enable two-finger drag-scrolling"; + }; }; layout = mkOption { @@ -413,6 +417,8 @@ let Option "TapButton1" "1" Option "TapButton2" "2" Option "TapButton3" "3" + Option "VertTwoFingerScroll" "${if cfg.synaptics.twoFingerScroll then "1" else "0"}" + Option "HorizTwoFingerScroll" "${if cfg.synaptics.twoFingerScroll then "1" else "0"}" EndSection '' else "";