tar-payload.sh (1775B)
1 #!/bin/sh 2 ## tar-payload.sh — create a deterministic boot2 release archive. 3 ## 4 ## Usage: tools/release/tar-payload.sh <payload-dir> <output.tar.gz> 5 6 set -eu 7 8 PAYLOAD_ARG=${1:-} 9 OUTPUT_ARG=${2:-} 10 [ -d "$PAYLOAD_ARG" ] || { echo "tar-payload: missing payload dir: $PAYLOAD_ARG" >&2; exit 2; } 11 [ -n "$OUTPUT_ARG" ] || { echo "usage: $0 <payload-dir> <output.tar.gz>" >&2; exit 2; } 12 13 PAYLOAD_PARENT=$(cd "$(dirname "$PAYLOAD_ARG")" && pwd) 14 PAYLOAD_NAME=$(basename "$PAYLOAD_ARG") 15 PAYLOAD=$PAYLOAD_PARENT/$PAYLOAD_NAME 16 OUTPUT_PARENT=$(cd "$(dirname "$OUTPUT_ARG")" && pwd) 17 OUTPUT=$OUTPUT_PARENT/$(basename "$OUTPUT_ARG") 18 19 case "$OUTPUT" in 20 "$PAYLOAD"/*) 21 echo "tar-payload: output must not be inside payload: $OUTPUT" >&2 22 exit 2 23 ;; 24 esac 25 26 TAR_TMP=$OUTPUT_PARENT/.$(basename "$OUTPUT").tmp.tar 27 GZIP_TMP=$OUTPUT_PARENT/.$(basename "$OUTPUT").tmp.gz 28 DUPES=$OUTPUT_PARENT/.$(basename "$OUTPUT").entries.duplicate 29 cleanup() { rm -f "$TAR_TMP" "$GZIP_TMP" "$DUPES"; } 30 trap cleanup 0 1 2 15 31 32 # Normalize all archive metadata and ordering. The input list already 33 # contains every directory and file, so tar recursion must stay disabled. 34 find "$PAYLOAD" -exec touch -t 200001010000.00 {} + 35 ( 36 cd "$PAYLOAD_PARENT" 37 find "$PAYLOAD_NAME" -print0 | LC_ALL=C sort -z | \ 38 tar --null --no-recursion -T - \ 39 --uid 0 --gid 0 --uname '' --gname '' \ 40 --format ustar \ 41 -cf "$TAR_TMP" 42 ) 43 gzip -n -9 < "$TAR_TMP" > "$GZIP_TMP" 44 mv "$GZIP_TMP" "$OUTPUT" 45 46 # Reject recursive duplicates even if the tar command is changed later. 47 tar -tzf "$OUTPUT" | LC_ALL=C sort | uniq -d > "$DUPES" 48 if [ -s "$DUPES" ]; then 49 echo "tar-payload: duplicate archive entries:" >&2 50 sed 's/^/ /' "$DUPES" >&2 51 rm -f "$OUTPUT" 52 exit 1 53 fi