Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/nixpkgs: add option to specify Nixpkgs source path #373201

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
# See: failed attempt to make pkgs.path not copy when using flakes:
# https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1023287913
({ config, pkgs, lib, ... }: {
config.nixpkgs.flake.source = self.outPath;
config.nixpkgs.source = self.outPath;
config.system.build.usingFlakes = true;
})
];
} // builtins.removeAttrs args [ "modules" ]
Expand Down
2 changes: 1 addition & 1 deletion nixos/doc/manual/release-notes/rl-2405.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ In addition to numerous new and upgraded packages, this release has the followin

This may be undesirable if Nix commands are not going to be run on the built system since it adds nixpkgs to the system closure. For such closure-size-constrained non-interactive systems, this setting should be disabled.

To disable it, set [nixpkgs.flake.setNixPath](#opt-nixpkgs.flake.setNixPath) and [nixpkgs.flake.setFlakeRegistry](#opt-nixpkgs.flake.setFlakeRegistry) to false.
To disable it, set `nixpkgs.flake.setNixPath` and `nixpkgs.flake.setFlakeRegistry` to false.

- NixOS AMIs are now uploaded regularly to a new AWS Account.
Instructions on how to use them can be found on <https://nixos.github.io/amis>.
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2505.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
- A `nixos-rebuild build-image` sub-command has been added.
It allows users to build platform-specific (disk) images from their NixOS configurations. `nixos-rebuild build-image` works similar to the popular [nix-community/nixos-generators](https://github.com/nix-community/nixos-generators) project. See new [section on image building in the nixpkgs manual](https://nixos.org/manual/nixpkgs/unstable/#sec-image-nixos-rebuild-build-image). It is also available for `nixos-rebuild-ng`.

- Using the new `nixpkgs.source` option it is finally possible to build NixOS with a specific Nixpkgs version declaratively, without depending on nix-channel or flakes.

- `nixos-option` has been rewritten to a Nix expression called by a simple bash script. This lowers our maintenance threshold, makes eval errors less verbose, adds support for flake-based configurations, descending into `attrsOf` and `listOf` submodule options, and `--show-trace`.

<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@
...
}:
let
cfg = config.nixpkgs.flake;
cfg = config.nixpkgs;
usingFlakes = config.system.build.usingFlakes;
in
{
options.nixpkgs.flake = {

imports = [
(lib.mkRenamedOptionModule [ "nixpkgs" "flake" "source" ] [ "nixpkgs" "source" ])
(lib.mkRenamedOptionModule [ "nixpkgs" "flake" "setNixPath" ] [ "nixpkgs" "setNixPath" ])
(lib.mkRenamedOptionModule
[ "nixpkgs" "flake" "setFlakeRegistry" ]
[ "nixpkgs" "setFlakeRegistry" ]
)
];

options.nixpkgs = {
source = lib.mkOption {
# In newer Nix versions, particularly with lazy trees, outPath of
# flakes becomes a Nix-language path object. We deliberately allow this
Expand All @@ -19,49 +30,56 @@ in
type = lib.types.nullOr (lib.types.either lib.types.str lib.types.path);

default = null;
defaultText = "if (using nixpkgsFlake.lib.nixosSystem) then self.outPath else null";
defaultText = ''if (using nixpkgsFlake.lib.nixosSystem) then self.outPath else "<nixpkgs>"'';

example = ''builtins.fetchTarball { name = "source"; sha256 = "${lib.fakeHash}"; url = "https://github.com/nixos/nixpkgs/archive/somecommit.tar.gz"; }'';

description = ''
The path to the nixpkgs sources used to build the system. This is automatically set up to be
the store path of the nixpkgs flake used to build the system if using
`nixpkgs.lib.nixosSystem`, and is otherwise null by default.
If set, the path to the Nixpkgs sources that will be used by the
`nixos-rebuild` tool to build the NixOS system, otherwise the default
is to use `nixpkgs` from the {env}`NIX_PATH`.

This can also be optionally set if the NixOS system is not built with a flake but still uses
pinned sources: set this to the store path for the nixpkgs sources used to build the system,
as may be obtained by `builtins.fetchTarball`, for example.
When using flakes, this is automatically set up to be the store path of
the nixpkgs flake used to build the system if using
`nixpkgs.lib.nixosSystem`, and is otherwise null by default.

Note: the name of the store path must be "source" due to
::: {.note}
The name of the store path must be "source" due to
<https://github.com/NixOS/nix/issues/7075>.
:::
'';
};

setNixPath = lib.mkOption {
type = lib.types.bool;

default = cfg.source != null;
defaultText = "config.nixpkgs.flake.source != null";
defaultText = "config.nixpkgs.source != null";

description = ''
Whether to set {env}`NIX_PATH` to include `nixpkgs=flake:nixpkgs` such that `<nixpkgs>`
lookups receive the version of nixpkgs that the system was built with, in concert with
{option}`nixpkgs.flake.setFlakeRegistry`.
Whether to set {env}`NIX_PATH` so that `<nixpkgs>` lookups receive the
version of Nixpkgs that the system was built with, meaning the value of
{option}`nixpkgs.source`.

This is on by default for NixOS configurations built with flakes.
This makes, for example, {command}`nix-build '<nixpkgs>' -A hello` work
out of the box on systems built with flakes or with `nix-channel`
disabled.

This makes {command}`nix-build '<nixpkgs>' -A hello` work out of the box on flake systems.
When using flakes this option is on by default and will add
`nixpkgs=flake:nixpkgs` to the {env}`NIX_PATH`, in concert with
{option}`nixpkgs.setFlakeRegistry`.

Note that this option makes the NixOS closure depend on the nixpkgs sources, which may add
undesired closure size if the system will not have any nix commands run on it.
Note that this option makes the NixOS closure depend on the nixpkgs
sources, which may add undesired closure size if the system will not
have any nix commands run on it.
'';
};

setFlakeRegistry = lib.mkOption {
type = lib.types.bool;

default = cfg.source != null;
defaultText = "config.nixpkgs.flake.source != null";
default = usingFlakes && cfg.source != null;
defaultText = "config.nixpkgs.source != null";

description = ''
Whether to pin nixpkgs in the system-wide flake registry (`/etc/nix/registry.json`) to the
Expand All @@ -83,9 +101,9 @@ in
{
assertions = [
{
assertion = cfg.setNixPath -> cfg.setFlakeRegistry;
assertion = (usingFlakes && cfg.setNixPath) -> cfg.setFlakeRegistry;
message = ''
Setting `nixpkgs.flake.setNixPath` requires that `nixpkgs.flake.setFlakeRegistry` also
Setting `nixpkgs.setNixPath` requires that `nixpkgs.setFlakeRegistry` also
be set, since it is implemented in terms of indirection through the flake registry.
'';
}
Expand All @@ -103,8 +121,11 @@ in
# perhaps, to ever make that work (in order to know where the Nix expr for the system came
# from and how to call it).
nix.nixPath = lib.mkDefault (
[ "nixpkgs=flake:nixpkgs" ]
++ lib.optional config.nix.channel.enable "/nix/var/nix/profiles/per-user/root/channels"
lib.optional (!usingFlakes) "nixpkgs=${cfg.source}"
++ lib.optional usingFlakes "nixpkgs=flake:nixpkgs"
++ lib.optional (
usingFlakes && config.nix.channel.enable
) "/nix/var/nix/profiles/per-user/root/channels"
);
})
]
Expand Down
2 changes: 1 addition & 1 deletion nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
./misc/meta.nix
./misc/nixops-autoluks.nix
./misc/nixpkgs.nix
./misc/nixpkgs-flake.nix
./misc/nixpkgs-pin.nix
./misc/passthru.nix
./misc/version.nix
./misc/wordlist.nix
Expand Down
6 changes: 6 additions & 0 deletions nixos/modules/system/activation/top-level.nix
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ in
You can read this path in a custom deployment tool for example.
'';
};
usingFlakes = mkOption {
type = types.bool;
default = false;
readOnly = true;
description = "Whether the NixOS system is being built using flakes.";
};
};


Expand Down
27 changes: 26 additions & 1 deletion pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import platform
import re
import os
import subprocess
import textwrap
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
Expand Down Expand Up @@ -57,7 +59,30 @@ def to_attr(self, *attrs: str) -> str:
@classmethod
def from_arg(cls, attr: str | None, file: str | None) -> Self:
if not (attr or file):
return cls("<nixpkgs/nixos>", None)
# If present, use config.nixpkgs.source
nixos_config = os.getenv("NIXOS_CONFIG", "<nixos-config>")
r = run_wrapper(
[
"nix-instantiate",
"--eval",
"--expr",
textwrap.dedent(f"""
(import <nixpkgs/nixos> {{
configuration = {{
imports = [ {nixos_config} ];
_module.check = false;
}};
}}).config.nixpkgs.source
"""),
],
check=False,
capture_output=True,
)
if r.returncode == 0:
return cls(r.stdout.strip('"\n') + "/nixos", None)
else:
# Fall back to nixpkgs channel
return cls("<nixpkgs/nixos>", None)
return cls(Path(file or "default.nix"), attr)


Expand Down
Loading