From 47fae4dd17bd833da23cf291449f4a5e1400cc09 Mon Sep 17 00:00:00 2001 From: Jess Valarezo Date: Wed, 25 Oct 2017 11:04:46 -0700 Subject: [PATCH] ctr: move containers command Signed-off-by: Jess Valarezo --- cmd/ctr/commands/containers/containers.go | 210 ++++++++++++++++++++++ cmd/ctr/container_delete.go | 74 -------- cmd/ctr/containers.go | 69 ------- cmd/ctr/info.go | 35 ---- cmd/ctr/labels.go | 48 ----- cmd/ctr/main.go | 3 +- 6 files changed, 212 insertions(+), 227 deletions(-) create mode 100644 cmd/ctr/commands/containers/containers.go delete mode 100644 cmd/ctr/container_delete.go delete mode 100644 cmd/ctr/containers.go delete mode 100644 cmd/ctr/info.go delete mode 100644 cmd/ctr/labels.go diff --git a/cmd/ctr/commands/containers/containers.go b/cmd/ctr/commands/containers/containers.go new file mode 100644 index 000000000..9cf5df465 --- /dev/null +++ b/cmd/ctr/commands/containers/containers.go @@ -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] [, ...]", + 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] [=, ...]", + 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 + }, +} diff --git a/cmd/ctr/container_delete.go b/cmd/ctr/container_delete.go deleted file mode 100644 index aaba165d3..000000000 --- a/cmd/ctr/container_delete.go +++ /dev/null @@ -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) - -} diff --git a/cmd/ctr/containers.go b/cmd/ctr/containers.go deleted file mode 100644 index c91d6d8ac..000000000 --- a/cmd/ctr/containers.go +++ /dev/null @@ -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() - }, -} diff --git a/cmd/ctr/info.go b/cmd/ctr/info.go deleted file mode 100644 index e2eb63fbb..000000000 --- a/cmd/ctr/info.go +++ /dev/null @@ -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 - }, -} diff --git a/cmd/ctr/labels.go b/cmd/ctr/labels.go deleted file mode 100644 index 62be97ac1..000000000 --- a/cmd/ctr/labels.go +++ /dev/null @@ -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] [=, ...]", - 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 - }, -} diff --git a/cmd/ctr/main.go b/cmd/ctr/main.go index b96f1e92e..6b1f8ab6a 100644 --- a/cmd/ctr/main.go +++ b/cmd/ctr/main.go @@ -8,6 +8,7 @@ import ( "github.com/containerd/containerd/cmd/ctr/commands/plugins" versionCmd "github.com/containerd/containerd/cmd/ctr/commands/version" + "github.com/containerd/containerd/cmd/ctr/commands/containers" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/server" "github.com/containerd/containerd/version" @@ -69,7 +70,7 @@ containerd CLI plugins.Command, versionCmd.Command, applyCommand, - containersCommand, + containers.Command, contentCommand, eventsCommand, fetchCommand,