From b35e7493051479d38cdf3912f2e9170825bfce51 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Fri, 18 Mar 2022 09:55:12 -0700 Subject: [PATCH 01/14] Add BuildDate to version structure Signed-off-by: Mark Anderson --- GNUmakefile | 4 +++- command/agent/agent.go | 9 +++++++++ version/version.go | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 069a7bc2f0..6bc619e5cc 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -25,7 +25,9 @@ GIT_COMMIT?=$(shell git rev-parse --short HEAD) GIT_COMMIT_YEAR?=$(shell git show -s --format=%cd --date=format:%Y HEAD) GIT_DIRTY?=$(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true) GIT_IMPORT=github.com/hashicorp/consul/version -GOLDFLAGS=-X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT)$(GIT_DIRTY) +DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ" # it's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC +GIT_DATE=$(shell git show -s --format=%cd --date=format:"$(DATE_FORMAT)" HEAD) # we're using this for build date because it's stable across platform builds +GOLDFLAGS=-X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT)$(GIT_DIRTY) -X $(GIT_IMPORT).BuildDate=$(GIT_DATE) ifeq ($(FORCE_REBUILD),1) NOCACHE=--no-cache diff --git a/command/agent/agent.go b/command/agent/agent.go index 2167ba63b9..3bef84b0a8 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -27,12 +27,19 @@ import ( ) func New(ui cli.Ui) *cmd { + buildDate, err := time.Parse(time.RFC3339, consulversion.BuildDate) + if err != nil { + ui.Error(fmt.Sprintf("Fatal error with internal time set; check makefile for build date %v %v \n", buildDate, err)) + return nil + } + c := &cmd{ ui: ui, revision: consulversion.GitCommit, version: consulversion.Version, versionPrerelease: consulversion.VersionPrerelease, versionHuman: consulversion.GetHumanVersion(), + buildDate: buildDate, flags: flag.NewFlagSet("", flag.ContinueOnError), } config.AddFlags(c.flags, &c.configLoadOpts) @@ -53,6 +60,7 @@ type cmd struct { version string versionPrerelease string versionHuman string + buildDate time.Time configLoadOpts config.LoadOpts logger hclog.InterceptLogger } @@ -194,6 +202,7 @@ func (c *cmd) run(args []string) int { segment = "" } ui.Info(fmt.Sprintf(" Version: '%s'", c.versionHuman)) + ui.Info(fmt.Sprintf(" Build Date: %s", c.buildDate)) ui.Info(fmt.Sprintf(" Node ID: '%s'", config.NodeID)) ui.Info(fmt.Sprintf(" Node name: '%s'", config.NodeName)) if ap := config.PartitionOrEmpty(); ap != "" { diff --git a/version/version.go b/version/version.go index e7d187bfde..4ce586e77a 100644 --- a/version/version.go +++ b/version/version.go @@ -23,6 +23,9 @@ var ( // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. VersionPrerelease = "dev" + + // The date/time of the build + BuildDate string ) // GetHumanVersion composes the parts of the version in a way that's suitable From d8663a741dc469d265c9d71f08ec25af1b21400e Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Wed, 23 Mar 2022 18:26:42 -0700 Subject: [PATCH 02/14] Fixup build scripts Signed-off-by: Mark Anderson --- .circleci/bash_env.sh | 3 +- .github/workflows/build.yml | 7 ++- build-support/functions/10-util.sh | 39 ++++++++++++++- build-support/scripts/build-date.sh | 78 +++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 3 deletions(-) create mode 100755 build-support/scripts/build-date.sh diff --git a/.circleci/bash_env.sh b/.circleci/bash_env.sh index 8e19111654..f644a8b390 100644 --- a/.circleci/bash_env.sh +++ b/.circleci/bash_env.sh @@ -4,4 +4,5 @@ export GIT_COMMIT=$(git rev-parse --short HEAD) export GIT_COMMIT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) export GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true) export GIT_IMPORT=github.com/hashicorp/consul/version -export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY}" +export GIT_DATE=$("${CIRCLE_WORKING_DIRECTORY}/build-support/scripts/build-date.sh") # we're using this for build date because it's stable across platform builds +export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X $(GIT_IMPORT).BuildDate=$(GIT_DATE)" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb0e6ee075..654fb7c960 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,7 @@ jobs: runs-on: ubuntu-latest outputs: product-version: ${{ steps.get-product-version.outputs.product-version }} + product-date: ${{ steps.get-product-version.outputs.product-date }} pre-version: ${{ steps.get-product-version.outputs.pre-version }} pkg-version: ${{ steps.get-product-version.outputs.pkg-version }} shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }} @@ -24,6 +25,7 @@ jobs: id: get-product-version run: | CONSUL_VERSION=$(build-support/scripts/version.sh -r) + CONSUL_DATE=$(build-support/scripts/build-date.sh -r) ## TODO: This assumes `make version` outputs 1.1.1+ent-prerel IFS="+" read VERSION _other <<< "$CONSUL_VERSION" IFS="-" read _other PREREL_VERSION <<< "$CONSUL_VERSION" @@ -32,12 +34,15 @@ jobs: ## [version]{-prerelease}+ent before then, we'll need to add ## logic to handle presense/absence of the prerelease echo "::set-output name=product-version::${CONSUL_VERSION}" + echo "::set-output name=product-date::${CONSUL_DATE}" echo "::set-output name=pre-version::${PREREL_VERSION}" echo "::set-output name=pkg-version::${VERSION}" - name: Set shared -ldflags id: shared-ldflags - run: echo "::set-output name=shared-ldflags::-X github.com/hashicorp/consul/version.GitCommit=${GITHUB_SHA::8} -X github.com/hashicorp/consul/version.GitDescribe=${{ steps.get-product-version.outputs.product-version }}" + run: | + T="github.com/hashicorp/consul/version" + echo "::set-output name=shared-ldflags::-X ${T}.GitCommit=${GITHUB_SHA::8} -X ${T}.GitDescribe=${{ steps.get-product-version.outputs.product-version }} -X ${T}.BuildDate=${{ steps.get-product-version.outputs.product-date }}" generate-metadata-file: needs: get-product-version diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index 6a5f7282d1..e9a6837bab 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -274,6 +274,42 @@ function git_branch { return ${ret} } + +function git_date { + # Arguments: + # $1 - Path to the git repo (optional - assumes pwd is git repo otherwise) + # + # Returns: + # 0 - success + # * - failure + # + # Notes: + # Echos the date of the last git commit in + + local gdir="$(pwd)" + if test -d "$1" + then + gdir="$1" + fi + + pushd "${gdir}" > /dev/null + + local ret=0 + + # it's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC + local date_format="%Y-%m-%dT%H:%M:%SZ" + # we're using this for build date because it's stable across platform builds + local date=$(git show -s --format=%cd --date=format:"$date_format" HEAD) + + ##local head="$(git status -b --porcelain=v2 | awk '{if ($1 == "#" && $2 =="branch.head") { print $3 }}')" || ret=1 + + popd > /dev/null + + test ${ret} -eq 0 && echo "$date" + return ${ret} +} + + function is_git_clean { # Arguments: # $1 - Path to git repo @@ -325,7 +361,8 @@ function update_git_env { export GIT_COMMIT=$(git rev-parse --short HEAD) export GIT_DIRTY=$(test -n "$(git status --porcelain)" && echo "+CHANGES") export GIT_IMPORT=github.com/hashicorp/consul/version - export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY}" + export GIT_DATE=$(git_date "$1") + export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X ${T}.BuildDate=${GIT_DATE}" return 0 } diff --git a/build-support/scripts/build-date.sh b/build-support/scripts/build-date.sh new file mode 100755 index 0000000000..54b02fced7 --- /dev/null +++ b/build-support/scripts/build-date.sh @@ -0,0 +1,78 @@ +#!/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 uses the date of the last checkin on the branch as the build date. This + is to make the date consistent across the various platforms we build on, even if they + start at different times. In practice this is the commit where the version string is set. + +Options: + -s | --source DIR Path to source to build. + Defaults to "${SOURCE_DIR}" + +EOF +} + +function err_usage { + err "$1" + err "" + err "$(usage)" +} + +function main { + declare sdir="${SOURCE_DIR}" + declare -i date=0 + + 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 + ;; + *) + err_usage "ERROR: Unknown argument: '$1'" + return 1 + ;; + esac + done + + git_date "${sdir}" || return 1 + + return 0 +} + +main "$@" +exit $? From 8945b68a9dafee3a7018ac6a2dd011ccd82147cd Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Wed, 1 Jun 2022 19:29:40 -0700 Subject: [PATCH 03/14] Cleanup and extend basic build date Signed-off-by: Mark Anderson --- .github/workflows/build.yml | 4 +++- GNUmakefile | 2 +- build-support/functions/10-util.sh | 2 +- command/agent/agent.go | 3 +++ command/version/formatter.go | 3 +++ command/version/formatter_test.go | 1 + command/version/testdata/json.golden | 1 + command/version/testdata/pretty.golden | 1 + command/version/version.go | 11 +++++++++++ 9 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 654fb7c960..6481cff019 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: id: get-product-version run: | CONSUL_VERSION=$(build-support/scripts/version.sh -r) - CONSUL_DATE=$(build-support/scripts/build-date.sh -r) + CONSUL_DATE=$(build-support/scripts/build-date.sh) ## TODO: This assumes `make version` outputs 1.1.1+ent-prerel IFS="+" read VERSION _other <<< "$CONSUL_VERSION" IFS="-" read _other PREREL_VERSION <<< "$CONSUL_VERSION" @@ -100,9 +100,11 @@ jobs: - name: Build UI run: | CONSUL_VERSION=${{ needs.get-product-version.outputs.product-version }} + CONSUL_DATE=${{ needs.get-product-version.outputs.product-date }} CONSUL_BINARY_TYPE=${CONSUL_BINARY_TYPE} CONSUL_COPYRIGHT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) echo "consul_version is ${CONSUL_VERSION}" + echo "consul_date is ${CONSUL_DATE}" echo "consul binary type is ${CONSUL_BINARY_TYPE}" echo "consul copyright year is ${CONSUL_COPYRIGHT_YEAR}" cd ui && make && cd .. diff --git a/GNUmakefile b/GNUmakefile index 6bc619e5cc..197a3186d8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -26,7 +26,7 @@ GIT_COMMIT_YEAR?=$(shell git show -s --format=%cd --date=format:%Y HEAD) GIT_DIRTY?=$(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true) GIT_IMPORT=github.com/hashicorp/consul/version DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ" # it's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC -GIT_DATE=$(shell git show -s --format=%cd --date=format:"$(DATE_FORMAT)" HEAD) # we're using this for build date because it's stable across platform builds +GIT_DATE=$(shell $(CURDIR)/build-support/scripts/build-date.sh) # we're using this for build date because it's stable across platform builds GOLDFLAGS=-X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT)$(GIT_DIRTY) -X $(GIT_IMPORT).BuildDate=$(GIT_DATE) ifeq ($(FORCE_REBUILD),1) diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index e9a6837bab..9f8fe6d71e 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -299,7 +299,7 @@ function git_date { # it's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC local date_format="%Y-%m-%dT%H:%M:%SZ" # we're using this for build date because it's stable across platform builds - local date=$(git show -s --format=%cd --date=format:"$date_format" HEAD) + local date="$(git show -s --format=%cd --date=format:"$date_format" HEAD)" || ret=1 ##local head="$(git status -b --porcelain=v2 | awk '{if ($1 == "#" && $2 =="branch.head") { print $3 }}')" || ret=1 diff --git a/command/agent/agent.go b/command/agent/agent.go index 3bef84b0a8..a929575b52 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -202,6 +202,9 @@ func (c *cmd) run(args []string) int { segment = "" } ui.Info(fmt.Sprintf(" Version: '%s'", c.versionHuman)) + if strings.Contains(c.versionHuman, "dev") { + ui.Info(fmt.Sprintf(" Revision: '%s'", c.revision)) + } ui.Info(fmt.Sprintf(" Build Date: %s", c.buildDate)) ui.Info(fmt.Sprintf(" Node ID: '%s'", config.NodeID)) ui.Info(fmt.Sprintf(" Node name: '%s'", config.NodeName)) diff --git a/command/version/formatter.go b/command/version/formatter.go index 1cfcf5dfd6..c5753f1059 100644 --- a/command/version/formatter.go +++ b/command/version/formatter.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "time" ) const ( @@ -43,6 +44,8 @@ func (_ *prettyFormatter) Format(info *VersionInfo) (string, error) { buffer.WriteString(fmt.Sprintf("Revision %s\n", info.Revision)) } + buffer.WriteString(fmt.Sprintf("Build Date %s\n", info.BuildDate.Format(time.RFC3339))) + var supplement string if info.RPC.Default < info.RPC.Max { supplement = fmt.Sprintf(" (agent will automatically use protocol >%d when speaking to compatible agents)", diff --git a/command/version/formatter_test.go b/command/version/formatter_test.go index b9c6090ac7..bbb12e89f0 100644 --- a/command/version/formatter_test.go +++ b/command/version/formatter_test.go @@ -36,6 +36,7 @@ func TestFormat(t *testing.T) { Version: "1.99.3", Prerelease: "beta1", Revision: "5e5dbedd47a5f875b60e241c5555a9caab595246", + BuildDate: "2022-06-01T13:18:45Z", RPC: RPCVersionInfo{ Default: 2, Min: 1, diff --git a/command/version/testdata/json.golden b/command/version/testdata/json.golden index 20c4a80c07..2e8361f30b 100644 --- a/command/version/testdata/json.golden +++ b/command/version/testdata/json.golden @@ -2,6 +2,7 @@ "Version": "1.99.3", "Revision": "5e5dbedd47a5f875b60e241c5555a9caab595246", "Prerelease": "beta1", + "BuildDate": "2022-06-01T13:18:45Z", "RPC": { "Default": 2, "Min": 1, diff --git a/command/version/testdata/pretty.golden b/command/version/testdata/pretty.golden index 36cb2482c2..c9ee739df9 100644 --- a/command/version/testdata/pretty.golden +++ b/command/version/testdata/pretty.golden @@ -1,3 +1,4 @@ Consul v1.99.3-beta1 Revision 5e5dbedd47a5f875b60e241c5555a9caab595246 +Build Date 2022-06-01T13:18:45Z Protocol 2 spoken by default, understands 1 to 3 (agent will automatically use protocol >2 when speaking to compatible agents) diff --git a/command/version/version.go b/command/version/version.go index 423a6f97da..9cda50ed85 100644 --- a/command/version/version.go +++ b/command/version/version.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "strings" + "time" "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/command/flags" @@ -46,6 +47,7 @@ type VersionInfo struct { Version string Revision string Prerelease string + BuildDate time.Time RPC RPCVersionInfo } @@ -59,11 +61,20 @@ func (c *cmd) Run(args []string) int { c.UI.Error(err.Error()) return 1 } + + // We parse this here because consul version is used in our 'smoke' tests and we want to fail early + buildDate, err := time.Parse(time.RFC3339, version.BuildDate) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + out, err := formatter.Format(&VersionInfo{ HumanVersion: version.GetHumanVersion(), Version: version.Version, Revision: version.GitCommit, Prerelease: version.VersionPrerelease, + BuildDate: buildDate, RPC: RPCVersionInfo{ Default: consul.DefaultRPCProtocol, Min: int(consul.ProtocolVersionMin), From 4cd42a2e1f4129b639ed09fb2519e389b8800378 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Wed, 1 Jun 2022 20:25:03 -0700 Subject: [PATCH 04/14] Fixup agent startup Signed-off-by: Mark Anderson --- command/agent/agent.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index a929575b52..a69e630711 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -205,7 +205,7 @@ func (c *cmd) run(args []string) int { if strings.Contains(c.versionHuman, "dev") { ui.Info(fmt.Sprintf(" Revision: '%s'", c.revision)) } - ui.Info(fmt.Sprintf(" Build Date: %s", c.buildDate)) + ui.Info(fmt.Sprintf(" Build Date: '%s'", c.buildDate)) ui.Info(fmt.Sprintf(" Node ID: '%s'", config.NodeID)) ui.Info(fmt.Sprintf(" Node name: '%s'", config.NodeName)) if ap := config.PartitionOrEmpty(); ap != "" { From ec060e5e37ea9e14bddfe4a1a1cc5f9830d6b701 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Wed, 1 Jun 2022 19:37:47 -0700 Subject: [PATCH 05/14] Build date in config file Signed-off-by: Mark Anderson --- agent/config/builder.go | 9 +++++++++ agent/config/config.go | 26 ++++++++++++++------------ agent/config/default.go | 11 +++++++---- agent/config/runtime.go | 1 + 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/agent/config/builder.go b/agent/config/builder.go index 741aa06b12..bf78d92df7 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -804,6 +804,8 @@ func (b *builder) build() (rt RuntimeConfig, err error) { Version: stringVal(c.Version), VersionPrerelease: stringVal(c.VersionPrerelease), VersionMetadata: stringVal(c.VersionMetadata), + // What is a sensible default for BuildDate? + BuildDate: timeValWithDefault(c.BuildDate, time.Now()), // consul configuration ConsulCoordinateUpdateBatchSize: intVal(c.Consul.Coordinate.UpdateBatchSize), @@ -1946,6 +1948,13 @@ func stringVal(v *string) string { return *v } +func timeValWithDefault(v *time.Time, defaultVal time.Time) time.Time { + if v == nil { + return defaultVal + } + return *v +} + func float64ValWithDefault(v *float64, defaultVal float64) float64 { if v == nil { return defaultVal diff --git a/agent/config/config.go b/agent/config/config.go index dbca8e1cf4..adef2e8772 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -3,6 +3,7 @@ package config import ( "encoding/json" "fmt" + "time" "github.com/hashicorp/consul/agent/consul" @@ -261,18 +262,19 @@ type Config struct { SnapshotAgent map[string]interface{} `mapstructure:"snapshot_agent"` // non-user configurable values - AEInterval *string `mapstructure:"ae_interval"` - CheckDeregisterIntervalMin *string `mapstructure:"check_deregister_interval_min"` - CheckReapInterval *string `mapstructure:"check_reap_interval"` - Consul Consul `mapstructure:"consul"` - Revision *string `mapstructure:"revision"` - SegmentLimit *int `mapstructure:"segment_limit"` - SegmentNameLimit *int `mapstructure:"segment_name_limit"` - SyncCoordinateIntervalMin *string `mapstructure:"sync_coordinate_interval_min"` - SyncCoordinateRateTarget *float64 `mapstructure:"sync_coordinate_rate_target"` - Version *string `mapstructure:"version"` - VersionPrerelease *string `mapstructure:"version_prerelease"` - VersionMetadata *string `mapstructure:"version_metadata"` + AEInterval *string `mapstructure:"ae_interval"` + CheckDeregisterIntervalMin *string `mapstructure:"check_deregister_interval_min"` + CheckReapInterval *string `mapstructure:"check_reap_interval"` + Consul Consul `mapstructure:"consul"` + Revision *string `mapstructure:"revision"` + SegmentLimit *int `mapstructure:"segment_limit"` + SegmentNameLimit *int `mapstructure:"segment_name_limit"` + SyncCoordinateIntervalMin *string `mapstructure:"sync_coordinate_interval_min"` + SyncCoordinateRateTarget *float64 `mapstructure:"sync_coordinate_rate_target"` + Version *string `mapstructure:"version"` + VersionPrerelease *string `mapstructure:"version_prerelease"` + VersionMetadata *string `mapstructure:"version_metadata"` + BuildDate *time.Time `mapstructure:"build_date"` // Enterprise Only Audit Audit `mapstructure:"audit"` diff --git a/agent/config/default.go b/agent/config/default.go index 8d1846e99a..951d9f1263 100644 --- a/agent/config/default.go +++ b/agent/config/default.go @@ -2,6 +2,7 @@ package config import ( "strconv" + "time" "github.com/hashicorp/raft" @@ -197,8 +198,8 @@ func NonUserSource() Source { # SegmentNameLimit is the maximum segment name length. segment_name_limit = 64 - - connect = { + + connect = { # 0s causes the value to be ignored and operate without capping # the max time before leaf certs can be generated after a roots change. test_ca_leaf_root_change_spread = "0s" @@ -210,7 +211,7 @@ func NonUserSource() Source { // versionSource creates a config source for the version parameters. // This should be merged in the tail since these values are not // user configurable. -func versionSource(rev, ver, verPre, meta string) Source { +func versionSource(rev, ver, verPre, meta string, buildDate time.Time) Source { return LiteralSource{ Name: "version", Config: Config{ @@ -218,6 +219,7 @@ func versionSource(rev, ver, verPre, meta string) Source { Version: &ver, VersionPrerelease: &verPre, VersionMetadata: &meta, + BuildDate: &buildDate, }, } } @@ -225,7 +227,8 @@ func versionSource(rev, ver, verPre, meta string) Source { // defaultVersionSource returns the version config source for the embedded // version numbers. func defaultVersionSource() Source { - return versionSource(version.GitCommit, version.Version, version.VersionPrerelease, version.VersionMetadata) + buildDate, _ := time.Parse(time.RFC3339, version.BuildDate) // This has been checked elsewhere + return versionSource(version.GitCommit, version.Version, version.VersionPrerelease, version.VersionMetadata, buildDate) } // DefaultConsulSource returns the default configuration for the consul agent. diff --git a/agent/config/runtime.go b/agent/config/runtime.go index dd2a7cabf8..069a463dc5 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -62,6 +62,7 @@ type RuntimeConfig struct { Version string VersionPrerelease string VersionMetadata string + BuildDate time.Time // consul config ConsulCoordinateUpdateMaxBatches int From 19c87be3a6caae61f8783b0a7ec7a6ca6ee8a596 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 2 Jun 2022 11:28:32 -0700 Subject: [PATCH 06/14] Add build date to self endpoint Signed-off-by: Mark Anderson --- agent/agent_endpoint.go | 5 ++++- agent/config/runtime.go | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index 86197f462f..3e29cf45ff 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -91,6 +91,7 @@ func (s *HTTPHandlers) AgentSelf(resp http.ResponseWriter, req *http.Request) (i Revision string Server bool Version string + BuildDate string }{ Datacenter: s.agent.config.Datacenter, PrimaryDatacenter: s.agent.config.PrimaryDatacenter, @@ -100,8 +101,10 @@ func (s *HTTPHandlers) AgentSelf(resp http.ResponseWriter, req *http.Request) (i Revision: s.agent.config.Revision, Server: s.agent.config.ServerMode, // We expect the ent version to be part of the reported version string, and that's now part of the metadata, not the actual version. - Version: s.agent.config.VersionWithMetadata(), + Version: s.agent.config.VersionWithMetadata(), + BuildDate: s.agent.config.BuildDate.Format(time.RFC3339), } + return Self{ Config: config, DebugConfig: s.agent.config.Sanitized(), diff --git a/agent/config/runtime.go b/agent/config/runtime.go index 069a463dc5..2ae9888ae0 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -1701,6 +1701,10 @@ func sanitize(name string, v reflect.Value) reflect.Value { x := v.Interface().(time.Duration) return reflect.ValueOf(x.String()) + case isTime(typ): + x := v.Interface().(time.Time) + return reflect.ValueOf(x.String()) + case isString(typ): if strings.HasPrefix(name, "RetryJoinLAN[") || strings.HasPrefix(name, "RetryJoinWAN[") { x := v.Interface().(string) @@ -1772,6 +1776,7 @@ func sanitize(name string, v reflect.Value) reflect.Value { } func isDuration(t reflect.Type) bool { return t == reflect.TypeOf(time.Second) } +func isTime(t reflect.Type) bool { return t == reflect.TypeOf(time.Time{}) } func isMap(t reflect.Type) bool { return t.Kind() == reflect.Map } func isNetAddr(t reflect.Type) bool { return t.Implements(reflect.TypeOf((*net.Addr)(nil)).Elem()) } func isPtr(t reflect.Type) bool { return t.Kind() == reflect.Ptr } From 9343e054984b72ab1f98ad04ba46b614b52a07e2 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 2 Jun 2022 11:52:30 -0700 Subject: [PATCH 07/14] Fix build-date to use UTC Signed-off-by: Mark Anderson --- build-support/functions/10-util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index 9f8fe6d71e..9b380dcbb1 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -299,7 +299,7 @@ function git_date { # it's tricky to do an RFC3339 format in a cross platform way, so we hardcode UTC local date_format="%Y-%m-%dT%H:%M:%SZ" # we're using this for build date because it's stable across platform builds - local date="$(git show -s --format=%cd --date=format:"$date_format" HEAD)" || ret=1 + local date="$(TZ=UTC0 git show -s --format=%cd --date=format-local:"$date_format" HEAD)" || ret=1 ##local head="$(git status -b --porcelain=v2 | awk '{if ($1 == "#" && $2 =="branch.head") { print $3 }}')" || ret=1 From 6eecb7cf800ef404454e37c1247127c6fb339618 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 2 Jun 2022 12:46:18 -0700 Subject: [PATCH 08/14] Set default for build date Signed-off-by: Mark Anderson --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 4ce586e77a..95e3961d71 100644 --- a/version/version.go +++ b/version/version.go @@ -24,8 +24,8 @@ var ( // such as "dev" (in development), "beta", "rc1", etc. VersionPrerelease = "dev" - // The date/time of the build - BuildDate string + // The date/time of the build (actually the HEAD commit in git, to preserve stability) + BuildDate string = "2022-06-02T18:28:32Z" ) // GetHumanVersion composes the parts of the version in a way that's suitable From 61a89958472248625e690e5691f239155405ffd6 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 2 Jun 2022 13:25:47 -0700 Subject: [PATCH 09/14] Fix issue with consul version tests Signed-off-by: Mark Anderson --- command/version/formatter_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/command/version/formatter_test.go b/command/version/formatter_test.go index bbb12e89f0..e532c487c0 100644 --- a/command/version/formatter_test.go +++ b/command/version/formatter_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "path/filepath" "testing" + "time" "github.com/stretchr/testify/require" ) @@ -31,12 +32,13 @@ func golden(t *testing.T, name, got string) string { } func TestFormat(t *testing.T) { + buildDate, _ := time.Parse(time.RFC3339, "2022-06-01T13:18:45Z") info := VersionInfo{ HumanVersion: "1.99.3-beta1", Version: "1.99.3", Prerelease: "beta1", Revision: "5e5dbedd47a5f875b60e241c5555a9caab595246", - BuildDate: "2022-06-01T13:18:45Z", + BuildDate: buildDate, RPC: RPCVersionInfo{ Default: 2, Min: 1, From f65093f1c625dbda8d9ee049c2158b9cd930cd05 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 2 Jun 2022 14:26:41 -0700 Subject: [PATCH 10/14] Fixup some more tests Signed-off-by: Mark Anderson --- agent/config/runtime_test.go | 5 ++++- agent/config/testdata/TestRuntimeConfig_Sanitize.golden | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/agent/config/runtime_test.go b/agent/config/runtime_test.go index cdbcb50bc9..9ca6cc5993 100644 --- a/agent/config/runtime_test.go +++ b/agent/config/runtime_test.go @@ -5661,6 +5661,7 @@ func TestLoad_FullConfig(t *testing.T) { Version: "R909Hblt", VersionPrerelease: "ZT1JOQLn", VersionMetadata: "GtTCa13", + BuildDate: time.Date(2019, 11, 20, 5, 0, 0, 0, time.UTC), // consul configuration ConsulCoordinateUpdateBatchSize: 128, @@ -6447,7 +6448,8 @@ func TestLoad_FullConfig(t *testing.T) { ConfigFiles: []string{"testdata/full-config." + format}, HCL: []string{fmt.Sprintf(`data_dir = "%s"`, dataDir)}, } - opts.Overrides = append(opts.Overrides, versionSource("JNtPSav3", "R909Hblt", "ZT1JOQLn", "GtTCa13")) + opts.Overrides = append(opts.Overrides, versionSource("JNtPSav3", "R909Hblt", "ZT1JOQLn", "GtTCa13", + time.Date(2019, 11, 20, 5, 0, 0, 0, time.UTC))) r, err := Load(opts) require.NoError(t, err) prototest.AssertDeepEqual(t, expected, r.RuntimeConfig) @@ -6641,6 +6643,7 @@ func parseCIDR(t *testing.T, cidr string) *net.IPNet { func TestRuntimeConfig_Sanitize(t *testing.T) { rt := RuntimeConfig{ BindAddr: &net.IPAddr{IP: net.ParseIP("127.0.0.1")}, + BuildDate: time.Date(2019, 11, 20, 5, 0, 0, 0, time.UTC), CheckOutputMaxSize: checks.DefaultBufSize, SerfAdvertiseAddrLAN: &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678}, DNSAddrs: []net.Addr{ diff --git a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden index 090a7191a8..79f3cc25ee 100644 --- a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden +++ b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden @@ -76,6 +76,7 @@ "BindAddr": "127.0.0.1", "Bootstrap": false, "BootstrapExpect": 0, + "BuildDate": "2019-11-20 05:00:00 +0000 UTC", "Cache": { "EntryFetchMaxBurst": 42, "EntryFetchRate": 0.334, From 45190d355b24fc0ff1716915483fd79c87e55203 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Fri, 3 Jun 2022 14:43:25 -0700 Subject: [PATCH 11/14] Add changelog Signed-off-by: Mark Anderson --- .changelog/13357.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changelog/13357.txt diff --git a/.changelog/13357.txt b/.changelog/13357.txt new file mode 100644 index 0000000000..dcf1aabb1e --- /dev/null +++ b/.changelog/13357.txt @@ -0,0 +1,4 @@ +```release-note:feature +agent: Added information about build date alongside other version information for Consul. Extended /agent/self endpoint and `consul version` commands +to report this. Agent also reports build date in log on startup. +``` \ No newline at end of file From dd22ceccd137c0ace208f36a532db0488892c4bf Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 9 Jun 2022 15:55:11 -0700 Subject: [PATCH 12/14] Change default dates Signed-off-by: Mark Anderson --- agent/config/builder.go | 2 +- version/version.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/agent/config/builder.go b/agent/config/builder.go index bf78d92df7..39c15c5d14 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -805,7 +805,7 @@ func (b *builder) build() (rt RuntimeConfig, err error) { VersionPrerelease: stringVal(c.VersionPrerelease), VersionMetadata: stringVal(c.VersionMetadata), // What is a sensible default for BuildDate? - BuildDate: timeValWithDefault(c.BuildDate, time.Now()), + BuildDate: timeValWithDefault(c.BuildDate, time.Date(1970, 1, 00, 00, 00, 01, 0, time.UTC)), // consul configuration ConsulCoordinateUpdateBatchSize: intVal(c.Consul.Coordinate.UpdateBatchSize), diff --git a/version/version.go b/version/version.go index 95e3961d71..8930b48224 100644 --- a/version/version.go +++ b/version/version.go @@ -25,7 +25,8 @@ var ( VersionPrerelease = "dev" // The date/time of the build (actually the HEAD commit in git, to preserve stability) - BuildDate string = "2022-06-02T18:28:32Z" + // This isn't just informational, but is also used by the licensing system. Default is chosen to be flagantly wrong. + BuildDate string = "1970-01-01T00:00:01Z" ) // GetHumanVersion composes the parts of the version in a way that's suitable From 175728b292dad0d38ed4e48faecbe50db3459fb3 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Thu, 9 Jun 2022 16:16:50 -0700 Subject: [PATCH 13/14] Minor cleanup for build-date script Signed-off-by: Mark Anderson --- build-support/scripts/build-date.sh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/build-support/scripts/build-date.sh b/build-support/scripts/build-date.sh index 54b02fced7..e3db3c6626 100755 --- a/build-support/scripts/build-date.sh +++ b/build-support/scripts/build-date.sh @@ -1,14 +1,8 @@ #!/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 +readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" +readonly SCRIPT_DIR="$(dirname ${BASH_SOURCE[0]})" +readonly SOURCE_DIR="$(dirname "$(dirname "${SCRIPT_DIR}")")" +readonly FN_DIR="$(dirname "${SCRIPT_DIR}")/functions" source "${SCRIPT_DIR}/functions.sh" From a5efa461ddc85991fe753a1cab7fb26efe457209 Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Fri, 10 Jun 2022 20:22:43 -0700 Subject: [PATCH 14/14] Fix infinite recursion in bash_env Signed-off-by: Mark Anderson --- .circleci/bash_env.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.circleci/bash_env.sh b/.circleci/bash_env.sh index f644a8b390..69004e7c8d 100644 --- a/.circleci/bash_env.sh +++ b/.circleci/bash_env.sh @@ -4,5 +4,7 @@ export GIT_COMMIT=$(git rev-parse --short HEAD) export GIT_COMMIT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) export GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true) export GIT_IMPORT=github.com/hashicorp/consul/version -export GIT_DATE=$("${CIRCLE_WORKING_DIRECTORY}/build-support/scripts/build-date.sh") # we're using this for build date because it's stable across platform builds -export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X $(GIT_IMPORT).BuildDate=$(GIT_DATE)" +# we're using this for build date because it's stable across platform builds +# the env -i and -noprofile are used to ensure we don't try to recursively call this profile when starting bash +export GIT_DATE=$(env -i /bin/bash --noprofile -norc ${CIRCLE_WORKING_DIRECTORY}/build-support/scripts/build-date.sh) +export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X ${GIT_IMPORT}.BuildDate=${GIT_DATE}"