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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
package main package snapshot
import ( import (
gocontext "context" gocontext "context"
@ -15,25 +15,26 @@ import (
"github.com/urfave/cli" "github.com/urfave/cli"
) )
var snapshotCommand = cli.Command{ // Command is the cli command for managing snapshots
var Command = cli.Command{
Name: "snapshot", Name: "snapshot",
Usage: "snapshot management", Usage: "manage snapshots",
Flags: commands.SnapshotterFlags, Flags: commands.SnapshotterFlags,
Subcommands: cli.Commands{ Subcommands: cli.Commands{
listSnapshotCommand, listCommand,
usageSnapshotCommand, usageCommand,
removeSnapshotCommand, removeCommand,
prepareSnapshotCommand, prepareCommand,
viewSnapshotCommand, viewCommand,
treeSnapshotCommand, treeCommand,
mountSnapshotCommand, mountCommand,
commitSnapshotCommand, commitCommand,
infoSnapshotCommand, infoCommand,
labelSnapshotCommand, setLabelCommand,
}, },
} }
var listSnapshotCommand = cli.Command{ var listCommand = cli.Command{
Name: "list", Name: "list",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Usage: "list snapshots", Usage: "list snapshots",
@ -62,7 +63,7 @@ var listSnapshotCommand = cli.Command{
}, },
} }
var usageSnapshotCommand = cli.Command{ var usageCommand = cli.Command{
Name: "usage", Name: "usage",
Usage: "usage snapshots", Usage: "usage snapshots",
ArgsUsage: "[flags] [<key>, ...]", ArgsUsage: "[flags] [<key>, ...]",
@ -118,7 +119,7 @@ var usageSnapshotCommand = cli.Command{
}, },
} }
var removeSnapshotCommand = cli.Command{ var removeCommand = cli.Command{
Name: "remove", Name: "remove",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
ArgsUsage: "<key> [<key>, ...]", ArgsUsage: "<key> [<key>, ...]",
@ -141,7 +142,7 @@ var removeSnapshotCommand = cli.Command{
}, },
} }
var prepareSnapshotCommand = cli.Command{ var prepareCommand = cli.Command{
Name: "prepare", Name: "prepare",
Usage: "prepare a snapshot from a committed snapshot", Usage: "prepare a snapshot from a committed snapshot",
ArgsUsage: "[flags] <key> [<parent>]", ArgsUsage: "[flags] <key> [<parent>]",
@ -180,7 +181,7 @@ var prepareSnapshotCommand = cli.Command{
}, },
} }
var viewSnapshotCommand = cli.Command{ var viewCommand = cli.Command{
Name: "view", Name: "view",
Usage: "create a read-only snapshot from a committed snapshot", Usage: "create a read-only snapshot from a committed snapshot",
ArgsUsage: "[flags] <key> [<parent>]", ArgsUsage: "[flags] <key> [<parent>]",
@ -219,11 +220,11 @@ var viewSnapshotCommand = cli.Command{
}, },
} }
var mountSnapshotCommand = cli.Command{ var mountCommand = cli.Command{
Name: "mounts", Name: "mounts",
Aliases: []string{"m", "mount"}, Aliases: []string{"m", "mount"},
Usage: "mount gets mount commands for the snapshots", Usage: "mount gets mount commands for the snapshots",
ArgsUsage: "[flags] <target> <key>", ArgsUsage: "<target> <key>",
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
if context.NArg() != 2 { if context.NArg() != 2 {
return cli.ShowSubcommandHelp(context) return cli.ShowSubcommandHelp(context)
@ -249,10 +250,10 @@ var mountSnapshotCommand = cli.Command{
}, },
} }
var commitSnapshotCommand = cli.Command{ var commitCommand = cli.Command{
Name: "commit", Name: "commit",
Usage: "commit an active snapshot into the provided name", Usage: "commit an active snapshot into the provided name",
ArgsUsage: "[flags] <key> <active>", ArgsUsage: "<key> <active>",
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
if context.NArg() != 2 { if context.NArg() != 2 {
return cli.ShowSubcommandHelp(context) return cli.ShowSubcommandHelp(context)
@ -271,7 +272,7 @@ var commitSnapshotCommand = cli.Command{
}, },
} }
var treeSnapshotCommand = cli.Command{ var treeCommand = cli.Command{
Name: "tree", Name: "tree",
Usage: "display tree view of snapshot branches", Usage: "display tree view of snapshot branches",
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
@ -305,7 +306,7 @@ var treeSnapshotCommand = cli.Command{
}, },
} }
var infoSnapshotCommand = cli.Command{ var infoCommand = cli.Command{
Name: "info", Name: "info",
Usage: "get info about a snapshot", Usage: "get info about a snapshot",
ArgsUsage: "<key>", ArgsUsage: "<key>",
@ -332,12 +333,11 @@ var infoSnapshotCommand = cli.Command{
}, },
} }
var labelSnapshotCommand = cli.Command{ var setLabelCommand = cli.Command{
Name: "label", Name: "label",
Usage: "add labels to content", Usage: "add labels to content",
ArgsUsage: "[flags] <name> [<label>=<value> ...]", ArgsUsage: "<name> [<label>=<value> ...]",
Description: `Labels snapshots in the snapshotter`, Description: "labels snapshots in the snapshotter",
Flags: []cli.Flag{},
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
key, labels := commands.ObjectWithLabelArgs(context) key, labels := commands.ObjectWithLabelArgs(context)
client, ctx, cancel, err := commands.NewClient(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" "log"
"os" "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/plugins"
"github.com/containerd/containerd/cmd/ctr/commands/snapshot"
versionCmd "github.com/containerd/containerd/cmd/ctr/commands/version" versionCmd "github.com/containerd/containerd/cmd/ctr/commands/version"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/server" "github.com/containerd/containerd/server"
@ -69,20 +75,20 @@ containerd CLI
plugins.Command, plugins.Command,
versionCmd.Command, versionCmd.Command,
applyCommand, applyCommand,
containersCommand, containers.Command,
contentCommand, content.Command,
eventsCommand, events.Command,
fetchCommand, fetchCommand,
fetchObjectCommand, fetchObjectCommand,
imageCommand, images.Command,
namespacesCommand, namespacesCmd.Command,
pprofCommand, pprofCommand,
pullCommand, pullCommand,
pushCommand, pushCommand,
pushObjectCommand, pushObjectCommand,
rootfsCommand, rootfsCommand,
runCommand, runCommand,
snapshotCommand, snapshot.Command,
tasksCommand, tasksCommand,
}, extraCmds...) }, extraCmds...)
app.Before = func(context *cli.Context) error { app.Before = func(context *cli.Context) error {