98bbec9b8d
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
290 lines
10 KiB
Bash
Executable File
290 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# pipelines/gitea/setup.sh — Automate Gitea initial setup via REST API
|
|
#
|
|
# Steps:
|
|
# 1. Create admin user (idempotent — skip if already exists)
|
|
# 2. Create OAuth2 application for Woodpecker CI (idempotent — reuse if exists)
|
|
# 3. Create stonks-oracle repository (idempotent — skip if already exists)
|
|
#
|
|
# Outputs OAuth2 client_id and client_secret to stdout and to
|
|
# gitea-oauth2.env (sourceable by runmefirst.sh).
|
|
#
|
|
# Requirements: 1.1, 1.2, 1.5, 2.3
|
|
|
|
# -------------------------------------------------------
|
|
# Configuration (override via environment variables)
|
|
# -------------------------------------------------------
|
|
GITEA_URL="${GITEA_URL:-http://10.1.1.12:30300}"
|
|
GITEA_ADMIN_USER="${GITEA_ADMIN_USER:-admin}"
|
|
GITEA_ADMIN_PASSWORD="${GITEA_ADMIN_PASSWORD:-St0nks0racl3!}"
|
|
GITEA_ADMIN_EMAIL="${GITEA_ADMIN_EMAIL:-admin@celestium.life}"
|
|
|
|
OAUTH2_APP_NAME="woodpecker-ci"
|
|
OAUTH2_REDIRECT_URI="https://stonks-ci.celestium.life/authorize"
|
|
REPO_NAME="stonks-oracle"
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
OAUTH2_ENV_FILE="${SCRIPT_DIR}/gitea-oauth2.env"
|
|
|
|
API="${GITEA_URL}/api/v1"
|
|
AUTH_HEADER="Authorization: Basic $(echo -n "${GITEA_ADMIN_USER}:${GITEA_ADMIN_PASSWORD}" | base64)"
|
|
|
|
echo "=== Gitea Setup ==="
|
|
echo " URL: ${GITEA_URL}"
|
|
echo " Admin user: ${GITEA_ADMIN_USER}"
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# Helper: wait for Gitea to be reachable
|
|
# (Gitea returns 404 on /api/v1/version when on install page, so check root)
|
|
# -------------------------------------------------------
|
|
echo "--- Waiting for Gitea to be reachable ---"
|
|
for i in $(seq 1 30); do
|
|
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "${GITEA_URL}/" 2>/dev/null || echo "000")
|
|
if [ "$HTTP_STATUS" != "000" ]; then
|
|
echo " ✓ Gitea is reachable (HTTP ${HTTP_STATUS})"
|
|
break
|
|
fi
|
|
if [ "$i" -eq 30 ]; then
|
|
echo " ✗ Gitea not reachable after 30 attempts"
|
|
exit 1
|
|
fi
|
|
echo " Attempt ${i}/30 — waiting 5s..."
|
|
sleep 5
|
|
done
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# Step 1: Create admin user
|
|
# -------------------------------------------------------
|
|
echo "--- Step 1: Create admin user ---"
|
|
|
|
# Check if admin user already exists by attempting to query the API with credentials
|
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 \
|
|
-H "${AUTH_HEADER}" \
|
|
"${API}/user")
|
|
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
echo " ✓ Admin user '${GITEA_ADMIN_USER}' already exists and credentials are valid"
|
|
elif [ "$HTTP_CODE" = "404" ]; then
|
|
# Gitea is on the install page — API not available yet
|
|
echo " Gitea API not available (install page) — completing initial setup..."
|
|
INSTALL_RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
-X POST "${GITEA_URL}/" \
|
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
--data-urlencode "db_type=sqlite3" \
|
|
--data-urlencode "db_host=localhost:3306" \
|
|
--data-urlencode "db_user=root" \
|
|
--data-urlencode "db_passwd=" \
|
|
--data-urlencode "db_name=gitea" \
|
|
--data-urlencode "ssl_mode=disable" \
|
|
--data-urlencode "db_path=/data/gitea/gitea.db" \
|
|
--data-urlencode "app_name=Gitea: Git with a cup of tea" \
|
|
--data-urlencode "repo_root_path=/data/git/repositories" \
|
|
--data-urlencode "lfs_root_path=/data/git/lfs" \
|
|
--data-urlencode "run_user=git" \
|
|
--data-urlencode "domain=git.celestium.life" \
|
|
--data-urlencode "ssh_port=22" \
|
|
--data-urlencode "http_port=3000" \
|
|
--data-urlencode "app_url=https://git.celestium.life/" \
|
|
--data-urlencode "log_root_path=/data/gitea/log" \
|
|
--data-urlencode "admin_name=${GITEA_ADMIN_USER}" \
|
|
--data-urlencode "admin_passwd=${GITEA_ADMIN_PASSWORD}" \
|
|
--data-urlencode "admin_confirm_passwd=${GITEA_ADMIN_PASSWORD}" \
|
|
--data-urlencode "admin_email=${GITEA_ADMIN_EMAIL}")
|
|
|
|
INSTALL_CODE=$(echo "$INSTALL_RESPONSE" | tail -n 1)
|
|
|
|
if [ "$INSTALL_CODE" = "200" ] || [ "$INSTALL_CODE" = "302" ]; then
|
|
echo " ✓ Gitea initial install completed with admin user"
|
|
# Gitea restarts after install — wait for API to become available
|
|
echo " Waiting for Gitea API to become available after install..."
|
|
for j in $(seq 1 30); do
|
|
API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "${API}/version" 2>/dev/null || echo "000")
|
|
if [ "$API_STATUS" = "200" ]; then
|
|
echo " ✓ Gitea API is ready"
|
|
break
|
|
fi
|
|
if [ "$j" -eq 30 ]; then
|
|
echo " ✗ Gitea API not available after install (waited 150s)"
|
|
exit 1
|
|
fi
|
|
sleep 5
|
|
done
|
|
else
|
|
echo " ✗ Install wizard returned HTTP ${INSTALL_CODE}"
|
|
echo " Response: $(echo "$INSTALL_RESPONSE" | head -n -1 | tail -5)"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo " Admin user not found or credentials invalid — creating via admin API..."
|
|
|
|
# Try creating the user via Gitea's admin create-user API
|
|
# This works when Gitea has been initialized but no admin user exists,
|
|
# or when using the built-in admin creation endpoint
|
|
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
-X POST "${API}/admin/users" \
|
|
-H "Content-Type: application/json" \
|
|
-H "${AUTH_HEADER}" \
|
|
-d "{
|
|
\"username\": \"${GITEA_ADMIN_USER}\",
|
|
\"password\": \"${GITEA_ADMIN_PASSWORD}\",
|
|
\"email\": \"${GITEA_ADMIN_EMAIL}\",
|
|
\"must_change_password\": false,
|
|
\"login_name\": \"${GITEA_ADMIN_USER}\",
|
|
\"source_id\": 0,
|
|
\"visibility\": \"public\"
|
|
}")
|
|
|
|
BODY=$(echo "$RESPONSE" | head -n -1)
|
|
CODE=$(echo "$RESPONSE" | tail -n 1)
|
|
|
|
if [ "$CODE" = "201" ]; then
|
|
echo " ✓ Admin user '${GITEA_ADMIN_USER}' created"
|
|
elif [ "$CODE" = "422" ]; then
|
|
echo " ✓ Admin user '${GITEA_ADMIN_USER}' already exists (422)"
|
|
else
|
|
echo " ✗ Unexpected response creating admin user: HTTP ${CODE}"
|
|
echo " Response: ${BODY}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# Step 2: Create OAuth2 application for Woodpecker CI
|
|
# -------------------------------------------------------
|
|
echo "--- Step 2: Create OAuth2 application '${OAUTH2_APP_NAME}' ---"
|
|
|
|
# Check if the OAuth2 app already exists
|
|
EXISTING_APPS=$(curl -s \
|
|
-H "${AUTH_HEADER}" \
|
|
"${API}/user/applications/oauth2")
|
|
|
|
EXISTING_APP=$(echo "$EXISTING_APPS" | python3 -c "
|
|
import sys, json
|
|
apps = json.load(sys.stdin)
|
|
for app in apps:
|
|
if app.get('name') == '${OAUTH2_APP_NAME}':
|
|
print(json.dumps(app))
|
|
break
|
|
" 2>/dev/null || echo "")
|
|
|
|
if [ -n "$EXISTING_APP" ]; then
|
|
echo " ✓ OAuth2 app '${OAUTH2_APP_NAME}' already exists"
|
|
OAUTH2_CLIENT_ID=$(echo "$EXISTING_APP" | python3 -c "import sys,json; print(json.load(sys.stdin)['client_id'])")
|
|
# Note: Gitea does not return client_secret for existing apps.
|
|
# If we need the secret, we must delete and recreate.
|
|
OAUTH2_CLIENT_SECRET=$(echo "$EXISTING_APP" | python3 -c "
|
|
import sys, json
|
|
data = json.load(sys.stdin)
|
|
print(data.get('client_secret', ''))
|
|
" 2>/dev/null || echo "")
|
|
|
|
if [ -z "$OAUTH2_CLIENT_SECRET" ]; then
|
|
echo " ✓ OAuth2 app exists, secret stored in Woodpecker DB (not recreating)"
|
|
# Write client_id only — secret is only available on first creation
|
|
cat > "${OAUTH2_ENV_FILE}" <<EOF
|
|
# Generated by gitea/setup.sh
|
|
# Secret only available on first creation — Woodpecker DB has it
|
|
GITEA_CLIENT_ID=${OAUTH2_CLIENT_ID}
|
|
GITEA_CLIENT_SECRET=EXISTING_APP_SECRET_IN_WOODPECKER_DB
|
|
EOF
|
|
echo ""
|
|
echo " ✓ Credentials written to ${OAUTH2_ENV_FILE}"
|
|
echo ""
|
|
echo "=== Gitea Setup Complete ==="
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
if [ -z "${EXISTING_APP:-}" ]; then
|
|
# Create the OAuth2 application
|
|
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
-X POST "${API}/user/applications/oauth2" \
|
|
-H "Content-Type: application/json" \
|
|
-H "${AUTH_HEADER}" \
|
|
-d "{
|
|
\"name\": \"${OAUTH2_APP_NAME}\",
|
|
\"redirect_uris\": [\"${OAUTH2_REDIRECT_URI}\"],
|
|
\"confidential_client\": true
|
|
}")
|
|
|
|
BODY=$(echo "$RESPONSE" | head -n -1)
|
|
CODE=$(echo "$RESPONSE" | tail -n 1)
|
|
|
|
if [ "$CODE" = "201" ]; then
|
|
OAUTH2_CLIENT_ID=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['client_id'])")
|
|
OAUTH2_CLIENT_SECRET=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['client_secret'])")
|
|
echo " ✓ OAuth2 app '${OAUTH2_APP_NAME}' created"
|
|
else
|
|
echo " ✗ Failed to create OAuth2 app: HTTP ${CODE}"
|
|
echo " Response: ${BODY}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo " Client ID: ${OAUTH2_CLIENT_ID}"
|
|
echo " Client Secret: ${OAUTH2_CLIENT_SECRET:0:8}..."
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# Step 3: Create stonks-oracle repository
|
|
# -------------------------------------------------------
|
|
echo "--- Step 3: Create '${REPO_NAME}' repository ---"
|
|
|
|
# Check if repo already exists
|
|
REPO_CHECK=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
-H "${AUTH_HEADER}" \
|
|
"${API}/repos/${GITEA_ADMIN_USER}/${REPO_NAME}")
|
|
|
|
if [ "$REPO_CHECK" = "200" ]; then
|
|
echo " ✓ Repository '${REPO_NAME}' already exists"
|
|
else
|
|
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
-X POST "${API}/user/repos" \
|
|
-H "Content-Type: application/json" \
|
|
-H "${AUTH_HEADER}" \
|
|
-d "{
|
|
\"name\": \"${REPO_NAME}\",
|
|
\"description\": \"Stonks Oracle — AI market intelligence and paper-trading platform\",
|
|
\"private\": false,
|
|
\"auto_init\": false
|
|
}")
|
|
|
|
BODY=$(echo "$RESPONSE" | head -n -1)
|
|
CODE=$(echo "$RESPONSE" | tail -n 1)
|
|
|
|
if [ "$CODE" = "201" ]; then
|
|
echo " ✓ Repository '${REPO_NAME}' created"
|
|
elif [ "$CODE" = "409" ]; then
|
|
echo " ✓ Repository '${REPO_NAME}' already exists (409)"
|
|
else
|
|
echo " ✗ Failed to create repository: HTTP ${CODE}"
|
|
echo " Response: ${BODY}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# Output OAuth2 credentials
|
|
# -------------------------------------------------------
|
|
echo "--- OAuth2 Credentials ---"
|
|
echo "GITEA_CLIENT_ID=${OAUTH2_CLIENT_ID}"
|
|
echo "GITEA_CLIENT_SECRET=${OAUTH2_CLIENT_SECRET}"
|
|
|
|
# Write to env file for runmefirst.sh to source
|
|
cat > "${OAUTH2_ENV_FILE}" <<EOF
|
|
# Generated by gitea/setup.sh — do not edit manually
|
|
GITEA_CLIENT_ID=${OAUTH2_CLIENT_ID}
|
|
GITEA_CLIENT_SECRET=${OAUTH2_CLIENT_SECRET}
|
|
EOF
|
|
echo ""
|
|
echo " ✓ Credentials written to ${OAUTH2_ENV_FILE}"
|
|
|
|
echo ""
|
|
echo "=== Gitea Setup Complete ==="
|