This package contains routines that configure and launch a container in an OCI bundle format, using a low-level OCI runtime, either crun
or runc
at this time. crun
is currently preferred. runc
is used where crun
is not available.
Note - at present, all functionality works with either crun
or runc
. However, in future crun
may be required for all functionality, as runc
does not support some limited ID mappings etc. that may be beneficial in an HPC scenario.
The package contrasts with internal/pkg/runtime/launcher/native
which executes Singularity format containers (SIF/Sandbox/squashfs/ext3), using one of our own runtime engines (internal/pkg/runtime/engine/*
).
There are two flows that are implemented here.
- Basic OCI runtime operations agains an existing bundle, which will be executed via the
singularity oci
command group. These are not widely used by end-users of singularity. - A
Launcher
, that implements anExec
function that will be called by 'actions' (run/shell/exec) in--oci
mode, and will:- Prepare an OCI bundle according to
launcher.Options
passed through from the CLI layer. - Execute the bundle, interactively, via the OCI Run operation.
- Prepare an OCI bundle according to
Note - this area of code is under heavy development for experimental introduction in CE 3.11. It is likely that it will be heavily refactored, and split, in future.
The following files implement basic OCI operations on a runtime bundle:
Defines constants, path resolution, and minimal bundle locking functions.
Holds implementations of the Run / Start / Exec / Kill / Delete / Pause / Resume / State OCI runtime operations.
See https://github.com/opencontainers/runtime-spec/blob/main/runtime.md#operations
These functions are thin wrappers around the runc
/crun
operations of the same name.
Hold an implementation of the Create OCI runtime operation. This calls out to conmon
, which in turn calls crun
or runc
.
conmon
is used to manage logging and console streams for containers that are started backgrounded, so we don't have to do that ourselves.
Implements an Attach
function, which can attach the user's console to the streams of a container running in the background, which is being monitored by conmon.
End-to-end flows of basic OCI operations on an existing bundle are tested in the OCI group of the e2e suite, e2e/oci
.
The Launcher
type connects the standard singularity CLI actions (run/shell/exec), to execution of an OCI container in a native bundle. Invoked with the --oci
flag, this is in contrast to running a Singularity format container, with Singularity's own runtime engine.
Provides a minimal OCI runtime spec, that will form the basis of container execution that is roughly comparable to running a native singularity container with --compat
(--containall
).
Provides code handling the addition of required mounts to the OCI runtime spec.
Provides code handling configuration of container process execution, including user mapping.
Implements Launcher.Exec
, which is called from the CLI layer. It will:
- Create a temporary bundle directory.
- Use
pkg/ocibundle/native
to retrieve the specified image, and extract it in the temporary bundle. - Configure the container by creating an appropriate runtime spec.
- Call the interactive OCI Run function to execute the container with
crun
orrunc
.
An OCI container started via Launch.Exec
as a non-root user always uses at least one user namespace.
The user namespace is created prior to calling runc
or crun
, so we'll call it an outer user namespace.
Creation of this outer user namespace is via using the RunNS
function, instead of Run
. The RunNS
function executes the Singularity starter
binary, with a minimal configuration of the fakeroot engine ( internal/pkg/runtime/engine/fakeroot/config
).
The starter
will create a user namespace and ID mapping, and will then execute singularity oci run
to perform the basic OCI Run operation against the bundle that the Launcher.Exec
function has prepared.
The outer user namespace from which runc
or crun
is called always maps the host user id to root inside the userns.
When a container is run in --fakeroot
mode, the outer user namespace is the only user namespace. The OCI runtime config does not request any additional userns or ID mapping be performed by crun
/ runc
.
When a container is not run in --fakeroot
mode, the OCI runtime config for the bundle requests that crun
/ runc
:
- Create another, inner, user namespace for the container.
- Apply an ID mapping which reverses the 'fakeroot' outer ID mapping.
I.E. when a container runs without --fakeroot
, the ID mapping is:
- User ID on host (1001)
- Root in outer user namespace (0)
- User ID in container (1001)
End-to-end testing of the launcher flow is via the e2e/actions
suite. Tests prefixed oci
.