Developer guidelines

This section describes the internal structure of SoftwareContainer, and the major design considerations.

The intended reader is a developer who wants to understand and work with the internals of SoftwareContainer, or anyone who simply wants a better insight for e.g. troubleshooting.

There is also some documentation of interest in the Filesystems chapter regarding filesystems in the container.

Todo

The diagrams in this chapter do not differ between sync and async calls, should be fixed

Design principles

This section describes some major design considerations and principles mostly related to the internals of SC and configuration formats.

Gateways

Gateway configs needs to be possible to extend in the future. In practice, this means that it should be possible to add new json objects to the root object without breaking current parsing of the config, or requiring unnecessary re-writes of existing integrated configs that are not affected by such addition.

Configs should have version indicated as part of the content, so SC could perform checks and adapt to the format for compatibility reasons.

This has implications on the json structure, e.g. it sometimes adds some redundancy to the structure. It also means that the parsing might not always be as efficient as it could be, as the objects need to be iterated to find, compared to getting values by keys already in the first level of nesting.

Important internal interfaces

Interface: softwarecontainer.h

The Agent uses softwarecontainer.h to manage the lifecycle of container instances, e.g. creation and destruction. The interface provides access to the underlying ContainerAbstractInterface which users can utilize to access the container interface. The interface is implemented by SoftwareContainer.

Below is a diagram showing the interaction between the user Agent and the interfaces SoftwareContainer subsequently uses:

blockdiag Agent SoftwareContainer ContainerAbstractInte rface Gateway multiple calls multiple calls multiple calls new() setContainerID() setMainLoopContext() init() initialize() bool create() bool start() bool new() addGateway() setContainer() bool further events here

Interface: containerabstractinterface.h

The abstract class ContainerAbstractInterface is the abstraction of the underlying container technology. The design intention is to have this interface container technology agnostic. The design is intended to:

  • Separate the higher level APIs and interfaces from the details of the container implementation.
  • Allow easier integration of other container technologies.
  • Isolate container implementation and domain specific details to enter the higher level code.

This is currently implemented by the LXC specific Container in container.h.

Below is a diagram showing the initialize, create, and start sequence focussing on the ContainerAbstractInterface implementation Container:

blockdiag SoftwareContainer Container liblxc initialize() createDirectory() createSharedMountP oint() bool create() lxc_container_new() container_struct bool start() bool various operations on the lxc struct various operations on the lxc struct

Interface: gateway.h

All gateway implementations must inherit Gateway and implement the pure virtual methods. The rationale and design intention for isolating gateway specific knowledge to respective gateway is to:

  • Allow gateways to have a flexible config structure and content to more easily suit their purpose.
  • Separate maintenance between gateways, e.g. updating the config and implementation of one will not propagate to the others.
  • Consistent interface towards the user of the class so there are no ripple effects into SoftwareContainer.

SoftwareContainer sets the configuration on the interface of this base class, and the derived classes are then called internally to do their specific parsing and application of the configs.

SoftwareContainer also queries the gateways about state and e.g. activates the gateway when it has been configured.

Below diagram show the major events during the configuration and activation sequence initiated by the Agent:

blockdiag Agent SoftwareContainer Gateway derived-gateway startGateways() id() ID setConfig() readConfigElement() bool bool isConfigured() bool activate() bool void