X Tutup
Skip to content

Commit 034682e

Browse files
committed
Honor context termination on Start and Exec
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
1 parent 8aa0f57 commit 034682e

File tree

8 files changed

+43
-16
lines changed

8 files changed

+43
-16
lines changed

api/grpc/server/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
5656
e.Runtime = c.Runtime
5757
e.RuntimeArgs = c.RuntimeArgs
5858
e.StartResponse = make(chan supervisor.StartResponse, 1)
59+
e.Ctx = ctx
5960
if c.Checkpoint != "" {
6061
e.CheckpointDir = c.CheckpointDir
6162
e.Checkpoint = &runtime.Checkpoint{

api/grpc/server/server_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
5050
e.Stdout = r.Stdout
5151
e.Stderr = r.Stderr
5252
e.StartResponse = make(chan supervisor.StartResponse, 1)
53+
e.Ctx = ctx
5354
s.sv.SendTask(e)
5455
if err := <-e.ErrorCh(); err != nil {
5556
return nil, err

containerd-shim/process_linux.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package main
44

55
import (
6+
"fmt"
67
"io"
78
"syscall"
89
"time"
@@ -94,18 +95,18 @@ func (p *process) openIO() error {
9495
} {
9596
fw, err := fifo.OpenFifo(ctx, name, syscall.O_WRONLY, 0)
9697
if err != nil {
97-
return err
98+
return fmt.Errorf("containerd-shim: opening %s failed: %s", name, err)
9899
}
99100
fr, err := fifo.OpenFifo(ctx, name, syscall.O_RDONLY, 0)
100101
if err != nil {
101-
return err
102+
return fmt.Errorf("containerd-shim: opening %s failed: %s", name, err)
102103
}
103104
dest(fw, fr)
104105
}
105106

106107
f, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_RDONLY, 0)
107108
if err != nil {
108-
return err
109+
return fmt.Errorf("containerd-shim: opening %s failed: %s", p.state.Stdin, err)
109110
}
110111
go func() {
111112
io.Copy(i.Stdin, f)

runtime/container.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/Sirupsen/logrus"
1515
"github.com/docker/containerd/specs"
1616
ocs "github.com/opencontainers/runtime-spec/specs-go"
17+
"golang.org/x/net/context"
1718
"golang.org/x/sys/unix"
1819
)
1920

@@ -24,9 +25,9 @@ type Container interface {
2425
// Path returns the path to the bundle
2526
Path() string
2627
// Start starts the init process of the container
27-
Start(checkpointPath string, s Stdio) (Process, error)
28+
Start(ctx context.Context, checkpointPath string, s Stdio) (Process, error)
2829
// Exec starts another process in an existing container
29-
Exec(string, specs.ProcessSpec, Stdio) (Process, error)
30+
Exec(context.Context, string, specs.ProcessSpec, Stdio) (Process, error)
3031
// Delete removes the container's state and any resources
3132
Delete() error
3233
// Processes returns all the containers processes that have been added
@@ -186,7 +187,7 @@ func Load(root, id, shimName string, timeout time.Duration) (Container, error) {
186187
}
187188
p, err := loadProcess(filepath.Join(root, id, pid), pid, c, s)
188189
if err != nil {
189-
logrus.WithField("id", id).WithField("pid", pid).Debug("containerd: error loading process %s", err)
190+
logrus.WithField("id", id).WithField("pid", pid).Debugf("containerd: error loading process %s", err)
190191
continue
191192
}
192193
c.processes[pid] = p
@@ -394,7 +395,7 @@ func (c *container) DeleteCheckpoint(name string, checkpointDir string) error {
394395
return os.RemoveAll(filepath.Join(checkpointDir, name))
395396
}
396397

397-
func (c *container) Start(checkpointPath string, s Stdio) (Process, error) {
398+
func (c *container) Start(ctx context.Context, checkpointPath string, s Stdio) (Process, error) {
398399
processRoot := filepath.Join(c.root, c.id, InitProcessID)
399400
if err := os.Mkdir(processRoot, 0755); err != nil {
400401
return nil, err
@@ -423,13 +424,13 @@ func (c *container) Start(checkpointPath string, s Stdio) (Process, error) {
423424
if err != nil {
424425
return nil, err
425426
}
426-
if err := c.createCmd(InitProcessID, cmd, p); err != nil {
427+
if err := c.createCmd(ctx, InitProcessID, cmd, p); err != nil {
427428
return nil, err
428429
}
429430
return p, nil
430431
}
431432

432-
func (c *container) Exec(pid string, pspec specs.ProcessSpec, s Stdio) (pp Process, err error) {
433+
func (c *container) Exec(ctx context.Context, pid string, pspec specs.ProcessSpec, s Stdio) (pp Process, err error) {
433434
processRoot := filepath.Join(c.root, c.id, pid)
434435
if err := os.Mkdir(processRoot, 0755); err != nil {
435436
return nil, err
@@ -463,13 +464,13 @@ func (c *container) Exec(pid string, pspec specs.ProcessSpec, s Stdio) (pp Proce
463464
if err != nil {
464465
return nil, err
465466
}
466-
if err := c.createCmd(pid, cmd, p); err != nil {
467+
if err := c.createCmd(ctx, pid, cmd, p); err != nil {
467468
return nil, err
468469
}
469470
return p, nil
470471
}
471472

472-
func (c *container) createCmd(pid string, cmd *exec.Cmd, p *process) error {
473+
func (c *container) createCmd(ctx context.Context, pid string, cmd *exec.Cmd, p *process) error {
473474
p.cmd = cmd
474475
if err := cmd.Start(); err != nil {
475476
close(p.cmdDoneCh)
@@ -508,10 +509,25 @@ func (c *container) createCmd(pid string, cmd *exec.Cmd, p *process) error {
508509
close(p.cmdDoneCh)
509510
}()
510511
}()
511-
if err := c.waitForCreate(p, cmd); err != nil {
512+
513+
ch := make(chan error)
514+
go func() {
515+
if err := c.waitForCreate(p, cmd); err != nil {
516+
ch <- err
517+
return
518+
}
519+
c.processes[pid] = p
520+
ch <- nil
521+
}()
522+
select {
523+
case <-ctx.Done():
524+
cmd.Process.Kill()
525+
cmd.Wait()
526+
<-ch
527+
return ctx.Err()
528+
case err := <-ch:
512529
return err
513530
}
514-
c.processes[pid] = p
515531
return nil
516532
}
517533

runtime/runtime_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package runtime
22

33
import (
4+
"context"
45
"flag"
56
"fmt"
67
"io"
@@ -163,7 +164,7 @@ func BenchmarkBusyboxSh(b *testing.B) {
163164
}
164165

165166
func benchmarkStartContainer(b *testing.B, c Container, s Stdio, bundleName string) {
166-
p, err := c.Start("", s)
167+
p, err := c.Start(context.Background(), "", s)
167168
if err != nil {
168169
b.Fatalf("Error starting container %v", err)
169170
}

supervisor/add_process.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/docker/containerd/runtime"
77
"github.com/docker/containerd/specs"
8+
"golang.org/x/net/context"
89
)
910

1011
// AddProcessTask holds everything necessary to add a process to a
@@ -18,6 +19,7 @@ type AddProcessTask struct {
1819
Stdin string
1920
ProcessSpec *specs.ProcessSpec
2021
StartResponse chan StartResponse
22+
Ctx context.Context
2123
}
2224

2325
func (s *Supervisor) addProcess(t *AddProcessTask) error {
@@ -26,7 +28,7 @@ func (s *Supervisor) addProcess(t *AddProcessTask) error {
2628
if !ok {
2729
return ErrContainerNotFound
2830
}
29-
process, err := ci.container.Exec(t.PID, *t.ProcessSpec, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
31+
process, err := ci.container.Exec(t.Ctx, t.PID, *t.ProcessSpec, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
3032
if err != nil {
3133
return err
3234
}

supervisor/create.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/docker/containerd/runtime"
8+
"golang.org/x/net/context"
89
)
910

1011
// StartTask holds needed parameters to create a new container
@@ -22,6 +23,7 @@ type StartTask struct {
2223
CheckpointDir string
2324
Runtime string
2425
RuntimeArgs []string
26+
Ctx context.Context
2527
}
2628

2729
func (s *Supervisor) start(t *StartTask) error {
@@ -57,6 +59,7 @@ func (s *Supervisor) start(t *StartTask) error {
5759
Stdin: t.Stdin,
5860
Stdout: t.Stdout,
5961
Stderr: t.Stderr,
62+
Ctx: t.Ctx,
6063
}
6164
if t.Checkpoint != nil {
6265
task.CheckpointPath = filepath.Join(t.CheckpointDir, t.Checkpoint.Name)

supervisor/worker.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/Sirupsen/logrus"
88
"github.com/docker/containerd/runtime"
9+
"golang.org/x/net/context"
910
)
1011

1112
// Worker interface
@@ -21,6 +22,7 @@ type startTask struct {
2122
Stderr string
2223
Err chan error
2324
StartResponse chan StartResponse
25+
Ctx context.Context
2426
}
2527

2628
// NewWorker return a new initialized worker
@@ -41,7 +43,7 @@ func (w *worker) Start() {
4143
defer w.wg.Done()
4244
for t := range w.s.startTasks {
4345
started := time.Now()
44-
process, err := t.Container.Start(t.CheckpointPath, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
46+
process, err := t.Container.Start(t.Ctx, t.CheckpointPath, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
4547
if err != nil {
4648
logrus.WithFields(logrus.Fields{
4749
"error": err,

0 commit comments

Comments
 (0)
X Tutup