From bf9113ea2ed36ad16678c3c3600cc3de9be85413 Mon Sep 17 00:00:00 2001 From: Filipe Brandenburger Date: Wed, 27 Aug 2014 13:17:52 -0700 Subject: [PATCH] Grab complete version information from git This replaces the gitcommit() shell function with kube::version_ldflags() which prepares a string suitable for Go's -ldflags parameter that fills in the git version fields in pkg/version/base.go. The gitCommit is now a full 40-character SHA1, the gitVersion will be filled from `git describe` output (which will only be available once we have annotated git tags) and gitTreeState will be filled with either "clean" or "dirty" depending on the tree status at the time of the build. Use a kube:: "namespace" (there's really no such a thing in shell, but the illusion still makes it nice) in order to make this nice to import into existing shell scripts or on a shell session. (In the future, I'm planning to introduce more functions and convert some of the top-level commands into other kube::* shell functions.) There's a difference now that -version will report a full SHA1, this will be improved in a follow up change which will improve the Go code for -version handling to give a more meaningful string that should be enough to identify the origin of the binary in git. Tested: - Built it and checked output of -version: $ hack/build-go.sh $ output/go/bin/kubelet -version Kubernetes version 0.1+, build 3ff7ee4b8c843c7767cd856fbf7d3027cd5410e6 - Ran the release script and checked output of the common.sls file: $ release/build-release.sh TESTINSTANCE $ cat output/release/master-release/src/saltbase/pillar/common.sls instance_prefix: TESTINSTANCE-minion go_opt: -ldflags '-X github.com/GoogleCloudPlatform/kubernetes/pkg/version.gitCommit 3ff7ee4b8c843c7767cd856fbf7d3027cd5410e6 -X github.com/GoogleCloudPlatform/kubernetes/pkg/version.gitTreeState clean' - Successful run of hack/e2e-test.sh end-to-end tests. Signed-off-by: Filipe Brandenburger --- hack/build-go.sh | 4 ++-- hack/config-go.sh | 52 ++++++++++++++++++++++++++-------------- release/build-release.sh | 10 ++++---- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/hack/build-go.sh b/hack/build-go.sh index 0ef121f04ea..24707a7b4c5 100755 --- a/hack/build-go.sh +++ b/hack/build-go.sh @@ -32,7 +32,7 @@ cd "${KUBE_REPO_ROOT}" kube::setup_go_environment # Fetch the version. -version=$(gitcommit) +version_ldflags=$(kube::version_ldflags) if [[ $# == 0 ]]; then # Update $@ with the default list of targets to build. @@ -48,4 +48,4 @@ done # our cluster deploy. If we add more command line options to our standard build # we'll want to duplicate them there. As we move to distributing pre- built # binaries we can eliminate this duplication. -go install -ldflags "-X github.com/GoogleCloudPlatform/kubernetes/pkg/version.gitCommit '${version}'" "${binaries[@]}" +go install -ldflags "${version_ldflags}" "${binaries[@]}" diff --git a/hack/config-go.sh b/hack/config-go.sh index 5e990e981d3..6bb6037c681 100644 --- a/hack/config-go.sh +++ b/hack/config-go.sh @@ -17,27 +17,43 @@ # This script sets up a go workspace locally and builds all go components. # You can 'source' this file if you want to set up GOPATH in your local shell. -# gitcommit prints the current Git commit information -function gitcommit() { - set -o errexit - set -o nounset - set -o pipefail +# --- Helper Functions --- - topdir=$(dirname "$0")/.. - cd "${topdir}" +# Function kube::version_ldflags() prints the value that needs to be passed to +# the -ldflags parameter of go build in order to set the Kubernetes based on the +# git tree status. +kube::version_ldflags() { + ( + # Run this in a subshell to prevent settings/variables from leaking. + set -o errexit + set -o nounset + set -o pipefail - # TODO: when we start making tags, switch to git describe? - if git_commit=$(git rev-parse --short "HEAD^{commit}" 2>/dev/null); then - # Check if the tree is dirty. - if ! dirty_tree=$(git status --porcelain) || [[ -n "${dirty_tree}" ]]; then - echo "${git_commit}-dirty" - else - echo "${git_commit}" + unset CDPATH + + cd "${KUBE_REPO_ROOT}" + + declare -a ldflags=() + if git_commit=$(git rev-parse "HEAD^{commit}" 2>/dev/null); then + ldflags+=(-X "${KUBE_GO_PACKAGE}/pkg/version.gitCommit" "${git_commit}") + + # Check if the tree is dirty. + if git_status=$(git status --porcelain) && [[ -z "${git_status}" ]]; then + git_tree_state="clean" + else + git_tree_state="dirty" + fi + ldflags+=(-X "${KUBE_GO_PACKAGE}/pkg/version.gitTreeState" "${git_tree_state}") + + # Use git describe to find the version based on annotated tags. + if git_version=$(git describe --abbrev=14 "${git_commit}^{commit}" 2>/dev/null); then + ldflags+=(-X "${KUBE_GO_PACKAGE}/pkg/version.gitVersion" "${git_version}") + fi fi - else - echo "(none)" - fi - return 0 + + # The -ldflags parameter takes a single string, so join the output. + echo "${ldflags[*]}" + ) } # kube::setup_go_environment will check that `go` and `godep` commands are diff --git a/release/build-release.sh b/release/build-release.sh index 71c87b892b9..57a562f1d9e 100755 --- a/release/build-release.sh +++ b/release/build-release.sh @@ -26,6 +26,8 @@ INSTANCE_PREFIX=$1 KUBE_DIR=$SCRIPT_DIR/.. +. "${KUBE_DIR}/hack/config-go.sh" + # Next build the release tar. This gets copied on to the master and installed # from there. It includes the go source for the necessary servers along with # the salt configs. @@ -41,15 +43,11 @@ cp -r $KUBE_DIR/cluster/saltbase $MASTER_RELEASE_DIR/src/saltbase # Capture the same version we are using to build the client tools and pass that # on. -version=$( - unset IFS - source $KUBE_DIR/hack/config-go.sh - gitcommit -) +version_ldflags=$(kube::version_ldflags) cat << EOF > $MASTER_RELEASE_DIR/src/saltbase/pillar/common.sls instance_prefix: $INSTANCE_PREFIX-minion -go_opt: -ldflags "-X github.com/GoogleCloudPlatform/kubernetes/pkg/version.gitCommit '$version'" +go_opt: -ldflags '${version_ldflags}' EOF function find_go_files() {