173 lines
4.9 KiB
Bash
Executable File
173 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
PROFILE="${PROFILE:-release}"
|
|
OUT_DIR="${OUT_DIR:-$REPO_ROOT/target/portable-soak}"
|
|
PACKAGE_PREFIX="${PACKAGE_PREFIX:-portable-soak}"
|
|
PACKAGE_DIR_NAME="${PACKAGE_DIR_NAME:-portable-soak}"
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage:
|
|
scripts/soak/build_portable_soak_package.sh [--out-dir <path>] [--profile <profile>]
|
|
|
|
Requires release binaries to already exist. Build them first, for example:
|
|
cargo build --release --bin rpki --bin rpki_daemon --bin db_stats
|
|
USAGE
|
|
}
|
|
|
|
die() {
|
|
echo "error: $*" >&2
|
|
exit 2
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--out-dir)
|
|
shift
|
|
OUT_DIR="${1:?--out-dir requires a value}"
|
|
;;
|
|
--profile)
|
|
shift
|
|
PROFILE="${1:?--profile requires a value}"
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
die "unknown argument: $1"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
command -v python3 >/dev/null 2>&1 || die "python3 is required"
|
|
command -v tar >/dev/null 2>&1 || die "tar is required"
|
|
|
|
if [[ "$PROFILE" == "release" ]]; then
|
|
TARGET_BIN_DIR="$REPO_ROOT/target/release"
|
|
else
|
|
TARGET_BIN_DIR="$REPO_ROOT/target/$PROFILE"
|
|
fi
|
|
|
|
REQUIRED_BINS=(rpki rpki_daemon db_stats)
|
|
OPTIONAL_BINS=(
|
|
ccr_dump
|
|
ccr_state_compare
|
|
ccr_to_compare_views
|
|
ccr_to_routinator_csv
|
|
ccr_verify
|
|
cir_drop_report
|
|
cir_dump_reject_list
|
|
cir_extract_inputs
|
|
cir_materialize
|
|
cir_probe_rpki_client_cache
|
|
cir_state_compare
|
|
rrdp_state_dump
|
|
)
|
|
|
|
for binary_name in "${REQUIRED_BINS[@]}"; do
|
|
[[ -x "$TARGET_BIN_DIR/$binary_name" ]] || die "missing required binary: $TARGET_BIN_DIR/$binary_name"
|
|
done
|
|
|
|
mkdir -p "$OUT_DIR"
|
|
GIT_SHA="$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || printf 'unknown')"
|
|
TIMESTAMP="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
PACKAGE_NAME="${PACKAGE_PREFIX}-${TIMESTAMP}-${GIT_SHA}"
|
|
BUILD_ROOT="$REPO_ROOT/target/portable-soak-build"
|
|
STAGE_DIR="$BUILD_ROOT/$PACKAGE_DIR_NAME"
|
|
ARCHIVE_PATH="$OUT_DIR/$PACKAGE_NAME.tar.gz"
|
|
|
|
rm -rf "$STAGE_DIR" "$ARCHIVE_PATH"
|
|
mkdir -p "$STAGE_DIR/bin" "$STAGE_DIR/fixtures" "$STAGE_DIR/scripts" \
|
|
"$STAGE_DIR/runs" "$STAGE_DIR/state" "$STAGE_DIR/logs" "$STAGE_DIR/tmp"
|
|
|
|
install -m 0755 "$SCRIPT_DIR/run_soak.sh" "$STAGE_DIR/run_soak.sh"
|
|
install -m 0644 "$SCRIPT_DIR/portable-soak.env.example" "$STAGE_DIR/.env"
|
|
install -m 0644 "$SCRIPT_DIR/portable-soak.env.example" "$STAGE_DIR/portable-soak.env.example"
|
|
|
|
COPIED_BIN_LIST="$STAGE_DIR/copied-binaries.txt"
|
|
MISSING_OPTIONAL_BIN_LIST="$STAGE_DIR/missing-optional-binaries.txt"
|
|
: > "$COPIED_BIN_LIST"
|
|
: > "$MISSING_OPTIONAL_BIN_LIST"
|
|
|
|
for binary_name in "${REQUIRED_BINS[@]}"; do
|
|
install -m 0755 "$TARGET_BIN_DIR/$binary_name" "$STAGE_DIR/bin/$binary_name"
|
|
printf '%s\n' "$binary_name" >> "$COPIED_BIN_LIST"
|
|
done
|
|
|
|
for binary_name in "${OPTIONAL_BINS[@]}"; do
|
|
if [[ -x "$TARGET_BIN_DIR/$binary_name" ]]; then
|
|
install -m 0755 "$TARGET_BIN_DIR/$binary_name" "$STAGE_DIR/bin/$binary_name"
|
|
printf '%s\n' "$binary_name" >> "$COPIED_BIN_LIST"
|
|
else
|
|
printf '%s\n' "$binary_name" >> "$MISSING_OPTIONAL_BIN_LIST"
|
|
fi
|
|
done
|
|
|
|
cp -a "$REPO_ROOT/tests/fixtures/tal" "$STAGE_DIR/fixtures/"
|
|
cp -a "$REPO_ROOT/tests/fixtures/ta" "$STAGE_DIR/fixtures/"
|
|
cp -a "$REPO_ROOT/scripts/periodic" "$STAGE_DIR/scripts/"
|
|
cp -a "$REPO_ROOT/scripts/cir" "$STAGE_DIR/scripts/"
|
|
find "$STAGE_DIR/scripts" -type d -name __pycache__ -prune -exec rm -rf {} +
|
|
|
|
(cd "$STAGE_DIR" && find fixtures -type f | sort > fixtures.txt)
|
|
(cd "$STAGE_DIR" && find scripts -type f | sort > scripts.txt)
|
|
|
|
GIT_DIRTY="false"
|
|
if [[ -n "$(git -C "$REPO_ROOT" status --short 2>/dev/null || true)" ]]; then
|
|
GIT_DIRTY="true"
|
|
fi
|
|
GIT_STATUS="$(git -C "$REPO_ROOT" status --short 2>/dev/null || true)"
|
|
|
|
python3 - "$STAGE_DIR/manifest.json" "$PACKAGE_NAME" "$TIMESTAMP" "$REPO_ROOT" "$GIT_SHA" \
|
|
"$GIT_DIRTY" "$PROFILE" "$TARGET_BIN_DIR" "$GIT_STATUS" <<'PY'
|
|
import json
|
|
import pathlib
|
|
import sys
|
|
|
|
(
|
|
manifest_path,
|
|
package_name,
|
|
created_at,
|
|
repo_root,
|
|
git_sha,
|
|
git_dirty,
|
|
profile,
|
|
target_bin_dir,
|
|
git_status,
|
|
) = sys.argv[1:]
|
|
stage_dir = pathlib.Path(manifest_path).parent
|
|
|
|
def read_lines(name):
|
|
path = stage_dir / name
|
|
if not path.exists():
|
|
return []
|
|
return [line for line in path.read_text(encoding="utf-8").splitlines() if line]
|
|
|
|
manifest = {
|
|
"packageName": package_name,
|
|
"createdAtUtc": created_at,
|
|
"sourceRepo": repo_root,
|
|
"gitCommit": git_sha,
|
|
"gitDirty": git_dirty == "true",
|
|
"gitStatusShort": git_status.splitlines(),
|
|
"rustProfile": profile,
|
|
"targetBinDir": target_bin_dir,
|
|
"copiedBinaries": read_lines("copied-binaries.txt"),
|
|
"missingOptionalBinaries": read_lines("missing-optional-binaries.txt"),
|
|
"fixtures": read_lines("fixtures.txt"),
|
|
"scripts": read_lines("scripts.txt"),
|
|
}
|
|
pathlib.Path(manifest_path).write_text(
|
|
json.dumps(manifest, indent=2, sort_keys=True) + "\n",
|
|
encoding="utf-8",
|
|
)
|
|
PY
|
|
|
|
tar -C "$BUILD_ROOT" -czf "$ARCHIVE_PATH" "$PACKAGE_DIR_NAME"
|
|
printf '%s\n' "$ARCHIVE_PATH"
|