release: sync public installer asset install.sh
This commit is contained in:
+34
-17
@@ -27,7 +27,7 @@ TTY_TEST_LINES=()
|
|||||||
if [[ -n ${XYMEDIA_INSTALL_TEST_TTY:-} ]]; then TTY_TEST_MODE=1; mapfile -t TTY_TEST_LINES <"$TTY_IN"; fi
|
if [[ -n ${XYMEDIA_INSTALL_TEST_TTY:-} ]]; then TTY_TEST_MODE=1; mapfile -t TTY_TEST_LINES <"$TTY_IN"; fi
|
||||||
XIAOYA_DIR=${XYMEDIA_XIAOYA_DIR:-}
|
XIAOYA_DIR=${XYMEDIA_XIAOYA_DIR:-}
|
||||||
XIAOYA_CONTAINER_EXPLICIT=${XYMEDIA_XIAOYA_CONTAINER:+1}
|
XIAOYA_CONTAINER_EXPLICIT=${XYMEDIA_XIAOYA_CONTAINER:+1}
|
||||||
XIAOYA_CONTAINER=${XYMEDIA_XIAOYA_CONTAINER:-xiaoya-alist}
|
XIAOYA_CONTAINER=${XYMEDIA_XIAOYA_CONTAINER:-xymedia-xiaoya}
|
||||||
CONTROLLER_ONLY=0
|
CONTROLLER_ONLY=0
|
||||||
MENU_PROFILES=
|
MENU_PROFILES=
|
||||||
CONTROLLER_URL=${XYMEDIA_XIAOYA_CONTROLLER_URL:-}
|
CONTROLLER_URL=${XYMEDIA_XIAOYA_CONTROLLER_URL:-}
|
||||||
@@ -106,7 +106,7 @@ done
|
|||||||
die() { printf '\n\033[31mxymediavault installer: %s\033[0m\n' "$*" >&2; [[ -n $INSTALL_LOG ]] && printf '详情日志:%s\n' "$INSTALL_LOG" >&2; exit 1; }
|
die() { printf '\n\033[31mxymediavault installer: %s\033[0m\n' "$*" >&2; [[ -n $INSTALL_LOG ]] && printf '详情日志:%s\n' "$INSTALL_LOG" >&2; exit 1; }
|
||||||
INSTALL_TMP_DIR=
|
INSTALL_TMP_DIR=
|
||||||
cleanup_installer_tmp() { [[ -z ${INSTALL_TMP_DIR:-} ]] || rm -rf -- "$INSTALL_TMP_DIR"; }
|
cleanup_installer_tmp() { [[ -z ${INSTALL_TMP_DIR:-} ]] || rm -rf -- "$INSTALL_TMP_DIR"; }
|
||||||
trap cleanup_installer_tmp EXIT INT TERM
|
trap cleanup_installer_tmp EXIT
|
||||||
init_installer_log() {
|
init_installer_log() {
|
||||||
local tmp_parent=${TMPDIR:-/tmp} mode
|
local tmp_parent=${TMPDIR:-/tmp} mode
|
||||||
[[ -d $tmp_parent && ! -L $tmp_parent ]] || die 'TMPDIR must be an existing non-symlink directory'
|
[[ -d $tmp_parent && ! -L $tmp_parent ]] || die 'TMPDIR must be an existing non-symlink directory'
|
||||||
@@ -184,7 +184,7 @@ menu() {
|
|||||||
read_tty choice || die 'unable to read terminal input'
|
read_tty choice || die 'unable to read terminal input'
|
||||||
case "$choice" in
|
case "$choice" in
|
||||||
1) return 0;;
|
1) return 0;;
|
||||||
2) ensure_xiaoya_dir; printf '小雅目录已准备:%s;将安装小雅和小雅控制器。\n' "$XIAOYA_DIR" >>$TTY_OUT; write_controller_token; CONTROLLER_URL='http://xymedia-edge-controller:19090'; MENU_PROFILES='xiaoya xiaoya-control'; return 0;;
|
2) ensure_xiaoya_dir; printf '小雅目录已准备:%s;将安装小雅和小雅控制器。\n' "$XIAOYA_DIR" >>$TTY_OUT; write_controller_token; CONTROLLER_URL='http://xymedia-controller:19090'; MENU_PROFILES='xiaoya xiaoya-control'; return 0;;
|
||||||
3) local url name key; url=$(prompt_tty '控制器地址:'); key=$(prompt_tty '控制器密钥:'); name=$(prompt_tty '显示名称:'); [[ $url == https://* || ${ALLOW_HTTP:-0} == 1 ]] || die '远程连接默认要求 HTTPS;设置 ALLOW_HTTP=1 后才允许 HTTP'; curl --fail --silent --show-error --location --max-time 10 -H "X-XyMedia-Controller-Token: $key" "${url%/}/health" >/dev/null || die '控制器健康检查失败,未保存连接'; REMOTE_MODE=1; REMOTE_TOKEN=$key; CONTROLLER_URL="${url%/}"; printf '远程连接 %s (%s) 校验成功,配置已保存;控制器密钥不会显示。\n' "$name" "$CONTROLLER_URL" >>$TTY_OUT; return 0;;
|
3) local url name key; url=$(prompt_tty '控制器地址:'); key=$(prompt_tty '控制器密钥:'); name=$(prompt_tty '显示名称:'); [[ $url == https://* || ${ALLOW_HTTP:-0} == 1 ]] || die '远程连接默认要求 HTTPS;设置 ALLOW_HTTP=1 后才允许 HTTP'; curl --fail --silent --show-error --location --max-time 10 -H "X-XyMedia-Controller-Token: $key" "${url%/}/health" >/dev/null || die '控制器健康检查失败,未保存连接'; REMOTE_MODE=1; REMOTE_TOKEN=$key; CONTROLLER_URL="${url%/}"; printf '远程连接 %s (%s) 校验成功,配置已保存;控制器密钥不会显示。\n' "$name" "$CONTROLLER_URL" >>$TTY_OUT; return 0;;
|
||||||
4) ensure_xiaoya_dir 1; if [[ ${XYMEDIA_INSTALL_TEST_DISCOVERY_ONLY:-0} != 1 && -z $CONTROLLER_BIND_EXPLICIT ]]; then prompt_tty_into CONTROLLER_BIND_ADDRESS "控制器监听地址 [${CONTROLLER_BIND_ADDRESS}]: "; CONTROLLER_BIND_ADDRESS=${CONTROLLER_BIND_ADDRESS:-0.0.0.0}; fi; if [[ ${XYMEDIA_INSTALL_TEST_DISCOVERY_ONLY:-0} != 1 && -z $CONTROLLER_PORT_EXPLICIT ]]; then prompt_tty_into CONTROLLER_PORT "控制器端口 [${CONTROLLER_PORT}]: "; CONTROLLER_PORT=${CONTROLLER_PORT:-19090}; fi; write_controller_token; CONTROLLER_ONLY=1; printf '小雅控制器安装目录已准备。\n' >>$TTY_OUT; MENU_PROFILES='xiaoya-control'; return 0;;
|
4) ensure_xiaoya_dir 1; if [[ ${XYMEDIA_INSTALL_TEST_DISCOVERY_ONLY:-0} != 1 && -z $CONTROLLER_BIND_EXPLICIT ]]; then prompt_tty_into CONTROLLER_BIND_ADDRESS "控制器监听地址 [${CONTROLLER_BIND_ADDRESS}]: "; CONTROLLER_BIND_ADDRESS=${CONTROLLER_BIND_ADDRESS:-0.0.0.0}; fi; if [[ ${XYMEDIA_INSTALL_TEST_DISCOVERY_ONLY:-0} != 1 && -z $CONTROLLER_PORT_EXPLICIT ]]; then prompt_tty_into CONTROLLER_PORT "控制器端口 [${CONTROLLER_PORT}]: "; CONTROLLER_PORT=${CONTROLLER_PORT:-19090}; fi; write_controller_token; CONTROLLER_ONLY=1; printf '小雅控制器安装目录已准备。\n' >>$TTY_OUT; MENU_PROFILES='xiaoya-control'; return 0;;
|
||||||
5) while :; do
|
5) while :; do
|
||||||
@@ -614,7 +614,7 @@ if (( ! SKIP_COMPONENTS )); then
|
|||||||
cp "$archive" "$INSTALL_DIR/components/$component.tar.zst"
|
cp "$archive" "$INSTALL_DIR/components/$component.tar.zst"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
CONTROLLER_URL="$CONTROLLER_URL" PG_HOST="$PG_HOST" PG_PORT="$PG_PORT" PG_DB="$PG_DB" PG_USER="$PG_USER" python3 - "$CONFIG_TEMPLATE" "$INSTALL_DIR/config.yaml" <<'PY'
|
CONTROLLER_URL="$CONTROLLER_URL" XIAOYA_CONTAINER="$XIAOYA_CONTAINER" PG_HOST="$PG_HOST" PG_PORT="$PG_PORT" PG_DB="$PG_DB" PG_USER="$PG_USER" python3 - "$CONFIG_TEMPLATE" "$INSTALL_DIR/config.yaml" <<'PY'
|
||||||
import os, pathlib, sys
|
import os, pathlib, sys
|
||||||
template, output = map(pathlib.Path, sys.argv[1:])
|
template, output = map(pathlib.Path, sys.argv[1:])
|
||||||
values = {
|
values = {
|
||||||
@@ -623,6 +623,7 @@ values = {
|
|||||||
"${XYMEDIA_POSTGRES_DATABASE}": os.environ["PG_DB"],
|
"${XYMEDIA_POSTGRES_DATABASE}": os.environ["PG_DB"],
|
||||||
"${XYMEDIA_POSTGRES_USER}": os.environ["PG_USER"],
|
"${XYMEDIA_POSTGRES_USER}": os.environ["PG_USER"],
|
||||||
"${XYMEDIA_XIAOYA_CONTROLLER_URL}": os.environ["CONTROLLER_URL"],
|
"${XYMEDIA_XIAOYA_CONTROLLER_URL}": os.environ["CONTROLLER_URL"],
|
||||||
|
"${XYMEDIA_XIAOYA_CONTAINER}": os.environ["XIAOYA_CONTAINER"],
|
||||||
}
|
}
|
||||||
content = template.read_text()
|
content = template.read_text()
|
||||||
for placeholder, value in values.items():
|
for placeholder, value in values.items():
|
||||||
@@ -662,35 +663,51 @@ if [[ $PG_HOST == postgres ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [[ $PG_HOST == postgres ]]; then
|
if [[ $PG_HOST == postgres ]]; then
|
||||||
ready=0
|
wait_for_postgres() {
|
||||||
for elapsed in $(seq 0 298 2); do
|
local started_at elapsed container_id health
|
||||||
|
local previous_int previous_term
|
||||||
|
postgres_wait_interrupted=0
|
||||||
|
started_at=$(date +%s)
|
||||||
|
previous_int=$(trap -p INT || true)
|
||||||
|
previous_term=$(trap -p TERM || true)
|
||||||
|
trap 'postgres_wait_interrupted=1' INT TERM
|
||||||
|
while :; do
|
||||||
|
if (( postgres_wait_interrupted )); then
|
||||||
|
printf '\n已收到中断信号,正在停止 PostgreSQL 等待。\n'
|
||||||
|
printf '%s\n' 'PostgreSQL wait interrupted by signal' >>"$INSTALL_LOG"
|
||||||
|
printf '\n--- PostgreSQL 容器日志 ---\n' >>"$INSTALL_LOG"
|
||||||
|
"${COMPOSE[@]}" --profile local-db --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" logs postgres >>"$INSTALL_LOG" 2>&1 || true
|
||||||
|
[[ -n $previous_int ]] && eval "$previous_int" || trap - INT
|
||||||
|
[[ -n $previous_term ]] && eval "$previous_term" || trap - TERM
|
||||||
|
return 130
|
||||||
|
fi
|
||||||
|
elapsed=$(( $(date +%s) - started_at ))
|
||||||
container_id=$("${COMPOSE[@]}" --profile local-db --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" ps -q postgres 2>>"$INSTALL_LOG" || true)
|
container_id=$("${COMPOSE[@]}" --profile local-db --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" ps -q postgres 2>>"$INSTALL_LOG" || true)
|
||||||
health=
|
health=
|
||||||
if [[ -n $container_id ]]; then
|
if [[ -n $container_id ]]; then
|
||||||
health=$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container_id" 2>>"$INSTALL_LOG" || true)
|
health=$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container_id" 2>>"$INSTALL_LOG" || true)
|
||||||
fi
|
fi
|
||||||
if [[ $health == healthy ]]; then
|
if [[ $health == healthy ]]; then
|
||||||
ready=1
|
printf '\033[2K\r[%d/%d] PostgreSQL 已就绪(%s 秒)\n' "$STEP" "$TOTAL_STEPS" "$elapsed"
|
||||||
break
|
[[ -n $previous_int ]] && eval "$previous_int" || trap - INT
|
||||||
|
[[ -n $previous_term ]] && eval "$previous_term" || trap - TERM
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
printf '\033[2K\r[%d/%d] 等待 PostgreSQL 就绪(%s 秒)' "$STEP" "$TOTAL_STEPS" "$elapsed"
|
printf '\033[2K\r[%d/%d] 等待 PostgreSQL 就绪(已用 %s 秒,状态:%s)' "$STEP" "$TOTAL_STEPS" "$elapsed" "${health:-unknown}"
|
||||||
|
printf 'PostgreSQL status: elapsed=%s health=%s\n' "$elapsed" "${health:-unknown}" >>"$INSTALL_LOG"
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
printf '\n'
|
}
|
||||||
if [[ $ready != 1 ]]; then
|
wait_for_postgres || die 'PostgreSQL 等待被中断,安装未完成'
|
||||||
printf '\n--- PostgreSQL 容器日志 ---\n' >>"$INSTALL_LOG"
|
|
||||||
"${COMPOSE[@]}" --profile local-db --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" logs postgres >>"$INSTALL_LOG" 2>&1 || true
|
|
||||||
die 'PostgreSQL 未在限定时间内就绪'
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
progress '初始化数据库结构'
|
progress '初始化数据库结构'
|
||||||
if (( EXISTING_DB )); then
|
if (( EXISTING_DB )); then
|
||||||
export XYMEDIA_EXTERNAL_MIGRATION_CONFIRM=YES
|
export XYMEDIA_EXTERNAL_MIGRATION_CONFIRM=YES
|
||||||
if ! run_visible_logged "${COMPOSE[@]}" --profile migration --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" "${COMPOSE_FUSE[@]}" run --rm --no-deps app-migrate migrate --config /app/config.yaml; then
|
if ! run_visible_logged "${COMPOSE[@]}" --profile migration --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" "${COMPOSE_FUSE[@]}" run --rm --name "xymedia-app-migrate-${INSTALL_NONCE}" --no-deps app-migrate migrate --config /app/config.yaml; then
|
||||||
die '已有数据库迁移失败'
|
die '已有数据库迁移失败'
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if ! run_visible_logged "${COMPOSE[@]}" --profile migration --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" "${COMPOSE_FUSE[@]}" run --rm --no-deps app-migrate migrate --new --config /app/config.yaml; then
|
if ! run_visible_logged "${COMPOSE[@]}" --profile migration --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" "${COMPOSE_FUSE[@]}" run --rm --name "xymedia-app-migrate-${INSTALL_NONCE}" --no-deps app-migrate migrate --new --config /app/config.yaml; then
|
||||||
die '数据库初始化失败'
|
die '数据库初始化失败'
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user