summaryrefslogtreecommitdiff
path: root/plugin/executor
diff options
context:
space:
mode:
authorBrian Goff <cpuguy83@gmail.com>2017-07-14 16:45:32 -0400
committerBrian Goff <cpuguy83@gmail.com>2017-09-19 12:17:55 -0400
commitc85e8622a4813d7b72d74517faa03ab5de4c4550 (patch)
treea10489134bcced753dd73a05cafb8e1f4196057d /plugin/executor
parent3fa72d38ec61377b506d31711f5cf1b855219926 (diff)
downloaddocker-c85e8622a4813d7b72d74517faa03ab5de4c4550.tar.gz
Decouple plugin manager from libcontainerd package
libcontainerd has a bunch of platform dependent code and huge interfaces that are a pain implement. To make the plugin manager a bit easier to work with, extract the plugin executor into an interface and move the containerd implementation to a separate package. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Diffstat (limited to 'plugin/executor')
-rw-r--r--plugin/executor/containerd/containerd.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go
new file mode 100644
index 0000000000..74cf530cf1
--- /dev/null
+++ b/plugin/executor/containerd/containerd.go
@@ -0,0 +1,77 @@
+package containerd
+
+import (
+ "io"
+
+ "github.com/docker/docker/libcontainerd"
+ "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/pkg/errors"
+)
+
+// ExitHandler represents an object that is called when the exit event is received from containerd
+type ExitHandler interface {
+ HandleExitEvent(id string) error
+}
+
+// New creates a new containerd plugin executor
+func New(remote libcontainerd.Remote, exitHandler ExitHandler) (*Executor, error) {
+ e := &Executor{exitHandler: exitHandler}
+ client, err := remote.Client(e)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating containerd exec client")
+ }
+ e.client = client
+ return e, nil
+}
+
+// Executor is the containerd client implementation of a plugin executor
+type Executor struct {
+ client libcontainerd.Client
+ exitHandler ExitHandler
+}
+
+// Create creates a new container
+func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error {
+ return e.client.Create(id, "", "", spec, attachStreamsFunc(stdout, stderr))
+}
+
+// Restore restores a container
+func (e *Executor) Restore(id string, stdout, stderr io.WriteCloser) error {
+ return e.client.Restore(id, attachStreamsFunc(stdout, stderr))
+}
+
+// IsRunning returns if the container with the given id is running
+func (e *Executor) IsRunning(id string) (bool, error) {
+ pids, err := e.client.GetPidsForContainer(id)
+ return len(pids) > 0, err
+}
+
+// Signal sends the specified signal to the container
+func (e *Executor) Signal(id string, signal int) error {
+ return e.client.Signal(id, signal)
+}
+
+// StateChanged handles state changes from containerd
+// All events are ignored except the exit event, which is sent of to the stored handler
+func (e *Executor) StateChanged(id string, event libcontainerd.StateInfo) error {
+ switch event.State {
+ case libcontainerd.StateExit:
+ return e.exitHandler.HandleExitEvent(id)
+ }
+ return nil
+}
+
+func attachStreamsFunc(stdout, stderr io.WriteCloser) func(libcontainerd.IOPipe) error {
+ return func(iop libcontainerd.IOPipe) error {
+ iop.Stdin.Close()
+ go func() {
+ io.Copy(stdout, iop.Stdout)
+ stdout.Close()
+ }()
+ go func() {
+ io.Copy(stderr, iop.Stderr)
+ stderr.Close()
+ }()
+ return nil
+ }
+}