Refactor runner setup and diagnostics; improve tooling support and NDJSON logging

- Enhance runner logging with status-specific messages and structured JSON fields for better traceability.
- Add SHA256 object format detection and initialization for Git repos when applicable.
- Improve shell script execution by adding verbose mode and safe commands handling.
- Extend package installation scripts to support Clang and related tooling across multiple environments.
- Increment orchestrator version for release.

Signed-off-by: Till Wegmueller <toasterson@gmail.com>
This commit is contained in:
Till Wegmueller 2025-11-18 12:50:20 +01:00
parent df1a3126b1
commit 7cc6ff856b
No known key found for this signature in database
2 changed files with 53 additions and 14 deletions

View file

@ -29,22 +29,22 @@ install_linux() {
apt) apt)
sudo -n true 2>/dev/null || true sudo -n true 2>/dev/null || true
sudo apt-get update -y || apt-get update -y || true sudo apt-get update -y || apt-get update -y || true
sudo apt-get install -y --no-install-recommends curl ca-certificates git build-essential pkg-config libssl-dev protobuf-compiler cmake || true sudo apt-get install -y --no-install-recommends curl ca-certificates git build-essential pkg-config libssl-dev protobuf-compiler cmake clang libclang-dev || true
;; ;;
dnf) dnf)
sudo dnf install -y curl ca-certificates git gcc gcc-c++ make pkgconf-pkg-config openssl-devel protobuf-compiler || true sudo dnf install -y curl ca-certificates git gcc gcc-c++ make pkgconf-pkg-config openssl-devel protobuf-compiler clang clang-libs || true
;; ;;
yum) yum)
sudo yum install -y curl ca-certificates git gcc gcc-c++ make pkgconfig openssl-devel protobuf-compiler || true sudo yum install -y curl ca-certificates git gcc gcc-c++ make pkgconfig openssl-devel protobuf-compiler clang clang-libs || true
;; ;;
zypper) zypper)
sudo zypper --non-interactive install curl ca-certificates git gcc gcc-c++ make pkg-config libopenssl-devel protobuf || true sudo zypper --non-interactive install curl ca-certificates git gcc gcc-c++ make pkg-config libopenssl-devel protobuf clang || true
;; ;;
apk) apk)
sudo apk add --no-cache curl ca-certificates git build-base pkgconfig openssl-dev protoc || true sudo apk add --no-cache curl ca-certificates git build-base pkgconfig openssl-dev protoc clang clang-libs || true
;; ;;
pacman) pacman)
sudo pacman -Sy --noconfirm curl ca-certificates git base-devel pkgconf openssl protobuf || true sudo pacman -Sy --noconfirm curl ca-certificates git base-devel pkgconf openssl protobuf clang || true
;; ;;
*) *)
log "unknown package manager ($PM); skipping linux deps install" log "unknown package manager ($PM); skipping linux deps install"
@ -56,9 +56,9 @@ install_illumos() {
if command -v pkg >/dev/null 2>&1; then if command -v pkg >/dev/null 2>&1; then
# OpenIndiana IPS packages (best-effort) # OpenIndiana IPS packages (best-effort)
sudo pkg refresh || true sudo pkg refresh || true
sudo pkg install -v developer/build/gnu-make developer/gcc-13 git developer/protobuf developer/rustc || true sudo pkg install -v developer/build/gnu-make developer/gcc-13 git developer/protobuf developer/rustc developer/clang || true
elif command -v pkgin >/dev/null 2>&1; then elif command -v pkgin >/dev/null 2>&1; then
sudo pkgin -y install git gcc gmake protobuf || true sudo pkgin -y install git gcc gmake protobuf clang || true
else else
log "no known package manager found on illumos" log "no known package manager found on illumos"
fi fi

View file

@ -181,7 +181,16 @@ async fn preflight(repo: &str, workdir: &str) -> Result<()> {
if let Some((host, port)) = parse_repo_host_port(repo) { if let Some((host, port)) = parse_repo_host_port(repo) {
let ok = check_network_connect(&host, port, 2000).await; let ok = check_network_connect(&host, port, 2000).await;
let lvl = if ok { "info" } else { "warn" }; let lvl = if ok { "info" } else { "warn" };
println!("{}", ndjson_line("env", lvl, "network connectivity", Some(serde_json::json!({"host": host, "port": port, "reachable": ok})))); let status_msg = if ok { "reachable" } else { "unreachable" };
println!(
"{}",
ndjson_line(
"env",
lvl,
&format!("network: {}:{} {}", host, port, status_msg),
Some(serde_json::json!({"host": host, "port": port, "reachable": ok}))
)
);
} }
Ok(()) Ok(())
@ -258,19 +267,48 @@ async fn fetch_repo_via_archive(repo_https: &str, sha: &str, workdir: &str) -> R
Err(miette::miette!("failed to fetch repo archive via HTTP for {url}")) Err(miette::miette!("failed to fetch repo archive via HTTP for {url}"))
} }
fn is_hex(s: &str) -> bool { s.chars().all(|c| c.is_ascii_hexdigit()) }
async fn ensure_repo(repo: &str, sha: &str, workdir: &str) -> Result<()> { async fn ensure_repo(repo: &str, sha: &str, workdir: &str) -> Result<()> {
fs::create_dir_all(workdir).await.into_diagnostic()?; fs::create_dir_all(workdir).await.into_diagnostic()?;
let repo_eff = to_https_if_codeberg(repo); let repo_eff = to_https_if_codeberg(repo);
// Prefer git when available; fall back to archive download when git is missing or fetch fails. // Prefer git when available; fall back to archive download when git is missing or fetch fails.
if has_cmd("git").await { if has_cmd("git").await {
// Determine object format: if SHA looks like 64-hex, assume sha256 object format
let sha_len = sha.len();
let is_sha256 = sha_len == 64 && is_hex(sha);
let obj_fmt = if is_sha256 { Some("sha256") } else { None };
// Emit NDJSON about chosen method
println!(
"{}",
ndjson_line(
"env_setup",
"info",
&format!(
"fetch via git (object-format={})",
obj_fmt.unwrap_or("sha1")
),
Some(serde_json::json!({
"method": "git",
"object_format": obj_fmt.unwrap_or("sha1"),
"sha_len": sha_len,
"detached": true
}))
)
);
let cmds = vec![ let cmds = vec![
format!("cd {workdir} && git init"), // Re-initialize repository to ensure correct object format
format!("cd {workdir} && rm -rf .git || true"),
if let Some(fmt) = obj_fmt { format!("cd {workdir} && git init --object-format={fmt}") } else { format!("cd {workdir} && git init") },
format!( format!(
"cd {workdir} && git remote remove origin >/dev/null 2>&1 || true && git remote add origin {repo_eff}" "cd {workdir} && git remote remove origin >/dev/null 2>&1 || true && git remote add origin {repo_eff}"
), ),
format!("cd {workdir} && git fetch --depth=1 origin {sha}"), // Use protocol v2 features when available and keep it light
format!("cd {workdir} && git checkout -q FETCH_HEAD"), format!("cd {workdir} && git -c protocol.version=2 fetch --filter=blob:none --depth=1 --no-tags origin {sha}"),
// Checkout the requested commit in detached HEAD
format!("cd {workdir} && git checkout -q --detach {sha}"),
]; ];
for c in cmds { for c in cmds {
match run_shell(&c).await { match run_shell(&c).await {
@ -301,7 +339,7 @@ async fn run_job_script(workdir: &str) -> Result<i32> {
let mut cmd = Command::new("/bin/sh"); let mut cmd = Command::new("/bin/sh");
cmd.arg("-lc") cmd.arg("-lc")
.arg(format!("cd {workdir} && {}", script)) .arg(format!("set -ex; cd {workdir}; {}", script))
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()); .stderr(Stdio::piped());
let mut child = cmd.spawn().into_diagnostic()?; let mut child = cmd.spawn().into_diagnostic()?;
@ -406,7 +444,8 @@ async fn main() -> Result<()> {
// Emit startup environment and tool checks // Emit startup environment and tool checks
let uname = Command::new("/bin/sh").arg("-lc").arg("uname -a || echo unknown").output().await.ok() let uname = Command::new("/bin/sh").arg("-lc").arg("uname -a || echo unknown").output().await.ok()
.and_then(|o| String::from_utf8(o.stdout).ok()).unwrap_or_else(|| "unknown".into()); .and_then(|o| String::from_utf8(o.stdout).ok()).unwrap_or_else(|| "unknown".into());
println!("{}", ndjson_line("env", "info", "system", Some(serde_json::json!({"uname": uname.trim()})))); let uname_trim = uname.trim().to_string();
println!("{}", ndjson_line("env", "info", &format!("system: {}", uname_trim), Some(serde_json::json!({"uname": uname_trim}))));
// Preflight environment checks (tools, workdir, network) // Preflight environment checks (tools, workdir, network)
if let Err(e) = preflight(&repo, &workdir).await { if let Err(e) = preflight(&repo, &workdir).await {