release: sync public installer asset install.sh

This commit is contained in:
2026-09-08 11:38:21 +00:00
parent 492f9e2547
commit 71a04e81f5
+95 -6
View File
@@ -21,6 +21,9 @@ PG_HOST_CLI=0
API_PORT=${XYMEDIA_API_PORT:-18080} API_PORT=${XYMEDIA_API_PORT:-18080}
WEBDAV_PORT=${XYMEDIA_WEBDAV_PORT:-18081} WEBDAV_PORT=${XYMEDIA_WEBDAV_PORT:-18081}
TVBOX_PORT=${XYMEDIA_TVBOX_PORT:-18082} TVBOX_PORT=${XYMEDIA_TVBOX_PORT:-18082}
XIAOYA_WEB_PORT=${XYMEDIA_XIAOYA_PORT:-5678}
XIAOYA_ADMIN_PORT=${XYMEDIA_XIAOYA_ADMIN_PORT:-2345}
XIAOYA_PROXY_PORT=${XYMEDIA_XIAOYA_PROXY_PORT:-2346}
TOTAL_STEPS=9 TOTAL_STEPS=9
STEP=0 STEP=0
INSTALL_LOG= INSTALL_LOG=
@@ -34,7 +37,9 @@ XIAOYA_DIR=${XYMEDIA_XIAOYA_DIR:-}
XIAOYA_CONTAINER_EXPLICIT=${XYMEDIA_XIAOYA_CONTAINER:+1} XIAOYA_CONTAINER_EXPLICIT=${XYMEDIA_XIAOYA_CONTAINER:+1}
XIAOYA_CONTAINER=${XYMEDIA_XIAOYA_CONTAINER:-xymedia-xiaoya} XIAOYA_CONTAINER=${XYMEDIA_XIAOYA_CONTAINER:-xymedia-xiaoya}
OPTION2_XIAOYA_PENDING=0 OPTION2_XIAOYA_PENDING=0
OPTION2_XIAOYA_CHOICE=
XIAOYA_FOUND=0 XIAOYA_FOUND=0
XIAOYA_STANDALONE=0
CONTROLLER_ONLY=0 CONTROLLER_ONLY=0
MENU_PROFILES= MENU_PROFILES=
CONTROLLER_URL=${XYMEDIA_XIAOYA_CONTROLLER_URL:-} CONTROLLER_URL=${XYMEDIA_XIAOYA_CONTROLLER_URL:-}
@@ -512,6 +517,52 @@ ensure_xiaoya_dir() {
fi fi
mkdir -p "$XIAOYA_DIR" "$INSTALL_DIR/secrets" mkdir -p "$XIAOYA_DIR" "$INSTALL_DIR/secrets"
} }
validate_xiaoya_ports() {
local port
for port in "$XIAOYA_WEB_PORT" "$XIAOYA_ADMIN_PORT" "$XIAOYA_PROXY_PORT"; do
[[ $port =~ ^[0-9]+$ && $port -ge 1 && $port -le 65535 ]] || die '小雅主机端口必须是 1 到 65535 之间的数字'
done
[[ $XIAOYA_WEB_PORT != "$XIAOYA_ADMIN_PORT" && $XIAOYA_WEB_PORT != "$XIAOYA_PROXY_PORT" && $XIAOYA_ADMIN_PORT != "$XIAOYA_PROXY_PORT" ]] || die '小雅三个主机端口不能重复'
for port in "$XIAOYA_WEB_PORT" "$XIAOYA_ADMIN_PORT" "$XIAOYA_PROXY_PORT"; do
if ! python3 - "$port" <<'PY'
import socket, sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.bind(('0.0.0.0', int(sys.argv[1])))
except OSError:
raise SystemExit(1)
finally:
sock.close()
PY
then die "小雅主机端口已被占用:$port"; fi
done
}
next_free_xiaoya_port() {
XIAOYA_PORT_START=$1 XIAOYA_PORT_USED=${2:-} python3 - <<'PY'
import os, socket
port = int(os.environ['XIAOYA_PORT_START'])
used = set(filter(None, os.environ.get('XIAOYA_PORT_USED', '').split(',')))
while port <= 65535:
if str(port) not in used:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.bind(('0.0.0.0', port)); print(port); break
except OSError: pass
finally: sock.close()
port += 1
else: raise SystemExit(1)
PY
}
select_xiaoya_ports() {
local default_port choice used=
default_port=$(next_free_xiaoya_port 5678) || die '无法选择小雅 Web 主机端口'
prompt_tty_into choice "小雅 Web 主机端口 [$default_port]"; XIAOYA_WEB_PORT=${choice:-$default_port}; used=$XIAOYA_WEB_PORT
default_port=$(next_free_xiaoya_port 2345 "$used") || die '无法选择小雅 2345 主机端口'
prompt_tty_into choice "小雅 2345 主机端口 [$default_port]"; XIAOYA_ADMIN_PORT=${choice:-$default_port}; used="$XIAOYA_WEB_PORT,$XIAOYA_ADMIN_PORT"
default_port=$(next_free_xiaoya_port 2346 "$used") || die '无法选择小雅 2346 主机端口'
prompt_tty_into choice "小雅 2346 主机端口 [$default_port]"; XIAOYA_PROXY_PORT=${choice:-$default_port}
validate_xiaoya_ports
}
write_controller_token() { write_controller_token() {
local file; mkdir -p "$INSTALL_DIR/secrets"; file=$(controller_token_file) local file; mkdir -p "$INSTALL_DIR/secrets"; file=$(controller_token_file)
if [[ ! -s $file ]]; then umask 077; if command -v openssl >/dev/null; then openssl rand -hex 32 >"$file"; else od -An -N32 -tx1 /dev/urandom | tr -d ' \n' >"$file"; fi; chmod 600 "$file"; fi if [[ ! -s $file ]]; then umask 077; if command -v openssl >/dev/null; then openssl rand -hex 32 >"$file"; else od -An -N32 -tx1 /dev/urandom | tr -d ' \n' >"$file"; fi; chmod 600 "$file"; fi
@@ -524,7 +575,7 @@ menu() {
read_tty choice || die '无法读取终端输入' read_tty choice || die '无法读取终端输入'
case "$choice" in case "$choice" in
1) return 0;; 1) 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;; 2) 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;; 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
@@ -554,6 +605,9 @@ if [[ -f "$INSTALL_DIR/.env" ]]; then
XIAOYA_CONTAINER_EXPLICIT=1 XIAOYA_CONTAINER_EXPLICIT=1
fi fi
fi fi
if [[ -z ${XYMEDIA_XIAOYA_PORT:-} ]]; then value=$(read_install_env XYMEDIA_XIAOYA_PORT); [[ -z $value ]] || XIAOYA_WEB_PORT=$value; fi
if [[ -z ${XYMEDIA_XIAOYA_ADMIN_PORT:-} ]]; then value=$(read_install_env XYMEDIA_XIAOYA_ADMIN_PORT); [[ -z $value ]] || XIAOYA_ADMIN_PORT=$value; fi
if [[ -z ${XYMEDIA_XIAOYA_PROXY_PORT:-} ]]; then value=$(read_install_env XYMEDIA_XIAOYA_PROXY_PORT); [[ -z $value ]] || XIAOYA_PROXY_PORT=$value; fi
fi fi
menu "$@" menu "$@"
validate_controller_settings() { validate_controller_settings() {
@@ -662,6 +716,8 @@ except (ValueError, IndexError, TypeError, AttributeError):
if ((${#ordered[@]} == 0)); then if ((${#ordered[@]} == 0)); then
if (( OPTION2_XIAOYA_PENDING )); then if (( OPTION2_XIAOYA_PENDING )); then
XIAOYA_FOUND=0 XIAOYA_FOUND=0
OPTION2_XIAOYA_CHOICE=standalone
XIAOYA_STANDALONE=1
XIAOYA_CONTAINER=xymedia-xiaoya XIAOYA_CONTAINER=xymedia-xiaoya
return 0 return 0
fi fi
@@ -672,9 +728,21 @@ except (ValueError, IndexError, TypeError, AttributeError):
XIAOYA_FOUND=1 XIAOYA_FOUND=1
printf '已确认手动指定的小雅容器:%s\n' "$XIAOYA_CONTAINER" >>$TTY_OUT printf '已确认手动指定的小雅容器:%s\n' "$XIAOYA_CONTAINER" >>$TTY_OUT
elif ((${#ordered[@]} == 1)); then elif ((${#ordered[@]} == 1)); then
IFS=$'\t' read -r XIAOYA_CONTAINER image state <<<"${ordered[0]}" IFS=$'\t' read -r selected image state <<<"${ordered[0]}"
printf '自动发现小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT if (( OPTION2_XIAOYA_PENDING )); then
printf '发现已有小雅容器:%s(镜像:%s,状态:%s)\n' "$selected" "$image" "$state" >>$TTY_OUT
prompt_tty_into choice '请选择:1) 复用该容器 2) 安装独立小雅 0) 取消:'
case "$choice" in
1) XIAOYA_CONTAINER=$selected; XIAOYA_FOUND=1; OPTION2_XIAOYA_CHOICE=reuse;;
2) XIAOYA_CONTAINER=xymedia-xiaoya; XIAOYA_FOUND=0; XIAOYA_STANDALONE=1; OPTION2_XIAOYA_CHOICE=standalone; return 0;;
0) exit 0;;
*) die '无效选择,请输入 1、2 或 0';;
esac
else
XIAOYA_CONTAINER=$selected
XIAOYA_FOUND=1 XIAOYA_FOUND=1
printf '自动发现小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT
fi
[[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT [[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT
else else
printf '发现多个可能的小雅容器(运行中的优先):\n' >>$TTY_OUT printf '发现多个可能的小雅容器(运行中的优先):\n' >>$TTY_OUT
@@ -684,12 +752,25 @@ except (ValueError, IndexError, TypeError, AttributeError):
printf '%d) %s(镜像:%s,状态:%s\n' "$index" "$name" "$image" "$state" >>$TTY_OUT printf '%d) %s(镜像:%s,状态:%s\n' "$index" "$name" "$image" "$state" >>$TTY_OUT
index=$((index + 1)) index=$((index + 1))
done done
if (( OPTION2_XIAOYA_PENDING )); then
prompt_tty_into choice '请选择:1) 复用已有容器 2) 安装独立小雅 0) 取消:'
else
prompt_tty_into choice '请选择容器编号:' prompt_tty_into choice '请选择容器编号:'
[[ $choice =~ ^[0-9]+$ && $choice -ge 1 && $choice -le ${#ordered[@]} ]] || die '无效的小雅容器编号' [[ $choice =~ ^[0-9]+$ && $choice -ge 1 && $choice -le ${#ordered[@]} ]] || die '无效的小雅容器编号'
IFS=$'\t' read -r XIAOYA_CONTAINER image state <<<"${ordered[$((choice - 1))]}" IFS=$'\t' read -r XIAOYA_CONTAINER image state <<<"${ordered[$((choice - 1))]}"
XIAOYA_FOUND=1 XIAOYA_FOUND=1
printf '已选择小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT printf '已选择小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT
[[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT [[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT
return 0
fi
case "$choice" in
1) 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; OPTION2_XIAOYA_CHOICE=reuse;;
2) XIAOYA_CONTAINER=xymedia-xiaoya; XIAOYA_FOUND=0; XIAOYA_STANDALONE=1; OPTION2_XIAOYA_CHOICE=standalone; return 0;;
0) exit 0;;
*) die '无效选择,请输入 1、2 或 0';;
esac
printf '已选择小雅容器:%s(镜像:%s,状态:%s)\n' "$XIAOYA_CONTAINER" "$image" "$state" >>$TTY_OUT
[[ $state == running ]] || printf '警告:小雅容器当前已停止;仍允许安装控制器,状态页会提示。\n' >>$TTY_OUT
fi fi
} }
prepare_option2_xiaoya() { prepare_option2_xiaoya() {
@@ -697,14 +778,20 @@ prepare_option2_xiaoya() {
discover_xiaoya_container discover_xiaoya_container
validate_container_name validate_container_name
if (( XIAOYA_FOUND )); then if (( XIAOYA_FOUND )); then
ensure_xiaoya_dir 1
validate_xiaoya_data_dir validate_xiaoya_data_dir
XYMEDIA_XIAOYA_MANAGED=0 XYMEDIA_XIAOYA_MANAGED=0
OPTION2_XIAOYA_CHOICE=reuse
MENU_PROFILES='xiaoya-control' MENU_PROFILES='xiaoya-control'
printf '检测到已有小雅容器:%s,将复用,不创建新的小雅容器。\n' "$XIAOYA_CONTAINER" >>$TTY_OUT printf '检测到已有小雅容器:%s,将复用,不创建新的小雅容器。\n' "$XIAOYA_CONTAINER" >>$TTY_OUT
else else
XIAOYA_STANDALONE=1
XIAOYA_DIR=$INSTALL_DIR/xiaoya
XYMEDIA_XIAOYA_MANAGED=1 XYMEDIA_XIAOYA_MANAGED=1
OPTION2_XIAOYA_CHOICE=standalone
MENU_PROFILES='xiaoya xiaoya-control' MENU_PROFILES='xiaoya xiaoya-control'
printf '未检测到已有小雅容器,将安装新的小雅容器:%s。\n' "$XIAOYA_CONTAINER" >>$TTY_OUT select_xiaoya_ports
printf '将安装独立的小雅容器:%s(数据目录:%s)。\n' "$XIAOYA_CONTAINER" "$XIAOYA_DIR" >>$TTY_OUT
fi fi
} }
validate_xiaoya_data_dir() { validate_xiaoya_data_dir() {
@@ -1015,14 +1102,16 @@ env_tmp=$(mktemp "$INSTALL_DIR/.env.tmp.XXXXXX") || die '无法创建安全的 .
chmod 600 "$env_tmp" chmod 600 "$env_tmp"
if [[ -f "$INSTALL_DIR/.env" ]]; then cp "$INSTALL_DIR/.env" "$env_tmp"; fi if [[ -f "$INSTALL_DIR/.env" ]]; then cp "$INSTALL_DIR/.env" "$env_tmp"; fi
XIAOYA_MANAGED_ENV=$(awk -F= '$1 == "XYMEDIA_XIAOYA_MANAGED" {print $2; exit}' "$env_tmp" 2>/dev/null || true) XIAOYA_MANAGED_ENV=$(awk -F= '$1 == "XYMEDIA_XIAOYA_MANAGED" {print $2; exit}' "$env_tmp" 2>/dev/null || true)
if [[ -z $OPTION2_XIAOYA_CHOICE ]]; then
[[ ${XYMEDIA_XIAOYA_MANAGED:-0} == 1 ]] || XYMEDIA_XIAOYA_MANAGED=${XIAOYA_MANAGED_ENV:-0} [[ ${XYMEDIA_XIAOYA_MANAGED:-0} == 1 ]] || XYMEDIA_XIAOYA_MANAGED=${XIAOYA_MANAGED_ENV:-0}
fi
FUSE_ENABLED=$(awk -F= '$1 == "XYMEDIA_FUSE_ENABLED" {print $2; exit}' "$env_tmp" 2>/dev/null || true) FUSE_ENABLED=$(awk -F= '$1 == "XYMEDIA_FUSE_ENABLED" {print $2; exit}' "$env_tmp" 2>/dev/null || true)
FUSE_HOST_PATH=$(awk -F= '$1 == "XYMEDIA_FUSE_HOST_PATH" {print $2; exit}' "$env_tmp" 2>/dev/null || true) FUSE_HOST_PATH=$(awk -F= '$1 == "XYMEDIA_FUSE_HOST_PATH" {print $2; exit}' "$env_tmp" 2>/dev/null || true)
[[ $FUSE_ENABLED == true || $FUSE_ENABLED == false ]] || FUSE_ENABLED=false [[ $FUSE_ENABLED == true || $FUSE_ENABLED == false ]] || FUSE_ENABLED=false
python3 - "$env_tmp" "$INSTALL_DIR" "$PG_HOST" "$PG_PORT" "$PG_DB" "$PG_USER" "$API_PORT" "$WEBDAV_PORT" "$TVBOX_PORT" "$CONTROLLER_URL" "${XIAOYA_DIR:-$INSTALL_DIR/xiaoya}" "$XIAOYA_CONTAINER" "$HOST_ADDRESSES_ENV" "$CONTROLLER_BIND_ADDRESS" "$CONTROLLER_PORT" "$FUSE_ENABLED" "$FUSE_HOST_PATH" "${XYMEDIA_XIAOYA_MANAGED:-0}" "$XYMEDIA_INSTANCE_ID" "$LOCAL_DB" "$XYMEDIA_POSTGRES_PUBLIC_PORT" <<'PY' python3 - "$env_tmp" "$INSTALL_DIR" "$PG_HOST" "$PG_PORT" "$PG_DB" "$PG_USER" "$API_PORT" "$WEBDAV_PORT" "$TVBOX_PORT" "$CONTROLLER_URL" "${XIAOYA_DIR:-$INSTALL_DIR/xiaoya}" "$XIAOYA_CONTAINER" "$HOST_ADDRESSES_ENV" "$CONTROLLER_BIND_ADDRESS" "$CONTROLLER_PORT" "$FUSE_ENABLED" "$FUSE_HOST_PATH" "${XYMEDIA_XIAOYA_MANAGED:-0}" "$XYMEDIA_INSTANCE_ID" "$LOCAL_DB" "$XYMEDIA_POSTGRES_PUBLIC_PORT" "$XIAOYA_WEB_PORT" "$XIAOYA_ADMIN_PORT" "$XIAOYA_PROXY_PORT" <<'PY'
import pathlib, sys import pathlib, sys
p=pathlib.Path(sys.argv[1]) p=pathlib.Path(sys.argv[1])
keys=('XYMEDIA_INSTALL_DIR','XYMEDIA_POSTGRES_HOST','XYMEDIA_POSTGRES_PORT','XYMEDIA_POSTGRES_DATABASE','XYMEDIA_POSTGRES_USER','XYMEDIA_API_PORT','XYMEDIA_WEBDAV_PORT','XYMEDIA_TVBOX_PORT','XYMEDIA_XIAOYA_CONTROLLER_URL','XYMEDIA_XIAOYA_DATA_DIR','XYMEDIA_XIAOYA_CONTAINER','XYMEDIA_HOST_ADDRESSES','XYMEDIA_CONTROLLER_BIND_ADDRESS','XYMEDIA_CONTROLLER_PORT','XYMEDIA_FUSE_ENABLED','XYMEDIA_FUSE_HOST_PATH','XYMEDIA_XIAOYA_MANAGED','XYMEDIA_INSTANCE_ID','XYMEDIA_POSTGRES_LOCAL_DB','XYMEDIA_POSTGRES_PUBLIC_PORT') keys=('XYMEDIA_INSTALL_DIR','XYMEDIA_POSTGRES_HOST','XYMEDIA_POSTGRES_PORT','XYMEDIA_POSTGRES_DATABASE','XYMEDIA_POSTGRES_USER','XYMEDIA_API_PORT','XYMEDIA_WEBDAV_PORT','XYMEDIA_TVBOX_PORT','XYMEDIA_XIAOYA_CONTROLLER_URL','XYMEDIA_XIAOYA_DATA_DIR','XYMEDIA_XIAOYA_CONTAINER','XYMEDIA_HOST_ADDRESSES','XYMEDIA_CONTROLLER_BIND_ADDRESS','XYMEDIA_CONTROLLER_PORT','XYMEDIA_FUSE_ENABLED','XYMEDIA_FUSE_HOST_PATH','XYMEDIA_XIAOYA_MANAGED','XYMEDIA_INSTANCE_ID','XYMEDIA_POSTGRES_LOCAL_DB','XYMEDIA_POSTGRES_PUBLIC_PORT','XYMEDIA_XIAOYA_PORT','XYMEDIA_XIAOYA_ADMIN_PORT','XYMEDIA_XIAOYA_PROXY_PORT')
values=dict(zip(keys, sys.argv[2:])) values=dict(zip(keys, sys.argv[2:]))
seen=set(); output=[] seen=set(); output=[]
for line in p.read_text().splitlines(): for line in p.read_text().splitlines():