@@ -14,7 +14,6 @@ import (
1414 "io"
1515 "os"
1616 "path/filepath"
17- "regexp"
1817 "runtime"
1918 "sort"
2019 "strings"
@@ -32,7 +31,6 @@ import (
3231 "k8s.io/apimachinery/pkg/util/sets"
3332 "k8s.io/cli-runtime/pkg/genericiooptions"
3433 appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1"
35- "k8s.io/client-go/rest"
3634 "sigs.k8s.io/yaml"
3735
3836 "github.com/MakeNowJust/heredoc"
@@ -43,7 +41,6 @@ import (
4341 "github.com/openshift/oc/pkg/cli/admin/internal/codesign"
4442 "github.com/openshift/oc/pkg/cli/image/extract"
4543 "github.com/openshift/oc/pkg/cli/image/imagesource"
46- "github.com/openshift/oc/pkg/version"
4744)
4845
4946// extractTarget describes how a file in the release image can be extracted to disk.
@@ -1167,17 +1164,9 @@ func copyAndReplace(errorOutput io.Writer, w io.Writer, r io.Reader, bufferSize
11671164
11681165}
11691166
1170- func findClusterIncludeConfigFromInstallConfig (ctx context.Context , installConfigPath string ) (manifestInclusionConfiguration , error ) {
1167+ func findClusterIncludeConfigFromInstallConfig (ctx context.Context , installConfigPath , ocVersion string ) (manifestInclusionConfiguration , error ) {
11711168 config := manifestInclusionConfiguration {}
11721169
1173- clientVersion , reportedVersion , err := version .ExtractVersion ()
1174- if err != nil {
1175- return config , err
1176- }
1177- if reportedVersion == "" {
1178- reportedVersion = clientVersion .String ()
1179- }
1180-
11811170 installConfigBytes , err := os .ReadFile (installConfigPath )
11821171 if err != nil {
11831172 return config , err
@@ -1205,67 +1194,69 @@ func findClusterIncludeConfigFromInstallConfig(ctx context.Context, installConfi
12051194 return config , fmt .Errorf ("unrecognized baselineCapabilitySet %q" , data .Capabilities .BaselineCapabilitySet )
12061195 } else {
12071196 if data .Capabilities .BaselineCapabilitySet == configv1 .ClusterVersionCapabilitySetCurrent {
1208- klog .Infof ("If the eventual cluster will not be the same minor version as this %s 'oc', the actual %s capability set may differ." , reportedVersion , data .Capabilities .BaselineCapabilitySet )
1197+ klog .Infof ("If the eventual cluster will not be the same minor version as this %s 'oc', the actual %s capability set may differ." , ocVersion , data .Capabilities .BaselineCapabilitySet )
12091198 }
12101199 config .Capabilities .EnabledCapabilities = append (config .Capabilities .EnabledCapabilities , enabled ... )
12111200 }
12121201 config .Capabilities .EnabledCapabilities = append (config .Capabilities .EnabledCapabilities , data .Capabilities .AdditionalEnabledCapabilities ... )
12131202
1214- klog .Infof ("If the eventual cluster will not be the same minor version as this %s 'oc', the known capability sets may differ." , reportedVersion )
1203+ klog .Infof ("If the eventual cluster will not be the same minor version as this %s 'oc', the known capability sets may differ." , ocVersion )
12151204 config .Capabilities .KnownCapabilities = configv1 .KnownClusterVersionCapabilities
12161205 }
12171206
12181207 return config , nil
12191208}
12201209
1221- func findClusterIncludeConfig (ctx context.Context , restConfig * rest. Config ) (manifestInclusionConfiguration , error ) {
1210+ func findClusterIncludeConfig (ctx context.Context , configv1client configv1client. ConfigV1Interface , appsv1client appsv1client. AppsV1Interface , ocVersion string ) (manifestInclusionConfiguration , error ) {
12221211 config := manifestInclusionConfiguration {}
12231212
1224- client , err := configv1client .NewForConfig (restConfig )
1225- if err != nil {
1226- return config , err
1227- }
1228-
1229- if featureGate , err := client .FeatureGates ().Get (ctx , "cluster" , metav1.GetOptions {}); err != nil {
1213+ if featureGate , err := configv1client .FeatureGates ().Get (ctx , "cluster" , metav1.GetOptions {}); err != nil {
12301214 return config , err
12311215 } else {
12321216 config .RequiredFeatureSet = ptr.To [string ](string (featureGate .Spec .FeatureSet ))
12331217 }
12341218
1235- if clusterVersion , err := client .ClusterVersions ().Get (ctx , "version" , metav1.GetOptions {}); err != nil {
1219+ if clusterVersion , err := configv1client .ClusterVersions ().Get (ctx , "version" , metav1.GetOptions {}); err != nil {
12361220 return config , err
12371221 } else {
12381222 config .Overrides = clusterVersion .Spec .Overrides
12391223 config .Capabilities = & clusterVersion .Status .Capabilities
12401224
1241- // FIXME: eventually pull in GetImplicitlyEnabledCapabilities from https://github.com/openshift/cluster-version-operator/blob/86e24d66119a73f50282b66a8d6f2e3518aa0e15/pkg/payload/payload.go#L237-L240 for cases where a minor update would implicitly enable some additional capabilities. For now, 4.13 to 4.14 will always enable MachineAPI, ImageRegistry, etc..
1242- currentVersion := clusterVersion .Status .Desired .Version
1243- matches := regexp .MustCompile (`^(\d+[.]\d+)[.].*` ).FindStringSubmatch (currentVersion )
1244- if len (matches ) < 2 {
1245- return config , fmt .Errorf ("failed to parse major.minor version from ClusterVersion status.desired.version %q" , currentVersion )
1246- } else if matches [1 ] == "4.13" {
1247- build := configv1 .ClusterVersionCapability ("Build" )
1248- deploymentConfig := configv1 .ClusterVersionCapability ("DeploymentConfig" )
1249- imageRegistry := configv1 .ClusterVersionCapability ("ImageRegistry" )
1250- config .Capabilities .EnabledCapabilities = append (config .Capabilities .EnabledCapabilities , configv1 .ClusterVersionCapabilityMachineAPI , build , deploymentConfig , imageRegistry )
1251- config .Capabilities .KnownCapabilities = append (config .Capabilities .KnownCapabilities , configv1 .ClusterVersionCapabilityMachineAPI , build , deploymentConfig , imageRegistry )
1225+ known := sets .New [configv1.ClusterVersionCapability ](configv1 .KnownClusterVersionCapabilities ... )
1226+ previouslyKnown := sets .New [configv1.ClusterVersionCapability ](config .Capabilities .KnownCapabilities ... )
1227+ config .Capabilities .KnownCapabilities = previouslyKnown .Union (known ).UnsortedList ()
1228+
1229+ // refresh BaselineCapabilitySet as more capabilities might be included across versions
1230+ key := configv1 .ClusterVersionCapabilitySetCurrent
1231+ if clusterVersion .Spec .Capabilities != nil && clusterVersion .Spec .Capabilities .BaselineCapabilitySet != "" {
1232+ key = clusterVersion .Spec .Capabilities .BaselineCapabilitySet
12521233 }
1234+ enabled := sets .New [configv1.ClusterVersionCapability ](configv1 .ClusterVersionCapabilitySets [key ]... )
1235+ // The set of the capabilities may grow over time. Without downloading the payload that is running on the cluster,
1236+ // it is hard to project all the enabled capabilities after upgrading to the incoming release.
1237+ // As an approximation, all newly introduced capabilities are considered enabled to check if a manifest from the
1238+ // release should be included while some of them might not be actually enabled on the cluster.
1239+ // As a result, unexpected manifests could be included. The number of such manifests is likely small, provided that
1240+ // only a small amount of capabilities are added over time and that happens only for minor level updates:
1241+ // #Cap(4.11)=4 -> #Cap(4.17)=15, averagely less than two per minor update.
1242+ // https://docs.openshift.com/container-platform/4.17/installing/overview/cluster-capabilities.html
1243+ deltaKnown := known .Difference (previouslyKnown )
1244+ if deltaKnown .Len () > 0 {
1245+ klog .Infof ("The new capabilities that are introduced in this oc version %s are considered enabled on checking if a manifest is included: %s. They may be disabled on the eventual cluster" , ocVersion , deltaKnown .UnsortedList ())
1246+ }
1247+ enabled = enabled .Union (deltaKnown )
1248+ config .Capabilities .EnabledCapabilities = sets .New [configv1.ClusterVersionCapability ](config .Capabilities .EnabledCapabilities ... ).Union (enabled ).UnsortedList ()
12531249 }
12541250
1255- if infrastructure , err := client .Infrastructures ().Get (ctx , "cluster" , metav1.GetOptions {}); err != nil {
1251+ if infrastructure , err := configv1client .Infrastructures ().Get (ctx , "cluster" , metav1.GetOptions {}); err != nil {
12561252 return config , err
12571253 } else if infrastructure .Status .PlatformStatus == nil {
12581254 return config , fmt .Errorf ("cluster infrastructure does not declare status.platformStatus: %v" , infrastructure .Status )
12591255 } else {
12601256 config .Platform = ptr.To [string ](strings .ToLower (string (infrastructure .Status .PlatformStatus .Type )))
12611257 }
12621258
1263- appsClient , err := appsv1client .NewForConfig (restConfig )
1264- if err != nil {
1265- return config , err
1266- }
1267-
1268- if deployment , err := appsClient .Deployments ("openshift-cluster-version" ).Get (ctx , "cluster-version-operator" , metav1.GetOptions {}); err != nil {
1259+ if deployment , err := appsv1client .Deployments ("openshift-cluster-version" ).Get (ctx , "cluster-version-operator" , metav1.GetOptions {}); err != nil {
12691260 return config , err
12701261 } else {
12711262 for _ , container := range deployment .Spec .Template .Spec .Containers {
0 commit comments