github.com/sgoings/helm@v2.0.0-alpha.2.0.20170406211108-734e92851ac3+incompatible/cmd/helm/list.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "io" 22 "strings" 23 24 "github.com/gosuri/uitable" 25 "github.com/spf13/cobra" 26 27 "k8s.io/helm/pkg/helm" 28 "k8s.io/helm/pkg/proto/hapi/release" 29 "k8s.io/helm/pkg/proto/hapi/services" 30 "k8s.io/helm/pkg/timeconv" 31 ) 32 33 var listHelp = ` 34 This command lists all of the releases. 35 36 By default, it lists only releases that are deployed or failed. Flags like 37 '--deleted' and '--all' will alter this behavior. Such flags can be combined: 38 '--deleted --failed'. 39 40 By default, items are sorted alphabetically. Use the '-d' flag to sort by 41 release date. 42 43 If an argument is provided, it will be treated as a filter. Filters are 44 regular expressions (Perl compatible) that are applied to the list of releases. 45 Only items that match the filter will be returned. 46 47 $ helm list 'ara[a-z]+' 48 NAME UPDATED CHART 49 maudlin-arachnid Mon May 9 16:07:08 2016 alpine-0.1.0 50 51 If no results are found, 'helm list' will exit 0, but with no output (or in 52 the case of no '-q' flag, only headers). 53 54 By default, up to 256 items may be returned. To limit this, use the '--max' flag. 55 Setting '--max' to 0 will not return all results. Rather, it will return the 56 server's default, which may be much higher than 256. Pairing the '--max' 57 flag with the '--offset' flag allows you to page through results. 58 ` 59 60 type listCmd struct { 61 filter string 62 short bool 63 limit int 64 offset string 65 byDate bool 66 sortDesc bool 67 out io.Writer 68 all bool 69 deleted bool 70 deleting bool 71 deployed bool 72 failed bool 73 namespace string 74 superseded bool 75 client helm.Interface 76 } 77 78 func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { 79 list := &listCmd{ 80 out: out, 81 client: client, 82 } 83 84 cmd := &cobra.Command{ 85 Use: "list [flags] [FILTER]", 86 Short: "list releases", 87 Long: listHelp, 88 Aliases: []string{"ls"}, 89 PersistentPreRunE: setupConnection, 90 RunE: func(cmd *cobra.Command, args []string) error { 91 if len(args) > 0 { 92 list.filter = strings.Join(args, " ") 93 } 94 if list.client == nil { 95 list.client = helm.NewClient(helm.Host(tillerHost)) 96 } 97 return list.run() 98 }, 99 } 100 101 f := cmd.Flags() 102 f.BoolVarP(&list.short, "short", "q", false, "output short (quiet) listing format") 103 f.BoolVarP(&list.byDate, "date", "d", false, "sort by release date") 104 f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order") 105 f.IntVarP(&list.limit, "max", "m", 256, "maximum number of releases to fetch") 106 f.StringVarP(&list.offset, "offset", "o", "", "next release name in the list, used to offset from start value") 107 f.BoolVar(&list.all, "all", false, "show all releases, not just the ones marked DEPLOYED") 108 f.BoolVar(&list.deleted, "deleted", false, "show deleted releases") 109 f.BoolVar(&list.deleting, "deleting", false, "show releases that are currently being deleted") 110 f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled") 111 f.BoolVar(&list.failed, "failed", false, "show failed releases") 112 f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace") 113 114 // TODO: Do we want this as a feature of 'helm list'? 115 //f.BoolVar(&list.superseded, "history", true, "show historical releases") 116 117 return cmd 118 } 119 120 func (l *listCmd) run() error { 121 sortBy := services.ListSort_NAME 122 if l.byDate { 123 sortBy = services.ListSort_LAST_RELEASED 124 } 125 126 sortOrder := services.ListSort_ASC 127 if l.sortDesc { 128 sortOrder = services.ListSort_DESC 129 } 130 131 stats := l.statusCodes() 132 133 res, err := l.client.ListReleases( 134 helm.ReleaseListLimit(l.limit), 135 helm.ReleaseListOffset(l.offset), 136 helm.ReleaseListFilter(l.filter), 137 helm.ReleaseListSort(int32(sortBy)), 138 helm.ReleaseListOrder(int32(sortOrder)), 139 helm.ReleaseListStatuses(stats), 140 helm.ReleaseListNamespace(l.namespace), 141 ) 142 143 if err != nil { 144 return prettyError(err) 145 } 146 147 if len(res.Releases) == 0 { 148 return nil 149 } 150 151 if res.Next != "" && !l.short { 152 fmt.Fprintf(l.out, "\tnext: %s\n", res.Next) 153 } 154 155 rels := res.Releases 156 157 if l.short { 158 for _, r := range rels { 159 fmt.Fprintln(l.out, r.Name) 160 } 161 return nil 162 } 163 fmt.Fprintln(l.out, formatList(rels)) 164 return nil 165 } 166 167 // statusCodes gets the list of status codes that are to be included in the results. 168 func (l *listCmd) statusCodes() []release.Status_Code { 169 if l.all { 170 return []release.Status_Code{ 171 release.Status_UNKNOWN, 172 release.Status_DEPLOYED, 173 release.Status_DELETED, 174 release.Status_DELETING, 175 release.Status_FAILED, 176 } 177 } 178 status := []release.Status_Code{} 179 if l.deployed { 180 status = append(status, release.Status_DEPLOYED) 181 } 182 if l.deleted { 183 status = append(status, release.Status_DELETED) 184 } 185 if l.deleting { 186 status = append(status, release.Status_DELETING) 187 } 188 if l.failed { 189 status = append(status, release.Status_FAILED) 190 } 191 if l.superseded { 192 status = append(status, release.Status_SUPERSEDED) 193 } 194 195 // Default case. 196 if len(status) == 0 { 197 status = append(status, release.Status_DEPLOYED, release.Status_FAILED) 198 } 199 return status 200 } 201 202 func formatList(rels []*release.Release) string { 203 table := uitable.New() 204 table.MaxColWidth = 60 205 table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "NAMESPACE") 206 for _, r := range rels { 207 c := fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version) 208 t := timeconv.String(r.Info.LastDeployed) 209 s := r.Info.Status.Code.String() 210 v := r.Version 211 n := r.Namespace 212 table.AddRow(r.Name, v, t, s, c, n) 213 } 214 return table.String() 215 }