mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
feat: загрузка локально собранного бинаря на сервер
This commit is contained in:
+33
-6
@@ -74,6 +74,7 @@ HAS_GUM=0
|
||||
NONINTERACTIVE=0
|
||||
ACTION=""
|
||||
FORCE_UPDATE=0
|
||||
LOCAL_BIN=""
|
||||
PURGE=0
|
||||
TARGET="all"
|
||||
TAIL=80
|
||||
@@ -99,7 +100,7 @@ valid_hostport() {
|
||||
[[ "$1" =~ ^(\[[0-9a-fA-F:]{2,39}\]|[a-zA-Z0-9.-]{1,253}):([0-9]{1,5})$ ]] && valid_port "${BASH_REMATCH[2]}"
|
||||
}
|
||||
valid_kcp() { [[ "$1" =~ ^((-kcp-(nodelay|interval|resend|nc|sndwnd|rcvwnd|mtu)\ [0-9]{1,6}|-kcp-acknodelay=(true|false))( |$))*$ ]]; }
|
||||
valid_version() { [[ "$1" =~ ^(latest|v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?)$ ]]; }
|
||||
valid_version() { [[ "$1" =~ ^(latest|local|v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?)$ ]]; }
|
||||
|
||||
# Подсеть WG: сетевой адрес, префикс /16../29 (сервер .1, клиенты с .2).
|
||||
valid_net() {
|
||||
@@ -535,7 +536,14 @@ validate_config() {
|
||||
[[ "$BACKEND" =~ ^(new|external)$ ]] || fail bad_arg "backend: new | external"
|
||||
[[ "$PROXY_MODE" =~ ^(udp|tcp)$ ]] || fail bad_arg "mode: udp | tcp"
|
||||
valid_port "$LISTEN_PORT" || fail bad_arg "listen-port: 1-65535"
|
||||
valid_version "$VERSION" || fail bad_arg "version: latest | vX.Y.Z"
|
||||
valid_version "$VERSION" || fail bad_arg "version: latest | local | vX.Y.Z"
|
||||
# local держится в install.conf: обычный apply оставляет залитый бинарь, --update без --bin
|
||||
# возвращает на релиз.
|
||||
if [ "$VERSION" = local ] && [ -z "$LOCAL_BIN" ]; then
|
||||
if [ "$FORCE_UPDATE" = 1 ]; then VERSION=latest
|
||||
else [ -x "$BIN" ] || fail bad_arg "version=local: нет $BIN - залейте его через --bin"; fi
|
||||
fi
|
||||
[ -z "$LOCAL_BIN" ] || [ -f "$LOCAL_BIN" ] || fail bad_arg "bin: нет файла $LOCAL_BIN"
|
||||
valid_kcp "$KCP_ARGS" || fail bad_arg "kcp: неверные параметры"
|
||||
valid_port "$FT_WEB_PORT" || fail bad_arg "web-port: 1-65535"
|
||||
[[ "$FT_WEB_TTL" =~ ^[0-9]{2,6}$ ]] && [ "$FT_WEB_TTL" -ge 60 ] || fail bad_arg "web-ttl: от 60 секунд"
|
||||
@@ -578,7 +586,8 @@ server_argv() {
|
||||
if [ "$PROXY_MODE" = tcp ] && [ -n "$KCP_ARGS" ]; then printf '%s\n' $KCP_ARGS; fi
|
||||
}
|
||||
|
||||
image_tag() { if [ "$VERSION" = latest ]; then echo latest; else echo "${VERSION#v}"; fi; }
|
||||
# local - свой бинарь поверх образа latest (рантайм из образа, /app/server подменён).
|
||||
image_tag() { case "$VERSION" in latest|local) echo latest ;; *) echo "${VERSION#v}" ;; esac; }
|
||||
|
||||
ft_installed() {
|
||||
[ -f "$UNIT_FILE" ] && return 0
|
||||
@@ -594,7 +603,8 @@ ft_running() {
|
||||
}
|
||||
|
||||
ft_version() {
|
||||
if [ "$INSTALL_METHOD" = systemd ]; then cat "$VERFILE" 2>/dev/null || true; else image_tag; fi
|
||||
if [ "$INSTALL_METHOD" = systemd ] || [ "$VERSION" = local ]; then cat "$VERFILE" 2>/dev/null || true
|
||||
else image_tag; fi
|
||||
}
|
||||
|
||||
ft_logs() {
|
||||
@@ -653,18 +663,33 @@ ensure_docker() {
|
||||
|
||||
docker_apply() {
|
||||
ensure_docker
|
||||
local ref="$IMAGE:$(image_tag)" argv
|
||||
local ref="$IMAGE:$(image_tag)" argv mount=()
|
||||
step "Загрузка образа $ref" docker pull "$ref" \
|
||||
|| docker image inspect "$ref" >/dev/null 2>&1 || fail docker_failed "docker pull $ref"
|
||||
if [ "$VERSION" = local ]; then
|
||||
binary_ensure
|
||||
mount=(-v "$BIN:/app/server:ro")
|
||||
fi
|
||||
mapfile -t argv < <(server_argv)
|
||||
docker run -d --name "$CONTAINER" --network host --restart unless-stopped \
|
||||
-v "$AUTH_DIR:$AUTH_DIR:ro" --entrypoint /app/server "$ref" "${argv[@]}" >/dev/null \
|
||||
-v "$AUTH_DIR:$AUTH_DIR:ro" ${mount[@]+"${mount[@]}"} --entrypoint /app/server "$ref" "${argv[@]}" >/dev/null \
|
||||
|| fail docker_failed "docker run $ref"
|
||||
}
|
||||
|
||||
_dl() { curl -fsSL --connect-timeout 15 --max-time 300 -o "$2" "$1"; }
|
||||
|
||||
# Свой бинарь (отладка ядра из приложения): без сети и checksums, ставится как есть.
|
||||
binary_local() {
|
||||
[ "$(head -c4 "$LOCAL_BIN" | od -An -c | tr -d ' \n')" = '177ELF' ] || fail bad_arg "bin: не ELF"
|
||||
mkdir -p "$PREFIX"
|
||||
{ install -m 0755 "$LOCAL_BIN" "$BIN.tmp" && mv -f "$BIN.tmp" "$BIN"; } \
|
||||
|| fail internal "не удалось поставить $LOCAL_BIN"
|
||||
rm -f "$LOCAL_BIN"
|
||||
echo local > "$VERFILE"
|
||||
}
|
||||
|
||||
binary_ensure() {
|
||||
if [ -n "$LOCAL_BIN" ]; then binary_local; return 0; fi
|
||||
if [ -x "$BIN" ] && [ "$FORCE_UPDATE" != 1 ] && [ "$(cat "$VERFILE" 2>/dev/null || true)" = "$VERSION" ]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -1257,6 +1282,7 @@ parse_opts() {
|
||||
--obf-profile=*) OBF_PROFILE=$v ;;
|
||||
--obf-key=*) OBF_KEY=$v; valid_hex64 "$v" || fail bad_arg "obf-key: 64 hex-символа" ;;
|
||||
--version=*) VERSION=$v ;;
|
||||
--bin=*) LOCAL_BIN=$v; VERSION=local ;;
|
||||
--web-port=*) FT_WEB_PORT=$v ;;
|
||||
--web-ttl=*) FT_WEB_TTL=$v ;;
|
||||
--kcp-nodelay=*|--kcp-interval=*|--kcp-resend=*|--kcp-nc=*|--kcp-sndwnd=*|--kcp-rcvwnd=*|--kcp-mtu=*)
|
||||
@@ -1646,6 +1672,7 @@ Free Turn Proxy - установщик и контроллер сервера.
|
||||
--obf-key=HEX64 ключ обфускации (нет - сгенерируется)
|
||||
--host=HOST адрес сервера в ссылках (нет - внешний IP)
|
||||
--version=TAG версия FreeTurn (default latest)
|
||||
--bin=PATH свой бинарь сервера вместо релиза (version=local)
|
||||
--kcp-*=N параметры KCP сервера для --mode=tcp
|
||||
--web-port=N --web-ttl=S веб-раздача файлов клиентов (default 8080, 900 c)
|
||||
|
||||
|
||||
@@ -299,6 +299,31 @@ need_jq() { command -v jq >/dev/null 2>&1 || skip "нет jq"; }
|
||||
[[ "$output" == *'"code":"bad_arg"'* ]]
|
||||
}
|
||||
|
||||
@test "version=local: держится без --bin, --update возвращает на релиз, не-ELF отбит" {
|
||||
_IS_RPC=1
|
||||
BACKEND=external CONNECT=127.0.0.1:443 VERSION=local
|
||||
run validate_config
|
||||
[[ "$output" == *'"code":"bad_arg"'* ]]
|
||||
printf '#!/bin/sh\n' > "$BIN"; chmod +x "$BIN"
|
||||
validate_config
|
||||
[ "$VERSION" = local ]
|
||||
FORCE_UPDATE=1
|
||||
validate_config
|
||||
[ "$VERSION" = latest ]
|
||||
|
||||
parse_opts --bin="$BATS_TEST_TMPDIR/up"
|
||||
[ "$VERSION" = local ]
|
||||
run validate_config
|
||||
[[ "$output" == *'"code":"bad_arg"'* ]]
|
||||
echo junk > "$LOCAL_BIN"
|
||||
run binary_local
|
||||
[[ "$output" == *'не ELF'* ]]
|
||||
printf '\177ELF....' > "$LOCAL_BIN"
|
||||
binary_local
|
||||
[ "$(cat "$VERFILE")" = local ] && [ -x "$BIN" ] && [ ! -e "$LOCAL_BIN" ]
|
||||
[ "$(image_tag)" = latest ]
|
||||
}
|
||||
|
||||
@test "диспетчер: CLI-флаги не RPC, все RPC-команды опознаются" {
|
||||
for f in -y --yes --update --uninstall --reconfigure --purge client ""; do
|
||||
! is_rpc_command "$f"
|
||||
|
||||
Reference in New Issue
Block a user