Skip to content

Commit

Permalink
Merge pull request NixOS#153211 from hercules-ci/minimal-nixos
Browse files Browse the repository at this point in the history
Add minimal NixOS entrypoint
  • Loading branch information
roberth authored Jan 20, 2022
2 parents 8072fdf + 3168017 commit 98ae5a9
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 4 deletions.
3 changes: 3 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
in
{
lib = lib.extend (final: prev: {

nixos = import ./nixos/lib { lib = final; };

nixosSystem = { modules, ... } @ args:
import ./nixos/lib/eval-config.nix (args // {
modules =
Expand Down
33 changes: 33 additions & 0 deletions nixos/lib/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
let
# The warning is in a top-level let binding so it is only printed once.
minimalModulesWarning = warn "lib.nixos.evalModules is experimental and subject to change. See nixos/lib/default.nix" null;
inherit (nonExtendedLib) warn;
nonExtendedLib = import ../../lib;
in
{ # Optional. Allows an extended `lib` to be used instead of the regular Nixpkgs lib.
lib ? nonExtendedLib,

# Feature flags allow you to opt in to unfinished code. These may change some
# behavior or disable warnings.
featureFlags ? {},

# This file itself is rather new, so we accept unknown parameters to be forward
# compatible. This is generally not recommended, because typos go undetected.
...
}:
let
seqIf = cond: if cond then builtins.seq else a: b: b;
# If cond, force `a` before returning any attr
seqAttrsIf = cond: a: lib.mapAttrs (_: v: seqIf cond a v);

eval-config-minimal = import ./eval-config-minimal.nix { inherit lib; };
in
/*
This attribute set appears as lib.nixos in the flake, or can be imported
using a binding like `nixosLib = import (nixpkgs + "/nixos/lib") { }`.
*/
{
inherit (seqAttrsIf (!featureFlags?minimalModules) minimalModulesWarning eval-config-minimal)
evalModules
;
}
49 changes: 49 additions & 0 deletions nixos/lib/eval-config-minimal.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

# DO NOT IMPORT. Use nixpkgsFlake.lib.nixos, or import (nixpkgs + "/nixos/lib")
{ lib }: # read -^

let

/*
Invoke NixOS. Unlike traditional NixOS, this does not include all modules.
Any such modules have to be explicitly added via the `modules` parameter,
or imported using `imports` in a module.
A minimal module list improves NixOS evaluation performance and allows
modules to be independently usable, supporting new use cases.
Parameters:
modules: A list of modules that constitute the configuration.
specialArgs: An attribute set of module arguments. Unlike
`config._module.args`, these are available for use in
`imports`.
`config._module.args` should be preferred when possible.
Return:
An attribute set containing `config.system.build.toplevel` among other
attributes. See `lib.evalModules` in the Nixpkgs library.
*/
evalModules = {
prefix ? [],
modules ? [],
specialArgs ? {},
}:
# NOTE: Regular NixOS currently does use this function! Don't break it!
# Ideally we don't diverge, unless we learn that we should.
# In other words, only the public interface of nixos.evalModules
# is experimental.
lib.evalModules {
inherit prefix modules;
specialArgs = {
modulesPath = builtins.toString ../modules;
} // specialArgs;
};

in
{
inherit evalModules;
}
12 changes: 8 additions & 4 deletions nixos/lib/eval-config.nix
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ let pkgs_ = pkgs;
in

let
evalModulesMinimal = (import ./default.nix {
inherit lib;
# Implicit use of feature is noted in implementation.
featureFlags.minimalModules = { };
}).evalModules;

pkgsModule = rec {
_file = ./eval-config.nix;
key = _file;
Expand Down Expand Up @@ -70,11 +76,9 @@ let
};
allUserModules = modules ++ legacyModules;

noUserModules = lib.evalModules ({
inherit prefix;
noUserModules = evalModulesMinimal ({
inherit prefix specialArgs;
modules = baseModules ++ extraModules ++ [ pkgsModule modulesModule ];
specialArgs =
{ modulesPath = builtins.toString ../modules; } // specialArgs;
});

# Extra arguments that are useful for constructing a similar configuration.
Expand Down
5 changes: 5 additions & 0 deletions nixos/modules/misc/nixpkgs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ let
in

{
imports = [
./assertions.nix
./meta.nix
];

options.nixpkgs = {

pkgs = mkOption {
Expand Down
8 changes: 8 additions & 0 deletions nixos/modules/misc/nixpkgs/test.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ evalMinimalConfig, pkgs, lib, stdenv }:
lib.recurseIntoAttrs {
invokeNixpkgsSimple =
(evalMinimalConfig ({ config, modulesPath, ... }: {
imports = [ (modulesPath + "/misc/nixpkgs.nix") ];
nixpkgs.system = stdenv.hostPlatform.system;
}))._module.args.pkgs.hello;
}
8 changes: 8 additions & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ let
handleTestOn = systems: path: args:
if elem system systems then handleTest path args
else {};

nixosLib = import ../lib {
# Experimental features need testing too, but there's no point in warning
# about it, so we enable the feature flag.
featureFlags.minimalModules = {};
};
evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; };
in
{
_3proxy = handleTest ./3proxy.nix {};
Expand Down Expand Up @@ -331,6 +338,7 @@ in
nix-serve-ssh = handleTest ./nix-serve-ssh.nix {};
nixops = handleTest ./nixops/default.nix {};
nixos-generate-config = handleTest ./nixos-generate-config.nix {};
nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; };
node-red = handleTest ./node-red.nix {};
nomad = handleTest ./nomad.nix {};
novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {};
Expand Down

0 comments on commit 98ae5a9

Please sign in to comment.