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