diff --git a/GNUmakefile b/GNUmakefile index 1a89de1620..5df83416b9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -79,11 +79,14 @@ PUB_GIT_ARG= endif ifeq ($(PUB_WEBSITE),1) -PUB_WEBSITE_ARG=-g +PUB_WEBSITE_ARG=-w else PUB_WEBSITE_ARG= endif +NOGOX?=1 + +export NOGOX export GO_BUILD_TAG export UI_BUILD_TAG export UI_LEGACY_BUILD_TAG @@ -94,10 +97,19 @@ export GIT_DESCRIBE export GOTAGS export GOLDFLAGS + +DEV_PUSH?=0 +ifeq ($(DEV_PUSH),1) +DEV_PUSH_ARG= +else +DEV_PUSH_ARG=--no-push +endif + # all builds binaries for all targets all: bin -bin: tools dev-build +bin: tools + @$(SHELL) $(CURDIR)/build-support/scripts/build-local.sh # dev creates binaries for testing locally - these are put into ./bin and $GOPATH dev: changelogfmt vendorfmt dev-build @@ -124,12 +136,15 @@ linux: # dist builds binaries for all platforms and packages them for distribution dist: @$(SHELL) $(CURDIR)/build-support/scripts/release.sh -t '$(DIST_TAG)' -b '$(DIST_BUILD)' -S '$(DIST_SIGN)' $(DIST_VERSION_ARG) $(DIST_DATE_ARG) $(DIST_REL_ARG) - + +verify: + @$(SHELL) $(CURDIR)/build-support/scripts/verify.sh + publish: @$(SHELL) $(CURDIR)/build-support/scripts/publish.sh $(PUB_GIT_ARG) $(PUB_WEBSITE_ARG) dev-tree: - @$(SHELL) $(CURDIR)/build-support/scripts/dev.sh + @$(SHELL) $(CURDIR)/build-support/scripts/dev.sh $(DEV_PUSH_ARG) cov: gocov test $(GOFILES) | gocov-html > /tmp/coverage.html diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index 1de0b949fb..1d0dfd1eae 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -919,3 +919,23 @@ function shasum_directory { return $ret } + + function ui_version { + # Arguments: + # $1 - path to index.html + # + # Returns: + # 0 - success + # * -failure + # + # Notes: echoes the version to stdout upon success + if ! test -f "$1" + then + err "ERROR: No such file: '$1'" + return 1 + fi + + local ui_version=$(sed -n ${SED_EXT} -e 's/.*CONSUL_VERSION%22%3A%22([^%]*)%22%2C%22.*/\1/p' < "$1") || return 1 + echo "$ui_version" + return 0 + } diff --git a/build-support/functions/20-build.sh b/build-support/functions/20-build.sh index 6297ead7f1..4118a654c5 100644 --- a/build-support/functions/20-build.sh +++ b/build-support/functions/20-build.sh @@ -26,6 +26,7 @@ function build_ui { # Arguments: # $1 - Path to the top level Consul source # $2 - The docker image to run the build within (optional) + # $3 - Version override # # Returns: # 0 - success @@ -52,6 +53,11 @@ function build_ui { # parse the version version=$(parse_version "${sdir}") + if test -n "$3" + then + version="$3" + fi + local commit_hash="${GIT_COMMIT}" if test -z "${commit_hash}" then @@ -61,7 +67,7 @@ function build_ui { # make sure we run within the ui dir pushd ${ui_dir} > /dev/null - status "Creating the UI Build Container with image: ${image_name}" + status "Creating the UI Build Container with image: ${image_name} and version '${version}'" local container_id=$(docker create -it -e "CONSUL_GIT_SHA=${commit_hash}" -e "CONSUL_VERSION=${version}" ${image_name}) local ret=$? if test $ret -eq 0 @@ -79,9 +85,18 @@ function build_ui { if test ${ret} -eq 0 then - rm -rf ${1}/pkg/web_ui/v2 - cp -r ${1}/ui-v2/dist ${1}/pkg/web_ui/v2 + local ui_vers=$(ui_version "${1}/ui-v2/dist/index.html") + if test "${version}" != "${ui_vers}" + then + err "ERROR: UI version mismatch. Expecting: '${version}' found '${ui_vers}'" + ret=1 + else + rm -rf ${1}/pkg/web_ui/v2 + mkdir -p ${1}/pkg/web_ui + cp -r ${1}/ui-v2/dist ${1}/pkg/web_ui/v2 + fi fi + popd > /dev/null return $ret } @@ -409,13 +424,20 @@ function build_consul_local { do outdir="pkg.bin.new/${extra_dir}${os}_${arch}" osarch="${os}/${arch}" - if test "${osarch}" == "darwin/arm" -o "${osarch}" == "darwin/arm64" + if test "${osarch}" == "darwin/arm" -o "${osarch}" == "darwin/arm64" -o "${osarch}" == "freebsd/arm64" -o "${osarch}" == "windows/arm" -o "${osarch}" == "windows/arm64" then continue fi + if test "${os}" == "solaris" -a "${arch}" != "amd64" + then + continue + fi + + echo "---> ${osarch}" + mkdir -p "${outdir}" - GOOS=${os} GOARCH=${arch} go install -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}" && cp "${MAIN_GOPATH}/bin/consul" "${outdir}/consul" + CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go install -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}" && cp "${MAIN_GOPATH}/bin/consul" "${outdir}/consul" if test $? -ne 0 then err "ERROR: Failed to build Consul for ${osarch}" diff --git a/build-support/functions/30-release.sh b/build-support/functions/30-release.sh index 8021d73f1b..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 } @@ -448,12 +467,14 @@ function build_release { fi status_stage "==> Building UI for version ${vers}" - build_ui "${sdir}" "${UI_BUILD_TAG}" + # passing the version to override the version determined via tags + build_ui "${sdir}" "${UI_BUILD_TAG}" "${vers}" if test $? -ne 0 then 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/build-docker.sh b/build-support/scripts/build-docker.sh index d741ef243c..9a8453f29c 100755 --- a/build-support/scripts/build-docker.sh +++ b/build-support/scripts/build-docker.sh @@ -128,6 +128,7 @@ function main { fi status_stage "==> Building UI" build_ui "${sdir}" "${image}" || return 1 + status "==> UI Built with Version: $(ui_version ${sdir}/pkg/web_ui/v2/index.html)" ;; ui-legacy ) if is_set "${refresh}" @@ -149,4 +150,4 @@ function main { } main "$@" -exit $? \ No newline at end of file +exit $? diff --git a/build-support/scripts/dev.sh b/build-support/scripts/dev.sh index 222002d993..12a2e88492 100755 --- a/build-support/scripts/dev.sh +++ b/build-support/scripts/dev.sh @@ -43,6 +43,7 @@ function main { declare build_os="" declare build_arch="" declare -i do_git=1 + declare -i do_push=1 while test $# -gt 0 @@ -72,6 +73,10 @@ function main { do_git=0 shift ;; + --no-push ) + do_push=0 + shift + ;; * ) err_usage "ERROR: Unknown argument: '$1'" return 1 @@ -86,11 +91,14 @@ function main { status_stage "==> Commiting Dev Mode Changes" commit_dev_mode "${sdir}" || return 1 - status_stage "==> Confirming Git Changes" - confirm_git_push_changes "${sdir}" || return 1 - - status_stage "==> Pushing to Git" - git_push_ref "${sdir}" || return 1 + if is_set "${do_push}" + then + status_stage "==> Confirming Git Changes" + confirm_git_push_changes "${sdir}" || return 1 + + status_stage "==> Pushing to Git" + git_push_ref "${sdir}" || return 1 + fi fi return 0 diff --git a/build-support/scripts/verify.sh b/build-support/scripts/verify.sh new file mode 100755 index 0000000000..c1678bd1a3 --- /dev/null +++ b/build-support/scripts/verify.sh @@ -0,0 +1,96 @@ +#!/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="" + + 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 + + if test -z "${vers}" + then + vers=$(parse_version "${sdir}" true false) + fi + + 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