From a2ebd021d729b617a60a4801fd9be53eaa81fa11 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 14 Jan 2020 22:44:52 -0500 Subject: [PATCH] feat(tests): Allow to provision memory driver The memory driver is used for go tests. It can also be used from the command-line by setting the environment variable HELM_DRIVER=memory. In the latter case however, there was no way to pre-provision some releases. This commit introduces the HELM_MEMORY_DRIVER_DATA variable which can be used to provide a colon-separated list of yaml files specifying releases to provision automatically. For example: HELM_DRIVER=memory \ HELM_MEMORY_DRIVER_DATA=./testdata/releases.yaml \ helm list --all-namespaces Signed-off-by: Marc Khouzam Signed-off-by: Matheus Hunsche --- cmd/helm/helm.go | 49 +++++++++++++++++++++++++++++++++++++++++- pkg/action/action.go | 13 ++++++++++- testdata/releases.yaml | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 testdata/releases.yaml diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 0ce40732b..257387547 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -19,6 +19,7 @@ package main // import "helm.sh/helm/v3/cmd/helm" import ( "flag" "fmt" + "io/ioutil" "log" "os" "strings" @@ -26,6 +27,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" "k8s.io/klog" + "sigs.k8s.io/yaml" // Import to initialize client auth plugins. _ "k8s.io/client-go/plugin/pkg/client/auth" @@ -34,6 +36,9 @@ import ( "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/gates" + kubefake "helm.sh/helm/v3/pkg/kube/fake" + "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v3/pkg/storage/driver" ) // FeatureGateOCI is the feature gate for checking if `helm chart` and `helm registry` commands should work @@ -78,9 +83,13 @@ func main() { } } - if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), debug); err != nil { + helmDriver := os.Getenv("HELM_DRIVER") + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), helmDriver, debug); err != nil { log.Fatal(err) } + if helmDriver == "memory" { + loadReleasesInMemory(actionConfig) + } if err := cmd.Execute(); err != nil { debug("%+v", err) @@ -106,3 +115,41 @@ func checkOCIFeatureGate() func(_ *cobra.Command, _ []string) error { return nil } } + +// This function loads releases into the memory storage if the +// environment variable is properly set. +func loadReleasesInMemory(actionConfig *action.Configuration) { + filePaths := strings.Split(os.Getenv("HELM_MEMORY_DRIVER_DATA"), ":") + if len(filePaths) == 0 { + return + } + + store := actionConfig.Releases + mem, ok := store.Driver.(*driver.Memory) + if !ok { + // For an unexpected reason we are not dealing with the memory storage driver. + return + } + + actionConfig.KubeClient = &kubefake.PrintingKubeClient{Out: ioutil.Discard} + + for _, path := range filePaths { + b, err := ioutil.ReadFile(path) + if err != nil { + log.Fatal("Unable to read memory driver data", err) + } + + releases := []*release.Release{} + if err := yaml.Unmarshal(b, &releases); err != nil { + log.Fatal("Unable to unmarshal memory driver data: ", err) + } + + for _, rel := range releases { + if err := store.Create(rel); err != nil { + log.Fatal(err) + } + } + } + // Must reset namespace to the proper one + mem.SetNamespace(settings.Namespace()) +} diff --git a/pkg/action/action.go b/pkg/action/action.go index 1af5b3d9a..e4db942c8 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -241,7 +241,18 @@ func (c *Configuration) Init(getter genericclioptions.RESTClientGetter, namespac d.Log = log store = storage.Init(d) case "memory": - d := driver.NewMemory() + var d *driver.Memory + if c.Releases != nil { + if mem, ok := c.Releases.Driver.(*driver.Memory); ok { + // This function can be called more than once (e.g., helm list --all-namespaces). + // If a memory driver was already initialized, re-use it but set the possibly new namespace. + // We re-use it in case some releases where already created in the existing memory driver. + d = mem + } + } + if d == nil { + d = driver.NewMemory() + } d.SetNamespace(namespace) store = storage.Init(d) default: diff --git a/testdata/releases.yaml b/testdata/releases.yaml new file mode 100644 index 000000000..fef79f424 --- /dev/null +++ b/testdata/releases.yaml @@ -0,0 +1,43 @@ +# This file can be used as input to create test releases: +# HELM_MEMORY_DRIVER_DATA=./testdata/releases.yaml HELM_DRIVER=memory helm list --all-namespaces +- name: athos + version: 1 + namespace: default + info: + status: deployed + chart: + metadata: + name: athos-chart + version: 1.0.0 + appversion: 1.1.0 +- name: porthos + version: 2 + namespace: default + info: + status: deployed + chart: + metadata: + name: prothos-chart + version: 0.2.0 + appversion: 0.2.2 +- name: aramis + version: 3 + namespace: default + info: + status: deployed + chart: + metadata: + name: aramis-chart + version: 0.0.3 + appversion: 3.0.3 +- name: dartagnan + version: 4 + namespace: gascony + info: + status: deployed + chart: + metadata: + name: dartagnan-chart + version: 0.4.4 + appversion: 4.4.4 +