139 lines
4.9 KiB
Bash
Executable File
139 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
BUILD_DIR="$ROOT_DIR/deployment/build"
|
|
ART_ROOT="$ROOT_DIR/deployment/artifact"
|
|
|
|
. "$BUILD_DIR/common.sh"
|
|
|
|
usage() { cat <<'EOF'
|
|
Build Argus Server Offline Package
|
|
|
|
Usage: build_server_package.sh [--version YYYYMMDD] [--out DIR] [--resave-image]
|
|
|
|
Outputs into deployment/artifact/server/<YYYYMMDD>/ by default.
|
|
EOF
|
|
}
|
|
|
|
VERSION="$(today_version)"
|
|
OUT_DIR=""
|
|
RESAVE_IMAGE=false
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--version) VERSION="$2"; shift 2;;
|
|
--out) OUT_DIR="$2"; shift 2;;
|
|
--resave-image) RESAVE_IMAGE=true; shift;;
|
|
-h|--help) usage; exit 0;;
|
|
*) err "unknown arg: $1"; usage; exit 1;;
|
|
esac
|
|
done
|
|
|
|
PKG_DIR="${OUT_DIR:-$ART_ROOT/server/$VERSION}"
|
|
STAGE="$(mktemp -d)"
|
|
trap 'rm -rf "$STAGE"' EXIT
|
|
|
|
log "Version: $VERSION"
|
|
log "Staging: $STAGE"
|
|
|
|
# 1) Layout
|
|
make_dir "$STAGE/images"
|
|
make_dir "$STAGE/compose"
|
|
make_dir "$STAGE/scripts"
|
|
make_dir "$STAGE/docs"
|
|
make_dir "$STAGE/private/argus"
|
|
|
|
# 2) Compose: derive from sys/tests by removing test-only services
|
|
SRC_COMPOSE="$ROOT_DIR/src/sys/tests/docker-compose.yml"
|
|
[[ -f "$SRC_COMPOSE" ]] || { err "missing $SRC_COMPOSE"; exit 1; }
|
|
# 2.1 filter out test services
|
|
tmp_compose1="$STAGE/compose/docker-compose.filtered.yml"
|
|
awk -f "$BUILD_DIR/templates/docker-compose.filter.awk" -v remove="node-a,node-b,test-node,test-gpu-node" "$SRC_COMPOSE" > "$tmp_compose1"
|
|
# 2.2 transform to external overlay network (remove sysnet and per-service blocks)
|
|
awk -f "$BUILD_DIR/templates/docker-compose.overlay.awk" "$tmp_compose1" > "$STAGE/compose/docker-compose.yml"
|
|
cp "$BUILD_DIR/templates/.env.example" "$STAGE/compose/.env.example"
|
|
# fix relative private path to match package layout (compose/ and private/ are siblings)
|
|
sed -i 's#\./private/#../private/#g' "$STAGE/compose/docker-compose.yml"
|
|
# also handle bind mount form without trailing slash
|
|
sed -i -E 's#- \./private:/private#- ../private:/private#g' "$STAGE/compose/docker-compose.yml"
|
|
# drop timezone file bind which may not exist on target distros (e.g. NixOS)
|
|
sed -i '/\/etc\/timezone:\/etc\/timezone:ro/d' "$STAGE/compose/docker-compose.yml"
|
|
|
|
# sanity-check: ensure test services are absent and external network present
|
|
if grep -E '^(\s{2})(node-a|node-b|test-node|test-gpu-node):\s*$' -n "$STAGE/compose/docker-compose.yml" >/dev/null; then
|
|
err "compose filter failed: test services still present"; exit 1;
|
|
fi
|
|
if ! grep -q '^networks:' "$STAGE/compose/docker-compose.yml" || ! grep -q 'argus-sys-net:' "$STAGE/compose/docker-compose.yml"; then
|
|
err "compose overlay transform failed: external network missing"; exit 1;
|
|
fi
|
|
|
|
# 3) Images (reuse if already exported unless --resave-image)
|
|
existing_images_tar="$PKG_DIR/images/all-images.tar.gz"
|
|
if [[ "$RESAVE_IMAGE" == false && -f "$existing_images_tar" ]]; then
|
|
log "Reusing existing images tar: $existing_images_tar"
|
|
cp "$existing_images_tar" "$STAGE/images/"
|
|
elif [[ "$RESAVE_IMAGE" == false ]]; then
|
|
# Try cross-version reuse from latest server_*.tar.gz
|
|
latest_pkg=$(ls -1t "$ART_ROOT/server"/server_*.tar.gz 2>/dev/null | head -n1 || true)
|
|
if [[ -n "$latest_pkg" ]]; then
|
|
log "Reusing images from: $latest_pkg"
|
|
mkdir -p "$STAGE/images"
|
|
# extract matching file regardless of top-level dir
|
|
if tar -xzf "$latest_pkg" -C "$STAGE" --wildcards '*/images/all-images.tar.gz' 2>/dev/null; then
|
|
# locate and move
|
|
found=$(find "$STAGE" -type f -path '*/images/all-images.tar.gz' | head -n1 || true)
|
|
if [[ -n "$found" ]]; then
|
|
mv "$found" "$STAGE/images/all-images.tar.gz"
|
|
# cleanup leftover extracted dir
|
|
dir_to_clean=$(dirname "$found")
|
|
rm -rf "${dir_to_clean%/images}" 2>/dev/null || true
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# If still not present, save from local docker daemon
|
|
if [[ ! -f "$STAGE/images/all-images.tar.gz" ]]; then
|
|
require_cmd docker gzip
|
|
images=(
|
|
argus-bind9:latest
|
|
argus-master:latest
|
|
argus-elasticsearch:latest
|
|
argus-kibana:latest
|
|
argus-metric-ftp:latest
|
|
argus-metric-prometheus:latest
|
|
argus-metric-grafana:latest
|
|
argus-alertmanager:latest
|
|
argus-web-frontend:latest
|
|
argus-web-proxy:latest
|
|
)
|
|
log "Saving images: ${#images[@]}"
|
|
tarfile="$STAGE/images/all-images.tar"
|
|
docker save -o "$tarfile" "${images[@]}"
|
|
gzip -f "$tarfile"
|
|
fi
|
|
|
|
# 4) Scripts & Docs
|
|
copy_tree "$BUILD_DIR/templates/scripts" "$STAGE/scripts"
|
|
copy_tree "$BUILD_DIR/templates/docs" "$STAGE/docs"
|
|
|
|
# 5) Manifests
|
|
gen_manifest "$STAGE" "$STAGE/manifest.txt"
|
|
checksum_dir "$STAGE" "$STAGE/checksums.txt"
|
|
|
|
# 6) Move to artifact
|
|
make_dir "$PKG_DIR"
|
|
rsync -a "$STAGE/" "$PKG_DIR/" 2>/dev/null || cp -r "$STAGE/." "$PKG_DIR/"
|
|
log "Server package ready: $PKG_DIR"
|
|
|
|
echo "$VERSION" > "$PKG_DIR/version.json"
|
|
|
|
# 7) Create distributable tarball
|
|
OUT_TAR_DIR="$(dirname "$PKG_DIR")"
|
|
OUT_TAR="$OUT_TAR_DIR/server_${VERSION}.tar.gz"
|
|
log "Creating tarball: $OUT_TAR"
|
|
(cd "$PKG_DIR/.." && tar -czf "$OUT_TAR" "$(basename "$PKG_DIR")")
|
|
log "Tarball ready: $OUT_TAR"
|
|
|
|
exit 0
|