diff options
| author | Michael Crosby <crosbymichael@gmail.com> | 2019-03-25 16:17:17 -0400 |
|---|---|---|
| committer | Michael Crosby <crosbymichael@gmail.com> | 2019-04-05 15:48:07 -0400 |
| commit | b9b5dc37e37e67d1cd46d9a3448c96e3f57ef4bc (patch) | |
| tree | d406c2839e114f4efffa134125e962c42fd49e16 /plugin/executor | |
| parent | adb15c2899d22011b70edab0a380416295f626ed (diff) | |
| download | docker-b9b5dc37e37e67d1cd46d9a3448c96e3f57ef4bc.tar.gz | |
Remove inmemory container map
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Diffstat (limited to 'plugin/executor')
| -rw-r--r-- | plugin/executor/containerd/containerd.go | 40 | ||||
| -rw-r--r-- | plugin/executor/containerd/containerd_test.go | 149 |
2 files changed, 15 insertions, 174 deletions
diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go index 61aaedf3ee..23418558d8 100644 --- a/plugin/executor/containerd/containerd.go +++ b/plugin/executor/containerd/containerd.go @@ -5,7 +5,6 @@ import ( "io" "path/filepath" "sync" - "time" "github.com/containerd/containerd" "github.com/containerd/containerd/cio" @@ -26,19 +25,6 @@ type ExitHandler interface { HandleExitEvent(id string) error } -// Client is used by the exector to perform operations. -// TODO(@cpuguy83): This should really just be based off the containerd client interface. -// However right now this whole package is tied to github.com/docker/docker/libcontainerd -type Client interface { - Create(ctx context.Context, containerID string, spec *specs.Spec, runtimeOptions interface{}) error - Restore(ctx context.Context, containerID string, attachStdio libcontainerdtypes.StdioCallback) (alive bool, pid int, err error) - Status(ctx context.Context, containerID string) (containerd.ProcessStatus, error) - Delete(ctx context.Context, containerID string) error - DeleteTask(ctx context.Context, containerID string) (uint32, time.Time, error) - Start(ctx context.Context, containerID, checkpointDir string, withStdin bool, attachStdio libcontainerdtypes.StdioCallback) (pid int, err error) - SignalProcess(ctx context.Context, containerID, processID string, signal int) error -} - // New creates a new containerd plugin executor func New(ctx context.Context, rootDir string, cli *containerd.Client, exitHandler ExitHandler) (*Executor, error) { e := &Executor{ @@ -57,19 +43,23 @@ func New(ctx context.Context, rootDir string, cli *containerd.Client, exitHandle // Executor is the containerd client implementation of a plugin executor type Executor struct { rootDir string - client Client + client libcontainerdtypes.Client exitHandler ExitHandler } // deleteTaskAndContainer deletes plugin task and then plugin container from containerd -func deleteTaskAndContainer(ctx context.Context, cli Client, id string) { - _, _, err := cli.DeleteTask(ctx, id) - if err != nil && !errdefs.IsNotFound(err) { - logrus.WithError(err).WithField("id", id).Error("failed to delete plugin task from containerd") +func deleteTaskAndContainer(ctx context.Context, cli libcontainerdtypes.Client, id string, p libcontainerdtypes.Process) { + if p != nil { + if _, _, err := p.Delete(ctx); err != nil && !errdefs.IsNotFound(err) { + logrus.WithError(err).WithField("id", id).Error("failed to delete plugin task from containerd") + } + } else { + if _, _, err := cli.DeleteTask(ctx, id); err != nil && !errdefs.IsNotFound(err) { + logrus.WithError(err).WithField("id", id).Error("failed to delete plugin task from containerd") + } } - err = cli.Delete(ctx, id) - if err != nil && !errdefs.IsNotFound(err) { + if err := cli.Delete(ctx, id); err != nil && !errdefs.IsNotFound(err) { logrus.WithError(err).WithField("id", id).Error("failed to delete plugin container from containerd") } } @@ -103,19 +93,19 @@ func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteClo _, err = e.client.Start(ctx, id, "", false, attachStreamsFunc(stdout, stderr)) if err != nil { - deleteTaskAndContainer(ctx, e.client, id) + deleteTaskAndContainer(ctx, e.client, id, nil) } return err } // Restore restores a container func (e *Executor) Restore(id string, stdout, stderr io.WriteCloser) (bool, error) { - alive, _, err := e.client.Restore(context.Background(), id, attachStreamsFunc(stdout, stderr)) + alive, _, p, err := e.client.Restore(context.Background(), id, attachStreamsFunc(stdout, stderr)) if err != nil && !errdefs.IsNotFound(err) { return false, err } if !alive { - deleteTaskAndContainer(context.Background(), e.client, id) + deleteTaskAndContainer(context.Background(), e.client, id, p) } return alive, nil } @@ -136,7 +126,7 @@ func (e *Executor) Signal(id string, signal int) error { func (e *Executor) ProcessEvent(id string, et libcontainerdtypes.EventType, ei libcontainerdtypes.EventInfo) error { switch et { case libcontainerdtypes.EventExit: - deleteTaskAndContainer(context.Background(), e.client, id) + deleteTaskAndContainer(context.Background(), e.client, id, nil) return e.exitHandler.HandleExitEvent(ei.ContainerID) } return nil diff --git a/plugin/executor/containerd/containerd_test.go b/plugin/executor/containerd/containerd_test.go deleted file mode 100644 index 8e2d616784..0000000000 --- a/plugin/executor/containerd/containerd_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package containerd - -import ( - "context" - "io/ioutil" - "os" - "sync" - "testing" - "time" - - "github.com/containerd/containerd" - libcontainerdtypes "github.com/docker/docker/libcontainerd/types" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - "gotest.tools/assert" -) - -func TestLifeCycle(t *testing.T) { - t.Parallel() - - mock := newMockClient() - exec, cleanup := setupTest(t, mock, mock) - defer cleanup() - - id := "test-create" - mock.simulateStartError(true, id) - err := exec.Create(id, specs.Spec{}, nil, nil) - assert.Assert(t, err != nil) - mock.simulateStartError(false, id) - - err = exec.Create(id, specs.Spec{}, nil, nil) - assert.NilError(t, err) - running, _ := exec.IsRunning(id) - assert.Assert(t, running) - - // create with the same ID - err = exec.Create(id, specs.Spec{}, nil, nil) - assert.Assert(t, err != nil) - - mock.HandleExitEvent(id) // simulate a plugin that exits - - err = exec.Create(id, specs.Spec{}, nil, nil) - assert.NilError(t, err) -} - -func setupTest(t *testing.T, client Client, eh ExitHandler) (*Executor, func()) { - rootDir, err := ioutil.TempDir("", "test-daemon") - assert.NilError(t, err) - assert.Assert(t, client != nil) - assert.Assert(t, eh != nil) - - return &Executor{ - rootDir: rootDir, - client: client, - exitHandler: eh, - }, func() { - assert.Assert(t, os.RemoveAll(rootDir)) - } -} - -type mockClient struct { - mu sync.Mutex - containers map[string]bool - errorOnStart map[string]bool -} - -func newMockClient() *mockClient { - return &mockClient{ - containers: make(map[string]bool), - errorOnStart: make(map[string]bool), - } -} - -func (c *mockClient) Create(ctx context.Context, id string, _ *specs.Spec, _ interface{}) error { - c.mu.Lock() - defer c.mu.Unlock() - - if _, ok := c.containers[id]; ok { - return errors.New("exists") - } - - c.containers[id] = false - return nil -} - -func (c *mockClient) Restore(ctx context.Context, id string, attachStdio libcontainerdtypes.StdioCallback) (alive bool, pid int, err error) { - return false, 0, nil -} - -func (c *mockClient) Status(ctx context.Context, id string) (containerd.ProcessStatus, error) { - c.mu.Lock() - defer c.mu.Unlock() - - running, ok := c.containers[id] - if !ok { - return containerd.Unknown, errors.New("not found") - } - if running { - return containerd.Running, nil - } - return containerd.Stopped, nil -} - -func (c *mockClient) Delete(ctx context.Context, id string) error { - c.mu.Lock() - defer c.mu.Unlock() - delete(c.containers, id) - return nil -} - -func (c *mockClient) DeleteTask(ctx context.Context, id string) (uint32, time.Time, error) { - return 0, time.Time{}, nil -} - -func (c *mockClient) Start(ctx context.Context, id, checkpointDir string, withStdin bool, attachStdio libcontainerdtypes.StdioCallback) (pid int, err error) { - c.mu.Lock() - defer c.mu.Unlock() - - if _, ok := c.containers[id]; !ok { - return 0, errors.New("not found") - } - - if c.errorOnStart[id] { - return 0, errors.New("some startup error") - } - c.containers[id] = true - return 1, nil -} - -func (c *mockClient) SignalProcess(ctx context.Context, containerID, processID string, signal int) error { - return nil -} - -func (c *mockClient) simulateStartError(sim bool, id string) { - c.mu.Lock() - defer c.mu.Unlock() - if sim { - c.errorOnStart[id] = sim - return - } - delete(c.errorOnStart, id) -} - -func (c *mockClient) HandleExitEvent(id string) error { - c.mu.Lock() - defer c.mu.Unlock() - delete(c.containers, id) - return nil -} |
