Skip to content

Partition model

SpaceOS uses a partition to group services from one project. The partition sets their memory limit, communication rules, and supervisor. Each service still runs in its own virtual machine or container sandbox. Use the same partition names in build.yaml and run.yaml.

build.yaml defines the services and interfaces in a partition. run.yaml assigns memory, CPUs, isolation, and frame routes. SpaceOS starts each service in its selected sandbox.

Configure and inspect a partition

Use the same partition and service names in both manifests. In build.yaml, declare the service and the interfaces it may use:

partitions:
payload:
services:
- name: classifier
image: ghcr.io/<your-org>/classifier:1
runtime: oci
isolation: runc
interfaces:
- type: frame_bus
apids: [0x120, 0x12F]
send_to: [ground]

In run.yaml, assign resources and route the frames:

partitions:
payload:
memory: 512
apids: [0x120, 0x12F]
send_to: [ground]
services:
- name: classifier
isolation: runc
cpus: [0, 1]

Build the composition and check the placement before booting it:

Terminal window
space build . -t classifier:dev
space run classifier:dev --runtime run.yaml --dry-run
space run classifier:dev --runtime run.yaml

Inspect the running partition:

Terminal window
space ps --json
space report --json
space logs classifier

The report names the payload partition, its 512 MB memory limit, the two CPU assignments, and the allowed APID range. A mismatched service name or an unavailable backend fails during --dry-run.

Partitions

A partition is the unit that receives memory and communication rules. SpaceOS runs each service in that partition with one of these isolation methods:

  • A Solo5 micro-VM. A unikernel service is its own sealed guest, launched by a Solo5 tender: hvt where the board offers hardware virtualization through /dev/kvm, or the seccomp-confined spt where it does not. There is no general-purpose OS inside the guest.
  • A runc sandbox. A Linux service runs as an OCI container with a read-only root, user namespace, default-deny seccomp profile, and cgroup limits. It shares the kernel of dom0, the SpaceOS control domain, so its isolation is weaker than a micro-VM’s.

A multi-service partition boots its own init process (the supervisor, pid1 by default) which starts the declared services in dependency order and reports lifecycle and health. Memory is assigned per partition and CPUs per service in run.yaml; what the partition contains is declared in build.yaml.

Services in one project may share communication rules while keeping separate sandboxes.

Service interfaces

A service declares typed interfaces at build time; the runner wires them at launch. There are four kinds:

  • Frame bus. Carries fixed-size telemetry and command messages between services and ground. Each message carries an APID, the stream label used to sort messages. The send_to list controls where a service may send it.
  • IP. Provides a standard IP network. The service binds ports on its declared bridges. space-net, the isolated SpaceOS network switch, rejects connections not listed in the signed release.
  • Data link. Carries large sensor products over a spacecraft serial fabric such as SpaceWire or SpaceFibre, or over a high-bandwidth virtual queue. Its settings name the link, direction, and maximum rate.
  • Supervision page. A small shared-memory page between the host and the guest carrying heartbeat, mission time, health, and the safe-mode command word. space-runner owns the host side and can put the service in safe mode.

Authorization and APID routing

Each signed release lists what every service may read, write, or open. An APID is the 11-bit CCSDS number used to label a telemetry or command stream. The number helps receivers sort messages. It does not grant permission to send them. Declare the APID range and allowed destinations in run.yaml.

Isolation layers

Partition level. A micro-VM partition is isolated by the CPU’s virtualization hardware; a fault, a crash, or a radiation-induced bit flip (a single-event upset) in one partition cannot reach another through memory. A runc partition is isolated by kernel namespaces and cgroups, a weaker boundary. The strength of the guarantee is a property of the substrate, the mechanism that actually runs the service.

Service level. Within a multi-service partition, the supervisor keeps services in separate processes with declared dependencies, healthchecks, and restart policy. Services communicate through their declared interfaces; there is no shared memory between services. For co-located bulk exchange, enable the partition block device (disk: true). The frame bus is sized for telemetry and command messages.

Isolation backends

The service-level isolation field selects the concrete backend:

  • hvt: Solo5 on KVM. The unikernel path with hardware VM isolation.
  • spt: Solo5 seccomp tender. The unikernel path where KVM is unavailable.
  • runc: OCI container. Any Linux application, shared dom0 kernel.
  • qemu: QEMU launcher for Unikraft images (x86_64 only).
  • host: host-native process, for development and test fixtures.
  • auto: let the runtime pick a compatible backend.
  • firecracker: KVM-backed micro-VM for Linux images.

Flight-domain boundary

The spacecraft’s safety-critical flight software (attitude control, orbit propagation, command and data handling, typically a real-time operating system running a framework such as F-Prime) is a separate trust domain, not a SpaceOS partition. It boots on its own authority, runs its own fault protection, and is backstopped by a hardware watchdog. SpaceOS observes it over a spacecraft bus and may relay commands that carry its authority. Boot, supervision, and recovery remain under the flight domain’s control.

A partition can be bus-facing: trusted to exchange telemetry and commands with the flight domain over the frame bus. That is a relay role, not ownership of the flight software.

Hardware acceleration

An accelerator broker opens the GPU, FPGA, or AI engine for a service. Before opening the device, the broker checks the service and device listed in the signed release. A service receives no device access by default.

  • Linux services (isolation: runc) reach accelerators through the device nodes the target profile grants (for example /dev/dri for a GPU).
  • Unikernel services use host-mediated delegation: the guest calls a narrow API and the host forwards it to the device, the same shape as Solo5’s virtual block and network devices.
  • Direct passthrough, where the guest drives the device itself, requires a dedicated device and an IOMMU, the hardware that limits which memory a device may reach. Targets without both disable passthrough and preserve the isolation boundary.

The delegation path is a named interface per accelerator class, not a generic passthrough:

AcceleratorInterfaceExercised on
GPU (NVIDIA)vAccelJetson TX2i
FPGAukAccelXilinx Versal
AI engineVitis AIVCK190
Many-coreOpenCL [roadmap]Kalray MPPA

For a GPU shared between services, a broker multiplexes the device so each service sees its own queue rather than the raw hardware.

The target profile lists its accelerators. A service that needs one runs only on a target that lists the matching device.

Manifest references

The two manifests use the same partition names as keys:

build.yaml defines…run.yaml defines…
Supervisor override (optional)How much memory to allocate
What services to bundleWhich CPUs to assign per service
Service interfaces and dependenciesPer-service isolation backend
Per-service healthcheck probeAPID ownership and send_to flow policy
Whether to enable the partition diskRelay shape and ground endpoint

The same composition can run with different placements: 512 MB on a development laptop or 128 MB on a constrained on-board computer, without rebuilding. Board facts (kernel, device tree, firmware, secure-boot keys) belong to neither file; they are properties of a connected target.