github.com/containerd/containerd@v22.0.0-20200918172823-438c87b8e050+incompatible/cmd/ctr/commands/run/run_windows.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 run
    18  
    19  import (
    20  	gocontext "context"
    21  
    22  	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
    23  	"github.com/containerd/console"
    24  	"github.com/containerd/containerd"
    25  	"github.com/containerd/containerd/cmd/ctr/commands"
    26  	"github.com/containerd/containerd/oci"
    27  	specs "github.com/opencontainers/runtime-spec/specs-go"
    28  	"github.com/pkg/errors"
    29  	"github.com/sirupsen/logrus"
    30  	"github.com/urfave/cli"
    31  )
    32  
    33  var platformRunFlags = []cli.Flag{
    34  	cli.BoolFlag{
    35  		Name:  "isolated",
    36  		Usage: "run the container with vm isolation",
    37  	},
    38  }
    39  
    40  // NewContainer creates a new container
    41  func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
    42  	var (
    43  		id    string
    44  		opts  []oci.SpecOpts
    45  		cOpts []containerd.NewContainerOpts
    46  		spec  containerd.NewContainerOpts
    47  
    48  		config = context.IsSet("config")
    49  	)
    50  
    51  	if config {
    52  		id = context.Args().First()
    53  		opts = append(opts, oci.WithSpecFromFile(context.String("config")))
    54  	} else {
    55  		var (
    56  			ref  = context.Args().First()
    57  			args = context.Args()[2:]
    58  		)
    59  
    60  		id = context.Args().Get(1)
    61  		snapshotter := context.String("snapshotter")
    62  		if snapshotter == "windows-lcow" {
    63  			opts = append(opts, oci.WithDefaultSpecForPlatform("linux/amd64"))
    64  			// Clear the rootfs section.
    65  			opts = append(opts, oci.WithRootFSPath(""))
    66  		} else {
    67  			opts = append(opts, oci.WithDefaultSpec())
    68  			opts = append(opts, oci.WithWindowNetworksAllowUnqualifiedDNSQuery())
    69  			opts = append(opts, oci.WithWindowsIgnoreFlushesDuringBoot())
    70  		}
    71  		if ef := context.String("env-file"); ef != "" {
    72  			opts = append(opts, oci.WithEnvFile(ef))
    73  		}
    74  		opts = append(opts, oci.WithEnv(context.StringSlice("env")))
    75  		opts = append(opts, withMounts(context))
    76  
    77  		image, err := client.GetImage(ctx, ref)
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  		unpacked, err := image.IsUnpacked(ctx, snapshotter)
    82  		if err != nil {
    83  			return nil, err
    84  		}
    85  		if !unpacked {
    86  			if err := image.Unpack(ctx, snapshotter); err != nil {
    87  				return nil, err
    88  			}
    89  		}
    90  		opts = append(opts, oci.WithImageConfig(image))
    91  		cOpts = append(cOpts, containerd.WithImage(image))
    92  		cOpts = append(cOpts, containerd.WithSnapshotter(snapshotter))
    93  		cOpts = append(cOpts, containerd.WithNewSnapshot(id, image))
    94  
    95  		if len(args) > 0 {
    96  			opts = append(opts, oci.WithProcessArgs(args...))
    97  		}
    98  		if cwd := context.String("cwd"); cwd != "" {
    99  			opts = append(opts, oci.WithProcessCwd(cwd))
   100  		}
   101  		if context.Bool("tty") {
   102  			opts = append(opts, oci.WithTTY)
   103  
   104  			con := console.Current()
   105  			size, err := con.Size()
   106  			if err != nil {
   107  				logrus.WithError(err).Error("console size")
   108  			}
   109  			opts = append(opts, oci.WithTTYSize(int(size.Width), int(size.Height)))
   110  		}
   111  		if context.Bool("net-host") {
   112  			return nil, errors.New("Cannot use host mode networking with Windows containers")
   113  		}
   114  		if context.Bool("isolated") {
   115  			opts = append(opts, oci.WithWindowsHyperV)
   116  		}
   117  		limit := context.Uint64("memory-limit")
   118  		if limit != 0 {
   119  			opts = append(opts, oci.WithMemoryLimit(limit))
   120  		}
   121  		ccount := context.Uint64("cpu-count")
   122  		if ccount != 0 {
   123  			opts = append(opts, oci.WithWindowsCPUCount(ccount))
   124  		}
   125  	}
   126  
   127  	cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
   128  	runtime := context.String("runtime")
   129  	var runtimeOpts interface{}
   130  	if runtime == "io.containerd.runhcs.v1" {
   131  		runtimeOpts = &options.Options{
   132  			Debug: context.GlobalBool("debug"),
   133  		}
   134  	}
   135  	cOpts = append(cOpts, containerd.WithRuntime(runtime, runtimeOpts))
   136  
   137  	var s specs.Spec
   138  	spec = containerd.WithSpec(&s, opts...)
   139  
   140  	cOpts = append(cOpts, spec)
   141  
   142  	return client.NewContainer(ctx, id, cOpts...)
   143  }
   144  
   145  func getNewTaskOpts(_ *cli.Context) []containerd.NewTaskOpts {
   146  	return nil
   147  }