Skip to content

Commit 6cb3f2d

Browse files
committed
fix: update e2e test to use internal docker registry and openshift
registry. removes quay credentials.
1 parent 8534ecd commit 6cb3f2d

File tree

7 files changed

+283
-82
lines changed

7 files changed

+283
-82
lines changed

pkg/package-server/client/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
// NewClient creates a client that can interact with the ALM resources in k8s api
1010
func NewClient(kubeconfig string) (client versioned.Interface, err error) {
1111
var config *rest.Config
12-
config, err = getConfig(kubeconfig)
12+
config, err = GetConfig(kubeconfig)
1313
if err != nil {
1414
return
1515
}

pkg/package-server/client/util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"k8s.io/client-go/tools/clientcmd"
1111
)
1212

13-
// getConfig returns a kubernetes config for configuring a client from a kubeconfig string
14-
func getConfig(kubeconfig string) (*rest.Config, error) {
13+
// GetConfig returns a kubernetes config for configuring a client from a kubeconfig string
14+
func GetConfig(kubeconfig string) (*rest.Config, error) {
1515
if len(kubeconfig) == 0 {
1616
// Work around https://github.com/kubernetes/kubernetes/issues/40973
1717
// See https://github.com/coreos/etcd-operator/issues/731#issuecomment-283804819

test/e2e/catalog_e2e_test.go

Lines changed: 89 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ import (
2727
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
2828
)
2929

30-
const (
31-
oldsha256 = "sha256:aeb23777c920d98605c4c960f109a9994f5af1aab49bed51c94b88fe8463a919"
32-
newsha256 = "sha256:f04cd65be9767684c7399cc0f183af15c0933e91124bc1f8312654e26678dc11"
33-
catsrcImage = "docker://quay.io/olmtest/catsrc-update-test:"
34-
)
35-
3630
func TestCatalogLoadingBetweenRestarts(t *testing.T) {
3731
defer cleaner.NotifyTestComplete(t, true)
3832

@@ -704,6 +698,11 @@ func TestDeleteGRPCRegistryPodTriggersRecreation(t *testing.T) {
704698
require.Equal(t, 1, len(registryPods.Items), "unexpected number of replacement registry pods found")
705699
}
706700

701+
const (
702+
openshiftregistryFQDN = "image-registry.openshift-image-registry.svc:5000/openshift-operators"
703+
catsrcImage = "docker://quay.io/olmtest/catsrc-update-test:"
704+
)
705+
707706
func TestCatalogImageUpdate(t *testing.T) {
708707
// Create an image based catalog source from public Quay image
709708
// Use a unique tag as identifier
@@ -713,21 +712,68 @@ func TestCatalogImageUpdate(t *testing.T) {
713712
// etcd operator updated from 0.9.0 to 0.9.2-clusterwide
714713
// Subscription should detect the latest version of the operator in the new catalog source and pull it
715714

716-
// 0. check old tag to ensure correct image is used
717-
image := fmt.Sprint(catsrcImage, "old")
718-
tagOk, err := skopeoInspectDigest(image, oldsha256)
715+
// create internal registry for purposes of pushing/pulling IF running e2e test locally
716+
// registry is insecure and for purposes of this test only
717+
c := newKubeClient(t)
718+
crc := newCRClient(t)
719+
720+
local, err := Local(c)
719721
if err != nil {
720-
t.Fatalf("error confirming old catalog image: %s", err)
722+
t.Fatalf("cannot determine if test running locally or on CI: %s", err)
721723
}
722-
if !tagOk {
723-
t.Fatal("cannot confirm old catalog image integrity")
724+
725+
var registryURL string
726+
var registryAuth string
727+
if local {
728+
registryURL, err = createDockerRegistry(c, testNamespace)
729+
if err != nil {
730+
t.Fatalf("error creating container registry: %s", err)
731+
}
732+
defer deleteDockerRegistry(c, testNamespace)
733+
734+
// ensure registry pod is ready before attempting port-forwarding
735+
_ = awaitPod(t, c, testNamespace, registryName, podReady)
736+
737+
err = registryPortForward(testNamespace)
738+
if err != nil {
739+
t.Fatalf("port-forwarding local registry: %s", err)
740+
}
741+
} else {
742+
registryURL = openshiftregistryFQDN
743+
registryAuth, err = openshiftRegistryAuth(c, testNamespace)
744+
if err != nil {
745+
t.Fatalf("error getting openshift registry authentication: %s", err)
746+
}
724747
}
725748

726-
// 1. copy old catalog image into test-specific tag
749+
// testImage is the name of the image used throughout the test - the image overwritten by skopeo
750+
// the tag is generated randomly and appended to the end of the testImage
751+
testImage := fmt.Sprint("docker://", registryURL, "/catsrc-update", ":")
727752
tag := genName("x")
728-
oldImage, err := skopeoCopy(catsrcImage, tag, catsrcImage, "old")
729-
if err != nil {
730-
t.Fatalf("copying old registry file: %s", err)
753+
754+
// 1. copy old catalog image into test-specific tag in internal docker registry
755+
// create skopeo pod to actually do the work of copying (on openshift) or exec out to local skopeo
756+
if local {
757+
_, err := skopeoLocalCopy(testImage, tag, catsrcImage, "old")
758+
if err != nil {
759+
t.Fatalf("error copying old registry file: %s", err)
760+
}
761+
} else {
762+
skopeoArgs := skopeoCopyCmd(testImage, tag, catsrcImage, "old", registryAuth)
763+
err = createSkopeoPod(c, skopeoArgs, testNamespace)
764+
if err != nil {
765+
t.Fatalf("error creating skopeo pod: %s", err)
766+
}
767+
768+
// wait for skopeo pod to exit successfully
769+
awaitPod(t, c, testNamespace, skopeo, func(pod *corev1.Pod) bool {
770+
return pod.Status.Phase == corev1.PodSucceeded
771+
})
772+
773+
err = deleteSkopeoPod(c, testNamespace)
774+
if err != nil {
775+
t.Fatalf("error deleting skopeo pod: %s", err)
776+
}
731777
}
732778

733779
// 2. setup catalog source
@@ -738,6 +784,10 @@ func TestCatalogImageUpdate(t *testing.T) {
738784
channelName := "clusterwide-alpha"
739785

740786
// Create gRPC CatalogSource using an external registry image and poll interval
787+
var image string
788+
image = testImage[9:] // strip off docker://
789+
image = fmt.Sprint(image, tag)
790+
741791
source := &v1alpha1.CatalogSource{
742792
TypeMeta: metav1.TypeMeta{
743793
Kind: v1alpha1.CatalogSourceKind,
@@ -750,7 +800,7 @@ func TestCatalogImageUpdate(t *testing.T) {
750800
},
751801
Spec: v1alpha1.CatalogSourceSpec{
752802
SourceType: v1alpha1.SourceTypeGrpc,
753-
Image: oldImage[9:], // strip off docker://
803+
Image: image,
754804
UpdateStrategy: &v1alpha1.UpdateStrategy{
755805
RegistryPoll: &v1alpha1.RegistryPoll{
756806
Interval: &metav1.Duration{Duration: 1 * time.Minute},
@@ -759,7 +809,6 @@ func TestCatalogImageUpdate(t *testing.T) {
759809
},
760810
}
761811

762-
crc := newCRClient(t)
763812
source, err = crc.OperatorsV1alpha1().CatalogSources(source.GetNamespace()).Create(source)
764813
require.NoError(t, err)
765814
defer func() {
@@ -768,7 +817,6 @@ func TestCatalogImageUpdate(t *testing.T) {
768817

769818
// wait for new catalog source pod to be created
770819
// Wait for a new registry pod to be created
771-
c := newKubeClient(t)
772820
selector := labels.SelectorFromSet(map[string]string{"olm.catalogSource": source.GetName()})
773821
singlePod := podCount(1)
774822
registryPods, err := awaitPods(t, c, source.GetNamespace(), selector.String(), singlePod)
@@ -790,16 +838,6 @@ func TestCatalogImageUpdate(t *testing.T) {
790838
_, err = fetchCSV(t, crc, subscription.Status.CurrentCSV, subscription.GetNamespace(), csvSucceededChecker)
791839
require.NoError(t, err)
792840

793-
// check new image pod is as we expect
794-
image = fmt.Sprint(catsrcImage, "new")
795-
tagOk, err = skopeoInspectDigest(image, newsha256)
796-
if err != nil {
797-
t.Fatalf("error confirming new catalog image: %s", err)
798-
}
799-
if !tagOk {
800-
t.Fatal("cannot confirm new catalog image integrity")
801-
}
802-
803841
registryCheckFunc := func(podList *corev1.PodList) bool {
804842
if len(podList.Items) > 1 {
805843
return false
@@ -810,9 +848,28 @@ func TestCatalogImageUpdate(t *testing.T) {
810848
registryPod, err := awaitPods(t, c, source.GetNamespace(), selector.String(), registryCheckFunc)
811849
// 3. Update image on registry via skopeo: this should trigger a newly updated version of the catalog source pod
812850
// to be deployed after some time
813-
_, err = skopeoCopy(catsrcImage, tag, catsrcImage, "new")
814-
if err != nil {
815-
t.Fatalf("copying new registry file: %s", err)
851+
// Make another skopeo pod to do the work of copying the image
852+
if local {
853+
_, err := skopeoLocalCopy(testImage, tag, catsrcImage, "new")
854+
if err != nil {
855+
t.Fatalf("error copying new registry file: %s", err)
856+
}
857+
} else {
858+
skopeoArgs := skopeoCopyCmd(testImage, tag, catsrcImage, "new", registryAuth)
859+
err = createSkopeoPod(c, skopeoArgs, testNamespace)
860+
if err != nil {
861+
t.Fatalf("error creating skopeo pod: %s", err)
862+
}
863+
864+
// wait for skopeo pod to exit successfully
865+
awaitPod(t, c, testNamespace, skopeo, func(pod *corev1.Pod) bool {
866+
return pod.Status.Phase == corev1.PodSucceeded
867+
})
868+
869+
err = deleteSkopeoPod(c, testNamespace)
870+
if err != nil {
871+
t.Fatalf("error deleting skopeo pod: %s", err)
872+
}
816873
}
817874

818875
// update catalog source with annotation (to kick resync)

test/e2e/registry.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package e2e
2+
3+
import (
4+
"fmt"
5+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
6+
corev1 "k8s.io/api/core/v1"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
"os/exec"
9+
)
10+
11+
// This module contains helper functions for copying images and creating image registries
12+
// Use for tests that require manipulating images or use of custom container registries
13+
14+
const (
15+
registryImage = "registry:2.7.1"
16+
registryName = "registry"
17+
localFQDN = "localhost:5000"
18+
)
19+
20+
func createDockerRegistry(client operatorclient.ClientInterface, namespace string) (string, error) {
21+
registry := &corev1.Pod{
22+
ObjectMeta: metav1.ObjectMeta{
23+
Name: registryName,
24+
Namespace: namespace,
25+
Labels: map[string]string{"name": registryName},
26+
},
27+
Spec: corev1.PodSpec{
28+
Containers: []corev1.Container{
29+
{
30+
Name: registryName,
31+
Image: registryImage,
32+
Ports: []corev1.ContainerPort{
33+
{
34+
HostPort: int32(5000),
35+
ContainerPort: int32(5000),
36+
},
37+
},
38+
},
39+
},
40+
},
41+
}
42+
43+
svc := &corev1.Service{
44+
ObjectMeta: metav1.ObjectMeta{
45+
Name: registryName,
46+
Namespace: namespace,
47+
},
48+
Spec: corev1.ServiceSpec{
49+
Selector: map[string]string{"name": registryName},
50+
Ports: []corev1.ServicePort{
51+
{
52+
Port: int32(5000),
53+
},
54+
},
55+
},
56+
}
57+
58+
_, err := client.KubernetesInterface().CoreV1().Pods(namespace).Create(registry)
59+
if err != nil {
60+
return "", fmt.Errorf("creating test registry: %s", err)
61+
}
62+
63+
_, err = client.KubernetesInterface().CoreV1().Services(namespace).Create(svc)
64+
if err != nil {
65+
return "", fmt.Errorf("creating test registry: %s", err)
66+
}
67+
68+
return localFQDN, nil
69+
}
70+
71+
func deleteDockerRegistry(client operatorclient.ClientInterface, namespace string) {
72+
_ = client.KubernetesInterface().CoreV1().Pods(namespace).Delete(registryName, &metav1.DeleteOptions{})
73+
_ = client.KubernetesInterface().CoreV1().Services(namespace).Delete(registryName, &metav1.DeleteOptions{})
74+
}
75+
76+
// port-forward registry pod port 5000 for local test
77+
// port-forwarding ends when registry pod is deleted: no need for explicit port-forward stop
78+
func registryPortForward(namespace string) error {
79+
cmd := exec.Command("kubectl", "-n", namespace, "port-forward", "registry", "5000:5000")
80+
err := cmd.Start()
81+
if err != nil {
82+
return fmt.Errorf("failed to exec %#v: %v", cmd.Args, err)
83+
}
84+
return nil
85+
}

test/e2e/skopeo.Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM fedora:31
2+
RUN yum install -y skopeo
3+
4+
ENTRYPOINT ["skopeo"]

0 commit comments

Comments
 (0)