#!/bin/sh # Assemble runnable PHP backend from ac-workspace submodules (overlay on legacy seed). set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd)" # shellcheck source=/dev/null . "$ROOT/scripts/lib/common.sh" load_cluster_env WS="${AC_WORKSPACE_ROOT:-/var/www/ac/workspace}" LAB_SEED="${ROOT}/lab-seeds/backend" MONOLITH_BACKEND="${APP_ROOT}/android_cast/examples/crash_reporter/backend" if [ -d "${LAB_SEED}/public" ]; then LEGACY="$LAB_SEED" elif [ "${COMPOSE_SKIP_MONOLITH:-0}" = "1" ]; then die "lab-seeds missing at ${LAB_SEED} and COMPOSE_SKIP_MONOLITH=1" else LEGACY="$MONOLITH_BACKEND" fi COMPOSED="${COMPOSE_BACKEND:-/var/www/ac/composed/backend}" PLATFORM_ROOT="${AC_PLATFORM_ROOT:-/var/www/ac/platform}" APP_PASS="$(read_cred mariadb_app password)" DB_HOST="$PRIMARY_DB_HOST" if is_primary_node; then DB_HOST=127.0.0.1 fi [ -d "$WS/.git" ] || die "missing ac-workspace at $WS (run deploy-ac-workspace.sh first)" overlay_src() { _repo="$1" _dir="${WS}/${_repo}/src" [ -d "$_dir" ] || { log "skip src ${_repo} (no src/)"; return 0; } log "overlay src ${_repo}" cp -a "$_dir"/. "${COMPOSED}/src/" } overlay_api() { _repo="$1" _dir="${WS}/${_repo}/public/api" [ -d "$_dir" ] || return 0 log "overlay api ${_repo}" mkdir -p "${COMPOSED}/public/api" cp -a "$_dir"/. "${COMPOSED}/public/api/" } overlay_views() { _repo="$1" _dir="${WS}/${_repo}/views" [ -d "$_dir" ] || return 0 log "overlay views ${_repo}" mkdir -p "${COMPOSED}/views" cp -a "$_dir"/. "${COMPOSED}/views/" } if [ ! -f "${COMPOSED}/public/index.php" ] || [ "${FORCE_COMPOSE_SEED:-0}" = "1" ]; then [ -d "$LEGACY/public" ] || die "backend seed missing at $LEGACY (lab-seeds or deploy-app.sh monolith)" log "seed composed backend from ${LEGACY}" mkdir -p "$(dirname "$COMPOSED")" rm -rf "$COMPOSED" mkdir -p "$COMPOSED" cp -a "${LEGACY}/." "$COMPOSED/" fi mkdir -p "$PLATFORM_ROOT" if [ -d "${WS}/ac-platform-php/platform" ]; then log "sync platform helpers → ${PLATFORM_ROOT}" cp -a "${WS}/ac-platform-php/platform/." "$PLATFORM_ROOT/" fi if [ -d "${WS}/ac-platform-web/assets" ]; then log "sync platform-web assets" mkdir -p "${COMPOSED}/public/assets" cp -a "${WS}/ac-platform-web/assets/." "${COMPOSED}/public/assets/" if [ -f "${WS}/ac-platform-web/src/AnalyticsHead.php" ]; then cp -a "${WS}/ac-platform-web/src/AnalyticsHead.php" "${COMPOSED}/src/" fi fi overlay_src ac-platform-php overlay_src ac-ms-identity overlay_src ac-ms-rbac overlay_src ac-ms-devices overlay_src ac-ms-issues overlay_src ac-ms-tickets overlay_src ac-ms-graphs overlay_src ac-ms-remote-access # Lab-seed PHP not yet split into ac-ms-* repos — NFS seed stays authoritative after overlays. overlay_lab_seed_src() { _f="$1" if [ -f "${LEGACY}/src/${_f}" ]; then log "overlay lab-seed src ${_f}" cp -a "${LEGACY}/src/${_f}" "${COMPOSED}/src/" fi } overlay_lab_seed_src ShortLinksRepository.php overlay_lab_seed_src UrlShortenerDatabase.php overlay_api ac-ms-identity overlay_api ac-ms-rbac overlay_api ac-ms-devices overlay_api ac-ms-issues overlay_api ac-ms-tickets overlay_api ac-ms-graphs overlay_api ac-ms-remote-access overlay_views ac-be-auth overlay_views ac-be-issues overlay_views ac-be-tickets overlay_views ac-be-graphs overlay_views ac-be-remote-access overlay_views ac-be-access ISSUES_BASE="${APP_BASE_PATH:-/app/androidcast_project/issues}" PUBLIC_ORIGIN_CFG="${LAB_PUBLIC_ORIGIN:-https://acl0.f0xx.org}" load_secrets_lab AUTH_KEY="${AUTH_ENCRYPTION_KEY:-lab-cluster-dev-32-char-min-secret!!}" _MSMTP_PASS="$(read_secret MSMTP_APP_PASSWORD 2>/dev/null || true)" [ -n "$_MSMTP_PASS" ] || _MSMTP_PASS="${MSMTP_APP_PASSWORD:-}" MAIL_TRANSPORT="${MAIL_TRANSPORT:-sendmail}" MAIL_FROM="${MAIL_FROM:-Android Cast Lab }" MAIL_REPLY="${MAIL_REPLY_TO:-bestcastr@gmail.com}" SMTP_HOST="${SMTP_HOST:-127.0.0.1}" SMTP_PORT="${SMTP_PORT:-587}" SMTP_ENC="${SMTP_ENCRYPTION:-tls}" SMTP_USER="${SMTP_USER:-${MSMTP_USER:-}}" SMTP_PASS="${SMTP_PASS:-}" if [ -n "$_MSMTP_PASS" ]; then MAIL_TRANSPORT=smtp SMTP_HOST=smtp.gmail.com SMTP_USER="${MSMTP_USER:-bestcastr@gmail.com}" SMTP_PASS="$_MSMTP_PASS" MAIL_FROM="${MAIL_FROM:-Android Cast }" fi unset _MSMTP_PASS AUTH_BEARER_ID="$(read_secret URL_SHORTENER_AUTH_BEARER_ID 2>/dev/null || true)" [ -n "$AUTH_BEARER_ID" ] || AUTH_BEARER_ID="${URL_SHORTENER_AUTH_BEARER_ID:-0}" mkdir -p "${COMPOSED}/config" log "write composed config.php base_path=${ISSUES_BASE}" cat > "${COMPOSED}/config/config.php" < 'Android Cast Issues', 'base_path' => '${ISSUES_BASE}', 'public_origin' => '${PUBLIC_ORIGIN_CFG}', 'db' => [ 'driver' => 'mariadb', 'sqlite_path' => __DIR__ . '/../data/crashes.sqlite', 'mysql' => [ 'host' => '${DB_HOST}', 'port' => ${PRIMARY_DB_PORT}, 'socket' => '', 'database' => 'androidcast_crashes', 'username' => 'androidcast', 'password' => '${APP_PASS}', 'charset' => 'utf8mb4', ], ], 'session_name' => 'ac_crash_sess', 'session_cookie_path' => '${APP_HUB_PATH}', 'debug' => true, 'rbac' => ['default_company_slug' => 'default', 'default_company_id' => 1], 'analytics' => ['enabled' => false, 'measurement_id' => '', 'debug' => false], 'remote_access' => [ 'wg_endpoint' => '', 'wg_server_public_key' => '', 'provision_peers' => false, 'require_wg_tools' => false, ], 'auth' => [ 'encryption_key' => '${AUTH_KEY}', 'max_attempts' => 8, 'lockout_window_minutes' => 15, ], 'mail' => [ 'transport' => '${MAIL_TRANSPORT}', 'from' => '${MAIL_FROM}', 'reply_to' => '${MAIL_REPLY}', 'smtp' => [ 'host' => '${SMTP_HOST}', 'port' => ${SMTP_PORT}, 'encryption' => '${SMTP_ENC}', 'username' => '${SMTP_USER}', 'password' => '${SMTP_PASS}', ], ], 'url_shortener' => [ 'enabled' => true, 'public_base' => '${SHORT_LINKS_PUBLIC_BASE}', 'auth_bearer_id' => ${AUTH_BEARER_ID:-0}, 'db' => [ 'mysql' => [ 'host' => '${DB_HOST}', 'port' => ${PRIMARY_DB_PORT}, 'socket' => '', 'database' => 'url_shortener', 'username' => 'androidcast', 'password' => '${APP_PASS}', 'charset' => 'utf8mb4', ], ], ], ]; PHP if command -v composer >/dev/null 2>&1; then log "composer dump-autoload (optional)" cat > "${COMPOSED}/composer.json" <<'JSON' { "name": "androidcast/lab-composed-backend", "require": { "php": ">=8.1" }, "autoload": { "classmap": ["src/"] } } JSON (cd "$COMPOSED" && composer dump-autoload -o 2>/dev/null) || true fi chown -R nginx:nginx "$(dirname "$COMPOSED")" "$PLATFORM_ROOT" 2>/dev/null || true log "compose-lab-backend_ok $(host_short) → ${COMPOSED}"