13.5. Base Filesystem¶
A GEISA LEE container provides the following minimum filesystem
within each Application Container environment. The container filesystem
contents may be derived from the platform host filesystem or separately
constructed specifically for GEISA container environments.
13.5.1. Filesystem Mounts¶
Each GEISA Application MUST be provisioned in its own container environment separate from other Applications. As such, application-specific names, IDs, and other identifiers do not need to be encoded in filesystem paths within the Application environment.
The GEISA platform implementation MUST provide the following virtual filesystem mounts within the container environment:
/
a filesystem containing base binaries, libraries, the application and other files and directories not specifically listed below. It MUST be either mounted read-only, or the application MUST lack write permission to all items within the filesystem except as explained below.
/proc
a Linux procfs filesystem populated by the kernel for the specific application’s container
/dev
MAY be part of the / filesystem or separate mount such as tmpfs or devtmpfs types
MUST contain at a minimum: console full log null random stderr stdin stdout urandom and zero
/dev/log MUST be backed by the platform to filter and direct logs into the GEISA ADM or another system logging mechanism if the implementation is not ADM conformant
/sys
a Linux sysfs filesystem populated by the kernel for the specific application’s container
/tmp
A separate filesystem or directory within / that is writable by the Application process
MUST be limited in size as described in the Application’s Deployment Manifest
MAY be backed by tmpfs or a persistent filesystem
Applications MUST handle stale files and cleanup contents it created to remain under limits
Platform MAY clean, purge, or delete contents while the Application is NOT running
/home/geisa
A separate filesystem or directory within / that is writable by the Application process
MUST be limited in size as described in the Application’s Deployment Manifest
Applications MUST handle stale files and cleanup contents it created to remain under limits
MUST be persistent across application restarts and device reboots
Platform SHALL be responsible for metadata integrity (journaling, startup checks, etc…)
Application SHALL be tolerant to data corruption and missing files
13.5.2. Utilities and Environment¶
A base set of executables typically found in an embedded or minimal container environment MUST be present.
GEISA does not require a specific implementation, however Busybox is recommended with the default build options.
A skeleton filesystem MUST be populated including typical paths for binaries and libraries:
bin
dev
etc
home
lib
proc
sys
tmp
var
and optionally:
sbin
usr/sbin
usr/bin
usr/lib
run (if present, SHOULD be non-persistent and share /tmp size limits)
A skeleton filesystem MUST be populated with typical files including at a minimum:
/etc/group
/etc/hostname
/etc/hosts (including a localhost entry)
/etc/passwd
and if provided by libc implementation:
/etc/resolv.conf
/etc/nsswitch.conf
/etc/locale.conf
/etc/services
/etc/protocols
/etc/shells
/etc/timezone
The following environment variables MUST be set at a minimum when invoking Applications processes:
SHELL
HOME
USER
PATH
13.5.3. GEISA Components¶
The Application needs to determine information about the environment it is running on and as such can expect certain GEISA specific configuration to be present. As explained in API Architecture and Platform Discovery these files are placed in /etc/geisa within the container environment.
13.5.4. Base Libraries¶
A set of base libraries SHALL be provided in the base filesystem. See Linux Base Libraries for further details.
13.5.5. Construction of the Filesystem¶
Each Application container filesystem has different content based on the specific Application.
GEISA implementations SHOULD construct a container filesystem using Linux
overlayfs to reduce flash and ram waste.
Immutable images such as the base utilities and libraries common to all
Applications and Application-specific binaries, libraries, and other files
provided by the Application vendor SHOULD be overlayfs lower layers,
while the upper MAY be used for generated configuration files, any unix
domain sockets and/or the non-persistent storage depending on the design
choices of the LEE.
An efficient read-only file system, like squashfs for the base and
application images SHOULD be used, but this is not required.
Overlayfs allows an Application to provide their own or even replace a base library, fixed data, and executables as needed without having to construct a copy of the lower layer data in flash or ram.
When an Application is upgraded, its overlayfs MUST be re-constructed and any non-persistent files deleted while the persistant files (in /home/geisa) MUST be preserved.
When an Application is stopped and restarted (or device rebooted), the platform MAY re-construct the filesystem including deletion of any non-persistent files while the persistant files (in /home/geisa) MUST be preserved.
13.5.6. Example Filesystem Construction¶
As an example of how this might be composed, consider a platform using lxc
as its container engine. /platform is persistant storage for the GEISA
platform and a shared base image is at /platform/base/geisa-base-1.0.0.sqfs.
The Platform receives an application manifest for a given application,
including the image’s digital signature. Upon receiving the application image
through the application download process, the platform stores the
application image in /platform/apps/geisa-app-1/app-1.0.1.sqfs, and then
validates the image against the digital signature contained in the manifest.
Based on the permissions specified in the manifest, the platform creates the
necessary MQTT user for the application, granting that user access to the
necessary APIs allowed in the manifest. It generates a random login token for
the application and stores the username and token as the application’s user
credentials in /platform/apps/geisa-app-1/config/etc/geisa/mqtt.conf.
To launch the application the platform will mount each of the required file
system images. This example LEE implementation uses a separate writable
/tmp filesystem mount with the rootfs mounted read-only.
For a system running lxc, the platform might create a
geisa-app-1 directory under /var/lib/lxc. Then sub-directories for the
various overlayfs layers and a resulting rootfs directory.
The application persistant storage is in /platform/apps/geisa-app-1/persist
and this example LEE uses a quota to limit application usage as specified in the
deployment manifest. Other mechanisms could be used to limit a persistent
volume such as a file-backed loopback device.
Example geisa-app-1 with 50MiB persistent and 4MiB non-persistant volumes
mkdir -p /platform/apps/geisa-app-1/config/etc/geisa
geisa_create_mqtt_conf geisa-app-1 /platform/apps/geisa-app-1/config/etc/geisa/mqtt.conf
mkdir -p /platform/apps/geisa-app-1/persist
chown geisa-app-1:nogroup /platform/apps/geisa-app-1/persist
chmod 0700 /platform/apps/geisa-app-1/persist
setquota -u geisa-app-1 50M 50M 0 0 /platform
mkdir -p /var/lxc/geisa-app-1/{base,app,config,upper,work,rootfs}
mount -t squashfs /platform/base/geisa-base-1.0.0.sqfs /var/lxc/geisa-app-1/base
mount -t squashfs -o nosuid,nodev /platform/apps/geisa-app-1/app-1.0.1.sqfs /var/lxc/geisa-app-1/app
mount --bind /platform/apps/geisa-app-1/config /var/lxc/geisa-app-1/config
mount -t overlay -oro overlay \
-olowerdir=/var/lxc/geisa-app-1/base:/var/lxc/geisa-app-1/app:/var/lxc/geisa-app-1/config \
-oupperdir=/var/lxc/geisa-app-1/upper \
-oworkdir=/var/lxc/geisa-app-1/work \
/var/lxc/geisa-app-1/rootfs
mount --bind /platform/apps/geisa-app-1/persist /var/lxc/geisa-app-1/rootfs/home/geisa
mount -t tmpfs -osize=4M,mode=1777 tmpfs /var/lxc/geisa-app-1/rootfs/tmp
mount -t sysfs sysfs /var/lxc/geisa-app-1/rootfs/sys
mount -t proc proc /var/lxc/geisa-app-1/rootfs/proc
Note
GEISA LEE SHOULD have their / filesystem mounted read-only in the kernel to follow the principle of least privilege. This prevents Applications from modifying or adding files in unexpected places and forces deterministic Application behavior on each startup.
If an implementation chooses to mount / read-write, it MUST enforce file and directory permissions appropriately as well as limit the growable size of the filesystem to the same limits as the Application’s Deployment Manifest specifies for non-persistent storage. In this case a seperate /tmp mount is unnecessary and any changes outside of the persistent /home/geisa are non-persistent.