A runner offers only the tiers it can run c5b702e59c1f
The MicroVM tier is offered only when /dev/kvm opens for reading and writing and flow.toml pins Firecracker; the runner names its tiers when it starts, and with none refuses to start, saying why, instead of claiming jobs it would fail (spec §11.1). refs #36
- Author
- Andy McCall @andymccall <[email protected]>
- When
- · 2026-10-04 23:57 UTC
- Signature
- ✔ signed by Andy McCall
- Hash
c5b702e59c1f884f01afc1c62f02ae023e83b8b27a39b092d52ca5977d212ec4- Depends on
- 3007d8f011fa 47c1d64dec8a bb643c252515 c3db750ed96e e0918b887850 f53e6d47b56a
- Depended on by
- 77c8c24066ef e6949d87205b b11e30f5031d ea56c56eaf90
- In bookmarks
- main newer-pipeline push-uses-login
- In tags
- v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.5.0 v0.5.1 v0.5.2 v0.5.3
- Edits
- 7 atoms, 0 tree operations, 2 files
Browse the tree at this change
modified CHANGELOG.md +2 −0
| … | 3 unchanged lines |
||
| 4 | 4 | ||
| 5 | 5 | ## Unreleased |
|
| 6 | 6 | ||
| 7 | + | - **A runner offers only the tiers it can run (#36).** It checks that `/dev/kvm` opens before offering the MicroVM tier, says which tiers it serves when it starts, and refuses to start with none, naming why, rather than claiming jobs it would fail. |
|
| 8 | + | ||
| 7 | 9 | - **A runner tries a fetch again after a network hiccup (oxygenhub#111).** Fetching or cloning the job's repository or a subrepo is retried on DNS, connection, timeout and 502/503/504 errors, waiting 2, 4, 8, 16 and 30 seconds; any other error still ends the job at once. |
|
| 8 | 10 | ||
| 9 | 11 | - **Architecture awareness (#36, spec §11.2).** `flow rootfs import` records an image's architecture from its shell's ELF header and refuses an image for another architecture; a claim reports each image's architecture, and a sandbox may say `arch "riscv64"`. |
|
| … | 18 unchanged lines |
modified crates/flow/src/runner.rs +20 −2
| … | 248 unchanged lines |
||
| 249 | 249 | } |
|
| 250 | 250 | } |
|
| 251 | 251 | ||
| 252 | + | /// The isolation tiers this machine can honour now (spec §11.1): the |
|
| 253 | + | /// MicroVM tier only when `/dev/kvm` opens for reading and writing and |
|
| 254 | + | /// flow.toml pins Firecracker. `Err` says why there are none. |
|
| 255 | + | pub fn tiers(home: &Home) -> std::result::Result<Vec<String>, String> { |
|
| 256 | + | let kvm = std::fs::OpenOptions::new().read(true).write(true).open("/dev/kvm"); |
|
| 257 | + | match (kvm, home.config.microvm.is_some()) { |
|
| 258 | + | (Ok(_), true) => Ok(vec!["microvm".into()]), |
|
| 259 | + | (Ok(_), false) => Err("flow.toml has no [microvm] section, so no tier can run".into()), |
|
| 260 | + | (Err(e), _) => Err(format!( |
|
| 261 | + | "/dev/kvm cannot be opened ({e}): the MicroVM tier needs hardware virtualisation and this user in the kvm group, and no other tier is in this build" |
|
| 262 | + | )), |
|
| 263 | + | } |
|
| 264 | + | } |
|
| 265 | + | ||
| 252 | 266 | pub fn serve(home: &Home) -> Result<()> { |
|
| 253 | 267 | let cfg = home.config.runner.clone().context("flow.toml has no [runner] section")?; |
|
| 268 | + | // A runner offers only what it can run: a machine without KVM claims |
|
| 269 | + | // nothing rather than taking MicroVM jobs and failing them (#36). |
|
| 270 | + | let runtimes = tiers(home).map_err(|why| anyhow::anyhow!("flow runner: {why}"))?; |
|
| 254 | 271 | let hub = Hub::new(&cfg)?; |
|
| 255 | 272 | let name = cfg.name.clone().unwrap_or_else(|| "flow".into()); |
|
| 256 | 273 | let budget = Budget::of(&cfg); |
|
| 257 | 274 | let key = home.runner_key(&name)?; |
|
| 258 | 275 | eprintln!( |
|
| 259 | - | "flow runner {name}: polling {} (up to {} jobs at once), signing receipts as {}", |
|
| 276 | + | "flow runner {name}: polling {} (up to {} jobs at once, tiers {}), signing receipts as {}", |
|
| 260 | 277 | cfg.hub, |
|
| 261 | 278 | budget.max_jobs, |
|
| 279 | + | runtimes.join(", "), |
|
| 262 | 280 | key.identity.hash().to_hex() |
|
| 263 | 281 | ); |
|
| 264 | 282 | let used = std::sync::Mutex::new(Used::default()); |
|
| … | 21 unchanged lines |
||
| 286 | 304 | }; |
|
| 287 | 305 | let req = ClaimRequest { |
|
| 288 | 306 | runner: name.clone(), |
|
| 289 | - | runtimes: vec!["microvm".into()], |
|
| 307 | + | runtimes: runtimes.clone(), |
|
| 290 | 308 | free_memory_mib, |
|
| 291 | 309 | free_cpus, |
|
| 292 | 310 | info: Some(RunnerInfo { |
|
| … | 498 unchanged lines |