Skip to main content

CreateImageRequest

Struct CreateImageRequest 

Source
pub struct CreateImageRequest {
Show 17 fields pub name: String, pub base_image: BaseImage, pub base_image_version: Option<String>, pub dockerfile: Option<String>, pub binary: Vec<u8>, pub project_files: Option<ProjectFiles>, pub code_artifact_uri: String, pub build_role_arn: String, pub size: SizeClass, pub repair_guest_identity: bool, pub inherit_workdir: bool, pub run_hook_timeout: RunHookTimeout, pub build_hook_timeout: BuildHookTimeout, pub tags: BTreeMap<String, String>, pub log_group: Option<String>, pub log_stream: Option<String>, pub token_scope: Option<String>,
}
Expand description

Everything CreateMicrovmImage needs, with the traps closed in the type.

§What is deliberately not here

A client_token field. See token for the fifteen-hour wedge that absence prevents; CreateImageRequest::token_scope is a label folded in beside a fresh nonce and cannot become the token.

A capabilities list. See repair_guest_identity.

An architecture field. The model’s enum has exactly one value, so the only thing a field could express is a rejected request — and the rejection arrives after the artifact upload, reported as a constraint on a field the caller thought was a choice. ARM_64 is injected. A caller who built an x86 binary finds out from doctor’s ELF check, not from a build cycle.

Fields§

§name: String

The image name. Validated against ImageName (1..=64, [a-zA-Z0-9-_]+) before the artifact is uploaded, because AWS’s rejection arrives after the upload.

§base_image: BaseImage

The base image, pairing the baseImageArn with the Dockerfile FROM.

§base_image_version: Option<String>

baseImageVersion, or None to take whatever the service currently defaults to.

§Why pinning is worth a field

Without it a build floats. The managed base’s version list is not static — al2023-1 carried one version in June and two by July ("0" and "1", measured 2026-08-16) — so two builds of identical inputs weeks apart can sit on different bases, and neither recorded which. That is a reproducibility hole with no local symptom: the build succeeds either way, and the difference appears in the guest.

None is the default and stays the default, because pinning without knowing the legal values is how a caller pins to a version that has been withdrawn. ControlPlane::managed_base_versions is what answers that, and the version strings are bare integers for a managed base where a custom image’s are "1.0" — the two are not comparable, so a value from anywhere else does not belong here.

Checked against the Version shape before the call, because the create happens after the artifact upload.

§dockerfile: Option<String>

The Dockerfile, or None for the derived default.

A caller-supplied one is checked against base_image’s docker_ref: the two disagreeing builds against a base none of the measured platform behaviour applies to.

§binary: Vec<u8>

The daemon binary’s bytes, zipped into the artifact.

§project_files: Option<ProjectFiles>

The project’s dependency files — the lockfile plus its manifest — zipped into the artifact beside the Dockerfile, or None for an image with no environment layer.

This is what lets the derived Dockerfile’s install step (uv sync --locked, npm ci, cargo fetch per Ecosystem) see the files it installs from (#74). The entry names are fixed by the ecosystem; there is no way to put an arbitrary file into the shared snapshot through this field, which is the TRAP-5 property restated as a type.

§code_artifact_uri: String

Where the artifact is uploaded to. create_image does not upload: the caller puts the bytes there and passes the URI. crate::sandbox::Sandbox::ensure_image is the path that uploads for itself (services).

§build_role_arn: String

The build role, which must grant logs on /aws/lambda-microvms/*.

§size: SizeClass

The size class. Selects a documented baseline; it does not size the VM (TRAP-10).

§repair_guest_identity: bool

Whether to repair guest identity (TRAP-3).

§Why a bool and not a capability list

Measured 2026-08-06: without the capability, a guest running as root still gets EPERM from sethostname and from a bind mount over /proc/sys/kernel/random/boot_id, because the MicroVM drops CAP_SYS_ADMIN by default. Writing /etc/machine-id needs no capability and succeeds either way, which is what makes the gap easy to miss — identity repair looks like it works until you check the two steps that need the kernel’s permission rather than the filesystem’s.

Capability’s enum is exactly ["ALL"], so there is no way to ask for CAP_SYS_ADMIN alone. A list parameter would let a caller write ["CAP_SYS_ADMIN"] — the request AWS rejects after the artifact upload — so the intent is a boolean and the request injects ["ALL"] itself.

§inherit_workdir: bool

Whether the daemon should inherit the image’s WORKDIR.

Rejected when nothing declares one: most public ARM64 bases leave it empty, so the inheritance silently resolves to / and the symptom appears in the guest a build cycle later.

§run_hook_timeout: RunHookTimeout

The run-family hook timeout: run, resume, suspend, terminate. Caps at 60s, and the type is what keeps a build-sized value out of it.

§build_hook_timeout: BuildHookTimeout

The build-family hook timeout: ready, validate. Caps at 3600s.

§tags: BTreeMap<String, String>

Tags, or none.

§log_group: Option<String>

logging.cloudWatch.logGroup, or None for the service default — a service-created group under /aws/lambda-microvms/<image-name> with random stream names.

Checked against CloudWatchLoggingLogGroupString (1..=512, [a-zA-Z0-9_\-/.#]+) before the artifact upload. The build role must be able to write to whatever this names: the conformance account’s role grants logs only on /aws/lambda-microvms/*, so a group outside that prefix builds with no logs at all — the same failure mode as the wrong-prefix policy (docs/PLATFORM.md).

§log_stream: Option<String>

logging.cloudWatch.logStream — a stream-name prefix, never the exact name.

§The client always appends a per-build discriminator

The wire member is an EXACT stream name (prefixes unsupported — measured 2026-08, docs/PLATFORM.md ‘An image build is three VMs and three log streams’), and one build emits three streams. A fixed configured name collapses all three of every build into one stream, so ControlPlane::create_image sends <this>/<16 hex> with fresh CSPRNG per create attempt — the same mechanism as the clientToken nonce (TRAP-1) — and the resolved name comes back on image::Image::log_stream so the caller can find their logs.

Capped at crate::constants::MAX_USER_LOG_STREAM_LEN (495) so the resolved name fits the shape’s 512, and refused when it carries : or * (the pattern is [^:*]*). Requires Self::log_group: a stream inside a group the service chose randomly is a stream nobody can predict the location of.

§token_scope: Option<String>

A label folded into the create token for CloudTrail readability, defaulting to the image name. Not the token, and cannot become it (TRAP-1).

Implementations§

Source§

impl CreateImageRequest

Source

pub fn new( name: impl Into<String>, binary: Vec<u8>, code_artifact_uri: impl Into<String>, build_role_arn: impl Into<String>, ) -> CreateImageRequest

A request with the measured defaults: the al2023 base, the default size class, the derived Dockerfile, identity repair off, and 30-second hook timeouts.

The hook timeouts are expected rather than propagated because 30 is legal for both families by construction — it is below the run family’s 60s ceiling, which is the lower of the two — and a Result here would put a ? on every call site for a value this function chose itself.

Trait Implementations§

Source§

impl Clone for CreateImageRequest

Source§

fn clone(&self) -> CreateImageRequest

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CreateImageRequest

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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