diff --git a/etc/default.nix b/etc/default.nix index de5d6bbd9add..53ab49d62bd7 100644 --- a/etc/default.nix +++ b/etc/default.nix @@ -1,20 +1,42 @@ -{ config, pkgs, systemPath, wrapperDir -, defaultShell -}: +# produce a script to generate /etc +{config, pkgs, ...}: -let - extraEtc = config.environment.etc; +###### interface +let + inherit (pkgs.lib) mkOption; + + option = { + environment = { + etc = mkOption { + default = []; + example = [ + { source = "/nix/store/.../etc/dir/file.conf.example"; + target = "dir/file.conf"; + mode = "0440"; + } + ]; + description = " + List of files that have to be linked in /etc. + "; + }; + }; + }; +in + +###### implementation +let nixEnvVars = config.nix.envVars; modulesTree = config.system.modulesTree; nssModulesPath = config.system.nssModules.path; - + wrapperDir = config.system.wrapperDir; + systemPath = config.system.path; 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} @@ -23,13 +45,7 @@ let pamConsolePerms = ./security/console.perms; - -in - - -import ../helpers/make-etc.nix { - inherit (pkgs) stdenv; - + # These should be moved into the corresponding configuration files. configFiles = [ { # TCP/UDP port assignments. source = pkgs.iana_etc + "/etc/services"; @@ -68,7 +84,7 @@ import ../helpers/make-etc.nix { # You cannot login without it! source = ./login.defs; target = "login.defs"; - } + } { # Configuration for passwd and friends (e.g., hash algorithm # for /etc/passwd). @@ -79,7 +95,7 @@ import ../helpers/make-etc.nix { { # Configuration for useradd. source = pkgs.substituteAll { src = ./default/useradd; - inherit defaultShell; + defaultShell = config.system.shell; }; target = "default/useradd"; } @@ -246,7 +262,82 @@ import ../helpers/make-etc.nix { source = pkgs.writeText "odbcinst.ini" (pkgs.lib.concatStringsSep "\n" inis); target = "odbcinst.ini"; }) + ; +in - # Additional /etc files declared by Upstart jobs. - ++ extraEtc; +let + inherit (pkgs.stringsWithDeps) noDepEntry FullDepEntry PackEntry; + + activateLib = config.system.activationScripts.lib; + + copyScript = {source, target, mode ? "644", own ? "root.root"}: + assert target != "nixos"; '' + source="${source}" + target="/etc/${target}" + mkdir -p $(dirname "$target") + test -e "$target" && rm -f "$target" + cp "$source" "$target" + chown ${own} "$target" + chmod ${mode} "$target" + ''; + + makeEtc = import ../helpers/make-etc.nix { + inherit (pkgs) stdenv; + configFiles = configFiles ++ config.environment.etc; + }; +in + +{ + require = [ + option + + # config.system.build + (import ../system/system-options.nix) + + # config.system.activationScripts + (import ../system/activate-configuration.nix) + ]; + + system = { + build = { + etc = makeEtc; + }; + + activationScripts = { + etc = FullDepEntry '' + # Set up the statically computed bits of /etc. + staticEtc=/etc/static + rm -f $staticEtc + ln -s ${makeEtc}/etc $staticEtc + for i in $(cd $staticEtc && find * -type l); do + mkdir -p /etc/$(dirname $i) + rm -f /etc/$i + if test -e "$staticEtc/$i.mode"; then + # Create a regular file in /etc. + cp $staticEtc/$i /etc/$i + chown 0.0 /etc/$i + chmod "$(cat "$staticEtc/$i.mode")" /etc/$i + else + # Create a symlink in /etc. + ln -s $staticEtc/$i /etc/$i + fi + done + + # Remove dangling symlinks that point to /etc/static. These are + # configuration files that existed in a previous configuration but not + # in the current one. For efficiency, don't look under /etc/nixos + # (where all the NixOS sources live). + for i in $(find /etc/ \( -path /etc/nixos -prune \) -o -type l); do + target=$(readlink "$i") + if test "''${target:0:''${#staticEtc}}" = "$staticEtc" -a ! -e "$i"; then + rm -f "$i" + fi + done + '' [ + activateLib.systemConfig + activateLib.defaultPath # path to cp, chmod, chown + activateLib.stdio + ]; + }; + }; } diff --git a/system/activate-configuration.sh b/system/activate-configuration.sh index ea329ce23652..4d2bbc319af6 100644 --- a/system/activate-configuration.sh +++ b/system/activate-configuration.sh @@ -2,36 +2,6 @@ source @newActivationScript@ -# Set up the statically computed bits of /etc. -staticEtc=/etc/static -rm -f $staticEtc -ln -s @etc@/etc $staticEtc -for i in $(cd $staticEtc && find * -type l); do - mkdir -p /etc/$(dirname $i) - rm -f /etc/$i - if test -e "$staticEtc/$i.mode"; then - # Create a regular file in /etc. - cp $staticEtc/$i /etc/$i - chown 0.0 /etc/$i - chmod "$(cat "$staticEtc/$i.mode")" /etc/$i - else - # Create a symlink in /etc. - ln -s $staticEtc/$i /etc/$i - fi -done - - -# Remove dangling symlinks that point to /etc/static. These are -# configuration files that existed in a previous configuration but not -# in the current one. For efficiency, don't look under /etc/nixos -# (where all the NixOS sources live). -for i in $(find /etc/ \( -path /etc/nixos -prune \) -o -type l); do - target=$(readlink "$i") - if test "${target:0:${#staticEtc}}" = "$staticEtc" -a ! -e "$i"; then - rm -f "$i" - fi -done - # Create the required /bin/sh symlink; otherwise lots of things # (notably the system() function) won't work. diff --git a/system/options.nix b/system/options.nix index ce7667b2fa8a..be544d80677d 100644 --- a/system/options.nix +++ b/system/options.nix @@ -2853,20 +2853,6 @@ root ALL=(ALL) SETENV: ALL "; }; - # should be moved to etc/default.nix - etc = mkOption { - default = []; - example = [ - { source = "/nix/store/.../etc/dir/file.conf.example"; - target = "dir/file.conf"; - mode = "0440"; - } - ]; - description = " - List of files that have to be linked in /etc. - "; - }; - nix = mkOption { default = pkgs.nixUnstable; example = pkgs.nixCustomFun /root/nix.tar.gz; @@ -2916,6 +2902,9 @@ root ALL=(ALL) SETENV: ALL (import ../system/activate-configuration.nix) (import ../upstart-jobs/default.nix) + # environment + (import ../etc/default.nix) + # newtworking (import ../upstart-jobs/dhclient.nix) diff --git a/system/system-options.nix b/system/system-options.nix index 1924db9aec89..0514e87dc67a 100644 --- a/system/system-options.nix +++ b/system/system-options.nix @@ -1,6 +1,76 @@ # this file contains all extendable options originally defined in system.nix {pkgs, config, ...}: +###### interface +let + inherit (pkgs.lib) mkOption; + + option = { + system = { + build = mkOption { + default = {}; + description = '' + Attribute set of derivation used to setup the system. The system + is built by aggregating all derivations. + ''; + apply = components: components // { + # all components have to build directories + result = pkgs.buildEnv { + name = "system"; + paths = pkgs.lib.mapRecordFlatten (n: v: v) components; + }; + }; + }; + + shell = mkOption { + default = "/var/run/current-system/sw/bin/bash"; + description = '' + You should not redefine this option unless you want to change the + bash version for security issues. + ''; + merge = list: + assert list != [] && builtins.tail list == []; + builtins.head list; + }; + + wrapperDir = mkOption { + default = "/var/setuid-wrappers"; + description = '' + You should not redefine this option unless you want to change the + path for security issues. + ''; + }; + + overridePath = mkOption { + default = []; + description = '' + You should not redefine this option unless you have trouble with a + package define in path. + ''; + }; + + path = mkOption { + default = []; + description = '' + The packages you want in the boot environment. + ''; + apply = list: pkgs.buildEnv { + name = "system-path"; + paths = config.system.overridePath ++ list; + + # Note: We need `/lib' to be among `pathsToLink' for NSS modules + # to work. + inherit (config.environment) pathsToLink; + + ignoreCollisions = true; + }; + }; + + }; + }; +in + +###### implementation let inherit (pkgs.stringsWithDeps) noDepEntry FullDepEntry PackEntry; @@ -9,6 +79,8 @@ in { require = [ + option + # config.system.activationScripts (import ../system/activate-configuration.nix) ]; diff --git a/system/system.nix b/system/system.nix index 5f05a4ddde88..cf0ec45a9e4f 100644 --- a/system/system.nix +++ b/system/system.nix @@ -8,6 +8,7 @@ rec { configComponents = [ configuration (import ./options.nix) + systemPathList ]; noOption = name: values: @@ -66,12 +67,9 @@ rec { # Environment variables for running Nix. nixEnvVars = config.nix.envVars; - + # The static parts of /etc. - etc = import ../etc/default.nix { - inherit config pkgs systemPath wrapperDir - defaultShell; - }; + etc = config.system.build.etc; # Font aggregation @@ -84,7 +82,7 @@ rec { # The wrapper setuid programs (since we can't have setuid programs # in the Nix store). - wrapperDir = "/var/setuid-wrappers"; + wrapperDir = config.system.wrapperDir; setuidWrapper = import ../helpers/setuid { inherit (pkgs) stdenv; @@ -99,100 +97,97 @@ rec { # The packages you want in the boot environment. - systemPathList = [ - # Better leave them here - they are small, needed, - # and hard to refer from anywhere outside. - modprobe # must take precedence over module_init_tools - mount # must take precedence over util-linux - nix - nixosTools.nixosInstall - nixosTools.nixosRebuild - nixosTools.nixosCheckout - nixosTools.nixosHardwareScan - nixosTools.nixosGenSeccureKeys - setuidWrapper - ] - ++ pkgs.lib.optionals (!config.environment.cleanStart) [ - pkgs.bashInteractive # bash with ncurses support - pkgs.bzip2 - pkgs.coreutils - pkgs.cpio - pkgs.curl - pkgs.e2fsprogs - pkgs.findutils - pkgs.glibc # for ldd, getent - pkgs.gnugrep - pkgs.gnused - pkgs.gnutar - pkgs.grub - pkgs.gzip - pkgs.iputils - pkgs.less - pkgs.lvm2 - pkgs.man - pkgs.mdadm - pkgs.module_init_tools - pkgs.nano - pkgs.ncurses - pkgs.netcat - pkgs.nettools - pkgs.ntp - pkgs.openssh - pkgs.pciutils - pkgs.perl - pkgs.procps - pkgs.pwdutils - pkgs.reiserfsprogs - pkgs.rsync - pkgs.seccureUser - pkgs.strace - pkgs.su - pkgs.sysklogd - pkgs.sysvtools - pkgs.time - pkgs.udev - pkgs.upstart - pkgs.usbutils - pkgs.utillinux - pkgs.wirelesstools - ] - ++ pkgs.lib.optional config.security.sudo.enable pkgs.sudo - ++ pkgs.lib.optional config.services.atd.enable pkgs.at - ++ pkgs.lib.optional config.services.bitlbee.enable pkgs.bitlbee - ++ pkgs.lib.optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp - ++ config.environment.extraPackages - ++ pkgs.lib.optional config.fonts.enableFontDir fontDir - ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007 + # This have to be split up. + systemPathList = { + system = { + overridePath = [ + # Better leave them here - they are small, needed, + # and hard to refer from anywhere outside. + modprobe # must take precedence over module_init_tools + mount # must take precedence over util-linux + nix + nixosTools.nixosInstall + nixosTools.nixosRebuild + nixosTools.nixosCheckout + nixosTools.nixosHardwareScan + nixosTools.nixosGenSeccureKeys + setuidWrapper + ]; + path = + pkgs.lib.optionals (!config.environment.cleanStart) [ + pkgs.bashInteractive # bash with ncurses support + pkgs.bzip2 + pkgs.coreutils + pkgs.cpio + pkgs.curl + pkgs.e2fsprogs + pkgs.findutils + pkgs.glibc # for ldd, getent + pkgs.gnugrep + pkgs.gnused + pkgs.gnutar + pkgs.grub + pkgs.gzip + pkgs.iputils + pkgs.less + pkgs.lvm2 + pkgs.man + pkgs.mdadm + pkgs.module_init_tools + pkgs.nano + pkgs.ncurses + pkgs.netcat + pkgs.nettools + pkgs.ntp + pkgs.openssh + pkgs.pciutils + pkgs.perl + pkgs.procps + pkgs.pwdutils + pkgs.reiserfsprogs + pkgs.rsync + pkgs.seccureUser + pkgs.strace + pkgs.su + pkgs.sysklogd + pkgs.sysvtools + pkgs.time + pkgs.udev + pkgs.upstart + pkgs.usbutils + pkgs.utillinux + pkgs.wirelesstools + ] + ++ pkgs.lib.optional config.security.sudo.enable pkgs.sudo + ++ pkgs.lib.optional config.services.atd.enable pkgs.at + ++ pkgs.lib.optional config.services.bitlbee.enable pkgs.bitlbee + ++ pkgs.lib.optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp + ++ config.environment.extraPackages + ++ pkgs.lib.optional config.fonts.enableFontDir fontDir + ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007 + + # NSS modules need to be in `systemPath' so that (i) the builder + # chroot gets to seem them, and (ii) applications can benefit from + # changes in the list of NSS modules at run-time, without requiring + # a reboot. + ++ nssModules; + }; + }; - # NSS modules need to be in `systemPath' so that (i) the builder - # chroot gets to seem them, and (ii) applications can benefit from - # changes in the list of NSS modules at run-time, without requiring - # a reboot. - ++ nssModules; - # We don't want to put all of `startPath' and `path' in $PATH, since # then we get an embarrassingly long $PATH. So use the user # environment builder to make a directory with symlinks to those # packages. - systemPath = pkgs.buildEnv { - name = "system-path"; - paths = systemPathList; - - # Note: We need `/lib' to be among `pathsToLink' for NSS modules - # to work. - inherit (config.environment) pathsToLink; - - ignoreCollisions = true; - }; + systemPath = config.system.path; usersGroups = import ./users-groups.nix { inherit pkgs config defaultShell; }; - defaultShell = "/var/run/current-system/sw/bin/bash"; + defaultShell = config.system.shell; + - # The script that activates the configuration, i.e., it sets up # /etc, accounts, etc. It doesn't do anything that can only be done # at boot time (such as start `init'). @@ -203,7 +198,7 @@ rec { newActivationScript = config.system.activationScripts.script; - inherit etc wrapperDir systemPath modprobe defaultShell kernel; + inherit wrapperDir systemPath modprobe defaultShell kernel; hostName = config.networking.hostName; setuidPrograms = config.security.setuidPrograms ++