···1# pkgs.ociTools {#sec-pkgs-ociTools}
23-`pkgs.ociTools` is a set of functions for creating containers according to the [OCI container specification v1.0.0](https://github.com/opencontainers/runtime-spec). Beyond that, it makes no assumptions about the container runner you choose to use to run the created container.
000000045## buildContainer {#ssec-pkgs-ociTools-buildContainer}
67-This function creates a simple OCI container that runs a single command inside of it. An OCI container consists of a `config.json` and a rootfs directory. The nix store of the container will contain all referenced dependencies of the given command.
00000000000000000000000000000000000000000000000000000000000089-The parameters of `buildContainer` with an example value are described below:
1011```nix
12-buildContainer {
013 args = [
14- (with pkgs;
15- writeScript "run.sh" ''
16- #!${bash}/bin/bash
17- exec ${bash}/bin/bash
18- '').outPath
19 ];
2021- mounts = {
22- "/data" = {
23- type = "none";
24- source = "/var/lib/mydata";
25- options = [ "bind" ];
26- };
27- };
28-29 readonly = false;
30}
31```
3233-- `args` specifies a set of arguments to run inside the container. This is the only required argument for `buildContainer`. All referenced packages inside the derivation will be made available inside the container.
03435-- `mounts` specifies additional mount points chosen by the user. By default only a minimal set of necessary filesystems are mounted into the container (e.g procfs, cgroupfs)
0003637-- `readonly` makes the container's rootfs read-only if it is set to true. The default value is false `false`.
0000000
···1# pkgs.ociTools {#sec-pkgs-ociTools}
23+`pkgs.ociTools` is a set of functions for creating runtime container bundles according to the [OCI runtime specification v1.0.0](https://github.com/opencontainers/runtime-spec/blob/v1.0.0/spec.md).
4+It makes no assumptions about the container runner you choose to use to run the created container.
5+6+The set of functions in `pkgs.ociTools` currently does not handle the [OCI image specification](https://github.com/opencontainers/image-spec).
7+8+At a high-level an OCI implementation would download an OCI Image then unpack that image into an OCI Runtime filesystem bundle.
9+At this point the OCI Runtime Bundle would be run by an OCI Runtime.
10+`pkgs.ociTools` provides utilities to create OCI Runtime bundles.
1112## buildContainer {#ssec-pkgs-ociTools-buildContainer}
1314+This function creates an OCI runtime container (consisting of a `config.json` and a root filesystem directory) that runs a single command inside of it.
15+The nix store of the container will contain all referenced dependencies of the given command.
16+17+This function has an assumption that the container will run on POSIX platforms, and sets configurations (such as the user running the process or certain mounts) according to this assumption.
18+Because of this, a container built with `buildContainer` will not work on Windows or other non-POSIX platforms without modifications to the container configuration.
19+These modifications aren't supported by `buildContainer`.
20+21+For `linux` platforms, `buildContainer` also configures the following namespaces (see {manpage}`unshare(1)`) to isolate the OCI container from the global namespace:
22+PID, network, mount, IPC, and UTS.
23+24+Note that no user namespace is created, which means that you won't be able to run the container unless you are the `root` user.
25+26+### Inputs {#ssec-pkgs-ociTools-buildContainer-inputs}
27+28+`buildContainer` expects an argument with the following attributes:
29+30+`args` (List of String)
31+32+: Specifies a set of arguments to run inside the container.
33+ Any packages referenced by `args` will be made available inside the container.
34+35+`mounts` (Attribute Set; _optional_)
36+37+: Would specify additional mounts that the runtime must make available to the container.
38+39+ :::{.warning}
40+ As explained in [issue #290879](https://github.com/NixOS/nixpkgs/issues/290879), this attribute is currently ignored.
41+ :::
42+43+ :::{.note}
44+ `buildContainer` includes a minimal set of necessary filesystems to be mounted into the container, and this set can't be changed with the `mounts` attribute.
45+ :::
46+47+ _Default value:_ `{}`.
48+49+`readonly` (Boolean; _optional_)
50+51+: If `true`, sets the container's root filesystem as read-only.
52+53+ _Default value:_ `false`.
54+55+`os` **DEPRECATED**
56+57+: Specifies the operating system on which the container filesystem is based on.
58+ If specified, its value should follow the [OCI Image Configuration Specification](https://github.com/opencontainers/image-spec/blob/main/config.md#properties).
59+ According to the linked specification, all possible values for `$GOOS` in [the Go docs](https://go.dev/doc/install/source#environment) should be valid, but will commonly be one of `darwin` or `linux`.
60+61+ _Default value:_ `"linux"`.
62+63+`arch` **DEPRECATED**
64+65+: Used to specify the architecture for which the binaries in the container filesystem have been compiled.
66+ If specified, its value should follow the [OCI Image Configuration Specification](https://github.com/opencontainers/image-spec/blob/main/config.md#properties).
67+ According to the linked specification, all possible values for `$GOARCH` in [the Go docs](https://go.dev/doc/install/source#environment) should be valid, but will commonly be one of `386`, `amd64`, `arm`, or `arm64`.
68+69+ _Default value:_ `x86_64`.
70+71+### Examples {#ssec-pkgs-ociTools-buildContainer-examples}
72+73+::: {.example #ex-ociTools-buildContainer-bash}
74+# Creating an OCI runtime container that runs `bash`
7576+This example uses `ociTools.buildContainer` to create a simple container that runs `bash`.
7778```nix
79+{ ociTools, lib, bash }:
80+ociTools.buildContainer {
81 args = [
82+ (lib.getExe bash)
000083 ];
840000000085 readonly = false;
86}
87```
8889+As an example of how to run the container generated by this package, we'll use `runc` to start the container.
90+Any other tool that supports OCI containers could be used instead.
9192+```shell
93+$ nix-build
94+(some output removed for clarity)
95+/nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join
9697+$ cd /nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join
98+$ nix-shell -p runc
99+[nix-shell:/nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join]$ sudo runc run ocitools-example
100+help
101+GNU bash, version 5.2.26(1)-release (x86_64-pc-linux-gnu)
102+(some output removed for clarity)
103+```
104+:::
···1# pkgs.portableService {#sec-pkgs-portableService}
23-`pkgs.portableService` is a function to create _portable service images_,
4-as read-only, immutable, `squashfs` archives.
56-systemd supports a concept of [Portable Services](https://systemd.io/PORTABLE_SERVICES/).
7-Portable Services are a delivery method for system services that uses two specific features of container management:
089-* Applications are bundled. I.e. multiple services, their binaries and
10- all their dependencies are packaged in an image, and are run directly from it.
11-* Stricter default security policies, i.e. sandboxing of applications.
1213-This allows using Nix to build images which can be run on many recent Linux distributions.
1415-The primary tool for interacting with Portable Services is `portablectl`,
16-and they are managed by the `systemd-portabled` system service.
1718-::: {.note}
19-Portable services are supported starting with systemd 239 (released on 2018-06-22).
20-:::
2122-A very simple example of using `portableService` is described below:
000000000000000000000000000000000000000000000000000000000000000002324[]{#ex-pkgs-portableService}
00002526```nix
27-pkgs.portableService {
28- pname = "demo";
29- version = "1.0";
30- units = [ demo-service demo-socket ];
0000000000031}
32```
3334-The above example will build an squashfs archive image in `result/$pname_$version.raw`. The image will contain the
35-file system structure as required by the portable service specification, and a subset of the Nix store with all the
36-dependencies of the two derivations in the `units` list.
37-`units` must be a list of derivations, and their names must be prefixed with the service name (`"demo"` in this case).
38-Otherwise `systemd-portabled` will ignore them.
3940-::: {.note}
41-The `.raw` file extension of the image is required by the portable services specification.
42-:::
04344-Some other options available are:
45-- `description`, `homepage`
000004647- Are added to the `/etc/os-release` in the image and are shown by the portable services tooling.
48- Default to empty values, not added to os-release.
49-- `symlinks`
0005051- A list of attribute sets {object, symlink}. Symlinks will be created in the root filesystem of the image to
52- objects in the Nix store. Defaults to an empty list.
53-- `contents`
0000005455- A list of additional derivations to be included in the image Nix store, as-is. Defaults to an empty list.
56-- `squashfsTools`
5758- Defaults to `pkgs.squashfsTools`, allows you to override the package that provides `mksquashfs`.
59-- `squash-compression`, `squash-block-size`
6061- Options to `mksquashfs`. Default to `"xz -Xdict-size 100%"` and `"1M"` respectively.
06263-A typical usage of `symlinks` would be:
64```nix
00000000000000065 symlinks = [
66- { object = "${pkgs.cacert}/etc/ssl"; symlink = "/etc/ssl"; }
67- { object = "${pkgs.bash}/bin/bash"; symlink = "/bin/sh"; }
68- { object = "${pkgs.php}/bin/php"; symlink = "/usr/bin/php"; }
69 ];
70-```
71-to create these symlinks for legacy applications that assume them existing globally.
72-73-Once the image is created, and deployed on a host in `/var/lib/portables/`, you can attach the image and run the service. As root run:
74-```console
75-portablectl attach demo_1.0.raw
76-systemctl enable --now demo.socket
77-systemctl enable --now demo.service
78```
79-::: {.note}
80-See the [man page](https://www.freedesktop.org/software/systemd/man/portablectl.html) of `portablectl` for more info on its usage.
81:::
···1# pkgs.portableService {#sec-pkgs-portableService}
23+`pkgs.portableService` is a function to create [Portable Services](https://systemd.io/PORTABLE_SERVICES/) in a read-only, immutable, `squashfs` raw disk image.
4+This lets you use Nix to build images which can be run on many recent Linux distributions.
56+::: {.note}
7+Portable services are supported starting with systemd 239 (released on 2018-06-22).
8+:::
910+The generated image will contain the file system structure as required by the Portable Services specification, along with the packages given to `portableService` and all of their dependencies.
11+When generated, the image will exist in the Nix store with the `.raw` file extension, as required by the specification.
12+See [](#ex-portableService-hello) to understand how to use the output of `portableService`.
1314+## Inputs {#ssec-pkgs-portableService-inputs}
1516+`portableService` expects one argument with the following attributes:
01718+`pname` (String)
001920+: The name of the portable service.
21+ The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification.
22+23+`version` (String)
24+25+: The version of the portable service.
26+ The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification.
27+28+`units` (List of Attribute Set)
29+30+: A list of derivations for systemd unit files.
31+ Each derivation must produce a single file, and must have a name that starts with the value of `pname` and ends with the suffix of the unit type (e.g. ".service", ".socket", ".timer", and so on).
32+ See [](#ex-portableService-hello) to better understand this naming constraint.
33+34+`description` (String or Null; _optional_)
35+36+: If specified, the value is added as `PORTABLE_PRETTY_NAME` to the `/etc/os-release` file in the generated image.
37+ This could be used to provide more information to anyone inspecting the image.
38+39+ _Default value:_ `null`.
40+41+`homepage` (String or Null; _optional_)
42+43+: If specified, the value is added as `HOME_URL` to the `/etc/os-release` file in the generated image.
44+ This could be used to provide more information to anyone inspecting the image.
45+46+ _Default value:_ `null`.
47+48+`symlinks` (List of Attribute Set; _optional_)
49+50+: A list of attribute sets in the format `{object, symlink}`.
51+ For each item in the list, `portableService` will create a symlink in the path specified by `symlink` (relative to the root of the image) that points to `object`.
52+53+ All packages that `object` depends on and their dependencies are automatically copied into the image.
54+55+ This can be used to create symlinks for applications that assume some files to exist globally (`/etc/ssl` or `/bin/bash`, for example).
56+ See [](#ex-portableService-symlinks) to understand how to do that.
57+58+ _Default value:_ `[]`.
59+60+`contents` (List of Attribute Set; _optional_)
61+62+: A list of additional derivations to be included as-is in the image.
63+ These derivations will be included directly in a `/nix/store` directory inside the image.
64+65+ _Default value:_ `[]`.
66+67+`squashfsTools` (Attribute Set; _optional_)
68+69+: Allows you to override the package that provides {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
70+71+ _Default value:_ `pkgs.squashfsTools`.
72+73+`squash-compression` (String; _optional_)
74+75+: Passed as the compression option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
76+77+ _Default value:_ `"xz -Xdict-size 100%"`.
78+79+`squash-block-size` (String; _optional_)
80+81+: Passed as the block size option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
82+83+ _Default value:_ `"1M"`.
84+85+## Examples {#ssec-pkgs-portableService-examples}
8687[]{#ex-pkgs-portableService}
88+:::{.example #ex-portableService-hello}
89+# Building a Portable Service image
90+91+The following example builds a Portable Service image with the `hello` package, along with a service unit that runs it.
9293```nix
94+{ lib, writeText, portableService, hello }:
95+let
96+ hello-service = writeText "hello.service" ''
97+ [Unit]
98+ Description=Hello world service
99+100+ [Service]
101+ Type=oneshot
102+ ExecStart=${lib.getExe hello}
103+ '';
104+in
105+portableService {
106+ pname = "hello";
107+ inherit (hello) version;
108+ units = [ hello-service ];
109}
110```
111112+After building the package, the generated image can be loaded into a system through {manpage}`portablectl(1)`:
0000113114+```shell
115+$ nix-build
116+(some output removed for clarity)
117+/nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1
118119+$ portablectl attach /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw
120+Created directory /etc/systemd/system.attached.
121+Created directory /etc/systemd/system.attached/hello.service.d.
122+Written /etc/systemd/system.attached/hello.service.d/20-portable.conf.
123+Created symlink /etc/systemd/system.attached/hello.service.d/10-profile.conf → /usr/lib/systemd/portable/profile/default/service.conf.
124+Copied /etc/systemd/system.attached/hello.service.
125+Created symlink /etc/portables/hello_2.12.1.raw → /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw.
126127+$ systemctl start hello
128+$ journalctl -u hello
129+Feb 28 22:39:16 hostname systemd[1]: Starting Hello world service...
130+Feb 28 22:39:16 hostname hello[102887]: Hello, world!
131+Feb 28 22:39:16 hostname systemd[1]: hello.service: Deactivated successfully.
132+Feb 28 22:39:16 hostname systemd[1]: Finished Hello world service.
133134+$ portablectl detach hello_2.12.1
135+Removed /etc/systemd/system.attached/hello.service.
136+Removed /etc/systemd/system.attached/hello.service.d/10-profile.conf.
137+Removed /etc/systemd/system.attached/hello.service.d/20-portable.conf.
138+Removed /etc/systemd/system.attached/hello.service.d.
139+Removed /etc/portables/hello_2.12.1.raw.
140+Removed /etc/systemd/system.attached.
141+```
142+:::
143144+:::{.example #ex-portableService-symlinks}
145+# Specifying symlinks when building a Portable Service image
146147+Some services may expect files or directories to be available globally.
148+An example is a service which expects all trusted SSL certificates to exist in a specific location by default.
149150+To make things available globally, you must specify the `symlinks` attribute when using `portableService`.
151+The following package builds on the package from [](#ex-portableService-hello) to make `/etc/ssl` available globally (this is only for illustrative purposes, because `hello` doesn't use `/etc/ssl`).
1520153```nix
154+{ lib, writeText, portableService, hello, cacert }:
155+let
156+ hello-service = writeText "hello.service" ''
157+ [Unit]
158+ Description=Hello world service
159+160+ [Service]
161+ Type=oneshot
162+ ExecStart=${lib.getExe hello}
163+ '';
164+in
165+portableService {
166+ pname = "hello";
167+ inherit (hello) version;
168+ units = [ hello-service ];
169 symlinks = [
170+ { object = "${cacert}/etc/ssl"; symlink = "/etc/ssl"; }
00171 ];
172+}
0000000173```
00174:::
···145 in fix g
146 ```
147000000148 :::{.example}
149150 # Extend a fixed-point function with an overlay
···230231 fix (extends (final: prev: { c = final.a + final.b; }) f)
232 => { a = 1; b = 3; c = 4; }
233-234- :::{.note}
235- The argument to the given fixed-point function after applying an overlay will *not* refer to its own return value, but rather to the value after evaluating the overlay function.
236-237- The given fixed-point function is called with a separate argument than if it was evaluated with `lib.fix`.
238- The new argument
239- :::
240 */
241 extends =
242 # The overlay to apply to the fixed-point function
···145 in fix g
146 ```
147148+ :::{.note}
149+ The argument to the given fixed-point function after applying an overlay will *not* refer to its own return value, but rather to the value after evaluating the overlay function.
150+151+ The given fixed-point function is called with a separate argument than if it was evaluated with `lib.fix`.
152+ :::
153+154 :::{.example}
155156 # Extend a fixed-point function with an overlay
···236237 fix (extends (final: prev: { c = final.a + final.b; }) f)
238 => { a = 1; b = 3; c = 4; }
0000000239 */
240 extends =
241 # The overlay to apply to the fixed-point function
···1-From 001549503eed364d4baaa5804242f67c6236f6c2 Mon Sep 17 00:00:00 2001
2From: Flakebi <flakebi@t-online.de>
3-Date: Sat, 2 Dec 2023 16:55:05 +0100
4Subject: [PATCH] Fix with new dependency versions
56- cookie_jar is private in werkzeug 2.3, so recreate the client instead
7- set_cookie does not take a hostname argument anymore, use domain instead
8- Headers need to specify a content type
9---
10- test_seasurf.py | 63 ++++++++++++++++++++++++-------------------------
11- 1 file changed, 31 insertions(+), 32 deletions(-)
1213diff --git a/test_seasurf.py b/test_seasurf.py
14-index 517b2d7..501f82d 100644
15--- a/test_seasurf.py
16+++ b/test_seasurf.py
17@@ -71,18 +71,18 @@ class SeaSurfTestCase(BaseTestCase):
···37 self.assertIn(b('403 Forbidden'), rv.data)
3839 def test_json_token_validation_bad(self):
00000000040@@ -107,7 +107,7 @@ class SeaSurfTestCase(BaseTestCase):
41 data = {'_csrf_token': token}
42 with self.app.test_client() as client:
···55 sess[self.csrf._csrf_name] = token
5657 # once this is reached the session was stored
58-@@ -144,7 +144,7 @@ class SeaSurfTestCase(BaseTestCase):
59 with client.session_transaction() as sess:
60 token = self.csrf._generate_token()
61···64 sess[self.csrf._csrf_name] = token
6566 # once this is reached the session was stored
000000000000067@@ -167,7 +167,7 @@ class SeaSurfTestCase(BaseTestCase):
68 with client.session_transaction() as sess:
69 token = self.csrf._generate_token()
···252 self.assertEqual(res2.status_code, 200)
253254 def test_header_set_cookie_samesite(self):
000000000255--
256-2.42.0
257
···1+From d3aed2c18cc3a1c88a8052af1f34d7f81f1be11a Mon Sep 17 00:00:00 2001
2From: Flakebi <flakebi@t-online.de>
3+Date: Wed, 28 Feb 2024 23:24:14 +0100
4Subject: [PATCH] Fix with new dependency versions
56- cookie_jar is private in werkzeug 2.3, so recreate the client instead
7- set_cookie does not take a hostname argument anymore, use domain instead
8- Headers need to specify a content type
9---
10+ test_seasurf.py | 71 ++++++++++++++++++++++++-------------------------
11+ 1 file changed, 35 insertions(+), 36 deletions(-)
1213diff --git a/test_seasurf.py b/test_seasurf.py
14+index 517b2d7..f940b91 100644
15--- a/test_seasurf.py
16+++ b/test_seasurf.py
17@@ -71,18 +71,18 @@ class SeaSurfTestCase(BaseTestCase):
···37 self.assertIn(b('403 Forbidden'), rv.data)
3839 def test_json_token_validation_bad(self):
40+@@ -93,7 +93,7 @@ class SeaSurfTestCase(BaseTestCase):
41+ with self.app.test_client() as client:
42+ with client.session_transaction() as sess:
43+ sess[self.csrf._csrf_name] = tokenA
44+- client.set_cookie('www.example.com', self.csrf._csrf_name, tokenB)
45++ client.set_cookie(self.csrf._csrf_name, tokenB, domain='www.example.com')
46+47+ rv = client.post('/bar', data=data)
48+ self.assertEqual(rv.status_code, 403, rv)
49@@ -107,7 +107,7 @@ class SeaSurfTestCase(BaseTestCase):
50 data = {'_csrf_token': token}
51 with self.app.test_client() as client:
···64 sess[self.csrf._csrf_name] = token
6566 # once this is reached the session was stored
67+@@ -144,18 +144,18 @@ class SeaSurfTestCase(BaseTestCase):
68 with client.session_transaction() as sess:
69 token = self.csrf._generate_token()
70···73 sess[self.csrf._csrf_name] = token
7475 # once this is reached the session was stored
76+- rv = client.post('/bar',
77++ rv = client.post('/bar', content_type='application/json',
78+ data={self.csrf._csrf_name: token},
79+ base_url='https://www.example.com',
80+ headers={'Referer': 'https://www.example.com/foobar'})
81+82+ self.assertEqual(rv.status_code, 200)
83+84+- rv = client.post(u'/bar/\xf8',
85++ rv = client.post(u'/bar/\xf8', content_type='application/json',
86+ data={self.csrf._csrf_name: token},
87+ base_url='https://www.example.com',
88+ headers={'Referer': 'https://www.example.com/foobar\xf8'})
89@@ -167,7 +167,7 @@ class SeaSurfTestCase(BaseTestCase):
90 with client.session_transaction() as sess:
91 token = self.csrf._generate_token()
···274 self.assertEqual(res2.status_code, 200)
275276 def test_header_set_cookie_samesite(self):
277+@@ -789,7 +788,7 @@ class SeaSurfTestCaseGenerateNewToken(BaseTestCase):
278+ client.get('/foo')
279+ tokenA = self.csrf._get_token()
280+281+- client.set_cookie('www.example.com', self.csrf._csrf_name, tokenA)
282++ client.set_cookie(self.csrf._csrf_name, tokenA, domain='www.example.com')
283+ with client.session_transaction() as sess:
284+ sess[self.csrf._csrf_name] = tokenA
285+286--
287+2.43.0
288
···1718 nativeCheckInputs = [ python ];
1920+ # reptyr needs to do ptrace of a non-child process
21+ # It can be neither used nor tested if the kernel is not told to allow this
22+ doCheck = false;
2324 checkFlags = [
25 "PYTHON_CMD=${python.interpreter}"