Getting started¶
Structure¶
The user API is implemented by the SoftwareContainer Agent as a D-bus service. That API is used to start, configure, and control containers. On the bus, the Agent has the name com.pelagicore.SoftwareContainer and object path /com/pelagicore/SoftwareContainerAgent.
The Agent in turn links to the SoftwareContainer library which is to be considered an internal API for most users.
The Agent and the SoftwareContainer library are split to allow for development directly towards the library. One use case where this could be useful is when you have project specific requirements on the integration towards SoftwareContainer. The Agent/library split is also useful when integrating a launcher that e.g. launches apps from a UI, when it is not appropriate to run the launcher with root privileges. In this case the launcher can use the Agent D-Bus API without being root while the Agent has been started with root privileges.
Below is an example of the major entities involved in a call to create a container:
Container config¶
This section is about the config used when a container is created using the D-Bus interface. This config is only one pice of the overall configuration, for more info see Configuration
When creating containers, a configuration is passed as a JSON string. The string is an array with objects, in the JSON sense. The currently supported configs are:
- Disk writing buffer - on or off. Key: “writeBufferEnabled”, value:
true
for on orfalse
for off.- Temporary FileSystem buffers - on or off. Key: “temporaryFileSystemWriteBufferEnabled”, value
true
for on orfalse
for off.- Temporary FileSystem Size - integer. Key: “temporaryFileSystemSize”, value: Integer Size in bytes of the Temporary FileSystem Size.
Example config JSON:
[{
"writeBufferEnabled": true,
"temporaryFileSystemWriteBufferEnabled": true,
"temporaryFileSystemSize": 10485760
}]
The main reason this config is passed as raw JSON is to support additions in supported config options without breaking the API.
Write buffer configuration¶
The writeBufferEnabled
is used to enable or disable write buffers on the mounted
filesystems in the container. These
buffers consists of a RAM overlay on top of the existing filesystem, and are
synced to the underlying filesystem on
shutdown of the container.
The temporaryFileSystemWriteBufferEnabled
is used to enable or disable the
tmpfs
being mounted on top of the containers temporary filesystem
containing temporary files. This can be used to separate the containers from
accidentally overcommitting and thereby denying service to any other containers
currently running.
The temporaryFileSystemSize
is used to set the RAM size
of the
tmpfs
being mounted on top of the containers temporary filesystem location.
The variable is set in bytes
. This will be shared between all the
upper
and work
directories being mounted using overlayfs
into a
specific container.
Working with containers¶
This section describes how to work with the Agent D-Bus API and how to configure gateways to make the container useful for specific application and platform needs.
Running a command in a container¶
In this section we will create a container, run a command in it and then shut down the container.
- Prerequisites:
- configure and build (see project README.md)
From the build directory, run the agent:
sudo -E softwarecontainer-agent
Note that we are running this command with sudo
, the Agent needs to be started with root privileges.
Using e.g. gdbus
, we can introspect the Agent D-Bus service API:
gdbus introspect --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent
Next, we will start a new container so take note of the parameters of Create.
Start a container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.Create \
'[{"writeBufferEnabled": false}]'
The JSON string passed as argument to the config
parameter is documented in the Container
config section.
The return value of Create is the ID of the newly created container. This is used to identify the container when e.g. shutting it down.
Bind mount a directory inside the container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.BindMount \
0 \
"$HOME/softwarecontainer" \
"/app" \
false
- Parameters:
containerID
- a int32 with the ID of the created container, as returned by theCreate
method.pathInHost
- a string with the host path of the directory to be bind mounted into the container. The host path must exist before running the command.pathInContainer
- a string representing the absolute mount path inside the container.readOnly
- a boolean with a flag to set the bind mounted directory to read only or not. This is currently not supported.
The method assumes the path pathInHost
exists, so choose another path if it is more convenient.
The result of the method is that the content of $HOME/softwarecontainer/
will be
visible in the path /app
inside the container. The actual location on the host can be found in
/tmp/container/SC-<container ID>/
where the created app
directory will be.
Launch something in the container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.Execute \
0 \
"touch hello" \
"/app" \
"" \
'{"": ""}'
- Parameters:
containerID
- a int32 with the ID of the created container, as returned by theCreate
method.commandLine
- a string with the method to run at the method line insider the container.workingDirectory
- a string with a path to a directory which will be set as the working directory.outputFile
- a string with a path to where stdout will be directed from within the container.env
- a string:string dictionary with environment variables and values to be set in the container. These will override any variables with the same name previously set by the Environment gateway.
The method returns the PID of the process run inside the container.
The above method call results in a file hello
being created inside the conainer in /app/
.
This can also be seen in the bind mounted host location.
Suspend the container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.Suspend \
0
This will suspend execution inside the container. The value passed as the containerID parameter should be the same value that was returned from the call to Create. It is not possible to run LaunchCommand on a suspended container.
Resume the container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.Resume \
0
This will resume the suspended container. The value passed as the containerID parameter should be the same value that was returned from the call to Create.
List all available Capabilities:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.ListCapabilities
This will list all the capabilities that are available and possible to set on containers.
Set Capabilities on a specific container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.SetCapabilities \
0 \
"['com.pelagicore.temperatureservice.gettemperature',
'com.pelagicore.temperatureservice.settemperature']"
This will set the capabilities listed in the last argument to the container identified by the containerID parameter returned from the Create call.
Shut down the container:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.Destroy \
0
The value passed as the containerID parameter should be the same value that was returned from the call to Create.
Configure gateways¶
For details about the gateway configurations, see Gateways
Once a container is created and before e.g. an application is launched in the container, gateway configurations can be set in order to configure what the application will have access to. However, one does not set gateway configurations directly, they are grouped together into capabilities.
Note that this requires you to have service manifests with capabilities defined and pointed out for
the softwarecontainer-agent
. See service manifests for more info.
Set capabilities:
gdbus call --system \
--dest com.pelagicore.SoftwareContainerAgent \
--object-path /com/pelagicore/SoftwareContainerAgent \
--method com.pelagicore.SoftwareContainerAgent.SetCapabilities \
0 \
"['com.acme.example','com.acme.sample']"
- Parameters:
containerID
- an int with the id of the created container, as returned by theCreate
method.capabilities
- a string array of capability names