release: sync public installer asset install.sh

This commit is contained in:
2026-09-02 07:40:30 +00:00
parent de9c0688ba
commit 679b0d31d3
+58 -7
View File
@@ -33,6 +33,8 @@ if [[ -n ${XYMEDIA_INSTALL_TEST_TTY:-} ]]; then TTY_TEST_MODE=1; mapfile -t TTY_
XIAOYA_DIR=${XYMEDIA_XIAOYA_DIR:-}
XIAOYA_CONTAINER_EXPLICIT=${XYMEDIA_XIAOYA_CONTAINER:+1}
XIAOYA_CONTAINER=${XYMEDIA_XIAOYA_CONTAINER:-xymedia-xiaoya}
OPTION2_XIAOYA_PENDING=0
XIAOYA_FOUND=0
CONTROLLER_ONLY=0
MENU_PROFILES=
CONTROLLER_URL=${XYMEDIA_XIAOYA_CONTROLLER_URL:-}
@@ -373,7 +375,7 @@ menu() {
read_tty choice || die '无法读取终端输入'
case "$choice" in
1) return 0;;
2) ensure_xiaoya_dir; printf '小雅目录已准备:%s安装小雅和小雅控制器。\n' "$XIAOYA_DIR" >>$TTY_OUT; write_controller_token; CONTROLLER_URL='http://xymedia-controller:19090'; [[ -f "$INSTALL_DIR/.env" ]] || XYMEDIA_XIAOYA_MANAGED=1; MENU_PROFILES='xiaoya xiaoya-control'; return 0;;
2) ensure_xiaoya_dir; printf '小雅目录已准备:%s;安装器将在 Docker 检查后检测并复用已有小雅。\n' "$XIAOYA_DIR" >>$TTY_OUT; write_controller_token; CONTROLLER_URL='http://xymedia-controller:19090'; OPTION2_XIAOYA_PENDING=1; 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;;
5) while :; do
@@ -394,11 +396,17 @@ menu() {
esac
done
}
menu "$@"
if [[ ${XYMEDIA_INSTALL_TEST_MENU_ONLY:-0} == 1 ]]; then
printf 'TEST_MENU_PROFILES=%s\n' "$MENU_PROFILES" >$TTY_OUT
exit 0
if [[ -f "$INSTALL_DIR/.env" ]]; then
[[ -n ${XYMEDIA_XIAOYA_DIR:-} ]] || XIAOYA_DIR=$(read_install_env XYMEDIA_XIAOYA_DATA_DIR)
if [[ -z ${XYMEDIA_XIAOYA_CONTAINER:-} ]]; then
existing_xiaoya_container=$(read_install_env XYMEDIA_XIAOYA_CONTAINER)
if [[ -n $existing_xiaoya_container ]]; then
XIAOYA_CONTAINER=$existing_xiaoya_container
XIAOYA_CONTAINER_EXPLICIT=1
fi
fi
fi
menu "$@"
validate_controller_settings() {
[[ $CONTROLLER_PORT =~ ^[0-9]+$ && $CONTROLLER_PORT -ge 1 && $CONTROLLER_PORT -le 65535 ]] || die '控制器端口必须是 1 到 65535 之间的数字'
[[ $CONTROLLER_BIND_ADDRESS != *$'\r'* && $CONTROLLER_BIND_ADDRESS != *$'\n'* ]] || die '控制器监听地址不能包含换行'
@@ -423,6 +431,18 @@ progress '检查安装环境'
[[ $INSTALL_DIR = /* && $INSTALL_DIR != / ]] || die '安装目录必须是绝对路径且不能是根目录'
guard_existing_install_tree
if [[ -f "$INSTALL_DIR/.env" ]]; then INSTALL_EXISTING=1; fi
if (( INSTALL_EXISTING )); then
if [[ -z ${XYMEDIA_XIAOYA_DIR:-} ]]; then
XIAOYA_DIR=$(read_install_env XYMEDIA_XIAOYA_DATA_DIR)
fi
if [[ -z ${XYMEDIA_XIAOYA_CONTAINER:-} ]]; then
existing_xiaoya_container=$(read_install_env XYMEDIA_XIAOYA_CONTAINER)
if [[ -n $existing_xiaoya_container ]]; then
XIAOYA_CONTAINER=$existing_xiaoya_container
XIAOYA_CONTAINER_EXPLICIT=1
fi
fi
fi
init_installer_log
command -v docker >/dev/null || die '需要安装 Docker'
if docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose); elif command -v docker-compose >/dev/null; then COMPOSE=(docker-compose); else die '需要安装 Docker Compose'; fi
@@ -464,6 +484,7 @@ discover_xiaoya_container() {
local -a ids=() candidates=() ordered=()
if [[ -n ${XIAOYA_CONTAINER_EXPLICIT:-} ]]; then
docker container inspect "$XIAOYA_CONTAINER" >/dev/null 2>&1 || die "未找到小雅容器:$XIAOYA_CONTAINER"
XIAOYA_FOUND=1
printf '使用指定的小雅容器:%sDocker inspect 已确认)\n' "$XIAOYA_CONTAINER" >>$TTY_OUT
return 0
fi
@@ -489,14 +510,21 @@ except (ValueError, IndexError, TypeError, AttributeError):
for record in "${candidates[@]}"; do [[ $record == *$'\trunning' ]] && ordered+=("$record"); done
for record in "${candidates[@]}"; do [[ $record == *$'\trunning' ]] || ordered+=("$record"); done
if ((${#ordered[@]} == 0)); then
if (( OPTION2_XIAOYA_PENDING )); then
XIAOYA_FOUND=0
XIAOYA_CONTAINER=xymedia-xiaoya
return 0
fi
prompt_tty_into selected '未自动发现小雅容器,请输入容器名称(将执行 Docker inspect):'
[[ -n $selected ]] || die '小雅容器名称不能为空'
docker container inspect "$selected" >/dev/null 2>&1 || die "容器不存在或无法 inspect$selected"
XIAOYA_CONTAINER=$selected
XIAOYA_FOUND=1
printf '已确认手动指定的小雅容器:%s\n' "$XIAOYA_CONTAINER" >>$TTY_OUT
elif ((${#ordered[@]} == 1)); then
IFS=$'\t' read -r XIAOYA_CONTAINER image state <<<"${ordered[0]}"
printf '自动发现小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT
XIAOYA_FOUND=1
[[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT
else
printf '发现多个可能的小雅容器(运行中的优先):\n' >>$TTY_OUT
@@ -509,10 +537,26 @@ except (ValueError, IndexError, TypeError, AttributeError):
prompt_tty_into choice '请选择容器编号:'
[[ $choice =~ ^[0-9]+$ && $choice -ge 1 && $choice -le ${#ordered[@]} ]] || die '无效的小雅容器编号'
IFS=$'\t' read -r XIAOYA_CONTAINER image state <<<"${ordered[$((choice - 1))]}"
XIAOYA_FOUND=1
printf '已选择小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT
[[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT
fi
}
prepare_option2_xiaoya() {
(( OPTION2_XIAOYA_PENDING )) || return 0
discover_xiaoya_container
validate_container_name
if (( XIAOYA_FOUND )); then
validate_xiaoya_data_dir
XYMEDIA_XIAOYA_MANAGED=0
MENU_PROFILES='xiaoya-control'
printf '检测到已有小雅容器:%s,将复用,不创建新的小雅容器。\n' "$XIAOYA_CONTAINER" >>$TTY_OUT
else
XYMEDIA_XIAOYA_MANAGED=1
MENU_PROFILES='xiaoya xiaoya-control'
printf '未检测到已有小雅容器,将安装新的小雅容器:%s。\n' "$XIAOYA_CONTAINER" >>$TTY_OUT
fi
}
validate_xiaoya_data_dir() {
local inspect_json
[[ -d $XIAOYA_DIR && $XIAOYA_DIR = /* && $XIAOYA_DIR != / ]] || die '小雅数据目录必须是已存在的绝对目录'
@@ -585,6 +629,11 @@ if (( CONTROLLER_ONLY )); then
[[ ${XYMEDIA_INSTALL_TEST_DISCOVERY_ONLY:-0} == 1 ]] && exit 0
validate_xiaoya_data_dir
fi
prepare_option2_xiaoya
if [[ ${XYMEDIA_INSTALL_TEST_MENU_ONLY:-0} == 1 || ${XYMEDIA_INSTALL_TEST_OPTION2_ONLY:-0} == 1 ]]; then
printf 'TEST_MENU_PROFILES=%s\nTEST_XIAOYA_CONTAINER=%s\nTEST_XIAOYA_MANAGED=%s\n' "$MENU_PROFILES" "$XIAOYA_CONTAINER" "${XYMEDIA_XIAOYA_MANAGED:-0}" >>$TTY_OUT
exit 0
fi
if (( ! CONTROLLER_ONLY )) && (( PG_HOST_CLI )) && [[ $PG_HOST != postgres && $EXISTING_DB != 1 ]]; then die 'an external database requires --existing-db confirmation'; fi
if (( ! CONTROLLER_ONLY )) && (( PG_HOST_CLI )) && [[ $PG_HOST != postgres && -z $PG_PASSWORD_FILE ]]; then die 'an external database requires --postgres-password-file'; fi
if ! [[ $API_PORT =~ ^[0-9]+$ && $WEBDAV_PORT =~ ^[0-9]+$ && $TVBOX_PORT =~ ^[0-9]+$ ]]; then die 'ports must be numeric'; fi
@@ -980,7 +1029,9 @@ tmp.write_text(text)
tmp.replace(p)
PY
if [[ -n $MENU_PROFILES ]]; then
if [[ ${XYMEDIA_XIAOYA_MANAGED:-0} == 1 ]]; then
[[ ${XYMEDIA_INSTALL_CONFIRM:-} == INSTALL_XIAOYA ]] || { confirm=$(prompt_tty '安装小雅将创建并启动相关容器,输入 1 继续,其他内容取消: '); [[ $confirm == 1 ]] || die '已取消小雅安装'; }
fi
for profile in $MENU_PROFILES; do run_logged "${COMPOSE[@]}" --profile "$profile" --project-directory "$INSTALL_DIR" --env-file "$INSTALL_DIR/.env" -f "$INSTALL_DIR/compose.yaml" up -d || die "小雅 profile 启动失败:$profile"; done
if [[ $MENU_PROFILES == *xiaoya-control* ]]; then
controller_state=$(docker inspect --format '{{.State.Status}}' xymedia-controller 2>>"$INSTALL_LOG" || true)
@@ -1075,7 +1126,7 @@ if [[ $migration_rc -ne 0 ]]; then
fi
printf '数据库初始化完成\n'
printf '数据库初始化完成\n' >>"$INSTALL_LOG"
if [[ $MENU_PROFILES == 'xiaoya xiaoya-control' ]]; then
if [[ $MENU_PROFILES == *xiaoya-control* ]]; then
printf '本机小雅控制器连接信息:\n'
print_controller_info
fi
@@ -1119,7 +1170,7 @@ wait_for_app_health || die 'XyMediaVault 健康检查被中断,安装未完成
cp "$INSTALL_LOG" "$INSTALL_DIR/install.log" 2>/dev/null || true
printf '\033[2K\r[%d/%d] 安装完成:XyMediaVault 已就绪\n' "$TOTAL_STEPS" "$TOTAL_STEPS"
printf '管理地址:http://127.0.0.1:%s\n' "$API_PORT"
if [[ $MENU_PROFILES == 'xiaoya xiaoya-control' ]]; then
if [[ $MENU_PROFILES == *xiaoya-control* ]]; then
print_controller_info
fi
if (( LOCAL_DB )); then