Merge pull request #1685 from jessvalarezo/ctr-refactor

ctr: move ctr commands
This commit is contained in:
Derek McGowan 2017-10-26 11:36:18 -07:00 committed by GitHub
commit 638f3a3380
13 changed files with 332 additions and 344 deletions

View File

@ -0,0 +1,210 @@
package containers
import (
"context"
"errors"
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/log"
"github.com/urfave/cli"
)
// Command is the cli command for managing containers
var Command = cli.Command{
Name: "containers",
Usage: "manage containers",
Aliases: []string{"c"},
Subcommands: []cli.Command{
listCommand,
deleteCommand,
setLabelsCommand,
infoCommand,
},
}
var listCommand = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list containers",
ArgsUsage: "[flags] [<filter>, ...]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet, q",
Usage: "print only the container id",
},
},
Action: func(context *cli.Context) error {
var (
filters = context.Args()
quiet = context.Bool("quiet")
)
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
containers, err := client.Containers(ctx, filters...)
if err != nil {
return err
}
if quiet {
for _, c := range containers {
fmt.Printf("%s\n", c.ID())
}
return nil
}
w := tabwriter.NewWriter(os.Stdout, 4, 8, 4, ' ', 0)
fmt.Fprintln(w, "CONTAINER\tIMAGE\tRUNTIME\t")
for _, c := range containers {
info, err := c.Info(ctx)
if err != nil {
return err
}
imageName := info.Image
if imageName == "" {
imageName = "-"
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t\n",
c.ID(),
imageName,
info.Runtime.Name,
); err != nil {
return err
}
}
return w.Flush()
},
}
var deleteCommand = cli.Command{
Name: "delete",
Usage: "delete one or more existing containers",
ArgsUsage: "[flags] CONTAINER [CONTAINER, ...]",
Aliases: []string{"del", "rm"},
Flags: []cli.Flag{
cli.BoolFlag{
Name: "keep-snapshot",
Usage: "do not clean up snapshot with container",
},
},
Action: func(context *cli.Context) error {
var exitErr error
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
deleteOpts := []containerd.DeleteOpts{}
if !context.Bool("keep-snapshot") {
deleteOpts = append(deleteOpts, containerd.WithSnapshotCleanup)
}
if context.NArg() == 0 {
return errors.New("must specify at least one container to delete")
}
for _, arg := range context.Args() {
if err := deleteContainer(ctx, client, arg, deleteOpts...); err != nil {
if exitErr == nil {
exitErr = err
}
log.G(ctx).WithError(err).Errorf("failed to delete container %q", arg)
}
}
return exitErr
},
}
func deleteContainer(ctx context.Context, client *containerd.Client, id string, opts ...containerd.DeleteOpts) error {
container, err := client.LoadContainer(ctx, id)
if err != nil {
return err
}
task, err := container.Task(ctx, nil)
if err != nil {
return container.Delete(ctx, opts...)
}
status, err := task.Status(ctx)
if err != nil {
return err
}
if status.Status == containerd.Stopped || status.Status == containerd.Created {
if _, err := task.Delete(ctx); err != nil {
return err
}
return container.Delete(ctx, opts...)
}
return fmt.Errorf("cannot delete a non stopped container: %v", status)
}
var setLabelsCommand = cli.Command{
Name: "label",
Usage: "set and clear labels for a container",
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
Description: "set and clear labels for a container",
Flags: []cli.Flag{},
Action: func(context *cli.Context) error {
containerID, labels := commands.ObjectWithLabelArgs(context)
if containerID == "" {
return errors.New("please specify a container")
}
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
container, err := client.LoadContainer(ctx, containerID)
if err != nil {
return err
}
setlabels, err := container.SetLabels(ctx, labels)
if err != nil {
return err
}
var labelStrings []string
for k, v := range setlabels {
labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
}
fmt.Println(strings.Join(labelStrings, ","))
return nil
},
}
var infoCommand = cli.Command{
Name: "info",
Usage: "get info about a container",
ArgsUsage: "CONTAINER",
Action: func(context *cli.Context) error {
id := context.Args().First()
if id == "" {
return errors.New("container id must be provided")
}
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
container, err := client.LoadContainer(ctx, id)
if err != nil {
return err
}
info, err := container.Info(ctx)
if err != nil {
return err
}
commands.PrintAsJSON(info)
return nil
},
}

View File

@ -1,4 +1,4 @@
package main
package content
import (
"fmt"
@ -21,26 +21,26 @@ import (
)
var (
contentCommand = cli.Command{
// Command is the cli command for managing content
Command = cli.Command{
Name: "content",
Usage: "manage content",
Subcommands: cli.Commands{
listContentCommand,
ingestContentCommand,
listCommand,
ingestCommand,
activeIngestCommand,
getContentCommand,
editContentCommand,
deleteContentCommand,
labelContentCommand,
getCommand,
editCommand,
deleteCommand,
setLabelsCommand,
},
}
getContentCommand = cli.Command{
getCommand = cli.Command{
Name: "get",
Usage: "get the data for an object",
ArgsUsage: "[flags] [<digest>, ...]",
Description: "Display the image object.",
Flags: []cli.Flag{},
ArgsUsage: "[<digest>, ...]",
Description: "display the image object",
Action: func(context *cli.Context) error {
dgst, err := digest.Parse(context.Args().First())
if err != nil {
@ -63,11 +63,11 @@ var (
},
}
ingestContentCommand = cli.Command{
ingestCommand = cli.Command{
Name: "ingest",
Usage: "accept content into the store",
ArgsUsage: "[flags] <key>",
Description: `Ingest objects into the local content store.`,
Description: "ingest objects into the local content store",
Flags: []cli.Flag{
cli.Int64Flag{
Name: "expected-size",
@ -107,9 +107,9 @@ var (
activeIngestCommand = cli.Command{
Name: "active",
Usage: "display active transfers.",
Usage: "display active transfers",
ArgsUsage: "[flags] [<regexp>]",
Description: `Display the ongoing transfers.`,
Description: "display the ongoing transfers",
Flags: []cli.Flag{
cli.DurationFlag{
Name: "timeout, t",
@ -147,12 +147,12 @@ var (
},
}
listContentCommand = cli.Command{
listCommand = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list all blobs in the store.",
ArgsUsage: "[flags] [<filter>, ...]",
Description: `List blobs in the content store.`,
Usage: "list all blobs in the store",
ArgsUsage: "[flags]",
Description: "list blobs in the content store",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet, q",
@ -206,12 +206,11 @@ var (
},
}
labelContentCommand = cli.Command{
setLabelsCommand = cli.Command{
Name: "label",
Usage: "add labels to content",
ArgsUsage: "[flags] <digest> [<label>=<value> ...]",
Description: `Labels blobs in the content store`,
Flags: []cli.Flag{},
ArgsUsage: "<digest> [<label>=<value> ...]",
Description: "labels blobs in the content store",
Action: func(context *cli.Context) error {
object, labels := commands.ObjectWithLabelArgs(context)
client, ctx, cancel, err := commands.NewClient(context)
@ -261,11 +260,11 @@ var (
},
}
editContentCommand = cli.Command{
editCommand = cli.Command{
Name: "edit",
Usage: "edit a blob and return a new digest.",
Usage: "edit a blob and return a new digest",
ArgsUsage: "[flags] <digest>",
Description: `Edit a blob and return a new digest.`,
Description: "edit a blob and return a new digest",
Flags: []cli.Flag{
cli.StringFlag{
Name: "validate",
@ -325,14 +324,13 @@ var (
},
}
deleteContentCommand = cli.Command{
deleteCommand = cli.Command{
Name: "delete",
Aliases: []string{"del", "remove", "rm"},
Usage: "permanently delete one or more blobs.",
ArgsUsage: "[flags] [<digest>, ...]",
Usage: "permanently delete one or more blobs",
ArgsUsage: "[<digest>, ...]",
Description: `Delete one or more blobs permanently. Successfully deleted
blobs are printed to stdout.`,
Flags: []cli.Flag{},
Action: func(context *cli.Context) error {
var (
args = []string(context.Args())

View File

@ -1,4 +1,4 @@
package main
package events
import (
"encoding/json"
@ -10,7 +10,8 @@ import (
"github.com/urfave/cli"
)
var eventsCommand = cli.Command{
// Command is the cli command for displaying containerd events
var Command = cli.Command{
Name: "events",
Usage: "display containerd events",
Action: func(context *cli.Context) error {

View File

@ -1,4 +1,4 @@
package main
package images
import (
"io"
@ -12,11 +12,11 @@ import (
"github.com/urfave/cli"
)
var imagesExportCommand = cli.Command{
var exportCommand = cli.Command{
Name: "export",
Usage: "export an image",
ArgsUsage: "[flags] <out> <image>",
Description: `Export an image to a tar stream.`,
Description: "export an image to a tar stream",
Flags: []cli.Flag{
cli.StringFlag{
Name: "oci-ref-name",

View File

@ -1,4 +1,4 @@
package main
package images
import (
"fmt"
@ -17,25 +17,26 @@ import (
"github.com/urfave/cli"
)
var imageCommand = cli.Command{
// Command is the cli command for managing images
var Command = cli.Command{
Name: "images",
Usage: "manage images",
Subcommands: cli.Commands{
imagesListCommand,
imagesCheckCommand,
imageRemoveCommand,
imagesSetLabelsCommand,
imagesImportCommand,
imagesExportCommand,
listCommand,
checkCommand,
removeCommand,
setLabelsCommand,
importCommand,
exportCommand,
},
}
var imagesListCommand = cli.Command{
var listCommand = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list images known to containerd",
ArgsUsage: "[flags] <ref>",
Description: `List images registered with containerd.`,
Description: "list images registered with containerd",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet, q",
@ -114,11 +115,11 @@ var imagesListCommand = cli.Command{
},
}
var imagesSetLabelsCommand = cli.Command{
var setLabelsCommand = cli.Command{
Name: "label",
Usage: "set and clear labels for an image.",
Usage: "set and clear labels for an image",
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
Description: "Set and clear labels for an image.",
Description: "set and clear labels for an image",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "replace-all, r",
@ -173,12 +174,11 @@ var imagesSetLabelsCommand = cli.Command{
},
}
var imagesCheckCommand = cli.Command{
var checkCommand = cli.Command{
Name: "check",
Usage: "Check that an image has all content available locally.",
ArgsUsage: "[flags] <ref> [<ref>, ...]",
Description: "Check that an image has all content available locally.",
Flags: []cli.Flag{},
Usage: "check that an image has all content available locally",
ArgsUsage: "<ref> [<ref>, ...]",
Description: "check that an image has all content available locally",
Action: func(context *cli.Context) error {
var (
exitErr error
@ -255,13 +255,12 @@ var imagesCheckCommand = cli.Command{
},
}
var imageRemoveCommand = cli.Command{
var removeCommand = cli.Command{
Name: "remove",
Aliases: []string{"rm"},
Usage: "Remove one or more images by reference.",
ArgsUsage: "[flags] <ref> [<ref>, ...]",
Description: `Remove one or more images by reference.`,
Flags: []cli.Flag{},
Usage: "remove one or more images by reference",
ArgsUsage: "<ref> [<ref>, ...]",
Description: "remove one or more images by reference",
Action: func(context *cli.Context) error {
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {

View File

@ -1,4 +1,4 @@
package main
package images
import (
"fmt"
@ -11,11 +11,11 @@ import (
"github.com/urfave/cli"
)
var imagesImportCommand = cli.Command{
var importCommand = cli.Command{
Name: "import",
Usage: "import an image",
ArgsUsage: "[flags] <ref> <in>",
Description: `Import an image from a tar stream.`,
Description: "import an image from a tar stream",
Flags: []cli.Flag{
cli.StringFlag{
Name: "ref-object",

View File

@ -1,4 +1,4 @@
package main
package namespaces
import (
"fmt"
@ -14,22 +14,23 @@ import (
"github.com/urfave/cli"
)
var namespacesCommand = cli.Command{
// Command is the cli command for managing namespaces
var Command = cli.Command{
Name: "namespaces",
Usage: "manage namespaces",
Subcommands: cli.Commands{
namespacesCreateCommand,
namespacesSetLabelsCommand,
namespacesListCommand,
namespacesRemoveCommand,
createCommand,
setLabelsCommand,
listCommand,
removeCommand,
},
}
var namespacesCreateCommand = cli.Command{
var createCommand = cli.Command{
Name: "create",
Usage: "create a new namespace.",
ArgsUsage: "[flags] <name> [<key>=<value]",
Description: "Create a new namespace. It must be unique.",
Usage: "create a new namespace",
ArgsUsage: "<name> [<key>=<value]",
Description: "create a new namespace. it must be unique",
Action: func(context *cli.Context) error {
namespace, labels := commands.ObjectWithLabelArgs(context)
if namespace == "" {
@ -45,12 +46,11 @@ var namespacesCreateCommand = cli.Command{
},
}
var namespacesSetLabelsCommand = cli.Command{
var setLabelsCommand = cli.Command{
Name: "label",
Usage: "set and clear labels for a namespace.",
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
Description: "Set and clear labels for a namespace.",
Flags: []cli.Flag{},
Usage: "set and clear labels for a namespace",
ArgsUsage: "<name> [<key>=<value>, ...]",
Description: "set and clear labels for a namespace",
Action: func(context *cli.Context) error {
namespace, labels := commands.ObjectWithLabelArgs(context)
if namespace == "" {
@ -71,16 +71,16 @@ var namespacesSetLabelsCommand = cli.Command{
},
}
var namespacesListCommand = cli.Command{
var listCommand = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list namespaces.",
Usage: "list namespaces",
ArgsUsage: "[flags]",
Description: "List namespaces.",
Description: "list namespaces",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet, q",
Usage: "print only the namespace name.",
Usage: "print only the namespace name",
},
},
Action: func(context *cli.Context) error {
@ -123,12 +123,12 @@ var namespacesListCommand = cli.Command{
},
}
var namespacesRemoveCommand = cli.Command{
var removeCommand = cli.Command{
Name: "remove",
Aliases: []string{"rm"},
Usage: "remove one or more namespaces",
ArgsUsage: "[flags] <name> [<name>, ...]",
Description: "Remove one or more namespaces. For now, the namespace must be empty.",
ArgsUsage: "<name> [<name>, ...]",
Description: "remove one or more namespaces. for now, the namespace must be empty",
Action: func(context *cli.Context) error {
var exitErr error
client, ctx, cancel, err := commands.NewClient(context)

View File

@ -1,4 +1,4 @@
package main
package snapshot
import (
gocontext "context"
@ -15,25 +15,26 @@ import (
"github.com/urfave/cli"
)
var snapshotCommand = cli.Command{
// Command is the cli command for managing snapshots
var Command = cli.Command{
Name: "snapshot",
Usage: "snapshot management",
Usage: "manage snapshots",
Flags: commands.SnapshotterFlags,
Subcommands: cli.Commands{
listSnapshotCommand,
usageSnapshotCommand,
removeSnapshotCommand,
prepareSnapshotCommand,
viewSnapshotCommand,
treeSnapshotCommand,
mountSnapshotCommand,
commitSnapshotCommand,
infoSnapshotCommand,
labelSnapshotCommand,
listCommand,
usageCommand,
removeCommand,
prepareCommand,
viewCommand,
treeCommand,
mountCommand,
commitCommand,
infoCommand,
setLabelCommand,
},
}
var listSnapshotCommand = cli.Command{
var listCommand = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list snapshots",
@ -62,7 +63,7 @@ var listSnapshotCommand = cli.Command{
},
}
var usageSnapshotCommand = cli.Command{
var usageCommand = cli.Command{
Name: "usage",
Usage: "usage snapshots",
ArgsUsage: "[flags] [<key>, ...]",
@ -118,7 +119,7 @@ var usageSnapshotCommand = cli.Command{
},
}
var removeSnapshotCommand = cli.Command{
var removeCommand = cli.Command{
Name: "remove",
Aliases: []string{"rm"},
ArgsUsage: "<key> [<key>, ...]",
@ -141,7 +142,7 @@ var removeSnapshotCommand = cli.Command{
},
}
var prepareSnapshotCommand = cli.Command{
var prepareCommand = cli.Command{
Name: "prepare",
Usage: "prepare a snapshot from a committed snapshot",
ArgsUsage: "[flags] <key> [<parent>]",
@ -180,7 +181,7 @@ var prepareSnapshotCommand = cli.Command{
},
}
var viewSnapshotCommand = cli.Command{
var viewCommand = cli.Command{
Name: "view",
Usage: "create a read-only snapshot from a committed snapshot",
ArgsUsage: "[flags] <key> [<parent>]",
@ -219,11 +220,11 @@ var viewSnapshotCommand = cli.Command{
},
}
var mountSnapshotCommand = cli.Command{
var mountCommand = cli.Command{
Name: "mounts",
Aliases: []string{"m", "mount"},
Usage: "mount gets mount commands for the snapshots",
ArgsUsage: "[flags] <target> <key>",
ArgsUsage: "<target> <key>",
Action: func(context *cli.Context) error {
if context.NArg() != 2 {
return cli.ShowSubcommandHelp(context)
@ -249,10 +250,10 @@ var mountSnapshotCommand = cli.Command{
},
}
var commitSnapshotCommand = cli.Command{
var commitCommand = cli.Command{
Name: "commit",
Usage: "commit an active snapshot into the provided name",
ArgsUsage: "[flags] <key> <active>",
ArgsUsage: "<key> <active>",
Action: func(context *cli.Context) error {
if context.NArg() != 2 {
return cli.ShowSubcommandHelp(context)
@ -271,7 +272,7 @@ var commitSnapshotCommand = cli.Command{
},
}
var treeSnapshotCommand = cli.Command{
var treeCommand = cli.Command{
Name: "tree",
Usage: "display tree view of snapshot branches",
Action: func(context *cli.Context) error {
@ -305,7 +306,7 @@ var treeSnapshotCommand = cli.Command{
},
}
var infoSnapshotCommand = cli.Command{
var infoCommand = cli.Command{
Name: "info",
Usage: "get info about a snapshot",
ArgsUsage: "<key>",
@ -332,12 +333,11 @@ var infoSnapshotCommand = cli.Command{
},
}
var labelSnapshotCommand = cli.Command{
var setLabelCommand = cli.Command{
Name: "label",
Usage: "add labels to content",
ArgsUsage: "[flags] <name> [<label>=<value> ...]",
Description: `Labels snapshots in the snapshotter`,
Flags: []cli.Flag{},
ArgsUsage: "<name> [<label>=<value> ...]",
Description: "labels snapshots in the snapshotter",
Action: func(context *cli.Context) error {
key, labels := commands.ObjectWithLabelArgs(context)
client, ctx, cancel, err := commands.NewClient(context)

View File

@ -1,74 +0,0 @@
package main
import (
"context"
"errors"
"fmt"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/log"
"github.com/urfave/cli"
)
var containersDeleteCommand = cli.Command{
Name: "delete",
Usage: "delete one or more existing containers",
ArgsUsage: "CONTAINER [CONTAINER, ...]",
Aliases: []string{"del", "rm"},
Flags: []cli.Flag{
cli.BoolFlag{
Name: "keep-snapshot",
Usage: "do not clean up snapshot with container",
},
},
Action: func(context *cli.Context) error {
var exitErr error
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
deleteOpts := []containerd.DeleteOpts{}
if !context.Bool("keep-snapshot") {
deleteOpts = append(deleteOpts, containerd.WithSnapshotCleanup)
}
if context.NArg() == 0 {
return errors.New("must specify at least one container to delete")
}
for _, arg := range context.Args() {
if err := deleteContainer(ctx, client, arg, deleteOpts...); err != nil {
if exitErr == nil {
exitErr = err
}
log.G(ctx).WithError(err).Errorf("failed to delete container %q", arg)
}
}
return exitErr
},
}
func deleteContainer(ctx context.Context, client *containerd.Client, id string, opts ...containerd.DeleteOpts) error {
container, err := client.LoadContainer(ctx, id)
if err != nil {
return err
}
task, err := container.Task(ctx, nil)
if err != nil {
return container.Delete(ctx, opts...)
}
status, err := task.Status(ctx)
if err != nil {
return err
}
if status.Status == containerd.Stopped || status.Status == containerd.Created {
if _, err := task.Delete(ctx); err != nil {
return err
}
return container.Delete(ctx, opts...)
}
return fmt.Errorf("cannot delete a non stopped container: %v", status)
}

View File

@ -1,69 +0,0 @@
package main
import (
"fmt"
"os"
"text/tabwriter"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/urfave/cli"
)
var containersCommand = cli.Command{
Name: "containers",
Usage: "manage containers (metadata)",
Aliases: []string{"c"},
Flags: []cli.Flag{
cli.BoolFlag{
Name: "quiet, q",
Usage: "print only the container id",
},
},
Subcommands: []cli.Command{
containersDeleteCommand,
containersSetLabelsCommand,
containerInfoCommand,
},
ArgsUsage: "[filter, ...]",
Action: func(context *cli.Context) error {
var (
filters = context.Args()
quiet = context.Bool("quiet")
)
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
containers, err := client.Containers(ctx, filters...)
if err != nil {
return err
}
if quiet {
for _, c := range containers {
fmt.Printf("%s\n", c.ID())
}
return nil
}
w := tabwriter.NewWriter(os.Stdout, 4, 8, 4, ' ', 0)
fmt.Fprintln(w, "CONTAINER\tIMAGE\tRUNTIME\t")
for _, c := range containers {
info, err := c.Info(ctx)
if err != nil {
return err
}
imageName := info.Image
if imageName == "" {
imageName = "-"
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t\n",
c.ID(),
imageName,
info.Runtime.Name,
); err != nil {
return err
}
}
return w.Flush()
},
}

View File

@ -1,35 +0,0 @@
package main
import (
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
var containerInfoCommand = cli.Command{
Name: "info",
Usage: "get info about a container",
ArgsUsage: "CONTAINER",
Action: func(context *cli.Context) error {
id := context.Args().First()
if id == "" {
return errors.New("container id must be provided")
}
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
container, err := client.LoadContainer(ctx, id)
if err != nil {
return err
}
info, err := container.Info(ctx)
if err != nil {
return err
}
commands.PrintAsJSON(info)
return nil
},
}

View File

@ -1,48 +0,0 @@
package main
import (
"errors"
"fmt"
"strings"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/urfave/cli"
)
var containersSetLabelsCommand = cli.Command{
Name: "label",
Usage: "set and clear labels for a container.",
ArgsUsage: "[flags] <name> [<key>=<value>, ...]",
Description: "Set and clear labels for a container.",
Flags: []cli.Flag{},
Action: func(context *cli.Context) error {
containerID, labels := commands.ObjectWithLabelArgs(context)
if containerID == "" {
return errors.New("please specify a container")
}
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
container, err := client.LoadContainer(ctx, containerID)
if err != nil {
return err
}
setlabels, err := container.SetLabels(ctx, labels)
if err != nil {
return err
}
var labelStrings []string
for k, v := range setlabels {
labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v))
}
fmt.Println(strings.Join(labelStrings, ","))
return nil
},
}

View File

@ -6,7 +6,13 @@ import (
"log"
"os"
"github.com/containerd/containerd/cmd/ctr/commands/containers"
"github.com/containerd/containerd/cmd/ctr/commands/content"
"github.com/containerd/containerd/cmd/ctr/commands/events"
"github.com/containerd/containerd/cmd/ctr/commands/images"
namespacesCmd "github.com/containerd/containerd/cmd/ctr/commands/namespaces"
"github.com/containerd/containerd/cmd/ctr/commands/plugins"
"github.com/containerd/containerd/cmd/ctr/commands/snapshot"
versionCmd "github.com/containerd/containerd/cmd/ctr/commands/version"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/server"
@ -69,20 +75,20 @@ containerd CLI
plugins.Command,
versionCmd.Command,
applyCommand,
containersCommand,
contentCommand,
eventsCommand,
containers.Command,
content.Command,
events.Command,
fetchCommand,
fetchObjectCommand,
imageCommand,
namespacesCommand,
images.Command,
namespacesCmd.Command,
pprofCommand,
pullCommand,
pushCommand,
pushObjectCommand,
rootfsCommand,
runCommand,
snapshotCommand,
snapshot.Command,
tasksCommand,
}, extraCmds...)
app.Before = func(context *cli.Context) error {