Update ISO installer tiers and backend deployment
This commit is contained in:
1 parent
79784a6743
commit
56668f7bdc
38 files changed
+7206
-175
No files matched your search
+156
-16
@@ -1,17 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
# ─────────────────────────────────────────────
|
||||
# Cezen AI Suite — Entry Level Installer
|
||||
# Nexus One AI — Installer
|
||||
# Usage:
|
||||
# sudo bash install.sh → Phase 1 (drivers + schedules reboot → Phase 2)
|
||||
# sudo bash install.sh --phase=2 → Phase 2 (all software, run after reboot)
|
||||
# sudo bash install.sh → auto-detect tier, Phase 1
|
||||
# sudo bash install.sh --tier=starter → Starter tier, Phase 1
|
||||
# sudo bash install.sh --tier=basic → Basic tier, Phase 1
|
||||
# sudo bash install.sh --tier=pro → Pro tier, Phase 1
|
||||
# sudo bash install.sh --tier=max → Max tier, Phase 1
|
||||
# sudo bash install.sh --phase=2 --tier=... → Phase 2 only (post-reboot)
|
||||
# sudo bash install.sh --software-only → install on customer-owned hardware
|
||||
# sudo bash install.sh --feasibility-only → scan hardware and exit
|
||||
# sudo bash install.sh --skip-model-pull → install Ollama without preloading models
|
||||
# ─────────────────────────────────────────────
|
||||
set -e
|
||||
|
||||
TIER="entry"
|
||||
# Auto-detect tier from ISO marker written by autoinstall user-data
|
||||
if [ -f /opt/cezen/tier ]; then
|
||||
TIER="$(cat /opt/cezen/tier | tr -d '[:space:]')"
|
||||
elif [ -f /opt/aipackage/autoinstall/.tier ]; then
|
||||
TIER="$(cat /opt/aipackage/autoinstall/.tier | tr -d '[:space:]')"
|
||||
else
|
||||
TIER="basic" # default if no marker found
|
||||
fi
|
||||
PHASE="1"
|
||||
SKIP_ROLES=""
|
||||
SOFTWARE_ONLY=false
|
||||
FEASIBILITY_ONLY=false
|
||||
SKIP_MODEL_PULL=false
|
||||
PROFILE="auto"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ANSIBLE_DIR="$SCRIPT_DIR/ansible"
|
||||
FEASIBILITY_SCRIPT="$SCRIPT_DIR/scripts/cezen-feasibility.sh"
|
||||
FEASIBILITY_JSON="/opt/cezen/feasibility.json"
|
||||
|
||||
# Load saved config (written by web setup UI before phase 1)
|
||||
[ -f /opt/cezen/install.conf ] && source /opt/cezen/install.conf
|
||||
@@ -21,9 +41,24 @@ for arg in "$@"; do
|
||||
--tier=*) TIER="${arg#*=}" ;;
|
||||
--phase=*) PHASE="${arg#*=}" ;;
|
||||
--skip=*) SKIP_ROLES="${arg#*=}" ;;
|
||||
--profile=*) PROFILE="${arg#*=}" ;;
|
||||
--software-only) SOFTWARE_ONLY=true ;;
|
||||
--feasibility-only) FEASIBILITY_ONLY=true ;;
|
||||
--skip-model-pull) SKIP_MODEL_PULL=true ;;
|
||||
esac
|
||||
done
|
||||
|
||||
normalize_tier() {
|
||||
case "$TIER" in
|
||||
entry|basic) TIER="basic" ;;
|
||||
mid|pro) TIER="pro" ;;
|
||||
advanced|max) TIER="max" ;;
|
||||
starter) TIER="starter" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
normalize_tier
|
||||
|
||||
# ── Preflight ──────────────────────────────────
|
||||
check_root() {
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
@@ -52,6 +87,84 @@ install_ansible() {
|
||||
echo "✓ Ansible ready"
|
||||
}
|
||||
|
||||
append_skip_role() {
|
||||
local role="$1"
|
||||
if [ -z "$SKIP_ROLES" ]; then
|
||||
SKIP_ROLES="$role"
|
||||
elif [[ ",$SKIP_ROLES," != *",$role,"* ]]; then
|
||||
SKIP_ROLES="$SKIP_ROLES,$role"
|
||||
fi
|
||||
}
|
||||
|
||||
run_feasibility() {
|
||||
if [ -f "$FEASIBILITY_SCRIPT" ]; then
|
||||
bash "$FEASIBILITY_SCRIPT" "$FEASIBILITY_JSON"
|
||||
else
|
||||
echo "WARNING: Feasibility checker not found: $FEASIBILITY_SCRIPT"
|
||||
fi
|
||||
}
|
||||
|
||||
json_field() {
|
||||
local expr="$1"
|
||||
python3 - "$FEASIBILITY_JSON" "$expr" <<'PY'
|
||||
import json, sys
|
||||
try:
|
||||
d=json.load(open(sys.argv[1]))
|
||||
cur=d
|
||||
for part in sys.argv[2].split("."):
|
||||
cur=cur[part]
|
||||
print(cur)
|
||||
except Exception:
|
||||
print("")
|
||||
PY
|
||||
}
|
||||
|
||||
apply_profile_from_feasibility() {
|
||||
[ -f "$FEASIBILITY_JSON" ] || return 0
|
||||
local detected_profile
|
||||
detected_profile="$(json_field recommendation.recommended_profile)"
|
||||
if [ "$PROFILE" = "auto" ] && [ -n "$detected_profile" ]; then
|
||||
PROFILE="$detected_profile"
|
||||
fi
|
||||
|
||||
case "$PROFILE" in
|
||||
core)
|
||||
append_skip_role docker
|
||||
append_skip_role k3s
|
||||
append_skip_role ollama
|
||||
append_skip_role vllm
|
||||
append_skip_role jupyterlab
|
||||
append_skip_role chromadb
|
||||
append_skip_role mlflow
|
||||
append_skip_role minio
|
||||
append_skip_role monitoring
|
||||
SKIP_MODEL_PULL=true
|
||||
;;
|
||||
cpu-ai)
|
||||
append_skip_role k3s
|
||||
append_skip_role vllm
|
||||
append_skip_role mlflow
|
||||
append_skip_role minio
|
||||
SKIP_MODEL_PULL=true
|
||||
;;
|
||||
gpu-lite|gpu-starter)
|
||||
append_skip_role k3s
|
||||
append_skip_role mlflow
|
||||
append_skip_role minio
|
||||
SKIP_MODEL_PULL=true
|
||||
;;
|
||||
gpu-standard)
|
||||
append_skip_role mlflow
|
||||
append_skip_role minio
|
||||
;;
|
||||
gpu-pro|gpu-max)
|
||||
;;
|
||||
*)
|
||||
echo "WARNING: Unknown profile '$PROFILE'; using explicit skip list only."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
has_nvidia_pci_gpu() {
|
||||
for vendor_file in /sys/bus/pci/devices/*/vendor; do
|
||||
[ -f "$vendor_file" ] || continue
|
||||
@@ -70,7 +183,7 @@ has_working_nvidia_driver() {
|
||||
run_phase1() {
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ Cezen AI Suite — Phase 1: NVIDIA ║"
|
||||
echo "║ Nexus One AI — Phase 1: NVIDIA ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
|
||||
if ! has_nvidia_pci_gpu; then
|
||||
@@ -87,7 +200,7 @@ run_phase1() {
|
||||
# Register phase 2 as a one-shot systemd service so it runs after reboot
|
||||
cat > /etc/systemd/system/cezen-phase2.service << EOF
|
||||
[Unit]
|
||||
Description=Cezen AI Suite Phase 2 Installer
|
||||
Description=Nexus One AI Phase 2 Installer
|
||||
After=network-online.target nvidia-persistenced.service
|
||||
Wants=network-online.target
|
||||
|
||||
@@ -116,7 +229,7 @@ EOF
|
||||
run_phase2() {
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ Cezen AI Suite — Phase 2: Stack ║"
|
||||
echo "║ Nexus One AI — Phase 2: Stack ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
|
||||
GPU_AVAILABLE=false
|
||||
@@ -129,12 +242,26 @@ run_phase2() {
|
||||
fi
|
||||
|
||||
# Build skip_roles extra var (comma-separated list, empty string = skip nothing)
|
||||
EXTRA_VARS="tier=$TIER skip_roles=\"$SKIP_ROLES\" gpu_available=$GPU_AVAILABLE"
|
||||
EXTRA_VARS="tier=$TIER skip_roles=\"$SKIP_ROLES\" gpu_available=$GPU_AVAILABLE skip_model_pull=$SKIP_MODEL_PULL"
|
||||
echo "→ Tier: $TIER | Skip: ${SKIP_ROLES:-none}"
|
||||
echo "→ GPU available: $GPU_AVAILABLE"
|
||||
echo "→ Skip model pull: $SKIP_MODEL_PULL"
|
||||
|
||||
# Select Ansible playbook by tier
|
||||
case "$TIER" in
|
||||
starter) PLAYBOOK="$ANSIBLE_DIR/starter.yml" ;;
|
||||
basic|entry) PLAYBOOK="$ANSIBLE_DIR/entry.yml" ;;
|
||||
pro) PLAYBOOK="$ANSIBLE_DIR/pro.yml" ;;
|
||||
max) PLAYBOOK="$ANSIBLE_DIR/max.yml" ;;
|
||||
*)
|
||||
echo "ERROR: Unknown tier '$TIER'. Valid: starter | basic | pro | max"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "→ Playbook: $PLAYBOOK"
|
||||
ANSIBLE_STDOUT_CALLBACK=yaml \
|
||||
ansible-playbook -i localhost, -c local "$ANSIBLE_DIR/entry.yml" \
|
||||
ansible-playbook -i localhost, -c local "$PLAYBOOK" \
|
||||
-e "$EXTRA_VARS"
|
||||
|
||||
# Disable one-shot service so it doesn't run again on next reboot
|
||||
@@ -142,19 +269,32 @@ run_phase2() {
|
||||
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ Cezen AI Suite installation complete! ║"
|
||||
echo "║ Nexus One AI installation complete! ║"
|
||||
echo "║ Tier: $(printf '%-33s' "$TIER")║"
|
||||
echo "║ ║"
|
||||
echo "║ JupyterLab → http://localhost:8888 ║"
|
||||
echo "║ Ollama API → http://localhost:11434 ║"
|
||||
echo "║ MLflow → http://localhost:5000 ║"
|
||||
echo "║ MinIO → http://localhost:9001 ║"
|
||||
echo "║ Grafana → http://localhost:3000 ║"
|
||||
echo "║ Portal → http://localhost ║"
|
||||
echo "║ Ollama API → http://localhost:11434 ║"
|
||||
echo "║ vLLM API → http://localhost:8000 ║"
|
||||
echo "║ Grafana → http://localhost:3000 ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
}
|
||||
|
||||
# ── Main ───────────────────────────────────────
|
||||
check_root
|
||||
check_os
|
||||
|
||||
if [ "$FEASIBILITY_ONLY" = true ]; then
|
||||
run_feasibility
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_root
|
||||
run_feasibility
|
||||
|
||||
if [ "$SOFTWARE_ONLY" = true ]; then
|
||||
PHASE="2"
|
||||
apply_profile_from_feasibility
|
||||
fi
|
||||
|
||||
install_ansible
|
||||
|
||||
if [ "$PHASE" = "1" ]; then
|
||||
|
||||
Reference in new issue
Block a user