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 4 commits into
base: master
Choose a base branch
from

Conversation

rnhmjoj
Copy link
Contributor

@rnhmjoj rnhmjoj commented Jan 12, 2025

A non-breaking and (IMHO) simpler alternative to #333788 for setting the Nixpkgs versions declaratively from configuration.nix.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change (nixos-rebuild, nixos-rebuild-ng)
  • Tested basic functionality of all binary files
  • 25.05 Release Notes (or backporting 24.11 and 25.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: documentation This PR adds or changes documentation 8.has: changelog 8.has: module (update) This PR changes an existing module in `nixos/` labels Jan 12, 2025
@nix-owners nix-owners bot requested a review from thiagokokada January 12, 2025 14:32
Comment on lines 12 to 22
@patch(get_qualified_name(nr.process.subprocess.run), autospec=True)
def test_build_attr_from_arg(mock_run: Any, tmp_path: Path) -> None:
nixpkgs_path = tmp_path / "nixpkgs"
mock_run.side_effect = [
# with config.nixpkgs.source
subprocess.CompletedProcess([], 0, f"\"{nixpkgs_path}\"\n"),
# without config.nixpkgs.source
subprocess.CompletedProcess([], 1, ""),
]
assert m.BuildAttr.from_arg(None, None) == m.BuildAttr(str(nixpkgs_path / "nixos"), None)
assert m.BuildAttr.from_arg(None, None) == m.BuildAttr("<nixpkgs/nixos>", None)
Copy link
Contributor

@thiagokokada thiagokokada Jan 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to do a scoped patch here instead:

Suggested change
@patch(get_qualified_name(nr.process.subprocess.run), autospec=True)
def test_build_attr_from_arg(mock_run: Any, tmp_path: Path) -> None:
nixpkgs_path = tmp_path / "nixpkgs"
mock_run.side_effect = [
# with config.nixpkgs.source
subprocess.CompletedProcess([], 0, f"\"{nixpkgs_path}\"\n"),
# without config.nixpkgs.source
subprocess.CompletedProcess([], 1, ""),
]
assert m.BuildAttr.from_arg(None, None) == m.BuildAttr(str(nixpkgs_path / "nixos"), None)
assert m.BuildAttr.from_arg(None, None) == m.BuildAttr("<nixpkgs/nixos>", None)
def test_build_attr_from_arg(tmp_path: Path) -> None:
nixpkgs_path = tmp_path / "nixpkgs"
with patch(get_qualified_name(nr.process.subprocess.run), autospec=True, return_value=subprocess.CompletedProcess([], 0, f"\"{nixpkgs_path}\"\n")):
assert m.BuildAttr.from_arg(None, None) == m.BuildAttr(str(nixpkgs_path / "nixos"), None)
with patch(get_qualified_name(nr.process.subprocess.run), autospec=True, return_value=subprocess.CompletedProcess([], 1, "")):
assert m.BuildAttr.from_arg(None, None) == m.BuildAttr("<nixpkgs/nixos>", None)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thank you!

Copy link
Contributor

@thiagokokada thiagokokada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't comment too much about the change itself since I use Flakes, but at least the nixos-rebuild-ng changes looks good to me.

Left a comment about the tests mocks but this is not a merge blocker.

Copy link
Contributor

@amozeo amozeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, nixpkgs.source option in nixos is an interesting approach to pin nixpkgs for a given nixos configuration. I found several issues with your implementation of it.

I cannot review changes in nixos-rebuild-ng because I am not familiar with its code.

in nixos-rebuild.sh, there is also one more instance of getting nixpkgs from nix path in line 646 (after changes). I think you forgot about that occurence.

@@ -157,6 +157,30 @@ in
'';
};

source = lib.mkOption {
type = lib.types.str;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current type allows to point to a path outside of the nix store.
I don't think this was intended to allow out of store paths or any string here. Consider using lib.types.derivation, which checks if the path, or string, is a store path.

@@ -157,6 +157,30 @@ in
'';
};

source = lib.mkOption {
type = lib.types.str;
defaultText = "<nixpkgs>";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not sufficiently described for/if flakes are used. I would remove defaultText.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm, I'm actually not sure what happens if you use flakes. I guess it will be completely ignored.

description = ''
If set, the path to the Nixpkgs source that will be used by the
`nixos-rebuild` tool to build the NixOS system, otherwise the default
is to use the `<nixpkgs>` channel.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not sufficiently described for/if flakes are used. Consider adding what the default is, when flakes are used.

Suggested change
is to use the `<nixpkgs>` channel.
is to use the nixpkgs NIX_PATH, or the flake input from where you're
using 'lib.nixosSystem'.

Comment on lines +386 to +394
# Link the Nixpkgs source to the system closure
system.extraSystemBuilderCmds = lib.mkIf (
config.nixpkgs ? source
) "ln -s ${config.nixpkgs.source} $out/nixpkgs";

# Set nixpkgs in NIX_PATH if nix-channel is disabled
nix.nixPath = lib.optional (
config.nixpkgs ? source && !config.nix.channel.enable
) "nixpkgs=/run/current-system/nixpkgs";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is necessary to link nixpkgs to system derivation. You can directly use config.nixpkgs.source in config.nix.nixPath option definition.

What if I don't want to have nixpkgs in nixPath? there is no enable/disable option for that.

config.nixpkgs ? source is not how you check if option is set or not, use options.nixpkgs.source.isDefined

Suggested change
# Link the Nixpkgs source to the system closure
system.extraSystemBuilderCmds = lib.mkIf (
config.nixpkgs ? source
) "ln -s ${config.nixpkgs.source} $out/nixpkgs";
# Set nixpkgs in NIX_PATH if nix-channel is disabled
nix.nixPath = lib.optional (
config.nixpkgs ? source && !config.nix.channel.enable
) "nixpkgs=/run/current-system/nixpkgs";
# Set nixpkgs in NIX_PATH if nix-channel is disabled
nix.nixPath = lib.optional (
options.nixpkgs.source.isDefined && !config.nix.channel.enable
) "nixpkgs=${config.nixpkgs.source}";

@@ -489,7 +489,7 @@ if [[ -z $_NIXOS_REBUILD_REEXEC && -n $canRun && -z $fast ]]; then
p=$(runCmd nix-build --no-out-link $buildFile -A "${attr:+$attr.}config.system.build.nixos-rebuild" "${extraBuildFlags[@]}")
SHOULD_REEXEC=1
elif [[ -z $flake ]]; then
if p=$(runCmd nix-build --no-out-link --expr 'with import <nixpkgs/nixos> {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then
if p=$(runCmd nix-build --no-out-link --expr 'with import "$nixpkgsPath/nixos" {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$nixpkgsPath used here is set from an environment variable, because function that set that variable is ran after this line.

this is also true for $nixpkgsPath in line 579, 580, 582 (after changes).

@@ -604,6 +621,8 @@ getVersion() {
}


getNixpkgsPath
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function should be ran at least before the first use of $nixpkgsPath. Consider moving this and the function itself at least before the first use in line 492

Comment on lines +555 to +559
# Get NixOS configuration
NIXOS_CONFIG=${NIXOS_CONFIG:-$(runCmd nix-instantiate --find-file nixos-config)}
if [[ -d $NIXOS_CONFIG ]]; then
NIXOS_CONFIG=$NIXOS_CONFIG/default.nix
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is necessary to move that code from line 517 (before changes) here.
What is the purpose of moving it?

@amozeo
Copy link
Contributor

amozeo commented Jan 12, 2025

I just noticed that there is option nixpkgs.flake.sources that tries to hold similar information as the option that you want to add, nixpkgs.source, maybe we want to deprecate it/change it/reuse it? doesn't look like it's used anywhere else in nixos module system except that file where is declared.

@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Jan 12, 2025

Hey, nixpkgs.source option in nixos is an interesting approach to pin nixpkgs for a given nixos configuration.
I found several issues with your implementation of it.

Thank you for reviewing!

in nixos-rebuild.sh, there is also one more instance of getting nixpkgs from nix path in line 646 (after changes). I think you forgot about that occurence.

Yes, I missed it because I was looking only for the angle brackets syntax.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 1-10 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants