Skip to main content

Crate cargo_athena

Crate cargo_athena 

Source
Expand description

cargo-athena — compile regular Rust into Argo Workflow YAML.

This facade is the only crate users depend on. It re-exports the runtime (cargo_athena_core) and the proc macros (cargo_athena_macros) behind one stable ::cargo_athena path, which is also the path the generated code targets.

use cargo_athena::{workflow, container};   // `host!` is used path-qualified

#[workflow]
fn run_foo() {
    let a = some_other_workflow("asdf".to_string());
    run_a_container(a);
}

#[container(image = "ghcr.io/acme/app:latest")]
fn run_a_container(a: String) {
    let cfg = cargo_athena::host!("/etc/myapp");  // -> hostPath volume; compile error outside #[container]/#[fragment]
    println!("{cfg} {a}");
}

// entrypoint is a *type*; referencing it force-links the closure.
fn main() { cargo_athena::entrypoint!(run_foo); }

Modules§

api
Argo Workflows API types — a hand-owned, curated subset.
inventory
githubcrates-iodocs-rs
rt
Runtime shims referenced by the declaration macros. Artifact ports are plain files at fixed paths; Argo moves them (no S3 from us).
serde_json
Serde JSON
serde_norway
![github]![crates-io]![docs-rs]

Macros§

entrypoint
User-facing entrypoint. Captures the calling binary’s identity (CARGO_PKG_NAME/CARGO_PKG_VERSION/CARGO_BIN_NAME) at the user binary’s compile time and threads it into entrypoint_impl so the emitted S3 artifact key ({crate}/<tag>/{bin}.tar.gz) matches what cargo athena publish uploads. Use as cargo_athena::entrypoint!(MyRootWorkflow).
host
host!("/lit/path") — declare a hostPath volume for the enclosing container, evaluating to the (already-mounted) path at runtime.
load_artifact
Declare an Argo input artifact port and read it (bytes) at runtime. See the host! doc for the gate / LSP-stub pattern shared by every decl macro.
load_artifact_str
Declare an Argo input artifact port and read it (UTF-8) at runtime.
pvc
Mount a PVC of type T (a unit struct that implements Pvc via #[ephemeral_pvc] or #[external_pvc]) on this container’s pod, and evaluate to the (already-mounted) path — &'static Path, picked deterministically from the type’s Pvc::MOUNT_PATH so emit-side and in-pod always agree.
save_artifact
Declare an Argo output artifact port and write bytes to it at runtime.
save_artifact_str
Declare an Argo output artifact port and write a string at runtime.
secret
Declare a K8s Secret-sourced env var and read it back at runtime as a String. Two literal args: (secret_name, key). Panics at runtime if the env var the macro plants isn’t set; pair with secret_opt! for the no-panic variant.
secret_opt
Same as secret! but returns Option<String> and emits optional: true on the Argo secretKeyRef — Argo skips the env entry instead of failing pod-start when the secret/key is missing.

Structs§

Artifact
A DAG-wired S3-backed value. Wrap a #[container] (or #[workflow]) return in Artifact<T> to flow the value via Argo’s native artifact passing (outputs.artifacts.return + arguments.artifacts.from) instead of the inline-parameter path (outputs.parameters.return). Lifts the parameter-size ceiling and is the natural shape for binary/large payloads. A consumer accepting Artifact<T> reads the same value on the other side; the wire is the user’s serialized T (JSON, tar+gzip’d by Argo on the producer and untarred on the consumer, transparent to user code).
ArtifactRef
One artifact bound into the container at path, backed by S3.
ArtifactRepository
AthenaConfig
athena.toml — required by cargo athena at emit time. Mirrors the parts of Argo’s S3 ArtifactRepository we inject, plus bootstrap config.
Bootstrap
BuildCtx
Fragment registry snapshot, passed to container builds.
Collector
Accumulates the reachable templates (as WorkflowTemplates) and the run-mode dispatch table while Template::collect walks the closure.
ContainerDelivery
What container_delivery produces for one #[container] template.
ContainerRunMeta
Purpose-built introspection of one #[container], derived from the same Template::build() emit uses (so it never drifts), but expressed in the runner’s vocabulary instead of Argo’s. Emitted as JSON by the binary when CARGO_ATHENA_DESCRIBE=<name> is set; consumed by cargo athena emulate to realize the spec under docker/podman locally, and by cargo athena describe.
Defaults
FragmentReg
A #[fragment]: a plain helper carrying host! decls. Still inventory-based — a container’s real body actually calls its fragments, so the symbol reference exists and DCE is not a concern.
ParamRef
An input parameter and its stringified Rust type ("" if unknown, e.g. synthetic templates). The position in the enclosing params vector is the positional argv slot the parameter occupies in-pod.
ProbeInfo
What a cargo-athena binary reports in CARGO_ATHENA_PROBE mode: a handshake the CLI uses to (a) confirm the executable really is a cargo-athena binary, (b) detect CLI/binary version skew, and (c) learn the default/root template (so the workflow argument is optional). Produced with NO athena.toml (no BuildCtx::collect): works source-free / config-free.
PvcReg
Inventory-registered PVC spec, submitted by every #[ephemeral_pvc] and #[external_pvc]. BuildCtx::collect loads them all into a argo_name → PvcReg map so emit-side code can materialize the full PVC spec from just a name string (which is what fragment closures propagate).
S3Ref
Resolved S3 coordinates for one artifact (creds are supplied locally, e.g. via AWS env vars - cargo athena emulate uses object_store; the in-cluster path uses the k8s Secret refs).
S3Repo
SecretRef

Enums§

IoKind
How a single Argo input or output flows: inline as a parameter (Argo stores it in workflow status, sized like a JSON parameter) or via S3 as an artifact (DAG-wired via outputs.artifacts / arguments.artifacts.from). The #[container] and #[workflow] macros derive these per-slot from the function signature: a fn argument or return type of cargo_athena::Artifact<T> is Artifact, everything else is Parameter. Stamped into Template::INPUT_KINDS / Template::OUTPUT_KIND and read at emit-time by the workflow’s per-task wiring (parallel to how Template::INPUTS is read for parameter names).
PvcLifecycle
PVC lifecycle, exposed via Pvc::LIFECYCLE.
TemplateKind
What kind of Argo template a type produces.

Constants§

ATHENA_BIN_DIR
Where Argo’s executor (init container) extracts the per-arch binaries from our .tar.gz input artifact. We rely on Argo’s built-in tarball auto-extraction (no archive: none, no tar in the main container’s image — see container_delivery).
ATHENA_DIR
Pod-scoped scratch root, backed by an emptyDir on every container template so all athena paths are writable regardless of the image (distroless / read-only rootfs) and shared with Argo’s init/wait containers for artifact load/collect.
ATHENA_DIST_ARTIFACT
Argo input-artifact name of the binary tarball emit injects.
ATHENA_INPUT_ARTIFACT_DIR
Where an Artifact<T>-typed input lands inside the container, one file per arg, named after the arg. The template declares inputs.artifacts[].path = "/athena/in/<name>"; the run-side body reads + deserializes from there.
ATHENA_MOUNTS_DIR
In-pod root for host!("/p") mounts — the macro never lets the user pick the in-container path (host!("/") would otherwise overlay the host root over the container fs). Each host! lands at <this>/<fnv-hex-of-literal>.
ATHENA_PROBE_KIND
Fixed marker in a ProbeInfo response (the kind field). Lets a consumer positively identify a cargo-athena binary and reject stray stdout from a non-athena executable with a clear error, rather than an opaque deserialization failure.
ATHENA_PROTOCOL
Wire-format version of the binary’s metadata modes (PROBE / LIST / DESCRIBE / EMIT_JSON). The cargo athena CLI checks this on PROBE before trusting the other modes. Bump ONLY on a breaking change to those JSON shapes, NOT on every release, so an older CLI keeps working with a newer binary at the same protocol. Within one release line, a ProbeInfo struct mismatch at a matching protocol means the workflow binary’s library and the CLI were built from different cargo-athena versions (a dev path-dependency skew) — BinarySource::probe names that precisely rather than failing an opaque deserialize.
ATHENA_PVCS_DIR
In-pod root for pvc!(Type) mounts. Same shape as ATHENA_MOUNTS_DIR: each PVC lands at <this>/<fnv-hex-of-argo- name>, never at a user-chosen path, so two crates declaring the same explicit PVC name can’t accidentally overlay each other’s directories.
ATHENA_RESULT_ARTIFACT_FILE
Where an artifact-output #[container] body writes its serialized return value (read by the template’s outputs.artifacts.return.path, then tar+gzip’d and uploaded by Argo’s executor). The bootstrap exports this as CARGO_ATHENA_OUTPUT for artifact-output templates; the run-side body has one write site (CARGO_ATHENA_OUTPUT) and stays kind-agnostic.
ATHENA_RESULT_FILE
Where a parameter-output #[container] body writes its serialized return value (read by the template’s outputs.parameters.return.valueFrom.path). The bootstrap exports this as CARGO_ATHENA_OUTPUT for parameter-output templates.
CARGO_ATHENA_TEMPLATE_ENV
Env var the in-pod entrypoint reads to pick which container template to run. Argv (positional, in INPUTS order) carries the function’s own parameters.
SCRATCH_VOLUME
Name of the scratch emptyDir volume.

Traits§

AthenaList
Fan-out: list.fan_out(|x| template(x, ..)) runs template once per element (Argo withParam); the binding is the aggregated Vec<U> of the per-element returns. This trait exists only so the ghost type-checks the element type, the closure, and the resulting Vec<U>; the macro lowers the call to Argo and it never runs.
Pvc
The cross-crate identity of a PVC, implemented by the unit struct #[ephemeral_pvc] / #[external_pvc] generates.
Template
The cross-crate identity of a template, implemented by the unit struct the #[workflow]/#[container] macros generate.

Functions§

artifact_inputs
load_artifact!("key") input ports: Argo pulls the exact S3 object key from the configured repo into the pod (raw, archive: none).
artifact_outputs
save_artifact!("key") output ports: Argo pushes the written file to the exact S3 object key in the configured repo (raw, archive: none).
container_delivery
The arch-resolving bootstrap + the S3 binary artifact for one container template. Called from macro-generated Template::build (emit only).
container_volumes
Every container template’s volumes/mounts: the always-present emptyDir scratch at ATHENA_DIR + the declared hostPaths. Two hostPath sources:
entrypoint_impl
The entrypoint a user’s main calls, parameterised by the root workflow type. Referencing E force-links the entire reachable closure (each collect calls callees’ collect directly).
host_mount_path
In-pod mount path for a host!("/p") literal.
host_path_volumes
volumes + volumeMounts for a set of hostPaths (from host!). Each mounts at host_mount_path (/athena/mounts/<munged>), NOT at the host’s own path — safe-by-construction.
is_container_run
true if this binary is dispatching a container body (in-pod, started by Argo via the emitted bootstrap); false for every other mode (cargo athena emit / ls / describe / submit-emit-JSON).
kebab
<crate>-<fn> argo names: lowercases, swaps _ for -, trims leading/trailing - so that idiomatic Rust names like fn _unused_helper() or fn foo_() don’t produce DNS-1123-invalid Argo template names (-foo / foo-, both rejected by k8s). Internal __ becomes -- and is kept (valid).
pvc_mount_path
In-pod mount path for a PVC, keyed on its argo name.
pvc_volume_name
K8s Volume name for a PVC mount. pvc- (4) + 16 hex = 20 chars, fits DNS-1123.
s3_loc
Build an Argo S3 location (artifact-repository creds from athena.toml) for an exact object key.
secret_env_name
Pod env var name a secret!/secret_opt! decl gets. Derived deterministically from the K8s (secret_name, key) pair so the emit-side (declares the matching secretKeyRef envFrom) and the run-side (reads via std::env::var) agree. Uppercased, non- alphanumerics flattened to _, halves separated by __ to stay distinguishable.
service_account
Resolve a container template’s ServiceAccount: the #[container(service_account=...)] override, else [defaults].
wrap_workflow_template
Wrap one inner Argo template as a standalone WorkflowTemplate whose resource name == the inner template name == its entrypoint.

Type Aliases§

TolerationTuple
(key, operator, value, effect, toleration_seconds) — the lowered shape the macro produces for each toleration entry, threaded through Template::TOLERATIONS_IF_ROOT and into WorkflowSpec.Tolerations by Collector::stamp_spec.

Attribute Macros§

container
#[container]
ephemeral_pvc
Declare a transient (per-workflow-run) PersistentVolumeClaim type. Apply to a pub struct Foo; (unit struct, no fields, no generics); athena emits an impl Pvc for Foo and a WorkflowSpec.volume_claim_templates[] entry on every workflow in the binary, so Argo creates the PVC at run start and deletes it at run end. Mount with pvc!(Foo) inside a #[container] / #[fragment].
external_pvc
Declare a reference to a pre-existing PersistentVolumeClaim in the workflow’s namespace. Apply to a pub struct Foo;. Mount with pvc!(Foo). The PVC must already exist; athena emits no volume_claim_templates entry.
fragment
A plain helper function (not a template) that carries pod-resource declarations (host!, artifact ports) across function boundaries into every #[container] that transitively calls it. It runs as ordinary Rust inside the caller’s pod and cannot be called from a #[workflow]. See the #[fragment] section of the container docs (CONTAINER.md) for the full model.
workflow
#[workflow]