Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cmd/openshift-install/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"strings"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -33,6 +34,14 @@ func runVersionCmd(cmd *cobra.Command, args []string) error {
if image, err := releaseimage.Default(); err == nil {
fmt.Printf("release image %s\n", image)
}
fmt.Printf("release architecture %s\n", version.DefaultArch())
releaseArch, err := version.ReleaseArchitecture()
if err != nil {
return err
}
fmt.Printf("release architecture %s\n", releaseArch)
if strings.Contains(releaseArch, "multi") || strings.Contains(releaseArch, "unknown") {
fmt.Printf("default architecture %s\n", version.DefaultArch())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@r4f4 Thought it might be a good idea to print default arch when release arch is unknown? This would give some indication of what the installer will do?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 from me.

}

return nil
}
54 changes: 54 additions & 0 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package version

import (
"fmt"
"os"
"strings"

"github.com/sirupsen/logrus"

"github.com/openshift/installer/pkg/types"
)

Expand Down Expand Up @@ -34,12 +37,23 @@ var (
// Set in hack/build.sh.
defaultArch = "amd64"

// releaseArchitecture is the architecture of the release payload: multi, amd64, arm64, ppc64le, or s390x.
// we don't know the releaseArchitecure by default "".
releaseArchitecture = ""

// 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)

// releaseArchitecturesPadded may be replaced in the binary with Release Image Architecture(s): RELEASE_ARCHITECTURE that overrides releaseArchitecture 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.
releaseArchitecturesPadded = "\x00_RELEASE_ARCHITECTURE_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
releaseArchitecturesPrefix = "\x00_RELEASE_ARCHITECTURE_LOCATION_\x00"
releaseArchitecturesLength = len(releaseArchitecturesPadded)
)

// String returns the human-friendly representation of the version.
Expand Down Expand Up @@ -71,6 +85,46 @@ func Version() (string, error) {
return releaseName, nil
}

// ReleaseArchitecture returns the release image cpu architecture version.
func ReleaseArchitecture() (string, error) {
ri, okRI := os.LookupEnv("OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE")
if okRI {
logrus.Warnf("Found override for release image (%s). Release Image Architecture is unknown", ri)
return "unknown", nil
}
if strings.HasPrefix(releaseArchitecturesPadded, releaseArchitecturesPrefix) {
logrus.Warn("Release Image Architecture not detected. Release Image Architecture is unknown")
return "unknown", nil
}
nullTerminator := strings.IndexByte(releaseArchitecturesPadded, '\x00')
if nullTerminator == -1 {
// the binary has been altered, but we didn't find a null terminator within the release architecture constant which is an error
return Raw, fmt.Errorf("release architecture location was replaced but without a null terminator before %d bytes", releaseArchitecturesLength)
}
if nullTerminator > len(releaseArchitecturesPadded) {
// the binary has been altered, but the null terminator is *longer* than the constant encoded in the binary
return Raw, fmt.Errorf("release architecture location contains no null-terminator and constant is corrupted")
}
releaseArchitecture = releaseArchitecturesPadded[:nullTerminator]
if len(releaseArchitecture) == 0 {
// the binary has been altered, but the replaced release architecture is empty which is incorrect
return Raw, fmt.Errorf("release architecture was incorrectly replaced during extract")
}
return cleanArch(releaseArchitecture), nil
}

// cleanArch oc will embed linux/<arch> or multi (linux/<arch>) we want to clean this up so validation can more cleanly use this method.
// multi (linux/amd64) -> multi
// linux/amd64 -> amd64
// linux/<arch> -> <arch>.
func cleanArch(releaseArchitecture string) string {
if strings.HasPrefix(releaseArchitecture, "multi") {
return "multi"
}
// remove 'linux/', we just want <arch>
return strings.ReplaceAll(releaseArchitecture, "linux/", "")
}

// DefaultArch returns the default release architecture
func DefaultArch() types.Architecture {
return types.Architecture(defaultArch)
Expand Down