Closed llakala closed 2 weeks ago
I'm splitting this into two issues. There's really two separate problems here: flake registry stuff for nix run
, and configuration for use of pkgs
and pkgs-unstable
within the configuration. That second one will now be at #48. This issue will be limited to finding a workaround for the registry stuff.
Thanks to @frontear educating me, I know more about the flake registry. I also now dislike it.
See, nix.registry.nixpkgs.flake = inputs.nixpkgs;
won't do anything for actually applying configuration options. It just changes the version of nixpkgs we're referencing -- the path.
So, how do we make the
nixpkgs
referenced innix run
allow unfree?
Oh, it's simple. We don't.
Well, at least, there's no supported way. But I'm one for workarounds. These include:
nix run
to NIXPKGS_ALLOW_UNFREE=1 nix run --impure
nix.registry.nixpkgs.flake
point to a file that basically runs the equivalent of import nixpkgs { config.allowUnfree = true; }
, then we can have our cake and eat it too. Everything works!That last one sounds simple in theory. Sadly, the execution is a bit more complicated. Time to over-explain, otherwise I'll never be able to remember this:
See, the import nixpkgs
thing has to know which store path to grab nixpkgs from. So, we'll have to pass that into the file.
Oh, but can't I just pass in inputs? Problem solved.
Well, yes, but no. Apparently, we have to make sure to "resolve inputs beforehand". My understanding of this is:
When writing to the nix store, we have to make sure we don't write down a $REPLACEMEATCOMPILETIME. Instead, it has to be written with the input value.
But, if I can't pass in inputs, what can I do?
Well, the problem isn't passing in inputs. It's making sure that we write to the nix store with the input path replaced before writing it down . With this code snippet:
runCommandLocal "make-nix-thingy" {}
''
substituteInPlace @nixpkgs@ ${inputs.nixpkgs}
''
This will apparently work.
Hi 👋
Let me quickly add that last snippet of runCommandLocal is incomplete, but it should work completely fine in theory due to how nix evaluations will handle the runCommandLocal.
If you'd like I can run a test on this type of thing and send you a complete reproducible example of what you're looking for.
Hi 👋
Let me quickly add that last snippet of runCommandLocal is incomplete, but it should work completely fine in theory due to how nix evaluations will handle the runCommandLocal.
If you'd like I can run a test on this type of thing and send you a complete reproducible example of what you're looking for.
That'd be awesome! Thanks so much for all your help ♥️
I had a gut feeling I was missing something, and I just discovered it during my testing. Our idea would have been fine (maybe) if nix run
and the other nix
cli used a default.nix
, but they do not! They use a flake.nix
, which complicates the matter pretty significantly.
Not to worry though, I figured a very easy solution (it kind of does the same thing as https://github.com/numtide/nixpkgs-unfree but with more granular control).
This code might look wack as FUCK but this will work, I've confirmed it on my own system:
{
path,
runCommandLocal,
}:
runCommandLocal "nixpkgs-configured" { src = path; } ''
mkdir -p $out
substitute $src/flake.nix $out/flake.nix \
--replace-fail "{ inherit system; }" "{ inherit system; config.allowUnfree = true; }"
cp --update=none -Rt $out $src/*
''
Use this in your nixos configuration like this:
# nixpkgs.nix is just the above file copy-pasted
nix.registry.nixpkgs.flake = pkgs.callPackage ./nixpkgs.nix {};
Then when your system is built, go ahead and do nix run nixpkgs#google-chrome
or some other unfree package, and boom, it works.
I had a gut feeling I was missing something, and I just discovered it during my testing. Our idea would have been fine (maybe) if
nix run
and the othernix
cli used adefault.nix
, but they do not! They use aflake.nix
, which complicates the matter pretty significantly.Not to worry though, I figured a very easy solution (it kind of does the same thing as numtide/nixpkgs-unfree but with more granular control).
This code might look wack as FUCK but this will work, I've confirmed it on my own system:
{ path, runCommandLocal, }: runCommandLocal "nixpkgs-configured" { src = path; } '' mkdir -p $out substitute $src/flake.nix $out/flake.nix \ --replace-fail "{ inherit system; }" "{ inherit system; config.allowUnfree = true; }" cp --update=none -Rt $out $src/* ''
Use this in your nixos configuration like this:
# nixpkgs.nix is just the above file copy-pasted nix.registry.nixpkgs.flake = pkgs.callPackage ./nixpkgs.nix {};
Then when your system is built, go ahead and do
nix run nixpkgs#google-chrome
or some other unfree package, and boom, it works.
Got it working!
I did have to make one small edit:
nix.registry = lib.mkForce
{
nixpkgs.flake = pkgs.callPackage ./nixpkgs/unfree.nix {}; # Makes `nix run` commands use unfree
};
If I didn't use lib.mkForce, I got this error for conflicting statements:
error: The option `nix.registry.nixpkgs.to.path' has conflicting definition values:
- In `/nix/store/m1g5a7agja7si7y9l1lzwhp3capbv7x9-source/nixos/modules/config/nix-flakes.nix': "/nix/store/xhf7lw9yrn6jlwfnvwkkhfzlvap04rjq-nixpkgs-configured"
- In `/nix/store/m1g5a7agja7si7y9l1lzwhp3capbv7x9-source/nixos/modules/misc/nixpkgs-flake.nix': "/nix/store/m1g5a7agja7si7y9l1lzwhp3capbv7x9-source"
Use `lib.mkForce value` or `lib.mkDefault value` to change the priority on any of these definitions.
Finished at 09:59:59 after 17s
i thought this would go away when I stopped doing nixpkgs.pkgs = pkgs;
, but it was still happening.
One question: is there any way to specify an input to base off, as we'd typically do with nix.registry.nixpkgs.flake
? I assume that the current approach is based off whatever version of nixpkgs the registry uses by default: but if I want to have a registry entry for both nixpkgs
and nixpkgs-unstable
, I'd need to find a way to specify a version from inputs.
The path
attribute is a path to the nix store containing the root of the nixpkgs source. You can replace it with any input and itll extrapolate the .outPath
of that input.
Say you want to have nixpkgs-unstable, you simply do pkgs.callPackage ./nixpkgs.nix { path = "${inputs.nixpkgs-unstable}"; }
The
path
attribute is a path to the nix store containing the root of the nixpkgs source. You can replace it with any input and itll extrapolate the.outPath
of that input.Say you want to have nixpkgs-unstable, you simply do
pkgs.callPackage ./nixpkgs.nix { path = "${inputs.nixpkgs-unstable}"; }
Works perfectly! Thanks so much again, this is exactly what I needed and is super customizable. Someday I'll make a blog post about this and give you all the credit in the world.
Currently, we have all our settings for pkgs declared when we import
pkgs
andpkgs-unstable
viamyLib
. However, this makes it sonix run
uses the versionnixpkgs
from our inputs, which doesn't haveallowUnfree
applied to it.