Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1773257: pkg/version: Prepare of extract-time oc version injection #2682

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmd/openshift-install/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ func setupFileHook(baseDir string) func() {
DisableLevelTruncation: false,
}))

logrus.Debugf(version.String)
versionString, err := version.String()
if err != nil {
logrus.Fatal(err)
}
logrus.Debugf(versionString)
if version.Commit != "" {
logrus.Debugf("Built from commit %s", version.Commit)
}
Expand Down
7 changes: 6 additions & 1 deletion cmd/openshift-install/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ func newVersionCmd() *cobra.Command {
}

func runVersionCmd(cmd *cobra.Command, args []string) error {
fmt.Printf("%s %s\n", os.Args[0], version.Raw)
versionString, err := version.Version()
if err != nil {
return err
}

fmt.Printf("%s %s\n", os.Args[0], versionString)
if version.Commit != "" {
fmt.Printf("built from commit %s\n", version.Commit)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/asset/releaseimage/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
//
// 1. Extract a release binary from the installer image referenced within the release image
// 2. Identify the release image pull spec, add a NUL terminator byte (0x00) to the end, calculate length
// 3. Length must be less than 300 bytes
// 3. Length must be less than the marker length
// 4. Search through the installer binary looking for `\x00_RELEASE_IMAGE_LOCATION_\x00<PADDING_TO_LENGTH>`
// where padding is the ASCII character X and length is the total length of the image
// 5. Overwrite that chunk of the bytes if found, otherwise return error.
// where padding is the ASCII character X and length is the total length of the marker
// 5. Overwrite the beginning of the marker with the release pullspec and a NUL terminator byte (0x00)
//
// On start the installer examines the constant and if it has been modified from the default the installer
// will use that image.
Expand Down
54 changes: 50 additions & 4 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,64 @@
// Package version includes the version information for installer.
package version

import "fmt"
import (
"fmt"
"strings"
)

// This file handles correctly identifying the default release version, which is expected to be
// replaced in the binary post-compile by the release name extracted from a payload. The expected modification is:
//
// 1. Extract a release binary from the installer image referenced within the release image
// 2. Identify the release name, add a NUL terminator byte (0x00) to the end, calculate length
// 3. Length must be less than the marker length
// 4. Search through the installer binary looking for `\x00_RELEASE_VERSION_LOCATION_\x00<PADDING_TO_LENGTH>`
// where padding is the ASCII character X and length is the total length of the marker
// 5. Overwrite the beginning of the marker with the release name and a NUL terminator byte (0x00)

var (
// Raw is the string representation of the version. This will be replaced
// with the calculated version at build time.
// set in hack/build.sh
Raw = "was not built correctly"

// String is the human-friendly representation of the version.
String = fmt.Sprintf("OpenShift Installer %s", Raw)

// Commit is the commit hash from which the installer was built.
// Set in hack/build.sh.
Commit = ""

// defaultReleaseInfoPadded may be replaced in the binary with Release Metadata: Version that overrides defaultVersion as
// a null-terminated string within the allowed character length. This allows a distributor to override the payload
// location without having to rebuild the source.
defaultVersionPadded = "\x00_RELEASE_VERSION_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
defaultVersionPrefix = "\x00_RELEASE_VERSION_LOCATION_\x00"
defaultVersionLength = len(defaultVersionPadded)
)

// String returns the human-friendly representation of the version.
func String() (string, error) {
version, err := Version()
return fmt.Sprintf("OpenShift Installer %s", version), err
}

// Version returns the installer/release version.
func Version() (string, error) {
if strings.HasPrefix(defaultVersionPadded, defaultVersionPrefix) {
return Raw, nil
}
nullTerminator := strings.IndexByte(defaultVersionPadded, '\x00')
if nullTerminator == -1 {
// the binary has been altered, but we didn't find a null terminator within the release name constant which is an error
return Raw, fmt.Errorf("release name location was replaced but without a null terminator before %d bytes", defaultVersionLength)
}
if nullTerminator > len(defaultVersionPadded) {
// the binary has been altered, but the null terminator is *longer* than the constant encoded in the binary
return Raw, fmt.Errorf("release name location contains no null-terminator and constant is corrupted")
}
releaseName := defaultVersionPadded[:nullTerminator]
if len(releaseName) == 0 {
// the binary has been altered, but the replaced release name is empty which is incorrect
// the oc binary will not be pinned to Release Metadata:Version
return Raw, fmt.Errorf("release name was incorrectly replaced during extract")
}
return releaseName, nil
}