OXYGENHUB

Windows runner: helpers start from the running binary; microVM says Linux only e6949d87205b

Found running flow.exe in the Windows VM: the WASM helper was started
from /proc/self/exe. tier::self_exe is /proc/self/exe on Linux and
Android, the binary's own path elsewhere. Registered as windows-1 it ran
andymccall/windows-runner-demo's job from the hub (run #1).

refs #83
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-10-26 02:24 UTC
Signature
◈ sealed by Andy McCall
Hash
e6949d87205b25ba552afd5865dc144149d4dc8a45031cf177ba3777554de2f6
Depends on
28cc603f737d 3554afefb6aa c3db750ed96e c5b702e59c1f cc462b56fbbb e0918b887850 ea56c56eaf90
Depended on by
6f66e397539c
In bookmarks
main
In tags
v0.4.0 v0.5.0 v0.5.1 v0.5.2 v0.5.3
Edits
8 atoms, 0 tree operations, 4 files

Browse the tree at this change

modified CHANGELOG.md +1 −1
…
3 unchanged lines
4 4
5 5
## Unreleased
6 6
7 -
- **`flow` builds for Windows (#83, step 2 begun):** `cargo build --target x86_64-pc-windows-gnu` gives a `flow.exe` that offers the WASM tier: the syscall tier, the guest helpers and the egress proxy are Linux's only (a Windows build says the syscall tier "runs only on Linux"), cache pruning by reads stays on Linux, and file modes, links and sizes go through a small `portable` module (modes are not kept on Windows). Free disk, load and kernel are not measured there yet, and a Windows runner does not update itself. Nothing changes on Linux or Android.
7 +
- **`flow` builds for Windows (#83, step 2 begun):** `cargo build --target x86_64-pc-windows-gnu` gives a `flow.exe` that offers the WASM tier: the syscall tier, the guest helpers and the egress proxy are Linux's only (a Windows build says the syscall tier "runs only on Linux"), cache pruning by reads stays on Linux, and file modes, links and sizes go through a small `portable` module (modes are not kept on Windows). Free disk, load and kernel are not measured there yet, and a Windows runner does not update itself. Nothing changes on Linux or Android. Tried in the Windows VM on Earth: `flow.exe tiers` offers wasm, a local `flow run` of a 120-step WASM job passes, and registered as runner `windows-1` (label `windows`) it ran andymccall/windows-runner-demo's job from the hub (run #1). Helpers start from the running binary's path on Windows (`/proc/self/exe` on Linux and Android).
8 8
- **The syscall tier's loopback reaches TCP (#73):** with `network "loopback"`, a job may open IPv4 and IPv6 sockets, which in its own network namespace reach only its `lo`, so a server it starts on 127.0.0.1 answers it (a conformance suite over an emulator's HTTP control port, which skipped every test on narvi-1). With `network "isolated"` sockets other than `AF_UNIX` are still refused.
9 9
- **Runner builds in releases (oxygenhub#322):** a `dist` job (`scripts/dist.sh`, on a change to `Cargo.toml` or the script) builds `flow` stripped for Linux x86_64, aarch64 and riscv64 (glibc 2.28 and later) as `flow-linux-ARCH`, named by the architecture a runner reports, with `SHA256SUMS`: the files a release carries for runners that update themselves.
10 10
- **Runners ask the hub for their update (oxygenhub#322):** once the hub has answered a claim, and every 15 minutes, a runner asks `GET /api/v1/flow/runner/update`; when the hub offers a build, it downloads it (kept in the home's `updates/`), refuses it unless its size and BLAKE3 are those the hub attests, and installs it as `flow runner update` does, leaving within 600 s, or for a dry run checks it and says what would happen. What it did goes back to the hub once per outcome, and a proof or a rollback is told at the next start. `[runner.update] allow = false` refuses and says so; a hub without runner updates (404) is simply asked again later.
…
99 unchanged lines
modified crates/flow/src/runner.rs +1 −0
…
532 unchanged lines
533 533
    let mut missing = Vec::new();
534 534
    let kvm = std::fs::OpenOptions::new().read(true).write(true).open("/dev/kvm");
535 535
    match (kvm, home.config.microvm.is_some()) {
536 +
        _ if !cfg!(target_os = "linux") => missing.push("microvm: the tier runs only on Linux (Firecracker and KVM)".to_string()),
536 537
        (Ok(_), true) => have.push("microvm".to_string()),
537 538
        (Ok(_), false) => missing.push("microvm: flow.toml has no [microvm] section".to_string()),
538 539
        (Err(e), _) => missing.push(format!(
…
1707 unchanged lines
modified crates/flow/src/tier.rs +12 −8
…
33 unchanged lines
34 34
    }
35 35
}
36 36
37 +
/// This binary, to start helpers from and hash: `/proc/self/exe` on Linux
38 +
/// and Android (the running file, even after an update replaced its name),
39 +
/// the path it was started from elsewhere (oxygenflow#83).
40 +
pub fn self_exe() -> PathBuf {
41 +
    if cfg!(target_os = "linux") || cfg!(target_os = "android") {
42 +
        PathBuf::from("/proc/self/exe")
43 +
    } else {
44 +
        std::env::current_exe().unwrap_or_default()
45 +
    }
46 +
}
47 +
37 48
/// This binary's hash, which receipts name as the sandbox.
38 49
pub(crate) fn self_hash() -> &'static str {
39 50
    static HASH: OnceLock<String> = OnceLock::new();
40 -
    HASH.get_or_init(|| {
41 -
        let exe = if cfg!(target_os = "linux") || cfg!(target_os = "android") {
42 -
            PathBuf::from("/proc/self/exe")
43 -
        } else {
44 -
            std::env::current_exe().unwrap_or_default()
45 -
        };
46 -
        crate::home::hash_file(&exe).unwrap_or_else(|_| "unknown".into())
47 -
    })
51 +
    HASH.get_or_init(|| crate::home::hash_file(&self_exe()).unwrap_or_else(|_| "unknown".into()))
48 52
}
modified crates/flow/src/wasm.rs +1 −1
…
157 unchanged lines
158 158
    std::fs::write(&spec_path, serde_json::to_vec(&spec)?)?;
159 159
160 160
    let started = Instant::now();
161 -
    let mut child = std::process::Command::new("/proc/self/exe")
161 +
    let mut child = std::process::Command::new(crate::tier::self_exe())
162 162
        .arg("__wasm")
163 163
        .arg(&spec_path)
164 164
        .env_clear()
…
392 unchanged lines