pub struct WindowsBuilder { /* private fields */ }Expand description
Native WCOW image builder.
Stateless apart from the static WindowsBuildConfig passed at
construction. Per-build state lives entirely on the stack of
WindowsBuilder::build_skeleton and inside the returned
BuildSkeleton.
Implementations§
Source§impl WindowsBuilder
impl WindowsBuilder
Sourcepub fn new(config: WindowsBuildConfig) -> Self
pub fn new(config: WindowsBuildConfig) -> Self
Construct a new WindowsBuilder with the given configuration.
Does no I/O: the cache directory is lazily created when
build_skeleton first runs.
Sourcepub fn config(&self) -> &WindowsBuildConfig
pub fn config(&self) -> &WindowsBuildConfig
Borrow the configuration this builder was constructed with.
Sourcepub async fn build_skeleton(&self, ctx: &BuildContext) -> Result<BuildSkeleton>
pub async fn build_skeleton(&self, ctx: &BuildContext) -> Result<BuildSkeleton>
Parse the Dockerfile, pull the base image, and materialise the foreign-layer chain.
Returns a BuildSkeleton for downstream Phase 4 tasks to
extend. Does not execute COPY or ADD — those route
through Self::execute_instruction and surface
BuildError::NotYetImplemented until 4.C lands. RUN is
implemented here (4.B).
§Errors
BuildError::ContextReadwhen the Dockerfile cannot be read.BuildError::DockerfileParseon a malformed Dockerfile.BuildError::NotSupportedwhen the Dockerfile has more than one stage (multi-stage WCOW builds are intentionally out of scope for the skeleton — Phase 4 follow-up task).BuildError::InvalidInstructionwhen the FROM target isscratchor a stage reference.BuildError::RegistryError/BuildError::IoErroron registry-side failures.BuildError::NotSupportedwhen invoked on a non-Windows host (the base layer materialisation step needs the HCS storage filter APIs).
Sourcepub async fn build_skeleton_with_parsed(
&self,
parsed: Dockerfile,
ctx: &BuildContext,
) -> Result<BuildSkeleton>
pub async fn build_skeleton_with_parsed( &self, parsed: Dockerfile, ctx: &BuildContext, ) -> Result<BuildSkeleton>
Variant of build_skeleton that takes an
already-parsed Dockerfile instead of reading it from disk.
Used by build_image_for_backend
where the parsed AST is already in hand and the dockerfile is not
guaranteed to exist on the local filesystem in the form the
caller’s BuildContext::dockerfile_path claims (e.g. when
HcsBackend is given a Dockerfile value directly by a higher
layer that did its own parse). The bulk of the work — stage
validation, FROM target resolution, LTSC rewrite, base image
pull + materialisation — is identical to build_skeleton.
§Errors
Same shape as build_skeleton minus the
dockerfile read error (which can’t happen because the caller has
already produced the AST).
Sourcepub async fn execute_instruction(
&self,
skeleton: &mut BuildSkeleton,
ctx: &BuildContext,
instruction: &Instruction,
) -> Result<()>
pub async fn execute_instruction( &self, skeleton: &mut BuildSkeleton, ctx: &BuildContext, instruction: &Instruction, ) -> Result<()>
Apply a single non-FROM instruction to a BuildSkeleton.
Dispatches to a per-instruction handler. Config-only instructions
mutate BuildSkeleton::image_config in place; COPY/ADD/RUN
commit a new RO layer per instruction (the per-instruction layer
model documented at the top of this module).
§Errors
BuildError::NotSupportedfor cross-stageCOPY --from=(multi-stage support arrives in a later task).BuildError::PathTraversalwhen a COPY/ADD source contains...BuildError::HttpFetchFailedwhen an ADD URL fetch fails.BuildError::TarExtractFailedwhen an ADD tarball auto-extract fails.BuildError::ContextRead/BuildError::IoErrorfor filesystem failures.BuildError::RunStepFailedwhen the RUN command exits non-zero.BuildError::LayerCreate/BuildError::LayerExportFailedon HCS or wclayer failures.BuildError::NotSupportedwhen COPY/ADD/RUN is invoked on a non-Windows host (HCS layer commits require the Windows APIs).
Sourcepub async fn emit_image(
&self,
skeleton: &BuildSkeleton,
tag: &str,
) -> Result<BuiltImage>
pub async fn emit_image( &self, skeleton: &BuildSkeleton, tag: &str, ) -> Result<BuiltImage>
Emit a final OCI image manifest + image config blob from the
accumulated BuildSkeleton state.
Walks the base-first BuildSkeleton::base_layers vector
alongside BuildSkeleton::working_chain to build one
EmittedLayer per descriptor. The first descriptor — the
foreign Windows base layer pulled from MCR — gets the
application/vnd.docker.image.rootfs.foreign.diff.tar.gzip media
type AND preserves the urls[] mirror list so Windows daemons
pull the bytes from MCR rather than the user’s destination
registry. Subsequent layers (RUN / COPY / ADD outputs) get
application/vnd.oci.image.layer.v1.tar+gzip and no urls[].
os.version resolution order:
WindowsBuildConfig::os_version_override(explicit user pin).BaseImageManifest::os_version(from the resolved base manifest’s platform descriptor / config blob).- Fallback to
BuildError::OsVersionUnresolved— the Windows runtime refuses to launch a container whoseos.versiondoes not match the host kernel build, so emitting a manifest without one would produce a container nothing can run.
§Errors
BuildError::OsVersionUnresolvedwhen neither the override nor the base manifest carries anos.version.BuildError::SerializeManifestFailedwhen serialising the image config or manifest blob fails (programmer error in this crate).BuildError::LayerDigestComputationFailedwhen computing adiff_idover a non-foreign layer blob fails because the blob path could not be read.
Sourcepub async fn push(&self, image: &BuiltImage, tag: &str) -> Result<()>
pub async fn push(&self, image: &BuiltImage, tag: &str) -> Result<()>
Push an already-emitted BuiltImage to its target registry
(task 4.E).
Uploads every non-foreign layer blob, the image config blob, and
finally PUTs the manifest at tag. Foreign Windows base layers
(those carrying a non-None urls[] on their EmittedLayer)
are NEVER re-uploaded — Windows daemons pulling the image will
follow the manifest’s urls[] array back to MCR (or the configured
mirror) for those blobs. This is the entire point of foreign-layer
distribution and why the WCOW push path must round-trip urls[]
verbatim into the manifest blob.
Authentication is sourced from
WindowsBuildConfig::registry_auth.
§Arguments
image— output ofSelf::emit_image.tag— full image reference ("ghcr.io/org/name:version","localhost:5000/repo:tag", …). Used verbatim as the manifest’s PUT target.
§Errors
BuildError::BlobUploadFailedwhen uploading a non-foreign layer blob or the image config blob fails.BuildError::ManifestPutFailedwhen the final manifest PUT fails.BuildError::PushFailedwhen staging a local blob (reading off disk) fails before any wire interaction.
Sourcepub async fn push_with(
&self,
image: &BuiltImage,
tag: &str,
target: &dyn PushTarget,
) -> Result<()>
pub async fn push_with( &self, image: &BuiltImage, tag: &str, target: &dyn PushTarget, ) -> Result<()>
Push variant that takes an explicit PushTarget. The public
Self::push wires up the real registry-backed implementation;
this variant exists so unit tests can inject a recording double
without needing a live registry. The split also means the wire
protocol details (how many PATCHes per blob, what Content-Type
the manifest carries, etc.) live entirely behind the trait and can
be unit-tested independently of WindowsBuilder.
§Errors
Same shape as Self::push: BuildError::BlobUploadFailed,
BuildError::ManifestPutFailed, or BuildError::PushFailed
depending on which stage of the push tripped.
Sourcepub async fn build_and_push(&self, ctx: &BuildContext) -> Result<()>
pub async fn build_and_push(&self, ctx: &BuildContext) -> Result<()>
Convenience: skeleton → execute every parsed instruction → emit
manifest → push. Single entry point for callers that want a
one-shot WCOW build from a BuildContext.
Walks ctx’s Dockerfile in order. After each Instruction the
instruction is routed through Self::execute_instruction which
commits a new RO layer per RUN/COPY/ADD and mutates the in-memory
image config for config-only instructions. After the last
instruction the manifest is emitted via Self::emit_image and
pushed via Self::push.
§Errors
Any BuildError that Self::build_skeleton,
Self::execute_instruction, Self::emit_image, or
Self::push can produce.
Sourcepub async fn build_image_for_backend(
&self,
context: &Path,
dockerfile: &Dockerfile,
options: &BuildOptions,
event_tx: Option<&Sender<BuildEvent>>,
) -> Result<BuiltImage, BuildError>
pub async fn build_image_for_backend( &self, context: &Path, dockerfile: &Dockerfile, options: &BuildOptions, event_tx: Option<&Sender<BuildEvent>>, ) -> Result<BuiltImage, BuildError>
Run a full Windows build conforming to the
crate::backend::BuildBackend::build_image contract.
This is the canonical Windows build entry point used by
[crate::backend::hcs::HcsBackend::build_image] — that backend
is a thin shim that constructs a WindowsBuilder and delegates
here. Drives the same pipeline as Self::build_and_push but
(a) accepts an already-parsed Dockerfile and a
[BuildOptions] from the public builder API instead of the
builder-internal BuildContext; (b) emits [BuildEvent]s into
the optional event_tx channel so the TUI / plain-logger surface
stays driven; (c) detects the provisioned toolchain language for
the resolved (post-rewrite) base image and threads it through
every RUN step’s apt→choco translator; (d) returns the
CLI-facing crate::builder::BuiltImage type, not the
builder-internal BuiltImage.
event_tx is a std::sync::mpsc::Sender — matching the
BuildBackend::build_image trait signature — and is consumed
fire-and-forget: a closed receiver does not fail the build.
§Errors
BuildError::NotSupportedwhen the dockerfile has multiple stages (single-stage only in the first iteration; same asHcsBackend’s existing constraint).BuildError::stage_not_foundwhen the FROM target is a stage reference.BuildError::InvalidInstructionwhen the FROM target isscratch(HCS requires a Windows base).- Any error
build_skeleton_with_parsed,execute_instruction,emit_image, orpushcan produce. BuildError::NotSupportedwhen invoked on a non-Windows host (the underlying base materialisation step needs HCS).
Sourcepub async fn build_image_for_backend_with_artifact(
&self,
context: &Path,
dockerfile: &Dockerfile,
options: &BuildOptions,
event_tx: Option<&Sender<BuildEvent>>,
) -> Result<(BuiltImage, BuiltImage), BuildError>
pub async fn build_image_for_backend_with_artifact( &self, context: &Path, dockerfile: &Dockerfile, options: &BuildOptions, event_tx: Option<&Sender<BuildEvent>>, ) -> Result<(BuiltImage, BuiltImage), BuildError>
Same pipeline as Self::build_image_for_backend, but also returns the
builder-internal BuiltImage (manifest + config + every layer
descriptor) alongside the CLI-facing one.
The native HCS backend uses this so that, after the build succeeds, it can
assemble a buildah-free oci-archive: for the local-registry import
(HcsBackend::export_oci_archive) without rebuilding — the internal
BuiltImage carries exactly the manifest/config bytes and the on-disk
layer paths the archive needs.
§Errors
Identical to Self::build_image_for_backend.
Auto Trait Implementations§
impl Freeze for WindowsBuilder
impl RefUnwindSafe for WindowsBuilder
impl Send for WindowsBuilder
impl Sync for WindowsBuilder
impl Unpin for WindowsBuilder
impl UnsafeUnpin for WindowsBuilder
impl UnwindSafe for WindowsBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request