]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - docs/PORTABLE_SERVICES.md
mkosi: Keep mkosi.default out of the repository.
[thirdparty/systemd.git] / docs / PORTABLE_SERVICES.md
index 1833244447277ba0e0b9776437d97633f7c08cf9..8248275cedc6f097fe87cf0c2df3d9db11ffbc79 100644 (file)
@@ -1,3 +1,9 @@
+---
+title: Portable Services Introduction
+category: Concepts
+layout: default
+---
+
 # Portable Services Introduction
 
 This systemd version includes a preview of the "portable service"
@@ -20,7 +26,7 @@ Portable services don't bring anything inherently new to the table. All they do
 is put together known concepts in a slightly nicer way to cover a specific set
 of use-cases in a nicer way.
 
-# So, what *is* a "Portable Service"?
+## So, what *is* a "Portable Service"?
 
 A portable service is ultimately just an OS tree, either inside of a directory
 tree, or inside a raw disk image containing a Linux file system. This tree is
@@ -43,7 +49,7 @@ do too.
 If you so will, "Portable Services" are a nicer way to manage chroot()
 environments, with better security, tooling and behavior.
 
-# Where's the difference to a "Container"?
+## Where's the difference to a "Container"?
 
 "Container" is a very vague term, after all it is used for
 systemd-nspawn/LXC-type OS containers, for Docker/rkt-like micro service
@@ -74,7 +80,7 @@ Note that portable services are only available for system services, not for
 user services. i.e. the functionality cannot be used for the stuff
 bubblewrap/flatpak is focusing on.
 
-# Mode of Operation
+## Mode of Operation
 
 If you have portable service image, maybe in a raw disk image called
 `foobar_0.7.23.raw`, then attaching the services to the host is as easy as:
@@ -85,8 +91,9 @@ If you have portable service image, maybe in a raw disk image called
 
 This command does the following:
 
-1. It dissects the image, checks and validates the `/etc/os-release` data of
-   the image, and looks for all included unit files.
+1. It dissects the image, checks and validates the `/etc/os-release`
+   (or `/usr/lib/os-release`, see below)  data of the image, and looks for
+   all included unit files.
 
 2. It copies out all unit files with a suffix of `.service`, `.socket`,
    `.target`, `.timer` and `.path`. whose name begins with the image's name
@@ -98,16 +105,17 @@ This command does the following:
    `foobar@.{service|socket|target|timer|path}` as well as
    `foobar.*.{service|socket|target|timer|path}` and
    `foobar.{service|socket|target|timer|path}` are copied out. These unit files
-   are placed in `/etc/systemd/system/` like regular unit files. Within the
-   images the unit files are looked for at the usual locations, i.e. in
-   `/usr/lib/systemd/system/` and `/etc/systemd/system/` and so on, relative to
-   the image's root.
+   are placed in `/etc/systemd/system.attached/` (which is part of the normal
+   unit file search path of PID 1, and thus loaded exactly like regular unit
+   files). Within the images the unit files are looked for at the usual
+   locations, i.e. in `/usr/lib/systemd/system/` and `/etc/systemd/system/` and
+   so on, relative to the image's root.
 
 3. For each such unit file a drop-in file is created. Let's say
    `foobar-waldo.service` was one of the unit files copied to
-   `/etc/systemd/system/`, then a drop-in file
-   `/etc/systemd/system/foobar-waldo.service.d/20-portable.conf` is created,
-   containing a few lines of additional configuration:
+   `/etc/systemd/system.attached/`, then a drop-in file
+   `/etc/systemd/system.attached/foobar-waldo.service.d/20-portable.conf` is
+   created, containing a few lines of additional configuration:
 
    ```
    [Service]
@@ -140,16 +148,16 @@ Note that `portable attach` won't enable or start any of the units it copies
 out. This still has to take place in a second, separate step. (That said We
 might add options to do this automatically later on.).
 
-# Requirements on Images
+## Requirements on Images
 
 Note that portable services don't introduce any new image format, but most OS
 images should just work the way they are. Specifically, the following
 requirements are made for an image that can be attached/detached with
 `portablectl`.
 
-1. It must contain a binary (and its dependencies) that shall be invoked,
-   including all its dependencies. If binary code, the code needs to be
-   compiled for an architecture compatible with the host.
+1. It must contain an executable that shall be invoked, along with all its
+   dependencies. If binary code, the code needs to be compiled for an
+   architecture compatible with the host.
 
 2. The image must either be a plain sub-directory (or btrfs subvolume)
    containing the binaries and its dependencies in a classic Linux OS tree, or
@@ -157,7 +165,7 @@ requirements are made for an image that can be attached/detached with
    an image with a partition table understood by the Linux kernel with only a
    single partition defined, or alternatively, a GPT partition table with a set
    of properly marked partitions following the [Discoverable Partitions
-   Specification](https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/).
+   Specification](https://systemd.io/DISCOVERABLE_PARTITIONS).
 
 3. The image must at least contain one matching unit file, with the right name
    prefix and suffix (see above). The unit file is searched in the usual paths,
@@ -165,18 +173,41 @@ requirements are made for an image that can be attached/detached with
    image. (The implementation will check a couple of other paths too, but it's
    recommended to use these two paths.)
 
-4. The image must contain an os-release file, either in /etc/os-release or
-   /usr/lib/os-release. The file should follow the standard format.
+4. The image must contain an os-release file, either in `/etc/os-release` or
+   `/usr/lib/os-release`. The file should follow the standard format.
+
+5. The image must contain the files `/etc/resolv.conf` and `/etc/machine-id`
+   (empty files are ok), they will be bind mounted from the host at runtime.
+
+6. The image must contain directories `/proc/`, `/sys/`, `/dev/`, `/run/`,
+   `/tmp/`, `/var/tmp/` that can be mounted over with the corresponding version
+   from the host.
 
-Note that generally images created by tools such as `debootstrap`, `dnf
---installroot=` or `mkosi` qualify for all of the above in one way or
-another. If you wonder what the most minimal image would be that complies with
-the requirements above, it could consist of this:
+7. The OS might require other files or directories to be in place. For example,
+   if the image is built based on glibc, the dynamic loader needs to be
+   available in `/lib/ld-linux.so.2` or `/lib64/ld-linux-x86-64.so.2` (or
+   similar, depending on architecture), and if the distribution implements a
+   merged `/usr/` tree, this means `/lib` and/or `/lib64` need to be symlinks
+   to their respective counterparts below `/usr/`. For details see your
+   distribution's documentation.
+
+Note that images created by tools such as `debootstrap`, `dnf --installroot=`
+or `mkosi` generally qualify for all of the above in one way or another. If you
+wonder what the most minimal image would be that complies with the requirements
+above, it could consist of this:
 
 ```
-/usr/bin/minimald                        # a statically compiled binary
-/usr/lib/systemd/minimal-test.service    # the unit file for the service, with ExecStart=/usr/bin/minimald
-/usr/lib/os-release                      # an os-release file explaining what this is
+/usr/bin/minimald                            # a statically compiled binary
+/usr/lib/systemd/system/minimal-test.service # the unit file for the service, with ExecStart=/usr/bin/minimald
+/usr/lib/os-release                          # an os-release file explaining what this is
+/etc/resolv.conf                             # empty file to mount over with host's version
+/etc/machine-id                              # ditto
+/proc/                                       # empty directory to use as mount point for host's API fs
+/sys/                                        # ditto
+/dev/                                        # ditto
+/run/                                        # ditto
+/tmp/                                        # ditto
+/var/tmp/                                    # ditto
 ```
 
 And that's it.
@@ -186,6 +217,11 @@ own. If they do, it's fine, it will be ignored by the portable service logic,
 but they generally don't have to, and it might make sense to avoid any, to keep
 images minimal.
 
+If the image is writable, and some of the files or directories that are
+overmounted from the host do not exist yet they are automatically created. On
+read-only, immutable images (e.g. squashfs images) all files and directories to
+over-mount must exist already.
+
 Note that as no new image format or metadata is defined, it's very
 straight-forward to define images than can be made use of it a number of
 different ways. For example, by using `mkosi -b` you can trivially build a
@@ -207,14 +243,14 @@ image. To facility 3 and 4 you also need to include a boot loader in the
 image. As mentioned `mkosi -b` takes care of all of that for you, but any other
 image generator should work too.
 
-# Execution Environment
+## Execution Environment
 
 Note that the code in portable service images is run exactly like regular
 services. Hence there's no new execution environment to consider. Oh, unlike
 Docker would do it, as these are regular system services they aren't run as PID
 1 either, but with regular PID values.
 
-# Access to host resources
+## Access to host resources
 
 If services shipped with this mechanism shall be able to access host resources
 (such as files or AF_UNIX sockets for IPC), use the normal `BindPaths=` and
@@ -223,7 +259,7 @@ If services shipped with this mechanism shall be able to access host resources
 `/etc/resolv.conf`, the D-Bus system bus socket or write access to the logging
 subsystem are available to the service.
 
-# Instantiation
+## Instantiation
 
 Sometimes it makes sense to instantiate the same set of services multiple
 times. The portable service concept does not introduce a new logic for this. It
@@ -241,7 +277,7 @@ simple as:
 The benefit of this approach is that templating works exactly the same for
 units shipped with the OS itself as for attached portable services.
 
-# Immutable images with local data
+## Immutable images with local data
 
 It's a good idea to keep portable service images read-only during normal
 operation. In fact all but the `trusted` profile will default to this kind of