ctr: add commands package with shared utility functions
Signed-off-by: Jess Valarezo <valarezo.jessica@gmail.com>
This commit is contained in:
parent
04659d9405
commit
a19a20303a
84
cmd/ctr/commands/commands.go
Normal file
84
cmd/ctr/commands/commands.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// SnapshotterFlags are cli flags specifying snapshotter names
|
||||||
|
SnapshotterFlags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "snapshotter",
|
||||||
|
Usage: "snapshotter name. Empty value stands for the daemon default value.",
|
||||||
|
Value: containerd.DefaultSnapshotter,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelFlag is a cli flag specifying labels
|
||||||
|
LabelFlag = cli.StringSliceFlag{
|
||||||
|
Name: "label",
|
||||||
|
Usage: "labels to attach to the image",
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryFlags are cli flags specifying registry options
|
||||||
|
RegistryFlags = []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "skip-verify,k",
|
||||||
|
Usage: "skip SSL certificate validation",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "plain-http",
|
||||||
|
Usage: "allow connections using plain HTTP",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "user,u",
|
||||||
|
Usage: "user[:password] Registry user and password",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "refresh",
|
||||||
|
Usage: "refresh token for authorization server",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ObjectWithLabelArgs returns the first arg and a LabelArgs object
|
||||||
|
func ObjectWithLabelArgs(clicontext *cli.Context) (string, map[string]string) {
|
||||||
|
var (
|
||||||
|
first = clicontext.Args().First()
|
||||||
|
labelStrings = clicontext.Args().Tail()
|
||||||
|
)
|
||||||
|
|
||||||
|
return first, LabelArgs(labelStrings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelArgs returns a map of label key,value pairs
|
||||||
|
func LabelArgs(labelStrings []string) map[string]string {
|
||||||
|
labels := make(map[string]string, len(labelStrings))
|
||||||
|
for _, label := range labelStrings {
|
||||||
|
parts := strings.SplitN(label, "=", 2)
|
||||||
|
key := parts[0]
|
||||||
|
value := "true"
|
||||||
|
if len(parts) > 1 {
|
||||||
|
value = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
labels[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return labels
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintAsJSON prints input in JSON format
|
||||||
|
func PrintAsJSON(x interface{}) {
|
||||||
|
b, err := json.MarshalIndent(x, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "can't marshal %+v as a JSON string: %v\n", x, err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(b))
|
||||||
|
}
|
@ -10,6 +10,7 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -212,7 +213,7 @@ var (
|
|||||||
Description: `Labels blobs in the content store`,
|
Description: `Labels blobs in the content store`,
|
||||||
Flags: []cli.Flag{},
|
Flags: []cli.Flag{},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
object, labels := objectWithLabelArgs(context)
|
object, labels := commands.ObjectWithLabelArgs(context)
|
||||||
client, ctx, cancel, err := newClient(context)
|
client, ctx, cancel, err := newClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
@ -39,7 +40,7 @@ not use this implementation as a guide. The end goal should be having metadata,
|
|||||||
content and snapshots ready for a direct use via the 'ctr run'.
|
content and snapshots ready for a direct use via the 'ctr run'.
|
||||||
|
|
||||||
Most of this is experimental and there are few leaps to make this work.`,
|
Most of this is experimental and there are few leaps to make this work.`,
|
||||||
Flags: append(registryFlags, labelFlag),
|
Flags: append(commands.RegistryFlags, commands.LabelFlag),
|
||||||
Action: func(clicontext *cli.Context) error {
|
Action: func(clicontext *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = clicontext.Args().First()
|
ref = clicontext.Args().First()
|
||||||
@ -82,7 +83,7 @@ func fetch(ref string, cliContext *cli.Context) (containerd.Image, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
log.G(pctx).WithField("image", ref).Debug("fetching")
|
log.G(pctx).WithField("image", ref).Debug("fetching")
|
||||||
labels := labelArgs(cliContext.StringSlice("label"))
|
labels := commands.LabelArgs(cliContext.StringSlice("label"))
|
||||||
img, err := client.Pull(pctx, ref,
|
img, err := client.Pull(pctx, ref,
|
||||||
containerd.WithPullLabels(labels),
|
containerd.WithPullLabels(labels),
|
||||||
containerd.WithResolver(resolver),
|
containerd.WithResolver(resolver),
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -17,7 +18,7 @@ var fetchObjectCommand = cli.Command{
|
|||||||
Usage: "retrieve objects from a remote",
|
Usage: "retrieve objects from a remote",
|
||||||
ArgsUsage: "[flags] <remote> <object> [<hint>, ...]",
|
ArgsUsage: "[flags] <remote> <object> [<hint>, ...]",
|
||||||
Description: `Fetch objects by identifier from a remote.`,
|
Description: `Fetch objects by identifier from a remote.`,
|
||||||
Flags: registryFlags,
|
Flags: commands.RegistryFlags,
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -127,7 +128,7 @@ var imagesSetLabelsCommand = cli.Command{
|
|||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
replaceAll = context.Bool("replace-all")
|
replaceAll = context.Bool("replace-all")
|
||||||
name, labels = objectWithLabelArgs(context)
|
name, labels = commands.ObjectWithLabelArgs(context)
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := newClient(context)
|
client, ctx, cancel, err := newClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -21,14 +22,14 @@ var imagesImportCommand = cli.Command{
|
|||||||
Value: "",
|
Value: "",
|
||||||
Usage: "reference object e.g. tag@digest (default: use the object specified in ref)",
|
Usage: "reference object e.g. tag@digest (default: use the object specified in ref)",
|
||||||
},
|
},
|
||||||
labelFlag,
|
commands.LabelFlag,
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
in = context.Args().Get(1)
|
in = context.Args().Get(1)
|
||||||
refObject = context.String("ref-object")
|
refObject = context.String("ref-object")
|
||||||
labels = labelArgs(context.StringSlice("label"))
|
labels = commands.LabelArgs(context.StringSlice("label"))
|
||||||
)
|
)
|
||||||
client, ctx, cancel, err := newClient(context)
|
client, ctx, cancel, err := newClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -27,7 +28,7 @@ var containerInfoCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printAsJSON(info)
|
commands.PrintAsJSON(info)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ var containersSetLabelsCommand = cli.Command{
|
|||||||
Description: "Set and clear labels for a container.",
|
Description: "Set and clear labels for a container.",
|
||||||
Flags: []cli.Flag{},
|
Flags: []cli.Flag{},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
containerID, labels := objectWithLabelArgs(context)
|
containerID, labels := commands.ObjectWithLabelArgs(context)
|
||||||
if containerID == "" {
|
if containerID == "" {
|
||||||
return errors.New("please specify a container")
|
return errors.New("please specify a container")
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -30,7 +31,7 @@ var namespacesCreateCommand = cli.Command{
|
|||||||
ArgsUsage: "[flags] <name> [<key>=<value]",
|
ArgsUsage: "[flags] <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 := objectWithLabelArgs(context)
|
namespace, labels := commands.ObjectWithLabelArgs(context)
|
||||||
if namespace == "" {
|
if namespace == "" {
|
||||||
return errors.New("please specify a namespace")
|
return errors.New("please specify a namespace")
|
||||||
}
|
}
|
||||||
@ -51,7 +52,7 @@ var namespacesSetLabelsCommand = cli.Command{
|
|||||||
Description: "Set and clear labels for a namespace.",
|
Description: "Set and clear labels for a namespace.",
|
||||||
Flags: []cli.Flag{},
|
Flags: []cli.Flag{},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
namespace, labels := objectWithLabelArgs(context)
|
namespace, labels := commands.ObjectWithLabelArgs(context)
|
||||||
if namespace == "" {
|
if namespace == "" {
|
||||||
return errors.New("please specify a namespace")
|
return errors.New("please specify a namespace")
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -20,7 +21,7 @@ command. As part of this process, we do the following:
|
|||||||
2. Prepare the snapshot filesystem with the pulled resources.
|
2. Prepare the snapshot filesystem with the pulled resources.
|
||||||
3. Register metadata for the image.
|
3. Register metadata for the image.
|
||||||
`,
|
`,
|
||||||
Flags: append(registryFlags, append(snapshotterFlags, labelFlag)...),
|
Flags: append(commands.RegistryFlags, append(commands.SnapshotterFlags, commands.LabelFlag)...),
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/progress"
|
"github.com/containerd/containerd/progress"
|
||||||
@ -37,7 +38,7 @@ var pushCommand = cli.Command{
|
|||||||
creating the associated configuration, and creating the manifest
|
creating the associated configuration, and creating the manifest
|
||||||
which references those resources.
|
which references those resources.
|
||||||
`,
|
`,
|
||||||
Flags: append(registryFlags, cli.StringFlag{
|
Flags: append(commands.RegistryFlags, cli.StringFlag{
|
||||||
Name: "manifest",
|
Name: "manifest",
|
||||||
Usage: "digest of manifest",
|
Usage: "digest of manifest",
|
||||||
}, cli.StringFlag{
|
}, cli.StringFlag{
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
@ -15,7 +16,7 @@ var pushObjectCommand = cli.Command{
|
|||||||
Usage: "push an object to a remote",
|
Usage: "push an object to a remote",
|
||||||
ArgsUsage: "[flags] <remote> <object> <type>",
|
ArgsUsage: "[flags] <remote> <object> <type>",
|
||||||
Description: `Push objects by identifier to a remote.`,
|
Description: `Push objects by identifier to a remote.`,
|
||||||
Flags: registryFlags,
|
Flags: commands.RegistryFlags,
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
ref = context.Args().Get(0)
|
ref = context.Args().Get(0)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -21,7 +22,7 @@ var rootfsUnpackCommand = cli.Command{
|
|||||||
Name: "unpack",
|
Name: "unpack",
|
||||||
Usage: "unpack applies layers from a manifest to a snapshot",
|
Usage: "unpack applies layers from a manifest to a snapshot",
|
||||||
ArgsUsage: "[flags] <digest>",
|
ArgsUsage: "[flags] <digest>",
|
||||||
Flags: snapshotterFlags,
|
Flags: commands.SnapshotterFlags,
|
||||||
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 {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -100,7 +101,7 @@ var runCommand = cli.Command{
|
|||||||
Name: "detach,d",
|
Name: "detach,d",
|
||||||
Usage: "detach from the task after it has started execution",
|
Usage: "detach from the task after it has started execution",
|
||||||
},
|
},
|
||||||
}, snapshotterFlags...),
|
}, commands.SnapshotterFlags...),
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -76,7 +77,7 @@ func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
opts []containerd.SpecOpts
|
opts []containerd.SpecOpts
|
||||||
cOpts []containerd.NewContainerOpts
|
cOpts []containerd.NewContainerOpts
|
||||||
)
|
)
|
||||||
cOpts = append(cOpts, containerd.WithContainerLabels(labelArgs(context.StringSlice("label"))))
|
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
|
||||||
if context.Bool("rootfs") {
|
if context.Bool("rootfs") {
|
||||||
opts = append(opts, containerd.WithRootFSPath(ref))
|
opts = append(opts, containerd.WithRootFSPath(ref))
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -92,7 +93,7 @@ func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
labelStrings = context.StringSlice("label")
|
labelStrings = context.StringSlice("label")
|
||||||
)
|
)
|
||||||
|
|
||||||
labels := labelArgs(labelStrings)
|
labels := commands.LabelArgs(labelStrings)
|
||||||
|
|
||||||
// TODO(mlaventure): get base image once we have a snapshotter
|
// TODO(mlaventure): get base image once we have a snapshotter
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
shim "github.com/containerd/containerd/linux/shim/v1"
|
shim "github.com/containerd/containerd/linux/shim/v1"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
protobuf "github.com/gogo/protobuf/types"
|
protobuf "github.com/gogo/protobuf/types"
|
||||||
@ -182,7 +183,7 @@ var shimStateCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printAsJSON(r)
|
commands.PrintAsJSON(r)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/progress"
|
"github.com/containerd/containerd/progress"
|
||||||
"github.com/containerd/containerd/snapshot"
|
"github.com/containerd/containerd/snapshot"
|
||||||
@ -17,7 +18,7 @@ import (
|
|||||||
var snapshotCommand = cli.Command{
|
var snapshotCommand = cli.Command{
|
||||||
Name: "snapshot",
|
Name: "snapshot",
|
||||||
Usage: "snapshot management",
|
Usage: "snapshot management",
|
||||||
Flags: snapshotterFlags,
|
Flags: commands.SnapshotterFlags,
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
listSnapshotCommand,
|
listSnapshotCommand,
|
||||||
usageSnapshotCommand,
|
usageSnapshotCommand,
|
||||||
@ -325,7 +326,7 @@ var infoSnapshotCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
printAsJSON(info)
|
commands.PrintAsJSON(info)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@ -338,7 +339,7 @@ var labelSnapshotCommand = cli.Command{
|
|||||||
Description: `Labels snapshots in the snapshotter`,
|
Description: `Labels snapshots in the snapshotter`,
|
||||||
Flags: []cli.Flag{},
|
Flags: []cli.Flag{},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
key, labels := objectWithLabelArgs(context)
|
key, labels := commands.ObjectWithLabelArgs(context)
|
||||||
client, ctx, cancel, err := newClient(context)
|
client, ctx, cancel, err := newClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
106
cmd/ctr/utils.go
106
cmd/ctr/utils.go
@ -5,7 +5,6 @@ import (
|
|||||||
gocontext "context"
|
gocontext "context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -18,54 +17,15 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/content"
|
|
||||||
"github.com/containerd/containerd/images"
|
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/containerd/containerd/platforms"
|
|
||||||
"github.com/containerd/containerd/remotes"
|
"github.com/containerd/containerd/remotes"
|
||||||
"github.com/containerd/containerd/remotes/docker"
|
"github.com/containerd/containerd/remotes/docker"
|
||||||
"github.com/containerd/containerd/rootfs"
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
snapshotterFlags = []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "snapshotter",
|
|
||||||
Usage: "snapshotter name. Empty value stands for the daemon default value.",
|
|
||||||
Value: containerd.DefaultSnapshotter,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
labelFlag = cli.StringSliceFlag{
|
|
||||||
Name: "label",
|
|
||||||
Usage: "labels to attach to the pulled image",
|
|
||||||
}
|
|
||||||
|
|
||||||
registryFlags = []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "skip-verify,k",
|
|
||||||
Usage: "skip SSL certificate validation",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "plain-http",
|
|
||||||
Usage: "allow connections using plain HTTP",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "user,u",
|
|
||||||
Usage: "user[:password] Registry user and password",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "refresh",
|
|
||||||
Usage: "refresh token for authorization server",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// appContext returns the context for a command. Should only be called once per
|
// appContext returns the context for a command. Should only be called once per
|
||||||
// command, near the start.
|
// command, near the start.
|
||||||
//
|
//
|
||||||
@ -114,39 +74,6 @@ func passwordPrompt() (string, error) {
|
|||||||
return string(line), nil
|
return string(line), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImageLayers(ctx gocontext.Context, image images.Image, cs content.Store) ([]rootfs.Layer, error) {
|
|
||||||
p, err := content.ReadBlob(ctx, cs, image.Target.Digest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to read manifest blob")
|
|
||||||
}
|
|
||||||
|
|
||||||
var manifest ocispec.Manifest
|
|
||||||
if err := json.Unmarshal(p, &manifest); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal manifest")
|
|
||||||
}
|
|
||||||
|
|
||||||
diffIDs, err := image.RootFS(ctx, cs, platforms.Default())
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to resolve rootfs")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(diffIDs) != len(manifest.Layers) {
|
|
||||||
return nil, errors.Errorf("mismatched image rootfs and manifest layers")
|
|
||||||
}
|
|
||||||
|
|
||||||
layers := make([]rootfs.Layer, len(diffIDs))
|
|
||||||
for i := range diffIDs {
|
|
||||||
layers[i].Diff = ocispec.Descriptor{
|
|
||||||
// TODO: derive media type from compressed type
|
|
||||||
MediaType: ocispec.MediaTypeImageLayer,
|
|
||||||
Digest: diffIDs[i],
|
|
||||||
}
|
|
||||||
layers[i].Blob = manifest.Layers[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return layers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getResolver prepares the resolver from the environment and options.
|
// getResolver prepares the resolver from the environment and options.
|
||||||
func getResolver(ctx gocontext.Context, clicontext *cli.Context) (remotes.Resolver, error) {
|
func getResolver(ctx gocontext.Context, clicontext *cli.Context) (remotes.Resolver, error) {
|
||||||
username := clicontext.String("user")
|
username := clicontext.String("user")
|
||||||
@ -312,36 +239,3 @@ func replaceOrAppendEnvValues(defaults, overrides []string) []string {
|
|||||||
|
|
||||||
return defaults
|
return defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
func objectWithLabelArgs(clicontext *cli.Context) (string, map[string]string) {
|
|
||||||
var (
|
|
||||||
namespace = clicontext.Args().First()
|
|
||||||
labelStrings = clicontext.Args().Tail()
|
|
||||||
)
|
|
||||||
|
|
||||||
return namespace, labelArgs(labelStrings)
|
|
||||||
}
|
|
||||||
|
|
||||||
func labelArgs(labelStrings []string) map[string]string {
|
|
||||||
labels := make(map[string]string, len(labelStrings))
|
|
||||||
for _, label := range labelStrings {
|
|
||||||
parts := strings.SplitN(label, "=", 2)
|
|
||||||
key := parts[0]
|
|
||||||
value := "true"
|
|
||||||
if len(parts) > 1 {
|
|
||||||
value = parts[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
labels[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
return labels
|
|
||||||
}
|
|
||||||
|
|
||||||
func printAsJSON(x interface{}) {
|
|
||||||
b, err := json.MarshalIndent(x, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "can't marshal %+v as a JSON string: %v\n", x, err)
|
|
||||||
}
|
|
||||||
fmt.Println(string(b))
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user