Skip to content

Instantly share code, notes, and snippets.

@noteed
Last active July 22, 2020 19:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noteed/f6213ff6feafd405e361e1b333495933 to your computer and use it in GitHub Desktop.
Save noteed/f6213ff6feafd405e361e1b333495933 to your computer and use it in GitHub Desktop.
Nix notes

Note: this gist is a bit dated. Start at https://github.com/noteed/nix-notes instead.

Nix notes

Getting started

Specific topics

Useful examples for newcomers

Play with the expression language from the command line:

> nix-instantiate --eval --expr '1'
1
> nix-instantiate --eval --expr 'a: a + 1'
<LAMBDA>
> nix-instantiate --eval --expr '(a: a + 1) 2'
3

Understand the nested keys syntactic sugar:

> nix-instantiate --eval --expr '{ a = 1; }'
{ a = 1; }
> nix-instantiate --eval --expr '{ a.b.c = 1; }.a.b'
{ c = 1; }
> nix-instantiate --eval --expr '{ a.b.c = 1; }'
{ a = <CODE>; }
> nix-instantiate --eval --expr --strict '{ a.b.c = 1; }'
{ a = { b = { c = 1; }; }; }

Understand the <nixpkgs> path notation:

> pwd
/tmp
> cat a.nix
{ a = 1 ; }
> nix-instantiate --eval a.nix
{ a = 1; }
> nix-instantiate --eval -I mypkgs=./a.nix --expr '<mypkgs>'
/tmp/a.nix
> nix-instantiate --eval -I mypkgs=./a.nix --expr 'import <mypkgs>'
{ a = 1; }
> nix-instantiate --eval -I mypkgs=./a.nix --expr 'with import <mypkgs> ; a'
1
$ nix-instantiate --eval --expr --strict '<nixpkgs>'
/home/thu/.nix-defexpr/channels/nixpkgs

Minimal example

default.nix:

{ pkgs ? import <nixpkgs> { } }:

let
  kernel-version = "4.4.52";
  kernel-sha256 = "e8d2ddaece73e1a34e045bbdcdcc1383f658e24537797f8d8e0dd520cf1b1f06";
in
{
  linux_tarball = pkgs.fetchurl {
    url = "https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-${kernel-version}.tar.xz";
    sha256 = kernel-sha256;
  };
}
> nix-build -A linux_tarball default.nix 
/nix/store/85ss4k779bnqadvazxcgsqz4h1pbgkyp-linux-4.4.52.tar.xz
> ls -la result 
lrwxrwxrwx 1 thu thu 63 May  7 14:00 result -> /nix/store/85ss4k779bnqadvazxcgsqz4h1pbgkyp-linux-4.4.52.tar.xz

Update packages

> nix-channel --u
> nix-env -u

Using NixOps to install NixOS on Digital Ocean

>  cat do.nix 
{
  resources.sshKeyPairs.ssh-key = {};

  machine = { config, pkgs, ... }: {
    services.nginx.enable = true;
    services.openssh.enable = true;

    deployment.targetEnv = "digitalOcean";
    deployment.digitalOcean.region = "ams2";
    deployment.digitalOcean.size = "512mb";
  };
}
> nixops create -d do do.nix
> DIGITAL_OCEAN_AUTH_TOKEN=xxxxx nixops deploy -d do
> nixops show-option -d do machine services.nginx.enable
> nixops ssh -d do machine

Adding

networking.firewall.allowedTCPPorts = [ 80 ];

will result in the following rule:

nixos-fw-accept  tcp  --  anywhere             anywhere             tcp dpt:http

There is no need for something similar to allow SSH connections.

After a new call to nixops deploy, using curl on the machine IP address will work.

Tutorial

This builds on the minimal example above.

  • Add a minimal derivation (name, builder, args, system), point to Nix Pill 6 and 7 for further reading.
  • Add an environment variable (e.g. kernel_version).
  • Add a dependency (e.g. coreutils for mkdir).
  • Add a file (e.g. kernel-config).
  • Add another dependency and explain the inherit (xxx) xxx notation.
  • Add hardeningDisable = ["pic" "format" "stackprotector" "fortify"]; to avoid
kernel/bounds.c:1:0: error: code model kernel does not support PIC mode

and

arch/x86/kernel/e820.c:807:2: error: format not a string literal and no format arguments

and

undefined reference to `__stack_chk_fail'

and

crypto/jitterentropy.c:54:3: error: #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy.c."

Those are described at http://nixos.org/nixpkgs/manual/#sec-hardening-in-nixpkgs.

  • Add busybox, this time relying on the existing derivation.
  • Add a derivation to build the rootfs, using both the kernel and busybox.
  • Digression on how to call qemu with the kernel and the rootfs (the kernel is not needed in the rootfs here).
  • Complete the rootfs.

Custom images

From within nixpkgs/nixos, the documented way to build an image is

nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix

It is similar to calling this with <nixos-config> set (it is evaluated by default.nix using lib/eval-config.nix):

> nix-instantiate --eval --expr 'with import ./default.nix {} ; config.system.build.isoImage'
error: attribute ‘system’ missing, at (string):1:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment