1
0
Fork 0
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:
Brian Goff 2016-08-16 17:18:43 -04:00 committed by GitHub
commit 37302bbb3f
42 changed files with 241 additions and 182 deletions

View file

@ -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 \

View file

@ -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 \

View file

@ -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 \

View file

@ -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

View file

@ -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 \

View file

@ -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 \

View file

@ -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
} }

View file

@ -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) {

View file

@ -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)

View file

@ -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)

View file

@ -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
} }

View file

@ -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

View file

@ -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)
} }

View file

@ -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),
}) })
} }

View file

@ -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,
} }

View file

@ -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, ",")...)
} }

View file

@ -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)
} }

View file

@ -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

View file

@ -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

View file

@ -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))
} }

View file

@ -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)
} }

View file

@ -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}

View file

@ -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)
} }

View file

@ -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)
} }

View file

@ -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
} }

View file

@ -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 {

View file

@ -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)
} }

View file

@ -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()
}

View file

@ -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 = &notifyingReader{resp.Body, c} resp.Body = &notifyingReader{ReadCloser: resp.Body, notify: c}
return resp, nil 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. // Close is called or a Read fails on the underlying ReadCloser.
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 {
close(r.notify) r.notifyOnce.Do(func() {
r.notify = nil close(r.notify)
})
} }
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
} }

View file

@ -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
} }

View file

@ -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

View file

@ -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"`
} }

View 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"`
}

View file

@ -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())

View file

@ -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"`
}

View file

@ -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"`

View file

@ -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

View file

@ -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 {
Name string `json:",omitempty"` Type mount.Type `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

View file

@ -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,8 +93,8 @@ 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
// Use a pointer here so we can tell if the user set this value explicitly // Use a pointer here so we can tell if the user set this value explicitly

View file

@ -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
} }
} }

View file

@ -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
} }

View file

@ -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++