You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
4.2 KiB
Bash

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
# 为构建出的 deb 注入 postinst安装时自动写入 apt 源与公钥。
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_SOURCE_URL="${APT_SOURCE_URL:-http://80.12.140.29:80/apt}"
APT_SOURCE_SUITE="${APT_SOURCE_SUITE:-v10}"
APT_SOURCE_COMPONENT="${APT_SOURCE_COMPONENT:-main}"
APT_SOURCE_LIST_FILE="${APT_SOURCE_LIST_FILE:-/etc/apt/sources.list.d/zyyun.list}"
APT_KEYRING_PATH="${APT_KEYRING_PATH:-/usr/share/keyrings/zyyun-archive-keyring.gpg}"
APT_BOOTSTRAP_KEY_IN_PKG="${APT_BOOTSTRAP_KEY_IN_PKG:-/usr/share/zyyun/bootstrap/zyyun-archive-keyring.gpg}"
GPG_KEY_ID="${APT_GPG_KEY_ID:-com.jgzy.product}"
AUTO_CREATE_GPG_KEY="${APT_GPG_AUTO_CREATE:-1}"
usage() {
cat <<EOF
用法:
$(basename "$0") [项目名...]
环境变量:
DEB_DIST_ROOT deb 目录(默认: dist/linux-deb
APT_GPG_KEY_ID 签名 Key默认: com.jgzy.product
APT_GPG_AUTO_CREATE 1/0缺失签名密钥时自动创建默认: 1
APT_SOURCE_URL 更新源地址(默认: http://80.12.140.29:80/apt
APT_SOURCE_SUITE 默认: v10
APT_SOURCE_COMPONENT 默认: main
EOF
}
if (($# > 0)); then
case "$1" in
--help|-h)
usage
exit 0
;;
esac
fi
if [[ ! -d "$DIST_ROOT" ]]; then
echo "错误: deb 产物目录不存在: $DIST_ROOT" >&2
exit 1
fi
if ! command -v gpg >/dev/null 2>&1; then
echo "错误: 未安装 gpg注入公钥需要" >&2
exit 1
fi
if ! command -v dpkg-deb >/dev/null 2>&1; then
echo "错误: 未安装 dpkg-debdeb 重新打包需要)" >&2
exit 1
fi
ensure_signing_key() {
local key="$1"
local quick_gen_cmd=(
gpg --batch --pinentry-mode loopback --passphrase ""
--quick-gen-key "$key" rsa4096 sign 5y
)
if gpg --list-secret-keys "$key" >/dev/null 2>&1; then
return 0
fi
if [[ "$AUTO_CREATE_GPG_KEY" != "1" ]]; then
echo "错误: 未找到签名私钥: $key" >&2
echo "请先执行以下命令创建密钥,或设置 APT_GPG_AUTO_CREATE=1 自动创建:" >&2
echo " ${quick_gen_cmd[*]}" >&2
exit 1
fi
echo "==> gpg key not found, generating: $key"
"${quick_gen_cmd[@]}"
}
PROJECTS=()
if ((${#@} > 0)); then
PROJECTS=("$@")
else
shopt -s nullglob
for p in "$DIST_ROOT"/*; do
[[ -d "$p" ]] || continue
PROJECTS+=( "$(basename "$p")" )
done
shopt -u nullglob
fi
if ((${#PROJECTS[@]} == 0)); then
echo "错误: 未发现可注入项目($DIST_ROOT 为空)" >&2
exit 1
fi
ensure_signing_key "$GPG_KEY_ID"
tmp_key="$(mktemp)"
cleanup() {
rm -f "$tmp_key"
}
trap cleanup EXIT
gpg --export "$GPG_KEY_ID" > "$tmp_key"
inject_one_deb() {
local deb_file="$1"
local tmp_dir
tmp_dir="$(mktemp -d)"
dpkg-deb -R "$deb_file" "$tmp_dir" >/dev/null
mkdir -p "$tmp_dir/DEBIAN"
mkdir -p "$tmp_dir$(dirname "$APT_BOOTSTRAP_KEY_IN_PKG")"
install -m 0644 "$tmp_key" "$tmp_dir$APT_BOOTSTRAP_KEY_IN_PKG"
cat > "$tmp_dir/DEBIAN/postinst" <<EOF
#!/bin/sh
set -e
KEY_SRC="$APT_BOOTSTRAP_KEY_IN_PKG"
KEY_DST="$APT_KEYRING_PATH"
LIST_FILE="$APT_SOURCE_LIST_FILE"
SOURCE_LINE='deb [signed-by=$APT_KEYRING_PATH] $APT_SOURCE_URL $APT_SOURCE_SUITE $APT_SOURCE_COMPONENT'
if [ ! -f "\$KEY_SRC" ]; then
echo "warning: bootstrap key file missing: \$KEY_SRC" >&2
else
install -d "\$(dirname "\$KEY_DST")"
install -m 0644 "\$KEY_SRC" "\$KEY_DST"
fi
install -d "\$(dirname "\$LIST_FILE")"
printf '%s\n' "\$SOURCE_LINE" > "\$LIST_FILE"
if command -v apt-get >/dev/null 2>&1; then
apt-get update || true
elif command -v apt >/dev/null 2>&1; then
apt update || true
fi
exit 0
EOF
chmod 0755 "$tmp_dir/DEBIAN/postinst"
dpkg-deb -b "$tmp_dir" "$deb_file" >/dev/null
rm -rf "$tmp_dir"
}
for project in "${PROJECTS[@]}"; do
for arch in amd64 arm64; do
shopt -s nullglob
debs=( "$DIST_ROOT/$project/$arch"/*.deb )
shopt -u nullglob
if (( ${#debs[@]} == 0 )); then
continue
fi
for deb_file in "${debs[@]}"; do
echo "==> inject bootstrap into $(basename "$deb_file")"
inject_one_deb "$deb_file"
done
done
done
echo "==> deb bootstrap 注入完成"
echo " source: $APT_SOURCE_URL $APT_SOURCE_SUITE $APT_SOURCE_COMPONENT"
echo " keyring: $APT_KEYRING_PATH"