#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck disable=SC1091 . "$SCRIPT_DIR/common.sh" load_runtime_env mkdir -p "$STATE_DIR/run" "$STATE_DIR/logs" resolve_targets() { if [ $# -eq 0 ]; then echo "No target specified." >&2 exit 1 fi case "$1" in core) printf '%s\n' "ollama" "open-webui" ;; all) service_list ;; *) printf '%s\n' "$@" ;; esac } has_live_pid() { local service=$1 local pid_file pid_file=$(service_pid_file "$service") if [ -f "$pid_file" ]; then local pid pid=$(cat "$pid_file") if kill -0 "$pid" >/dev/null 2>&1; then return 0 fi fi return 1 } is_running() { local service=$1 has_live_pid "$service" || service_ready "$service" } service_ready() { local service=$1 case "$service" in ollama) curl -fsS "$(service_url "$service")/api/tags" >/dev/null 2>&1 ;; promptfoo) curl -fsS "$(service_url "$service")/health" >/dev/null 2>&1 ;; open-webui|transformerlab|chunkviz|embedding-atlas|unsloth|wiki) curl -fsS "$(service_url "$service")" >/dev/null 2>&1 ;; *) return 1 ;; esac } start_one() { local service=$1 local cmd local log_file local pid_file local attempt if has_live_pid "$service"; then echo "$service already running" return 0 fi if service_ready "$service"; then echo "$service already available" return 0 fi case "$service" in open-webui) start_one ollama ;; *) ;; esac cmd=$(service_command "$service") log_file=$(service_log_file "$service") pid_file=$(service_pid_file "$service") if command -v setsid >/dev/null 2>&1; then nohup setsid bash -lc "$cmd" >"$log_file" 2>&1 & else nohup bash -lc "$cmd" >"$log_file" 2>&1 & fi echo $! >"$pid_file" for attempt in $(seq 1 60); do if service_ready "$service"; then echo "started $service" return 0 fi if ! has_live_pid "$service"; then rm -f "$pid_file" echo "failed to start $service; check $log_file" >&2 exit 1 fi sleep 1 done echo "$service did not become ready in time; check $log_file" >&2 exit 1 } stop_one() { local service=$1 local pid_file pid_file=$(service_pid_file "$service") if [ ! -f "$pid_file" ]; then echo "$service not running" return 0 fi local pid pid=$(cat "$pid_file") if kill -0 "$pid" >/dev/null 2>&1; then kill "$pid" >/dev/null 2>&1 || true sleep 2 if kill -0 "$pid" >/dev/null 2>&1; then kill -9 "$pid" >/dev/null 2>&1 || true fi fi rm -f "$pid_file" echo "stopped $service" } status_one() { local service=$1 if service_ready "$service"; then printf 'RUNNING %-15s %s\n' "$service" "$(service_url "$service")" elif has_live_pid "$service"; then printf 'STARTING %-15s %s\n' "$service" "$(service_url "$service")" else printf 'STOPPED %-15s %s\n' "$service" "$(service_url "$service")" fi } urls() { cat </dev/null 2>&1 & echo "started Kiln from $KILN_LINUX_BIN" return 0 fi echo "Kiln is not installed." >&2 exit 1 } show_logs() { local service=$1 local log_file log_file=$(service_log_file "$service") if [ ! -f "$log_file" ]; then echo "No log file for $service" >&2 exit 1 fi tail -n 80 "$log_file" } main() { local cmd=${1:-} shift || true ensure_runtime_env case "$cmd" in start) while IFS= read -r service; do start_one "$service" done < <(resolve_targets "$@") ;; stop) while IFS= read -r service; do stop_one "$service" done < <(resolve_targets "$@") ;; status) if [ $# -eq 0 ]; then set -- all fi while IFS= read -r service; do status_one "$service" done < <(resolve_targets "$@") ;; urls) urls ;; open) if [ "${1:-}" != "kiln" ]; then echo "Only 'open kiln' is supported." >&2 exit 1 fi open_kiln ;; logs) if [ $# -ne 1 ]; then echo "Usage: ./labctl logs " >&2 exit 1 fi show_logs "$1" ;; *) echo "Unknown command: $cmd" >&2 exit 1 ;; esac } main "$@"