#!/usr/bin/env bash # SPDX-License-Identifier: Apache-2.0 # # Builds .deb and .rpm packages with nfpm from the release tarballs in DIST # (made by scripts/build-release.sh) and rewrites DIST/SHA256SUMS to cover # tarballs and packages (ADR 0024). # # Usage: scripts/build-packages.sh [-d DIST] [-p "linux/amd64 linux/arm64"] # # Each package holds the binary from its tarball as /usr/bin/, the # systemd unit rendered for /usr/bin and the license text. Names and version # come from the environment (Makefile, ADR 0018): VERSION, PRODUCT, # DISPLAY_NAME, BIN_SERVER, BIN_AGENT_DNS, BIN_AGENT_DHCP. NFPM names the # nfpm binary (default: nfpm from PATH, installed by scripts/ci/install-tools.sh). # Optional: PKG_MAINTAINER, PKG_VENDOR, PKG_HOMEPAGE. set -euo pipefail PRODUCT="${PRODUCT:-ddi-suite}" DISPLAY_NAME="${DISPLAY_NAME:-DDI-Suite}" BIN_SERVER="${BIN_SERVER:-ddi-server}" BIN_AGENT_DNS="${BIN_AGENT_DNS:-ddi-agent-dns}" BIN_AGENT_DHCP="${BIN_AGENT_DHCP:-ddi-agent-dhcp}" NFPM="${NFPM:-nfpm}" dist="dist" platforms="linux/amd64 linux/arm64" usage() { sed -n '4,16p' "$0" | sed 's/^# \{0,1\}//' } while getopts ":d:p:h" opt; do case "$opt" in d) dist="$OPTARG" ;; p) platforms="$OPTARG" ;; h) usage exit 0 ;; *) usage >&2 exit 2 ;; esac done root="$(git rev-parse --show-toplevel)" cd "$root" if ! command -v "$NFPM" >/dev/null; then echo "nfpm not found (set NFPM or run scripts/ci/install-tools.sh)" >&2 exit 1 fi VERSION="${VERSION:-$(git describe --tags --always --dirty 2>/dev/null || echo dev)}" BUILD_DATE="${BUILD_DATE:-$(git log -1 --format=%cI 2>/dev/null || date -u +%Y-%m-%dT%H:%M:%SZ)}" # Package versions must be semantic versions: v1.2.3 -> 1.2.3; anything else # (a commit hash, "dev") becomes a 0.0.0 pre-release that sorts below every # real release. if [[ "$VERSION" =~ ^v?([0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.+-]*)?)$ ]]; then pkg_version="${BASH_REMATCH[1]}" else pkg_version="0.0.0-dev.$(tr -c '0-9A-Za-z.\n' '.' <<<"$VERSION")" fi # Reproducible timestamps inside the packages. SOURCE_DATE_EPOCH="$(date -u -d "$BUILD_DATE" +%s 2>/dev/null || echo 0)" export SOURCE_DATE_EPOCH declare -A descriptions=( ["$BIN_SERVER"]="${DISPLAY_NAME} management server (IPAM, DNS and DHCP)" ["$BIN_AGENT_DNS"]="${DISPLAY_NAME} agent for BIND 9" ["$BIN_AGENT_DHCP"]="${DISPLAY_NAME} agent for Kea DHCPv4" ) declare -A licenses=( ["$BIN_SERVER"]="LICENSES/LicenseRef-DDI-Proprietary.txt" ["$BIN_AGENT_DNS"]="LICENSES/Apache-2.0.txt" ["$BIN_AGENT_DHCP"]="LICENSES/Apache-2.0.txt" ) declare -A license_names=( ["$BIN_SERVER"]="Proprietary" ["$BIN_AGENT_DNS"]="Apache-2.0" ["$BIN_AGENT_DHCP"]="Apache-2.0" ) workdir="$(mktemp -d)" trap 'rm -rf "$workdir"' EXIT # Git Bash on Windows (development): nfpm.exe needs Windows paths. if command -v cygpath >/dev/null; then workdir="$(cygpath -m "$workdir")" fi export PRODUCT DISPLAY_NAME BIN_SERVER BIN_AGENT_DNS BIN_AGENT_DHCP scripts/render-units.sh /usr/bin "$workdir/units" PKG_MAINTAINER="${PKG_MAINTAINER:-${DISPLAY_NAME} }" PKG_VENDOR="${PKG_VENDOR:-$DISPLAY_NAME}" PKG_HOMEPAGE="${PKG_HOMEPAGE:-https://git.beugsiud.de/beug.k/DDI}" # render_config NAME ARCH SRC_DIR LICENSE DESCRIPTION > nfpm.yaml render_config() { local -a subst=( PKG_NAME "$1" PKG_ARCH "$2" PKG_SRC_DIR "$3" PKG_LICENSE "$4" PKG_DESCRIPTION "$5" PKG_VERSION "$pkg_version" PKG_MAINTAINER "$PKG_MAINTAINER" PKG_VENDOR "$PKG_VENDOR" PKG_HOMEPAGE "$PKG_HOMEPAGE" PKG_SCRIPTS_DIR "$root/deploy/nfpm" ) local -a expr=() local i value for ((i = 0; i < ${#subst[@]}; i += 2)); do value="${subst[i + 1]}" # The values end up in sed replacements and double-quoted YAML. if [[ "$value" == *[\|\&\\\"]* ]]; then echo "unsafe value for ${subst[i]}: ${value}" >&2 exit 2 fi expr+=(-e "s|@${subst[i]}@|${value}|g") done sed "${expr[@]}" deploy/nfpm/package.yaml.in } for platform in $platforms; do goos="${platform%/*}" goarch="${platform#*/}" for bin in "$BIN_SERVER" "$BIN_AGENT_DNS" "$BIN_AGENT_DHCP"; do name="${bin}_${VERSION}_${goos}_${goarch}" tarball="${dist}/${name}.tar.gz" if [[ ! -f "$tarball" ]]; then echo "missing ${tarball}: run make release first" >&2 exit 1 fi src="${workdir}/${name}" mkdir -p "$src" tar -xzf "$tarball" -C "$workdir" "${name}/${bin}" mv "${workdir}/${name}/${bin}" "${src}/binary" cp "$workdir/units/${bin}.service" "${src}/unit.service" cp "${licenses[$bin]}" "${src}/LICENSE" render_config "$bin" "$goarch" "$src" "${license_names[$bin]}" "${descriptions[$bin]}" >"${src}/nfpm.yaml" if grep -q '@[A-Z_]*@' "${src}/nfpm.yaml"; then echo "unreplaced placeholder in the nfpm configuration of ${name}" >&2 exit 1 fi for packager in deb rpm; do echo "packaging ${bin} ${pkg_version} ${goarch} (${packager})" "$NFPM" package --config "${src}/nfpm.yaml" --packager "$packager" --target "$dist/" >/dev/null done done done ( cd "$dist" shopt -s nullglob sha256sum -- *.tar.gz *.deb *.rpm >SHA256SUMS ) echo "artefacts in ${dist}:" cat "${dist}/SHA256SUMS"