Skip to content

Commit 05ba4d5

Browse files
committed
fix(package-server): get icons from default channel
Get icons from the default channel for icon subresource requests. Fixes an issue which caused package-server to erroneously return icons from the first channel declared.
1 parent 66c4a9d commit 05ba4d5

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

pkg/package-server/storage/subresources.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,29 @@ func (s *LogoStorage) Connect(ctx context.Context, name string, options runtime.
5151
return
5252
}
5353
imgBytes, mimeType, etag := func() ([]byte, string, string) {
54-
if len(pkg.Status.Channels) == 0 || len(pkg.Status.Channels[0].CurrentCSVDesc.Icon) == 0 {
55-
return []byte(defaultIcon), "image/svg+xml", ""
56-
} else {
57-
data := pkg.Status.Channels[0].CurrentCSVDesc.Icon[0].Base64Data
58-
mimeType := pkg.Status.Channels[0].CurrentCSVDesc.Icon[0].Mediatype
59-
etag := `"` + strings.Join([]string{name, pkg.Status.Channels[0].Name, pkg.Status.Channels[0].CurrentCSV}, ".") + `"`
54+
for _, pkgChannel := range pkg.Status.Channels {
55+
if pkgChannel.Name != pkg.Status.DefaultChannel {
56+
continue
57+
}
58+
59+
desc := pkgChannel.CurrentCSVDesc
60+
if len(desc.Icon) == 0 {
61+
break
62+
}
63+
64+
// The first icon is call we care about
65+
icon := desc.Icon[0]
66+
data := icon.Base64Data
67+
mimeType := icon.Mediatype
68+
etag := `"` + strings.Join([]string{name, pkgChannel.Name, pkgChannel.CurrentCSV}, ".") + `"`
6069

6170
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(data))
6271
imgBytes, _ := ioutil.ReadAll(reader)
6372

6473
return imgBytes, mimeType, etag
6574
}
75+
76+
return []byte(defaultIcon), "image/svg+xml", ""
6677
}()
6778

6879
w.Header().Set("Content-Type", mimeType)

pkg/package-server/storage/subresources_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,15 @@ func testPackage() *operators.PackageManifest {
104104
Icon: []operators.Icon{{Mediatype: "image/png", Base64Data: iconData}},
105105
},
106106
},
107+
{
108+
Name: "alpha",
109+
CurrentCSV: "csv-b",
110+
CurrentCSVDesc: operators.CSVDescription{
111+
Icon: []operators.Icon{{Mediatype: "image/png", Base64Data: "different-icon"}},
112+
},
113+
},
107114
},
115+
DefaultChannel: "stable",
108116
},
109117
}
110118
}

test/e2e/packagemanifest_e2e_test.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package e2e
22

33
import (
44
"context"
5+
"encoding/base64"
56
"encoding/json"
67

78
"github.com/blang/semver"
@@ -10,7 +11,9 @@ import (
1011
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
1112
"k8s.io/apimachinery/pkg/api/errors"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/client-go/rest"
1315

16+
opver "github.com/operator-framework/api/pkg/lib/version"
1417
"github.com/operator-framework/api/pkg/operators/v1alpha1"
1518
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
1619
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
@@ -51,12 +54,15 @@ var _ = Describe("Package Manifest API lists available Operators from Catalog So
5154

5255
// create a simple catalogsource
5356
packageName = genName("nginx")
57+
alphaChannel := "alpha"
58+
packageAlpha := packageName + "-alpha"
5459
stableChannel := "stable"
5560
packageStable = packageName + "-stable"
5661
manifests := []registry.PackageManifest{
5762
{
5863
PackageName: packageName,
5964
Channels: []registry.PackageChannel{
65+
{Name: alphaChannel, CurrentCSVName: packageAlpha},
6066
{Name: stableChannel, CurrentCSVName: packageStable},
6167
},
6268
DefaultChannelName: stableChannel,
@@ -84,12 +90,29 @@ var _ = Describe("Package Manifest API lists available Operators from Catalog So
8490
}
8591
csv.Spec.Maturity = "foo"
8692
csv.Spec.NativeAPIs = []metav1.GroupVersionKind{{Group: "kubenative.io", Version: "v1", Kind: "Native"}}
93+
csv.Spec.Icon = []v1alpha1.Icon{
94+
{
95+
Data: "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",
96+
MediaType: "image/png",
97+
},
98+
}
99+
100+
csvAlpha := csv.DeepCopy()
101+
csvAlpha.SetName(packageAlpha)
102+
csvAlpha.Spec.Version = opver.OperatorVersion{semver.MustParse("0.1.1")}
103+
csvAlpha.Spec.Replaces = csv.GetName()
104+
csvAlpha.Spec.Icon = []v1alpha1.Icon{
105+
{
106+
Data: base64.StdEncoding.EncodeToString([]byte(csvAlpha.GetName())),
107+
MediaType: "image/png",
108+
},
109+
}
87110

88111
var err error
89112
csvJSON, err = json.Marshal(csv)
90113
Expect(err).ToNot(HaveOccurred())
91114

92-
_, cleanupCatalogSource = createInternalCatalogSource(c, crc, catsrcName, testNamespace, manifests, []apiextensions.CustomResourceDefinition{crd}, []v1alpha1.ClusterServiceVersion{csv})
115+
_, cleanupCatalogSource = createInternalCatalogSource(c, crc, catsrcName, testNamespace, manifests, []apiextensions.CustomResourceDefinition{crd}, []v1alpha1.ClusterServiceVersion{csv, *csvAlpha})
93116

94117
// Verify catalog source was created
95118
_, err = fetchCatalogSourceOnStatus(crc, catsrcName, testNamespace, catalogSourceRegistryPodSynced)
@@ -134,6 +157,7 @@ var _ = Describe("Package Manifest API lists available Operators from Catalog So
134157
Expect(pm.Status.Channels[0].CurrentCSVDesc.Links).Should(Equal([]packagev1.AppLink{{Name: "foo", URL: "example.com"}}))
135158
Expect(pm.Status.Channels[0].CurrentCSVDesc.Maintainers).Should(Equal([]packagev1.Maintainer{{Name: "foo", Email: "[email protected]"}}))
136159
})
160+
137161
It("lists PackageManifest and ensures it has valid PackageManifest item", func() {
138162
// Get a PackageManifestList and ensure it has the correct items
139163
Eventually(func() (bool, error) {
@@ -142,6 +166,21 @@ var _ = Describe("Package Manifest API lists available Operators from Catalog So
142166
}).Should(BeTrue(), "required package name not found in the list")
143167
})
144168

169+
It("gets the icon from the default channel", func() {
170+
var res rest.Result
171+
Eventually(func() error {
172+
res = pmc.OperatorsV1().RESTClient().Get().Resource("packagemanifests").SubResource("icon").Namespace(testNamespace).Name(packageName).Do(context.Background())
173+
return res.Error()
174+
}).Should(Succeed(), "error getting icon")
175+
176+
data, err := res.Raw()
177+
Expect(err).ToNot(HaveOccurred())
178+
179+
// Match against icon from the default
180+
expected, err := base64.StdEncoding.DecodeString(csv.Spec.Icon[0].Data)
181+
Expect(err).ToNot(HaveOccurred())
182+
Expect(data).To(Equal(expected))
183+
})
145184
})
146185

147186
Context("Given a CatalogSource created using gRPC catalog source type", func() {

0 commit comments

Comments
 (0)