diff --git a/pkg/action/install.go b/pkg/action/install.go index c33d6bf3c..c8ab11458 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -309,7 +309,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release. if err != nil { return nil, err } - if _, err := i.cfg.KubeClient.Create(resourceList); err != nil && !apierrors.IsAlreadyExists(err) { + if _, err := i.cfg.KubeClient.CreateIfNotExists(resourceList); err != nil { return nil, err } } diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 2565d1832..53f1ecfeb 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -117,6 +117,14 @@ func (c *Client) IsReachable() error { return nil } +func (c *Client) CreateIfNotExists(resources ResourceList) (*Result, error) { + c.Log("creating %d resource(s)", len(resources)) + if err := perform(resources, createResourceIfNotExists); err != nil { + return nil, err + } + return &Result{Created: resources}, nil +} + // Create creates Kubernetes resources specified in the resource list. func (c *Client) Create(resources ResourceList) (*Result, error) { c.Log("creating %d resource(s)", len(resources)) @@ -384,6 +392,17 @@ func createResource(info *resource.Info) error { return info.Refresh(obj, true) } +func createResourceIfNotExists(info *resource.Info) error { + _, err := resource.NewHelper(info.Client, info.Mapping).Get(info.Namespace, info.Name) + if apierrors.IsNotFound(err) { + return createResource(info) + } else if err != nil { + return err + } + + return nil +} + func deleteResource(info *resource.Info) error { policy := metav1.DeletePropagationBackground opts := &metav1.DeleteOptions{PropagationPolicy: &policy} diff --git a/pkg/kube/fake/printer.go b/pkg/kube/fake/printer.go index e8bd1845b..c334e92e2 100644 --- a/pkg/kube/fake/printer.go +++ b/pkg/kube/fake/printer.go @@ -47,6 +47,11 @@ func (p *PrintingKubeClient) Create(resources kube.ResourceList) (*kube.Result, return &kube.Result{Created: resources}, nil } +// Create prints the values of what would be created with a real KubeClient. +func (p *PrintingKubeClient) CreateIfNotExists(resources kube.ResourceList) (*kube.Result, error) { + return p.Create(resources) +} + func (p *PrintingKubeClient) Wait(resources kube.ResourceList, _ time.Duration) error { _, err := io.Copy(p.Out, bufferize(resources)) return err diff --git a/pkg/kube/interface.go b/pkg/kube/interface.go index 545985996..b81119d15 100644 --- a/pkg/kube/interface.go +++ b/pkg/kube/interface.go @@ -29,6 +29,8 @@ import ( type Interface interface { // Create creates one or more resources. Create(resources ResourceList) (*Result, error) + // Create creates one or more resources with resource existance check. + CreateIfNotExists(resources ResourceList) (*Result, error) Wait(resources ResourceList, timeout time.Duration) error