mirror of
git://f0xx.org/ac/ac-deploy
synced 2026-07-29 03:38:07 +03:00
cluster0: lab seeds, Gitea mirrors, compose mail, verify tooling
Freeze lab-seeds backend for COMPOSE_SKIP_MONOLITH; fix Gitea mirror scripts for 1.25 API; add secrets.lab.env template, verify-mail-lab, LAB_PUBLIC_ORIGIN, and credentials pointers for mirror token recovery. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,7 +7,15 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
load_cluster_env
|
||||
|
||||
WS="${AC_WORKSPACE_ROOT:-/var/www/ac/workspace}"
|
||||
LEGACY="${APP_ROOT}/android_cast/examples/crash_reporter/backend"
|
||||
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)"
|
||||
@@ -45,8 +53,8 @@ overlay_views() {
|
||||
}
|
||||
|
||||
if [ ! -f "${COMPOSED}/public/index.php" ] || [ "${FORCE_COMPOSE_SEED:-0}" = "1" ]; then
|
||||
[ -d "$LEGACY/public" ] || die "legacy backend missing at $LEGACY — run deploy-app.sh first"
|
||||
log "seed composed backend from legacy ${LEGACY}"
|
||||
[ -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"
|
||||
@@ -93,6 +101,17 @@ 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!!}"
|
||||
MAIL_TRANSPORT="${MAIL_TRANSPORT:-smtp}"
|
||||
MAIL_FROM="${MAIL_FROM:-Android Cast Lab <noreply@acl0.f0xx.org>}"
|
||||
MAIL_REPLY="${MAIL_REPLY_TO:-info@apps.f0xx.org}"
|
||||
SMTP_HOST="${SMTP_HOST:-127.0.0.1}"
|
||||
SMTP_PORT="${SMTP_PORT:-587}"
|
||||
SMTP_ENC="${SMTP_ENCRYPTION:-tls}"
|
||||
SMTP_USER="${SMTP_USER:-}"
|
||||
SMTP_PASS="${SMTP_PASS:-}"
|
||||
mkdir -p "${COMPOSED}/config"
|
||||
log "write composed config.php base_path=${ISSUES_BASE}"
|
||||
cat > "${COMPOSED}/config/config.php" <<PHP
|
||||
@@ -100,6 +119,7 @@ cat > "${COMPOSED}/config/config.php" <<PHP
|
||||
return [
|
||||
'app_name' => 'Android Cast Issues',
|
||||
'base_path' => '${ISSUES_BASE}',
|
||||
'public_origin' => '${PUBLIC_ORIGIN_CFG}',
|
||||
'db' => [
|
||||
'driver' => 'mariadb',
|
||||
'sqlite_path' => __DIR__ . '/../data/crashes.sqlite',
|
||||
@@ -125,10 +145,22 @@ return [
|
||||
'require_wg_tools' => false,
|
||||
],
|
||||
'auth' => [
|
||||
'encryption_key' => 'lab-cluster-dev-32-char-min-secret!!',
|
||||
'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}',
|
||||
|
||||
@@ -6,6 +6,11 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
. "$ROOT/scripts/lib/common.sh"
|
||||
ensure_shared_mounted
|
||||
|
||||
if [ "${COMPOSE_SKIP_MONOLITH:-0}" = "1" ]; then
|
||||
log "COMPOSE_SKIP_MONOLITH=1 — skip monolith git pull (use lab-seeds + compose-lab-backend.sh)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
APP_PASS="$(read_cred mariadb_app password)"
|
||||
DB_HOST="$PRIMARY_DB_HOST"
|
||||
if is_primary_node; then
|
||||
|
||||
128
sim/cluster0/scripts/deploy-gitea.sh
Executable file
128
sim/cluster0/scripts/deploy-gitea.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/bin/sh
|
||||
# Install and start Gitea on cluster primary (cast01) — config only, no repo mirrors yet.
|
||||
set -eu
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
. "$ROOT/scripts/lib/common.sh"
|
||||
load_cluster_env
|
||||
|
||||
GITEA_DIR="${ROOT}/gitea"
|
||||
TEMPLATE="${GITEA_DIR}/app.ini.template"
|
||||
INI="/etc/gitea/app.ini"
|
||||
GITEA_APP_DATA="${GITEA_APP_DATA:-/var/lib/gitea}"
|
||||
GITEA_HTTP_PORT="${GITEA_HTTP_PORT:-3000}"
|
||||
GITEA_DOMAIN="${GITEA_PUBLIC_HOST:-${ACL0_CNAME:-acl0.f0xx.org}}"
|
||||
GITEA_ROOT_URL="${GITEA_ROOT_URL:-https://${GITEA_DOMAIN}/app/androidcast_project/git/}"
|
||||
GITEA_DB_USER="${GITEA_DB_USER:-androidcast}"
|
||||
GITEA_DB_PASS="$(read_cred mariadb_app password)"
|
||||
GITEA_SECRETS="${GITEA_APP_DATA}/.lab-secrets.env"
|
||||
|
||||
if [ "${GITEA_ENABLE:-0}" != "1" ]; then
|
||||
log "GITEA_ENABLE!=1 — skip deploy-gitea"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! is_primary_node; then
|
||||
log "deploy-gitea: skip on replica $(host_short) (Gitea runs on ${CAST01_HOST} only)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
gitea_stop_clean() {
|
||||
rc-service gitea stop 2>/dev/null || true
|
||||
sleep 2
|
||||
pkill -u gitea -f '/usr/bin/gitea web' 2>/dev/null || true
|
||||
sleep 1
|
||||
rm -f "${GITEA_APP_DATA}/gitea.db-shm" "${GITEA_APP_DATA}/gitea.db-wal" 2>/dev/null || true
|
||||
}
|
||||
|
||||
gitea_wait_http() {
|
||||
_port="${1:-$GITEA_HTTP_PORT}"
|
||||
_i=0
|
||||
while [ "$_i" -lt 180 ]; do
|
||||
if curl -fsS -m 2 -o /dev/null "http://127.0.0.1:${_port}/" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
_i=$((_i + 1))
|
||||
sleep 2
|
||||
done
|
||||
die "timeout waiting for gitea http://127.0.0.1:${_port}/"
|
||||
}
|
||||
|
||||
[ -f "$TEMPLATE" ] || die "missing $TEMPLATE"
|
||||
|
||||
apk add --no-cache gitea 2>/dev/null || apk add --no-cache gitea
|
||||
|
||||
mkdir -p "$GITEA_APP_DATA/data/gitea-repositories" "$GITEA_APP_DATA/lfs" /var/log/gitea /etc/gitea
|
||||
chown -R gitea:www-data "$GITEA_APP_DATA" /var/log/gitea 2>/dev/null || true
|
||||
|
||||
# Optional MariaDB backend (set GITEA_DB_TYPE=mysql in cluster.env). Default: sqlite3 for lab.
|
||||
if [ "${GITEA_DB_TYPE:-sqlite3}" = "mysql" ]; then
|
||||
mariadb -u root -e "CREATE DATABASE IF NOT EXISTS gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null \
|
||||
|| mariadb -e "CREATE DATABASE IF NOT EXISTS gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
mariadb -u root -e "GRANT ALL PRIVILEGES ON gitea.* TO '${GITEA_DB_USER}'@'localhost'; FLUSH PRIVILEGES;" 2>/dev/null \
|
||||
|| mariadb -e "GRANT ALL PRIVILEGES ON gitea.* TO '${GITEA_DB_USER}'@'localhost'; FLUSH PRIVILEGES;"
|
||||
fi
|
||||
|
||||
gitea_rand_secret() {
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
openssl rand -base64 48 | tr -d '/+=' | head -c 64
|
||||
return 0
|
||||
fi
|
||||
head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 64
|
||||
}
|
||||
|
||||
if [ -f "$GITEA_SECRETS" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$GITEA_SECRETS"
|
||||
else
|
||||
GITEA_INTERNAL_TOKEN="$(gitea_rand_secret)"
|
||||
GITEA_OAUTH_JWT="$(gitea_rand_secret)"
|
||||
GITEA_LFS_JWT="$(gitea_rand_secret)"
|
||||
umask 077
|
||||
cat > "$GITEA_SECRETS" <<EOF
|
||||
GITEA_INTERNAL_TOKEN=${GITEA_INTERNAL_TOKEN}
|
||||
GITEA_OAUTH_JWT=${GITEA_OAUTH_JWT}
|
||||
GITEA_LFS_JWT=${GITEA_LFS_JWT}
|
||||
EOF
|
||||
chown gitea:gitea "$GITEA_SECRETS" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ ! -f "$INI" ] || [ "${FORCE_GITEA_CONFIG:-0}" = "1" ] || ! grep -q 'AndroidCast lab' "$INI" 2>/dev/null; then
|
||||
log "render $INI from template (ROOT_URL=$GITEA_ROOT_URL)"
|
||||
_tmp="$(mktemp)"
|
||||
sed \
|
||||
-e "s|@GITEA_APP_DATA@|${GITEA_APP_DATA}|g" \
|
||||
-e "s|@GITEA_DOMAIN@|${GITEA_DOMAIN}|g" \
|
||||
-e "s|@GITEA_ROOT_URL@|${GITEA_ROOT_URL}|g" \
|
||||
-e "s|@GITEA_HTTP_PORT@|${GITEA_HTTP_PORT}|g" \
|
||||
-e "s|@GITEA_INTERNAL_TOKEN@|${GITEA_INTERNAL_TOKEN}|g" \
|
||||
-e "s|@GITEA_OAUTH_JWT@|${GITEA_OAUTH_JWT}|g" \
|
||||
-e "s|@GITEA_LFS_JWT@|${GITEA_LFS_JWT}|g" \
|
||||
"$TEMPLATE" > "$_tmp"
|
||||
install -m 640 -o gitea -g www-data "$_tmp" "$INI"
|
||||
rm -f "$_tmp"
|
||||
if [ -d "${GITEA_APP_DATA}/custom/conf" ]; then
|
||||
install -D -m 640 -o gitea -g www-data "$INI" "${GITEA_APP_DATA}/custom/conf/app.ini"
|
||||
fi
|
||||
fi
|
||||
|
||||
gitea_stop_clean
|
||||
rc-update add gitea default 2>/dev/null || true
|
||||
rc-service gitea start 2>/dev/null || rc-service gitea restart 2>/dev/null || true
|
||||
gitea_wait_http "$GITEA_HTTP_PORT"
|
||||
# First admin (lab) — idempotent.
|
||||
GITEA_ADMIN_USER="${GITEA_ADMIN_USER:-admin}"
|
||||
GITEA_ADMIN_PASS="$(read_cred gitea_admin password)"
|
||||
if [ -z "$GITEA_ADMIN_PASS" ]; then
|
||||
GITEA_ADMIN_PASS="$(read_cred mariadb_app password)"
|
||||
fi
|
||||
if ! su -s /bin/sh gitea -c "gitea -c '$INI' admin user list" 2>/dev/null | awk 'NR>1 && NF>=2 {found=1} END{exit !found}'; then
|
||||
log "create Gitea admin user ${GITEA_ADMIN_USER}"
|
||||
su -s /bin/sh gitea -c "gitea -c '$INI' admin user create \
|
||||
--username '${GITEA_ADMIN_USER}' \
|
||||
--password '${GITEA_ADMIN_PASS}' \
|
||||
--email 'admin@${GITEA_DOMAIN}' \
|
||||
--admin" 2>/dev/null || log "WARN: admin user create skipped (may already exist)"
|
||||
fi
|
||||
|
||||
log "deploy-gitea_ok $(host_short) ROOT_URL=${GITEA_ROOT_URL} port=${GITEA_HTTP_PORT}"
|
||||
@@ -185,6 +185,16 @@ read_cred() {
|
||||
' "$_file"
|
||||
}
|
||||
|
||||
# Optional NFS secrets (not in git): secrets.lab.env
|
||||
load_secrets_lab() {
|
||||
_file="${CAST_CLUSTER_ROOT}/secrets.lab.env"
|
||||
[ -f "$_file" ] || return 0
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
. "$_file"
|
||||
set +a
|
||||
}
|
||||
|
||||
ssh_node() {
|
||||
_host="$1"
|
||||
shift
|
||||
|
||||
91
sim/cluster0/scripts/mirror-gitea-ac-org.sh
Executable file
91
sim/cluster0/scripts/mirror-gitea-ac-org.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/sh
|
||||
# Mirror git://f0xx.org/ac/* (and legacy android_cast) into lab Gitea org ac on cast01.
|
||||
set -eu
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
. "$ROOT/scripts/lib/common.sh"
|
||||
load_cluster_env
|
||||
|
||||
GITEA_SCRIPTS="${ROOT}/lab-seeds/backend/scripts/gitea"
|
||||
REPOS_FILE="${ROOT}/gitea/ac-repos.list"
|
||||
TOKEN_FILE="${GITEA_APP_DATA:-/var/lib/gitea}/.mirror-admin-token"
|
||||
GITEA_ORG="${GITEA_ORG:-ac}"
|
||||
AC_GIT_BASE="${AC_GIT_BASE:-git://f0xx.org/ac}"
|
||||
|
||||
if [ "${GITEA_ENABLE:-0}" != "1" ]; then
|
||||
log "GITEA_ENABLE!=1 — skip mirror-gitea-ac-org"
|
||||
exit 0
|
||||
fi
|
||||
if ! is_primary_node; then
|
||||
log "mirror-gitea-ac-org: skip on $(host_short) (Gitea on ${CAST01_HOST})"
|
||||
exit 0
|
||||
fi
|
||||
[ -d "$GITEA_SCRIPTS" ] || die "missing $GITEA_SCRIPTS"
|
||||
[ -f "$REPOS_FILE" ] || die "missing $REPOS_FILE"
|
||||
|
||||
ensure_admin_token() {
|
||||
if [ -n "${GITEA_ADMIN_TOKEN:-}" ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ -r "$TOKEN_FILE" ]; then
|
||||
GITEA_ADMIN_TOKEN="$(cat "$TOKEN_FILE")"
|
||||
export GITEA_ADMIN_TOKEN
|
||||
return 0
|
||||
fi
|
||||
log "generate Gitea admin API token"
|
||||
GITEA_ADMIN_TOKEN="$(su -s /bin/sh gitea -c \
|
||||
"gitea -c /etc/gitea/app.ini admin user generate-access-token --username admin --token-name mirror-ac --scopes all --raw" \
|
||||
| tail -1)"
|
||||
[ -n "$GITEA_ADMIN_TOKEN" ] || die "failed to generate GITEA_ADMIN_TOKEN"
|
||||
umask 077
|
||||
printf '%s' "$GITEA_ADMIN_TOKEN" > "$TOKEN_FILE"
|
||||
chown gitea:www-data "$TOKEN_FILE" 2>/dev/null || true
|
||||
export GITEA_ADMIN_TOKEN
|
||||
}
|
||||
|
||||
ensure_admin_token
|
||||
export GITEA_ORG GITEA_OWNER="$GITEA_ORG" GITEA_ORG_OWNERS="${GITEA_ORG_OWNERS:-admin}"
|
||||
export GITEA_ORG_FULL_NAME="${GITEA_ORG_FULL_NAME:-Android Cast (ac)}"
|
||||
export GITEA_TRANSFER_FROM="${GITEA_TRANSFER_FROM:-admin}"
|
||||
export GITEA_MIRROR_INTERVAL="${GITEA_MIRROR_INTERVAL:-10m}"
|
||||
export GITEA_PRIVATE="${GITEA_PRIVATE:-false}"
|
||||
|
||||
log "ensure Gitea org ${GITEA_ORG}"
|
||||
sh "$GITEA_SCRIPTS/gitea_migrate_org_setup.sh" || die "org setup failed"
|
||||
|
||||
OK=0
|
||||
SKIP=0
|
||||
FAIL=0
|
||||
|
||||
while IFS= read -r _line || [ -n "$_line" ]; do
|
||||
_line="$(printf '%s' "$_line" | sed 's/#.*//;s/^[ \t]*//;s/[ \t]*$//')"
|
||||
[ -n "$_line" ] || continue
|
||||
_repo="$_line"
|
||||
_url=""
|
||||
case "$_line" in
|
||||
*'|'*)
|
||||
_repo="${_line%%|*}"
|
||||
_url="${_line#*|}"
|
||||
;;
|
||||
*)
|
||||
_url="${AC_GIT_BASE}/${_repo}"
|
||||
;;
|
||||
esac
|
||||
log "mirror ${_repo} <= ${_url}"
|
||||
if command -v sqlite3 >/dev/null 2>&1 && \
|
||||
sqlite3 /var/lib/gitea/gitea.db "SELECT 1 FROM repository r JOIN user u ON r.owner_id=u.id WHERE u.lower_name='$(printf '%s' "$GITEA_ORG" | tr '[:upper:]' '[:lower:]')' AND r.lower_name='$(printf '%s' "$_repo" | tr '[:upper:]' '[:lower:]')' LIMIT 1;" 2>/dev/null | grep -q 1; then
|
||||
log "skip existing $_repo"
|
||||
SKIP=$((SKIP + 1))
|
||||
continue
|
||||
fi
|
||||
if GITEA_OWNER="$GITEA_ORG" GITEA_REPO="$_repo" GITEA_MIRROR_URL="$_url" \
|
||||
sh "$GITEA_SCRIPTS/gitea_attach_remote.sh" "$_url"; then
|
||||
OK=$((OK + 1))
|
||||
else
|
||||
FAIL=$((FAIL + 1))
|
||||
log "WARN: mirror failed for $_repo"
|
||||
fi
|
||||
done < "$REPOS_FILE"
|
||||
|
||||
log "mirror-gitea-ac-org summary ok=$OK skip=$SKIP fail=$FAIL org=$GITEA_ORG"
|
||||
[ "$FAIL" -eq 0 ] || exit 1
|
||||
55
sim/cluster0/scripts/verify-gitea-mirrors.sh
Executable file
55
sim/cluster0/scripts/verify-gitea-mirrors.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/sh
|
||||
# Verify lab Gitea org ac mirrors vs ac-repos.list (cast01).
|
||||
set -eu
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
. "$ROOT/scripts/lib/common.sh"
|
||||
load_cluster_env
|
||||
|
||||
REPOS_FILE="${ROOT}/gitea/ac-repos.list"
|
||||
DB="${GITEA_APP_DATA:-/var/lib/gitea}/gitea.db"
|
||||
ORG="${GITEA_ORG:-ac}"
|
||||
|
||||
if [ "${GITEA_ENABLE:-0}" != "1" ]; then
|
||||
log "GITEA_ENABLE!=1 — skip"
|
||||
exit 0
|
||||
fi
|
||||
if ! is_primary_node; then
|
||||
log "verify-gitea-mirrors: skip on $(host_short)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
FAIL=0
|
||||
rc-service gitea status 2>/dev/null | grep -qi started || { log "FAIL gitea not running"; FAIL=1; }
|
||||
curl -fsS -m 5 -o /dev/null http://127.0.0.1:3000/ || { log "FAIL gitea http"; FAIL=1; }
|
||||
|
||||
GITEA_COUNT="$(sqlite3 "$DB" "SELECT COUNT(*) FROM repository r JOIN user u ON r.owner_id=u.id WHERE u.lower_name='$(printf '%s' "$ORG" | tr '[:upper:]' '[:lower:]')';" 2>/dev/null || echo 0)"
|
||||
log "gitea_org_${ORG}_repos=${GITEA_COUNT}"
|
||||
|
||||
while IFS= read -r _line || [ -n "$_line" ]; do
|
||||
_line="$(printf '%s' "$_line" | sed 's/#.*//;s/^[ \t]*//;s/[ \t]*$//')"
|
||||
[ -n "$_line" ] || continue
|
||||
_repo="${_line%%|*}"
|
||||
_url="${_line#*|}"
|
||||
[ "$_url" = "$_repo" ] && _url="${AC_GIT_BASE:-git://f0xx.org/ac}/${_repo}"
|
||||
if ! git ls-remote "$_url" HEAD >/dev/null 2>&1 && \
|
||||
! git ls-remote "$_url" refs/heads/next >/dev/null 2>&1 && \
|
||||
! git ls-remote "$_url" 2>/dev/null | grep -q refs/heads/; then
|
||||
log "WARN git_missing $_url (not exported on git server)"
|
||||
FAIL=1
|
||||
continue
|
||||
fi
|
||||
if sqlite3 "$DB" "SELECT 1 FROM repository r JOIN user u ON r.owner_id=u.id WHERE u.lower_name='$(printf '%s' "$ORG" | tr '[:upper:]' '[:lower:]')' AND r.lower_name='$(printf '%s' "$_repo" | tr '[:upper:]' '[:lower:]')' LIMIT 1;" 2>/dev/null | grep -q 1; then
|
||||
log "OK gitea_mirror ${ORG}/${_repo}"
|
||||
else
|
||||
log "FAIL gitea_missing ${ORG}/${_repo} (git remote OK)"
|
||||
FAIL=1
|
||||
fi
|
||||
done < "$REPOS_FILE"
|
||||
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
log "verify-gitea-mirrors_ok"
|
||||
exit 0
|
||||
fi
|
||||
log "verify-gitea-mirrors_WARN (see git_missing / gitea_missing above)"
|
||||
exit 1
|
||||
30
sim/cluster0/scripts/verify-mail-lab.sh
Executable file
30
sim/cluster0/scripts/verify-mail-lab.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
# Lab SMTP smoke — requires secrets.lab.env SMTP_* or local relay on cast01.
|
||||
set -eu
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
. "$ROOT/scripts/lib/common.sh"
|
||||
load_cluster_env
|
||||
load_secrets_lab
|
||||
|
||||
TO="${1:-}"
|
||||
[ -n "$TO" ] || die "usage: verify-mail-lab.sh recipient@example.com"
|
||||
|
||||
COMPOSED="${COMPOSE_BACKEND:-/var/www/ac/composed/backend}"
|
||||
[ -f "${COMPOSED}/config/config.php" ] || die "missing composed backend — run compose-lab-backend.sh"
|
||||
|
||||
export MAIL_TEST_TO="$TO"
|
||||
_out="$(php -r '
|
||||
require "'"${COMPOSED}"'/src/bootstrap.php";
|
||||
$to = getenv("MAIL_TEST_TO") ?: "";
|
||||
$origin = rtrim((string) cfg("public_origin", "https://acl0.f0xx.org"), "/");
|
||||
$base = rtrim((string) cfg("base_path", ""), "/");
|
||||
$ok = AuthMailer::sendVerifyEmail($to, $origin . $base . "/verify-email?token=lab-smoke");
|
||||
echo $ok ? "mail_ok" : "mail_fail";
|
||||
' 2>&1)" || _out="mail_fail"
|
||||
|
||||
log "$_out to=$TO"
|
||||
case "$_out" in
|
||||
mail_ok) exit 0 ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user