Skip to main content

Crate solti_model

Crate solti_model 

Source
Expand description

§solti-model

Shared resource model for Solti agents and control planes.

This crate defines task resources, workloads, policies, selectors, queries, output events, capabilities, and bearer tokens. It does not execute tasks or own resource storage.

§Start Here

Use TaskManifest for caller-owned desired state. Use Task for a stored resource with server metadata and status. Use TaskSpec to describe execution. Use TaskWorkload to select a built-in or extension workload.

§Resource Flow

caller
  │ TaskManifest
  ▼
Task::from_manifest ── generates uid and creationTimestamp
  │                   └─ starts generation at 1
  ▼
Task
  ├── metadata: ObjectMeta
  ├── spec:     TaskSpec
  ├── status:   TaskStatus
  │
  └── state store assigns resourceVersion

The model validates values and applies state transitions. Storage, reconciliation, execution, and transport stay in higher layers.

§Features

The default schema feature implements schemars::JsonSchema for resource, workload, selector, capability, and output types. Disable default features when schema generation is not needed. Runtime validation remains authoritative for cross-field and byte-budget rules.

§Quick Start

Build a task spec:

use solti_model::{
    Flag, SubprocessMode, SubprocessSpec, TaskEnv, TaskSpec, TaskWorkload,
};

let workload = TaskWorkload::Subprocess(SubprocessSpec::new(
    SubprocessMode::Command {
        command: "echo".into(),
        args: vec!["hello".into()],
    },
    TaskEnv::default(),
    None,
    Flag::enabled(),
));

let spec = TaskSpec::builder("hello", workload, 5_000u64)
    .build()
    .expect("valid spec");

spec.validate().expect("valid spec");
assert_eq!(spec.slot().as_str(), "hello");

Create a stored task resource:

use solti_model::{EmbeddedSpec, Task, TaskPhase, TaskSpec, TaskWorkload};

let workload = TaskWorkload::Embedded(EmbeddedSpec::new("v1").unwrap());
let spec = TaskSpec::builder("cleanup", workload, 1_000u64)
    .build()
    .unwrap();

let task = Task::new("embedded-cleanup-1", spec).unwrap();

assert_eq!(*task.phase(), TaskPhase::Pending);
assert_eq!(task.name().as_str(), "embedded-cleanup-1");

TaskWorkload::Embedded is valid in the shared model. API and runner layers apply their own admission rules.

§Resource Model

Task
  apiVersion, kind
  metadata: ObjectMeta
  spec:     TaskSpec
  status:   TaskStatus

TaskSpec
  slot, workload, timeout, restart, backoff, admission
  max_retries, runner_selector

TaskStatus
  observed_generation, conditions, phase, attempt, exit_code, error

TaskSpec is desired state. TaskStatus is observed state. ObjectMeta carries identity, versions, labels, annotations, and timestamps.

§Lifecycle

Pending ──▶ Running ──▶ Succeeded
            ├────────▶ Failed
            ├────────▶ Timeout
            └────────▶ Canceled

Failed | Timeout ── retry budget exhausted ──▶ Exhausted

Terminal phases are Succeeded, Failed, Timeout, Canceled, and Exhausted. See TaskPhase::is_terminal.

§Task Workloads

TaskWorkload describes what a task runs:

KindMeaningRouted by runner
SubprocessHost command or scriptyes
ContainerOCI imageyes
WasmWASI moduleyes
EmbeddedIn-process taskno
ExtensionApplication-definedyes

Routable variants are consumed by solti-runner. Embedded workloads bypass runner routing.

§Selectors

LabelSelector matches runner labels. All requirements are ANDed:

use solti_model::{Labels, LabelSelector, SelectorRequirement};

let selector = LabelSelector {
    match_labels: {
        let mut labels = Labels::new();
        labels.insert("zone", "eu");
        labels
    },
    match_expressions: vec![SelectorRequirement::exists("gpu")],
};

let mut runner = Labels::new();
runner.insert("zone", "eu");
runner.insert("gpu", "h100");

assert!(selector.matches(&runner));

§Auth

Token wraps a bearer secret. Its Debug output is redacted. Token::verify uses a constant-time comparison for equal-length values.

§Main Types

§See Also

  • solti-runner consumes TaskSpec and TaskWorkload to build executable tasks.
  • solti-core manages Task lifecycle and state transitions.
  • solti-api serializes model types over gRPC and HTTP.

Structs§

AgentCapabilities
Immutable snapshot of agent execution capabilities.
AgentId
Caller-provided identifier for a Solti agent.
Annotations
Key-sorted, free-form resource metadata.
BackoffPolicy
Exponential backoff configuration for task restart delays.
ContainerSpec
Specification for OCI-compatible container execution.
EmbeddedSpec
Desired state of an embedded task implementation.
ExtensionWorkload
GVK envelope for an application-provided workload.
Flag
Boolean flag with explicit enable/disable constructors.
KeyValue
Key-value pair used for environment variables or generic metadata.
LabelSelector
Label selector for matching any labeled object.
Labels
Structured key-value metadata based on BTreeMap.
LabelsIter
Iterator over Labels yielding (&str, &str) pairs.
ObjectMeta
Identity, concurrency version, generation and user metadata for a task.
OutputChunk
Output bytes from one task run.
RunnerCapability
One registered runner and the workload GVKs it can execute.
SelectorRequirement
Single set-based requirement for label matching.
Slot
Logical identifier for a controller slot.
SubprocessSpec
Specification for subprocess execution on the host.
Task
Stored Task resource.
TaskCondition
One observed condition for a Task resource.
TaskConditionType
Stable and extensible type of condition reported for a Task.
TaskContinuation
Position of the next page in one Task collection snapshot.
TaskEnv
Environment variables passed to a task at submission time.
TaskFilter
Filters shared by task list and watch operations.
TaskId
Stable name used to address a task resource.
TaskManifest
Caller-owned desired state for create and apply.
TaskManifestMeta
User-owned metadata accepted in a TaskManifest.
TaskPage
One page from a Task collection snapshot.
TaskQuery
Query parameters for filtered, snapshot-consistent Task listing.
TaskRun
Record of one execution attempt.
TaskSpec
Desired state for a task.
TaskSpecBuilder
Builder for TaskSpec.
TaskStatus
Observed runtime state of a task.
Timeout
Timeout value in milliseconds.
Token
Validated bearer token.
TypeMeta
Group/version and kind of resource schema.
Uid
Opaque, server-assigned identity of one resource incarnation.
WasmSpec
Specification for WebAssembly module execution via a WASI-compatible runtime.
WorkloadTypeMeta
Group/version and kind of one workload schema.
WritePreconditions
Optional identity and version checks for a resource write.

Enums§

AdmissionPolicy
Admission behavior for a busy slot.
ConditionStatus
Condition status.
DesiredChange
Classification of an apply operation.
JitterPolicy
Jitter applied to a backoff delay.
ModelError
Error type for parsing and validating model values.
OutputEvent
Event in a task live-output stream.
RestartPolicy
Policy for starting another attempt.
SelectorOperator
Set-based operator for super::SelectorRequirement.
StreamKind
Standard stream that produced a chunk.
SubprocessMode
Execution strategy for a subprocess task.
TaskPhase
Current execution phase of a task.
TaskWatchEvent
One change emitted by a task watch.
TaskWorkload
Executable desired state nested in a TaskSpec.

Constants§

AGENT_ID_MAX_LEN
Maximum length of an AgentId.
DEFAULT_LIMIT
Default page size when the caller does not specify one.
MAX_LIMIT
Hard cap on page size.
MAX_SCRIPT_BODY_BYTES
Maximum decoded script body size.
SLOT_MAX_LEN
Maximum length of a Slot identifier.
TASK_API_VERSION
API group and version of the built-in Task resource.
TASK_API_VERSION_MAJOR
Major version of the built-in Task resource API.
TASK_ID_MAX_LEN
Maximum length of a TaskId.
TASK_KIND
Kind of the built-in Task resource.
WORKLOAD_API_VERSION
API group and version of built-in Solti workloads.

Type Aliases§

ModelResult
Convenience alias for Result<T, ModelError>.