Skip to content

Commit 03dfc1e

Browse files
Merge pull request openshift#8515 from jeffdyoung/MULTIARCH-4568
MULTIARCH-4568: Print release image arch and default arch when the payload is multi
2 parents 318dc21 + e4e1679 commit 03dfc1e

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

cmd/openshift-install/version.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"os"
6+
"strings"
67

78
"github.com/spf13/cobra"
89

@@ -33,6 +34,14 @@ func runVersionCmd(cmd *cobra.Command, args []string) error {
3334
if image, err := releaseimage.Default(); err == nil {
3435
fmt.Printf("release image %s\n", image)
3536
}
36-
fmt.Printf("release architecture %s\n", version.DefaultArch())
37+
releaseArch, err := version.ReleaseArchitecture()
38+
if err != nil {
39+
return err
40+
}
41+
fmt.Printf("release architecture %s\n", releaseArch)
42+
if strings.Contains(releaseArch, "multi") || strings.Contains(releaseArch, "unknown") {
43+
fmt.Printf("default architecture %s\n", version.DefaultArch())
44+
}
45+
3746
return nil
3847
}

pkg/version/version.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ package version
33

44
import (
55
"fmt"
6+
"os"
67
"strings"
78

9+
"github.com/sirupsen/logrus"
10+
811
"github.com/openshift/installer/pkg/types"
912
)
1013

@@ -34,12 +37,23 @@ var (
3437
// Set in hack/build.sh.
3538
defaultArch = "amd64"
3639

40+
// releaseArchitecture is the architecture of the release payload: multi, amd64, arm64, ppc64le, or s390x.
41+
// we don't know the releaseArchitecure by default "".
42+
releaseArchitecture = ""
43+
3744
// defaultReleaseInfoPadded may be replaced in the binary with Release Metadata: Version that overrides defaultVersion as
3845
// a null-terminated string within the allowed character length. This allows a distributor to override the payload
3946
// location without having to rebuild the source.
4047
defaultVersionPadded = "\x00_RELEASE_VERSION_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
4148
defaultVersionPrefix = "\x00_RELEASE_VERSION_LOCATION_\x00"
4249
defaultVersionLength = len(defaultVersionPadded)
50+
51+
// releaseArchitecturesPadded may be replaced in the binary with Release Image Architecture(s): RELEASE_ARCHITECTURE that overrides releaseArchitecture as
52+
// a null-terminated string within the allowed character length. This allows a distributor to override the payload
53+
// location without having to rebuild the source.
54+
releaseArchitecturesPadded = "\x00_RELEASE_ARCHITECTURE_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
55+
releaseArchitecturesPrefix = "\x00_RELEASE_ARCHITECTURE_LOCATION_\x00"
56+
releaseArchitecturesLength = len(releaseArchitecturesPadded)
4357
)
4458

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

88+
// ReleaseArchitecture returns the release image cpu architecture version.
89+
func ReleaseArchitecture() (string, error) {
90+
ri, okRI := os.LookupEnv("OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE")
91+
if okRI {
92+
logrus.Warnf("Found override for release image (%s). Release Image Architecture is unknown", ri)
93+
return "unknown", nil
94+
}
95+
if strings.HasPrefix(releaseArchitecturesPadded, releaseArchitecturesPrefix) {
96+
logrus.Warn("Release Image Architecture not detected. Release Image Architecture is unknown")
97+
return "unknown", nil
98+
}
99+
nullTerminator := strings.IndexByte(releaseArchitecturesPadded, '\x00')
100+
if nullTerminator == -1 {
101+
// the binary has been altered, but we didn't find a null terminator within the release architecture constant which is an error
102+
return Raw, fmt.Errorf("release architecture location was replaced but without a null terminator before %d bytes", releaseArchitecturesLength)
103+
}
104+
if nullTerminator > len(releaseArchitecturesPadded) {
105+
// the binary has been altered, but the null terminator is *longer* than the constant encoded in the binary
106+
return Raw, fmt.Errorf("release architecture location contains no null-terminator and constant is corrupted")
107+
}
108+
releaseArchitecture = releaseArchitecturesPadded[:nullTerminator]
109+
if len(releaseArchitecture) == 0 {
110+
// the binary has been altered, but the replaced release architecture is empty which is incorrect
111+
return Raw, fmt.Errorf("release architecture was incorrectly replaced during extract")
112+
}
113+
return cleanArch(releaseArchitecture), nil
114+
}
115+
116+
// cleanArch oc will embed linux/<arch> or multi (linux/<arch>) we want to clean this up so validation can more cleanly use this method.
117+
// multi (linux/amd64) -> multi
118+
// linux/amd64 -> amd64
119+
// linux/<arch> -> <arch>.
120+
func cleanArch(releaseArchitecture string) string {
121+
if strings.HasPrefix(releaseArchitecture, "multi") {
122+
return "multi"
123+
}
124+
// remove 'linux/', we just want <arch>
125+
return strings.ReplaceAll(releaseArchitecture, "linux/", "")
126+
}
127+
74128
// DefaultArch returns the default release architecture
75129
func DefaultArch() types.Architecture {
76130
return types.Architecture(defaultArch)

0 commit comments

Comments
 (0)