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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ require (
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
github.com/opencontainers/go-digest v1.0.0
github.com/openshift/api v0.0.0-20241001152557-e415140e5d5f
github.com/openshift/api v0.0.0-20241115001638-1392f06a4040
github.com/openshift/apiserver-library-go v0.0.0-20241001175710-6064b62894a6
github.com/openshift/build-machinery-go v0.0.0-20240613134303-8359781da660
github.com/openshift/client-go v0.0.0-20241001162912-da6d55e4611f
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,8 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78 h1:R
github.com/opencontainers/runtime-spec v1.0.3-0.20220909204839-494a5a6aca78/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/openshift/api v0.0.0-20241001152557-e415140e5d5f h1:ya1OmyZm3LIIxI3U9VE9Nyx3ehCHgBwxyFUPflYPWls=
github.com/openshift/api v0.0.0-20241001152557-e415140e5d5f/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
github.com/openshift/api v0.0.0-20241115001638-1392f06a4040 h1:HmxLLsQbvisvucUHyccf45hDsGVU6fYY4u5LXHKJ1+o=
github.com/openshift/api v0.0.0-20241115001638-1392f06a4040/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
github.com/openshift/apiserver-library-go v0.0.0-20241001175710-6064b62894a6 h1:Wban+ggY6sbg611SQSOeavUeug2cRJGz0rEeXxTxIH0=
github.com/openshift/apiserver-library-go v0.0.0-20241001175710-6064b62894a6/go.mod h1:9Anrq7+DZmmw1Brchx4zmh26hAZbe6Dv7bGXRclnhYI=
github.com/openshift/build-machinery-go v0.0.0-20240613134303-8359781da660 h1:F0zE2bmdVvaEd18VXuGYQdJJ1FYJu4MIDW9PYZWc9No=
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/upgrade/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ func clusterUpgrade(f *framework.Framework, c configv1client.Interface, dc dynam
f,
"[sig-cluster-lifecycle] ClusterOperators are available and not degraded after upgrade",
func() (error, bool) {
if err := operator.WaitForOperatorsToSettle(context.TODO(), c); err != nil {
if err := operator.WaitForOperatorsToSettle(context.TODO(), c, 5); err != nil {
return err, false
}
return nil, false
Expand Down
191 changes: 191 additions & 0 deletions test/extended/images/tagimportmode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package images

import (
"context"
"fmt"
"time"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"

g "github.com/onsi/ginkgo/v2"
o "github.com/onsi/gomega"
configv1 "github.com/openshift/api/config/v1"
imagev1 "github.com/openshift/api/image/v1"
configclient "github.com/openshift/client-go/config/clientset/versioned"
"github.com/openshift/library-go/pkg/image/imageutil"
exutil "github.com/openshift/origin/test/extended/util"
"github.com/openshift/origin/test/extended/util/operator"
)

var _ = g.Describe("[sig-imageregistry][OCPFeatureGate:ImageStreamImportMode][Serial] ImageStream API", func() {
defer g.GinkgoRecover()
oc := exutil.NewCLI("imagestream-api")

g.It("import mode should be PreserveOriginal or Legacy depending on desired.architecture field in the CV [apigroup:image.openshift.io]", func() {
TestImageStreamImportMode(g.GinkgoT(), oc)
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.

Given that the two test cases below cover both Legacy and PreserveOriginal, do we really need this test case? I can't really see what value it's adding, though I may be missing something.

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.

this test case is actually the only "necessary" one in my opinion because it changes the default import mode based on the CV's architecture. The other two test cases are specifically for testing the knob to change the import mode which I don't see being used frequently

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.

the main idea here is that we have these tests which are exercised behind the featuregate and once we let them run for a release (or maybe a few sprint cycles), we use that signal to promote the featuregate to default and then I was thinking we remove the two tests which change the import mode knob.

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.

ack, thanks for expanding!

})

g.It("import mode should be Legacy if the import mode specified in image.config.openshift.io config is Legacy [apigroup:image.openshift.io]", func() {
TestImageConfigImageStreamImportModeLegacy(g.GinkgoT(), oc)
})

g.It("import mode should be PreserveOriginal if the import mode specified in image.config.openshift.io config is PreserveOriginal [apigroup:image.openshift.io]", func() {
TestImageConfigImageStreamImportModePreserveOriginal(g.GinkgoT(), oc)
})
})

func changeImportModeAndWaitForApiServer(ctx context.Context, t g.GinkgoTInterface, oc *exutil.CLI, importMode string) error {
data := fmt.Sprintf(`{"spec":{"imageStreamImportMode":null}}`)
if len(importMode) > 0 {
data = fmt.Sprintf(`{"spec":{"imageStreamImportMode":"%s"}}`, importMode)
}
_, err := oc.AdminConfigClient().ConfigV1().Images().Patch(context.Background(), "cluster", types.MergePatchType, []byte(data), metav1.PatchOptions{})
if err != nil {
return err
}

// when pods are pending it means the config has started to propagate
t.Log("waiting for image controller configuration to propagate")
_, err = exutil.WaitForPods(oc.AdminKubeClient().CoreV1().Pods("openshift-apiserver"), labels.Everything(), exutil.CheckPodIsPending, 1, 5*time.Minute)
if err != nil {
return fmt.Errorf("error waiting for new apiserver pods: %s", err)
}

t.Log("waiting for new openshift-apiserver operator to settle")
if err := operator.WaitForOperatorsToSettle(ctx, oc.AdminConfigClient(), 10); err != nil {
return err
}
t.Log("image controller configuration propagated")
return nil
}

func TestImageStreamImportMode(t g.GinkgoTInterface, oc *exutil.CLI) {
ctx := context.Background()
if !exutil.IsTechPreviewNoUpgrade(ctx, oc.AdminConfigClient()) {
g.Skip("skipping, this feature is only supported on TechPreviewNoUpgrade clusters")
}

// Check desired.Architecture in the CV
configClient, err := configclient.NewForConfig(oc.AdminConfig())
o.Expect(err).NotTo(o.HaveOccurred())
clusterVersion, err := configClient.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())

importmode := imagev1.ImportModeLegacy
if clusterVersion.Status.Desired.Architecture == configv1.ClusterVersionArchitectureMulti {
importmode = imagev1.ImportModePreserveOriginal
}

clusterAdminImageClient := oc.AdminImageClient().ImageV1()
g.By("creating an imagestream and imagestream tag")
stream := &imagev1.ImageStream{ObjectMeta: metav1.ObjectMeta{Name: "test-importmode"}}

expected, err := clusterAdminImageClient.ImageStreams(oc.Namespace()).Create(ctx, stream, metav1.CreateOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(expected.Name).NotTo(o.BeEmpty())

_, err = clusterAdminImageClient.ImageStreamTags(oc.Namespace()).Create(ctx, &imagev1.ImageStreamTag{
ObjectMeta: metav1.ObjectMeta{Name: "test-importmode:1"},
Tag: &imagev1.TagReference{
From: &corev1.ObjectReference{Kind: "ImageStreamTag", Namespace: "openshift", Name: "tools:latest"},
},
}, metav1.CreateOptions{})
o.Expect(err).ToNot(o.HaveOccurred())

is, err := clusterAdminImageClient.ImageStreams(oc.Namespace()).Get(ctx, stream.Name, metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
tag, ok := imageutil.SpecHasTag(is, "1")
o.Expect(ok).To(o.BeTrue())
o.Expect(tag.ImportPolicy.ImportMode).To(o.Equal(importmode))
}

func TestImageConfigImageStreamImportModeLegacy(t g.GinkgoTInterface, oc *exutil.CLI) {
ctx := context.Background()
if !exutil.IsTechPreviewNoUpgrade(ctx, oc.AdminConfigClient()) {
g.Skip("skipping, this feature is only supported on TechPreviewNoUpgrade clusters")
}

clusterAdminConfigClient := oc.AdminConfigClient().ConfigV1()
imageConfig, err := clusterAdminConfigClient.Images().Get(ctx, "cluster", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())

if imageConfig.Status.ImageStreamImportMode == configv1.ImportModeLegacy {
g.Skip("skipping, import mode is already Legacy")
}

err = changeImportModeAndWaitForApiServer(ctx, t, oc, string(configv1.ImportModeLegacy))
o.Expect(err).NotTo(o.HaveOccurred())

g.By("creating an imagestream and imagestream tag")
stream := &imagev1.ImageStream{ObjectMeta: metav1.ObjectMeta{Name: "test-importmode"}}

clusterAdminImageClient := oc.AdminImageClient().ImageV1()
expected, err := clusterAdminImageClient.ImageStreams(oc.Namespace()).Create(ctx, stream, metav1.CreateOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(expected.Name).NotTo(o.BeEmpty())

_, err = clusterAdminImageClient.ImageStreamTags(oc.Namespace()).Create(ctx, &imagev1.ImageStreamTag{
ObjectMeta: metav1.ObjectMeta{Name: "test-importmode:2"},
Tag: &imagev1.TagReference{
From: &corev1.ObjectReference{Kind: "ImageStreamTag", Namespace: "openshift", Name: "tools:latest"},
},
}, metav1.CreateOptions{})
o.Expect(err).ToNot(o.HaveOccurred())

is, err := clusterAdminImageClient.ImageStreams(oc.Namespace()).Get(ctx, stream.Name, metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
tag, ok := imageutil.SpecHasTag(is, "2")
o.Expect(ok).To(o.BeTrue())
o.Expect(tag.ImportPolicy.ImportMode).To(o.Equal(imagev1.ImportModeLegacy))

// Revert back to original
err = changeImportModeAndWaitForApiServer(ctx, t, oc, "")
o.Expect(err).NotTo(o.HaveOccurred())
}

func TestImageConfigImageStreamImportModePreserveOriginal(t g.GinkgoTInterface, oc *exutil.CLI) {
ctx := context.Background()
if !exutil.IsTechPreviewNoUpgrade(ctx, oc.AdminConfigClient()) {
g.Skip("skipping, this feature is only supported on TechPreviewNoUpgrade clusters")
}

clusterAdminConfigClient := oc.AdminConfigClient().ConfigV1()
imageConfig, err := clusterAdminConfigClient.Images().Get(ctx, "cluster", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())

if imageConfig.Status.ImageStreamImportMode == configv1.ImportModePreserveOriginal {
g.Skip("skipping, import mode is already PreserveOriginal")
}

err = changeImportModeAndWaitForApiServer(ctx, t, oc, string(configv1.ImportModePreserveOriginal))
o.Expect(err).NotTo(o.HaveOccurred())

g.By("creating an imagestream and imagestream tag")
stream := &imagev1.ImageStream{ObjectMeta: metav1.ObjectMeta{Name: "test-importmode"}}

clusterAdminImageClient := oc.AdminImageClient().ImageV1()
expected, err := clusterAdminImageClient.ImageStreams(oc.Namespace()).Create(ctx, stream, metav1.CreateOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(expected.Name).NotTo(o.BeEmpty())

_, err = clusterAdminImageClient.ImageStreamTags(oc.Namespace()).Create(ctx, &imagev1.ImageStreamTag{
ObjectMeta: metav1.ObjectMeta{Name: "test-importmode:3"},
Tag: &imagev1.TagReference{
From: &corev1.ObjectReference{Kind: "ImageStreamTag", Namespace: "openshift", Name: "tools:latest"},
},
}, metav1.CreateOptions{})
o.Expect(err).ToNot(o.HaveOccurred())

is, err := clusterAdminImageClient.ImageStreams(oc.Namespace()).Get(ctx, stream.Name, metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred())
tag, ok := imageutil.SpecHasTag(is, "3")
o.Expect(ok).To(o.BeTrue())
o.Expect(tag.ImportPolicy.ImportMode).To(o.Equal(imagev1.ImportModePreserveOriginal))

// Revert back to original
err = changeImportModeAndWaitForApiServer(ctx, t, oc, "")
o.Expect(err).NotTo(o.HaveOccurred())
}
2 changes: 1 addition & 1 deletion test/extended/networking/cnimigration.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,6 @@ var _ = g.Describe("[sig-network][Feature:CNIMigration]", g.Ordered, func() {
framework.ExpectNoError(err)
client := configv1client.NewForConfigOrDie(config)
// 5 min timeout for operators to "settle"
framework.ExpectNoError(operator.WaitForOperatorsToSettle(ctx, client))
framework.ExpectNoError(operator.WaitForOperatorsToSettle(ctx, client, 5))
})
})

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions test/extended/util/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,11 @@ func CheckPodIsSucceeded(pod corev1.Pod) bool {
return pod.Status.Phase == corev1.PodSucceeded
}

// CheckPodIsRunning returns true if the pod is running
func CheckPodIsPending(pod corev1.Pod) bool {
return pod.Status.Phase == corev1.PodPending
}

// CheckPodIsReady returns true if the pod's ready probe determined that the pod is ready.
func CheckPodIsReady(pod corev1.Pod) bool {
if pod.Status.Phase != corev1.PodRunning {
Expand Down
6 changes: 3 additions & 3 deletions test/extended/util/operator/settle.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func WaitForOperatorsToSettleWithDefaultClient(ctx context.Context) error {
if err != nil {
return err
}
return WaitForOperatorsToSettle(ctx, configClient)
return WaitForOperatorsToSettle(ctx, configClient, 5)
}

// can be overridden for tests
Expand All @@ -34,10 +34,10 @@ func realNow() time.Time {
return time.Now()
}

func WaitForOperatorsToSettle(ctx context.Context, configClient clientconfigv1.Interface) error {
func WaitForOperatorsToSettle(ctx context.Context, configClient clientconfigv1.Interface, waitTime int) error {
framework.Logf("Waiting for operators to settle")
unsettledOperatorStatus := []string{}
if err := wait.PollImmediate(10*time.Second, 5*time.Minute, func() (bool, error) {
if err := wait.PollImmediate(10*time.Second, time.Duration(waitTime)*time.Minute, func() (bool, error) {
coList, err := configClient.ConfigV1().ClusterOperators().List(ctx, metav1.ListOptions{})
if err != nil {
framework.Logf("error getting ClusterOperators %v", err)
Expand Down
21 changes: 19 additions & 2 deletions vendor/github.com/openshift/api/config/v1/types_cluster_version.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 21 additions & 7 deletions vendor/github.com/openshift/api/config/v1/types_infrastructure.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading