Recipes
A recipe is a Nix file in /rod/recipes, named NAME.nix, that adds software that is not in the package index or replaces an index package. rod +i NAME looks for the file before the index and installs it into the same profile as every other package, with the same pre-install frame. It is listed in /rod/installed and appears as a recipe line in a file written by rod +o.
Which recipes ship
The image copies the recipes of the repository to /rod/recipes: avtty, doas-uranium, initramfs-uranium, linux-uranium, uranium-tools, zen and zoneinfo. linux-uranium, initramfs-uranium and uranium-tools are the kernel, the initramfs and the tools including rod. zen is part of @desktop. Patch files a recipe names sit in the same directory and are referenced as ./fetch-system-dir.patch.
The shape of a file
A recipe is a function of the package set with a default, so nix-env can call it without arguments. It returns one derivation. This is the recipe for avtty:
{ pkgs ? import /rod/nixpkgs { } }:
pkgs.stdenv.mkDerivation {
pname = "avtty";
version = "0.12.0";
src = pkgs.fetchurl {
url = "https://github.com/texivi/avtty/archive/d4baa2f176a529d3f27b218a43bae51685df2c87.tar.gz";
sha256 = "79262e08234c5ddd997e21fc00df13fecd336ec45af6ceab4493d2f819bb5a99";
};
buildPhase = "cc -O2 avtty.c -o avtty";
installPhase = "install -Dm755 avtty $out/bin/avtty";
meta.license = pkgs.lib.licenses.gpl3Only;
}
Install it with the index in place:
# rod +s
# rod +i avtty
A recipe that only assembles other packages needs no source. zoneinfo links the time zone data of tzdata under a name of it's own:
{ pkgs ? import /rod/nixpkgs { } }:
pkgs.runCommand "zoneinfo" { } ''
mkdir -p $out/share
ln -s ${pkgs.tzdata}/share/zoneinfo $out/share/zoneinfo
''
Libraries and tools come from pkgs, for example buildInputs = [ pkgs.zlib ];. The zen recipe unpacks a prebuilt browser and patches it with nativeBuildInputs = [ pkgs.autoPatchelfHook pkgs.makeWrapper ]; and a buildInputs list, so its libraries are found in the store.
Name of the recipe and name of the package
rod picks the recipe by file name, but the profile records the package by the pname and version, or the name, in the derivation. rod +r and the holds use the profile name. They agree when the file is named after the pname, as with avtty and zen. The initramfs-uranium recipe sets name = "uranium-initrd", so it is installed with rod +i initramfs-uranium and removed with rod +r uranium-initrd. Name the file after the pname in your own recipes.
The hash
A recipe pins its source with a hash, and Nix refuses to build when the download differs. For a new source, write the recipe with hash = pkgs.lib.fakeHash; and let the build fail. Nix prints the real hash on a line that starts with got:, and rod looks for that line after a failed recipe build.
- If the recipe has exactly one line that starts with
sha256orhashfollowed by=, and standard input is a terminal, rod asksrod: set the hash in avtty.nix to HASH? [y/N], where HASH is the value aftergot:. yorYreplaces that line withhash = "HASH";at the same indentation and runs the install again. Any other answer ends rod with status 1 and leaves the file alone.- If there is not exactly one such line, or standard input is not a terminal, rod does not touch the file. Edit the line by hand.
The rewrite replaces the whole line, so keep the hash on one line with nothing else on it. A sha256 line in hexadecimal becomes a hash line in the form Nix prints. The recipe file has to be writable, so run rod as root.
Check the source before you accept a hash. It is the hash of whatever the URL returned at that moment, and it only protects later builds against a changed download.
Build and trust
A recipe is built from source on your machine. The sandbox is off, so the build runs as the user that started rod, normally root, with the network and the whole filesystem visible. Read a recipe before you install it, and do not install recipes you did not write or read. The result goes into /nix/store and the profile like any other package.
A recipe does not enter the index. rod +f WORD lists it as recipe: NAME, but rod +e, rod +d and rod +n only look at the index. rod +u upgrades against the index, and what it does to a recipe package whose name also exists there is untested. To update a recipe, edit the file and run rod +r NAME +i NAME, with the profile name for +r. rod -n +i NAME shows what the recipe would build.
See rod and package not in rod.