Skip to content

Commit de77cbe

Browse files
authored
fix(orion): reclaim Antares overlays and reject builds under disk pressure (#2150)
* fix(orion): return all tasks for a CL instead of Multiple tasks GET /v2/task/{cl} now returns Vec<OrionTaskDTO> (empty when none), so repeated pushes no longer break Checks. Also document regenerating gitmono.json / generated.ts via moon/script/gen-client, and bump tokio-stream to 0.1.19. * fix(orion): reclaim Antares overlays and reject builds under disk pressure Prevent long-lived VMs from filling the guest root FS (which drops WebSocket heartbeats and marks workers Lost) by deleting upper/cl after umount, pruning orphans on runner start, and refusing TaskBuild when usage exceeds the reject threshold. Also raise default image_disk_gb to 50. * feat(orion): stream runner startup logs to the /oc UI Proxy orion-scheduler's /logs/orion/stream through mono as admin-only SSE, and show live provision/startup output on the Orion Clients page after Start Runner. * fix(orion): drop DashMap guard before await on build dispatch Holding workers.get_mut across DB awaits on retry could stall the tokio runtime under heartbeat/health-check contention. Extract claim_worker_for_build and cover with a concurrency regression test. * fix clippy * fix ui fmt
1 parent cebf4ce commit de77cbe

50 files changed

Lines changed: 1013 additions & 181 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/mono-engine-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ jobs:
128128
129129
deploy-aws:
130130
needs: manifest
131-
if: ${{ github.repository == 'gitmono-dev/mega' }}
131+
if: false # disabled
132132
runs-on: ubuntu-latest
133133
permissions:
134134
contents: read

.github/workflows/orion-server-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ jobs:
118118
119119
deploy-aws:
120120
needs: manifest
121-
if: ${{ github.repository == 'gitmono-dev/mega' }}
121+
if: false # disabled
122122
runs-on: ubuntu-latest
123123
permissions:
124124
contents: read

.github/workflows/web-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ jobs:
128128
129129
deploy-aws:
130130
needs: manifest
131-
if: ${{ github.repository == 'gitmono-dev/mega' }}
131+
if: false # disabled
132132
runs-on: ubuntu-latest
133133
permissions:
134134
contents: read

.github/workflows/web-sync-server-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
6969
deploy-aws:
7070
needs: build-and-push
71-
if: ${{ github.repository == 'gitmono-dev/mega' }}
71+
if: false # disabled
7272
runs-on: ubuntu-latest
7373
strategy:
7474
matrix:

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ clap = "4.6.4"
5454

5555
#====
5656
tokio = "1.53.1"
57-
tokio-stream = "0.1.18"
57+
tokio-stream = "0.1.19"
5858
tokio-util = "0.7.19"
5959
async-trait = "0.1.89"
6060
async-stream = "0.3.6"

ceres/src/model/admin.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ pub struct AdminListResponse {
1111
pub admins: Vec<String>,
1212
}
1313

14-
/// Request body for generating `.mega_cedar.json` content from admin usernames.
14+
/// Request body for generating `.mega_cedar.json` content from admin GitHub logins.
1515
#[derive(Debug, Deserialize, ToSchema)]
1616
pub struct GenerateCedarRequest {
17+
/// GitHub login names used as Cedar `User` euids (e.g. `octocat`).
1718
pub admins: Vec<String>,
1819
}
1920

clients/orion-scheduler-client/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ path = "src/lib.rs"
1010

1111
[dependencies]
1212
common = { workspace = true }
13-
reqwest = { workspace = true, features = ["json"] }
13+
reqwest = { workspace = true, features = ["json", "stream"] }
1414
anyhow = { workspace = true }
1515
serde = { workspace = true }
1616
serde_json = { workspace = true }

clients/orion-scheduler-client/src/http_client.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,60 @@ impl OrionSchedulerHttpClient {
128128
))
129129
}
130130
}
131+
132+
/// Open an SSE stream of live Orion runner logs (`GET /logs/orion/stream`).
133+
///
134+
/// Prefer `vm_id`; when absent, `domain` is used. At least one must be set.
135+
/// The returned response body is a long-lived `text/event-stream` — do not
136+
/// apply a short request timeout.
137+
pub async fn stream_orion_logs(
138+
&self,
139+
vm_id: Option<&str>,
140+
domain: Option<&str>,
141+
) -> anyhow::Result<reqwest::Response> {
142+
if vm_id.is_none() && domain.is_none() {
143+
return Err(anyhow::anyhow!(
144+
"stream_orion_logs requires vm_id or domain"
145+
));
146+
}
147+
148+
let mut url = format!("{}/logs/orion/stream?", self.base_url);
149+
let mut params: Vec<String> = Vec::new();
150+
if let Some(id) = vm_id {
151+
params.push(format!("vm_id={}", urlencoding_query(id)));
152+
}
153+
if let Some(d) = domain {
154+
params.push(format!("domain={}", urlencoding_query(d)));
155+
}
156+
url.push_str(&params.join("&"));
157+
158+
let req = self.client.get(&url);
159+
let res = self.auth_headers(req).send().await?;
160+
let status = res.status();
161+
if status.is_success() {
162+
Ok(res)
163+
} else {
164+
let body = res.text().await.unwrap_or_default();
165+
Err(anyhow::anyhow!(
166+
"Scheduler stream_orion_logs failed ({}): {}",
167+
status,
168+
body
169+
))
170+
}
171+
}
172+
}
173+
174+
fn urlencoding_query(value: &str) -> String {
175+
let mut out = String::with_capacity(value.len());
176+
for b in value.bytes() {
177+
match b {
178+
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
179+
out.push(b as char)
180+
}
181+
_ => out.push_str(&format!("%{b:02X}")),
182+
}
183+
}
184+
out
131185
}
132186

133187
#[cfg(test)]
@@ -139,4 +193,10 @@ mod tests {
139193
let client = OrionSchedulerHttpClient::new("http://127.0.0.1:8080/", "");
140194
assert_eq!(client.base_url, "http://127.0.0.1:8080");
141195
}
196+
197+
#[test]
198+
fn urlencoding_query_encodes_reserved_bytes() {
199+
assert_eq!(urlencoding_query("a b"), "a%20b");
200+
assert_eq!(urlencoding_query("orion.gitmega.com"), "orion.gitmega.com");
201+
}
142202
}

clients/orion-scheduler-client/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! HTTP client for orion-scheduler VM provisioning (`/webhook`, `/status`, `/vms/{id}`).
1+
//! HTTP client for orion-scheduler VM provisioning (`/webhook`, `/status`, `/vms/{id}`, logs SSE).
22
33
mod http_client;
44

@@ -95,4 +95,13 @@ impl OrionSchedulerClient {
9595
pub async fn get_status(&self) -> anyhow::Result<SchedulerStatusResponse> {
9696
self.http.get_status().await
9797
}
98+
99+
/// Proxy-friendly SSE stream of runner / orion-client startup logs.
100+
pub async fn stream_orion_logs(
101+
&self,
102+
vm_id: Option<&str>,
103+
domain: Option<&str>,
104+
) -> anyhow::Result<reqwest::Response> {
105+
self.http.stream_orion_logs(vm_id, domain).await
106+
}
98107
}

0 commit comments

Comments
 (0)