Merge pull request #6794 from nbp/module-system-tweaks

Module system improvements
This commit is contained in:
Nicolas B. Pierron 2015-04-03 14:22:33 -07:00
commit 889f72bad4
20 changed files with 280 additions and 123 deletions

View File

@ -9,25 +9,69 @@ rec {
/* Evaluate a set of modules. The result is a set of two /* Evaluate a set of modules. The result is a set of two
attributes: options: the nested set of all option declarations, attributes: options: the nested set of all option declarations,
and config: the nested set of all option values. */ and config: the nested set of all option values.
evalModules = { modules, prefix ? [], args ? {}, check ? true }: !!! Please think twice before adding to this argument list! The more
that is specified here instead of in the modules themselves the harder
it is to transparently move a set of modules to be a submodule of another
config (as the proper arguments need to be replicated at each call to
evalModules) and the less declarative the module set is. */
evalModules = { modules
, prefix ? []
, # This would be remove in the future, Prefer _module.args option instead.
args ? {}
, # This would be remove in the future, Prefer _module.check option instead.
check ? true
}:
let let
args' = args // { lib = import ./.; } // result; # This internal module declare internal options under the `_module'
closed = closeModules modules args'; # attribute. These options are fragile, as they are used by the
# module system to change the interpretation of modules.
internalModule = rec {
_file = ./modules.nix;
key = _file;
options = {
_module.args = mkOption {
type = types.attrsOf types.unspecified;
internal = true;
description = "Arguments passed to each module.";
};
_module.check = mkOption {
type = types.uniq types.bool;
internal = true;
default = check;
description = "Whether to check whether all option definitions have matching declarations.";
};
};
config = {
_module.args = args;
};
};
closed = closeModules (modules ++ [ internalModule ]) { inherit config options; lib = import ./.; };
# Note: the list of modules is reversed to maintain backward # Note: the list of modules is reversed to maintain backward
# compatibility with the old module system. Not sure if this is # compatibility with the old module system. Not sure if this is
# the most sensible policy. # the most sensible policy.
options = mergeModules prefix (reverseList closed); options = mergeModules prefix (reverseList closed);
# Traverse options and extract the option values into the final # Traverse options and extract the option values into the final
# config set. At the same time, check whether all option # config set. At the same time, check whether all option
# definitions have matching declarations. # definitions have matching declarations.
# !!! _module.check's value can't depend on any other config values
# without an infinite recursion. One way around this is to make the
# 'config' passed around to the modules be unconditionally unchecked,
# and only do the check in 'result'.
config = yieldConfig prefix options; config = yieldConfig prefix options;
yieldConfig = prefix: set: yieldConfig = prefix: set:
let res = removeAttrs (mapAttrs (n: v: let res = removeAttrs (mapAttrs (n: v:
if isOption v then v.value if isOption v then v.value
else yieldConfig (prefix ++ [n]) v) set) ["_definedNames"]; else yieldConfig (prefix ++ [n]) v) set) ["_definedNames"];
in in
if check && set ? _definedNames then if options._module.check.value && set ? _definedNames then
fold (m: res: fold (m: res:
fold (name: res: fold (name: res:
if set ? ${name} then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.") if set ? ${name} then res else throw "The option `${showOption (prefix ++ [name])}' defined in `${m.file}' does not exist.")
@ -43,7 +87,7 @@ rec {
let let
toClosureList = file: parentKey: imap (n: x: toClosureList = file: parentKey: imap (n: x:
if isAttrs x || isFunction x then if isAttrs x || isFunction x then
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args) unifyModuleSyntax file "${parentKey}:anon-${toString n}" (unpackSubmodule applyIfFunction x args)
else else
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args)); unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
in in
@ -74,7 +118,39 @@ rec {
config = removeAttrs m ["key" "_file" "require" "imports"]; config = removeAttrs m ["key" "_file" "require" "imports"];
}; };
applyIfFunction = f: arg: if isFunction f then f arg else f; applyIfFunction = f: arg@{ config, options, lib }: if isFunction f then
let
# Module arguments are resolved in a strict manner when attribute set
# deconstruction is used. As the arguments are now defined with the
# config._module.args option, the strictness used on the attribute
# set argument would cause an infinite loop, if the result of the
# option is given as argument.
#
# To work-around the strictness issue on the deconstruction of the
# attributes set argument, we create a new attribute set which is
# constructed to satisfy the expected set of attributes. Thus calling
# a module will resolve strictly the attributes used as argument but
# not their values. The values are forwarding the result of the
# evaluation of the option.
requiredArgs = builtins.attrNames (builtins.functionArgs f);
extraArgs = builtins.listToAttrs (map (name: {
inherit name;
value = config._module.args.${name};
}) requiredArgs);
in f (extraArgs // arg)
else
f;
/* We have to pack and unpack submodules. We cannot wrap the expected
result of the function as we would no longer be able to list the arguments
of the submodule. (see applyIfFunction) */
unpackSubmodule = unpack: m: args:
if isType "submodule" m then
{ _file = m.file; } // (unpack m.submodule args)
else unpack m args;
packSubmodule = file: m:
{ _type = "submodule"; file = file; submodule = m; };
/* Merge a list of modules. This will recurse over the option /* Merge a list of modules. This will recurse over the option
declarations in all modules, combining them into a single set. declarations in all modules, combining them into a single set.
@ -106,12 +182,9 @@ rec {
else [] else []
) configs); ) configs);
nrOptions = count (m: isOption m.options) decls; nrOptions = count (m: isOption m.options) decls;
# Process mkMerge and mkIf properties. # Extract the definitions for this loc
defns' = concatMap (m: defns' = map (m: { inherit (m) file; value = m.config.${name}; })
if m.config ? ${name} (filter (m: m.config ? ${name}) configs);
then map (m': { inherit (m) file; value = m'; }) (dischargeProperties m.config.${name})
else []
) configs;
in in
if nrOptions == length decls then if nrOptions == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls); let opt = fixupOptionType loc (mergeOptionDecls loc decls);
@ -156,15 +229,12 @@ rec {
current option declaration as the file use for the submodule. If the current option declaration as the file use for the submodule. If the
submodule defines any filename, then we ignore the enclosing option file. */ submodule defines any filename, then we ignore the enclosing option file. */
options' = toList opt.options.options; options' = toList opt.options.options;
addModuleFile = m:
if isFunction m then args: { _file = opt.file; } // (m args)
else { _file = opt.file; } // m;
coerceOption = file: opt: coerceOption = file: opt:
if isFunction opt then args: { _file = file; } // (opt args) if isFunction opt then packSubmodule file opt
else { _file = file; options = opt; }; else packSubmodule file { options = opt; };
getSubModules = opt.options.type.getSubModules or null; getSubModules = opt.options.type.getSubModules or null;
submodules = submodules =
if getSubModules != null then map addModuleFile getSubModules ++ res.options if getSubModules != null then map (packSubmodule opt.file) getSubModules ++ res.options
else if opt.options ? options then map (coerceOption opt.file) options' ++ res.options else if opt.options ? options then map (coerceOption opt.file) options' ++ res.options
else res.options; else res.options;
in opt.options // res // in opt.options // res //
@ -177,27 +247,17 @@ rec {
config value. */ config value. */
evalOptionValue = loc: opt: defs: evalOptionValue = loc: opt: defs:
let let
# Process mkOverride properties, adding in the default # Add in the default value for this option, if any.
# value specified in the option declaration (if any). defs' = (optional (opt ? default)
defsFinal' = filterOverrides { file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;
((if opt ? default then [{ file = head opt.declarations; value = mkOptionDefault opt.default; }] else []) ++ defs);
# Sort mkOrder properties. # Handle properties, check types, and merge everything together
defsFinal = inherit (mergeDefinitions loc opt.type defs') isDefined defsFinal mergedValue;
# Avoid sorting if we don't have to.
if any (def: def.value._type or "" == "order") defsFinal'
then sortProperties defsFinal'
else defsFinal';
files = map (def: def.file) defsFinal; files = map (def: def.file) defsFinal;
# Type-check the remaining definitions, and merge them if
# possible.
merged = merged =
if defsFinal == [] then if isDefined then mergedValue
throw "The option `${showOption loc}' is used but not defined." else throw "The option `${showOption loc}' is used but not defined.";
else
fold (def: res:
if opt.type.check def.value then res
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${opt.type.name}.")
(opt.type.merge loc defsFinal) defsFinal;
# Finally, apply the apply function to the merged # Finally, apply the apply function to the merged
# value. This allows options to yield a value computed # value. This allows options to yield a value computed
# from the definitions. # from the definitions.
@ -205,8 +265,40 @@ rec {
in opt // in opt //
{ value = addErrorContext "while evaluating the option `${showOption loc}':" value; { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
definitions = map (def: def.value) defsFinal; definitions = map (def: def.value) defsFinal;
inherit isDefined files;
};
# Merge definitions of a value of a given type
mergeDefinitions = loc: type: defs: rec {
defsFinal =
let
# Process mkMerge and mkIf properties
processIfAndMerge = defs: concatMap (m:
map (value: { inherit (m) file; inherit value; }) (dischargeProperties m.value)
) defs;
# Process mkOverride properties
processOverride = defs: filterOverrides defs;
# Sort mkOrder properties
processOrder = defs:
# Avoid sorting if we don't have to.
if any (def: def.value._type or "" == "order") defs
then sortProperties defs
else defs;
in
processOrder (processOverride (processIfAndMerge defs));
# Type-check the remaining definitions, and merge them
mergedValue = fold (def: res:
if type.check def.value then res
else throw "The option value `${showOption loc}' in `${def.file}' is not a ${type.name}.")
(type.merge loc defsFinal) defsFinal;
isDefined = defsFinal != []; isDefined = defsFinal != [];
inherit files; optionalValue =
if isDefined then { value = mergedValue; }
else {};
}; };
/* Given a config set, expand mkMerge properties, and push down the /* Given a config set, expand mkMerge properties, and push down the

View File

@ -57,13 +57,17 @@ checkConfigError() {
fi fi
} }
# Check boolean option.
checkConfigOutput "false" config.enable ./declare-enable.nix checkConfigOutput "false" config.enable ./declare-enable.nix
checkConfigError 'The option .* defined in .* does not exist.' config.enable ./define-enable.nix checkConfigError 'The option .* defined in .* does not exist.' config.enable ./define-enable.nix
# Check mkForce without submodules.
set -- config.enable ./declare-enable.nix ./define-enable.nix set -- config.enable ./declare-enable.nix ./define-enable.nix
checkConfigOutput "true" "$@" checkConfigOutput "true" "$@"
checkConfigOutput "false" "$@" ./define-force-enable.nix checkConfigOutput "false" "$@" ./define-force-enable.nix
checkConfigOutput "false" "$@" ./define-enable-force.nix checkConfigOutput "false" "$@" ./define-enable-force.nix
# Check mkForce with option and submodules.
checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix
checkConfigOutput 'false' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix checkConfigOutput 'false' config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix
set -- config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo-enable.nix set -- config.loaOfSub.foo.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo-enable.nix
@ -73,6 +77,7 @@ checkConfigOutput 'false' "$@" ./define-loaOfSub-force-foo-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-force-enable.nix checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-force-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-force.nix checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-force.nix
# Check overriding effect of mkForce on submodule definitions.
checkConfigError 'attribute .*bar.* .* not found' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix checkConfigError 'attribute .*bar.* .* not found' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix
checkConfigOutput 'false' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar.nix checkConfigOutput 'false' config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar.nix
set -- config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar-enable.nix set -- config.loaOfSub.bar.enable ./declare-loaOfSub-any-enable.nix ./define-loaOfSub-foo.nix ./define-loaOfSub-bar-enable.nix
@ -82,6 +87,26 @@ checkConfigError 'attribute .*bar.* .* not found' "$@" ./define-loaOfSub-force-f
checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-force-enable.nix checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-force-enable.nix
checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-enable-force.nix checkConfigOutput 'true' "$@" ./define-loaOfSub-foo-enable-force.nix
# Check mkIf with submodules.
checkConfigError 'attribute .*foo.* .* not found' config.loaOfSub.foo.enable ./declare-enable.nix ./declare-loaOfSub-any-enable.nix
set -- config.loaOfSub.foo.enable ./declare-enable.nix ./declare-loaOfSub-any-enable.nix
checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-if-loaOfSub-foo-enable.nix
checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-loaOfSub-if-foo-enable.nix
checkConfigError 'attribute .*foo.* .* not found' "$@" ./define-loaOfSub-foo-if-enable.nix
checkConfigOutput 'false' "$@" ./define-loaOfSub-foo-enable-if.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-if-loaOfSub-foo-enable.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-if-foo-enable.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-if-enable.nix
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-enable-if.nix
# Check _module.args.
checkConfigOutput "true" config.enable ./declare-enable.nix ./custom-arg-define-enable.nix
# Check _module.check.
set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-loaOfSub-foo.nix
checkConfigError 'The option .* defined in .* does not exist.' "$@"
checkConfigOutput "true" "$@" ./define-module-check.nix
cat <<EOF cat <<EOF
====== module tests ====== ====== module tests ======
$pass Pass $pass Pass

View File

@ -0,0 +1,8 @@
{ lib, custom, ... }:
{
config = {
_module.args.custom = true;
enable = custom;
};
}

View File

@ -0,0 +1,5 @@
{ config, lib, ... }:
lib.mkIf config.enable {
loaOfSub.foo.enable = true;
}

View File

@ -0,0 +1,5 @@
{ config, lib, ... }:
{
loaOfSub.foo.enable = lib.mkIf config.enable true;
}

View File

@ -0,0 +1,7 @@
{ config, lib, ... }:
{
loaOfSub.foo = lib.mkIf config.enable {
enable = true;
};
}

View File

@ -0,0 +1,7 @@
{ config, lib, ... }:
{
loaOfSub = lib.mkIf config.enable {
foo.enable = true;
};
}

View File

@ -0,0 +1,3 @@
{
_module.check = false;
}

View File

@ -6,6 +6,7 @@ with import ./attrsets.nix;
with import ./options.nix; with import ./options.nix;
with import ./trivial.nix; with import ./trivial.nix;
with import ./strings.nix; with import ./strings.nix;
with {inherit (import ./modules.nix) mergeDefinitions; };
rec { rec {
@ -109,11 +110,15 @@ rec {
listOf = elemType: mkOptionType { listOf = elemType: mkOptionType {
name = "list of ${elemType.name}s"; name = "list of ${elemType.name}s";
check = value: isList value && all elemType.check value; check = isList;
merge = loc: defs: merge = loc: defs:
concatLists (imap (n: def: imap (m: def': map (x: x.value) (filter (x: x ? value) (concatLists (imap (n: def: imap (m: def':
elemType.merge (loc ++ ["[${toString n}-${toString m}]"]) (mergeDefinitions
[{ inherit (def) file; value = def'; }]) def.value) defs); (loc ++ ["[definition ${toString n}-entry ${toString m}]"])
elemType
[{ inherit (def) file; value = def'; }]
).optionalValue
) def.value) defs)));
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]); getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
getSubModules = elemType.getSubModules; getSubModules = elemType.getSubModules;
substSubModules = m: listOf (elemType.substSubModules m); substSubModules = m: listOf (elemType.substSubModules m);
@ -121,12 +126,14 @@ rec {
attrsOf = elemType: mkOptionType { attrsOf = elemType: mkOptionType {
name = "attribute set of ${elemType.name}s"; name = "attribute set of ${elemType.name}s";
check = x: isAttrs x && all elemType.check (attrValues x); check = isAttrs;
merge = loc: defs: merge = loc: defs:
zipAttrsWith (name: elemType.merge (loc ++ [name])) mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
(mergeDefinitions (loc ++ [name]) elemType defs).optionalValue
)
# Push down position info. # Push down position info.
(map (def: listToAttrs (mapAttrsToList (n: def': (map (def: listToAttrs (mapAttrsToList (n: def':
{ name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs); { name = n; value = { inherit (def) file; value = def'; }; }) def.value)) defs)));
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]); getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name>"]);
getSubModules = elemType.getSubModules; getSubModules = elemType.getSubModules;
substSubModules = m: attrsOf (elemType.substSubModules m); substSubModules = m: attrsOf (elemType.substSubModules m);
@ -150,10 +157,7 @@ rec {
attrOnly = attrsOf elemType; attrOnly = attrsOf elemType;
in mkOptionType { in mkOptionType {
name = "list or attribute set of ${elemType.name}s"; name = "list or attribute set of ${elemType.name}s";
check = x: check = x: isList x || isAttrs x;
if isList x then listOnly.check x
else if isAttrs x then attrOnly.check x
else false;
merge = loc: defs: attrOnly.merge loc (imap convertIfList defs); merge = loc: defs: attrOnly.merge loc (imap convertIfList defs);
getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]); getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["<name?>"]);
getSubModules = elemType.getSubModules; getSubModules = elemType.getSubModules;
@ -194,7 +198,11 @@ rec {
let let
coerce = def: if isFunction def then def else { config = def; }; coerce = def: if isFunction def then def else { config = def; };
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs; modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config; in (evalModules {
inherit modules;
args.name = last loc;
prefix = loc;
}).config;
getSubOptions = prefix: (evalModules getSubOptions = prefix: (evalModules
{ modules = opts'; inherit prefix; { modules = opts'; inherit prefix;
# FIXME: hack to get shit to evaluate. # FIXME: hack to get shit to evaluate.

View File

@ -2,27 +2,51 @@
# configuration object (`config') from which we can retrieve option # configuration object (`config') from which we can retrieve option
# values. # values.
{ system ? builtins.currentSystem # !!! Please think twice before adding to this argument list!
, pkgs ? null # Ideally eval-config.nix would be an extremely thin wrapper
, baseModules ? import ../modules/module-list.nix # around lib.evalModules, so that modular systems that have nixos configs
, extraArgs ? {} # as subcomponents (e.g. the container feature, or nixops if network
# expressions are ever made modular at the top level) can just use
# types.submodule instead of using eval-config.nix
{ # !!! system can be set modularly, would be nice to remove
system ? builtins.currentSystem
, # !!! is this argument needed any more? The pkgs argument can
# be set modularly anyway.
pkgs ? null
, # !!! what do we gain by making this configurable?
baseModules ? import ../modules/module-list.nix
, # !!! See comment about args in lib/modules.nix
extraArgs ? {}
, modules , modules
, check ? true , # !!! See comment about check in lib/modules.nix
check ? true
, prefix ? [] , prefix ? []
, lib ? import ../../lib
}: }:
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system;
extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH"; extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
in if e == "" then [] else [(import (builtins.toPath e))]; in if e == "" then [] else [(import (builtins.toPath e))];
in
let
pkgsModule = rec {
_file = ./eval-config.nix;
key = _file;
config = {
nixpkgs.system = lib.mkDefault system_;
_module.args.pkgs = lib.mkIf (pkgs_ != null) (lib.mkForce pkgs_);
};
};
in rec { in rec {
# Merge the option definitions in all modules, forming the full # Merge the option definitions in all modules, forming the full
# system configuration. # system configuration.
inherit (pkgs.lib.evalModules { inherit (lib.evalModules {
inherit prefix; inherit prefix check;
modules = modules ++ extraModules ++ baseModules; modules = modules ++ extraModules ++ baseModules ++ [ pkgsModule ];
args = extraArgs; args = extraArgs;
check = check && options.environment.checkConfigurationOptions.value;
}) config options; }) config options;
# These are the extra arguments passed to every module. In # These are the extra arguments passed to every module. In
@ -33,40 +57,8 @@ in rec {
# the 64-bit package anyway. However, it would be cleaner to respect # the 64-bit package anyway. However, it would be cleaner to respect
# nixpkgs.config here. # nixpkgs.config here.
extraArgs = extraArgs_ // { extraArgs = extraArgs_ // {
inherit pkgs modules baseModules; inherit modules baseModules;
modulesPath = ../modules;
pkgs_i686 = import ./nixpkgs.nix { system = "i686-linux"; config.allowUnfree = true; };
utils = import ./utils.nix pkgs;
}; };
# Import Nixpkgs, allowing the NixOS option nixpkgs.config to inherit (config._module.args) pkgs;
# specify the Nixpkgs configuration (e.g., to set package options
# such as firefox.enableGeckoMediaPlayer, or to apply global
# overrides such as changing GCC throughout the system), and the
# option nixpkgs.system to override the platform type. This is
# tricky, because we have to prevent an infinite recursion: "pkgs"
# is passed as an argument to NixOS modules, but the value of "pkgs"
# depends on config.nixpkgs.config, which we get from the modules.
# So we call ourselves here with "pkgs" explicitly set to an
# instance that doesn't depend on nixpkgs.config.
pkgs =
if pkgs_ != null
then pkgs_
else import ./nixpkgs.nix (
let
system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
nixpkgsOptions = (import ./eval-config.nix {
inherit system extraArgs modules prefix;
# For efficiency, leave out most NixOS modules; they don't
# define nixpkgs.config, so it's pointless to evaluate them.
baseModules = [ ../modules/misc/nixpkgs.nix ../modules/config/no-x-libs.nix ];
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
check = false;
}).config.nixpkgs;
in
{
inherit system;
inherit (nixpkgsOptions) config;
});
} }

View File

@ -1,6 +1,6 @@
{ config, pkgs, ... }: { config, pkgs, lib, ... }:
with pkgs.lib; with lib;
let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>"; let fcBool = x: if x then "<bool>true</bool>" else "<bool>false</bool>";
in in

View File

@ -1,15 +0,0 @@
{ lib, ... }:
with lib;
{
options = {
environment.checkConfigurationOptions = mkOption {
type = types.bool;
default = true;
description = ''
Whether to check the validity of the entire configuration.
'';
};
};
}

View File

@ -0,0 +1,14 @@
{ lib, pkgs, config, ... }:
{
_module.args = {
modulesPath = ../.;
pkgs_i686 = import ../../lib/nixpkgs.nix {
system = "i686-linux";
config.allowUnfree = true;
};
utils = import ../../lib/utils.nix pkgs;
};
}

View File

@ -60,6 +60,7 @@ in
nixpkgs.system = mkOption { nixpkgs.system = mkOption {
type = types.str; type = types.str;
default = builtins.currentSystem;
description = '' description = ''
Specifies the Nix platform type for which NixOS should be built. Specifies the Nix platform type for which NixOS should be built.
If unset, it defaults to the platform type of your host system. If unset, it defaults to the platform type of your host system.
@ -71,6 +72,10 @@ in
}; };
config = { config = {
nixpkgs.system = mkDefault pkgs.stdenv.system; _module.args.pkgs = import ../../lib/nixpkgs.nix {
system = config.nixpkgs.system;
inherit (config.nixpkgs) config;
};
}; };
} }

View File

@ -44,8 +44,8 @@
./installer/tools/nixos-checkout.nix ./installer/tools/nixos-checkout.nix
./installer/tools/tools.nix ./installer/tools/tools.nix
./misc/assertions.nix ./misc/assertions.nix
./misc/check-config.nix
./misc/crashdump.nix ./misc/crashdump.nix
./misc/extra-arguments.nix
./misc/ids.nix ./misc/ids.nix
./misc/lib.nix ./misc/lib.nix
./misc/locate.nix ./misc/locate.nix

View File

@ -135,6 +135,8 @@ in zipModules ([]
++ obsolete [ "services" "mysql55" ] [ "services" "mysql" ] ++ obsolete [ "services" "mysql55" ] [ "services" "mysql" ]
++ obsolete [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ]
# XBMC # XBMC
++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ] ++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ] ++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]

View File

@ -6,8 +6,9 @@
with lib; with lib;
let let
parentConfig = config;
pamOpts = args: { pamOpts = { config, name, ... }: let cfg = config; in let config = parentConfig; in {
options = { options = {
@ -180,8 +181,8 @@ let
}; };
config = let cfg = args.config; in { config = {
name = mkDefault args.name; name = mkDefault name;
setLoginUid = mkDefault cfg.startSession; setLoginUid = mkDefault cfg.startSession;
limits = mkDefault config.security.pam.loginLimits; limits = mkDefault config.security.pam.loginLimits;

View File

@ -3,7 +3,7 @@
# of the virtual consoles. The latter is useful for the installation # of the virtual consoles. The latter is useful for the installation
# CD. # CD.
{ config, lib, pkgs, baseModules, ... } @ extraArgs: { config, lib, pkgs, baseModules, ... }:
with lib; with lib;
@ -18,7 +18,7 @@ let
eval = evalModules { eval = evalModules {
modules = [ versionModule ] ++ baseModules; modules = [ versionModule ] ++ baseModules;
args = (removeAttrs extraArgs ["config" "options"]) // { modules = [ ]; }; args = (config._module.args) // { modules = [ ]; };
}; };
manual = import ../../../doc/manual { manual = import ../../../doc/manual {

View File

@ -1,7 +1,7 @@
{ config, lib, pkgs, utils, ... }: { config, lib, pkgs, utils, ... }:
with lib;
with utils; with utils;
with lib;
with import ./systemd-unit-options.nix { inherit config lib; }; with import ./systemd-unit-options.nix { inherit config lib; };
let let

View File

@ -1,5 +1,3 @@
{ config, pkgs, modulesPath, ... }:
{ {
imports = [ "${modulesPath}/virtualisation/amazon-image.nix" ]; imports = [ ./amazon-image.nix ];
} }