jungle/web/content/intro-nix/ch2.md

5.4 KiB

title date weight
Chapter 2: Your first shell 2023-09-15 2

Creating a shell with flake.nix

First, create an empty git repository where your shells will live:

hut% mkdir jungle-examples
hut% cd jungle-examples
hut% git init
Initialized empty Git repository in /home/Computational/rarias/jungle-examples/.git/

And then, place a file named flake.nix on the repo with this content:

{
  inputs.jungle.url = "jungle";
  nixConfig.bash-prompt = "\[nix-develop\]$ ";

  outputs = { self, jungle }:  
  let
    pkgs = jungle.outputs.packages.x86_64-linux;
  in {
    devShells.x86_64-linux.default = pkgs.mkShell rec {
      pname = "my-shell";
      buildInputs = with pkgs.bsc; [
        ovni osumb # other packages here...
      ];
    };
  };
}

This file defines a how to create a shell in the Nix language with the pkgs.mkShell function using the packages listed in buildInputs. It also requests the packages to be taken from the jungle input, which corresponds to the set of packages that we defined earlier, tuned for the cluster. We will describe it in more detail later.

The tool nix develop tries to find a flake.nix in the current directory and enter the shell described by devShells.x86_64-linux.default (or the corresponding architecture).

Now, it is important that all the files of the repository are committed in git, as nix will only read what is in the index of git. If we try to enter the shell with the nix develop command, it will complain and fail:

hut% nix develop
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
error: getting status of '/nix/store/0ccnxa25whszw7mgbgyzdm4nqc0zwnm8-source/flake.nix': No such file or directory

The first warning states that the git directory has modified files not added to the index. Then the error occurs because the flake.nix is not in the index of git, so nix develop doesn't see it. So let's add it to a commit and try again:

hut% git add flake.nix
hut% git commit flake.nix -m 'First shell'
[master (root-commit) eb8a4ac] First shell
 1 file changed, 13 insertions(+)
 create mode 100644 flake.nix
hut% nix develop
warning: creating lock file '/home/Computational/rarias/jungle-examples/flake.lock'
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
[nix-develop]$

In the flake.nix we have set the shell prompt to [nix-develop] so we can easily spot that we are inside a nix develop shell. To exit:

[nix-develop]$ exit
hut%

Using the flake.lock file

Now we see the creating lock file message and the git tree becomes dirty again (however, we enter the shell successfully).

This flake.lock file that has been created collects the current state of the jungle packages in a file, so future invocations will use the same versions. We can see more details with nix flake metadata:

hut% nix flake metadata
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
Resolved URL:  git+file:///home/Computational/rarias/jungle-examples
Locked URL:    git+file:///home/Computational/rarias/jungle-examples
Path:          /nix/store/bckxqjkkv52hy4pzgb96r7fchhmvmql8-source
Revision:      eb8a4ac544a74e3995d859c751e9ff4339de6509-dirty
Last modified: 2023-09-15 13:06:12
Inputs:
└───jungle: path:/nix/store/3wv6q0f3pkgw840nnkn4jsp9xi650dyj-source?lastModified=1694772033&narHash=sha256-7a09O0Jb8WncxeB32ywmQEMqJdEFLrOG/XVT9bdII6I%3D&rev=653d411b9e46076a7878be9574ed6b3bd627cff1&revCount=195
    ├───agenix: github:ryantm/agenix/d8c973fd228949736dedf61b7f8cc1ece3236792
    │   ├───darwin: github:lnl7/nix-darwin/87b9d090ad39b25b2400029c64825fc2a8868943
    │   │   └───nixpkgs follows input 'jungle/agenix/nixpkgs'
    │   ├───home-manager: github:nix-community/home-manager/32d3e39c491e2f91152c84f8ad8b003420eab0a1
    │   │   └───nixpkgs follows input 'jungle/agenix/nixpkgs'
    │   └───nixpkgs follows input 'jungle/nixpkgs'
    ├───bscpkgs: git+https://pm.bsc.es/gitlab/rarias/bscpkgs.git?ref=refs/heads/master&rev=3a4062ac04be6263c64a481420d8e768c2521b80
    │   └───nixpkgs follows input 'jungle/nixpkgs'
    └───nixpkgs: github:NixOS/nixpkgs/e56990880811a451abd32515698c712788be5720

Now, as long as we keep these two files flake.nix and flake.lock, we can reproduce the same shell in the future, so let's add the lock file into git too.

hut% git commit -m 'Add flake.lock file'
[master d3725ec] Add flake.lock file
 1 file changed, 135 insertions(+)
 create mode 100644 flake.lock
hut% git status
On branch master
nothing to commit, working tree clean

Using the shell with nix develop

Now, the invocations of nix develop won't complain that the git tree is dirty anymore and will enter the shell:

hut% nix develop
[nix-develop]$

And the requested packages are now available:

[nix-develop]$ which ovniemu
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0/bin/ovniemu

The packages of the shell are listed in the $buildInputs variable, in case you need to examine them:

[nix-develop]$ printf '%s\n' $buildInputs
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0
/nix/store/lnjirzllhjn2fadlqzrz7a547iawl8jc-osu-micro-benchmarks-7.1-1
[nix-develop]$ exit
hut%

In the next chapter we will see how to add more packages and also how to modify them.