Mixing channels in nixos

Tagged with: nixos

When upgrading NixOS to its most recent release I had a problem. One of the packages in my configuration.nix file, Brittany, was marked as broken in the current nixpkgs. I still wanted to upgrade because the release updated the version of Krita available in nixpkgs to one that fixed a bug affecting my graphics tablet. But what to do about Brittany? NixOS had me covered.

The fetchTarball function in nix fetches a tarball, funnily enough, and caches it for an hour by default. You can then make it available to your configuration.nix. The start of the packages section of my config thus now looks like the below:

{ config, pkgs, ... }:

let
  oldTarball = fetchTarball https://nixos.org/channels/nixos-18.09/nixexprs.tar.xz;
in

{
  # Setup nixpkgs
  nixpkgs.config = {
    allowUnfree = true;
    firefox = {
      enableGnomeExtensions = true;
    };
    packageOverrides = pkgs: {
      old = import oldTarball {
        config = config.nixpkgs.config;
      };
    };
  };

  # List packages installed in system profile. To search by name, run:

The important parts for what we're doing here are the oldTarball definition and the packageOverrides inside nixpkgs.config. These are fairly readable I think, and give us the option of installing packages from 18.09 while the rest of the system defaults to 19.03. An abridged look at the rest of my packages definition shows how we can use this in context:

  # $ nix-env -qaP | grep wget
  environment.systemPackages = with pkgs; [
    cabal2nix
    ...

    # Haskell packages
    cabal-install
    old.haskellPackages.brittany
    haskellPackages.hakyll

  ];
}

Edit

u/srhb on reddit pointed out that my approach was impure (I presume because the tarball at the URL to which I'm pointing is fetched each time and subject to change). The suggestion was that we use the additional arguments available in fetchTarball to fetch a specific commit once. Using this approach my original import of the tarball now looks like this:

let
  oldTarball = fetchTarball {
    url = https://github.com/NixOS/nixpkgs/archive/373c8c385e66a0cca98c1078bb3cbea0b10708a7.tar.gz;
    sha256 = "0jvi7p3hnm6fl2wv4z9gj3lapda52xnln83jl33qs0q620v8zalz";
  };
in

The URL references an up-to-date commit of the branch in which you're interested. NixOS also makes fetching the value for sha256 simple; we just run:

nix-prefetch-url https://github.com/NixOS/nixpkgs/archive/373c8c385e66a0cca98c1078bb3cbea0b10708a7.tar.gz --unpack

and take the value from what it returns.