Merge pull request #1704 from jessvalarezo/ctr-move-tasks
ctr: move commands (tasks, run, pprof, shim)
This commit is contained in:
commit
aa3516487c
@ -20,10 +20,10 @@ var Command = cli.Command{
|
|||||||
Usage: "manage containers",
|
Usage: "manage containers",
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
listCommand,
|
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
setLabelsCommand,
|
|
||||||
infoCommand,
|
infoCommand,
|
||||||
|
listCommand,
|
||||||
|
setLabelsCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,16 +27,16 @@ var (
|
|||||||
Name: "content",
|
Name: "content",
|
||||||
Usage: "manage content",
|
Usage: "manage content",
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
listCommand,
|
|
||||||
ingestCommand,
|
|
||||||
activeIngestCommand,
|
activeIngestCommand,
|
||||||
getCommand,
|
|
||||||
editCommand,
|
|
||||||
deleteCommand,
|
deleteCommand,
|
||||||
setLabelsCommand,
|
editCommand,
|
||||||
fetchCommand,
|
fetchCommand,
|
||||||
fetchObjectCommand,
|
fetchObjectCommand,
|
||||||
|
getCommand,
|
||||||
|
ingestCommand,
|
||||||
|
listCommand,
|
||||||
pushObjectCommand,
|
pushObjectCommand,
|
||||||
|
setLabelsCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ var Command = cli.Command{
|
|||||||
Usage: "manage namespaces",
|
Usage: "manage namespaces",
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
createCommand,
|
createCommand,
|
||||||
setLabelsCommand,
|
|
||||||
listCommand,
|
listCommand,
|
||||||
removeCommand,
|
removeCommand,
|
||||||
|
setLabelsCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package pprof
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -17,7 +17,8 @@ type pprofDialer struct {
|
|||||||
addr string
|
addr string
|
||||||
}
|
}
|
||||||
|
|
||||||
var pprofCommand = cli.Command{
|
// Command is the cli command for providing golang pprof outputs for containerd
|
||||||
|
var Command = cli.Command{
|
||||||
Name: "pprof",
|
Name: "pprof",
|
||||||
Usage: "provide golang pprof outputs for containerd",
|
Usage: "provide golang pprof outputs for containerd",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
@ -28,12 +29,12 @@ var pprofCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
|
pprofBlockCommand,
|
||||||
pprofGoroutinesCommand,
|
pprofGoroutinesCommand,
|
||||||
pprofHeapCommand,
|
pprofHeapCommand,
|
||||||
pprofProfileCommand,
|
pprofProfileCommand,
|
||||||
pprofTraceCommand,
|
|
||||||
pprofBlockCommand,
|
|
||||||
pprofThreadcreateCommand,
|
pprofThreadcreateCommand,
|
||||||
|
pprofTraceCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ var pprofTraceCommand = cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.DurationFlag{
|
cli.DurationFlag{
|
||||||
Name: "seconds,s",
|
Name: "seconds,s",
|
||||||
Usage: "Trace time (seconds)",
|
Usage: "trace time (seconds)",
|
||||||
Value: time.Duration(5 * time.Second),
|
Value: time.Duration(5 * time.Second),
|
||||||
},
|
},
|
||||||
},
|
},
|
@ -1,6 +1,6 @@
|
|||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package main
|
package pprof
|
||||||
|
|
||||||
import "net"
|
import "net"
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package pprof
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
@ -1,13 +1,16 @@
|
|||||||
package main
|
package run
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"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/cmd/ctr/commands"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands/tasks"
|
||||||
"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"
|
||||||
@ -15,10 +18,6 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
type resizer interface {
|
|
||||||
Resize(ctx gocontext.Context, w, h uint32) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func withEnv(context *cli.Context) containerd.SpecOpts {
|
func withEnv(context *cli.Context) containerd.SpecOpts {
|
||||||
return func(_ gocontext.Context, _ *containerd.Client, _ *containers.Container, s *specs.Spec) error {
|
return func(_ gocontext.Context, _ *containerd.Client, _ *containers.Container, s *specs.Spec) error {
|
||||||
env := context.StringSlice("env")
|
env := context.StringSlice("env")
|
||||||
@ -42,10 +41,84 @@ func withMounts(context *cli.Context) containerd.SpecOpts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var runCommand = cli.Command{
|
// parseMountFlag parses a mount string in the form "type=foo,source=/path,destination=/target,options=rbind:rw"
|
||||||
|
func parseMountFlag(m string) (specs.Mount, error) {
|
||||||
|
mount := specs.Mount{}
|
||||||
|
r := csv.NewReader(strings.NewReader(m))
|
||||||
|
|
||||||
|
fields, err := r.Read()
|
||||||
|
if err != nil {
|
||||||
|
return mount, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, field := range fields {
|
||||||
|
v := strings.Split(field, "=")
|
||||||
|
if len(v) != 2 {
|
||||||
|
return mount, fmt.Errorf("invalid mount specification: expected key=val")
|
||||||
|
}
|
||||||
|
|
||||||
|
key := v[0]
|
||||||
|
val := v[1]
|
||||||
|
switch key {
|
||||||
|
case "type":
|
||||||
|
mount.Type = val
|
||||||
|
case "source", "src":
|
||||||
|
mount.Source = val
|
||||||
|
case "destination", "dst":
|
||||||
|
mount.Destination = val
|
||||||
|
case "options":
|
||||||
|
mount.Options = strings.Split(val, ":")
|
||||||
|
default:
|
||||||
|
return mount, fmt.Errorf("mount option %q not supported", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mount, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaceOrAppendEnvValues returns the defaults with the overrides either
|
||||||
|
// replaced by env key or appended to the list
|
||||||
|
func replaceOrAppendEnvValues(defaults, overrides []string) []string {
|
||||||
|
cache := make(map[string]int, len(defaults))
|
||||||
|
for i, e := range defaults {
|
||||||
|
parts := strings.SplitN(e, "=", 2)
|
||||||
|
cache[parts[0]] = i
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range overrides {
|
||||||
|
// Values w/o = means they want this env to be removed/unset.
|
||||||
|
if !strings.Contains(value, "=") {
|
||||||
|
if i, exists := cache[value]; exists {
|
||||||
|
defaults[i] = "" // Used to indicate it should be removed
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just do a normal set/update
|
||||||
|
parts := strings.SplitN(value, "=", 2)
|
||||||
|
if i, exists := cache[parts[0]]; exists {
|
||||||
|
defaults[i] = value
|
||||||
|
} else {
|
||||||
|
defaults = append(defaults, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now remove all entries that we want to "unset"
|
||||||
|
for i := 0; i < len(defaults); i++ {
|
||||||
|
if defaults[i] == "" {
|
||||||
|
defaults = append(defaults[:i], defaults[i+1:]...)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaults
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command runs a container
|
||||||
|
var Command = cli.Command{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Usage: "run a container",
|
Usage: "run a container",
|
||||||
ArgsUsage: "Image|RootFS ID [COMMAND] [ARG...]",
|
ArgsUsage: "[flags] Image|RootFS ID [COMMAND] [ARG...]",
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "tty,t",
|
Name: "tty,t",
|
||||||
@ -125,7 +198,7 @@ var runCommand = cli.Command{
|
|||||||
if context.Bool("rm") && !detach {
|
if context.Bool("rm") && !detach {
|
||||||
defer container.Delete(ctx, containerd.WithSnapshotCleanup)
|
defer container.Delete(ctx, containerd.WithSnapshotCleanup)
|
||||||
}
|
}
|
||||||
task, err := newTask(ctx, client, container, context.String("checkpoint"), tty, context.Bool("null-io"))
|
task, err := tasks.NewTask(ctx, client, container, context.String("checkpoint"), tty, context.Bool("null-io"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -151,7 +224,7 @@ var runCommand = cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if tty {
|
if tty {
|
||||||
if err := handleConsoleResize(ctx, task, con); err != nil {
|
if err := tasks.HandleConsoleResize(ctx, task, con); err != nil {
|
||||||
logrus.WithError(err).Error("console resize")
|
logrus.WithError(err).Error("console resize")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
@ -1,56 +1,23 @@
|
|||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package main
|
package run
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
"github.com/containerd/console"
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"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/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runCommand.Flags = append(runCommand.Flags, cli.BoolFlag{
|
Command.Flags = append(Command.Flags, cli.BoolFlag{
|
||||||
Name: "rootfs",
|
Name: "rootfs",
|
||||||
Usage: "use custom rootfs that is not managed by containerd snapshotter.",
|
Usage: "use custom rootfs that is not managed by containerd snapshotter",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConsoleResize(ctx gocontext.Context, task resizer, con console.Console) error {
|
|
||||||
// do an initial resize of the console
|
|
||||||
size, err := con.Size()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
|
||||||
logrus.WithError(err).Error("resize pty")
|
|
||||||
}
|
|
||||||
s := make(chan os.Signal, 16)
|
|
||||||
signal.Notify(s, unix.SIGWINCH)
|
|
||||||
go func() {
|
|
||||||
for range s {
|
|
||||||
size, err := con.Size()
|
|
||||||
if err != nil {
|
|
||||||
logrus.WithError(err).Error("get pty size")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
|
||||||
logrus.WithError(err).Error("resize pty")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func withTTY() containerd.SpecOpts {
|
func withTTY() containerd.SpecOpts {
|
||||||
return containerd.WithTTY
|
return containerd.WithTTY
|
||||||
}
|
}
|
||||||
@ -115,24 +82,3 @@ func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
cOpts = append([]containerd.NewContainerOpts{containerd.WithNewSpec(opts...)}, cOpts...)
|
cOpts = append([]containerd.NewContainerOpts{containerd.WithNewSpec(opts...)}, cOpts...)
|
||||||
return client.NewContainer(ctx, id, cOpts...)
|
return client.NewContainer(ctx, id, cOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, tty, nullIO bool) (containerd.Task, error) {
|
|
||||||
if checkpoint == "" {
|
|
||||||
io := containerd.Stdio
|
|
||||||
if tty {
|
|
||||||
io = containerd.StdioTerminal
|
|
||||||
}
|
|
||||||
if nullIO {
|
|
||||||
if tty {
|
|
||||||
return nil, errors.New("tty and null-io cannot be used together")
|
|
||||||
}
|
|
||||||
io = containerd.NullIO
|
|
||||||
}
|
|
||||||
return container.NewTask(ctx, io)
|
|
||||||
}
|
|
||||||
im, err := client.GetImage(ctx, checkpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return container.NewTask(ctx, containerd.Stdio, containerd.WithTaskCheckpoint(im))
|
|
||||||
}
|
|
@ -1,15 +1,13 @@
|
|||||||
package main
|
package run
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"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/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"
|
|
||||||
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"
|
||||||
@ -19,7 +17,7 @@ import (
|
|||||||
const pipeRoot = `\\.\pipe`
|
const pipeRoot = `\\.\pipe`
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runCommand.Flags = append(runCommand.Flags, cli.StringSliceFlag{
|
Command.Flags = append(Command.Flags, cli.StringSliceFlag{
|
||||||
Name: "layer",
|
Name: "layer",
|
||||||
Usage: "HCSSHIM Layers to be used",
|
Usage: "HCSSHIM Layers to be used",
|
||||||
})
|
})
|
||||||
@ -36,34 +34,6 @@ func withLayers(context *cli.Context) containerd.SpecOpts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConsoleResize(ctx gocontext.Context, task resizer, con console.Console) error {
|
|
||||||
// do an initial resize of the console
|
|
||||||
size, err := con.Size()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
prevSize := size
|
|
||||||
for {
|
|
||||||
time.Sleep(time.Millisecond * 250)
|
|
||||||
|
|
||||||
size, err := con.Size()
|
|
||||||
if err != nil {
|
|
||||||
log.G(ctx).WithError(err).Error("get pty size")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if size.Width != prevSize.Width || size.Height != prevSize.Height {
|
|
||||||
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
|
||||||
logrus.WithError(err).Error("resize pty")
|
|
||||||
}
|
|
||||||
prevSize = size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func withTTY(terminal bool) containerd.SpecOpts {
|
func withTTY(terminal bool) containerd.SpecOpts {
|
||||||
if !terminal {
|
if !terminal {
|
||||||
return func(ctx gocontext.Context, client *containerd.Client, c *containers.Container, s *specs.Spec) error {
|
return func(ctx gocontext.Context, client *containerd.Client, c *containers.Container, s *specs.Spec) error {
|
||||||
@ -117,17 +87,3 @@ func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
// TODO(mlaventure): containerd.WithImage(image),
|
// TODO(mlaventure): containerd.WithImage(image),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, _ string, tty, nullIO bool) (containerd.Task, error) {
|
|
||||||
io := containerd.Stdio
|
|
||||||
if tty {
|
|
||||||
io = containerd.StdioTerminal
|
|
||||||
}
|
|
||||||
if nullIO {
|
|
||||||
if tty {
|
|
||||||
return nil, errors.New("tty and null-io cannot be used together")
|
|
||||||
}
|
|
||||||
io = containerd.NullIO
|
|
||||||
}
|
|
||||||
return container.NewTask(ctx, io)
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package main
|
package shim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package shim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
@ -1,6 +1,6 @@
|
|||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package main
|
package shim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -45,7 +45,8 @@ var fifoFlags = []cli.Flag{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var shimCommand = cli.Command{
|
// Command is the cli command for interacting with a shim
|
||||||
|
var Command = cli.Command{
|
||||||
Name: "shim",
|
Name: "shim",
|
||||||
Usage: "interact with a shim directly",
|
Usage: "interact with a shim directly",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
@ -55,89 +56,14 @@ var shimCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
shimCreateCommand,
|
deleteCommand,
|
||||||
shimStartCommand,
|
execCommand,
|
||||||
shimDeleteCommand,
|
startCommand,
|
||||||
shimStateCommand,
|
stateCommand,
|
||||||
shimExecCommand,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var shimCreateCommand = cli.Command{
|
var startCommand = cli.Command{
|
||||||
Name: "create",
|
|
||||||
Usage: "create a container with a shim",
|
|
||||||
Flags: append(fifoFlags,
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "bundle",
|
|
||||||
Usage: "bundle path for the container",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "runtime",
|
|
||||||
Value: "runc",
|
|
||||||
Usage: "runtime to use for the container",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "attach,a",
|
|
||||||
Usage: "stay attached to the container and open the fifos",
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Action: func(context *cli.Context) error {
|
|
||||||
var (
|
|
||||||
id = context.Args().First()
|
|
||||||
ctx = gocontext.Background()
|
|
||||||
)
|
|
||||||
|
|
||||||
if id == "" {
|
|
||||||
return errors.New("container id must be provided")
|
|
||||||
}
|
|
||||||
service, err := getShimService(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tty := context.Bool("tty")
|
|
||||||
wg, err := prepareStdio(context.String("stdin"), context.String("stdout"), context.String("stderr"), tty)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
r, err := service.Create(ctx, &shim.CreateTaskRequest{
|
|
||||||
ID: id,
|
|
||||||
Bundle: context.String("bundle"),
|
|
||||||
Runtime: context.String("runtime"),
|
|
||||||
Stdin: context.String("stdin"),
|
|
||||||
Stdout: context.String("stdout"),
|
|
||||||
Stderr: context.String("stderr"),
|
|
||||||
Terminal: tty,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("container created with id %s and pid %d\n", id, r.Pid)
|
|
||||||
if context.Bool("attach") {
|
|
||||||
if tty {
|
|
||||||
current := console.Current()
|
|
||||||
defer current.Reset()
|
|
||||||
if err := current.SetRaw(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
size, err := current.Size()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := service.ResizePty(ctx, &shim.ResizePtyRequest{
|
|
||||||
ID: id,
|
|
||||||
Width: uint32(size.Width),
|
|
||||||
Height: uint32(size.Height),
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var shimStartCommand = cli.Command{
|
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Usage: "start a container with a shim",
|
Usage: "start a container with a shim",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -152,7 +78,7 @@ var shimStartCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var shimDeleteCommand = cli.Command{
|
var deleteCommand = cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Usage: "delete a container with a shim",
|
Usage: "delete a container with a shim",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -169,7 +95,7 @@ var shimDeleteCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var shimStateCommand = cli.Command{
|
var stateCommand = cli.Command{
|
||||||
Name: "state",
|
Name: "state",
|
||||||
Usage: "get the state of all the processes of the shim",
|
Usage: "get the state of all the processes of the shim",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -188,7 +114,7 @@ var shimStateCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var shimExecCommand = cli.Command{
|
var execCommand = cli.Command{
|
||||||
Name: "exec",
|
Name: "exec",
|
||||||
Usage: "exec a new process in the shim's container",
|
Usage: "exec a new process in the shim's container",
|
||||||
Flags: append(fifoFlags,
|
Flags: append(fifoFlags,
|
@ -23,17 +23,17 @@ var Command = cli.Command{
|
|||||||
Usage: "manage snapshots",
|
Usage: "manage snapshots",
|
||||||
Flags: commands.SnapshotterFlags,
|
Flags: commands.SnapshotterFlags,
|
||||||
Subcommands: cli.Commands{
|
Subcommands: cli.Commands{
|
||||||
listCommand,
|
|
||||||
usageCommand,
|
|
||||||
removeCommand,
|
|
||||||
prepareCommand,
|
|
||||||
viewCommand,
|
|
||||||
treeCommand,
|
|
||||||
mountCommand,
|
|
||||||
commitCommand,
|
commitCommand,
|
||||||
infoCommand,
|
infoCommand,
|
||||||
|
listCommand,
|
||||||
|
mountCommand,
|
||||||
|
prepareCommand,
|
||||||
|
removeCommand,
|
||||||
setLabelCommand,
|
setLabelCommand,
|
||||||
|
treeCommand,
|
||||||
unpackCommand,
|
unpackCommand,
|
||||||
|
usageCommand,
|
||||||
|
viewCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskAttachCommand = cli.Command{
|
var attachCommand = cli.Command{
|
||||||
Name: "attach",
|
Name: "attach",
|
||||||
Usage: "attach to the IO of a running container",
|
Usage: "attach to the IO of a running container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
@ -51,7 +51,7 @@ var taskAttachCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tty {
|
if tty {
|
||||||
if err := handleConsoleResize(ctx, task, con); err != nil {
|
if err := HandleConsoleResize(ctx, task, con); err != nil {
|
||||||
logrus.WithError(err).Error("console resize")
|
logrus.WithError(err).Error("console resize")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -9,10 +9,10 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskCheckpointCommand = cli.Command{
|
var checkpointCommand = cli.Command{
|
||||||
Name: "checkpoint",
|
Name: "checkpoint",
|
||||||
Usage: "checkpoint a container",
|
Usage: "checkpoint a container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "[flags] CONTAINER",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "exit",
|
Name: "exit",
|
@ -1,11 +1,11 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskDeleteCommand = cli.Command{
|
var deleteCommand = cli.Command{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
Usage: "delete a task",
|
Usage: "delete a task",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -11,10 +11,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//TODO:(jessvalarezo) exec-id is optional here, update to required arg
|
//TODO:(jessvalarezo) exec-id is optional here, update to required arg
|
||||||
var taskExecCommand = cli.Command{
|
var execCommand = cli.Command{
|
||||||
Name: "exec",
|
Name: "exec",
|
||||||
Usage: "execute additional processes in an existing container",
|
Usage: "execute additional processes in an existing container",
|
||||||
ArgsUsage: "CONTAINER CMD [ARG...]",
|
ArgsUsage: "[flags] CONTAINER CMD [ARG...]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "cwd",
|
Name: "cwd",
|
||||||
@ -84,7 +84,7 @@ var taskExecCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tty {
|
if tty {
|
||||||
if err := handleConsoleResize(ctx, process, con); err != nil {
|
if err := HandleConsoleResize(ctx, process, con); err != nil {
|
||||||
logrus.WithError(err).Error("console resize")
|
logrus.WithError(err).Error("console resize")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
@ -8,10 +8,10 @@ import (
|
|||||||
|
|
||||||
// TODO:(jessvalarezo) the pid flag is not used here
|
// TODO:(jessvalarezo) the pid flag is not used here
|
||||||
// update to be able to signal given pid
|
// update to be able to signal given pid
|
||||||
var taskKillCommand = cli.Command{
|
var killCommand = cli.Command{
|
||||||
Name: "kill",
|
Name: "kill",
|
||||||
Usage: "signal a container (default: SIGTERM)",
|
Usage: "signal a container (default: SIGTERM)",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "[flags] CONTAINER",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "signal, s",
|
Name: "signal, s",
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -10,28 +10,11 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tasksCommand = cli.Command{
|
var listCommand = cli.Command{
|
||||||
Name: "tasks",
|
|
||||||
Usage: "manage tasks",
|
|
||||||
Aliases: []string{"t"},
|
|
||||||
Subcommands: []cli.Command{
|
|
||||||
taskAttachCommand,
|
|
||||||
taskCheckpointCommand,
|
|
||||||
taskExecCommand,
|
|
||||||
taskKillCommand,
|
|
||||||
taskPauseCommand,
|
|
||||||
taskPsCommand,
|
|
||||||
taskResumeCommand,
|
|
||||||
taskStartCommand,
|
|
||||||
taskDeleteCommand,
|
|
||||||
taskListCommand,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var taskListCommand = cli.Command{
|
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Usage: "list tasks",
|
Usage: "list tasks",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
|
ArgsUsage: "[flags]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet, q",
|
@ -1,11 +1,11 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskPauseCommand = cli.Command{
|
var pauseCommand = cli.Command{
|
||||||
Name: "pause",
|
Name: "pause",
|
||||||
Usage: "pause an existing container",
|
Usage: "pause an existing container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,7 +11,7 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskPsCommand = cli.Command{
|
var psCommand = cli.Command{
|
||||||
Name: "ps",
|
Name: "ps",
|
||||||
Usage: "list processes for container",
|
Usage: "list processes for container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
@ -1,11 +1,11 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskResumeCommand = cli.Command{
|
var resumeCommand = cli.Command{
|
||||||
Name: "resume",
|
Name: "resume",
|
||||||
Usage: "resume a paused container",
|
Usage: "resume a paused container",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
@ -1,4 +1,4 @@
|
|||||||
package main
|
package tasks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var taskStartCommand = cli.Command{
|
var startCommand = cli.Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Usage: "start a container that have been created",
|
Usage: "start a container that have been created",
|
||||||
ArgsUsage: "CONTAINER",
|
ArgsUsage: "CONTAINER",
|
||||||
@ -43,7 +43,7 @@ var taskStartCommand = cli.Command{
|
|||||||
|
|
||||||
tty := spec.Process.Terminal
|
tty := spec.Process.Terminal
|
||||||
|
|
||||||
task, err := newTask(ctx, client, container, "", tty, context.Bool("null-io"))
|
task, err := NewTask(ctx, client, container, "", tty, context.Bool("null-io"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ var taskStartCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if tty {
|
if tty {
|
||||||
if err := handleConsoleResize(ctx, task, con); err != nil {
|
if err := HandleConsoleResize(ctx, task, con); err != nil {
|
||||||
logrus.WithError(err).Error("console resize")
|
logrus.WithError(err).Error("console resize")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
30
cmd/ctr/commands/tasks/tasks.go
Normal file
30
cmd/ctr/commands/tasks/tasks.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package tasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
gocontext "context"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
type resizer interface {
|
||||||
|
Resize(ctx gocontext.Context, w, h uint32) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command is the cli command for managing tasks
|
||||||
|
var Command = cli.Command{
|
||||||
|
Name: "tasks",
|
||||||
|
Usage: "manage tasks",
|
||||||
|
Aliases: []string{"t"},
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
attachCommand,
|
||||||
|
checkpointCommand,
|
||||||
|
deleteCommand,
|
||||||
|
execCommand,
|
||||||
|
listCommand,
|
||||||
|
killCommand,
|
||||||
|
pauseCommand,
|
||||||
|
psCommand,
|
||||||
|
resumeCommand,
|
||||||
|
startCommand,
|
||||||
|
},
|
||||||
|
}
|
64
cmd/ctr/commands/tasks/tasks_unix.go
Normal file
64
cmd/ctr/commands/tasks/tasks_unix.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package tasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
gocontext "context"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
|
||||||
|
"github.com/containerd/console"
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandleConsoleResize resizes the console
|
||||||
|
func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Console) error {
|
||||||
|
// do an initial resize of the console
|
||||||
|
size, err := con.Size()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("resize pty")
|
||||||
|
}
|
||||||
|
s := make(chan os.Signal, 16)
|
||||||
|
signal.Notify(s, unix.SIGWINCH)
|
||||||
|
go func() {
|
||||||
|
for range s {
|
||||||
|
size, err := con.Size()
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("get pty size")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("resize pty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTask creates a new task
|
||||||
|
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, tty, nullIO bool) (containerd.Task, error) {
|
||||||
|
if checkpoint == "" {
|
||||||
|
io := containerd.Stdio
|
||||||
|
if tty {
|
||||||
|
io = containerd.StdioTerminal
|
||||||
|
}
|
||||||
|
if nullIO {
|
||||||
|
if tty {
|
||||||
|
return nil, errors.New("tty and null-io cannot be used together")
|
||||||
|
}
|
||||||
|
io = containerd.NullIO
|
||||||
|
}
|
||||||
|
return container.NewTask(ctx, io)
|
||||||
|
}
|
||||||
|
im, err := client.GetImage(ctx, checkpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return container.NewTask(ctx, containerd.Stdio, containerd.WithTaskCheckpoint(im))
|
||||||
|
}
|
55
cmd/ctr/commands/tasks/tasks_windows.go
Normal file
55
cmd/ctr/commands/tasks/tasks_windows.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package tasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
gocontext "context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/containerd/console"
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandleConsoleResize resizes the console
|
||||||
|
func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Console) error {
|
||||||
|
// do an initial resize of the console
|
||||||
|
size, err := con.Size()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
prevSize := size
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Millisecond * 250)
|
||||||
|
|
||||||
|
size, err := con.Size()
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("get pty size")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if size.Width != prevSize.Width || size.Height != prevSize.Height {
|
||||||
|
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("resize pty")
|
||||||
|
}
|
||||||
|
prevSize = size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTask creates a new task
|
||||||
|
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, _ string, tty, nullIO bool) (containerd.Task, error) {
|
||||||
|
io := containerd.Stdio
|
||||||
|
if tty {
|
||||||
|
io = containerd.StdioTerminal
|
||||||
|
}
|
||||||
|
if nullIO {
|
||||||
|
if tty {
|
||||||
|
return nil, errors.New("tty and null-io cannot be used together")
|
||||||
|
}
|
||||||
|
io = containerd.NullIO
|
||||||
|
}
|
||||||
|
return container.NewTask(ctx, io)
|
||||||
|
}
|
@ -12,7 +12,10 @@ import (
|
|||||||
"github.com/containerd/containerd/cmd/ctr/commands/images"
|
"github.com/containerd/containerd/cmd/ctr/commands/images"
|
||||||
namespacesCmd "github.com/containerd/containerd/cmd/ctr/commands/namespaces"
|
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/pprof"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands/run"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands/snapshot"
|
"github.com/containerd/containerd/cmd/ctr/commands/snapshot"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands/tasks"
|
||||||
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"
|
||||||
@ -79,10 +82,10 @@ containerd CLI
|
|||||||
events.Command,
|
events.Command,
|
||||||
images.Command,
|
images.Command,
|
||||||
namespacesCmd.Command,
|
namespacesCmd.Command,
|
||||||
pprofCommand,
|
pprof.Command,
|
||||||
runCommand,
|
run.Command,
|
||||||
snapshot.Command,
|
snapshot.Command,
|
||||||
tasksCommand,
|
tasks.Command,
|
||||||
}, extraCmds...)
|
}, extraCmds...)
|
||||||
app.Before = func(context *cli.Context) error {
|
app.Before = func(context *cli.Context) error {
|
||||||
if context.GlobalBool("debug") {
|
if context.GlobalBool("debug") {
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/cmd/ctr/commands/shim"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
extraCmds = append(extraCmds, shimCommand)
|
extraCmds = append(extraCmds, shim.Command)
|
||||||
}
|
}
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/csv"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
// parseMountFlag parses a mount string in the form "type=foo,source=/path,destination=/target,options=rbind:rw"
|
|
||||||
func parseMountFlag(m string) (specs.Mount, error) {
|
|
||||||
mount := specs.Mount{}
|
|
||||||
r := csv.NewReader(strings.NewReader(m))
|
|
||||||
|
|
||||||
fields, err := r.Read()
|
|
||||||
if err != nil {
|
|
||||||
return mount, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, field := range fields {
|
|
||||||
v := strings.Split(field, "=")
|
|
||||||
if len(v) != 2 {
|
|
||||||
return mount, fmt.Errorf("invalid mount specification: expected key=val")
|
|
||||||
}
|
|
||||||
|
|
||||||
key := v[0]
|
|
||||||
val := v[1]
|
|
||||||
switch key {
|
|
||||||
case "type":
|
|
||||||
mount.Type = val
|
|
||||||
case "source", "src":
|
|
||||||
mount.Source = val
|
|
||||||
case "destination", "dst":
|
|
||||||
mount.Destination = val
|
|
||||||
case "options":
|
|
||||||
mount.Options = strings.Split(val, ":")
|
|
||||||
default:
|
|
||||||
return mount, fmt.Errorf("mount option %q not supported", key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mount, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// replaceOrAppendEnvValues returns the defaults with the overrides either
|
|
||||||
// replaced by env key or appended to the list
|
|
||||||
func replaceOrAppendEnvValues(defaults, overrides []string) []string {
|
|
||||||
cache := make(map[string]int, len(defaults))
|
|
||||||
for i, e := range defaults {
|
|
||||||
parts := strings.SplitN(e, "=", 2)
|
|
||||||
cache[parts[0]] = i
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, value := range overrides {
|
|
||||||
// Values w/o = means they want this env to be removed/unset.
|
|
||||||
if !strings.Contains(value, "=") {
|
|
||||||
if i, exists := cache[value]; exists {
|
|
||||||
defaults[i] = "" // Used to indicate it should be removed
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just do a normal set/update
|
|
||||||
parts := strings.SplitN(value, "=", 2)
|
|
||||||
if i, exists := cache[parts[0]]; exists {
|
|
||||||
defaults[i] = value
|
|
||||||
} else {
|
|
||||||
defaults = append(defaults, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove all entries that we want to "unset"
|
|
||||||
for i := 0; i < len(defaults); i++ {
|
|
||||||
if defaults[i] == "" {
|
|
||||||
defaults = append(defaults[:i], defaults[i+1:]...)
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaults
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user