#!/usr/bin/env bash set -euo pipefail log() { printf '[logs] %s\n' "$*" } usage() { cat <<'EOF' Usage: ./logs.sh [--follow] Prints the Firecracker log for a VM. Use --follow to tail -f. EOF } get_prop() { local info="$1" local key="$2" awk -F= -v k="$key" '$1==k {print $2}' "$info" } find_vm_info() { local query="$1" local info match_count=0 match="" for info in state/vms/*/info; do [[ -f "$info" ]] || continue local id name id="$(get_prop "$info" "id")" name="$(get_prop "$info" "name")" if [[ "$id" == "$query"* || "$name" == "$query"* ]]; then match="$info" match_count=$((match_count + 1)) fi done if (( match_count == 0 )); then log "no VM found for prefix: $query" exit 1 fi if (( match_count > 1 )); then log "multiple VMs found for prefix: $query" exit 1 fi printf '%s' "$match" } QUERY="${1:-}" FOLLOW=0 while [[ $# -gt 0 ]]; do case "$1" in --follow|-f) FOLLOW=1 shift ;; -h|--help) usage exit 0 ;; *) if [[ -z "$QUERY" ]]; then QUERY="$1" shift else log "unknown option: $1" usage exit 1 fi ;; esac done if [[ -z "$QUERY" ]]; then usage exit 1 fi INFO_FILE="$(find_vm_info "$QUERY")" LOG_FILE="$(get_prop "$INFO_FILE" "log")" if [[ -z "$LOG_FILE" || ! -f "$LOG_FILE" ]]; then log "log file not found: $LOG_FILE" exit 1 fi if (( FOLLOW == 1 )); then tail -f "$LOG_FILE" else cat "$LOG_FILE" fi