Add prune command

Signed-off-by: Alex Kreidler <alex.kreidler@deciphernow.com>
pull/5947/head
Alex Kreidler 6 years ago
parent 0b474e688f
commit 889572d7ff

@ -190,6 +190,7 @@ func newRootCmd(args []string) *cobra.Command {
newRollbackCmd(nil, out),
newStatusCmd(nil, out),
newUpgradeCmd(nil, out),
newPruneCmd(nil, out),
newReleaseTestCmd(nil, out),
newResetCmd(nil, out),

@ -0,0 +1,86 @@
/*
Copyright The Helm Authors.
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 (
"fmt"
"io"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
)
const pruneDesc = `
This command purges all deleted releases, cleaning them from removing them permanently so they can't be rolled back.
`
type pruneCmd struct {
disableHooks bool
timeout int64
out io.Writer
client helm.Interface
}
func newPruneCmd(c helm.Interface, out io.Writer) *cobra.Command {
prune := &pruneCmd{
out: out,
client: c,
}
cmd := &cobra.Command{
Use: "prune",
Short: "Purges deleted releases",
Long: pruneDesc,
PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error {
prune.client = ensureHelmClient(prune.client)
if err := prune.run(); err != nil {
return err
}
fmt.Fprintf(out, "Releases pruned\n")
return nil
},
}
f := cmd.Flags()
settings.AddFlagsTLS(f)
f.BoolVar(&prune.disableHooks, "no-hooks", false, "Prevent hooks from running during deletion")
f.Int64Var(&prune.timeout, "timeout", 300, "Time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
// set defaults from environment
settings.InitTLS(f)
return cmd
}
func (d *pruneCmd) run() error {
opts := []helm.DeleteOption{
helm.DeleteDisableHooks(d.disableHooks),
helm.DeleteTimeout(d.timeout),
}
_, errs := d.client.PruneReleases(opts...)
for _, err := range errs {
if err != nil {
return prettyError(err)
}
}
return nil
}

@ -29,6 +29,7 @@ import (
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/proto/hapi/release"
rls "k8s.io/helm/pkg/proto/hapi/services"
)
@ -148,6 +149,25 @@ func (h *Client) DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.Unins
return h.delete(ctx, req)
}
func (h *Client) PruneReleases(opts ...DeleteOption) ([]*rls.UninstallReleaseResponse, []error) {
res, err := h.ListReleases(ReleaseListStatuses([]release.Status_Code{release.Status_DELETED}))
if err != nil {
return nil, []error{err}
}
if res != nil && res.Releases != nil {
resps := make([]*rls.UninstallReleaseResponse, len(res.Releases))
errs := make([]error, len(res.Releases))
for _, rel := range res.Releases {
res, err := h.DeleteRelease(rel.Name, append(opts, DeletePurge(true))...)
resps = append(resps, res)
errs = append(errs, err)
}
return resps, errs
} else {
return nil, []error{fmt.Errorf("No deleted releases to prune")}
}
}
// UpdateRelease loads a chart from chstr and updates a release to a new/different chart.
func (h *Client) UpdateRelease(rlsName string, chstr string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) {
// load the chart to update

@ -19,6 +19,7 @@ package helm // import "k8s.io/helm/pkg/helm"
import (
"bytes"
"errors"
"fmt"
"math/rand"
"strings"
"sync"
@ -141,6 +142,29 @@ func (c *FakeClient) DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.U
return nil, storageerrors.ErrReleaseNotFound(rlsName)
}
func (c *FakeClient) PruneReleases(opts ...DeleteOption) ([]*rls.UninstallReleaseResponse, []error) {
relsToDelete := make([]*release.Release, 0)
for _, rel := range c.Rels {
if rel.Info.GetStatus().Code == release.Status_DELETED {
relsToDelete = append(relsToDelete, rel)
}
}
res := &rls.ListReleasesResponse{Releases: relsToDelete}
if res != nil && res.Releases != nil {
resps := make([]*rls.UninstallReleaseResponse, len(res.Releases))
errs := make([]error, len(res.Releases))
for _, rel := range res.Releases {
res, err := c.DeleteRelease(rel.Name, append(opts, DeletePurge(true))...)
resps = append(resps, res)
errs = append(errs, err)
}
return resps, errs
} else {
return nil, []error{fmt.Errorf("No deleted releases to prune")}
}
}
// GetVersion returns a fake version
func (c *FakeClient) GetVersion(opts ...VersionOption) (*rls.GetVersionResponse, error) {
return &rls.GetVersionResponse{

@ -27,6 +27,7 @@ type Interface interface {
InstallRelease(chStr, namespace string, opts ...InstallOption) (*rls.InstallReleaseResponse, error)
InstallReleaseFromChart(chart *chart.Chart, namespace string, opts ...InstallOption) (*rls.InstallReleaseResponse, error)
DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error)
PruneReleases(opts ...DeleteOption) ([]*rls.UninstallReleaseResponse, []error)
ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error)
UpdateRelease(rlsName, chStr string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error)
UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error)

Loading…
Cancel
Save