#!/bin/bash set -e NODE_EXPORTER_VERSION="${NODE_EXPORTER_VERSION:-1.7.0}" SKILLS_DIR="${SKILLS_DIR:-/skills}" # Idempotent node_exporter installation install_node_exporter() { if command -v node_exporter &>/dev/null; then echo "node_exporter already installed" return 0 fi echo "Installing node_exporter v${NODE_EXPORTER_VERSION}..." local arch case "$(uname -m)" in x86_64) arch="amd64" ;; aarch64) arch="arm64" ;; armv7l) arch="armv7" ;; *) echo "Unsupported architecture: $(uname -m)" exit 1 ;; esac local url="https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-${arch}.tar.gz" curl -sSL "$url" -o /tmp/node_exporter.tar.gz tar -xzf /tmp/node_exporter.tar.gz -C /tmp mv /tmp/node_exporter-*/node_exporter /usr/local/bin/ rm -rf /tmp/node_exporter* echo "node_exporter installed" } # Discover skills with metrics ports discover_metrics_targets() { local targets_file="/tmp/metrics_targets.txt" echo "# Auto-discovered metrics targets" > "$targets_file" for skill_dir in "$SKILLS_DIR"/*/; do local skill_name=$(basename "$skill_dir") local skill_md="$skill_dir/SKILL.md" # Skip self [ "$skill_name" = "metrics" ] && continue # Check for metrics-port in SKILL.md if [ -f "$skill_md" ]; then local port=$(yq -r '.metadata.vibestack."metrics-port" // empty' < <(sed -n '/^---$/,/^---$/p' "$skill_md" | sed '1d;$d') 2>/dev/null) if [ -n "$port" ] && [ "$port" != "null" ]; then echo "$skill_name localhost:$port" >> "$targets_file" echo " $skill_name: metrics on port $port" fi fi # Check for METRICS_PORT_skillname env var local env_var="METRICS_PORT_${skill_name//-/_}" local env_port="${!env_var}" if [ -n "$env_port" ]; then echo "$skill_name localhost:$env_port" >> "$targets_file" echo " $skill_name: metrics on port $env_port (from env)" fi done echo "Targets written to $targets_file" } # Configure Caddy if present configure_caddy() { local caddy_dir="$SKILLS_DIR/caddy" local metrics_port="${METRICS_PORT:-9090}" local metrics_domain="${METRICS_DOMAIN:-}" if [ ! -d "$caddy_dir" ]; then echo "Caddy not found - metrics on port $metrics_port" return 0 fi echo "Caddy detected - configuring reverse proxy..." mkdir -p "$caddy_dir/snippets.d" local snippet="$caddy_dir/snippets.d/metrics.caddy" if [ -n "$metrics_domain" ]; then cat > "$snippet" << EOF # Auto-generated by metrics skill $metrics_domain { reverse_proxy localhost:$metrics_port } EOF echo "Caddy config: $metrics_domain -> localhost:$metrics_port" else cat > "$snippet" << EOF # Auto-generated by metrics skill # Add to your site block: # handle /metrics { # reverse_proxy localhost:$metrics_port # } EOF echo "Caddy snippet created (manual config needed)" fi } # Install socat for HTTP server install_socat() { if command -v socat &>/dev/null; then echo "socat already installed" return 0 fi echo "Installing socat..." apt-get update apt-get install -y socat echo "socat installed" } install_node_exporter install_socat discover_metrics_targets configure_caddy echo "Metrics setup complete"