Using Nix

From Alliance Doc
Revision as of 21:26, 4 February 2019 by Tyson (talk | contribs) (Missing an --attr flag on the final example)
Jump to navigation Jump to search


This article is a draft

This is not a complete article: This is a draft, a work in progress that is intended to be published into an article, which may or may not be ready for inclusion in the main wiki. It should not necessarily be considered factual or authoritative.




Nix is a package manager system that allows users to manage their own persistent software environment. At the moment it is only available on graham.

  • Users can build, install, upgrade, downgrade, and remove packages from their environment without root privileges and without affecting other users.
  • Operations either succeed and create a new environment or fail leaving the previous environment in place (operations are atomic).
  • Previous environments can be switched back to at any point.
  • Users can add their own packages and share them with other users.

The default Nix package set includes a huge selection (over 10,000) of recent versions of many packages.

NOTE: The message failed to lock thread to CPU XX is a harmless warning that can be ignored.

Enabling and disabling the Nix environment

The user's current Nix environment is enabled by loading the nix module. This creates some .nix* files and sets some environment variables.

[name@cluster:~] module load nix


It is disabled by unloading the nix module. This unsets the environment variables but leaves the .nix* files alone.

[name@cluster:~] module unload nix


Completely reseting the Nix environment

Most operations can be undone with the --rollback option (i.e., nix-env --rollback or nix-channel --rollback). Sometimes it is useful to entirely reset nix though. This is done by unloading the module, erasing all user related nix files, and then reloading the module file.

[name@cluster:~] module unload nix
[name@cluster:~] rm -fr ~/.nix-profile ~/.nix-defexpr ~/.nix-channels ~/.config/nixpkgs
[name@cluster:~] rm -fr /nix/var/nix/profiles/per-user/$USER /nix/var/nix/gcroots/per-user/$USER
[name@cluster:~] module load nix


Installing and removing packages

The nix-env command is used to setup your Nix environment.

What do I have installed and what can I install

Lets first see what we currently have installed.

[name@cluster:~] nix-env --query


Now let's see what is available. We request the attribute paths (unambiguous way of specifying a package) and the descriptions too (cursor to the right to see them). This takes a bit of time as it visits a lot of small files. Especially over NFS it can be a good idea to pipe it to a file and then grep that in the future.

[name@cluster:~] nix-env --query --available --attr-path --description


Installing packages

Let's say that we need a newer version of git than provided by default. First lets check what our OS comes with.

[name@cluster:~] git --version
[name@cluster:~] which git


Let's tell Nix to install its version in our environment.

[name@cluster:~] nix-env --install --attr nixpkgs.git
[name@cluster:~] nix-env --query


Let's checkout what we have now (it may be necessary to tell bash to to forget remembered executable locations with hash -r so it notices the new one).

[name@cluster:~] git --version
[name@cluster:~] which git


Removing packages

For completeness, lets add in the other usual version-control suspects.

[name@cluster:~] nix-env --install --attr nixpkgs.subversion nixpkgs.mercurial
[name@cluster:~] nix-env --query


Actually, we probably don't really want subversion any more. Let's remove that.

[name@cluster:~] nix-env --uninstall subversion
[name@cluster:~] nix-env --query


Environments

Nix keeps referring to user environments. Each time we install or remove packages we create a new environment based off of the previous environment.

Switching between previous environments

This means the previous environments still exist and we can switch back to them at any point. Let's say we changed our mind and want subversion back. It's trivial to restore the previous environment.

[name@cluster:~] nix-env --rollback
[name@cluster:~] nix-env --query


Of course we may want to do more than just move to the previous environment. We can get a list of all our environments so far and then jump directly to whatever one we want. Let's undo the rollback.

[name@cluster:~] nix-env --list-generations
[name@cluster:~] nix-env --switch-generation 4
[name@cluster:~] nix-env --query


Operations are atomic

Due to the atomic property of Nix environments, we can't be left halfway through installing/updating packages. They either succeed and create us a new environment or leave us with the previous one intact.

Let's go back to the start when we just had Nix itself and install the one true GNU distributed version control system tla. Don't let it complete though. Hit it with CTRL+c partway through.

[name@cluster:~] nix-env --switch-generation 1
[name@cluster:~] nix-env --install --attr nixpkgs.tla
CTRL+c


Nothing bad happens. The operation didn't complete so it has no effect on the environment whatsoever.

[name@cluster:~] nix-env --query
[name@cluster:~] nix-env --list-generations


Nix only does things once

The install and remove commands take the current environment and create a new environment with the changes. This works regardless of which environment we are currently in. Let's create a new environment from our original environment by just adding git and mercurial.

[name@cluster:~] nix-env --list-generations
[name@cluster:~] nix-env --install --attr nixpkgs.git nixpkgs.mercurial
[name@cluster:~] nix-env --list-generations


Notice how much much faster it was to install git and mercurial the second time? That is because the software already existed in the local Nix store from the previous installs so Nix just reused it.

Garbage collection

Nix periodically goes through and removes any software not accessible from any existing environments. This means we have to explicitly delete environments we don't want anymore so Nix is able to reclaim the space. We can delete specific environments or any sufficiently old.

[name@cluster:~] nix-env --delete-generations 30d