#!/usr/bin/env bash # Fetch VictoriaMetrics single-node, verify it, and stage it for go:embed. # # For each of linux/amd64 and linux/arm64 this produces, in internal/vmsup/bin/: # victoria-metrics-prod-linux- the extracted binary (used by tests) # victoria-metrics-prod-linux-.gz gzbin of it (what vmembed embeds) # # The release tarball is checked against the release's _checksums.txt AND # against the SHA-256 pinned below. The same hashes are pinned in # internal/vmsup/pins.go; keep the two in step when bumping VM_VERSION. # Idempotent: nothing is downloaded when the outputs already match the pins. set -euo pipefail VM_VERSION="v1.153.0" BASE_URL="https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}" # SHA-256 of victoria-metrics-linux--.tar.gz PIN_TAR_AMD64="1b495bde563825cf83dc7c0425a9d8fa03e7214858e0949f9177efc6bb1f8bfc" PIN_TAR_ARM64="3d5f965b7a75f713742a7f37195c1d845f47d9dc9d096a2cce29e693f08fd641" # SHA-256 of the extracted victoria-metrics-prod binary PIN_BIN_AMD64="f7dcb151fd1fef69364d6d6da49c0d3f1b9c2415ef4b4432b08e416a5c73a49b" PIN_BIN_ARM64="bba4c4f46cda51beff65b55c41e59b99e310387c72fd96ee83134d2fa20848e5" # SHA-256 of the .gz produced by internal/vmsup/internal/gzbin (Go compress/gzip, # BestCompression, zero header), so it does not depend on the host's gzip. PIN_GZ_AMD64="2a5e0c1a7fe9825b3ab0a1f2652471608736736670eb6d8953273f4743f909d1" PIN_GZ_ARM64="d7d763d9f81fc3ab7fb3da5a71ce36e8b3e3083d331f7733d1eec9998da23d78" ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" OUT="${ROOT}/internal/vmsup/bin" die() { echo "fetch-vm: $*" >&2; exit 1; } sha() { sha256sum "$1" | awk '{print $1}'; } if ! command -v sha256sum >/dev/null; then die "sha256sum not found"; fi if ! command -v curl >/dev/null; then die "curl not found"; fi mkdir -p "$OUT" work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT fetch_arch() { local arch="$1" pin_tar="$2" pin_bin="$3" pin_gz="$4" local bin="${OUT}/victoria-metrics-prod-linux-${arch}" local gz="${bin}.gz" if [[ -f "$bin" && -f "$gz" && "$(sha "$bin")" == "$pin_bin" ]]; then echo "fetch-vm: linux/${arch} already present (${pin_bin:0:12})" return 0 fi local name="victoria-metrics-linux-${arch}-${VM_VERSION}" local d="${work}/${arch}" mkdir -p "$d/x" echo "fetch-vm: downloading ${name}.tar.gz" curl -fsSL --retry 3 -o "${d}/${name}.tar.gz" "${BASE_URL}/${name}.tar.gz" curl -fsSL --retry 3 -o "${d}/${name}_checksums.txt" "${BASE_URL}/${name}_checksums.txt" local got got="$(sha "${d}/${name}.tar.gz")" [[ "$got" == "$pin_tar" ]] || die "${name}.tar.gz: sha256 ${got} does not match pinned ${pin_tar}" local listed listed="$(awk -v f="${name}.tar.gz" '$2 == f {print $1}' "${d}/${name}_checksums.txt")" [[ "$listed" == "$got" ]] || die "${name}.tar.gz: sha256 ${got} does not match release checksums (${listed:-none})" # Extract only the one member, by name, into an empty directory. tar -xzf "${d}/${name}.tar.gz" -C "${d}/x" victoria-metrics-prod got="$(sha "${d}/x/victoria-metrics-prod")" [[ "$got" == "$pin_bin" ]] || die "victoria-metrics-prod (${arch}): sha256 ${got} does not match pinned ${pin_bin}" listed="$(awk '$2 == "victoria-metrics-prod" {print $1}' "${d}/${name}_checksums.txt")" [[ -z "$listed" || "$listed" == "$got" ]] || die "victoria-metrics-prod (${arch}): does not match release checksums (${listed})" command -v go >/dev/null || die "go not found (needed to build the reproducible .gz)" (cd "$ROOT" && go run ./internal/vmsup/internal/gzbin "${d}/x/victoria-metrics-prod" "${d}/bin.gz") got="$(sha "${d}/bin.gz")" [[ "$got" == "$pin_gz" ]] || die "${arch} .gz: sha256 ${got} does not match pinned ${pin_gz}" # Install atomically so an interrupted run never leaves a half file. install -m 0755 "${d}/x/victoria-metrics-prod" "${bin}.tmp" && mv -f "${bin}.tmp" "$bin" install -m 0644 "${d}/bin.gz" "${gz}.tmp" && mv -f "${gz}.tmp" "$gz" echo "fetch-vm: linux/${arch} ready (${pin_bin:0:12})" } fetch_arch amd64 "$PIN_TAR_AMD64" "$PIN_BIN_AMD64" "$PIN_GZ_AMD64" fetch_arch arm64 "$PIN_TAR_ARM64" "$PIN_BIN_ARM64" "$PIN_GZ_ARM64"