Or, the goal: How can I take a single package from Nix unstable in a declarative manner?
I'm new to NixOS and currently trying to install a newer version of Consul than the default 0.5.2
of my NixOS version (latest stable). I'm attempting this by overriding the derivative in my /etc/nix/configuration.nix
.
I'd like to keep running stable, but I found unstable had the version of Consul that I wanted (0.7.0
) already, and so I decided to use this package's attributes as a starting point to override https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/consul/default.nix
I copied it for most part into my configuration.nix
, here are the relevant sections:
nixpkgs.config.packageOverrides = pkgs: rec {
consul = pkgs.lib.overrideDerivation pkgs.consul (attrs: rec {
version = "0.7.0";
name = "consul-${version}";
rev = "v${version}";
goPackagePath = "github.com/hashicorp/consul";
src = pkgs.fetchFromGitHub {
owner = "hashicorp";
repo = "consul";
inherit rev;
sha256 = "04h5y5vixjh9np9lsrk02ypbqwcq855h7l1jlnl1vmfq3sfqjds7";
};
# Keep consul.ui for backward compatability
passthru.ui = pkgs.consul-ui;
});
};
environment.systemPackages = with pkgs; [
vim
which
telnet
consul-ui
consul-alerts
consul-template
consul
];
I'm running nix-build (Nix) 1.11.2
which throws:
$ nixos-rebuild switch
building Nix...
building the system configuration...
error: cannot coerce a set to a string, at /etc/nixos/configuration.nix:19:7
(use ‘--show-trace’ to show detailed location information)
When I look at line 19
it's where name
is set to "consul-${version}"
.
Why there is type-coercion going on here? Any tips will be greatly appreciated!
I'm also wondering if there is a better way to run just a single package in unstable, yet doing so declaratively from configuration.nix
, rather than imperatively?
To add to what Rok said:
Which should point you that an error actually happens at passthru, line. If you comment it out it will probably build. I'm assuming some recursive calls are at play here and error occurs when it tries to evaluate consul/consul-ui packages.
If you're just starting out, you can safely ignore what follows and perhaps come back to it if/when you're curious about the nitty-gritty.
The problem here is that overrideDerivation
is a kind of low-level approach to overriding things. Behind stdenv.mkDerivation
, we have a much smaller primitive function called derivation
. The derivation
function takes some attributes and (more or less -- see the docs for the finer details) just passes those attributes as environment variables during the build. The stdenv.mkDerivation
function, on the other hand, has a whole bunch of smarts layered on top that massages the attributes given to it before passing them onto derivation
-- and in some cases, as is the case with passthru
, it doesn't pass the attribute to derivation
at all.
Back to overrideDerivation
: it takes the final, tweaked attributes that stdenv.mkDerivation
would pass to derivation
, and just before that happens it allows you to override those attributes with the function you give it (e.g. that implies that, at that point, passthru
has already been removed). When your function adds a passthru
, that makes its way into derivation
, which then wants to coerce the value of passthru
into a string so it can make passthru
an environment variable during the build; however, because passthru
now points at a attribute-set, and such coercion isn't supported, Nix then complains.
So this sort of puts us in an odd situation. To illustrate, I'll copy the source for the consul package here:
{ stdenv, lib, buildGoPackage, consul-ui, fetchFromGitHub }:
buildGoPackage rec {
name = "consul-${version}";
version = "0.6.4";
rev = "v${version}";
goPackagePath = "github.com/hashicorp/consul";
src = fetchFromGitHub {
owner = "hashicorp";
repo = "consul";
inherit rev;
sha256 = "0p6m2rl0d30w418n4fzc4vymqs3vzfa468czmy4znkjmxdl5vp5a";
};
# Keep consul.ui for backward compatability
passthru.ui = consul-ui;
}
(Note that buildGoPackage
is a wrapper around stdenv.mkDerivation
.)
You might be familiar with e.g. consul.override
, which allows you to supply different inputs (e.g. maybe a different version of consul-ui
, or buildGoPackage
), but it doesn't allow you to override things that aren't inputs (e.g. src
, passthru
, etc). Meanwhile, overrideDerivation
allows you to modify the attrs given to derivation
, but not the ones given to stdenv.mkDerivation
. Ideally there would be something in-between, that would allow for manipulating the attrs given to stdenv.mkDerivation
, and it so happens that there's a PR open to address this:
https://github.com/NixOS/nixpkgs/pull/18660
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With