aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/installer
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/installer')
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/channel.nix4
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix3
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix21
-rw-r--r--nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix14
-rw-r--r--nixpkgs/nixos/modules/installer/netboot/netboot.nix14
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix8
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix2
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-enter.sh18
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc251
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh98
-rw-r--r--nixpkgs/nixos/modules/installer/tools/nixos-version.sh9
-rw-r--r--nixpkgs/nixos/modules/installer/tools/tools.nix9
12 files changed, 296 insertions, 155 deletions
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix b/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix
index ab5e7c0645f..92164d65e53 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix
@@ -21,7 +21,9 @@ let
if [ ! -e $out/nixos/nixpkgs ]; then
ln -s . $out/nixos/nixpkgs
fi
- echo -n ${config.system.nixos.revision} > $out/nixos/.git-revision
+ ${optionalString (config.system.nixos.revision != null) ''
+ echo -n ${config.system.nixos.revision} > $out/nixos/.git-revision
+ ''}
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
echo ${config.system.nixos.versionSuffix} | sed -e s/pre// > $out/nixos/svn-revision
'';
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
index e0b558dcb0d..fa19daf1328 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
@@ -44,6 +44,9 @@ with lib;
pkgs.bvi # binary editor
pkgs.joe
+ # Include some version control tools.
+ pkgs.git
+
# Firefox for reading the manual.
pkgs.firefox
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix
index 23c3426bff0..62cbdbcfd17 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix
@@ -1,5 +1,4 @@
-# This module defines a NixOS installation CD that contains X11 and
-# GNOME 3.
+# This module defines a NixOS installation CD that contains GNOME.
{ lib, ... }:
@@ -10,10 +9,22 @@ with lib;
services.xserver.desktopManager.gnome3.enable = true;
- # Auto-login as root.
- services.xserver.displayManager.gdm.autoLogin = {
+ # Wayland can be problematic for some hardware like Nvidia graphics cards.
+ services.xserver.displayManager.defaultSession = "gnome-xorg";
+
+ services.xserver.displayManager.gdm = {
enable = true;
- user = "root";
+ # autoSuspend makes the machine automatically suspend after inactivity.
+ # It's possible someone could/try to ssh'd into the machine and obviously
+ # have issues because it's inactive.
+ # See:
+ # * https://github.com/NixOS/nixpkgs/pull/63790
+ # * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
+ autoSuspend = false;
+ autoLogin = {
+ enable = true;
+ user = "nixos";
+ };
};
}
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
index 11319e5f4f8..4558b4dc955 100644
--- a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -569,14 +569,18 @@ in
};
fileSystems."/nix/store" =
- { fsType = "unionfs-fuse";
- device = "unionfs";
- options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
+ { fsType = "overlay";
+ device = "overlay";
+ options = [
+ "lowerdir=/nix/.ro-store"
+ "upperdir=/nix/.rw-store/store"
+ "workdir=/nix/.rw-store/work"
+ ];
};
- boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" ];
+ boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ];
- boot.initrd.kernelModules = [ "loop" ];
+ boot.initrd.kernelModules = [ "loop" "overlay" ];
# Closures to be copied to the Nix store on the CD, namely the init
# script and the top-level system configuration directory.
diff --git a/nixpkgs/nixos/modules/installer/netboot/netboot.nix b/nixpkgs/nixos/modules/installer/netboot/netboot.nix
index 5146858cccf..95eba86bcb6 100644
--- a/nixpkgs/nixos/modules/installer/netboot/netboot.nix
+++ b/nixpkgs/nixos/modules/installer/netboot/netboot.nix
@@ -50,14 +50,18 @@ with lib;
};
fileSystems."/nix/store" =
- { fsType = "unionfs-fuse";
- device = "unionfs";
- options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
+ { fsType = "overlay";
+ device = "overlay";
+ options = [
+ "lowerdir=/nix/.ro-store"
+ "upperdir=/nix/.rw-store/store"
+ "workdir=/nix/.rw-store/work"
+ ];
};
- boot.initrd.availableKernelModules = [ "squashfs" ];
+ boot.initrd.availableKernelModules = [ "squashfs" "overlay" ];
- boot.initrd.kernelModules = [ "loop" ];
+ boot.initrd.kernelModules = [ "loop" "overlay" ];
# Closures to be copied to the Nix store, namely the init
# script and the top-level system configuration directory.
diff --git a/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix b/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
index c2f2578733b..2068f27f1c9 100644
--- a/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
+++ b/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
@@ -1,6 +1,6 @@
{
- x86_64-linux = "/nix/store/0q5qnh10m2sfrriszc1ysmggw659q6qm-nix-2.3.2";
- i686-linux = "/nix/store/i7ad7r5d8a5b3l22hg4a1im2qq05y6vd-nix-2.3.2";
- aarch64-linux = "/nix/store/bv06pavfw0dbqzr8w3l7s71nx27gnxa0-nix-2.3.2";
- x86_64-darwin = "/nix/store/x6mnl1nij7y4v5ihlplr4k937ayr403r-nix-2.3.2";
+ x86_64-linux = "/nix/store/ddmmzn4ggz1f66lwxjy64n89864yj9w9-nix-2.3.3";
+ i686-linux = "/nix/store/5axys7hsggb4282dsbps5k5p0v59yv13-nix-2.3.3";
+ aarch64-linux = "/nix/store/k80nwvi19hxwbz3c9cxgp24f1jjxwmcc-nix-2.3.3";
+ x86_64-darwin = "/nix/store/lrnvapsqmf0ja6zfyx4cpxr7ahdr7f9b-nix-2.3.3";
}
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix b/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
index c1028a0ad7e..90f0702f717 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
@@ -5,7 +5,7 @@
let nodes = import networkExpr; in
-with import ../../../../lib/testing.nix {
+with import ../../../../lib/testing-python.nix {
inherit system;
pkgs = import ../../../../.. { inherit system config; };
};
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh b/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
index 4680cd8ae95..1fdd4627a90 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
@@ -60,15 +60,15 @@ chmod 0755 "$mountPoint/dev" "$mountPoint/sys"
mount --rbind /dev "$mountPoint/dev"
mount --rbind /sys "$mountPoint/sys"
-# If silent, write both stdout and stderr of activation script to /dev/null
-# otherwise, write both streams to stderr of this process
-if [ "$silent" -eq 0 ]; then
- PIPE_TARGET="/dev/stderr"
-else
- PIPE_TARGET="/dev/null"
-fi
+(
+ # If silent, write both stdout and stderr of activation script to /dev/null
+ # otherwise, write both streams to stderr of this process
+ if [ "$silent" -eq 1 ]; then
+ exec 2>/dev/null
+ fi
-# Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
-LOCALE_ARCHIVE="$system/sw/lib/locale/locale-archive" chroot "$mountPoint" "$system/activate" >>$PIPE_TARGET 2>&1 || true
+ # Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
+ LOCALE_ARCHIVE="$system/sw/lib/locale/locale-archive" chroot "$mountPoint" "$system/activate" 1>&2 || true
+)
exec chroot "$mountPoint" "${command[@]}"
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc b/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
index 9b92dc829cd..1a7b07a74f8 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
@@ -131,12 +131,12 @@ bool isOption(Context & ctx, const Value & v)
if (v.type != tAttrs) {
return false;
}
- const auto & atualType = v.attrs->find(ctx.underscoreType);
- if (atualType == v.attrs->end()) {
+ const auto & actualType = v.attrs->find(ctx.underscoreType);
+ if (actualType == v.attrs->end()) {
return false;
}
try {
- Value evaluatedType = evaluateValue(ctx, *atualType->value);
+ Value evaluatedType = evaluateValue(ctx, *actualType->value);
if (evaluatedType.type != tString) {
return false;
}
@@ -197,9 +197,107 @@ void recurse(const std::function<bool(const std::string & path, std::variant<Val
}
}
-// Calls f on all the option names
-void mapOptions(const std::function<void(const std::string & path)> & f, Context & ctx, Value root)
+bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType)
{
+ try {
+ const auto & typeLookup = v.attrs->find(ctx.state.sType);
+ if (typeLookup == v.attrs->end()) {
+ return false;
+ }
+ Value type = evaluateValue(ctx, *typeLookup->value);
+ if (type.type != tAttrs) {
+ return false;
+ }
+ const auto & nameLookup = type.attrs->find(ctx.state.sName);
+ if (nameLookup == type.attrs->end()) {
+ return false;
+ }
+ Value name = evaluateValue(ctx, *nameLookup->value);
+ if (name.type != tString) {
+ return false;
+ }
+ return name.string.s == soughtType;
+ } catch (Error &) {
+ return false;
+ }
+}
+
+bool isAggregateOptionType(Context & ctx, Value & v)
+{
+ return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf") || optionTypeIs(ctx, v, "loaOf");
+}
+
+MakeError(OptionPathError, EvalError);
+
+Value getSubOptions(Context & ctx, Value & option)
+{
+ Value getSubOptions = evaluateValue(ctx, *findAlongAttrPath(ctx.state, "type.getSubOptions", ctx.autoArgs, option));
+ if (getSubOptions.type != tLambda) {
+ throw OptionPathError("Option's type.getSubOptions isn't a function");
+ }
+ Value emptyString{};
+ nix::mkString(emptyString, "");
+ Value v;
+ ctx.state.callFunction(getSubOptions, emptyString, v, nix::Pos{});
+ return v;
+}
+
+// Carefully walk an option path, looking for sub-options when a path walks past
+// an option value.
+struct FindAlongOptionPathRet
+{
+ Value option;
+ std::string path;
+};
+FindAlongOptionPathRet findAlongOptionPath(Context & ctx, const std::string & path)
+{
+ Strings tokens = parseAttrPath(path);
+ Value v = ctx.optionsRoot;
+ std::string processedPath;
+ for (auto i = tokens.begin(); i != tokens.end(); i++) {
+ const auto & attr = *i;
+ try {
+ bool lastAttribute = std::next(i) == tokens.end();
+ v = evaluateValue(ctx, v);
+ if (attr.empty()) {
+ throw OptionPathError("empty attribute name");
+ }
+ if (isOption(ctx, v) && optionTypeIs(ctx, v, "submodule")) {
+ v = getSubOptions(ctx, v);
+ }
+ if (isOption(ctx, v) && isAggregateOptionType(ctx, v)) {
+ auto subOptions = getSubOptions(ctx, v);
+ if (lastAttribute && subOptions.attrs->empty()) {
+ break;
+ }
+ v = subOptions;
+ // Note that we've consumed attr, but didn't actually use it. This is the path component that's looked
+ // up in the list or attribute set that doesn't name an option -- the "root" in "users.users.root.name".
+ } else if (v.type != tAttrs) {
+ throw OptionPathError("Value is %s while a set was expected", showType(v));
+ } else {
+ const auto & next = v.attrs->find(ctx.state.symbols.create(attr));
+ if (next == v.attrs->end()) {
+ throw OptionPathError("Attribute not found", attr, path);
+ }
+ v = *next->value;
+ }
+ processedPath = appendPath(processedPath, attr);
+ } catch (OptionPathError & e) {
+ throw OptionPathError("At '%s' in path '%s': %s", attr, path, e.msg());
+ }
+ }
+ return {v, processedPath};
+}
+
+// Calls f on all the option names at or below the option described by `path`.
+// Note that "the option described by `path`" is not trivial -- if path describes a value inside an aggregate
+// option (such as users.users.root), the *option* described by that path is one path component shorter
+// (eg: users.users), which results in f being called on sibling-paths (eg: users.users.nixbld1). If f
+// doesn't want these, it must do its own filtering.
+void mapOptions(const std::function<void(const std::string & path)> & f, Context & ctx, const std::string & path)
+{
+ auto root = findAlongOptionPath(ctx, path);
recurse(
[f, &ctx](const std::string & path, std::variant<Value, std::exception_ptr> v) {
bool isOpt = std::holds_alternative<std::exception_ptr>(v) || isOption(ctx, std::get<Value>(v));
@@ -208,7 +306,7 @@ void mapOptions(const std::function<void(const std::string & path)> & f, Context
}
return !isOpt;
},
- ctx, root, "");
+ ctx, root.option, root.path);
}
// Calls f on all the config values inside one option.
@@ -294,9 +392,11 @@ void printAttrs(Context & ctx, Out & out, Value & v, const std::string & path)
Out attrsOut(out, "{", "}", v.attrs->size());
for (const auto & a : v.attrs->lexicographicOrder()) {
std::string name = a->name;
- attrsOut << name << " = ";
- printValue(ctx, attrsOut, *a->value, appendPath(path, name));
- attrsOut << ";" << Out::sep;
+ if (!forbiddenRecursionName(name)) {
+ attrsOut << name << " = ";
+ printValue(ctx, attrsOut, *a->value, appendPath(path, name));
+ attrsOut << ";" << Out::sep;
+ }
}
}
@@ -380,17 +480,26 @@ void printConfigValue(Context & ctx, Out & out, const std::string & path, std::v
out << ";\n";
}
-void printAll(Context & ctx, Out & out)
+// Replace with std::starts_with when C++20 is available
+bool starts_with(const std::string & s, const std::string & prefix)
+{
+ return s.size() >= prefix.size() &&
+ std::equal(s.begin(), std::next(s.begin(), prefix.size()), prefix.begin(), prefix.end());
+}
+
+void printRecursive(Context & ctx, Out & out, const std::string & path)
{
mapOptions(
- [&ctx, &out](const std::string & optionPath) {
+ [&ctx, &out, &path](const std::string & optionPath) {
mapConfigValuesInOption(
- [&ctx, &out](const std::string & configPath, std::variant<Value, std::exception_ptr> v) {
- printConfigValue(ctx, out, configPath, v);
+ [&ctx, &out, &path](const std::string & configPath, std::variant<Value, std::exception_ptr> v) {
+ if (starts_with(configPath, path)) {
+ printConfigValue(ctx, out, configPath, v);
+ }
},
optionPath, ctx);
},
- ctx, ctx.optionsRoot);
+ ctx, path);
}
void printAttr(Context & ctx, Out & out, const std::string & path, Value & root)
@@ -450,95 +559,17 @@ void printListing(Out & out, Value & v)
}
}
-bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType)
-{
- try {
- const auto & typeLookup = v.attrs->find(ctx.state.sType);
- if (typeLookup == v.attrs->end()) {
- return false;
- }
- Value type = evaluateValue(ctx, *typeLookup->value);
- if (type.type != tAttrs) {
- return false;
- }
- const auto & nameLookup = type.attrs->find(ctx.state.sName);
- if (nameLookup == type.attrs->end()) {
- return false;
- }
- Value name = evaluateValue(ctx, *nameLookup->value);
- if (name.type != tString) {
- return false;
- }
- return name.string.s == soughtType;
- } catch (Error &) {
- return false;
- }
-}
-
-bool isAggregateOptionType(Context & ctx, Value & v)
-{
- return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf") || optionTypeIs(ctx, v, "loaOf");
-}
-
-MakeError(OptionPathError, EvalError);
-
-Value getSubOptions(Context & ctx, Value & option)
-{
- Value getSubOptions = evaluateValue(ctx, *findAlongAttrPath(ctx.state, "type.getSubOptions", ctx.autoArgs, option));
- if (getSubOptions.type != tLambda) {
- throw OptionPathError("Option's type.getSubOptions isn't a function");
- }
- Value emptyString{};
- nix::mkString(emptyString, "");
- Value v;
- ctx.state.callFunction(getSubOptions, emptyString, v, nix::Pos{});
- return v;
-}
-
-// Carefully walk an option path, looking for sub-options when a path walks past
-// an option value.
-Value findAlongOptionPath(Context & ctx, const std::string & path)
-{
- Strings tokens = parseAttrPath(path);
- Value v = ctx.optionsRoot;
- for (auto i = tokens.begin(); i != tokens.end(); i++) {
- const auto & attr = *i;
- try {
- bool lastAttribute = std::next(i) == tokens.end();
- v = evaluateValue(ctx, v);
- if (attr.empty()) {
- throw OptionPathError("empty attribute name");
- }
- if (isOption(ctx, v) && optionTypeIs(ctx, v, "submodule")) {
- v = getSubOptions(ctx, v);
- }
- if (isOption(ctx, v) && isAggregateOptionType(ctx, v) && !lastAttribute) {
- v = getSubOptions(ctx, v);
- // Note that we've consumed attr, but didn't actually use it. This is the path component that's looked
- // up in the list or attribute set that doesn't name an option -- the "root" in "users.users.root.name".
- } else if (v.type != tAttrs) {
- throw OptionPathError("Value is %s while a set was expected", showType(v));
- } else {
- const auto & next = v.attrs->find(ctx.state.symbols.create(attr));
- if (next == v.attrs->end()) {
- throw OptionPathError("Attribute not found", attr, path);
- }
- v = *next->value;
- }
- } catch (OptionPathError & e) {
- throw OptionPathError("At '%s' in path '%s': %s", attr, path, e.msg());
- }
- }
- return v;
-}
-
void printOne(Context & ctx, Out & out, const std::string & path)
{
try {
- Value option = findAlongOptionPath(ctx, path);
+ auto result = findAlongOptionPath(ctx, path);
+ Value & option = result.option;
option = evaluateValue(ctx, option);
+ if (path != result.path) {
+ out << "Note: showing " << result.path << " instead of " << path << "\n";
+ }
if (isOption(ctx, option)) {
- printOption(ctx, out, path, option);
+ printOption(ctx, out, result.path, option);
} else {
printListing(out, option);
}
@@ -552,7 +583,7 @@ void printOne(Context & ctx, Out & out, const std::string & path)
int main(int argc, char ** argv)
{
- bool all = false;
+ bool recursive = false;
std::string path = ".";
std::string optionsExpr = "(import <nixpkgs/nixos> {}).options";
std::string configExpr = "(import <nixpkgs/nixos> {}).config";
@@ -568,8 +599,8 @@ int main(int argc, char ** argv)
nix::showManPage("nixos-option");
} else if (*arg == "--version") {
nix::printVersion("nixos-option");
- } else if (*arg == "--all") {
- all = true;
+ } else if (*arg == "-r" || *arg == "--recursive") {
+ recursive = true;
} else if (*arg == "--path") {
path = nix::getArg(*arg, arg, end);
} else if (*arg == "--options_expr") {
@@ -598,18 +629,12 @@ int main(int argc, char ** argv)
Context ctx{*state, *myArgs.getAutoArgs(*state), optionsRoot, configRoot};
Out out(std::cout);
- if (all) {
- if (!args.empty()) {
- throw UsageError("--all cannot be used with arguments");
- }
- printAll(ctx, out);
- } else {
- if (args.empty()) {
- printOne(ctx, out, "");
- }
- for (const auto & arg : args) {
- printOne(ctx, out, arg);
- }
+ auto print = recursive ? printRecursive : printOne;
+ if (args.empty()) {
+ print(ctx, out, "");
+ }
+ for (const auto & arg : args) {
+ print(ctx, out, arg);
}
ctx.state.printStats();
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh b/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
index 61b4af11027..354274478a3 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -3,6 +3,9 @@
if [ -x "@shell@" ]; then export SHELL="@shell@"; fi;
set -e
+set -o pipefail
+
+export PATH=@path@:$PATH
showSyntax() {
exec man nixos-rebuild
@@ -13,6 +16,7 @@ showSyntax() {
# Parse the command line.
origArgs=("$@")
extraBuildFlags=()
+lockFlags=()
action=
buildNix=1
fast=
@@ -58,7 +62,7 @@ while [ "$#" -gt 0 ]; do
j="$1"; shift 1
extraBuildFlags+=("$i" "$j")
;;
- --show-trace|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*)
+ --show-trace|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*|-L|--refresh|--no-net)
extraBuildFlags+=("$i")
;;
--option)
@@ -91,10 +95,24 @@ while [ "$#" -gt 0 ]; do
shift 1
;;
--use-remote-sudo)
- # note the trailing space
maybeSudo=(sudo --)
+ ;;
+ --flake)
+ flake="$1"
shift 1
;;
+ --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
+ lockFlags+=("$i")
+ ;;
+ --update-input)
+ j="$1"; shift 1
+ lockFlags+=("$i" "$j")
+ ;;
+ --override-input)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ lockFlags+=("$i" "$j" "$k")
+ ;;
*)
echo "$0: unknown option \`$i'"
exit 1
@@ -204,7 +222,7 @@ fi
# If ‘--upgrade’ is given, run ‘nix-channel --update nixos’.
-if [ -n "$upgrade" -a -z "$_NIXOS_REBUILD_REEXEC" ]; then
+if [[ -n $upgrade && -z $_NIXOS_REBUILD_REEXEC && -z $flake ]]; then
nix-channel --update nixos
# If there are other channels that contain a file called
@@ -227,8 +245,15 @@ if [ -z "$_NIXOS_REBUILD_REEXEC" ]; then
export PATH=@nix@/bin:$PATH
fi
+# Use /etc/nixos/flake.nix if it exists. It can be a symlink to the
+# actual flake.
+if [[ -z $flake && -e /etc/nixos/flake.nix ]]; then
+ flake="$(dirname "$(readlink -f /etc/nixos/flake.nix)")"
+fi
+
# Re-execute nixos-rebuild from the Nixpkgs tree.
-if [ -z "$_NIXOS_REBUILD_REEXEC" -a -n "$canRun" -a -z "$fast" ]; then
+# FIXME: get nixos-rebuild from $flake.
+if [[ -z $_NIXOS_REBUILD_REEXEC && -n $canRun && -z $fast && -z $flake ]]; then
if p=$(nix-build --no-out-link --expr 'with import <nixpkgs/nixos> {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then
export _NIXOS_REBUILD_REEXEC=1
exec $p/bin/nixos-rebuild "${origArgs[@]}"
@@ -236,10 +261,37 @@ if [ -z "$_NIXOS_REBUILD_REEXEC" -a -n "$canRun" -a -z "$fast" ]; then
fi
fi
+# For convenience, use the hostname as the default configuration to
+# build from the flake.
+if [[ -n $flake ]]; then
+ if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
+ flake="${BASH_REMATCH[1]}"
+ flakeAttr="${BASH_REMATCH[2]}"
+ fi
+ if [[ -z $flakeAttr ]]; then
+ read -r hostname < /proc/sys/kernel/hostname
+ if [[ -z $hostname ]]; then
+ hostname=default
+ fi
+ flakeAttr="nixosConfigurations.\"$hostname\""
+ else
+ flakeAttr="nixosConfigurations.\"$flakeAttr\""
+ fi
+fi
+
+# Resolve the flake.
+if [[ -n $flake ]]; then
+ flake=$(nix flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
+fi
+
# Find configuration.nix and open editor instead of building.
if [ "$action" = edit ]; then
- NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)}
- exec "${EDITOR:-nano}" "$NIXOS_CONFIG"
+ if [[ -z $flake ]]; then
+ NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)}
+ exec "${EDITOR:-nano}" "$NIXOS_CONFIG"
+ else
+ exec nix edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
+ fi
exit 1
fi
@@ -298,7 +350,7 @@ prebuiltNix() {
remotePATH=
-if [ -n "$buildNix" ]; then
+if [[ -n $buildNix && -z $flake ]]; then
echo "building Nix..." >&2
nixDrv=
if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then
@@ -339,7 +391,7 @@ fi
# Update the version suffix if we're building from Git (so that
# nixos-version shows something useful).
-if [ -n "$canRun" ]; then
+if [[ -n $canRun && -z $flake ]]; then
if nixpkgs=$(nix-instantiate --find-file nixpkgs "${extraBuildFlags[@]}"); then
suffix=$($SHELL $nixpkgs/nixos/modules/installer/tools/get-version-suffix "${extraBuildFlags[@]}" || true)
if [ -n "$suffix" ]; then
@@ -360,15 +412,37 @@ fi
if [ -z "$rollback" ]; then
echo "building the system configuration..." >&2
if [ "$action" = switch -o "$action" = boot ]; then
- pathToConfig="$(nixBuild '<nixpkgs/nixos>' --no-out-link -A system "${extraBuildFlags[@]}")"
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' --no-out-link -A system "${extraBuildFlags[@]}")"
+ else
+ outLink=$tmpDir/result
+ nix build "$flake#$flakeAttr.config.system.build.toplevel" \
+ "${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link $outLink
+ pathToConfig="$(readlink -f $outLink)"
+ fi
copyToTarget "$pathToConfig"
targetHostCmd nix-env -p "$profile" --set "$pathToConfig"
elif [ "$action" = test -o "$action" = build -o "$action" = dry-build -o "$action" = dry-activate ]; then
- pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}")"
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}")"
+ else
+ nix build "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}"
+ pathToConfig="$(readlink -f ./result)"
+ fi
elif [ "$action" = build-vm ]; then
- pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}")"
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}")"
+ else
+ echo "$0: 'build-vm' is not supported with '--flake'" >&2
+ exit 1
+ fi
elif [ "$action" = build-vm-with-bootloader ]; then
- pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}")"
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}")"
+ else
+ echo "$0: 'build-vm-with-bootloader' is not supported with '--flake'" >&2
+ exit 1
+ fi
else
showSyntax
fi
diff --git a/nixpkgs/nixos/modules/installer/tools/nixos-version.sh b/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
index 190c49a33ec..fb0fe26116a 100644
--- a/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
+++ b/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
@@ -6,8 +6,17 @@ case "$1" in
exit 1
;;
--hash|--revision)
+ if ! [[ @revision@ =~ ^[0-9a-f]+$ ]]; then
+ echo "$0: Nixpkgs commit hash is unknown"
+ exit 1
+ fi
echo "@revision@"
;;
+ --json)
+ cat <<EOF
+@json@
+EOF
+ ;;
*)
echo "@version@ (@codeName@)"
;;
diff --git a/nixpkgs/nixos/modules/installer/tools/tools.nix b/nixpkgs/nixos/modules/installer/tools/tools.nix
index 5df9c23e6b6..833865e99bb 100644
--- a/nixpkgs/nixos/modules/installer/tools/tools.nix
+++ b/nixpkgs/nixos/modules/installer/tools/tools.nix
@@ -31,6 +31,7 @@ let
nix = config.nix.package.out;
nix_x86_64_linux = fallback.x86_64-linux;
nix_i686_linux = fallback.i686-linux;
+ path = makeBinPath [ pkgs.jq ];
};
nixos-generate-config = makeProg {
@@ -47,6 +48,14 @@ let
name = "nixos-version";
src = ./nixos-version.sh;
inherit (config.system.nixos) version codeName revision;
+ inherit (config.system) configurationRevision;
+ json = builtins.toJSON ({
+ nixosVersion = config.system.nixos.version;
+ } // optionalAttrs (config.system.nixos.revision != null) {
+ nixpkgsRevision = config.system.nixos.revision;
+ } // optionalAttrs (config.system.configurationRevision != null) {
+ configurationRevision = config.system.configurationRevision;
+ });
};
nixos-enter = makeProg {