Created
September 1, 2026 06:27
-
-
Save sakti/02592fcdb298ff5d5e856bcd2a5ab66a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Check whether this node can run microVMs (Firecracker, Cloud Hypervisor, etc). | |
| # | |
| # Usage: ./check-microvm-support.sh [-q] | |
| # -q quiet mode: no output, just exit code (0 = supported, 1 = not supported) | |
| set -uo pipefail | |
| QUIET=0 | |
| [[ "${1:-}" == "-q" ]] && QUIET=1 | |
| PASS=0 | |
| FAIL=0 | |
| WARN=0 | |
| log() { [[ $QUIET -eq 0 ]] && printf '%s\n' "$1"; } | |
| ok() { PASS=$((PASS+1)); log " [OK] $1"; } | |
| bad() { FAIL=$((FAIL+1)); log " [FAIL] $1"; } | |
| warn() { WARN=$((WARN+1)); log " [WARN] $1"; } | |
| section() { log ""; log "== $1 =="; } | |
| ARCH=$(uname -m) | |
| section "CPU virtualization extensions ($ARCH)" | |
| case "$ARCH" in | |
| x86_64|i686|i386) | |
| if grep -qE '(vmx|svm)' /proc/cpuinfo 2>/dev/null; then | |
| flag=$(grep -oE '(vmx|svm)' /proc/cpuinfo | sort -u | tr '\n' ' ') | |
| ok "hardware virtualization present ($flag)" | |
| else | |
| bad "no vmx/svm flag found in /proc/cpuinfo" | |
| fi | |
| ;; | |
| aarch64|arm64) | |
| # ARM: virtualization is provided by EL2/hypervisor mode, exposed via /dev/kvm. | |
| # There's no simple /proc/cpuinfo flag equivalent to vmx/svm. | |
| if [[ -e /sys/devices/system/cpu/cpu0 ]]; then | |
| ok "ARM64 CPU detected; virtualization support is determined by /dev/kvm below" | |
| else | |
| warn "unable to inspect CPU details" | |
| fi | |
| ;; | |
| *) | |
| warn "unrecognized architecture '$ARCH'; skipping CPU flag check" | |
| ;; | |
| esac | |
| section "KVM kernel support" | |
| if [[ -e /dev/kvm ]]; then | |
| ok "/dev/kvm exists" | |
| if [[ -r /dev/kvm && -w /dev/kvm ]]; then | |
| ok "/dev/kvm is readable/writable by current user ($(id -un))" | |
| else | |
| perms=$(ls -l /dev/kvm 2>/dev/null) | |
| bad "/dev/kvm exists but is not read/write for current user ($(id -un)) -- $perms" | |
| warn "consider: sudo usermod -aG kvm $(id -un) (then re-login)" | |
| fi | |
| else | |
| bad "/dev/kvm does not exist" | |
| fi | |
| if command -v lsmod >/dev/null 2>&1; then | |
| if lsmod 2>/dev/null | grep -qE '^kvm'; then | |
| mods=$(lsmod | awk '$1 ~ /^kvm/ {print $1}' | tr '\n' ' ') | |
| ok "KVM kernel module(s) loaded: $mods" | |
| else | |
| warn "no kvm* kernel module reported by lsmod (may be built-in, or unloaded)" | |
| fi | |
| else | |
| warn "lsmod not available; cannot check loaded kernel modules" | |
| fi | |
| section "Nested / virtualized environment check" | |
| if command -v systemd-detect-virt >/dev/null 2>&1; then | |
| # systemd-detect-virt exits non-zero when the result is "none", so capture | |
| # stdout separately from the exit status instead of using `|| echo fallback`. | |
| virt=$(systemd-detect-virt 2>/dev/null) | |
| [[ -z "$virt" ]] && virt="unknown" | |
| if [[ "$virt" == "none" ]]; then | |
| ok "running on bare metal (systemd-detect-virt: none)" | |
| else | |
| warn "running inside a virtualized environment (systemd-detect-virt: $virt) -- nested virtualization may be required" | |
| fi | |
| else | |
| warn "systemd-detect-virt not found; cannot determine bare-metal vs. VM" | |
| fi | |
| section "Required tooling" | |
| for bin in firecracker cloud-hypervisor; do | |
| if command -v "$bin" >/dev/null 2>&1; then | |
| ver=$("$bin" --version 2>/dev/null | head -n1) | |
| ok "$bin found in PATH ($ver)" | |
| else | |
| warn "$bin not found in PATH" | |
| fi | |
| done | |
| # Also check the local bin/ directory next to this script, common for this project layout. | |
| SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) | |
| if [[ -d "$SCRIPT_DIR" ]]; then | |
| for f in "$SCRIPT_DIR"/firecracker* "$SCRIPT_DIR"/cloud-hypervisor*; do | |
| [[ -f "$f" && -x "$f" ]] && ok "local binary present: $f" | |
| done | |
| fi | |
| section "Summary" | |
| log " PASS=$PASS WARN=$WARN FAIL=$FAIL" | |
| if [[ $FAIL -eq 0 ]]; then | |
| log "" | |
| log "Result: this node SUPPORTS running microVMs." | |
| exit 0 | |
| else | |
| log "" | |
| log "Result: this node does NOT fully support running microVMs." | |
| exit 1 | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment