feat(container): add build source to manifest schema

ContainerConfig.image is now Option<String>, mutually exclusive with a new
optional ContainerConfig.build: Option<BuildConfig>. Exactly one of image
or build must be present, enforced in AppManifest::validate.

Adds ResolvedSource enum (Pull | Build) and ContainerConfig::resolve +
::image_ref helpers so the orchestrator can treat pull and build uniformly.
All 26 existing pull-only manifests continue to parse unchanged
(covered by existing_pull_only_manifests_still_parse test).

Call sites updated: podman_client, runtime::DockerRuntime, dev_orchestrator.
Dev orchestrator errors out cleanly on Build sources until Step 2 lands
build_image support on the runtime trait.

Step 1 of docs/rust-orchestrator-migration.md. 10 new unit tests, all pass.

Also includes: docs/rust-orchestrator-migration.md (design spec) and
docs/STATUS.md resume section for the next session.
This commit is contained in:
archipelago
2026-04-22 17:46:36 -04:00
parent 0ac673deb4
commit 919055f3f1
7 changed files with 1046 additions and 17 deletions

View File

@@ -1,7 +1,7 @@
use anyhow::{Context, Result};
use archipelago_container::{
AppManifest, BitcoinSimulationMode, BitcoinSimulator,
ContainerRuntime as ContainerRuntimeTrait, ContainerStatus, PortManager,
ContainerRuntime as ContainerRuntimeTrait, ContainerStatus, PortManager, ResolvedSource,
};
use std::sync::Arc;
@@ -103,14 +103,30 @@ impl DevContainerOrchestrator {
volume.source = dev_path.to_string_lossy().to_string();
}
// Pull image
self.runtime
.pull_image(
&manifest.app.container.image,
manifest.app.container.image_signature.as_deref(),
)
.await
.context("Failed to pull image")?;
// Resolve pull-or-build. Dev orchestrator currently only supports pull;
// Build support lands in Step 2 of the rust-orchestrator migration.
match manifest
.app
.container
.resolve()
.ok_or_else(|| anyhow::anyhow!("manifest container config invalid (neither image nor build)"))?
{
ResolvedSource::Pull {
image,
image_signature,
..
} => {
self.runtime
.pull_image(&image, image_signature.as_deref())
.await
.context("Failed to pull image")?;
}
ResolvedSource::Build(_) => {
anyhow::bail!(
"dev orchestrator does not yet support local image builds (see rust-orchestrator-migration.md Step 2)"
);
}
}
// Create container with port offset
let port_offset = if self.config.dev_mode {