Repository: helm/helm
Pull request #6779 (2019-10-24 15:13:26)

fix(registry): change mediatype for chart content layer
Mediatype changed to application/tar+gzip. Please see the
following OCI mailing list item for more info:
https://groups.google.com/a/opencontainers.org/forum/#!topic/dev/pdc1lucm_Ak

Also, improved check for invalid manifests, a nil reference error was
occurring when upgrading from existing cache with old mediatype.


Patch:
diff --git a/README.md b/README.md
index 9af358e10..91a06916a 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,8 @@ Use Helm to:
 Helm is a tool that streamlines installing and managing Kubernetes applications.
 Think of it like apt/yum/homebrew for Kubernetes.
 
-- Helm renders your templates and communicates with the Kubernetes API
+- Helm has two parts: a client (`helm`) and a library
+- The library renders your templates and communicates with the Kubernetes API
 - Helm runs on your laptop, CI/CD, or wherever you want it to run.
 - Charts are Helm packages that contain at least two things:
   - A description of the package (`Chart.yaml`)
diff --git a/internal/experimental/registry/cache.go b/internal/experimental/registry/cache.go
index 19ceb86ea..fbd62562a 100644
--- a/internal/experimental/registry/cache.go
+++ b/internal/experimental/registry/cache.go
@@ -122,10 +122,14 @@ func (cache *Cache) FetchReference(ref *Reference) (*CacheRefSummary, error) {
 					contentLayer = &layer
 				}
 			}
-			if contentLayer.Size == 0 {
+			if contentLayer == nil {
 				return &r, errors.New(
 					fmt.Sprintf("manifest does not contain a layer with mediatype %s", HelmChartContentLayerMediaType))
 			}
+			if contentLayer.Size == 0 {
+				return &r, errors.New(
+					fmt.Sprintf("manifest layer with mediatype %s is of size 0", HelmChartContentLayerMediaType))
+			}
 			r.ContentLayer = contentLayer
 			info, err := cache.ociStore.Info(ctx(cache.out, cache.debug), contentLayer.Digest)
 			if err != nil {
diff --git a/internal/experimental/registry/constants.go b/internal/experimental/registry/constants.go
index e0f17fe61..dafb3c9e5 100644
--- a/internal/experimental/registry/constants.go
+++ b/internal/experimental/registry/constants.go
@@ -21,7 +21,7 @@ const (
 	HelmChartConfigMediaType = "application/vnd.cncf.helm.config.v1+json"
 
 	// HelmChartContentLayerMediaType is the reserved media type for Helm chart package content
-	HelmChartContentLayerMediaType = "application/vnd.cncf.helm.chart.content.layer.v1+tar"
+	HelmChartContentLayerMediaType = "application/tar+gzip"
 )
 
 // KnownMediaTypes returns a list of layer mediaTypes that the Helm client knows about
diff --git a/pkg/action/list.go b/pkg/action/list.go
index 4af0ef8e5..f72edc83b 100644
--- a/pkg/action/list.go
+++ b/pkg/action/list.go
@@ -17,7 +17,6 @@ limitations under the License.
 package action
 
 import (
-	"path"
 	"regexp"
 
 	"helm.sh/helm/v3/pkg/release"
@@ -219,23 +218,27 @@ func (l *List) sort(rels []*release.Release) {
 }
 
 // filterList returns a list scrubbed of old releases.
-func filterList(releases []*release.Release) []*release.Release {
-	latestReleases := make(map[string]*release.Release)
-
-	for _, rls := range releases {
-		name, namespace := rls.Name, rls.Namespace
-		key := path.Join(namespace, name)
-		if latestRelease, exists := latestReleases[key]; exists && latestRelease.Version > rls.Version {
-			continue
+func filterList(rels []*release.Release) []*release.Release {
+	idx := map[string]int{}
+
+	for _, r := range rels {
+		name, version := r.Name, r.Version
+		if max, ok := idx[name]; ok {
+			// check if we have a greater version already
+			if max > version {
+				continue
+			}
 		}
-		latestReleases[key] = rls
+		idx[name] = version
 	}
 
-	var list = make([]*release.Release, 0, len(latestReleases))
-	for _, rls := range latestReleases {
-		list = append(list, rls)
+	uniq := make([]*release.Release, 0, len(idx))
+	for _, r := range rels {
+		if idx[r.Name] == r.Version {
+			uniq = append(uniq, r)
+		}
 	}
-	return list
+	return uniq
 }
 
 // setStateMask calculates the state mask based on parameters.


Test patch:
diff --git a/pkg/action/list_test.go b/pkg/action/list_test.go
index cd86aee68..cab0111fd 100644
--- a/pkg/action/list_test.go
+++ b/pkg/action/list_test.go
@@ -159,7 +159,6 @@ func TestList_LimitOffsetOutOfBounds(t *testing.T) {
 	is.NoError(err)
 	is.Len(list, 2)
 }
-
 func TestList_StateMask(t *testing.T) {
 	is := assert.New(t)
 	lister := newListFixture(t)
@@ -167,8 +166,7 @@ func TestList_StateMask(t *testing.T) {
 	one, err := lister.cfg.Releases.Get("one", 1)
 	is.NoError(err)
 	one.SetStatus(release.StatusUninstalled, "uninstalled")
-	err = lister.cfg.Releases.Update(one)
-	is.NoError(err)
+	lister.cfg.Releases.Update(one)
 
 	res, err := lister.Run()
 	is.NoError(err)
@@ -224,6 +222,11 @@ func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
 	three.Name = "three"
 	three.Namespace = "default"
 	three.Version = 3
+	four := releaseStub()
+	four.Name = "four"
+	four.Namespace = "default"
+	four.Version = 4
+	four.Info.Status = release.StatusSuperseded
 
 	for _, rel := range []*release.Release{one, two, three} {
 		if err := store.Create(rel); err != nil {
@@ -235,29 +238,3 @@ func makeMeSomeReleases(store *storage.Storage, t *testing.T) {
 	assert.NoError(t, err)
 	assert.Len(t, all, 3, "sanity test: three items added")
 }
-
-func TestFilterList(t *testing.T) {
-	one := releaseStub()
-	one.Name = "one"
-	one.Namespace = "default"
-	one.Version = 1
-	two := releaseStub()
-	two.Name = "two"
-	two.Namespace = "default"
-	two.Version = 1
-	anotherOldOne := releaseStub()
-	anotherOldOne.Name = "one"
-	anotherOldOne.Namespace = "testing"
-	anotherOldOne.Version = 1
-	anotherOne := releaseStub()
-	anotherOne.Name = "one"
-	anotherOne.Namespace = "testing"
-	anotherOne.Version = 2
-
-	list := []*release.Release{one, two, anotherOne}
-	expectedFilteredList := []*release.Release{one, two, anotherOne}
-
-	filteredList := filterList(list)
-
-	assert.ElementsMatch(t, expectedFilteredList, filteredList)
-}
diff --git a/pkg/storage/driver/cfgmaps_test.go b/pkg/storage/driver/cfgmaps_test.go
index 2aa38f284..6efd790ce 100644
--- a/pkg/storage/driver/cfgmaps_test.go
+++ b/pkg/storage/driver/cfgmaps_test.go
@@ -51,7 +51,7 @@ func TestConfigMapGet(t *testing.T) {
 	}
 }
 
-func TestUncompressedConfigMapGet(t *testing.T) {
+func TestUNcompressedConfigMapGet(t *testing.T) {
 	vers := 1
 	name := "smug-pigeon"
 	namespace := "default"