mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-08 08:57:09 +08:00
fix(docker): scope package proxy env (#5991)
* Revert "Add NO_PROXY defaults to Docker proxy setup"
This reverts commit 109be58abe.
* fix(docker): scope package proxy env
This commit is contained in:
+10
-42
@@ -35,43 +35,15 @@ function apply_package_cache_env() {
|
|||||||
mkdir -p "${PIP_CACHE_DIR}" "${UV_CACHE_DIR}"
|
mkdir -p "${PIP_CACHE_DIR}" "${UV_CACHE_DIR}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply_no_proxy_env() {
|
function run_package_command() {
|
||||||
local default_no_proxy="localhost,127.0.0.1,::1,0.0.0.0,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.168.0.0/16,fc00::/7,fe80::/10,host.docker.internal,host.containers.internal,gateway.docker.internal,.local,.lan,.internal,.home.arpa,.localdomain"
|
if [ -n "${PROXY_HOST}" ]; then
|
||||||
local merged="${NO_PROXY:-}"
|
HTTP_PROXY="${PROXY_HOST}" \
|
||||||
local source_value item old_ifs
|
HTTPS_PROXY="${PROXY_HOST}" \
|
||||||
local -a no_proxy_items
|
http_proxy="${PROXY_HOST}" \
|
||||||
|
https_proxy="${PROXY_HOST}" \
|
||||||
# Docker 内常见本机、局域网和内网服务必须直连,避免 PROXY_HOST 被映射到
|
"$@"
|
||||||
# HTTP_PROXY 后拦截 Telegram 回调、下载器、媒体服务器等本地请求。
|
else
|
||||||
for source_value in "${no_proxy:-}" "${default_no_proxy}"; do
|
"$@"
|
||||||
old_ifs="${IFS}"
|
|
||||||
IFS=','
|
|
||||||
read -ra no_proxy_items <<< "${source_value}"
|
|
||||||
IFS="${old_ifs}"
|
|
||||||
for item in "${no_proxy_items[@]}"; do
|
|
||||||
item="${item#"${item%%[![:space:]]*}"}"
|
|
||||||
item="${item%"${item##*[![:space:]]}"}"
|
|
||||||
if [ -z "${item}" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
case ",${merged}," in
|
|
||||||
*",${item},"*) ;;
|
|
||||||
*) merged="${merged:+${merged},}${item}" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
export NO_PROXY="${merged}"
|
|
||||||
export no_proxy="${merged}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function apply_package_proxy_env() {
|
|
||||||
if [ -n "${PROXY_HOST:-}" ]; then
|
|
||||||
export HTTP_PROXY="${PROXY_HOST}"
|
|
||||||
export HTTPS_PROXY="${PROXY_HOST}"
|
|
||||||
export http_proxy="${PROXY_HOST}"
|
|
||||||
export https_proxy="${PROXY_HOST}"
|
|
||||||
apply_no_proxy_env
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,9 +170,6 @@ function load_config_from_app_env() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
shopt -u extglob
|
shopt -u extglob
|
||||||
if [ -n "${PROXY_HOST:-}${HTTP_PROXY:-}${HTTPS_PROXY:-}${http_proxy:-}${https_proxy:-}" ]; then
|
|
||||||
apply_no_proxy_env
|
|
||||||
fi
|
|
||||||
INFO "配置加载流程执行完毕。"
|
INFO "配置加载流程执行完毕。"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,13 +297,12 @@ function ensure_backend_runtime_dependencies() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
WARN "→ 检测到后端核心依赖异常,开始尝试恢复主程序依赖..."
|
WARN "→ 检测到后端核心依赖异常,开始尝试恢复主程序依赖..."
|
||||||
apply_package_proxy_env
|
|
||||||
local -a pip_cmd=("${VENV_PATH}/bin/pip" "install" "-r" "/app/requirements.txt")
|
local -a pip_cmd=("${VENV_PATH}/bin/pip" "install" "-r" "/app/requirements.txt")
|
||||||
if [ -n "${PIP_PROXY}" ]; then
|
if [ -n "${PIP_PROXY}" ]; then
|
||||||
pip_cmd+=("-i" "${PIP_PROXY}")
|
pip_cmd+=("-i" "${PIP_PROXY}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! "${pip_cmd[@]}" > /dev/stdout 2> /dev/stderr; then
|
if ! run_package_command "${pip_cmd[@]}" > /dev/stdout 2> /dev/stderr; then
|
||||||
ERROR "→ 自动恢复主程序依赖失败,后端无法启动。"
|
ERROR "→ 自动恢复主程序依赖失败,后端无法启动。"
|
||||||
diagnostic_keepalive 1
|
diagnostic_keepalive 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
+15
-39
@@ -36,42 +36,17 @@ function apply_package_cache_env() {
|
|||||||
|
|
||||||
apply_package_cache_env
|
apply_package_cache_env
|
||||||
|
|
||||||
function apply_no_proxy_env() {
|
PIP_ENV=()
|
||||||
local default_no_proxy="localhost,127.0.0.1,::1,0.0.0.0,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.168.0.0/16,fc00::/7,fe80::/10,host.docker.internal,host.containers.internal,gateway.docker.internal,.local,.lan,.internal,.home.arpa,.localdomain"
|
|
||||||
local merged="${NO_PROXY:-}"
|
|
||||||
local source_value item old_ifs
|
|
||||||
local -a no_proxy_items
|
|
||||||
|
|
||||||
# 代理仅用于外网依赖下载,容器访问本机、局域网和内网服务时应保持直连。
|
function set_package_proxy_env() {
|
||||||
for source_value in "${no_proxy:-}" "${default_no_proxy}"; do
|
PIP_ENV=()
|
||||||
old_ifs="${IFS}"
|
if [[ -n "${PROXY_HOST}" ]]; then
|
||||||
IFS=','
|
PIP_ENV=(
|
||||||
read -ra no_proxy_items <<< "${source_value}"
|
"HTTP_PROXY=${PROXY_HOST}"
|
||||||
IFS="${old_ifs}"
|
"HTTPS_PROXY=${PROXY_HOST}"
|
||||||
for item in "${no_proxy_items[@]}"; do
|
"http_proxy=${PROXY_HOST}"
|
||||||
item="${item#"${item%%[![:space:]]*}"}"
|
"https_proxy=${PROXY_HOST}"
|
||||||
item="${item%"${item##*[![:space:]]}"}"
|
)
|
||||||
if [[ -z "${item}" ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
case ",${merged}," in
|
|
||||||
*",${item},"*) ;;
|
|
||||||
*) merged="${merged:+${merged},}${item}" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
export NO_PROXY="${merged}"
|
|
||||||
export no_proxy="${merged}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function apply_package_proxy_env() {
|
|
||||||
if [[ -n "${PROXY_HOST:-}" ]]; then
|
|
||||||
export HTTP_PROXY="${PROXY_HOST}"
|
|
||||||
export HTTPS_PROXY="${PROXY_HOST}"
|
|
||||||
export http_proxy="${PROXY_HOST}"
|
|
||||||
export https_proxy="${PROXY_HOST}"
|
|
||||||
apply_no_proxy_env
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,13 +95,13 @@ function install_backend_and_download_resources() {
|
|||||||
# 复制新的requirements.in
|
# 复制新的requirements.in
|
||||||
cp "${TMP_PATH}/App/requirements.in" /app/requirements.in
|
cp "${TMP_PATH}/App/requirements.in" /app/requirements.in
|
||||||
# 重新编译依赖
|
# 重新编译依赖
|
||||||
if ! ${VENV_PATH}/bin/pip-compile /app/requirements.in -o /app/requirements.txt; then
|
if ! env "${PIP_ENV[@]}" ${VENV_PATH}/bin/pip-compile /app/requirements.in -o /app/requirements.txt; then
|
||||||
ERROR "依赖编译失败,恢复原依赖"
|
ERROR "依赖编译失败,恢复原依赖"
|
||||||
cp /tmp/requirements.txt.backup /app/requirements.txt
|
cp /tmp/requirements.txt.backup /app/requirements.txt
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
# 安装新依赖
|
# 安装新依赖
|
||||||
if ! ${VENV_PATH}/bin/pip install ${PIP_OPTIONS} -r /app/requirements.txt; then
|
if ! env "${PIP_ENV[@]}" ${VENV_PATH}/bin/pip install ${PIP_OPTIONS} -r /app/requirements.txt; then
|
||||||
ERROR "依赖安装失败,恢复原依赖"
|
ERROR "依赖安装失败,恢复原依赖"
|
||||||
cp /tmp/requirements.txt.backup /app/requirements.txt
|
cp /tmp/requirements.txt.backup /app/requirements.txt
|
||||||
return 1
|
return 1
|
||||||
@@ -236,7 +211,7 @@ function test_connectivity_pip() {
|
|||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
PIP_OPTIONS="-i ${PIP_PROXY}"
|
PIP_OPTIONS="-i ${PIP_PROXY}"
|
||||||
PIP_LOG="镜像代理模式"
|
PIP_LOG="镜像代理模式"
|
||||||
apply_package_proxy_env
|
set_package_proxy_env
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -248,13 +223,14 @@ function test_connectivity_pip() {
|
|||||||
${VENV_PATH}/bin/pip install pip-hello-world > /dev/null 2>&1; then
|
${VENV_PATH}/bin/pip install pip-hello-world > /dev/null 2>&1; then
|
||||||
PIP_OPTIONS=""
|
PIP_OPTIONS=""
|
||||||
PIP_LOG="全局代理模式"
|
PIP_LOG="全局代理模式"
|
||||||
apply_package_proxy_env
|
set_package_proxy_env
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
|
PIP_ENV=()
|
||||||
PIP_OPTIONS=""
|
PIP_OPTIONS=""
|
||||||
PIP_LOG="不使用代理"
|
PIP_LOG="不使用代理"
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ cat > "${TMP_DIR}/venv/bin/pip" <<'SH'
|
|||||||
printf 'argv=%s\n' "$*" >> "${MP_FAKE_PIP_LOG}"
|
printf 'argv=%s\n' "$*" >> "${MP_FAKE_PIP_LOG}"
|
||||||
printf 'HTTP_PROXY=%s\n' "${HTTP_PROXY:-}" >> "${MP_FAKE_PIP_LOG}"
|
printf 'HTTP_PROXY=%s\n' "${HTTP_PROXY:-}" >> "${MP_FAKE_PIP_LOG}"
|
||||||
printf 'HTTPS_PROXY=%s\n' "${HTTPS_PROXY:-}" >> "${MP_FAKE_PIP_LOG}"
|
printf 'HTTPS_PROXY=%s\n' "${HTTPS_PROXY:-}" >> "${MP_FAKE_PIP_LOG}"
|
||||||
printf 'NO_PROXY=%s\n' "${NO_PROXY:-}" >> "${MP_FAKE_PIP_LOG}"
|
|
||||||
printf 'no_proxy=%s\n' "${no_proxy:-}" >> "${MP_FAKE_PIP_LOG}"
|
|
||||||
printf 'PACKAGE_CACHE_ROOT=%s\n' "${PACKAGE_CACHE_ROOT:-}" >> "${MP_FAKE_PIP_LOG}"
|
printf 'PACKAGE_CACHE_ROOT=%s\n' "${PACKAGE_CACHE_ROOT:-}" >> "${MP_FAKE_PIP_LOG}"
|
||||||
printf 'PIP_CACHE_DIR=%s\n' "${PIP_CACHE_DIR:-}" >> "${MP_FAKE_PIP_LOG}"
|
printf 'PIP_CACHE_DIR=%s\n' "${PIP_CACHE_DIR:-}" >> "${MP_FAKE_PIP_LOG}"
|
||||||
printf 'UV_CACHE_DIR=%s\n' "${UV_CACHE_DIR:-}" >> "${MP_FAKE_PIP_LOG}"
|
printf 'UV_CACHE_DIR=%s\n' "${UV_CACHE_DIR:-}" >> "${MP_FAKE_PIP_LOG}"
|
||||||
@@ -58,18 +56,13 @@ export CONFIG_DIR="${TMP_DIR}/config"
|
|||||||
export MOVIEPILOT_AUTO_UPDATE=false
|
export MOVIEPILOT_AUTO_UPDATE=false
|
||||||
export PIP_PROXY="https://mirror.example/simple"
|
export PIP_PROXY="https://mirror.example/simple"
|
||||||
export PROXY_HOST="http://proxy.example:7890"
|
export PROXY_HOST="http://proxy.example:7890"
|
||||||
export NO_PROXY="custom.internal,127.0.0.1"
|
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR HTTP_PROXY HTTPS_PROXY http_proxy https_proxy
|
||||||
unset no_proxy
|
|
||||||
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR
|
|
||||||
source "${UPDATE_FUNCS}" >/dev/null
|
source "${UPDATE_FUNCS}" >/dev/null
|
||||||
|
|
||||||
: > "${MP_FAKE_PIP_LOG}"
|
: > "${MP_FAKE_PIP_LOG}"
|
||||||
test_connectivity_pip 0
|
test_connectivity_pip 0
|
||||||
assert_contains "argv=install -i https://mirror.example/simple pip-hello-world" "${MP_FAKE_PIP_LOG}"
|
assert_contains "argv=install -i https://mirror.example/simple pip-hello-world" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "HTTPS_PROXY=http://proxy.example:7890" "${MP_FAKE_PIP_LOG}"
|
assert_contains "HTTPS_PROXY=http://proxy.example:7890" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "NO_PROXY=custom.internal,127.0.0.1,localhost,::1,0.0.0.0,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.168.0.0/16" "${MP_FAKE_PIP_LOG}"
|
|
||||||
assert_contains "host.docker.internal,host.containers.internal,gateway.docker.internal" "${MP_FAKE_PIP_LOG}"
|
|
||||||
assert_contains "no_proxy=custom.internal,127.0.0.1,localhost,::1,0.0.0.0,10.0.0.0/8,100.64.0.0/10" "${MP_FAKE_PIP_LOG}"
|
|
||||||
assert_contains "PACKAGE_CACHE_ROOT=${TMP_DIR}/config/.cache" "${MP_FAKE_PIP_LOG}"
|
assert_contains "PACKAGE_CACHE_ROOT=${TMP_DIR}/config/.cache" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "PIP_CACHE_DIR=${TMP_DIR}/config/.cache/pip" "${MP_FAKE_PIP_LOG}"
|
assert_contains "PIP_CACHE_DIR=${TMP_DIR}/config/.cache/pip" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "UV_CACHE_DIR=${TMP_DIR}/config/.cache/uv" "${MP_FAKE_PIP_LOG}"
|
assert_contains "UV_CACHE_DIR=${TMP_DIR}/config/.cache/uv" "${MP_FAKE_PIP_LOG}"
|
||||||
@@ -81,6 +74,11 @@ if [[ "${PIP_OPTIONS}" == *"--proxy"* ]]; then
|
|||||||
echo "PIP_OPTIONS must not contain --proxy: ${PIP_OPTIONS}" >&2
|
echo "PIP_OPTIONS must not contain --proxy: ${PIP_OPTIONS}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ -n "${HTTP_PROXY:-}" || -n "${HTTPS_PROXY:-}" || -n "${http_proxy:-}" || -n "${https_proxy:-}" ]]; then
|
||||||
|
echo "pip connectivity must not leak PROXY_HOST into parent proxy env" >&2
|
||||||
|
env | grep -E '^(HTTP_PROXY|HTTPS_PROXY|http_proxy|https_proxy)=' >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
assert_not_contains "user:pass" "${MP_FAKE_PIP_LOG}"
|
assert_not_contains "user:pass" "${MP_FAKE_PIP_LOG}"
|
||||||
|
|
||||||
: > "${MP_FAKE_PIP_LOG}"
|
: > "${MP_FAKE_PIP_LOG}"
|
||||||
@@ -92,6 +90,33 @@ if [[ -n "${PIP_OPTIONS}" ]]; then
|
|||||||
echo "proxy branch must keep PIP_OPTIONS empty: ${PIP_OPTIONS}" >&2
|
echo "proxy branch must keep PIP_OPTIONS empty: ${PIP_OPTIONS}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ -n "${HTTP_PROXY:-}" || -n "${HTTPS_PROXY:-}" || -n "${http_proxy:-}" || -n "${https_proxy:-}" ]]; then
|
||||||
|
echo "proxy connectivity must not leak PROXY_HOST into parent proxy env" >&2
|
||||||
|
env | grep -E '^(HTTP_PROXY|HTTPS_PROXY|http_proxy|https_proxy)=' >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
MP_FAKE_PIP_LOG="${TMP_DIR}/update-explicit-standard-proxy.log"
|
||||||
|
export MP_FAKE_PIP_LOG
|
||||||
|
(
|
||||||
|
export VENV_PATH="${TMP_DIR}/venv"
|
||||||
|
export CONFIG_DIR="${TMP_DIR}/config"
|
||||||
|
export MOVIEPILOT_AUTO_UPDATE=false
|
||||||
|
export PIP_PROXY=""
|
||||||
|
export PROXY_HOST="http://proxy.example:7890"
|
||||||
|
export HTTP_PROXY="http://explicit.example:8080"
|
||||||
|
export HTTPS_PROXY="http://explicit.example:8080"
|
||||||
|
export http_proxy="http://explicit.example:8080"
|
||||||
|
export https_proxy="http://explicit.example:8080"
|
||||||
|
source "${UPDATE_FUNCS}" >/dev/null
|
||||||
|
test_connectivity_pip 1
|
||||||
|
if [[ "${HTTP_PROXY}" != "http://explicit.example:8080" || "${HTTPS_PROXY}" != "http://explicit.example:8080" ]]; then
|
||||||
|
echo "explicit standard proxy env must be preserved" >&2
|
||||||
|
env | grep -E '^(HTTP_PROXY|HTTPS_PROXY|http_proxy|https_proxy)=' >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
assert_contains "HTTPS_PROXY=http://proxy.example:7890" "${MP_FAKE_PIP_LOG}"
|
||||||
|
|
||||||
MP_FAKE_PIP_LOG="${TMP_DIR}/update-explicit-cache.log"
|
MP_FAKE_PIP_LOG="${TMP_DIR}/update-explicit-cache.log"
|
||||||
export MP_FAKE_PIP_LOG
|
export MP_FAKE_PIP_LOG
|
||||||
@@ -104,7 +129,6 @@ export MP_FAKE_PIP_LOG
|
|||||||
export UV_CACHE_DIR="${TMP_DIR}/explicit-uv-cache"
|
export UV_CACHE_DIR="${TMP_DIR}/explicit-uv-cache"
|
||||||
export PIP_PROXY="https://mirror.example/simple"
|
export PIP_PROXY="https://mirror.example/simple"
|
||||||
export PROXY_HOST="http://proxy.example:7890"
|
export PROXY_HOST="http://proxy.example:7890"
|
||||||
unset NO_PROXY no_proxy
|
|
||||||
source "${UPDATE_FUNCS}" >/dev/null
|
source "${UPDATE_FUNCS}" >/dev/null
|
||||||
test_connectivity_pip 0
|
test_connectivity_pip 0
|
||||||
)
|
)
|
||||||
@@ -121,7 +145,7 @@ export MP_FAKE_PIP_LOG
|
|||||||
export MOVIEPILOT_AUTO_UPDATE=false
|
export MOVIEPILOT_AUTO_UPDATE=false
|
||||||
export PIP_PROXY="https://mirror.example/simple"
|
export PIP_PROXY="https://mirror.example/simple"
|
||||||
export PROXY_HOST="http://proxy.example:7890"
|
export PROXY_HOST="http://proxy.example:7890"
|
||||||
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR HTTP_PROXY HTTPS_PROXY http_proxy https_proxy NO_PROXY no_proxy
|
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR HTTP_PROXY HTTPS_PROXY http_proxy https_proxy
|
||||||
source "${UPDATE_FUNCS}" >/dev/null
|
source "${UPDATE_FUNCS}" >/dev/null
|
||||||
MP_FAKE_PIP_FAIL=1 test_connectivity_pip 0 && exit 1
|
MP_FAKE_PIP_FAIL=1 test_connectivity_pip 0 && exit 1
|
||||||
if [[ -n "${HTTPS_PROXY:-}" || -n "${https_proxy:-}" ]]; then
|
if [[ -n "${HTTPS_PROXY:-}" || -n "${https_proxy:-}" ]]; then
|
||||||
@@ -165,25 +189,51 @@ export MP_FAKE_PIP_LOG MP_FAKE_PYTHON_COUNT
|
|||||||
(
|
(
|
||||||
export VENV_PATH="${TMP_DIR}/venv"
|
export VENV_PATH="${TMP_DIR}/venv"
|
||||||
export CONFIG_DIR="${TMP_DIR}/config"
|
export CONFIG_DIR="${TMP_DIR}/config"
|
||||||
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR NO_PROXY no_proxy
|
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR HTTP_PROXY HTTPS_PROXY http_proxy https_proxy
|
||||||
export PIP_PROXY=""
|
export PIP_PROXY=""
|
||||||
export PROXY_HOST="http://proxy.example:7890"
|
export PROXY_HOST="http://proxy.example:7890"
|
||||||
export NO_PROXY="service.local"
|
|
||||||
export no_proxy="extra.lan"
|
|
||||||
source "${ENTRYPOINT_FUNCS}"
|
source "${ENTRYPOINT_FUNCS}"
|
||||||
apply_package_cache_env
|
apply_package_cache_env
|
||||||
ensure_backend_runtime_dependencies
|
ensure_backend_runtime_dependencies
|
||||||
|
if [[ -n "${HTTP_PROXY:-}" || -n "${HTTPS_PROXY:-}" || -n "${http_proxy:-}" || -n "${https_proxy:-}" ]]; then
|
||||||
|
echo "dependency recovery must not leak PROXY_HOST into parent proxy env" >&2
|
||||||
|
env | grep -E '^(HTTP_PROXY|HTTPS_PROXY|http_proxy|https_proxy)=' >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
) >/dev/null
|
) >/dev/null
|
||||||
|
|
||||||
assert_contains "argv=install -r /app/requirements.txt" "${MP_FAKE_PIP_LOG}"
|
assert_contains "argv=install -r /app/requirements.txt" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "HTTPS_PROXY=http://proxy.example:7890" "${MP_FAKE_PIP_LOG}"
|
assert_contains "HTTPS_PROXY=http://proxy.example:7890" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "NO_PROXY=service.local,extra.lan,localhost,127.0.0.1,::1,0.0.0.0,10.0.0.0/8" "${MP_FAKE_PIP_LOG}"
|
|
||||||
assert_contains "no_proxy=service.local,extra.lan,localhost,127.0.0.1,::1,0.0.0.0,10.0.0.0/8" "${MP_FAKE_PIP_LOG}"
|
|
||||||
assert_contains "PACKAGE_CACHE_ROOT=${TMP_DIR}/config/.cache" "${MP_FAKE_PIP_LOG}"
|
assert_contains "PACKAGE_CACHE_ROOT=${TMP_DIR}/config/.cache" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "PIP_CACHE_DIR=${TMP_DIR}/config/.cache/pip" "${MP_FAKE_PIP_LOG}"
|
assert_contains "PIP_CACHE_DIR=${TMP_DIR}/config/.cache/pip" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_contains "UV_CACHE_DIR=${TMP_DIR}/config/.cache/uv" "${MP_FAKE_PIP_LOG}"
|
assert_contains "UV_CACHE_DIR=${TMP_DIR}/config/.cache/uv" "${MP_FAKE_PIP_LOG}"
|
||||||
assert_not_contains "--proxy" "${MP_FAKE_PIP_LOG}"
|
assert_not_contains "--proxy" "${MP_FAKE_PIP_LOG}"
|
||||||
|
|
||||||
|
MP_FAKE_PIP_LOG="${TMP_DIR}/entrypoint-explicit-standard-proxy.log"
|
||||||
|
MP_FAKE_PYTHON_COUNT="${TMP_DIR}/python-count-explicit-standard-proxy"
|
||||||
|
export MP_FAKE_PIP_LOG MP_FAKE_PYTHON_COUNT
|
||||||
|
(
|
||||||
|
export VENV_PATH="${TMP_DIR}/venv"
|
||||||
|
export CONFIG_DIR="${TMP_DIR}/config"
|
||||||
|
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR
|
||||||
|
export PIP_PROXY=""
|
||||||
|
export PROXY_HOST="http://proxy.example:7890"
|
||||||
|
export HTTP_PROXY="http://explicit.example:8080"
|
||||||
|
export HTTPS_PROXY="http://explicit.example:8080"
|
||||||
|
export http_proxy="http://explicit.example:8080"
|
||||||
|
export https_proxy="http://explicit.example:8080"
|
||||||
|
source "${ENTRYPOINT_FUNCS}"
|
||||||
|
apply_package_cache_env
|
||||||
|
ensure_backend_runtime_dependencies
|
||||||
|
if [[ "${HTTP_PROXY}" != "http://explicit.example:8080" || "${HTTPS_PROXY}" != "http://explicit.example:8080" ]]; then
|
||||||
|
echo "dependency recovery must preserve explicit standard proxy env" >&2
|
||||||
|
env | grep -E '^(HTTP_PROXY|HTTPS_PROXY|http_proxy|https_proxy)=' >&2 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
) >/dev/null
|
||||||
|
|
||||||
|
assert_contains "HTTPS_PROXY=http://proxy.example:7890" "${MP_FAKE_PIP_LOG}"
|
||||||
|
|
||||||
MP_FAKE_PIP_LOG="${TMP_DIR}/entrypoint-app-env.log"
|
MP_FAKE_PIP_LOG="${TMP_DIR}/entrypoint-app-env.log"
|
||||||
MP_FAKE_PYTHON_COUNT="${TMP_DIR}/python-count-app-env"
|
MP_FAKE_PYTHON_COUNT="${TMP_DIR}/python-count-app-env"
|
||||||
cat > "${TMP_DIR}/config/app.env" <<EOF
|
cat > "${TMP_DIR}/config/app.env" <<EOF
|
||||||
@@ -194,7 +244,7 @@ export MP_FAKE_PIP_LOG MP_FAKE_PYTHON_COUNT
|
|||||||
(
|
(
|
||||||
export VENV_PATH="${TMP_DIR}/venv"
|
export VENV_PATH="${TMP_DIR}/venv"
|
||||||
export CONFIG_DIR="${TMP_DIR}/config"
|
export CONFIG_DIR="${TMP_DIR}/config"
|
||||||
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR PIP_PROXY PROXY_HOST NO_PROXY no_proxy
|
unset PACKAGE_CACHE_ROOT PIP_CACHE_DIR UV_CACHE_DIR PIP_PROXY PROXY_HOST
|
||||||
source "${ENTRYPOINT_FUNCS}"
|
source "${ENTRYPOINT_FUNCS}"
|
||||||
load_config_from_app_env
|
load_config_from_app_env
|
||||||
apply_package_cache_env
|
apply_package_cache_env
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
|
||||||
|
|
||||||
|
|
||||||
def _read_shell_prefix(path: Path, stop_marker: str) -> str:
|
|
||||||
"""
|
|
||||||
读取 Docker 脚本中可独立执行的函数定义前缀。
|
|
||||||
"""
|
|
||||||
lines = []
|
|
||||||
for line in path.read_text(encoding="utf-8").splitlines():
|
|
||||||
if line.startswith(stop_marker):
|
|
||||||
break
|
|
||||||
lines.append(line)
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
("script_path", "stop_marker"),
|
|
||||||
[
|
|
||||||
(ROOT / "docker" / "entrypoint.sh", "# 环境变量补全"),
|
|
||||||
(ROOT / "docker" / "update.sh", "# 下载及解压"),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_docker_proxy_env_adds_default_no_proxy_ranges(
|
|
||||||
tmp_path: Path, script_path: Path, stop_marker: str
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Docker 代理环境应默认绕过本机、局域网和常见容器内部地址。
|
|
||||||
"""
|
|
||||||
shell_prefix = _read_shell_prefix(script_path, stop_marker)
|
|
||||||
config_dir = tmp_path / "config"
|
|
||||||
script = f"""
|
|
||||||
set -euo pipefail
|
|
||||||
CONFIG_DIR="{config_dir}"
|
|
||||||
PROXY_HOST="http://proxy.example:7890"
|
|
||||||
NO_PROXY="custom.internal,127.0.0.1"
|
|
||||||
no_proxy="extra.lan,127.0.0.1"
|
|
||||||
{shell_prefix}
|
|
||||||
apply_package_proxy_env
|
|
||||||
printf 'HTTP_PROXY=%s\\n' "${{HTTP_PROXY:-}}"
|
|
||||||
printf 'HTTPS_PROXY=%s\\n' "${{HTTPS_PROXY:-}}"
|
|
||||||
printf 'NO_PROXY=%s\\n' "${{NO_PROXY:-}}"
|
|
||||||
printf 'no_proxy=%s\\n' "${{no_proxy:-}}"
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = subprocess.run(
|
|
||||||
["bash"],
|
|
||||||
input=script,
|
|
||||||
text=True,
|
|
||||||
capture_output=True,
|
|
||||||
check=True,
|
|
||||||
env={"PATH": os.environ.get("PATH", "")},
|
|
||||||
)
|
|
||||||
output = dict(line.split("=", 1) for line in result.stdout.splitlines())
|
|
||||||
|
|
||||||
assert output["HTTP_PROXY"] == "http://proxy.example:7890"
|
|
||||||
assert output["HTTPS_PROXY"] == "http://proxy.example:7890"
|
|
||||||
assert output["NO_PROXY"] == output["no_proxy"]
|
|
||||||
assert output["NO_PROXY"].count("127.0.0.1") == 1
|
|
||||||
for item in (
|
|
||||||
"localhost",
|
|
||||||
"::1",
|
|
||||||
"10.0.0.0/8",
|
|
||||||
"100.64.0.0/10",
|
|
||||||
"172.16.0.0/12",
|
|
||||||
"192.168.0.0/16",
|
|
||||||
"host.docker.internal",
|
|
||||||
"host.containers.internal",
|
|
||||||
"gateway.docker.internal",
|
|
||||||
"custom.internal",
|
|
||||||
"extra.lan",
|
|
||||||
):
|
|
||||||
assert item in output["NO_PROXY"]
|
|
||||||
Reference in New Issue
Block a user