#!/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 < $(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[@]} 个)"