This is an automated email from the ASF dual-hosted git repository.

apurtell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix.git


The following commit(s) were added to refs/heads/master by this push:
     new 4e8472ce9b PHOENIX-7841 Harden the phoenix-vote script (#2458)
4e8472ce9b is described below

commit 4e8472ce9bd73ff79eb6e1187276b73966ef7bf7
Author: Andrew Purtell <[email protected]>
AuthorDate: Tue May 5 13:21:08 2026 -0700

    PHOENIX-7841 Harden the phoenix-vote script (#2458)
    
    Signed-off-by: Viraj Jasani <[email protected]>
---
 dev/phoenix-vote.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 60 insertions(+), 12 deletions(-)

diff --git a/dev/phoenix-vote.sh b/dev/phoenix-vote.sh
index 8a45eaaea1..4f1ff79983 100755
--- a/dev/phoenix-vote.sh
+++ b/dev/phoenix-vote.sh
@@ -77,16 +77,29 @@ operator may still consider to verify the following manually
 3. Other concerns if any
 __EOF
 
+if ! command -v wget >/dev/null 2>&1; then
+    echo "ERROR: wget is required but was not found on PATH."
+    echo "       On macOS install with: brew install wget"
+    exit 1
+fi
+
 [[ "${SOURCE_URL}" != */ ]] && SOURCE_URL="${SOURCE_URL}/"
-PHOENIX_RC_VERSION=$(tr "/" "\n" <<< "${SOURCE_URL}" | tail -n2)
-PHOENIX_VERSION=$(echo "${PHOENIX_RC_VERSION}" | sed -e 's/RC[0-9]//g' | sed 
-e 's/phoenix-//g')
+# Extract the trailing path component without depending on a fixed number of 
path segments.
+PHOENIX_RC_VERSION=$(echo "${SOURCE_URL}" | sed -E 's|/+$||' | awk -F/ '{ 
print $NF }')
+PHOENIX_VERSION=$(echo "${PHOENIX_RC_VERSION}" | sed -E 's/RC[0-9]+//' | sed 
-e 's/phoenix-//')
+# Number of path components above the RC directory; wget --cut-dirs needs this
+# to drop the leading host-relative path so files land under 
./${PHOENIX_RC_VERSION}/.
+URL_PATH=$(echo "${SOURCE_URL}" | sed -E 's|^https?://[^/]+/||; s|/+$||')
+WGET_CUT_DIRS=$(echo "${URL_PATH%/*}" | tr -cd '/' | wc -c | tr -d ' ')
+WGET_CUT_DIRS=$((WGET_CUT_DIRS + 1))
 JAVA_VERSION=$(java -version 2>&1 | cut -f3 -d' ' | head -n1 | sed -e 's/"//g')
 OUTPUT_DIR="${OUTPUT_DIR:-$(pwd)}"
 
-if [ ! -d "${OUTPUT_DIR}" ]; then
-    echo "Output directory ${OUTPUT_DIR} does not exist, please create it 
before running this script."
-    exit 1
-fi
+# Create the output dir if it doesn't exist, then resolve to an absolute path 
so
+# logs and downloaded artifacts stay together regardless of CWD.
+mkdir -p "${OUTPUT_DIR}"
+OUTPUT_DIR="$(cd "${OUTPUT_DIR}" && pwd)"
+cd "${OUTPUT_DIR}"
 
 OUTPUT_PATH_PREFIX="${OUTPUT_DIR}"/"${PHOENIX_RC_VERSION}"
 
@@ -109,24 +122,59 @@ function download_and_import_keys() {
 }
 
 function download_release_candidate () {
-    # get all files from release candidate repo
-    wget -r -np -N -nH --cut-dirs 4 "${SOURCE_URL}"
+    # dist.apache.org's robots.txt disallows /repos/, so wget would otherwise
+    # stop after fetching the directory index. -e robots=off lets it follow the
+    # links to the artifacts. -A scopes the recursion to release files only.
+    wget -r -np -N -nH \
+        -e robots=off \
+        -A 
"*.tar.gz,*.tar.gz.asc,*.tar.gz.sha512,*.tar.gz.sha256,CHANGES.md,RELEASENOTES.md"
 \
+        --cut-dirs "${WGET_CUT_DIRS}" "${SOURCE_URL}"
+    if ! ls "${PHOENIX_RC_VERSION}"/*.tar.gz >/dev/null 2>&1; then
+        echo "ERROR: no .tar.gz files were downloaded under 
${OUTPUT_DIR}/${PHOENIX_RC_VERSION}/."
+        echo "       Check that ${SOURCE_URL} is a valid release candidate 
URL."
+        exit 1
+    fi
 }
 
 function verify_signatures() {
     rm -f "${OUTPUT_PATH_PREFIX}"_verify_signatures
+    SIGNATURE_PASSED=1
     for file in *.tar.gz; do
-        gpg --verify "${file}".asc "${file}" 2>&1 | tee -a 
"${OUTPUT_PATH_PREFIX}"_verify_signatures && SIGNATURE_PASSED=1 || 
SIGNATURE_PASSED=0
+        if ! gpg --verify "${file}".asc "${file}" 2>&1 | tee -a 
"${OUTPUT_PATH_PREFIX}"_verify_signatures; then
+            SIGNATURE_PASSED=0
+        fi
     done
 }
 
+function _sha512_hex() {
+    # Pull just the lowercase hex digest out of a `gpg --print-md SHA512`
+    # output (or a Phoenix .sha512 file produced by the same tool). The file
+    # is wrapped across N lines and the wrap width can differ between gpg
+    # versions, so we strip the leading "<filename>: " prefix on line 1 and
+    # then drop all whitespace before lower-casing.
+    sed -e '1s/^[^:]*: //' "$1" | tr -d '[:space:]' | tr 'A-F' 'a-f'
+}
+
 function verify_checksums() {
     rm -f "${OUTPUT_PATH_PREFIX}"_verify_checksums
     SHA_EXT=$(find . -name "*.sha*" | awk -F '.' '{ print $NF }' | head -n 1)
+    CHECKSUM_PASSED=1
     for file in *.tar.gz; do
-        gpg --print-md SHA512 "${file}" > "${file}"."${SHA_EXT}".tmp
-        diff "${file}"."${SHA_EXT}".tmp "${file}"."${SHA_EXT}" 2>&1 | tee -a 
"${OUTPUT_PATH_PREFIX}"_verify_checksums && CHECKSUM_PASSED=1 || 
CHECKSUM_PASSED=0
-        rm -f "${file}"."${SHA_EXT}".tmp
+        local_tmp="${file}.${SHA_EXT}.tmp"
+        gpg --print-md SHA512 "${file}" > "${local_tmp}"
+        local_hex=$(_sha512_hex "${local_tmp}")
+        dist_hex=$(_sha512_hex "${file}.${SHA_EXT}")
+        rm -f "${local_tmp}"
+        if [ -n "${local_hex}" ] && [ "${local_hex}" = "${dist_hex}" ]; then
+            echo "${file}: SHA512 OK" | tee -a 
"${OUTPUT_PATH_PREFIX}"_verify_checksums
+        else
+            {
+                echo "${file}: SHA512 MISMATCH"
+                echo "  expected: ${dist_hex}"
+                echo "  actual:   ${local_hex}"
+            } | tee -a "${OUTPUT_PATH_PREFIX}"_verify_checksums
+            CHECKSUM_PASSED=0
+        fi
     done
 }
 

Reply via email to