diff options
author | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2024-03-01 00:14:10 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-01 00:14:10 +0000 |
commit | a1ed79952d0edc51a55931a28fba93fca0cf00fd (patch) | |
tree | f3b3ffecba4907d35227c8d32bf20115a208817b /doc | |
parent | 47e7b83fd1c8d5fdacf6a5a7a56a93b578a3e973 (diff) | |
parent | a6a84940248f7ea903c9dfffbb777c558b6cfe3d (diff) |
Merge master into haskell-updates
Diffstat (limited to 'doc')
-rw-r--r-- | doc/build-helpers/images/ocitools.section.md | 107 | ||||
-rw-r--r-- | doc/build-helpers/images/portableservice.section.md | 205 | ||||
-rw-r--r-- | doc/manpage-urls.json | 4 |
3 files changed, 239 insertions, 77 deletions
diff --git a/doc/build-helpers/images/ocitools.section.md b/doc/build-helpers/images/ocitools.section.md index c35f65bce007..96627615ffb5 100644 --- a/doc/build-helpers/images/ocitools.section.md +++ b/doc/build-helpers/images/ocitools.section.md @@ -1,37 +1,104 @@ # pkgs.ociTools {#sec-pkgs-ociTools} -`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. +`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). +It makes no assumptions about the container runner you choose to use to run the created container. + +The set of functions in `pkgs.ociTools` currently does not handle the [OCI image specification](https://github.com/opencontainers/image-spec). + +At a high-level an OCI implementation would download an OCI Image then unpack that image into an OCI Runtime filesystem bundle. +At this point the OCI Runtime Bundle would be run by an OCI Runtime. +`pkgs.ociTools` provides utilities to create OCI Runtime bundles. ## buildContainer {#ssec-pkgs-ociTools-buildContainer} -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. +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. +The nix store of the container will contain all referenced dependencies of the given command. + +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. +Because of this, a container built with `buildContainer` will not work on Windows or other non-POSIX platforms without modifications to the container configuration. +These modifications aren't supported by `buildContainer`. + +For `linux` platforms, `buildContainer` also configures the following namespaces (see {manpage}`unshare(1)`) to isolate the OCI container from the global namespace: +PID, network, mount, IPC, and UTS. + +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. + +### Inputs {#ssec-pkgs-ociTools-buildContainer-inputs} + +`buildContainer` expects an argument with the following attributes: + +`args` (List of String) + +: Specifies a set of arguments to run inside the container. + Any packages referenced by `args` will be made available inside the container. + +`mounts` (Attribute Set; _optional_) + +: Would specify additional mounts that the runtime must make available to the container. + + :::{.warning} + As explained in [issue #290879](https://github.com/NixOS/nixpkgs/issues/290879), this attribute is currently ignored. + ::: + + :::{.note} + `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. + ::: + + _Default value:_ `{}`. -The parameters of `buildContainer` with an example value are described below: +`readonly` (Boolean; _optional_) + +: If `true`, sets the container's root filesystem as read-only. + + _Default value:_ `false`. + +`os` **DEPRECATED** + +: Specifies the operating system on which the container filesystem is based on. + If specified, its value should follow the [OCI Image Configuration Specification](https://github.com/opencontainers/image-spec/blob/main/config.md#properties). + 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`. + + _Default value:_ `"linux"`. + +`arch` **DEPRECATED** + +: Used to specify the architecture for which the binaries in the container filesystem have been compiled. + If specified, its value should follow the [OCI Image Configuration Specification](https://github.com/opencontainers/image-spec/blob/main/config.md#properties). + 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`. + + _Default value:_ `x86_64`. + +### Examples {#ssec-pkgs-ociTools-buildContainer-examples} + +::: {.example #ex-ociTools-buildContainer-bash} +# Creating an OCI runtime container that runs `bash` + +This example uses `ociTools.buildContainer` to create a simple container that runs `bash`. ```nix -buildContainer { +{ ociTools, lib, bash }: +ociTools.buildContainer { args = [ - (with pkgs; - writeScript "run.sh" '' - #!${bash}/bin/bash - exec ${bash}/bin/bash - '').outPath + (lib.getExe bash) ]; - mounts = { - "/data" = { - type = "none"; - source = "/var/lib/mydata"; - options = [ "bind" ]; - }; - }; - readonly = false; } ``` -- `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. +As an example of how to run the container generated by this package, we'll use `runc` to start the container. +Any other tool that supports OCI containers could be used instead. -- `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) +```shell +$ nix-build +(some output removed for clarity) +/nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join -- `readonly` makes the container's rootfs read-only if it is set to true. The default value is false `false`. +$ cd /nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join +$ nix-shell -p runc +[nix-shell:/nix/store/7f9hgx0arvhzp2a3qphp28rxbn748l25-join]$ sudo runc run ocitools-example +help +GNU bash, version 5.2.26(1)-release (x86_64-pc-linux-gnu) +(some output removed for clarity) +``` +::: diff --git a/doc/build-helpers/images/portableservice.section.md b/doc/build-helpers/images/portableservice.section.md index 5400928b158f..c271bc775dba 100644 --- a/doc/build-helpers/images/portableservice.section.md +++ b/doc/build-helpers/images/portableservice.section.md @@ -1,81 +1,174 @@ # pkgs.portableService {#sec-pkgs-portableService} -`pkgs.portableService` is a function to create _portable service images_, -as read-only, immutable, `squashfs` archives. +`pkgs.portableService` is a function to create [Portable Services](https://systemd.io/PORTABLE_SERVICES/) in a read-only, immutable, `squashfs` raw disk image. +This lets you use Nix to build images which can be run on many recent Linux distributions. -systemd supports a concept of [Portable Services](https://systemd.io/PORTABLE_SERVICES/). -Portable Services are a delivery method for system services that uses two specific features of container management: +::: {.note} +Portable services are supported starting with systemd 239 (released on 2018-06-22). +::: -* Applications are bundled. I.e. multiple services, their binaries and - all their dependencies are packaged in an image, and are run directly from it. -* Stricter default security policies, i.e. sandboxing of applications. +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. +When generated, the image will exist in the Nix store with the `.raw` file extension, as required by the specification. +See [](#ex-portableService-hello) to understand how to use the output of `portableService`. -This allows using Nix to build images which can be run on many recent Linux distributions. +## Inputs {#ssec-pkgs-portableService-inputs} -The primary tool for interacting with Portable Services is `portablectl`, -and they are managed by the `systemd-portabled` system service. +`portableService` expects one argument with the following attributes: -::: {.note} -Portable services are supported starting with systemd 239 (released on 2018-06-22). -::: +`pname` (String) + +: The name of the portable service. + The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification. + +`version` (String) + +: The version of the portable service. + The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification. + +`units` (List of Attribute Set) + +: A list of derivations for systemd unit files. + 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). + See [](#ex-portableService-hello) to better understand this naming constraint. + +`description` (String or Null; _optional_) + +: If specified, the value is added as `PORTABLE_PRETTY_NAME` to the `/etc/os-release` file in the generated image. + This could be used to provide more information to anyone inspecting the image. + + _Default value:_ `null`. + +`homepage` (String or Null; _optional_) + +: If specified, the value is added as `HOME_URL` to the `/etc/os-release` file in the generated image. + This could be used to provide more information to anyone inspecting the image. + + _Default value:_ `null`. + +`symlinks` (List of Attribute Set; _optional_) + +: A list of attribute sets in the format `{object, symlink}`. + 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`. + + All packages that `object` depends on and their dependencies are automatically copied into the image. + + This can be used to create symlinks for applications that assume some files to exist globally (`/etc/ssl` or `/bin/bash`, for example). + See [](#ex-portableService-symlinks) to understand how to do that. + + _Default value:_ `[]`. + +`contents` (List of Attribute Set; _optional_) -A very simple example of using `portableService` is described below: +: A list of additional derivations to be included as-is in the image. + These derivations will be included directly in a `/nix/store` directory inside the image. + + _Default value:_ `[]`. + +`squashfsTools` (Attribute Set; _optional_) + +: Allows you to override the package that provides {manpage}`mksquashfs(1)`, which is used internally by `portableService`. + + _Default value:_ `pkgs.squashfsTools`. + +`squash-compression` (String; _optional_) + +: Passed as the compression option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`. + + _Default value:_ `"xz -Xdict-size 100%"`. + +`squash-block-size` (String; _optional_) + +: Passed as the block size option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`. + + _Default value:_ `"1M"`. + +## Examples {#ssec-pkgs-portableService-examples} []{#ex-pkgs-portableService} +:::{.example #ex-portableService-hello} +# Building a Portable Service image + +The following example builds a Portable Service image with the `hello` package, along with a service unit that runs it. ```nix -pkgs.portableService { - pname = "demo"; - version = "1.0"; - units = [ demo-service demo-socket ]; +{ lib, writeText, portableService, hello }: +let + hello-service = writeText "hello.service" '' + [Unit] + Description=Hello world service + + [Service] + Type=oneshot + ExecStart=${lib.getExe hello} + ''; +in +portableService { + pname = "hello"; + inherit (hello) version; + units = [ hello-service ]; } ``` -The above example will build an squashfs archive image in `result/$pname_$version.raw`. The image will contain the -file system structure as required by the portable service specification, and a subset of the Nix store with all the -dependencies of the two derivations in the `units` list. -`units` must be a list of derivations, and their names must be prefixed with the service name (`"demo"` in this case). -Otherwise `systemd-portabled` will ignore them. - -::: {.note} -The `.raw` file extension of the image is required by the portable services specification. +After building the package, the generated image can be loaded into a system through {manpage}`portablectl(1)`: + +```shell +$ nix-build +(some output removed for clarity) +/nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1 + +$ portablectl attach /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw +Created directory /etc/systemd/system.attached. +Created directory /etc/systemd/system.attached/hello.service.d. +Written /etc/systemd/system.attached/hello.service.d/20-portable.conf. +Created symlink /etc/systemd/system.attached/hello.service.d/10-profile.conf → /usr/lib/systemd/portable/profile/default/service.conf. +Copied /etc/systemd/system.attached/hello.service. +Created symlink /etc/portables/hello_2.12.1.raw → /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw. + +$ systemctl start hello +$ journalctl -u hello +Feb 28 22:39:16 hostname systemd[1]: Starting Hello world service... +Feb 28 22:39:16 hostname hello[102887]: Hello, world! +Feb 28 22:39:16 hostname systemd[1]: hello.service: Deactivated successfully. +Feb 28 22:39:16 hostname systemd[1]: Finished Hello world service. + +$ portablectl detach hello_2.12.1 +Removed /etc/systemd/system.attached/hello.service. +Removed /etc/systemd/system.attached/hello.service.d/10-profile.conf. +Removed /etc/systemd/system.attached/hello.service.d/20-portable.conf. +Removed /etc/systemd/system.attached/hello.service.d. +Removed /etc/portables/hello_2.12.1.raw. +Removed /etc/systemd/system.attached. +``` ::: -Some other options available are: -- `description`, `homepage` - - Are added to the `/etc/os-release` in the image and are shown by the portable services tooling. - Default to empty values, not added to os-release. -- `symlinks` - - A list of attribute sets {object, symlink}. Symlinks will be created in the root filesystem of the image to - objects in the Nix store. Defaults to an empty list. -- `contents` +:::{.example #ex-portableService-symlinks} +# Specifying symlinks when building a Portable Service image - A list of additional derivations to be included in the image Nix store, as-is. Defaults to an empty list. -- `squashfsTools` +Some services may expect files or directories to be available globally. +An example is a service which expects all trusted SSL certificates to exist in a specific location by default. - Defaults to `pkgs.squashfsTools`, allows you to override the package that provides `mksquashfs`. -- `squash-compression`, `squash-block-size` +To make things available globally, you must specify the `symlinks` attribute when using `portableService`. +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`). - Options to `mksquashfs`. Default to `"xz -Xdict-size 100%"` and `"1M"` respectively. - -A typical usage of `symlinks` would be: ```nix +{ lib, writeText, portableService, hello, cacert }: +let + hello-service = writeText "hello.service" '' + [Unit] + Description=Hello world service + + [Service] + Type=oneshot + ExecStart=${lib.getExe hello} + ''; +in +portableService { + pname = "hello"; + inherit (hello) version; + units = [ hello-service ]; symlinks = [ - { object = "${pkgs.cacert}/etc/ssl"; symlink = "/etc/ssl"; } - { object = "${pkgs.bash}/bin/bash"; symlink = "/bin/sh"; } - { object = "${pkgs.php}/bin/php"; symlink = "/usr/bin/php"; } + { object = "${cacert}/etc/ssl"; symlink = "/etc/ssl"; } ]; +} ``` -to create these symlinks for legacy applications that assume them existing globally. - -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: -```console -portablectl attach demo_1.0.raw -systemctl enable --now demo.socket -systemctl enable --now demo.service -``` -::: {.note} -See the [man page](https://www.freedesktop.org/software/systemd/man/portablectl.html) of `portablectl` for more info on its usage. ::: diff --git a/doc/manpage-urls.json b/doc/manpage-urls.json index 5739a59d9420..2cc03af4360f 100644 --- a/doc/manpage-urls.json +++ b/doc/manpage-urls.json @@ -318,5 +318,7 @@ "passwd(5)": "https://man.archlinux.org/man/passwd.5", "group(5)": "https://man.archlinux.org/man/group.5", "login.defs(5)": "https://man.archlinux.org/man/login.defs.5", - "nix-shell(1)": "https://nixos.org/manual/nix/stable/command-ref/nix-shell.html" + "unshare(1)": "https://man.archlinux.org/man/unshare.1.en", + "nix-shell(1)": "https://nixos.org/manual/nix/stable/command-ref/nix-shell.html", + "mksquashfs(1)": "https://man.archlinux.org/man/extra/squashfs-tools/mksquashfs.1.en" } |