Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions nixos/default.nix
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
{ configuration ? import ./lib/from-env.nix "NIXOS_CONFIG" <nixos-config>
, system ? builtins.currentSystem
, extraModules ? []
# This attribute is used to specify a different nixos version, a different
# system or additional modules which might be set conditionally.
, reEnter ? false
}:

let
reEnterModule = {
config.nixos.path = with (import ../lib); mkIf reEnter (mkForce null);
config.nixos.configuration = configuration;
};

eval = import ./lib/eval-config.nix {
inherit system;
modules = [ configuration ];
modules = [ configuration reEnterModule ] ++ extraModules;
};

inherit (eval) pkgs;

# This is for `nixos-rebuild build-vm'.
vmConfig = (import ./lib/eval-config.nix {
inherit system;
modules = [ configuration ./modules/virtualisation/qemu-vm.nix ];
modules = [ configuration reEnterModule ./modules/virtualisation/qemu-vm.nix ] ++ extraModules;
}).config;

# This is for `nixos-rebuild build-vm-with-bootloader'.
vmWithBootLoaderConfig = (import ./lib/eval-config.nix {
inherit system;
modules =
[ configuration
[ configuration reEnterModule
./modules/virtualisation/qemu-vm.nix
{ virtualisation.useBootLoader = true; }
];
Expand All @@ -30,7 +38,7 @@ let
in

{
inherit (eval) config options;
inherit (eval.config.nixos.reflect) config options;

system = eval.config.system.build.toplevel;

Expand Down
1 change: 1 addition & 0 deletions nixos/doc/manual/configuration/configuration.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ effect after you run <command>nixos-rebuild</command>.</para>

<!-- FIXME: auto-include NixOS module docs -->
<xi:include href="postgresql.xml" />
<xi:include href="nixos.xml" />

<!-- Apache; libvirtd virtualisation -->

Expand Down
1 change: 1 addition & 0 deletions nixos/doc/manual/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ let
cp -prd $sources/* . # */
chmod -R u+w .
cp ${../../modules/services/databases/postgresql.xml} configuration/postgresql.xml
cp ${../../modules/misc/nixos.xml} configuration/nixos.xml
ln -s ${optionsDocBook} options-db.xml
echo "${version}" > version
'';
Expand Down
20 changes: 20 additions & 0 deletions nixos/doc/manual/release-notes/rl-unstable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@

<title>Unstable</title>

<para>In addition to numerous new and upgraded packages, this release
has the following highlights:</para>

<itemizedlist>

<listitem>
<para>You can now pin a specific version of NixOS in your <filename>configuration.nix</filename>
by setting:

<programlisting>
nixos.path = ./nixpkgs-unstable-2015-12-06/nixos;
</programlisting>

This will make NixOS re-evaluate your configuration with the modules of
the specified NixOS version at the given path. For more details, see
<xref linkend="module-misc-nixos" /></para>
</listitem>

</itemizedlist>

<para>When upgrading from a previous release, please be aware of the
following incompatible changes:</para>

Expand Down
82 changes: 82 additions & 0 deletions nixos/modules/misc/nixos.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{ config, options, lib, ... }:

# This modules is used to inject a different NixOS version as well as its
# argument such that one can pin a specific version with the versionning
# system of the configuration.
let
nixosReentry = import config.nixos.path {
inherit (config.nixos) configuration extraModules;
inherit (config.nixpkgs) system;
reEnter = true;
};
in

with lib;

{
options = {
nixos.path = mkOption {
default = null;
example = literalExample "./nixpkgs-15.09/nixos";
type = types.nullOr types.path;
description = ''
This option give the ability to evaluate the current set of modules
with a different version of NixOS. This option can be used version
the version of NixOS with the configuration without relying on the
<literal>NIX_PATH</literal> environment variable.
'';
};

nixos.system = mkOption {
example = "i686-linux";
type = types.uniq types.str;
description = ''
Name of the system used to compile NixOS.
'';
};

nixos.extraModules = mkOption {
default = [];
example = literalExample "mkIf config.services.openssh.enable [ ./sshd-config.nix ]";
type = types.listOf types.unspecified;
description = ''
Define additional modules which would be loaded to evaluate the
configuration.
'';
};

nixos.configuration = mkOption {
type = types.unspecified;
internal = true;
description = ''
Option used by <filename>nixos/default.nix</filename> to re-inject
the same configuration module as the one used for the current
execution.
'';
};

nixos.reflect = mkOption {
default = { inherit config options; };
type = types.unspecified;
internal = true;
description = ''
Provides <literal>config</literal> and <literal>options</literal>
computed by the module system and given as argument to all
modules. These are used for introspection of options and
configuration by tools such as <literal>nixos-option</literal>.
'';
};
};

config = mkMerge [
(mkIf (config.nixos.path != null) (mkForce {
system.build.toplevel = nixosReentry.system;
system.build.vm = nixosReentry.vm;
nixos.reflect = { inherit (nixosReentry) config options; };
}))

{ meta.maintainers = singleton lib.maintainers.pierron;
meta.doc = ./nixos.xml;
}
];
}
84 changes: 84 additions & 0 deletions nixos/modules/misc/nixos.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="module-misc-nixos">

<title>NixOS Reentry</title>

<!-- FIXME: render nicely -->

<!-- FIXME: source can be added automatically -->
<para><emphasis>Source:</emphasis> <filename>modules/misc/nixos.nix</filename></para>

<!-- FIXME: more stuff, like maintainer? -->

<para>NixOS reentry can be used for both pinning the evaluation to a
specific version of NixOS, and to dynamically add additional modules into
the Module evaluation.</para>

<section><title>NixOS Version Pinning</title>

<para>To pin a specific version of NixOS, you need a version that you can
either clone localy, or that you can fetch remotely.</para>

<para>If you already have a cloned version of NixOS in the directory
<filename>/etc/nixos/nixpkgs-16-03</filename>, then you can specify the
<option>nixos.path</option> with either the path or the relative path of
your NixOS clone. For example, you can add the following to your
<filename>/etc/nixos/configuration.nix</filename> file:

<programlisting>
nixos.path = ./nixpkgs-16-03/nixos;
</programlisting>
</para>

<para>Another option is to fetch a specific version of NixOS, with either
the <literal>fetchTarball</literal> builtin, or the
<literal>pkgs.fetchFromGithub</literal> function and use the result as an
input.

<programlisting>
nixos.path = "${builtins.fetchTarball https://github.com/NixOS/nixpkgs/archive/1f27976e03c15183191d1b4aa1a40d1f14666cd2.tar.gz}/nixos";
</programlisting>
</para>

</section>


<section><title>Adding Module Dynamically</title>

<para>To add additional module, the recommended way is to use statically
known modules in the list of imported arguments as described in <xref
linkend="sec-modularity" />. Unfortunately, this recommended method has
limitation, such that the list of imported files cannot be selected based on
the content of the configuration.

Fortunately, NixOS reentry system can be used as an alternative to register
new imported modules based on the content of the configuration. To do so,
one should define both <option>nixos.path</option> and
<option>nixos.extraModules</option> options.

<programlisting>
nixos.path = &lt;nixos&gt;;
nixos.extraModules =
if config.networking.hostName == "server" then
[ ./server.nix ] else [ ./client.nix ];
</programlisting>

Also note, that the above can be reimplemented in a different way which is
not as expensive, by using <literal>mkIf</literal> at the top each
configuration if both modules are present on the file system (see <xref
linkend="sec-option-definitions" />) and by always inmporting both
modules.</para>

</section>

<section><title>Options</title>

<para>FIXME: auto-generated list of module options.</para>

</section>


</chapter>
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
./misc/lib.nix
./misc/locate.nix
./misc/meta.nix
./misc/nixos.nix
./misc/nixpkgs.nix
./misc/passthru.nix
./misc/version.nix
Expand Down
1 change: 1 addition & 0 deletions nixos/release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ in rec {
tests.networkingProxy = callTest tests/networking-proxy.nix {};
tests.nfs3 = callTest tests/nfs.nix { version = 3; };
tests.nfs4 = callTest tests/nfs.nix { version = 4; };
tests.nixosPinVersion = callTest tests/nixos-pin-version.nix {};
tests.nsd = callTest tests/nsd.nix {};
tests.openssh = callTest tests/openssh.nix {};
tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; });
Expand Down
57 changes: 57 additions & 0 deletions nixos/tests/nixos-pin-version.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{ system ? builtins.currentSystem }:

with import ../lib/testing.nix { inherit system; };
let
in

pkgs.stdenv.mkDerivation rec {
name = "nixos-pin-version";
src = ../..;
buildInputs = with pkgs; [ nix gnugrep ];

withoutPath = pkgs.writeText "configuration.nix" ''
{
nixos.extraModules = [ ({lib, ...}: { system.nixosRevision = lib.mkForce "ABCDEF"; }) ];
}
'';

withPath = pkgs.writeText "configuration.nix" ''
{
nixos.path = ${src}/nixos ;
nixos.extraModules = [ ({lib, ...}: { system.nixosRevision = lib.mkForce "ABCDEF"; }) ];
}
'';

phases = "buildPhase";
buildPhase = ''
datadir="${pkgs.nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_STORE_DIR=$TEST_ROOT/store
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_DB_DIR=$TEST_ROOT/db
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests
export NIX_BUILD_HOOK=
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
nix-store --init

export NIX_PATH="nixpkgs=$src:nixos=$src/nixos:nixos-config=${withoutPath}" ;
if test $(nix-instantiate $src/nixos -A config.system.nixosRevision --eval-only) != '"ABCDEF"' ; then :;
else
echo "Unexpected re-entry without the nixos.path option defined.";
exit 1;
fi;

export NIX_PATH="nixpkgs=$src:nixos=$src/nixos:nixos-config=${withPath}" ;
if test $(nix-instantiate $src/nixos -A config.system.nixosRevision --eval-only) = '"ABCDEF"' ; then :;
else
echo "Expected a re-entry when the nixos.path option is defined.";
exit 1;
fi;

touch $out;
'';
}