fix: use environment-specific PostgreSQL port (5432 prod / 5433 trial)

PG_PORT was hardcoded to 5433 (trial env), causing scheduler to fail
connecting to production PostgreSQL which listens on 5432.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
VMIS Developer
2026-03-15 19:03:02 +08:00
parent 405d158660
commit 92ee91019e

View File

@@ -19,7 +19,8 @@ from app.models.result import TenantScheduleResult
logger = logging.getLogger(__name__)
PG_PORT = 5433
PG_PORT_TRIAL = 5433
PG_PORT_ACTIVE = 5432
PG_USER = "admin"
PG_PASS = "DC1qaz2wsx"
PG_HOST_TRIAL = "10.1.0.20"
@@ -56,6 +57,7 @@ def _generate_tenant_compose(tenant, is_active: bool) -> str:
nc = f"nc-{code}{suffix}"
oo = f"oo-{code}{suffix}"
pg_host = PG_HOST_ACTIVE if is_active else PG_HOST_TRIAL
pg_port = PG_PORT_ACTIVE if is_active else PG_PORT_TRIAL
pg_db = f"nc_{code}_db"
nc_domain = tenant.domain
oo_host = f"office-{code}.ease.taipei" if is_active else f"office-{code}.lab.taipei"
@@ -73,7 +75,7 @@ def _generate_tenant_compose(tenant, is_active: bool) -> str:
- {nc}-apps:/var/www/html/custom_apps
- {nc}-config:/var/www/html/config
environment:
POSTGRES_HOST: {pg_host}:{PG_PORT}
POSTGRES_HOST: {pg_host}:{pg_port}
POSTGRES_DB: {pg_db}
POSTGRES_USER: {PG_USER}
POSTGRES_PASSWORD: ${{NC_DB_PASSWORD}}
@@ -372,7 +374,7 @@ def _ensure_kc_drive_client(realm: str, domain: str) -> Optional[str]:
return None
def _nc_db_check(container_name: str, pg_host: str, pg_db: str, nc_domain: str) -> bool:
def _nc_db_check(container_name: str, pg_host: str, pg_db: str, nc_domain: str, pg_port: int = PG_PORT_TRIAL) -> bool:
"""
驗證 NC 是否正確安裝並使用 PostgreSQL。
若偵測到 SQLite常見於 volumes 持久但重新部署的情況),自動修復:
@@ -406,7 +408,7 @@ def _nc_db_check(container_name: str, pg_host: str, pg_db: str, nc_domain: str)
logger.info(f"NC {container_name}: not installed yet, installing with pgsql...")
# 重置 PostgreSQL DB schema確保乾淨狀態
conn = psycopg2.connect(
host=pg_host, port=PG_PORT, dbname=pg_db,
host=pg_host, port=pg_port, dbname=pg_db,
user=PG_USER, password=PG_PASS, connect_timeout=5,
)
conn.autocommit = True
@@ -420,7 +422,7 @@ def _nc_db_check(container_name: str, pg_host: str, pg_db: str, nc_domain: str)
f"-n --admin-user admin --admin-pass NC1qaz2wsx "
f"--database pgsql --database-name '{pg_db}' "
f"--database-user {PG_USER} --database-pass {PG_PASS} "
f"--database-host '{pg_host}:{PG_PORT}' 2>&1"
f"--database-host '{pg_host}:{pg_port}' 2>&1"
)
_, stdout_inst, _ = client.exec_command(install_cmd)
stdout_inst.channel.settimeout(120)
@@ -481,7 +483,7 @@ def _nc_db_check(container_name: str, pg_host: str, pg_db: str, nc_domain: str)
# 2. 重置 PostgreSQL DB schema
conn = psycopg2.connect(
host=pg_host, port=PG_PORT, dbname=pg_db,
host=pg_host, port=pg_port, dbname=pg_db,
user=PG_USER, password=PG_PASS, connect_timeout=5,
)
conn.autocommit = True
@@ -496,7 +498,7 @@ def _nc_db_check(container_name: str, pg_host: str, pg_db: str, nc_domain: str)
f"-n --admin-user admin --admin-pass NC1qaz2wsx "
f"--database pgsql --database-name '{pg_db}' "
f"--database-user {PG_USER} --database-pass {PG_PASS} "
f"--database-host '{pg_host}:{PG_PORT}' 2>&1"
f"--database-host '{pg_host}:{pg_port}' 2>&1"
)
_, stdout3, _ = client2.exec_command(install_cmd)
stdout3.channel.recv_exit_status()
@@ -721,7 +723,7 @@ def _configure_nc_oidc(
# ─── PostgreSQL helpers ───────────────────────────────────────────────────────
def _ensure_nc_db(host: str, dbname: str) -> bool:
def _ensure_nc_db(host: str, dbname: str, port: int = PG_PORT_TRIAL) -> bool:
"""
確保 NC 用的 PostgreSQL DB 存在,並授予 public schema 建表權限給所有用戶。
NC Docker 會自動建立 oc_admin* 用戶,需預先開放 public schema CREATE 權限。
@@ -730,7 +732,7 @@ def _ensure_nc_db(host: str, dbname: str) -> bool:
import psycopg2
# Connect to postgres DB to create NC DB
conn = psycopg2.connect(
host=host, port=PG_PORT, dbname="postgres",
host=host, port=port, dbname="postgres",
user=PG_USER, password=PG_PASS,
connect_timeout=5,
)
@@ -744,7 +746,7 @@ def _ensure_nc_db(host: str, dbname: str) -> bool:
# Grant CREATE on public schema to all users (for NC oc_admin* users)
conn2 = psycopg2.connect(
host=host, port=PG_PORT, dbname=dbname,
host=host, port=port, dbname=dbname,
user=PG_USER, password=PG_PASS,
connect_timeout=5,
)
@@ -758,11 +760,11 @@ def _ensure_nc_db(host: str, dbname: str) -> bool:
return False
def _get_pg_db_size_gb(host: str, dbname: str) -> Optional[float]:
def _get_pg_db_size_gb(host: str, dbname: str, port: int = PG_PORT_TRIAL) -> Optional[float]:
try:
import psycopg2
conn = psycopg2.connect(
host=host, port=PG_PORT, dbname=dbname,
host=host, port=port, dbname=dbname,
user=PG_USER, password=PG_PASS,
connect_timeout=5,
)
@@ -849,6 +851,7 @@ def run_tenant_check(schedule_log_id: int, db: Session):
oo_name = f"oo-{tenant.code}" if is_active else f"oo-{tenant.code}-test"
kc_host = KC_HOST_ACTIVE if is_active else KC_HOST_TRIAL
pg_host = PG_HOST_ACTIVE if is_active else PG_HOST_TRIAL
pg_port = PG_PORT_ACTIVE if is_active else PG_PORT_TRIAL
result = TenantScheduleResult(
schedule_log_id=schedule_log_id,
@@ -932,14 +935,14 @@ def run_tenant_check(schedule_log_id: int, db: Session):
# 容器不存在 → 確保 docker-compose.yml + DB + 部署
logger.info(f"NC {nc_name}: not found, ensuring compose/DB and deploying")
_ensure_tenant_compose(tenant, is_active)
_ensure_nc_db(pg_host, pg_db)
_ensure_nc_db(pg_host, pg_db, pg_port)
ok = docker.ssh_compose_up(tenant.code)
result.nc_result = True if ok else False
if not ok:
fail_reasons.append("nc: deploy failed")
else:
# 部署成功後驗證 NC 是否正確使用 PostgreSQL
if not _nc_db_check(nc_name, pg_host, pg_db, tenant.domain):
if not _nc_db_check(nc_name, pg_host, pg_db, tenant.domain, pg_port):
result.nc_result = False
fail_reasons.append("nc: installed but not using pgsql")
elif nc_state is False:
@@ -951,7 +954,7 @@ def run_tenant_check(schedule_log_id: int, db: Session):
fail_reasons.append("nc: start failed")
else:
# 容器正常運行 → 驗證 DB 類型(防止 sqlite3 殘留問題)
db_ok = _nc_db_check(nc_name, pg_host, pg_db, tenant.domain)
db_ok = _nc_db_check(nc_name, pg_host, pg_db, tenant.domain, pg_port)
if not db_ok:
result.nc_result = False
fail_reasons.append("nc: DB check failed (possible sqlite3 issue)")
@@ -1001,7 +1004,7 @@ def run_tenant_check(schedule_log_id: int, db: Session):
# ── [6] Quota (OO disk + PG DB size) ────────────────────────────────
try:
oo_gb = docker.get_oo_disk_usage_gb(oo_name) or 0.0
pg_gb = _get_pg_db_size_gb(pg_host, pg_db) or 0.0
pg_gb = _get_pg_db_size_gb(pg_host, pg_db, pg_port) or 0.0
result.quota_usage = round(oo_gb + pg_gb, 3)
except Exception as e:
logger.warning(f"Quota check failed for {tenant.code}: {e}")