[#2] agent二进制依赖改成glic 2.35版本
This commit is contained in:
parent
60a6c65f90
commit
143345ce9e
@ -9,7 +9,21 @@ cd src/agent
|
|||||||
./scripts/build_binary.sh # 生成 dist/argus-agent
|
./scripts/build_binary.sh # 生成 dist/argus-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本会在本地创建虚拟环境、通过 `pyproject.toml` 安装依赖,并调用 PyInstaller 产出单文件可执行程序。构建过程中生成的 `build/`、`dist/` 会被 `.gitignore` 忽略。
|
脚本默认会在 Docker 容器 (`python:3.11-slim-bullseye`) 内执行 PyInstaller,确保产物运行时兼容 glibc 2.31+(覆盖 2.35 环境)。构建流程注意事项:
|
||||||
|
|
||||||
|
- 每次构建前会清理 `build/`、`dist/` 并在容器内重新创建虚拟环境。
|
||||||
|
- 需要使用内网 Python 镜像时,可通过 `PIP_INDEX_URL`、`PIP_EXTRA_INDEX_URL`、`PIP_TRUSTED_HOST` 等环境变量传入,脚本会自动透传给容器。
|
||||||
|
- 如果宿主机无法运行 Docker,可设置 `AGENT_BUILD_USE_DOCKER=0` 回退到本地构建;此时代码必须在 glibc ≤ 2.35 的机器上执行。
|
||||||
|
|
||||||
|
构建结束后脚本会在 `build/compat_check/` 下解包关键动态库并输出最高 `GLIBC_x.y` 版本,便于快速核对兼容性。如果结果中缺少 `libssl.so.3` / `libcrypto.so.3`,表示系统会在目标宿主机上使用本地 OpenSSL 库,无需额外处理。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
strings build/compat_check/libpython*.so.1.0 | grep -Eo 'GLIBC_[0-9]+\.[0-9]+' | sort -Vu | tail -n1
|
||||||
|
```
|
||||||
|
|
||||||
|
如遇构建失败,常见原因是 Docker 不可用(请改用 `AGENT_BUILD_USE_DOCKER=0`)或无法访问 Python 包镜像(先设置上述镜像环境变量后重试)。
|
||||||
|
|
||||||
## 运行时配置
|
## 运行时配置
|
||||||
|
|
||||||
|
BIN
src/agent/dist/argus-agent
vendored
BIN
src/agent/dist/argus-agent
vendored
Binary file not shown.
@ -6,37 +6,257 @@ MODULE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|||||||
BUILD_ROOT="$MODULE_ROOT/build"
|
BUILD_ROOT="$MODULE_ROOT/build"
|
||||||
DIST_DIR="$MODULE_ROOT/dist"
|
DIST_DIR="$MODULE_ROOT/dist"
|
||||||
PYINSTALLER_BUILD="$BUILD_ROOT/pyinstaller"
|
PYINSTALLER_BUILD="$BUILD_ROOT/pyinstaller"
|
||||||
|
PYINSTALLER_SPEC="$PYINSTALLER_BUILD/spec"
|
||||||
|
PYINSTALLER_WORK="$PYINSTALLER_BUILD/work"
|
||||||
VENV_DIR="$BUILD_ROOT/venv"
|
VENV_DIR="$BUILD_ROOT/venv"
|
||||||
|
|
||||||
mkdir -p "$PYINSTALLER_BUILD"
|
AGENT_BUILD_IMAGE="${AGENT_BUILD_IMAGE:-python:3.11-slim-bullseye}"
|
||||||
mkdir -p "$DIST_DIR"
|
AGENT_BUILD_USE_DOCKER="${AGENT_BUILD_USE_DOCKER:-1}"
|
||||||
|
USED_DOCKER=0
|
||||||
|
|
||||||
if [[ ! -d "$VENV_DIR" ]]; then
|
run_host_build() {
|
||||||
python3 -m venv "$VENV_DIR"
|
echo "[INFO] Using host Python environment for build" >&2
|
||||||
fi
|
rm -rf "$BUILD_ROOT" "$DIST_DIR"
|
||||||
|
mkdir -p "$PYINSTALLER_BUILD" "$DIST_DIR"
|
||||||
|
python3 -m venv --copies "$VENV_DIR"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$VENV_DIR/bin/activate"
|
||||||
|
|
||||||
# shellcheck disable=SC1091
|
pip install --upgrade pip
|
||||||
source "$VENV_DIR/bin/activate"
|
pip install .
|
||||||
|
pip install "pyinstaller==6.6.0"
|
||||||
|
|
||||||
|
pyinstaller \
|
||||||
|
--clean \
|
||||||
|
--onefile \
|
||||||
|
--name argus-agent \
|
||||||
|
--distpath "$DIST_DIR" \
|
||||||
|
--workpath "$PYINSTALLER_WORK" \
|
||||||
|
--specpath "$PYINSTALLER_SPEC" \
|
||||||
|
--add-data "$MODULE_ROOT/pyproject.toml:." \
|
||||||
|
"$MODULE_ROOT/entry.py"
|
||||||
|
|
||||||
|
chmod +x "$DIST_DIR/argus-agent"
|
||||||
|
deactivate
|
||||||
|
}
|
||||||
|
|
||||||
|
run_docker_build() {
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "[ERROR] docker 命令不存在,无法在容器内构建。请安装 Docker 或设置 AGENT_BUILD_USE_DOCKER=0" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
USED_DOCKER=1
|
||||||
|
echo "[INFO] Building agent binary inside $AGENT_BUILD_IMAGE" >&2
|
||||||
|
|
||||||
|
docker_env=("--rm" "-u" "$(id -u):$(id -g)" "-v" "$MODULE_ROOT:/workspace" "-w" "/workspace")
|
||||||
|
|
||||||
|
pass_env_if_set() {
|
||||||
|
local var="$1"
|
||||||
|
local value="${!var:-}"
|
||||||
|
if [[ -n "$value" ]]; then
|
||||||
|
docker_env+=("--env" "$var=$value")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pass_env_if_set PIP_INDEX_URL
|
||||||
|
pass_env_if_set PIP_EXTRA_INDEX_URL
|
||||||
|
pass_env_if_set PIP_TRUSTED_HOST
|
||||||
|
pass_env_if_set HTTP_PROXY
|
||||||
|
pass_env_if_set HTTPS_PROXY
|
||||||
|
pass_env_if_set NO_PROXY
|
||||||
|
pass_env_if_set http_proxy
|
||||||
|
pass_env_if_set https_proxy
|
||||||
|
pass_env_if_set no_proxy
|
||||||
|
|
||||||
|
build_script=$(cat <<'INNER'
|
||||||
|
set -euo pipefail
|
||||||
|
cd /workspace
|
||||||
|
apt-get update >/dev/null
|
||||||
|
apt-get install -y --no-install-recommends binutils >/dev/null
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
rm -rf build dist
|
||||||
|
mkdir -p build/pyinstaller dist
|
||||||
|
python3 -m venv --copies build/venv
|
||||||
|
source build/venv/bin/activate
|
||||||
pip install --upgrade pip
|
pip install --upgrade pip
|
||||||
pip install "$MODULE_ROOT"
|
pip install .
|
||||||
pip install "pyinstaller==6.6.0"
|
pip install pyinstaller==6.6.0
|
||||||
|
|
||||||
rm -rf "$PYINSTALLER_BUILD"/*
|
|
||||||
rm -f "$DIST_DIR/argus-agent"
|
|
||||||
|
|
||||||
pyinstaller \
|
pyinstaller \
|
||||||
--clean \
|
--clean \
|
||||||
--onefile \
|
--onefile \
|
||||||
--name argus-agent \
|
--name argus-agent \
|
||||||
--distpath "$DIST_DIR" \
|
--distpath dist \
|
||||||
--workpath "$PYINSTALLER_BUILD/work" \
|
--workpath build/pyinstaller/work \
|
||||||
--specpath "$PYINSTALLER_BUILD/spec" \
|
--specpath build/pyinstaller/spec \
|
||||||
--add-data "$MODULE_ROOT/pyproject.toml:." \
|
--add-data /workspace/pyproject.toml:. \
|
||||||
"$MODULE_ROOT/entry.py"
|
entry.py
|
||||||
|
chmod +x dist/argus-agent
|
||||||
|
|
||||||
chmod +x "$DIST_DIR/argus-agent"
|
python3 - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
from PyInstaller.archive.readers import CArchiveReader
|
||||||
|
import sys
|
||||||
|
|
||||||
|
archive = Path('dist/argus-agent')
|
||||||
|
out_dir = Path('build/compat_check')
|
||||||
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
major, minor = sys.version_info[:2]
|
||||||
|
libpython = f'libpython{major}.{minor}.so.1.0'
|
||||||
|
expected_libs = [
|
||||||
|
libpython,
|
||||||
|
'libssl.so.3',
|
||||||
|
'libcrypto.so.3',
|
||||||
|
]
|
||||||
|
reader = CArchiveReader(str(archive))
|
||||||
|
extracted = []
|
||||||
|
missing = []
|
||||||
|
for name in expected_libs:
|
||||||
|
try:
|
||||||
|
data = reader.extract(name)
|
||||||
|
except KeyError:
|
||||||
|
missing.append(name)
|
||||||
|
continue
|
||||||
|
(out_dir / name).write_bytes(data)
|
||||||
|
extracted.append(name)
|
||||||
|
(out_dir / 'manifest').write_text('\n'.join(extracted))
|
||||||
|
if extracted:
|
||||||
|
print('[INFO] Extracted libraries: ' + ', '.join(extracted))
|
||||||
|
if missing:
|
||||||
|
print('[WARN] Missing expected libraries in bundle: ' + ', '.join(missing))
|
||||||
|
PY
|
||||||
|
|
||||||
|
compat_check() {
|
||||||
|
local lib_path="$1"
|
||||||
|
if [[ ! -f "$lib_path" ]]; then
|
||||||
|
echo "[WARN] Missing $lib_path for GLIBC check"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local max_glibc
|
||||||
|
max_glibc=$(strings -a "$lib_path" | grep -Eo 'GLIBC_[0-9]+\.[0-9]+' | sort -Vu | tail -n 1 || true)
|
||||||
|
if [[ -n "$max_glibc" ]]; then
|
||||||
|
echo "[INFO] $lib_path references up to $max_glibc"
|
||||||
|
else
|
||||||
|
echo "[INFO] $lib_path does not expose GLIBC version strings"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
compat_libs=()
|
||||||
|
if [[ -f build/compat_check/manifest ]]; then
|
||||||
|
mapfile -t compat_libs < build/compat_check/manifest
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${#compat_libs[@]} -eq 0 ]]; then
|
||||||
|
echo "[WARN] No libraries captured for GLIBC inspection"
|
||||||
|
else
|
||||||
|
for lib in "${compat_libs[@]}"; do
|
||||||
|
compat_check "build/compat_check/$lib"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
deactivate
|
deactivate
|
||||||
|
INNER
|
||||||
|
)
|
||||||
|
|
||||||
|
if ! docker run "${docker_env[@]}" "$AGENT_BUILD_IMAGE" bash -lc "$build_script"; then
|
||||||
|
echo "[ERROR] Docker 构建失败,请检查 Docker 权限或设置 AGENT_BUILD_USE_DOCKER=0 在兼容主机上构建" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$AGENT_BUILD_USE_DOCKER" == "1" ]]; then
|
||||||
|
run_docker_build
|
||||||
|
else
|
||||||
|
run_host_build
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$DIST_DIR/argus-agent" ]]; then
|
||||||
|
echo "[ERROR] Agent binary was not produced" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$USED_DOCKER" != "1" ]]; then
|
||||||
|
if [[ ! -x "$VENV_DIR/bin/python" ]]; then
|
||||||
|
echo "[WARN] PyInstaller virtualenv missing at $VENV_DIR; skipping compatibility check" >&2
|
||||||
|
else
|
||||||
|
COMPAT_DIR="$BUILD_ROOT/compat_check"
|
||||||
|
rm -rf "$COMPAT_DIR"
|
||||||
|
mkdir -p "$COMPAT_DIR"
|
||||||
|
|
||||||
|
EXTRACT_SCRIPT=$(cat <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
from PyInstaller.archive.readers import CArchiveReader
|
||||||
|
import sys
|
||||||
|
|
||||||
|
archive = Path('dist/argus-agent')
|
||||||
|
out_dir = Path('build/compat_check')
|
||||||
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
major, minor = sys.version_info[:2]
|
||||||
|
libpython = f'libpython{major}.{minor}.so.1.0'
|
||||||
|
expected_libs = [
|
||||||
|
libpython,
|
||||||
|
'libssl.so.3',
|
||||||
|
'libcrypto.so.3',
|
||||||
|
]
|
||||||
|
reader = CArchiveReader(str(archive))
|
||||||
|
extracted = []
|
||||||
|
missing = []
|
||||||
|
for name in expected_libs:
|
||||||
|
try:
|
||||||
|
data = reader.extract(name)
|
||||||
|
except KeyError:
|
||||||
|
missing.append(name)
|
||||||
|
continue
|
||||||
|
(out_dir / name).write_bytes(data)
|
||||||
|
extracted.append(name)
|
||||||
|
(out_dir / 'manifest').write_text('\n'.join(extracted))
|
||||||
|
if extracted:
|
||||||
|
print('[INFO] Extracted libraries: ' + ', '.join(extracted))
|
||||||
|
if missing:
|
||||||
|
print('[WARN] Missing expected libraries in bundle: ' + ', '.join(missing))
|
||||||
|
PY
|
||||||
|
)
|
||||||
|
|
||||||
|
"$VENV_DIR/bin/python" - <<PY
|
||||||
|
$EXTRACT_SCRIPT
|
||||||
|
PY
|
||||||
|
|
||||||
|
compat_libs=()
|
||||||
|
if [[ -f "$COMPAT_DIR/manifest" ]]; then
|
||||||
|
mapfile -t compat_libs < "$COMPAT_DIR/manifest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_glibc_version() {
|
||||||
|
local lib_path="$1"
|
||||||
|
if [[ ! -f "$lib_path" ]]; then
|
||||||
|
echo "[WARN] Skipping GLIBC check; file not found: $lib_path" >&2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if command -v strings >/dev/null 2>&1; then
|
||||||
|
local max_glibc
|
||||||
|
max_glibc=$(strings -a "$lib_path" | grep -Eo 'GLIBC_[0-9]+\.[0-9]+' | sort -Vu | tail -n 1 || true)
|
||||||
|
if [[ -n "$max_glibc" ]]; then
|
||||||
|
echo "[INFO] $lib_path references up to $max_glibc"
|
||||||
|
else
|
||||||
|
echo "[INFO] $lib_path does not expose GLIBC version strings"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[WARN] strings command unavailable; cannot inspect $lib_path" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${#compat_libs[@]} -eq 0 ]]; then
|
||||||
|
echo "[WARN] No libraries captured for GLIBC inspection" >&2
|
||||||
|
else
|
||||||
|
for lib in "${compat_libs[@]}"; do
|
||||||
|
check_glibc_version "$COMPAT_DIR/$lib"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[INFO] Compatibility check executed inside container"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "[INFO] Agent binary generated at $DIST_DIR/argus-agent"
|
echo "[INFO] Agent binary generated at $DIST_DIR/argus-agent"
|
||||||
|
@ -21,9 +21,14 @@ done
|
|||||||
|
|
||||||
if [[ -x "$DNS_SCRIPT" ]]; then
|
if [[ -x "$DNS_SCRIPT" ]]; then
|
||||||
log "执行 update-dns.sh 更新容器 DNS"
|
log "执行 update-dns.sh 更新容器 DNS"
|
||||||
if ! "$DNS_SCRIPT"; then
|
while true; do
|
||||||
log "update-dns.sh 执行失败,继续尝试默认 DNS"
|
if "$DNS_SCRIPT"; then
|
||||||
fi
|
log "update-dns.sh 执行成功"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
log "update-dns.sh 执行失败,3 秒后重试"
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
else
|
else
|
||||||
log "未获取到 update-dns.sh,使用镜像默认 DNS"
|
log "未获取到 update-dns.sh,使用镜像默认 DNS"
|
||||||
fi
|
fi
|
||||||
|
Loading…
x
Reference in New Issue
Block a user