mirror of https://github.com/helm/helm
Merge pull request #1850 from frodenas/deinit
feat(helm): Add command to uninstall Tillerpull/1888/head
commit
d41f093331
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package installer // import "k8s.io/helm/cmd/helm/installer"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ghodss/yaml"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
kerrors "k8s.io/kubernetes/pkg/api/errors"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
|
|
||||||
|
"k8s.io/helm/pkg/kube"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Uninstall uses kubernetes client to uninstall tiller
|
||||||
|
func Uninstall(kubeClient internalclientset.Interface, kubeCmd *kube.Client, namespace string, verbose bool) error {
|
||||||
|
if _, err := kubeClient.Core().Services(namespace).Get("tiller-deploy"); err != nil {
|
||||||
|
if !kerrors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err := deleteService(kubeClient.Core(), namespace); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if obj, err := kubeClient.Extensions().Deployments(namespace).Get("tiller-deploy"); err != nil {
|
||||||
|
if !kerrors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err := deleteDeployment(kubeCmd, namespace, obj); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// deleteService deletes the Tiller Service resource
|
||||||
|
func deleteService(client internalversion.ServicesGetter, namespace string) error {
|
||||||
|
return client.Services(namespace).Delete("tiller-deploy", &api.DeleteOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// deleteDeployment deletes the Tiller Deployment resource
|
||||||
|
// We need to use the kubeCmd reaper instead of the kube API because GC for deployment dependents
|
||||||
|
// is not yet supported at the k8s server level (<= 1.5)
|
||||||
|
func deleteDeployment(kubeCmd *kube.Client, namespace string, obj *extensions.Deployment) error {
|
||||||
|
obj.Kind = "Deployment"
|
||||||
|
obj.APIVersion = "extensions/v1beta1"
|
||||||
|
buf, err := yaml.Marshal(obj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reader := strings.NewReader(string(buf))
|
||||||
|
infos, err := kubeCmd.Build(namespace, reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, info := range infos {
|
||||||
|
reaper, err := kubeCmd.Reaper(info.Mapping)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = reaper.Stop(info.Namespace, info.Name, 0, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package installer // import "k8s.io/helm/cmd/helm/installer"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
apierrors "k8s.io/kubernetes/pkg/api/errors"
|
||||||
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||||
|
testcore "k8s.io/kubernetes/pkg/client/testing/core"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
|
|
||||||
|
"k8s.io/helm/pkg/kube"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fakeReaper struct {
|
||||||
|
namespace string
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *fakeReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||||
|
r.namespace = namespace
|
||||||
|
r.name = name
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeReaperFactory struct {
|
||||||
|
cmdutil.Factory
|
||||||
|
reaper kubectl.Reaper
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeReaperFactory) Reaper(mapping *meta.RESTMapping) (kubectl.Reaper, error) {
|
||||||
|
return f.reaper, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUninstall(t *testing.T) {
|
||||||
|
existingService := service(api.NamespaceDefault)
|
||||||
|
existingDeployment := deployment(api.NamespaceDefault, "image", false)
|
||||||
|
|
||||||
|
fc := &fake.Clientset{}
|
||||||
|
fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, existingService, nil
|
||||||
|
})
|
||||||
|
fc.AddReactor("delete", "services", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, nil
|
||||||
|
})
|
||||||
|
fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, existingDeployment, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
f, _, _, _ := cmdtesting.NewAPIFactory()
|
||||||
|
r := &fakeReaper{}
|
||||||
|
rf := &fakeReaperFactory{Factory: f, reaper: r}
|
||||||
|
kc := &kube.Client{Factory: rf}
|
||||||
|
|
||||||
|
if err := Uninstall(fc, kc, api.NamespaceDefault, false); err != nil {
|
||||||
|
t.Errorf("unexpected error: %#+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions := fc.Actions(); len(actions) != 3 {
|
||||||
|
t.Errorf("unexpected actions: %v, expected 3 actions got %d", actions, len(actions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.namespace != api.NamespaceDefault {
|
||||||
|
t.Errorf("unexpected reaper namespace: %s", r.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.name != "tiller-deploy" {
|
||||||
|
t.Errorf("unexpected reaper name: %s", r.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUninstall_serviceNotFound(t *testing.T) {
|
||||||
|
existingDeployment := deployment(api.NamespaceDefault, "imageToReplace", false)
|
||||||
|
|
||||||
|
fc := &fake.Clientset{}
|
||||||
|
fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, apierrors.NewNotFound(api.Resource("services"), "1")
|
||||||
|
})
|
||||||
|
fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, existingDeployment, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
f, _, _, _ := cmdtesting.NewAPIFactory()
|
||||||
|
r := &fakeReaper{}
|
||||||
|
rf := &fakeReaperFactory{Factory: f, reaper: r}
|
||||||
|
kc := &kube.Client{Factory: rf}
|
||||||
|
|
||||||
|
if err := Uninstall(fc, kc, api.NamespaceDefault, false); err != nil {
|
||||||
|
t.Errorf("unexpected error: %#+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions := fc.Actions(); len(actions) != 2 {
|
||||||
|
t.Errorf("unexpected actions: %v, expected 2 actions got %d", actions, len(actions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.namespace != api.NamespaceDefault {
|
||||||
|
t.Errorf("unexpected reaper namespace: %s", r.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.name != "tiller-deploy" {
|
||||||
|
t.Errorf("unexpected reaper name: %s", r.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUninstall_deploymentNotFound(t *testing.T) {
|
||||||
|
existingService := service(api.NamespaceDefault)
|
||||||
|
|
||||||
|
fc := &fake.Clientset{}
|
||||||
|
fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, existingService, nil
|
||||||
|
})
|
||||||
|
fc.AddReactor("delete", "services", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, nil
|
||||||
|
})
|
||||||
|
fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||||
|
return true, nil, apierrors.NewNotFound(api.Resource("deployments"), "1")
|
||||||
|
})
|
||||||
|
|
||||||
|
f, _, _, _ := cmdtesting.NewAPIFactory()
|
||||||
|
r := &fakeReaper{}
|
||||||
|
rf := &fakeReaperFactory{Factory: f, reaper: r}
|
||||||
|
kc := &kube.Client{Factory: rf}
|
||||||
|
|
||||||
|
if err := Uninstall(fc, kc, api.NamespaceDefault, false); err != nil {
|
||||||
|
t.Errorf("unexpected error: %#+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actions := fc.Actions(); len(actions) != 3 {
|
||||||
|
t.Errorf("unexpected actions: %v, expected 3 actions got %d", actions, len(actions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.namespace != "" {
|
||||||
|
t.Errorf("unexpected reaper namespace: %s", r.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.name != "" {
|
||||||
|
t.Errorf("unexpected reaper name: %s", r.name)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
|
|
||||||
|
"k8s.io/helm/cmd/helm/helmpath"
|
||||||
|
"k8s.io/helm/cmd/helm/installer"
|
||||||
|
"k8s.io/helm/pkg/helm"
|
||||||
|
"k8s.io/helm/pkg/kube"
|
||||||
|
"k8s.io/helm/pkg/proto/hapi/release"
|
||||||
|
)
|
||||||
|
|
||||||
|
const resetDesc = `
|
||||||
|
This command uninstalls Tiller (the helm server side component) from your
|
||||||
|
Kubernetes Cluster and optionally deletes local configuration in
|
||||||
|
$HELM_HOME (default ~/.helm/)
|
||||||
|
`
|
||||||
|
|
||||||
|
type resetCmd struct {
|
||||||
|
force bool
|
||||||
|
removeHelmHome bool
|
||||||
|
namespace string
|
||||||
|
out io.Writer
|
||||||
|
home helmpath.Home
|
||||||
|
client helm.Interface
|
||||||
|
kubeClient internalclientset.Interface
|
||||||
|
kubeCmd *kube.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||||
|
d := &resetCmd{
|
||||||
|
out: out,
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "reset",
|
||||||
|
Short: "uninstalls Tiller from a cluster",
|
||||||
|
Long: resetDesc,
|
||||||
|
PersistentPreRunE: setupConnection,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 0 {
|
||||||
|
return errors.New("This command does not accept arguments")
|
||||||
|
}
|
||||||
|
|
||||||
|
d.namespace = tillerNamespace
|
||||||
|
d.home = helmpath.Home(homePath())
|
||||||
|
d.client = ensureHelmClient(d.client)
|
||||||
|
|
||||||
|
return d.run()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f := cmd.Flags()
|
||||||
|
f.BoolVarP(&d.force, "force", "f", false, "forces Tiller uninstall even if there are releases installed")
|
||||||
|
f.BoolVar(&d.removeHelmHome, "remove-helm-home", false, "if set deletes $HELM_HOME")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// runReset uninstalls tiller from Kubernetes Cluster and deletes local config
|
||||||
|
func (d *resetCmd) run() error {
|
||||||
|
if d.kubeClient == nil {
|
||||||
|
_, c, err := getKubeClient(kubeContext)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not get kubernetes client: %s", err)
|
||||||
|
}
|
||||||
|
d.kubeClient = c
|
||||||
|
}
|
||||||
|
if d.kubeCmd == nil {
|
||||||
|
d.kubeCmd = getKubeCmd(kubeContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := d.client.ListReleases(
|
||||||
|
helm.ReleaseListStatuses([]release.Status_Code{release.Status_DEPLOYED}),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return prettyError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res.Releases) > 0 && !d.force {
|
||||||
|
return fmt.Errorf("There are still %d deployed releases (Tip: use --force).", len(res.Releases))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := installer.Uninstall(d.kubeClient, d.kubeCmd, d.namespace, flagDebug); err != nil {
|
||||||
|
return fmt.Errorf("error unstalling Tiller: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.removeHelmHome {
|
||||||
|
if err := deleteDirectories(d.home, d.out); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(d.out, "Tiller (the helm server side component) has been uninstalled from your Kubernetes Cluster.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// deleteDirectories deletes $HELM_HOME
|
||||||
|
func deleteDirectories(home helmpath.Home, out io.Writer) error {
|
||||||
|
if _, err := os.Stat(home.String()); err == nil {
|
||||||
|
fmt.Fprintf(out, "Deleting %s \n", home.String())
|
||||||
|
if err := os.RemoveAll(home.String()); err != nil {
|
||||||
|
return fmt.Errorf("Could not remove %s: %s", home.String(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||||
|
|
||||||
|
"k8s.io/helm/cmd/helm/helmpath"
|
||||||
|
"k8s.io/helm/pkg/proto/hapi/release"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResetCmd(t *testing.T) {
|
||||||
|
home, err := ioutil.TempDir("", "helm_home")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(home)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
c := &fakeReleaseClient{}
|
||||||
|
fc := fake.NewSimpleClientset()
|
||||||
|
cmd := &resetCmd{
|
||||||
|
out: &buf,
|
||||||
|
home: helmpath.Home(home),
|
||||||
|
client: c,
|
||||||
|
kubeClient: fc,
|
||||||
|
namespace: api.NamespaceDefault,
|
||||||
|
}
|
||||||
|
if err := cmd.run(); err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
actions := fc.Actions()
|
||||||
|
if len(actions) != 2 {
|
||||||
|
t.Errorf("Expected 2 actions, got %d", len(actions))
|
||||||
|
}
|
||||||
|
if !actions[0].Matches("get", "services") {
|
||||||
|
t.Errorf("unexpected action: %v, expected get service", actions[1])
|
||||||
|
}
|
||||||
|
if !actions[1].Matches("get", "deployments") {
|
||||||
|
t.Errorf("unexpected action: %v, expected get deployment", actions[0])
|
||||||
|
}
|
||||||
|
expected := "Tiller (the helm server side component) has been uninstalled from your Kubernetes Cluster."
|
||||||
|
if !strings.Contains(buf.String(), expected) {
|
||||||
|
t.Errorf("expected %q, got %q", expected, buf.String())
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(home); err != nil {
|
||||||
|
t.Errorf("Helm home directory %s does not exists", home)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResetCmd_removeHelmHome(t *testing.T) {
|
||||||
|
home, err := ioutil.TempDir("", "helm_home")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(home)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
c := &fakeReleaseClient{}
|
||||||
|
fc := fake.NewSimpleClientset()
|
||||||
|
cmd := &resetCmd{
|
||||||
|
removeHelmHome: true,
|
||||||
|
out: &buf,
|
||||||
|
home: helmpath.Home(home),
|
||||||
|
client: c,
|
||||||
|
kubeClient: fc,
|
||||||
|
namespace: api.NamespaceDefault,
|
||||||
|
}
|
||||||
|
if err := cmd.run(); err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
actions := fc.Actions()
|
||||||
|
if len(actions) != 2 {
|
||||||
|
t.Errorf("Expected 2 actions, got %d", len(actions))
|
||||||
|
}
|
||||||
|
if !actions[0].Matches("get", "services") {
|
||||||
|
t.Errorf("unexpected action: %v, expected get service", actions[1])
|
||||||
|
}
|
||||||
|
if !actions[1].Matches("get", "deployments") {
|
||||||
|
t.Errorf("unexpected action: %v, expected get deployment", actions[0])
|
||||||
|
}
|
||||||
|
expected := "Tiller (the helm server side component) has been uninstalled from your Kubernetes Cluster."
|
||||||
|
if !strings.Contains(buf.String(), expected) {
|
||||||
|
t.Errorf("expected %q, got %q", expected, buf.String())
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(home); err == nil {
|
||||||
|
t.Errorf("Helm home directory %s already exists", home)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReset_deployedReleases(t *testing.T) {
|
||||||
|
home, err := ioutil.TempDir("", "helm_home")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(home)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
resp := []*release.Release{
|
||||||
|
releaseMock(&releaseOptions{name: "atlas-guide", statusCode: release.Status_DEPLOYED}),
|
||||||
|
}
|
||||||
|
c := &fakeReleaseClient{
|
||||||
|
rels: resp,
|
||||||
|
}
|
||||||
|
fc := fake.NewSimpleClientset()
|
||||||
|
cmd := &resetCmd{
|
||||||
|
out: &buf,
|
||||||
|
home: helmpath.Home(home),
|
||||||
|
client: c,
|
||||||
|
kubeClient: fc,
|
||||||
|
namespace: api.NamespaceDefault,
|
||||||
|
}
|
||||||
|
err = cmd.run()
|
||||||
|
expected := "There are still 1 deployed releases (Tip: use --force)"
|
||||||
|
if !strings.Contains(err.Error(), expected) {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(home); err != nil {
|
||||||
|
t.Errorf("Helm home directory %s does not exists", home)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReset_forceFlag(t *testing.T) {
|
||||||
|
home, err := ioutil.TempDir("", "helm_home")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.Remove(home)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
resp := []*release.Release{
|
||||||
|
releaseMock(&releaseOptions{name: "atlas-guide", statusCode: release.Status_DEPLOYED}),
|
||||||
|
}
|
||||||
|
c := &fakeReleaseClient{
|
||||||
|
rels: resp,
|
||||||
|
}
|
||||||
|
fc := fake.NewSimpleClientset()
|
||||||
|
cmd := &resetCmd{
|
||||||
|
force: true,
|
||||||
|
out: &buf,
|
||||||
|
home: helmpath.Home(home),
|
||||||
|
client: c,
|
||||||
|
kubeClient: fc,
|
||||||
|
namespace: api.NamespaceDefault,
|
||||||
|
}
|
||||||
|
if err := cmd.run(); err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
actions := fc.Actions()
|
||||||
|
if len(actions) != 2 {
|
||||||
|
t.Errorf("Expected 2 actions, got %d", len(actions))
|
||||||
|
}
|
||||||
|
if !actions[0].Matches("get", "services") {
|
||||||
|
t.Errorf("unexpected action: %v, expected get service", actions[1])
|
||||||
|
}
|
||||||
|
if !actions[1].Matches("get", "deployments") {
|
||||||
|
t.Errorf("unexpected action: %v, expected get deployment", actions[0])
|
||||||
|
}
|
||||||
|
expected := "Tiller (the helm server side component) has been uninstalled from your Kubernetes Cluster."
|
||||||
|
if !strings.Contains(buf.String(), expected) {
|
||||||
|
t.Errorf("expected %q, got %q", expected, buf.String())
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(home); err != nil {
|
||||||
|
t.Errorf("Helm home directory %s does not exists", home)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue