mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-28 20:15:51 +00:00
Fixes: #2023 We can get OCI spec config from bundle instead of annotations, so this field isn't necessary. Signed-off-by: Wei Zhang <weizhang555.zw@gmail.com>
186 lines
4.8 KiB
Go
186 lines
4.8 KiB
Go
// Copyright (c) 2014,2015,2016 Docker, Inc.
|
|
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/kata-containers/runtime/pkg/katautils"
|
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/compatoci"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
var createCLICommand = cli.Command{
|
|
Name: "create",
|
|
Usage: "Create a container",
|
|
ArgsUsage: `<container-id>
|
|
|
|
<container-id> is your name for the instance of the container that you
|
|
are starting. The name you provide for the container instance must be unique
|
|
on your host.`,
|
|
Description: `The create command creates an instance of a container for a bundle. The
|
|
bundle is a directory with a specification file named "` + specConfig + `" and a
|
|
root filesystem.
|
|
The specification file includes an args parameter. The args parameter is
|
|
used to specify command(s) that get run when the container is started.
|
|
To change the command(s) that get executed on start, edit the args
|
|
parameter of the spec.`,
|
|
Flags: []cli.Flag{
|
|
cli.StringFlag{
|
|
Name: "bundle, b",
|
|
Value: "",
|
|
Usage: `path to the root of the bundle directory, defaults to the current directory`,
|
|
},
|
|
cli.StringFlag{
|
|
Name: "console",
|
|
Value: "",
|
|
Usage: "path to a pseudo terminal",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "console-socket",
|
|
Value: "",
|
|
Usage: "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "pid-file",
|
|
Value: "",
|
|
Usage: "specify the file to write the process id to",
|
|
},
|
|
cli.BoolFlag{
|
|
Name: "no-pivot",
|
|
Usage: "warning: this flag is meaningless to kata-runtime, just defined in order to be compatible with docker in ramdisk",
|
|
},
|
|
},
|
|
Action: func(context *cli.Context) error {
|
|
ctx, err := cliContextToContext(context)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
runtimeConfig, ok := context.App.Metadata["runtimeConfig"].(oci.RuntimeConfig)
|
|
if !ok {
|
|
return errors.New("invalid runtime config")
|
|
}
|
|
|
|
console, err := setupConsole(context.String("console"), context.String("console-socket"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return create(ctx, context.Args().First(),
|
|
context.String("bundle"),
|
|
console,
|
|
context.String("pid-file"),
|
|
true,
|
|
context.Bool("systemd-cgroup"),
|
|
runtimeConfig,
|
|
)
|
|
},
|
|
}
|
|
|
|
func create(ctx context.Context, containerID, bundlePath, console, pidFilePath string, detach, systemdCgroup bool,
|
|
runtimeConfig oci.RuntimeConfig) error {
|
|
var err error
|
|
|
|
span, ctx := katautils.Trace(ctx, "create")
|
|
defer span.Finish()
|
|
|
|
kataLog = kataLog.WithField("container", containerID)
|
|
setExternalLoggers(ctx, kataLog)
|
|
span.SetTag("container", containerID)
|
|
|
|
if bundlePath == "" {
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
kataLog.WithField("directory", cwd).Debug("Defaulting bundle path to current directory")
|
|
|
|
bundlePath = cwd
|
|
}
|
|
|
|
// Checks the MUST and MUST NOT from OCI runtime specification
|
|
if bundlePath, err = validCreateParams(ctx, containerID, bundlePath); err != nil {
|
|
return err
|
|
}
|
|
|
|
ociSpec, err := compatoci.ParseConfigJSON(bundlePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
containerType, err := oci.ContainerType(ociSpec)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
katautils.HandleFactory(ctx, vci, &runtimeConfig)
|
|
|
|
disableOutput := noNeedForOutput(detach, ociSpec.Process.Terminal)
|
|
|
|
//rootfs has been mounted by containerd shim
|
|
rootFs := vc.RootFs{Mounted: true}
|
|
|
|
var process vc.Process
|
|
switch containerType {
|
|
case vc.PodSandbox:
|
|
_, process, err = katautils.CreateSandbox(ctx, vci, ociSpec, runtimeConfig, rootFs, containerID, bundlePath, console, disableOutput, systemdCgroup, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
case vc.PodContainer:
|
|
process, err = katautils.CreateContainer(ctx, vci, nil, ociSpec, rootFs, containerID, bundlePath, console, disableOutput, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Creation of PID file has to be the last thing done in the create
|
|
// because containerd considers the create complete after this file
|
|
// is created.
|
|
return createPIDFile(ctx, pidFilePath, process.Pid)
|
|
}
|
|
|
|
func createPIDFile(ctx context.Context, pidFilePath string, pid int) error {
|
|
span, _ := katautils.Trace(ctx, "createPIDFile")
|
|
defer span.Finish()
|
|
|
|
if pidFilePath == "" {
|
|
// runtime should not fail since pid file is optional
|
|
return nil
|
|
}
|
|
|
|
if err := os.RemoveAll(pidFilePath); err != nil {
|
|
return err
|
|
}
|
|
|
|
f, err := os.Create(pidFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
pidStr := fmt.Sprintf("%d", pid)
|
|
|
|
n, err := f.WriteString(pidStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if n < len(pidStr) {
|
|
return fmt.Errorf("Could not write pid to '%s': only %d bytes written out of %d", pidFilePath, n, len(pidStr))
|
|
}
|
|
|
|
return nil
|
|
}
|