pub struct PipelineRunner { /* private fields */ }Implementations§
Source§impl PipelineRunner
impl PipelineRunner
Sourcepub fn new(pipeline: Pipeline) -> Self
pub fn new(pipeline: Pipeline) -> Self
Local execution — steps run as subprocesses on this machine.
Sourcepub fn new_with_dispatcher(
pipeline: Pipeline,
dispatcher: Arc<dyn OutcomeDispatcher>,
) -> Self
pub fn new_with_dispatcher( pipeline: Pipeline, dispatcher: Arc<dyn OutcomeDispatcher>, ) -> Self
Local execution with a custom outcome dispatcher.
Sourcepub fn with_events(self, sink: UnboundedSender<QedEvent>) -> Self
pub fn with_events(self, sink: UnboundedSender<QedEvent>) -> Self
Attach a live-event sink (R325-F2). Composes with any constructor:
PipelineRunner::new(p).with_events(tx). The runner emits a
QedEvent for run start, each step start, every stdout/stderr line,
each step finish, and run finish. Send failures (no receiver) are
ignored — events are best-effort and never block the run.
Sourcepub fn with_dispatcher(self, dispatcher: Arc<dyn OutcomeDispatcher>) -> Self
pub fn with_dispatcher(self, dispatcher: Arc<dyn OutcomeDispatcher>) -> Self
Override the OutcomeDispatcher. Composes with any constructor —
notably new_remote, which defaults to the
log-only dispatcher, so a remote run can share the same publishing
dispatcher the local in-process path uses (R590-F2).
Sourcepub fn with_camp_root(self, root: PathBuf) -> Self
pub fn with_camp_root(self, root: PathBuf) -> Self
Override the camp root used to resolve per-camp catalog overrides and
the BuildKit cache + OCI archive output directories. Production
callers leave this unset (falls back to std::env::current_dir);
tests pass a tempdir so generated .yah/cache/ files don’t leak into
the workspace.
Sourcepub fn with_ref(self, ref: Option<String>) -> Self
pub fn with_ref(self, ref: Option<String>) -> Self
Set the target git ref for this run (W224, R330-B27) — a branch, tag,
or commit SHA; git checkout / git worktree add accept any
committish. Drives workspace positioning for gha-workflow steps per
the pipeline’s WorkspaceMode. None /
unset ⇒ HEAD (whatever is already checked out). Composes with any
constructor.
Sourcepub fn with_signer(self, signer: Arc<dyn SigstoreSigner>) -> Self
pub fn with_signer(self, signer: Arc<dyn SigstoreSigner>) -> Self
Attach a Sigstore signer (R407-T5). Composes with any constructor:
PipelineRunner::new(p).with_signer(Arc::new(CosignSigner::default())).
Release pipelines MUST call this with a real signer; the default
LoggingSigner writes placeholders so local yah qed run flows
don’t fail when cosign isn’t on PATH.
Sourcepub fn with_include_stubbed(self, include: bool) -> Self
pub fn with_include_stubbed(self, include: bool) -> Self
On-demand runner of status = "stubbed" steps (R506). When true,
the runner ignores the stubbed marker and runs the step normally.
enabled = false is still honored regardless. Composes with any
constructor: PipelineRunner::new(p).with_include_stubbed(true).
Sourcepub fn with_matrix_coord(self, coord: MatrixCoord) -> Self
pub fn with_matrix_coord(self, coord: MatrixCoord) -> Self
Bind the runner to a matrix coordinate (R506). Set by the planner
when fanning a pipeline over its [matrix] block — the coord shows
up as matrix.<key> in if= expressions. Composes with any
constructor.
Sourcepub fn new_remote(
pipeline: Pipeline,
scryer: Arc<Scryer>,
yubaba: Arc<dyn WardenClient>,
) -> Self
pub fn new_remote( pipeline: Pipeline, scryer: Arc<Scryer>, yubaba: Arc<dyn WardenClient>, ) -> Self
Remote execution — steps run as task::remote workloads dispatched via
the provided WardenClient.
Sourcepub fn new_auto(
pipeline: Pipeline,
scryer: Arc<Scryer>,
yubaba: Arc<dyn WardenClient>,
) -> Self
pub fn new_auto( pipeline: Pipeline, scryer: Arc<Scryer>, yubaba: Arc<dyn WardenClient>, ) -> Self
Policy-derived execution (R590-F4, the default yah qed run mode). Like
new_remote it wires a fleet dispatcher, but leaves
placement on RunWhere::Auto: local steps run as local subprocesses and
only a native = true cross-arch step (resolving to
Offload) is dispatched to an
arch-matched build-worker — no --where=remote flag required. The CLI
stands this up only when the pipeline actually needs offload (see
pipeline_needs_offload); a pipeline with no offload step stays on the
driverless local path.
Sourcepub fn with_executor(self, executor: Arc<dyn ForgeExecutor>) -> Self
pub fn with_executor(self, executor: Arc<dyn ForgeExecutor>) -> Self
Attach a custom ForgeExecutor for local subprocess steps
(R438-T14). Composes with any constructor. The default is
LocalForgeDriver; callers override to share a configured driver
across multiple runs.
Sourcepub fn with_sub_pipeline_resolver(
self,
resolver: Arc<dyn SubPipelineResolver + Send + Sync>,
) -> Self
pub fn with_sub_pipeline_resolver( self, resolver: Arc<dyn SubPipelineResolver + Send + Sync>, ) -> Self
Attach a SubPipelineResolver
for kind = "sub-pipeline" steps (R488-F2). Composes with any
constructor. The default resolver returns None for every target —
any SubPipeline step will fail with a clear “no resolver configured”
message until this is called. Production callers pass a
PipelineLoader-backed resolver;
tests pass an in-memory map.
Sourcepub fn with_release_providers(
self,
registry: Arc<ProviderRegistry>,
secrets: Arc<dyn SecretSource>,
) -> Self
pub fn with_release_providers( self, registry: Arc<ProviderRegistry>, secrets: Arc<dyn SecretSource>, ) -> Self
Wire the vendor release-provider registry + credential source (R509)
used to dispatch Outcome::Provider outcomes (notarize, authenticode,
sparkle, …). Composes with any constructor and is inherited by
SubPipeline children. The defaults are an empty registry + empty
secrets, so a pipeline with no vendor outcomes needs no wiring; a
pipeline that does declare one fails with a typed unknown-provider
error until this is called with a populated registry
(crate::provider::ProviderRegistry::production).
Sourcepub fn with_index_offset(self, offset: usize) -> Self
pub fn with_index_offset(self, offset: usize) -> Self
Offset added to every emitted step index. Use this when the
pipeline’s leading steps were drained for a resume-from-step run so
that events still carry the original positions (e.g. step 5 of 6
instead of step 0 of 1 after a drain(0..5)).
Sourcepub fn with_gha_matrix_subset(
self,
subset: HashMap<String, HashSet<String>>,
) -> Self
pub fn with_gha_matrix_subset( self, subset: HashMap<String, HashSet<String>>, ) -> Self
R499-F3 phase 2: per-step gha-workflow matrix subset. Each entry
maps a qed step name to the chosen instance keys (see
[yah_qed_gha::graph::JobInstance::key]). Steps absent from the map
run their full matrix. Inherited by SubPipeline children.
Sourcepub fn with_host_triple(self, triple: impl Into<String>) -> Self
pub fn with_host_triple(self, triple: impl Into<String>) -> Self
Override the self-detected host triple (R531-T1). Constructors default
to crate::platform::detect_host_triple (the process host); callers
that know the execution host differs — e.g. a daemon constructing a
runner whose steps will land on a remote runner of a known triple —
set it explicitly. Composes with any constructor.
Sourcepub fn with_cross_availability(self, avail: ToolAvailability) -> Self
pub fn with_cross_availability(self, avail: ToolAvailability) -> Self
Seed the host-native cross-toolchain availability (R531-T6) instead of
probing it. Tests use this to drive the NativeCross rewrite
deterministically; a daemon constructing a runner for a remote host of a
known toolchain set uses it to avoid a wrong local probe. Composes with
any constructor; takes effect only if set before the first
Self::cross_availability read.
Sourcepub fn host_triple(&self) -> &str
pub fn host_triple(&self) -> &str
The host triple this runner executes on (R531-T1, W222), e.g.
aarch64-apple-darwin. Threaded into the GHA runner.{os,arch}
context and (F2/F3) the host leg of each step’s Platform triple.
Sourcepub fn with_host_toolchains(
self,
detected: HashMap<String, Option<String>>,
) -> Self
pub fn with_host_toolchains( self, detected: HashMap<String, Option<String>>, ) -> Self
Seed the host’s detected toolchain versions (R507, W208) instead of
probing them. Tests drive the plan-time pinning check deterministically
with this; a daemon constructing a runner for a remote host of a known
toolchain set uses it to avoid a wrong local probe. Maps pin key →
detected version (None = tool absent). Takes effect only if set before
the first Self::host_toolchains read.
Sourcepub fn toolchain_preflight(&self) -> ToolchainPreflight
pub fn toolchain_preflight(&self) -> ToolchainPreflight
Plan-time toolchain pinning check (R507, W208 pillar 3): for every step,
overlay its toolchain.* overrides onto the pipeline-level
[toolchain] pins, then resolve each pin against the host’s detected
versions (or mark it image-provided). Pure given the (seeded or probed)
host versions — builds the verdict from the static pipeline, runs
nothing. The runner gates run() on
ToolchainPreflight::is_satisfied
and fails fast with its error report.
Sourcepub fn step_platform(&self, step: &QedStep) -> Platform
pub fn step_platform(&self, step: &QedStep) -> Platform
Compose a step’s full Platform triple-set
(R531-F2, W222): this runner’s self-detected host, the step’s declared
target (its [platform].target, falling back to the legacy per-kind
triple field), and the container_platform it pulls. This is the
value F3’s resolve(host, target, container_platform) decision table
reasons over.
Sourcepub fn resolve_step(&self, step: &QedStep) -> Resolution
pub fn resolve_step(&self, step: &QedStep) -> Resolution
Resolve how a step’s build is satisfied on this runner’s host (R531-F3,
W222): compose its Platform triple-set,
then run the cross-first decision table. Feeds the T4 portability
preflight and (P2) the container-seam wiring.
Sourcepub fn native_cross_plan(
&self,
step: &QedStep,
avail: &ToolAvailability,
) -> Option<Result<NativeCrossPlan, CrossToolUnavailable>>
pub fn native_cross_plan( &self, step: &QedStep, avail: &ToolAvailability, ) -> Option<Result<NativeCrossPlan, CrossToolUnavailable>>
Plan the host-native cross build for a step that resolves to the
NativeCross tier (R531-F5,
W222) — the concrete cargo-zigbuild / musl-cross invocation that should
replace the recipe’s cross build / bare cargo build argv.
Returns None for any step F3 does not resolve to NativeCross
(those go through emulate / cross-docker / offload, not this tier), and
for a NativeCross verdict with no concrete target (a plain host build
needs no rewrite). For an in-tier step it selects the toolchain against
avail and rewrites the step’s argv, yielding the emulation-free
plan (or a CrossToolUnavailable
carrying an install hint).
This is the seam T6 wires into the subprocess executor; F5 only defines
and tests it — run() does not yet route through it.
Sourcepub fn portability_preflight(&self) -> Vec<String>
pub fn portability_preflight(&self) -> Vec<String>
Portability preflight (R531-T4, W222): one rendered line per step
describing what it targets, the host it runs on, and the resolution
verdict — so an operator sees where mac and linux will diverge (and at
what cost) before the run. Pure: builds the lines from the static
pipeline, no execution. The index_offset is honored so a
resume-from-step run still shows original step positions.
Sourcepub fn run_id(&self) -> &str
pub fn run_id(&self) -> &str
The run id assigned at construction. Lets a caller (e.g. the camp
daemon’s qed.run handler) register a run as Running before
Self::run completes, so qed.status can observe it in flight.
pub async fn run(&self) -> Result<QedRunMeta, RunnerError>
Sourcepub async fn resume_terminal_publish_for_remote_step(
&self,
step_index: usize,
forge_id: &ObsForgeId,
) -> Result<(), RunnerError>
pub async fn resume_terminal_publish_for_remote_step( &self, step_index: usize, forge_id: &ObsForgeId, ) -> Result<(), RunnerError>
R603-T4: replay the terminal publish for a remote step that finished
while the camp daemon was down. The boot reconciler
(camp.rs::finalize_reconciled_run) rebuilds a fleet-wired runner and
calls this once it confirms the persisted yubaba workload reached a
terminal Success — retrieving the artifact the build produced off the
(possibly already-exited) build-worker and pushing it through the same
on_success outcome chain a live run would have fired.
step_index is the pipeline-local index of the remote step whose
produces we retrieve; forge_id is the persisted workload identity
(the bare ObsForgeId uuid — the mesh forge.<uuid> prefix is derived
internally by retrieve_remote_artifacts).
Best-effort on the retrieval leg: kamaji reaps exited containers, so a
build that finished during the outage may be un-retrievable. This
surfaces that as a RunnerError (which the caller renders as “artifact
reaped, re-run”) rather than silently claiming published. The robust fix
— the build writing its tar to a durable host volume so retrieval
survives reaping — is tracked as follow-up (see the ticket’s reaping-
window fork).
Auto Trait Implementations§
impl !Freeze for PipelineRunner
impl !RefUnwindSafe for PipelineRunner
impl !UnwindSafe for PipelineRunner
impl Send for PipelineRunner
impl Sync for PipelineRunner
impl Unpin for PipelineRunner
impl UnsafeUnpin for PipelineRunner
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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 more