From c8f706a1417fe9adbcaaa031c724cc826bf15427 Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Tue, 26 Jun 2018 11:33:26 -0400 Subject: [PATCH] Added release verification script Also implemented shasum verification and gpg signature verification --- build-support/functions/30-release.sh | 22 +++++- build-support/functions/40-publish.sh | 98 +++++++++++++++++++++++---- build-support/scripts/verify.sh | 91 +++++++++++++++++++++++++ 3 files changed, 197 insertions(+), 14 deletions(-) create mode 100644 build-support/scripts/verify.sh diff --git a/build-support/functions/30-release.sh b/build-support/functions/30-release.sh index f2940b7930..9679bcd07c 100644 --- a/build-support/functions/30-release.sh +++ b/build-support/functions/30-release.sh @@ -301,7 +301,6 @@ function check_release_one { ret=1 fi done - popd > /dev/null for fname in "${expected_files[@]}" do @@ -309,6 +308,24 @@ function check_release_one { ret=1 done + if test $ret -eq 0 + then + if ! shasum -c -s "${CONSUL_PKG_NAME}_${2}_SHA256SUMS" + then + err "ERROR: Failed SHA-256 hash verification" + shasum -c "${CONSUL_PKG_NAME}_${2}_SHA256SUMS" + ret=1 + fi + fi + + if test $ret -eq 0 && is_set "${3}" + then + if ! gpg --verify "${CONSUL_PKG_NAME}_${2}_SHA256SUMS.sig" "${CONSUL_PKG_NAME}_${2}_SHA256SUMS" > /dev/null 2>&1 + then + err "ERROR: Failed GPG verification of SHA256SUMS signature" + ret=1 + fi + fi if test $ret -eq 0 then @@ -319,6 +336,8 @@ function check_release_one { done fi + popd > /dev/null + return $ret } @@ -455,6 +474,7 @@ function build_release { err "ERROR: Failed to build the ui" return 1 fi + status "UI Built with Version: $(ui_version "${sdir}/pkg/web_ui/v2/index.html")" status_stage "==> Building Static Assets for version ${vers}" build_assetfs "${sdir}" "${GO_BUILD_TAG}" diff --git a/build-support/functions/40-publish.sh b/build-support/functions/40-publish.sh index ffb8e64bf9..c2fd062ad3 100644 --- a/build-support/functions/40-publish.sh +++ b/build-support/functions/40-publish.sh @@ -251,6 +251,47 @@ function confirm_consul_info { done fi + if test "${ret}" -eq 0 + then + local tfile="$(mktemp) -t "${CONSUL_PKG_NAME}_")" + if ! curl -o "${tfile}" "http://localhost:8500/ui/" + then + err "ERROR: Failed to curl http://localhost:8500/ui/" + return 1 + fi + + local ui_vers=$(ui_version "${tfile}") + if test $? -ne 0 + then + err "ERROR: Failed to determine the ui version from the index.html file" + return 1 + fi + + status "UI Version: ${ui_vers}" + echo "" + local answer="" + + while true + do + case "${answer}" in + [yY]* ) + status "Consul UI Version Accepted" + break + ;; + [nN]* ) + err "Consul UI Version Rejected" + return 1 + break + ;; + * ) + read -p "Is this Consul UI Version correct? [y/n]: " answer + ;; + esac + done + fi + + + status "Requesting Consul to leave the cluster / shutdown" "${consul_exe}" leave wait ${consul_pid} > /dev/null 2>&1 @@ -262,6 +303,49 @@ function extract_consul { extract_consul_local "$1" "$2" } +function verify_release_build { + # Arguments: + # $1 - Path to top level Consul source + # $2 - expected version (optional - will parse if empty) + # + # Returns: + # 0 - success + # * - failure + + if ! test -d "$1" + then + err "ERROR: '$1' is not a directory. publish_release must be called with the path to the top level source as the first argument'" + return 1 + fi + + local sdir="$1" + + local vers="$(get_version ${sdir} true false)" + if test -n "$2" + then + vers="$2" + fi + + if test -z "${vers}" + then + err "Please specify a version (couldn't parse one from the source)." + return 1 + fi + + status_stage "==> Verifying release files" + check_release "${sdir}/pkg/dist" "${vers}" true || return 1 + + status_stage "==> Extracting Consul version for local system" + local consul_exe=$(extract_consul "${sdir}/pkg/dist" "${vers}") || return 1 + # make sure to remove the temp file + trap "rm '${consul_exe}'" EXIT + + status_stage "==> Confirming Consul Version" + confirm_consul_version "${consul_exe}" || return 1 + + status_stage "==> Confirming Consul Agent Info" + confirm_consul_info "${consul_exe}" || return 1 +} function publish_release { # Arguments: @@ -300,19 +384,7 @@ function publish_release { return 1 fi - status_stage "==> Verifying release files" - check_release "${sdir}/pkg/dist" "${vers}" true || return 1 - - status_stage "==> Extracting Consul version for local system" - local consul_exe=$(extract_consul "${sdir}/pkg/dist" "${vers}") || return 1 - # make sure to remove the temp file - trap "rm '${consul_exe}'" EXIT - - status_stage "==> Confirming Consul Version" - confirm_consul_version "${consul_exe}" || return 1 - - status_stage "==> Confirming Consul Agent Info" - confirm_consul_info "${consul_exe}" || return 1 + verify_release_build "$1" "${vers}" || return 1 status_stage "==> Confirming Git is clean" is_git_clean "$1" true || return 1 diff --git a/build-support/scripts/verify.sh b/build-support/scripts/verify.sh new file mode 100644 index 0000000000..e137aec052 --- /dev/null +++ b/build-support/scripts/verify.sh @@ -0,0 +1,91 @@ +#!/bin/bash +SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" +pushd $(dirname ${BASH_SOURCE[0]}) > /dev/null +SCRIPT_DIR=$(pwd) +pushd ../.. > /dev/null +SOURCE_DIR=$(pwd) +popd > /dev/null +pushd ../functions > /dev/null +FN_DIR=$(pwd) +popd > /dev/null +popd > /dev/null + +source "${SCRIPT_DIR}/functions.sh" + +function usage { +cat <<-EOF +Usage: ${SCRIPT_NAME} [] + +Description: + + This script will verify a Consul release build. It will check for prebuilt + files, verify shasums and gpg signatures as well as run some commands + and prompt for manual verification where required. + +Options: + -s | --source DIR Path to source to build. + Defaults to "${SOURCE_DIR}" + + -h | --help Print this help text. +EOF +} + +function err_usage { + err "$1" + err "" + err "$(usage)" +} + +function main { + declare sdir="${SOURCE_DIR}" + declare vers="$(parse_version true false)" + + while test $# -gt 0 + do + case "$1" in + -h | --help ) + usage + return 0 + ;; + -s | --source ) + if test -z "$2" + then + err_usage "ERROR: option -s/--source requires an argument" + return 1 + fi + + if ! test -d "$2" + then + err_usage "ERROR: '$2' is not a directory and not suitable for the value of -s/--source" + return 1 + fi + + sdir="$2" + shift 2 + ;; + -v | --version ) + if test -z "$2" + then + err_usage "ERROR: option -v/--version requires an argument" + return 1 + fi + + vers="$2" + shift 2 + ;; + *) + err_usage "ERROR: Unknown argument: '$1'" + return 1 + ;; + esac + done + + status_stage "=> Starting release verification for version: ${version}" + verify_release_build "${sdir}" "${vers}" || return 1 + + return 0 +} + +main "$@" +exit $? + \ No newline at end of file