mirror of https://github.com/status-im/consul.git
Merge pull request #13357 from hashicorp/ma/add-build-date-oss
Add build date (oss)
This commit is contained in:
commit
edbf19f4e8
|
@ -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.
|
||||||
|
```
|
|
@ -4,4 +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_COMMIT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD)
|
||||||
export GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true)
|
export GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true)
|
||||||
export GIT_IMPORT=github.com/hashicorp/consul/version
|
export GIT_IMPORT=github.com/hashicorp/consul/version
|
||||||
export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY}"
|
# 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}"
|
||||||
|
|
|
@ -15,6 +15,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
product-version: ${{ steps.get-product-version.outputs.product-version }}
|
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 }}
|
pre-version: ${{ steps.get-product-version.outputs.pre-version }}
|
||||||
pkg-version: ${{ steps.get-product-version.outputs.pkg-version }}
|
pkg-version: ${{ steps.get-product-version.outputs.pkg-version }}
|
||||||
shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }}
|
shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }}
|
||||||
|
@ -24,6 +25,7 @@ jobs:
|
||||||
id: get-product-version
|
id: get-product-version
|
||||||
run: |
|
run: |
|
||||||
CONSUL_VERSION=$(build-support/scripts/version.sh -r)
|
CONSUL_VERSION=$(build-support/scripts/version.sh -r)
|
||||||
|
CONSUL_DATE=$(build-support/scripts/build-date.sh)
|
||||||
## TODO: This assumes `make version` outputs 1.1.1+ent-prerel
|
## TODO: This assumes `make version` outputs 1.1.1+ent-prerel
|
||||||
IFS="+" read VERSION _other <<< "$CONSUL_VERSION"
|
IFS="+" read VERSION _other <<< "$CONSUL_VERSION"
|
||||||
IFS="-" read _other PREREL_VERSION <<< "$CONSUL_VERSION"
|
IFS="-" read _other PREREL_VERSION <<< "$CONSUL_VERSION"
|
||||||
|
@ -32,12 +34,15 @@ jobs:
|
||||||
## [version]{-prerelease}+ent before then, we'll need to add
|
## [version]{-prerelease}+ent before then, we'll need to add
|
||||||
## logic to handle presense/absence of the prerelease
|
## logic to handle presense/absence of the prerelease
|
||||||
echo "::set-output name=product-version::${CONSUL_VERSION}"
|
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=pre-version::${PREREL_VERSION}"
|
||||||
echo "::set-output name=pkg-version::${VERSION}"
|
echo "::set-output name=pkg-version::${VERSION}"
|
||||||
|
|
||||||
- name: Set shared -ldflags
|
- name: Set shared -ldflags
|
||||||
id: 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:
|
generate-metadata-file:
|
||||||
needs: get-product-version
|
needs: get-product-version
|
||||||
|
@ -95,9 +100,11 @@ jobs:
|
||||||
- name: Build UI
|
- name: Build UI
|
||||||
run: |
|
run: |
|
||||||
CONSUL_VERSION=${{ needs.get-product-version.outputs.product-version }}
|
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_BINARY_TYPE=${CONSUL_BINARY_TYPE}
|
||||||
CONSUL_COPYRIGHT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD)
|
CONSUL_COPYRIGHT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD)
|
||||||
echo "consul_version is ${CONSUL_VERSION}"
|
echo "consul_version is ${CONSUL_VERSION}"
|
||||||
|
echo "consul_date is ${CONSUL_DATE}"
|
||||||
echo "consul binary type is ${CONSUL_BINARY_TYPE}"
|
echo "consul binary type is ${CONSUL_BINARY_TYPE}"
|
||||||
echo "consul copyright year is ${CONSUL_COPYRIGHT_YEAR}"
|
echo "consul copyright year is ${CONSUL_COPYRIGHT_YEAR}"
|
||||||
cd ui && make && cd ..
|
cd ui && make && cd ..
|
||||||
|
|
|
@ -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_COMMIT_YEAR?=$(shell git show -s --format=%cd --date=format:%Y HEAD)
|
||||||
GIT_DIRTY?=$(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true)
|
GIT_DIRTY?=$(shell test -n "`git status --porcelain`" && echo "+CHANGES" || true)
|
||||||
GIT_IMPORT=github.com/hashicorp/consul/version
|
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 $(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)
|
ifeq ($(FORCE_REBUILD),1)
|
||||||
NOCACHE=--no-cache
|
NOCACHE=--no-cache
|
||||||
|
|
|
@ -91,6 +91,7 @@ func (s *HTTPHandlers) AgentSelf(resp http.ResponseWriter, req *http.Request) (i
|
||||||
Revision string
|
Revision string
|
||||||
Server bool
|
Server bool
|
||||||
Version string
|
Version string
|
||||||
|
BuildDate string
|
||||||
}{
|
}{
|
||||||
Datacenter: s.agent.config.Datacenter,
|
Datacenter: s.agent.config.Datacenter,
|
||||||
PrimaryDatacenter: s.agent.config.PrimaryDatacenter,
|
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,
|
Revision: s.agent.config.Revision,
|
||||||
Server: s.agent.config.ServerMode,
|
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.
|
// 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{
|
return Self{
|
||||||
Config: config,
|
Config: config,
|
||||||
DebugConfig: s.agent.config.Sanitized(),
|
DebugConfig: s.agent.config.Sanitized(),
|
||||||
|
|
|
@ -804,6 +804,8 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
||||||
Version: stringVal(c.Version),
|
Version: stringVal(c.Version),
|
||||||
VersionPrerelease: stringVal(c.VersionPrerelease),
|
VersionPrerelease: stringVal(c.VersionPrerelease),
|
||||||
VersionMetadata: stringVal(c.VersionMetadata),
|
VersionMetadata: stringVal(c.VersionMetadata),
|
||||||
|
// What is a sensible default for BuildDate?
|
||||||
|
BuildDate: timeValWithDefault(c.BuildDate, time.Date(1970, 1, 00, 00, 00, 01, 0, time.UTC)),
|
||||||
|
|
||||||
// consul configuration
|
// consul configuration
|
||||||
ConsulCoordinateUpdateBatchSize: intVal(c.Consul.Coordinate.UpdateBatchSize),
|
ConsulCoordinateUpdateBatchSize: intVal(c.Consul.Coordinate.UpdateBatchSize),
|
||||||
|
@ -1946,6 +1948,13 @@ func stringVal(v *string) string {
|
||||||
return *v
|
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 {
|
func float64ValWithDefault(v *float64, defaultVal float64) float64 {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return defaultVal
|
return defaultVal
|
||||||
|
|
|
@ -3,6 +3,7 @@ package config
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/consul"
|
"github.com/hashicorp/consul/agent/consul"
|
||||||
|
|
||||||
|
@ -261,18 +262,19 @@ type Config struct {
|
||||||
SnapshotAgent map[string]interface{} `mapstructure:"snapshot_agent"`
|
SnapshotAgent map[string]interface{} `mapstructure:"snapshot_agent"`
|
||||||
|
|
||||||
// non-user configurable values
|
// non-user configurable values
|
||||||
AEInterval *string `mapstructure:"ae_interval"`
|
AEInterval *string `mapstructure:"ae_interval"`
|
||||||
CheckDeregisterIntervalMin *string `mapstructure:"check_deregister_interval_min"`
|
CheckDeregisterIntervalMin *string `mapstructure:"check_deregister_interval_min"`
|
||||||
CheckReapInterval *string `mapstructure:"check_reap_interval"`
|
CheckReapInterval *string `mapstructure:"check_reap_interval"`
|
||||||
Consul Consul `mapstructure:"consul"`
|
Consul Consul `mapstructure:"consul"`
|
||||||
Revision *string `mapstructure:"revision"`
|
Revision *string `mapstructure:"revision"`
|
||||||
SegmentLimit *int `mapstructure:"segment_limit"`
|
SegmentLimit *int `mapstructure:"segment_limit"`
|
||||||
SegmentNameLimit *int `mapstructure:"segment_name_limit"`
|
SegmentNameLimit *int `mapstructure:"segment_name_limit"`
|
||||||
SyncCoordinateIntervalMin *string `mapstructure:"sync_coordinate_interval_min"`
|
SyncCoordinateIntervalMin *string `mapstructure:"sync_coordinate_interval_min"`
|
||||||
SyncCoordinateRateTarget *float64 `mapstructure:"sync_coordinate_rate_target"`
|
SyncCoordinateRateTarget *float64 `mapstructure:"sync_coordinate_rate_target"`
|
||||||
Version *string `mapstructure:"version"`
|
Version *string `mapstructure:"version"`
|
||||||
VersionPrerelease *string `mapstructure:"version_prerelease"`
|
VersionPrerelease *string `mapstructure:"version_prerelease"`
|
||||||
VersionMetadata *string `mapstructure:"version_metadata"`
|
VersionMetadata *string `mapstructure:"version_metadata"`
|
||||||
|
BuildDate *time.Time `mapstructure:"build_date"`
|
||||||
|
|
||||||
// Enterprise Only
|
// Enterprise Only
|
||||||
Audit Audit `mapstructure:"audit"`
|
Audit Audit `mapstructure:"audit"`
|
||||||
|
|
|
@ -2,6 +2,7 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/raft"
|
"github.com/hashicorp/raft"
|
||||||
|
|
||||||
|
@ -210,7 +211,7 @@ func NonUserSource() Source {
|
||||||
// versionSource creates a config source for the version parameters.
|
// versionSource creates a config source for the version parameters.
|
||||||
// This should be merged in the tail since these values are not
|
// This should be merged in the tail since these values are not
|
||||||
// user configurable.
|
// user configurable.
|
||||||
func versionSource(rev, ver, verPre, meta string) Source {
|
func versionSource(rev, ver, verPre, meta string, buildDate time.Time) Source {
|
||||||
return LiteralSource{
|
return LiteralSource{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
Config: Config{
|
Config: Config{
|
||||||
|
@ -218,6 +219,7 @@ func versionSource(rev, ver, verPre, meta string) Source {
|
||||||
Version: &ver,
|
Version: &ver,
|
||||||
VersionPrerelease: &verPre,
|
VersionPrerelease: &verPre,
|
||||||
VersionMetadata: &meta,
|
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
|
// defaultVersionSource returns the version config source for the embedded
|
||||||
// version numbers.
|
// version numbers.
|
||||||
func defaultVersionSource() Source {
|
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.
|
// DefaultConsulSource returns the default configuration for the consul agent.
|
||||||
|
|
|
@ -62,6 +62,7 @@ type RuntimeConfig struct {
|
||||||
Version string
|
Version string
|
||||||
VersionPrerelease string
|
VersionPrerelease string
|
||||||
VersionMetadata string
|
VersionMetadata string
|
||||||
|
BuildDate time.Time
|
||||||
|
|
||||||
// consul config
|
// consul config
|
||||||
ConsulCoordinateUpdateMaxBatches int
|
ConsulCoordinateUpdateMaxBatches int
|
||||||
|
@ -1700,6 +1701,10 @@ func sanitize(name string, v reflect.Value) reflect.Value {
|
||||||
x := v.Interface().(time.Duration)
|
x := v.Interface().(time.Duration)
|
||||||
return reflect.ValueOf(x.String())
|
return reflect.ValueOf(x.String())
|
||||||
|
|
||||||
|
case isTime(typ):
|
||||||
|
x := v.Interface().(time.Time)
|
||||||
|
return reflect.ValueOf(x.String())
|
||||||
|
|
||||||
case isString(typ):
|
case isString(typ):
|
||||||
if strings.HasPrefix(name, "RetryJoinLAN[") || strings.HasPrefix(name, "RetryJoinWAN[") {
|
if strings.HasPrefix(name, "RetryJoinLAN[") || strings.HasPrefix(name, "RetryJoinWAN[") {
|
||||||
x := v.Interface().(string)
|
x := v.Interface().(string)
|
||||||
|
@ -1771,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 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 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 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 }
|
func isPtr(t reflect.Type) bool { return t.Kind() == reflect.Ptr }
|
||||||
|
|
|
@ -5661,6 +5661,7 @@ func TestLoad_FullConfig(t *testing.T) {
|
||||||
Version: "R909Hblt",
|
Version: "R909Hblt",
|
||||||
VersionPrerelease: "ZT1JOQLn",
|
VersionPrerelease: "ZT1JOQLn",
|
||||||
VersionMetadata: "GtTCa13",
|
VersionMetadata: "GtTCa13",
|
||||||
|
BuildDate: time.Date(2019, 11, 20, 5, 0, 0, 0, time.UTC),
|
||||||
|
|
||||||
// consul configuration
|
// consul configuration
|
||||||
ConsulCoordinateUpdateBatchSize: 128,
|
ConsulCoordinateUpdateBatchSize: 128,
|
||||||
|
@ -6447,7 +6448,8 @@ func TestLoad_FullConfig(t *testing.T) {
|
||||||
ConfigFiles: []string{"testdata/full-config." + format},
|
ConfigFiles: []string{"testdata/full-config." + format},
|
||||||
HCL: []string{fmt.Sprintf(`data_dir = "%s"`, dataDir)},
|
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)
|
r, err := Load(opts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
prototest.AssertDeepEqual(t, expected, r.RuntimeConfig)
|
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) {
|
func TestRuntimeConfig_Sanitize(t *testing.T) {
|
||||||
rt := RuntimeConfig{
|
rt := RuntimeConfig{
|
||||||
BindAddr: &net.IPAddr{IP: net.ParseIP("127.0.0.1")},
|
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,
|
CheckOutputMaxSize: checks.DefaultBufSize,
|
||||||
SerfAdvertiseAddrLAN: &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678},
|
SerfAdvertiseAddrLAN: &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678},
|
||||||
DNSAddrs: []net.Addr{
|
DNSAddrs: []net.Addr{
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
"BindAddr": "127.0.0.1",
|
"BindAddr": "127.0.0.1",
|
||||||
"Bootstrap": false,
|
"Bootstrap": false,
|
||||||
"BootstrapExpect": 0,
|
"BootstrapExpect": 0,
|
||||||
|
"BuildDate": "2019-11-20 05:00:00 +0000 UTC",
|
||||||
"Cache": {
|
"Cache": {
|
||||||
"EntryFetchMaxBurst": 42,
|
"EntryFetchMaxBurst": 42,
|
||||||
"EntryFetchRate": 0.334,
|
"EntryFetchRate": 0.334,
|
||||||
|
|
|
@ -274,6 +274,42 @@ function git_branch {
|
||||||
return ${ret}
|
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="$(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
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
|
||||||
|
test ${ret} -eq 0 && echo "$date"
|
||||||
|
return ${ret}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function is_git_clean {
|
function is_git_clean {
|
||||||
# Arguments:
|
# Arguments:
|
||||||
# $1 - Path to git repo
|
# $1 - Path to git repo
|
||||||
|
@ -325,7 +361,8 @@ function update_git_env {
|
||||||
export GIT_COMMIT=$(git rev-parse --short HEAD)
|
export GIT_COMMIT=$(git rev-parse --short HEAD)
|
||||||
export GIT_DIRTY=$(test -n "$(git status --porcelain)" && echo "+CHANGES")
|
export GIT_DIRTY=$(test -n "$(git status --porcelain)" && echo "+CHANGES")
|
||||||
export GIT_IMPORT=github.com/hashicorp/consul/version
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/bin/bash
|
||||||
|
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"
|
||||||
|
|
||||||
|
function usage {
|
||||||
|
cat <<-EOF
|
||||||
|
Usage: ${SCRIPT_NAME} [<options ...>]
|
||||||
|
|
||||||
|
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 $?
|
|
@ -27,12 +27,19 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(ui cli.Ui) *cmd {
|
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{
|
c := &cmd{
|
||||||
ui: ui,
|
ui: ui,
|
||||||
revision: consulversion.GitCommit,
|
revision: consulversion.GitCommit,
|
||||||
version: consulversion.Version,
|
version: consulversion.Version,
|
||||||
versionPrerelease: consulversion.VersionPrerelease,
|
versionPrerelease: consulversion.VersionPrerelease,
|
||||||
versionHuman: consulversion.GetHumanVersion(),
|
versionHuman: consulversion.GetHumanVersion(),
|
||||||
|
buildDate: buildDate,
|
||||||
flags: flag.NewFlagSet("", flag.ContinueOnError),
|
flags: flag.NewFlagSet("", flag.ContinueOnError),
|
||||||
}
|
}
|
||||||
config.AddFlags(c.flags, &c.configLoadOpts)
|
config.AddFlags(c.flags, &c.configLoadOpts)
|
||||||
|
@ -53,6 +60,7 @@ type cmd struct {
|
||||||
version string
|
version string
|
||||||
versionPrerelease string
|
versionPrerelease string
|
||||||
versionHuman string
|
versionHuman string
|
||||||
|
buildDate time.Time
|
||||||
configLoadOpts config.LoadOpts
|
configLoadOpts config.LoadOpts
|
||||||
logger hclog.InterceptLogger
|
logger hclog.InterceptLogger
|
||||||
}
|
}
|
||||||
|
@ -194,6 +202,10 @@ func (c *cmd) run(args []string) int {
|
||||||
segment = "<all>"
|
segment = "<all>"
|
||||||
}
|
}
|
||||||
ui.Info(fmt.Sprintf(" Version: '%s'", c.versionHuman))
|
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 ID: '%s'", config.NodeID))
|
||||||
ui.Info(fmt.Sprintf(" Node name: '%s'", config.NodeName))
|
ui.Info(fmt.Sprintf(" Node name: '%s'", config.NodeName))
|
||||||
if ap := config.PartitionOrEmpty(); ap != "" {
|
if ap := config.PartitionOrEmpty(); ap != "" {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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("Revision %s\n", info.Revision))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffer.WriteString(fmt.Sprintf("Build Date %s\n", info.BuildDate.Format(time.RFC3339)))
|
||||||
|
|
||||||
var supplement string
|
var supplement string
|
||||||
if info.RPC.Default < info.RPC.Max {
|
if info.RPC.Default < info.RPC.Max {
|
||||||
supplement = fmt.Sprintf(" (agent will automatically use protocol >%d when speaking to compatible agents)",
|
supplement = fmt.Sprintf(" (agent will automatically use protocol >%d when speaking to compatible agents)",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -31,11 +32,13 @@ func golden(t *testing.T, name, got string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFormat(t *testing.T) {
|
func TestFormat(t *testing.T) {
|
||||||
|
buildDate, _ := time.Parse(time.RFC3339, "2022-06-01T13:18:45Z")
|
||||||
info := VersionInfo{
|
info := VersionInfo{
|
||||||
HumanVersion: "1.99.3-beta1",
|
HumanVersion: "1.99.3-beta1",
|
||||||
Version: "1.99.3",
|
Version: "1.99.3",
|
||||||
Prerelease: "beta1",
|
Prerelease: "beta1",
|
||||||
Revision: "5e5dbedd47a5f875b60e241c5555a9caab595246",
|
Revision: "5e5dbedd47a5f875b60e241c5555a9caab595246",
|
||||||
|
BuildDate: buildDate,
|
||||||
RPC: RPCVersionInfo{
|
RPC: RPCVersionInfo{
|
||||||
Default: 2,
|
Default: 2,
|
||||||
Min: 1,
|
Min: 1,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"Version": "1.99.3",
|
"Version": "1.99.3",
|
||||||
"Revision": "5e5dbedd47a5f875b60e241c5555a9caab595246",
|
"Revision": "5e5dbedd47a5f875b60e241c5555a9caab595246",
|
||||||
"Prerelease": "beta1",
|
"Prerelease": "beta1",
|
||||||
|
"BuildDate": "2022-06-01T13:18:45Z",
|
||||||
"RPC": {
|
"RPC": {
|
||||||
"Default": 2,
|
"Default": 2,
|
||||||
"Min": 1,
|
"Min": 1,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
Consul v1.99.3-beta1
|
Consul v1.99.3-beta1
|
||||||
Revision 5e5dbedd47a5f875b60e241c5555a9caab595246
|
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)
|
Protocol 2 spoken by default, understands 1 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/consul"
|
"github.com/hashicorp/consul/agent/consul"
|
||||||
"github.com/hashicorp/consul/command/flags"
|
"github.com/hashicorp/consul/command/flags"
|
||||||
|
@ -46,6 +47,7 @@ type VersionInfo struct {
|
||||||
Version string
|
Version string
|
||||||
Revision string
|
Revision string
|
||||||
Prerelease string
|
Prerelease string
|
||||||
|
BuildDate time.Time
|
||||||
RPC RPCVersionInfo
|
RPC RPCVersionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +61,20 @@ func (c *cmd) Run(args []string) int {
|
||||||
c.UI.Error(err.Error())
|
c.UI.Error(err.Error())
|
||||||
return 1
|
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{
|
out, err := formatter.Format(&VersionInfo{
|
||||||
HumanVersion: version.GetHumanVersion(),
|
HumanVersion: version.GetHumanVersion(),
|
||||||
Version: version.Version,
|
Version: version.Version,
|
||||||
Revision: version.GitCommit,
|
Revision: version.GitCommit,
|
||||||
Prerelease: version.VersionPrerelease,
|
Prerelease: version.VersionPrerelease,
|
||||||
|
BuildDate: buildDate,
|
||||||
RPC: RPCVersionInfo{
|
RPC: RPCVersionInfo{
|
||||||
Default: consul.DefaultRPCProtocol,
|
Default: consul.DefaultRPCProtocol,
|
||||||
Min: int(consul.ProtocolVersionMin),
|
Min: int(consul.ProtocolVersionMin),
|
||||||
|
|
|
@ -23,6 +23,10 @@ var (
|
||||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||||
// such as "dev" (in development), "beta", "rc1", etc.
|
// such as "dev" (in development), "beta", "rc1", etc.
|
||||||
VersionPrerelease = "dev"
|
VersionPrerelease = "dev"
|
||||||
|
|
||||||
|
// The date/time of the build (actually the HEAD commit in git, to preserve stability)
|
||||||
|
// 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
|
// GetHumanVersion composes the parts of the version in a way that's suitable
|
||||||
|
|
Loading…
Reference in New Issue