Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/Skidbladnir

probe/src/bin/skidbladnir-testsvc.rs

//! skidbladnir-testsvc — a deliberately trivial "product" the install-matrix
//! installs as a real service (via the ServiceSpec renderer's unit) inside each
//! KVM guest. It does exactly enough for the probe to assert "installed + started
//! + healthy": it binds a TCP port and answers `GET /health` with `200 OK`.
//!
//! std-only, static musl → the SAME binary runs under systemd (Ubuntu/Debian/
//! Fedora) and OpenRC (Alpine).
//!
//! Usage: `skidbladnir-testsvc [--port N] [--name S]`  (or env SKID_PORT).

use std::io::{Read, Write};
use std::net::TcpListener;

fn arg_val(flag: &str) -> Option<String> {
    let args: Vec<String> = std::env::args().collect();
    args.iter().position(|a| a == flag).and_then(|i| args.get(i + 1).cloned())
}

/// `<version> (<git-hash>)` — stamped by the pure-fs `build.rs`
/// (build-version-githash-law).
pub const VERSION_LINE: &str =
    concat!(env!("CARGO_PKG_VERSION"), " (", env!("SKIDBLADNIR_PROBE_GIT_HASH"), ")");

fn main() {
    // Answer `--version` before binding a port: a test service that cannot say
    // which build it is turns a matrix failure into a guessing game.
    if std::env::args().skip(1).any(|a| a == "--version" || a == "-V") {
        println!("skidbladnir-testsvc {VERSION_LINE}");
        return;
    }
    let port: u16 = arg_val("--port")
        .or_else(|| std::env::var("SKID_PORT").ok())
        .and_then(|s| s.parse().ok())
        .unwrap_or(7070);
    let name = arg_val("--name").unwrap_or_else(|| "skidtest".to_string());

    let addr = format!("127.0.0.1:{port}");
    let listener = match TcpListener::bind(&addr) {
        Ok(l) => l,
        Err(e) => {
            eprintln!("skidbladnir-testsvc: bind {addr} failed: {e}");
            std::process::exit(1);
        }
    };
    println!("skidbladnir-testsvc `{name}` listening on {addr} (pid {})", std::process::id());

    for stream in listener.incoming() {
        let mut s = match stream {
            Ok(s) => s,
            Err(_) => continue,
        };
        // Read (and ignore) the request line; respond to anything with a health body.
        let mut buf = [0u8; 1024];
        let _ = s.read(&mut buf);
        let body = format!("OK {name}\n");
        let resp = format!(
            "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
            body.len(),
            body
        );
        let _ = s.write_all(resp.as_bytes());
        let _ = s.flush();
    }
}