The tree adds the installer, service and test paths admitted by this source commit. Nothing else changes about what may cross. Source-Sha: 3e4a3aa4ce092e9e3f51bc78daf3ddc14d9638f8 Policy-Sha: 3e4a3aa4ce092e9e3f51bc78daf3ddc14d9638f8 Tree-Digest: 89d6fce3828a0e0de0c8eeb41ee6750f4462217e2a04b5190297134d7f4a50c3
150 lines
6.2 KiB
Shell
150 lines
6.2 KiB
Shell
#!/bin/bash
|
|
# build-deb.sh — assemble the RedFlag Debian package from already-built Linux
|
|
# amd64 binaries. This script never compiles anything; it stages, sets modes,
|
|
# and calls dpkg-deb.
|
|
#
|
|
# Usage:
|
|
# installer/linux/build-deb.sh --version 0.3.0 \
|
|
# --agent dist/redflag-agent-linux-amd64 \
|
|
# --helper dist/redflag-helper-linux-amd64 \
|
|
# --desktop dist/redflag-desktop-linux-amd64 \
|
|
# [--outdir dist] [--maintainer "Name <mail>"]
|
|
#
|
|
# Binaries default to $BINDIR (--bindir, default ./dist) using the release
|
|
# artifact names above. Output: <outdir>/redflag_<version>_amd64.deb
|
|
# Validate the result with installer/linux/inspect-deb.sh.
|
|
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$HERE/../.." && pwd)"
|
|
|
|
VERSION=""
|
|
BINDIR="dist"
|
|
OUTDIR="dist"
|
|
MAINTAINER="RedFlag <redflag@localhost>"
|
|
AGENT_BIN=""; HELPER_BIN=""; DESKTOP_BIN=""
|
|
|
|
fail() { echo "[ERROR] [build-deb] $*" >&2; exit 1; }
|
|
log() { echo "[INFO] [build-deb] $*"; }
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--version) VERSION="$2"; shift 2 ;;
|
|
--bindir) BINDIR="$2"; shift 2 ;;
|
|
--outdir) OUTDIR="$2"; shift 2 ;;
|
|
--maintainer) MAINTAINER="$2"; shift 2 ;;
|
|
--agent) AGENT_BIN="$2"; shift 2 ;;
|
|
--helper) HELPER_BIN="$2"; shift 2 ;;
|
|
--desktop) DESKTOP_BIN="$2"; shift 2 ;;
|
|
-h|--help) sed -n '2,20p' "$0"; exit 0 ;;
|
|
*) fail "unknown option: $1" ;;
|
|
esac
|
|
done
|
|
|
|
[ -n "$VERSION" ] || fail "--version is required"
|
|
# Debian upstream versions must start with a digit and use a restricted alphabet.
|
|
[[ "$VERSION" =~ ^[0-9][A-Za-z0-9.+~-]*$ ]] || fail "invalid Debian version: $VERSION"
|
|
|
|
AGENT_BIN="${AGENT_BIN:-$BINDIR/redflag-agent-linux-amd64}"
|
|
HELPER_BIN="${HELPER_BIN:-$BINDIR/redflag-helper-linux-amd64}"
|
|
DESKTOP_BIN="${DESKTOP_BIN:-$BINDIR/redflag-desktop-linux-amd64}"
|
|
|
|
command -v dpkg-deb >/dev/null 2>&1 || fail "dpkg-deb not found (apt-get install dpkg-dev)"
|
|
|
|
# Refuse to package anything that is not a Linux amd64 ELF executable. A silently
|
|
# wrong-arch or truncated artifact would produce a .deb that installs and then
|
|
# fails at first start, which is worse than not building.
|
|
check_bin() {
|
|
local path="$1" name="$2"
|
|
[ -f "$path" ] || fail "$name binary missing: $path (build it first; this script does not compile)"
|
|
[ -s "$path" ] || fail "$name binary is empty: $path"
|
|
if command -v file >/dev/null 2>&1; then
|
|
local desc; desc="$(file -b "$path")"
|
|
case "$desc" in
|
|
*"ELF 64-bit"*x86-64*) ;;
|
|
*) fail "$name is not a Linux x86-64 ELF: $desc" ;;
|
|
esac
|
|
else
|
|
# No file(1): check the ELF magic and e_machine=EM_X86_64 (0x3e) directly.
|
|
local magic; magic="$(head -c 20 "$path" | od -An -tx1 | tr -d ' \n')"
|
|
[ "${magic:0:8}" = "7f454c46" ] || fail "$name is not an ELF binary: $path"
|
|
[ "${magic:36:4}" = "3e00" ] || fail "$name is not x86-64 (e_machine=${magic:36:4})"
|
|
fi
|
|
log "$name ok: $path ($(stat -c%s "$path") bytes)"
|
|
}
|
|
|
|
check_bin "$AGENT_BIN" agent
|
|
check_bin "$HELPER_BIN" helper
|
|
check_bin "$DESKTOP_BIN" desktop
|
|
|
|
PROVISION_SRC="$REPO_ROOT/scripts/provision-standalone-authority.sh"
|
|
[ -f "$PROVISION_SRC" ] || fail "provisioning script missing: $PROVISION_SRC"
|
|
|
|
STAGE="$(mktemp -d)"
|
|
trap 'rm -rf "$STAGE"' EXIT
|
|
|
|
# ---- payload ----------------------------------------------------------------
|
|
# Package files live in policy-correct locations; /usr/local/bin compatibility
|
|
# symlinks for the binaries' compiled-in paths are created by postinst, which is
|
|
# where policy allows /usr/local to be touched at all.
|
|
install -D -m 0755 "$AGENT_BIN" "$STAGE/usr/bin/redflag-agent"
|
|
install -D -m 0755 "$HELPER_BIN" "$STAGE/usr/bin/redflag-helper"
|
|
install -D -m 0755 "$DESKTOP_BIN" "$STAGE/usr/bin/redflag-desktop"
|
|
|
|
install -D -m 0644 "$HERE/systemd/redflag-agent.service" \
|
|
"$STAGE/lib/systemd/system/redflag-agent.service"
|
|
install -D -m 0644 "$HERE/desktop/redflag-desktop.desktop" \
|
|
"$STAGE/usr/share/applications/redflag-desktop.desktop"
|
|
install -D -m 0644 "$HERE/desktop/redflag-desktop.desktop" \
|
|
"$STAGE/etc/xdg/autostart/redflag-desktop.desktop"
|
|
install -D -m 0440 "$HERE/sudoers/redflag-agent" \
|
|
"$STAGE/etc/sudoers.d/redflag-agent"
|
|
install -D -m 0644 "$HERE/polkit/50-redflag-agent.rules" \
|
|
"$STAGE/etc/polkit-1/rules.d/50-redflag-agent.rules"
|
|
|
|
# The authority provisioning script ships verbatim — postinst calls it with path
|
|
# overrides rather than reimplementing any of its logic.
|
|
install -D -m 0755 "$PROVISION_SRC" \
|
|
"$STAGE/usr/lib/redflag/provision-standalone-authority.sh"
|
|
install -D -m 0644 "$REPO_ROOT/LICENSE" "$STAGE/usr/share/doc/redflag/copyright"
|
|
install -D -m 0644 "$REPO_ROOT/THIRD_PARTY_LICENSES.md" "$STAGE/usr/share/doc/redflag/THIRD_PARTY_LICENSES.md"
|
|
|
|
# ---- control ----------------------------------------------------------------
|
|
install -d -m 0755 "$STAGE/DEBIAN"
|
|
sed -e "s|@VERSION@|$VERSION|g" -e "s|@MAINTAINER@|$MAINTAINER|g" \
|
|
"$HERE/debian/control.in" > "$STAGE/DEBIAN/control"
|
|
|
|
for script in preinst postinst prerm postrm; do
|
|
sed -e "s|@VERSION@|$VERSION|g" "$HERE/debian/$script" > "$STAGE/DEBIAN/$script"
|
|
chmod 0755 "$STAGE/DEBIAN/$script"
|
|
done
|
|
|
|
# Static config files are conffiles so operator edits survive upgrades.
|
|
cat > "$STAGE/DEBIAN/conffiles" <<'EOF'
|
|
/etc/sudoers.d/redflag-agent
|
|
/etc/polkit-1/rules.d/50-redflag-agent.rules
|
|
/etc/xdg/autostart/redflag-desktop.desktop
|
|
EOF
|
|
|
|
# md5sums so `dpkg -V` / debsums can detect tampering with installed files.
|
|
( cd "$STAGE" && find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
|
|
| xargs -0 md5sum > DEBIAN/md5sums )
|
|
|
|
# Syntax-check the maintainer scripts before shipping them. A broken postinst is
|
|
# discovered at install time on the operator's machine otherwise.
|
|
for script in preinst postinst prerm postrm; do
|
|
sh -n "$STAGE/DEBIAN/$script" || fail "$script failed shell syntax check"
|
|
done
|
|
if command -v visudo >/dev/null 2>&1; then
|
|
visudo -c -f "$STAGE/etc/sudoers.d/redflag-agent" >/dev/null \
|
|
|| fail "sudoers file failed validation"
|
|
log "sudoers validated"
|
|
fi
|
|
|
|
mkdir -p "$OUTDIR"
|
|
DEB="$OUTDIR/redflag_${VERSION}_amd64.deb"
|
|
# root:root ownership without needing root to build.
|
|
dpkg-deb --root-owner-group --build "$STAGE" "$DEB" >/dev/null
|
|
log "built: $DEB ($(stat -c%s "$DEB") bytes)"
|
|
echo "$DEB"
|