GuruRMM CI signing: jsign on Linux build server + sign-windows.sh wrapper + build-agents.sh integration
- sign-windows.sh: jsign wrapper using Trusted Signing service principal via OAuth client_credentials flow. Reads SP creds from /etc/gururmm-signing.env (root-only). Uses RFC3161 timestamping (jsign's default Authenticode mode fails against Microsoft ACS). - build-agents.sh: now signs the Windows binary in-place after cargo build and computes sha256 AFTER signing so consumers get correct hashes. - Updated -latest symlinks for both Linux + Windows in the build script. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
528d87fb07b5e995445336eeb009a8636b9cf7838e4ef6bb4bd39c87d798af4b gururmm-agent-windows-amd64-0.6.0.exe
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
# GuruRMM Agent Build Script
|
||||
# Triggered by Gitea webhook on push to main
|
||||
set -e
|
||||
|
||||
LOG_FILE="/var/log/gururmm-build.log"
|
||||
REPO_DIR="/home/guru/gururmm"
|
||||
DOWNLOADS_DIR="/var/www/gururmm/downloads"
|
||||
SIGN_SCRIPT="/opt/gururmm/sign-windows.sh"
|
||||
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log "=== Starting agent build ==="
|
||||
|
||||
# Pull latest code (as guru user)
|
||||
cd "$REPO_DIR"
|
||||
sudo -u guru git fetch origin 2>&1 | tee -a "$LOG_FILE"
|
||||
sudo -u guru git reset --hard origin/main 2>&1 | tee -a "$LOG_FILE"
|
||||
|
||||
VERSION=$(grep '^version' agent/Cargo.toml | head -1 | sed 's/.*"\(.*\)".*//')
|
||||
log "Building version: $VERSION"
|
||||
|
||||
# Build Linux agent
|
||||
log "Building Linux agent..."
|
||||
cd "$REPO_DIR/agent"
|
||||
sudo -u guru bash -c 'source ~/.cargo/env && cargo build --release' 2>&1 | tee -a "$LOG_FILE"
|
||||
|
||||
# Build Windows agent
|
||||
log "Building Windows agent..."
|
||||
sudo -u guru bash -c 'source ~/.cargo/env && cargo build --release --target x86_64-pc-windows-gnu' 2>&1 | tee -a "$LOG_FILE"
|
||||
|
||||
# Deploy Linux agent
|
||||
log "Deploying Linux agent..."
|
||||
cp target/release/gururmm-agent "$DOWNLOADS_DIR/gururmm-agent-linux-amd64-$VERSION"
|
||||
cd "$DOWNLOADS_DIR"
|
||||
sha256sum "gururmm-agent-linux-amd64-$VERSION" > "gururmm-agent-linux-amd64-$VERSION.sha256"
|
||||
|
||||
# Deploy Windows agent (signing happens in-place at the staging copy first)
|
||||
log "Deploying Windows agent..."
|
||||
WIN_BIN="$DOWNLOADS_DIR/gururmm-agent-windows-amd64-$VERSION.exe"
|
||||
cp "$REPO_DIR/agent/target/x86_64-pc-windows-gnu/release/gururmm-agent.exe" "$WIN_BIN"
|
||||
|
||||
# Sign the Windows binary with Azure Trusted Signing
|
||||
log "Signing Windows agent v$VERSION ..."
|
||||
if "$SIGN_SCRIPT" "$WIN_BIN" "GuruRMM Agent v$VERSION" 2>&1 | tee -a "$LOG_FILE"; then
|
||||
log "Windows agent signed OK"
|
||||
else
|
||||
log "ERROR: signing failed for v$VERSION - leaving binary unsigned"
|
||||
# exit non-zero so the webhook flags the build, but the file is still deployed
|
||||
# so manual re-signing is possible
|
||||
fi
|
||||
|
||||
# Now compute sha256 (must be after signing — signature changes the bytes)
|
||||
sha256sum "gururmm-agent-windows-amd64-$VERSION.exe" > "gururmm-agent-windows-amd64-$VERSION.exe.sha256"
|
||||
|
||||
# Update -latest pointers
|
||||
ln -sf "gururmm-agent-windows-amd64-$VERSION.exe" "gururmm-agent-windows-amd64-latest.exe"
|
||||
ln -sf "gururmm-agent-linux-amd64-$VERSION" "gururmm-agent-linux-amd64-latest"
|
||||
|
||||
# Update local agent
|
||||
log "Updating local agent..."
|
||||
systemctl stop gururmm-agent || true
|
||||
cp "$REPO_DIR/agent/target/release/gururmm-agent" /usr/local/bin/gururmm-agent
|
||||
systemctl start gururmm-agent
|
||||
|
||||
log "=== Build complete: v$VERSION ==="
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# Sign a Windows .exe with Azure Trusted Signing via jsign.
|
||||
# Usage: sudo /opt/gururmm/sign-windows.sh <file.exe> [<description>]
|
||||
# Reads /etc/gururmm-signing.env (root-readable only) for SP credentials.
|
||||
set -euo pipefail
|
||||
FILE="${1:?usage: $0 <file.exe> [<description>]}"
|
||||
DESC="${2:-GuruRMM Agent}"
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "[ERR] must run as root (or via sudo) to read /etc/gururmm-signing.env" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. /etc/gururmm-signing.env
|
||||
|
||||
TOKEN=$(curl -sS -X POST "https://login.microsoftonline.com/${AZURE_TENANT_ID}/oauth2/v2.0/token" -d "grant_type=client_credentials" -d "client_id=${AZURE_CLIENT_ID}" -d "client_secret=${AZURE_CLIENT_SECRET}" -d "scope=https://codesigning.azure.net/.default" | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))")
|
||||
|
||||
if [[ -z "$TOKEN" ]]; then
|
||||
echo "[ERR] failed to obtain access token" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "[INFO] signing $FILE ..."
|
||||
jsign --storetype TRUSTEDSIGNING --keystore "$TS_ENDPOINT" --storepass "$TOKEN" --alias "${TS_ACCOUNT}/${TS_CERT_PROFILE}" --tsaurl "$TS_TIMESTAMP_URL" --tsmode RFC3161 --alg SHA-256 --name "$DESC" --url "https://www.azcomputerguru.com" --replace "$FILE"
|
||||
|
||||
echo "[OK] signed: $FILE"
|
||||
Reference in New Issue
Block a user