From 47fae4dd17bd833da23cf291449f4a5e1400cc09 Mon Sep 17 00:00:00 2001 From: Jess Valarezo Date: Wed, 25 Oct 2017 11:04:46 -0700 Subject: [PATCH 1/6] 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, From f980cc197e187d941862b99e022c5a22a48cdf84 Mon Sep 17 00:00:00 2001 From: Jess Valarezo Date: Wed, 25 Oct 2017 21:05:00 -0400 Subject: [PATCH 2/6] ctr: move images command Signed-off-by: Jess Valarezo --- cmd/ctr/{ => commands/images}/export.go | 6 ++-- cmd/ctr/{ => commands/images}/images.go | 45 ++++++++++++------------- cmd/ctr/{ => commands/images}/import.go | 6 ++-- cmd/ctr/main.go | 5 +-- 4 files changed, 31 insertions(+), 31 deletions(-) rename cmd/ctr/{ => commands/images}/export.go (95%) rename cmd/ctr/{ => commands/images}/images.go (87%) rename cmd/ctr/{ => commands/images}/import.go (93%) diff --git a/cmd/ctr/export.go b/cmd/ctr/commands/images/export.go similarity index 95% rename from cmd/ctr/export.go rename to cmd/ctr/commands/images/export.go index f2b4ea77a..26821008b 100644 --- a/cmd/ctr/export.go +++ b/cmd/ctr/commands/images/export.go @@ -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] ", - 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", diff --git a/cmd/ctr/images.go b/cmd/ctr/commands/images/images.go similarity index 87% rename from cmd/ctr/images.go rename to cmd/ctr/commands/images/images.go index 2c99bd4f9..074e118d3 100644 --- a/cmd/ctr/images.go +++ b/cmd/ctr/commands/images/images.go @@ -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] ", - 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] [=, ...]", - 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] [, ...]", - Description: "Check that an image has all content available locally.", - Flags: []cli.Flag{}, + Usage: "check that an image has all content available locally", + ArgsUsage: " [, ...]", + 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] [, ...]", - Description: `Remove one or more images by reference.`, - Flags: []cli.Flag{}, + Usage: "remove one or more images by reference", + ArgsUsage: " [, ...]", + Description: "remove one or more images by reference", Action: func(context *cli.Context) error { client, ctx, cancel, err := commands.NewClient(context) if err != nil { diff --git a/cmd/ctr/import.go b/cmd/ctr/commands/images/import.go similarity index 93% rename from cmd/ctr/import.go rename to cmd/ctr/commands/images/import.go index 1a59feec5..74f204ea9 100644 --- a/cmd/ctr/import.go +++ b/cmd/ctr/commands/images/import.go @@ -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] ", - Description: `Import an image from a tar stream.`, + Description: "import an image from a tar stream", Flags: []cli.Flag{ cli.StringFlag{ Name: "ref-object", diff --git a/cmd/ctr/main.go b/cmd/ctr/main.go index 6b1f8ab6a..9e044b3ee 100644 --- a/cmd/ctr/main.go +++ b/cmd/ctr/main.go @@ -6,9 +6,10 @@ import ( "log" "os" + "github.com/containerd/containerd/cmd/ctr/commands/containers" + "github.com/containerd/containerd/cmd/ctr/commands/images" "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" @@ -75,7 +76,7 @@ containerd CLI eventsCommand, fetchCommand, fetchObjectCommand, - imageCommand, + images.Command, namespacesCommand, pprofCommand, pullCommand, From 0895dbe93244ede91b975f8a16db1eb63d4b54f2 Mon Sep 17 00:00:00 2001 From: Jess Valarezo Date: Wed, 25 Oct 2017 13:22:53 -0700 Subject: [PATCH 3/6] ctr: move content command Signed-off-by: Jess Valarezo --- cmd/ctr/{ => commands/content}/content.go | 60 +++++++++++------------ cmd/ctr/main.go | 3 +- 2 files changed, 31 insertions(+), 32 deletions(-) rename cmd/ctr/{ => commands/content}/content.go (88%) diff --git a/cmd/ctr/content.go b/cmd/ctr/commands/content/content.go similarity index 88% rename from cmd/ctr/content.go rename to cmd/ctr/commands/content/content.go index 63587b1c5..424b81da3 100644 --- a/cmd/ctr/content.go +++ b/cmd/ctr/commands/content/content.go @@ -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] [, ...]", - Description: "Display the image object.", - Flags: []cli.Flag{}, + ArgsUsage: "[, ...]", + 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] ", - 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] []", - 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] [, ...]", - 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] [