diff options
author | Nicolas B. Pierron <nicolas.b.pierron@gmail.com> | 2015-11-20 20:11:21 +0000 |
---|---|---|
committer | Nicolas B. Pierron <nicolas.b.pierron@gmail.com> | 2015-11-20 20:11:21 +0000 |
commit | 4e61fc89d261eb4815186b451e43a5925a4eb2a1 (patch) | |
tree | 18a0003e7d917216a91d5f1e544c5f11f029b4de /nixos | |
parent | eae62caf916bae65c40a69f88a088d540c6c7765 (diff) | |
parent | a5992ad61b314104aff7e28a41ce101a1b0e7c35 (diff) |
Merge pull request #11106 from nbp/nixos-reentry
Add a way to pin a NixOS version within the module system.
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/default.nix | 16 | ||||
-rw-r--r-- | nixos/doc/manual/configuration/configuration.xml | 1 | ||||
-rw-r--r-- | nixos/doc/manual/default.nix | 1 | ||||
-rw-r--r-- | nixos/doc/manual/release-notes/rl-unstable.xml | 20 | ||||
-rw-r--r-- | nixos/modules/misc/nixos.nix | 82 | ||||
-rw-r--r-- | nixos/modules/misc/nixos.xml | 84 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/release.nix | 1 | ||||
-rw-r--r-- | nixos/tests/nixos-pin-version.nix | 57 |
9 files changed, 259 insertions, 4 deletions
diff --git a/nixos/default.nix b/nixos/default.nix index 5d69b79e13a69..6359d10c88059 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -1,12 +1,20 @@ { 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; @@ -14,14 +22,14 @@ let # 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; } ]; @@ -30,7 +38,7 @@ let in { - inherit (eval) config options; + inherit (eval.config.nixos.reflect) config options; system = eval.config.system.build.toplevel; diff --git a/nixos/doc/manual/configuration/configuration.xml b/nixos/doc/manual/configuration/configuration.xml index 8fde0dc7e6110..afffd60bc485f 100644 --- a/nixos/doc/manual/configuration/configuration.xml +++ b/nixos/doc/manual/configuration/configuration.xml @@ -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 --> diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 87964e27bb9cd..844cba57cd857 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -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 ''; diff --git a/nixos/doc/manual/release-notes/rl-unstable.xml b/nixos/doc/manual/release-notes/rl-unstable.xml index 573b99d4902f4..65aa36586cb02 100644 --- a/nixos/doc/manual/release-notes/rl-unstable.xml +++ b/nixos/doc/manual/release-notes/rl-unstable.xml @@ -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> diff --git a/nixos/modules/misc/nixos.nix b/nixos/modules/misc/nixos.nix new file mode 100644 index 0000000000000..356129211d065 --- /dev/null +++ b/nixos/modules/misc/nixos.nix @@ -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; + } + ]; +} diff --git a/nixos/modules/misc/nixos.xml b/nixos/modules/misc/nixos.xml new file mode 100644 index 0000000000000..f8d3b4bc6e33b --- /dev/null +++ b/nixos/modules/misc/nixos.xml @@ -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 = <nixos>; +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> diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 6c219575bf04c..ecdf2264d698d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -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 diff --git a/nixos/release.nix b/nixos/release.nix index 1a1ed4bca4106..e48954ceaf592 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -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"; }); diff --git a/nixos/tests/nixos-pin-version.nix b/nixos/tests/nixos-pin-version.nix new file mode 100644 index 0000000000000..91fba2e759d28 --- /dev/null +++ b/nixos/tests/nixos-pin-version.nix @@ -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; + ''; +} |