Octl, Podman detection
How octl probes for Podman and installs if needed
octl deploy needs Podman + podman-compose available. On macOS it can auto-install via Homebrew; on Linux the user installs themselves.
Detection chain
1. Is `podman` on PATH?
→ Yes: check version
→ No: try to install (macOS) or error (Linux)
2. Is Podman version >= required (e.g. 4.5)?
→ No: warn and suggest upgrade
→ Yes: continue
3. Is `podman-compose` on PATH?
→ Yes: continue
→ No: install via brew / pip / error
4. Is Podman machine initialized? (macOS only)
→ Yes: check it's running
→ No: `podman machine init && podman machine start`
5. Is Podman machine running?
→ Yes: continue
→ No: `podman machine start`macOS install path
async function installPodmanMacOS() {
await spawn("brew", ["install", "podman"]);
await spawn("brew", ["install", "podman-compose"]);
await spawn("podman", ["machine", "init"]);
await spawn("podman", ["machine", "start"]);
}If Homebrew isn't installed, octl prints instructions to install Homebrew first; it doesn't attempt that itself.
Linux
async function checkPodmanLinux() {
if (!hasCommand("podman")) {
throw new Error("Podman not found. Install via your package manager: `apt install podman` or `dnf install podman`");
}
}Octl deliberately doesn't try to sudo apt install, too many things can go wrong, and Linux distros vary too much.
Why Homebrew on macOS but not Linux
- macOS users almost universally use Homebrew (or Macports, but Brew is dominant).
- Linux distros vary too much (apt, dnf, pacman, zypper, …).
- Auto-installing requires root on Linux; better to ask the user.
Version check
async function getPodmanVersion(): Promise<string> {
const result = await spawn("podman", ["--version"]);
const match = result.stdout.match(/(\d+\.\d+\.\d+)/);
if (!match) throw new Error("Could not parse podman version");
return match[1];
}If version is too old (< 4.5), octl warns but proceeds. New compose features may not work.
Podman machine on macOS
podman machine is the Podman virtual machine layer for non-Linux hosts. macOS runs containers inside a Linux VM via QEMU.
octl deploy:
- Checks
podman machine list, is there at least one machine? - If not,
podman machine init(creates a default machine). - Checks
podman machine ps, is it running? - If not,
podman machine start. - Now
podmancommands target this machine.
For older macOS users: starting the machine can take 30+ seconds. octl streams progress.
What octl does NOT install
- Docker. We target Podman; Docker is an unrelated alternative.
kubectl. Olympus doesn't use Kubernetes (ADR 0001). Some seed scripts mention kubectl-style commands for clarity but don't actually need it.- Postgres CLI. Optional; users can install if they want to introspect locally.
When detection fails
octl prints a clear error:
ERROR: Podman not found.
On macOS: brew install podman
On Linux: apt install podman (or your package manager equivalent)
Re-run `octl deploy` after installing.No silent failures.