examples/render-knut-flight-k8s.rs
//! N5 — render the knut Arrow Flight server's **Kubernetes manifests** through the
//! ONE Skidbladnir renderer (`Runtime=Kube`), so the k8s deploy is Skidbladnir-driven
//! from the SAME [`crate::product::ComponentSpec`] that drives the systemd install —
//! not a hand-written YAML that can drift.
//!
//! ```sh
//! cargo run --example render-knut-flight-k8s -- dist/k8s/knut
//! # → dist/k8s/knut/knut/knut-flight-deployment.yaml + knut-flight-service.yaml
//! kubectl apply -f dist/k8s/knut/knut
//! ```
//!
//! Writes the rendered files (paths as the renderer emits them, `<ns>/<name>-*.yaml`)
//! under the given out dir (default `dist/k8s/knut`) and prints the lifecycle verbs
//! the async applier maps onto the k8s API.
use std::path::{Path, PathBuf};
use skidbladnir::layout::Layout;
use skidbladnir::product::ComponentSpec;
use skidbladnir::service::{Backend, renderer_for};
fn main() -> anyhow::Result<()> {
let out = PathBuf::from(
std::env::args()
.nth(1)
.unwrap_or_else(|| "dist/k8s/knut".to_string()),
);
// The Layout only matters to the systemd projection (paths); for the k8s render
// the shape comes entirely from the ComponentSpec's k8s fields.
let layout = Layout::dated("/var/lib/lake", "/var/log/lake", "/opt/lake");
let spec = ComponentSpec::knut_flight().to_service_spec(&layout, Backend::Kubernetes);
let rendered = renderer_for(Backend::Kubernetes)
.ok_or_else(|| anyhow::anyhow!("no Kubernetes renderer"))?
.render(&spec)?;
for f in &rendered.files {
let dest = out.join(&f.path);
if let Some(parent) = dest.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(&dest, &f.contents)?;
set_mode(&dest, f.mode);
println!("wrote {} (mode {:o})", dest.display(), f.mode);
}
println!(
"\nlifecycle verbs (applied over the k8s API by the async driver, NOT literal kubectl):"
);
println!(" enable: {}", rendered.enable.join(" "));
println!(" start : {}", rendered.start.join(" "));
println!(" status: {}", rendered.status.join(" "));
println!(" stop : {}", rendered.stop.join(" "));
Ok(())
}
#[cfg(unix)]
fn set_mode(path: &Path, mode: u32) {
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(path, std::fs::Permissions::from_mode(mode));
}
#[cfg(not(unix))]
fn set_mode(_path: &Path, _mode: u32) {}