How TencentCloud CubeSandbox Converts OCI Images into Deployable Sandboxes
CubeSandbox converts OCI images into deployable sandboxes through a three-stage pipeline: the API layer constructs a CreateTemplateFromImageReq, CubeMaster pulls the image and creates a read-only snapshot with a unique template ID, and CubeShim instantiates isolated sandboxes using copy-on-write layers on top of that template.
The TencentCloud CubeSandbox project provides a secure, isolated execution environment for containerized workloads. Understanding how the template system converts OCI images into deployable sandboxes is essential for operators managing large-scale template libraries and sandbox lifecycles.
The Three-Stage Template Conversion Pipeline
The conversion process bridges user-supplied OCI image references with ready-to-run sandboxes through three distinct architectural stages.
Stage 1: Request Construction in the API Layer
The process begins when the API layer receives a CreateTemplateRequest containing the OCI image reference, optional registry credentials, and sandbox configuration parameters. In CubeAPI/src/services/templates.rs, the create_template() function (lines 108‑30) builds a CreateTemplateFromImageReq struct, populating the source_image_ref field with the OCI image reference before forwarding it to CubeMaster.
Stage 2: Image Pull and Snapshot Creation via CubeMaster
CubeMaster (the controller service) receives the request through the client method create_template_from_image. As implemented in CubeAPI/src/cubemaster/mod.rs (lines 71‑85), this posts to the HTTP endpoint POST /cube/template/from-image. While the actual pull-and-snapshot logic resides in CubeMaster (outside this repository), the triggered process pulls the OCI image using the configured container runtime (containerd/cri‑o), extracts the layered filesystem, and creates a read‑only snapshot identified as tpl‑<uuid>. This snapshot stores the root filesystem, metadata, and the template compatibility matrix required for CPU/feature filtering.
Stage 3: Sandbox Instantiation via CubeShim
When a sandbox launches, CubeShim reads the template_id from the sandbox spec annotations. As shown in CubeShim/shim/src/sandbox/sb.rs, the system locates the template snapshot and creates a copy‑on‑write (COW) writable layer on top of the read‑only template. It applies the CPU/feature template via cpuid_filter::apply_compatible_template (defined in hypervisor/arch/src/x86_64/cpuid_filter.rs), configuring network, logging, and other runtime overrides. The result is a sandbox that runs the original OCI image’s contents but remains isolated and mutable only within its own COW layer.
Step-by-Step Technical Walkthrough
-
API receives the request – A client POSTs to
/templateswith JSON containing the OCI image reference. -
TemplateService::create_templatebuilds aCreateTemplateFromImageReq(see lines 20‑38 oftemplates.rs). -
CubeMasterClient::create_template_from_imagesends the request to the CubeMaster HTTP endpointPOST /cube/template/from-image(seecubemaster/mod.rslines 71‑85). -
CubeMaster pulls the image – It contacts the OCI registry, authenticates if needed, and downloads the image layers.
-
Rootfs assembly – The layers unpack in order to a temporary directory; a read‑only snapshot is recorded in the internal storage backend (typically using overlayfs).
-
Template metadata – CubeMaster generates a unique ID prefixed with
tpl-and attaches a CPU template (e.g., T2CL/T2A) to guarantee compatible instruction‑set exposure. The CPU templates are defined inhypervisor/arch/src/x86_64/cpuid_filter.rs. -
Template storage – CubeMaster returns a
TemplateJobResponsecontaining thetemplate_idand job status. The API layer converts this to aTemplateBuildJoband returns it to the caller. -
Launching a sandbox – The sandbox spec includes
template_id. CubeShim reads this annotation, creates a new writable overlay on top of the read‑only template snapshot, and starts the container with the supplied overrides (ports, environment variables, network config).
Implementation Examples
Creating a Template from an OCI Image
let create_req = CreateTemplateRequest {
image: "registry.example.com/myapp:1.2.3".to_string(),
// optional fields …
..Default::default()
};
let template_job = template_service.create_template(create_req).await?;
println!("Template creation started, job id: {}", template_job.job_id);
Relevant source: CubeAPI/src/services/templates.rs – create_template() (lines 108‑30).
Retrieving Template Details
let detail = template_service.get_template(&template_job.template_id).await?;
println!("Template ID: {}", detail.template_id);
println!("Status: {}", detail.status);
Relevant source: CubeAPI/src/services/templates.rs – get_template() (lines 60‑73).
Launching a Sandbox Using the Template
{
"metadata": {
"annotations": {
"cube.master.appsnapshot.template.id": "tpl-1234abcd"
}
},
"spec": {
"container_overrides": { /* … */ },
"network_type": "vpc"
}
}
The CubeShim reads cube.master.appsnapshot.template.id and builds the sandbox on top of that template.
Relevant source: CubeShim/shim/src/sandbox/sb.rs (uses the template_id annotation).
Key Source Files and Components
| File | Purpose |
|---|---|
CubeAPI/src/services/templates.rs |
Implements the high‑level template API (create, get, delete, build status). |
CubeAPI/src/cubemaster/mod.rs |
HTTP client that forwards template‑creation requests to CubeMaster (POST /cube/template/from-image). |
CubeShim/shim/src/sandbox/sb.rs |
Consumes a template ID to construct a sandbox’s root filesystem (read‑only template + writable overlay). |
hypervisor/arch/src/x86_64/cpuid_filter.rs |
Defines the CPU feature templates (T2CL, T2A) applied during template instantiation. |
hypervisor/arch/src/x86_64/mod.rs (function get_json_template) |
Loads the static CPU template JSON used by the hypervisor. |
Summary
- Three-stage pipeline: Request construction (API), image pull and snapshot creation (CubeMaster), and sandbox instantiation (CubeShim).
- Read-only template snapshots: Created with the prefix
tpl-<uuid>and stored as the base layer for all derivative sandboxes. - Copy-on-write isolation: Each sandbox receives a writable COW layer on top of the immutable template, ensuring filesystem isolation.
- CPU compatibility: Templates include compatibility matrices (T2CL/T2A) defined in
cpuid_filter.rsto ensure consistent instruction-set exposure. - Annotation-driven binding: Sandboxes reference templates via the
cube.master.appsnapshot.template.idannotation.
Frequently Asked Questions
What is the format of the template ID generated by CubeMaster?
CubeMaster generates template IDs using the prefix tpl- followed by a UUID (e.g., tpl-1234abcd). This identifier is returned in the TemplateJobResponse and stored in the cube.master.appsnapshot.template.id annotation when creating sandboxes.
How does CubeSandbox handle CPU feature compatibility when converting OCI images?
During template creation, CubeMaster attaches a CPU template (such as T2CL or T2A) to the snapshot. When CubeShim instantiates a sandbox, it applies this template via cpuid_filter::apply_compatible_template (defined in hypervisor/arch/src/x86_64/cpuid_filter.rs) to filter CPU features and ensure compatible instruction-set exposure across different hardware.
Can multiple sandboxes share the same template snapshot?
Yes. Multiple sandboxes can reference the same template_id and mount the same read‑only template snapshot as their base layer. Each sandbox receives its own copy‑on‑write (COW) writable layer for isolation, allowing efficient storage reuse while maintaining runtime separation.
What happens if the OCI image pull fails during template creation?
If the image pull fails in CubeMaster, the create_template_from_image operation returns an error status in the TemplateJobResponse. The API layer surfaces this failure to the caller, and no template snapshot is created. The client must retry the request after resolving the registry authentication or connectivity issues.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →