Skip to content
Open
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
4 changes: 2 additions & 2 deletions pkg/asset/installconfig/aws/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import (
"github.com/sirupsen/logrus"

"github.com/openshift/installer/pkg/rhcos"
"github.com/openshift/installer/pkg/types"
"github.com/openshift/installer/pkg/types/aws"
"github.com/openshift/installer/pkg/version"
)

// Platform collects AWS-specific configuration.
func Platform(ctx context.Context) (*aws.Platform, error) {
architecture := version.DefaultArch()
architecture := types.DefaultArch()
regions, err := knownPublicRegions(architecture, rhcos.DefaultOSImageStream)
if err != nil {
return nil, fmt.Errorf("failed to get AWS public regions: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/rhcos/iso.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func GetMetalArtifact(ctx context.Context, archName string) (stream.PlatformArti
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

st, err := rhcos.FetchCoreOSBuild(ctx, rhcos.DefaultOSImageStream)
st, err := rhcos.FetchCoreOSBuild(ctx, types.OSImageStreamRHCOS9)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just waiting for MCO-2200 to land?

Note that this affects not only ABI, but also the baremetal IPI bootstrap VM.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is this just waiting for MCO-2200 to land?

Note that this affects not only ABI, but also the baremetal IPI bootstrap VM.

Yes, and it's something I knew and identified.
We have been already booting with RHEL 9 and pivoting to RHEL 10 during the MCD firstboot so I don't think having this for a short period of time (if the ABI change doesn't land before) is problematic.

if err != nil {
return stream.PlatformArtifacts{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/rhcos/releaseextract.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func (r *releasePayload) getHashFromInstaller(architecture string) (bool, string
ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
defer cancel()

st, err := rhcos.FetchCoreOSBuild(ctx, rhcos.DefaultOSImageStream)
st, err := rhcos.FetchCoreOSBuild(ctx, types.OSImageStreamRHCOS9)
if err != nil {
return false, ""
}
Expand Down
11 changes: 10 additions & 1 deletion pkg/coreoscli/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"os"

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

"github.com/spf13/cobra"

"github.com/openshift/installer/pkg/rhcos"
Expand All @@ -13,11 +15,12 @@ import (

// printStreamJSON is the implementation of print-stream-json
func printStreamJSON(cmd *cobra.Command, _ []string) error {
osImageStream := rhcos.DefaultOSImageStream
streamFlag, err := cmd.Flags().GetString("stream")
if err != nil {
return err
}

osImageStream := rhcos.DefaultOSImageStream
if streamFlag != "" {
s := types.OSImageStream(streamFlag)
valid := false
Expand All @@ -31,7 +34,13 @@ func printStreamJSON(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("invalid value %q for --stream; must be one of %v", streamFlag, types.OSImageStreamValues)
}
osImageStream = s
} else {
// If no stream is given get it from the default FeatureSet for the build version
installConfig := types.InstallConfig{}
defaults.SetInstallConfigDefaults(&installConfig)
osImageStream = installConfig.OSImageStream
}

streamData, err := rhcos.FetchRawCoreOSStream(context.Background(), osImageStream)
if err != nil {
return err
Expand Down
6 changes: 3 additions & 3 deletions pkg/destroy/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ func Destroy(ctx context.Context, dir string) (err error) {
}
}

featureSets, ok := types.FeatureSetsForProfile()
if !ok {
return fmt.Errorf("no feature sets for cluster profile %q", types.GetClusterProfileName())
featureSets, err := types.FeatureSetsForProfile()
if err != nil {
return fmt.Errorf("no feature sets for cluster profile %q. %w", types.GetClusterProfileName(), err)
}
fg := featuregates.FeatureGateFromFeatureSets(featureSets, metadata.FeatureSet, metadata.CustomFeatureSet)

Expand Down
20 changes: 3 additions & 17 deletions pkg/rhcos/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@ import (
"github.com/openshift/installer/pkg/types"
)

const (
// DefaultOSImageStream is the OS image stream used when the install-config
// does not specify one.
DefaultOSImageStream = types.OSImageStreamRHCOS9

payloadImageStreamTagRHCOS9 = "rhel-coreos"
payloadImageStreamTagRHCOS10 = "rhel-coreos-10"
)
// DefaultOSImageStream is the OS image stream used when the install-config
// does not specify one.
const DefaultOSImageStream = types.OSImageStreamRHCOS10

func getStreamFileName(stream types.OSImageStream) string {
return fmt.Sprintf("coreos/coreos-%v.json", stream)
Expand All @@ -24,12 +19,3 @@ func getStreamFileName(stream types.OSImageStream) string {
func getMarketplaceStreamFileName(stream types.OSImageStream) string {
return fmt.Sprintf("coreos/marketplace/coreos-%v.json", stream)
}

// GetPayloadImageStreamTag returns the payload image stream tag corresponding
// to the given OS image stream.
func GetPayloadImageStreamTag(stream types.OSImageStream) string {
if stream == types.OSImageStreamRHCOS9 {
return payloadImageStreamTagRHCOS9
}
return payloadImageStreamTagRHCOS10
}
6 changes: 0 additions & 6 deletions pkg/rhcos/stream_scos.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,3 @@ func getMarketplaceStreamFileName(_ types.OSImageStream) string {
// functions will gracefully handle the missing file.
return "coreos/marketplace/marketplace-scos.json"
}

// GetPayloadImageStreamTag returns the payload image stream tag corresponding
// to the given OS image stream. For SCOS, this always returns "stream-coreos".
func GetPayloadImageStreamTag(_ types.OSImageStream) string {
return "stream-coreos"
}
6 changes: 6 additions & 0 deletions pkg/types/defaults/installconfig.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package defaults

import (
"github.com/openshift/api/features"
operv1 "github.com/openshift/api/operator/v1"
"github.com/openshift/installer/pkg/ipnet"
"github.com/openshift/installer/pkg/rhcos"
Expand Down Expand Up @@ -137,6 +138,11 @@ func SetInstallConfigDefaults(c *types.InstallConfig) {

if c.OSImageStream == "" {
c.OSImageStream = rhcos.DefaultOSImageStream
if !c.IsSCOS() && !c.Enabled(features.FeatureGateOSStreams) {
// Use RHEL 9 by default only if the FG is disabled
// OKD uses only 1 stream so this condition doesn't apply
c.OSImageStream = types.OSImageStreamRHCOS9
}
}

if c.AdditionalTrustBundlePolicy == "" {
Expand Down
3 changes: 1 addition & 2 deletions pkg/types/defaults/machinepools.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
azuredefaults "github.com/openshift/installer/pkg/types/azure/defaults"
"github.com/openshift/installer/pkg/types/gcp"
gcpdefaults "github.com/openshift/installer/pkg/types/gcp/defaults"
"github.com/openshift/installer/pkg/version"
)

// SetMachinePoolDefaults sets the defaults for the machine pool.
Expand All @@ -26,7 +25,7 @@ func SetMachinePoolDefaults(p *types.MachinePool, platform *types.Platform) {
p.Hyperthreading = types.HyperthreadingEnabled
}
if p.Architecture == "" {
p.Architecture = version.DefaultArch()
p.Architecture = types.DefaultArch()
}

if p.Fencing != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/types/installconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,9 +623,9 @@ func (c *InstallConfig) EnabledFeatureGates() featuregates.FeatureGate {
customFS = featuregates.GenerateCustomFeatures(c.FeatureGates)
}

featureSets, ok := FeatureSetsForProfile()
if !ok {
logrus.Warnf("no feature sets for cluster profile %q", GetClusterProfileName())
featureSets, err := FeatureSetsForProfile()
if err != nil {
logrus.Warnf("no feature sets for cluster profile %q. %v", GetClusterProfileName(), err)
}
fg := featuregates.FeatureGateFromFeatureSets(featureSets, c.FeatureSet, customFS)

Expand Down
26 changes: 18 additions & 8 deletions pkg/types/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"os"

"github.com/openshift/installer/pkg/version"

"github.com/sirupsen/logrus"
capz "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"

Expand Down Expand Up @@ -43,21 +45,24 @@ func MachineNetworksToCIDRs(nets []MachineNetworkEntry) []configv1.CIDR {
return res
}

// openshiftMajorVersion is the major version of OpenShift that this installer targets.
// This is used when looking up feature sets from the API.
const openshiftMajorVersion uint64 = 4

// FeatureSetsForProfile returns the feature sets for the current cluster profile
// and OpenShift major version.
func FeatureSetsForProfile() (map[configv1.FeatureSet]*features.FeatureGateEnabledDisabled, bool) {
func FeatureSetsForProfile() (map[configv1.FeatureSet]*features.FeatureGateEnabledDisabled, error) {
clusterProfile := GetClusterProfileName()
allSets := features.AllFeatureSets()
versionSets, ok := allSets[openshiftMajorVersion]
versionInfo, err := version.GetVersionInfo()
if err != nil {
return nil, fmt.Errorf("unable to determine version information to calculate FeatureSets: %w", err)
}
versionSets, ok := allSets[uint64(versionInfo.Major)]
if !ok {
return nil, false
return nil, fmt.Errorf("no FeatureSet available for version %d", versionInfo.Major)
}
profileSets, ok := versionSets[clusterProfile]
return profileSets, ok
if !ok {
return nil, fmt.Errorf("no FeatureSet available for %s cluster profile", clusterProfile)
}
return profileSets, nil
}

// GetClusterProfileName utility method to retrieve the cluster profile setting. This is used
Expand Down Expand Up @@ -103,3 +108,8 @@ func (c *InstallConfig) CreateAzureIdentity() bool {

return defaultNeedsID && (computeNeedsID || cpNeedsID)
}

// DefaultArch returns the default release architecture
func DefaultArch() Architecture {
return Architecture(version.DefaultArch())
}
8 changes: 4 additions & 4 deletions pkg/types/validation/installconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -1574,9 +1574,9 @@ func validateAdditionalCABundlePolicy(c *types.InstallConfig) error {
func ValidateFeatureSet(c *types.InstallConfig) field.ErrorList {
allErrs := field.ErrorList{}

featureSets, ok := types.FeatureSetsForProfile()
if !ok {
logrus.Warnf("no feature sets for cluster profile %q", types.GetClusterProfileName())
featureSets, err := types.FeatureSetsForProfile()
if err != nil {
logrus.Warnf("no feature sets for cluster profile %q. %s", types.GetClusterProfileName(), err)
}
if _, ok := featureSets[c.FeatureSet]; c.FeatureSet != configv1.CustomNoUpgrade && !ok {
sortedFeatureSets := func() []string {
Expand Down Expand Up @@ -1679,7 +1679,7 @@ func validateGatedFeatures(c *types.InstallConfig) field.ErrorList {
func validateReleaseArchitecture(controlPlanePool *types.MachinePool, computePool []types.MachinePool, releaseArch types.Architecture) field.ErrorList {
allErrs := field.ErrorList{}

clusterArch := version.DefaultArch()
clusterArch := types.DefaultArch()
if controlPlanePool != nil && controlPlanePool.Architecture != "" {
clusterArch = controlPlanePool.Architecture
}
Expand Down
63 changes: 57 additions & 6 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,51 @@ package version
import (
"fmt"
"os"
"strconv"
"strings"

"github.com/sirupsen/logrus"

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

// VersionInfo represents a parsed semantic version.
type VersionInfo struct {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

suggestion (non-blocking): This repo has the following semver libraries already vendored which could be a more robust implementation:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I known, and I've seen them. Unfortunately, some of them are strict with semver format and requires the version to start with v, others don't. Given that not only the Makefile is in charge of injecting the version, I prefer to use this hand-crafted methods that at least is safe and should do the job to get major, minor and patch fields.

Major int
Minor int
Patch int
}

// GetVersionInfo returns the build version parsed as a VersionInfo.
func GetVersionInfo() (VersionInfo, error) {
s, err := Version()
if err != nil {
return VersionInfo{}, err
}
return parseVersionInfo(s)
}

func parseVersionInfo(s string) (VersionInfo, error) {
if idx := strings.Index(s, "-"); idx != -1 {
s = s[:idx]
}
parts := strings.Split(s, ".")
if len(parts) == 0 {
return VersionInfo{}, fmt.Errorf("invalid version %q", s)
}
var v VersionInfo
major, err := strconv.Atoi(parts[0])
if err != nil {
return VersionInfo{}, fmt.Errorf("invalid version %q", s)
}
v.Major = major
if len(parts) > 1 {
v.Minor, _ = strconv.Atoi(parts[1])
}
if len(parts) > 2 {
v.Patch, _ = strconv.Atoi(parts[2])
}
return v, nil
}

// 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:
//
Expand Down Expand Up @@ -65,7 +103,7 @@ func String() (string, error) {
// Version returns the installer/release version.
func Version() (string, error) {
if strings.HasPrefix(defaultVersionPadded, defaultVersionPrefix) {
return Raw, nil
return removeGoVersionPrefix(Raw), nil
}
nullTerminator := strings.IndexByte(defaultVersionPadded, '\x00')
if nullTerminator == -1 {
Expand Down Expand Up @@ -125,7 +163,20 @@ func cleanArch(releaseArchitecture string) string {
return strings.ReplaceAll(releaseArchitecture, "linux/", "")
}

// DefaultArch returns the default release architecture
func DefaultArch() types.Architecture {
return types.Architecture(defaultArch)
// removeGoVersionPrefix converts a Go module version tag (e.g. "v1.4.22")
// into the corresponding OCP version (e.g. "4.22").
func removeGoVersionPrefix(version string) string {
if strings.HasPrefix(version, "v") {
version = strings.TrimPrefix(version, "v")
parts := strings.SplitN(version, ".", 2)
if len(parts) > 1 {
version = parts[1]
}
}
return version
}

// DefaultArch returns the default release architecture embedded in the binary
func DefaultArch() string {
return defaultArch
}