diff --git a/cmd/helm/testdata/output/template-name-template.txt b/cmd/helm/testdata/output/template-name-template.txt index 229ffe20f..88408e57a 100644 --- a/cmd/helm/testdata/output/template-name-template.txt +++ b/cmd/helm/testdata/output/template-name-template.txt @@ -42,8 +42,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "foobar-YWJj-baz" kube-version/major: "1" - kube-version/minor: "9" - kube-version/gitversion: "v1.9.0" + kube-version/minor: "14" + kube-version/version: "v1.14.0" spec: type: ClusterIP ports: diff --git a/cmd/helm/testdata/output/template-set.txt b/cmd/helm/testdata/output/template-set.txt index fec32bcae..2bbeb5e0d 100644 --- a/cmd/helm/testdata/output/template-set.txt +++ b/cmd/helm/testdata/output/template-set.txt @@ -42,8 +42,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "9" - kube-version/gitversion: "v1.9.0" + kube-version/minor: "14" + kube-version/version: "v1.14.0" spec: type: ClusterIP ports: diff --git a/cmd/helm/testdata/output/template-values-files.txt b/cmd/helm/testdata/output/template-values-files.txt index fec32bcae..2bbeb5e0d 100644 --- a/cmd/helm/testdata/output/template-values-files.txt +++ b/cmd/helm/testdata/output/template-values-files.txt @@ -42,8 +42,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "9" - kube-version/gitversion: "v1.9.0" + kube-version/minor: "14" + kube-version/version: "v1.14.0" spec: type: ClusterIP ports: diff --git a/cmd/helm/testdata/output/template.txt b/cmd/helm/testdata/output/template.txt index c0ddca8d8..a8919534c 100644 --- a/cmd/helm/testdata/output/template.txt +++ b/cmd/helm/testdata/output/template.txt @@ -42,8 +42,8 @@ metadata: helm.sh/chart: "subchart1-0.1.0" app.kubernetes.io/instance: "RELEASE-NAME" kube-version/major: "1" - kube-version/minor: "9" - kube-version/gitversion: "v1.9.0" + kube-version/minor: "14" + kube-version/version: "v1.14.0" spec: type: ClusterIP ports: diff --git a/docs/chart_template_guide/builtin_objects.md b/docs/chart_template_guide/builtin_objects.md index 570ea73ce..5d9f42d0b 100644 --- a/docs/chart_template_guide/builtin_objects.md +++ b/docs/chart_template_guide/builtin_objects.md @@ -19,7 +19,10 @@ In the previous section, we use `{{.Release.Name}}` to insert the name of a rele - `Capabilities`: This provides information about what capabilities the Kubernetes cluster supports. - `Capabilities.APIVersions` is a set of versions. - `Capabilities.APIVersions.Has $version` indicates whether a version (`batch/v1`) is enabled on the cluster. - - `Capabilities.KubeVersion` provides a way to look up the Kubernetes version. It has the following values: `Major`, `Minor`, `GitVersion`, `GitCommit`, `GitTreeState`, `BuildDate`, `GoVersion`, `Compiler`, and `Platform`. + - `Capabilities.Kube.Version` is the Kubernetes version. + - `Capabilities.Kube` is a short form for Kubernetes version. + - `Capabilities.Kube.Major` is the Kubernetes major version. + - `Capabilities.Kube.Minor` is the Kubernetes minor version. - `Template`: Contains information about the current template that is being executed - `Name`: A namespaced filepath to the current template (e.g. `mychart/templates/mytemplate.yaml`) - `BasePath`: The namespaced path to the templates directory of the current chart (e.g. `mychart/templates`). diff --git a/docs/faq.md b/docs/faq.md index 85bfc5350..bcb5afc7e 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -25,6 +25,11 @@ In Helm 2, in order to purge the release ledger, the `--purge` flag had to be pr functionality is now enabled by default. To retain the previous behaviour, use `helm uninstall --keep-history`. +### Capabilities + +Capabilities built-in has been simplified. + +[Built-in Objects](chart_template_guide/builtin_objects.md) ## Installing diff --git a/pkg/action/action.go b/pkg/action/action.go index 11c3107d4..5fa941964 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -86,7 +86,6 @@ func (c *Configuration) getCapabilities() (*chartutil.Capabilities, error) { if c.Capabilities != nil { return c.Capabilities, nil } - dc, err := c.RESTClientGetter.ToDiscoveryClient() if err != nil { return nil, errors.Wrap(err, "could not get Kubernetes discovery client") @@ -95,15 +94,18 @@ func (c *Configuration) getCapabilities() (*chartutil.Capabilities, error) { if err != nil { return nil, errors.Wrap(err, "could not get server version from Kubernetes") } - apiVersions, err := GetVersionSet(dc) if err != nil { return nil, errors.Wrap(err, "could not get apiVersions from Kubernetes") } c.Capabilities = &chartutil.Capabilities{ - KubeVersion: kubeVersion, APIVersions: apiVersions, + KubeVersion: chartutil.KubeVersion{ + Version: kubeVersion.GitVersion, + Major: kubeVersion.Major, + Minor: kubeVersion.Minor, + }, } return c.Capabilities, nil } @@ -144,7 +146,7 @@ func GetVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet } versions := metav1.ExtractGroupVersions(groups) - return chartutil.NewVersionSet(versions...), nil + return chartutil.VersionSet(versions), nil } // recordRelease with an update operation in case reuse has been set. diff --git a/pkg/action/install.go b/pkg/action/install.go index 090d650ba..21be22c0d 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -304,10 +304,8 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values } if ch.Metadata.KubeVersion != "" { - gitVersion := caps.KubeVersion.String() - k8sVersion := strings.Split(gitVersion, "+")[0] - if !version.IsCompatibleRange(ch.Metadata.KubeVersion, k8sVersion) { - return hs, b, "", errors.Errorf("chart requires kubernetesVersion: %s which is incompatible with Kubernetes %s", ch.Metadata.KubeVersion, k8sVersion) + if !version.IsCompatibleRange(ch.Metadata.KubeVersion, caps.KubeVersion.String()) { + return hs, b, "", errors.Errorf("chart requires kubernetesVersion: %s which is incompatible with Kubernetes %s", ch.Metadata.KubeVersion, caps.KubeVersion.String()) } } diff --git a/pkg/chartutil/capabilities.go b/pkg/chartutil/capabilities.go index 88d0530b9..a211fbdb3 100644 --- a/pkg/chartutil/capabilities.go +++ b/pkg/chartutil/capabilities.go @@ -16,13 +16,6 @@ limitations under the License. package chartutil import ( - "encoding/json" - "fmt" - "runtime" - "sort" - - "k8s.io/apimachinery/pkg/version" - "k8s.io/client-go/kubernetes/scheme" ) @@ -30,75 +23,60 @@ var ( // DefaultVersionSet is the default version set, which includes only Core V1 ("v1"). DefaultVersionSet = allKnownVersions() - // DefaultKubeVersion is the default kubernetes version - DefaultKubeVersion = &version.Info{ - Major: "1", - Minor: "9", - GitVersion: "v1.9.0", - GoVersion: runtime.Version(), - Compiler: runtime.Compiler, - Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), - } - // DefaultCapabilities is the default set of capabilities. DefaultCapabilities = &Capabilities{ + KubeVersion: KubeVersion{ + Version: "v1.14.0", + Major: "1", + Minor: "14", + }, APIVersions: DefaultVersionSet, - KubeVersion: DefaultKubeVersion, } ) -// Capabilities describes the capabilities of the Kubernetes cluster that Tiller is attached to. +// Capabilities describes the capabilities of the Kubernetes cluster. type Capabilities struct { - // List of all supported API versions + // KubeVersion is the Kubernetes version. + KubeVersion KubeVersion + // APIversions are supported Kubernetes API versions. APIVersions VersionSet - // KubeVerison is the Kubernetes version - KubeVersion *version.Info } -// VersionSet is a set of Kubernetes API versions. -type VersionSet map[string]struct{} - -// NewVersionSet creates a new version set from a list of strings. -func NewVersionSet(apiVersions ...string) VersionSet { - vs := make(VersionSet) - for _, v := range apiVersions { - vs[v] = struct{}{} - } - return vs +// KubeVersion is the Kubernetes version. +type KubeVersion struct { + Version string // Kubernetes version + Major string // Kubernetes major version + Minor string // Kubernetes minor version } +// String implements fmt.Stringer +func (kv *KubeVersion) String() string { return kv.Version } + +// GitVersion returns the Kubernetes version string. +// +// Deprecated: use KubeVersion.Version. +func (kv *KubeVersion) GitVersion() string { return kv.Version } + +// VersionSet is a set of Kubernetes API versions. +type VersionSet []string + // Has returns true if the version string is in the set. // // vs.Has("apps/v1") func (v VersionSet) Has(apiVersion string) bool { - _, ok := v[apiVersion] - return ok + for _, x := range v { + if x == apiVersion { + return true + } + } + return false } func allKnownVersions() VersionSet { - vs := make(VersionSet) - for _, gv := range scheme.Scheme.PrioritizedVersionsAllGroups() { - vs[gv.String()] = struct{}{} + groups := scheme.Scheme.PrioritizedVersionsAllGroups() + vs := make(VersionSet, 0, len(groups)) + for _, gv := range groups { + vs = append(vs, gv.String()) } return vs } - -// MarshalJSON implements the encoding/json.Marshaler interface. -func (v VersionSet) MarshalJSON() ([]byte, error) { - out := make([]string, 0, len(v)) - for i := range v { - out = append(out, i) - } - sort.Strings(out) - return json.Marshal(out) -} - -// UnmarshalJSON implements the encoding/json.Unmarshaler interface. -func (v *VersionSet) UnmarshalJSON(data []byte) error { - var vs []string - if err := json.Unmarshal(data, &vs); err != nil { - return err - } - *v = NewVersionSet(vs...) - return nil -} diff --git a/pkg/chartutil/capabilities_test.go b/pkg/chartutil/capabilities_test.go index fd798ca0d..88dc1bd83 100644 --- a/pkg/chartutil/capabilities_test.go +++ b/pkg/chartutil/capabilities_test.go @@ -16,12 +16,11 @@ limitations under the License. package chartutil import ( - "encoding/json" "testing" ) func TestVersionSet(t *testing.T) { - vs := NewVersionSet("v1", "apps/v1") + vs := VersionSet{"v1", "apps/v1"} if d := len(vs); d != 2 { t.Errorf("Expected 2 versions, got %d", d) } @@ -41,38 +40,21 @@ func TestDefaultVersionSet(t *testing.T) { } } -func TestCapabilities(t *testing.T) { - cap := Capabilities{ - APIVersions: DefaultVersionSet, +func TestDefaultCapabilities(t *testing.T) { + kv := DefaultCapabilities.KubeVersion + if kv.String() != "v1.14.0" { + t.Errorf("Expected default KubeVersion.String() to be v1.14.0, got %q", kv.String()) } - - if !cap.APIVersions.Has("v1") { - t.Error("APIVersions should have v1") + if kv.Version != "v1.14.0" { + t.Errorf("Expected default KubeVersion.Version to be v1.14.0, got %q", kv.Version) } -} - -func TestCapabilitiesJSONMarshal(t *testing.T) { - vs := NewVersionSet("v1", "apps/v1") - b, err := json.Marshal(vs) - if err != nil { - t.Fatal(err) + if kv.GitVersion() != "v1.14.0" { + t.Errorf("Expected default KubeVersion.GitVersion() to be v1.14.0, got %q", kv.Version) } - - expect := `["apps/v1","v1"]` - if string(b) != expect { - t.Fatalf("JSON marshaled semantic version not equal: expected %q, got %q", expect, string(b)) + if kv.Major != "1" { + t.Errorf("Expected default KubeVersion.Major to be 1, got %q", kv.Major) } -} - -func TestCapabilitiesJSONUnmarshal(t *testing.T) { - in := `["apps/v1","v1"]` - - var vs VersionSet - if err := json.Unmarshal([]byte(in), &vs); err != nil { - t.Fatal(err) - } - - if len(vs) != 2 { - t.Fatalf("JSON unmarshaled semantic version not equal: expected 2, got %d", len(vs)) + if kv.Minor != "14" { + t.Errorf("Expected default KubeVersion.Minor to be 14, got %q", kv.Minor) } } diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml index 0ce52ac43..967e1700f 100644 --- a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/instance: "{{ .Release.Name }}" kube-version/major: "{{ .Capabilities.KubeVersion.Major }}" kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}" - kube-version/gitversion: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0" + kube-version/version: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0" spec: type: {{ .Values.service.type }} ports: diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go index 7edc75233..9d4a4fc15 100644 --- a/pkg/chartutil/values.go +++ b/pkg/chartutil/values.go @@ -375,6 +375,9 @@ type ReleaseOptions struct { // // This takes both ReleaseOptions and Capabilities to merge into the render values. func ToRenderValues(chrt *chart.Chart, chrtVals map[string]interface{}, options ReleaseOptions, caps *Capabilities) (Values, error) { + if caps == nil { + caps = DefaultCapabilities + } top := map[string]interface{}{ "Chart": chrt.Metadata, "Capabilities": caps, diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index 43aa72189..b5bb76801 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -24,8 +24,6 @@ import ( "testing" "text/template" - kversion "k8s.io/apimachinery/pkg/version" - "helm.sh/helm/pkg/chart" ) @@ -105,12 +103,7 @@ func TestToRenderValues(t *testing.T) { IsInstall: true, } - caps := &Capabilities{ - APIVersions: DefaultVersionSet, - KubeVersion: &kversion.Info{Major: "1"}, - } - - res, err := ToRenderValues(c, overideValues, o, caps) + res, err := ToRenderValues(c, overideValues, o, nil) if err != nil { t.Fatal(err) } diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 41a3c7438..ae7a75ca7 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -56,8 +56,7 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace if err != nil { return } - caps := chartutil.DefaultCapabilities - valuesToRender, err := chartutil.ToRenderValues(chart, cvals, options, caps) + valuesToRender, err := chartutil.ToRenderValues(chart, cvals, options, nil) if err != nil { // FIXME: This seems to generate a duplicate, but I can't find where the first // error is coming from. diff --git a/pkg/releaseutil/manifest_sorter_test.go b/pkg/releaseutil/manifest_sorter_test.go index fad8caf9f..580b83137 100644 --- a/pkg/releaseutil/manifest_sorter_test.go +++ b/pkg/releaseutil/manifest_sorter_test.go @@ -139,7 +139,7 @@ metadata: manifests[o.path] = o.manifest } - hs, generic, err := SortManifests(manifests, chartutil.NewVersionSet("v1", "v1beta1"), InstallOrder) + hs, generic, err := SortManifests(manifests, chartutil.VersionSet{"v1", "v1beta1"}, InstallOrder) if err != nil { t.Fatalf("Unexpected error: %s", err) }