ctr: move containers command
Signed-off-by: Jess Valarezo <valarezo.jessica@gmail.com>
This commit is contained in:
parent
8c77d9ac72
commit
47fae4dd17
210
cmd/ctr/commands/containers/containers.go
Normal file
210
cmd/ctr/commands/containers/containers.go
Normal 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
|
||||
},
|
||||
}
|
@ -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)
|
||||
|
||||
}
|
@ -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()
|
||||
},
|
||||
}
|
@ -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
|
||||
},
|
||||
}
|
@ -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
|
||||
},
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user