Some checks failed
Test / test (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
324 lines
10 KiB
Bash
Executable File
324 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
source ~/.bashrc
|
|
# Complete All Remaining Tasks Automatically
|
|
# Uses successful methods from previous deployments
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
# Load environment variables
|
|
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
set -a
|
|
source <(grep -v '^#' "$PROJECT_ROOT/.env" | grep -v '^$' | sed 's/#.*$//' | grep '=')
|
|
set +a
|
|
fi
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
log_step() { echo -e "\n${BLUE}=== $1 ===${NC}"; }
|
|
|
|
SSH_KEY="${SSH_KEY:-$HOME/.ssh/id_ed25519_proxmox}"
|
|
SSH_OPTS="-i $SSH_KEY -o StrictHostKeyChecking=no"
|
|
VM_USER="${VM_USER:-ubuntu}"
|
|
|
|
# VM IPs (discovered earlier)
|
|
VM_100_IP="192.168.1.57" # cloudflare-tunnel
|
|
VM_101_IP="192.168.1.188" # k3s-master
|
|
VM_102_IP="192.168.1.121" # git-server
|
|
VM_103_IP="192.168.1.82" # observability
|
|
|
|
PROXMOX_HOST="${PROXMOX_ML110_IP:-192.168.1.206}"
|
|
|
|
# Step 1: Install K3s on VM 101
|
|
install_k3s() {
|
|
log_step "Step 1: Installing K3s on VM 101 (k3s-master)"
|
|
|
|
log_info "Installing K3s on $VM_101_IP..."
|
|
ssh $SSH_OPTS "${VM_USER}@${VM_101_IP}" <<'K3S_EOF'
|
|
set -e
|
|
echo "=== Installing K3s ==="
|
|
|
|
# Check if already installed
|
|
if command -v k3s &>/dev/null; then
|
|
echo "K3s already installed"
|
|
k3s --version
|
|
sudo systemctl is-active k3s && echo "K3s is running" || echo "K3s is not running"
|
|
exit 0
|
|
fi
|
|
|
|
# Install K3s
|
|
echo "Downloading and installing K3s..."
|
|
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=latest sh -
|
|
|
|
# Verify installation
|
|
if command -v k3s &>/dev/null; then
|
|
echo "K3s installed successfully"
|
|
k3s --version
|
|
|
|
# Start and enable service
|
|
sudo systemctl enable k3s
|
|
sudo systemctl start k3s
|
|
|
|
# Wait for service to be ready
|
|
echo "Waiting for K3s to start..."
|
|
sleep 15
|
|
|
|
# Verify service status
|
|
if sudo systemctl is-active --quiet k3s; then
|
|
echo "✓ K3s service is running"
|
|
sudo k3s kubectl get nodes
|
|
sudo k3s kubectl get pods --all-namespaces
|
|
else
|
|
echo "✗ K3s service failed to start"
|
|
sudo systemctl status k3s --no-pager | head -20
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "✗ K3s installation failed"
|
|
exit 1
|
|
fi
|
|
K3S_EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
log_info "✓ K3s installed and running on VM 101"
|
|
else
|
|
log_error "K3s installation failed"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Step 2: Install and Configure Cloudflare Tunnel on VM 100
|
|
install_cloudflare_tunnel() {
|
|
log_step "Step 2: Installing Cloudflare Tunnel on VM 100 (cloudflare-tunnel)"
|
|
|
|
local tunnel_token="${CLOUDFLARE_TUNNEL_TOKEN:-}"
|
|
if [ -z "$tunnel_token" ]; then
|
|
log_warn "CLOUDFLARE_TUNNEL_TOKEN not set. Skipping Cloudflare Tunnel configuration."
|
|
log_info "Installing cloudflared only..."
|
|
fi
|
|
|
|
log_info "Installing cloudflared on $VM_100_IP..."
|
|
ssh $SSH_OPTS "${VM_USER}@${VM_100_IP}" <<CLOUDFLARE_EOF
|
|
set -e
|
|
echo "=== Installing Cloudflare Tunnel ==="
|
|
|
|
# Install cloudflared
|
|
if ! command -v cloudflared &>/dev/null; then
|
|
echo "Downloading cloudflared..."
|
|
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /tmp/cloudflared
|
|
sudo mv /tmp/cloudflared /usr/local/bin/cloudflared
|
|
sudo chmod +x /usr/local/bin/cloudflared
|
|
cloudflared --version
|
|
echo "✓ cloudflared installed"
|
|
else
|
|
echo "cloudflared already installed"
|
|
cloudflared --version
|
|
fi
|
|
|
|
# Configure tunnel if token is provided
|
|
if [ -n "${tunnel_token}" ]; then
|
|
echo "Configuring Cloudflare Tunnel..."
|
|
sudo mkdir -p /etc/cloudflared
|
|
|
|
# Create config file
|
|
sudo tee /etc/cloudflared/config.yml > /dev/null <<CONFIG_EOF
|
|
tunnel: \$(cloudflared tunnel token ${tunnel_token} | grep -oP 'Tunnel ID: \K[^ ]+' || echo '')
|
|
credentials-file: /etc/cloudflared/credentials.json
|
|
|
|
ingress:
|
|
- hostname: grafana.${CLOUDFLARE_DOMAIN:-d-bis.org}
|
|
service: http://${VM_103_IP}:3000
|
|
- hostname: prometheus.${CLOUDFLARE_DOMAIN:-d-bis.org}
|
|
service: http://${VM_103_IP}:9090
|
|
- hostname: git.${CLOUDFLARE_DOMAIN:-d-bis.org}
|
|
service: http://${VM_102_IP}:3000
|
|
- hostname: proxmox.${CLOUDFLARE_DOMAIN:-d-bis.org}
|
|
service: https://${PROXMOX_HOST}:8006
|
|
- service: http_status:404
|
|
CONFIG_EOF
|
|
|
|
# Install as systemd service
|
|
sudo cloudflared service install ${tunnel_token}
|
|
|
|
# Start service
|
|
sudo systemctl enable cloudflared
|
|
sudo systemctl start cloudflared
|
|
|
|
sleep 5
|
|
if sudo systemctl is-active --quiet cloudflared; then
|
|
echo "✓ Cloudflare Tunnel service is running"
|
|
sudo systemctl status cloudflared --no-pager | head -10
|
|
else
|
|
echo "⚠ Cloudflare Tunnel service may need manual configuration"
|
|
sudo systemctl status cloudflared --no-pager | head -10
|
|
fi
|
|
else
|
|
echo "⚠ Tunnel token not provided. Install manually with:"
|
|
echo " cloudflared tunnel login"
|
|
echo " cloudflared tunnel create <tunnel-name>"
|
|
echo " cloudflared tunnel route dns <tunnel-name> <hostname>"
|
|
fi
|
|
CLOUDFLARE_EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
log_info "✓ Cloudflare Tunnel installed on VM 100"
|
|
else
|
|
log_warn "Cloudflare Tunnel installation had issues (may need manual config)"
|
|
fi
|
|
}
|
|
|
|
# Step 3: Configure Gitea Initial Setup (via API)
|
|
configure_gitea() {
|
|
log_step "Step 3: Configuring Gitea Initial Setup"
|
|
|
|
log_info "Waiting for Gitea to be ready..."
|
|
local max_attempts=30
|
|
local attempt=0
|
|
local gitea_ready=false
|
|
|
|
while [ $attempt -lt $max_attempts ]; do
|
|
if curl -s "http://${VM_102_IP}:3000" | grep -q "Gitea"; then
|
|
gitea_ready=true
|
|
break
|
|
fi
|
|
sleep 2
|
|
attempt=$((attempt + 1))
|
|
done
|
|
|
|
if [ "$gitea_ready" = false ]; then
|
|
log_warn "Gitea not ready after $max_attempts attempts"
|
|
log_info "Gitea initial setup must be completed manually:"
|
|
log_info " 1. Visit http://${VM_102_IP}:3000"
|
|
log_info " 2. Complete the installation wizard"
|
|
return 0
|
|
fi
|
|
|
|
log_info "Gitea is ready. Attempting automated setup..."
|
|
|
|
# Try to configure via API (Gitea 1.19+ supports installation API)
|
|
local response=$(curl -s -X POST "http://${VM_102_IP}:3000/api/v1/setup" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"db_type": "sqlite3",
|
|
"db_host": "",
|
|
"db_user": "",
|
|
"db_passwd": "",
|
|
"db_name": "gitea",
|
|
"ssl_mode": "disable",
|
|
"db_path": "data/gitea.db",
|
|
"app_name": "Gitea",
|
|
"repo_root_path": "/data/git/repositories",
|
|
"lfs_root_path": "/data/git/lfs",
|
|
"run_user": "git",
|
|
"domain": "'${VM_102_IP}'",
|
|
"ssh_port": 2222,
|
|
"http_port": 3000,
|
|
"app_url": "http://'${VM_102_IP}':3000/",
|
|
"log_root_path": "/data/gitea/log",
|
|
"smtp_host": "",
|
|
"smtp_from": "",
|
|
"smtp_user": "",
|
|
"smtp_passwd": "",
|
|
"admin_name": "admin",
|
|
"admin_passwd": "admin123",
|
|
"admin_confirm_passwd": "admin123",
|
|
"admin_email": "admin@'${CLOUDFLARE_DOMAIN:-d-bis.org}'"
|
|
}' 2>/dev/null || echo "")
|
|
|
|
if echo "$response" | grep -q "success\|created"; then
|
|
log_info "✓ Gitea configured successfully"
|
|
log_info " Admin user: admin"
|
|
log_info " Admin password: admin123 (change on first login!)"
|
|
else
|
|
log_warn "Automated Gitea setup may have failed"
|
|
log_info "Complete setup manually at http://${VM_102_IP}:3000"
|
|
log_info "Or check if setup was already completed"
|
|
fi
|
|
}
|
|
|
|
# Step 4: Final Status and Summary
|
|
final_summary() {
|
|
log_step "Final Summary"
|
|
|
|
echo ""
|
|
log_info "VM Status:"
|
|
ssh $SSH_OPTS "root@$PROXMOX_HOST" "qm list | grep -E '(100|101|102|103)'"
|
|
|
|
echo ""
|
|
log_info "Service Status:"
|
|
|
|
# Check K3s
|
|
if ssh $SSH_OPTS "${VM_USER}@${VM_101_IP}" "sudo systemctl is-active k3s &>/dev/null && echo 'active' || echo 'inactive'" | grep -q "active"; then
|
|
log_info " ✓ K3s (VM 101): Running"
|
|
ssh $SSH_OPTS "${VM_USER}@${VM_101_IP}" "sudo k3s kubectl get nodes 2>/dev/null | head -3" || true
|
|
else
|
|
log_warn " ✗ K3s (VM 101): Not running"
|
|
fi
|
|
|
|
# Check Cloudflare Tunnel
|
|
if ssh $SSH_OPTS "${VM_USER}@${VM_100_IP}" "sudo systemctl is-active cloudflared &>/dev/null && echo 'active' || echo 'inactive'" 2>/dev/null | grep -q "active"; then
|
|
log_info " ✓ Cloudflare Tunnel (VM 100): Running"
|
|
else
|
|
log_warn " ⚠ Cloudflare Tunnel (VM 100): May need manual configuration"
|
|
fi
|
|
|
|
# Check Gitea
|
|
if curl -s "http://${VM_102_IP}:3000" | grep -q "Gitea"; then
|
|
log_info " ✓ Gitea (VM 102): Running at http://${VM_102_IP}:3000"
|
|
else
|
|
log_warn " ✗ Gitea (VM 102): Not accessible"
|
|
fi
|
|
|
|
# Check Observability
|
|
if curl -s "http://${VM_103_IP}:9090/-/healthy" &>/dev/null; then
|
|
log_info " ✓ Prometheus (VM 103): Running at http://${VM_103_IP}:9090"
|
|
else
|
|
log_warn " ✗ Prometheus (VM 103): Not accessible"
|
|
fi
|
|
|
|
if curl -s "http://${VM_103_IP}:3000/api/health" &>/dev/null; then
|
|
log_info " ✓ Grafana (VM 103): Running at http://${VM_103_IP}:3000"
|
|
else
|
|
log_warn " ✗ Grafana (VM 103): Not accessible"
|
|
fi
|
|
|
|
echo ""
|
|
log_info "Service URLs:"
|
|
log_info " K3s Dashboard: Use 'kubectl' commands on VM 101"
|
|
log_info " Gitea: http://${VM_102_IP}:3000"
|
|
log_info " Prometheus: http://${VM_103_IP}:9090"
|
|
log_info " Grafana: http://${VM_103_IP}:3000 (admin/admin)"
|
|
|
|
echo ""
|
|
log_warn "Tasks Requiring Manual Steps or External Dependencies:"
|
|
log_info " 1. Join R630 to cluster: SSH to R630 (192.168.1.49) not accessible"
|
|
log_info " 2. Configure NFS storage: NFS server (10.10.10.1) not reachable"
|
|
log_info " 3. Configure VLAN bridges on R630: Requires SSH to R630"
|
|
log_info " 4. Complete Gitea setup: May need manual web UI access if API setup failed"
|
|
|
|
echo ""
|
|
log_info "✓ All automated tasks completed!"
|
|
}
|
|
|
|
main() {
|
|
log_step "Completing All Remaining Tasks"
|
|
|
|
install_k3s
|
|
install_cloudflare_tunnel
|
|
configure_gitea
|
|
final_summary
|
|
}
|
|
|
|
main "$@"
|
|
|