github.com/containerd/Containerd@v1.4.13/cmd/ctr/commands/tasks/start.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package tasks
    18  
    19  import (
    20  	"github.com/containerd/console"
    21  	"github.com/containerd/containerd"
    22  	"github.com/containerd/containerd/cio"
    23  	"github.com/containerd/containerd/cmd/ctr/commands"
    24  	"github.com/pkg/errors"
    25  	"github.com/sirupsen/logrus"
    26  	"github.com/urfave/cli"
    27  )
    28  
    29  var startCommand = cli.Command{
    30  	Name:      "start",
    31  	Usage:     "start a container that has been created",
    32  	ArgsUsage: "CONTAINER",
    33  	Flags: []cli.Flag{
    34  		cli.BoolFlag{
    35  			Name:  "null-io",
    36  			Usage: "send all IO to /dev/null",
    37  		},
    38  		cli.StringFlag{
    39  			Name:  "log-uri",
    40  			Usage: "log uri",
    41  		},
    42  		cli.StringFlag{
    43  			Name:  "fifo-dir",
    44  			Usage: "directory used for storing IO FIFOs",
    45  		},
    46  		cli.StringFlag{
    47  			Name:  "pid-file",
    48  			Usage: "file path to write the task's pid",
    49  		},
    50  		cli.BoolFlag{
    51  			Name:  "detach,d",
    52  			Usage: "detach from the task after it has started execution",
    53  		},
    54  	},
    55  	Action: func(context *cli.Context) error {
    56  		var (
    57  			err    error
    58  			id     = context.Args().Get(0)
    59  			detach = context.Bool("detach")
    60  		)
    61  		if id == "" {
    62  			return errors.New("container id must be provided")
    63  		}
    64  		client, ctx, cancel, err := commands.NewClient(context)
    65  		if err != nil {
    66  			return err
    67  		}
    68  		defer cancel()
    69  		container, err := client.LoadContainer(ctx, id)
    70  		if err != nil {
    71  			return err
    72  		}
    73  
    74  		spec, err := container.Spec(ctx)
    75  		if err != nil {
    76  			return err
    77  		}
    78  		var (
    79  			tty    = spec.Process.Terminal
    80  			opts   = getNewTaskOpts(context)
    81  			ioOpts = []cio.Opt{cio.WithFIFODir(context.String("fifo-dir"))}
    82  		)
    83  		var con console.Console
    84  		if tty {
    85  			con = console.Current()
    86  			defer con.Reset()
    87  			if err := con.SetRaw(); err != nil {
    88  				return err
    89  			}
    90  		}
    91  
    92  		task, err := NewTask(ctx, client, container, "", con, context.Bool("null-io"), context.String("log-uri"), ioOpts, opts...)
    93  		if err != nil {
    94  			return err
    95  		}
    96  		var statusC <-chan containerd.ExitStatus
    97  		if !detach {
    98  			defer task.Delete(ctx)
    99  			if statusC, err = task.Wait(ctx); err != nil {
   100  				return err
   101  			}
   102  		}
   103  		if context.IsSet("pid-file") {
   104  			if err := commands.WritePidFile(context.String("pid-file"), int(task.Pid())); err != nil {
   105  				return err
   106  			}
   107  		}
   108  
   109  		if err := task.Start(ctx); err != nil {
   110  			return err
   111  		}
   112  		if detach {
   113  			return nil
   114  		}
   115  		if tty {
   116  			if err := HandleConsoleResize(ctx, task, con); err != nil {
   117  				logrus.WithError(err).Error("console resize")
   118  			}
   119  		} else {
   120  			sigc := commands.ForwardAllSignals(ctx, task)
   121  			defer commands.StopCatch(sigc)
   122  		}
   123  
   124  		status := <-statusC
   125  		code, _, err := status.Result()
   126  		if err != nil {
   127  			return err
   128  		}
   129  		if _, err := task.Delete(ctx); err != nil {
   130  			return err
   131  		}
   132  		if code != 0 {
   133  			return cli.NewExitError("", int(code))
   134  		}
   135  		return nil
   136  	},
   137  }