github.com/demonoid81/containerd@v1.3.4/cmd/ctr/commands/leases/leases.go (about) 1 /* 2 Copyright The containerd Authors. 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 leases 18 19 import ( 20 "fmt" 21 "os" 22 "sort" 23 "strings" 24 "text/tabwriter" 25 "time" 26 27 "github.com/containerd/containerd/cmd/ctr/commands" 28 "github.com/containerd/containerd/leases" 29 "github.com/pkg/errors" 30 "github.com/urfave/cli" 31 ) 32 33 // Command is the cli command for managing content 34 var Command = cli.Command{ 35 Name: "leases", 36 Usage: "manage leases", 37 Subcommands: cli.Commands{ 38 listCommand, 39 createCommand, 40 deleteCommand, 41 }, 42 } 43 44 var listCommand = cli.Command{ 45 46 Name: "list", 47 Aliases: []string{"ls"}, 48 Usage: "list all active leases", 49 ArgsUsage: "[flags] <filter>", 50 Description: "list active leases by containerd", 51 Flags: []cli.Flag{ 52 cli.BoolFlag{ 53 Name: "quiet, q", 54 Usage: "print only the blob digest", 55 }, 56 }, 57 Action: func(context *cli.Context) error { 58 var ( 59 filters = context.Args() 60 quiet = context.Bool("quiet") 61 ) 62 client, ctx, cancel, err := commands.NewClient(context) 63 if err != nil { 64 return err 65 } 66 defer cancel() 67 68 ls := client.LeasesService() 69 70 leaseList, err := ls.List(ctx, filters...) 71 if err != nil { 72 return errors.Wrap(err, "failed to list leases") 73 } 74 if quiet { 75 for _, l := range leaseList { 76 fmt.Println(l.ID) 77 } 78 return nil 79 } 80 tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0) 81 fmt.Fprintln(tw, "ID\tCREATED AT\tLABELS\t") 82 for _, l := range leaseList { 83 labels := "-" 84 if len(l.Labels) > 0 { 85 var pairs []string 86 for k, v := range l.Labels { 87 pairs = append(pairs, fmt.Sprintf("%v=%v", k, v)) 88 } 89 sort.Strings(pairs) 90 labels = strings.Join(pairs, ",") 91 } 92 93 fmt.Fprintf(tw, "%v\t%v\t%s\t\n", 94 l.ID, 95 l.CreatedAt.Local().Format(time.RFC3339), 96 labels) 97 } 98 99 return tw.Flush() 100 }, 101 } 102 103 var createCommand = cli.Command{ 104 Name: "create", 105 Usage: "create lease", 106 ArgsUsage: "[flags] <label>=<value> ...", 107 Description: "create a new lease", 108 Flags: []cli.Flag{ 109 cli.StringFlag{ 110 Name: "id", 111 Usage: "set the id for the lease, will be generated by default", 112 }, 113 cli.DurationFlag{ 114 Name: "expires, x", 115 Usage: "expiration of lease (0 value will not expire)", 116 Value: 24 * time.Hour, 117 }, 118 }, 119 Action: func(context *cli.Context) error { 120 var labelstr = context.Args() 121 client, ctx, cancel, err := commands.NewClient(context) 122 if err != nil { 123 return err 124 } 125 defer cancel() 126 127 ls := client.LeasesService() 128 opts := []leases.Opt{} 129 if len(labelstr) > 0 { 130 labels := map[string]string{} 131 for _, lstr := range labelstr { 132 l := strings.SplitN(lstr, "=", 2) 133 if len(l) == 1 { 134 labels[l[0]] = "" 135 } else { 136 labels[l[0]] = l[1] 137 } 138 } 139 opts = append(opts, leases.WithLabels(labels)) 140 } 141 142 if id := context.String("id"); id != "" { 143 opts = append(opts, leases.WithID(id)) 144 } 145 if exp := context.Duration("expires"); exp > 0 { 146 opts = append(opts, leases.WithExpiration(exp)) 147 } 148 149 l, err := ls.Create(ctx, opts...) 150 if err != nil { 151 return err 152 } 153 154 fmt.Println(l.ID) 155 156 return nil 157 }, 158 } 159 160 var deleteCommand = cli.Command{ 161 Name: "delete", 162 Aliases: []string{"rm"}, 163 Usage: "delete a lease", 164 ArgsUsage: "[flags] <lease id> ...", 165 Description: "delete a lease", 166 Flags: []cli.Flag{ 167 cli.BoolFlag{ 168 Name: "sync", 169 Usage: "Synchronously remove leases and all unreferenced resources", 170 }, 171 }, 172 Action: func(context *cli.Context) error { 173 var lids = context.Args() 174 if len(lids) == 0 { 175 return cli.ShowSubcommandHelp(context) 176 } 177 client, ctx, cancel, err := commands.NewClient(context) 178 if err != nil { 179 return err 180 } 181 defer cancel() 182 183 ls := client.LeasesService() 184 sync := context.Bool("sync") 185 for i, lid := range lids { 186 var opts []leases.DeleteOpt 187 if sync && i == len(lids)-1 { 188 opts = append(opts, leases.SynchronousDelete) 189 } 190 191 lease := leases.Lease{ 192 ID: lid, 193 } 194 if err := ls.Delete(ctx, lease, opts...); err != nil { 195 return err 196 } 197 fmt.Println(lid) 198 } 199 200 return nil 201 }, 202 }