Skip to content

Commit 00a99c0

Browse files
committed
Add leases subcommand in ctr
Signed-off-by: Derek McGowan <derek@mcgstyle.net>
1 parent 4c2ad9c commit 00a99c0

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed

cmd/ctr/app/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/containerd/containerd/cmd/ctr/commands/content"
2525
"github.com/containerd/containerd/cmd/ctr/commands/events"
2626
"github.com/containerd/containerd/cmd/ctr/commands/images"
27+
"github.com/containerd/containerd/cmd/ctr/commands/leases"
2728
namespacesCmd "github.com/containerd/containerd/cmd/ctr/commands/namespaces"
2829
"github.com/containerd/containerd/cmd/ctr/commands/plugins"
2930
"github.com/containerd/containerd/cmd/ctr/commands/pprof"
@@ -96,6 +97,7 @@ containerd CLI
9697
content.Command,
9798
events.Command,
9899
images.Command,
100+
leases.Command,
99101
namespacesCmd.Command,
100102
pprof.Command,
101103
run.Command,

cmd/ctr/commands/leases/leases.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
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 * 3600 * time.Second,
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+
Action: func(context *cli.Context) error {
167+
var lids = context.Args()
168+
if len(lids) == 0 {
169+
return cli.ShowSubcommandHelp(context)
170+
}
171+
client, ctx, cancel, err := commands.NewClient(context)
172+
if err != nil {
173+
return err
174+
}
175+
defer cancel()
176+
177+
ls := client.LeasesService()
178+
for _, lid := range lids {
179+
lease := leases.Lease{
180+
ID: lid,
181+
}
182+
if err := ls.Delete(ctx, lease); err != nil {
183+
return err
184+
}
185+
fmt.Println(lid)
186+
}
187+
188+
return nil
189+
},
190+
}

0 commit comments

Comments
 (0)