Skip to content

Commit

Permalink
pkg/version: Prepare of extract-time oc version injection
Browse files Browse the repository at this point in the history
Set a marker for oc to inject the release version to avoid potential
confusion from:

  $ oc adm release extract --command=openshift-install quay.io/openshift-release-dev/ocp-release:4.2.7
  $ ./openshift-install version
  ./openshift-install v4.2.5
  built from commit 425e4ff
  release image quay.io/openshift-release-dev/ocp-release@sha256:bac62983757570b9b8f8bc84c740782984a255c16372b3e30cfc8b52c0a187b9

The actual oc injection logic is in [1].

[1]: openshift/oc#165
  • Loading branch information
wking committed Nov 16, 2019
1 parent 55ac3ac commit e24708d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 9 deletions.
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
}

0 comments on commit e24708d

Please sign in to comment.