Use packages from flakes
Warning
This is based on the basic VM and we will only pay attention to the changes required to have the VM use packages defined by other flakes.
Overview
To install packages from another flake into the VM, we need to do the following:
- Add the other flake(s) as input(s) to our flake
- Pass the inputs to the NixOS configuration file (
configuration.nix
) - Right now, only
pkgs
(effectivelynixpkgs
) is passed along - Add the packages to install to the
environment.systemPackages
list
Setup
Add new flake as input
In this example, we will install libvfn
and xnvme, which as of writing are not available in nixpkgs.
They are available as packages in the flake github:nix4noobs/pkg-c-meson/master
:
inputs = {
# ...
nix4noobs-pkg-c-meson.url = "github:nix4noobs/pkg-c-meson/master";
# ...
};
Pass flake inputs to configuration.nix
Presently, configuration.nix
, which holds the NixOS configuration of our VM,
only gets the pkgs
argument, which itself is an alias of the nixpkgs
input.
Looking at configuration.nix
, we see that the file contains a single Nix
expression, which is really a function taking an attribute set (which must
have a pkgs
attribute), and returning another attribute set, the NixOS
configuration.
You could view the type signature of configuration.nix
as
{ pkgs, ...} -> { ... }
where the latter is the attribute set containing the
configuration of our NixOS VM.
In flake.nix
, we have the following:
vm = nixos-generators.nixosGenerate {
system = pkgs.system;
modules = [
# add configuration.nix here
./configuration.nix
];
format = "qcow";
}
The first thing to do, is to change ./configuration.nix
(a path) into
(import ./configuration.nix { inputs = self.inputs; })
. import
is
a builtin function which parses the given file and returns its nix expression.
In this case the full function we discussed.
Secondly, we use the self
argument which references the flake itself, to get
the inputs
attribute set - and we pass which along as an attribute set with
inputs = self.inputs
.
This will fail, recall configuration.nix
is presently
{ pkgs, ... } -> { ... }
, but now we need something like
{ inputs, ... } -> { pkgs, ... } -> { ... }
.
That is, we need to wrap the contents of configuration.nix
in another function.
Now we have passed the flake inputs attribute set to our NixOS configuration, which means we can reference packages from those inputs.
Install packages from flake
After adding the two new packages, the environment.systemPackages
list looks
like so:
environment.systemPackages = [
pkgs.fortune
inputs.nix4noobs-pkg-c-meson.packages.${pkgs.system}.libvfn
inputs.nix4noobs-pkg-c-meson.packages.${pkgs.system}.xnvme
];
Note that packages from flakes follow the form
inputs.<flake name>.packages.<system>.<package name>
. Note also that
pkgs.system
holds the current system. This comes from the definition of
forAllSystems
:
forAllSystems = fn:
nixpkgs.lib.genAttrs allSystems
(system: fn {
pkgs = import nixpkgs { inherit system; };
});
Note how pkgs
is the result of calling the function returned by import nixpkgs
with an attribute set where system
is the current system
value.