diff --git a/logs.sh b/logs.sh new file mode 100755 index 0000000..75d2b9a --- /dev/null +++ b/logs.sh @@ -0,0 +1,91 @@ +#!/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