mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #25721 from cpuguy83/revendor_engine-api
revendor engine-api
This commit is contained in:
commit
37302bbb3f
42 changed files with 241 additions and 182 deletions
|
@ -182,7 +182,7 @@ RUN set -x \
|
||||||
&& rm -rf "$GOPATH"
|
&& rm -rf "$GOPATH"
|
||||||
|
|
||||||
# Get the "docker-py" source so we can run their integration tests
|
# Get the "docker-py" source so we can run their integration tests
|
||||||
ENV DOCKER_PY_COMMIT 7befe694bd21e3c54bb1d7825270ea4bd6864c13
|
ENV DOCKER_PY_COMMIT e2655f658408f9ad1f62abdef3eb6ed43c0cf324
|
||||||
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||||
&& cd /docker-py \
|
&& cd /docker-py \
|
||||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||||
|
|
|
@ -133,7 +133,7 @@ RUN set -x \
|
||||||
&& rm -rf "$GOPATH"
|
&& rm -rf "$GOPATH"
|
||||||
|
|
||||||
# Get the "docker-py" source so we can run their integration tests
|
# Get the "docker-py" source so we can run their integration tests
|
||||||
ENV DOCKER_PY_COMMIT 7befe694bd21e3c54bb1d7825270ea4bd6864c13
|
ENV DOCKER_PY_COMMIT e2655f658408f9ad1f62abdef3eb6ed43c0cf324
|
||||||
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||||
&& cd /docker-py \
|
&& cd /docker-py \
|
||||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||||
|
|
|
@ -138,7 +138,7 @@ RUN set -x \
|
||||||
&& rm -rf "$GOPATH"
|
&& rm -rf "$GOPATH"
|
||||||
|
|
||||||
# Get the "docker-py" source so we can run their integration tests
|
# Get the "docker-py" source so we can run their integration tests
|
||||||
ENV DOCKER_PY_COMMIT 7befe694bd21e3c54bb1d7825270ea4bd6864c13
|
ENV DOCKER_PY_COMMIT e2655f658408f9ad1f62abdef3eb6ed43c0cf324
|
||||||
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||||
&& cd /docker-py \
|
&& cd /docker-py \
|
||||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||||
|
|
|
@ -60,7 +60,7 @@ RUN set -x \
|
||||||
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
|
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
|
||||||
|
|
||||||
# Get the "docker-py" source so we can run their integration tests
|
# Get the "docker-py" source so we can run their integration tests
|
||||||
ENV DOCKER_PY_COMMIT 7befe694bd21e3c54bb1d7825270ea4bd6864c13
|
ENV DOCKER_PY_COMMIT e2655f658408f9ad1f62abdef3eb6ed43c0cf324
|
||||||
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||||
&& cd /docker-py \
|
&& cd /docker-py \
|
||||||
&& git checkout -q $DOCKER_PY_COMMIT
|
&& git checkout -q $DOCKER_PY_COMMIT
|
||||||
|
|
|
@ -151,7 +151,7 @@ RUN set -x \
|
||||||
&& rm -rf "$GOPATH"
|
&& rm -rf "$GOPATH"
|
||||||
|
|
||||||
# Get the "docker-py" source so we can run their integration tests
|
# Get the "docker-py" source so we can run their integration tests
|
||||||
ENV DOCKER_PY_COMMIT 7befe694bd21e3c54bb1d7825270ea4bd6864c13
|
ENV DOCKER_PY_COMMIT e2655f658408f9ad1f62abdef3eb6ed43c0cf324
|
||||||
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||||
&& cd /docker-py \
|
&& cd /docker-py \
|
||||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||||
|
|
|
@ -155,7 +155,7 @@ RUN set -x \
|
||||||
&& rm -rf "$GOPATH"
|
&& rm -rf "$GOPATH"
|
||||||
|
|
||||||
# Get the "docker-py" source so we can run their integration tests
|
# Get the "docker-py" source so we can run their integration tests
|
||||||
ENV DOCKER_PY_COMMIT 7befe694bd21e3c54bb1d7825270ea4bd6864c13
|
ENV DOCKER_PY_COMMIT e2655f658408f9ad1f62abdef3eb6ed43c0cf324
|
||||||
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
RUN git clone https://github.com/docker/docker-py.git /docker-py \
|
||||||
&& cd /docker-py \
|
&& cd /docker-py \
|
||||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
"github.com/docker/engine-api/types/swarm"
|
"github.com/docker/engine-api/types/swarm"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
|
@ -130,7 +131,7 @@ func (i *Uint64Opt) Value() *uint64 {
|
||||||
|
|
||||||
// MountOpt is a Value type for parsing mounts
|
// MountOpt is a Value type for parsing mounts
|
||||||
type MountOpt struct {
|
type MountOpt struct {
|
||||||
values []swarm.Mount
|
values []mounttypes.Mount
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a new mount value
|
// Set a new mount value
|
||||||
|
@ -141,23 +142,23 @@ func (m *MountOpt) Set(value string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mount := swarm.Mount{}
|
mount := mounttypes.Mount{}
|
||||||
|
|
||||||
volumeOptions := func() *swarm.VolumeOptions {
|
volumeOptions := func() *mounttypes.VolumeOptions {
|
||||||
if mount.VolumeOptions == nil {
|
if mount.VolumeOptions == nil {
|
||||||
mount.VolumeOptions = &swarm.VolumeOptions{
|
mount.VolumeOptions = &mounttypes.VolumeOptions{
|
||||||
Labels: make(map[string]string),
|
Labels: make(map[string]string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mount.VolumeOptions.DriverConfig == nil {
|
if mount.VolumeOptions.DriverConfig == nil {
|
||||||
mount.VolumeOptions.DriverConfig = &swarm.Driver{}
|
mount.VolumeOptions.DriverConfig = &mounttypes.Driver{}
|
||||||
}
|
}
|
||||||
return mount.VolumeOptions
|
return mount.VolumeOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
bindOptions := func() *swarm.BindOptions {
|
bindOptions := func() *mounttypes.BindOptions {
|
||||||
if mount.BindOptions == nil {
|
if mount.BindOptions == nil {
|
||||||
mount.BindOptions = new(swarm.BindOptions)
|
mount.BindOptions = new(mounttypes.BindOptions)
|
||||||
}
|
}
|
||||||
return mount.BindOptions
|
return mount.BindOptions
|
||||||
}
|
}
|
||||||
|
@ -171,7 +172,7 @@ func (m *MountOpt) Set(value string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mount.Type = swarm.MountTypeVolume // default to volume mounts
|
mount.Type = mounttypes.TypeVolume // default to volume mounts
|
||||||
// Set writable as the default
|
// Set writable as the default
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
parts := strings.SplitN(field, "=", 2)
|
parts := strings.SplitN(field, "=", 2)
|
||||||
|
@ -195,7 +196,7 @@ func (m *MountOpt) Set(value string) error {
|
||||||
value := parts[1]
|
value := parts[1]
|
||||||
switch key {
|
switch key {
|
||||||
case "type":
|
case "type":
|
||||||
mount.Type = swarm.MountType(strings.ToLower(value))
|
mount.Type = mounttypes.Type(strings.ToLower(value))
|
||||||
case "source", "src":
|
case "source", "src":
|
||||||
mount.Source = value
|
mount.Source = value
|
||||||
case "target", "dst", "destination":
|
case "target", "dst", "destination":
|
||||||
|
@ -206,7 +207,7 @@ func (m *MountOpt) Set(value string) error {
|
||||||
return fmt.Errorf("invalid value for %s: %s", key, value)
|
return fmt.Errorf("invalid value for %s: %s", key, value)
|
||||||
}
|
}
|
||||||
case "bind-propagation":
|
case "bind-propagation":
|
||||||
bindOptions().Propagation = swarm.MountPropagation(strings.ToLower(value))
|
bindOptions().Propagation = mounttypes.Propagation(strings.ToLower(value))
|
||||||
case "volume-nocopy":
|
case "volume-nocopy":
|
||||||
volumeOptions().NoCopy, err = strconv.ParseBool(value)
|
volumeOptions().NoCopy, err = strconv.ParseBool(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -238,11 +239,11 @@ func (m *MountOpt) Set(value string) error {
|
||||||
return fmt.Errorf("source is required when specifying volume-* options")
|
return fmt.Errorf("source is required when specifying volume-* options")
|
||||||
}
|
}
|
||||||
|
|
||||||
if mount.Type == swarm.MountTypeBind && mount.VolumeOptions != nil {
|
if mount.Type == mounttypes.TypeBind && mount.VolumeOptions != nil {
|
||||||
return fmt.Errorf("cannot mix 'volume-*' options with mount type '%s'", swarm.MountTypeBind)
|
return fmt.Errorf("cannot mix 'volume-*' options with mount type '%s'", mounttypes.TypeBind)
|
||||||
}
|
}
|
||||||
if mount.Type == swarm.MountTypeVolume && mount.BindOptions != nil {
|
if mount.Type == mounttypes.TypeVolume && mount.BindOptions != nil {
|
||||||
return fmt.Errorf("cannot mix 'bind-*' options with mount type '%s'", swarm.MountTypeVolume)
|
return fmt.Errorf("cannot mix 'bind-*' options with mount type '%s'", mounttypes.TypeVolume)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.values = append(m.values, mount)
|
m.values = append(m.values, mount)
|
||||||
|
@ -265,7 +266,7 @@ func (m *MountOpt) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns the mounts
|
// Value returns the mounts
|
||||||
func (m *MountOpt) Value() []swarm.Mount {
|
func (m *MountOpt) Value() []mounttypes.Mount {
|
||||||
return m.values
|
return m.values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/testutil/assert"
|
"github.com/docker/docker/pkg/testutil/assert"
|
||||||
"github.com/docker/engine-api/types/swarm"
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMemBytesString(t *testing.T) {
|
func TestMemBytesString(t *testing.T) {
|
||||||
|
@ -59,14 +59,14 @@ func TestUint64OptSetAndValue(t *testing.T) {
|
||||||
|
|
||||||
func TestMountOptString(t *testing.T) {
|
func TestMountOptString(t *testing.T) {
|
||||||
mount := MountOpt{
|
mount := MountOpt{
|
||||||
values: []swarm.Mount{
|
values: []mounttypes.Mount{
|
||||||
{
|
{
|
||||||
Type: swarm.MountTypeBind,
|
Type: mounttypes.TypeBind,
|
||||||
Source: "/home/path",
|
Source: "/home/path",
|
||||||
Target: "/target",
|
Target: "/target",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: swarm.MountTypeVolume,
|
Type: mounttypes.TypeVolume,
|
||||||
Source: "foo",
|
Source: "foo",
|
||||||
Target: "/target/foo",
|
Target: "/target/foo",
|
||||||
},
|
},
|
||||||
|
@ -90,8 +90,8 @@ func TestMountOptSetNoError(t *testing.T) {
|
||||||
|
|
||||||
mounts := mount.Value()
|
mounts := mount.Value()
|
||||||
assert.Equal(t, len(mounts), 1)
|
assert.Equal(t, len(mounts), 1)
|
||||||
assert.Equal(t, mounts[0], swarm.Mount{
|
assert.Equal(t, mounts[0], mounttypes.Mount{
|
||||||
Type: swarm.MountTypeBind,
|
Type: mounttypes.TypeBind,
|
||||||
Source: "/source",
|
Source: "/source",
|
||||||
Target: "/target",
|
Target: "/target",
|
||||||
})
|
})
|
||||||
|
@ -103,7 +103,7 @@ func TestMountOptSetNoError(t *testing.T) {
|
||||||
func TestMountOptDefaultType(t *testing.T) {
|
func TestMountOptDefaultType(t *testing.T) {
|
||||||
var mount MountOpt
|
var mount MountOpt
|
||||||
assert.NilError(t, mount.Set("target=/target,source=/foo"))
|
assert.NilError(t, mount.Set("target=/target,source=/foo"))
|
||||||
assert.Equal(t, mount.values[0].Type, swarm.MountTypeVolume)
|
assert.Equal(t, mount.values[0].Type, mounttypes.TypeVolume)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMountOptSetErrorNoTarget(t *testing.T) {
|
func TestMountOptSetErrorNoTarget(t *testing.T) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
"github.com/docker/engine-api/types/swarm"
|
"github.com/docker/engine-api/types/swarm"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
shlex "github.com/flynn-archive/go-shlex"
|
shlex "github.com/flynn-archive/go-shlex"
|
||||||
|
@ -353,14 +354,14 @@ func removeItems(
|
||||||
return newSeq
|
return newSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateMounts(flags *pflag.FlagSet, mounts *[]swarm.Mount) {
|
func updateMounts(flags *pflag.FlagSet, mounts *[]mounttypes.Mount) {
|
||||||
if flags.Changed(flagMountAdd) {
|
if flags.Changed(flagMountAdd) {
|
||||||
values := flags.Lookup(flagMountAdd).Value.(*MountOpt).Value()
|
values := flags.Lookup(flagMountAdd).Value.(*MountOpt).Value()
|
||||||
*mounts = append(*mounts, values...)
|
*mounts = append(*mounts, values...)
|
||||||
}
|
}
|
||||||
toRemove := buildToRemoveSet(flags, flagMountRemove)
|
toRemove := buildToRemoveSet(flags, flagMountRemove)
|
||||||
|
|
||||||
newMounts := []swarm.Mount{}
|
newMounts := []mounttypes.Mount{}
|
||||||
for _, mount := range *mounts {
|
for _, mount := range *mounts {
|
||||||
if _, exists := toRemove[mount.Target]; !exists {
|
if _, exists := toRemove[mount.Target]; !exists {
|
||||||
newMounts = append(newMounts, mount)
|
newMounts = append(newMounts, mount)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/testutil/assert"
|
"github.com/docker/docker/pkg/testutil/assert"
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
"github.com/docker/engine-api/types/swarm"
|
"github.com/docker/engine-api/types/swarm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -104,9 +105,9 @@ func TestUpdateMounts(t *testing.T) {
|
||||||
flags.Set("mount-add", "type=volume,target=/toadd")
|
flags.Set("mount-add", "type=volume,target=/toadd")
|
||||||
flags.Set("mount-rm", "/toremove")
|
flags.Set("mount-rm", "/toremove")
|
||||||
|
|
||||||
mounts := []swarm.Mount{
|
mounts := []mounttypes.Mount{
|
||||||
{Target: "/toremove", Type: swarm.MountTypeBind},
|
{Target: "/toremove", Type: mounttypes.TypeBind},
|
||||||
{Target: "/tokeep", Type: swarm.MountTypeBind},
|
{Target: "/tokeep", Type: mounttypes.TypeBind},
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMounts(flags, &mounts)
|
updateMounts(flags, &mounts)
|
||||||
|
|
|
@ -54,7 +54,7 @@ func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error {
|
||||||
}
|
}
|
||||||
case "image":
|
case "image":
|
||||||
getRefFunc = func(ref string) (interface{}, []byte, error) {
|
getRefFunc = func(ref string) (interface{}, []byte, error) {
|
||||||
return client.ImageInspectWithRaw(ctx, ref, opts.size)
|
return client.ImageInspectWithRaw(ctx, ref)
|
||||||
}
|
}
|
||||||
case "task":
|
case "task":
|
||||||
if opts.size {
|
if opts.size {
|
||||||
|
@ -81,7 +81,7 @@ func inspectAll(ctx context.Context, dockerCli *client.DockerCli, getSize bool)
|
||||||
return c, rawContainer, err
|
return c, rawContainer, err
|
||||||
}
|
}
|
||||||
// Search for image with that id if a container doesn't exist.
|
// Search for image with that id if a container doesn't exist.
|
||||||
i, rawImage, err := client.ImageInspectWithRaw(ctx, ref, getSize)
|
i, rawImage, err := client.ImageInspectWithRaw(ctx, ref)
|
||||||
if err == nil || !apiclient.IsErrNotFound(err) {
|
if err == nil || !apiclient.IsErrNotFound(err) {
|
||||||
return i, rawImage, err
|
return i, rawImage, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ func runRemove(dockerCli *client.DockerCli, volumes []string) error {
|
||||||
status := 0
|
status := 0
|
||||||
|
|
||||||
for _, name := range volumes {
|
for _, name := range volumes {
|
||||||
if err := client.VolumeRemove(ctx, name); err != nil {
|
if err := client.VolumeRemove(ctx, name, false); err != nil {
|
||||||
fmt.Fprintf(dockerCli.Err(), "%s\n", err)
|
fmt.Fprintf(dockerCli.Err(), "%s\n", err)
|
||||||
status = 1
|
status = 1
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/docker/engine-api/types/events"
|
"github.com/docker/engine-api/types/events"
|
||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
timetypes "github.com/docker/engine-api/types/time"
|
timetypes "github.com/docker/engine-api/types/time"
|
||||||
|
"github.com/docker/engine-api/types/versions"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,6 +38,14 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
|
||||||
info.Swarm = s.clusterProvider.Info()
|
info.Swarm = s.clusterProvider.Info()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if versions.LessThan("1.25", httputils.VersionFromContext(ctx)) {
|
||||||
|
// TODO: handle this conversion in engine-api
|
||||||
|
type oldInfo struct {
|
||||||
|
*types.Info
|
||||||
|
ExecutionDriver string
|
||||||
|
}
|
||||||
|
return httputils.WriteJSON(w, http.StatusOK, &oldInfo{Info: info, ExecutionDriver: "<not supported>"})
|
||||||
|
}
|
||||||
return httputils.WriteJSON(w, http.StatusOK, info)
|
return httputils.WriteJSON(w, http.StatusOK, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ func (container *Container) NetworkMounts() []Mount {
|
||||||
Source: container.ResolvConfPath,
|
Source: container.ResolvConfPath,
|
||||||
Destination: "/etc/resolv.conf",
|
Destination: "/etc/resolv.conf",
|
||||||
Writable: writable,
|
Writable: writable,
|
||||||
Propagation: volume.DefaultPropagationMode,
|
Propagation: string(volume.DefaultPropagationMode),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ func (container *Container) NetworkMounts() []Mount {
|
||||||
Source: container.HostnamePath,
|
Source: container.HostnamePath,
|
||||||
Destination: "/etc/hostname",
|
Destination: "/etc/hostname",
|
||||||
Writable: writable,
|
Writable: writable,
|
||||||
Propagation: volume.DefaultPropagationMode,
|
Propagation: string(volume.DefaultPropagationMode),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ func (container *Container) NetworkMounts() []Mount {
|
||||||
Source: container.HostsPath,
|
Source: container.HostsPath,
|
||||||
Destination: "/etc/hosts",
|
Destination: "/etc/hosts",
|
||||||
Writable: writable,
|
Writable: writable,
|
||||||
Propagation: volume.DefaultPropagationMode,
|
Propagation: string(volume.DefaultPropagationMode),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ func (container *Container) IpcMounts() []Mount {
|
||||||
Source: container.ShmPath,
|
Source: container.ShmPath,
|
||||||
Destination: "/dev/shm",
|
Destination: "/dev/shm",
|
||||||
Writable: true,
|
Writable: true,
|
||||||
Propagation: volume.DefaultPropagationMode,
|
Propagation: string(volume.DefaultPropagationMode),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
types "github.com/docker/engine-api/types/swarm"
|
types "github.com/docker/engine-api/types/swarm"
|
||||||
swarmapi "github.com/docker/swarmkit/api"
|
swarmapi "github.com/docker/swarmkit/api"
|
||||||
"github.com/docker/swarmkit/protobuf/ptypes"
|
"github.com/docker/swarmkit/protobuf/ptypes"
|
||||||
|
@ -22,26 +23,26 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) types.ContainerSpec {
|
||||||
|
|
||||||
// Mounts
|
// Mounts
|
||||||
for _, m := range c.Mounts {
|
for _, m := range c.Mounts {
|
||||||
mount := types.Mount{
|
mount := mounttypes.Mount{
|
||||||
Target: m.Target,
|
Target: m.Target,
|
||||||
Source: m.Source,
|
Source: m.Source,
|
||||||
Type: types.MountType(strings.ToLower(swarmapi.Mount_MountType_name[int32(m.Type)])),
|
Type: mounttypes.Type(strings.ToLower(swarmapi.Mount_MountType_name[int32(m.Type)])),
|
||||||
ReadOnly: m.ReadOnly,
|
ReadOnly: m.ReadOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.BindOptions != nil {
|
if m.BindOptions != nil {
|
||||||
mount.BindOptions = &types.BindOptions{
|
mount.BindOptions = &mounttypes.BindOptions{
|
||||||
Propagation: types.MountPropagation(strings.ToLower(swarmapi.Mount_BindOptions_MountPropagation_name[int32(m.BindOptions.Propagation)])),
|
Propagation: mounttypes.Propagation(strings.ToLower(swarmapi.Mount_BindOptions_MountPropagation_name[int32(m.BindOptions.Propagation)])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.VolumeOptions != nil {
|
if m.VolumeOptions != nil {
|
||||||
mount.VolumeOptions = &types.VolumeOptions{
|
mount.VolumeOptions = &mounttypes.VolumeOptions{
|
||||||
NoCopy: m.VolumeOptions.NoCopy,
|
NoCopy: m.VolumeOptions.NoCopy,
|
||||||
Labels: m.VolumeOptions.Labels,
|
Labels: m.VolumeOptions.Labels,
|
||||||
}
|
}
|
||||||
if m.VolumeOptions.DriverConfig != nil {
|
if m.VolumeOptions.DriverConfig != nil {
|
||||||
mount.VolumeOptions.DriverConfig = &types.Driver{
|
mount.VolumeOptions.DriverConfig = &mounttypes.Driver{
|
||||||
Name: m.VolumeOptions.DriverConfig.Name,
|
Name: m.VolumeOptions.DriverConfig.Name,
|
||||||
Options: m.VolumeOptions.DriverConfig.Options,
|
Options: m.VolumeOptions.DriverConfig.Options,
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,7 +481,7 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c
|
||||||
|
|
||||||
if m.Source == "tmpfs" {
|
if m.Source == "tmpfs" {
|
||||||
data := c.HostConfig.Tmpfs[m.Destination]
|
data := c.HostConfig.Tmpfs[m.Destination]
|
||||||
options := []string{"noexec", "nosuid", "nodev", volume.DefaultPropagationMode}
|
options := []string{"noexec", "nosuid", "nodev", string(volume.DefaultPropagationMode)}
|
||||||
if data != "" {
|
if data != "" {
|
||||||
options = append(options, strings.Split(data, ",")...)
|
options = append(options, strings.Split(data, ",")...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
|
||||||
Source: path,
|
Source: path,
|
||||||
Destination: m.Destination,
|
Destination: m.Destination,
|
||||||
Writable: m.RW,
|
Writable: m.RW,
|
||||||
Propagation: m.Propagation,
|
Propagation: string(m.Propagation),
|
||||||
}
|
}
|
||||||
if m.Volume != nil {
|
if m.Volume != nil {
|
||||||
attributes := map[string]string{
|
attributes := map[string]string{
|
||||||
|
@ -45,7 +45,7 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
|
||||||
"container": c.ID,
|
"container": c.ID,
|
||||||
"destination": m.Destination,
|
"destination": m.Destination,
|
||||||
"read/write": strconv.FormatBool(m.RW),
|
"read/write": strconv.FormatBool(m.RW),
|
||||||
"propagation": m.Propagation,
|
"propagation": string(m.Propagation),
|
||||||
}
|
}
|
||||||
daemon.LogVolumeEvent(m.Volume.Name(), "mount", attributes)
|
daemon.LogVolumeEvent(m.Volume.Name(), "mount", attributes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://gith
|
||||||
clone git github.com/docker/go-units eb879ae3e2b84e2a142af415b679ddeda47ec71c
|
clone git github.com/docker/go-units eb879ae3e2b84e2a142af415b679ddeda47ec71c
|
||||||
clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d
|
clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d
|
||||||
|
|
||||||
clone git github.com/docker/engine-api 603ec41824c63d1e6498a22271987fa1f268c0c0
|
clone git github.com/docker/engine-api ebc51d1954fc8934307dd15841b8d64f7cd505df
|
||||||
clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
|
clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
|
||||||
clone git github.com/imdario/mergo 0.2.1
|
clone git github.com/imdario/mergo 0.2.1
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
||||||
|
|
||||||
serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
|
serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if serverResp != nil && serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {
|
if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {
|
||||||
return response, imageNotFoundError{config.Image}
|
return response, imageNotFoundError{config.Image}
|
||||||
}
|
}
|
||||||
return response, err
|
return response, err
|
||||||
|
|
|
@ -74,6 +74,10 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro
|
||||||
query.Set("pull", "1")
|
query.Set("pull", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.Squash {
|
||||||
|
query.Set("squash", "1")
|
||||||
|
}
|
||||||
|
|
||||||
if !container.Isolation.IsDefault(options.Isolation) {
|
if !container.Isolation.IsDefault(options.Isolation) {
|
||||||
query.Set("isolation", string(options.Isolation))
|
query.Set("isolation", string(options.Isolation))
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti
|
||||||
return resp.body, nil
|
return resp.body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (*serverResponse, error) {
|
func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
||||||
return cli.post(ctx, "/images/create", query, nil, headers)
|
return cli.post(ctx, "/images/create", query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,14 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImageInspectWithRaw returns the image information and its raw representation.
|
// ImageInspectWithRaw returns the image information and its raw representation.
|
||||||
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string, getSize bool) (types.ImageInspect, []byte, error) {
|
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
|
||||||
query := url.Values{}
|
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil)
|
||||||
if getSize {
|
|
||||||
query.Set("size", "1")
|
|
||||||
}
|
|
||||||
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if serverResp.statusCode == http.StatusNotFound {
|
if serverResp.statusCode == http.StatusNotFound {
|
||||||
return types.ImageInspect{}, nil, imageNotFoundError{imageID}
|
return types.ImageInspect{}, nil, imageNotFoundError{imageID}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (cli *Client) ImagePush(ctx context.Context, ref string, options types.Imag
|
||||||
return resp.body, nil
|
return resp.body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (*serverResponse, error) {
|
func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
||||||
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers)
|
return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I
|
||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (*serverResponse, error) {
|
func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
||||||
return cli.get(ctx, "/images/search", query, headers)
|
return cli.get(ctx, "/images/search", query, headers)
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ type ImageAPIClient interface {
|
||||||
ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
|
ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
|
||||||
ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error)
|
ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error)
|
||||||
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error)
|
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error)
|
||||||
ImageInspectWithRaw(ctx context.Context, image string, getSize bool) (types.ImageInspect, []byte, error)
|
ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error)
|
||||||
ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error)
|
ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error)
|
||||||
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error)
|
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error)
|
||||||
ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error)
|
ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error)
|
||||||
|
@ -131,5 +131,5 @@ type VolumeAPIClient interface {
|
||||||
VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error)
|
VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error)
|
||||||
VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, error)
|
VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, error)
|
||||||
VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error)
|
VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error)
|
||||||
VolumeRemove(ctx context.Context, volumeID string) error
|
VolumeRemove(ctx context.Context, volumeID string, force bool) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error) {
|
func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error) {
|
||||||
resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil)
|
resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil)
|
||||||
|
|
||||||
if resp != nil && resp.statusCode == http.StatusUnauthorized {
|
if resp.statusCode == http.StatusUnauthorized {
|
||||||
return types.AuthResponse{}, unauthorizedError{err}
|
return types.AuthResponse{}, unauthorizedError{err}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
|
||||||
return cli.PluginEnable(ctx, name)
|
return cli.PluginEnable(ctx, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, registryAuth string) (*serverResponse, error) {
|
func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
||||||
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
||||||
return cli.post(ctx, "/plugins/pull", query, nil, headers)
|
return cli.post(ctx, "/plugins/pull", query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -24,47 +25,47 @@ type serverResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// head sends an http request to the docker API using the method HEAD.
|
// head sends an http request to the docker API using the method HEAD.
|
||||||
func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, "HEAD", path, query, nil, headers)
|
return cli.sendRequest(ctx, "HEAD", path, query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getWithContext sends an http request to the docker API using the method GET with a specific go context.
|
// getWithContext sends an http request to the docker API using the method GET with a specific go context.
|
||||||
func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, "GET", path, query, nil, headers)
|
return cli.sendRequest(ctx, "GET", path, query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// postWithContext sends an http request to the docker API using the method POST with a specific go context.
|
// postWithContext sends an http request to the docker API using the method POST with a specific go context.
|
||||||
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, "POST", path, query, obj, headers)
|
return cli.sendRequest(ctx, "POST", path, query, obj, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendClientRequest(ctx, "POST", path, query, body, headers)
|
return cli.sendClientRequest(ctx, "POST", path, query, body, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// put sends an http request to the docker API using the method PUT.
|
// put sends an http request to the docker API using the method PUT.
|
||||||
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, "PUT", path, query, obj, headers)
|
return cli.sendRequest(ctx, "PUT", path, query, obj, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// put sends an http request to the docker API using the method PUT.
|
// put sends an http request to the docker API using the method PUT.
|
||||||
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendClientRequest(ctx, "PUT", path, query, body, headers)
|
return cli.sendClientRequest(ctx, "PUT", path, query, body, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete sends an http request to the docker API using the method DELETE.
|
// delete sends an http request to the docker API using the method DELETE.
|
||||||
func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
|
||||||
return cli.sendRequest(ctx, "DELETE", path, query, nil, headers)
|
return cli.sendRequest(ctx, "DELETE", path, query, nil, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, obj interface{}, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
|
||||||
var body io.Reader
|
var body io.Reader
|
||||||
|
|
||||||
if obj != nil {
|
if obj != nil {
|
||||||
var err error
|
var err error
|
||||||
body, err = encodeData(obj)
|
body, err = encodeData(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return serverResponse{}, err
|
||||||
}
|
}
|
||||||
if headers == nil {
|
if headers == nil {
|
||||||
headers = make(map[string][]string)
|
headers = make(map[string][]string)
|
||||||
|
@ -75,8 +76,8 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u
|
||||||
return cli.sendClientRequest(ctx, method, path, query, body, headers)
|
return cli.sendClientRequest(ctx, method, path, query, body, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) sendClientRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
|
func (cli *Client) sendClientRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||||
serverResp := &serverResponse{
|
serverResp := serverResponse{
|
||||||
body: nil,
|
body: nil,
|
||||||
statusCode: -1,
|
statusCode: -1,
|
||||||
}
|
}
|
||||||
|
@ -105,10 +106,6 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q
|
||||||
|
|
||||||
resp, err := cancellable.Do(ctx, cli.transport, req)
|
resp, err := cancellable.Do(ctx, cli.transport, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if isTimeout(err) || strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") {
|
|
||||||
return serverResp, ErrConnectionFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
if !cli.transport.Secure() && strings.Contains(err.Error(), "malformed HTTP response") {
|
if !cli.transport.Secure() && strings.Contains(err.Error(), "malformed HTTP response") {
|
||||||
return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)
|
return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)
|
||||||
}
|
}
|
||||||
|
@ -117,6 +114,23 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q
|
||||||
return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err)
|
return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't decorate context sentinel errors; users may be comparing to
|
||||||
|
// them directly.
|
||||||
|
switch err {
|
||||||
|
case context.Canceled, context.DeadlineExceeded:
|
||||||
|
return serverResp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := err.(net.Error); ok {
|
||||||
|
if err.Timeout() {
|
||||||
|
return serverResp, ErrConnectionFailed
|
||||||
|
}
|
||||||
|
if !err.Temporary() {
|
||||||
|
if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") {
|
||||||
|
return serverResp, ErrConnectionFailed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return serverResp, fmt.Errorf("An error occurred trying to connect: %v", err)
|
return serverResp, fmt.Errorf("An error occurred trying to connect: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,23 +199,10 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureReaderClosed(response *serverResponse) {
|
func ensureReaderClosed(response serverResponse) {
|
||||||
if response != nil && response.body != nil {
|
if body := response.body; body != nil {
|
||||||
// Drain up to 512 bytes and close the body to let the Transport reuse the connection
|
// Drain up to 512 bytes and close the body to let the Transport reuse the connection
|
||||||
io.CopyN(ioutil.Discard, response.body, 512)
|
io.CopyN(ioutil.Discard, body, 512)
|
||||||
response.body.Close()
|
response.body.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isTimeout(err error) bool {
|
|
||||||
type timeout interface {
|
|
||||||
Timeout() bool
|
|
||||||
}
|
|
||||||
e := err
|
|
||||||
switch urlErr := err.(type) {
|
|
||||||
case *url.Error:
|
|
||||||
e = urlErr.Err
|
|
||||||
}
|
|
||||||
t, ok := e.(timeout)
|
|
||||||
return ok && t.Timeout()
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ package cancellable
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/docker/engine-api/client/transport"
|
"github.com/docker/engine-api/client/transport"
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.
|
||||||
// The response's Body is closed.
|
// The response's Body is closed.
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
resp.Body = ¬ifyingReader{resp.Body, c}
|
resp.Body = ¬ifyingReader{ReadCloser: resp.Body, notify: c}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
@ -92,22 +93,23 @@ func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.
|
||||||
type notifyingReader struct {
|
type notifyingReader struct {
|
||||||
io.ReadCloser
|
io.ReadCloser
|
||||||
notify chan<- struct{}
|
notify chan<- struct{}
|
||||||
|
notifyOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *notifyingReader) Read(p []byte) (int, error) {
|
func (r *notifyingReader) Read(p []byte) (int, error) {
|
||||||
n, err := r.ReadCloser.Read(p)
|
n, err := r.ReadCloser.Read(p)
|
||||||
if err != nil && r.notify != nil {
|
if err != nil {
|
||||||
|
r.notifyOnce.Do(func() {
|
||||||
close(r.notify)
|
close(r.notify)
|
||||||
r.notify = nil
|
})
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *notifyingReader) Close() error {
|
func (r *notifyingReader) Close() error {
|
||||||
err := r.ReadCloser.Close()
|
err := r.ReadCloser.Close()
|
||||||
if r.notify != nil {
|
r.notifyOnce.Do(func() {
|
||||||
close(r.notify)
|
close(r.notify)
|
||||||
r.notify = nil
|
})
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import "golang.org/x/net/context"
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
// VolumeRemove removes a volume from the docker host.
|
// VolumeRemove removes a volume from the docker host.
|
||||||
func (cli *Client) VolumeRemove(ctx context.Context, volumeID string) error {
|
func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool) error {
|
||||||
resp, err := cli.delete(ctx, "/volumes/"+volumeID, nil, nil)
|
query := url.Values{}
|
||||||
|
if force {
|
||||||
|
query.Set("force", "1")
|
||||||
|
}
|
||||||
|
resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil)
|
||||||
ensureReaderClosed(resp)
|
ensureReaderClosed(resp)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,10 @@ type ImageBuildOptions struct {
|
||||||
AuthConfigs map[string]AuthConfig
|
AuthConfigs map[string]AuthConfig
|
||||||
Context io.Reader
|
Context io.Reader
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
|
// squash the resulting image's layers to the parent
|
||||||
|
// preserves the original image and creates a new one from the parent with all
|
||||||
|
// the changes applied to a single layer
|
||||||
|
Squash bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageBuildResponse holds information
|
// ImageBuildResponse holds information
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/engine-api/types/blkiodev"
|
"github.com/docker/engine-api/types/blkiodev"
|
||||||
|
"github.com/docker/engine-api/types/mount"
|
||||||
"github.com/docker/engine-api/types/strslice"
|
"github.com/docker/engine-api/types/strslice"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
|
@ -317,4 +318,7 @@ type HostConfig struct {
|
||||||
|
|
||||||
// Contains container's resources (cgroups, ulimits)
|
// Contains container's resources (cgroups, ulimits)
|
||||||
Resources
|
Resources
|
||||||
|
|
||||||
|
// Mounts specs used by the container
|
||||||
|
Mounts []mount.Mount `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
58
vendor/src/github.com/docker/engine-api/types/mount/mount.go
vendored
Normal file
58
vendor/src/github.com/docker/engine-api/types/mount/mount.go
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package mount
|
||||||
|
|
||||||
|
// Type represents the type of a mount.
|
||||||
|
type Type string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TypeBind BIND
|
||||||
|
TypeBind Type = "bind"
|
||||||
|
// TypeVolume VOLUME
|
||||||
|
TypeVolume Type = "volume"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mount represents a mount (volume).
|
||||||
|
type Mount struct {
|
||||||
|
Type Type `json:",omitempty"`
|
||||||
|
Source string `json:",omitempty"`
|
||||||
|
Target string `json:",omitempty"`
|
||||||
|
ReadOnly bool `json:",omitempty"`
|
||||||
|
|
||||||
|
BindOptions *BindOptions `json:",omitempty"`
|
||||||
|
VolumeOptions *VolumeOptions `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Propagation represents the propagation of a mount.
|
||||||
|
type Propagation string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PropagationRPrivate RPRIVATE
|
||||||
|
PropagationRPrivate Propagation = "rprivate"
|
||||||
|
// PropagationPrivate PRIVATE
|
||||||
|
PropagationPrivate Propagation = "private"
|
||||||
|
// PropagationRShared RSHARED
|
||||||
|
PropagationRShared Propagation = "rshared"
|
||||||
|
// PropagationShared SHARED
|
||||||
|
PropagationShared Propagation = "shared"
|
||||||
|
// PropagationRSlave RSLAVE
|
||||||
|
PropagationRSlave Propagation = "rslave"
|
||||||
|
// PropagationSlave SLAVE
|
||||||
|
PropagationSlave Propagation = "slave"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BindOptions defines options specific to mounts of type "bind".
|
||||||
|
type BindOptions struct {
|
||||||
|
Propagation Propagation `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VolumeOptions represents the options for a mount of type volume.
|
||||||
|
type VolumeOptions struct {
|
||||||
|
NoCopy bool `json:",omitempty"`
|
||||||
|
Labels map[string]string `json:",omitempty"`
|
||||||
|
DriverConfig *Driver `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver represents a volume driver.
|
||||||
|
type Driver struct {
|
||||||
|
Name string `json:",omitempty"`
|
||||||
|
Options map[string]string `json:",omitempty"`
|
||||||
|
}
|
|
@ -16,6 +16,11 @@ type ServiceConfig struct {
|
||||||
// unmarshalled to JSON
|
// unmarshalled to JSON
|
||||||
type NetIPNet net.IPNet
|
type NetIPNet net.IPNet
|
||||||
|
|
||||||
|
// String returns the CIDR notation of ipnet
|
||||||
|
func (ipnet *NetIPNet) String() string {
|
||||||
|
return (*net.IPNet)(ipnet).String()
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON returns the JSON representation of the IPNet
|
// MarshalJSON returns the JSON representation of the IPNet
|
||||||
func (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {
|
func (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal((*net.IPNet)(ipnet).String())
|
return json.Marshal((*net.IPNet)(ipnet).String())
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package swarm
|
package swarm
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/engine-api/types/mount"
|
||||||
|
)
|
||||||
|
|
||||||
// ContainerSpec represents the spec of a container.
|
// ContainerSpec represents the spec of a container.
|
||||||
type ContainerSpec struct {
|
type ContainerSpec struct {
|
||||||
|
@ -11,57 +15,8 @@ type ContainerSpec struct {
|
||||||
Env []string `json:",omitempty"`
|
Env []string `json:",omitempty"`
|
||||||
Dir string `json:",omitempty"`
|
Dir string `json:",omitempty"`
|
||||||
User string `json:",omitempty"`
|
User string `json:",omitempty"`
|
||||||
Mounts []Mount `json:",omitempty"`
|
Groups []string `json:",omitempty"`
|
||||||
|
TTY bool `json:",omitempty"`
|
||||||
|
Mounts []mount.Mount `json:",omitempty"`
|
||||||
StopGracePeriod *time.Duration `json:",omitempty"`
|
StopGracePeriod *time.Duration `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MountType represents the type of a mount.
|
|
||||||
type MountType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// MountTypeBind BIND
|
|
||||||
MountTypeBind MountType = "bind"
|
|
||||||
// MountTypeVolume VOLUME
|
|
||||||
MountTypeVolume MountType = "volume"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Mount represents a mount (volume).
|
|
||||||
type Mount struct {
|
|
||||||
Type MountType `json:",omitempty"`
|
|
||||||
Source string `json:",omitempty"`
|
|
||||||
Target string `json:",omitempty"`
|
|
||||||
ReadOnly bool `json:",omitempty"`
|
|
||||||
|
|
||||||
BindOptions *BindOptions `json:",omitempty"`
|
|
||||||
VolumeOptions *VolumeOptions `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// MountPropagation represents the propagation of a mount.
|
|
||||||
type MountPropagation string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// MountPropagationRPrivate RPRIVATE
|
|
||||||
MountPropagationRPrivate MountPropagation = "rprivate"
|
|
||||||
// MountPropagationPrivate PRIVATE
|
|
||||||
MountPropagationPrivate MountPropagation = "private"
|
|
||||||
// MountPropagationRShared RSHARED
|
|
||||||
MountPropagationRShared MountPropagation = "rshared"
|
|
||||||
// MountPropagationShared SHARED
|
|
||||||
MountPropagationShared MountPropagation = "shared"
|
|
||||||
// MountPropagationRSlave RSLAVE
|
|
||||||
MountPropagationRSlave MountPropagation = "rslave"
|
|
||||||
// MountPropagationSlave SLAVE
|
|
||||||
MountPropagationSlave MountPropagation = "slave"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BindOptions defines options specific to mounts of type "bind".
|
|
||||||
type BindOptions struct {
|
|
||||||
Propagation MountPropagation `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// VolumeOptions represents the options for a mount of type volume.
|
|
||||||
type VolumeOptions struct {
|
|
||||||
NoCopy bool `json:",omitempty"`
|
|
||||||
Labels map[string]string `json:",omitempty"`
|
|
||||||
DriverConfig *Driver `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ type IPAMConfig struct {
|
||||||
Gateway string `json:",omitempty"`
|
Gateway string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Driver represents a driver (network/volume).
|
// Driver represents a network driver.
|
||||||
type Driver struct {
|
type Driver struct {
|
||||||
Name string `json:",omitempty"`
|
Name string `json:",omitempty"`
|
||||||
Options map[string]string `json:",omitempty"`
|
Options map[string]string `json:",omitempty"`
|
||||||
|
|
|
@ -2,7 +2,7 @@ package swarm
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// ClusterInfo represents info about a the cluster for outputing in "info"
|
// ClusterInfo represents info about the cluster for outputing in "info"
|
||||||
// it contains the same information as "Swarm", but without the JoinTokens
|
// it contains the same information as "Swarm", but without the JoinTokens
|
||||||
type ClusterInfo struct {
|
type ClusterInfo struct {
|
||||||
ID string
|
ID string
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/engine-api/types/container"
|
"github.com/docker/engine-api/types/container"
|
||||||
|
"github.com/docker/engine-api/types/mount"
|
||||||
"github.com/docker/engine-api/types/network"
|
"github.com/docker/engine-api/types/network"
|
||||||
"github.com/docker/engine-api/types/registry"
|
"github.com/docker/engine-api/types/registry"
|
||||||
"github.com/docker/engine-api/types/swarm"
|
"github.com/docker/engine-api/types/swarm"
|
||||||
|
@ -230,7 +231,6 @@ type Info struct {
|
||||||
OomKillDisable bool
|
OomKillDisable bool
|
||||||
NGoroutines int
|
NGoroutines int
|
||||||
SystemTime string
|
SystemTime string
|
||||||
ExecutionDriver string
|
|
||||||
LoggingDriver string
|
LoggingDriver string
|
||||||
CgroupDriver string
|
CgroupDriver string
|
||||||
NEventsListener int
|
NEventsListener int
|
||||||
|
@ -409,14 +409,16 @@ type DefaultNetworkSettings struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MountPoint represents a mount point configuration inside the container.
|
// MountPoint represents a mount point configuration inside the container.
|
||||||
|
// This is used for reporting the mountpoints in use by a container.
|
||||||
type MountPoint struct {
|
type MountPoint struct {
|
||||||
|
Type mount.Type `json:",omitempty"`
|
||||||
Name string `json:",omitempty"`
|
Name string `json:",omitempty"`
|
||||||
Source string
|
Source string
|
||||||
Destination string
|
Destination string
|
||||||
Driver string `json:",omitempty"`
|
Driver string `json:",omitempty"`
|
||||||
Mode string
|
Mode string
|
||||||
RW bool
|
RW bool
|
||||||
Propagation string
|
Propagation mount.Propagation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume represents the configuration of a volume for the remote API
|
// Volume represents the configuration of a volume for the remote API
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
"github.com/opencontainers/runc/libcontainer/label"
|
"github.com/opencontainers/runc/libcontainer/label"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ type MountPoint struct {
|
||||||
Mode string `json:"Relabel"` // Originally field was `Relabel`"
|
Mode string `json:"Relabel"` // Originally field was `Relabel`"
|
||||||
|
|
||||||
// Note Propagation is not used on Windows
|
// Note Propagation is not used on Windows
|
||||||
Propagation string // Mount propagation string
|
Propagation mounttypes.Propagation // Mount propagation string
|
||||||
Named bool // specifies if the mountpoint was specified by name
|
Named bool // specifies if the mountpoint was specified by name
|
||||||
|
|
||||||
// Specifies if data should be copied from the container before the first mount
|
// Specifies if data should be copied from the container before the first mount
|
||||||
|
|
|
@ -4,28 +4,31 @@ package volume
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultPropagationMode defines what propagation mode should be used by
|
// DefaultPropagationMode defines what propagation mode should be used by
|
||||||
// default if user has not specified one explicitly.
|
// default if user has not specified one explicitly.
|
||||||
const DefaultPropagationMode string = "rprivate"
|
const DefaultPropagationMode mounttypes.Propagation = "rprivate"
|
||||||
|
|
||||||
// propagation modes
|
// propagation modes
|
||||||
var propagationModes = map[string]bool{
|
var propagationModes = map[mounttypes.Propagation]bool{
|
||||||
"private": true,
|
mounttypes.PropagationPrivate: true,
|
||||||
"rprivate": true,
|
mounttypes.PropagationRPrivate: true,
|
||||||
"slave": true,
|
mounttypes.PropagationSlave: true,
|
||||||
"rslave": true,
|
mounttypes.PropagationRSlave: true,
|
||||||
"shared": true,
|
mounttypes.PropagationShared: true,
|
||||||
"rshared": true,
|
mounttypes.PropagationRShared: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPropagation extracts and returns the mount propagation mode. If there
|
// GetPropagation extracts and returns the mount propagation mode. If there
|
||||||
// are no specifications, then by default it is "private".
|
// are no specifications, then by default it is "private".
|
||||||
func GetPropagation(mode string) string {
|
func GetPropagation(mode string) mounttypes.Propagation {
|
||||||
for _, o := range strings.Split(mode, ",") {
|
for _, o := range strings.Split(mode, ",") {
|
||||||
if propagationModes[o] {
|
prop := mounttypes.Propagation(o)
|
||||||
return o
|
if propagationModes[prop] {
|
||||||
|
return prop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DefaultPropagationMode
|
return DefaultPropagationMode
|
||||||
|
@ -36,7 +39,7 @@ func GetPropagation(mode string) string {
|
||||||
// present, false otherwise.
|
// present, false otherwise.
|
||||||
func HasPropagation(mode string) bool {
|
func HasPropagation(mode string) bool {
|
||||||
for _, o := range strings.Split(mode, ",") {
|
for _, o := range strings.Split(mode, ",") {
|
||||||
if propagationModes[o] {
|
if propagationModes[mounttypes.Propagation(o)] {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
|
|
||||||
package volume
|
package volume
|
||||||
|
|
||||||
|
import mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
|
|
||||||
// DefaultPropagationMode is used only in linux. In other cases it returns
|
// DefaultPropagationMode is used only in linux. In other cases it returns
|
||||||
// empty string.
|
// empty string.
|
||||||
const DefaultPropagationMode string = ""
|
const DefaultPropagationMode mounttypes.Propagation = ""
|
||||||
|
|
||||||
// propagation modes not supported on this platform.
|
// propagation modes not supported on this platform.
|
||||||
var propagationModes = map[string]bool{}
|
var propagationModes = map[string]bool{}
|
||||||
|
|
||||||
// GetPropagation is not supported. Return empty string.
|
// GetPropagation is not supported. Return empty string.
|
||||||
func GetPropagation(mode string) string {
|
func GetPropagation(mode string) mounttypes.Propagation {
|
||||||
return DefaultPropagationMode
|
return DefaultPropagationMode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
mounttypes "github.com/docker/engine-api/types/mount"
|
||||||
)
|
)
|
||||||
|
|
||||||
// read-write modes
|
// read-write modes
|
||||||
|
@ -152,7 +154,7 @@ func ValidMountMode(mode string) bool {
|
||||||
rwModeCount++
|
rwModeCount++
|
||||||
case labelModes[o]:
|
case labelModes[o]:
|
||||||
labelModeCount++
|
labelModeCount++
|
||||||
case propagationModes[o]:
|
case propagationModes[mounttypes.Propagation(o)]:
|
||||||
propagationModeCount++
|
propagationModeCount++
|
||||||
case copyModeExists(o):
|
case copyModeExists(o):
|
||||||
copyModeCount++
|
copyModeCount++
|
||||||
|
|
Loading…
Add table
Reference in a new issue