Merge remote-tracking branch 'helm/master'

pull/8054/head
Liu Ming 4 years ago
commit 3bd084c35d

@ -45,19 +45,19 @@ Environment variables:
| Name | Description |
|------------------------------------|-----------------------------------------------------------------------------------|
| $XDG_CACHE_HOME | set an alternative location for storing cached files. |
| $XDG_CONFIG_HOME | set an alternative location for storing Helm configuration. |
| $XDG_DATA_HOME | set an alternative location for storing Helm data. |
| $HELM_CACHE_HOME | set an alternative location for storing cached files. |
| $HELM_CONFIG_HOME | set an alternative location for storing Helm configuration. |
| $HELM_DATA_HOME | set an alternative location for storing Helm data. |
| $HELM_DRIVER | set the backend storage driver. Values are: configmap, secret, memory, postgres |
| $HELM_DRIVER_SQL_CONNECTION_STRING | set the connection string the SQL storage driver should use. |
| $HELM_NO_PLUGINS | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. |
| $KUBECONFIG | set an alternative Kubernetes configuration file (default "~/.kube/config") |
Helm stores configuration based on the XDG base directory specification, so
Helm stores cache, configuration, and data based on the following configuration order:
- cached files are stored in $XDG_CACHE_HOME/helm
- configuration is stored in $XDG_CONFIG_HOME/helm
- data is stored in $XDG_DATA_HOME/helm
- If a HELM_*_HOME environment variable is set, it will be used
- Otherwise, on systems supporting the XDG base directory specification, the XDG variables will be used
- When no other location is set a default location will be used based on the operating system
By default, the default directories depend on the Operating System. The defaults are listed below:

@ -55,6 +55,24 @@ func TestRootCmd(t *testing.T) {
envvars: map[string]string{xdg.DataHomeEnvVar: "/bar"},
dataPath: "/bar/helm",
},
{
name: "with $HELM_CACHE_HOME set",
args: "env",
envvars: map[string]string{helmpath.CacheHomeEnvVar: "/foo/helm"},
cachePath: "/foo/helm",
},
{
name: "with $HELM_CONFIG_HOME set",
args: "env",
envvars: map[string]string{helmpath.ConfigHomeEnvVar: "/foo/helm"},
configPath: "/foo/helm",
},
{
name: "with $HELM_DATA_HOME set",
args: "env",
envvars: map[string]string{helmpath.DataHomeEnvVar: "/foo/helm"},
dataPath: "/foo/helm",
},
}
for _, tt := range tests {

@ -1 +1 @@
version.BuildInfo{Version:"v3.1", GitCommit:"", GitTreeState:"", GoVersion:""}
version.BuildInfo{Version:"v3.2", GitCommit:"", GitTreeState:"", GoVersion:""}

@ -1 +1 @@
version.BuildInfo{Version:"v3.1", GitCommit:"", GitTreeState:"", GoVersion:""}
version.BuildInfo{Version:"v3.2", GitCommit:"", GitTreeState:"", GoVersion:""}

@ -1 +1 @@
Version: v3.1
Version: v3.2

@ -1 +1 @@
version.BuildInfo{Version:"v3.1", GitCommit:"", GitTreeState:"", GoVersion:""}
version.BuildInfo{Version:"v3.2", GitCommit:"", GitTreeState:"", GoVersion:""}

@ -21,6 +21,7 @@ import (
"os"
"testing"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/helmpath/xdg"
)
@ -31,6 +32,9 @@ func HelmHome(t *testing.T) func() {
os.Setenv(xdg.CacheHomeEnvVar, base)
os.Setenv(xdg.ConfigHomeEnvVar, base)
os.Setenv(xdg.DataHomeEnvVar, base)
os.Setenv(helmpath.CacheHomeEnvVar, "")
os.Setenv(helmpath.ConfigHomeEnvVar, "")
os.Setenv(helmpath.DataHomeEnvVar, "")
return func() {
os.RemoveAll(base)
}

@ -30,7 +30,7 @@ var (
// Increment major number for new feature additions and behavioral changes.
// Increment minor number for bug fixes and performance enhancements.
// Increment patch number for critical fixes to existing releases.
version = "v3.1"
version = "v3.2"
// metadata is extra build time data
metadata = ""

@ -105,6 +105,9 @@ func envOr(name, def string) string {
func (s *EnvSettings) EnvVars() map[string]string {
envvars := map[string]string{
"HELM_BIN": os.Args[0],
"HELM_CACHE_HOME": helmpath.CachePath(""),
"HELM_CONFIG_HOME": helmpath.ConfigPath(""),
"HELM_DATA_HOME": helmpath.DataPath(""),
"HELM_DEBUG": fmt.Sprint(s.Debug),
"HELM_PLUGINS": s.PluginsDirectory,
"HELM_REGISTRY_CONFIG": s.RegistryConfig,

@ -20,11 +20,34 @@ import (
"helm.sh/helm/v3/pkg/helmpath/xdg"
)
const (
// CacheHomeEnvVar is the environment variable used by Helm
// for the cache directory. When no value is set a default is used.
CacheHomeEnvVar = "HELM_CACHE_HOME"
// ConfigHomeEnvVar is the environment variable used by Helm
// for the config directory. When no value is set a default is used.
ConfigHomeEnvVar = "HELM_CONFIG_HOME"
// DataHomeEnvVar is the environment variable used by Helm
// for the data directory. When no value is set a default is used.
DataHomeEnvVar = "HELM_DATA_HOME"
)
// lazypath is an lazy-loaded path buffer for the XDG base directory specification.
type lazypath string
func (l lazypath) path(envVar string, defaultFn func() string, elem ...string) string {
base := os.Getenv(envVar)
func (l lazypath) path(helmEnvVar, xdgEnvVar string, defaultFn func() string, elem ...string) string {
// There is an order to checking for a path.
// 1. See if a Helm specific environment variable has been set.
// 2. Check if an XDG environment variable is set
// 3. Fall back to a default
base := os.Getenv(helmEnvVar)
if base != "" {
return filepath.Join(base, filepath.Join(elem...))
}
base = os.Getenv(xdgEnvVar)
if base == "" {
base = defaultFn()
}
@ -34,16 +57,16 @@ func (l lazypath) path(envVar string, defaultFn func() string, elem ...string) s
// cachePath defines the base directory relative to which user specific non-essential data files
// should be stored.
func (l lazypath) cachePath(elem ...string) string {
return l.path(xdg.CacheHomeEnvVar, cacheHome, filepath.Join(elem...))
return l.path(CacheHomeEnvVar, xdg.CacheHomeEnvVar, cacheHome, filepath.Join(elem...))
}
// configPath defines the base directory relative to which user specific configuration files should
// be stored.
func (l lazypath) configPath(elem ...string) string {
return l.path(xdg.ConfigHomeEnvVar, configHome, filepath.Join(elem...))
return l.path(ConfigHomeEnvVar, xdg.ConfigHomeEnvVar, configHome, filepath.Join(elem...))
}
// dataPath defines the base directory relative to which user specific data files should be stored.
func (l lazypath) dataPath(elem ...string) string {
return l.path(xdg.DataHomeEnvVar, dataHome, filepath.Join(elem...))
return l.path(DataHomeEnvVar, xdg.DataHomeEnvVar, dataHome, filepath.Join(elem...))
}

@ -22,20 +22,36 @@ import "fmt"
//
// An empty rvalue indicates that the API is completely deprecated.
var deprecatedAPIs = map[string]string{
"extensions/v1 Deployment": "apps/v1 Deployment",
"extensions/v1 DaemonSet": "apps/v1 DaemonSet",
"extensions/v1 ReplicaSet": "apps/v1 ReplicaSet",
"extensions/v1beta1 Deployment": "apps/v1 Deployment",
"extensions/v1beta1 DaemonSet": "apps/v1 DaemonSet",
"extensions/v1beta1 ReplicaSet": "apps/v1 ReplicaSet",
"extensions/v1beta1 PodSecurityPolicy": "policy/v1beta1 PodSecurityPolicy",
"extensions/v1beta1 NetworkPolicy": "networking.k8s.io/v1beta1 NetworkPolicy",
"extensions/v1beta1 Ingress": "networking.k8s.io/v1beta1 Ingress",
"apps/v1beta1 Deployment": "apps/v1 Deployment",
"apps/v1beta1 StatefulSet": "apps/v1 StatefulSet",
"apps/v1beta1 DaemonSet": "apps/v1 DaemonSet",
"apps/v1beta1 ReplicaSet": "apps/v1 ReplicaSet",
"apps/v1beta2 Deployment": "apps/v1 Deployment",
"apps/v1beta2 StatefulSet": "apps/v1 StatefulSet",
"apps/v1beta2 DaemonSet": "apps/v1 DaemonSet",
"apps/v1beta2 ReplicaSet": "apps/v1 ReplicaSet",
"apiextensions.k8s.io/v1beta1 CustomResourceDefinition": "apiextensions.k8s.io/v1 CustomResourceDefinition",
"rbac.authorization.k8s.io/v1alpha1 ClusterRole": "rbac.authorization.k8s.io/v1 ClusterRole",
"rbac.authorization.k8s.io/v1alpha1 ClusterRoleList": "rbac.authorization.k8s.io/v1 ClusterRoleList",
"rbac.authorization.k8s.io/v1alpha1 ClusterRoleBinding": "rbac.authorization.k8s.io/v1 ClusterRoleBinding",
"rbac.authorization.k8s.io/v1alpha1 ClusterRoleBindingList": "rbac.authorization.k8s.io/v1 ClusterRoleBindingList",
"rbac.authorization.k8s.io/v1alpha1 Role": "rbac.authorization.k8s.io/v1 Role",
"rbac.authorization.k8s.io/v1alpha1 RoleList": "rbac.authorization.k8s.io/v1 RoleList",
"rbac.authorization.k8s.io/v1alpha1 RoleBinding": "rbac.authorization.k8s.io/v1 RoleBinding",
"rbac.authorization.k8s.io/v1alpha1 RoleBindingList": "rbac.authorization.k8s.io/v1 RoleBindingList",
"rbac.authorization.k8s.io/v1beta1 ClusterRole": "rbac.authorization.k8s.io/v1 ClusterRole",
"rbac.authorization.k8s.io/v1beta1 ClusterRoleList": "rbac.authorization.k8s.io/v1 ClusterRoleList",
"rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding": "rbac.authorization.k8s.io/v1 ClusterRoleBinding",
"rbac.authorization.k8s.io/v1beta1 ClusterRoleBindingList": "rbac.authorization.k8s.io/v1 ClusterRoleBindingList",
"rbac.authorization.k8s.io/v1beta1 Role": "rbac.authorization.k8s.io/v1 Role",
"rbac.authorization.k8s.io/v1beta1 RoleList": "rbac.authorization.k8s.io/v1 RoleList",
"rbac.authorization.k8s.io/v1beta1 RoleBinding": "rbac.authorization.k8s.io/v1 RoleBinding",
"rbac.authorization.k8s.io/v1beta1 RoleBindingList": "rbac.authorization.k8s.io/v1 RoleBindingList",
}
// deprecatedAPIError indicates than an API is deprecated in Kubernetes

@ -20,7 +20,7 @@ import "testing"
func TestValidateNoDeprecations(t *testing.T) {
deprecated := &K8sYamlStruct{
APIVersion: "extensions/v1",
APIVersion: "extensions/v1beta1",
Kind: "Deployment",
}
err := validateNoDeprecations(deprecated)

@ -81,7 +81,6 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace
return
}
var e engine.Engine
e.Strict = strict
e.LintMode = true
renderedContentMap, err := e.Render(chart, valuesToRender)

@ -174,3 +174,55 @@ func TestDeprecatedAPIFails(t *testing.T) {
t.Errorf("Surprised to learn that %q is deprecated", err.Deprecated)
}
}
const manifest = `apiVersion: v1
kind: ConfigMap
metadata:
name: foo
data:
myval1: {{default "val" .Values.mymap.key1 }}
myval2: {{default "val" .Values.mymap.key2 }}
`
// TestSTrictTemplatePrasingMapError is a regression test.
//
// The template engine should not produce an error when a map in values.yaml does
// not contain all possible keys.
//
// See https://github.com/helm/helm/issues/7483
func TestStrictTemplateParsingMapError(t *testing.T) {
ch := chart.Chart{
Metadata: &chart.Metadata{
Name: "regression7483",
APIVersion: "v2",
Version: "0.1.0",
},
Values: map[string]interface{}{
"mymap": map[string]string{
"key1": "val1",
},
},
Templates: []*chart.File{
{
Name: "templates/configmap.yaml",
Data: []byte(manifest),
},
},
}
dir := ensure.TempDir(t)
defer os.RemoveAll(dir)
if err := chartutil.SaveDir(&ch, dir); err != nil {
t.Fatal(err)
}
linter := &support.Linter{
ChartDir: filepath.Join(dir, ch.Metadata.Name),
}
Templates(linter, ch.Values, namespace, strict)
if len(linter.Messages) != 0 {
t.Errorf("expected zero messages, got %d", len(linter.Messages))
for i, msg := range linter.Messages {
t.Logf("Message %d: %q", i, msg)
}
}
}

@ -23,6 +23,8 @@ import (
"strings"
"github.com/pkg/errors"
"helm.sh/helm/v3/pkg/plugin"
)
// ErrMissingMetadata indicates that plugin.yaml is missing.
@ -100,7 +102,7 @@ func isRemoteHTTPArchive(source string) bool {
// isPlugin checks if the directory contains a plugin.yaml file.
func isPlugin(dirname string) bool {
_, err := os.Stat(filepath.Join(dirname, "plugin.yaml"))
_, err := os.Stat(filepath.Join(dirname, plugin.PluginFileName))
return err == nil
}

@ -28,7 +28,7 @@ import (
"helm.sh/helm/v3/pkg/cli"
)
const pluginFileName = "plugin.yaml"
const PluginFileName = "plugin.yaml"
// Downloaders represents the plugins capability if it can retrieve
// charts from special sources
@ -159,7 +159,7 @@ func (p *Plugin) PrepareCommand(extraArgs []string) (string, []string, error) {
// LoadDir loads a plugin from the given directory.
func LoadDir(dirname string) (*Plugin, error) {
data, err := ioutil.ReadFile(filepath.Join(dirname, pluginFileName))
data, err := ioutil.ReadFile(filepath.Join(dirname, PluginFileName))
if err != nil {
return nil, err
}
@ -177,7 +177,7 @@ func LoadDir(dirname string) (*Plugin, error) {
func LoadAll(basedir string) ([]*Plugin, error) {
plugins := []*Plugin{}
// We want basedir/*/plugin.yaml
scanpath := filepath.Join(basedir, "*", pluginFileName)
scanpath := filepath.Join(basedir, "*", PluginFileName)
matches, err := filepath.Glob(scanpath)
if err != nil {
return plugins, err

Loading…
Cancel
Save