Skip to content

Commit 1a577d4

Browse files
committed
Prepare startContainer() to have more action
Currently startContainer() is used to create and to run a container. In the next patch it will be used to restore a container. Signed-off-by: Andrei Vagin <[email protected]>
1 parent 0711b5d commit 1a577d4

File tree

5 files changed

+39
-112
lines changed

5 files changed

+39
-112
lines changed

create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ command(s) that get executed on start, edit the args parameter of the spec. See
6262
if err != nil {
6363
return err
6464
}
65-
status, err := startContainer(context, spec, true)
65+
status, err := startContainer(context, spec, CT_ACT_CREATE, nil)
6666
if err != nil {
6767
return err
6868
}

exec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ func execProcess(context *cli.Context) (int, error) {
138138
consoleSocket: context.String("console-socket"),
139139
detach: detach,
140140
pidFile: context.String("pid-file"),
141+
action: CT_ACT_RUN,
141142
}
142143
return r.run(p)
143144
}

restore.go

Lines changed: 9 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,8 @@ package main
44

55
import (
66
"os"
7-
"syscall"
87

9-
"github.com/Sirupsen/logrus"
108
"github.com/opencontainers/runc/libcontainer"
11-
"github.com/opencontainers/runc/libcontainer/configs"
12-
"github.com/opencontainers/runc/libcontainer/specconv"
13-
"github.com/opencontainers/runtime-spec/specs-go"
149
"github.com/urfave/cli"
1510
)
1611

@@ -86,111 +81,25 @@ using the runc checkpoint command.`,
8681
if err := checkArgs(context, 1, exactArgs); err != nil {
8782
return err
8883
}
89-
imagePath := context.String("image-path")
90-
id := context.Args().First()
91-
if id == "" {
92-
return errEmptyID
93-
}
94-
if imagePath == "" {
95-
imagePath = getDefaultImagePath(context)
96-
}
97-
bundle := context.String("bundle")
98-
if bundle != "" {
99-
if err := os.Chdir(bundle); err != nil {
100-
return err
101-
}
84+
if err := revisePidFile(context); err != nil {
85+
return err
10286
}
103-
spec, err := loadSpec(specConfig)
87+
spec, err := setupSpec(context)
10488
if err != nil {
10589
return err
10690
}
107-
config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
108-
CgroupName: id,
109-
UseSystemdCgroup: context.GlobalBool("systemd-cgroup"),
110-
NoPivotRoot: context.Bool("no-pivot"),
111-
Spec: spec,
112-
})
91+
options := criuOptions(context)
92+
status, err := startContainer(context, spec, CT_ACT_RESTORE, options)
11393
if err != nil {
11494
return err
11595
}
116-
status, err := restoreContainer(context, spec, config, imagePath)
117-
if err == nil {
118-
os.Exit(status)
119-
}
120-
return err
96+
// exit with the container's exit status so any external supervisor is
97+
// notified of the exit with the correct exit status.
98+
os.Exit(status)
99+
return nil
121100
},
122101
}
123102

124-
func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Config, imagePath string) (int, error) {
125-
var (
126-
rootuid = 0
127-
rootgid = 0
128-
id = context.Args().First()
129-
)
130-
factory, err := loadFactory(context)
131-
if err != nil {
132-
return -1, err
133-
}
134-
container, err := factory.Load(id)
135-
if err != nil {
136-
container, err = factory.Create(id, config)
137-
if err != nil {
138-
return -1, err
139-
}
140-
}
141-
options := criuOptions(context)
142-
143-
status, err := container.Status()
144-
if err != nil {
145-
logrus.Error(err)
146-
}
147-
if status == libcontainer.Running {
148-
fatalf("Container with id %s already running", id)
149-
}
150-
151-
setManageCgroupsMode(context, options)
152-
153-
if err = setEmptyNsMask(context, options); err != nil {
154-
return -1, err
155-
}
156-
157-
// ensure that the container is always removed if we were the process
158-
// that created it.
159-
detach := context.Bool("detach")
160-
if !detach {
161-
defer destroy(container)
162-
}
163-
process := &libcontainer.Process{}
164-
tty, err := setupIO(process, rootuid, rootgid, false, detach, "")
165-
if err != nil {
166-
return -1, err
167-
}
168-
169-
notifySocket := newNotifySocket(context, os.Getenv("NOTIFY_SOCKET"), id)
170-
if notifySocket != nil {
171-
notifySocket.setupSpec(context, spec)
172-
notifySocket.setupSocket()
173-
}
174-
175-
handler := newSignalHandler(!context.Bool("no-subreaper"), notifySocket)
176-
if err := container.Restore(process, options); err != nil {
177-
return -1, err
178-
}
179-
// We don't need to do a tty.recvtty because config.Terminal is always false.
180-
defer tty.Close()
181-
if err := tty.ClosePostStart(); err != nil {
182-
return -1, err
183-
}
184-
if pidFile := context.String("pid-file"); pidFile != "" {
185-
if err := createPidFile(pidFile, process); err != nil {
186-
_ = process.Signal(syscall.SIGKILL)
187-
_, _ = process.Wait()
188-
return -1, err
189-
}
190-
}
191-
return handler.forward(process, tty, detach)
192-
}
193-
194103
func criuOptions(context *cli.Context) *libcontainer.CriuOpts {
195104
imagePath := getCheckpointImagePath(context)
196105
if err := os.MkdirAll(imagePath, 0655); err != nil {

run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ command(s) that get executed on start, edit the args parameter of the spec. See
7373
if err != nil {
7474
return err
7575
}
76-
status, err := startContainer(context, spec, false)
76+
status, err := startContainer(context, spec, CT_ACT_RUN, nil)
7777
if err == nil {
7878
// exit with the container's exit status so any external supervisor is
7979
// notified of the exit with the correct exit status.

utils_linux.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,9 @@ type runner struct {
214214
pidFile string
215215
consoleSocket string
216216
container libcontainer.Container
217-
create bool
217+
action CtAct
218218
notifySocket *notifySocket
219+
criuOpts *libcontainer.CriuOpts
219220
}
220221

221222
func (r *runner) run(config *specs.Process) (int, error) {
@@ -247,12 +248,8 @@ func (r *runner) run(config *specs.Process) (int, error) {
247248
return -1, err
248249
}
249250
var (
250-
detach = r.detach || r.create
251-
startFn = r.container.Start
251+
detach = r.detach || (r.action == CT_ACT_CREATE)
252252
)
253-
if !r.create {
254-
startFn = r.container.Run
255-
}
256253
// Setting up IO is a two stage process. We need to modify process to deal
257254
// with detaching containers, and then we get a tty after the container has
258255
// started.
@@ -263,7 +260,18 @@ func (r *runner) run(config *specs.Process) (int, error) {
263260
return -1, err
264261
}
265262
defer tty.Close()
266-
if err = startFn(process); err != nil {
263+
264+
switch r.action {
265+
case CT_ACT_CREATE:
266+
err = r.container.Start(process)
267+
case CT_ACT_RESTORE:
268+
err = r.container.Restore(process, r.criuOpts)
269+
case CT_ACT_RUN:
270+
err = r.container.Run(process)
271+
default:
272+
panic("Unknown action")
273+
}
274+
if err != nil {
267275
r.destroy()
268276
return -1, err
269277
}
@@ -307,7 +315,7 @@ func (r *runner) terminate(p *libcontainer.Process) {
307315
}
308316

309317
func (r *runner) checkTerminal(config *specs.Process) error {
310-
detach := r.detach || r.create
318+
detach := r.detach || (r.action == CT_ACT_CREATE)
311319
// Check command-line for sanity.
312320
if detach && config.Terminal && r.consoleSocket == "" {
313321
return fmt.Errorf("cannot allocate tty if runc will detach without setting console socket")
@@ -331,7 +339,15 @@ func validateProcessSpec(spec *specs.Process) error {
331339
return nil
332340
}
333341

334-
func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, error) {
342+
type CtAct uint8
343+
344+
const (
345+
CT_ACT_CREATE CtAct = iota + 1
346+
CT_ACT_RUN
347+
CT_ACT_RESTORE
348+
)
349+
350+
func startContainer(context *cli.Context, spec *specs.Spec, action CtAct, criuOpts *libcontainer.CriuOpts) (int, error) {
335351
id := context.Args().First()
336352
if id == "" {
337353
return -1, errEmptyID
@@ -366,7 +382,8 @@ func startContainer(context *cli.Context, spec *specs.Spec, create bool) (int, e
366382
detach: context.Bool("detach"),
367383
pidFile: context.String("pid-file"),
368384
preserveFDs: context.Int("preserve-fds"),
369-
create: create,
385+
action: action,
386+
criuOpts: criuOpts,
370387
}
371388
return r.run(&spec.Process)
372389
}

0 commit comments

Comments
 (0)