mirror of https://github.com/docker/docs.git
Adding new client interface in Swarm
Signed-off-by: Nishant Totla <nishanttotla@gmail.com>
This commit is contained in:
parent
936f2f7914
commit
62b0b29aa6
|
@ -2,6 +2,7 @@ package mockclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/container"
|
"github.com/docker/engine-api/types/container"
|
||||||
|
@ -161,7 +162,7 @@ func (client *MockClient) ContainerResize(ctx context.Context, container string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerRestart stops and starts a container again
|
// ContainerRestart stops and starts a container again
|
||||||
func (client *MockClient) ContainerRestart(ctx context.Context, container string, timeout int) error {
|
func (client *MockClient) ContainerRestart(ctx context.Context, container string, timeout *time.Duration) error {
|
||||||
args := client.Mock.Called(ctx, container, timeout)
|
args := client.Mock.Called(ctx, container, timeout)
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
|
@ -179,13 +180,13 @@ func (client *MockClient) ContainerStats(ctx context.Context, container string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStart sends a request to the docker daemon to start a container
|
// ContainerStart sends a request to the docker daemon to start a container
|
||||||
func (client *MockClient) ContainerStart(ctx context.Context, container string, checkpointID string) error {
|
func (client *MockClient) ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error {
|
||||||
args := client.Mock.Called(ctx, container, checkpointID)
|
args := client.Mock.Called(ctx, container, options)
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStop stops a container without terminating the process
|
// ContainerStop stops a container without terminating the process
|
||||||
func (client *MockClient) ContainerStop(ctx context.Context, container string, timeout int) error {
|
func (client *MockClient) ContainerStop(ctx context.Context, container string, timeout *time.Duration) error {
|
||||||
args := client.Mock.Called(ctx, container, timeout)
|
args := client.Mock.Called(ctx, container, timeout)
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
|
@ -305,8 +306,8 @@ func (client *MockClient) ImageSave(ctx context.Context, images []string) (io.Re
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageTag tags an image in the docker host
|
// ImageTag tags an image in the docker host
|
||||||
func (client *MockClient) ImageTag(ctx context.Context, image, ref string, options types.ImageTagOptions) error {
|
func (client *MockClient) ImageTag(ctx context.Context, image, ref string) error {
|
||||||
args := client.Mock.Called(ctx, image, ref, options)
|
args := client.Mock.Called(ctx, image, ref)
|
||||||
return args.Error(0)
|
return args.Error(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/engine-api/client"
|
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
|
"github.com/docker/swarm/swarmclient"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@ func TestMock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMockInterface(t *testing.T) {
|
func TestMockInterface(t *testing.T) {
|
||||||
iface := reflect.TypeOf((*client.APIClient)(nil)).Elem()
|
iface := reflect.TypeOf((*swarmclient.SwarmAPIClient)(nil)).Elem()
|
||||||
mockClient := NewMockClient()
|
mockClient := NewMockClient()
|
||||||
|
|
||||||
if !reflect.TypeOf(mockClient).Implements(iface) {
|
if !reflect.TypeOf(mockClient).Implements(iface) {
|
||||||
t.Fatalf("Mock does not implement the APIClient interface")
|
t.Fatalf("Mock does not implement the SwarmAPIClient interface")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package nopclient
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
@ -142,7 +143,7 @@ func (client *NopClient) ContainerResize(ctx context.Context, container string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerRestart stops and starts a container again
|
// ContainerRestart stops and starts a container again
|
||||||
func (client *NopClient) ContainerRestart(ctx context.Context, container string, timeout int) error {
|
func (client *NopClient) ContainerRestart(ctx context.Context, container string, timeout *time.Duration) error {
|
||||||
return errNoEngine
|
return errNoEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,12 +158,12 @@ func (client *NopClient) ContainerStats(ctx context.Context, container string, s
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStart sends a request to the docker daemon to start a container
|
// ContainerStart sends a request to the docker daemon to start a container
|
||||||
func (client *NopClient) ContainerStart(ctx context.Context, container string, checkpointID string) error {
|
func (client *NopClient) ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error {
|
||||||
return errNoEngine
|
return errNoEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStop stops a container without terminating the process
|
// ContainerStop stops a container without terminating the process
|
||||||
func (client *NopClient) ContainerStop(ctx context.Context, container string, timeout int) error {
|
func (client *NopClient) ContainerStop(ctx context.Context, container string, timeout *time.Duration) error {
|
||||||
return errNoEngine
|
return errNoEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +263,7 @@ func (client *NopClient) ImageSave(ctx context.Context, images []string) (io.Rea
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageTag tags an image in the docker host
|
// ImageTag tags an image in the docker host
|
||||||
func (client *NopClient) ImageTag(ctx context.Context, image, ref string, options types.ImageTagOptions) error {
|
func (client *NopClient) ImageTag(ctx context.Context, image, ref string) error {
|
||||||
return errNoEngine
|
return errNoEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/swarm/swarmclient"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/engine-api/client"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNop(t *testing.T) {
|
func TestNop(t *testing.T) {
|
||||||
|
@ -18,10 +17,10 @@ func TestNop(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNopInterface(t *testing.T) {
|
func TestNopInterface(t *testing.T) {
|
||||||
iface := reflect.TypeOf((*client.APIClient)(nil)).Elem()
|
iface := reflect.TypeOf((*swarmclient.SwarmAPIClient)(nil)).Elem()
|
||||||
nop := NewNopClient()
|
nop := NewNopClient()
|
||||||
|
|
||||||
if !reflect.TypeOf(nop).Implements(iface) {
|
if !reflect.TypeOf(nop).Implements(iface) {
|
||||||
t.Fatalf("Nop does not implement the APIClient interface")
|
t.Fatalf("Nop does not implement the SwarmAPIClient interface")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
networktypes "github.com/docker/engine-api/types/network"
|
networktypes "github.com/docker/engine-api/types/network"
|
||||||
engineapinop "github.com/docker/swarm/api/nopclient"
|
engineapinop "github.com/docker/swarm/api/nopclient"
|
||||||
|
"github.com/docker/swarm/swarmclient"
|
||||||
"github.com/samalba/dockerclient"
|
"github.com/samalba/dockerclient"
|
||||||
"github.com/samalba/dockerclient/nopclient"
|
"github.com/samalba/dockerclient/nopclient"
|
||||||
)
|
)
|
||||||
|
@ -123,7 +124,7 @@ type Engine struct {
|
||||||
networks map[string]*Network
|
networks map[string]*Network
|
||||||
volumes map[string]*Volume
|
volumes map[string]*Volume
|
||||||
client dockerclient.Client
|
client dockerclient.Client
|
||||||
apiClient engineapi.APIClient
|
apiClient swarmclient.SwarmAPIClient
|
||||||
eventHandler EventHandler
|
eventHandler EventHandler
|
||||||
state engineState
|
state engineState
|
||||||
lastError string
|
lastError string
|
||||||
|
@ -209,7 +210,7 @@ func (e *Engine) StartMonitorEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectWithClient is exported
|
// ConnectWithClient is exported
|
||||||
func (e *Engine) ConnectWithClient(client dockerclient.Client, apiClient engineapi.APIClient) error {
|
func (e *Engine) ConnectWithClient(client dockerclient.Client, apiClient swarmclient.SwarmAPIClient) error {
|
||||||
e.client = client
|
e.client = client
|
||||||
e.apiClient = apiClient
|
e.apiClient = apiClient
|
||||||
e.eventsMonitor = NewEventsMonitor(e.apiClient, e.handler)
|
e.eventsMonitor = NewEventsMonitor(e.apiClient, e.handler)
|
||||||
|
@ -1335,8 +1336,8 @@ func (e *Engine) StartContainer(id string, hostConfig *dockerclient.HostConfig)
|
||||||
if hostConfig != nil {
|
if hostConfig != nil {
|
||||||
err = e.client.StartContainer(id, hostConfig)
|
err = e.client.StartContainer(id, hostConfig)
|
||||||
} else {
|
} else {
|
||||||
// TODO(nishanttotla): Figure out what the checkpoint id (second string argument) should be
|
// TODO(nishanttotla): Should ContainerStartOptions be provided?
|
||||||
err = e.apiClient.ContainerStart(context.Background(), id, "")
|
err = e.apiClient.ContainerStart(context.Background(), id, types.ContainerStartOptions{})
|
||||||
}
|
}
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1375,11 +1376,7 @@ func (e *Engine) BuildImage(buildContext io.Reader, buildImage *types.ImageBuild
|
||||||
// TagImage tags an image
|
// TagImage tags an image
|
||||||
func (e *Engine) TagImage(IDOrName string, ref string, force bool) error {
|
func (e *Engine) TagImage(IDOrName string, ref string, force bool) error {
|
||||||
// send tag request to docker engine
|
// send tag request to docker engine
|
||||||
opts := types.ImageTagOptions{
|
err := e.apiClient.ImageTag(context.Background(), IDOrName, ref)
|
||||||
Force: force,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := e.apiClient.ImageTag(context.Background(), IDOrName, ref, opts)
|
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -4,16 +4,16 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/engine-api/client"
|
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/events"
|
"github.com/docker/engine-api/types/events"
|
||||||
|
"github.com/docker/swarm/swarmclient"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
//EventsMonitor monitors events
|
//EventsMonitor monitors events
|
||||||
type EventsMonitor struct {
|
type EventsMonitor struct {
|
||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
cli client.APIClient
|
cli swarmclient.SwarmAPIClient
|
||||||
handler func(msg events.Message) error
|
handler func(msg events.Message) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ type decodingResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEventsMonitor returns an EventsMonitor
|
// NewEventsMonitor returns an EventsMonitor
|
||||||
func NewEventsMonitor(cli client.APIClient, handler func(msg events.Message) error) *EventsMonitor {
|
func NewEventsMonitor(cli swarmclient.SwarmAPIClient, handler func(msg events.Message) error) *EventsMonitor {
|
||||||
return &EventsMonitor{
|
return &EventsMonitor{
|
||||||
cli: cli,
|
cli: cli,
|
||||||
handler: handler,
|
handler: handler,
|
||||||
|
|
|
@ -264,7 +264,7 @@ func TestTagImage(t *testing.T) {
|
||||||
c.engines[engine.ID] = engine
|
c.engines[engine.ID] = engine
|
||||||
|
|
||||||
// tag image
|
// tag image
|
||||||
apiClient.On("ImageTag", mock.Anything, mock.Anything, mock.Anything, mock.AnythingOfType("types.ImageTagOptions")).Return(nil).Once()
|
apiClient.On("ImageTag", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
|
||||||
assert.Nil(t, c.TagImage("busybox", "test_busybox:latest", false))
|
assert.Nil(t, c.TagImage("busybox", "test_busybox:latest", false))
|
||||||
assert.NotNil(t, c.TagImage("busybox_not_exists", "test_busybox:latest", false))
|
assert.NotNil(t, c.TagImage("busybox_not_exists", "test_busybox:latest", false))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package swarmclient
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/engine-api/client"
|
||||||
|
"github.com/docker/engine-api/types"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SwarmAPIClient contains the subset of the engine-api interface relevant to Docker Swarm
|
||||||
|
type SwarmAPIClient interface {
|
||||||
|
client.ContainerAPIClient
|
||||||
|
client.ImageAPIClient
|
||||||
|
client.NetworkAPIClient
|
||||||
|
client.SystemAPIClient
|
||||||
|
client.VolumeAPIClient
|
||||||
|
ClientVersion() string
|
||||||
|
ServerVersion(ctx context.Context) (types.Version, error)
|
||||||
|
UpdateClientVersion(v string)
|
||||||
|
}
|
Loading…
Reference in New Issue