Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
4da36899f5 | |||
3906876a69 |
7
web/content/intro-nix/_index.md
Normal file
7
web/content/intro-nix/_index.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
title: "Intro to nix"
|
||||
date: 2023-09-15
|
||||
---
|
||||
|
||||
Basic introduction to Nix for users of the jungle machines. You should be able
|
||||
to access the jungle machines, otherwise [request access](/access).
|
100
web/content/intro-nix/ch1.md
Normal file
100
web/content/intro-nix/ch1.md
Normal file
@ -0,0 +1,100 @@
|
||||
---
|
||||
title: "Chapter 1: Packages"
|
||||
description: "Here we show where packages come from"
|
||||
date: 2023-06-13T19:36:57+02:00
|
||||
weight: 1
|
||||
---
|
||||
|
||||
In this chapter we describe where the packages available in the cluster come
|
||||
from and how to load them.
|
||||
|
||||
## Where packages come from
|
||||
|
||||
The packages in the jungle cluster are constructed by *layers*. Each layer
|
||||
applies some changes over the previous one:
|
||||
|
||||
1. The first layer is [nixpkgs][1], a large repository of packages maintained by
|
||||
the NixOS community. It provides packages like gcc, bash, gcc or the linux
|
||||
kernel.
|
||||
|
||||
[1]: https://github.com/NixOS/nixpkgs/
|
||||
|
||||
2. The second layer is [bscpkgs][2], it takes the nixpkgs set of packages and
|
||||
expands it by adding custom packages from the BSC such as Nanos6, nOS-V,
|
||||
NODES, ovni or wxparaver.
|
||||
|
||||
[2]: https://pm.bsc.es/gitlab/rarias/bscpkgs
|
||||
|
||||
3. The third layer is [jungle][3], it takes the extended packages from bscpkgs
|
||||
and configures them for the jungle cluster. For example, we configure MPICH
|
||||
to use the OmniPath network and set it as the default implementation.
|
||||
|
||||
[3]: https://pm.bsc.es/gitlab/rarias/jungle
|
||||
|
||||
These layers are called *overlays* in Nix and they are the default mechanism
|
||||
used to modify the packages. Generally you will use the packages defined in the
|
||||
last layer (jungle) but you can define your own additional layer to specify
|
||||
custom changes. For example, instead of choosing MPICH, you may want to use
|
||||
Intel MPI instead by default.
|
||||
|
||||
## Loading packages in an ephemeral shell
|
||||
|
||||
You can manually load packages in a *new* shell with `nix shell jungle#<pkg>`,
|
||||
for example:
|
||||
|
||||
```
|
||||
hut% which ovniemu
|
||||
ovniemu not found
|
||||
hut% nix shell jungle#bsc.ovni
|
||||
hut% which ovniemu
|
||||
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0/bin/ovniemu
|
||||
hut% exit
|
||||
hut%
|
||||
```
|
||||
|
||||
You can also specify multiple packages by listing them as parameters of `nix
|
||||
shell`:
|
||||
|
||||
```
|
||||
hut% nix shell jungle#bsc.ovni jungle#bsc.osumb
|
||||
hut% which osu_bw
|
||||
/nix/store/lnjirzllhjn2fadlqzrz7a547iawl8jc-osu-micro-benchmarks-7.1-1/bin/osu_bw
|
||||
hut% exit
|
||||
```
|
||||
|
||||
Or make the bash (zsh in this case) shell expand them:
|
||||
|
||||
```
|
||||
hut% echo nix shell jungle#bsc.{ovni,osumb}
|
||||
nix shell jungle#bsc.ovni jungle#bsc.osumb
|
||||
hut% nix shell jungle#bsc.{ovni,osumb}
|
||||
hut% which osu_bw
|
||||
/nix/store/lnjirzllhjn2fadlqzrz7a547iawl8jc-osu-micro-benchmarks-7.1-1/bin/osu_bw
|
||||
hut% exit
|
||||
```
|
||||
|
||||
You can use TAB to see which packages are available:
|
||||
|
||||
```
|
||||
hut% nix shell jungle#bsc.n<TAB>
|
||||
jungle\#bsc.nanos6 jungle\#bsc.nixtools
|
||||
jungle\#bsc.nanos6Debug jungle\#bsc.nix-wrap
|
||||
jungle\#bsc.nanos6Git jungle\#bsc.nodes
|
||||
jungle\#bsc.nanos6GlibcxxDebug jungle\#bsc.nodesGit
|
||||
jungle\#bsc.nanos6-icc jungle\#bsc.nodesRelease
|
||||
jungle\#bsc.nanos6-icx jungle\#bsc.nodesWithOvni
|
||||
jungle\#bsc.nanos6Release jungle\#bsc.nosv
|
||||
jungle\#bsc.nix-mn4
|
||||
```
|
||||
|
||||
Notice that these packages are evaluated at the moment the command is invoked.
|
||||
So if you come back a month later and run the same command, you may find that
|
||||
the packages have been updated and that could be problematic.
|
||||
|
||||
In the next section we will create a new flake that defines the packages of the
|
||||
shell and also records the exact version of the packages that we used at the
|
||||
evaluation time for future use.
|
||||
|
||||
In the [next chapter](../ch2) we will see how to create a permanent shell that
|
||||
will retain the same packages even if they are upgraded in the cluster, until we
|
||||
decide to upgrade them.
|
155
web/content/intro-nix/ch2.md
Normal file
155
web/content/intro-nix/ch2.md
Normal file
@ -0,0 +1,155 @@
|
||||
---
|
||||
title: "Chapter 2: Your first shell"
|
||||
date: 2023-09-15
|
||||
weight: 2
|
||||
---
|
||||
|
||||
## Creating a shell with flake.nix
|
||||
|
||||
First, create an empty git repository where your shells will live:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```nix
|
||||
{
|
||||
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](../ch1#where-packages-come-from),
|
||||
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:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
[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`:
|
||||
|
||||
```txt
|
||||
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.
|
||||
|
||||
```txt
|
||||
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:
|
||||
|
||||
```txt
|
||||
hut% nix develop
|
||||
[nix-develop]$
|
||||
```
|
||||
|
||||
And the requested packages are now available:
|
||||
|
||||
```txt
|
||||
[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:
|
||||
|
||||
```txt
|
||||
[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](../ch3) we will see how to add more packages and also how to modify
|
||||
them.
|
160
web/content/intro-nix/ch3.md
Normal file
160
web/content/intro-nix/ch3.md
Normal file
@ -0,0 +1,160 @@
|
||||
---
|
||||
title: "Chapter 3: Custom packages"
|
||||
date: 2023-09-15
|
||||
weight: 3
|
||||
---
|
||||
|
||||
## Adding more packages
|
||||
|
||||
So far we have define all the packages using:
|
||||
|
||||
```nix
|
||||
pkgs.mkShell rec {
|
||||
pname = "my-shell";
|
||||
buildInputs = with pkgs.bsc; [
|
||||
ovni osumb # other packages here...
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
This line specifies that all packages come from the `pkgs.bsc` set. We can add
|
||||
additional packages adding them to the list:
|
||||
|
||||
```nix
|
||||
pkgs.mkShell rec {
|
||||
pname = "my-shell";
|
||||
buildInputs = with pkgs.bsc; [
|
||||
ovni osumb sonar
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
And running `nix develop` again:
|
||||
|
||||
```txt
|
||||
hut% nix develop
|
||||
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
|
||||
[nix-develop]$ printf '%s\n' $buildInputs
|
||||
/nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0
|
||||
/nix/store/lnjirzllhjn2fadlqzrz7a547iawl8jc-osu-micro-benchmarks-7.1-1
|
||||
/nix/store/fjxj4xs0wblw3jyhp4vsrsfnlfwawifa-sonar-0.1.0
|
||||
```
|
||||
|
||||
In the jungle cluster, the default MPI implementation is currently set to MPICH,
|
||||
as it can be shown with ldd:
|
||||
|
||||
```txt
|
||||
[nix-develop]$ ldd $(which ovnisync) | grep mpi
|
||||
libmpi.so.12 => /nix/store/nnnaly6hgylravdrmqkhpx1ndg5p79nc-mpich-4.1.2/lib/libmpi.so.12 (0x00007ffff5200000)
|
||||
```
|
||||
|
||||
Now, what if we want to replace the MPI implementation by another one?
|
||||
|
||||
## Modifying a package
|
||||
|
||||
You notice that the packages we are using are coming directly from the ones
|
||||
specified in jungle. However, what if we need to modify some option at build
|
||||
time or change a dependency?
|
||||
|
||||
The Nix language is used to describe how to build each package, and can be
|
||||
extended to create derived versions very easily.
|
||||
|
||||
Let's focus on the `ovni` package. First, to load the definition we can use the
|
||||
`nix edit` command, which opens the definition file using the editor defined in
|
||||
`$EDITOR`:
|
||||
|
||||
```txt
|
||||
hut% nix edit jungle#bsc.ovni
|
||||
...
|
||||
```
|
||||
|
||||
This particular package has several inputs that can be modified directly:
|
||||
|
||||
```txt
|
||||
{
|
||||
stdenv
|
||||
, lib
|
||||
, cmake
|
||||
, mpi
|
||||
, fetchFromGitHub
|
||||
, useGit ? false
|
||||
, gitBranch ? "master"
|
||||
, gitUrl ? "ssh://git@bscpm03.bsc.es/rarias/ovni.git"
|
||||
, gitCommit ? "d0a47783f20f8b177a48418966dae45454193a6a"
|
||||
, enableDebug ? false
|
||||
}:
|
||||
...
|
||||
```
|
||||
|
||||
For example, the `enableDebug` flag, currently set to false, affects how the
|
||||
build is configured:
|
||||
|
||||
```txt
|
||||
cmakeBuildType = if (enableDebug) then "Debug" else "Release";
|
||||
```
|
||||
|
||||
Now, to change this option we could replace `ovni` for our version:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.jungle.url = "jungle";
|
||||
nixConfig.bash-prompt = "\[nix-develop\]$ ";
|
||||
|
||||
outputs = { self, jungle }:
|
||||
let
|
||||
pkgs = jungle.outputs.packages.x86_64-linux;
|
||||
ovniDebug = pkgs.bsc.ovni.override { enableDebug = true; };
|
||||
in {
|
||||
devShells.x86_64-linux.default = pkgs.mkShell rec {
|
||||
pname = "my-shell";
|
||||
buildInputs = with pkgs.bsc; [
|
||||
ovniDebug osumb sonar
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
And then, when we now enter the develop shell we can see that ovni gets build
|
||||
with the Debug option:
|
||||
|
||||
```txt
|
||||
hut% nix develop -L
|
||||
warning: Git tree '/home/Computational/rarias/jungle-examples' is dirty
|
||||
ovni> unpacking sources
|
||||
ovni> unpacking source archive /nix/store/cz4si0vsw85r9s6dyiqr5ybngh9aympi-source
|
||||
ovni> source root is source
|
||||
ovni> patching sources
|
||||
ovni> updateAutotoolsGnuConfigScriptsPhase
|
||||
ovni> configuring
|
||||
ovni> fixing cmake files...
|
||||
ovni> cmake flags: ... -DCMAKE_BUILD_TYPE=Debug ...
|
||||
...
|
||||
[nix-develop]$ which ovniver
|
||||
/nix/store/hg0xs7fpibwjhsp9ajqfcbffsh69mrsm-ovni-1.3.0/bin/ovniver
|
||||
|
||||
[nix-develop]$ file $(which ovniver) | fold
|
||||
/nix/store/hg0xs7fpibwjhsp9ajqfcbffsh69mrsm-ovni-1.3.0/bin/ovniver: ELF 64-bit L
|
||||
SB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/st
|
||||
ore/9la894yvmmksqlapd4v16wvxpaw3rg70-glibc-2.37-8/lib/ld-linux-x86-64.so.2, for
|
||||
GNU/Linux 3.10.0, with debug_info, not stripped
|
||||
```
|
||||
|
||||
And we see that the ovniver program is now compiled with debug symbols.
|
||||
|
||||
However, this *only* replaces the ovni package that we specify in the shell. The
|
||||
sonar library also depends on ovni, but that package is still using the old one:
|
||||
|
||||
```txt
|
||||
[nix-develop]$ find $buildInputs -name 'libovni.so.1'
|
||||
/nix/store/hg0xs7fpibwjhsp9ajqfcbffsh69mrsm-ovni-1.3.0/lib/libovni.so.1
|
||||
|
||||
[nix-develop]$ find $buildInputs -name 'libsonar-mpi.so'
|
||||
/nix/store/fjxj4xs0wblw3jyhp4vsrsfnlfwawifa-sonar-0.1.0/lib/libsonar-mpi.so
|
||||
|
||||
[nix-develop]$ ldd /nix/store/fjxj4xs0wblw3jyhp4vsrsfnlfwawifa-sonar-0.1.0/lib/libsonar-mpi.so | grep ovni
|
||||
libovni.so.1 => /nix/store/0yzas8007x9djlpbb0pckcr1vhd0mcfy-ovni-1.3.0/lib/libovni.so.1 (0x00007ffff7f8d000)
|
||||
```
|
||||
|
||||
In the [next chapter](../ch4) we will see how to replace packages in such a way
|
||||
that all the dependences are automatically updated too.
|
29
web/content/intro-nix/ch4.md
Normal file
29
web/content/intro-nix/ch4.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
title: "Chapter 4: Adding an overlay"
|
||||
date: 2023-09-15
|
||||
weight: 4
|
||||
---
|
||||
|
||||
NOTE: We shouldn't be instructing users to use an overlay to replace packages in
|
||||
`bsc.` until we have determined if we move them to the root attribute set
|
||||
first!
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.jungle.url = "jungle";
|
||||
nixConfig.bash-prompt = "\[nix-develop\]$ ";
|
||||
|
||||
outputs = { self, jungle }:
|
||||
let
|
||||
pkgs = jungle.outputs.packages.x86_64-linux;
|
||||
ovniDebug = pkgs.bsc.ovni.override { enableDebug = true; };
|
||||
in {
|
||||
devShells.x86_64-linux.default = pkgs.mkShell rec {
|
||||
pname = "my-shell";
|
||||
buildInputs = with pkgs.bsc; [
|
||||
ovniDebug osumb sonar
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
@ -3,3 +3,6 @@ languageCode = 'en-us'
|
||||
title = 'The jungle'
|
||||
theme = 'PaperMod'
|
||||
sectionPagesMenu = "main"
|
||||
|
||||
[params]
|
||||
ShowBreadCrumbs = true
|
||||
|
Loading…
Reference in New Issue
Block a user