#!/usr/bin/env bash BANGER_PACKAGES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BANGER_APT_PACKAGES_FILE="${BANGER_APT_PACKAGES_FILE:-$BANGER_PACKAGES_DIR/packages.apt}" banger_packages_file() { printf '%s' "$BANGER_APT_PACKAGES_FILE" } banger_packages_normalized_lines() { local packages_file="${1:-$BANGER_APT_PACKAGES_FILE}" [[ -f "$packages_file" ]] || return 1 awk ' { sub(/\r$/, "") sub(/[[:space:]]*#.*$/, "") gsub(/^[[:space:]]+|[[:space:]]+$/, "") if ($0 != "") print } ' "$packages_file" } banger_packages_read_array() { local -n out="$1" local packages_file="${2:-$BANGER_APT_PACKAGES_FILE}" mapfile -t out < <(banger_packages_normalized_lines "$packages_file") (( ${#out[@]} > 0 )) } banger_packages_hash_stream() { command -v sha256sum >/dev/null 2>&1 || return 1 sha256sum | awk '{print $1}' } banger_packages_manifest_hash() { local packages_file="${1:-$BANGER_APT_PACKAGES_FILE}" [[ -f "$packages_file" ]] || return 1 banger_packages_normalized_lines "$packages_file" | banger_packages_hash_stream } banger_rootfs_manifest_metadata_path() { local rootfs_path="$1" printf '%s.packages.sha256' "$rootfs_path" } banger_rootfs_manifest_recorded_hash() { local rootfs_path="$1" local metadata_file recorded_hash metadata_file="$(banger_rootfs_manifest_metadata_path "$rootfs_path")" [[ -f "$metadata_file" ]] || return 1 recorded_hash="$(head -n 1 "$metadata_file" | tr -d '[:space:]')" [[ -n "$recorded_hash" ]] || return 1 printf '%s' "$recorded_hash" } banger_write_rootfs_manifest_metadata() { local rootfs_path="$1" local manifest_hash="$2" local metadata_file metadata_file="$(banger_rootfs_manifest_metadata_path "$rootfs_path")" printf '%s\n' "$manifest_hash" > "$metadata_file" } banger_rootfs_manifest_status() { local rootfs_path="$1" local current_hash recorded_hash if [[ ! -f "$rootfs_path" ]]; then printf '%s' "missing-rootfs" return 0 fi if ! current_hash="$(banger_packages_manifest_hash)"; then printf '%s' "unknown" return 0 fi if ! recorded_hash="$(banger_rootfs_manifest_recorded_hash "$rootfs_path")"; then printf '%s' "missing-metadata" return 0 fi if [[ "$recorded_hash" == "$current_hash" ]]; then printf '%s' "fresh" else printf '%s' "stale" fi } banger_rootfs_manifest_warning() { local rootfs_path="$1" local status status="$(banger_rootfs_manifest_status "$rootfs_path")" case "$status" in stale) printf '%s was built with an older package manifest; rebuild it explicitly to pick up package changes' "$rootfs_path" ;; missing-metadata) printf '%s has no package manifest metadata; rebuild it explicitly to pick up package changes' "$rootfs_path" ;; unknown) printf 'unable to compare %s against %s; install sha256sum and verify the package manifest manually' "$rootfs_path" "$BANGER_APT_PACKAGES_FILE" ;; *) return 1 ;; esac }