Commit 8fc88ab6 authored by Taylor Thomas's avatar Taylor Thomas Committed by GitHub

Merge pull request #2681 from at1012/at-helm-list

feat(2063): Better 'helm list' visibility into state of pending upgrades
parents 014dcc0a 915e7023
......@@ -37,6 +37,12 @@ message Status {
FAILED = 4;
// Status_DELETING indicates that a delete operation is underway.
DELETING = 5;
// Status_PENDING_INSTALL indicates that an install operation is underway.
PENDING_INSTALL = 6;
// Status_PENDING_UPGRADE indicates that an upgrade operation is underway.
PENDING_UPGRADE = 7;
// Status_PENDING_ROLLBACK indicates that an rollback operation is underway.
PENDING_ROLLBACK = 8;
}
Code code = 1;
......
......@@ -72,6 +72,7 @@ type listCmd struct {
failed bool
namespace string
superseded bool
pending bool
client helm.Interface
}
......@@ -109,6 +110,7 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&list.deleting, "deleting", false, "show releases that are currently being deleted")
f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled")
f.BoolVar(&list.failed, "failed", false, "show failed releases")
f.BoolVar(&list.pending, "pending", false, "show pending releases")
f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace")
// TODO: Do we want this as a feature of 'helm list'?
......@@ -173,6 +175,9 @@ func (l *listCmd) statusCodes() []release.Status_Code {
release.Status_DELETED,
release.Status_DELETING,
release.Status_FAILED,
release.Status_PENDING_INSTALL,
release.Status_PENDING_UPGRADE,
release.Status_PENDING_ROLLBACK,
}
}
status := []release.Status_Code{}
......@@ -191,6 +196,9 @@ func (l *listCmd) statusCodes() []release.Status_Code {
if l.superseded {
status = append(status, release.Status_SUPERSEDED)
}
if l.pending {
status = append(status, release.Status_PENDING_INSTALL, release.Status_PENDING_UPGRADE, release.Status_PENDING_ROLLBACK)
}
// Default case.
if len(status) == 0 {
......
......@@ -98,6 +98,26 @@ func TestListCmd(t *testing.T) {
// See note on previous test.
expected: "thomas-guide",
},
{
name: "with a pending release, multiple flags",
args: []string{"--all", "-q"},
resp: []*release.Release{
releaseMock(&releaseOptions{name: "thomas-guide", statusCode: release.Status_PENDING_INSTALL}),
releaseMock(&releaseOptions{name: "atlas-guide", statusCode: release.Status_DEPLOYED}),
},
expected: "thomas-guide\natlas-guide",
},
{
name: "with a pending release, pending flag",
args: []string{"--pending", "-q"},
resp: []*release.Release{
releaseMock(&releaseOptions{name: "thomas-guide", statusCode: release.Status_PENDING_INSTALL}),
releaseMock(&releaseOptions{name: "wild-idea", statusCode: release.Status_PENDING_UPGRADE}),
releaseMock(&releaseOptions{name: "crazy-maps", statusCode: release.Status_PENDING_ROLLBACK}),
releaseMock(&releaseOptions{name: "atlas-guide", statusCode: release.Status_DEPLOYED}),
},
expected: "thomas-guide\nwild-idea\ncrazy-maps",
},
}
var buf bytes.Buffer
......
......@@ -48,6 +48,7 @@ helm list [flags] [FILTER]
-m, --max int maximum number of releases to fetch (default 256)
--namespace string show releases within a specific namespace
-o, --offset string next release name in the list, used to offset from start value
--pending show pending releases
-r, --reverse reverse the sort order
-q, --short output short (quiet) listing format
--tls enable TLS for request
......@@ -70,4 +71,4 @@ helm list [flags] [FILTER]
### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 10-Jul-2017
###### Auto generated by spf13/cobra on 12-Jul-2017
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/chart/chart.proto
// DO NOT EDIT!
/*
Package chart is a generated protocol buffer package.
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/chart/config.proto
// DO NOT EDIT!
package chart
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/chart/metadata.proto
// DO NOT EDIT!
package chart
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/chart/template.proto
// DO NOT EDIT!
package chart
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/hook.proto
// DO NOT EDIT!
/*
Package release is a generated protocol buffer package.
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/info.proto
// DO NOT EDIT!
package release
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/release.proto
// DO NOT EDIT!
package release
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/status.proto
// DO NOT EDIT!
package release
......@@ -29,6 +28,12 @@ const (
Status_FAILED Status_Code = 4
// Status_DELETING indicates that a delete operation is underway.
Status_DELETING Status_Code = 5
// Status_PENDING_INSTALL indicates that an install operation is underway.
Status_PENDING_INSTALL Status_Code = 6
// Status_PENDING_UPGRADE indicates that an upgrade operation is underway.
Status_PENDING_UPGRADE Status_Code = 7
// Status_PENDING_ROLLBACK indicates that an rollback operation is underway.
Status_PENDING_ROLLBACK Status_Code = 8
)
var Status_Code_name = map[int32]string{
......@@ -38,14 +43,20 @@ var Status_Code_name = map[int32]string{
3: "SUPERSEDED",
4: "FAILED",
5: "DELETING",
6: "PENDING_INSTALL",
7: "PENDING_UPGRADE",
8: "PENDING_ROLLBACK",
}
var Status_Code_value = map[string]int32{
"UNKNOWN": 0,
"DEPLOYED": 1,
"DELETED": 2,
"SUPERSEDED": 3,
"FAILED": 4,
"DELETING": 5,
"UNKNOWN": 0,
"DEPLOYED": 1,
"DELETED": 2,
"SUPERSEDED": 3,
"FAILED": 4,
"DELETING": 5,
"PENDING_INSTALL": 6,
"PENDING_UPGRADE": 7,
"PENDING_ROLLBACK": 8,
}
func (x Status_Code) String() string {
......@@ -105,24 +116,26 @@ func init() {
func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor3) }
var fileDescriptor3 = []byte{
// 291 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xdf, 0x6a, 0xc2, 0x30,
0x14, 0xc6, 0x57, 0xad, 0x3a, 0x8f, 0x22, 0x21, 0x1b, 0xac, 0xca, 0x06, 0xc5, 0xab, 0xde, 0xac,
0x05, 0xf7, 0x04, 0xdb, 0x12, 0x87, 0xac, 0x54, 0x69, 0x2b, 0xfb, 0x73, 0x53, 0xaa, 0x9e, 0x39,
0xa1, 0x34, 0xd2, 0x24, 0x17, 0x7b, 0x88, 0xbd, 0xf3, 0x68, 0x2b, 0x74, 0x5e, 0x7e, 0xf9, 0xfd,
0x4e, 0xce, 0xc7, 0x81, 0xf1, 0x77, 0x7a, 0x3c, 0x78, 0x05, 0x66, 0x98, 0x4a, 0xf4, 0xa4, 0x4a,
0x95, 0x96, 0xee, 0xb1, 0x10, 0x4a, 0xd0, 0x61, 0x89, 0xdc, 0x13, 0x9a, 0xdc, 0x9d, 0x89, 0x0a,
0xa5, 0x4a, 0xa4, 0x3e, 0x28, 0xac, 0xe5, 0xc9, 0x78, 0x2f, 0xc4, 0x3e, 0x43, 0xaf, 0x4a, 0x1b,
0xfd, 0xe5, 0xa5, 0xf9, 0x4f, 0x8d, 0xa6, 0xbf, 0x2d, 0xe8, 0x46, 0xd5, 0xc7, 0xf4, 0x1e, 0xcc,
0xad, 0xd8, 0xa1, 0x65, 0xd8, 0x86, 0x33, 0x9a, 0x8d, 0xdd, 0xff, 0x1b, 0xdc, 0xda, 0x71, 0x9f,
0xc5, 0x0e, 0xc3, 0x4a, 0xa3, 0xb7, 0xd0, 0x2f, 0x50, 0x0a, 0x5d, 0x6c, 0x51, 0x5a, 0x6d, 0xdb,
0x70, 0xfa, 0x61, 0xf3, 0x40, 0xaf, 0xa1, 0x93, 0x0b, 0x85, 0xd2, 0x32, 0x2b, 0x52, 0x07, 0x3a,
0x87, 0xab, 0x2c, 0x95, 0x2a, 0x69, 0x1a, 0x26, 0x85, 0xce, 0xad, 0x8e, 0x6d, 0x38, 0x83, 0xd9,
0xcd, 0xf9, 0xc6, 0x18, 0xa5, 0x8a, 0x4a, 0x25, 0x24, 0xe5, 0x4c, 0x13, 0x75, 0x3e, 0x7d, 0x07,
0xb3, 0x6c, 0x42, 0x07, 0xd0, 0x5b, 0x07, 0xaf, 0xc1, 0xf2, 0x2d, 0x20, 0x17, 0x74, 0x08, 0x97,
0x8c, 0xaf, 0xfc, 0xe5, 0x07, 0x67, 0xc4, 0x28, 0x11, 0xe3, 0x3e, 0x8f, 0x39, 0x23, 0x2d, 0x3a,
0x02, 0x88, 0xd6, 0x2b, 0x1e, 0x46, 0x9c, 0x71, 0x46, 0xda, 0x14, 0xa0, 0x3b, 0x7f, 0x5c, 0xf8,
0x9c, 0x11, 0xb3, 0x1e, 0xf3, 0x79, 0xbc, 0x08, 0x5e, 0x48, 0xe7, 0xa9, 0xff, 0xd9, 0x3b, 0x15,
0xd8, 0x74, 0xab, 0x0b, 0x3d, 0xfc, 0x05, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x11, 0x21, 0x30, 0x86,
0x01, 0x00, 0x00,
// 333 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xd1, 0x6e, 0xa2, 0x40,
0x14, 0x86, 0x17, 0x45, 0xd4, 0xa3, 0x71, 0x27, 0xa3, 0xc9, 0xa2, 0xd9, 0x4d, 0x8c, 0x57, 0xde,
0x2c, 0x24, 0xf6, 0x09, 0xd0, 0x19, 0x0d, 0x71, 0x82, 0x04, 0x30, 0x4d, 0x7b, 0x43, 0x50, 0xa7,
0xd6, 0xc4, 0x30, 0x86, 0x19, 0x2e, 0xfa, 0x26, 0x7d, 0xaa, 0x3e, 0x53, 0x03, 0xd8, 0xa8, 0x97,
0xff, 0xff, 0x7d, 0x87, 0x73, 0x18, 0x18, 0xbe, 0x27, 0x97, 0x93, 0x9d, 0xf1, 0x33, 0x4f, 0x24,
0xb7, 0xa5, 0x4a, 0x54, 0x2e, 0xad, 0x4b, 0x26, 0x94, 0xc0, 0xdd, 0x02, 0x59, 0x57, 0x34, 0xfa,
0xf7, 0x20, 0x2a, 0x2e, 0x55, 0x2c, 0xf3, 0x93, 0xe2, 0x95, 0x3c, 0x1a, 0x1e, 0x85, 0x38, 0x9e,
0xb9, 0x5d, 0xa6, 0x5d, 0xfe, 0x66, 0x27, 0xe9, 0x47, 0x85, 0x26, 0x5f, 0x35, 0x30, 0xc2, 0xf2,
0xc3, 0xf8, 0x3f, 0xe8, 0x7b, 0x71, 0xe0, 0xa6, 0x36, 0xd6, 0xa6, 0xbd, 0xd9, 0xd0, 0xba, 0xdf,
0x60, 0x55, 0x8e, 0xb5, 0x10, 0x07, 0x1e, 0x94, 0x1a, 0xfe, 0x0b, 0xed, 0x8c, 0x4b, 0x91, 0x67,
0x7b, 0x2e, 0xcd, 0xfa, 0x58, 0x9b, 0xb6, 0x83, 0x5b, 0x81, 0x07, 0xd0, 0x48, 0x85, 0xe2, 0xd2,
0xd4, 0x4b, 0x52, 0x05, 0xbc, 0x84, 0xfe, 0x39, 0x91, 0x2a, 0xbe, 0x5d, 0x18, 0x67, 0x79, 0x6a,
0x36, 0xc6, 0xda, 0xb4, 0x33, 0xfb, 0xf3, 0xb8, 0x31, 0xe2, 0x52, 0x85, 0x85, 0x12, 0xa0, 0x62,
0xe6, 0x16, 0xf3, 0x74, 0xf2, 0xa9, 0x81, 0x5e, 0x9c, 0x82, 0x3b, 0xd0, 0xdc, 0x7a, 0x6b, 0x6f,
0xf3, 0xec, 0xa1, 0x5f, 0xb8, 0x0b, 0x2d, 0x42, 0x7d, 0xb6, 0x79, 0xa1, 0x04, 0x69, 0x05, 0x22,
0x94, 0xd1, 0x88, 0x12, 0x54, 0xc3, 0x3d, 0x80, 0x70, 0xeb, 0xd3, 0x20, 0xa4, 0x84, 0x12, 0x54,
0xc7, 0x00, 0xc6, 0xd2, 0x71, 0x19, 0x25, 0x48, 0xaf, 0xc6, 0x18, 0x8d, 0x5c, 0x6f, 0x85, 0x1a,
0xb8, 0x0f, 0xbf, 0x7d, 0xea, 0x11, 0xd7, 0x5b, 0xc5, 0xae, 0x17, 0x46, 0x0e, 0x63, 0xc8, 0xb8,
0x2f, 0xb7, 0xfe, 0x2a, 0x70, 0x08, 0x45, 0x4d, 0x3c, 0x00, 0xf4, 0x53, 0x06, 0x1b, 0xc6, 0xe6,
0xce, 0x62, 0x8d, 0x5a, 0xf3, 0xf6, 0x6b, 0xf3, 0xfa, 0x07, 0x3b, 0xa3, 0x7c, 0xe2, 0xa7, 0xef,
0x00, 0x00, 0x00, 0xff, 0xff, 0x09, 0x48, 0x18, 0xba, 0xc7, 0x01, 0x00, 0x00,
}
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/test_run.proto
// DO NOT EDIT!
package release
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/release/test_suite.proto
// DO NOT EDIT!
package release
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/rudder/rudder.proto
// DO NOT EDIT!
/*
Package rudder is a generated protocol buffer package.
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/services/tiller.proto
// DO NOT EDIT!
/*
Package services is a generated protocol buffer package.
......
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hapi/version/version.proto
// DO NOT EDIT!
/*
Package version is a generated protocol buffer package.
......
......@@ -116,7 +116,7 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
Info: &release.Info{
FirstDeployed: ts,
LastDeployed: ts,
Status: &release.Status{Code: release.Status_UNKNOWN},
Status: &release.Status{Code: release.Status_PENDING_INSTALL},
Description: "Initial install underway", // Will be overwritten.
},
Manifest: manifestDoc.String(),
......@@ -172,6 +172,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
Recreate: false,
Timeout: req.Timeout,
}
s.recordRelease(r, false)
if err := s.ReleaseModule.Update(old, r, updateReq, s.env); err != nil {
msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err)
s.Log("warning: %s", msg)
......@@ -179,19 +180,20 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
r.Info.Status.Code = release.Status_FAILED
r.Info.Description = msg
s.recordRelease(old, true)
s.recordRelease(r, false)
s.recordRelease(r, true)
return res, err
}
default:
// nothing to replace, create as normal
// regular manifests
s.recordRelease(r, false)
if err := s.ReleaseModule.Create(r, req, s.env); err != nil {
msg := fmt.Sprintf("Release %q failed: %s", r.Name, err)
s.Log("warning: %s", msg)
r.Info.Status.Code = release.Status_FAILED
r.Info.Description = msg
s.recordRelease(r, false)
s.recordRelease(r, true)
return res, fmt.Errorf("release %s failed: %s", r.Name, err)
}
}
......@@ -203,7 +205,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
s.Log("warning: %s", msg)
r.Info.Status.Code = release.Status_FAILED
r.Info.Description = msg
s.recordRelease(r, false)
s.recordRelease(r, true)
return res, err
}
}
......@@ -217,7 +219,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
//
// One possible strategy would be to do a timed retry to see if we can get
// this stored in the future.
s.recordRelease(r, false)
s.recordRelease(r, true)
return res, nil
}
......@@ -41,6 +41,12 @@ func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackRel
return nil, err
}
if !req.DryRun {
s.Log("creating rolled back release for %s", req.Name)
if err := s.env.Releases.Create(targetRelease); err != nil {
return nil, err
}
}
s.Log("performing rollback of %s", req.Name)
res, err := s.performRollback(currentRelease, targetRelease, req)
if err != nil {
......@@ -48,8 +54,8 @@ func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackRel
}
if !req.DryRun {
s.Log("creating rolled back release %s", req.Name)
if err := s.env.Releases.Create(targetRelease); err != nil {
s.Log("updating status for rolled back release for %s", req.Name)
if err := s.env.Releases.Update(targetRelease); err != nil {
return res, err
}
}
......@@ -96,7 +102,7 @@ func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*
FirstDeployed: crls.Info.FirstDeployed,
LastDeployed: timeconv.Now(),
Status: &release.Status{
Code: release.Status_UNKNOWN,
Code: release.Status_PENDING_ROLLBACK,
Notes: prls.Info.Status.Notes,
},
// Because we lose the reference to rbv elsewhere, we set the
......
......@@ -47,6 +47,13 @@ func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
return nil, err
}
if !req.DryRun {
s.Log("creating updated release for %s", req.Name)
if err := s.env.Releases.Create(updatedRelease); err != nil {
return nil, err
}
}
s.Log("performing update for %s", req.Name)
res, err := s.performUpdate(currentRelease, updatedRelease, req)
if err != nil {
......@@ -54,8 +61,8 @@ func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
}
if !req.DryRun {
s.Log("creating updated release for %s", req.Name)
if err := s.env.Releases.Create(updatedRelease); err != nil {
s.Log("updating status for updated release for %s", req.Name)
if err := s.env.Releases.Update(updatedRelease); err != nil {
return res, err
}
}
......@@ -116,7 +123,7 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele
Info: &release.Info{
FirstDeployed: currentRelease.Info.FirstDeployed,
LastDeployed: ts,
Status: &release.Status{Code: release.Status_UNKNOWN},
Status: &release.Status{Code: release.Status_PENDING_UPGRADE},
Description: "Preparing upgrade", // This should be overwritten later.
},
Version: revision,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment