Use pversion to retrieve buildtime information
This commit is contained in:
parent
8edecffcc0
commit
38230fc518
@ -9,6 +9,9 @@ WORKDIR /work
|
||||
COPY . .
|
||||
ARG GOPROXY
|
||||
|
||||
ARG KUBE_GIT_VERSION
|
||||
ENV KUBE_GIT_VERSION=$KUBE_GIT_VERSION
|
||||
|
||||
# Build the executable binary (CGO_ENABLED=0 means static linking)
|
||||
# Pass in GOCACHE (build cache) and GOMODCACHE (module cache) so they
|
||||
# can be re-used between image builds.
|
||||
|
@ -1,13 +1,16 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/component-base/version"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"go.pinniped.dev/internal/pversion"
|
||||
)
|
||||
|
||||
//nolint:gochecknoinits
|
||||
@ -15,14 +18,44 @@ func init() {
|
||||
rootCmd.AddCommand(newVersionCommand())
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
output = new(string)
|
||||
// getBuildInfo can be overwritten by tests.
|
||||
getBuildInfo = pversion.Get
|
||||
)
|
||||
|
||||
func newVersionCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "%#v\n", version.Get())
|
||||
return nil
|
||||
},
|
||||
c := &cobra.Command{
|
||||
RunE: runner,
|
||||
Args: cobra.NoArgs, // do not accept positional arguments for this command
|
||||
Use: "version",
|
||||
Short: "Print the version of this Pinniped CLI",
|
||||
}
|
||||
c.Flags().StringVarP(output, "output", "o", "", "one of 'yaml' or 'json'")
|
||||
return c
|
||||
}
|
||||
|
||||
func runner(cmd *cobra.Command, _ []string) error {
|
||||
buildVersion := getBuildInfo()
|
||||
|
||||
switch {
|
||||
case output == nil || *output == "":
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s\n", buildVersion.GitVersion)
|
||||
case *output == "json":
|
||||
bytes, err := json.MarshalIndent(buildVersion, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s\n", bytes)
|
||||
case *output == "yaml":
|
||||
bytes, err := yaml.Marshal(buildVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), string(bytes))
|
||||
default:
|
||||
return fmt.Errorf("'%s' is not a valid option for output", *output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package cmd
|
||||
@ -9,8 +9,10 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/pversion"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -19,8 +21,8 @@ var (
|
||||
version \[flags\]
|
||||
|
||||
Flags:
|
||||
-h, --help help for version
|
||||
|
||||
-h, --help help for version
|
||||
-o, --output string one of 'yaml' or 'json'
|
||||
`)
|
||||
|
||||
knownGoodHelpRegexpForVersion = here.Doc(`
|
||||
@ -30,24 +32,55 @@ var (
|
||||
version \[flags\]
|
||||
|
||||
Flags:
|
||||
-h, --help help for version
|
||||
-h, --help help for version
|
||||
-o, --output string one of 'yaml' or 'json'
|
||||
`)
|
||||
|
||||
emptyVersionRegexp = `version.Info{Major:"", Minor:"", GitVersion:".*", GitCommit:".*", GitTreeState:"", BuildDate:".*", GoVersion:".*", Compiler:".*", Platform:".*/.*"}`
|
||||
jsonRegexp = here.Doc(`{
|
||||
"major": "\d*",
|
||||
"minor": "\d*",
|
||||
"gitVersion": "i am a version for json output",
|
||||
"gitCommit": ".*",
|
||||
"gitTreeState": ".*",
|
||||
"buildDate": ".*",
|
||||
"goVersion": ".*",
|
||||
"compiler": ".*",
|
||||
"platform": ".*/.*"
|
||||
}`)
|
||||
|
||||
yamlRegexp = here.Doc(`buildDate: ".*"
|
||||
compiler: .*
|
||||
gitCommit: .*
|
||||
gitTreeState: .*
|
||||
gitVersion: i am a version for yaml output
|
||||
goVersion: .*
|
||||
major: "\d*"
|
||||
minor: "\d*"
|
||||
platform: .*/.*
|
||||
`)
|
||||
)
|
||||
|
||||
func TestNewVersionCmd(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
getBuildInfo = pversion.Get
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
vars string
|
||||
getBuildInfo func() apimachineryversion.Info
|
||||
wantError bool
|
||||
wantStdoutRegexp string
|
||||
wantStderrRegexp string
|
||||
}{
|
||||
{
|
||||
name: "no flags",
|
||||
args: []string{},
|
||||
wantStdoutRegexp: emptyVersionRegexp + "\n",
|
||||
name: "no flags",
|
||||
args: []string{},
|
||||
getBuildInfo: func() apimachineryversion.Info {
|
||||
return apimachineryversion.Info{GitVersion: "v55.66.44"}
|
||||
},
|
||||
wantStdoutRegexp: "v55.66.44\n",
|
||||
},
|
||||
{
|
||||
name: "help flag passed",
|
||||
@ -61,10 +94,44 @@ func TestNewVersionCmd(t *testing.T) {
|
||||
wantStderrRegexp: `Error: unknown command "tuna" for "version"`,
|
||||
wantStdoutRegexp: knownGoodUsageRegexpForVersion,
|
||||
},
|
||||
{
|
||||
name: "json output",
|
||||
args: []string{"--output", "json"},
|
||||
getBuildInfo: func() apimachineryversion.Info {
|
||||
return apimachineryversion.Info{
|
||||
GitVersion: "i am a version for json output",
|
||||
Platform: "a/b",
|
||||
}
|
||||
},
|
||||
wantStdoutRegexp: jsonRegexp,
|
||||
},
|
||||
{
|
||||
name: "yaml output",
|
||||
args: []string{"--output", "yaml"},
|
||||
getBuildInfo: func() apimachineryversion.Info {
|
||||
return apimachineryversion.Info{
|
||||
GitVersion: "i am a version for yaml output",
|
||||
Platform: "c/d",
|
||||
}
|
||||
},
|
||||
wantStdoutRegexp: yamlRegexp,
|
||||
},
|
||||
{
|
||||
name: "incorrect output",
|
||||
args: []string{"--output", "foo"},
|
||||
wantError: true,
|
||||
wantStderrRegexp: `Error: 'foo' is not a valid option for output`,
|
||||
wantStdoutRegexp: knownGoodUsageRegexpForVersion,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.getBuildInfo != nil {
|
||||
getBuildInfo = tt.getBuildInfo
|
||||
}
|
||||
|
||||
cmd := newVersionCommand()
|
||||
require.NotNil(t, cmd)
|
||||
|
||||
|
2
go.mod
2
go.mod
@ -10,6 +10,7 @@ require (
|
||||
github.com/chromedp/cdproto v0.0.0-20230828023241-f357fd93b5d6
|
||||
github.com/chromedp/chromedp v0.9.2
|
||||
github.com/coreos/go-oidc/v3 v3.6.0
|
||||
github.com/coreos/go-semver v0.3.1
|
||||
github.com/creack/pty v1.1.18
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/felixge/httpsnoop v1.0.3
|
||||
@ -67,7 +68,6 @@ require (
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/cristalhq/jwt/v4 v4.0.2 // indirect
|
||||
|
@ -1,13 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
|
||||
|
||||
KUBE_ROOT="${ROOT}" # required by `hack/lib/version.sh`
|
||||
source "${ROOT}/hack/lib/version.sh"
|
||||
|
||||
kube::version::ldflags
|
||||
echo "-X 'go.pinniped.dev/internal/pversion.gitVersion=$KUBE_GIT_VERSION'"
|
||||
|
@ -1,102 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2014 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#
|
||||
# This has been changed from kube's default version.sh to expect KUBE_GIT_VERSION to be set
|
||||
# by the caller. If it is set, it must be a semver version number, and it will be included
|
||||
# in the result. If it is not set, then defaults indicating that the version is unknown will
|
||||
# be included in the result.
|
||||
#
|
||||
# These changes are to allow the CI build steps to set the version number at build time
|
||||
# without using the original behavior of this script, which was to look at previous git
|
||||
# tags to guess the version number.
|
||||
#
|
||||
|
||||
kube::version::get_version_vars() {
|
||||
local git=(git --work-tree "${KUBE_ROOT}")
|
||||
|
||||
if [[ -n ${KUBE_GIT_COMMIT-} ]] || KUBE_GIT_COMMIT=$("${git[@]}" rev-parse "HEAD^{commit}" 2>/dev/null); then
|
||||
if [[ -z ${KUBE_GIT_TREE_STATE-} ]]; then
|
||||
# Check if the tree is dirty. default to dirty
|
||||
if git_status=$("${git[@]}" status --porcelain 2>/dev/null) && [[ -z ${git_status} ]]; then
|
||||
KUBE_GIT_TREE_STATE="clean"
|
||||
else
|
||||
KUBE_GIT_TREE_STATE="dirty"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If KUBE_GIT_VERSION is supplied
|
||||
if [[ -n "${KUBE_GIT_VERSION:-""}" ]]; then
|
||||
|
||||
# If KUBE_GIT_VERSION is not a valid Semantic Version, then refuse to build.
|
||||
if ! [[ "${KUBE_GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
|
||||
echo "KUBE_GIT_VERSION should be a valid Semantic Version starting with a \"v\". Current value: ${KUBE_GIT_VERSION}"
|
||||
echo "Please see more details here: https://semver.org"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${KUBE_GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?([-].*)?([+].*)?$ ]]; then
|
||||
KUBE_GIT_MAJOR=${BASH_REMATCH[1]}
|
||||
KUBE_GIT_MINOR=${BASH_REMATCH[2]}
|
||||
fi
|
||||
|
||||
else
|
||||
# KUBE_GIT_VERSION was not supplied
|
||||
# These values need to pass the validation in k8s.io/component-base/metrics:
|
||||
# https://github.com/kubernetes/component-base/blob/v0.20.5/metrics/version_parser.go#L28-L50
|
||||
KUBE_GIT_VERSION='v0.0.0'
|
||||
KUBE_GIT_MAJOR='0'
|
||||
KUBE_GIT_MINOR='0'
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 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.
|
||||
# IMPORTANT: if you update any of these, also update the lists in
|
||||
# pkg/version/def.bzl and hack/print-workspace-status.sh.
|
||||
kube::version::ldflags() {
|
||||
kube::version::get_version_vars
|
||||
|
||||
local -a ldflags
|
||||
function add_ldflag() {
|
||||
local key=${1}
|
||||
local val=${2}
|
||||
# If you update these, also update the list component-base/version/def.bzl.
|
||||
ldflags+=(
|
||||
"-X 'k8s.io/client-go/pkg/version.${key}=${val}'"
|
||||
"-X 'k8s.io/component-base/version.${key}=${val}'"
|
||||
)
|
||||
}
|
||||
|
||||
add_ldflag "buildDate" "$(date ${SOURCE_DATE_EPOCH:+"--date=@${SOURCE_DATE_EPOCH}"} -u +'%Y-%m-%dT%H:%M:%SZ')"
|
||||
if [[ -n ${KUBE_GIT_COMMIT-} ]]; then
|
||||
add_ldflag "gitCommit" "${KUBE_GIT_COMMIT}"
|
||||
add_ldflag "gitTreeState" "${KUBE_GIT_TREE_STATE}"
|
||||
fi
|
||||
|
||||
if [[ -n ${KUBE_GIT_VERSION-} ]]; then
|
||||
add_ldflag "gitVersion" "${KUBE_GIT_VERSION}"
|
||||
fi
|
||||
|
||||
if [[ -n ${KUBE_GIT_MAJOR-} && -n ${KUBE_GIT_MINOR-} ]]; then
|
||||
add_ldflag "gitMajor" "${KUBE_GIT_MAJOR}"
|
||||
add_ldflag "gitMinor" "${KUBE_GIT_MINOR}"
|
||||
fi
|
||||
|
||||
# The -ldflags parameter takes a single string, so join the output.
|
||||
echo "${ldflags[*]-}"
|
||||
}
|
@ -206,12 +206,12 @@ registry_repo_tag="${registry_repo}:${tag}"
|
||||
if [[ "$do_build" == "yes" ]]; then
|
||||
# Rebuild the code
|
||||
if [[ "$dockerfile_path" != "" ]]; then
|
||||
log_note "Docker building the app with dockerfile $dockerfile_path..."
|
||||
DOCKER_BUILDKIT=1 docker build . --tag "$registry_repo_tag" --file "$dockerfile_path"
|
||||
log_note "Docker building the app with dockerfile $dockerfile_path and KUBE_GIT_VERSION=$KUBE_GIT_VERSION"
|
||||
DOCKER_BUILDKIT=1 docker build . --tag "$registry_repo_tag" --file "$dockerfile_path" --build-arg "KUBE_GIT_VERSION=$KUBE_GIT_VERSION"
|
||||
else
|
||||
log_note "Docker building the app..."
|
||||
log_note "Docker building the app with KUBE_GIT_VERSION=$KUBE_GIT_VERSION"
|
||||
# DOCKER_BUILDKIT=1 is optional on MacOS but required on linux.
|
||||
DOCKER_BUILDKIT=1 docker build . --tag "$registry_repo_tag"
|
||||
DOCKER_BUILDKIT=1 docker build . --tag "$registry_repo_tag" --build-arg "KUBE_GIT_VERSION=$KUBE_GIT_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiserver
|
||||
@ -14,11 +14,11 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/client-go/pkg/version"
|
||||
|
||||
"go.pinniped.dev/internal/controllerinit"
|
||||
"go.pinniped.dev/internal/issuer"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/pversion"
|
||||
"go.pinniped.dev/internal/registry/credentialrequest"
|
||||
"go.pinniped.dev/internal/registry/whoamirequest"
|
||||
)
|
||||
@ -59,7 +59,7 @@ func (c *Config) Complete() CompletedConfig {
|
||||
&c.ExtraConfig,
|
||||
}
|
||||
|
||||
versionInfo := version.Get()
|
||||
versionInfo := pversion.Get()
|
||||
completedCfg.GenericConfig.Version = &versionInfo
|
||||
|
||||
return CompletedConfig{completedConfig: &completedCfg}
|
||||
|
@ -19,7 +19,6 @@ import (
|
||||
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/client-go/pkg/version"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
conciergeopenapi "go.pinniped.dev/generated/latest/client/concierge/openapi"
|
||||
@ -37,6 +36,7 @@ import (
|
||||
"go.pinniped.dev/internal/issuer"
|
||||
"go.pinniped.dev/internal/kubeclient"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/pversion"
|
||||
"go.pinniped.dev/internal/registry/credentialrequest"
|
||||
)
|
||||
|
||||
@ -266,13 +266,13 @@ func main() error {
|
||||
|
||||
// Dump out the time since compile (mostly useful for benchmarking our local development cycle latency).
|
||||
var timeSinceCompile time.Duration
|
||||
if buildDate, err := time.Parse(time.RFC3339, version.Get().BuildDate); err == nil {
|
||||
if buildDate, err := time.Parse(time.RFC3339, pversion.Get().BuildDate); err == nil {
|
||||
timeSinceCompile = time.Since(buildDate).Round(time.Second)
|
||||
}
|
||||
|
||||
plog.Always("Running concierge",
|
||||
"user-agent", rest.DefaultKubernetesUserAgent(),
|
||||
"version", versionInfo(version.Get()),
|
||||
"version", versionInfo(pversion.Get()),
|
||||
"time-since-build", timeSinceCompile,
|
||||
)
|
||||
|
||||
|
83
internal/pversion/version.go
Normal file
83
internal/pversion/version.go
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
k8sstrings "k8s.io/utils/strings"
|
||||
)
|
||||
|
||||
// readBuildInfo is meant to be overwritten by tests.
|
||||
//
|
||||
//nolint:gochecknoglobals // these are swapped during unit tests.
|
||||
var readBuildInfo = debug.ReadBuildInfo
|
||||
|
||||
// gitVersion is set using a linker flag
|
||||
// -ldflags "-X 'go.pinniped.dev/internal/pversion.gitVersion=v9.8.7'"
|
||||
// (or set for unit tests).
|
||||
//
|
||||
//nolint:gochecknoglobals // these are swapped during unit tests.
|
||||
var gitVersion string
|
||||
|
||||
// Get returns the overall codebase version. It's for detecting
|
||||
// what code a binary was built from.
|
||||
//
|
||||
// This function is very similar to the function defined in k8s.io/component-base (version/version.go)
|
||||
// but is designed to work with golang's VCS build-time information.
|
||||
//
|
||||
// See:
|
||||
// - https://github.com/kubernetes/component-base/blob/v0.28.0/version/version.go#L26-L42
|
||||
// - https://tip.golang.org/doc/go1.18#go-version
|
||||
func Get() apimachineryversion.Info {
|
||||
info := apimachineryversion.Info{
|
||||
Major: "0",
|
||||
Minor: "0",
|
||||
GitVersion: "v0.0.0",
|
||||
GitTreeState: "dirty",
|
||||
GoVersion: runtime.Version(),
|
||||
Compiler: runtime.Compiler,
|
||||
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
gitVersionWithoutLeadingV := gitVersion
|
||||
if strings.HasPrefix(gitVersion, "v") {
|
||||
gitVersionWithoutLeadingV, _ = strings.CutPrefix(gitVersion, "v")
|
||||
}
|
||||
|
||||
gitVersionSemver, err := semver.NewVersion(gitVersionWithoutLeadingV)
|
||||
if err == nil && gitVersionSemver != nil {
|
||||
info.GitVersion = gitVersion
|
||||
info.Major = fmt.Sprintf("%d", gitVersionSemver.Major)
|
||||
info.Minor = fmt.Sprintf("%d", gitVersionSemver.Minor)
|
||||
}
|
||||
|
||||
if debugBuildInfo, ok := readBuildInfo(); ok {
|
||||
for _, buildSetting := range debugBuildInfo.Settings {
|
||||
switch buildSetting.Key {
|
||||
case "vcs.revision":
|
||||
info.GitCommit = buildSetting.Value
|
||||
case "vcs.time":
|
||||
info.BuildDate = buildSetting.Value
|
||||
case "vcs.modified":
|
||||
if buildSetting.Value == "false" {
|
||||
info.GitTreeState = "clean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if info.GitVersion == "v0.0.0" && info.GitCommit != "" {
|
||||
info.GitVersion += fmt.Sprintf("-%s-%s",
|
||||
k8sstrings.ShortenString(info.GitCommit, 8),
|
||||
info.GitTreeState)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
127
internal/pversion/version_test.go
Normal file
127
internal/pversion/version_test.go
Normal file
@ -0,0 +1,127 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
originalGitVersion := gitVersion
|
||||
t.Cleanup(func() {
|
||||
gitVersion = originalGitVersion
|
||||
readBuildInfo = debug.ReadBuildInfo
|
||||
})
|
||||
|
||||
t.Run("when readBuildInfo() returns not ok", func(t *testing.T) {
|
||||
gitVersion = ""
|
||||
readBuildInfo = func() (info *debug.BuildInfo, ok bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
info := apimachineryversion.Info{
|
||||
Major: "0",
|
||||
Minor: "0",
|
||||
GitVersion: "v0.0.0",
|
||||
GitTreeState: "dirty",
|
||||
GoVersion: runtime.Version(),
|
||||
Compiler: runtime.Compiler,
|
||||
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
require.Equal(t, info, Get())
|
||||
})
|
||||
|
||||
t.Run("when readBuildInfo() returns ok", func(t *testing.T) {
|
||||
gitVersion = "9.8.7"
|
||||
readBuildInfo = func() (info *debug.BuildInfo, ok bool) {
|
||||
buildInfo := debug.BuildInfo{
|
||||
Settings: []debug.BuildSetting{
|
||||
{Key: "vcs.revision", Value: "revision-value"},
|
||||
{Key: "vcs.time", Value: "time-value"},
|
||||
{Key: "vcs.modified", Value: "anything but 'true'"},
|
||||
{Key: "other", Value: "ignored"},
|
||||
},
|
||||
}
|
||||
return &buildInfo, true
|
||||
}
|
||||
|
||||
expected := apimachineryversion.Info{
|
||||
Major: "9",
|
||||
Minor: "8",
|
||||
GitVersion: "9.8.7",
|
||||
GitCommit: "revision-value",
|
||||
GitTreeState: "dirty",
|
||||
BuildDate: "time-value",
|
||||
GoVersion: runtime.Version(),
|
||||
Compiler: runtime.Compiler,
|
||||
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
require.Equal(t, expected, Get())
|
||||
})
|
||||
|
||||
t.Run("when readBuildInfo() returns ok but gitVersion is not provided", func(t *testing.T) {
|
||||
gitVersion = ""
|
||||
readBuildInfo = func() (info *debug.BuildInfo, ok bool) {
|
||||
buildInfo := debug.BuildInfo{
|
||||
Settings: []debug.BuildSetting{
|
||||
{Key: "vcs.revision", Value: "384850953501b7d66d466b4ca4d13a81bc54a7c3"},
|
||||
{Key: "vcs.time", Value: "time-value"},
|
||||
{Key: "vcs.modified", Value: "anything but 'true'"},
|
||||
{Key: "other", Value: "ignored"},
|
||||
},
|
||||
}
|
||||
return &buildInfo, true
|
||||
}
|
||||
|
||||
expected := apimachineryversion.Info{
|
||||
Major: "0",
|
||||
Minor: "0",
|
||||
GitVersion: "v0.0.0-38485095-dirty",
|
||||
GitCommit: "384850953501b7d66d466b4ca4d13a81bc54a7c3",
|
||||
GitTreeState: "dirty",
|
||||
BuildDate: "time-value",
|
||||
GoVersion: runtime.Version(),
|
||||
Compiler: runtime.Compiler,
|
||||
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
require.Equal(t, expected, Get())
|
||||
})
|
||||
|
||||
t.Run("when gitVersion is complex", func(t *testing.T) {
|
||||
gitVersion = "v1.2.3-abc123"
|
||||
readBuildInfo = func() (info *debug.BuildInfo, ok bool) {
|
||||
buildInfo := debug.BuildInfo{
|
||||
Settings: []debug.BuildSetting{
|
||||
{Key: "vcs.revision", Value: "abc123"},
|
||||
{Key: "vcs.time", Value: "time-value"},
|
||||
{Key: "vcs.modified", Value: "false"},
|
||||
{Key: "other", Value: "ignored"},
|
||||
},
|
||||
}
|
||||
return &buildInfo, true
|
||||
}
|
||||
|
||||
expected := apimachineryversion.Info{
|
||||
Major: "1",
|
||||
Minor: "2",
|
||||
GitVersion: "v1.2.3-abc123",
|
||||
GitCommit: "abc123",
|
||||
GitTreeState: "clean",
|
||||
BuildDate: "time-value",
|
||||
GoVersion: runtime.Version(),
|
||||
Compiler: runtime.Compiler,
|
||||
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
require.Equal(t, expected, Get())
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2022 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiserver
|
||||
@ -17,11 +17,11 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/pkg/version"
|
||||
|
||||
configv1alpha1clientset "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
|
||||
"go.pinniped.dev/internal/controllerinit"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/pversion"
|
||||
"go.pinniped.dev/internal/registry/clientsecretrequest"
|
||||
)
|
||||
|
||||
@ -61,7 +61,7 @@ func (c *Config) Complete() CompletedConfig {
|
||||
&c.ExtraConfig,
|
||||
}
|
||||
|
||||
versionInfo := version.Get()
|
||||
versionInfo := pversion.Get()
|
||||
completedCfg.GenericConfig.Version = &versionInfo
|
||||
|
||||
return CompletedConfig{completedConfig: &completedCfg}
|
||||
|
@ -33,7 +33,6 @@ import (
|
||||
kubeinformers "k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/pkg/version"
|
||||
"k8s.io/client-go/rest"
|
||||
aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/utils/clock"
|
||||
@ -66,6 +65,7 @@ import (
|
||||
"go.pinniped.dev/internal/oidc/provider"
|
||||
"go.pinniped.dev/internal/oidc/provider/manager"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/pversion"
|
||||
"go.pinniped.dev/internal/secret"
|
||||
"go.pinniped.dev/internal/supervisor/apiserver"
|
||||
supervisorscheme "go.pinniped.dev/internal/supervisor/scheme"
|
||||
@ -681,7 +681,7 @@ func main() error { // return an error instead of plog.Fatal to allow defer stat
|
||||
|
||||
plog.Always("Running supervisor",
|
||||
"user-agent", rest.DefaultKubernetesUserAgent(),
|
||||
"version", versionInfo(version.Get()),
|
||||
"version", versionInfo(pversion.Get()),
|
||||
"arguments", os.Args,
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user