Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Formula/bluefin-kubestellar.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# typed: false
# frozen_string_literal: true

class BluefinKubestellar < Formula
desc "Single-command launcher and manager for kc-agent (KubeStellar Console)"
homepage "https://github.com/projectbluefin/server"
version "0.1.0"
license "Apache-2.0"

depends_on "kubestellar/tap/kc-agent"

def install
bin.install "files/bin/bluefin-kubestellar" => "bluefin-kubestellar"
end

def caveats
<<~EOS
To start kc-agent with Bluefin Server console defaults:
bluefin-kubestellar start

To check status:
bluefin-kubestellar status
EOS
end

test do
system bin/"bluefin-kubestellar", "help"
end
end
60 changes: 60 additions & 0 deletions Formula/kc-agent.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# typed: false
# frozen_string_literal: true

# Formula for kc-agent packaged with bluefin-server service integration
class KcAgent < Formula
desc "Local agent for KubeStellar Console: browser to kubeconfig"
homepage "https://github.com/kubestellar/console"
version "0.3.41"
license "Apache-2.0"

on_macos do
if Hardware::CPU.intel?
url "https://github.com/kubestellar/console/releases/download/v0.3.41/kc-agent_0.3.41_darwin_amd64.tar.gz"
sha256 "238d15ca0e710f5f709cc776c664989fb16ebc1c6e7ac3d68c378d14f4ed0482"

def install
bin.install "kc-agent"
end
end
if Hardware::CPU.arm?
url "https://github.com/kubestellar/console/releases/download/v0.3.41/kc-agent_0.3.41_darwin_arm64.tar.gz"
sha256 "8be0327ad033e77b7d32d8620a82fbb7b9423fad550965a25dc8f8f3769a9753"

def install
bin.install "kc-agent"
end
end
end

on_linux do
if Hardware::CPU.intel? && Hardware::CPU.is_64_bit?
url "https://github.com/kubestellar/console/releases/download/v0.3.41/kc-agent_0.3.41_linux_amd64.tar.gz"
sha256 "052b80bd0700f1c7e22ed5d6ad7547a45d6441d6a2cd40609fed1e69bf592df2"

def install
bin.install "kc-agent"
end
end
if Hardware::CPU.arm? && Hardware::CPU.is_64_bit?
url "https://github.com/kubestellar/console/releases/download/v0.3.41/kc-agent_0.3.41_linux_arm64.tar.gz"
sha256 "a1fefe20ebf64d938a92d0a61661f8ad79cdb2b6d9cf1f63673d9f42959f0ccb"

def install
bin.install "kc-agent"
end
end
end

service do
run [opt_bin/"kc-agent", "-allowed-origins", "http://localhost:8080,http://127.0.0.1:8080"]
keep_alive true
environment_variables KAGENTI_CONTROLLER_URL: "none"
log_path var/"log/kc-agent.log"
error_log_path var/"log/kc-agent.log"
end

test do
system bin/"kc-agent", "-version"
end
end
33 changes: 33 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,36 @@ install-vm:
echo "==> Access URL (Local): http://localhost:8080/"
xdg-open "http://${HOST_IP:-localhost}:8080/" || xdg-open http://localhost:8080/ || true
wait "$QEMU_PID"

# Set up KubeStellar kc-agent for the user in ONE command.
[group('test')]
setup-kubestellar ORIGIN="http://localhost:8080,http://127.0.0.1:8080":
#!/usr/bin/env bash
set -euo pipefail
if [ -x "files/bin/bluefin-kubestellar" ]; then
exec ./files/bin/bluefin-kubestellar start --origin "{{ORIGIN}}"
else
if ! command -v kc-agent >/dev/null 2>&1; then
echo "==> Installing kc-agent from kubestellar/tap..."
brew tap kubestellar/tap
brew install kc-agent
fi
export KAGENTI_CONTROLLER_URL="none"
kc-agent -kubeconfig "${KUBECONFIG:-$HOME/.kube/config}" -allowed-origins "{{ORIGIN}}" &
fi

# Run fully automated headless browser test against the KubeStellar console.
[group('test')]
test-e2e-browser CONSOLE_URL="http://127.0.0.1:8080":
python3 tests/e2e/test_kubestellar_browser_login.py --console-url "{{CONSOLE_URL}}"

# Complete end-to-end Lima VM orchestration test.
[group('test')]
test-e2e-lima:
#!/usr/bin/env bash
set -euo pipefail
limactl validate files/lima/bluefin-server-kiosk.yaml
echo "==> Lima VM template validation passed: files/lima/bluefin-server-kiosk.yaml"
if [ "${RUN_LIMA_VM:-0}" = "1" ]; then
./scripts/lima-e2e-kubestellar-test.sh
fi
223 changes: 223 additions & 0 deletions files/bin/bluefin-kubestellar
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
#!/usr/bin/env bash
# bluefin-kubestellar: Single-command launcher and manager for kc-agent
#
# Provides bulletproof setup and launch for connecting client workstations to the
# Bluefin Server KubeStellar Console kiosk:
# 1. Installs kc-agent via Homebrew (kubestellar/tap) if missing.
# 2. Configures origin flags for the local console (default: http://localhost:8080,http://127.0.0.1:8080).
# 3. Optimizes client environment by disabling in-cluster Kagenti DNS queries (KAGENTI_CONTROLLER_URL="none").
# 4. Launches kc-agent backgrounded with health verification, or in foreground.
# 5. Provides lifecycle management (status, stop, logs).

set -euo pipefail

STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/bluefin-server"
PID_FILE="${STATE_DIR}/kc-agent.pid"
LOG_FILE="${STATE_DIR}/kc-agent.log"

CMD="start"
ORIGIN=""
PORT="8585"
FOREGROUND=0
AUTO_INSTALL=1

usage() {
cat <<EOF
Usage: $(basename "$0") [command] [options]

Commands:
start Install (if needed), configure, and launch kc-agent (default)
stop Stop background kc-agent instance
status Check kc-agent process and health endpoint
logs Display kc-agent log output
help Show this help message

Options:
-o, --origin <urls> Allowed origin URL(s) (comma-separated)
Default: http://localhost:8080,http://127.0.0.1:8080
-p, --port <port> kc-agent local health/listen port (default: 8585)
-f, --foreground Run kc-agent in foreground instead of backgrounding
--no-install Do not attempt Homebrew installation if kc-agent is missing
-h, --help Show this help message
EOF
}

while [ $# -gt 0 ]; do
case "$1" in
start|stop|status|logs|help)
CMD="$1"
shift
;;
-o|--origin)
[ $# -gt 1 ] || { echo "ERROR: --origin requires an argument" >&2; exit 1; }
ORIGIN="$2"
shift 2
;;
--origin=*)
ORIGIN="${1#*=}"
shift
;;
-p|--port)
[ $# -gt 1 ] || { echo "ERROR: --port requires an argument" >&2; exit 1; }
PORT="$2"
shift 2
;;
--port=*)
PORT="${1#*=}"
shift
;;
-f|--foreground)
FOREGROUND=1
shift
;;
--no-install)
AUTO_INSTALL=0
shift
;;
-h|--help)
CMD="help"
shift
;;
*)
if [[ "$1" =~ ^https?:// ]]; then
ORIGIN="$1"
shift
else
echo "ERROR: Unknown option or command: $1" >&2
usage >&2
exit 1
fi
;;
esac
done

case "$CMD" in
help)
usage
exit 0
;;
stop)
if [ -f "$PID_FILE" ]; then
PID=$(<"$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
kill "$PID" 2>/dev/null || true
echo "==> Stopped kc-agent (PID: $PID)"
else
echo "==> kc-agent process ($PID) was not running"
fi
rm -f "$PID_FILE"
else
echo "==> No active kc-agent PID file found at $PID_FILE"
fi
exit 0
;;
status)
HEALTH_URL="http://127.0.0.1:${PORT}/health"
if curl --silent --fail --max-time 2 "$HEALTH_URL" >/dev/null 2>&1; then
echo "==> kc-agent is running and healthy at $HEALTH_URL"
if [ -f "$PID_FILE" ]; then
echo "==> Process PID: $(<"$PID_FILE")"
fi
exit 0
fi
if [ -f "$PID_FILE" ]; then
PID=$(<"$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
echo "==> kc-agent process $PID is running but $HEALTH_URL is not responding" >&2
exit 1
fi
fi
echo "==> kc-agent is not running"
exit 3
;;
logs)
if [ -f "$LOG_FILE" ]; then
tail -n 50 "$LOG_FILE"
else
echo "==> No log file found at $LOG_FILE"
fi
exit 0
;;
start)
ORIGIN="${ORIGIN:-http://localhost:8080,http://127.0.0.1:8080}"
mkdir -p "$STATE_DIR"

# Optimize client environment: disable in-cluster Kagenti DNS queries
export KAGENTI_CONTROLLER_URL="${KAGENTI_CONTROLLER_URL:-none}"
export KC_ALLOWED_ORIGINS="${ORIGIN}"

# Check if already running and healthy (background mode only)
if [ "$FOREGROUND" -eq 0 ]; then
if curl --silent --fail --max-time 1 "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; then
echo "==> kc-agent is already running and healthy at http://127.0.0.1:${PORT}/health"
echo "==> Allowed origin(s): ${ORIGIN}"
exit 0
fi
fi

# Ensure kc-agent is installed
if ! command -v kc-agent >/dev/null 2>&1; then
if [ "$AUTO_INSTALL" -eq 1 ] && command -v brew >/dev/null 2>&1; then
echo "==> kc-agent not found in PATH; installing from kubestellar/tap via Homebrew..."
brew tap kubestellar/tap
brew install kc-agent
else
echo "ERROR: kc-agent is not installed and cannot be auto-installed." >&2
echo "Please install Homebrew (https://brew.sh) or install kc-agent manually:" >&2
echo " brew tap kubestellar/tap && brew install kc-agent" >&2
exit 1
fi
fi

# Foreground execution
if [ "$FOREGROUND" -eq 1 ]; then
echo "==> Starting kc-agent in foreground..."
echo "==> Allowed origins: ${ORIGIN}"
echo "==> KAGENTI_CONTROLLER_URL: ${KAGENTI_CONTROLLER_URL}"
exec kc-agent -allowed-origins "${ORIGIN}"
fi

# Clean up stale PID file if process died
if [ -f "$PID_FILE" ]; then
OLD_PID=$(<"$PID_FILE")
if kill -0 "$OLD_PID" 2>/dev/null; then
kill "$OLD_PID" 2>/dev/null || true
sleep 0.5
fi
rm -f "$PID_FILE"
fi

# Background execution
echo "==> Starting kc-agent in background..."
echo "==> Allowed origins: ${ORIGIN}"
echo "==> KAGENTI_CONTROLLER_URL: ${KAGENTI_CONTROLLER_URL}"
nohup kc-agent -allowed-origins "${ORIGIN}" > "$LOG_FILE" 2>&1 &
AGENT_PID=$!
echo "$AGENT_PID" > "$PID_FILE"

echo "==> Waiting for kc-agent health probe at http://127.0.0.1:${PORT}/health..."
DEADLINE=15
START_TIME=$(date +%s)
while true; do
if ! kill -0 "$AGENT_PID" 2>/dev/null; then
echo "ERROR: kc-agent process ($AGENT_PID) exited unexpectedly!" >&2
[ -f "$LOG_FILE" ] && tail -n 20 "$LOG_FILE" >&2
rm -f "$PID_FILE"
exit 1
fi
if curl --silent --fail --max-time 1 "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; then
echo "==> kc-agent is healthy and connected! (PID: $AGENT_PID)"
echo "==> Console client connectivity active for origin(s): ${ORIGIN}"
echo "==> Log file: ${LOG_FILE}"
break
fi
NOW=$(date +%s)
if [ $((NOW - START_TIME)) -ge "$DEADLINE" ]; then
echo "ERROR: Timed out waiting for kc-agent to become healthy on port ${PORT}." >&2
[ -f "$LOG_FILE" ] && tail -n 20 "$LOG_FILE" >&2
exit 1
fi
sleep 0.5
done
;;
esac
28 changes: 28 additions & 0 deletions files/lima/bluefin-server-kiosk.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Lima VM configuration template for Bluefin Server KubeStellar Kiosk appliance.
#
# Enables running Bluefin Server directly in Lima with hardware acceleration (KVM/QEMU)
# and port forwarding for KubeStellar Console (8080) and Kubernetes API (6443).
#
# Note: The images section can be overridden at creation time with:
# limactl create --set '.images[0].location = "/path/to/target.raw"' files/lima/bluefin-server-kiosk.yaml
images:
- location: "{{.Dir}}/target.raw"
arch: "x86_64"

vmType: "qemu"
arch: "x86_64"
cpus: 4
memory: "8GiB"
disk: "20GiB"

containerd:
system: false
user: false

mounts: []

portForwards:
- guestPort: 8080
hostPort: 8080
- guestPort: 6443
hostPort: 6443
Loading