Skip to content

Commit 5f2e5fd

Browse files
add clusterctl version
1 parent 0f62f83 commit 5f2e5fd

File tree

4 files changed

+232
-3
lines changed

4 files changed

+232
-3
lines changed

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ ifeq ($(SELINUX_ENABLED),1)
8585
DOCKER_VOL_OPTS?=:z
8686
endif
8787

88+
# Set build time variables including version details
89+
LDFLAGS := $(shell hack/version.sh)
90+
8891
all: test manager clusterctl
8992

9093
help: ## Display this help
@@ -133,7 +136,7 @@ managers: ## Build all managers
133136

134137
.PHONY: clusterctl
135138
clusterctl: ## Build clusterctl binary
136-
go build -o bin/clusterctl sigs.k8s.io/cluster-api/cmd/clusterctl
139+
go build -ldflags "$(LDFLAGS)" -o bin/clusterctl sigs.k8s.io/cluster-api/cmd/clusterctl
137140

138141
$(KUSTOMIZE): $(TOOLS_DIR)/go.mod # Build kustomize from tools folder.
139142
cd $(TOOLS_DIR); go build -tags=tools -o $(BIN_DIR)/kustomize sigs.k8s.io/kustomize/kustomize/v3

cmd/clusterctl/cmd/version.go

+66-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019 The Kubernetes Authors.
2+
Copyright 2020 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -16,4 +16,68 @@ limitations under the License.
1616

1717
package cmd
1818

19-
// TODO: version command
19+
import (
20+
"encoding/json"
21+
"fmt"
22+
23+
"github.com/pkg/errors"
24+
"github.com/spf13/cobra"
25+
"sigs.k8s.io/cluster-api/cmd/version"
26+
"sigs.k8s.io/yaml"
27+
)
28+
29+
// Version provides the version information of clusterctl
30+
type Version struct {
31+
ClientVersion *version.Info `json:"clusterctl"`
32+
}
33+
34+
type versionOptions struct {
35+
output string
36+
}
37+
38+
var vo = &versionOptions{}
39+
40+
var versionCmd = &cobra.Command{
41+
Use: "version",
42+
Short: "Print version of clusterawsadm",
43+
Args: cobra.ExactArgs(0),
44+
RunE: func(cmd *cobra.Command, args []string) error {
45+
return runVersion()
46+
},
47+
}
48+
49+
func init() {
50+
versionCmd.Flags().StringVarP(&vo.output, "output", "o", "", "Output format; available options are 'yaml', 'json' and 'short'")
51+
52+
RootCmd.AddCommand(versionCmd)
53+
}
54+
55+
func runVersion() error {
56+
clientVersion := version.Get()
57+
v := Version{
58+
ClientVersion: &clientVersion,
59+
}
60+
61+
switch vo.output {
62+
case "":
63+
fmt.Printf("clusterctl version: %#v\n", v.ClientVersion)
64+
case "short":
65+
fmt.Printf("%s\n", v.ClientVersion.GitVersion)
66+
case "yaml":
67+
y, err := yaml.Marshal(&v)
68+
if err != nil {
69+
return err
70+
}
71+
fmt.Print(string(y))
72+
case "json":
73+
y, err := json.MarshalIndent(&v, "", " ")
74+
if err != nil {
75+
return err
76+
}
77+
fmt.Println(string(y))
78+
default:
79+
return errors.Errorf("invalid output format: %s", vo.output)
80+
}
81+
82+
return nil
83+
}

cmd/version/version.go

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package version
18+
19+
import (
20+
"fmt"
21+
"runtime"
22+
)
23+
24+
var (
25+
gitMajor string // major version, always numeric
26+
gitMinor string // minor version, numeric possibly followed by "+"
27+
gitVersion string // semantic version, derived by build scripts
28+
gitCommit string // sha1 from git, output of $(git rev-parse HEAD)
29+
gitTreeState string // state of git tree, either "clean" or "dirty"
30+
buildDate string // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
31+
)
32+
33+
type Info struct {
34+
Major string `json:"major,omitempty"`
35+
Minor string `json:"minor,omitempty"`
36+
GitVersion string `json:"gitVersion,omitempty"`
37+
GitCommit string `json:"gitCommit,omitempty"`
38+
GitTreeState string `json:"gitTreeState,omitempty"`
39+
BuildDate string `json:"buildDate,omitempty"`
40+
GoVersion string `json:"goVersion,omitempty"`
41+
Compiler string `json:"compiler,omitempty"`
42+
Platform string `json:"platform,omitempty"`
43+
}
44+
45+
func Get() Info {
46+
return Info{
47+
Major: gitMajor,
48+
Minor: gitMinor,
49+
GitVersion: gitVersion,
50+
GitCommit: gitCommit,
51+
GitTreeState: gitTreeState,
52+
BuildDate: buildDate,
53+
GoVersion: runtime.Version(),
54+
Compiler: runtime.Compiler,
55+
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
56+
}
57+
}
58+
59+
// String returns info as a human-friendly version string.
60+
func (info Info) String() string {
61+
return info.GitVersion
62+
}

hack/version.sh

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/bash
2+
# Copyright 2020 The Kubernetes Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -o errexit
17+
set -o nounset
18+
set -o pipefail
19+
20+
version::get_version_vars() {
21+
GIT_COMMIT="$(git rev-parse HEAD^{commit})"
22+
23+
if git_status=$(git status --porcelain 2>/dev/null) && [[ -z ${git_status} ]]; then
24+
GIT_TREE_STATE="clean"
25+
else
26+
GIT_TREE_STATE="dirty"
27+
fi
28+
29+
# stolen from k8s.io/hack/lib/version.sh
30+
# Use git describe to find the version based on tags.
31+
if GIT_VERSION=$(git describe --tags --abbrev=14 2>/dev/null); then
32+
# This translates the "git describe" to an actual semver.org
33+
# compatible semantic version that looks something like this:
34+
# v1.1.0-alpha.0.6+84c76d1142ea4d
35+
#
36+
# TODO: We continue calling this "git version" because so many
37+
# downstream consumers are expecting it there.
38+
DASHES_IN_VERSION=$(echo "${GIT_VERSION}" | sed "s/[^-]//g")
39+
if [[ "${DASHES_IN_VERSION}" == "---" ]] ; then
40+
# We have distance to subversion (v1.1.0-subversion-1-gCommitHash)
41+
GIT_VERSION=$(echo "${GIT_VERSION}" | sed "s/-\([0-9]\{1,\}\)-g\([0-9a-f]\{14\}\)$/.\1\-\2/")
42+
elif [[ "${DASHES_IN_VERSION}" == "--" ]] ; then
43+
# We have distance to base tag (v1.1.0-1-gCommitHash)
44+
GIT_VERSION=$(echo "${GIT_VERSION}" | sed "s/-g\([0-9a-f]\{14\}\)$/-\1/")
45+
fi
46+
if [[ "${GIT_TREE_STATE}" == "dirty" ]]; then
47+
# git describe --dirty only considers changes to existing files, but
48+
# that is problematic since new untracked .go files affect the build,
49+
# so use our idea of "dirty" from git status instead.
50+
GIT_VERSION+="-dirty"
51+
fi
52+
53+
54+
# Try to match the "git describe" output to a regex to try to extract
55+
# the "major" and "minor" versions and whether this is the exact tagged
56+
# version or whether the tree is between two tagged versions.
57+
if [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?([-].*)?([+].*)?$ ]]; then
58+
GIT_MAJOR=${BASH_REMATCH[1]}
59+
GIT_MINOR=${BASH_REMATCH[2]}
60+
fi
61+
62+
# If GIT_VERSION is not a valid Semantic Version, then refuse to build.
63+
if ! [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
64+
echo "GIT_VERSION should be a valid Semantic Version. Current value: ${GIT_VERSION}"
65+
echo "Please see more details here: https://semver.org"
66+
exit 1
67+
fi
68+
fi
69+
70+
GIT_RELEASE_TAG=$(git describe --abbrev=0 --tags)
71+
GIT_RELEASE_COMMIT=$(git rev-list -n 1 ${GIT_RELEASE_TAG})
72+
}
73+
74+
# stolen from k8s.io/hack/lib/version.sh and modified
75+
# Prints the value that needs to be passed to the -ldflags parameter of go build
76+
version::ldflags() {
77+
version::get_version_vars
78+
79+
local -a ldflags
80+
function add_ldflag() {
81+
local key=${1}
82+
local val=${2}
83+
ldflags+=(
84+
"-X 'sigs.k8s.io/cluster-api/cmd/version.${key}=${val}'"
85+
)
86+
}
87+
88+
add_ldflag "buildDate" "$(date ${SOURCE_DATE_EPOCH:+"--date=@${SOURCE_DATE_EPOCH}"} -u +'%Y-%m-%dT%H:%M:%SZ')"
89+
add_ldflag "gitCommit" "${GIT_COMMIT}"
90+
add_ldflag "gitTreeState" "${GIT_TREE_STATE}"
91+
add_ldflag "gitMajor" "${GIT_MAJOR}"
92+
add_ldflag "gitMinor" "${GIT_MINOR}"
93+
add_ldflag "gitVersion" "${GIT_VERSION}"
94+
add_ldflag "gitReleaseCommit" "${GIT_RELEASE_COMMIT}"
95+
96+
# The -ldflags parameter takes a single string, so join the output.
97+
echo "${ldflags[*]-}"
98+
}
99+
100+
version::ldflags

0 commit comments

Comments
 (0)