Fix factory reset and improve reset_stage CI job

- Add create_default_admin() call to factory reset (admin user wasn't being
  created after reset, only on server restart)
- Add retry logic to reset_stage CI job (3 attempts with 5s delay)
- Use proper context manager for httpx client
- Increase timeout to 120s for reset operation
- Add retry: 1 at job level for transient failures
This commit is contained in:
Mondo Diaz
2026-01-21 23:20:48 +00:00
parent 693613f111
commit 1ac75e1017
2 changed files with 49 additions and 28 deletions

View File

@@ -154,6 +154,7 @@ reset_stage:
needs: [integration_test_stage] needs: [integration_test_stage]
image: deps.global.bsf.tools/docker/python:3.12-slim image: deps.global.bsf.tools/docker/python:3.12-slim
timeout: 5m timeout: 5m
retry: 1 # Retry once on transient failures
before_script: before_script:
- pip install --index-url "$PIP_INDEX_URL" httpx - pip install --index-url "$PIP_INDEX_URL" httpx
script: script:
@@ -162,10 +163,13 @@ reset_stage:
import httpx import httpx
import sys import sys
import os import os
import time
BASE_URL = os.environ.get("STAGE_URL", "") BASE_URL = os.environ.get("STAGE_URL", "")
ADMIN_USER = "admin" ADMIN_USER = "admin"
ADMIN_PASS = "changeme123" # Default admin password ADMIN_PASS = "changeme123" # Default admin password
MAX_RETRIES = 3
RETRY_DELAY = 5 # seconds
if not BASE_URL: if not BASE_URL:
print("ERROR: STAGE_URL environment variable not set") print("ERROR: STAGE_URL environment variable not set")
@@ -173,37 +177,50 @@ reset_stage:
print(f"=== Resetting stage environment at {BASE_URL} ===") print(f"=== Resetting stage environment at {BASE_URL} ===")
client = httpx.Client(base_url=BASE_URL, timeout=60.0) def do_reset():
with httpx.Client(base_url=BASE_URL, timeout=120.0) as client:
# Login as admin
print("Logging in as admin...")
login_response = client.post(
"/api/v1/auth/login",
json={"username": ADMIN_USER, "password": ADMIN_PASS},
)
if login_response.status_code != 200:
raise Exception(f"Login failed: {login_response.status_code} - {login_response.text}")
print("Login successful")
# Login as admin # Call factory reset endpoint
print("Logging in as admin...") print("Calling factory reset endpoint...")
login_response = client.post( reset_response = client.post(
"/api/v1/auth/login", "/api/v1/admin/factory-reset",
json={"username": ADMIN_USER, "password": ADMIN_PASS}, headers={"X-Confirm-Reset": "yes-delete-all-data"},
) )
if login_response.status_code != 200:
print(f"Login failed: {login_response.status_code} - {login_response.text}")
sys.exit(1)
print("Login successful")
# Call factory reset endpoint if reset_response.status_code == 200:
print("Calling factory reset endpoint...") result = reset_response.json()
reset_response = client.post( print("Factory reset successful!")
"/api/v1/admin/factory-reset", print(f" Database tables dropped: {result['results']['database_tables_dropped']}")
headers={"X-Confirm-Reset": "yes-delete-all-data"}, print(f" S3 objects deleted: {result['results']['s3_objects_deleted']}")
) print(f" Database reinitialized: {result['results']['database_reinitialized']}")
print(f" Seeded: {result['results']['seeded']}")
return True
else:
raise Exception(f"Factory reset failed: {reset_response.status_code} - {reset_response.text}")
if reset_response.status_code == 200: # Retry loop
result = reset_response.json() for attempt in range(1, MAX_RETRIES + 1):
print(f"Factory reset successful!") try:
print(f" Database tables dropped: {result['results']['database_tables_dropped']}") print(f"Attempt {attempt}/{MAX_RETRIES}")
print(f" S3 objects deleted: {result['results']['s3_objects_deleted']}") if do_reset():
print(f" Database reinitialized: {result['results']['database_reinitialized']}") sys.exit(0)
print(f" Seeded: {result['results']['seeded']}") except Exception as e:
sys.exit(0) print(f"Attempt {attempt} failed: {e}")
else: if attempt < MAX_RETRIES:
print(f"Factory reset failed: {reset_response.status_code} - {reset_response.text}") print(f"Retrying in {RETRY_DELAY} seconds...")
sys.exit(1) time.sleep(RETRY_DELAY)
else:
print("All retry attempts failed")
sys.exit(1)
RESET_SCRIPT RESET_SCRIPT
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'

View File

@@ -6481,8 +6481,12 @@ def factory_reset(
# Step 4: Re-seed with default data (need fresh session after schema recreate) # Step 4: Re-seed with default data (need fresh session after schema recreate)
logger.info("Seeding database with defaults...") logger.info("Seeding database with defaults...")
from .seed import seed_database from .seed import seed_database
from .auth import create_default_admin
fresh_db = SessionLocal() fresh_db = SessionLocal()
try: try:
# Create default admin user first (normally done at startup)
create_default_admin(fresh_db)
# Then seed other test data
seed_database(fresh_db) seed_database(fresh_db)
fresh_db.commit() fresh_db.commit()
finally: finally: