Skip to main content

Workload

Enum Workload 

Source
pub enum Workload {
    MesofactStatic(MesofactStaticWorkload),
    Container(ContainerManifest),
    Almanac(AlmanacManifest),
    StaticAsset(StaticAssetWorkload),
}
Expand description

On-disk workload.toml manifest. Each variant matches one ServiceComponent.kind value; the kind field on the wire is the serde discriminator.

This is the on-disk envelope — distinct from WorkloadSpec, the containerd wire format yubaba receives over RPC. A kind = "container" workload deserializes its remaining fields as a ContainerManifest, which is either a digest-pinned WorkloadSpec or a local Dockerfile recipe (R783-F1 / W324); other kinds carry their own per-reconciler payload shape.

Never put #[serde(skip_serializing_if = "Option::is_none")] on a field of this enum or any type it reaches. These types ride the kamaji-proto postcard wire, which is non-self-describing and positional: skip_serializing_if omits the field’s byte on serialize while decode still expects to read it at that offset, so the byte stream misaligns and the round-trip fails. Use #[serde(default)] + #[ts(optional = nullable)] instead — that still gives TOML/JSON back-compat (missing field → None) while the field is always encoded. MesofactStaticWorkload::ssr_runtime and ::serve_bundle are the reference shape. Two wire shapes, one type (R546-B7). Serialize/Deserialize are hand-written and branch on is_human_readable:

  • TOML/JSON (human-readable)internally tagged on kind, i.e. the flat shape every on-disk workload.toml actually uses (kind = "static-asset" beside schema_version, [[asset]], [aliases]).
  • postcard (binary)externally tagged, byte-identical to the derived representation R590-B3 established for the kamaji UDS.

Why not just #[serde(tag = "kind")]: internal tagging buffers through deserialize_any, which postcard (non-self-describing) refuses with WontImplement — that is exactly the failure R590-B3 fixed by flipping this enum to external tagging. But external tagging wants a single-key map, so every flat on-disk file then failed with wanted exactly 1 element, more than 1 element and yah cloud apply broke for every static-asset component. Branching on the format satisfies both, and mirrors what ImageRef already does for its string-vs-struct form.

Variants§

§

MesofactStatic(MesofactStaticWorkload)

Static-site build that publishes an artifact directory to the service’s static provider slot. Reconciled by the mesofact-static reconciler — does not deploy to yubaba.

§

Container(ContainerManifest)

A container-shaped workload. Two on-disk forms (R783-F1 / W324), see ContainerManifest: a digest-pinned WorkloadSpec reference (the form that crosses the kamaji wire) or a local Dockerfile ContainerBuild recipe (which cannot, because it names no digest until it has been built).

Construct the wire form with Workload::container and read it back with Workload::container_spec — most callers only ever mean the reference form and should not have to name the manifest enum.

The reference form’s inline fields are the full WorkloadSpec minus the kind discriminator.

This is also the shape of the W267 sovereign-public-ingress appliance (R594-F2): a container-kind workload with archetype = Some(LifecycleArchetype::Appliance) and requires_taint() == Some(PUBLIC_IP_TAINT), not a dedicated Workload::ingress(..) variant. It runs an ordinary OCI image (the passway proxy, R594-F4) supervised by kamaji exactly like any other Container, so no admission-list or wire-codec change was needed to let kamaji accept it. A new enum variant would have forced an exhaustive-match update in every Workload consumer, including peer-owned kamaji-proto/src/codec.rs — the archetype + annotation combination expresses “this is the public ingress appliance” without that blast radius. See WorkloadSpec::requires_taint and LifecycleArchetype::Appliance.

§

Almanac(AlmanacManifest)

Data-pipeline job with declared I/O and a readiness policy. The orchestrator checks all inputs are reachable before each run and verifies outputs afterward. Generalises the OpenRouter JSON-cache refresher (spawn_almanac_refresher) to the full manifest form.

§

StaticAsset(StaticAssetWorkload)

Content-addressed static files uploaded to the mirror’s object_store provider slot. Wave-0 by default — gating mesofact and container waves. Rollback is a pointer-flip via mirror.toml [asset_aliases]; bytes are append-only and never re-pushed on rollback. See W160.

Implementations§

Source§

impl Workload

Source

pub fn kind_str(&self) -> &'static str

The kind discriminator this variant serializes as — the same string a workload.toml writes and a ServiceComponent.kind names.

Lives here rather than at a call site because this enum now has FIVE places that enumerate its variants (itself plus the four tagging mirrors below); a caller-local match would be a sixth, in another crate, with nothing to force it to keep up.

Source

pub fn container(spec: WorkloadSpec) -> Self

Wrap a digest-pinned WorkloadSpec as a kind = "container" workload — the form that crosses the kamaji wire.

Every caller that synthesizes a container workload in code (ingress appliances, forge runs, kamaji’s own deploy path) means this form; the ContainerManifest::Recipe arm only ever arrives by parsing a workload.toml with a [build] table. Keeping the constructor here means R783-F1 did not have to teach ~25 call sites the name of a manifest enum they have no opinion about.

Source

pub fn container_spec(&self) -> Option<&WorkloadSpec>

The digest-pinned spec of a kind = "container" workload, if this is a container workload in the reference form.

None covers both “not a container” and “a container recipe, which has no spec until it is built” — a consumer that speaks the wire (kamaji, yubaba’s deploy path) must treat both as inadmissible, so collapsing them into one None is deliberate rather than lossy. Use Workload::container_manifest when the two need distinguishing.

Source

pub fn container_manifest(&self) -> Option<&ContainerManifest>

The container manifest, in whichever on-disk form it was written.

Trait Implementations§

Source§

impl Clone for Workload

Source§

fn clone(&self) -> Workload

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 Workload

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Workload

Source§

fn deserialize<D>(de: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Workload

Source§

fn eq(&self, other: &Workload) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Workload

Source§

fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Workload

Source§

impl TS for Workload

Source§

type WithoutGenerics = Workload

If this type does not have generic parameters, then WithoutGenerics should just be Self. If the type does have generic parameters, then all generic parameters must be replaced with a dummy type, e.g ts_rs::Dummy or ().
The only requirement for these dummy types is that EXPORT_TO must be None. Read more
Source§

type OptionInnerType = Workload

If the implementing type is std::option::Option<T>, then this associated type is set to T. All other implementations of TS should set this type to Self instead.
Source§

fn ident(cfg: &Config) -> String

Identifier of this type, excluding generic parameters.
Source§

fn docs() -> Option<String>

JSDoc comment to describe this type in TypeScript - when TS is derived, docs are automatically read from your doc comments or #[doc = ".."] attributes
Source§

fn name(cfg: &Config) -> String

Name of this type in TypeScript, including generic parameters
Source§

fn decl_concrete(cfg: &Config) -> String

Declaration of this type using the supplied generic arguments. The resulting TypeScript definition will not be generic. For that, see TS::decl(). If this type is not generic, then this function is equivalent to TS::decl().
Source§

fn decl(cfg: &Config) -> String

Declaration of this type, e.g. type User = { user_id: number, ... }. This function will panic if the type has no declaration. Read more
Source§

fn inline(cfg: &Config) -> String

Formats this types definition in TypeScript, e.g { user_id: number }. This function will panic if the type cannot be inlined.
Source§

fn inline_flattened(cfg: &Config) -> String

Flatten a type declaration. This function will panic if the type cannot be flattened.
Source§

fn visit_generics(v: &mut impl TypeVisitor)
where Self: 'static,

Iterates over all type parameters of this type.
Source§

fn output_path() -> Option<PathBuf>

Returns the output path to where T should be exported, relative to the output directory. The returned path does not include any base directory. Read more
Source§

fn visit_dependencies(v: &mut impl TypeVisitor)
where Self: 'static,

Iterates over all dependency of this type.
Source§

fn dependencies(cfg: &Config) -> Vec<Dependency>
where Self: 'static,

Resolves all dependencies of this type recursively.
Source§

fn export(cfg: &Config) -> Result<(), ExportError>
where Self: 'static,

Manually export this type to the filesystem. To export this type together with all of its dependencies, use TS::export_all. Read more
Source§

fn export_all(cfg: &Config) -> Result<(), ExportError>
where Self: 'static,

Manually export this type to the filesystem, together with all of its dependencies. To export only this type, without its dependencies, use TS::export. Read more
Source§

fn export_to_string(cfg: &Config) -> Result<String, ExportError>
where Self: 'static,

Manually generate bindings for this type, returning a String. This function does not format the output, even if the format feature is enabled. 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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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