diff --git a/cmd/ctr/main.go b/cmd/ctr/main.go index 717795a1d..61d8b5d92 100644 --- a/cmd/ctr/main.go +++ b/cmd/ctr/main.go @@ -87,6 +87,7 @@ containerd CLI rootfsCommand, runCommand, snapshotCommand, + startCommand, taskListCommand, versionCommand, }, extraCmds...) diff --git a/cmd/ctr/start.go b/cmd/ctr/start.go new file mode 100644 index 000000000..066b3c53c --- /dev/null +++ b/cmd/ctr/start.go @@ -0,0 +1,87 @@ +package main + +import ( + "github.com/containerd/console" + "github.com/opencontainers/go-digest" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +var startCommand = cli.Command{ + Name: "start", + Usage: "start a container that have been created", + ArgsUsage: "CONTAINER", + Action: func(context *cli.Context) error { + var ( + err error + + ctx, cancel = appContext(context) + id = context.Args().Get(0) + ) + + defer cancel() + + if id == "" { + return errors.New("container id must be provided") + } + client, err := newClient(context) + if err != nil { + return err + } + container, err := client.LoadContainer(ctx, id) + if err != nil { + return err + } + + spec, err := container.Spec() + if err != nil { + return err + } + + tty := spec.Process.Terminal + + task, err := newTask(ctx, container, digest.Digest(""), tty) + if err != nil { + return err + } + defer task.Delete(ctx) + + statusC := make(chan uint32, 1) + go func() { + status, err := task.Wait(ctx) + if err != nil { + logrus.WithError(err).Error("wait process") + } + statusC <- status + }() + var con console.Console + if tty { + con = console.Current() + defer con.Reset() + if err := con.SetRaw(); err != nil { + return err + } + } + if err := task.Start(ctx); err != nil { + return err + } + if tty { + if err := handleConsoleResize(ctx, task, con); err != nil { + logrus.WithError(err).Error("console resize") + } + } else { + sigc := forwardAllSignals(ctx, task) + defer stopCatch(sigc) + } + + status := <-statusC + if _, err := task.Delete(ctx); err != nil { + return err + } + if status != 0 { + return cli.NewExitError("", int(status)) + } + return nil + }, +}