modify code to compile on updated containerd

Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
Mike Brown
2017-06-07 14:41:30 -05:00
committed by Lantao Liu
parent 67e884e6cf
commit 484a326717
27 changed files with 444 additions and 453 deletions

View File

@@ -22,9 +22,9 @@ import (
"sync"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/api/services/execution"
"github.com/containerd/containerd/api/types/container"
"github.com/containerd/containerd/api/types/task"
"github.com/containerd/containerd/plugin"
googleprotobuf "github.com/golang/protobuf/ptypes/empty"
"golang.org/x/net/context"
"google.golang.org/grpc"
@@ -32,7 +32,7 @@ import (
)
// ContainerNotExistError is the fake error returned when container does not exist.
var ContainerNotExistError = grpc.Errorf(codes.Unknown, containerd.ErrContainerNotExist.Error())
var ContainerNotExistError = grpc.Errorf(codes.Unknown, plugin.ErrContainerNotExist.Error())
// CalledDetail is the struct contains called function name and arguments.
type CalledDetail struct {
@@ -42,16 +42,16 @@ type CalledDetail struct {
Argument interface{}
}
var _ execution.ContainerService_EventsClient = &EventClient{}
var _ execution.Tasks_EventsClient = &EventClient{}
// EventClient is a test implementation of execution.ContainerService_EventsClient
type EventClient struct {
Events chan *container.Event
Events chan *task.Event
grpc.ClientStream
}
// Recv is a test implementation of Recv
func (cli *EventClient) Recv() (*container.Event, error) {
func (cli *EventClient) Recv() (*task.Event, error) {
event, ok := <-cli.Events
if !ok {
return nil, fmt.Errorf("event channel closed")
@@ -65,18 +65,18 @@ type FakeExecutionClient struct {
sync.Mutex
called []CalledDetail
errors map[string]error
ContainerList map[string]container.Container
eventsQueue chan *container.Event
ContainerList map[string]task.Task
eventsQueue chan *task.Event
eventClients []*EventClient
}
var _ execution.ContainerServiceClient = &FakeExecutionClient{}
var _ execution.TasksClient = &FakeExecutionClient{}
// NewFakeExecutionClient creates a FakeExecutionClient
func NewFakeExecutionClient() *FakeExecutionClient {
return &FakeExecutionClient{
errors: make(map[string]error),
ContainerList: make(map[string]container.Container),
ContainerList: make(map[string]task.Task),
}
}
@@ -95,7 +95,7 @@ func (f *FakeExecutionClient) Stop() {
// WithEvents setup events publisher for FakeExecutionClient
func (f *FakeExecutionClient) WithEvents() *FakeExecutionClient {
f.eventsQueue = make(chan *container.Event, 1024)
f.eventsQueue = make(chan *task.Event, 1024)
go func() {
for e := range f.eventsQueue {
f.Lock()
@@ -146,7 +146,7 @@ func generatePid() uint32 {
return randPid
}
func (f *FakeExecutionClient) sendEvent(event *container.Event) {
func (f *FakeExecutionClient) sendEvent(event *task.Event) {
if f.eventsQueue != nil {
f.eventsQueue <- event
}
@@ -184,7 +184,7 @@ func (f *FakeExecutionClient) GetCalledDetails() []CalledDetail {
}
// SetFakeContainers injects fake containers.
func (f *FakeExecutionClient) SetFakeContainers(containers []container.Container) {
func (f *FakeExecutionClient) SetFakeContainers(containers []task.Task) {
f.Lock()
defer f.Unlock()
for _, c := range containers {
@@ -200,24 +200,24 @@ func (f *FakeExecutionClient) Create(ctx context.Context, createOpts *execution.
if err := f.getError("create"); err != nil {
return nil, err
}
_, ok := f.ContainerList[createOpts.ID]
_, ok := f.ContainerList[createOpts.ContainerID]
if ok {
return nil, containerd.ErrContainerExists
return nil, plugin.ErrContainerExists
}
pid := generatePid()
f.ContainerList[createOpts.ID] = container.Container{
ID: createOpts.ID,
Pid: pid,
Status: container.Status_CREATED,
f.ContainerList[createOpts.ContainerID] = task.Task{
ContainerID: createOpts.ContainerID,
Pid: pid,
Status: task.StatusCreated,
}
f.sendEvent(&container.Event{
ID: createOpts.ID,
Type: container.Event_CREATE,
f.sendEvent(&task.Event{
ID: createOpts.ContainerID,
Type: task.Event_CREATE,
Pid: pid,
})
return &execution.CreateResponse{
ID: createOpts.ID,
Pid: pid,
ContainerID: createOpts.ContainerID,
Pid: pid,
}, nil
}
@@ -229,23 +229,23 @@ func (f *FakeExecutionClient) Start(ctx context.Context, startOpts *execution.St
if err := f.getError("start"); err != nil {
return nil, err
}
c, ok := f.ContainerList[startOpts.ID]
c, ok := f.ContainerList[startOpts.ContainerID]
if !ok {
return nil, ContainerNotExistError
}
f.sendEvent(&container.Event{
f.sendEvent(&task.Event{
ID: c.ID,
Type: container.Event_START,
Type: task.Event_START,
Pid: c.Pid,
})
switch c.Status {
case container.Status_CREATED:
c.Status = container.Status_RUNNING
f.ContainerList[startOpts.ID] = c
case task.StatusCreated:
c.Status = task.StatusRunning
f.ContainerList[startOpts.ContainerID] = c
return &googleprotobuf.Empty{}, nil
case container.Status_STOPPED:
case task.StatusStopped:
return &googleprotobuf.Empty{}, fmt.Errorf("cannot start a container that has stopped")
case container.Status_RUNNING:
case task.StatusRunning:
return &googleprotobuf.Empty{}, fmt.Errorf("cannot start an already running container")
default:
return &googleprotobuf.Empty{}, fmt.Errorf("cannot start a container in the %s state", c.Status)
@@ -260,32 +260,32 @@ func (f *FakeExecutionClient) Delete(ctx context.Context, deleteOpts *execution.
if err := f.getError("delete"); err != nil {
return nil, err
}
c, ok := f.ContainerList[deleteOpts.ID]
c, ok := f.ContainerList[deleteOpts.ContainerID]
if !ok {
return nil, ContainerNotExistError
}
delete(f.ContainerList, deleteOpts.ID)
f.sendEvent(&container.Event{
delete(f.ContainerList, deleteOpts.ContainerID)
f.sendEvent(&task.Event{
ID: c.ID,
Type: container.Event_EXIT,
Type: task.Event_EXIT,
Pid: c.Pid,
})
return nil, nil
}
// Info is a test implementation of execution.Info
func (f *FakeExecutionClient) Info(ctx context.Context, infoOpts *execution.InfoRequest, opts ...grpc.CallOption) (*container.Container, error) {
func (f *FakeExecutionClient) Info(ctx context.Context, infoOpts *execution.InfoRequest, opts ...grpc.CallOption) (*execution.InfoResponse, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("info", infoOpts)
if err := f.getError("info"); err != nil {
return nil, err
}
c, ok := f.ContainerList[infoOpts.ID]
c, ok := f.ContainerList[infoOpts.ContainerID]
if !ok {
return nil, ContainerNotExistError
}
return &c, nil
return &execution.InfoResponse{Task: &c}, nil
}
// List is a test implementation of execution.List
@@ -298,7 +298,7 @@ func (f *FakeExecutionClient) List(ctx context.Context, listOpts *execution.List
}
resp := &execution.ListResponse{}
for _, c := range f.ContainerList {
resp.Containers = append(resp.Containers, &container.Container{
resp.Tasks = append(resp.Tasks, &task.Task{
ID: c.ID,
Pid: c.Pid,
Status: c.Status,
@@ -315,22 +315,22 @@ func (f *FakeExecutionClient) Kill(ctx context.Context, killOpts *execution.Kill
if err := f.getError("kill"); err != nil {
return nil, err
}
c, ok := f.ContainerList[killOpts.ID]
c, ok := f.ContainerList[killOpts.ContainerID]
if !ok {
return nil, ContainerNotExistError
}
c.Status = container.Status_STOPPED
f.ContainerList[killOpts.ID] = c
f.sendEvent(&container.Event{
c.Status = task.StatusStopped
f.ContainerList[killOpts.ContainerID] = c
f.sendEvent(&task.Event{
ID: c.ID,
Type: container.Event_EXIT,
Type: task.Event_EXIT,
Pid: c.Pid,
})
return &googleprotobuf.Empty{}, nil
}
// Events is a test implementation of execution.Events
func (f *FakeExecutionClient) Events(ctx context.Context, eventsOpts *execution.EventsRequest, opts ...grpc.CallOption) (execution.ContainerService_EventsClient, error) {
func (f *FakeExecutionClient) Events(ctx context.Context, eventsOpts *execution.EventsRequest, opts ...grpc.CallOption) (execution.Tasks_EventsClient, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("events", eventsOpts)
@@ -338,7 +338,7 @@ func (f *FakeExecutionClient) Events(ctx context.Context, eventsOpts *execution.
return nil, err
}
var client = &EventClient{
Events: make(chan *container.Event, 100),
Events: make(chan *task.Event, 100),
}
f.eventClients = append(f.eventClients, client)
return client, nil
@@ -373,3 +373,15 @@ func (f *FakeExecutionClient) Resume(ctx context.Context, in *execution.ResumeRe
// TODO: implement Resume()
return nil, nil
}
// Checkpoint is a test implementation of execution.Checkpoint
func (f *FakeExecutionClient) Checkpoint(ctx context.Context, in *execution.CheckpointRequest, opts ...grpc.CallOption) (*execution.CheckpointResponse, error) {
// TODO: implement Checkpoint()
return nil, nil
}
// Processes is a test implementation of execution.Processes
func (f *FakeExecutionClient) Processes(ctx context.Context, in *execution.ProcessesRequest, opts ...grpc.CallOption) (*execution.ProcessesResponse, error) {
// TODO: implement Processes()
return nil, nil
}

View File

@@ -1,197 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testing
import (
"fmt"
"sync"
"github.com/containerd/containerd/api/services/rootfs"
"github.com/containerd/containerd/api/types/descriptor"
"github.com/containerd/containerd/api/types/mount"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
// FakeRootfsClient is a simple fake rootfs client, so that cri-containerd
// can be run for testing without requiring a real containerd setup.
type FakeRootfsClient struct {
sync.Mutex
called []CalledDetail
errors map[string]error
ChainIDList map[digest.Digest]struct{}
MountList map[string][]*mount.Mount
}
var _ rootfs.RootFSClient = &FakeRootfsClient{}
// NewFakeRootfsClient creates a FakeRootfsClient
func NewFakeRootfsClient() *FakeRootfsClient {
return &FakeRootfsClient{
errors: make(map[string]error),
ChainIDList: make(map[digest.Digest]struct{}),
MountList: make(map[string][]*mount.Mount),
}
}
func (f *FakeRootfsClient) getError(op string) error {
err, ok := f.errors[op]
if ok {
delete(f.errors, op)
return err
}
return nil
}
// InjectError inject error for call
func (f *FakeRootfsClient) InjectError(fn string, err error) {
f.Lock()
defer f.Unlock()
f.errors[fn] = err
}
// InjectErrors inject errors for calls
func (f *FakeRootfsClient) InjectErrors(errs map[string]error) {
f.Lock()
defer f.Unlock()
for fn, err := range errs {
f.errors[fn] = err
}
}
// ClearErrors clear errors for call
func (f *FakeRootfsClient) ClearErrors() {
f.Lock()
defer f.Unlock()
f.errors = make(map[string]error)
}
//For uncompressed layers, diffID and digest will be the same. For compressed
//layers, we can look up the diffID from the digest if we've already unpacked it.
//In the FakeRootfsClient, We just use layer digest as diffID.
func generateChainID(layers []*descriptor.Descriptor) digest.Digest {
var digests []digest.Digest
for _, layer := range layers {
digests = append(digests, layer.Digest)
}
parent := identity.ChainID(digests)
return parent
}
func (f *FakeRootfsClient) appendCalled(name string, argument interface{}) {
call := CalledDetail{Name: name, Argument: argument}
f.called = append(f.called, call)
}
// GetCalledNames get names of call
func (f *FakeRootfsClient) GetCalledNames() []string {
f.Lock()
defer f.Unlock()
names := []string{}
for _, detail := range f.called {
names = append(names, detail.Name)
}
return names
}
// GetCalledDetails get detail of each call.
func (f *FakeRootfsClient) GetCalledDetails() []CalledDetail {
f.Lock()
defer f.Unlock()
// Copy the list and return.
return append([]CalledDetail{}, f.called...)
}
// SetFakeChainIDs injects fake chainIDs.
func (f *FakeRootfsClient) SetFakeChainIDs(chainIDs []digest.Digest) {
f.Lock()
defer f.Unlock()
for _, c := range chainIDs {
f.ChainIDList[c] = struct{}{}
}
}
// SetFakeMounts injects fake mounts.
func (f *FakeRootfsClient) SetFakeMounts(name string, mounts []*mount.Mount) {
f.Lock()
defer f.Unlock()
f.MountList[name] = mounts
}
// Unpack is a test implementation of rootfs.Unpack
func (f *FakeRootfsClient) Unpack(ctx context.Context, unpackOpts *rootfs.UnpackRequest, opts ...grpc.CallOption) (*rootfs.UnpackResponse, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("unpack", unpackOpts)
if err := f.getError("unpack"); err != nil {
return nil, err
}
chainID := generateChainID(unpackOpts.Layers)
_, ok := f.ChainIDList[chainID]
if ok {
return nil, fmt.Errorf("already unpacked")
}
f.ChainIDList[chainID] = struct{}{}
return &rootfs.UnpackResponse{
ChainID: chainID,
}, nil
}
// Prepare is a test implementation of rootfs.Prepare
func (f *FakeRootfsClient) Prepare(ctx context.Context, prepareOpts *rootfs.PrepareRequest, opts ...grpc.CallOption) (*rootfs.MountResponse, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("prepare", prepareOpts)
if err := f.getError("prepare"); err != nil {
return nil, err
}
_, ok := f.ChainIDList[prepareOpts.ChainID]
if !ok {
return nil, fmt.Errorf("have not been unpacked")
}
_, ok = f.MountList[prepareOpts.Name]
if ok {
return nil, fmt.Errorf("mounts already exist")
}
f.MountList[prepareOpts.Name] = []*mount.Mount{{
Type: "bind",
Source: prepareOpts.Name,
// TODO(random-liu): Fake options based on Readonly option.
}}
return &rootfs.MountResponse{
Mounts: f.MountList[prepareOpts.Name],
}, nil
}
// Mounts is a test implementation of rootfs.Mounts
func (f *FakeRootfsClient) Mounts(ctx context.Context, mountsOpts *rootfs.MountsRequest, opts ...grpc.CallOption) (*rootfs.MountResponse, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("mounts", mountsOpts)
if err := f.getError("mounts"); err != nil {
return nil, err
}
mounts, ok := f.MountList[mountsOpts.Name]
if !ok {
return nil, fmt.Errorf("mounts not exist")
}
return &rootfs.MountResponse{
Mounts: mounts,
}, nil
}

View File

@@ -0,0 +1,179 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package testing
import (
"fmt"
"sync"
"github.com/containerd/containerd/api/services/snapshot"
"github.com/containerd/containerd/api/types/mount"
google_protobuf1 "github.com/golang/protobuf/ptypes/empty"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
// FakeSnapshotClient is a simple fake snapshot client, so that cri-containerd
// can be run for testing without requiring a real containerd setup.
type FakeSnapshotClient struct {
sync.Mutex
called []CalledDetail
errors map[string]error
MountList map[string][]*mount.Mount
}
var _ snapshot.SnapshotClient = &FakeSnapshotClient{}
// NewFakeSnapshotClient creates a FakeSnapshotClient
func NewFakeSnapshotClient() *FakeSnapshotClient {
return &FakeSnapshotClient{
errors: make(map[string]error),
MountList: make(map[string][]*mount.Mount),
}
}
func (f *FakeSnapshotClient) getError(op string) error {
err, ok := f.errors[op]
if ok {
delete(f.errors, op)
return err
}
return nil
}
// InjectError inject error for call
func (f *FakeSnapshotClient) InjectError(fn string, err error) {
f.Lock()
defer f.Unlock()
f.errors[fn] = err
}
// InjectErrors inject errors for calls
func (f *FakeSnapshotClient) InjectErrors(errs map[string]error) {
f.Lock()
defer f.Unlock()
for fn, err := range errs {
f.errors[fn] = err
}
}
// ClearErrors clear errors for call
func (f *FakeSnapshotClient) ClearErrors() {
f.Lock()
defer f.Unlock()
f.errors = make(map[string]error)
}
func (f *FakeSnapshotClient) appendCalled(name string, argument interface{}) {
call := CalledDetail{Name: name, Argument: argument}
f.called = append(f.called, call)
}
// GetCalledNames get names of call
func (f *FakeSnapshotClient) GetCalledNames() []string {
f.Lock()
defer f.Unlock()
names := []string{}
for _, detail := range f.called {
names = append(names, detail.Name)
}
return names
}
// GetCalledDetails get detail of each call.
func (f *FakeSnapshotClient) GetCalledDetails() []CalledDetail {
f.Lock()
defer f.Unlock()
// Copy the list and return.
return append([]CalledDetail{}, f.called...)
}
// SetFakeMounts injects fake mounts.
func (f *FakeSnapshotClient) SetFakeMounts(name string, mounts []*mount.Mount) {
f.Lock()
defer f.Unlock()
f.MountList[name] = mounts
}
// Prepare is a test implementation of snapshot.Prepare
func (f *FakeSnapshotClient) Prepare(ctx context.Context, prepareOpts *snapshot.PrepareRequest, opts ...grpc.CallOption) (*snapshot.MountsResponse, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("prepare", prepareOpts)
if err := f.getError("prepare"); err != nil {
return nil, err
}
_, ok := f.MountList[prepareOpts.Key]
if ok {
return nil, fmt.Errorf("mounts already exist")
}
f.MountList[prepareOpts.Key] = []*mount.Mount{{
Type: "bind",
Source: prepareOpts.Key,
// TODO(random-liu): Fake options based on Readonly option.
}}
return &snapshot.MountsResponse{
Mounts: f.MountList[prepareOpts.Key],
}, nil
}
// Mounts is a test implementation of snapshot.Mounts
func (f *FakeSnapshotClient) Mounts(ctx context.Context, mountsOpts *snapshot.MountsRequest, opts ...grpc.CallOption) (*snapshot.MountsResponse, error) {
f.Lock()
defer f.Unlock()
f.appendCalled("mounts", mountsOpts)
if err := f.getError("mounts"); err != nil {
return nil, err
}
mounts, ok := f.MountList[mountsOpts.Key]
if !ok {
return nil, fmt.Errorf("mounts not exist")
}
return &snapshot.MountsResponse{
Mounts: mounts,
}, nil
}
// Commit is a test implementation of snapshot.Commit
func (f *FakeSnapshotClient) Commit(ctx context.Context, in *snapshot.CommitRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error) {
return nil, nil
}
// View is a test implementation of snapshot.View
func (f *FakeSnapshotClient) View(ctx context.Context, in *snapshot.PrepareRequest, opts ...grpc.CallOption) (*snapshot.MountsResponse, error) {
return nil, nil
}
// Remove is a test implementation of snapshot.Remove
func (f *FakeSnapshotClient) Remove(ctx context.Context, in *snapshot.RemoveRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error) {
return nil, nil
}
// Stat is a test implementation of snapshot.Stat
func (f *FakeSnapshotClient) Stat(ctx context.Context, in *snapshot.StatRequest, opts ...grpc.CallOption) (*snapshot.StatResponse, error) {
return nil, nil
}
// List is a test implementation of snapshot.List
func (f *FakeSnapshotClient) List(ctx context.Context, in *snapshot.ListRequest, opts ...grpc.CallOption) (snapshot.Snapshot_ListClient, error) {
return nil, nil
}
// Usage is a test implementation of snapshot.Usage
func (f *FakeSnapshotClient) Usage(ctx context.Context, in *snapshot.UsageRequest, opts ...grpc.CallOption) (*snapshot.UsageResponse, error) {
return nil, nil
}