diff --git a/default.nix b/default.nix index 3923cb9592b..1a621c3457e 100644 --- a/default.nix +++ b/default.nix @@ -42,13 +42,5 @@ in manifests = system.config.installer.manifests; # exported here because nixos-rebuild uses it - upstartJobsCombined = system.upstartJobs; - - # Make it easier to build individual Upstart jobs (e.g., "nix-build - # /etc/nixos/nixos -A upstartJobs.xserver"). - upstartJobs = { recurseForDerivations = true; } // - builtins.listToAttrs (map (job: - { name = if job ? jobName then job.jobName else job.name; value = job; } - ) system.upstartJobs.jobs); - + tests = system.config.tests; } diff --git a/doc/manual/development.xml b/doc/manual/development.xml index 3c48acfa57b..f4d68526c5e 100644 --- a/doc/manual/development.xml +++ b/doc/manual/development.xml @@ -51,7 +51,7 @@ where attr is an attribute in An attribute set containing the Upstart jobs. For instance, the sshd Upstart job can be built by doing nix-build /etc/nixos/nixos -A - upstartJobs.sshd. + tests.upstartJobs.sshd. diff --git a/etc/default.nix b/etc/default.nix index 6b8bc81503d..dd219dc74ef 100644 --- a/etc/default.nix +++ b/etc/default.nix @@ -1,4 +1,4 @@ -{ config, pkgs, upstartJobs, systemPath, wrapperDir +{ config, pkgs, systemPath, wrapperDir , defaultShell, extraEtc, nixEnvVars, modulesTree, nssModulesPath }: @@ -73,11 +73,6 @@ import ../helpers/make-etc.nix { target = "login.defs"; } - { # The Upstart events defined above. - source = upstartJobs + "/etc/event.d"; - target = "event.d"; - } - { # Configuration for passwd and friends (e.g., hash algorithm # for /etc/passwd). source = ./default/passwd; diff --git a/system/options.nix b/system/options.nix index 2d670e97200..014ae9da8bd 100644 --- a/system/options.nix +++ b/system/options.nix @@ -332,6 +332,92 @@ in }; + system = { + # NSS modules. Hacky! + nssModules = mkOption { + internal = true; + default = []; + description = " + Search path for NSS (Name Service Switch) modules. This allows + several DNS resolution methods to be specified via + /etc/nsswitch.conf. + "; + merge = pkgs.lib.mergeListOption; + apply = list: + let + list2 = + list + ++ pkgs.lib.optional config.users.ldap.enable pkgs.nss_ldap + ++ pkgs.lib.optional config.services.avahi.nssmdns pkgs.nssmdns; + in { + list = list2; + path = pkgs.lib.makeLibraryPath list2; + }; + }; + + modulesTree = mkOption { + internal = true; + default = []; + description = " + Tree of kernel modules. This includes the kernel, plus modules + built outside of the kernel. Combine these into a single tree of + symlinks because modprobe only supports one directory. + "; + merge = pkgs.lib.mergeListOption; + + # Convert the list of path to only one path. + apply = list: pkgs.aggregateModules ( + let + kernelPackages = config.boot.kernelPackages; + kernel = kernelPackages.kernel; + in + [ kernel ] + ++ pkgs.lib.optional ((config.networking.enableIntel3945ABGFirmware || config.networking.enableIntel4965AGNFirmware) && !kernel.features ? iwlwifi) kernelPackages.iwlwifi + # !!! this should be declared by the xserver Upstart job. + ++ pkgs.lib.optional (config.services.xserver.enable && config.services.xserver.videoDriver == "nvidia") kernelPackages.nvidiaDrivers + ++ 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. + ++ list + ); + }; + + sbin = { + modprobe = mkOption { + # should be moved in module-init-tools + internal = true; + default = pkgs.substituteAll { + dir = "sbin"; + src = ./modprobe; + isExecutable = true; + inherit (pkgs) module_init_tools; + inherit (config.system) modulesTree; + }; + description = " + Path to the modprobe binary used by the system. + "; + }; + + mount = mkOption { + internal = true; + default = pkgs.utillinux.passthru.function { + buildMountOnly = true; + mountHelpers = pkgs.buildEnv { + name = "mount-helpers"; + paths = [ + pkgs.ntfs3g + pkgs.mount_cifs + ]; + pathsToLink = "/sbin"; + } + "/sbin"; + }; + description = " + Install a special version of mount to search mount tools in + unusual path. + "; + }; + }; + }; # Hm, this sounds like a catch-all... hardware = { @@ -594,24 +680,6 @@ in services = { - - extraJobs = mkOption { - default = []; - example = [ - { name = "test-job"; - job = '' - description "nc" - start on started network-interfaces - respawn - env PATH=/var/run/current-system/sw/bin - exec sh -c "echo 'hello world' | ${pkgs.netcat}/bin/nc -l -p 9000" - ''; - } ]; - description = " - Additional Upstart jobs. - "; - }; - syslogd = { @@ -2659,6 +2727,36 @@ in "; }; + # Environment variables for running Nix. + envVars = mkOption { + internal = true; + default = ""; + description = " + Define the environment variables used by nix to + "; + + merge = pkgs.lib.mergeStringOption; + + # other option should be used to define the content instead of using + # the apply function. + apply = conf: '' + export NIX_CONF_DIR=/nix/etc/nix + + # Enable the copy-from-other-stores substituter, which allows builds + # to be sped up by copying build results from remote Nix stores. To + # do this, mount the remote file system on a subdirectory of + # /var/run/nix/remote-stores. + export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix + + '' + # */ + (if config.nix.distributedBuilds then + '' + export NIX_BUILD_HOOK=${config.environment.nix}/libexec/nix/build-remote.pl + export NIX_REMOTE_SYSTEMS=/etc/nix.machines + export NIX_CURRENT_LOAD=/var/run/nix/current-load + '' + else "") + conf; + }; }; @@ -3020,6 +3118,9 @@ root ALL=(ALL) SETENV: ALL }; require = [ + # system + (import ../upstart-jobs/default.nix) + # newtworking (import ../upstart-jobs/dhclient.nix) diff --git a/system/system.nix b/system/system.nix index eaa26cdea56..5e831f24425 100644 --- a/system/system.nix +++ b/system/system.nix @@ -36,19 +36,7 @@ rec { kernel = kernelPackages.kernel; - - # Tree of kernel modules. This includes the kernel, plus modules - # built outside of the kernel. We have to combine these into a - # single tree of symlinks because modprobe only supports one - # directory. - modulesTree = pkgs.aggregateModules ( - [kernel] - ++ pkgs.lib.optional ((config.networking.enableIntel3945ABGFirmware || config.networking.enableIntel4965AGNFirmware) && !kernel.features ? iwlwifi) kernelPackages.iwlwifi - # !!! this should be declared by the xserver Upstart job. - ++ pkgs.lib.optional (config.services.xserver.enable && config.services.xserver.videoDriver == "nvidia") kernelPackages.nvidiaDrivers - ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007 - ++ config.boot.extraModulePackages - ); + modulesTree = config.system.modulesTree; # The initial ramdisk. @@ -66,59 +54,24 @@ rec { # NSS modules. Hacky! - nssModules = - pkgs.lib.optional config.users.ldap.enable pkgs.nss_ldap - ++ pkgs.lib.optional config.services.avahi.nssmdns pkgs.nssmdns; + nssModules = config.system.nssModules.list; - nssModulesPath = pkgs.lib.concatStrings (pkgs.lib.intersperse ":" - (map (mod: mod + "/lib") nssModules)); + nssModulesPath = config.system.nssModules.path; # Wrapper around modprobe to set the path to the modules. - modprobe = pkgs.substituteAll { - dir = "sbin"; - src = ./modprobe; - isExecutable = true; - inherit (pkgs) module_init_tools; - inherit modulesTree; - }; + modprobe = config.system.sbin.modprobe; # Environment variables for running Nix. - nixEnvVars = - '' - export NIX_CONF_DIR=/nix/etc/nix - - # Enable the copy-from-other-stores substituter, which allows builds - # to be sped up by copying build results from remote Nix stores. To - # do this, mount the remote file system on a subdirectory of - # /var/run/nix/remote-stores. - export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix - - '' + # */ - (if config.nix.distributedBuilds then - '' - export NIX_BUILD_HOOK=${nix}/libexec/nix/build-remote.pl - export NIX_REMOTE_SYSTEMS=/etc/nix.machines - export NIX_CURRENT_LOAD=/var/run/nix/current-load - '' - else ""); + nixEnvVars = config.nix.envVars; - # The services (Upstart) configuration for the system. - upstartJobs = import ../upstart-jobs/default.nix { - inherit config pkgs nix modprobe nssModulesPath nixEnvVars - optionDeclarations kernelPackages mount; - }; - - # The static parts of /etc. etc = import ../etc/default.nix { - inherit config pkgs upstartJobs systemPath wrapperDir + inherit config pkgs systemPath wrapperDir defaultShell nixEnvVars modulesTree nssModulesPath; - extraEtc = - (pkgs.lib.concatLists (map (job: job.extraEtc) upstartJobs.jobs)) - ++ config.environment.etc; + extraEtc = config.environment.etc; }; @@ -143,18 +96,7 @@ rec { # A patched `mount' command that looks in a directory in the Nix # store instead of in /sbin for mount helpers (like mount.ntfs-3g or # mount.cifs). - mount = import "${nixpkgsPath}/pkgs/os-specific/linux/util-linux" { - inherit (pkgs) fetchurl stdenv; - buildMountOnly = true; - mountHelpers = pkgs.buildEnv { - name = "mount-helpers"; - paths = [ - pkgs.ntfs3g - pkgs.mount_cifs - ]; - pathsToLink = "/sbin"; - } + "/sbin"; - }; + mount = config.system.sbin.mount; # The packages you want in the boot environment. @@ -220,7 +162,6 @@ rec { ++ pkgs.lib.optional config.services.bitlbee.enable pkgs.bitlbee ++ pkgs.lib.optional config.services.avahi.enable pkgs.avahi ++ pkgs.lib.optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp - ++ pkgs.lib.concatLists (map (job: job.extraPath) upstartJobs.jobs) ++ config.environment.extraPackages ++ pkgs.lib.optional config.fonts.enableFontDir fontDir ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007 @@ -248,7 +189,7 @@ rec { }; - usersGroups = import ./users-groups.nix { inherit pkgs config upstartJobs defaultShell; }; + usersGroups = import ./users-groups.nix { inherit pkgs config defaultShell; }; defaultShell = "/var/run/current-system/sw/bin/bash"; diff --git a/system/users-groups.nix b/system/users-groups.nix index 7aeeddaa3a1..48c4db65bdf 100644 --- a/system/users-groups.nix +++ b/system/users-groups.nix @@ -1,4 +1,4 @@ -{pkgs, config, upstartJobs, defaultShell}: +{pkgs, config, defaultShell}: let ids = import ./ids.nix; in @@ -7,8 +7,6 @@ rec { # User accounts to be created/updated by NixOS. users = let - jobUsers = pkgs.lib.concatLists (map (job: job.users) upstartJobs.jobs); - defaultUsers = [ { name = "root"; @@ -46,14 +44,12 @@ rec { }: { inherit name description uid group extraGroups home shell createHome; }; - in map addAttrs (defaultUsers ++ jobUsers ++ nixBuildUsers ++ config.users.extraUsers); + in map addAttrs (defaultUsers ++ nixBuildUsers ++ config.users.extraUsers); # Groups to be created/updated by NixOS. groups = let - jobGroups = pkgs.lib.concatLists (map (job: job.groups) upstartJobs.jobs); - defaultGroups = [ { name = "root"; @@ -95,7 +91,7 @@ rec { { name, gid ? "" }: { inherit name gid; }; - in map addAttrs (defaultGroups ++ jobGroups ++ config.users.extraGroups); + in map addAttrs (defaultGroups ++ config.users.extraGroups); # Awful hackery necessary to pass the users/groups to the activation script. diff --git a/test/test-upstart-job.sh b/test/test-upstart-job.sh index 83af32e7956..86be01bf602 100755 --- a/test/test-upstart-job.sh +++ b/test/test-upstart-job.sh @@ -10,7 +10,7 @@ fi for i in $*; do echo "building job $i..." - nix-build /etc/nixos/nixos -A "upstartJobs.$i" -o $tmpDir/.result + nix-build /etc/nixos/nixos -A "tests.upstartJobs.$i" -o $tmpDir/.result ln -sfn $(readlink -f $tmpDir/.result)/etc/event.d/* /tmp/event.d/ done diff --git a/upstart-jobs/cron.nix b/upstart-jobs/cron.nix index 4220de6d647..0876f776f47 100644 --- a/upstart-jobs/cron.nix +++ b/upstart-jobs/cron.nix @@ -49,7 +49,7 @@ in { require = [ - # (import ../upstart-jobs/default.nix) # config.services.extraJobs + (import ../upstart-jobs/default.nix) # config.services.extraJobs # (import ?) # config.time.timeZone # (import ?) # config.environment.etc # (import ?) # config.environment.extraPackages diff --git a/upstart-jobs/default.nix b/upstart-jobs/default.nix index 6bc7cff9ceb..fce6b2520b3 100644 --- a/upstart-jobs/default.nix +++ b/upstart-jobs/default.nix @@ -1,6 +1,54 @@ -{config, pkgs, nix, modprobe, nssModulesPath, nixEnvVars, optionDeclarations, kernelPackages, mount}: +{config, pkgs}: -let +###### interface +let + inherit (pkgs.lib) mkOption; + + options = { + services = { + extraJobs = mkOption { + default = []; + example = [ + { name = "test-job"; + job = '' + description "nc" + start on started network-interfaces + respawn + env PATH=/var/run/current-system/sw/bin + exec sh -c "echo 'hello world' | ${pkgs.netcat}/bin/nc -l -p 9000" + ''; + } ]; + # should have some checks to everify the syntax + merge = pkgs.lib.mergeListOption; + description = " + Additional Upstart jobs. + "; + }; + }; + + tests = { + upstartJobs = mkOption { + internal = true; + default = {}; + description = " + Make it easier to build individual Upstart jobs. (e.g., + nix-build /etc/nixos/nixos -A + tests.upstartJobs.xserver). + "; + }; + }; + }; +in + +###### implementation +let + # should be moved to the corresponding jobs. + nix = config.environment.nix; + nixEnvVars = config.nix.envVars; + kernelPackages = config.boot.kernelPackages; + nssModulesPath = config.system.nssModules.path; + modprobe = config.system.sbin.modprobe; + mount = config.system.sbin.mount; makeJob = import ../upstart-jobs/make-job.nix { inherit (pkgs) runCommand; @@ -58,9 +106,7 @@ let then let v = (__getAttr name thisConfig); in if opt ? apply then opt.apply v else v else if opt ? default then opt.default else abort "you need to specify the configuration option ${errorWhere name}" else abort "unkown option ${errorWhere name}"; - checkConfig = (pkgs.lib.getAttr ["environment" "checkConfigurationOptions"] - optionDeclarations.environment.checkConfigurationOptions.default - config); + checkConfig = config.environment.checkConfigurationOptions; in # TODO: pass path to checker so it can show full path in the abort case pkgs.checker ( (jobFunc (args configV)).jobs ) checkConfig @@ -464,8 +510,43 @@ let # For the built-in logd job. ++ [(makeJob { jobDrv = pkgs.upstart; })]; + + command = import ../upstart-jobs/gather.nix { + inherit (pkgs) runCommand; + inherit jobs; + }; -in import ../upstart-jobs/gather.nix { - inherit (pkgs) runCommand; - inherit jobs; -} +in + +{ + require = [ + options + ]; + + environment = { + etc = [{ # The Upstart events defined above. + source = command + "/etc/event.d"; + target = "event.d"; + }] + ++ pkgs.lib.concatLists (map (job: job.extraEtc) jobs); + + extraPackages = + pkgs.lib.concatLists (map (job: job.extraPath) jobs); + }; + + users = { + extraUsers = + pkgs.lib.concatLists (map (job: job.users) jobs); + + extraGroups = + pkgs.lib.concatLists (map (job: job.groups) jobs); + }; + + tests = { + # see test/test-upstart-job.sh + upstartJobs = { recurseForDerivations = true; } // + builtins.listToAttrs (map (job: + { name = if job ? jobName then job.jobName else job.name; value = job; } + ) jobs); + }; +} \ No newline at end of file diff --git a/upstart-jobs/dhclient.nix b/upstart-jobs/dhclient.nix index 061af3d8f84..5be6c6c0e54 100644 --- a/upstart-jobs/dhclient.nix +++ b/upstart-jobs/dhclient.nix @@ -56,7 +56,7 @@ in { require = [ - # (import ../upstart-jobs/default.nix) + (import ../upstart-jobs/default.nix) options ];