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"
|
||||
|
||||
# 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 \
|
||||
&& cd /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
|
|
|
@ -133,7 +133,7 @@ RUN set -x \
|
|||
&& rm -rf "$GOPATH"
|
||||
|
||||
# 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 \
|
||||
&& cd /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
|
|
|
@ -138,7 +138,7 @@ RUN set -x \
|
|||
&& rm -rf "$GOPATH"
|
||||
|
||||
# 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 \
|
||||
&& cd /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
|
|
|
@ -60,7 +60,7 @@ RUN set -x \
|
|||
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
|
||||
|
||||
# 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 \
|
||||
&& cd /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT
|
||||
|
|
|
@ -151,7 +151,7 @@ RUN set -x \
|
|||
&& rm -rf "$GOPATH"
|
||||
|
||||
# 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 \
|
||||
&& cd /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
|
|
|
@ -155,7 +155,7 @@ RUN set -x \
|
|||
&& rm -rf "$GOPATH"
|
||||
|
||||
# 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 \
|
||||
&& cd /docker-py \
|
||||
&& git checkout -q $DOCKER_PY_COMMIT \
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/docker/docker/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/go-connections/nat"
|
||||
units "github.com/docker/go-units"
|
||||
|
@ -130,7 +131,7 @@ func (i *Uint64Opt) Value() *uint64 {
|
|||
|
||||
// MountOpt is a Value type for parsing mounts
|
||||
type MountOpt struct {
|
||||
values []swarm.Mount
|
||||
values []mounttypes.Mount
|
||||
}
|
||||
|
||||
// Set a new mount value
|
||||
|
@ -141,23 +142,23 @@ func (m *MountOpt) Set(value string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
mount := swarm.Mount{}
|
||||
mount := mounttypes.Mount{}
|
||||
|
||||
volumeOptions := func() *swarm.VolumeOptions {
|
||||
volumeOptions := func() *mounttypes.VolumeOptions {
|
||||
if mount.VolumeOptions == nil {
|
||||
mount.VolumeOptions = &swarm.VolumeOptions{
|
||||
mount.VolumeOptions = &mounttypes.VolumeOptions{
|
||||
Labels: make(map[string]string),
|
||||
}
|
||||
}
|
||||
if mount.VolumeOptions.DriverConfig == nil {
|
||||
mount.VolumeOptions.DriverConfig = &swarm.Driver{}
|
||||
mount.VolumeOptions.DriverConfig = &mounttypes.Driver{}
|
||||
}
|
||||
return mount.VolumeOptions
|
||||
}
|
||||
|
||||
bindOptions := func() *swarm.BindOptions {
|
||||
bindOptions := func() *mounttypes.BindOptions {
|
||||
if mount.BindOptions == nil {
|
||||
mount.BindOptions = new(swarm.BindOptions)
|
||||
mount.BindOptions = new(mounttypes.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
|
||||
for _, field := range fields {
|
||||
parts := strings.SplitN(field, "=", 2)
|
||||
|
@ -195,7 +196,7 @@ func (m *MountOpt) Set(value string) error {
|
|||
value := parts[1]
|
||||
switch key {
|
||||
case "type":
|
||||
mount.Type = swarm.MountType(strings.ToLower(value))
|
||||
mount.Type = mounttypes.Type(strings.ToLower(value))
|
||||
case "source", "src":
|
||||
mount.Source = value
|
||||
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)
|
||||
}
|
||||
case "bind-propagation":
|
||||
bindOptions().Propagation = swarm.MountPropagation(strings.ToLower(value))
|
||||
bindOptions().Propagation = mounttypes.Propagation(strings.ToLower(value))
|
||||
case "volume-nocopy":
|
||||
volumeOptions().NoCopy, err = strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
|
@ -238,11 +239,11 @@ func (m *MountOpt) Set(value string) error {
|
|||
return fmt.Errorf("source is required when specifying volume-* options")
|
||||
}
|
||||
|
||||
if mount.Type == swarm.MountTypeBind && mount.VolumeOptions != nil {
|
||||
return fmt.Errorf("cannot mix 'volume-*' options with mount type '%s'", swarm.MountTypeBind)
|
||||
if mount.Type == mounttypes.TypeBind && mount.VolumeOptions != nil {
|
||||
return fmt.Errorf("cannot mix 'volume-*' options with mount type '%s'", mounttypes.TypeBind)
|
||||
}
|
||||
if mount.Type == swarm.MountTypeVolume && mount.BindOptions != nil {
|
||||
return fmt.Errorf("cannot mix 'bind-*' options with mount type '%s'", swarm.MountTypeVolume)
|
||||
if mount.Type == mounttypes.TypeVolume && mount.BindOptions != nil {
|
||||
return fmt.Errorf("cannot mix 'bind-*' options with mount type '%s'", mounttypes.TypeVolume)
|
||||
}
|
||||
|
||||
m.values = append(m.values, mount)
|
||||
|
@ -265,7 +266,7 @@ func (m *MountOpt) String() string {
|
|||
}
|
||||
|
||||
// Value returns the mounts
|
||||
func (m *MountOpt) Value() []swarm.Mount {
|
||||
func (m *MountOpt) Value() []mounttypes.Mount {
|
||||
return m.values
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"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) {
|
||||
|
@ -59,14 +59,14 @@ func TestUint64OptSetAndValue(t *testing.T) {
|
|||
|
||||
func TestMountOptString(t *testing.T) {
|
||||
mount := MountOpt{
|
||||
values: []swarm.Mount{
|
||||
values: []mounttypes.Mount{
|
||||
{
|
||||
Type: swarm.MountTypeBind,
|
||||
Type: mounttypes.TypeBind,
|
||||
Source: "/home/path",
|
||||
Target: "/target",
|
||||
},
|
||||
{
|
||||
Type: swarm.MountTypeVolume,
|
||||
Type: mounttypes.TypeVolume,
|
||||
Source: "foo",
|
||||
Target: "/target/foo",
|
||||
},
|
||||
|
@ -90,8 +90,8 @@ func TestMountOptSetNoError(t *testing.T) {
|
|||
|
||||
mounts := mount.Value()
|
||||
assert.Equal(t, len(mounts), 1)
|
||||
assert.Equal(t, mounts[0], swarm.Mount{
|
||||
Type: swarm.MountTypeBind,
|
||||
assert.Equal(t, mounts[0], mounttypes.Mount{
|
||||
Type: mounttypes.TypeBind,
|
||||
Source: "/source",
|
||||
Target: "/target",
|
||||
})
|
||||
|
@ -103,7 +103,7 @@ func TestMountOptSetNoError(t *testing.T) {
|
|||
func TestMountOptDefaultType(t *testing.T) {
|
||||
var mount MountOpt
|
||||
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) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/docker/docker/opts"
|
||||
runconfigopts "github.com/docker/docker/runconfig/opts"
|
||||
"github.com/docker/engine-api/types"
|
||||
mounttypes "github.com/docker/engine-api/types/mount"
|
||||
"github.com/docker/engine-api/types/swarm"
|
||||
"github.com/docker/go-connections/nat"
|
||||
shlex "github.com/flynn-archive/go-shlex"
|
||||
|
@ -353,14 +354,14 @@ func removeItems(
|
|||
return newSeq
|
||||
}
|
||||
|
||||
func updateMounts(flags *pflag.FlagSet, mounts *[]swarm.Mount) {
|
||||
func updateMounts(flags *pflag.FlagSet, mounts *[]mounttypes.Mount) {
|
||||
if flags.Changed(flagMountAdd) {
|
||||
values := flags.Lookup(flagMountAdd).Value.(*MountOpt).Value()
|
||||
*mounts = append(*mounts, values...)
|
||||
}
|
||||
toRemove := buildToRemoveSet(flags, flagMountRemove)
|
||||
|
||||
newMounts := []swarm.Mount{}
|
||||
newMounts := []mounttypes.Mount{}
|
||||
for _, mount := range *mounts {
|
||||
if _, exists := toRemove[mount.Target]; !exists {
|
||||
newMounts = append(newMounts, mount)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/testutil/assert"
|
||||
mounttypes "github.com/docker/engine-api/types/mount"
|
||||
"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-rm", "/toremove")
|
||||
|
||||
mounts := []swarm.Mount{
|
||||
{Target: "/toremove", Type: swarm.MountTypeBind},
|
||||
{Target: "/tokeep", Type: swarm.MountTypeBind},
|
||||
mounts := []mounttypes.Mount{
|
||||
{Target: "/toremove", Type: mounttypes.TypeBind},
|
||||
{Target: "/tokeep", Type: mounttypes.TypeBind},
|
||||
}
|
||||
|
||||
updateMounts(flags, &mounts)
|
||||
|
|
|
@ -54,7 +54,7 @@ func runInspect(dockerCli *client.DockerCli, opts inspectOptions) error {
|
|||
}
|
||||
case "image":
|
||||
getRefFunc = func(ref string) (interface{}, []byte, error) {
|
||||
return client.ImageInspectWithRaw(ctx, ref, opts.size)
|
||||
return client.ImageInspectWithRaw(ctx, ref)
|
||||
}
|
||||
case "task":
|
||||
if opts.size {
|
||||
|
@ -81,7 +81,7 @@ func inspectAll(ctx context.Context, dockerCli *client.DockerCli, getSize bool)
|
|||
return c, rawContainer, err
|
||||
}
|
||||
// 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) {
|
||||
return i, rawImage, err
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ func runRemove(dockerCli *client.DockerCli, volumes []string) error {
|
|||
status := 0
|
||||
|
||||
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)
|
||||
status = 1
|
||||
continue
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/docker/engine-api/types/events"
|
||||
"github.com/docker/engine-api/types/filters"
|
||||
timetypes "github.com/docker/engine-api/types/time"
|
||||
"github.com/docker/engine-api/types/versions"
|
||||
"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()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
Source: container.ResolvConfPath,
|
||||
Destination: "/etc/resolv.conf",
|
||||
Writable: writable,
|
||||
Propagation: volume.DefaultPropagationMode,
|
||||
Propagation: string(volume.DefaultPropagationMode),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
Source: container.HostnamePath,
|
||||
Destination: "/etc/hostname",
|
||||
Writable: writable,
|
||||
Propagation: volume.DefaultPropagationMode,
|
||||
Propagation: string(volume.DefaultPropagationMode),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
Source: container.HostsPath,
|
||||
Destination: "/etc/hosts",
|
||||
Writable: writable,
|
||||
Propagation: volume.DefaultPropagationMode,
|
||||
Propagation: string(volume.DefaultPropagationMode),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ func (container *Container) IpcMounts() []Mount {
|
|||
Source: container.ShmPath,
|
||||
Destination: "/dev/shm",
|
||||
Writable: true,
|
||||
Propagation: volume.DefaultPropagationMode,
|
||||
Propagation: string(volume.DefaultPropagationMode),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
mounttypes "github.com/docker/engine-api/types/mount"
|
||||
types "github.com/docker/engine-api/types/swarm"
|
||||
swarmapi "github.com/docker/swarmkit/api"
|
||||
"github.com/docker/swarmkit/protobuf/ptypes"
|
||||
|
@ -22,26 +23,26 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) types.ContainerSpec {
|
|||
|
||||
// Mounts
|
||||
for _, m := range c.Mounts {
|
||||
mount := types.Mount{
|
||||
mount := mounttypes.Mount{
|
||||
Target: m.Target,
|
||||
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,
|
||||
}
|
||||
|
||||
if m.BindOptions != nil {
|
||||
mount.BindOptions = &types.BindOptions{
|
||||
Propagation: types.MountPropagation(strings.ToLower(swarmapi.Mount_BindOptions_MountPropagation_name[int32(m.BindOptions.Propagation)])),
|
||||
mount.BindOptions = &mounttypes.BindOptions{
|
||||
Propagation: mounttypes.Propagation(strings.ToLower(swarmapi.Mount_BindOptions_MountPropagation_name[int32(m.BindOptions.Propagation)])),
|
||||
}
|
||||
}
|
||||
|
||||
if m.VolumeOptions != nil {
|
||||
mount.VolumeOptions = &types.VolumeOptions{
|
||||
mount.VolumeOptions = &mounttypes.VolumeOptions{
|
||||
NoCopy: m.VolumeOptions.NoCopy,
|
||||
Labels: m.VolumeOptions.Labels,
|
||||
}
|
||||
if m.VolumeOptions.DriverConfig != nil {
|
||||
mount.VolumeOptions.DriverConfig = &types.Driver{
|
||||
mount.VolumeOptions.DriverConfig = &mounttypes.Driver{
|
||||
Name: m.VolumeOptions.DriverConfig.Name,
|
||||
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" {
|
||||
data := c.HostConfig.Tmpfs[m.Destination]
|
||||
options := []string{"noexec", "nosuid", "nodev", volume.DefaultPropagationMode}
|
||||
options := []string{"noexec", "nosuid", "nodev", string(volume.DefaultPropagationMode)}
|
||||
if data != "" {
|
||||
options = append(options, strings.Split(data, ",")...)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
|
|||
Source: path,
|
||||
Destination: m.Destination,
|
||||
Writable: m.RW,
|
||||
Propagation: m.Propagation,
|
||||
Propagation: string(m.Propagation),
|
||||
}
|
||||
if m.Volume != nil {
|
||||
attributes := map[string]string{
|
||||
|
@ -45,7 +45,7 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
|
|||
"container": c.ID,
|
||||
"destination": m.Destination,
|
||||
"read/write": strconv.FormatBool(m.RW),
|
||||
"propagation": m.Propagation,
|
||||
"propagation": string(m.Propagation),
|
||||
}
|
||||
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-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/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)
|
||||
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, err
|
||||
|
|
|
@ -74,6 +74,10 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro
|
|||
query.Set("pull", "1")
|
||||
}
|
||||
|
||||
if options.Squash {
|
||||
query.Set("squash", "1")
|
||||
}
|
||||
|
||||
if !container.Isolation.IsDefault(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
|
||||
}
|
||||
|
||||
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}}
|
||||
return cli.post(ctx, "/images/create", query, nil, headers)
|
||||
}
|
||||
|
|
|
@ -5,19 +5,14 @@ import (
|
|||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/docker/engine-api/types"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// ImageInspectWithRaw returns the image information and its raw representation.
|
||||
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string, getSize bool) (types.ImageInspect, []byte, error) {
|
||||
query := url.Values{}
|
||||
if getSize {
|
||||
query.Set("size", "1")
|
||||
}
|
||||
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", query, nil)
|
||||
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
|
||||
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil)
|
||||
if err != nil {
|
||||
if serverResp.statusCode == http.StatusNotFound {
|
||||
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
|
||||
}
|
||||
|
||||
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}}
|
||||
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
|
||||
}
|
||||
|
||||
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}}
|
||||
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)
|
||||
ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, 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)
|
||||
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, 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)
|
||||
VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, 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) {
|
||||
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}
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
@ -53,7 +53,7 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
|
|||
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}}
|
||||
return cli.post(ctx, "/plugins/pull", query, nil, headers)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -24,47 +25,47 @@ type serverResponse struct {
|
|||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if obj != nil {
|
||||
var err error
|
||||
body, err = encodeData(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return serverResponse{}, err
|
||||
}
|
||||
if headers == nil {
|
||||
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)
|
||||
}
|
||||
|
||||
func (cli *Client) sendClientRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers map[string][]string) (*serverResponse, error) {
|
||||
serverResp := &serverResponse{
|
||||
func (cli *Client) sendClientRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
|
||||
serverResp := serverResponse{
|
||||
body: nil,
|
||||
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)
|
||||
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") {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
@ -185,23 +199,10 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
|
|||
return params, nil
|
||||
}
|
||||
|
||||
func ensureReaderClosed(response *serverResponse) {
|
||||
if response != nil && response.body != nil {
|
||||
func ensureReaderClosed(response serverResponse) {
|
||||
if body := response.body; body != nil {
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
|
||||
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 (
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"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.
|
||||
}
|
||||
}()
|
||||
resp.Body = ¬ifyingReader{resp.Body, c}
|
||||
resp.Body = ¬ifyingReader{ReadCloser: resp.Body, notify: c}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
@ -91,23 +92,24 @@ func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.
|
|||
// Close is called or a Read fails on the underlying ReadCloser.
|
||||
type notifyingReader struct {
|
||||
io.ReadCloser
|
||||
notify chan<- struct{}
|
||||
notify chan<- struct{}
|
||||
notifyOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *notifyingReader) Read(p []byte) (int, error) {
|
||||
n, err := r.ReadCloser.Read(p)
|
||||
if err != nil && r.notify != nil {
|
||||
close(r.notify)
|
||||
r.notify = nil
|
||||
if err != nil {
|
||||
r.notifyOnce.Do(func() {
|
||||
close(r.notify)
|
||||
})
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *notifyingReader) Close() error {
|
||||
err := r.ReadCloser.Close()
|
||||
if r.notify != nil {
|
||||
r.notifyOnce.Do(func() {
|
||||
close(r.notify)
|
||||
r.notify = nil
|
||||
}
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
package client
|
||||
|
||||
import "golang.org/x/net/context"
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// VolumeRemove removes a volume from the docker host.
|
||||
func (cli *Client) VolumeRemove(ctx context.Context, volumeID string) error {
|
||||
resp, err := cli.delete(ctx, "/volumes/"+volumeID, nil, nil)
|
||||
func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool) error {
|
||||
query := url.Values{}
|
||||
if force {
|
||||
query.Set("force", "1")
|
||||
}
|
||||
resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil)
|
||||
ensureReaderClosed(resp)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -147,6 +147,10 @@ type ImageBuildOptions struct {
|
|||
AuthConfigs map[string]AuthConfig
|
||||
Context io.Reader
|
||||
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
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/docker/engine-api/types/blkiodev"
|
||||
"github.com/docker/engine-api/types/mount"
|
||||
"github.com/docker/engine-api/types/strslice"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/docker/go-units"
|
||||
|
@ -317,4 +318,7 @@ type HostConfig struct {
|
|||
|
||||
// Contains container's resources (cgroups, ulimits)
|
||||
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
|
||||
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
|
||||
func (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal((*net.IPNet)(ipnet).String())
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package swarm
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/engine-api/types/mount"
|
||||
)
|
||||
|
||||
// ContainerSpec represents the spec of a container.
|
||||
type ContainerSpec struct {
|
||||
|
@ -11,57 +15,8 @@ type ContainerSpec struct {
|
|||
Env []string `json:",omitempty"`
|
||||
Dir 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"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// Driver represents a driver (network/volume).
|
||||
// Driver represents a network driver.
|
||||
type Driver struct {
|
||||
Name string `json:",omitempty"`
|
||||
Options map[string]string `json:",omitempty"`
|
||||
|
|
|
@ -2,7 +2,7 @@ package swarm
|
|||
|
||||
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
|
||||
type ClusterInfo struct {
|
||||
ID string
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"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/registry"
|
||||
"github.com/docker/engine-api/types/swarm"
|
||||
|
@ -230,7 +231,6 @@ type Info struct {
|
|||
OomKillDisable bool
|
||||
NGoroutines int
|
||||
SystemTime string
|
||||
ExecutionDriver string
|
||||
LoggingDriver string
|
||||
CgroupDriver string
|
||||
NEventsListener int
|
||||
|
@ -409,14 +409,16 @@ type DefaultNetworkSettings struct {
|
|||
}
|
||||
|
||||
// MountPoint represents a mount point configuration inside the container.
|
||||
// This is used for reporting the mountpoints in use by a container.
|
||||
type MountPoint struct {
|
||||
Name string `json:",omitempty"`
|
||||
Type mount.Type `json:",omitempty"`
|
||||
Name string `json:",omitempty"`
|
||||
Source string
|
||||
Destination string
|
||||
Driver string `json:",omitempty"`
|
||||
Mode string
|
||||
RW bool
|
||||
Propagation string
|
||||
Propagation mount.Propagation
|
||||
}
|
||||
|
||||
// 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/system"
|
||||
mounttypes "github.com/docker/engine-api/types/mount"
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
)
|
||||
|
||||
|
@ -92,8 +93,8 @@ type MountPoint struct {
|
|||
Mode string `json:"Relabel"` // Originally field was `Relabel`"
|
||||
|
||||
// Note Propagation is not used on Windows
|
||||
Propagation string // Mount propagation string
|
||||
Named bool // specifies if the mountpoint was specified by name
|
||||
Propagation mounttypes.Propagation // Mount propagation string
|
||||
Named bool // specifies if the mountpoint was specified by name
|
||||
|
||||
// Specifies if data should be copied from the container before the first mount
|
||||
// Use a pointer here so we can tell if the user set this value explicitly
|
||||
|
|
|
@ -4,28 +4,31 @@ package volume
|
|||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
mounttypes "github.com/docker/engine-api/types/mount"
|
||||
)
|
||||
|
||||
// DefaultPropagationMode defines what propagation mode should be used by
|
||||
// default if user has not specified one explicitly.
|
||||
const DefaultPropagationMode string = "rprivate"
|
||||
const DefaultPropagationMode mounttypes.Propagation = "rprivate"
|
||||
|
||||
// propagation modes
|
||||
var propagationModes = map[string]bool{
|
||||
"private": true,
|
||||
"rprivate": true,
|
||||
"slave": true,
|
||||
"rslave": true,
|
||||
"shared": true,
|
||||
"rshared": true,
|
||||
var propagationModes = map[mounttypes.Propagation]bool{
|
||||
mounttypes.PropagationPrivate: true,
|
||||
mounttypes.PropagationRPrivate: true,
|
||||
mounttypes.PropagationSlave: true,
|
||||
mounttypes.PropagationRSlave: true,
|
||||
mounttypes.PropagationShared: true,
|
||||
mounttypes.PropagationRShared: true,
|
||||
}
|
||||
|
||||
// GetPropagation extracts and returns the mount propagation mode. If there
|
||||
// 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, ",") {
|
||||
if propagationModes[o] {
|
||||
return o
|
||||
prop := mounttypes.Propagation(o)
|
||||
if propagationModes[prop] {
|
||||
return prop
|
||||
}
|
||||
}
|
||||
return DefaultPropagationMode
|
||||
|
@ -36,7 +39,7 @@ func GetPropagation(mode string) string {
|
|||
// present, false otherwise.
|
||||
func HasPropagation(mode string) bool {
|
||||
for _, o := range strings.Split(mode, ",") {
|
||||
if propagationModes[o] {
|
||||
if propagationModes[mounttypes.Propagation(o)] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
|
||||
package volume
|
||||
|
||||
import mounttypes "github.com/docker/engine-api/types/mount"
|
||||
|
||||
// DefaultPropagationMode is used only in linux. In other cases it returns
|
||||
// empty string.
|
||||
const DefaultPropagationMode string = ""
|
||||
const DefaultPropagationMode mounttypes.Propagation = ""
|
||||
|
||||
// propagation modes not supported on this platform.
|
||||
var propagationModes = map[string]bool{}
|
||||
|
||||
// GetPropagation is not supported. Return empty string.
|
||||
func GetPropagation(mode string) string {
|
||||
func GetPropagation(mode string) mounttypes.Propagation {
|
||||
return DefaultPropagationMode
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
mounttypes "github.com/docker/engine-api/types/mount"
|
||||
)
|
||||
|
||||
// read-write modes
|
||||
|
@ -152,7 +154,7 @@ func ValidMountMode(mode string) bool {
|
|||
rwModeCount++
|
||||
case labelModes[o]:
|
||||
labelModeCount++
|
||||
case propagationModes[o]:
|
||||
case propagationModes[mounttypes.Propagation(o)]:
|
||||
propagationModeCount++
|
||||
case copyModeExists(o):
|
||||
copyModeCount++
|
||||
|
|
Loading…
Reference in a new issue