Skip to main content

WindowsBuilder

Struct WindowsBuilder 

Source
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

Source

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.

Source

pub fn config(&self) -> &WindowsBuildConfig

Borrow the configuration this builder was constructed with.

Source

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
Source

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).

Source

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
Source

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:

  1. WindowsBuildConfig::os_version_override (explicit user pin).
  2. BaseImageManifest::os_version (from the resolved base manifest’s platform descriptor / config blob).
  3. Fallback to BuildError::OsVersionUnresolved — the Windows runtime refuses to launch a container whose os.version does not match the host kernel build, so emitting a manifest without one would produce a container nothing can run.
§Errors
Source

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 of Self::emit_image.
  • tag — full image reference ("ghcr.io/org/name:version", "localhost:5000/repo:tag", …). Used verbatim as the manifest’s PUT target.
§Errors
Source

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.

Source

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.

Source

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
Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more