aboutsummaryrefslogtreecommitdiff
path: root/contrib/guix/guix-attest
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/guix/guix-attest')
-rwxr-xr-xcontrib/guix/guix-attest169
1 files changed, 101 insertions, 68 deletions
diff --git a/contrib/guix/guix-attest b/contrib/guix/guix-attest
index 081d1c0465..c8cf73d400 100755
--- a/contrib/guix/guix-attest
+++ b/contrib/guix/guix-attest
@@ -99,24 +99,34 @@ fi
# We should be able to find at least one output
################
-echo "Looking for build output directories in ${OUTDIR_BASE}"
+echo "Looking for build output SHA256SUMS fragments in ${OUTDIR_BASE}"
shopt -s nullglob
-OUTDIRS=( "${OUTDIR_BASE}"/* ) # This expands to an array of directories...
+sha256sum_fragments=( "$OUTDIR_BASE"/*/SHA256SUMS.part ) # This expands to an array of directories...
shopt -u nullglob
-if (( ${#OUTDIRS[@]} )); then
- echo "Found build output directories:"
- for outdir in "${OUTDIRS[@]}"; do
+noncodesigned_fragments=()
+codesigned_fragments=()
+
+if (( ${#sha256sum_fragments[@]} )); then
+ echo "Found build output SHA256SUMS fragments:"
+ for outdir in "${sha256sum_fragments[@]}"; do
echo " '$outdir'"
+ case "$outdir" in
+ "$OUTDIR_BASE"/*-codesigned/SHA256SUMS.part)
+ codesigned_fragments+=("$outdir")
+ ;;
+ *)
+ noncodesigned_fragments+=("$outdir")
+ ;;
+ esac
done
echo
else
- echo "ERR: Could not find any build output directories in ${OUTDIR_BASE}"
+ echo "ERR: Could not find any build output SHA256SUMS fragments in ${OUTDIR_BASE}"
exit 1
fi
-
##############
## Attest ##
##############
@@ -126,82 +136,105 @@ fi
# HOST: The output directory being attested
#
out_name() {
- basename "$1"
+ basename "$(dirname "$1")"
}
-# Usage: out_sig_dir $outdir
-#
-# outdir: The output directory being attested
-#
-out_sig_dir() {
- echo "$GUIX_SIGS_REPO/$VERSION/$(out_name "$1")/$signer_name"
-}
+shasum_already_exists() {
+cat <<EOF
+--
-# Accumulate a list of signature directories that already exist...
-outdirs_already_attested_to=()
+ERR: An ${1} file already exists for '${VERSION}' and attests
+ differently. You likely previously attested to a partial build (e.g. one
+ where you specified the HOST environment variable).
-echo "Attesting to build outputs for version: '${VERSION}'"
-echo ""
+ See the diff above for more context.
-# MAIN LOGIC: Loop through each output for VERSION and attest to output in
-# GUIX_SIGS_REPO as SIGNER, if attestation does not exist
-for outdir in "${OUTDIRS[@]}"; do
- if [ -e "${outdir}/SKIPATTEST.TAG" ]; then
- echo "${outname}: SKIPPING: Output directory marked with SKIPATTEST.TAG file"
- continue
- fi
- outname="$(out_name "$outdir")"
- outsigdir="$(out_sig_dir "$outdir")"
- if [ -e "$outsigdir" ]; then
- echo "${outname}: SKIPPING: Signature directory already exists in the specified guix.sigs repository"
- outdirs_already_attested_to+=("$outdir")
- else
- # Clean up incomplete sigdir if something fails (likely gpg)
- trap 'rm -rf "$outsigdir"' ERR
+Hint: You may wish to remove the existing attestations and their signatures by
+ invoking:
- mkdir -p "$outsigdir"
+ rm '${PWD}/${1}'{,.asc}
- (
- cd "$outdir"
+ Then try running this script again.
- if [ -e inputs.SHA256SUMS ]; then
- echo "${outname}: Including existent input SHA256SUMS"
- cat inputs.SHA256SUMS >> "$outsigdir"/SHA256SUMS
- fi
+EOF
+}
- echo "${outname}: Hashing build outputs to produce SHA256SUMS"
- files="$(find -L . -type f ! -iname '*.SHA256SUMS')"
- if [ -n "$files" ]; then
- cut -c3- <<< "$files" | env LC_ALL=C sort | xargs sha256sum >> "$outsigdir"/SHA256SUMS
+echo "Attesting to build outputs for version: '${VERSION}'"
+echo ""
+
+outsigdir="$GUIX_SIGS_REPO/$VERSION/$signer_name"
+mkdir -p "$outsigdir"
+(
+ cd "$outsigdir"
+
+ temp_noncodesigned="$(mktemp)"
+ trap 'rm -rf -- "$temp_noncodesigned"' EXIT
+
+ if (( ${#noncodesigned_fragments[@]} )); then
+ cat "${noncodesigned_fragments[@]}" \
+ | sort -u \
+ | sort -k2 \
+ > "$temp_noncodesigned"
+ if [ -e noncodesigned.SHA256SUMS ]; then
+ # The SHA256SUMS already exists, make sure it's exactly what we
+ # expect, error out if not
+ if diff -u noncodesigned.SHA256SUMS "$temp_noncodesigned"; then
+ echo "A noncodesigned.SHA256SUMS file already exists for '${VERSION}' and is up-to-date."
else
- echo "ERR: ${outname}: No outputs found in '${outdir}'"
+ shasum_already_exists noncodesigned.SHA256SUMS
exit 1
fi
- )
- if [ -z "$NO_SIGN" ]; then
- echo "${outname}: Signing SHA256SUMS to produce SHA256SUMS.asc"
- gpg --detach-sign --local-user "$gpg_key_name" --armor --output "$outsigdir"/SHA256SUMS.asc "$outsigdir"/SHA256SUMS
else
- echo "${outname}: Not signing SHA256SUMS as \$NO_SIGN is not empty"
+ mv "$temp_noncodesigned" noncodesigned.SHA256SUMS
fi
- echo ""
-
- trap - ERR # Reset ERR trap
+ else
+ echo "ERR: No noncodesigned outputs found for '${VERSION}', exiting..."
+ exit 1
fi
-done
-
-if (( ${#outdirs_already_attested_to[@]} )); then
-# ...so that we can print them out nicely in a warning message
-cat << EOF
-WARN: Signature directories from '$signer_name' already exist in the specified
- guix.sigs repository for the following output directories and were
- skipped:
+ temp_codesigned="$(mktemp)"
+ trap 'rm -rf -- "$temp_codesigned"' EXIT
+
+ if (( ${#codesigned_fragments[@]} )); then
+ # Note: all.SHA256SUMS attests to all of $sha256sum_fragments, but is
+ # not needed if there are no $codesigned_fragments
+ cat "${sha256sum_fragments[@]}" \
+ | sort -u \
+ | sort -k2 \
+ > "$temp_codesigned"
+ if [ -e codesigned.SHA256SUMS ]; then
+ # The SHA256SUMS already exists, make sure it's exactly what we
+ # expect, error out if not
+ if diff -u all.SHA256SUMS "$temp_codesigned"; then
+ echo "An all.SHA256SUMS file already exists for '${VERSION}' and is up-to-date."
+ else
+ shasum_already_exists all.SHA256SUMS
+ exit 1
+ fi
+ else
+ mv "$temp_codesigned" codesigned.SHA256SUMS
+ fi
+ else
+ # It is fine to have the codesigned outputs be missing (perhaps the
+ # detached codesigs have not been published yet), just print a log
+ # message instead of erroring out
+ echo "INFO: No codesigned outputs found for '${VERSION}', skipping..."
+ fi
-EOF
-for outdir in "${outdirs_already_attested_to[@]}"; do
- echo " '${outdir}'"
- echo " Corresponds to: '$(out_sig_dir "$outdir")'"
+ if [ -z "$NO_SIGN" ]; then
+ echo "Signing SHA256SUMS to produce SHA256SUMS.asc"
+ for i in *.SHA256SUMS; do
+ if [ ! -e "$i".asc ]; then
+ gpg --detach-sign \
+ --local-user "$gpg_key_name" \
+ --armor \
+ --output "$i".asc "$i"
+ else
+ echo "Signature already there"
+ fi
+ done
+ else
+ echo "Not signing SHA256SUMS as \$NO_SIGN is not empty"
+ fi
echo ""
-done
-fi
+)