This repository has been archived by the owner on May 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 373
/
Copy pathcreate.go
185 lines (155 loc) · 4.83 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// 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
}