diff --git a/README.md b/README.md index 665e48a..b8b9485 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,61 @@ # NSpawn-OCI -Script to import OCI (Docker) containers to systemd-nspawn + +Script to import OCI (Docker) containers to machined as nspawn containers + +# Requirements + +- systemd-machined +- systemd-nspawn + - these are components of the monolithic systemd software. + Availibility and packaging of these components can vary wildy by distro. + Refer to your distro's documentation. +- [skopeo](https://pkgs.org/download/skopeo) +- [umoci](https://pkgs.org/download/umoci) +- `--convert` requires [jq](https://pkgs.org/download/jq) + ## Usage + +This script was tested under Arch Linux. +At the time of writing, this script's usage of `umoci` and `machinectl` require root access, so this script must be run as root. + ```bash import.sh $SOURCE $HOSTNAME [--convert|-c] ``` + `$SOURCE` can be any supported [container transport](https://github.com/containers/image/blob/main/docs/containers-transports.5.md) `$HOSTNAME` may consist of only letters, digits, and the hyphen (`-`) symbol, and has a maximum length of 15 characters. -`--convert` will attempt to convert the container from OCI to nspawn with the following caveats: -- the nspawn container uses host networking. If you wish to use bridged or nat, there are many ways to do so, and you will need to decide for yourself. -- a small subset of common options are converted, including: - 1. Environment Variables - 2. Working Directory - 3. Process Parameters - 4. Bind Mounts - - when a container has declared a mount point, you will be prompted for the host bind point +`--convert` will read a subset of the OCI `config.json` and install an equivalent `.nspawn` file. If the container has empty mount ponts, you will be prompted for a bind point. -After importing, you may need to edit either `config.json` or `name.nspawn`. The appropriate config path will be printed at the end of the script. Keep in mind when using converted containers that guest networking is likely to be completely unconfigured, so if you want to change from host networking mode to use port mapping or bridge networking you will need to configure both a bridge interface on the host and guest networking inside each container. \ No newline at end of file +## How it works + +### OCI mode + +Below is a simplified version of the script containing the important lines. + +```bash +# step 1: download the container to a temporary directory +skopeo copy "$source" oci:"$skopeo_output":latest +# step 2: convert the container to a format nspawn understands +umoci --verbose unpack --image "$skopeo_output" "$umoci_output" --keep-dirlinks +# step 3: override the default launch options for this container to use oci mode +cat << end > "$override" +[Service] +ExecStart=systemd-nspawn --oci-bundle=/var/lib/machines/%i --machine %i +end +# step 4: import the entire oci bundle +machinectl import-fs "$umoci_output" "$hostname" +``` + +### Convert mode + +Instead of importing the entire OCI runtime bundle and creating an override in systemd for the relevant container, +only the rootfs is imported and an [`.nspawn`](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html) file is generated from a few common options in the OCI `config.json`, namely: + +- [Environment Variables](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html#Environment=) +- [Working Directory](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html#WorkingDirectory=) +- [Process Parameters](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html#Parameters=) +- [Bind Mounts](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html#Bind=) + +Two additional options are added, [`ProcessTwo=true`](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html) and [`VirtualEthernet=no`](https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html#VirtualEthernet=) \ No newline at end of file