|
|
#!/usr/bin/env bash
|
|
|
# 校验 deb 是否已注入 bootstrap(postinst + 内置公钥)。
|
|
|
set -euo pipefail
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
|
|
DIST_ROOT="${DEB_DIST_ROOT:-$REPO_ROOT/dist/linux-deb}"
|
|
|
APT_BOOTSTRAP_KEY_IN_PKG="${APT_BOOTSTRAP_KEY_IN_PKG:-/usr/share/zyyun/bootstrap/zyyun-archive-keyring.gpg}"
|
|
|
|
|
|
usage() {
|
|
|
cat <<EOF
|
|
|
用法:
|
|
|
$(basename "$0") <deb文件路径...>
|
|
|
$(basename "$0") --all
|
|
|
|
|
|
说明:
|
|
|
- 指定 deb 路径时,仅校验这些文件
|
|
|
- 使用 --all 时,扫描 dist/linux-deb 下全部 deb
|
|
|
|
|
|
环境变量:
|
|
|
DEB_DIST_ROOT 默认扫描目录(默认: dist/linux-deb)
|
|
|
APT_BOOTSTRAP_KEY_IN_PKG 包内公钥路径(默认: /usr/share/zyyun/bootstrap/zyyun-archive-keyring.gpg)
|
|
|
EOF
|
|
|
}
|
|
|
|
|
|
collect_all_debs() {
|
|
|
local root="$1"
|
|
|
if [[ ! -d "$root" ]]; then
|
|
|
return 0
|
|
|
fi
|
|
|
shopt -s globstar nullglob
|
|
|
local all=( "$root"/**/*.deb )
|
|
|
shopt -u globstar nullglob
|
|
|
printf '%s\n' "${all[@]}"
|
|
|
}
|
|
|
|
|
|
check_one_deb() {
|
|
|
local deb_file="$1"
|
|
|
if [[ ! -f "$deb_file" ]]; then
|
|
|
echo "✗ 文件不存在: $deb_file" >&2
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
local tmp_ctrl tmp_data
|
|
|
tmp_ctrl="$(mktemp -d)"
|
|
|
tmp_data="$(mktemp -d)"
|
|
|
|
|
|
cleanup_local() {
|
|
|
rm -rf "$tmp_ctrl" "$tmp_data"
|
|
|
}
|
|
|
|
|
|
if ! dpkg-deb -e "$deb_file" "$tmp_ctrl" >/dev/null 2>&1; then
|
|
|
echo "✗ 无法解析控制信息: $deb_file" >&2
|
|
|
cleanup_local
|
|
|
return 1
|
|
|
fi
|
|
|
if ! dpkg-deb -x "$deb_file" "$tmp_data" >/dev/null 2>&1; then
|
|
|
echo "✗ 无法解包数据内容: $deb_file" >&2
|
|
|
cleanup_local
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
local postinst_path="$tmp_ctrl/postinst"
|
|
|
if [[ ! -f "$postinst_path" ]]; then
|
|
|
echo "✗ 缺少 postinst: $deb_file" >&2
|
|
|
cleanup_local
|
|
|
return 1
|
|
|
fi
|
|
|
if ! rg -q "SOURCE_LINE=.*80\\.12\\.140\\.29:80/apt" "$postinst_path"; then
|
|
|
echo "✗ postinst 未发现固定源地址配置: $deb_file" >&2
|
|
|
cleanup_local
|
|
|
return 1
|
|
|
fi
|
|
|
if ! rg -q "apt-get update|apt update" "$postinst_path"; then
|
|
|
echo "✗ postinst 未发现 apt update 调用: $deb_file" >&2
|
|
|
cleanup_local
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
local key_path="$tmp_data$APT_BOOTSTRAP_KEY_IN_PKG"
|
|
|
if [[ ! -f "$key_path" ]]; then
|
|
|
echo "✗ 包内缺少 bootstrap 公钥: $deb_file ($APT_BOOTSTRAP_KEY_IN_PKG)" >&2
|
|
|
cleanup_local
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
echo "✓ 已注入: $deb_file"
|
|
|
cleanup_local
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
if (($# == 0)); then
|
|
|
usage
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
if ! command -v dpkg-deb >/dev/null 2>&1; then
|
|
|
echo "错误: 未安装 dpkg-deb(校验 deb 需要)" >&2
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
TARGET_DEBS=()
|
|
|
if [[ "$1" == "--all" ]]; then
|
|
|
mapfile -t TARGET_DEBS < <(collect_all_debs "$DIST_ROOT")
|
|
|
else
|
|
|
TARGET_DEBS=("$@")
|
|
|
fi
|
|
|
|
|
|
if ((${#TARGET_DEBS[@]} == 0)); then
|
|
|
echo "错误: 未找到可校验的 deb 文件" >&2
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
fail_count=0
|
|
|
for deb in "${TARGET_DEBS[@]}"; do
|
|
|
if ! check_one_deb "$deb"; then
|
|
|
fail_count=$((fail_count + 1))
|
|
|
fi
|
|
|
done
|
|
|
|
|
|
if ((fail_count > 0)); then
|
|
|
echo ""
|
|
|
echo "校验完成:失败 $fail_count 个" >&2
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
echo ""
|
|
|
echo "校验完成:全部通过(${#TARGET_DEBS[@]} 个)"
|