OXYGENHUB
# c23d519168d8 oxygenflow / crates / flow-core / src / api.rs
2.8 KiB · Rust · last changed Pinned subrepos in job workspaces: the claim lists them, the runner fetches each with the job token and exports its pinned state at its path, inside the scope hash 1 month ago source blame history raw
1
//! The runner API between OxygenHub and `flow runner` (docs/m0.md §5).
2
//! Both sides use these types, so they cannot drift.
3
4
use crate::pipeline::{Job, Sandbox};
5
use crate::receipt::Receipt;
6
use serde::{Deserialize, Serialize};
7
8
/// `POST /api/v1/flow/claim`.
9
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
10
pub struct ClaimRequest {
11
    /// The runner's name, shown on job pages.
12
    pub runner: String,
13
    /// Tiers this runner can run (`microvm`, `syscall`).
14
    pub runtimes: Vec<String>,
15
}
16
17
/// A pinned subrepo to put in the workspace: `repo`'s state `heads`, at `path`.
18
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
19
pub struct SubrepoInput {
20
    pub path: String,
21
    /// `owner/name` on the hub.
22
    pub repo: String,
23
    pub clone_url: String,
24
    pub heads: Vec<String>,
25
}
26
27
/// A claimed job: everything the runner needs, nothing more.
28
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
29
pub struct Claim {
30
    pub job_id: i64,
31
    pub run_id: i64,
32
    /// `owner/name`.
33
    pub repo: String,
34
    /// Where to fetch the repository from (`oxy` wire protocol).
35
    pub clone_url: String,
36
    /// Read access to this repository only, until the job finishes.
37
    pub token: String,
38
    /// The state to build, as full change hashes.
39
    pub heads: Vec<String>,
40
    /// Hex BLAKE3 of the canonical pipeline.
41
    pub pipeline_hash: String,
42
    pub job: Job,
43
    pub sandbox: Sandbox,
44
    /// The hub's limit for this job.
45
    pub timeout_s: u64,
46
    /// Subrepos the state pins (Oxygen spec §7.8) that the job may read,
47
    /// fetched with the same token and written at their paths.
48
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
49
    pub subrepos: Vec<SubrepoInput>,
50
}
51
52
/// One line of output (docs/m0.md §2).
53
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
54
pub struct Record {
55
    /// Milliseconds since the job started.
56
    pub t: u64,
57
    /// `out`, `err`, `console` (the VM outside the job) or `flow` (the runner).
58
    pub stream: String,
59
    pub text: String,
60
}
61
62
/// `POST /api/v1/flow/jobs/{id}/log`.
63
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
64
pub struct LogBatch {
65
    pub records: Vec<Record>,
66
}
67
68
/// `POST /api/v1/flow/jobs/{id}/finish`.
69
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
70
pub struct Finish {
71
    /// The job's exit code; absent when the runner could not run it.
72
    pub exit_code: Option<i32>,
73
    pub duration_ms: u64,
74
    pub receipt: Option<Receipt>,
75
    /// Why the runner could not run the job (rootfs missing, VM failed).
76
    pub error: Option<String>,
77
}
78
79
/// Longest text of one record the hub keeps; longer lines are cut.
80
pub const MAX_RECORD_TEXT: usize = 16 * 1024;
81
/// Most records the hub keeps per job; later ones are dropped with a note.
82
pub const MAX_RECORDS: usize = 50_000;