From 9a662c12514de8db76fe1673632267339435643c Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 8 Apr 2026 13:20:32 +0000 Subject: [PATCH] =?UTF-8?q?=EC=8A=A4=EB=A7=88=ED=8A=B8=20=EC=9E=AC?= =?UTF-8?q?=EC=8B=A4=ED=96=89:=20=EA=B8=B0=EC=A1=B4=20VM/CT/VPN=20?= =?UTF-8?q?=EA=B0=90=EC=A7=80=ED=95=98=EC=97=AC=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=EB=90=9C=20Phase=20=EC=9E=90=EB=8F=99=20=EC=8A=A4=ED=82=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Phase 4: VM이 이미 존재하면 PBS 복원 스킵 (qm status 체크) - Phase 5: ubuntu-api CT가 이미 있으면 생성 스킵 (200~299 스캔) - Phase 6: CT에 Tailscale + API 코드가 있으면 환경 구축 스킵 - PBS 인증 실패 시 exit 대신 스킵 후 계속 진행 - 상태 파일 없이 시스템 상태만 보고 판단 Co-Authored-By: Claude Opus 4.6 (1M context) --- pharmq-setup.sh | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/pharmq-setup.sh b/pharmq-setup.sh index bd3442a..99e461f 100644 --- a/pharmq-setup.sh +++ b/pharmq-setup.sh @@ -336,6 +336,14 @@ phase3_collect_info() { phase4_pbs_restore() { print_phase "Phase 4/8: PBS 등록 + Windows VM 복원" + # 이미 VM이 존재하면 스킵 + local TARGET_CHECK="${ARGS_VM_VMID:-201}" + if qm status "$TARGET_CHECK" 2>/dev/null | grep -q "running\|stopped"; then + VM_VMID="$TARGET_CHECK" + print_ok "VM $VM_VMID 이미 존재 — PBS 복원 스킵" + return 0 + fi + # PBS 스토리지 등록 print_step "PBS 스토리지 등록 중..." if pvesm status 2>/dev/null | grep -q "^${PBS_STORAGE_NAME} "; then @@ -369,8 +377,10 @@ phase4_pbs_restore() { PBS_CSRF=$(python3 -c 'import json; data=json.load(open("/tmp/pbs_auth.json")); print(data["data"]["CSRFPreventionToken"])' 2>/dev/null) if [ -z "$PBS_TICKET" ]; then - print_err "PBS API 인증 실패" - exit 1 + print_err "PBS API 인증 실패 (PBS 서버 연결 확인 필요)" + print_warn "VM 복원을 건너뛰고 계속 진행합니다." + VM_VMID="" + return 1 fi print_ok "PBS API 인증 완료" @@ -579,6 +589,26 @@ PYEOF phase5_create_ct() { print_phase "Phase 5/8: Ubuntu CT 생성" + # 이미 ubuntu-api CT가 존재하면 스킵 + for vmid in $(seq 200 299); do + if pct status "$vmid" 2>/dev/null | grep -q "running\|stopped"; then + local ct_hostname + ct_hostname=$(pct config "$vmid" 2>/dev/null | grep "^hostname:" | awk '{print $2}') + if [ "$ct_hostname" = "ubuntu-api" ]; then + CT_VMID="$vmid" + CT_LAN_IP=$(pct config "$vmid" 2>/dev/null | grep "^net0:" | grep -oP 'ip=\K[^/]+') + print_ok "CT $CT_VMID (ubuntu-api) 이미 존재 — 생성 스킵" + # CT가 꺼져있으면 시작 + if pct status "$vmid" 2>/dev/null | grep -q "stopped"; then + print_step "CT 시작 중..." + pct start "$vmid" + sleep 5 + fi + return 0 + fi + fi + done + # 템플릿 준비 print_step "Ubuntu 템플릿 확인 중..." if pveam list local 2>/dev/null | grep -q "$CT_TEMPLATE"; then @@ -662,6 +692,15 @@ phase6_setup_ct() { pct exec "$CT_VMID" -- bash -c "$1" } + # 이미 CT에 Tailscale이 등록되어있고 API 코드가 있으면 스킵 + local existing_vpn + existing_vpn=$(ct_exec "tailscale ip -4 2>/dev/null" 2>/dev/null | tr -d '[:space:]') + if [ -n "$existing_vpn" ] && ct_exec "test -d /srv/person-lookup-web-local" 2>/dev/null; then + CT_VPN_IP="$existing_vpn" + print_ok "CT 환경 이미 구축됨 (VPN: $CT_VPN_IP) — 스킵" + return 0 + fi + # 6-1. 기본 패키지 print_step "기본 패키지 설치 중..." ct_exec "apt-get update -qq && apt-get install -y curl git python3-pip python3-dev python3-venv pkg-config unixodbc unixodbc-dev build-essential" >/dev/null 2>&1