github.com/danielqsj/helm@v2.0.0-alpha.4.0.20160908204436-976e0ba5199b+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. Flags like '--delete' and 37 '--all' will alter this behavior. Such flags can be combined: '--deleted --failed'. 38 39 By default, items are sorted alphabetically. Use the '-d' flag to sort by 40 release date. 41 42 If an argument is provided, it will be treated as a filter. Filters are 43 regular expressions (Perl compatible) that are applied to the list of releases. 44 Only items that match the filter will be returned. 45 46 $ helm list -l 'ara[a-z]+' 47 NAME UPDATED CHART 48 maudlin-arachnid Mon May 9 16:07:08 2016 alpine-0.1.0 49 50 If no results are found, 'helm list' will exit 0, but with no output (or in 51 the case of '-l', only headers). 52 53 By default, up to 256 items may be returned. To limit this, use the '--max' flag. 54 Setting '--max' to 0 will not return all results. Rather, it will return the 55 server's default, which may be much higher than 256. Pairing the '--max' 56 flag with the '--offset' flag allows you to page through results. 57 ` 58 59 type listCmd struct { 60 filter string 61 long bool 62 limit int 63 offset string 64 byDate bool 65 sortDesc bool 66 out io.Writer 67 all bool 68 deleted bool 69 deployed bool 70 failed bool 71 superseded bool 72 client helm.Interface 73 } 74 75 func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { 76 list := &listCmd{ 77 out: out, 78 client: client, 79 } 80 cmd := &cobra.Command{ 81 Use: "list [flags] [FILTER]", 82 Short: "list releases", 83 Long: listHelp, 84 Aliases: []string{"ls"}, 85 PersistentPreRunE: setupConnection, 86 RunE: func(cmd *cobra.Command, args []string) error { 87 if len(args) > 0 { 88 list.filter = strings.Join(args, " ") 89 } 90 if list.client == nil { 91 list.client = helm.NewClient(helm.Host(tillerHost)) 92 } 93 return list.run() 94 }, 95 } 96 f := cmd.Flags() 97 f.BoolVarP(&list.long, "long", "l", false, "output long listing format") 98 f.BoolVarP(&list.byDate, "date", "d", false, "sort by release date") 99 f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order") 100 f.IntVarP(&list.limit, "max", "m", 256, "maximum number of releases to fetch") 101 f.StringVarP(&list.offset, "offset", "o", "", "the next release name in the list, used to offset from start value") 102 f.BoolVar(&list.all, "all", false, "show all releases, not just the ones marked DEPLOYED") 103 f.BoolVar(&list.deleted, "deleted", false, "show deleted releases") 104 f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled") 105 f.BoolVar(&list.failed, "failed", false, "show failed releases") 106 // TODO: Do we want this as a feature of 'helm list'? 107 //f.BoolVar(&list.superseded, "history", true, "show historical releases") 108 return cmd 109 } 110 111 func (l *listCmd) run() error { 112 sortBy := services.ListSort_NAME 113 if l.byDate { 114 sortBy = services.ListSort_LAST_RELEASED 115 } 116 117 sortOrder := services.ListSort_ASC 118 if l.sortDesc { 119 sortOrder = services.ListSort_DESC 120 } 121 122 stats := l.statusCodes() 123 124 res, err := l.client.ListReleases( 125 helm.ReleaseListLimit(l.limit), 126 helm.ReleaseListOffset(l.offset), 127 helm.ReleaseListFilter(l.filter), 128 helm.ReleaseListSort(int32(sortBy)), 129 helm.ReleaseListOrder(int32(sortOrder)), 130 helm.ReleaseListStatuses(stats), 131 ) 132 133 if err != nil { 134 return prettyError(err) 135 } 136 137 if len(res.Releases) == 0 { 138 return nil 139 } 140 141 if res.Next != "" { 142 fmt.Fprintf(l.out, "\tnext: %s", res.Next) 143 } 144 145 rels := res.Releases 146 147 if l.long { 148 fmt.Fprintln(l.out, formatList(rels)) 149 return nil 150 } 151 for _, r := range rels { 152 fmt.Fprintln(l.out, r.Name) 153 } 154 155 return nil 156 } 157 158 // statusCodes gets the list of status codes that are to be included in the results. 159 func (l *listCmd) statusCodes() []release.Status_Code { 160 if l.all { 161 return []release.Status_Code{ 162 release.Status_UNKNOWN, 163 release.Status_DEPLOYED, 164 release.Status_DELETED, 165 // TODO: Should we return superseded records? These are records 166 // that were replaced by an upgrade. 167 //release.Status_SUPERSEDED, 168 release.Status_FAILED, 169 } 170 } 171 status := []release.Status_Code{} 172 if l.deployed { 173 status = append(status, release.Status_DEPLOYED) 174 } 175 if l.deleted { 176 status = append(status, release.Status_DELETED) 177 } 178 if l.failed { 179 status = append(status, release.Status_FAILED) 180 } 181 if l.superseded { 182 status = append(status, release.Status_SUPERSEDED) 183 } 184 185 // Default case. 186 if len(status) == 0 { 187 status = append(status, release.Status_DEPLOYED) 188 } 189 return status 190 } 191 192 func formatList(rels []*release.Release) string { 193 table := uitable.New() 194 table.MaxColWidth = 30 195 table.AddRow("NAME", "VERSION", "UPDATED", "STATUS", "CHART") 196 for _, r := range rels { 197 c := fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version) 198 t := timeconv.String(r.Info.LastDeployed) 199 s := r.Info.Status.Code.String() 200 v := r.Version 201 table.AddRow(r.Name, v, t, s, c) 202 } 203 return table.String() 204 }