From 085895342c7f797f0eef7ec956438e33489f211f Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 15 Jun 2016 14:30:54 -0700 Subject: [PATCH] fix docker swarm init/update --secret Signed-off-by: Victor Vieux --- api/client/container/restart.go | 3 +- api/client/container/stop.go | 3 +- api/client/swarm/init.go | 15 ++-- api/client/swarm/opts.go | 2 +- api/client/swarm/update.go | 16 ++-- daemon/cluster/cluster.go | 6 +- daemon/cluster/convert/swarm.go | 41 +++++++-- hack/vendor.sh | 2 +- integration-cli/daemon_swarm.go | 21 +++-- .../engine-api/client/container_restart.go | 6 +- .../engine-api/client/container_stop.go | 6 +- .../docker/engine-api/client/interface.go | 87 +++++++++++++------ .../client/interface_experimental.go | 13 +++ .../engine-api/types/container/host_config.go | 2 +- .../docker/engine-api/types/swarm/swarm.go | 2 +- 15 files changed, 159 insertions(+), 66 deletions(-) diff --git a/api/client/container/restart.go b/api/client/container/restart.go index 98618b5073..04544e4b97 100644 --- a/api/client/container/restart.go +++ b/api/client/container/restart.go @@ -41,7 +41,8 @@ func runRestart(dockerCli *client.DockerCli, opts *restartOptions) error { ctx := context.Background() var errs []string for _, name := range opts.containers { - if err := dockerCli.Client().ContainerRestart(ctx, name, time.Duration(opts.nSeconds)*time.Second); err != nil { + timeout := time.Duration(opts.nSeconds) * time.Second + if err := dockerCli.Client().ContainerRestart(ctx, name, &timeout); err != nil { errs = append(errs, err.Error()) } else { fmt.Fprintf(dockerCli.Out(), "%s\n", name) diff --git a/api/client/container/stop.go b/api/client/container/stop.go index 40b02b73d4..b05b0e3dfe 100644 --- a/api/client/container/stop.go +++ b/api/client/container/stop.go @@ -43,7 +43,8 @@ func runStop(dockerCli *client.DockerCli, opts *stopOptions) error { var errs []string for _, container := range opts.containers { - if err := dockerCli.Client().ContainerStop(ctx, container, time.Duration(opts.time)*time.Second); err != nil { + timeout := time.Duration(opts.time) * time.Second + if err := dockerCli.Client().ContainerStop(ctx, container, &timeout); err != nil { errs = append(errs, err.Error()) } else { fmt.Fprintf(dockerCli.Out(), "%s\n", container) diff --git a/api/client/swarm/init.go b/api/client/swarm/init.go index 0c66246390..d16c09793b 100644 --- a/api/client/swarm/init.go +++ b/api/client/swarm/init.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/cli" "github.com/docker/engine-api/types/swarm" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) type initOptions struct { @@ -19,6 +20,7 @@ type initOptions struct { } func newInitCommand(dockerCli *client.DockerCli) *cobra.Command { + var flags *pflag.FlagSet opts := initOptions{ listenAddr: NewNodeAddrOption(), autoAccept: NewAutoAcceptOption(), @@ -29,11 +31,11 @@ func newInitCommand(dockerCli *client.DockerCli) *cobra.Command { Short: "Initialize a Swarm.", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - return runInit(dockerCli, opts) + return runInit(dockerCli, flags, opts) }, } - flags := cmd.Flags() + flags = cmd.Flags() flags.Var(&opts.listenAddr, "listen-addr", "Listen address") flags.Var(&opts.autoAccept, "auto-accept", "Auto acceptance policy (worker, manager, or none)") flags.StringVar(&opts.secret, "secret", "", "Set secret value needed to accept nodes into cluster") @@ -41,7 +43,7 @@ func newInitCommand(dockerCli *client.DockerCli) *cobra.Command { return cmd } -func runInit(dockerCli *client.DockerCli, opts initOptions) error { +func runInit(dockerCli *client.DockerCli, flags *pflag.FlagSet, opts initOptions) error { client := dockerCli.Client() ctx := context.Background() @@ -50,8 +52,11 @@ func runInit(dockerCli *client.DockerCli, opts initOptions) error { ForceNewCluster: opts.forceNewCluster, } - req.Spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(opts.secret) - + if flags.Changed("secret") { + req.Spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(&opts.secret) + } else { + req.Spec.AcceptancePolicy.Policies = opts.autoAccept.Policies(nil) + } nodeID, err := client.SwarmInit(ctx, req) if err != nil { return err diff --git a/api/client/swarm/opts.go b/api/client/swarm/opts.go index fa543b6596..741f0cf8e8 100644 --- a/api/client/swarm/opts.go +++ b/api/client/swarm/opts.go @@ -102,7 +102,7 @@ func (o *AutoAcceptOption) Type() string { } // Policies returns a representation of this option for the api -func (o *AutoAcceptOption) Policies(secret string) []swarm.Policy { +func (o *AutoAcceptOption) Policies(secret *string) []swarm.Policy { policies := []swarm.Policy{} for _, p := range defaultPolicies { if len(o.values) != 0 { diff --git a/api/client/swarm/update.go b/api/client/swarm/update.go index 0a851a632a..a26b0d59f2 100644 --- a/api/client/swarm/update.go +++ b/api/client/swarm/update.go @@ -54,6 +54,7 @@ func runUpdate(dockerCli *client.DockerCli, flags *pflag.FlagSet, opts updateOpt if err != nil { return err } + err = client.SwarmUpdate(ctx, swarm.Version, swarm.Spec) if err != nil { return err @@ -68,18 +69,17 @@ func mergeSwarm(swarm *swarm.Swarm, flags *pflag.FlagSet) error { if flags.Changed("auto-accept") { value := flags.Lookup("auto-accept").Value.(*AutoAcceptOption) - if len(spec.AcceptancePolicy.Policies) > 0 { - spec.AcceptancePolicy.Policies = value.Policies(spec.AcceptancePolicy.Policies[0].Secret) - } else { - spec.AcceptancePolicy.Policies = value.Policies("") - } + spec.AcceptancePolicy.Policies = value.Policies(nil) } + var psecret *string if flags.Changed("secret") { secret, _ := flags.GetString("secret") - for _, policy := range spec.AcceptancePolicy.Policies { - policy.Secret = secret - } + psecret = &secret + } + + for i := range spec.AcceptancePolicy.Policies { + spec.AcceptancePolicy.Policies[i].Secret = psecret } if flags.Changed("task-history-limit") { diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index d2f972e721..b8e56432a3 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -444,12 +444,12 @@ func (c *Cluster) Update(version uint64, spec types.Spec) error { return ErrNoManager } - swarmSpec, err := convert.SwarmSpecToGRPC(spec) + swarm, err := getSwarm(c.getRequestContext(), c.client) if err != nil { return err } - swarm, err := getSwarm(c.getRequestContext(), c.client) + swarmSpec, err := convert.SwarmSpecToGRPCandMerge(spec, &swarm.Spec) if err != nil { return err } @@ -1030,7 +1030,7 @@ func initAcceptancePolicy(node *swarmagent.Node, acceptancePolicy types.Acceptan } spec := &cluster.Spec - if err := convert.SwarmSpecUpdateAcceptancePolicy(spec, acceptancePolicy); err != nil { + if err := convert.SwarmSpecUpdateAcceptancePolicy(spec, acceptancePolicy, nil); err != nil { return fmt.Errorf("error updating cluster settings: %v", err) } _, err := client.UpdateCluster(ctx, &swarmapi.UpdateClusterRequest{ diff --git a/daemon/cluster/convert/swarm.go b/daemon/cluster/convert/swarm.go index cb9d7d0821..84ed73c0c1 100644 --- a/daemon/cluster/convert/swarm.go +++ b/daemon/cluster/convert/swarm.go @@ -49,7 +49,8 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm { Autoaccept: policy.Autoaccept, } if policy.Secret != nil { - p.Secret = string(policy.Secret.Data) + secret := string(policy.Secret.Data) + p.Secret = &secret } swarm.Spec.AcceptancePolicy.Policies = append(swarm.Spec.AcceptancePolicy.Policies, p) } @@ -57,8 +58,8 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm { return swarm } -// SwarmSpecToGRPC converts a Spec to a grpc ClusterSpec. -func SwarmSpecToGRPC(s types.Spec) (swarmapi.ClusterSpec, error) { +// SwarmSpecToGRPCandMerge converts a Spec to a grpc ClusterSpec and merge AcceptancePolicy from an existing grpc ClusterSpec if provided. +func SwarmSpecToGRPCandMerge(s types.Spec, existingSpec *swarmapi.ClusterSpec) (swarmapi.ClusterSpec, error) { spec := swarmapi.ClusterSpec{ Annotations: swarmapi.Annotations{ Name: s.Name, @@ -82,14 +83,15 @@ func SwarmSpecToGRPC(s types.Spec) (swarmapi.ClusterSpec, error) { }, } - if err := SwarmSpecUpdateAcceptancePolicy(&spec, s.AcceptancePolicy); err != nil { + if err := SwarmSpecUpdateAcceptancePolicy(&spec, s.AcceptancePolicy, existingSpec); err != nil { return swarmapi.ClusterSpec{}, err } + return spec, nil } // SwarmSpecUpdateAcceptancePolicy updates a grpc ClusterSpec using AcceptancePolicy. -func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolicy types.AcceptancePolicy) error { +func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolicy types.AcceptancePolicy, oldSpec *swarmapi.ClusterSpec) error { spec.AcceptancePolicy.Policies = nil for _, p := range acceptancePolicy.Policies { role, ok := swarmapi.NodeRole_value[strings.ToUpper(string(p.Role))] @@ -102,11 +104,20 @@ func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolic Autoaccept: p.Autoaccept, } - if p.Secret != "" { - hashPwd, _ := bcrypt.GenerateFromPassword([]byte(p.Secret), 0) + if p.Secret != nil { + if *p.Secret == "" { // if provided secret is empty, it means erase previous secret. + policy.Secret = nil + } else { // if provided secret is not empty, we generate a new one. + hashPwd, _ := bcrypt.GenerateFromPassword([]byte(*p.Secret), 0) + policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{ + Data: hashPwd, + Alg: "bcrypt", + } + } + } else if oldSecret := getOldSecret(oldSpec, policy.Role); oldSecret != nil { // else use the old one. policy.Secret = &swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret{ - Data: hashPwd, - Alg: "bcrypt", + Data: oldSecret.Data, + Alg: oldSecret.Alg, } } @@ -114,3 +125,15 @@ func SwarmSpecUpdateAcceptancePolicy(spec *swarmapi.ClusterSpec, acceptancePolic } return nil } + +func getOldSecret(oldSpec *swarmapi.ClusterSpec, role swarmapi.NodeRole) *swarmapi.AcceptancePolicy_RoleAdmissionPolicy_HashedSecret { + if oldSpec == nil { + return nil + } + for _, p := range oldSpec.AcceptancePolicy.Policies { + if p.Role == role { + return p.Secret + } + } + return nil +} diff --git a/hack/vendor.sh b/hack/vendor.sh index 1159a77390..0298bab10d 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -60,7 +60,7 @@ clone git golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://gith clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d -clone git github.com/docker/engine-api f3b5ad20d4576de14c96603db522dec530d03f62 +clone git github.com/docker/engine-api f50fbe5f9c4c8eeed591549d2c8187f4076f3717 clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 clone git github.com/imdario/mergo 0.2.1 diff --git a/integration-cli/daemon_swarm.go b/integration-cli/daemon_swarm.go index 0b553d34f8..526ac21e27 100644 --- a/integration-cli/daemon_swarm.go +++ b/integration-cli/daemon_swarm.go @@ -26,11 +26,16 @@ func (d *SwarmDaemon) Init(autoAccept map[string]bool, secret string) error { ListenAddr: d.listenAddr, } for _, role := range []swarm.NodeRole{swarm.NodeRoleManager, swarm.NodeRoleWorker} { - req.Spec.AcceptancePolicy.Policies = append(req.Spec.AcceptancePolicy.Policies, swarm.Policy{ + policy := swarm.Policy{ Role: role, Autoaccept: autoAccept[strings.ToLower(string(role))], - Secret: secret, - }) + } + + if secret != "" { + policy.Secret = &secret + } + + req.Spec.AcceptancePolicy.Policies = append(req.Spec.AcceptancePolicy.Policies, policy) } status, out, err := d.SockRequest("POST", "/swarm/init", req) if status != http.StatusOK { @@ -49,13 +54,17 @@ func (d *SwarmDaemon) Init(autoAccept map[string]bool, secret string) error { // Join joins a current daemon with existing cluster. func (d *SwarmDaemon) Join(remoteAddr, secret, cahash string, manager bool) error { - status, out, err := d.SockRequest("POST", "/swarm/join", swarm.JoinRequest{ + req := swarm.JoinRequest{ ListenAddr: d.listenAddr, RemoteAddrs: []string{remoteAddr}, Manager: manager, - Secret: secret, CACertHash: cahash, - }) + } + + if secret != "" { + req.Secret = secret + } + status, out, err := d.SockRequest("POST", "/swarm/join", req) if status != http.StatusOK { return fmt.Errorf("joining swarm: invalid statuscode %v, %q", status, out) } diff --git a/vendor/src/github.com/docker/engine-api/client/container_restart.go b/vendor/src/github.com/docker/engine-api/client/container_restart.go index 9ae2e4b2bb..93c042d085 100644 --- a/vendor/src/github.com/docker/engine-api/client/container_restart.go +++ b/vendor/src/github.com/docker/engine-api/client/container_restart.go @@ -11,9 +11,11 @@ import ( // ContainerRestart stops and starts a container again. // It makes the daemon to wait for the container to be up again for // a specific amount of time, given the timeout. -func (cli *Client) ContainerRestart(ctx context.Context, containerID string, timeout time.Duration) error { +func (cli *Client) ContainerRestart(ctx context.Context, containerID string, timeout *time.Duration) error { query := url.Values{} - query.Set("t", timetypes.DurationToSecondsString(timeout)) + if timeout != nil { + query.Set("t", timetypes.DurationToSecondsString(*timeout)) + } resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil) ensureReaderClosed(resp) return err diff --git a/vendor/src/github.com/docker/engine-api/client/container_stop.go b/vendor/src/github.com/docker/engine-api/client/container_stop.go index 890650d69a..1fc577f2b9 100644 --- a/vendor/src/github.com/docker/engine-api/client/container_stop.go +++ b/vendor/src/github.com/docker/engine-api/client/container_stop.go @@ -10,9 +10,11 @@ import ( // ContainerStop stops a container without terminating the process. // The process is blocked until the container stops or the timeout expires. -func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout time.Duration) error { +func (cli *Client) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error { query := url.Values{} - query.Set("t", timetypes.DurationToSecondsString(timeout)) + if timeout != nil { + query.Set("t", timetypes.DurationToSecondsString(*timeout)) + } resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil) ensureReaderClosed(resp) return err diff --git a/vendor/src/github.com/docker/engine-api/client/interface.go b/vendor/src/github.com/docker/engine-api/client/interface.go index 95d775561f..7fb04aced3 100644 --- a/vendor/src/github.com/docker/engine-api/client/interface.go +++ b/vendor/src/github.com/docker/engine-api/client/interface.go @@ -15,26 +15,21 @@ import ( // CommonAPIClient is the common methods between stable and experimental versions of APIClient. type CommonAPIClient interface { + ContainerAPIClient + ImageAPIClient + NodeAPIClient + NetworkAPIClient + ServiceAPIClient + SwarmAPIClient + SystemAPIClient + VolumeAPIClient ClientVersion() string - CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error - CheckpointDelete(ctx context.Context, container string, checkpointID string) error - CheckpointList(ctx context.Context, container string) ([]types.Checkpoint, error) - SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) - SwarmJoin(ctx context.Context, req swarm.JoinRequest) error - SwarmLeave(ctx context.Context, force bool) error - SwarmInspect(ctx context.Context) (swarm.Swarm, error) - SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec) error - NodeInspect(ctx context.Context, nodeID string) (swarm.Node, error) - NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) - NodeRemove(ctx context.Context, nodeID string) error - NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error - ServiceCreate(ctx context.Context, service swarm.ServiceSpec) (types.ServiceCreateResponse, error) - ServiceInspect(ctx context.Context, serviceID string) (swarm.Service, error) - ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) - ServiceRemove(ctx context.Context, serviceID string) error - ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec) error - TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) - TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) + ServerVersion(ctx context.Context) (types.Version, error) + UpdateClientVersion(v string) +} + +// ContainerAPIClient defines API client methods for the containers +type ContainerAPIClient interface { ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) @@ -54,18 +49,21 @@ type CommonAPIClient interface { ContainerRemove(ctx context.Context, container string, options types.ContainerRemoveOptions) error ContainerRename(ctx context.Context, container, newContainerName string) error ContainerResize(ctx context.Context, container string, options types.ResizeOptions) error - ContainerRestart(ctx context.Context, container string, timeout time.Duration) error + ContainerRestart(ctx context.Context, container string, timeout *time.Duration) error ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) ContainerStats(ctx context.Context, container string, stream bool) (io.ReadCloser, error) ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error - ContainerStop(ctx context.Context, container string, timeout time.Duration) error + ContainerStop(ctx context.Context, container string, timeout *time.Duration) error ContainerTop(ctx context.Context, container string, arguments []string) (types.ContainerProcessList, error) ContainerUnpause(ctx context.Context, container string) error ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) error ContainerWait(ctx context.Context, container string) (int, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error - Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error) +} + +// ImageAPIClient defines API client methods for the images +type ImageAPIClient interface { ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error) @@ -79,7 +77,10 @@ type CommonAPIClient interface { ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) ImageTag(ctx context.Context, image, ref string) error - Info(ctx context.Context) (types.Info, error) +} + +// NetworkAPIClient defines API client methods for the networks +type NetworkAPIClient interface { NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error @@ -87,9 +88,45 @@ type CommonAPIClient interface { NetworkInspectWithRaw(ctx context.Context, networkID string) (types.NetworkResource, []byte, error) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) NetworkRemove(ctx context.Context, networkID string) error +} + +// NodeAPIClient defines API client methods for the nodes +type NodeAPIClient interface { + NodeInspect(ctx context.Context, nodeID string) (swarm.Node, error) + NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) + NodeRemove(ctx context.Context, nodeID string) error + NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error +} + +// ServiceAPIClient defines API client methods for the services +type ServiceAPIClient interface { + ServiceCreate(ctx context.Context, service swarm.ServiceSpec) (types.ServiceCreateResponse, error) + ServiceInspect(ctx context.Context, serviceID string) (swarm.Service, error) + ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) + ServiceRemove(ctx context.Context, serviceID string) error + ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec) error + TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) + TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) +} + +// SwarmAPIClient defines API client methods for the swarm +type SwarmAPIClient interface { + SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) + SwarmJoin(ctx context.Context, req swarm.JoinRequest) error + SwarmLeave(ctx context.Context, force bool) error + SwarmInspect(ctx context.Context) (swarm.Swarm, error) + SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec) error +} + +// SystemAPIClient defines API client methods for the system +type SystemAPIClient interface { + Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error) + Info(ctx context.Context) (types.Info, error) RegistryLogin(ctx context.Context, auth types.AuthConfig) (types.AuthResponse, error) - ServerVersion(ctx context.Context) (types.Version, error) - UpdateClientVersion(v string) +} + +// VolumeAPIClient defines API client methods for the volumes +type VolumeAPIClient interface { VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error) VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error) VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, error) diff --git a/vendor/src/github.com/docker/engine-api/client/interface_experimental.go b/vendor/src/github.com/docker/engine-api/client/interface_experimental.go index c968e530bf..a63ae70bb6 100644 --- a/vendor/src/github.com/docker/engine-api/client/interface_experimental.go +++ b/vendor/src/github.com/docker/engine-api/client/interface_experimental.go @@ -12,6 +12,19 @@ import ( // APIClient is an interface that clients that talk with a docker server must implement. type APIClient interface { CommonAPIClient + CheckpointAPIClient + PluginAPIClient +} + +// CheckpointAPIClient defines API client methods for the checkpoints +type CheckpointAPIClient interface { + CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error + CheckpointDelete(ctx context.Context, container string, checkpointID string) error + CheckpointList(ctx context.Context, container string) ([]types.Checkpoint, error) +} + +// PluginAPIClient defines API client methods for the plugins +type PluginAPIClient interface { PluginList(ctx context.Context) (types.PluginsListResponse, error) PluginRemove(ctx context.Context, name string) error PluginEnable(ctx context.Context, name string) error diff --git a/vendor/src/github.com/docker/engine-api/types/container/host_config.go b/vendor/src/github.com/docker/engine-api/types/container/host_config.go index 43c33434c8..8e653fcf8d 100644 --- a/vendor/src/github.com/docker/engine-api/types/container/host_config.go +++ b/vendor/src/github.com/docker/engine-api/types/container/host_config.go @@ -303,7 +303,7 @@ type HostConfig struct { PublishAllPorts bool // Should docker publish all exposed port for the container ReadonlyRootfs bool // Is the container root filesystem in read-only SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. - StorageOpt map[string]string // Storage driver options per container. + StorageOpt map[string]string `json:",omitempty"` // Storage driver options per container. Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container UTSMode UTSMode // UTS namespace to use for the container UsernsMode UsernsMode // The user namespace to use for the container diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/swarm.go b/vendor/src/github.com/docker/engine-api/types/swarm/swarm.go index 052b6b3a7f..27a0ab6d14 100644 --- a/vendor/src/github.com/docker/engine-api/types/swarm/swarm.go +++ b/vendor/src/github.com/docker/engine-api/types/swarm/swarm.go @@ -29,7 +29,7 @@ type AcceptancePolicy struct { type Policy struct { Role NodeRole Autoaccept bool - Secret string `json:",omitempty"` + Secret *string `json:",omitempty"` } // OrchestrationConfig represents ochestration configuration.