Skip to content

Commit 789c29a

Browse files
committed
OCPBUGS-60903: v2/version: add OCP release info support
This change makes it possible for `oc` to inject the current OCP release version information into the `oc-mirror` binary so that we can report a better version output other than just a commit hash.
1 parent 4a5c543 commit 789c29a

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

v2/internal/pkg/version/version.go

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"os"
88
"runtime"
9+
"strings"
910

1011
"github.com/spf13/cobra"
1112
"k8s.io/apimachinery/pkg/version"
@@ -32,6 +33,37 @@ var (
3233
gitTreeState string
3334
)
3435

36+
var (
37+
// releaseVersionPadded may be replaced in the binary with Release
38+
// Metadata: Version that overrides releaseVersion as a null-terminated
39+
// string within the allowed character length. This allows a distributor to
40+
// override the version without having to rebuild the source.
41+
releaseVersionPadded = "\x00_RELEASE_VERSION_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
42+
releaseVersionPrefix = "\x00_RELEASE_VERSION_LOCATION_\x00"
43+
releaseVersionLength = len(releaseVersionPadded)
44+
)
45+
46+
func ExtractVersion() (version.Info, string, error) {
47+
if strings.HasPrefix(releaseVersionPadded, releaseVersionPrefix) {
48+
return Get(), "", nil
49+
}
50+
nullTerminator := strings.IndexByte(releaseVersionPadded, '\x00')
51+
if nullTerminator == -1 {
52+
// the binary has been altered, but we didn't find a null terminator within the release name constant which is an error
53+
return version.Info{}, "", fmt.Errorf("release name location was replaced but without a null terminator before %d bytes", releaseVersionLength)
54+
} else if nullTerminator > releaseVersionLength {
55+
// the binary has been altered, but the null terminator is *longer* than the constant encoded in the library
56+
return version.Info{}, "", fmt.Errorf("release name location contains no null-terminator and constant is corrupted")
57+
}
58+
releaseName := releaseVersionPadded[:nullTerminator]
59+
if len(releaseName) == 0 {
60+
// the binary has been altered, but the replaced release name is empty which is incorrect
61+
// the oc-mirror binary will not be pinned to Release Metadata: Version
62+
return version.Info{}, "", fmt.Errorf("release name was incorrectly replaced during extract")
63+
}
64+
return Get(), releaseName, nil
65+
}
66+
3567
type VersionOptions struct {
3668
Output string
3769
Short bool
@@ -40,7 +72,8 @@ type VersionOptions struct {
4072

4173
// Version is a struct for version information
4274
type Version struct {
43-
ClientVersion *version.Info `json:"clientVersion,omitempty" yaml:"clientVersion,omitempty"`
75+
ClientVersion *version.Info `json:"clientVersion,omitempty" yaml:"clientVersion,omitempty"`
76+
ReleaseVersion string `json:"releaseVersion,omitempty" yaml:"releaseVersion,omitempty"`
4477
}
4578

4679
func NewVersionCommand(log clog.PluggableLoggerInterface) *cobra.Command {
@@ -86,7 +119,13 @@ func (o *VersionOptions) Validate() error {
86119
func (o *VersionOptions) Run() error {
87120
var versionInfo Version
88121

89-
clientVersion := Get()
122+
clientVersion, reportedVersion, err := ExtractVersion()
123+
if err != nil {
124+
return fmt.Errorf("could not determine binary version: %w", err)
125+
}
126+
if len(reportedVersion) != 0 {
127+
versionInfo.ReleaseVersion = reportedVersion
128+
}
90129
versionInfo.ClientVersion = &clientVersion
91130

92131
switch o.Output {
@@ -97,6 +136,9 @@ func (o *VersionOptions) Run() error {
97136
fmt.Fprintf(os.Stderr, "WARNING: This version information is deprecated and will be replaced with the output from --short. Use --output=yaml|json to get the full version.\n")
98137
fmt.Fprintf(os.Stdout, "Client Version: %#v\n", clientVersion)
99138
}
139+
if len(versionInfo.ReleaseVersion) != 0 {
140+
fmt.Fprintf(os.Stdout, "Client Release Version: %s\n", versionInfo.ReleaseVersion)
141+
}
100142
case "yaml":
101143
marshalled, err := yaml.Marshal(&versionInfo)
102144
if err != nil {

0 commit comments

Comments
 (0)