diff --git a/api/client/network/create.go b/api/client/network/create.go index 9bec170a7c..8de2c9cd4c 100644 --- a/api/client/network/create.go +++ b/api/client/network/create.go @@ -23,6 +23,7 @@ type createOptions struct { labels []string internal bool ipv6 bool + attachable bool ipamDriver string ipamSubnet []string @@ -55,6 +56,7 @@ func newCreateCommand(dockerCli *client.DockerCli) *cobra.Command { flags.StringSliceVar(&opts.labels, "label", []string{}, "Set metadata on a network") flags.BoolVar(&opts.internal, "internal", false, "Restrict external access to the network") flags.BoolVar(&opts.ipv6, "ipv6", false, "Enable IPv6 networking") + flags.BoolVar(&opts.attachable, "attachable", false, "Enable manual container attachment") flags.StringVar(&opts.ipamDriver, "ipam-driver", "default", "IP Address Management Driver") flags.StringSliceVar(&opts.ipamSubnet, "subnet", []string{}, "Subnet in CIDR format that represents a network segment") @@ -87,6 +89,7 @@ func runCreate(dockerCli *client.DockerCli, opts createOptions) error { CheckDuplicate: true, Internal: opts.internal, EnableIPv6: opts.ipv6, + Attachable: opts.attachable, Labels: runconfigopts.ConvertKVStringsToMap(opts.labels), } diff --git a/api/client/service/opts.go b/api/client/service/opts.go index 7151bca4b0..7236980e80 100644 --- a/api/client/service/opts.go +++ b/api/client/service/opts.go @@ -451,6 +451,7 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) { Mounts: opts.mounts.Value(), StopGracePeriod: opts.stopGrace.Value(), }, + Networks: convertNetworks(opts.networks), Resources: opts.resources.ToResourceRequirements(), RestartPolicy: opts.restartPolicy.ToRestartPolicy(), Placement: &swarm.Placement{ @@ -458,13 +459,13 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) { }, LogDriver: opts.logDriver.toLogDriver(), }, - Mode: swarm.ServiceMode{}, + Networks: convertNetworks(opts.networks), + Mode: swarm.ServiceMode{}, UpdateConfig: &swarm.UpdateConfig{ Parallelism: opts.update.parallelism, Delay: opts.update.delay, FailureAction: opts.update.onFailure, }, - Networks: convertNetworks(opts.networks), EndpointSpec: opts.endpoint.ToEndpointSpec(), } diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index 1e508ab302..d6e7334800 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -2,7 +2,6 @@ package network import ( "encoding/json" - "fmt" "net/http" "golang.org/x/net/context" @@ -11,7 +10,6 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/network" - "github.com/docker/docker/errors" "github.com/docker/libnetwork" ) @@ -116,17 +114,7 @@ func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseW return err } - nw, err := n.backend.FindNetwork(vars["id"]) - if err != nil { - return err - } - - if nw.Info().Dynamic() { - err := fmt.Errorf("operation not supported for swarm scoped networks") - return errors.NewRequestForbiddenError(err) - } - - return n.backend.ConnectContainerToNetwork(connect.Container, nw.Name(), connect.EndpointConfig) + return n.backend.ConnectContainerToNetwork(connect.Container, vars["id"], connect.EndpointConfig) } func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { @@ -143,13 +131,6 @@ func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.Respon return err } - nw, _ := n.backend.FindNetwork(vars["id"]) - - if nw != nil && nw.Info().Dynamic() { - err := fmt.Errorf("operation not supported for swarm scoped networks") - return errors.NewRequestForbiddenError(err) - } - return n.backend.DisconnectContainerFromNetwork(disconnect.Container, vars["id"], disconnect.Force) } diff --git a/container/container.go b/container/container.go index b4c59f4ab7..243450db3f 100644 --- a/container/container.go +++ b/container/container.go @@ -700,7 +700,9 @@ func (container *Container) BuildEndpointInfo(n libnetwork.Network, ep libnetwor } if _, ok := networkSettings.Networks[n.Name()]; !ok { - networkSettings.Networks[n.Name()] = new(networktypes.EndpointSettings) + networkSettings.Networks[n.Name()] = &network.EndpointSettings{ + EndpointSettings: &networktypes.EndpointSettings{}, + } } networkSettings.Networks[n.Name()].NetworkID = n.ID() networkSettings.Networks[n.Name()].EndpointID = ep.ID() diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index 5b84cef1d1..8106115837 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -16,6 +16,7 @@ import ( "github.com/Sirupsen/logrus" apitypes "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/network" types "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/daemon/cluster/convert" executorpkg "github.com/docker/docker/daemon/cluster/executor" @@ -126,6 +127,18 @@ type Cluster struct { stop bool err error cancelDelay func() + attachers map[string]*attacher +} + +// attacher manages the in-memory attachment state of a container +// attachment to a global scope network managed by swarm manager. It +// helps in identifying the attachment ID via the taskID and the +// corresponding attachment configuration obtained from the manager. +type attacher struct { + taskID string + config *network.NetworkingConfig + attachWaitCh chan *network.NetworkingConfig + detachWaitCh chan struct{} } type node struct { @@ -154,6 +167,7 @@ func New(config Config) (*Cluster, error) { config: config, configEvent: make(chan struct{}, 10), runtimeRoot: config.RuntimeRoot, + attachers: make(map[string]*attacher), } st, err := c.loadState() @@ -1212,6 +1226,120 @@ func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) { return networks, nil } +func attacherKey(target, containerID string) string { + return containerID + ":" + target +} + +// UpdateAttachment signals the attachment config to the attachment +// waiter who is trying to start or attach the container to the +// network. +func (c *Cluster) UpdateAttachment(target, containerID string, config *network.NetworkingConfig) error { + c.RLock() + attacher, ok := c.attachers[attacherKey(target, containerID)] + c.RUnlock() + if !ok || attacher == nil { + return fmt.Errorf("could not find attacher for container %s to network %s", containerID, target) + } + + attacher.attachWaitCh <- config + close(attacher.attachWaitCh) + return nil +} + +// WaitForDetachment waits for the container to stop or detach from +// the network. +func (c *Cluster) WaitForDetachment(ctx context.Context, networkName, networkID, taskID, containerID string) error { + c.RLock() + attacher, ok := c.attachers[attacherKey(networkName, containerID)] + if !ok { + attacher, ok = c.attachers[attacherKey(networkID, containerID)] + } + if c.node == nil || c.node.Agent() == nil { + c.RUnlock() + return fmt.Errorf("invalid cluster node while waiting for detachment") + } + + agent := c.node.Agent() + c.RUnlock() + + if ok && attacher != nil && attacher.detachWaitCh != nil { + select { + case <-attacher.detachWaitCh: + case <-ctx.Done(): + return ctx.Err() + } + } + + return agent.ResourceAllocator().DetachNetwork(ctx, taskID) +} + +// AttachNetwork generates an attachment request towards the manager. +func (c *Cluster) AttachNetwork(target string, containerID string, addresses []string) (*network.NetworkingConfig, error) { + aKey := attacherKey(target, containerID) + c.Lock() + if c.node == nil || c.node.Agent() == nil { + c.Unlock() + return nil, fmt.Errorf("invalid cluster node while attaching to network") + } + if attacher, ok := c.attachers[aKey]; ok { + c.Unlock() + return attacher.config, nil + } + + agent := c.node.Agent() + attachWaitCh := make(chan *network.NetworkingConfig) + detachWaitCh := make(chan struct{}) + c.attachers[aKey] = &attacher{ + attachWaitCh: attachWaitCh, + detachWaitCh: detachWaitCh, + } + c.Unlock() + + ctx, cancel := c.getRequestContext() + defer cancel() + + taskID, err := agent.ResourceAllocator().AttachNetwork(ctx, containerID, target, addresses) + if err != nil { + c.Lock() + delete(c.attachers, aKey) + c.Unlock() + return nil, fmt.Errorf("Could not attach to network %s: %v", target, err) + } + + logrus.Debugf("Successfully attached to network %s with tid %s", target, taskID) + + var config *network.NetworkingConfig + select { + case config = <-attachWaitCh: + case <-ctx.Done(): + return nil, fmt.Errorf("attaching to network failed, make sure your network options are correct and check manager logs: %v", ctx.Err()) + } + + c.Lock() + c.attachers[aKey].taskID = taskID + c.attachers[aKey].config = config + c.Unlock() + return config, nil +} + +// DetachNetwork unblocks the waiters waiting on WaitForDetachment so +// that a request to detach can be generated towards the manager. +func (c *Cluster) DetachNetwork(target string, containerID string) error { + aKey := attacherKey(target, containerID) + + c.Lock() + attacher, ok := c.attachers[aKey] + delete(c.attachers, aKey) + c.Unlock() + + if !ok { + return fmt.Errorf("could not find network attachment for container %s to network %s", containerID, target) + } + + close(attacher.detachWaitCh) + return nil +} + // CreateNetwork creates a new cluster managed network. func (c *Cluster) CreateNetwork(s apitypes.NetworkCreateRequest) (string, error) { c.RLock() @@ -1262,7 +1390,14 @@ func (c *Cluster) RemoveNetwork(input string) error { } func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.ControlClient, s *types.ServiceSpec) error { - for i, n := range s.Networks { + // Always prefer NetworkAttachmentConfigs from TaskTemplate + // but fallback to service spec for backward compatibility + networks := s.TaskTemplate.Networks + if len(networks) == 0 { + networks = s.Networks + } + + for i, n := range networks { apiNetwork, err := getNetwork(ctx, client, n.Target) if err != nil { if ln, _ := c.config.Backend.FindNetwork(n.Target); ln != nil && !ln.Info().Dynamic() { @@ -1271,7 +1406,7 @@ func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.Control } return err } - s.Networks[i].Target = apiNetwork.ID + networks[i].Target = apiNetwork.ID } return nil } diff --git a/daemon/cluster/convert/network.go b/daemon/cluster/convert/network.go index decc320151..f643f620a6 100644 --- a/daemon/cluster/convert/network.go +++ b/daemon/cluster/convert/network.go @@ -27,6 +27,7 @@ func networkFromGRPC(n *swarmapi.Network) types.Network { Spec: types.NetworkSpec{ IPv6Enabled: n.Spec.Ipv6Enabled, Internal: n.Spec.Internal, + Attachable: n.Spec.Attachable, IPAMOptions: ipamFromGRPC(n.Spec.IPAM), }, IPAMOptions: ipamFromGRPC(n.IPAM), @@ -155,6 +156,7 @@ func BasicNetworkFromGRPC(n swarmapi.Network) basictypes.NetworkResource { EnableIPv6: spec.Ipv6Enabled, IPAM: ipam, Internal: spec.Internal, + Attachable: spec.Attachable, Labels: n.Spec.Annotations.Labels, } @@ -179,6 +181,7 @@ func BasicNetworkCreateToGRPC(create basictypes.NetworkCreateRequest) swarmapi.N }, Ipv6Enabled: create.EnableIPv6, Internal: create.Internal, + Attachable: create.Attachable, } if create.IPAM != nil { ns.IPAM = &swarmapi.IPAMOptions{ diff --git a/daemon/cluster/convert/service.go b/daemon/cluster/convert/service.go index 5c20bf6c4f..b87b3259c9 100644 --- a/daemon/cluster/convert/service.go +++ b/daemon/cluster/convert/service.go @@ -15,10 +15,16 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service { spec := s.Spec containerConfig := spec.Task.Runtime.(*swarmapi.TaskSpec_Container).Container - networks := make([]types.NetworkAttachmentConfig, 0, len(spec.Networks)) + serviceNetworks := make([]types.NetworkAttachmentConfig, 0, len(spec.Networks)) for _, n := range spec.Networks { - networks = append(networks, types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) + serviceNetworks = append(serviceNetworks, types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) } + + taskNetworks := make([]types.NetworkAttachmentConfig, 0, len(spec.Task.Networks)) + for _, n := range spec.Task.Networks { + taskNetworks = append(taskNetworks, types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) + } + service := types.Service{ ID: s.ID, @@ -29,9 +35,10 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service { RestartPolicy: restartPolicyFromGRPC(s.Spec.Task.Restart), Placement: placementFromGRPC(s.Spec.Task.Placement), LogDriver: driverFromGRPC(s.Spec.Task.LogDriver), + Networks: taskNetworks, }, - Networks: networks, + Networks: serviceNetworks, EndpointSpec: endpointSpecFromGRPC(s.Spec.Endpoint), }, Endpoint: endpointFromGRPC(s.Endpoint), @@ -99,9 +106,14 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) { name = namesgenerator.GetRandomName(0) } - networks := make([]*swarmapi.ServiceSpec_NetworkAttachmentConfig, 0, len(s.Networks)) + serviceNetworks := make([]*swarmapi.NetworkAttachmentConfig, 0, len(s.Networks)) for _, n := range s.Networks { - networks = append(networks, &swarmapi.ServiceSpec_NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) + serviceNetworks = append(serviceNetworks, &swarmapi.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) + } + + taskNetworks := make([]*swarmapi.NetworkAttachmentConfig, 0, len(s.TaskTemplate.Networks)) + for _, n := range s.TaskTemplate.Networks { + taskNetworks = append(taskNetworks, &swarmapi.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) } spec := swarmapi.ServiceSpec{ @@ -112,8 +124,9 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) { Task: swarmapi.TaskSpec{ Resources: resourcesToGRPC(s.TaskTemplate.Resources), LogDriver: driverToGRPC(s.TaskTemplate.LogDriver), + Networks: taskNetworks, }, - Networks: networks, + Networks: serviceNetworks, } containerSpec, err := containerToGRPC(s.TaskTemplate.ContainerSpec) diff --git a/daemon/cluster/convert/task.go b/daemon/cluster/convert/task.go index f23bccb545..2d60458ac9 100644 --- a/daemon/cluster/convert/task.go +++ b/daemon/cluster/convert/task.go @@ -12,6 +12,11 @@ import ( func TaskFromGRPC(t swarmapi.Task) types.Task { containerConfig := t.Spec.Runtime.(*swarmapi.TaskSpec_Container).Container containerStatus := t.Status.GetContainer() + networks := make([]types.NetworkAttachmentConfig, 0, len(t.Spec.Networks)) + for _, n := range t.Spec.Networks { + networks = append(networks, types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) + } + task := types.Task{ ID: t.ID, ServiceID: t.ServiceID, @@ -23,6 +28,7 @@ func TaskFromGRPC(t swarmapi.Task) types.Task { RestartPolicy: restartPolicyFromGRPC(t.Spec.Restart), Placement: placementFromGRPC(t.Spec.Placement), LogDriver: driverFromGRPC(t.Spec.LogDriver), + Networks: networks, }, Status: types.TaskStatus{ State: types.TaskState(strings.ToLower(t.Status.State.String())), diff --git a/daemon/cluster/executor/backend.go b/daemon/cluster/executor/backend.go index af09be55d4..756e1bb30e 100644 --- a/daemon/cluster/executor/backend.go +++ b/daemon/cluster/executor/backend.go @@ -40,4 +40,6 @@ type Backend interface { IsSwarmCompatible() error SubscribeToEvents(since, until time.Time, filter filters.Args) ([]events.Message, chan interface{}) UnsubscribeFromEvents(listener chan interface{}) + UpdateAttachment(string, string, string, *network.NetworkingConfig) error + WaitForDetachment(context.Context, string, string, string, string) error } diff --git a/daemon/cluster/executor/container/adapter.go b/daemon/cluster/executor/container/adapter.go index 85a7017ba1..bac9a1542c 100644 --- a/daemon/cluster/executor/container/adapter.go +++ b/daemon/cluster/executor/container/adapter.go @@ -144,6 +144,44 @@ func (c *containerAdapter) removeNetworks(ctx context.Context) error { return nil } +func (c *containerAdapter) networkAttach(ctx context.Context) error { + config := c.container.createNetworkingConfig() + + var ( + networkName string + networkID string + ) + + if config != nil { + for n, epConfig := range config.EndpointsConfig { + networkName = n + networkID = epConfig.NetworkID + break + } + } + + return c.backend.UpdateAttachment(networkName, networkID, c.container.id(), config) +} + +func (c *containerAdapter) waitForDetach(ctx context.Context) error { + config := c.container.createNetworkingConfig() + + var ( + networkName string + networkID string + ) + + if config != nil { + for n, epConfig := range config.EndpointsConfig { + networkName = n + networkID = epConfig.NetworkID + break + } + } + + return c.backend.WaitForDetachment(ctx, networkName, networkID, c.container.taskID(), c.container.id()) +} + func (c *containerAdapter) create(ctx context.Context) error { var cr types.ContainerCreateResponse var err error @@ -233,7 +271,7 @@ func (c *containerAdapter) events(ctx context.Context) <-chan events.Message { } func (c *containerAdapter) wait(ctx context.Context) error { - return c.backend.ContainerWaitWithContext(ctx, c.container.name()) + return c.backend.ContainerWaitWithContext(ctx, c.container.nameOrID()) } func (c *containerAdapter) shutdown(ctx context.Context) error { diff --git a/daemon/cluster/executor/container/attachment.go b/daemon/cluster/executor/container/attachment.go new file mode 100644 index 0000000000..f3b738f70b --- /dev/null +++ b/daemon/cluster/executor/container/attachment.go @@ -0,0 +1,80 @@ +package container + +import ( + executorpkg "github.com/docker/docker/daemon/cluster/executor" + "github.com/docker/swarmkit/api" + "golang.org/x/net/context" +) + +// networkAttacherController implements agent.Controller against docker's API. +// +// networkAttacherController manages the lifecycle of network +// attachment of a docker unmanaged container managed as a task from +// agent point of view. It provides network attachment information to +// the unmanaged container for it to attach to the network and run. +type networkAttacherController struct { + backend executorpkg.Backend + task *api.Task + adapter *containerAdapter + closed chan struct{} +} + +func newNetworkAttacherController(b executorpkg.Backend, task *api.Task) (*networkAttacherController, error) { + adapter, err := newContainerAdapter(b, task) + if err != nil { + return nil, err + } + + return &networkAttacherController{ + backend: b, + task: task, + adapter: adapter, + closed: make(chan struct{}), + }, nil +} + +func (nc *networkAttacherController) Update(ctx context.Context, t *api.Task) error { + return nil +} + +func (nc *networkAttacherController) Prepare(ctx context.Context) error { + // Make sure all the networks that the task needs are created. + if err := nc.adapter.createNetworks(ctx); err != nil { + return err + } + + return nil +} + +func (nc *networkAttacherController) Start(ctx context.Context) error { + return nc.adapter.networkAttach(ctx) +} + +func (nc *networkAttacherController) Wait(pctx context.Context) error { + ctx, cancel := context.WithCancel(pctx) + defer cancel() + + return nc.adapter.waitForDetach(ctx) +} + +func (nc *networkAttacherController) Shutdown(ctx context.Context) error { + return nil +} + +func (nc *networkAttacherController) Terminate(ctx context.Context) error { + return nil +} + +func (nc *networkAttacherController) Remove(ctx context.Context) error { + // Try removing the network referenced in this task in case this + // task is the last one referencing it + if err := nc.adapter.removeNetworks(ctx); err != nil { + return err + } + + return nil +} + +func (nc *networkAttacherController) Close() error { + return nil +} diff --git a/daemon/cluster/executor/container/container.go b/daemon/cluster/executor/container/container.go index c48873121b..c0415fa2bf 100644 --- a/daemon/cluster/executor/container/container.go +++ b/daemon/cluster/executor/container/container.go @@ -44,17 +44,19 @@ func newContainerConfig(t *api.Task) (*containerConfig, error) { } func (c *containerConfig) setTask(t *api.Task) error { - container := t.Spec.GetContainer() - if container == nil { + if t.Spec.GetContainer() == nil && t.Spec.GetAttachment() == nil { return exec.ErrRuntimeUnsupported } - if container.Image == "" { - return ErrImageRequired - } + container := t.Spec.GetContainer() + if container != nil { + if container.Image == "" { + return ErrImageRequired + } - if err := validateMounts(container.Mounts); err != nil { - return err + if err := validateMounts(container.Mounts); err != nil { + return err + } } // index the networks by name @@ -67,6 +69,19 @@ func (c *containerConfig) setTask(t *api.Task) error { return nil } +func (c *containerConfig) id() string { + attachment := c.task.Spec.GetAttachment() + if attachment == nil { + return "" + } + + return attachment.ContainerID +} + +func (c *containerConfig) taskID() string { + return c.task.ID +} + func (c *containerConfig) endpoint() *api.Endpoint { return c.task.Endpoint } @@ -75,6 +90,14 @@ func (c *containerConfig) spec() *api.ContainerSpec { return c.task.Spec.GetContainer() } +func (c *containerConfig) nameOrID() string { + if c.task.Spec.GetContainer() != nil { + return c.name() + } + + return c.id() +} + func (c *containerConfig) name() string { if c.task.Annotations.Name != "" { // if set, use the container Annotations.Name field, set in the orchestrator. @@ -342,7 +365,7 @@ func (c *containerConfig) resources() enginecontainer.Resources { // Docker daemon supports just 1 network during container create. func (c *containerConfig) createNetworkingConfig() *network.NetworkingConfig { var networks []*api.NetworkAttachment - if c.task.Spec.GetContainer() != nil { + if c.task.Spec.GetContainer() != nil || c.task.Spec.GetAttachment() != nil { networks = c.task.Networks } @@ -392,6 +415,7 @@ func getEndpointConfig(na *api.NetworkAttachment) *network.EndpointSettings { } return &network.EndpointSettings{ + NetworkID: na.Network.ID, IPAMConfig: &network.EndpointIPAMConfig{ IPv4Address: ipv4, IPv6Address: ipv6, diff --git a/daemon/cluster/executor/container/executor.go b/daemon/cluster/executor/container/executor.go index 2295c44108..844821b83e 100644 --- a/daemon/cluster/executor/container/executor.go +++ b/daemon/cluster/executor/container/executor.go @@ -121,6 +121,10 @@ func (e *executor) Configure(ctx context.Context, node *api.Node) error { // Controller returns a docker container runner. func (e *executor) Controller(t *api.Task) (exec.Controller, error) { + if t.Spec.GetAttachment() != nil { + return newNetworkAttacherController(e.backend, t) + } + ctlr, err := newController(e.backend, t) if err != nil { return nil, err diff --git a/daemon/container_operations.go b/daemon/container_operations.go index 68bd1b458a..818c82ccbf 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -178,7 +178,7 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]lib // return if this call to build join options is not for default bridge network // Legacy Link is only supported by docker run --link bridgeSettings, ok := container.NetworkSettings.Networks[defaultNetName] - if !ok { + if !ok || bridgeSettings.EndpointSettings == nil { return sboxOptions, nil } @@ -238,9 +238,9 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]lib return sboxOptions, nil } -func (daemon *Daemon) updateNetworkSettings(container *container.Container, n libnetwork.Network) error { +func (daemon *Daemon) updateNetworkSettings(container *container.Container, n libnetwork.Network, endpointConfig *networktypes.EndpointSettings) error { if container.NetworkSettings == nil { - container.NetworkSettings = &network.Settings{Networks: make(map[string]*networktypes.EndpointSettings)} + container.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)} } if !container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() { @@ -268,7 +268,9 @@ func (daemon *Daemon) updateNetworkSettings(container *container.Container, n li } if _, ok := container.NetworkSettings.Networks[n.Name()]; !ok { - container.NetworkSettings.Networks[n.Name()] = new(networktypes.EndpointSettings) + container.NetworkSettings.Networks[n.Name()] = &network.EndpointSettings{ + EndpointSettings: endpointConfig, + } } return nil @@ -331,12 +333,63 @@ func errClusterNetworkOnRun(n string) error { return fmt.Errorf("swarm-scoped network (%s) is not compatible with `docker create` or `docker run`. This network can only be used by a docker service", n) } +func (daemon *Daemon) findAndAttachNetwork(container *container.Container, idOrName string, epConfig *networktypes.EndpointSettings) (libnetwork.Network, *networktypes.NetworkingConfig, error) { + n, err := daemon.FindNetwork(idOrName) + if err != nil { + // We should always be able to find the network for a + // managed container. + if container.Managed { + return nil, nil, err + } + } + + // If we found a network and if it is not dynamically created + // we should never attempt to attach to that network here. + if n != nil { + if container.Managed || !n.Info().Dynamic() { + return n, nil, nil + } + } + + var addresses []string + if epConfig != nil && epConfig.IPAMConfig != nil { + if epConfig.IPAMConfig.IPv4Address != "" { + addresses = append(addresses, epConfig.IPAMConfig.IPv4Address) + } + + if epConfig.IPAMConfig.IPv6Address != "" { + addresses = append(addresses, epConfig.IPAMConfig.IPv6Address) + } + } + + // In all other cases, attempt to attach to the network to + // trigger attachment in the swarm cluster manager. + var config *networktypes.NetworkingConfig + if daemon.clusterProvider != nil { + var err error + config, err = daemon.clusterProvider.AttachNetwork(idOrName, container.ID, addresses) + if err != nil { + return nil, nil, err + } + } + + n, err = daemon.FindNetwork(idOrName) + if err != nil { + if daemon.clusterProvider != nil { + if err := daemon.clusterProvider.DetachNetwork(idOrName, container.ID); err != nil { + logrus.Warnf("Could not rollback attachment for container %s to network %s: %v", container.ID, idOrName, err) + } + } + + return nil, nil, err + } + + return n, config, nil +} + // updateContainerNetworkSettings update the network settings func (daemon *Daemon) updateContainerNetworkSettings(container *container.Container, endpointsConfig map[string]*networktypes.EndpointSettings) error { - var ( - n libnetwork.Network - err error - ) + var n libnetwork.Network mode := container.HostConfig.NetworkMode if container.Config.NetworkDisabled || mode.IsContainer() { @@ -347,26 +400,48 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai if mode.IsDefault() { networkName = daemon.netController.Config().Daemon.DefaultNetwork } + if mode.IsUserDefined() { + var err error + n, err = daemon.FindNetwork(networkName) - if err != nil { - return err + if err == nil { + networkName = n.Name() } - if !container.Managed && n.Info().Dynamic() { - return errClusterNetworkOnRun(networkName) - } - networkName = n.Name() } + if container.NetworkSettings == nil { container.NetworkSettings = &network.Settings{} } + if len(endpointsConfig) > 0 { - container.NetworkSettings.Networks = endpointsConfig + if container.NetworkSettings.Networks == nil { + container.NetworkSettings.Networks = make(map[string]*network.EndpointSettings) + } + + for name, epConfig := range endpointsConfig { + container.NetworkSettings.Networks[name] = &network.EndpointSettings{ + EndpointSettings: epConfig, + } + } } + if container.NetworkSettings.Networks == nil { - container.NetworkSettings.Networks = make(map[string]*networktypes.EndpointSettings) - container.NetworkSettings.Networks[networkName] = new(networktypes.EndpointSettings) + container.NetworkSettings.Networks = make(map[string]*network.EndpointSettings) + container.NetworkSettings.Networks[networkName] = &network.EndpointSettings{ + EndpointSettings: &networktypes.EndpointSettings{}, + } } + + // Convert any settings added by client in default name to + // engine's default network name key + if mode.IsDefault() { + if nConf, ok := container.NetworkSettings.Networks[mode.NetworkName()]; ok { + container.NetworkSettings.Networks[networkName] = nConf + delete(container.NetworkSettings.Networks, mode.NetworkName()) + } + } + if !mode.IsUserDefined() { return nil } @@ -374,10 +449,13 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai if _, ok := container.NetworkSettings.Networks[networkName]; ok { return nil } - if nwConfig, ok := container.NetworkSettings.Networks[n.ID()]; ok { - container.NetworkSettings.Networks[networkName] = nwConfig - delete(container.NetworkSettings.Networks, n.ID()) - return nil + + if n != nil { + if nwConfig, ok := container.NetworkSettings.Networks[n.ID()]; ok { + container.NetworkSettings.Networks[networkName] = nwConfig + delete(container.NetworkSettings.Networks, n.ID()) + return nil + } } return nil @@ -414,16 +492,27 @@ func (daemon *Daemon) allocateNetwork(container *container.Container) error { // on first network connecting. defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName() if nConf, ok := container.NetworkSettings.Networks[defaultNetName]; ok { - if err := daemon.connectToNetwork(container, defaultNetName, nConf, updateSettings); err != nil { + if err := daemon.connectToNetwork(container, defaultNetName, nConf.EndpointSettings, updateSettings); err != nil { return err } } - for n, nConf := range container.NetworkSettings.Networks { + var ( + networks []string + epConfigs []*network.EndpointSettings + ) + + for n, epConf := range container.NetworkSettings.Networks { if n == defaultNetName { continue } - if err := daemon.connectToNetwork(container, n, nConf, updateSettings); err != nil { + + networks = append(networks, n) + epConfigs = append(epConfigs, epConf) + } + + for i, epConf := range epConfigs { + if err := daemon.connectToNetwork(container, networks[i], epConf.EndpointSettings, updateSettings); err != nil { return err } } @@ -488,7 +577,7 @@ func validateNetworkingConfig(n libnetwork.Network, epConfig *networktypes.Endpo } // cleanOperationalData resets the operational data from the passed endpoint settings -func cleanOperationalData(es *networktypes.EndpointSettings) { +func cleanOperationalData(es *network.EndpointSettings) { es.EndpointID = "" es.Gateway = "" es.IPAddress = "" @@ -497,25 +586,18 @@ func cleanOperationalData(es *networktypes.EndpointSettings) { es.GlobalIPv6Address = "" es.GlobalIPv6PrefixLen = 0 es.MacAddress = "" + if es.IPAMOperational { + es.IPAMConfig = nil + } } -func (daemon *Daemon) updateNetworkConfig(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (libnetwork.Network, error) { - if container.HostConfig.NetworkMode.IsContainer() { - return nil, runconfig.ErrConflictSharedNetwork - } - - if containertypes.NetworkMode(idOrName).IsBridge() && - daemon.configStore.DisableBridge { - container.Config.NetworkDisabled = true - return nil, nil - } - - if !containertypes.NetworkMode(idOrName).IsUserDefined() { +func (daemon *Daemon) updateNetworkConfig(container *container.Container, n libnetwork.Network, endpointConfig *networktypes.EndpointSettings, updateSettings bool) error { + if !containertypes.NetworkMode(n.Name()).IsUserDefined() { if hasUserDefinedIPAddress(endpointConfig) && !enableIPOnPredefinedNetwork() { - return nil, runconfig.ErrUnsupportedNetworkAndIP + return runconfig.ErrUnsupportedNetworkAndIP } if endpointConfig != nil && len(endpointConfig.Aliases) > 0 { - return nil, runconfig.ErrUnsupportedNetworkAndAlias + return runconfig.ErrUnsupportedNetworkAndAlias } } else { addShortID := true @@ -531,28 +613,34 @@ func (daemon *Daemon) updateNetworkConfig(container *container.Container, idOrNa } } - n, err := daemon.FindNetwork(idOrName) - if err != nil { - return nil, err - } - if err := validateNetworkingConfig(n, endpointConfig); err != nil { - return nil, err + return err } if updateSettings { - if err := daemon.updateNetworkSettings(container, n); err != nil { - return nil, err + if err := daemon.updateNetworkSettings(container, n, endpointConfig); err != nil { + return err } } - return n, nil + return nil } func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) { + if container.HostConfig.NetworkMode.IsContainer() { + return runconfig.ErrConflictSharedNetwork + } + + if containertypes.NetworkMode(idOrName).IsBridge() && + daemon.configStore.DisableBridge { + container.Config.NetworkDisabled = true + return nil + } + if endpointConfig == nil { endpointConfig = &networktypes.EndpointSettings{} } - n, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, updateSettings) + + n, config, err := daemon.findAndAttachNetwork(container, idOrName, endpointConfig) if err != nil { return err } @@ -560,6 +648,25 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName return nil } + var operIPAM bool + if config != nil { + if epConfig, ok := config.EndpointsConfig[n.Name()]; ok { + if endpointConfig.IPAMConfig == nil || + (endpointConfig.IPAMConfig.IPv4Address == "" && + endpointConfig.IPAMConfig.IPv6Address == "" && + len(endpointConfig.IPAMConfig.LinkLocalIPs) == 0) { + operIPAM = true + } + + endpointConfig = epConfig + } + } + + err = daemon.updateNetworkConfig(container, n, endpointConfig, updateSettings) + if err != nil { + return err + } + controller := daemon.netController sb := daemon.getNetworkSandbox(container) @@ -580,7 +687,13 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName } } }() - container.NetworkSettings.Networks[n.Name()] = endpointConfig + container.NetworkSettings.Networks[n.Name()] = &network.EndpointSettings{ + EndpointSettings: endpointConfig, + IPAMOperational: operIPAM, + } + if _, ok := container.NetworkSettings.Networks[n.ID()]; ok { + delete(container.NetworkSettings.Networks, n.ID()) + } if err := daemon.updateEndpointNetworkSettings(container, n, ep); err != nil { return err @@ -632,7 +745,7 @@ func (daemon *Daemon) ForceEndpointDelete(name string, networkName string) error return ep.Delete(true) } -func disconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error { +func (daemon *Daemon) disconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error { var ( ep libnetwork.Endpoint sbox libnetwork.Sandbox @@ -678,6 +791,13 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network, } delete(container.NetworkSettings.Networks, n.Name()) + + if daemon.clusterProvider != nil && n.Info().Dynamic() && !container.Managed { + if err := daemon.clusterProvider.DetachNetwork(n.Name(), container.ID); err != nil { + logrus.Warnf("error detaching from network %s: %v", n, err) + } + } + return nil } @@ -751,6 +871,11 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) { if nw, err := daemon.FindNetwork(n); err == nil { networks = append(networks, nw) } + + if epSettings.EndpointSettings == nil { + continue + } + cleanOperationalData(epSettings) } @@ -765,6 +890,12 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) { } for _, nw := range networks { + if daemon.clusterProvider != nil && nw.Info().Dynamic() && !container.Managed { + if err := daemon.clusterProvider.DetachNetwork(nw.Name(), container.ID); err != nil { + logrus.Warnf("error detaching from network %s: %v", nw.Name(), err) + } + } + attributes := map[string]string{ "container": container.ID, } diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go index fc44932d4e..b39115c710 100644 --- a/daemon/container_operations_unix.go +++ b/daemon/container_operations_unix.go @@ -16,6 +16,7 @@ import ( networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/container" "github.com/docker/docker/daemon/links" + "github.com/docker/docker/daemon/network" "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/mount" @@ -35,7 +36,7 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s children := daemon.children(container) bridgeSettings := container.NetworkSettings.Networks[runconfig.DefaultDaemonNetworkMode().NetworkName()] - if bridgeSettings == nil { + if bridgeSettings == nil || bridgeSettings.EndpointSettings == nil { return nil, nil } @@ -45,7 +46,7 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s } childBridgeSettings := child.NetworkSettings.Networks[runconfig.DefaultDaemonNetworkMode().NetworkName()] - if childBridgeSettings == nil { + if childBridgeSettings == nil || childBridgeSettings.EndpointSettings == nil { return nil, fmt.Errorf("container %s not attached to default bridge network", child.ID) } @@ -107,10 +108,17 @@ func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName if container.RemovalInProgress || container.Dead { return errRemovalContainer(container.ID) } - if _, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, true); err != nil { - return err + + n, err := daemon.FindNetwork(idOrName) + if err == nil && n != nil { + if err := daemon.updateNetworkConfig(container, n, endpointConfig, true); err != nil { + return err + } + } else { + container.NetworkSettings.Networks[idOrName] = &network.EndpointSettings{ + EndpointSettings: endpointConfig, + } } - container.NetworkSettings.Networks[idOrName] = endpointConfig } else { if err := daemon.connectToNetwork(container, idOrName, endpointConfig, true); err != nil { return err @@ -143,7 +151,7 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, netw return runconfig.ErrConflictHostNetwork } - if err := disconnectFromNetwork(container, n, false); err != nil { + if err := daemon.disconnectFromNetwork(container, n, false); err != nil { return err } } else { diff --git a/daemon/create.go b/daemon/create.go index b9dbc8e83d..81cb7ac365 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -252,7 +252,7 @@ func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingCo } if len(nwConfig.EndpointsConfig) == 1 { for _, v := range nwConfig.EndpointsConfig { - if v.IPAMConfig != nil { + if v != nil && v.IPAMConfig != nil { if v.IPAMConfig.IPv4Address != "" && net.ParseIP(v.IPAMConfig.IPv4Address).To4() == nil { return errors.NewBadRequestError(fmt.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPv4Address)) } diff --git a/daemon/inspect.go b/daemon/inspect.go index 3577beaaea..e3fe03da76 100644 --- a/daemon/inspect.go +++ b/daemon/inspect.go @@ -42,6 +42,13 @@ func (daemon *Daemon) ContainerInspectCurrent(name string, size bool) (*types.Co return nil, err } + apiNetworks := make(map[string]*networktypes.EndpointSettings) + for name, epConf := range container.NetworkSettings.Networks { + if epConf.EndpointSettings != nil { + apiNetworks[name] = epConf.EndpointSettings + } + } + mountPoints := addMountPoints(container) networkSettings := &types.NetworkSettings{ NetworkSettingsBase: types.NetworkSettingsBase{ @@ -56,7 +63,7 @@ func (daemon *Daemon) ContainerInspectCurrent(name string, size bool) (*types.Co SecondaryIPv6Addresses: container.NetworkSettings.SecondaryIPv6Addresses, }, DefaultNetworkSettings: daemon.getDefaultNetworkSettings(container.NetworkSettings.Networks), - Networks: container.NetworkSettings.Networks, + Networks: apiNetworks, } return &types.ContainerJSON{ @@ -236,10 +243,10 @@ func (daemon *Daemon) getBackwardsCompatibleNetworkSettings(settings *network.Se // getDefaultNetworkSettings creates the deprecated structure that holds the information // about the bridge network for a container. -func (daemon *Daemon) getDefaultNetworkSettings(networks map[string]*networktypes.EndpointSettings) types.DefaultNetworkSettings { +func (daemon *Daemon) getDefaultNetworkSettings(networks map[string]*network.EndpointSettings) types.DefaultNetworkSettings { var settings types.DefaultNetworkSettings - if defaultNetwork, ok := networks["bridge"]; ok { + if defaultNetwork, ok := networks["bridge"]; ok && defaultNetwork.EndpointSettings != nil { settings.EndpointID = defaultNetwork.EndpointID settings.Gateway = defaultNetwork.Gateway settings.GlobalIPv6Address = defaultNetwork.GlobalIPv6Address diff --git a/daemon/list.go b/daemon/list.go index 91ccdd9adc..cb634333c3 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -400,6 +400,9 @@ func includeContainerInList(container *container.Container, ctx *listContext) it return networkExist } for _, nw := range container.NetworkSettings.Networks { + if nw.EndpointSettings == nil { + continue + } if nw.NetworkID == value { return networkExist } @@ -460,7 +463,7 @@ func (daemon *Daemon) transformContainer(container *container.Container, ctx *li // copy networks to avoid races networks := make(map[string]*networktypes.EndpointSettings) for name, network := range container.NetworkSettings.Networks { - if network == nil { + if network == nil || network.EndpointSettings == nil { continue } networks[name] = &networktypes.EndpointSettings{ diff --git a/daemon/network.go b/daemon/network.go index 48015c00a8..b15906b519 100644 --- a/daemon/network.go +++ b/daemon/network.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/runconfig" "github.com/docker/libnetwork" networktypes "github.com/docker/libnetwork/types" + "golang.org/x/net/context" ) // NetworkControllerEnabled checks if the networking stack is enabled. @@ -186,6 +187,29 @@ func (daemon *Daemon) SetNetworkBootstrapKeys(keys []*networktypes.EncryptionKey return daemon.netController.SetKeys(keys) } +// UpdateAttachment notifies the attacher about the attachment config. +func (daemon *Daemon) UpdateAttachment(networkName, networkID, containerID string, config *network.NetworkingConfig) error { + if daemon.clusterProvider == nil { + return fmt.Errorf("cluster provider is not initialized") + } + + if err := daemon.clusterProvider.UpdateAttachment(networkName, containerID, config); err != nil { + return daemon.clusterProvider.UpdateAttachment(networkID, containerID, config) + } + + return nil +} + +// WaitForDetachment makes the cluster manager wait for detachment of +// the container from the network. +func (daemon *Daemon) WaitForDetachment(ctx context.Context, networkName, networkID, taskID, containerID string) error { + if daemon.clusterProvider == nil { + return fmt.Errorf("cluster provider is not initialized") + } + + return daemon.clusterProvider.WaitForDetachment(ctx, networkName, networkID, taskID, containerID) +} + // CreateManagedNetwork creates an agent network. func (daemon *Daemon) CreateManagedNetwork(create clustertypes.NetworkCreateRequest) error { _, err := daemon.createNetwork(create.NetworkCreateRequest, create.ID, true) diff --git a/daemon/network/settings.go b/daemon/network/settings.go index 4320573c9a..1958f2330a 100644 --- a/daemon/network/settings.go +++ b/daemon/network/settings.go @@ -14,7 +14,7 @@ type Settings struct { HairpinMode bool LinkLocalIPv6Address string LinkLocalIPv6PrefixLen int - Networks map[string]*networktypes.EndpointSettings + Networks map[string]*EndpointSettings Service *clustertypes.ServiceConfig Ports nat.PortMap SandboxKey string @@ -22,3 +22,11 @@ type Settings struct { SecondaryIPv6Addresses []networktypes.Address IsAnonymousEndpoint bool } + +// EndpointSettings is a package local wrapper for +// networktypes.EndpointSettings which stores Endpoint state that +// needs to be persisted to disk but not exposed in the api. +type EndpointSettings struct { + *networktypes.EndpointSettings + IPAMOperational bool +} diff --git a/hack/vendor.sh b/hack/vendor.sh index 9e0171c033..255f0cd35f 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -71,8 +71,8 @@ clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 clone git github.com/imdario/mergo 0.2.1 #get libnetwork packages -clone git github.com/docker/libnetwork 82fb373e3eaa4e9bbb5b5ac148b0a3a71f80fca6 -clone git github.com/docker/go-events afb2b9f2c23f33ada1a22b03651775fdc65a5089 +clone git github.com/docker/libnetwork 00e7660daeb4b6108a333319d289bf7dc8b9932e +clone git github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b @@ -85,7 +85,7 @@ clone git github.com/vishvananda/netlink e73bad418fd727ed3a02830b1af1ad0283a1de6 clone git github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060 clone git github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374 clone git github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d -clone git github.com/coreos/etcd 06e2338108fdc694349aed923f4a7e45cf0cec1f +clone git github.com/coreos/etcd 3a49cbb769ebd8d1dd25abb1e83386e9883a5707 clone git github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065 clone git github.com/hashicorp/consul v0.5.2 clone git github.com/boltdb/bolt v1.2.1 @@ -144,11 +144,11 @@ clone git github.com/docker/docker-credential-helpers v0.3.0 clone git github.com/docker/containerd 8508d2bec90b96403143a1104cdcbd56f6aeb361 # cluster -clone git github.com/docker/swarmkit 8a761950fb4d9251c335dc6149a8a02756cb3b10 +clone git github.com/docker/swarmkit 27fbaef4ceed648bb575969ccc9083a6e104a719 clone git github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9 clone git github.com/gogo/protobuf 43a2e0b1c32252bfbbdf81f7faa7a88fb3fa4028 -clone git github.com/cloudflare/cfssl b895b0549c0ff676f92cf09ba971ae02bb41367b -clone git github.com/google/certificate-transparency 025a5cab06f6a819c455d9fdc9e2a1b6d0982284 +clone git github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a +clone git github.com/google/certificate-transparency 0f6e3d1d1ba4d03fdaab7cd716f36255c2e48341 clone git golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2 https://github.com/golang/crypto.git clone git golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb https://github.com/golang/time.git clone git github.com/mreiferson/go-httpclient 63fe23f7434723dc904c901043af07931f293c47 diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 3b5965e571..e33fc1f035 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -298,6 +298,8 @@ func (s *DockerSwarmSuite) TearDownTest(c *check.C) { if err := os.RemoveAll(walDir); err != nil { c.Logf("error removing %v: %v", walDir, err) } + + cleanupExecRoot(c, d.execRoot) } s.daemons = nil s.daemonsLock.Unlock() diff --git a/integration-cli/daemon_unix.go b/integration-cli/daemon_unix.go index 6f84fbbdfd..6ca7daf21c 100644 --- a/integration-cli/daemon_unix.go +++ b/integration-cli/daemon_unix.go @@ -2,7 +2,29 @@ package main -import "syscall" +import ( + "os" + "path/filepath" + "syscall" + + "github.com/go-check/check" +) + +func cleanupExecRoot(c *check.C, execRoot string) { + // Cleanup network namespaces in the exec root of this + // daemon because this exec root is specific to this + // daemon instance and has no chance of getting + // cleaned up when a new daemon is instantiated with a + // new exec root. + netnsPath := filepath.Join(execRoot, "netns") + filepath.Walk(netnsPath, func(path string, info os.FileInfo, err error) error { + if err := syscall.Unmount(path, syscall.MNT_FORCE); err != nil { + c.Logf("unmount of %s failed: %v", path, err) + } + os.Remove(path) + return nil + }) +} func signalDaemonDump(pid int) { syscall.Kill(pid, syscall.SIGQUIT) diff --git a/integration-cli/daemon_windows.go b/integration-cli/daemon_windows.go index c6310975d8..a6e9a09615 100644 --- a/integration-cli/daemon_windows.go +++ b/integration-cli/daemon_windows.go @@ -5,6 +5,8 @@ import ( "strconv" "syscall" "unsafe" + + "github.com/go-check/check" ) func openEvent(desiredAccess uint32, inheritHandle bool, name string, proc *syscall.LazyProc) (handle syscall.Handle, err error) { @@ -45,3 +47,6 @@ func signalDaemonDump(pid int) { func signalDaemonReload(pid int) error { return fmt.Errorf("daemon reload not supported") } + +func cleanupExecRoot(c *check.C, execRoot string) { +} diff --git a/vendor/src/github.com/cloudflare/cfssl/certdb/README.md b/vendor/src/github.com/cloudflare/cfssl/certdb/README.md index 31eff57ca3..fbd941e39c 100644 --- a/vendor/src/github.com/cloudflare/cfssl/certdb/README.md +++ b/vendor/src/github.com/cloudflare/cfssl/certdb/README.md @@ -69,3 +69,7 @@ JSON dictionary: or {"driver":"postgres","data_source":"postgres://user:password@host/db"} + +or + + {"driver":"mysql","data_source":"user:password@tcp(hostname:3306)/db?parseTime=true"} diff --git a/vendor/src/github.com/cloudflare/cfssl/config/config.go b/vendor/src/github.com/cloudflare/cfssl/config/config.go index a6837eb0db..d5eb7c3760 100644 --- a/vendor/src/github.com/cloudflare/cfssl/config/config.go +++ b/vendor/src/github.com/cloudflare/cfssl/config/config.go @@ -2,6 +2,7 @@ package config import ( + "crypto/tls" "crypto/x509" "encoding/asn1" "encoding/json" @@ -59,26 +60,35 @@ type AuthRemote struct { AuthKeyName string `json:"auth_key"` } +// CAConstraint specifies various CA constraints on the signed certificate. +// CAConstraint would verify against (and override) the CA +// extensions in the given CSR. +type CAConstraint struct { + IsCA bool `json:"is_ca"` + MaxPathLen int `json:"max_path_len"` + MaxPathLenZero bool `json:"max_path_len_zero"` +} + // A SigningProfile stores information that the CA needs to store // signature policy. type SigningProfile struct { - Usage []string `json:"usages"` - IssuerURL []string `json:"issuer_urls"` - OCSP string `json:"ocsp_url"` - CRL string `json:"crl_url"` - CA bool `json:"is_ca"` - OCSPNoCheck bool `json:"ocsp_no_check"` - ExpiryString string `json:"expiry"` - BackdateString string `json:"backdate"` - AuthKeyName string `json:"auth_key"` - RemoteName string `json:"remote"` - NotBefore time.Time `json:"not_before"` - NotAfter time.Time `json:"not_after"` - NameWhitelistString string `json:"name_whitelist"` - AuthRemote AuthRemote `json:"auth_remote"` - CTLogServers []string `json:"ct_log_servers"` - AllowedExtensions []OID `json:"allowed_extensions"` - CertStore string `json:"cert_store"` + Usage []string `json:"usages"` + IssuerURL []string `json:"issuer_urls"` + OCSP string `json:"ocsp_url"` + CRL string `json:"crl_url"` + CAConstraint CAConstraint `json:"ca_constraint"` + OCSPNoCheck bool `json:"ocsp_no_check"` + ExpiryString string `json:"expiry"` + BackdateString string `json:"backdate"` + AuthKeyName string `json:"auth_key"` + RemoteName string `json:"remote"` + NotBefore time.Time `json:"not_before"` + NotAfter time.Time `json:"not_after"` + NameWhitelistString string `json:"name_whitelist"` + AuthRemote AuthRemote `json:"auth_remote"` + CTLogServers []string `json:"ct_log_servers"` + AllowedExtensions []OID `json:"allowed_extensions"` + CertStore string `json:"cert_store"` Policies []CertificatePolicy Expiry time.Duration @@ -86,6 +96,8 @@ type SigningProfile struct { Provider auth.Provider RemoteProvider auth.Provider RemoteServer string + RemoteCAs *x509.CertPool + ClientCert *tls.Certificate CSRWhitelist *CSRWhitelist NameWhitelist *regexp.Regexp ExtensionWhitelist map[string]bool @@ -303,6 +315,44 @@ func (p *Signing) OverrideRemotes(remote string) error { return nil } +// SetClientCertKeyPairFromFile updates the properties to set client certificates for mutual +// authenticated TLS remote requests +func (p *Signing) SetClientCertKeyPairFromFile(certFile string, keyFile string) error { + if certFile != "" && keyFile != "" { + cert, err := helpers.LoadClientCertificate(certFile, keyFile) + if err != nil { + return err + } + for _, profile := range p.Profiles { + profile.ClientCert = cert + } + p.Default.ClientCert = cert + } + return nil +} + +// SetRemoteCAsFromFile reads root CAs from file and updates the properties to set remote CAs for TLS +// remote requests +func (p *Signing) SetRemoteCAsFromFile(caFile string) error { + if caFile != "" { + remoteCAs, err := helpers.LoadPEMCertPool(caFile) + if err != nil { + return err + } + p.SetRemoteCAs(remoteCAs) + } + return nil +} + +// SetRemoteCAs updates the properties to set remote CAs for TLS +// remote requests +func (p *Signing) SetRemoteCAs(remoteCAs *x509.CertPool) { + for _, profile := range p.Profiles { + profile.RemoteCAs = remoteCAs + } + p.Default.RemoteCAs = remoteCAs +} + // NeedsRemoteSigner returns true if one of the profiles has a remote set func (p *Signing) NeedsRemoteSigner() bool { for _, profile := range p.Profiles { @@ -360,6 +410,11 @@ func (p *SigningProfile) validProfile(isDefault bool) bool { return false } + if p.AuthRemote.RemoteName == "" && p.AuthRemote.AuthKeyName != "" { + log.Debugf("invalid auth remote profile: no remote signer specified") + return false + } + if p.RemoteName != "" { log.Debugf("validate remote profile") @@ -375,6 +430,7 @@ func (p *SigningProfile) validProfile(isDefault bool) bool { if p.AuthRemote.RemoteName != "" { log.Debugf("invalid remote profile: auth remote is also specified") + return false } } else if p.AuthRemote.RemoteName != "" { log.Debugf("validate auth remote profile") @@ -409,6 +465,43 @@ func (p *SigningProfile) validProfile(isDefault bool) bool { return true } +// This checks if the SigningProfile object contains configurations that are only effective with a local signer +// which has access to CA private key. +func (p *SigningProfile) hasLocalConfig() bool { + if p.Usage != nil || + p.IssuerURL != nil || + p.OCSP != "" || + p.ExpiryString != "" || + p.BackdateString != "" || + p.CAConstraint.IsCA != false || + !p.NotBefore.IsZero() || + !p.NotAfter.IsZero() || + p.NameWhitelistString != "" || + len(p.CTLogServers) != 0 { + return true + } + return false +} + +// warnSkippedSettings prints a log warning message about skipped settings +// in a SigningProfile, usually due to remote signer. +func (p *Signing) warnSkippedSettings() { + const warningMessage = `The configuration value by "usages", "issuer_urls", "ocsp_url", "crl_url", "ca_constraint", "expiry", "backdate", "not_before", "not_after", "cert_store" and "ct_log_servers" are skipped` + if p == nil { + return + } + + if (p.Default.RemoteName != "" || p.Default.AuthRemote.RemoteName != "") && p.Default.hasLocalConfig() { + log.Warning("default profile points to a remote signer: ", warningMessage) + } + + for name, profile := range p.Profiles { + if (profile.RemoteName != "" || profile.AuthRemote.RemoteName != "") && profile.hasLocalConfig() { + log.Warningf("Profiles[%s] points to a remote signer: %s", name, warningMessage) + } + } +} + // Signing codifies the signature configuration policy for a CA. type Signing struct { Profiles map[string]*SigningProfile `json:"profiles"` @@ -450,6 +543,9 @@ func (p *Signing) Valid() bool { return false } } + + p.warnSkippedSettings() + return true } diff --git a/vendor/src/github.com/cloudflare/cfssl/errors/error.go b/vendor/src/github.com/cloudflare/cfssl/errors/error.go index 88663b2c67..9913a84e10 100644 --- a/vendor/src/github.com/cloudflare/cfssl/errors/error.go +++ b/vendor/src/github.com/cloudflare/cfssl/errors/error.go @@ -149,6 +149,8 @@ const ( // UnknownProfile indicates that the profile does not exist. UnknownProfile // 54XX + + UnmatchedWhitelist // 55xx ) // The following are API client related errors, and should be @@ -313,6 +315,8 @@ func New(category Category, reason Reason) *Error { msg = "Policy violation request" case UnknownProfile: msg = "Unknown policy profile" + case UnmatchedWhitelist: + msg = "Request does not match policy whitelist" default: panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PolicyError.", reason)) diff --git a/vendor/src/github.com/cloudflare/cfssl/helpers/helpers.go b/vendor/src/github.com/cloudflare/cfssl/helpers/helpers.go index 85b0d4a314..48d096a987 100644 --- a/vendor/src/github.com/cloudflare/cfssl/helpers/helpers.go +++ b/vendor/src/github.com/cloudflare/cfssl/helpers/helpers.go @@ -8,6 +8,7 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rsa" + "crypto/tls" "crypto/x509" "encoding/asn1" "encoding/pem" @@ -311,11 +312,23 @@ func ParseOneCertificateFromPEM(certsPEM []byte) ([]*x509.Certificate, []byte, e // LoadPEMCertPool loads a pool of PEM certificates from file. func LoadPEMCertPool(certsFile string) (*x509.CertPool, error) { + if certsFile == "" { + return nil, nil + } pemCerts, err := ioutil.ReadFile(certsFile) if err != nil { return nil, err } + return PEMToCertPool(pemCerts) +} + +// PEMToCertPool concerts PEM certificates to a CertPool. +func PEMToCertPool(pemCerts []byte) (*x509.CertPool, error) { + if len(pemCerts) == 0 { + return nil, nil + } + certPool := x509.NewCertPool() if !certPool.AppendCertsFromPEM(pemCerts) { return nil, errors.New("failed to load cert pool") @@ -477,3 +490,29 @@ func SignerAlgo(priv crypto.Signer) x509.SignatureAlgorithm { return x509.UnknownSignatureAlgorithm } } + +// LoadClientCertificate load key/certificate from pem files +func LoadClientCertificate(certFile string, keyFile string) (*tls.Certificate, error) { + if certFile != "" && keyFile != "" { + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + log.Critical("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile) + return nil, err + } + log.Debug("Client certificate loaded ") + return &cert, nil + } + return nil, nil +} + +// CreateTLSConfig creates a tls.Config object from certs and roots +func CreateTLSConfig(remoteCAs *x509.CertPool, cert *tls.Certificate) *tls.Config { + var certs []tls.Certificate + if cert != nil { + certs = []tls.Certificate{*cert} + } + return &tls.Config{ + Certificates: certs, + RootCAs: remoteCAs, + } +} diff --git a/vendor/src/github.com/cloudflare/cfssl/initca/initca.go b/vendor/src/github.com/cloudflare/cfssl/initca/initca.go index 320ffb70b2..c9ab3bbc35 100644 --- a/vendor/src/github.com/cloudflare/cfssl/initca/initca.go +++ b/vendor/src/github.com/cloudflare/cfssl/initca/initca.go @@ -48,13 +48,16 @@ func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) { if req.CA.Expiry != "" { policy.Default.ExpiryString = req.CA.Expiry policy.Default.Expiry, err = time.ParseDuration(req.CA.Expiry) + if err != nil { + return + } } - signer.MaxPathLen = req.CA.PathLength + policy.Default.CAConstraint.MaxPathLen = req.CA.PathLength if req.CA.PathLength != 0 && req.CA.PathLenZero == true { log.Infof("ignore invalid 'pathlenzero' value") } else { - signer.MaxPathLenZero = req.CA.PathLenZero + policy.Default.CAConstraint.MaxPathLenZero = req.CA.PathLenZero } } @@ -72,12 +75,11 @@ func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) { return } - s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), nil) + s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), policy) if err != nil { log.Errorf("failed to create signer: %v", err) return } - s.SetPolicy(policy) signReq := signer.SignRequest{Hosts: req.Hosts, Request: string(csrPEM)} cert, err = s.Sign(signReq) @@ -143,11 +145,11 @@ func NewFromSigner(req *csr.CertificateRequest, priv crypto.Signer) (cert, csrPE } } - signer.MaxPathLen = req.CA.PathLength + policy.Default.CAConstraint.MaxPathLen = req.CA.PathLength if req.CA.PathLength != 0 && req.CA.PathLenZero == true { log.Infof("ignore invalid 'pathlenzero' value") } else { - signer.MaxPathLenZero = req.CA.PathLenZero + policy.Default.CAConstraint.MaxPathLenZero = req.CA.PathLenZero } } @@ -156,12 +158,11 @@ func NewFromSigner(req *csr.CertificateRequest, priv crypto.Signer) (cert, csrPE return nil, nil, err } - s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), nil) + s, err := local.NewSigner(priv, nil, signer.DefaultSigAlgo(priv), policy) if err != nil { log.Errorf("failed to create signer: %v", err) return } - s.SetPolicy(policy) signReq := signer.SignRequest{Request: string(csrPEM)} cert, err = s.Sign(signReq) @@ -217,7 +218,7 @@ var CAPolicy = func() *config.Signing { Usage: []string{"cert sign", "crl sign"}, ExpiryString: "43800h", Expiry: 5 * helpers.OneYear, - CA: true, + CAConstraint: config.CAConstraint{IsCA: true}, }, } } diff --git a/vendor/src/github.com/cloudflare/cfssl/log/log.go b/vendor/src/github.com/cloudflare/cfssl/log/log.go index 4ceacc9e2b..956c9d4604 100644 --- a/vendor/src/github.com/cloudflare/cfssl/log/log.go +++ b/vendor/src/github.com/cloudflare/cfssl/log/log.go @@ -6,7 +6,6 @@ package log import ( - "flag" "fmt" "log" "os" @@ -63,13 +62,6 @@ func SetLogger(logger SyslogWriter) { syslogWriter = logger } -func init() { - // Only define loglevel flag once. - if flag.Lookup("loglevel") == nil { - flag.IntVar(&Level, "loglevel", LevelInfo, "Log level (0 = DEBUG, 5 = FATAL)") - } -} - func print(l int, msg string) { if l >= Level { if syslogWriter != nil { diff --git a/vendor/src/github.com/cloudflare/cfssl/signer/local/local.go b/vendor/src/github.com/cloudflare/cfssl/signer/local/local.go index d565bc4f4f..6f2b5e57aa 100644 --- a/vendor/src/github.com/cloudflare/cfssl/signer/local/local.go +++ b/vendor/src/github.com/cloudflare/cfssl/signer/local/local.go @@ -115,9 +115,6 @@ func (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile template.EmailAddresses = nil s.ca = template initRoot = true - } else if template.IsCA { - template.DNSNames = nil - template.EmailAddresses = nil } derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv) @@ -250,18 +247,21 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { } if safeTemplate.IsCA { - if !profile.CA { - return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest) + if !profile.CAConstraint.IsCA { + log.Error("local signer policy disallows issuing CA certificate") + return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest) } if s.ca != nil && s.ca.MaxPathLen > 0 { if safeTemplate.MaxPathLen >= s.ca.MaxPathLen { + log.Error("local signer certificate disallows CA MaxPathLen extending") // do not sign a cert with pathlen > current - return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest) + return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest) } } else if s.ca != nil && s.ca.MaxPathLen == 0 && s.ca.MaxPathLenZero { + log.Error("local signer certificate disallows issuing CA certificate") // signer has pathlen of 0, do not sign more intermediate CAs - return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest) + return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest) } } @@ -272,17 +272,17 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { if profile.NameWhitelist != nil { if safeTemplate.Subject.CommonName != "" { if profile.NameWhitelist.Find([]byte(safeTemplate.Subject.CommonName)) == nil { - return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) + return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) } } for _, name := range safeTemplate.DNSNames { if profile.NameWhitelist.Find([]byte(name)) == nil { - return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) + return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) } } for _, name := range safeTemplate.EmailAddresses { if profile.NameWhitelist.Find([]byte(name)) == nil { - return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) + return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) } } } @@ -352,7 +352,7 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { for _, server := range profile.CTLogServers { log.Infof("submitting poisoned precertificate to %s", server) - var ctclient = client.New(server) + var ctclient = client.New(server, nil) var resp *ct.SignedCertificateTimestamp resp, err = ctclient.AddPreChain(prechain) if err != nil { diff --git a/vendor/src/github.com/cloudflare/cfssl/signer/signer.go b/vendor/src/github.com/cloudflare/cfssl/signer/signer.go index 6b0c3ea6f1..a34fa453bc 100644 --- a/vendor/src/github.com/cloudflare/cfssl/signer/signer.go +++ b/vendor/src/github.com/cloudflare/cfssl/signer/signer.go @@ -23,12 +23,6 @@ import ( "github.com/cloudflare/cfssl/info" ) -// MaxPathLen is the default path length for a new CA certificate. -var MaxPathLen = 2 - -// MaxPathLenZero indicates whether a new CA certificate has pathlen=0 -var MaxPathLenZero = false - // Subject contains the information that should be used to override the // subject information when signing a certificate. type Subject struct { @@ -294,7 +288,15 @@ func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.Si template.KeyUsage = ku template.ExtKeyUsage = eku template.BasicConstraintsValid = true - template.IsCA = profile.CA + template.IsCA = profile.CAConstraint.IsCA + if template.IsCA { + template.MaxPathLen = profile.CAConstraint.MaxPathLen + if template.MaxPathLen == 0 { + template.MaxPathLenZero = profile.CAConstraint.MaxPathLenZero + } + template.DNSNames = nil + template.EmailAddresses = nil + } template.SubjectKeyId = ski if ocspURL != "" { diff --git a/vendor/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go b/vendor/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go index c963a79032..8d9e725f09 100644 --- a/vendor/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go +++ b/vendor/src/github.com/coreos/etcd/pkg/fileutil/fileutil.go @@ -96,3 +96,26 @@ func Exist(name string) bool { _, err := os.Stat(name) return err == nil } + +// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily +// shorten the length of the file. +func ZeroToEnd(f *os.File) error { + // TODO: support FALLOC_FL_ZERO_RANGE + off, err := f.Seek(0, os.SEEK_CUR) + if err != nil { + return err + } + lenf, lerr := f.Seek(0, os.SEEK_END) + if lerr != nil { + return lerr + } + if err = f.Truncate(off); err != nil { + return err + } + // make sure blocks remain allocated + if err = Preallocate(f, lenf, true); err != nil { + return err + } + _, err = f.Seek(off, os.SEEK_SET) + return err +} diff --git a/vendor/src/github.com/coreos/etcd/raft/log.go b/vendor/src/github.com/coreos/etcd/raft/log.go index 83dcb662c5..c3036d3c90 100644 --- a/vendor/src/github.com/coreos/etcd/raft/log.go +++ b/vendor/src/github.com/coreos/etcd/raft/log.go @@ -232,7 +232,7 @@ func (l *raftLog) term(i uint64) (uint64, error) { if err == nil { return t, nil } - if err == ErrCompacted { + if err == ErrCompacted || err == ErrUnavailable { return 0, err } panic(err) // TODO(bdarnell) @@ -339,7 +339,7 @@ func (l *raftLog) mustCheckOutOfBounds(lo, hi uint64) error { return ErrCompacted } - length := l.lastIndex() - fi + 1 + length := l.lastIndex() + 1 - fi if lo < fi || hi > fi+length { l.logger.Panicf("slice[%d,%d) out of bound [%d,%d]", lo, hi, fi, l.lastIndex()) } diff --git a/vendor/src/github.com/coreos/etcd/raft/node.go b/vendor/src/github.com/coreos/etcd/raft/node.go index 4c2a8968f7..800fb07374 100644 --- a/vendor/src/github.com/coreos/etcd/raft/node.go +++ b/vendor/src/github.com/coreos/etcd/raft/node.go @@ -144,6 +144,9 @@ type Node interface { // to match MemoryStorage.Compact. ApplyConfChange(cc pb.ConfChange) *pb.ConfState + // TransferLeadership attempts to transfer leadership to the given transferee. + TransferLeadership(ctx context.Context, lead, transferee uint64) + // ReadIndex request a read state. The read state will be set in the ready. // Read state has a read index. Once the application advances further than the read // index, any linearizable read requests issued before the read request can be @@ -485,6 +488,15 @@ func (n *node) ReportSnapshot(id uint64, status SnapshotStatus) { } } +func (n *node) TransferLeadership(ctx context.Context, lead, transferee uint64) { + select { + // manually set 'from' and 'to', so that leader can voluntarily transfers its leadership + case n.recvc <- pb.Message{Type: pb.MsgTransferLeader, From: transferee, To: lead}: + case <-n.done: + case <-ctx.Done(): + } +} + func (n *node) ReadIndex(ctx context.Context, rctx []byte) error { return n.step(ctx, pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}}) } diff --git a/vendor/src/github.com/coreos/etcd/raft/raft.go b/vendor/src/github.com/coreos/etcd/raft/raft.go index adef48e725..740c832b8f 100644 --- a/vendor/src/github.com/coreos/etcd/raft/raft.go +++ b/vendor/src/github.com/coreos/etcd/raft/raft.go @@ -590,11 +590,6 @@ func (r *raft) Step(m pb.Message) error { } return nil } - if m.Type == pb.MsgTransferLeader { - if r.state != StateLeader { - r.logger.Debugf("%x [term %d state %v] ignoring MsgTransferLeader to %x", r.id, r.Term, r.state, m.From) - } - } switch { case m.Term == 0: @@ -874,6 +869,13 @@ func stepFollower(r *raft, m pb.Message) { r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.From, m.LogTerm, m.Index, r.Term) r.send(pb.Message{To: m.From, Type: pb.MsgVoteResp, Reject: true}) } + case pb.MsgTransferLeader: + if r.lead == None { + r.logger.Infof("%x no leader at term %d; dropping leader transfer msg", r.id, r.Term) + return + } + m.To = r.lead + r.send(m) case pb.MsgTimeoutNow: r.logger.Infof("%x [term %d] received MsgTimeoutNow from %x and starts an election to get leadership.", r.id, r.Term, m.From) r.campaign(campaignTransfer) diff --git a/vendor/src/github.com/coreos/etcd/raft/storage.go b/vendor/src/github.com/coreos/etcd/raft/storage.go index 4b18842fae..57a525e390 100644 --- a/vendor/src/github.com/coreos/etcd/raft/storage.go +++ b/vendor/src/github.com/coreos/etcd/raft/storage.go @@ -130,6 +130,9 @@ func (ms *MemoryStorage) Term(i uint64) (uint64, error) { if i < offset { return 0, ErrCompacted } + if int(i-offset) >= len(ms.ents) { + return 0, ErrUnavailable + } return ms.ents[i-offset].Term, nil } diff --git a/vendor/src/github.com/coreos/etcd/raft/util.go b/vendor/src/github.com/coreos/etcd/raft/util.go index c57855a174..0db0730036 100644 --- a/vendor/src/github.com/coreos/etcd/raft/util.go +++ b/vendor/src/github.com/coreos/etcd/raft/util.go @@ -48,7 +48,7 @@ func max(a, b uint64) uint64 { func IsLocalMsg(msgt pb.MessageType) bool { return msgt == pb.MsgHup || msgt == pb.MsgBeat || msgt == pb.MsgUnreachable || - msgt == pb.MsgSnapStatus || msgt == pb.MsgCheckQuorum || msgt == pb.MsgTransferLeader + msgt == pb.MsgSnapStatus || msgt == pb.MsgCheckQuorum } func IsResponseMsg(msgt pb.MessageType) bool { diff --git a/vendor/src/github.com/coreos/etcd/wal/wal.go b/vendor/src/github.com/coreos/etcd/wal/wal.go index ad1acb600c..13193c064a 100644 --- a/vendor/src/github.com/coreos/etcd/wal/wal.go +++ b/vendor/src/github.com/coreos/etcd/wal/wal.go @@ -131,22 +131,7 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { return nil, err } - // rename of directory with locked files doesn't work on windows; close - // the WAL to release the locks so the directory can be renamed - w.Close() - if err := os.Rename(tmpdirpath, dirpath); err != nil { - return nil, err - } - // reopen and relock - newWAL, oerr := Open(dirpath, walpb.Snapshot{}) - if oerr != nil { - return nil, oerr - } - if _, _, _, err := newWAL.ReadAll(); err != nil { - newWAL.Close() - return nil, err - } - return newWAL, nil + return w.renameWal(tmpdirpath) } // Open opens the WAL at the given snap. @@ -301,6 +286,18 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. state.Reset() return nil, state, nil, err } + // decodeRecord() will return io.EOF if it detects a zero record, + // but this zero record may be followed by non-zero records from + // a torn write. Overwriting some of these non-zero records, but + // not all, will cause CRC errors on WAL open. Since the records + // were never fully synced to disk in the first place, it's safe + // to zero them out to avoid any CRC errors from new writes. + if _, err = w.tail().Seek(w.decoder.lastOffset(), os.SEEK_SET); err != nil { + return nil, state, nil, err + } + if err = fileutil.ZeroToEnd(w.tail().File); err != nil { + return nil, state, nil, err + } } err = nil @@ -319,7 +316,6 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. if w.tail() != nil { // create encoder (chain crc with the decoder), enable appending - _, err = w.tail().Seek(w.decoder.lastOffset(), os.SEEK_SET) w.encoder = newEncoder(w.tail(), w.decoder.lastCRC()) } w.decoder = nil diff --git a/vendor/src/github.com/coreos/etcd/wal/wal_unix.go b/vendor/src/github.com/coreos/etcd/wal/wal_unix.go new file mode 100644 index 0000000000..101ea6acc3 --- /dev/null +++ b/vendor/src/github.com/coreos/etcd/wal/wal_unix.go @@ -0,0 +1,38 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +package wal + +import "os" + +func (w *WAL) renameWal(tmpdirpath string) (*WAL, error) { + // On non-Windows platforms, hold the lock while renaming. Releasing + // the lock and trying to reacquire it quickly can be flaky because + // it's possible the process will fork to spawn a process while this is + // happening. The fds are set up as close-on-exec by the Go runtime, + // but there is a window between the fork and the exec where another + // process holds the lock. + + if err := os.RemoveAll(w.dir); err != nil { + return nil, err + } + if err := os.Rename(tmpdirpath, w.dir); err != nil { + return nil, err + } + + w.fp = newFilePipeline(w.dir, SegmentSizeBytes) + return w, nil +} diff --git a/vendor/src/github.com/coreos/etcd/wal/wal_windows.go b/vendor/src/github.com/coreos/etcd/wal/wal_windows.go new file mode 100644 index 0000000000..0b9e434cf5 --- /dev/null +++ b/vendor/src/github.com/coreos/etcd/wal/wal_windows.go @@ -0,0 +1,41 @@ +// Copyright 2016 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package wal + +import ( + "os" + + "github.com/coreos/etcd/wal/walpb" +) + +func (w *WAL) renameWal(tmpdirpath string) (*WAL, error) { + // rename of directory with locked files doesn't work on + // windows; close the WAL to release the locks so the directory + // can be renamed + w.Close() + if err := os.Rename(tmpdirpath, w.dir); err != nil { + return nil, err + } + // reopen and relock + newWAL, oerr := Open(w.dir, walpb.Snapshot{}) + if oerr != nil { + return nil, oerr + } + if _, _, _, err := newWAL.ReadAll(); err != nil { + newWAL.Close() + return nil, err + } + return newWAL, nil +} diff --git a/vendor/src/github.com/docker/engine-api/client/checkpoint_create.go b/vendor/src/github.com/docker/engine-api/client/checkpoint_create.go deleted file mode 100644 index 23883cc06c..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/checkpoint_create.go +++ /dev/null @@ -1,13 +0,0 @@ -package client - -import ( - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// CheckpointCreate creates a checkpoint from the given container with the given name -func (cli *Client) CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error { - resp, err := cli.post(ctx, "/containers/"+container+"/checkpoints", nil, options, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/checkpoint_delete.go b/vendor/src/github.com/docker/engine-api/client/checkpoint_delete.go deleted file mode 100644 index a4e9ed0c06..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/checkpoint_delete.go +++ /dev/null @@ -1,12 +0,0 @@ -package client - -import ( - "golang.org/x/net/context" -) - -// CheckpointDelete deletes the checkpoint with the given name from the given container -func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, checkpointID string) error { - resp, err := cli.delete(ctx, "/containers/"+containerID+"/checkpoints/"+checkpointID, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/checkpoint_list.go b/vendor/src/github.com/docker/engine-api/client/checkpoint_list.go deleted file mode 100644 index ef5ec261b6..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/checkpoint_list.go +++ /dev/null @@ -1,22 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// CheckpointList returns the volumes configured in the docker host. -func (cli *Client) CheckpointList(ctx context.Context, container string) ([]types.Checkpoint, error) { - var checkpoints []types.Checkpoint - - resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", nil, nil) - if err != nil { - return checkpoints, err - } - - err = json.NewDecoder(resp.body).Decode(&checkpoints) - ensureReaderClosed(resp) - return checkpoints, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/client.go b/vendor/src/github.com/docker/engine-api/client/client.go deleted file mode 100644 index 02a70bab75..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/client.go +++ /dev/null @@ -1,156 +0,0 @@ -package client - -import ( - "fmt" - "net/http" - "net/url" - "os" - "path/filepath" - "strings" - - "github.com/docker/engine-api/client/transport" - "github.com/docker/go-connections/tlsconfig" -) - -// DefaultVersion is the version of the current stable API -const DefaultVersion string = "1.23" - -// Client is the API client that performs all operations -// against a docker server. -type Client struct { - // host holds the server address to connect to - host string - // proto holds the client protocol i.e. unix. - proto string - // addr holds the client address. - addr string - // basePath holds the path to prepend to the requests. - basePath string - // transport is the interface to send request with, it implements transport.Client. - transport transport.Client - // version of the server to talk to. - version string - // custom http headers configured by users. - customHTTPHeaders map[string]string -} - -// NewEnvClient initializes a new API client based on environment variables. -// Use DOCKER_HOST to set the url to the docker server. -// Use DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest. -// Use DOCKER_CERT_PATH to load the tls certificates from. -// Use DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default. -func NewEnvClient() (*Client, error) { - var client *http.Client - if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" { - options := tlsconfig.Options{ - CAFile: filepath.Join(dockerCertPath, "ca.pem"), - CertFile: filepath.Join(dockerCertPath, "cert.pem"), - KeyFile: filepath.Join(dockerCertPath, "key.pem"), - InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "", - } - tlsc, err := tlsconfig.Client(options) - if err != nil { - return nil, err - } - - client = &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: tlsc, - }, - } - } - - host := os.Getenv("DOCKER_HOST") - if host == "" { - host = DefaultDockerHost - } - - version := os.Getenv("DOCKER_API_VERSION") - if version == "" { - version = DefaultVersion - } - - return NewClient(host, version, client, nil) -} - -// NewClient initializes a new API client for the given host and API version. -// It uses the given http client as transport. -// It also initializes the custom http headers to add to each request. -// -// It won't send any version information if the version number is empty. It is -// highly recommended that you set a version or your client may break if the -// server is upgraded. -func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) { - proto, addr, basePath, err := ParseHost(host) - if err != nil { - return nil, err - } - - transport, err := transport.NewTransportWithHTTP(proto, addr, client) - if err != nil { - return nil, err - } - - return &Client{ - host: host, - proto: proto, - addr: addr, - basePath: basePath, - transport: transport, - version: version, - customHTTPHeaders: httpHeaders, - }, nil -} - -// getAPIPath returns the versioned request path to call the api. -// It appends the query parameters to the path if they are not empty. -func (cli *Client) getAPIPath(p string, query url.Values) string { - var apiPath string - if cli.version != "" { - v := strings.TrimPrefix(cli.version, "v") - apiPath = fmt.Sprintf("%s/v%s%s", cli.basePath, v, p) - } else { - apiPath = fmt.Sprintf("%s%s", cli.basePath, p) - } - - u := &url.URL{ - Path: apiPath, - } - if len(query) > 0 { - u.RawQuery = query.Encode() - } - return u.String() -} - -// ClientVersion returns the version string associated with this -// instance of the Client. Note that this value can be changed -// via the DOCKER_API_VERSION env var. -func (cli *Client) ClientVersion() string { - return cli.version -} - -// UpdateClientVersion updates the version string associated with this -// instance of the Client. -func (cli *Client) UpdateClientVersion(v string) { - cli.version = v -} - -// ParseHost verifies that the given host strings is valid. -func ParseHost(host string) (string, string, string, error) { - protoAddrParts := strings.SplitN(host, "://", 2) - if len(protoAddrParts) == 1 { - return "", "", "", fmt.Errorf("unable to parse docker host `%s`", host) - } - - var basePath string - proto, addr := protoAddrParts[0], protoAddrParts[1] - if proto == "tcp" { - parsed, err := url.Parse("tcp://" + addr) - if err != nil { - return "", "", "", err - } - addr = parsed.Host - basePath = parsed.Path - } - return proto, addr, basePath, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/client_unix.go b/vendor/src/github.com/docker/engine-api/client/client_unix.go deleted file mode 100644 index 89de892c85..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/client_unix.go +++ /dev/null @@ -1,6 +0,0 @@ -// +build linux freebsd solaris openbsd darwin - -package client - -// DefaultDockerHost defines os specific default if DOCKER_HOST is unset -const DefaultDockerHost = "unix:///var/run/docker.sock" diff --git a/vendor/src/github.com/docker/engine-api/client/client_windows.go b/vendor/src/github.com/docker/engine-api/client/client_windows.go deleted file mode 100644 index 07c0c7a774..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/client_windows.go +++ /dev/null @@ -1,4 +0,0 @@ -package client - -// DefaultDockerHost defines os specific default if DOCKER_HOST is unset -const DefaultDockerHost = "npipe:////./pipe/docker_engine" diff --git a/vendor/src/github.com/docker/engine-api/client/container_attach.go b/vendor/src/github.com/docker/engine-api/client/container_attach.go deleted file mode 100644 index 1b616bf038..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_attach.go +++ /dev/null @@ -1,34 +0,0 @@ -package client - -import ( - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerAttach attaches a connection to a container in the server. -// It returns a types.HijackedConnection with the hijacked connection -// and the a reader to get output. It's up to the called to close -// the hijacked connection by calling types.HijackedResponse.Close. -func (cli *Client) ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) { - query := url.Values{} - if options.Stream { - query.Set("stream", "1") - } - if options.Stdin { - query.Set("stdin", "1") - } - if options.Stdout { - query.Set("stdout", "1") - } - if options.Stderr { - query.Set("stderr", "1") - } - if options.DetachKeys != "" { - query.Set("detachKeys", options.DetachKeys) - } - - headers := map[string][]string{"Content-Type": {"text/plain"}} - return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers) -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_commit.go b/vendor/src/github.com/docker/engine-api/client/container_commit.go deleted file mode 100644 index d5c4749906..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_commit.go +++ /dev/null @@ -1,53 +0,0 @@ -package client - -import ( - "encoding/json" - "errors" - "net/url" - - distreference "github.com/docker/distribution/reference" - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/reference" - "golang.org/x/net/context" -) - -// ContainerCommit applies changes into a container and creates a new tagged image. -func (cli *Client) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) { - var repository, tag string - if options.Reference != "" { - distributionRef, err := distreference.ParseNamed(options.Reference) - if err != nil { - return types.ContainerCommitResponse{}, err - } - - if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical { - return types.ContainerCommitResponse{}, errors.New("refusing to create a tag with a digest reference") - } - - tag = reference.GetTagFromNamedRef(distributionRef) - repository = distributionRef.Name() - } - - query := url.Values{} - query.Set("container", container) - query.Set("repo", repository) - query.Set("tag", tag) - query.Set("comment", options.Comment) - query.Set("author", options.Author) - for _, change := range options.Changes { - query.Add("changes", change) - } - if options.Pause != true { - query.Set("pause", "0") - } - - var response types.ContainerCommitResponse - resp, err := cli.post(ctx, "/commit", query, options.Config, nil) - if err != nil { - return response, err - } - - err = json.NewDecoder(resp.body).Decode(&response) - ensureReaderClosed(resp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_copy.go b/vendor/src/github.com/docker/engine-api/client/container_copy.go deleted file mode 100644 index d3dd0b116c..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_copy.go +++ /dev/null @@ -1,97 +0,0 @@ -package client - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "path/filepath" - "strings" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" -) - -// ContainerStatPath returns Stat information about a path inside the container filesystem. -func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) { - query := url.Values{} - query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. - - urlStr := fmt.Sprintf("/containers/%s/archive", containerID) - response, err := cli.head(ctx, urlStr, query, nil) - if err != nil { - return types.ContainerPathStat{}, err - } - defer ensureReaderClosed(response) - return getContainerPathStatFromHeader(response.header) -} - -// CopyToContainer copies content into the container filesystem. -func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error { - query := url.Values{} - query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. - // Do not allow for an existing directory to be overwritten by a non-directory and vice versa. - if !options.AllowOverwriteDirWithFile { - query.Set("noOverwriteDirNonDir", "true") - } - - apiPath := fmt.Sprintf("/containers/%s/archive", container) - - response, err := cli.putRaw(ctx, apiPath, query, content, nil) - if err != nil { - return err - } - defer ensureReaderClosed(response) - - if response.statusCode != http.StatusOK { - return fmt.Errorf("unexpected status code from daemon: %d", response.statusCode) - } - - return nil -} - -// CopyFromContainer gets the content from the container and returns it as a Reader -// to manipulate it in the host. It's up to the caller to close the reader. -func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { - query := make(url.Values, 1) - query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. - - apiPath := fmt.Sprintf("/containers/%s/archive", container) - response, err := cli.get(ctx, apiPath, query, nil) - if err != nil { - return nil, types.ContainerPathStat{}, err - } - - if response.statusCode != http.StatusOK { - return nil, types.ContainerPathStat{}, fmt.Errorf("unexpected status code from daemon: %d", response.statusCode) - } - - // In order to get the copy behavior right, we need to know information - // about both the source and the destination. The response headers include - // stat info about the source that we can use in deciding exactly how to - // copy it locally. Along with the stat info about the local destination, - // we have everything we need to handle the multiple possibilities there - // can be when copying a file/dir from one location to another file/dir. - stat, err := getContainerPathStatFromHeader(response.header) - if err != nil { - return nil, stat, fmt.Errorf("unable to get resource stat from response: %s", err) - } - return response.body, stat, err -} - -func getContainerPathStatFromHeader(header http.Header) (types.ContainerPathStat, error) { - var stat types.ContainerPathStat - - encodedStat := header.Get("X-Docker-Container-Path-Stat") - statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat)) - - err := json.NewDecoder(statDecoder).Decode(&stat) - if err != nil { - err = fmt.Errorf("unable to decode container path stat header: %s", err) - } - - return stat, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_create.go b/vendor/src/github.com/docker/engine-api/client/container_create.go deleted file mode 100644 index bbef1c94bb..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_create.go +++ /dev/null @@ -1,46 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - "strings" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/container" - "github.com/docker/engine-api/types/network" - "golang.org/x/net/context" -) - -type configWrapper struct { - *container.Config - HostConfig *container.HostConfig - NetworkingConfig *network.NetworkingConfig -} - -// ContainerCreate creates a new container based in the given configuration. -// It can be associated with a name, but it's not mandatory. -func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (types.ContainerCreateResponse, error) { - var response types.ContainerCreateResponse - query := url.Values{} - if containerName != "" { - query.Set("name", containerName) - } - - body := configWrapper{ - Config: config, - HostConfig: hostConfig, - NetworkingConfig: networkingConfig, - } - - serverResp, err := cli.post(ctx, "/containers/create", query, body, nil) - if err != nil { - if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") { - return response, imageNotFoundError{config.Image} - } - return response, err - } - - err = json.NewDecoder(serverResp.body).Decode(&response) - ensureReaderClosed(serverResp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_diff.go b/vendor/src/github.com/docker/engine-api/client/container_diff.go deleted file mode 100644 index f4bb3a46b9..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_diff.go +++ /dev/null @@ -1,23 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerDiff shows differences in a container filesystem since it was started. -func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]types.ContainerChange, error) { - var changes []types.ContainerChange - - serverResp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil) - if err != nil { - return changes, err - } - - err = json.NewDecoder(serverResp.body).Decode(&changes) - ensureReaderClosed(serverResp) - return changes, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_exec.go b/vendor/src/github.com/docker/engine-api/client/container_exec.go deleted file mode 100644 index ff7e1a9d05..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_exec.go +++ /dev/null @@ -1,49 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerExecCreate creates a new exec configuration to run an exec process. -func (cli *Client) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.ContainerExecCreateResponse, error) { - var response types.ContainerExecCreateResponse - resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, config, nil) - if err != nil { - return response, err - } - err = json.NewDecoder(resp.body).Decode(&response) - ensureReaderClosed(resp) - return response, err -} - -// ContainerExecStart starts an exec process already created in the docker host. -func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error { - resp, err := cli.post(ctx, "/exec/"+execID+"/start", nil, config, nil) - ensureReaderClosed(resp) - return err -} - -// ContainerExecAttach attaches a connection to an exec process in the server. -// It returns a types.HijackedConnection with the hijacked connection -// and the a reader to get output. It's up to the called to close -// the hijacked connection by calling types.HijackedResponse.Close. -func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error) { - headers := map[string][]string{"Content-Type": {"application/json"}} - return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers) -} - -// ContainerExecInspect returns information about a specific exec process on the docker host. -func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) { - var response types.ContainerExecInspect - resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil) - if err != nil { - return response, err - } - - err = json.NewDecoder(resp.body).Decode(&response) - ensureReaderClosed(resp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_export.go b/vendor/src/github.com/docker/engine-api/client/container_export.go deleted file mode 100644 index 52194f3d34..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_export.go +++ /dev/null @@ -1,20 +0,0 @@ -package client - -import ( - "io" - "net/url" - - "golang.org/x/net/context" -) - -// ContainerExport retrieves the raw contents of a container -// and returns them as an io.ReadCloser. It's up to the caller -// to close the stream. -func (cli *Client) ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error) { - serverResp, err := cli.get(ctx, "/containers/"+containerID+"/export", url.Values{}, nil) - if err != nil { - return nil, err - } - - return serverResp.body, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_inspect.go b/vendor/src/github.com/docker/engine-api/client/container_inspect.go deleted file mode 100644 index 0fa096d38f..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_inspect.go +++ /dev/null @@ -1,54 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerInspect returns the container information. -func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) { - serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil) - if err != nil { - if serverResp.statusCode == http.StatusNotFound { - return types.ContainerJSON{}, containerNotFoundError{containerID} - } - return types.ContainerJSON{}, err - } - - var response types.ContainerJSON - err = json.NewDecoder(serverResp.body).Decode(&response) - ensureReaderClosed(serverResp) - return response, err -} - -// ContainerInspectWithRaw returns the container information and its raw representation. -func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) { - query := url.Values{} - if getSize { - query.Set("size", "1") - } - serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil) - if err != nil { - if serverResp.statusCode == http.StatusNotFound { - return types.ContainerJSON{}, nil, containerNotFoundError{containerID} - } - return types.ContainerJSON{}, nil, err - } - defer ensureReaderClosed(serverResp) - - body, err := ioutil.ReadAll(serverResp.body) - if err != nil { - return types.ContainerJSON{}, nil, err - } - - var response types.ContainerJSON - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&response) - return response, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_kill.go b/vendor/src/github.com/docker/engine-api/client/container_kill.go deleted file mode 100644 index 29f80c73ad..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_kill.go +++ /dev/null @@ -1,17 +0,0 @@ -package client - -import ( - "net/url" - - "golang.org/x/net/context" -) - -// ContainerKill terminates the container process but does not remove the container from the docker host. -func (cli *Client) ContainerKill(ctx context.Context, containerID, signal string) error { - query := url.Values{} - query.Set("signal", signal) - - resp, err := cli.post(ctx, "/containers/"+containerID+"/kill", query, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_list.go b/vendor/src/github.com/docker/engine-api/client/container_list.go deleted file mode 100644 index 87f7333dc7..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_list.go +++ /dev/null @@ -1,56 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - "strconv" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "golang.org/x/net/context" -) - -// ContainerList returns the list of containers in the docker host. -func (cli *Client) ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) { - query := url.Values{} - - if options.All { - query.Set("all", "1") - } - - if options.Limit != -1 { - query.Set("limit", strconv.Itoa(options.Limit)) - } - - if options.Since != "" { - query.Set("since", options.Since) - } - - if options.Before != "" { - query.Set("before", options.Before) - } - - if options.Size { - query.Set("size", "1") - } - - if options.Filter.Len() > 0 { - filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filter) - - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - - resp, err := cli.get(ctx, "/containers/json", query, nil) - if err != nil { - return nil, err - } - - var containers []types.Container - err = json.NewDecoder(resp.body).Decode(&containers) - ensureReaderClosed(resp) - return containers, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_logs.go b/vendor/src/github.com/docker/engine-api/client/container_logs.go deleted file mode 100644 index 08b9b91876..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_logs.go +++ /dev/null @@ -1,52 +0,0 @@ -package client - -import ( - "io" - "net/url" - "time" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" - timetypes "github.com/docker/engine-api/types/time" -) - -// ContainerLogs returns the logs generated by a container in an io.ReadCloser. -// It's up to the caller to close the stream. -func (cli *Client) ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) { - query := url.Values{} - if options.ShowStdout { - query.Set("stdout", "1") - } - - if options.ShowStderr { - query.Set("stderr", "1") - } - - if options.Since != "" { - ts, err := timetypes.GetTimestamp(options.Since, time.Now()) - if err != nil { - return nil, err - } - query.Set("since", ts) - } - - if options.Timestamps { - query.Set("timestamps", "1") - } - - if options.Details { - query.Set("details", "1") - } - - if options.Follow { - query.Set("follow", "1") - } - query.Set("tail", options.Tail) - - resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil) - if err != nil { - return nil, err - } - return resp.body, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_pause.go b/vendor/src/github.com/docker/engine-api/client/container_pause.go deleted file mode 100644 index 412067a782..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_pause.go +++ /dev/null @@ -1,10 +0,0 @@ -package client - -import "golang.org/x/net/context" - -// ContainerPause pauses the main process of a given container without terminating it. -func (cli *Client) ContainerPause(ctx context.Context, containerID string) error { - resp, err := cli.post(ctx, "/containers/"+containerID+"/pause", nil, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_remove.go b/vendor/src/github.com/docker/engine-api/client/container_remove.go deleted file mode 100644 index cef4b81220..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_remove.go +++ /dev/null @@ -1,27 +0,0 @@ -package client - -import ( - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerRemove kills and removes a container from the docker host. -func (cli *Client) ContainerRemove(ctx context.Context, containerID string, options types.ContainerRemoveOptions) error { - query := url.Values{} - if options.RemoveVolumes { - query.Set("v", "1") - } - if options.RemoveLinks { - query.Set("link", "1") - } - - if options.Force { - query.Set("force", "1") - } - - resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_rename.go b/vendor/src/github.com/docker/engine-api/client/container_rename.go deleted file mode 100644 index 0e718da7c6..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_rename.go +++ /dev/null @@ -1,16 +0,0 @@ -package client - -import ( - "net/url" - - "golang.org/x/net/context" -) - -// ContainerRename changes the name of a given container. -func (cli *Client) ContainerRename(ctx context.Context, containerID, newContainerName string) error { - query := url.Values{} - query.Set("name", newContainerName) - resp, err := cli.post(ctx, "/containers/"+containerID+"/rename", query, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_resize.go b/vendor/src/github.com/docker/engine-api/client/container_resize.go deleted file mode 100644 index b95d26b335..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_resize.go +++ /dev/null @@ -1,29 +0,0 @@ -package client - -import ( - "net/url" - "strconv" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerResize changes the size of the tty for a container. -func (cli *Client) ContainerResize(ctx context.Context, containerID string, options types.ResizeOptions) error { - return cli.resize(ctx, "/containers/"+containerID, options.Height, options.Width) -} - -// ContainerExecResize changes the size of the tty for an exec process running inside a container. -func (cli *Client) ContainerExecResize(ctx context.Context, execID string, options types.ResizeOptions) error { - return cli.resize(ctx, "/exec/"+execID, options.Height, options.Width) -} - -func (cli *Client) resize(ctx context.Context, basePath string, height, width int) error { - query := url.Values{} - query.Set("h", strconv.Itoa(height)) - query.Set("w", strconv.Itoa(width)) - - resp, err := cli.post(ctx, basePath+"/resize", query, nil, nil) - ensureReaderClosed(resp) - return err -} 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 deleted file mode 100644 index 93c042d085..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_restart.go +++ /dev/null @@ -1,22 +0,0 @@ -package client - -import ( - "net/url" - "time" - - timetypes "github.com/docker/engine-api/types/time" - "golang.org/x/net/context" -) - -// 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 { - query := url.Values{} - 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_start.go b/vendor/src/github.com/docker/engine-api/client/container_start.go deleted file mode 100644 index 1e22eec641..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_start.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "net/url" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" -) - -// ContainerStart sends a request to the docker daemon to start a container. -func (cli *Client) ContainerStart(ctx context.Context, containerID string, options types.ContainerStartOptions) error { - query := url.Values{} - if len(options.CheckpointID) != 0 { - query.Set("checkpoint", options.CheckpointID) - } - - resp, err := cli.post(ctx, "/containers/"+containerID+"/start", query, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_stats.go b/vendor/src/github.com/docker/engine-api/client/container_stats.go deleted file mode 100644 index 2cc67c3af1..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_stats.go +++ /dev/null @@ -1,24 +0,0 @@ -package client - -import ( - "io" - "net/url" - - "golang.org/x/net/context" -) - -// ContainerStats returns near realtime stats for a given container. -// It's up to the caller to close the io.ReadCloser returned. -func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error) { - query := url.Values{} - query.Set("stream", "0") - if stream { - query.Set("stream", "1") - } - - resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) - if err != nil { - return nil, err - } - return resp.body, 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 deleted file mode 100644 index 1fc577f2b9..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_stop.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "net/url" - "time" - - timetypes "github.com/docker/engine-api/types/time" - "golang.org/x/net/context" -) - -// 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 { - query := url.Values{} - 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/container_top.go b/vendor/src/github.com/docker/engine-api/client/container_top.go deleted file mode 100644 index 5ad926ae08..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_top.go +++ /dev/null @@ -1,28 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - "strings" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ContainerTop shows process information from within a container. -func (cli *Client) ContainerTop(ctx context.Context, containerID string, arguments []string) (types.ContainerProcessList, error) { - var response types.ContainerProcessList - query := url.Values{} - if len(arguments) > 0 { - query.Set("ps_args", strings.Join(arguments, " ")) - } - - resp, err := cli.get(ctx, "/containers/"+containerID+"/top", query, nil) - if err != nil { - return response, err - } - - err = json.NewDecoder(resp.body).Decode(&response) - ensureReaderClosed(resp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_unpause.go b/vendor/src/github.com/docker/engine-api/client/container_unpause.go deleted file mode 100644 index 5c76211256..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_unpause.go +++ /dev/null @@ -1,10 +0,0 @@ -package client - -import "golang.org/x/net/context" - -// ContainerUnpause resumes the process execution within a container -func (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error { - resp, err := cli.post(ctx, "/containers/"+containerID+"/unpause", nil, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_update.go b/vendor/src/github.com/docker/engine-api/client/container_update.go deleted file mode 100644 index 92e1f2771d..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_update.go +++ /dev/null @@ -1,23 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/container" - "golang.org/x/net/context" -) - -// ContainerUpdate updates resources of a container -func (cli *Client) ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) (types.ContainerUpdateResponse, error) { - var response types.ContainerUpdateResponse - serverResp, err := cli.post(ctx, "/containers/"+containerID+"/update", nil, updateConfig, nil) - if err != nil { - return response, err - } - - err = json.NewDecoder(serverResp.body).Decode(&response) - - ensureReaderClosed(serverResp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/container_wait.go b/vendor/src/github.com/docker/engine-api/client/container_wait.go deleted file mode 100644 index c26ff3f378..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/container_wait.go +++ /dev/null @@ -1,26 +0,0 @@ -package client - -import ( - "encoding/json" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" -) - -// ContainerWait pauses execution until a container exits. -// It returns the API status code as response of its readiness. -func (cli *Client) ContainerWait(ctx context.Context, containerID string) (int, error) { - resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", nil, nil, nil) - if err != nil { - return -1, err - } - defer ensureReaderClosed(resp) - - var res types.ContainerWaitResponse - if err := json.NewDecoder(resp.body).Decode(&res); err != nil { - return -1, err - } - - return res.StatusCode, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/errors.go b/vendor/src/github.com/docker/engine-api/client/errors.go deleted file mode 100644 index 71e25a7ae1..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/errors.go +++ /dev/null @@ -1,208 +0,0 @@ -package client - -import ( - "errors" - "fmt" -) - -// ErrConnectionFailed is an error raised when the connection between the client and the server failed. -var ErrConnectionFailed = errors.New("Cannot connect to the Docker daemon. Is the docker daemon running on this host?") - -// ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed. -func ErrorConnectionFailed(host string) error { - return fmt.Errorf("Cannot connect to the Docker daemon at %s. Is the docker daemon running?", host) -} - -type notFound interface { - error - NotFound() bool // Is the error a NotFound error -} - -// IsErrNotFound returns true if the error is caused with an -// object (image, container, network, volume, …) is not found in the docker host. -func IsErrNotFound(err error) bool { - te, ok := err.(notFound) - return ok && te.NotFound() -} - -// imageNotFoundError implements an error returned when an image is not in the docker host. -type imageNotFoundError struct { - imageID string -} - -// NoFound indicates that this error type is of NotFound -func (e imageNotFoundError) NotFound() bool { - return true -} - -// Error returns a string representation of an imageNotFoundError -func (e imageNotFoundError) Error() string { - return fmt.Sprintf("Error: No such image: %s", e.imageID) -} - -// IsErrImageNotFound returns true if the error is caused -// when an image is not found in the docker host. -func IsErrImageNotFound(err error) bool { - return IsErrNotFound(err) -} - -// containerNotFoundError implements an error returned when a container is not in the docker host. -type containerNotFoundError struct { - containerID string -} - -// NoFound indicates that this error type is of NotFound -func (e containerNotFoundError) NotFound() bool { - return true -} - -// Error returns a string representation of a containerNotFoundError -func (e containerNotFoundError) Error() string { - return fmt.Sprintf("Error: No such container: %s", e.containerID) -} - -// IsErrContainerNotFound returns true if the error is caused -// when a container is not found in the docker host. -func IsErrContainerNotFound(err error) bool { - return IsErrNotFound(err) -} - -// networkNotFoundError implements an error returned when a network is not in the docker host. -type networkNotFoundError struct { - networkID string -} - -// NoFound indicates that this error type is of NotFound -func (e networkNotFoundError) NotFound() bool { - return true -} - -// Error returns a string representation of a networkNotFoundError -func (e networkNotFoundError) Error() string { - return fmt.Sprintf("Error: No such network: %s", e.networkID) -} - -// IsErrNetworkNotFound returns true if the error is caused -// when a network is not found in the docker host. -func IsErrNetworkNotFound(err error) bool { - return IsErrNotFound(err) -} - -// volumeNotFoundError implements an error returned when a volume is not in the docker host. -type volumeNotFoundError struct { - volumeID string -} - -// NoFound indicates that this error type is of NotFound -func (e volumeNotFoundError) NotFound() bool { - return true -} - -// Error returns a string representation of a networkNotFoundError -func (e volumeNotFoundError) Error() string { - return fmt.Sprintf("Error: No such volume: %s", e.volumeID) -} - -// IsErrVolumeNotFound returns true if the error is caused -// when a volume is not found in the docker host. -func IsErrVolumeNotFound(err error) bool { - return IsErrNotFound(err) -} - -// unauthorizedError represents an authorization error in a remote registry. -type unauthorizedError struct { - cause error -} - -// Error returns a string representation of an unauthorizedError -func (u unauthorizedError) Error() string { - return u.cause.Error() -} - -// IsErrUnauthorized returns true if the error is caused -// when a remote registry authentication fails -func IsErrUnauthorized(err error) bool { - _, ok := err.(unauthorizedError) - return ok -} - -// nodeNotFoundError implements an error returned when a node is not found. -type nodeNotFoundError struct { - nodeID string -} - -// Error returns a string representation of a nodeNotFoundError -func (e nodeNotFoundError) Error() string { - return fmt.Sprintf("Error: No such node: %s", e.nodeID) -} - -// NoFound indicates that this error type is of NotFound -func (e nodeNotFoundError) NotFound() bool { - return true -} - -// IsErrNodeNotFound returns true if the error is caused -// when a node is not found. -func IsErrNodeNotFound(err error) bool { - _, ok := err.(nodeNotFoundError) - return ok -} - -// serviceNotFoundError implements an error returned when a service is not found. -type serviceNotFoundError struct { - serviceID string -} - -// Error returns a string representation of a serviceNotFoundError -func (e serviceNotFoundError) Error() string { - return fmt.Sprintf("Error: No such service: %s", e.serviceID) -} - -// NoFound indicates that this error type is of NotFound -func (e serviceNotFoundError) NotFound() bool { - return true -} - -// IsErrServiceNotFound returns true if the error is caused -// when a service is not found. -func IsErrServiceNotFound(err error) bool { - _, ok := err.(serviceNotFoundError) - return ok -} - -// taskNotFoundError implements an error returned when a task is not found. -type taskNotFoundError struct { - taskID string -} - -// Error returns a string representation of a taskNotFoundError -func (e taskNotFoundError) Error() string { - return fmt.Sprintf("Error: No such task: %s", e.taskID) -} - -// NoFound indicates that this error type is of NotFound -func (e taskNotFoundError) NotFound() bool { - return true -} - -// IsErrTaskNotFound returns true if the error is caused -// when a task is not found. -func IsErrTaskNotFound(err error) bool { - _, ok := err.(taskNotFoundError) - return ok -} - -type pluginPermissionDenied struct { - name string -} - -func (e pluginPermissionDenied) Error() string { - return "Permission denied while installing plugin " + e.name -} - -// IsErrPluginPermissionDenied returns true if the error is caused -// when a user denies a plugin's permissions -func IsErrPluginPermissionDenied(err error) bool { - _, ok := err.(pluginPermissionDenied) - return ok -} diff --git a/vendor/src/github.com/docker/engine-api/client/events.go b/vendor/src/github.com/docker/engine-api/client/events.go deleted file mode 100644 index f22a18e1d3..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/events.go +++ /dev/null @@ -1,48 +0,0 @@ -package client - -import ( - "io" - "net/url" - "time" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - timetypes "github.com/docker/engine-api/types/time" -) - -// Events returns a stream of events in the daemon in a ReadCloser. -// It's up to the caller to close the stream. -func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (io.ReadCloser, error) { - query := url.Values{} - ref := time.Now() - - if options.Since != "" { - ts, err := timetypes.GetTimestamp(options.Since, ref) - if err != nil { - return nil, err - } - query.Set("since", ts) - } - if options.Until != "" { - ts, err := timetypes.GetTimestamp(options.Until, ref) - if err != nil { - return nil, err - } - query.Set("until", ts) - } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } - - serverResponse, err := cli.get(ctx, "/events", query, nil) - if err != nil { - return nil, err - } - return serverResponse.body, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/hijack.go b/vendor/src/github.com/docker/engine-api/client/hijack.go deleted file mode 100644 index dbd91ef629..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/hijack.go +++ /dev/null @@ -1,174 +0,0 @@ -package client - -import ( - "crypto/tls" - "errors" - "fmt" - "net" - "net/http/httputil" - "net/url" - "strings" - "time" - - "github.com/docker/engine-api/types" - "github.com/docker/go-connections/sockets" - "golang.org/x/net/context" -) - -// tlsClientCon holds tls information and a dialed connection. -type tlsClientCon struct { - *tls.Conn - rawConn net.Conn -} - -func (c *tlsClientCon) CloseWrite() error { - // Go standard tls.Conn doesn't provide the CloseWrite() method so we do it - // on its underlying connection. - if conn, ok := c.rawConn.(types.CloseWriter); ok { - return conn.CloseWrite() - } - return nil -} - -// postHijacked sends a POST request and hijacks the connection. -func (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) { - bodyEncoded, err := encodeData(body) - if err != nil { - return types.HijackedResponse{}, err - } - - req, err := cli.newRequest("POST", path, query, bodyEncoded, headers) - if err != nil { - return types.HijackedResponse{}, err - } - req.Host = cli.addr - - req.Header.Set("Connection", "Upgrade") - req.Header.Set("Upgrade", "tcp") - - conn, err := dial(cli.proto, cli.addr, cli.transport.TLSConfig()) - if err != nil { - if strings.Contains(err.Error(), "connection refused") { - return types.HijackedResponse{}, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?") - } - return types.HijackedResponse{}, err - } - - // When we set up a TCP connection for hijack, there could be long periods - // of inactivity (a long running command with no output) that in certain - // network setups may cause ECONNTIMEOUT, leaving the client in an unknown - // state. Setting TCP KeepAlive on the socket connection will prohibit - // ECONNTIMEOUT unless the socket connection truly is broken - if tcpConn, ok := conn.(*net.TCPConn); ok { - tcpConn.SetKeepAlive(true) - tcpConn.SetKeepAlivePeriod(30 * time.Second) - } - - clientconn := httputil.NewClientConn(conn, nil) - defer clientconn.Close() - - // Server hijacks the connection, error 'connection closed' expected - _, err = clientconn.Do(req) - - rwc, br := clientconn.Hijack() - - return types.HijackedResponse{Conn: rwc, Reader: br}, err -} - -func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) { - return tlsDialWithDialer(new(net.Dialer), network, addr, config) -} - -// We need to copy Go's implementation of tls.Dial (pkg/cryptor/tls/tls.go) in -// order to return our custom tlsClientCon struct which holds both the tls.Conn -// object _and_ its underlying raw connection. The rationale for this is that -// we need to be able to close the write end of the connection when attaching, -// which tls.Conn does not provide. -func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) { - // We want the Timeout and Deadline values from dialer to cover the - // whole process: TCP connection and TLS handshake. This means that we - // also need to start our own timers now. - timeout := dialer.Timeout - - if !dialer.Deadline.IsZero() { - deadlineTimeout := dialer.Deadline.Sub(time.Now()) - if timeout == 0 || deadlineTimeout < timeout { - timeout = deadlineTimeout - } - } - - var errChannel chan error - - if timeout != 0 { - errChannel = make(chan error, 2) - time.AfterFunc(timeout, func() { - errChannel <- errors.New("") - }) - } - - proxyDialer, err := sockets.DialerFromEnvironment(dialer) - if err != nil { - return nil, err - } - - rawConn, err := proxyDialer.Dial(network, addr) - if err != nil { - return nil, err - } - // When we set up a TCP connection for hijack, there could be long periods - // of inactivity (a long running command with no output) that in certain - // network setups may cause ECONNTIMEOUT, leaving the client in an unknown - // state. Setting TCP KeepAlive on the socket connection will prohibit - // ECONNTIMEOUT unless the socket connection truly is broken - if tcpConn, ok := rawConn.(*net.TCPConn); ok { - tcpConn.SetKeepAlive(true) - tcpConn.SetKeepAlivePeriod(30 * time.Second) - } - - colonPos := strings.LastIndex(addr, ":") - if colonPos == -1 { - colonPos = len(addr) - } - hostname := addr[:colonPos] - - // If no ServerName is set, infer the ServerName - // from the hostname we're connecting to. - if config.ServerName == "" { - // Make a copy to avoid polluting argument or default. - c := *config - c.ServerName = hostname - config = &c - } - - conn := tls.Client(rawConn, config) - - if timeout == 0 { - err = conn.Handshake() - } else { - go func() { - errChannel <- conn.Handshake() - }() - - err = <-errChannel - } - - if err != nil { - rawConn.Close() - return nil, err - } - - // This is Docker difference with standard's crypto/tls package: returned a - // wrapper which holds both the TLS and raw connections. - return &tlsClientCon{conn, rawConn}, nil -} - -func dial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) { - if tlsConfig != nil && proto != "unix" && proto != "npipe" { - // Notice this isn't Go standard's tls.Dial function - return tlsDial(proto, addr, tlsConfig) - } - if proto == "npipe" { - return sockets.DialPipe(addr, 32*time.Second) - } - return net.Dial(proto, addr) -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_build.go b/vendor/src/github.com/docker/engine-api/client/image_build.go deleted file mode 100644 index 089d44dd5a..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_build.go +++ /dev/null @@ -1,123 +0,0 @@ -package client - -import ( - "encoding/base64" - "encoding/json" - "io" - "net/http" - "net/url" - "regexp" - "strconv" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/container" -) - -var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`) - -// ImageBuild sends request to the daemon to build images. -// The Body in the response implement an io.ReadCloser and it's up to the caller to -// close it. -func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { - query, err := imageBuildOptionsToQuery(options) - if err != nil { - return types.ImageBuildResponse{}, err - } - - headers := http.Header(make(map[string][]string)) - buf, err := json.Marshal(options.AuthConfigs) - if err != nil { - return types.ImageBuildResponse{}, err - } - headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) - headers.Set("Content-Type", "application/tar") - - serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) - if err != nil { - return types.ImageBuildResponse{}, err - } - - osType := getDockerOS(serverResp.header.Get("Server")) - - return types.ImageBuildResponse{ - Body: serverResp.body, - OSType: osType, - }, nil -} - -func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, error) { - query := url.Values{ - "t": options.Tags, - } - if options.SuppressOutput { - query.Set("q", "1") - } - if options.RemoteContext != "" { - query.Set("remote", options.RemoteContext) - } - if options.NoCache { - query.Set("nocache", "1") - } - if options.Remove { - query.Set("rm", "1") - } else { - query.Set("rm", "0") - } - - if options.ForceRemove { - query.Set("forcerm", "1") - } - - if options.PullParent { - query.Set("pull", "1") - } - - if options.Squash { - query.Set("squash", "1") - } - - if !container.Isolation.IsDefault(options.Isolation) { - query.Set("isolation", string(options.Isolation)) - } - - query.Set("cpusetcpus", options.CPUSetCPUs) - query.Set("cpusetmems", options.CPUSetMems) - query.Set("cpushares", strconv.FormatInt(options.CPUShares, 10)) - query.Set("cpuquota", strconv.FormatInt(options.CPUQuota, 10)) - query.Set("cpuperiod", strconv.FormatInt(options.CPUPeriod, 10)) - query.Set("memory", strconv.FormatInt(options.Memory, 10)) - query.Set("memswap", strconv.FormatInt(options.MemorySwap, 10)) - query.Set("cgroupparent", options.CgroupParent) - query.Set("shmsize", strconv.FormatInt(options.ShmSize, 10)) - query.Set("dockerfile", options.Dockerfile) - - ulimitsJSON, err := json.Marshal(options.Ulimits) - if err != nil { - return query, err - } - query.Set("ulimits", string(ulimitsJSON)) - - buildArgsJSON, err := json.Marshal(options.BuildArgs) - if err != nil { - return query, err - } - query.Set("buildargs", string(buildArgsJSON)) - - labelsJSON, err := json.Marshal(options.Labels) - if err != nil { - return query, err - } - query.Set("labels", string(labelsJSON)) - return query, nil -} - -func getDockerOS(serverHeader string) string { - var osType string - matches := headerRegexp.FindStringSubmatch(serverHeader) - if len(matches) > 0 { - osType = matches[1] - } - return osType -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_create.go b/vendor/src/github.com/docker/engine-api/client/image_create.go deleted file mode 100644 index 1528b0bcab..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_create.go +++ /dev/null @@ -1,34 +0,0 @@ -package client - -import ( - "io" - "net/url" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/reference" -) - -// ImageCreate creates a new image based in the parent options. -// It returns the JSON content in the response body. -func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) { - repository, tag, err := reference.Parse(parentReference) - if err != nil { - return nil, err - } - - query := url.Values{} - query.Set("fromImage", repository) - query.Set("tag", tag) - resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) - if err != nil { - return nil, err - } - return resp.body, nil -} - -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) -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_history.go b/vendor/src/github.com/docker/engine-api/client/image_history.go deleted file mode 100644 index b2840b5ed8..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_history.go +++ /dev/null @@ -1,22 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ImageHistory returns the changes in an image in history format. -func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]types.ImageHistory, error) { - var history []types.ImageHistory - serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", url.Values{}, nil) - if err != nil { - return history, err - } - - err = json.NewDecoder(serverResp.body).Decode(&history) - ensureReaderClosed(serverResp) - return history, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_import.go b/vendor/src/github.com/docker/engine-api/client/image_import.go deleted file mode 100644 index 4e8749a01d..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_import.go +++ /dev/null @@ -1,37 +0,0 @@ -package client - -import ( - "io" - "net/url" - - "golang.org/x/net/context" - - "github.com/docker/distribution/reference" - "github.com/docker/engine-api/types" -) - -// ImageImport creates a new image based in the source options. -// It returns the JSON content in the response body. -func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) { - if ref != "" { - //Check if the given image name can be resolved - if _, err := reference.ParseNamed(ref); err != nil { - return nil, err - } - } - - query := url.Values{} - query.Set("fromSrc", source.SourceName) - query.Set("repo", ref) - query.Set("tag", options.Tag) - query.Set("message", options.Message) - for _, change := range options.Changes { - query.Add("changes", change) - } - - resp, err := cli.postRaw(ctx, "/images/create", query, source.Source, nil) - if err != nil { - return nil, err - } - return resp.body, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_inspect.go b/vendor/src/github.com/docker/engine-api/client/image_inspect.go deleted file mode 100644 index d5f6bc5637..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_inspect.go +++ /dev/null @@ -1,33 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - "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) (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} - } - return types.ImageInspect{}, nil, err - } - defer ensureReaderClosed(serverResp) - - body, err := ioutil.ReadAll(serverResp.body) - if err != nil { - return types.ImageInspect{}, nil, err - } - - var response types.ImageInspect - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&response) - return response, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_list.go b/vendor/src/github.com/docker/engine-api/client/image_list.go deleted file mode 100644 index 7408258231..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_list.go +++ /dev/null @@ -1,40 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "golang.org/x/net/context" -) - -// ImageList returns a list of images in the docker host. -func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]types.Image, error) { - var images []types.Image - query := url.Values{} - - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) - if err != nil { - return images, err - } - query.Set("filters", filterJSON) - } - if options.MatchName != "" { - // FIXME rename this parameter, to not be confused with the filters flag - query.Set("filter", options.MatchName) - } - if options.All { - query.Set("all", "1") - } - - serverResp, err := cli.get(ctx, "/images/json", query, nil) - if err != nil { - return images, err - } - - err = json.NewDecoder(serverResp.body).Decode(&images) - ensureReaderClosed(serverResp) - return images, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_load.go b/vendor/src/github.com/docker/engine-api/client/image_load.go deleted file mode 100644 index 72f55fdc01..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_load.go +++ /dev/null @@ -1,30 +0,0 @@ -package client - -import ( - "io" - "net/url" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" -) - -// ImageLoad loads an image in the docker host from the client host. -// It's up to the caller to close the io.ReadCloser in the -// ImageLoadResponse returned by this function. -func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) { - v := url.Values{} - v.Set("quiet", "0") - if quiet { - v.Set("quiet", "1") - } - headers := map[string][]string{"Content-Type": {"application/x-tar"}} - resp, err := cli.postRaw(ctx, "/images/load", v, input, headers) - if err != nil { - return types.ImageLoadResponse{}, err - } - return types.ImageLoadResponse{ - Body: resp.body, - JSON: resp.header.Get("Content-Type") == "application/json", - }, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_pull.go b/vendor/src/github.com/docker/engine-api/client/image_pull.go deleted file mode 100644 index e2c49ec52b..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_pull.go +++ /dev/null @@ -1,46 +0,0 @@ -package client - -import ( - "io" - "net/http" - "net/url" - - "golang.org/x/net/context" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/reference" -) - -// ImagePull requests the docker host to pull an image from a remote registry. -// It executes the privileged function if the operation is unauthorized -// and it tries one more time. -// It's up to the caller to handle the io.ReadCloser and close it properly. -// -// FIXME(vdemeester): there is currently used in a few way in docker/docker -// - if not in trusted content, ref is used to pass the whole reference, and tag is empty -// - if in trusted content, ref is used to pass the reference name, and tag for the digest -func (cli *Client) ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) { - repository, tag, err := reference.Parse(ref) - if err != nil { - return nil, err - } - - query := url.Values{} - query.Set("fromImage", repository) - if tag != "" && !options.All { - query.Set("tag", tag) - } - - resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { - newAuthHeader, privilegeErr := options.PrivilegeFunc() - if privilegeErr != nil { - return nil, privilegeErr - } - resp, err = cli.tryImageCreate(ctx, query, newAuthHeader) - } - if err != nil { - return nil, err - } - return resp.body, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_push.go b/vendor/src/github.com/docker/engine-api/client/image_push.go deleted file mode 100644 index a30fc3b866..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_push.go +++ /dev/null @@ -1,54 +0,0 @@ -package client - -import ( - "errors" - "io" - "net/http" - "net/url" - - "golang.org/x/net/context" - - distreference "github.com/docker/distribution/reference" - "github.com/docker/engine-api/types" -) - -// ImagePush requests the docker host to push an image to a remote registry. -// It executes the privileged function if the operation is unauthorized -// and it tries one more time. -// It's up to the caller to handle the io.ReadCloser and close it properly. -func (cli *Client) ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) { - distributionRef, err := distreference.ParseNamed(ref) - if err != nil { - return nil, err - } - - if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical { - return nil, errors.New("cannot push a digest reference") - } - - var tag = "" - if nameTaggedRef, isNamedTagged := distributionRef.(distreference.NamedTagged); isNamedTagged { - tag = nameTaggedRef.Tag() - } - - query := url.Values{} - query.Set("tag", tag) - - resp, err := cli.tryImagePush(ctx, distributionRef.Name(), query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { - newAuthHeader, privilegeErr := options.PrivilegeFunc() - if privilegeErr != nil { - return nil, privilegeErr - } - resp, err = cli.tryImagePush(ctx, distributionRef.Name(), query, newAuthHeader) - } - if err != nil { - return nil, err - } - return resp.body, nil -} - -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) -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_remove.go b/vendor/src/github.com/docker/engine-api/client/image_remove.go deleted file mode 100644 index 47224326e0..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_remove.go +++ /dev/null @@ -1,31 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ImageRemove removes an image from the docker host. -func (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]types.ImageDelete, error) { - query := url.Values{} - - if options.Force { - query.Set("force", "1") - } - if !options.PruneChildren { - query.Set("noprune", "1") - } - - resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) - if err != nil { - return nil, err - } - - var dels []types.ImageDelete - err = json.NewDecoder(resp.body).Decode(&dels) - ensureReaderClosed(resp) - return dels, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_save.go b/vendor/src/github.com/docker/engine-api/client/image_save.go deleted file mode 100644 index ecac880a32..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_save.go +++ /dev/null @@ -1,22 +0,0 @@ -package client - -import ( - "io" - "net/url" - - "golang.org/x/net/context" -) - -// ImageSave retrieves one or more images from the docker host as an io.ReadCloser. -// It's up to the caller to store the images and close the stream. -func (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) { - query := url.Values{ - "names": imageIDs, - } - - resp, err := cli.get(ctx, "/images/get", query, nil) - if err != nil { - return nil, err - } - return resp.body, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_search.go b/vendor/src/github.com/docker/engine-api/client/image_search.go deleted file mode 100644 index b7a7de3b9d..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_search.go +++ /dev/null @@ -1,51 +0,0 @@ -package client - -import ( - "encoding/json" - "fmt" - "net/http" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "github.com/docker/engine-api/types/registry" - "golang.org/x/net/context" -) - -// ImageSearch makes the docker host to search by a term in a remote registry. -// The list of results is not sorted in any fashion. -func (cli *Client) ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) { - var results []registry.SearchResult - query := url.Values{} - query.Set("term", term) - query.Set("limit", fmt.Sprintf("%d", options.Limit)) - - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToParam(options.Filters) - if err != nil { - return results, err - } - query.Set("filters", filterJSON) - } - - resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { - newAuthHeader, privilegeErr := options.PrivilegeFunc() - if privilegeErr != nil { - return results, privilegeErr - } - resp, err = cli.tryImageSearch(ctx, query, newAuthHeader) - } - if err != nil { - return results, err - } - - err = json.NewDecoder(resp.body).Decode(&results) - ensureReaderClosed(resp) - return results, err -} - -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) -} diff --git a/vendor/src/github.com/docker/engine-api/client/image_tag.go b/vendor/src/github.com/docker/engine-api/client/image_tag.go deleted file mode 100644 index 7182913672..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/image_tag.go +++ /dev/null @@ -1,34 +0,0 @@ -package client - -import ( - "errors" - "fmt" - "net/url" - - "golang.org/x/net/context" - - distreference "github.com/docker/distribution/reference" - "github.com/docker/engine-api/types/reference" -) - -// ImageTag tags an image in the docker host -func (cli *Client) ImageTag(ctx context.Context, imageID, ref string) error { - distributionRef, err := distreference.ParseNamed(ref) - if err != nil { - return fmt.Errorf("Error parsing reference: %q is not a valid repository/tag", ref) - } - - if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical { - return errors.New("refusing to create a tag with a digest reference") - } - - tag := reference.GetTagFromNamedRef(distributionRef) - - query := url.Values{} - query.Set("repo", distributionRef.Name()) - query.Set("tag", tag) - - resp, err := cli.post(ctx, "/images/"+imageID+"/tag", query, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/info.go b/vendor/src/github.com/docker/engine-api/client/info.go deleted file mode 100644 index ff0958d65c..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/info.go +++ /dev/null @@ -1,26 +0,0 @@ -package client - -import ( - "encoding/json" - "fmt" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// Info returns information about the docker server. -func (cli *Client) Info(ctx context.Context) (types.Info, error) { - var info types.Info - serverResp, err := cli.get(ctx, "/info", url.Values{}, nil) - if err != nil { - return info, err - } - defer ensureReaderClosed(serverResp) - - if err := json.NewDecoder(serverResp.body).Decode(&info); err != nil { - return info, fmt.Errorf("Error reading remote info: %v", err) - } - - return info, nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/interface.go b/vendor/src/github.com/docker/engine-api/client/interface.go deleted file mode 100644 index 924cf5dd39..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/interface.go +++ /dev/null @@ -1,135 +0,0 @@ -package client - -import ( - "io" - "time" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/container" - "github.com/docker/engine-api/types/filters" - "github.com/docker/engine-api/types/network" - "github.com/docker/engine-api/types/registry" - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// 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 - 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) - ContainerDiff(ctx context.Context, container string) ([]types.ContainerChange, error) - ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error) - ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.ContainerExecCreateResponse, error) - ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) - ContainerExecResize(ctx context.Context, execID string, options types.ResizeOptions) error - ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error - ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) - ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) - ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) - ContainerKill(ctx context.Context, container, signal string) error - ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) - ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) - ContainerPause(ctx context.Context, container string) error - 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 - 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 - 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) (types.ContainerUpdateResponse, 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 -} - -// 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) - ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, 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) - ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) - ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDelete, error) - 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 -} - -// 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 - NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error) - 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 { - NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) - NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) - NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) 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, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) - ServiceInspectWithRaw(ctx context.Context, serviceID string) (swarm.Service, []byte, 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, options types.ServiceUpdateOptions) 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, flags swarm.UpdateFlags) 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) -} - -// 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) - VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error) - VolumeRemove(ctx context.Context, volumeID string, force bool) 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 deleted file mode 100644 index 1835995a91..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/interface_experimental.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build experimental - -package client - -import ( - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// 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, options types.PluginRemoveOptions) error - PluginEnable(ctx context.Context, name string) error - PluginDisable(ctx context.Context, name string) error - PluginInstall(ctx context.Context, name string, options types.PluginInstallOptions) error - PluginPush(ctx context.Context, name string, registryAuth string) error - PluginSet(ctx context.Context, name string, args []string) error - PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) -} - -// Ensure that Client always implements APIClient. -var _ APIClient = &Client{} diff --git a/vendor/src/github.com/docker/engine-api/client/interface_stable.go b/vendor/src/github.com/docker/engine-api/client/interface_stable.go deleted file mode 100644 index 496f522d51..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/interface_stable.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !experimental - -package client - -// APIClient is an interface that clients that talk with a docker server must implement. -type APIClient interface { - CommonAPIClient -} - -// Ensure that Client always implements APIClient. -var _ APIClient = &Client{} diff --git a/vendor/src/github.com/docker/engine-api/client/login.go b/vendor/src/github.com/docker/engine-api/client/login.go deleted file mode 100644 index b14f239f02..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/login.go +++ /dev/null @@ -1,28 +0,0 @@ -package client - -import ( - "encoding/json" - "net/http" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// RegistryLogin authenticates the docker server with a given docker registry. -// It returns UnauthorizerError when the authentication fails. -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.statusCode == http.StatusUnauthorized { - return types.AuthResponse{}, unauthorizedError{err} - } - if err != nil { - return types.AuthResponse{}, err - } - - var response types.AuthResponse - err = json.NewDecoder(resp.body).Decode(&response) - ensureReaderClosed(resp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/network_connect.go b/vendor/src/github.com/docker/engine-api/client/network_connect.go deleted file mode 100644 index 9a402a3e63..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/network_connect.go +++ /dev/null @@ -1,18 +0,0 @@ -package client - -import ( - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/network" - "golang.org/x/net/context" -) - -// NetworkConnect connects a container to an existent network in the docker host. -func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error { - nc := types.NetworkConnect{ - Container: containerID, - EndpointConfig: config, - } - resp, err := cli.post(ctx, "/networks/"+networkID+"/connect", nil, nc, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/network_create.go b/vendor/src/github.com/docker/engine-api/client/network_create.go deleted file mode 100644 index c9c0b9fde7..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/network_create.go +++ /dev/null @@ -1,25 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// NetworkCreate creates a new network in the docker host. -func (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) { - networkCreateRequest := types.NetworkCreateRequest{ - NetworkCreate: options, - Name: name, - } - var response types.NetworkCreateResponse - serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil) - if err != nil { - return response, err - } - - json.NewDecoder(serverResp.body).Decode(&response) - ensureReaderClosed(serverResp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/network_disconnect.go b/vendor/src/github.com/docker/engine-api/client/network_disconnect.go deleted file mode 100644 index a3e33672fe..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/network_disconnect.go +++ /dev/null @@ -1,14 +0,0 @@ -package client - -import ( - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// NetworkDisconnect disconnects a container from an existent network in the docker host. -func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error { - nd := types.NetworkDisconnect{Container: containerID, Force: force} - resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/network_inspect.go b/vendor/src/github.com/docker/engine-api/client/network_inspect.go deleted file mode 100644 index e22fcd6710..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/network_inspect.go +++ /dev/null @@ -1,38 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// NetworkInspect returns the information for a specific network configured in the docker host. -func (cli *Client) NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error) { - networkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID) - return networkResource, err -} - -// NetworkInspectWithRaw returns the information for a specific network configured in the docker host and its raw representation. -func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string) (types.NetworkResource, []byte, error) { - var networkResource types.NetworkResource - resp, err := cli.get(ctx, "/networks/"+networkID, nil, nil) - if err != nil { - if resp.statusCode == http.StatusNotFound { - return networkResource, nil, networkNotFoundError{networkID} - } - return networkResource, nil, err - } - defer ensureReaderClosed(resp) - - body, err := ioutil.ReadAll(resp.body) - if err != nil { - return networkResource, nil, err - } - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&networkResource) - return networkResource, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/network_list.go b/vendor/src/github.com/docker/engine-api/client/network_list.go deleted file mode 100644 index 0569552496..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/network_list.go +++ /dev/null @@ -1,31 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "golang.org/x/net/context" -) - -// NetworkList returns the list of networks configured in the docker host. -func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) { - query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - var networkResources []types.NetworkResource - resp, err := cli.get(ctx, "/networks", query, nil) - if err != nil { - return networkResources, err - } - err = json.NewDecoder(resp.body).Decode(&networkResources) - ensureReaderClosed(resp) - return networkResources, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/network_remove.go b/vendor/src/github.com/docker/engine-api/client/network_remove.go deleted file mode 100644 index 6bd6748924..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/network_remove.go +++ /dev/null @@ -1,10 +0,0 @@ -package client - -import "golang.org/x/net/context" - -// NetworkRemove removes an existent network from the docker host. -func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error { - resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/node_inspect.go b/vendor/src/github.com/docker/engine-api/client/node_inspect.go deleted file mode 100644 index 5f555bb357..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/node_inspect.go +++ /dev/null @@ -1,33 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// NodeInspectWithRaw returns the node information. -func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) { - serverResp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil) - if err != nil { - if serverResp.statusCode == http.StatusNotFound { - return swarm.Node{}, nil, nodeNotFoundError{nodeID} - } - return swarm.Node{}, nil, err - } - defer ensureReaderClosed(serverResp) - - body, err := ioutil.ReadAll(serverResp.body) - if err != nil { - return swarm.Node{}, nil, err - } - - var response swarm.Node - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&response) - return response, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/node_list.go b/vendor/src/github.com/docker/engine-api/client/node_list.go deleted file mode 100644 index 57cf14827d..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/node_list.go +++ /dev/null @@ -1,36 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// NodeList returns the list of nodes. -func (cli *Client) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) { - query := url.Values{} - - if options.Filter.Len() > 0 { - filterJSON, err := filters.ToParam(options.Filter) - - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - - resp, err := cli.get(ctx, "/nodes", query, nil) - if err != nil { - return nil, err - } - - var nodes []swarm.Node - err = json.NewDecoder(resp.body).Decode(&nodes) - ensureReaderClosed(resp) - return nodes, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/node_remove.go b/vendor/src/github.com/docker/engine-api/client/node_remove.go deleted file mode 100644 index a9cf8ba857..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/node_remove.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "net/url" - - "github.com/docker/engine-api/types" - - "golang.org/x/net/context" -) - -// NodeRemove removes a Node. -func (cli *Client) NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error { - query := url.Values{} - if options.Force { - query.Set("force", "1") - } - - resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/node_update.go b/vendor/src/github.com/docker/engine-api/client/node_update.go deleted file mode 100644 index 4722211517..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/node_update.go +++ /dev/null @@ -1,18 +0,0 @@ -package client - -import ( - "net/url" - "strconv" - - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// NodeUpdate updates a Node. -func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error { - query := url.Values{} - query.Set("version", strconv.FormatUint(version.Index, 10)) - resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, node, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_disable.go b/vendor/src/github.com/docker/engine-api/client/plugin_disable.go deleted file mode 100644 index 893fc6e823..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_disable.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build experimental - -package client - -import ( - "golang.org/x/net/context" -) - -// PluginDisable disables a plugin -func (cli *Client) PluginDisable(ctx context.Context, name string) error { - resp, err := cli.post(ctx, "/plugins/"+name+"/disable", nil, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_enable.go b/vendor/src/github.com/docker/engine-api/client/plugin_enable.go deleted file mode 100644 index 84422abc79..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_enable.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build experimental - -package client - -import ( - "golang.org/x/net/context" -) - -// PluginEnable enables a plugin -func (cli *Client) PluginEnable(ctx context.Context, name string) error { - resp, err := cli.post(ctx, "/plugins/"+name+"/enable", nil, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_inspect.go b/vendor/src/github.com/docker/engine-api/client/plugin_inspect.go deleted file mode 100644 index 1e58af3c5d..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_inspect.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build experimental - -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// PluginInspectWithRaw inspects an existing plugin -func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) { - resp, err := cli.get(ctx, "/plugins/"+name, nil, nil) - if err != nil { - return nil, nil, err - } - - defer ensureReaderClosed(resp) - body, err := ioutil.ReadAll(resp.body) - if err != nil { - return nil, nil, err - } - var p types.Plugin - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&p) - return &p, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_install.go b/vendor/src/github.com/docker/engine-api/client/plugin_install.go deleted file mode 100644 index 6cf50ff23e..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_install.go +++ /dev/null @@ -1,59 +0,0 @@ -// +build experimental - -package client - -import ( - "encoding/json" - "net/http" - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// PluginInstall installs a plugin -func (cli *Client) PluginInstall(ctx context.Context, name string, options types.PluginInstallOptions) error { - // FIXME(vdemeester) name is a ref, we might want to parse/validate it here. - query := url.Values{} - query.Set("name", name) - resp, err := cli.tryPluginPull(ctx, query, options.RegistryAuth) - if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil { - newAuthHeader, privilegeErr := options.PrivilegeFunc() - if privilegeErr != nil { - ensureReaderClosed(resp) - return privilegeErr - } - resp, err = cli.tryPluginPull(ctx, query, newAuthHeader) - } - if err != nil { - ensureReaderClosed(resp) - return err - } - var privileges types.PluginPrivileges - if err := json.NewDecoder(resp.body).Decode(&privileges); err != nil { - ensureReaderClosed(resp) - return err - } - ensureReaderClosed(resp) - - if !options.AcceptAllPermissions && options.AcceptPermissionsFunc != nil && len(privileges) > 0 { - accept, err := options.AcceptPermissionsFunc(privileges) - if err != nil { - return err - } - if !accept { - resp, _ := cli.delete(ctx, "/plugins/"+name, nil, nil) - ensureReaderClosed(resp) - return pluginPermissionDenied{name} - } - } - if options.Disabled { - return nil - } - return cli.PluginEnable(ctx, name) -} - -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) -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_list.go b/vendor/src/github.com/docker/engine-api/client/plugin_list.go deleted file mode 100644 index 7f2e2f21f3..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_list.go +++ /dev/null @@ -1,23 +0,0 @@ -// +build experimental - -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// PluginList returns the installed plugins -func (cli *Client) PluginList(ctx context.Context) (types.PluginsListResponse, error) { - var plugins types.PluginsListResponse - resp, err := cli.get(ctx, "/plugins", nil, nil) - if err != nil { - return plugins, err - } - - err = json.NewDecoder(resp.body).Decode(&plugins) - ensureReaderClosed(resp) - return plugins, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_push.go b/vendor/src/github.com/docker/engine-api/client/plugin_push.go deleted file mode 100644 index 3afea5ed79..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_push.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build experimental - -package client - -import ( - "golang.org/x/net/context" -) - -// PluginPush pushes a plugin to a registry -func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) error { - headers := map[string][]string{"X-Registry-Auth": {registryAuth}} - resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_remove.go b/vendor/src/github.com/docker/engine-api/client/plugin_remove.go deleted file mode 100644 index 9fe18b50ad..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_remove.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build experimental - -package client - -import ( - "net/url" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// PluginRemove removes a plugin -func (cli *Client) PluginRemove(ctx context.Context, name string, options types.PluginRemoveOptions) error { - query := url.Values{} - if options.Force { - query.Set("force", "1") - } - - resp, err := cli.delete(ctx, "/plugins/"+name, query, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/plugin_set.go b/vendor/src/github.com/docker/engine-api/client/plugin_set.go deleted file mode 100644 index fb40f38b22..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/plugin_set.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build experimental - -package client - -import ( - "golang.org/x/net/context" -) - -// PluginSet modifies settings for an existing plugin -func (cli *Client) PluginSet(ctx context.Context, name string, args []string) error { - resp, err := cli.post(ctx, "/plugins/"+name+"/set", nil, args, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/request.go b/vendor/src/github.com/docker/engine-api/client/request.go deleted file mode 100644 index 26e8769bc4..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/request.go +++ /dev/null @@ -1,208 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "strings" - - "github.com/docker/engine-api/client/transport/cancellable" - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/versions" - "golang.org/x/net/context" -) - -// serverResponse is a wrapper for http API responses. -type serverResponse struct { - body io.ReadCloser - header http.Header - statusCode int -} - -// 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - var body io.Reader - - if obj != nil { - var err error - body, err = encodeData(obj) - if err != nil { - return serverResponse{}, err - } - if headers == nil { - headers = make(map[string][]string) - } - headers["Content-Type"] = []string{"application/json"} - } - - 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{ - body: nil, - statusCode: -1, - } - - expectedPayload := (method == "POST" || method == "PUT") - if expectedPayload && body == nil { - body = bytes.NewReader([]byte{}) - } - - req, err := cli.newRequest(method, path, query, body, headers) - if err != nil { - return serverResp, err - } - - if cli.proto == "unix" || cli.proto == "npipe" { - // For local communications, it doesn't matter what the host is. We just - // need a valid and meaningful host name. (See #189) - req.Host = "docker" - } - req.URL.Host = cli.addr - req.URL.Scheme = cli.transport.Scheme() - - if expectedPayload && req.Header.Get("Content-Type") == "" { - req.Header.Set("Content-Type", "text/plain") - } - - resp, err := cancellable.Do(ctx, cli.transport, req) - if err != nil { - 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) - } - - if cli.transport.Secure() && strings.Contains(err.Error(), "bad certificate") { - 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, ErrorConnectionFailed(cli.host) - } - if !err.Temporary() { - if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") { - return serverResp, ErrorConnectionFailed(cli.host) - } - } - } - return serverResp, fmt.Errorf("An error occurred trying to connect: %v", err) - } - - if resp != nil { - serverResp.statusCode = resp.StatusCode - } - - if serverResp.statusCode < 200 || serverResp.statusCode >= 400 { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return serverResp, err - } - if len(body) == 0 { - return serverResp, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), req.URL) - } - - var errorMessage string - if (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) && - resp.Header.Get("Content-Type") == "application/json" { - var errorResponse types.ErrorResponse - if err := json.Unmarshal(body, &errorResponse); err != nil { - return serverResp, fmt.Errorf("Error reading JSON: %v", err) - } - errorMessage = errorResponse.Message - } else { - errorMessage = string(body) - } - - return serverResp, fmt.Errorf("Error response from daemon: %s", strings.TrimSpace(errorMessage)) - } - - serverResp.body = resp.Body - serverResp.header = resp.Header - return serverResp, nil -} - -func (cli *Client) newRequest(method, path string, query url.Values, body io.Reader, headers map[string][]string) (*http.Request, error) { - apiPath := cli.getAPIPath(path, query) - req, err := http.NewRequest(method, apiPath, body) - if err != nil { - return nil, err - } - - // Add CLI Config's HTTP Headers BEFORE we set the Docker headers - // then the user can't change OUR headers - for k, v := range cli.customHTTPHeaders { - req.Header.Set(k, v) - } - - if headers != nil { - for k, v := range headers { - req.Header[k] = v - } - } - - return req, nil -} - -func encodeData(data interface{}) (*bytes.Buffer, error) { - params := bytes.NewBuffer(nil) - if data != nil { - if err := json.NewEncoder(params).Encode(data); err != nil { - return nil, err - } - } - return params, 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, body, 512) - response.body.Close() - } -} diff --git a/vendor/src/github.com/docker/engine-api/client/service_create.go b/vendor/src/github.com/docker/engine-api/client/service_create.go deleted file mode 100644 index 7349a984e7..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/service_create.go +++ /dev/null @@ -1,30 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// ServiceCreate creates a new Service. -func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) { - var headers map[string][]string - - if options.EncodedRegistryAuth != "" { - headers = map[string][]string{ - "X-Registry-Auth": []string{options.EncodedRegistryAuth}, - } - } - - var response types.ServiceCreateResponse - resp, err := cli.post(ctx, "/services/create", nil, service, headers) - if err != nil { - return response, err - } - - err = json.NewDecoder(resp.body).Decode(&response) - ensureReaderClosed(resp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/service_inspect.go b/vendor/src/github.com/docker/engine-api/client/service_inspect.go deleted file mode 100644 index 958cd662ea..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/service_inspect.go +++ /dev/null @@ -1,33 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// ServiceInspectWithRaw returns the service information and the raw data. -func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string) (swarm.Service, []byte, error) { - serverResp, err := cli.get(ctx, "/services/"+serviceID, nil, nil) - if err != nil { - if serverResp.statusCode == http.StatusNotFound { - return swarm.Service{}, nil, serviceNotFoundError{serviceID} - } - return swarm.Service{}, nil, err - } - defer ensureReaderClosed(serverResp) - - body, err := ioutil.ReadAll(serverResp.body) - if err != nil { - return swarm.Service{}, nil, err - } - - var response swarm.Service - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&response) - return response, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/service_list.go b/vendor/src/github.com/docker/engine-api/client/service_list.go deleted file mode 100644 index b48964aa0f..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/service_list.go +++ /dev/null @@ -1,35 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// ServiceList returns the list of services. -func (cli *Client) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { - query := url.Values{} - - if options.Filter.Len() > 0 { - filterJSON, err := filters.ToParam(options.Filter) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - - resp, err := cli.get(ctx, "/services", query, nil) - if err != nil { - return nil, err - } - - var services []swarm.Service - err = json.NewDecoder(resp.body).Decode(&services) - ensureReaderClosed(resp) - return services, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/service_remove.go b/vendor/src/github.com/docker/engine-api/client/service_remove.go deleted file mode 100644 index a9331f92c2..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/service_remove.go +++ /dev/null @@ -1,10 +0,0 @@ -package client - -import "golang.org/x/net/context" - -// ServiceRemove kills and removes a service. -func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error { - resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/service_update.go b/vendor/src/github.com/docker/engine-api/client/service_update.go deleted file mode 100644 index ee8b46126b..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/service_update.go +++ /dev/null @@ -1,30 +0,0 @@ -package client - -import ( - "net/url" - "strconv" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// ServiceUpdate updates a Service. -func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) error { - var ( - headers map[string][]string - query = url.Values{} - ) - - if options.EncodedRegistryAuth != "" { - headers = map[string][]string{ - "X-Registry-Auth": []string{options.EncodedRegistryAuth}, - } - } - - query.Set("version", strconv.FormatUint(version.Index, 10)) - - resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/swarm_init.go b/vendor/src/github.com/docker/engine-api/client/swarm_init.go deleted file mode 100644 index 68f0a744a2..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/swarm_init.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// SwarmInit initializes the Swarm. -func (cli *Client) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) { - serverResp, err := cli.post(ctx, "/swarm/init", nil, req, nil) - if err != nil { - return "", err - } - - var response string - err = json.NewDecoder(serverResp.body).Decode(&response) - ensureReaderClosed(serverResp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/swarm_inspect.go b/vendor/src/github.com/docker/engine-api/client/swarm_inspect.go deleted file mode 100644 index d67c7c010b..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/swarm_inspect.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// SwarmInspect inspects the Swarm. -func (cli *Client) SwarmInspect(ctx context.Context) (swarm.Swarm, error) { - serverResp, err := cli.get(ctx, "/swarm", nil, nil) - if err != nil { - return swarm.Swarm{}, err - } - - var response swarm.Swarm - err = json.NewDecoder(serverResp.body).Decode(&response) - ensureReaderClosed(serverResp) - return response, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/swarm_join.go b/vendor/src/github.com/docker/engine-api/client/swarm_join.go deleted file mode 100644 index a9b14e0c48..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/swarm_join.go +++ /dev/null @@ -1,13 +0,0 @@ -package client - -import ( - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// SwarmJoin joins the Swarm. -func (cli *Client) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error { - resp, err := cli.post(ctx, "/swarm/join", nil, req, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/swarm_leave.go b/vendor/src/github.com/docker/engine-api/client/swarm_leave.go deleted file mode 100644 index a4df732174..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/swarm_leave.go +++ /dev/null @@ -1,18 +0,0 @@ -package client - -import ( - "net/url" - - "golang.org/x/net/context" -) - -// SwarmLeave leaves the Swarm. -func (cli *Client) SwarmLeave(ctx context.Context, force bool) error { - query := url.Values{} - if force { - query.Set("force", "1") - } - resp, err := cli.post(ctx, "/swarm/leave", query, nil, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/swarm_update.go b/vendor/src/github.com/docker/engine-api/client/swarm_update.go deleted file mode 100644 index 5adec81ca4..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/swarm_update.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "fmt" - "net/url" - "strconv" - - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// SwarmUpdate updates the Swarm. -func (cli *Client) SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error { - query := url.Values{} - query.Set("version", strconv.FormatUint(version.Index, 10)) - query.Set("rotateWorkerToken", fmt.Sprintf("%v", flags.RotateWorkerToken)) - query.Set("rotateManagerToken", fmt.Sprintf("%v", flags.RotateManagerToken)) - resp, err := cli.post(ctx, "/swarm/update", query, swarm, nil) - ensureReaderClosed(resp) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/task_inspect.go b/vendor/src/github.com/docker/engine-api/client/task_inspect.go deleted file mode 100644 index 3cac8882ef..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/task_inspect.go +++ /dev/null @@ -1,34 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/docker/engine-api/types/swarm" - - "golang.org/x/net/context" -) - -// TaskInspectWithRaw returns the task information and its raw representation.. -func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) { - serverResp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil) - if err != nil { - if serverResp.statusCode == http.StatusNotFound { - return swarm.Task{}, nil, taskNotFoundError{taskID} - } - return swarm.Task{}, nil, err - } - defer ensureReaderClosed(serverResp) - - body, err := ioutil.ReadAll(serverResp.body) - if err != nil { - return swarm.Task{}, nil, err - } - - var response swarm.Task - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&response) - return response, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/task_list.go b/vendor/src/github.com/docker/engine-api/client/task_list.go deleted file mode 100644 index 4604513caf..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/task_list.go +++ /dev/null @@ -1,35 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "github.com/docker/engine-api/types/swarm" - "golang.org/x/net/context" -) - -// TaskList returns the list of tasks. -func (cli *Client) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) { - query := url.Values{} - - if options.Filter.Len() > 0 { - filterJSON, err := filters.ToParam(options.Filter) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - - resp, err := cli.get(ctx, "/tasks", query, nil) - if err != nil { - return nil, err - } - - var tasks []swarm.Task - err = json.NewDecoder(resp.body).Decode(&tasks) - ensureReaderClosed(resp) - return tasks, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/transport/cancellable/canceler.go b/vendor/src/github.com/docker/engine-api/client/transport/cancellable/canceler.go deleted file mode 100644 index 11dff60026..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/transport/cancellable/canceler.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.5 - -package cancellable - -import ( - "net/http" - - "github.com/docker/engine-api/client/transport" -) - -func canceler(client transport.Sender, req *http.Request) func() { - // TODO(djd): Respect any existing value of req.Cancel. - ch := make(chan struct{}) - req.Cancel = ch - - return func() { - close(ch) - } -} diff --git a/vendor/src/github.com/docker/engine-api/client/transport/cancellable/canceler_go14.go b/vendor/src/github.com/docker/engine-api/client/transport/cancellable/canceler_go14.go deleted file mode 100644 index 8ff2845c28..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/transport/cancellable/canceler_go14.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.5 - -package cancellable - -import ( - "net/http" - - "github.com/docker/engine-api/client/transport" -) - -type requestCanceler interface { - CancelRequest(*http.Request) -} - -func canceler(client transport.Sender, req *http.Request) func() { - rc, ok := client.(requestCanceler) - if !ok { - return func() {} - } - return func() { - rc.CancelRequest(req) - } -} diff --git a/vendor/src/github.com/docker/engine-api/client/transport/cancellable/cancellable.go b/vendor/src/github.com/docker/engine-api/client/transport/cancellable/cancellable.go deleted file mode 100644 index 3e4b1796d7..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/transport/cancellable/cancellable.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cancellable provides helper function to cancel http requests. -package cancellable - -import ( - "io" - "net/http" - "sync" - - "github.com/docker/engine-api/client/transport" - - "golang.org/x/net/context" -) - -func nop() {} - -var ( - testHookContextDoneBeforeHeaders = nop - testHookDoReturned = nop - testHookDidBodyClose = nop -) - -// Do sends an HTTP request with the provided transport.Sender and returns an HTTP response. -// If the client is nil, http.DefaultClient is used. -// If the context is canceled or times out, ctx.Err() will be returned. -// -// FORK INFORMATION: -// -// This function deviates from the upstream version in golang.org/x/net/context/ctxhttp by -// taking a Sender interface rather than a *http.Client directly. That allow us to use -// this function with mocked clients and hijacked connections. -func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.Response, error) { - if client == nil { - client = http.DefaultClient - } - - // Request cancelation changed in Go 1.5, see canceler.go and canceler_go14.go. - cancel := canceler(client, req) - - type responseAndError struct { - resp *http.Response - err error - } - result := make(chan responseAndError, 1) - - go func() { - resp, err := client.Do(req) - testHookDoReturned() - result <- responseAndError{resp, err} - }() - - var resp *http.Response - - select { - case <-ctx.Done(): - testHookContextDoneBeforeHeaders() - cancel() - // Clean up after the goroutine calling client.Do: - go func() { - if r := <-result; r.resp != nil && r.resp.Body != nil { - testHookDidBodyClose() - r.resp.Body.Close() - } - }() - return nil, ctx.Err() - case r := <-result: - var err error - resp, err = r.resp, r.err - if err != nil { - return resp, err - } - } - - c := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - cancel() - case <-c: - // The response's Body is closed. - } - }() - resp.Body = ¬ifyingReader{ReadCloser: resp.Body, notify: c} - - return resp, nil -} - -// notifyingReader is an io.ReadCloser that closes the notify channel after -// Close is called or a Read fails on the underlying ReadCloser. -type notifyingReader struct { - io.ReadCloser - notify chan<- struct{} - notifyOnce sync.Once -} - -func (r *notifyingReader) Read(p []byte) (int, error) { - n, err := r.ReadCloser.Read(p) - if err != nil { - r.notifyOnce.Do(func() { - close(r.notify) - }) - } - return n, err -} - -func (r *notifyingReader) Close() error { - err := r.ReadCloser.Close() - r.notifyOnce.Do(func() { - close(r.notify) - }) - return err -} diff --git a/vendor/src/github.com/docker/engine-api/client/transport/client.go b/vendor/src/github.com/docker/engine-api/client/transport/client.go deleted file mode 100644 index 13d4b3ab3d..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/transport/client.go +++ /dev/null @@ -1,47 +0,0 @@ -package transport - -import ( - "crypto/tls" - "net/http" -) - -// Sender is an interface that clients must implement -// to be able to send requests to a remote connection. -type Sender interface { - // Do sends request to a remote endpoint. - Do(*http.Request) (*http.Response, error) -} - -// Client is an interface that abstracts all remote connections. -type Client interface { - Sender - // Secure tells whether the connection is secure or not. - Secure() bool - // Scheme returns the connection protocol the client uses. - Scheme() string - // TLSConfig returns any TLS configuration the client uses. - TLSConfig() *tls.Config -} - -// tlsInfo returns information about the TLS configuration. -type tlsInfo struct { - tlsConfig *tls.Config -} - -// TLSConfig returns the TLS configuration. -func (t *tlsInfo) TLSConfig() *tls.Config { - return t.tlsConfig -} - -// Scheme returns protocol scheme to use. -func (t *tlsInfo) Scheme() string { - if t.tlsConfig != nil { - return "https" - } - return "http" -} - -// Secure returns true if there is a TLS configuration. -func (t *tlsInfo) Secure() bool { - return t.tlsConfig != nil -} diff --git a/vendor/src/github.com/docker/engine-api/client/transport/transport.go b/vendor/src/github.com/docker/engine-api/client/transport/transport.go deleted file mode 100644 index ff28af1855..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/transport/transport.go +++ /dev/null @@ -1,57 +0,0 @@ -// Package transport provides function to send request to remote endpoints. -package transport - -import ( - "fmt" - "net/http" - - "github.com/docker/go-connections/sockets" -) - -// apiTransport holds information about the http transport to connect with the API. -type apiTransport struct { - *http.Client - *tlsInfo - transport *http.Transport -} - -// NewTransportWithHTTP creates a new transport based on the provided proto, address and http client. -// It uses Docker's default http transport configuration if the client is nil. -// It does not modify the client's transport if it's not nil. -func NewTransportWithHTTP(proto, addr string, client *http.Client) (Client, error) { - var transport *http.Transport - - if client != nil { - tr, ok := client.Transport.(*http.Transport) - if !ok { - return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport) - } - transport = tr - } else { - transport = defaultTransport(proto, addr) - client = &http.Client{ - Transport: transport, - } - } - - return &apiTransport{ - Client: client, - tlsInfo: &tlsInfo{transport.TLSClientConfig}, - transport: transport, - }, nil -} - -// CancelRequest stops a request execution. -func (a *apiTransport) CancelRequest(req *http.Request) { - a.transport.CancelRequest(req) -} - -// defaultTransport creates a new http.Transport with Docker's -// default transport configuration. -func defaultTransport(proto, addr string) *http.Transport { - tr := new(http.Transport) - sockets.ConfigureTransport(tr, proto, addr) - return tr -} - -var _ Client = &apiTransport{} diff --git a/vendor/src/github.com/docker/engine-api/client/version.go b/vendor/src/github.com/docker/engine-api/client/version.go deleted file mode 100644 index e037551a21..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/version.go +++ /dev/null @@ -1,21 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// ServerVersion returns information of the docker client and server host. -func (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) { - resp, err := cli.get(ctx, "/version", nil, nil) - if err != nil { - return types.Version{}, err - } - - var server types.Version - err = json.NewDecoder(resp.body).Decode(&server) - ensureReaderClosed(resp) - return server, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/volume_create.go b/vendor/src/github.com/docker/engine-api/client/volume_create.go deleted file mode 100644 index cc1e1c1772..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/volume_create.go +++ /dev/null @@ -1,20 +0,0 @@ -package client - -import ( - "encoding/json" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// VolumeCreate creates a volume in the docker host. -func (cli *Client) VolumeCreate(ctx context.Context, options types.VolumeCreateRequest) (types.Volume, error) { - var volume types.Volume - resp, err := cli.post(ctx, "/volumes/create", nil, options, nil) - if err != nil { - return volume, err - } - err = json.NewDecoder(resp.body).Decode(&volume) - ensureReaderClosed(resp) - return volume, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/volume_inspect.go b/vendor/src/github.com/docker/engine-api/client/volume_inspect.go deleted file mode 100644 index 2eaebfafa1..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/volume_inspect.go +++ /dev/null @@ -1,38 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/docker/engine-api/types" - "golang.org/x/net/context" -) - -// VolumeInspect returns the information about a specific volume in the docker host. -func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (types.Volume, error) { - volume, _, err := cli.VolumeInspectWithRaw(ctx, volumeID) - return volume, err -} - -// VolumeInspectWithRaw returns the information about a specific volume in the docker host and its raw representation -func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, error) { - var volume types.Volume - resp, err := cli.get(ctx, "/volumes/"+volumeID, nil, nil) - if err != nil { - if resp.statusCode == http.StatusNotFound { - return volume, nil, volumeNotFoundError{volumeID} - } - return volume, nil, err - } - defer ensureReaderClosed(resp) - - body, err := ioutil.ReadAll(resp.body) - if err != nil { - return volume, nil, err - } - rdr := bytes.NewReader(body) - err = json.NewDecoder(rdr).Decode(&volume) - return volume, body, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/volume_list.go b/vendor/src/github.com/docker/engine-api/client/volume_list.go deleted file mode 100644 index 7c6ccf834f..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/volume_list.go +++ /dev/null @@ -1,32 +0,0 @@ -package client - -import ( - "encoding/json" - "net/url" - - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/filters" - "golang.org/x/net/context" -) - -// VolumeList returns the volumes configured in the docker host. -func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (types.VolumesListResponse, error) { - var volumes types.VolumesListResponse - query := url.Values{} - - if filter.Len() > 0 { - filterJSON, err := filters.ToParamWithVersion(cli.version, filter) - if err != nil { - return volumes, err - } - query.Set("filters", filterJSON) - } - resp, err := cli.get(ctx, "/volumes", query, nil) - if err != nil { - return volumes, err - } - - err = json.NewDecoder(resp.body).Decode(&volumes) - ensureReaderClosed(resp) - return volumes, err -} diff --git a/vendor/src/github.com/docker/engine-api/client/volume_remove.go b/vendor/src/github.com/docker/engine-api/client/volume_remove.go deleted file mode 100644 index 3d5aeff252..0000000000 --- a/vendor/src/github.com/docker/engine-api/client/volume_remove.go +++ /dev/null @@ -1,18 +0,0 @@ -package client - -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, 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 -} diff --git a/vendor/src/github.com/docker/engine-api/types/auth.go b/vendor/src/github.com/docker/engine-api/types/auth.go deleted file mode 100644 index 056af6b842..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/auth.go +++ /dev/null @@ -1,22 +0,0 @@ -package types - -// AuthConfig contains authorization information for connecting to a Registry -type AuthConfig struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Auth string `json:"auth,omitempty"` - - // Email is an optional value associated with the username. - // This field is deprecated and will be removed in a later - // version of docker. - Email string `json:"email,omitempty"` - - ServerAddress string `json:"serveraddress,omitempty"` - - // IdentityToken is used to authenticate the user and get - // an access token for the registry. - IdentityToken string `json:"identitytoken,omitempty"` - - // RegistryToken is a bearer token to be sent to a registry - RegistryToken string `json:"registrytoken,omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/blkiodev/blkio.go b/vendor/src/github.com/docker/engine-api/types/blkiodev/blkio.go deleted file mode 100644 index 931ae10ab1..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/blkiodev/blkio.go +++ /dev/null @@ -1,23 +0,0 @@ -package blkiodev - -import "fmt" - -// WeightDevice is a structure that holds device:weight pair -type WeightDevice struct { - Path string - Weight uint16 -} - -func (w *WeightDevice) String() string { - return fmt.Sprintf("%s:%d", w.Path, w.Weight) -} - -// ThrottleDevice is a structure that holds device:rate_per_second pair -type ThrottleDevice struct { - Path string - Rate uint64 -} - -func (t *ThrottleDevice) String() string { - return fmt.Sprintf("%s:%d", t.Path, t.Rate) -} diff --git a/vendor/src/github.com/docker/engine-api/types/client.go b/vendor/src/github.com/docker/engine-api/types/client.go deleted file mode 100644 index b9245b0956..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/client.go +++ /dev/null @@ -1,300 +0,0 @@ -package types - -import ( - "bufio" - "io" - "net" - - "github.com/docker/engine-api/types/container" - "github.com/docker/engine-api/types/filters" - "github.com/docker/go-units" -) - -// CheckpointCreateOptions holds parameters to create a checkpoint from a container -type CheckpointCreateOptions struct { - CheckpointID string - Exit bool -} - -// ContainerAttachOptions holds parameters to attach to a container. -type ContainerAttachOptions struct { - Stream bool - Stdin bool - Stdout bool - Stderr bool - DetachKeys string -} - -// ContainerCommitOptions holds parameters to commit changes into a container. -type ContainerCommitOptions struct { - Reference string - Comment string - Author string - Changes []string - Pause bool - Config *container.Config -} - -// ContainerExecInspect holds information returned by exec inspect. -type ContainerExecInspect struct { - ExecID string - ContainerID string - Running bool - ExitCode int -} - -// ContainerListOptions holds parameters to list containers with. -type ContainerListOptions struct { - Quiet bool - Size bool - All bool - Latest bool - Since string - Before string - Limit int - Filter filters.Args -} - -// ContainerLogsOptions holds parameters to filter logs with. -type ContainerLogsOptions struct { - ShowStdout bool - ShowStderr bool - Since string - Timestamps bool - Follow bool - Tail string - Details bool -} - -// ContainerRemoveOptions holds parameters to remove containers. -type ContainerRemoveOptions struct { - RemoveVolumes bool - RemoveLinks bool - Force bool -} - -// ContainerStartOptions holds parameters to start containers. -type ContainerStartOptions struct { - CheckpointID string -} - -// CopyToContainerOptions holds information -// about files to copy into a container -type CopyToContainerOptions struct { - AllowOverwriteDirWithFile bool -} - -// EventsOptions hold parameters to filter events with. -type EventsOptions struct { - Since string - Until string - Filters filters.Args -} - -// NetworkListOptions holds parameters to filter the list of networks with. -type NetworkListOptions struct { - Filters filters.Args -} - -// HijackedResponse holds connection information for a hijacked request. -type HijackedResponse struct { - Conn net.Conn - Reader *bufio.Reader -} - -// Close closes the hijacked connection and reader. -func (h *HijackedResponse) Close() { - h.Conn.Close() -} - -// CloseWriter is an interface that implements structs -// that close input streams to prevent from writing. -type CloseWriter interface { - CloseWrite() error -} - -// CloseWrite closes a readWriter for writing. -func (h *HijackedResponse) CloseWrite() error { - if conn, ok := h.Conn.(CloseWriter); ok { - return conn.CloseWrite() - } - return nil -} - -// ImageBuildOptions holds the information -// necessary to build images. -type ImageBuildOptions struct { - Tags []string - SuppressOutput bool - RemoteContext string - NoCache bool - Remove bool - ForceRemove bool - PullParent bool - Isolation container.Isolation - CPUSetCPUs string - CPUSetMems string - CPUShares int64 - CPUQuota int64 - CPUPeriod int64 - Memory int64 - MemorySwap int64 - CgroupParent string - ShmSize int64 - Dockerfile string - Ulimits []*units.Ulimit - BuildArgs map[string]string - 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 -// returned by a server after building -// an image. -type ImageBuildResponse struct { - Body io.ReadCloser - OSType string -} - -// ImageCreateOptions holds information to create images. -type ImageCreateOptions struct { - RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry -} - -// ImageImportSource holds source information for ImageImport -type ImageImportSource struct { - Source io.Reader // Source is the data to send to the server to create this image from (mutually exclusive with SourceName) - SourceName string // SourceName is the name of the image to pull (mutually exclusive with Source) -} - -// ImageImportOptions holds information to import images from the client host. -type ImageImportOptions struct { - Tag string // Tag is the name to tag this image with. This attribute is deprecated. - Message string // Message is the message to tag the image with - Changes []string // Changes are the raw changes to apply to this image -} - -// ImageListOptions holds parameters to filter the list of images with. -type ImageListOptions struct { - MatchName string - All bool - Filters filters.Args -} - -// ImageLoadResponse returns information to the client about a load process. -type ImageLoadResponse struct { - // Body must be closed to avoid a resource leak - Body io.ReadCloser - JSON bool -} - -// ImagePullOptions holds information to pull images. -type ImagePullOptions struct { - All bool - RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry - PrivilegeFunc RequestPrivilegeFunc -} - -// RequestPrivilegeFunc is a function interface that -// clients can supply to retry operations after -// getting an authorization error. -// This function returns the registry authentication -// header value in base 64 format, or an error -// if the privilege request fails. -type RequestPrivilegeFunc func() (string, error) - -//ImagePushOptions holds information to push images. -type ImagePushOptions ImagePullOptions - -// ImageRemoveOptions holds parameters to remove images. -type ImageRemoveOptions struct { - Force bool - PruneChildren bool -} - -// ImageSearchOptions holds parameters to search images with. -type ImageSearchOptions struct { - RegistryAuth string - PrivilegeFunc RequestPrivilegeFunc - Filters filters.Args - Limit int -} - -// ResizeOptions holds parameters to resize a tty. -// It can be used to resize container ttys and -// exec process ttys too. -type ResizeOptions struct { - Height int - Width int -} - -// VersionResponse holds version information for the client and the server -type VersionResponse struct { - Client *Version - Server *Version -} - -// ServerOK returns true when the client could connect to the docker server -// and parse the information received. It returns false otherwise. -func (v VersionResponse) ServerOK() bool { - return v.Server != nil -} - -// NodeListOptions holds parameters to list nodes with. -type NodeListOptions struct { - Filter filters.Args -} - -// NodeRemoveOptions holds parameters to remove nodes with. -type NodeRemoveOptions struct { - Force bool -} - -// ServiceCreateOptions contains the options to use when creating a service. -type ServiceCreateOptions struct { - // EncodedRegistryAuth is the encoded registry authorization credentials to - // use when updating the service. - // - // This field follows the format of the X-Registry-Auth header. - EncodedRegistryAuth string -} - -// ServiceCreateResponse contains the information returned to a client -// on the creation of a new service. -type ServiceCreateResponse struct { - // ID is the ID of the created service. - ID string -} - -// ServiceUpdateOptions contains the options to be used for updating services. -type ServiceUpdateOptions struct { - // EncodedRegistryAuth is the encoded registry authorization credentials to - // use when updating the service. - // - // This field follows the format of the X-Registry-Auth header. - EncodedRegistryAuth string - - // TODO(stevvooe): Consider moving the version parameter of ServiceUpdate - // into this field. While it does open API users up to racy writes, most - // users may not need that level of consistency in practice. -} - -// ServiceListOptions holds parameters to list services with. -type ServiceListOptions struct { - Filter filters.Args -} - -// TaskListOptions holds parameters to list tasks with. -type TaskListOptions struct { - Filter filters.Args -} - -// PluginRemoveOptions holds parameters to remove plugins. -type PluginRemoveOptions struct { - Force bool -} diff --git a/vendor/src/github.com/docker/engine-api/types/configs.go b/vendor/src/github.com/docker/engine-api/types/configs.go deleted file mode 100644 index c371fa1df6..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/configs.go +++ /dev/null @@ -1,61 +0,0 @@ -package types - -import ( - "github.com/docker/engine-api/types/container" - "github.com/docker/engine-api/types/network" -) - -// configs holds structs used for internal communication between the -// frontend (such as an http server) and the backend (such as the -// docker daemon). - -// ContainerCreateConfig is the parameter set to ContainerCreate() -type ContainerCreateConfig struct { - Name string - Config *container.Config - HostConfig *container.HostConfig - NetworkingConfig *network.NetworkingConfig - AdjustCPUShares bool -} - -// ContainerRmConfig holds arguments for the container remove -// operation. This struct is used to tell the backend what operations -// to perform. -type ContainerRmConfig struct { - ForceRemove, RemoveVolume, RemoveLink bool -} - -// ContainerCommitConfig contains build configs for commit operation, -// and is used when making a commit with the current state of the container. -type ContainerCommitConfig struct { - Pause bool - Repo string - Tag string - Author string - Comment string - // merge container config into commit config before commit - MergeConfigs bool - Config *container.Config -} - -// ExecConfig is a small subset of the Config struct that holds the configuration -// for the exec feature of docker. -type ExecConfig struct { - User string // User that will run the command - Privileged bool // Is the container in privileged mode - Tty bool // Attach standard streams to a tty. - AttachStdin bool // Attach the standard input, makes possible user interaction - AttachStderr bool // Attach the standard error - AttachStdout bool // Attach the standard output - Detach bool // Execute in detach mode - DetachKeys string // Escape keys for detach - Env []string // Environment variables - Cmd []string // Execution commands and args -} - -// PluginRmConfig holds arguments for the plugin remove -// operation. This struct is used to tell the backend what operations -// to perform. -type PluginRmConfig struct { - ForceRemove bool -} diff --git a/vendor/src/github.com/docker/engine-api/types/container/config.go b/vendor/src/github.com/docker/engine-api/types/container/config.go deleted file mode 100644 index e300e119e7..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/container/config.go +++ /dev/null @@ -1,62 +0,0 @@ -package container - -import ( - "time" - - "github.com/docker/engine-api/types/strslice" - "github.com/docker/go-connections/nat" -) - -// HealthConfig holds configuration settings for the HEALTHCHECK feature. -type HealthConfig struct { - // Test is the test to perform to check that the container is healthy. - // An empty slice means to inherit the default. - // The options are: - // {} : inherit healthcheck - // {"NONE"} : disable healthcheck - // {"CMD", args...} : exec arguments directly - // {"CMD-SHELL", command} : run command with system's default shell - Test []string `json:",omitempty"` - - // Zero means to inherit. Durations are expressed as integer nanoseconds. - Interval time.Duration `json:",omitempty"` // Interval is the time to wait between checks. - Timeout time.Duration `json:",omitempty"` // Timeout is the time to wait before considering the check to have hung. - - // Retries is the number of consecutive failures needed to consider a container as unhealthy. - // Zero means inherit. - Retries int `json:",omitempty"` -} - -// Config contains the configuration data about a container. -// It should hold only portable information about the container. -// Here, "portable" means "independent from the host we are running on". -// Non-portable information *should* appear in HostConfig. -// All fields added to this struct must be marked `omitempty` to keep getting -// predictable hashes from the old `v1Compatibility` configuration. -type Config struct { - Hostname string // Hostname - Domainname string // Domainname - User string // User that will run the command(s) inside the container, also support user:group - AttachStdin bool // Attach the standard input, makes possible user interaction - AttachStdout bool // Attach the standard output - AttachStderr bool // Attach the standard error - ExposedPorts map[nat.Port]struct{} `json:",omitempty"` // List of exposed ports - Tty bool // Attach standard streams to a tty, including stdin if it is not closed. - OpenStdin bool // Open stdin - StdinOnce bool // If true, close stdin after the 1 attached client disconnects. - Env []string // List of environment variable to set in the container - Cmd strslice.StrSlice // Command to run when starting the container - Healthcheck *HealthConfig `json:",omitempty"` // Healthcheck describes how to check the container is healthy - ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific) - Image string // Name of the image as it was passed by the operator (eg. could be symbolic) - Volumes map[string]struct{} // List of volumes (mounts) used for the container - WorkingDir string // Current directory (PWD) in the command will be launched - Entrypoint strslice.StrSlice // Entrypoint to run when starting the container - NetworkDisabled bool `json:",omitempty"` // Is network disabled - MacAddress string `json:",omitempty"` // Mac Address of the container - OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile - Labels map[string]string // List of labels set to this container - StopSignal string `json:",omitempty"` // Signal to stop a container - StopTimeout *int `json:",omitempty"` // Timeout (in seconds) to stop a container - Shell strslice.StrSlice `json:",omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT -} 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 deleted file mode 100644 index 5a4069ac6b..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/container/host_config.go +++ /dev/null @@ -1,324 +0,0 @@ -package container - -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" -) - -// NetworkMode represents the container network stack. -type NetworkMode string - -// Isolation represents the isolation technology of a container. The supported -// values are platform specific -type Isolation string - -// IsDefault indicates the default isolation technology of a container. On Linux this -// is the native driver. On Windows, this is a Windows Server Container. -func (i Isolation) IsDefault() bool { - return strings.ToLower(string(i)) == "default" || string(i) == "" -} - -// IpcMode represents the container ipc stack. -type IpcMode string - -// IsPrivate indicates whether the container uses its private ipc stack. -func (n IpcMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsHost indicates whether the container uses the host's ipc stack. -func (n IpcMode) IsHost() bool { - return n == "host" -} - -// IsContainer indicates whether the container uses a container's ipc stack. -func (n IpcMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// Valid indicates whether the ipc stack is valid. -func (n IpcMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - case "container": - if len(parts) != 2 || parts[1] == "" { - return false - } - default: - return false - } - return true -} - -// Container returns the name of the container ipc stack is going to be used. -func (n IpcMode) Container() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// UsernsMode represents userns mode in the container. -type UsernsMode string - -// IsHost indicates whether the container uses the host's userns. -func (n UsernsMode) IsHost() bool { - return n == "host" -} - -// IsPrivate indicates whether the container uses the a private userns. -func (n UsernsMode) IsPrivate() bool { - return !(n.IsHost()) -} - -// Valid indicates whether the userns is valid. -func (n UsernsMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true -} - -// CgroupSpec represents the cgroup to use for the container. -type CgroupSpec string - -// IsContainer indicates whether the container is using another container cgroup -func (c CgroupSpec) IsContainer() bool { - parts := strings.SplitN(string(c), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// Valid indicates whether the cgroup spec is valid. -func (c CgroupSpec) Valid() bool { - return c.IsContainer() || c == "" -} - -// Container returns the name of the container whose cgroup will be used. -func (c CgroupSpec) Container() string { - parts := strings.SplitN(string(c), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// UTSMode represents the UTS namespace of the container. -type UTSMode string - -// IsPrivate indicates whether the container uses its private UTS namespace. -func (n UTSMode) IsPrivate() bool { - return !(n.IsHost()) -} - -// IsHost indicates whether the container uses the host's UTS namespace. -func (n UTSMode) IsHost() bool { - return n == "host" -} - -// Valid indicates whether the UTS namespace is valid. -func (n UTSMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true -} - -// PidMode represents the pid namespace of the container. -type PidMode string - -// IsPrivate indicates whether the container uses its own new pid namespace. -func (n PidMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsHost indicates whether the container uses the host's pid namespace. -func (n PidMode) IsHost() bool { - return n == "host" -} - -// IsContainer indicates whether the container uses a container's pid namespace. -func (n PidMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// Valid indicates whether the pid namespace is valid. -func (n PidMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - case "container": - if len(parts) != 2 || parts[1] == "" { - return false - } - default: - return false - } - return true -} - -// Container returns the name of the container whose pid namespace is going to be used. -func (n PidMode) Container() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// DeviceMapping represents the device mapping between the host and the container. -type DeviceMapping struct { - PathOnHost string - PathInContainer string - CgroupPermissions string -} - -// RestartPolicy represents the restart policies of the container. -type RestartPolicy struct { - Name string - MaximumRetryCount int -} - -// IsNone indicates whether the container has the "no" restart policy. -// This means the container will not automatically restart when exiting. -func (rp *RestartPolicy) IsNone() bool { - return rp.Name == "no" || rp.Name == "" -} - -// IsAlways indicates whether the container has the "always" restart policy. -// This means the container will automatically restart regardless of the exit status. -func (rp *RestartPolicy) IsAlways() bool { - return rp.Name == "always" -} - -// IsOnFailure indicates whether the container has the "on-failure" restart policy. -// This means the container will automatically restart of exiting with a non-zero exit status. -func (rp *RestartPolicy) IsOnFailure() bool { - return rp.Name == "on-failure" -} - -// IsUnlessStopped indicates whether the container has the -// "unless-stopped" restart policy. This means the container will -// automatically restart unless user has put it to stopped state. -func (rp *RestartPolicy) IsUnlessStopped() bool { - return rp.Name == "unless-stopped" -} - -// IsSame compares two RestartPolicy to see if they are the same -func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool { - return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount -} - -// LogConfig represents the logging configuration of the container. -type LogConfig struct { - Type string - Config map[string]string -} - -// Resources contains container's resources (cgroups config, ulimits...) -type Resources struct { - // Applicable to all platforms - CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) - Memory int64 // Memory limit (in bytes) - - // Applicable to UNIX platforms - CgroupParent string // Parent cgroup. - BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) - BlkioWeightDevice []*blkiodev.WeightDevice - BlkioDeviceReadBps []*blkiodev.ThrottleDevice - BlkioDeviceWriteBps []*blkiodev.ThrottleDevice - BlkioDeviceReadIOps []*blkiodev.ThrottleDevice - BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice - CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period - CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota - CpusetCpus string // CpusetCpus 0-2, 0,1 - CpusetMems string // CpusetMems 0-2, 0,1 - Devices []DeviceMapping // List of devices to map inside the container - DiskQuota int64 // Disk limit (in bytes) - KernelMemory int64 // Kernel memory limit (in bytes) - MemoryReservation int64 // Memory soft limit (in bytes) - MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap - MemorySwappiness *int64 // Tuning container memory swappiness behaviour - OomKillDisable *bool // Whether to disable OOM Killer or not - PidsLimit int64 // Setting pids limit for a container - Ulimits []*units.Ulimit // List of ulimits to be set in the container - - // Applicable to Windows - CPUCount int64 `json:"CpuCount"` // CPU count - CPUPercent int64 `json:"CpuPercent"` // CPU percent - IOMaximumIOps uint64 // Maximum IOps for the container system drive - IOMaximumBandwidth uint64 // Maximum IO in bytes per second for the container system drive -} - -// UpdateConfig holds the mutable attributes of a Container. -// Those attributes can be updated at runtime. -type UpdateConfig struct { - // Contains container's resources (cgroups, ulimits) - Resources - RestartPolicy RestartPolicy -} - -// HostConfig the non-portable Config structure of a container. -// Here, "non-portable" means "dependent of the host we are running on". -// Portable information *should* appear in Config. -type HostConfig struct { - // Applicable to all platforms - Binds []string // List of volume bindings for this container - ContainerIDFile string // File (path) where the containerId is written - LogConfig LogConfig // Configuration of the logs for this container - NetworkMode NetworkMode // Network mode to use for the container - PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host - RestartPolicy RestartPolicy // Restart policy to be used for the container - AutoRemove bool // Automatically remove container when it exits - VolumeDriver string // Name of the volume driver used to mount volumes - VolumesFrom []string // List of volumes to take from other container - - // Applicable to UNIX platforms - CapAdd strslice.StrSlice // List of kernel capabilities to add to the container - CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container - DNS []string `json:"Dns"` // List of DNS server to lookup - DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for - DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for - ExtraHosts []string // List of extra hosts - GroupAdd []string // List of additional groups that the container process will run as - IpcMode IpcMode // IPC namespace to use for the container - Cgroup CgroupSpec // Cgroup to use for the container - Links []string // List of links (in the name:alias form) - OomScoreAdj int // Container preference for OOM-killing - PidMode PidMode // PID namespace to use for the container - Privileged bool // Is the container in privileged mode - 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 `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 - ShmSize int64 // Total shm memory usage - Sysctls map[string]string `json:",omitempty"` // List of Namespaced sysctls used for the container - Runtime string `json:",omitempty"` // Runtime to use with this container - - // Applicable to Windows - ConsoleSize [2]int // Initial console size - Isolation Isolation // Isolation technology of the container (eg default, hyperv) - - // Contains container's resources (cgroups, ulimits) - Resources - - // Mounts specs used by the container - Mounts []mount.Mount `json:",omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/container/hostconfig_unix.go b/vendor/src/github.com/docker/engine-api/types/container/hostconfig_unix.go deleted file mode 100644 index 4171059a47..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/container/hostconfig_unix.go +++ /dev/null @@ -1,81 +0,0 @@ -// +build !windows - -package container - -import "strings" - -// IsValid indicates if an isolation technology is valid -func (i Isolation) IsValid() bool { - return i.IsDefault() -} - -// IsPrivate indicates whether container uses it's private network stack. -func (n NetworkMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsDefault indicates whether container uses the default network stack. -func (n NetworkMode) IsDefault() bool { - return n == "default" -} - -// NetworkName returns the name of the network stack. -func (n NetworkMode) NetworkName() string { - if n.IsBridge() { - return "bridge" - } else if n.IsHost() { - return "host" - } else if n.IsContainer() { - return "container" - } else if n.IsNone() { - return "none" - } else if n.IsDefault() { - return "default" - } else if n.IsUserDefined() { - return n.UserDefined() - } - return "" -} - -// IsBridge indicates whether container uses the bridge network stack -func (n NetworkMode) IsBridge() bool { - return n == "bridge" -} - -// IsHost indicates whether container uses the host network stack. -func (n NetworkMode) IsHost() bool { - return n == "host" -} - -// IsContainer indicates whether container uses a container network stack. -func (n NetworkMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// IsNone indicates whether container isn't using a network stack. -func (n NetworkMode) IsNone() bool { - return n == "none" -} - -// ConnectedContainer is the id of the container which network this container is connected to. -func (n NetworkMode) ConnectedContainer() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// IsUserDefined indicates user-created network -func (n NetworkMode) IsUserDefined() bool { - return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() -} - -//UserDefined indicates user-created network -func (n NetworkMode) UserDefined() string { - if n.IsUserDefined() { - return string(n) - } - return "" -} diff --git a/vendor/src/github.com/docker/engine-api/types/container/hostconfig_windows.go b/vendor/src/github.com/docker/engine-api/types/container/hostconfig_windows.go deleted file mode 100644 index 0ee332ba68..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/container/hostconfig_windows.go +++ /dev/null @@ -1,87 +0,0 @@ -package container - -import ( - "strings" -) - -// IsDefault indicates whether container uses the default network stack. -func (n NetworkMode) IsDefault() bool { - return n == "default" -} - -// IsNone indicates whether container isn't using a network stack. -func (n NetworkMode) IsNone() bool { - return n == "none" -} - -// IsContainer indicates whether container uses a container network stack. -// Returns false as windows doesn't support this mode -func (n NetworkMode) IsContainer() bool { - return false -} - -// IsBridge indicates whether container uses the bridge network stack -// in windows it is given the name NAT -func (n NetworkMode) IsBridge() bool { - return n == "nat" -} - -// IsHost indicates whether container uses the host network stack. -// returns false as this is not supported by windows -func (n NetworkMode) IsHost() bool { - return false -} - -// IsPrivate indicates whether container uses its private network stack. -func (n NetworkMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// ConnectedContainer is the id of the container which network this container is connected to. -// Returns blank string on windows -func (n NetworkMode) ConnectedContainer() string { - return "" -} - -// IsUserDefined indicates user-created network -func (n NetworkMode) IsUserDefined() bool { - return !n.IsDefault() && !n.IsNone() && !n.IsBridge() -} - -// IsHyperV indicates the use of a Hyper-V partition for isolation -func (i Isolation) IsHyperV() bool { - return strings.ToLower(string(i)) == "hyperv" -} - -// IsProcess indicates the use of process isolation -func (i Isolation) IsProcess() bool { - return strings.ToLower(string(i)) == "process" -} - -// IsValid indicates if an isolation technology is valid -func (i Isolation) IsValid() bool { - return i.IsDefault() || i.IsHyperV() || i.IsProcess() -} - -// NetworkName returns the name of the network stack. -func (n NetworkMode) NetworkName() string { - if n.IsDefault() { - return "default" - } else if n.IsBridge() { - return "nat" - } else if n.IsNone() { - return "none" - } else if n.IsUserDefined() { - return n.UserDefined() - } - - return "" -} - -//UserDefined indicates user-created network -func (n NetworkMode) UserDefined() string { - if n.IsUserDefined() { - return string(n) - } - return "" -} diff --git a/vendor/src/github.com/docker/engine-api/types/errors.go b/vendor/src/github.com/docker/engine-api/types/errors.go deleted file mode 100644 index 649ab95131..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/errors.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -// ErrorResponse is the response body of API errors. -type ErrorResponse struct { - Message string `json:"message"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/events/events.go b/vendor/src/github.com/docker/engine-api/types/events/events.go deleted file mode 100644 index 7129a65acf..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/events/events.go +++ /dev/null @@ -1,42 +0,0 @@ -package events - -const ( - // ContainerEventType is the event type that containers generate - ContainerEventType = "container" - // DaemonEventType is the event type that daemon generate - DaemonEventType = "daemon" - // ImageEventType is the event type that images generate - ImageEventType = "image" - // NetworkEventType is the event type that networks generate - NetworkEventType = "network" - // PluginEventType is the event type that plugins generate - PluginEventType = "plugin" - // VolumeEventType is the event type that volumes generate - VolumeEventType = "volume" -) - -// Actor describes something that generates events, -// like a container, or a network, or a volume. -// It has a defined name and a set or attributes. -// The container attributes are its labels, other actors -// can generate these attributes from other properties. -type Actor struct { - ID string - Attributes map[string]string -} - -// Message represents the information an event contains -type Message struct { - // Deprecated information from JSONMessage. - // With data only in container events. - Status string `json:"status,omitempty"` - ID string `json:"id,omitempty"` - From string `json:"from,omitempty"` - - Type string - Action string - Actor Actor - - Time int64 `json:"time,omitempty"` - TimeNano int64 `json:"timeNano,omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/filters/parse.go b/vendor/src/github.com/docker/engine-api/types/filters/parse.go deleted file mode 100644 index dc2c48b894..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/filters/parse.go +++ /dev/null @@ -1,307 +0,0 @@ -// Package filters provides helper function to parse and handle command line -// filter, used for example in docker ps or docker images commands. -package filters - -import ( - "encoding/json" - "errors" - "fmt" - "regexp" - "strings" - - "github.com/docker/engine-api/types/versions" -) - -// Args stores filter arguments as map key:{map key: bool}. -// It contains an aggregation of the map of arguments (which are in the form -// of -f 'key=value') based on the key, and stores values for the same key -// in a map with string keys and boolean values. -// e.g given -f 'label=label1=1' -f 'label=label2=2' -f 'image.name=ubuntu' -// the args will be {"image.name":{"ubuntu":true},"label":{"label1=1":true,"label2=2":true}} -type Args struct { - fields map[string]map[string]bool -} - -// NewArgs initializes a new Args struct. -func NewArgs() Args { - return Args{fields: map[string]map[string]bool{}} -} - -// ParseFlag parses the argument to the filter flag. Like -// -// `docker ps -f 'created=today' -f 'image.name=ubuntu*'` -// -// If prev map is provided, then it is appended to, and returned. By default a new -// map is created. -func ParseFlag(arg string, prev Args) (Args, error) { - filters := prev - if len(arg) == 0 { - return filters, nil - } - - if !strings.Contains(arg, "=") { - return filters, ErrBadFormat - } - - f := strings.SplitN(arg, "=", 2) - - name := strings.ToLower(strings.TrimSpace(f[0])) - value := strings.TrimSpace(f[1]) - - filters.Add(name, value) - - return filters, nil -} - -// ErrBadFormat is an error returned in case of bad format for a filter. -var ErrBadFormat = errors.New("bad format of filter (expected name=value)") - -// ToParam packs the Args into a string for easy transport from client to server. -func ToParam(a Args) (string, error) { - // this way we don't URL encode {}, just empty space - if a.Len() == 0 { - return "", nil - } - - buf, err := json.Marshal(a.fields) - if err != nil { - return "", err - } - return string(buf), nil -} - -// ToParamWithVersion packs the Args into a string for easy transport from client to server. -// The generated string will depend on the specified version (corresponding to the API version). -func ToParamWithVersion(version string, a Args) (string, error) { - // this way we don't URL encode {}, just empty space - if a.Len() == 0 { - return "", nil - } - - // for daemons older than v1.10, filter must be of the form map[string][]string - buf := []byte{} - err := errors.New("") - if version != "" && versions.LessThan(version, "1.22") { - buf, err = json.Marshal(convertArgsToSlice(a.fields)) - } else { - buf, err = json.Marshal(a.fields) - } - if err != nil { - return "", err - } - return string(buf), nil -} - -// FromParam unpacks the filter Args. -func FromParam(p string) (Args, error) { - if len(p) == 0 { - return NewArgs(), nil - } - - r := strings.NewReader(p) - d := json.NewDecoder(r) - - m := map[string]map[string]bool{} - if err := d.Decode(&m); err != nil { - r.Seek(0, 0) - - // Allow parsing old arguments in slice format. - // Because other libraries might be sending them in this format. - deprecated := map[string][]string{} - if deprecatedErr := d.Decode(&deprecated); deprecatedErr == nil { - m = deprecatedArgs(deprecated) - } else { - return NewArgs(), err - } - } - return Args{m}, nil -} - -// Get returns the list of values associates with a field. -// It returns a slice of strings to keep backwards compatibility with old code. -func (filters Args) Get(field string) []string { - values := filters.fields[field] - if values == nil { - return make([]string, 0) - } - slice := make([]string, 0, len(values)) - for key := range values { - slice = append(slice, key) - } - return slice -} - -// Add adds a new value to a filter field. -func (filters Args) Add(name, value string) { - if _, ok := filters.fields[name]; ok { - filters.fields[name][value] = true - } else { - filters.fields[name] = map[string]bool{value: true} - } -} - -// Del removes a value from a filter field. -func (filters Args) Del(name, value string) { - if _, ok := filters.fields[name]; ok { - delete(filters.fields[name], value) - } -} - -// Len returns the number of fields in the arguments. -func (filters Args) Len() int { - return len(filters.fields) -} - -// MatchKVList returns true if the values for the specified field matches the ones -// from the sources. -// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}}, -// field is 'label' and sources are {'label1': '1', 'label2': '2'} -// it returns true. -func (filters Args) MatchKVList(field string, sources map[string]string) bool { - fieldValues := filters.fields[field] - - //do not filter if there is no filter set or cannot determine filter - if len(fieldValues) == 0 { - return true - } - - if sources == nil || len(sources) == 0 { - return false - } - - for name2match := range fieldValues { - testKV := strings.SplitN(name2match, "=", 2) - - v, ok := sources[testKV[0]] - if !ok { - return false - } - if len(testKV) == 2 && testKV[1] != v { - return false - } - } - - return true -} - -// Match returns true if the values for the specified field matches the source string -// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}}, -// field is 'image.name' and source is 'ubuntu' -// it returns true. -func (filters Args) Match(field, source string) bool { - if filters.ExactMatch(field, source) { - return true - } - - fieldValues := filters.fields[field] - for name2match := range fieldValues { - match, err := regexp.MatchString(name2match, source) - if err != nil { - continue - } - if match { - return true - } - } - return false -} - -// ExactMatch returns true if the source matches exactly one of the filters. -func (filters Args) ExactMatch(field, source string) bool { - fieldValues, ok := filters.fields[field] - //do not filter if there is no filter set or cannot determine filter - if !ok || len(fieldValues) == 0 { - return true - } - - // try to match full name value to avoid O(N) regular expression matching - return fieldValues[source] -} - -// UniqueExactMatch returns true if there is only one filter and the source matches exactly this one. -func (filters Args) UniqueExactMatch(field, source string) bool { - fieldValues := filters.fields[field] - //do not filter if there is no filter set or cannot determine filter - if len(fieldValues) == 0 { - return true - } - if len(filters.fields[field]) != 1 { - return false - } - - // try to match full name value to avoid O(N) regular expression matching - return fieldValues[source] -} - -// FuzzyMatch returns true if the source matches exactly one of the filters, -// or the source has one of the filters as a prefix. -func (filters Args) FuzzyMatch(field, source string) bool { - if filters.ExactMatch(field, source) { - return true - } - - fieldValues := filters.fields[field] - for prefix := range fieldValues { - if strings.HasPrefix(source, prefix) { - return true - } - } - return false -} - -// Include returns true if the name of the field to filter is in the filters. -func (filters Args) Include(field string) bool { - _, ok := filters.fields[field] - return ok -} - -// Validate ensures that all the fields in the filter are valid. -// It returns an error as soon as it finds an invalid field. -func (filters Args) Validate(accepted map[string]bool) error { - for name := range filters.fields { - if !accepted[name] { - return fmt.Errorf("Invalid filter '%s'", name) - } - } - return nil -} - -// WalkValues iterates over the list of filtered values for a field. -// It stops the iteration if it finds an error and it returns that error. -func (filters Args) WalkValues(field string, op func(value string) error) error { - if _, ok := filters.fields[field]; !ok { - return nil - } - for v := range filters.fields[field] { - if err := op(v); err != nil { - return err - } - } - return nil -} - -func deprecatedArgs(d map[string][]string) map[string]map[string]bool { - m := map[string]map[string]bool{} - for k, v := range d { - values := map[string]bool{} - for _, vv := range v { - values[vv] = true - } - m[k] = values - } - return m -} - -func convertArgsToSlice(f map[string]map[string]bool) map[string][]string { - m := map[string][]string{} - for k, v := range f { - values := []string{} - for kk := range v { - if v[kk] { - values = append(values, kk) - } - } - m[k] = values - } - return m -} diff --git a/vendor/src/github.com/docker/engine-api/types/mount/mount.go b/vendor/src/github.com/docker/engine-api/types/mount/mount.go deleted file mode 100644 index 5516ed09db..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/mount/mount.go +++ /dev/null @@ -1,58 +0,0 @@ -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"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/network/network.go b/vendor/src/github.com/docker/engine-api/types/network/network.go deleted file mode 100644 index 47080b652e..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/network/network.go +++ /dev/null @@ -1,53 +0,0 @@ -package network - -// Address represents an IP address -type Address struct { - Addr string - PrefixLen int -} - -// IPAM represents IP Address Management -type IPAM struct { - Driver string - Options map[string]string //Per network IPAM driver options - Config []IPAMConfig -} - -// IPAMConfig represents IPAM configurations -type IPAMConfig struct { - Subnet string `json:",omitempty"` - IPRange string `json:",omitempty"` - Gateway string `json:",omitempty"` - AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"` -} - -// EndpointIPAMConfig represents IPAM configurations for the endpoint -type EndpointIPAMConfig struct { - IPv4Address string `json:",omitempty"` - IPv6Address string `json:",omitempty"` - LinkLocalIPs []string `json:",omitempty"` -} - -// EndpointSettings stores the network endpoint details -type EndpointSettings struct { - // Configurations - IPAMConfig *EndpointIPAMConfig - Links []string - Aliases []string - // Operational data - NetworkID string - EndpointID string - Gateway string - IPAddress string - IPPrefixLen int - IPv6Gateway string - GlobalIPv6Address string - GlobalIPv6PrefixLen int - MacAddress string -} - -// NetworkingConfig represents the container's networking configuration for each of its interfaces -// Carries the networking configs specified in the `docker run` and `docker network connect` commands -type NetworkingConfig struct { - EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network -} diff --git a/vendor/src/github.com/docker/engine-api/types/plugin.go b/vendor/src/github.com/docker/engine-api/types/plugin.go deleted file mode 100644 index 601c0ac12a..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/plugin.go +++ /dev/null @@ -1,170 +0,0 @@ -// +build experimental - -package types - -import ( - "encoding/json" - "fmt" -) - -// PluginInstallOptions holds parameters to install a plugin. -type PluginInstallOptions struct { - Disabled bool - AcceptAllPermissions bool - RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry - PrivilegeFunc RequestPrivilegeFunc - AcceptPermissionsFunc func(PluginPrivileges) (bool, error) -} - -// PluginConfig represents the values of settings potentially modifiable by a user -type PluginConfig struct { - Mounts []PluginMount - Env []string - Args []string - Devices []PluginDevice -} - -// Plugin represents a Docker plugin for the remote API -type Plugin struct { - ID string `json:"Id,omitempty"` - Name string - Tag string - // Enabled is true when the plugin is running, is false when the plugin is not running, only installed. - Enabled bool - Config PluginConfig - Manifest PluginManifest -} - -// PluginsListResponse contains the response for the remote API -type PluginsListResponse []*Plugin - -const ( - authzDriver = "AuthzDriver" - graphDriver = "GraphDriver" - ipamDriver = "IpamDriver" - networkDriver = "NetworkDriver" - volumeDriver = "VolumeDriver" -) - -// PluginInterfaceType represents a type that a plugin implements. -type PluginInterfaceType struct { - Prefix string // This is always "docker" - Capability string // Capability should be validated against the above list. - Version string // Plugin API version. Depends on the capability -} - -// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType -func (t *PluginInterfaceType) UnmarshalJSON(p []byte) error { - versionIndex := len(p) - prefixIndex := 0 - if len(p) < 2 || p[0] != '"' || p[len(p)-1] != '"' { - return fmt.Errorf("%q is not a plugin interface type", p) - } - p = p[1 : len(p)-1] -loop: - for i, b := range p { - switch b { - case '.': - prefixIndex = i - case '/': - versionIndex = i - break loop - } - } - t.Prefix = string(p[:prefixIndex]) - t.Capability = string(p[prefixIndex+1 : versionIndex]) - if versionIndex < len(p) { - t.Version = string(p[versionIndex+1:]) - } - return nil -} - -// MarshalJSON implements json.Marshaler for PluginInterfaceType -func (t *PluginInterfaceType) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} - -// String implements fmt.Stringer for PluginInterfaceType -func (t PluginInterfaceType) String() string { - return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version) -} - -// PluginInterface describes the interface between Docker and plugin -type PluginInterface struct { - Types []PluginInterfaceType - Socket string -} - -// PluginSetting is to be embedded in other structs, if they are supposed to be -// modifiable by the user. -type PluginSetting struct { - Name string - Description string - Settable []string -} - -// PluginNetwork represents the network configuration for a plugin -type PluginNetwork struct { - Type string -} - -// PluginMount represents the mount configuration for a plugin -type PluginMount struct { - PluginSetting - Source *string - Destination string - Type string - Options []string -} - -// PluginEnv represents an environment variable for a plugin -type PluginEnv struct { - PluginSetting - Value *string -} - -// PluginArgs represents the command line arguments for a plugin -type PluginArgs struct { - PluginSetting - Value []string -} - -// PluginDevice represents a device for a plugin -type PluginDevice struct { - PluginSetting - Path *string -} - -// PluginUser represents the user for the plugin's process -type PluginUser struct { - UID uint32 `json:"Uid,omitempty"` - GID uint32 `json:"Gid,omitempty"` -} - -// PluginManifest represents the manifest of a plugin -type PluginManifest struct { - ManifestVersion string - Description string - Documentation string - Interface PluginInterface - Entrypoint []string - Workdir string - User PluginUser `json:",omitempty"` - Network PluginNetwork - Capabilities []string - Mounts []PluginMount - Devices []PluginDevice - Env []PluginEnv - Args PluginArgs -} - -// PluginPrivilege describes a permission the user has to accept -// upon installing a plugin. -type PluginPrivilege struct { - Name string - Description string - Value []string -} - -// PluginPrivileges is a list of PluginPrivilege -type PluginPrivileges []PluginPrivilege diff --git a/vendor/src/github.com/docker/engine-api/types/registry/registry.go b/vendor/src/github.com/docker/engine-api/types/registry/registry.go deleted file mode 100644 index 28fafab901..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/registry/registry.go +++ /dev/null @@ -1,104 +0,0 @@ -package registry - -import ( - "encoding/json" - "net" -) - -// ServiceConfig stores daemon registry services configuration. -type ServiceConfig struct { - InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"` - IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"` - Mirrors []string -} - -// NetIPNet is the net.IPNet type, which can be marshalled and -// 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()) -} - -// UnmarshalJSON sets the IPNet from a byte array of JSON -func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) { - var ipnetStr string - if err = json.Unmarshal(b, &ipnetStr); err == nil { - var cidr *net.IPNet - if _, cidr, err = net.ParseCIDR(ipnetStr); err == nil { - *ipnet = NetIPNet(*cidr) - } - } - return -} - -// IndexInfo contains information about a registry -// -// RepositoryInfo Examples: -// { -// "Index" : { -// "Name" : "docker.io", -// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"], -// "Secure" : true, -// "Official" : true, -// }, -// "RemoteName" : "library/debian", -// "LocalName" : "debian", -// "CanonicalName" : "docker.io/debian" -// "Official" : true, -// } -// -// { -// "Index" : { -// "Name" : "127.0.0.1:5000", -// "Mirrors" : [], -// "Secure" : false, -// "Official" : false, -// }, -// "RemoteName" : "user/repo", -// "LocalName" : "127.0.0.1:5000/user/repo", -// "CanonicalName" : "127.0.0.1:5000/user/repo", -// "Official" : false, -// } -type IndexInfo struct { - // Name is the name of the registry, such as "docker.io" - Name string - // Mirrors is a list of mirrors, expressed as URIs - Mirrors []string - // Secure is set to false if the registry is part of the list of - // insecure registries. Insecure registries accept HTTP and/or accept - // HTTPS with certificates from unknown CAs. - Secure bool - // Official indicates whether this is an official registry - Official bool -} - -// SearchResult describes a search result returned from a registry -type SearchResult struct { - // StarCount indicates the number of stars this repository has - StarCount int `json:"star_count"` - // IsOfficial is true if the result is from an official repository. - IsOfficial bool `json:"is_official"` - // Name is the name of the repository - Name string `json:"name"` - // IsAutomated indicates whether the result is automated - IsAutomated bool `json:"is_automated"` - // Description is a textual description of the repository - Description string `json:"description"` -} - -// SearchResults lists a collection search results returned from a registry -type SearchResults struct { - // Query contains the query string that generated the search results - Query string `json:"query"` - // NumResults indicates the number of results the query returned - NumResults int `json:"num_results"` - // Results is a slice containing the actual results for the search - Results []SearchResult `json:"results"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/seccomp.go b/vendor/src/github.com/docker/engine-api/types/seccomp.go deleted file mode 100644 index 4f02ef36b8..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/seccomp.go +++ /dev/null @@ -1,93 +0,0 @@ -package types - -// Seccomp represents the config for a seccomp profile for syscall restriction. -type Seccomp struct { - DefaultAction Action `json:"defaultAction"` - // Architectures is kept to maintain backward compatibility with the old - // seccomp profile. - Architectures []Arch `json:"architectures,omitempty"` - ArchMap []Architecture `json:"archMap,omitempty"` - Syscalls []*Syscall `json:"syscalls"` -} - -// Architecture is used to represent an specific architecture -// and its sub-architectures -type Architecture struct { - Arch Arch `json:"architecture"` - SubArches []Arch `json:"subArchitectures"` -} - -// Arch used for architectures -type Arch string - -// Additional architectures permitted to be used for system calls -// By default only the native architecture of the kernel is permitted -const ( - ArchX86 Arch = "SCMP_ARCH_X86" - ArchX86_64 Arch = "SCMP_ARCH_X86_64" - ArchX32 Arch = "SCMP_ARCH_X32" - ArchARM Arch = "SCMP_ARCH_ARM" - ArchAARCH64 Arch = "SCMP_ARCH_AARCH64" - ArchMIPS Arch = "SCMP_ARCH_MIPS" - ArchMIPS64 Arch = "SCMP_ARCH_MIPS64" - ArchMIPS64N32 Arch = "SCMP_ARCH_MIPS64N32" - ArchMIPSEL Arch = "SCMP_ARCH_MIPSEL" - ArchMIPSEL64 Arch = "SCMP_ARCH_MIPSEL64" - ArchMIPSEL64N32 Arch = "SCMP_ARCH_MIPSEL64N32" - ArchPPC Arch = "SCMP_ARCH_PPC" - ArchPPC64 Arch = "SCMP_ARCH_PPC64" - ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE" - ArchS390 Arch = "SCMP_ARCH_S390" - ArchS390X Arch = "SCMP_ARCH_S390X" -) - -// Action taken upon Seccomp rule match -type Action string - -// Define actions for Seccomp rules -const ( - ActKill Action = "SCMP_ACT_KILL" - ActTrap Action = "SCMP_ACT_TRAP" - ActErrno Action = "SCMP_ACT_ERRNO" - ActTrace Action = "SCMP_ACT_TRACE" - ActAllow Action = "SCMP_ACT_ALLOW" -) - -// Operator used to match syscall arguments in Seccomp -type Operator string - -// Define operators for syscall arguments in Seccomp -const ( - OpNotEqual Operator = "SCMP_CMP_NE" - OpLessThan Operator = "SCMP_CMP_LT" - OpLessEqual Operator = "SCMP_CMP_LE" - OpEqualTo Operator = "SCMP_CMP_EQ" - OpGreaterEqual Operator = "SCMP_CMP_GE" - OpGreaterThan Operator = "SCMP_CMP_GT" - OpMaskedEqual Operator = "SCMP_CMP_MASKED_EQ" -) - -// Arg used for matching specific syscall arguments in Seccomp -type Arg struct { - Index uint `json:"index"` - Value uint64 `json:"value"` - ValueTwo uint64 `json:"valueTwo"` - Op Operator `json:"op"` -} - -// Filter is used to conditionally apply Seccomp rules -type Filter struct { - Caps []string `json:"caps,omitempty"` - Arches []string `json:"arches,omitempty"` -} - -// Syscall is used to match a group of syscalls in Seccomp -type Syscall struct { - Name string `json:"name,omitempty"` - Names []string `json:"names,omitempty"` - Action Action `json:"action"` - Args []*Arg `json:"args"` - Comment string `json:"comment"` - Includes Filter `json:"includes"` - Excludes Filter `json:"excludes"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/stats.go b/vendor/src/github.com/docker/engine-api/types/stats.go deleted file mode 100644 index b420ebe7f6..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/stats.go +++ /dev/null @@ -1,115 +0,0 @@ -// Package types is used for API stability in the types and response to the -// consumers of the API stats endpoint. -package types - -import "time" - -// ThrottlingData stores CPU throttling stats of one running container -type ThrottlingData struct { - // Number of periods with throttling active - Periods uint64 `json:"periods"` - // Number of periods when the container hits its throttling limit. - ThrottledPeriods uint64 `json:"throttled_periods"` - // Aggregate time the container was throttled for in nanoseconds. - ThrottledTime uint64 `json:"throttled_time"` -} - -// CPUUsage stores All CPU stats aggregated since container inception. -type CPUUsage struct { - // Total CPU time consumed. - // Units: nanoseconds. - TotalUsage uint64 `json:"total_usage"` - // Total CPU time consumed per core. - // Units: nanoseconds. - PercpuUsage []uint64 `json:"percpu_usage"` - // Time spent by tasks of the cgroup in kernel mode. - // Units: nanoseconds. - UsageInKernelmode uint64 `json:"usage_in_kernelmode"` - // Time spent by tasks of the cgroup in user mode. - // Units: nanoseconds. - UsageInUsermode uint64 `json:"usage_in_usermode"` -} - -// CPUStats aggregates and wraps all CPU related info of container -type CPUStats struct { - CPUUsage CPUUsage `json:"cpu_usage"` - SystemUsage uint64 `json:"system_cpu_usage"` - ThrottlingData ThrottlingData `json:"throttling_data,omitempty"` -} - -// MemoryStats aggregates All memory stats since container inception -type MemoryStats struct { - // current res_counter usage for memory - Usage uint64 `json:"usage"` - // maximum usage ever recorded. - MaxUsage uint64 `json:"max_usage"` - // TODO(vishh): Export these as stronger types. - // all the stats exported via memory.stat. - Stats map[string]uint64 `json:"stats"` - // number of times memory usage hits limits. - Failcnt uint64 `json:"failcnt"` - Limit uint64 `json:"limit"` -} - -// BlkioStatEntry is one small entity to store a piece of Blkio stats -// TODO Windows: This can be factored out -type BlkioStatEntry struct { - Major uint64 `json:"major"` - Minor uint64 `json:"minor"` - Op string `json:"op"` - Value uint64 `json:"value"` -} - -// BlkioStats stores All IO service stats for data read and write -// TODO Windows: This can be factored out -type BlkioStats struct { - // number of bytes transferred to and from the block device - IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"` - IoServicedRecursive []BlkioStatEntry `json:"io_serviced_recursive"` - IoQueuedRecursive []BlkioStatEntry `json:"io_queue_recursive"` - IoServiceTimeRecursive []BlkioStatEntry `json:"io_service_time_recursive"` - IoWaitTimeRecursive []BlkioStatEntry `json:"io_wait_time_recursive"` - IoMergedRecursive []BlkioStatEntry `json:"io_merged_recursive"` - IoTimeRecursive []BlkioStatEntry `json:"io_time_recursive"` - SectorsRecursive []BlkioStatEntry `json:"sectors_recursive"` -} - -// NetworkStats aggregates All network stats of one container -// TODO Windows: This will require refactoring -type NetworkStats struct { - RxBytes uint64 `json:"rx_bytes"` - RxPackets uint64 `json:"rx_packets"` - RxErrors uint64 `json:"rx_errors"` - RxDropped uint64 `json:"rx_dropped"` - TxBytes uint64 `json:"tx_bytes"` - TxPackets uint64 `json:"tx_packets"` - TxErrors uint64 `json:"tx_errors"` - TxDropped uint64 `json:"tx_dropped"` -} - -// PidsStats contains the stats of a container's pids -type PidsStats struct { - // Current is the number of pids in the cgroup - Current uint64 `json:"current,omitempty"` - // Limit is the hard limit on the number of pids in the cgroup. - // A "Limit" of 0 means that there is no limit. - Limit uint64 `json:"limit,omitempty"` -} - -// Stats is Ultimate struct aggregating all types of stats of one container -type Stats struct { - Read time.Time `json:"read"` - PreCPUStats CPUStats `json:"precpu_stats,omitempty"` - CPUStats CPUStats `json:"cpu_stats,omitempty"` - MemoryStats MemoryStats `json:"memory_stats,omitempty"` - BlkioStats BlkioStats `json:"blkio_stats,omitempty"` - PidsStats PidsStats `json:"pids_stats,omitempty"` -} - -// StatsJSON is newly used Networks -type StatsJSON struct { - Stats - - // Networks request version >=1.21 - Networks map[string]NetworkStats `json:"networks,omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/strslice/strslice.go b/vendor/src/github.com/docker/engine-api/types/strslice/strslice.go deleted file mode 100644 index bad493fb89..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/strslice/strslice.go +++ /dev/null @@ -1,30 +0,0 @@ -package strslice - -import "encoding/json" - -// StrSlice represents a string or an array of strings. -// We need to override the json decoder to accept both options. -type StrSlice []string - -// UnmarshalJSON decodes the byte slice whether it's a string or an array of -// strings. This method is needed to implement json.Unmarshaler. -func (e *StrSlice) UnmarshalJSON(b []byte) error { - if len(b) == 0 { - // With no input, we preserve the existing value by returning nil and - // leaving the target alone. This allows defining default values for - // the type. - return nil - } - - p := make([]string, 0, 1) - if err := json.Unmarshal(b, &p); err != nil { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - p = append(p, s) - } - - *e = p - return nil -} diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/common.go b/vendor/src/github.com/docker/engine-api/types/swarm/common.go deleted file mode 100644 index b87f545369..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/common.go +++ /dev/null @@ -1,21 +0,0 @@ -package swarm - -import "time" - -// Version represent the internal object version. -type Version struct { - Index uint64 `json:",omitempty"` -} - -// Meta is base object inherited by most of the other once. -type Meta struct { - Version Version `json:",omitempty"` - CreatedAt time.Time `json:",omitempty"` - UpdatedAt time.Time `json:",omitempty"` -} - -// Annotations represents how to describe an object. -type Annotations struct { - Name string `json:",omitempty"` - Labels map[string]string `json:",omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/container.go b/vendor/src/github.com/docker/engine-api/types/swarm/container.go deleted file mode 100644 index 11a3889b44..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/container.go +++ /dev/null @@ -1,22 +0,0 @@ -package swarm - -import ( - "time" - - "github.com/docker/engine-api/types/mount" -) - -// ContainerSpec represents the spec of a container. -type ContainerSpec struct { - Image string `json:",omitempty"` - Labels map[string]string `json:",omitempty"` - Command []string `json:",omitempty"` - Args []string `json:",omitempty"` - Env []string `json:",omitempty"` - Dir string `json:",omitempty"` - User string `json:",omitempty"` - Groups []string `json:",omitempty"` - TTY bool `json:",omitempty"` - Mounts []mount.Mount `json:",omitempty"` - StopGracePeriod *time.Duration `json:",omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/network.go b/vendor/src/github.com/docker/engine-api/types/swarm/network.go deleted file mode 100644 index 0af0ce1daa..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/network.go +++ /dev/null @@ -1,100 +0,0 @@ -package swarm - -// Endpoint represents an endpoint. -type Endpoint struct { - Spec EndpointSpec `json:",omitempty"` - Ports []PortConfig `json:",omitempty"` - VirtualIPs []EndpointVirtualIP `json:",omitempty"` -} - -// EndpointSpec represents the spec of an endpoint. -type EndpointSpec struct { - Mode ResolutionMode `json:",omitempty"` - Ports []PortConfig `json:",omitempty"` -} - -// ResolutionMode represents a resolution mode. -type ResolutionMode string - -const ( - // ResolutionModeVIP VIP - ResolutionModeVIP ResolutionMode = "vip" - // ResolutionModeDNSRR DNSRR - ResolutionModeDNSRR ResolutionMode = "dnsrr" -) - -// PortConfig represents the config of a port. -type PortConfig struct { - Name string `json:",omitempty"` - Protocol PortConfigProtocol `json:",omitempty"` - TargetPort uint32 `json:",omitempty"` - PublishedPort uint32 `json:",omitempty"` -} - -// PortConfigProtocol represents the protocol of a port. -type PortConfigProtocol string - -const ( - // TODO(stevvooe): These should be used generally, not just for PortConfig. - - // PortConfigProtocolTCP TCP - PortConfigProtocolTCP PortConfigProtocol = "tcp" - // PortConfigProtocolUDP UDP - PortConfigProtocolUDP PortConfigProtocol = "udp" -) - -// EndpointVirtualIP represents the virtual ip of a port. -type EndpointVirtualIP struct { - NetworkID string `json:",omitempty"` - Addr string `json:",omitempty"` -} - -// Network represents a network. -type Network struct { - ID string - Meta - Spec NetworkSpec `json:",omitempty"` - DriverState Driver `json:",omitempty"` - IPAMOptions *IPAMOptions `json:",omitempty"` -} - -// NetworkSpec represents the spec of a network. -type NetworkSpec struct { - Annotations - DriverConfiguration *Driver `json:",omitempty"` - IPv6Enabled bool `json:",omitempty"` - Internal bool `json:",omitempty"` - Attachable bool `json:",omitempty"` - IPAMOptions *IPAMOptions `json:",omitempty"` -} - -// NetworkAttachmentConfig represents the configuration of a network attachment. -type NetworkAttachmentConfig struct { - Target string `json:",omitempty"` - Aliases []string `json:",omitempty"` -} - -// NetworkAttachment represents a network attachment. -type NetworkAttachment struct { - Network Network `json:",omitempty"` - Addresses []string `json:",omitempty"` -} - -// IPAMOptions represents ipam options. -type IPAMOptions struct { - Driver Driver `json:",omitempty"` - Configs []IPAMConfig `json:",omitempty"` -} - -// IPAMConfig represents ipam configuration. -type IPAMConfig struct { - Subnet string `json:",omitempty"` - Range string `json:",omitempty"` - Gateway string `json:",omitempty"` -} - -// Driver represents a network driver. -type Driver struct { - Name string `json:",omitempty"` - Options map[string]string `json:",omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/node.go b/vendor/src/github.com/docker/engine-api/types/swarm/node.go deleted file mode 100644 index 9987662a58..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/node.go +++ /dev/null @@ -1,107 +0,0 @@ -package swarm - -// Node represents a node. -type Node struct { - ID string - Meta - - Spec NodeSpec `json:",omitempty"` - Description NodeDescription `json:",omitempty"` - Status NodeStatus `json:",omitempty"` - ManagerStatus *ManagerStatus `json:",omitempty"` -} - -// NodeSpec represents the spec of a node. -type NodeSpec struct { - Annotations - Role NodeRole `json:",omitempty"` - Availability NodeAvailability `json:",omitempty"` -} - -// NodeRole represents the role of a node. -type NodeRole string - -const ( - // NodeRoleWorker WORKER - NodeRoleWorker NodeRole = "worker" - // NodeRoleManager MANAGER - NodeRoleManager NodeRole = "manager" -) - -// NodeAvailability represents the availability of a node. -type NodeAvailability string - -const ( - // NodeAvailabilityActive ACTIVE - NodeAvailabilityActive NodeAvailability = "active" - // NodeAvailabilityPause PAUSE - NodeAvailabilityPause NodeAvailability = "pause" - // NodeAvailabilityDrain DRAIN - NodeAvailabilityDrain NodeAvailability = "drain" -) - -// NodeDescription represents the description of a node. -type NodeDescription struct { - Hostname string `json:",omitempty"` - Platform Platform `json:",omitempty"` - Resources Resources `json:",omitempty"` - Engine EngineDescription `json:",omitempty"` -} - -// Platform represents the platfrom (Arch/OS). -type Platform struct { - Architecture string `json:",omitempty"` - OS string `json:",omitempty"` -} - -// EngineDescription represents the description of an engine. -type EngineDescription struct { - EngineVersion string `json:",omitempty"` - Labels map[string]string `json:",omitempty"` - Plugins []PluginDescription `json:",omitempty"` -} - -// PluginDescription represents the description of an engine plugin. -type PluginDescription struct { - Type string `json:",omitempty"` - Name string `json:",omitempty"` -} - -// NodeStatus represents the status of a node. -type NodeStatus struct { - State NodeState `json:",omitempty"` - Message string `json:",omitempty"` -} - -// Reachability represents the reachability of a node. -type Reachability string - -const ( - // ReachabilityUnknown UNKNOWN - ReachabilityUnknown Reachability = "unknown" - // ReachabilityUnreachable UNREACHABLE - ReachabilityUnreachable Reachability = "unreachable" - // ReachabilityReachable REACHABLE - ReachabilityReachable Reachability = "reachable" -) - -// ManagerStatus represents the status of a manager. -type ManagerStatus struct { - Leader bool `json:",omitempty"` - Reachability Reachability `json:",omitempty"` - Addr string `json:",omitempty"` -} - -// NodeState represents the state of a node. -type NodeState string - -const ( - // NodeStateUnknown UNKNOWN - NodeStateUnknown NodeState = "unknown" - // NodeStateDown DOWN - NodeStateDown NodeState = "down" - // NodeStateReady READY - NodeStateReady NodeState = "ready" - // NodeStateDisconnected DISCONNECTED - NodeStateDisconnected NodeState = "disconnected" -) diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/service.go b/vendor/src/github.com/docker/engine-api/types/swarm/service.go deleted file mode 100644 index d679c45406..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/service.go +++ /dev/null @@ -1,77 +0,0 @@ -package swarm - -import "time" - -// Service represents a service. -type Service struct { - ID string - Meta - Spec ServiceSpec `json:",omitempty"` - Endpoint Endpoint `json:",omitempty"` - UpdateStatus UpdateStatus `json:",omitempty"` -} - -// ServiceSpec represents the spec of a service. -type ServiceSpec struct { - Annotations - - // TaskTemplate defines how the service should construct new tasks when - // orchestrating this service. - TaskTemplate TaskSpec `json:",omitempty"` - Mode ServiceMode `json:",omitempty"` - UpdateConfig *UpdateConfig `json:",omitempty"` - - // Networks field in ServiceSpec is being deprecated. Users of - // engine-api should start using the same field in - // TaskSpec. This field will be removed in future releases. - Networks []NetworkAttachmentConfig `json:",omitempty"` - EndpointSpec *EndpointSpec `json:",omitempty"` -} - -// ServiceMode represents the mode of a service. -type ServiceMode struct { - Replicated *ReplicatedService `json:",omitempty"` - Global *GlobalService `json:",omitempty"` -} - -// UpdateState is the state of a service update. -type UpdateState string - -const ( - // UpdateStateUpdating is the updating state. - UpdateStateUpdating UpdateState = "updating" - // UpdateStatePaused is the paused state. - UpdateStatePaused UpdateState = "paused" - // UpdateStateCompleted is the completed state. - UpdateStateCompleted UpdateState = "completed" -) - -// UpdateStatus reports the status of a service update. -type UpdateStatus struct { - State UpdateState `json:",omitempty"` - StartedAt time.Time `json:",omitempty"` - CompletedAt time.Time `json:",omitempty"` - Message string `json:",omitempty"` -} - -// ReplicatedService is a kind of ServiceMode. -type ReplicatedService struct { - Replicas *uint64 `json:",omitempty"` -} - -// GlobalService is a kind of ServiceMode. -type GlobalService struct{} - -const ( - // UpdateFailureActionPause PAUSE - UpdateFailureActionPause = "pause" - // UpdateFailureActionContinue CONTINUE - UpdateFailureActionContinue = "continue" -) - -// UpdateConfig represents the update configuration. -type UpdateConfig struct { - Parallelism uint64 `json:",omitempty"` - Delay time.Duration `json:",omitempty"` - FailureAction string `json:",omitempty"` -} 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 deleted file mode 100644 index 23b2e6affe..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/swarm.go +++ /dev/null @@ -1,155 +0,0 @@ -package swarm - -import "time" - -// 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 - Meta - Spec Spec -} - -// Swarm represents a swarm. -type Swarm struct { - ClusterInfo - JoinTokens JoinTokens -} - -// JoinTokens contains the tokens workers and managers need to join the swarm. -type JoinTokens struct { - Worker string - Manager string -} - -// Spec represents the spec of a swarm. -type Spec struct { - Annotations - - Orchestration OrchestrationConfig `json:",omitempty"` - Raft RaftConfig `json:",omitempty"` - Dispatcher DispatcherConfig `json:",omitempty"` - CAConfig CAConfig `json:",omitempty"` - TaskDefaults TaskDefaults `json:",omitempty"` -} - -// OrchestrationConfig represents orchestration configuration. -type OrchestrationConfig struct { - TaskHistoryRetentionLimit int64 `json:",omitempty"` -} - -// TaskDefaults parameterizes cluster-level task creation with default values. -type TaskDefaults struct { - // LogDriver selects the log driver to use for tasks created in the - // orchestrator if unspecified by a service. - // - // Updating this value will only have an affect on new tasks. Old tasks - // will continue use their previously configured log driver until - // recreated. - LogDriver *Driver `json:",omitempty"` -} - -// RaftConfig represents raft configuration. -type RaftConfig struct { - SnapshotInterval uint64 `json:",omitempty"` - KeepOldSnapshots uint64 `json:",omitempty"` - LogEntriesForSlowFollowers uint64 `json:",omitempty"` - - // ElectionTick is the number of ticks that a follower will wait for a message - // from the leader before becoming a candidate and starting an election. - // ElectionTick must be greater than HeartbeatTick. - // - // A tick currently defaults to one second, so these translate directly to - // seconds currently, but this is NOT guaranteed. - ElectionTick int - - // HeartbeatTick is the number of ticks between heartbeats. Every - // HeartbeatTick ticks, the leader will send a heartbeat to the - // followers. - // - // A tick currently defaults to one second, so these translate directly to - // seconds currently, but this is NOT guaranteed. - HeartbeatTick int -} - -// DispatcherConfig represents dispatcher configuration. -type DispatcherConfig struct { - HeartbeatPeriod time.Duration `json:",omitempty"` -} - -// CAConfig represents CA configuration. -type CAConfig struct { - NodeCertExpiry time.Duration `json:",omitempty"` - ExternalCAs []*ExternalCA `json:",omitempty"` -} - -// ExternalCAProtocol represents type of external CA. -type ExternalCAProtocol string - -// ExternalCAProtocolCFSSL CFSSL -const ExternalCAProtocolCFSSL ExternalCAProtocol = "cfssl" - -// ExternalCA defines external CA to be used by the cluster. -type ExternalCA struct { - Protocol ExternalCAProtocol - URL string - Options map[string]string `json:",omitempty"` -} - -// InitRequest is the request used to init a swarm. -type InitRequest struct { - ListenAddr string - AdvertiseAddr string - ForceNewCluster bool - Spec Spec -} - -// JoinRequest is the request used to join a swarm. -type JoinRequest struct { - ListenAddr string - AdvertiseAddr string - RemoteAddrs []string - JoinToken string // accept by secret -} - -// LocalNodeState represents the state of the local node. -type LocalNodeState string - -const ( - // LocalNodeStateInactive INACTIVE - LocalNodeStateInactive LocalNodeState = "inactive" - // LocalNodeStatePending PENDING - LocalNodeStatePending LocalNodeState = "pending" - // LocalNodeStateActive ACTIVE - LocalNodeStateActive LocalNodeState = "active" - // LocalNodeStateError ERROR - LocalNodeStateError LocalNodeState = "error" -) - -// Info represents generic information about swarm. -type Info struct { - NodeID string - NodeAddr string - - LocalNodeState LocalNodeState - ControlAvailable bool - Error string - - RemoteManagers []Peer - Nodes int - Managers int - - Cluster ClusterInfo -} - -// Peer represents a peer. -type Peer struct { - NodeID string - Addr string -} - -// UpdateFlags contains flags for SwarmUpdate. -type UpdateFlags struct { - RotateWorkerToken bool - RotateManagerToken bool -} diff --git a/vendor/src/github.com/docker/engine-api/types/swarm/task.go b/vendor/src/github.com/docker/engine-api/types/swarm/task.go deleted file mode 100644 index 591e07ba41..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/swarm/task.go +++ /dev/null @@ -1,117 +0,0 @@ -package swarm - -import "time" - -// TaskState represents the state of a task. -type TaskState string - -const ( - // TaskStateNew NEW - TaskStateNew TaskState = "new" - // TaskStateAllocated ALLOCATED - TaskStateAllocated TaskState = "allocated" - // TaskStatePending PENDING - TaskStatePending TaskState = "pending" - // TaskStateAssigned ASSIGNED - TaskStateAssigned TaskState = "assigned" - // TaskStateAccepted ACCEPTED - TaskStateAccepted TaskState = "accepted" - // TaskStatePreparing PREPARING - TaskStatePreparing TaskState = "preparing" - // TaskStateReady READY - TaskStateReady TaskState = "ready" - // TaskStateStarting STARTING - TaskStateStarting TaskState = "starting" - // TaskStateRunning RUNNING - TaskStateRunning TaskState = "running" - // TaskStateComplete COMPLETE - TaskStateComplete TaskState = "complete" - // TaskStateShutdown SHUTDOWN - TaskStateShutdown TaskState = "shutdown" - // TaskStateFailed FAILED - TaskStateFailed TaskState = "failed" - // TaskStateRejected REJECTED - TaskStateRejected TaskState = "rejected" -) - -// Task represents a task. -type Task struct { - ID string - Meta - Annotations - - Spec TaskSpec `json:",omitempty"` - ServiceID string `json:",omitempty"` - Slot int `json:",omitempty"` - NodeID string `json:",omitempty"` - Status TaskStatus `json:",omitempty"` - DesiredState TaskState `json:",omitempty"` - NetworksAttachments []NetworkAttachment `json:",omitempty"` -} - -// TaskSpec represents the spec of a task. -type TaskSpec struct { - ContainerSpec ContainerSpec `json:",omitempty"` - Resources *ResourceRequirements `json:",omitempty"` - RestartPolicy *RestartPolicy `json:",omitempty"` - Placement *Placement `json:",omitempty"` - Networks []NetworkAttachmentConfig `json:",omitempty"` - - // LogDriver specifies the LogDriver to use for tasks created from this - // spec. If not present, the one on cluster default on swarm.Spec will be - // used, finally falling back to the engine default if not specified. - LogDriver *Driver `json:",omitempty"` -} - -// Resources represents resources (CPU/Memory). -type Resources struct { - NanoCPUs int64 `json:",omitempty"` - MemoryBytes int64 `json:",omitempty"` -} - -// ResourceRequirements represents resources requirements. -type ResourceRequirements struct { - Limits *Resources `json:",omitempty"` - Reservations *Resources `json:",omitempty"` -} - -// Placement represents orchestration parameters. -type Placement struct { - Constraints []string `json:",omitempty"` -} - -// RestartPolicy represents the restart policy. -type RestartPolicy struct { - Condition RestartPolicyCondition `json:",omitempty"` - Delay *time.Duration `json:",omitempty"` - MaxAttempts *uint64 `json:",omitempty"` - Window *time.Duration `json:",omitempty"` -} - -// RestartPolicyCondition represents when to restart. -type RestartPolicyCondition string - -const ( - // RestartPolicyConditionNone NONE - RestartPolicyConditionNone RestartPolicyCondition = "none" - // RestartPolicyConditionOnFailure ON_FAILURE - RestartPolicyConditionOnFailure RestartPolicyCondition = "on-failure" - // RestartPolicyConditionAny ANY - RestartPolicyConditionAny RestartPolicyCondition = "any" -) - -// TaskStatus represents the status of a task. -type TaskStatus struct { - Timestamp time.Time `json:",omitempty"` - State TaskState `json:",omitempty"` - Message string `json:",omitempty"` - Err string `json:",omitempty"` - ContainerStatus ContainerStatus `json:",omitempty"` -} - -// ContainerStatus represents the status of a container. -type ContainerStatus struct { - ContainerID string `json:",omitempty"` - PID int `json:",omitempty"` - ExitCode int `json:",omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/time/duration_convert.go b/vendor/src/github.com/docker/engine-api/types/time/duration_convert.go deleted file mode 100644 index 63e1eec19e..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/time/duration_convert.go +++ /dev/null @@ -1,12 +0,0 @@ -package time - -import ( - "strconv" - "time" -) - -// DurationToSecondsString converts the specified duration to the number -// seconds it represents, formatted as a string. -func DurationToSecondsString(duration time.Duration) string { - return strconv.FormatFloat(duration.Seconds(), 'f', 0, 64) -} diff --git a/vendor/src/github.com/docker/engine-api/types/time/timestamp.go b/vendor/src/github.com/docker/engine-api/types/time/timestamp.go deleted file mode 100644 index d3695ba723..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/time/timestamp.go +++ /dev/null @@ -1,124 +0,0 @@ -package time - -import ( - "fmt" - "math" - "strconv" - "strings" - "time" -) - -// These are additional predefined layouts for use in Time.Format and Time.Parse -// with --since and --until parameters for `docker logs` and `docker events` -const ( - rFC3339Local = "2006-01-02T15:04:05" // RFC3339 with local timezone - rFC3339NanoLocal = "2006-01-02T15:04:05.999999999" // RFC3339Nano with local timezone - dateWithZone = "2006-01-02Z07:00" // RFC3339 with time at 00:00:00 - dateLocal = "2006-01-02" // RFC3339 with local timezone and time at 00:00:00 -) - -// GetTimestamp tries to parse given string as golang duration, -// then RFC3339 time and finally as a Unix timestamp. If -// any of these were successful, it returns a Unix timestamp -// as string otherwise returns the given value back. -// In case of duration input, the returned timestamp is computed -// as the given reference time minus the amount of the duration. -func GetTimestamp(value string, reference time.Time) (string, error) { - if d, err := time.ParseDuration(value); value != "0" && err == nil { - return strconv.FormatInt(reference.Add(-d).Unix(), 10), nil - } - - var format string - var parseInLocation bool - - // if the string has a Z or a + or three dashes use parse otherwise use parseinlocation - parseInLocation = !(strings.ContainsAny(value, "zZ+") || strings.Count(value, "-") == 3) - - if strings.Contains(value, ".") { - if parseInLocation { - format = rFC3339NanoLocal - } else { - format = time.RFC3339Nano - } - } else if strings.Contains(value, "T") { - // we want the number of colons in the T portion of the timestamp - tcolons := strings.Count(value, ":") - // if parseInLocation is off and we have a +/- zone offset (not Z) then - // there will be an extra colon in the input for the tz offset subtract that - // colon from the tcolons count - if !parseInLocation && !strings.ContainsAny(value, "zZ") && tcolons > 0 { - tcolons-- - } - if parseInLocation { - switch tcolons { - case 0: - format = "2006-01-02T15" - case 1: - format = "2006-01-02T15:04" - default: - format = rFC3339Local - } - } else { - switch tcolons { - case 0: - format = "2006-01-02T15Z07:00" - case 1: - format = "2006-01-02T15:04Z07:00" - default: - format = time.RFC3339 - } - } - } else if parseInLocation { - format = dateLocal - } else { - format = dateWithZone - } - - var t time.Time - var err error - - if parseInLocation { - t, err = time.ParseInLocation(format, value, time.FixedZone(reference.Zone())) - } else { - t, err = time.Parse(format, value) - } - - if err != nil { - // if there is a `-` then its an RFC3339 like timestamp otherwise assume unixtimestamp - if strings.Contains(value, "-") { - return "", err // was probably an RFC3339 like timestamp but the parser failed with an error - } - return value, nil // unixtimestamp in and out case (meaning: the value passed at the command line is already in the right format for passing to the server) - } - - return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond())), nil -} - -// ParseTimestamps returns seconds and nanoseconds from a timestamp that has the -// format "%d.%09d", time.Unix(), int64(time.Nanosecond())) -// if the incoming nanosecond portion is longer or shorter than 9 digits it is -// converted to nanoseconds. The expectation is that the seconds and -// seconds will be used to create a time variable. For example: -// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0) -// if err == nil since := time.Unix(seconds, nanoseconds) -// returns seconds as def(aultSeconds) if value == "" -func ParseTimestamps(value string, def int64) (int64, int64, error) { - if value == "" { - return def, 0, nil - } - sa := strings.SplitN(value, ".", 2) - s, err := strconv.ParseInt(sa[0], 10, 64) - if err != nil { - return s, 0, err - } - if len(sa) != 2 { - return s, 0, nil - } - n, err := strconv.ParseInt(sa[1], 10, 64) - if err != nil { - return s, n, err - } - // should already be in nanoseconds but just in case convert n to nanoseonds - n = int64(float64(n) * math.Pow(float64(10), float64(9-len(sa[1])))) - return s, n, nil -} diff --git a/vendor/src/github.com/docker/engine-api/types/types.go b/vendor/src/github.com/docker/engine-api/types/types.go deleted file mode 100644 index 76d7f6995f..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/types.go +++ /dev/null @@ -1,519 +0,0 @@ -package types - -import ( - "os" - "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" - "github.com/docker/go-connections/nat" -) - -// ContainerCreateResponse contains the information returned to a client on the -// creation of a new container. -type ContainerCreateResponse struct { - // ID is the ID of the created container. - ID string `json:"Id"` - - // Warnings are any warnings encountered during the creation of the container. - Warnings []string `json:"Warnings"` -} - -// ContainerExecCreateResponse contains response of Remote API: -// POST "/containers/{name:.*}/exec" -type ContainerExecCreateResponse struct { - // ID is the exec ID. - ID string `json:"Id"` -} - -// ContainerUpdateResponse contains response of Remote API: -// POST "/containers/{name:.*}/update" -type ContainerUpdateResponse struct { - // Warnings are any warnings encountered during the updating of the container. - Warnings []string `json:"Warnings"` -} - -// AuthResponse contains response of Remote API: -// POST "/auth" -type AuthResponse struct { - // Status is the authentication status - Status string `json:"Status"` - - // IdentityToken is an opaque token used for authenticating - // a user after a successful login. - IdentityToken string `json:"IdentityToken,omitempty"` -} - -// ContainerWaitResponse contains response of Remote API: -// POST "/containers/"+containerID+"/wait" -type ContainerWaitResponse struct { - // StatusCode is the status code of the wait job - StatusCode int `json:"StatusCode"` -} - -// ContainerCommitResponse contains response of Remote API: -// POST "/commit?container="+containerID -type ContainerCommitResponse struct { - ID string `json:"Id"` -} - -// ContainerChange contains response of Remote API: -// GET "/containers/{name:.*}/changes" -type ContainerChange struct { - Kind int - Path string -} - -// ImageHistory contains response of Remote API: -// GET "/images/{name:.*}/history" -type ImageHistory struct { - ID string `json:"Id"` - Created int64 - CreatedBy string - Tags []string - Size int64 - Comment string -} - -// ImageDelete contains response of Remote API: -// DELETE "/images/{name:.*}" -type ImageDelete struct { - Untagged string `json:",omitempty"` - Deleted string `json:",omitempty"` -} - -// Image contains response of Remote API: -// GET "/images/json" -type Image struct { - ID string `json:"Id"` - ParentID string `json:"ParentId"` - RepoTags []string - RepoDigests []string - Created int64 - Size int64 - VirtualSize int64 - Labels map[string]string -} - -// GraphDriverData returns Image's graph driver config info -// when calling inspect command -type GraphDriverData struct { - Name string - Data map[string]string -} - -// RootFS returns Image's RootFS description including the layer IDs. -type RootFS struct { - Type string - Layers []string `json:",omitempty"` - BaseLayer string `json:",omitempty"` -} - -// ImageInspect contains response of Remote API: -// GET "/images/{name:.*}/json" -type ImageInspect struct { - ID string `json:"Id"` - RepoTags []string - RepoDigests []string - Parent string - Comment string - Created string - Container string - ContainerConfig *container.Config - DockerVersion string - Author string - Config *container.Config - Architecture string - Os string - Size int64 - VirtualSize int64 - GraphDriver GraphDriverData - RootFS RootFS -} - -// Port stores open ports info of container -// e.g. {"PrivatePort": 8080, "PublicPort": 80, "Type": "tcp"} -type Port struct { - IP string `json:",omitempty"` - PrivatePort int - PublicPort int `json:",omitempty"` - Type string -} - -// Container contains response of Remote API: -// GET "/containers/json" -type Container struct { - ID string `json:"Id"` - Names []string - Image string - ImageID string - Command string - Created int64 - Ports []Port - SizeRw int64 `json:",omitempty"` - SizeRootFs int64 `json:",omitempty"` - Labels map[string]string - State string - Status string - HostConfig struct { - NetworkMode string `json:",omitempty"` - } - NetworkSettings *SummaryNetworkSettings - Mounts []MountPoint -} - -// CopyConfig contains request body of Remote API: -// POST "/containers/"+containerID+"/copy" -type CopyConfig struct { - Resource string -} - -// ContainerPathStat is used to encode the header from -// GET "/containers/{name:.*}/archive" -// "Name" is the file or directory name. -type ContainerPathStat struct { - Name string `json:"name"` - Size int64 `json:"size"` - Mode os.FileMode `json:"mode"` - Mtime time.Time `json:"mtime"` - LinkTarget string `json:"linkTarget"` -} - -// ContainerProcessList contains response of Remote API: -// GET "/containers/{name:.*}/top" -type ContainerProcessList struct { - Processes [][]string - Titles []string -} - -// Version contains response of Remote API: -// GET "/version" -type Version struct { - Version string - APIVersion string `json:"ApiVersion"` - GitCommit string - GoVersion string - Os string - Arch string - KernelVersion string `json:",omitempty"` - Experimental bool `json:",omitempty"` - BuildTime string `json:",omitempty"` -} - -// Info contains response of Remote API: -// GET "/info" -type Info struct { - ID string - Containers int - ContainersRunning int - ContainersPaused int - ContainersStopped int - Images int - Driver string - DriverStatus [][2]string - SystemStatus [][2]string - Plugins PluginsInfo - MemoryLimit bool - SwapLimit bool - KernelMemory bool - CPUCfsPeriod bool `json:"CpuCfsPeriod"` - CPUCfsQuota bool `json:"CpuCfsQuota"` - CPUShares bool - CPUSet bool - IPv4Forwarding bool - BridgeNfIptables bool - BridgeNfIP6tables bool `json:"BridgeNfIp6tables"` - Debug bool - NFd int - OomKillDisable bool - NGoroutines int - SystemTime string - LoggingDriver string - CgroupDriver string - NEventsListener int - KernelVersion string - OperatingSystem string - OSType string - Architecture string - IndexServerAddress string - RegistryConfig *registry.ServiceConfig - NCPU int - MemTotal int64 - DockerRootDir string - HTTPProxy string `json:"HttpProxy"` - HTTPSProxy string `json:"HttpsProxy"` - NoProxy string - Name string - Labels []string - ExperimentalBuild bool - ServerVersion string - ClusterStore string - ClusterAdvertise string - SecurityOptions []string - Runtimes map[string]Runtime - DefaultRuntime string - Swarm swarm.Info - // LiveRestoreEnabled determines whether containers should be kept - // running when the daemon is shutdown or upon daemon start if - // running containers are detected - LiveRestoreEnabled bool -} - -// PluginsInfo is a temp struct holding Plugins name -// registered with docker daemon. It is used by Info struct -type PluginsInfo struct { - // List of Volume plugins registered - Volume []string - // List of Network plugins registered - Network []string - // List of Authorization plugins registered - Authorization []string -} - -// ExecStartCheck is a temp struct used by execStart -// Config fields is part of ExecConfig in runconfig package -type ExecStartCheck struct { - // ExecStart will first check if it's detached - Detach bool - // Check if there's a tty - Tty bool -} - -// HealthcheckResult stores information about a single run of a healthcheck probe -type HealthcheckResult struct { - Start time.Time // Start is the time this check started - End time.Time // End is the time this check ended - ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe - Output string // Output from last check -} - -// Health states -const ( - Starting = "starting" // Starting indicates that the container is not yet ready - Healthy = "healthy" // Healthy indicates that the container is running correctly - Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem -) - -// Health stores information about the container's healthcheck results -type Health struct { - Status string // Status is one of Starting, Healthy or Unhealthy - FailingStreak int // FailingStreak is the number of consecutive failures - Log []*HealthcheckResult // Log contains the last few results (oldest first) -} - -// ContainerState stores container's running state -// it's part of ContainerJSONBase and will return by "inspect" command -type ContainerState struct { - Status string - Running bool - Paused bool - Restarting bool - OOMKilled bool - Dead bool - Pid int - ExitCode int - Error string - StartedAt string - FinishedAt string - Health *Health `json:",omitempty"` -} - -// ContainerNode stores information about the node that a container -// is running on. It's only available in Docker Swarm -type ContainerNode struct { - ID string - IPAddress string `json:"IP"` - Addr string - Name string - Cpus int - Memory int64 - Labels map[string]string -} - -// ContainerJSONBase contains response of Remote API: -// GET "/containers/{name:.*}/json" -type ContainerJSONBase struct { - ID string `json:"Id"` - Created string - Path string - Args []string - State *ContainerState - Image string - ResolvConfPath string - HostnamePath string - HostsPath string - LogPath string - Node *ContainerNode `json:",omitempty"` - Name string - RestartCount int - Driver string - MountLabel string - ProcessLabel string - AppArmorProfile string - ExecIDs []string - HostConfig *container.HostConfig - GraphDriver GraphDriverData - SizeRw *int64 `json:",omitempty"` - SizeRootFs *int64 `json:",omitempty"` -} - -// ContainerJSON is newly used struct along with MountPoint -type ContainerJSON struct { - *ContainerJSONBase - Mounts []MountPoint - Config *container.Config - NetworkSettings *NetworkSettings -} - -// NetworkSettings exposes the network settings in the api -type NetworkSettings struct { - NetworkSettingsBase - DefaultNetworkSettings - Networks map[string]*network.EndpointSettings -} - -// SummaryNetworkSettings provides a summary of container's networks -// in /containers/json -type SummaryNetworkSettings struct { - Networks map[string]*network.EndpointSettings -} - -// NetworkSettingsBase holds basic information about networks -type NetworkSettingsBase struct { - Bridge string // Bridge is the Bridge name the network uses(e.g. `docker0`) - SandboxID string // SandboxID uniquely represents a container's network stack - HairpinMode bool // HairpinMode specifies if hairpin NAT should be enabled on the virtual interface - LinkLocalIPv6Address string // LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix - LinkLocalIPv6PrefixLen int // LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address - Ports nat.PortMap // Ports is a collection of PortBinding indexed by Port - SandboxKey string // SandboxKey identifies the sandbox - SecondaryIPAddresses []network.Address - SecondaryIPv6Addresses []network.Address -} - -// DefaultNetworkSettings holds network information -// during the 2 release deprecation period. -// It will be removed in Docker 1.11. -type DefaultNetworkSettings struct { - EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox - Gateway string // Gateway holds the gateway address for the network - GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address - GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address - IPAddress string // IPAddress holds the IPv4 address for the network - IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address - IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6 - MacAddress string // MacAddress holds the MAC address for the network -} - -// 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 mount.Type `json:",omitempty"` - Name string `json:",omitempty"` - Source string - Destination string - Driver string `json:",omitempty"` - Mode string - RW bool - Propagation mount.Propagation -} - -// Volume represents the configuration of a volume for the remote API -type Volume struct { - Name string // Name is the name of the volume - Driver string // Driver is the Driver name used to create the volume - Mountpoint string // Mountpoint is the location on disk of the volume - Status map[string]interface{} `json:",omitempty"` // Status provides low-level status information about the volume - Labels map[string]string // Labels is metadata specific to the volume - Scope string // Scope describes the level at which the volume exists (e.g. `global` for cluster-wide or `local` for machine level) -} - -// VolumesListResponse contains the response for the remote API: -// GET "/volumes" -type VolumesListResponse struct { - Volumes []*Volume // Volumes is the list of volumes being returned - Warnings []string // Warnings is a list of warnings that occurred when getting the list from the volume drivers -} - -// VolumeCreateRequest contains the response for the remote API: -// POST "/volumes/create" -type VolumeCreateRequest struct { - Name string // Name is the requested name of the volume - Driver string // Driver is the name of the driver that should be used to create the volume - DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume. - Labels map[string]string // Labels holds metadata specific to the volume being created. -} - -// NetworkResource is the body of the "get network" http response message -type NetworkResource struct { - Name string // Name is the requested name of the network - ID string `json:"Id"` // ID uniquely identifies a network on a single machine - Scope string // Scope describes the level at which the network exists (e.g. `global` for cluster-wide or `local` for machine level) - Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`) - EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6 - IPAM network.IPAM // IPAM is the network's IP Address Management - Internal bool // Internal represents if the network is used internal only - Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode. - Containers map[string]EndpointResource // Containers contains endpoints belonging to the network - Options map[string]string // Options holds the network specific options to use for when creating the network - Labels map[string]string // Labels holds metadata specific to the network being created -} - -// EndpointResource contains network resources allocated and used for a container in a network -type EndpointResource struct { - Name string - EndpointID string - MacAddress string - IPv4Address string - IPv6Address string -} - -// NetworkCreate is the expected body of the "create network" http request message -type NetworkCreate struct { - CheckDuplicate bool - Driver string - EnableIPv6 bool - IPAM *network.IPAM - Internal bool - Attachable bool - Options map[string]string - Labels map[string]string -} - -// NetworkCreateRequest is the request message sent to the server for network create call. -type NetworkCreateRequest struct { - NetworkCreate - Name string -} - -// NetworkCreateResponse is the response message sent by the server for network create call -type NetworkCreateResponse struct { - ID string `json:"Id"` - Warning string -} - -// NetworkConnect represents the data to be used to connect a container to the network -type NetworkConnect struct { - Container string - EndpointConfig *network.EndpointSettings `json:",omitempty"` -} - -// NetworkDisconnect represents the data to be used to disconnect a container from the network -type NetworkDisconnect struct { - Container string - Force bool -} - -// Checkpoint represents the details of a checkpoint -type Checkpoint struct { - Name string // Name is the name of the checkpoint -} - -// Runtime describes an OCI runtime -type Runtime struct { - Path string `json:"path"` - Args []string `json:"runtimeArgs,omitempty"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/versions/README.md b/vendor/src/github.com/docker/engine-api/types/versions/README.md deleted file mode 100644 index cdac50a53c..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/versions/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## Legacy API type versions - -This package includes types for legacy API versions. The stable version of the API types live in `api/types/*.go`. - -Consider moving a type here when you need to keep backwards compatibility in the API. This legacy types are organized by the latest API version they appear in. For instance, types in the `v1p19` package are valid for API versions below or equal `1.19`. Types in the `v1p20` package are valid for the API version `1.20`, since the versions below that will use the legacy types in `v1p19`. - -### Package name conventions - -The package name convention is to use `v` as a prefix for the version number and `p`(patch) as a separator. We use this nomenclature due to a few restrictions in the Go package name convention: - -1. We cannot use `.` because it's interpreted by the language, think of `v1.20.CallFunction`. -2. We cannot use `_` because golint complains about it. The code is actually valid, but it looks probably more weird: `v1_20.CallFunction`. - -For instance, if you want to modify a type that was available in the version `1.21` of the API but it will have different fields in the version `1.22`, you want to create a new package under `api/types/versions/v1p21`. diff --git a/vendor/src/github.com/docker/engine-api/types/versions/compare.go b/vendor/src/github.com/docker/engine-api/types/versions/compare.go deleted file mode 100644 index 611d4fed66..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/versions/compare.go +++ /dev/null @@ -1,62 +0,0 @@ -package versions - -import ( - "strconv" - "strings" -) - -// compare compares two version strings -// returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise. -func compare(v1, v2 string) int { - var ( - currTab = strings.Split(v1, ".") - otherTab = strings.Split(v2, ".") - ) - - max := len(currTab) - if len(otherTab) > max { - max = len(otherTab) - } - for i := 0; i < max; i++ { - var currInt, otherInt int - - if len(currTab) > i { - currInt, _ = strconv.Atoi(currTab[i]) - } - if len(otherTab) > i { - otherInt, _ = strconv.Atoi(otherTab[i]) - } - if currInt > otherInt { - return 1 - } - if otherInt > currInt { - return -1 - } - } - return 0 -} - -// LessThan checks if a version is less than another -func LessThan(v, other string) bool { - return compare(v, other) == -1 -} - -// LessThanOrEqualTo checks if a version is less than or equal to another -func LessThanOrEqualTo(v, other string) bool { - return compare(v, other) <= 0 -} - -// GreaterThan checks if a version is greater than another -func GreaterThan(v, other string) bool { - return compare(v, other) == 1 -} - -// GreaterThanOrEqualTo checks if a version is greater than or equal to another -func GreaterThanOrEqualTo(v, other string) bool { - return compare(v, other) >= 0 -} - -// Equal checks if a version is equal to another -func Equal(v, other string) bool { - return compare(v, other) == 0 -} diff --git a/vendor/src/github.com/docker/engine-api/types/versions/v1p19/types.go b/vendor/src/github.com/docker/engine-api/types/versions/v1p19/types.go deleted file mode 100644 index 4ed4335881..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/versions/v1p19/types.go +++ /dev/null @@ -1,35 +0,0 @@ -// Package v1p19 provides specific API types for the API version 1, patch 19. -package v1p19 - -import ( - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/container" - "github.com/docker/engine-api/types/versions/v1p20" - "github.com/docker/go-connections/nat" -) - -// ContainerJSON is a backcompatibility struct for APIs prior to 1.20. -// Note this is not used by the Windows daemon. -type ContainerJSON struct { - *types.ContainerJSONBase - Volumes map[string]string - VolumesRW map[string]bool - Config *ContainerConfig - NetworkSettings *v1p20.NetworkSettings -} - -// ContainerConfig is a backcompatibility struct for APIs prior to 1.20. -type ContainerConfig struct { - *container.Config - - MacAddress string - NetworkDisabled bool - ExposedPorts map[nat.Port]struct{} - - // backward compatibility, they now live in HostConfig - VolumeDriver string - Memory int64 - MemorySwap int64 - CPUShares int64 `json:"CpuShares"` - CPUSet string `json:"Cpuset"` -} diff --git a/vendor/src/github.com/docker/engine-api/types/versions/v1p20/types.go b/vendor/src/github.com/docker/engine-api/types/versions/v1p20/types.go deleted file mode 100644 index 5736efad00..0000000000 --- a/vendor/src/github.com/docker/engine-api/types/versions/v1p20/types.go +++ /dev/null @@ -1,40 +0,0 @@ -// Package v1p20 provides specific API types for the API version 1, patch 20. -package v1p20 - -import ( - "github.com/docker/engine-api/types" - "github.com/docker/engine-api/types/container" - "github.com/docker/go-connections/nat" -) - -// ContainerJSON is a backcompatibility struct for the API 1.20 -type ContainerJSON struct { - *types.ContainerJSONBase - Mounts []types.MountPoint - Config *ContainerConfig - NetworkSettings *NetworkSettings -} - -// ContainerConfig is a backcompatibility struct used in ContainerJSON for the API 1.20 -type ContainerConfig struct { - *container.Config - - MacAddress string - NetworkDisabled bool - ExposedPorts map[nat.Port]struct{} - - // backward compatibility, they now live in HostConfig - VolumeDriver string -} - -// StatsJSON is a backcompatibility struct used in Stats for APIs prior to 1.21 -type StatsJSON struct { - types.Stats - Network types.NetworkStats `json:"network,omitempty"` -} - -// NetworkSettings is a backward compatible struct for APIs prior to 1.21 -type NetworkSettings struct { - types.NetworkSettingsBase - types.DefaultNetworkSettings -} diff --git a/vendor/src/github.com/docker/go-connections/sockets/tcp_socket.go b/vendor/src/github.com/docker/go-connections/sockets/tcp_socket.go index 53cbb6c79e..8a82727df0 100644 --- a/vendor/src/github.com/docker/go-connections/sockets/tcp_socket.go +++ b/vendor/src/github.com/docker/go-connections/sockets/tcp_socket.go @@ -7,7 +7,7 @@ import ( ) // NewTCPSocket creates a TCP socket listener with the specified address and -// the specified tls configuration. If TLSConfig is set, will encapsulate the +// and the specified tls configuration. If TLSConfig is set, will encapsulate the // TCP listener inside a TLS one. func NewTCPSocket(addr string, tlsConfig *tls.Config) (net.Listener, error) { l, err := net.Listen("tcp", addr) diff --git a/vendor/src/github.com/docker/go-events/broadcast.go b/vendor/src/github.com/docker/go-events/broadcast.go index e73d758bcf..ee0a894ad8 100644 --- a/vendor/src/github.com/docker/go-events/broadcast.go +++ b/vendor/src/github.com/docker/go-events/broadcast.go @@ -1,6 +1,11 @@ package events -import "github.com/Sirupsen/logrus" +import ( + "fmt" + "sync" + + "github.com/Sirupsen/logrus" +) // Broadcaster sends events to multiple, reliable Sinks. The goal of this // component is to dispatch events to configured endpoints. Reliability can be @@ -10,7 +15,10 @@ type Broadcaster struct { events chan Event adds chan configureRequest removes chan configureRequest - closed chan chan struct{} + + shutdown chan struct{} + closed chan struct{} + once sync.Once } // NewBroadcaster appends one or more sinks to the list of sinks. The @@ -19,11 +27,12 @@ type Broadcaster struct { // its own. Use of EventQueue and RetryingSink should be used here. func NewBroadcaster(sinks ...Sink) *Broadcaster { b := Broadcaster{ - sinks: sinks, - events: make(chan Event), - adds: make(chan configureRequest), - removes: make(chan configureRequest), - closed: make(chan chan struct{}), + sinks: sinks, + events: make(chan Event), + adds: make(chan configureRequest), + removes: make(chan configureRequest), + shutdown: make(chan struct{}), + closed: make(chan struct{}), } // Start the broadcaster @@ -82,24 +91,19 @@ func (b *Broadcaster) configure(ch chan configureRequest, sink Sink) error { // Close the broadcaster, ensuring that all messages are flushed to the // underlying sink before returning. func (b *Broadcaster) Close() error { - select { - case <-b.closed: - // already closed - return ErrSinkClosed - default: - // do a little chan handoff dance to synchronize closing - closed := make(chan struct{}) - b.closed <- closed - close(b.closed) - <-closed - return nil - } + b.once.Do(func() { + close(b.shutdown) + }) + + <-b.closed + return nil } // run is the main broadcast loop, started when the broadcaster is created. // Under normal conditions, it waits for events on the event channel. After // Close is called, this goroutine will exit. func (b *Broadcaster) run() { + defer close(b.closed) remove := func(target Sink) { for i, sink := range b.sinks { if sink == target { @@ -143,7 +147,7 @@ func (b *Broadcaster) run() { case request := <-b.removes: remove(request.sink) request.response <- nil - case closing := <-b.closed: + case <-b.shutdown: // close all the underlying sinks for _, sink := range b.sinks { if err := sink.Close(); err != nil && err != ErrSinkClosed { @@ -151,8 +155,24 @@ func (b *Broadcaster) run() { Errorf("broadcaster: closing sink failed") } } - closing <- struct{}{} return } } } + +func (b Broadcaster) String() string { + // Serialize copy of this broadcaster without the sync.Once, to avoid + // a data race. + + b2 := map[string]interface{}{ + "sinks": b.sinks, + "events": b.events, + "adds": b.adds, + "removes": b.removes, + + "shutdown": b.shutdown, + "closed": b.closed, + } + + return fmt.Sprint(b2) +} diff --git a/vendor/src/github.com/docker/go-events/channel.go b/vendor/src/github.com/docker/go-events/channel.go index ca24f8d5a2..de95fa4017 100644 --- a/vendor/src/github.com/docker/go-events/channel.go +++ b/vendor/src/github.com/docker/go-events/channel.go @@ -1,5 +1,10 @@ package events +import ( + "fmt" + "sync" +) + // Channel provides a sink that can be listened on. The writer and channel // listener must operate in separate goroutines. // @@ -8,6 +13,7 @@ type Channel struct { C chan Event closed chan struct{} + once sync.Once } // NewChannel returns a channel. If buffer is zero, the channel is @@ -37,11 +43,19 @@ func (ch *Channel) Write(event Event) error { // Close the channel sink. func (ch *Channel) Close() error { - select { - case <-ch.closed: - return ErrSinkClosed - default: + ch.once.Do(func() { close(ch.closed) - return nil - } + }) + + return nil +} + +func (ch Channel) String() string { + // Serialize a copy of the Channel that doesn't contain the sync.Once, + // to avoid a data race. + ch2 := map[string]interface{}{ + "C": ch.C, + "closed": ch.closed, + } + return fmt.Sprint(ch2) } diff --git a/vendor/src/github.com/docker/go-events/filter.go b/vendor/src/github.com/docker/go-events/filter.go index f2765cfe6b..e6c0eb69dd 100644 --- a/vendor/src/github.com/docker/go-events/filter.go +++ b/vendor/src/github.com/docker/go-events/filter.go @@ -44,7 +44,7 @@ func (f *Filter) Write(event Event) error { func (f *Filter) Close() error { // TODO(stevvooe): Not all sinks should have Close. if f.closed { - return ErrSinkClosed + return nil } f.closed = true diff --git a/vendor/src/github.com/docker/go-events/queue.go b/vendor/src/github.com/docker/go-events/queue.go index 8032f090b6..cbd657cff4 100644 --- a/vendor/src/github.com/docker/go-events/queue.go +++ b/vendor/src/github.com/docker/go-events/queue.go @@ -52,7 +52,7 @@ func (eq *Queue) Close() error { defer eq.mu.Unlock() if eq.closed { - return ErrSinkClosed + return nil } // set closed flag diff --git a/vendor/src/github.com/docker/go-events/retry.go b/vendor/src/github.com/docker/go-events/retry.go index 4ddb3ac6a7..55d40dce9e 100644 --- a/vendor/src/github.com/docker/go-events/retry.go +++ b/vendor/src/github.com/docker/go-events/retry.go @@ -1,6 +1,7 @@ package events import ( + "fmt" "math/rand" "sync" "sync/atomic" @@ -18,6 +19,7 @@ type RetryingSink struct { sink Sink strategy RetryStrategy closed chan struct{} + once sync.Once } // NewRetryingSink returns a sink that will retry writes to a sink, backing @@ -81,13 +83,22 @@ retry: // Close closes the sink and the underlying sink. func (rs *RetryingSink) Close() error { - select { - case <-rs.closed: - return ErrSinkClosed - default: + rs.once.Do(func() { close(rs.closed) - return rs.sink.Close() + }) + + return nil +} + +func (rs RetryingSink) String() string { + // Serialize a copy of the RetryingSink without the sync.Once, to avoid + // a data race. + rs2 := map[string]interface{}{ + "sink": rs.sink, + "strategy": rs.strategy, + "closed": rs.closed, } + return fmt.Sprint(rs2) } // RetryStrategy defines a strategy for retrying event sink writes. diff --git a/vendor/src/github.com/docker/libnetwork/agent.go b/vendor/src/github.com/docker/libnetwork/agent.go index 5a7e028cd6..2b2ecf4324 100644 --- a/vendor/src/github.com/docker/libnetwork/agent.go +++ b/vendor/src/github.com/docker/libnetwork/agent.go @@ -183,17 +183,23 @@ func (c *controller) agentSetup() error { } return false }) - - if c.agent != nil { - close(c.agentInitDone) - } } } + if remoteAddr != "" { if err := c.agentJoin(remoteAddr); err != nil { logrus.Errorf("Error in agentJoin : %v", err) + return nil } } + + c.Lock() + if c.agent != nil && c.agentInitDone != nil { + close(c.agentInitDone) + c.agentInitDone = nil + } + c.Unlock() + return nil } @@ -328,7 +334,10 @@ func (c *controller) agentClose() { c.agent.epTblCancel() c.agent.networkDB.Close() + + c.Lock() c.agent = nil + c.Unlock() } func (n *network) isClusterEligible() bool { diff --git a/vendor/src/github.com/docker/libnetwork/client/mflag/LICENSE b/vendor/src/github.com/docker/libnetwork/client/mflag/LICENSE new file mode 100644 index 0000000000..9b4f4a294e --- /dev/null +++ b/vendor/src/github.com/docker/libnetwork/client/mflag/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2014-2016 The Docker & Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/src/github.com/docker/libnetwork/cluster/provider.go b/vendor/src/github.com/docker/libnetwork/cluster/provider.go index f8dc6f09b8..7bbf5d3557 100644 --- a/vendor/src/github.com/docker/libnetwork/cluster/provider.go +++ b/vendor/src/github.com/docker/libnetwork/cluster/provider.go @@ -1,5 +1,10 @@ package cluster +import ( + "github.com/docker/docker/api/types/network" + "golang.org/x/net/context" +) + // Provider provides clustering config details type Provider interface { IsManager() bool @@ -8,4 +13,8 @@ type Provider interface { GetAdvertiseAddress() string GetRemoteAddress() string ListenClusterEvents() <-chan struct{} + AttachNetwork(string, string, []string) (*network.NetworkingConfig, error) + DetachNetwork(string, string) error + UpdateAttachment(string, string, *network.NetworkingConfig) error + WaitForDetachment(context.Context, string, string, string, string) error } diff --git a/vendor/src/github.com/docker/libnetwork/config/config.go b/vendor/src/github.com/docker/libnetwork/config/config.go index eb8afea8b4..832412ec74 100644 --- a/vendor/src/github.com/docker/libnetwork/config/config.go +++ b/vendor/src/github.com/docker/libnetwork/config/config.go @@ -6,7 +6,7 @@ import ( "github.com/BurntSushi/toml" log "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/discovery" - "github.com/docker/docker/pkg/tlsconfig" + "github.com/docker/go-connections/tlsconfig" "github.com/docker/libkv/store" "github.com/docker/libnetwork/cluster" "github.com/docker/libnetwork/datastore" diff --git a/vendor/src/github.com/docker/libnetwork/controller.go b/vendor/src/github.com/docker/libnetwork/controller.go index 382e64cdfb..b2499dc7f5 100644 --- a/vendor/src/github.com/docker/libnetwork/controller.go +++ b/vendor/src/github.com/docker/libnetwork/controller.go @@ -307,8 +307,41 @@ func (c *controller) clusterAgentInit() { c.Lock() c.clusterConfigAvailable = false c.agentInitDone = make(chan struct{}) + c.keys = nil c.Unlock() + + // We are leaving the cluster. Make sure we + // close the gossip so that we stop all + // incoming gossip updates before cleaning up + // any remaining service bindings. But before + // deleting the networks since the networks + // should still be present when cleaning up + // service bindings c.agentClose() + c.cleanupServiceBindings("") + + c.Lock() + ingressSandbox := c.ingressSandbox + c.ingressSandbox = nil + c.Unlock() + + if ingressSandbox != nil { + if err := ingressSandbox.Delete(); err != nil { + log.Warnf("Could not delete ingress sandbox while leaving: %v", err) + } + } + + n, err := c.NetworkByName("ingress") + if err != nil { + log.Warnf("Could not find ingress network while leaving: %v", err) + } + + if n != nil { + if err := n.Delete(); err != nil { + log.Warnf("Could not delete ingress network while leaving: %v", err) + } + } + return } } @@ -317,7 +350,13 @@ func (c *controller) clusterAgentInit() { // AgentInitWait waits for agent initialization to be completed in the // controller. func (c *controller) AgentInitWait() { - <-c.agentInitDone + c.Lock() + agentInitDone := c.agentInitDone + c.Unlock() + + if agentInitDone != nil { + <-agentInitDone + } } func (c *controller) makeDriverConfig(ntype string) map[string]interface{} { @@ -660,6 +699,9 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ... } joinCluster(network) + if !c.isDistributedControl() { + arrangeIngressFilterRule() + } return network, nil } diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go index 8410eb037a..6c6256a947 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go @@ -641,7 +641,10 @@ func (d *driver) createNetwork(config *networkConfiguration) error { d.Unlock() // Create or retrieve the bridge L3 interface - bridgeIface := newInterface(d.nlh, config) + bridgeIface, err := newInterface(d.nlh, config) + if err != nil { + return err + } network.bridge = bridgeIface // Verify the network configuration does not conflict with previously installed @@ -1243,8 +1246,17 @@ func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string return err } + defer func() { + if err != nil { + if e := network.releasePorts(endpoint); e != nil { + logrus.Errorf("Failed to release ports allocated for the bridge endpoint %s on failure %v because of %v", + eid, err, e) + } + endpoint.portMapping = nil + } + }() + if err = d.storeUpdate(endpoint); err != nil { - endpoint.portMapping = nil return fmt.Errorf("failed to update bridge endpoint %s to store: %v", endpoint.id[0:7], err) } diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/interface.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/interface.go index 4a5dbfcbe5..16a8c7722d 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/interface.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/interface.go @@ -28,7 +28,7 @@ type bridgeInterface struct { // an already existing device identified by the configuration BridgeName field, // or the default bridge name when unspecified, but doesn't attempt to create // one when missing -func newInterface(nlh *netlink.Handle, config *networkConfiguration) *bridgeInterface { +func newInterface(nlh *netlink.Handle, config *networkConfiguration) (*bridgeInterface, error) { var err error i := &bridgeInterface{nlh: nlh} @@ -41,8 +41,10 @@ func newInterface(nlh *netlink.Handle, config *networkConfiguration) *bridgeInte i.Link, err = nlh.LinkByName(config.BridgeName) if err != nil { logrus.Debugf("Did not find any interface with name %s: %v", config.BridgeName, err) + } else if _, ok := i.Link.(*netlink.Bridge); !ok { + return nil, fmt.Errorf("existing interface %s is not a bridge", i.Link.Attrs().Name) } - return i + return i, nil } // exists indicates if the existing bridge interface exists on the system. diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go index df526952f7..0852d0f165 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go @@ -1,4 +1,4 @@ -// +build !arm,!ppc64,!ppc64le +// +build !arm,!ppc64,!ppc64le,!s390x package bridge diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_s390x.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_s390x.go new file mode 100644 index 0000000000..2d9abdc2ce --- /dev/null +++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_s390x.go @@ -0,0 +1,7 @@ +// +build s390x + +package bridge + +func ifrDataByte(b byte) uint8 { + return uint8(b) +} diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go index 4b4c0c417f..b5af0f4b04 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go @@ -500,9 +500,13 @@ func (n *network) initSubnetSandbox(s *subnet, restore bool) error { vxlanName := n.generateVxlanName(s) if restore { - n.restoreSubnetSandbox(s, brName, vxlanName) + if err := n.restoreSubnetSandbox(s, brName, vxlanName); err != nil { + return err + } } else { - n.setupSubnetSandbox(s, brName, vxlanName) + if err := n.setupSubnetSandbox(s, brName, vxlanName); err != nil { + return err + } } n.Lock() diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go index 5b52a15c63..59877dd1ac 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go @@ -90,7 +90,20 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { } } - d.restoreEndpoints() + if err := d.restoreEndpoints(); err != nil { + logrus.Warnf("Failure during overlay endpoints restore: %v", err) + } + + // If an error happened when the network join the sandbox during the endpoints restore + // we should reset it now along with the once variable, so that subsequent endpoint joins + // outside of the restore path can potentially fix the network join and succeed. + for nid, n := range d.networks { + if n.initErr != nil { + logrus.Infof("resetting init error and once variable for network %s after unsuccesful endpoint restore: %v", nid, n.initErr) + n.initErr = nil + n.once = &sync.Once{} + } + } return dc.RegisterDriver(networkType, d, c) } diff --git a/vendor/src/github.com/docker/libnetwork/endpoint.go b/vendor/src/github.com/docker/libnetwork/endpoint.go index d211dafc53..44893573ff 100644 --- a/vendor/src/github.com/docker/libnetwork/endpoint.go +++ b/vendor/src/github.com/docker/libnetwork/endpoint.go @@ -757,17 +757,6 @@ func (ep *endpoint) Delete(force bool) error { } }() - if err = n.getEpCnt().DecEndpointCnt(); err != nil && !force { - return err - } - defer func() { - if err != nil && !force { - if e := n.getEpCnt().IncEndpointCnt(); e != nil { - log.Warnf("failed to update network %s : %v", n.name, e) - } - } - }() - // unwatch for service records n.getController().unWatchSvcRecord(ep) @@ -777,6 +766,10 @@ func (ep *endpoint) Delete(force bool) error { ep.releaseAddress() + if err := n.getEpCnt().DecEndpointCnt(); err != nil { + log.Warnf("failed to decrement endpoint coint for ep %s: %v", ep.ID(), err) + } + return nil } diff --git a/vendor/src/github.com/docker/libnetwork/network.go b/vendor/src/github.com/docker/libnetwork/network.go index ffdc232486..2cd857a462 100644 --- a/vendor/src/github.com/docker/libnetwork/network.go +++ b/vendor/src/github.com/docker/libnetwork/network.go @@ -756,6 +756,19 @@ func (n *network) delete(force bool) error { log.Warnf("Failed to update store after ipam release for network %s (%s): %v", n.Name(), n.ID(), err) } + // We are about to delete the network. Leave the gossip + // cluster for the network to stop all incoming network + // specific gossip updates before cleaning up all the service + // bindings for the network. But cleanup service binding + // before deleting the network from the store since service + // bindings cleanup requires the network in the store. + n.cancelDriverWatches() + if err = n.leaveCluster(); err != nil { + log.Errorf("Failed leaving network %s from the agent cluster: %v", n.Name(), err) + } + + c.cleanupServiceBindings(n.ID()) + // deleteFromStore performs an atomic delete operation and the // network.epCnt will help prevent any possible // race between endpoint join and network delete @@ -770,12 +783,6 @@ func (n *network) delete(force bool) error { return fmt.Errorf("error deleting network from store: %v", err) } - n.cancelDriverWatches() - - if err = n.leaveCluster(); err != nil { - log.Errorf("Failed leaving network %s from the agent cluster: %v", n.Name(), err) - } - return nil } @@ -1118,7 +1125,7 @@ func (n *network) getSvcRecords(ep *endpoint) []etchosts.Record { continue } if len(ip) == 0 { - log.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", h, n.Name(), n.ID()) + log.Warnf("Found empty list of IP addresses for service %s on network %s (%s)", h, n.name, n.id) continue } recs = append(recs, etchosts.Record{ diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go b/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go index 50661e1743..17563589dc 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go @@ -200,10 +200,7 @@ func (nDB *NetworkDB) reapNetworks() { } func (nDB *NetworkDB) reapTableEntries() { - var ( - paths []string - entries []*entry - ) + var paths []string now := time.Now() @@ -219,14 +216,12 @@ func (nDB *NetworkDB) reapTableEntries() { } paths = append(paths, path) - entries = append(entries, entry) return false }) nDB.RUnlock() nDB.Lock() - for i, path := range paths { - entry := entries[i] + for _, path := range paths { params := strings.Split(path[1:], "/") tname := params[0] nid := params[1] @@ -239,8 +234,6 @@ func (nDB *NetworkDB) reapTableEntries() { if _, ok := nDB.indexes[byNetwork].Delete(fmt.Sprintf("/%s/%s/%s", nid, tname, key)); !ok { logrus.Errorf("Could not delete entry in network %s with table name %s and key %s as it does not exist", nid, tname, key) } - - nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, entry.value)) } nDB.Unlock() } diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go b/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go index 98007516d4..35c126a847 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go @@ -53,6 +53,7 @@ func (nDB *NetworkDB) handleNetworkEvent(nEvent *NetworkEvent) bool { n.leaveTime = time.Now() } + nDB.addNetworkNode(nEvent.NetworkID, nEvent.NodeName) return true } @@ -66,7 +67,7 @@ func (nDB *NetworkDB) handleNetworkEvent(nEvent *NetworkEvent) bool { ltime: nEvent.LTime, } - nDB.networkNodes[nEvent.NetworkID] = append(nDB.networkNodes[nEvent.NetworkID], nEvent.NodeName) + nDB.addNetworkNode(nEvent.NetworkID, nEvent.NodeName) return true } @@ -84,28 +85,34 @@ func (nDB *NetworkDB) handleTableEvent(tEvent *TableEvent) bool { return true } - if entry, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key); err == nil { + e, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key) + if err != nil && tEvent.Type == TableEventTypeDelete { + // If it is a delete event and we don't have the entry here nothing to do. + return false + } + + if err == nil { // We have the latest state. Ignore the event // since it is stale. - if entry.ltime >= tEvent.LTime { + if e.ltime >= tEvent.LTime { return false } } - entry := &entry{ + e = &entry{ ltime: tEvent.LTime, node: tEvent.NodeName, value: tEvent.Value, deleting: tEvent.Type == TableEventTypeDelete, } - if entry.deleting { - entry.deleteTime = time.Now() + if e.deleting { + e.deleteTime = time.Now() } nDB.Lock() - nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.TableName, tEvent.NetworkID, tEvent.Key), entry) - nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.NetworkID, tEvent.TableName, tEvent.Key), entry) + nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.TableName, tEvent.NetworkID, tEvent.Key), e) + nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.NetworkID, tEvent.TableName, tEvent.Key), e) nDB.Unlock() var op opType diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go index f21e572e69..2f35be6ffa 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go @@ -326,6 +326,8 @@ func (nDB *NetworkDB) deleteNodeTableEntries(node string) { nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry) nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry) + + nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, entry.value)) return false }) nDB.Unlock() @@ -453,6 +455,20 @@ func (nDB *NetworkDB) LeaveNetwork(nid string) error { return nil } +// addNetworkNode adds the node to the list of nodes which participate +// in the passed network only if it is not already present. Caller +// should hold the NetworkDB lock while calling this +func (nDB *NetworkDB) addNetworkNode(nid string, nodeName string) { + nodes := nDB.networkNodes[nid] + for _, node := range nodes { + if node == nodeName { + return + } + } + + nDB.networkNodes[nid] = append(nDB.networkNodes[nid], nodeName) +} + // Deletes the node from the list of nodes which participate in the // passed network. Caller should hold the NetworkDB lock while calling // this diff --git a/vendor/src/github.com/docker/libnetwork/sandbox.go b/vendor/src/github.com/docker/libnetwork/sandbox.go index 52e9bb6783..775b92ab31 100644 --- a/vendor/src/github.com/docker/libnetwork/sandbox.go +++ b/vendor/src/github.com/docker/libnetwork/sandbox.go @@ -202,12 +202,14 @@ func (sb *sandbox) delete(force bool) error { retain := false for _, ep := range sb.getConnectedEndpoints() { // gw network endpoint detach and removal are automatic - if ep.endpointInGWNetwork() { + if ep.endpointInGWNetwork() && !force { continue } // Retain the sanbdox if we can't obtain the network from store. if _, err := c.getNetworkFromStore(ep.getNetwork().ID()); err != nil { - retain = true + if c.isDistributedControl() { + retain = true + } log.Warnf("Failed getting network for ep %s during sandbox %s delete: %v", ep.ID(), sb.ID(), err) continue } diff --git a/vendor/src/github.com/docker/libnetwork/service.go b/vendor/src/github.com/docker/libnetwork/service.go index 30a17c5056..a957026b2f 100644 --- a/vendor/src/github.com/docker/libnetwork/service.go +++ b/vendor/src/github.com/docker/libnetwork/service.go @@ -45,6 +45,9 @@ type service struct { // List of ingress ports exposed by the service ingressPorts portConfigs + // Service aliases + aliases []string + sync.Mutex } diff --git a/vendor/src/github.com/docker/libnetwork/service_linux.go b/vendor/src/github.com/docker/libnetwork/service_linux.go index 9dc27f5578..3fafa9af44 100644 --- a/vendor/src/github.com/docker/libnetwork/service_linux.go +++ b/vendor/src/github.com/docker/libnetwork/service_linux.go @@ -28,15 +28,52 @@ func init() { reexec.Register("fwmarker", fwMarker) } -func newService(name string, id string, ingressPorts []*PortConfig) *service { +func newService(name string, id string, ingressPorts []*PortConfig, aliases []string) *service { return &service{ name: name, id: id, ingressPorts: ingressPorts, loadBalancers: make(map[string]*loadBalancer), + aliases: aliases, } } +func (c *controller) cleanupServiceBindings(cleanupNID string) { + var cleanupFuncs []func() + c.Lock() + for _, s := range c.serviceBindings { + s.Lock() + for nid, lb := range s.loadBalancers { + if cleanupNID != "" && nid != cleanupNID { + continue + } + + for eid, ip := range lb.backEnds { + service := s + loadBalancer := lb + networkID := nid + epID := eid + epIP := ip + + cleanupFuncs = append(cleanupFuncs, func() { + if err := c.rmServiceBinding(service.name, service.id, networkID, epID, loadBalancer.vip, + service.ingressPorts, service.aliases, epIP); err != nil { + logrus.Errorf("Failed to remove service bindings for service %s network %s endpoint %s while cleanup: %v", + service.id, networkID, epID, err) + } + }) + } + } + s.Unlock() + } + c.Unlock() + + for _, f := range cleanupFuncs { + f() + } + +} + func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error { var ( s *service @@ -58,7 +95,7 @@ func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, i if !ok { // Create a new service if we are seeing this service // for the first time. - s = newService(name, sid, ingressPorts) + s = newService(name, sid, ingressPorts, aliases) c.serviceBindings[skey] = s } c.Unlock() @@ -230,6 +267,11 @@ func (n *network) connectedLoadbalancers() []*loadBalancer { func (sb *sandbox) populateLoadbalancers(ep *endpoint) { var gwIP net.IP + // This is an interface less endpoint. Nothing to do. + if ep.Iface() == nil { + return + } + n := ep.getNetwork() eIP := ep.Iface().Address() @@ -479,14 +521,19 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro } chainExists := iptables.ExistChain(ingressChain, iptables.Nat) + filterChainExists := iptables.ExistChain(ingressChain, iptables.Filter) ingressOnce.Do(func() { + // Flush nat table and filter table ingress chain rules during init if it + // exists. It might contain stale rules from previous life. if chainExists { - // Flush ingress chain rules during init if it - // exists. It might contain stale rules from - // previous life. if err := iptables.RawCombinedOutput("-t", "nat", "-F", ingressChain); err != nil { - logrus.Errorf("Could not flush ingress chain rules during init: %v", err) + logrus.Errorf("Could not flush nat table ingress chain rules during init: %v", err) + } + } + if filterChainExists { + if err := iptables.RawCombinedOutput("-F", ingressChain); err != nil { + logrus.Errorf("Could not flush filter table ingress chain rules during init: %v", err) } } }) @@ -497,10 +544,21 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro return fmt.Errorf("failed to create ingress chain: %v", err) } } + if !filterChainExists { + if err := iptables.RawCombinedOutput("-N", ingressChain); err != nil { + return fmt.Errorf("failed to create filter table ingress chain: %v", err) + } + } if !iptables.Exists(iptables.Nat, ingressChain, "-j", "RETURN") { if err := iptables.RawCombinedOutput("-t", "nat", "-A", ingressChain, "-j", "RETURN"); err != nil { - return fmt.Errorf("failed to add return rule in ingress chain: %v", err) + return fmt.Errorf("failed to add return rule in nat table ingress chain: %v", err) + } + } + + if !iptables.Exists(iptables.Filter, ingressChain, "-j", "RETURN") { + if err := iptables.RawCombinedOutput("-A", ingressChain, "-j", "RETURN"); err != nil { + return fmt.Errorf("failed to add return rule to filter table ingress chain: %v", err) } } @@ -512,6 +570,12 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro } } + if !iptables.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) { + if err := iptables.RawCombinedOutput("-I", "FORWARD", "-j", ingressChain); err != nil { + return fmt.Errorf("failed to add jump rule to %s in filter table forward chain: %v", ingressChain, err) + } + } + oifName, err := findOIFName(gwIP) if err != nil { return fmt.Errorf("failed to find gateway bridge interface name for %s: %v", gwIP, err) @@ -544,6 +608,30 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro } } + // Filter table rules to allow a published service to be accessible in the local node from.. + // 1) service tasks attached to other networks + // 2) unmanaged containers on bridge networks + rule := strings.Fields(fmt.Sprintf("%s %s -m state -p %s --sport %d --state ESTABLISHED,RELATED -j ACCEPT", + addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort)) + if err := iptables.RawCombinedOutput(rule...); err != nil { + errStr := fmt.Sprintf("setting up rule failed, %v: %v", rule, err) + if !isDelete { + return fmt.Errorf("%s", errStr) + } + logrus.Warnf("%s", errStr) + } + + rule = strings.Fields(fmt.Sprintf("%s %s -p %s --dport %d -j ACCEPT", + addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort)) + if err := iptables.RawCombinedOutput(rule...); err != nil { + errStr := fmt.Sprintf("setting up rule failed, %v: %v", rule, err) + if !isDelete { + return fmt.Errorf("%s", errStr) + } + + logrus.Warnf("%s", errStr) + } + if err := plumbProxy(iPort, isDelete); err != nil { logrus.Warnf("failed to create proxy for port %d: %v", iPort.PublishedPort, err) } @@ -552,6 +640,22 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro return nil } +// In the filter table FORWARD chain first rule should be to jump to INGRESS-CHAIN +// This chain has the rules to allow access to the published ports for swarm tasks +// from local bridge networks and docker_gwbridge (ie:taks on other swarm netwroks) +func arrangeIngressFilterRule() { + if iptables.ExistChain(ingressChain, iptables.Filter) { + if iptables.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) { + if err := iptables.RawCombinedOutput("-D", "FORWARD", "-j", ingressChain); err != nil { + logrus.Warnf("failed to delete jump rule to ingressChain in filter table: %v", err) + } + } + if err := iptables.RawCombinedOutput("-I", "FORWARD", "-j", ingressChain); err != nil { + logrus.Warnf("failed to add jump rule to ingressChain in filter table: %v", err) + } + } +} + func findOIFName(ip net.IP) (string, error) { nlh := ns.NlHandle() diff --git a/vendor/src/github.com/docker/libnetwork/service_unsupported.go b/vendor/src/github.com/docker/libnetwork/service_unsupported.go index 9668dcc07e..0ae384a99c 100644 --- a/vendor/src/github.com/docker/libnetwork/service_unsupported.go +++ b/vendor/src/github.com/docker/libnetwork/service_unsupported.go @@ -7,6 +7,9 @@ import ( "net" ) +func (c *controller) cleanupServiceBindings(nid string) { +} + func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error { return fmt.Errorf("not supported") } @@ -17,3 +20,6 @@ func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, in func (sb *sandbox) populateLoadbalancers(ep *endpoint) { } + +func arrangeIngressFilterRule() { +} diff --git a/vendor/src/github.com/docker/libnetwork/store.go b/vendor/src/github.com/docker/libnetwork/store.go index b622836498..9830a22d47 100644 --- a/vendor/src/github.com/docker/libnetwork/store.go +++ b/vendor/src/github.com/docker/libnetwork/store.go @@ -346,6 +346,10 @@ func (c *controller) networkWatchLoop(nw *netWatch, ep *endpoint, ecCh <-chan da } func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoint) { + if !c.isDistributedControl() && ep.getNetwork().driverScope() == datastore.GlobalScope { + return + } + c.Lock() nw, ok := nmap[ep.getNetwork().ID()] c.Unlock() @@ -400,6 +404,10 @@ func (c *controller) processEndpointCreate(nmap map[string]*netWatch, ep *endpoi } func (c *controller) processEndpointDelete(nmap map[string]*netWatch, ep *endpoint) { + if !c.isDistributedControl() && ep.getNetwork().driverScope() == datastore.GlobalScope { + return + } + c.Lock() nw, ok := nmap[ep.getNetwork().ID()] diff --git a/vendor/src/github.com/docker/libnetwork/support.sh b/vendor/src/github.com/docker/libnetwork/support.sh new file mode 100755 index 0000000000..e913bf33dd --- /dev/null +++ b/vendor/src/github.com/docker/libnetwork/support.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Required tools +DOCKER="${DOCKER:-docker}" +NSENTER="${NSENTER:-nsenter}" +BRIDGE="${BRIDGE:-bridge}" +BRCTL="${BRCTL:-brctl}" +IPTABLES="${IPTABLES:-iptables}" + +NSDIR=/var/run/docker/netns +BRIDGEIF=br0 + +function die { + echo $* + exit 1 +} + +type -P ${DOCKER} > /dev/null || die "This tool requires the docker binary" +type -P ${NSENTER} > /dev/null || die "This tool requires nsenter" +type -P ${BRIDGE} > /dev/null || die "This tool requires bridge" +type -P ${BRCTL} > /dev/null || die "This tool requires brctl" +type -P ${IPTABLES} > /dev/null || die "This tool requires iptables" + +echo "iptables configuration" +${IPTABLES} -n -v -L -t filter +${IPTABLES} -n -v -L -t nat +echo "" + +echo "Overlay network configuration" +for networkID in $(${DOCKER} network ls --filter driver=overlay -q) ; do + echo "Network ${networkID}" + nspath=(${NSDIR}/*-$(echo ${networkID}| cut -c1-10)) + ${NSENTER} --net=${nspath[0]} ${BRIDGE} fdb show ${BRIDGEIF} + ${NSENTER} --net=${nspath[0]} ${BRCTL} showmacs ${BRIDGEIF} + echo "" +done diff --git a/vendor/src/github.com/docker/swarmkit/agent/config.go b/vendor/src/github.com/docker/swarmkit/agent/config.go index 1f26f7797e..aac6b2e0f9 100644 --- a/vendor/src/github.com/docker/swarmkit/agent/config.go +++ b/vendor/src/github.com/docker/swarmkit/agent/config.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/docker/swarmkit/agent/exec" "github.com/docker/swarmkit/api" - "github.com/docker/swarmkit/picker" + "github.com/docker/swarmkit/remotes" "google.golang.org/grpc/credentials" ) @@ -17,7 +17,7 @@ type Config struct { // Managers provides the manager backend used by the agent. It will be // updated with managers weights as observed by the agent. - Managers picker.Remotes + Managers remotes.Remotes // Executor specifies the executor to use for the agent. Executor exec.Executor diff --git a/vendor/src/github.com/docker/swarmkit/agent/node.go b/vendor/src/github.com/docker/swarmkit/agent/node.go index 116436b972..2877149217 100644 --- a/vendor/src/github.com/docker/swarmkit/agent/node.go +++ b/vendor/src/github.com/docker/swarmkit/agent/node.go @@ -21,7 +21,7 @@ import ( "github.com/docker/swarmkit/ioutils" "github.com/docker/swarmkit/log" "github.com/docker/swarmkit/manager" - "github.com/docker/swarmkit/picker" + "github.com/docker/swarmkit/remotes" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -178,7 +178,7 @@ func (n *Node) run(ctx context.Context) (err error) { if n.config.JoinAddr != "" || n.config.ForceNewCluster { n.remotes = newPersistentRemotes(filepath.Join(n.config.StateDir, stateFilename)) if n.config.JoinAddr != "" { - n.remotes.Observe(api.Peer{Addr: n.config.JoinAddr}, picker.DefaultObservationWeight) + n.remotes.Observe(api.Peer{Addr: n.config.JoinAddr}, remotes.DefaultObservationWeight) } } @@ -204,7 +204,7 @@ func (n *Node) run(ctx context.Context) (err error) { }() certDir := filepath.Join(n.config.StateDir, "certificates") - securityConfig, err := ca.LoadOrCreateSecurityConfig(ctx, certDir, n.config.JoinToken, ca.ManagerRole, picker.NewPicker(n.remotes), issueResponseChan) + securityConfig, err := ca.LoadOrCreateSecurityConfig(ctx, certDir, n.config.JoinToken, ca.ManagerRole, n.remotes, issueResponseChan) if err != nil { return err } @@ -256,7 +256,7 @@ func (n *Node) run(ctx context.Context) (err error) { } }() - updates := ca.RenewTLSConfig(ctx, securityConfig, certDir, picker.NewPicker(n.remotes), forceCertRenewal) + updates := ca.RenewTLSConfig(ctx, securityConfig, certDir, n.remotes, forceCertRenewal) go func() { for { select { @@ -533,31 +533,29 @@ func (n *Node) initManagerConnection(ctx context.Context, ready chan<- struct{}) if err != nil { return err } - state := grpc.Idle + client := api.NewHealthClient(conn) for { - s, err := conn.WaitForStateChange(ctx, state) + resp, err := client.Check(ctx, &api.HealthCheckRequest{Service: "ControlAPI"}) if err != nil { - n.setControlSocket(nil) return err } - if s == grpc.Ready { - n.setControlSocket(conn) - if ready != nil { - close(ready) - ready = nil - } - } else if state == grpc.Shutdown { - n.setControlSocket(nil) + if resp.Status == api.HealthCheckResponse_SERVING { + break } - state = s + time.Sleep(500 * time.Millisecond) } + n.setControlSocket(conn) + if ready != nil { + close(ready) + } + return nil } -func (n *Node) waitRole(ctx context.Context, role string) { +func (n *Node) waitRole(ctx context.Context, role string) error { n.roleCond.L.Lock() if role == n.role { n.roleCond.L.Unlock() - return + return nil } finishCh := make(chan struct{}) defer close(finishCh) @@ -572,18 +570,24 @@ func (n *Node) waitRole(ctx context.Context, role string) { defer n.roleCond.L.Unlock() for role != n.role { n.roleCond.Wait() - if ctx.Err() != nil { - return + select { + case <-ctx.Done(): + if ctx.Err() != nil { + return ctx.Err() + } + default: } } + + return nil } func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}) error { for { - n.waitRole(ctx, ca.ManagerRole) - if ctx.Err() != nil { - return ctx.Err() + if err := n.waitRole(ctx, ca.ManagerRole); err != nil { + return err } + remoteAddr, _ := n.remotes.Select(n.nodeID) m, err := manager.New(&manager.Config{ ForceNewCluster: n.config.ForceNewCluster, @@ -620,14 +624,14 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig go func(ready chan struct{}) { select { case <-ready: - n.remotes.Observe(api.Peer{NodeID: n.nodeID, Addr: n.config.ListenRemoteAPI}, picker.DefaultObservationWeight) + n.remotes.Observe(api.Peer{NodeID: n.nodeID, Addr: n.config.ListenRemoteAPI}, remotes.DefaultObservationWeight) case <-connCtx.Done(): } }(ready) ready = nil } - n.waitRole(ctx, ca.AgentRole) + err = n.waitRole(ctx, ca.AgentRole) n.Lock() n.manager = nil @@ -641,6 +645,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig <-done } connCancel() + n.setControlSocket(nil) if err != nil { return err @@ -651,15 +656,15 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig type persistentRemotes struct { sync.RWMutex c *sync.Cond - picker.Remotes + remotes.Remotes storePath string lastSavedState []api.Peer } -func newPersistentRemotes(f string, remotes ...api.Peer) *persistentRemotes { +func newPersistentRemotes(f string, peers ...api.Peer) *persistentRemotes { pr := &persistentRemotes{ storePath: f, - Remotes: picker.NewRemotes(remotes...), + Remotes: remotes.NewRemotes(peers...), } pr.c = sync.NewCond(pr.RLocker()) return pr diff --git a/vendor/src/github.com/docker/swarmkit/agent/reporter.go b/vendor/src/github.com/docker/swarmkit/agent/reporter.go index 3f9c462a3b..eac4b3267a 100644 --- a/vendor/src/github.com/docker/swarmkit/agent/reporter.go +++ b/vendor/src/github.com/docker/swarmkit/agent/reporter.go @@ -79,6 +79,9 @@ func (sr *statusReporter) run(ctx context.Context) { done := make(chan struct{}) defer close(done) + sr.mu.Lock() // released during wait, below. + defer sr.mu.Unlock() + go func() { select { case <-ctx.Done(): @@ -88,27 +91,29 @@ func (sr *statusReporter) run(ctx context.Context) { } }() - sr.mu.Lock() // released during wait, below. - defer sr.mu.Unlock() - for { if len(sr.statuses) == 0 { sr.cond.Wait() } - for taskID, status := range sr.statuses { - if sr.closed { - // TODO(stevvooe): Add support here for waiting until all - // statuses are flushed before shutting down. - return - } + if sr.closed { + // TODO(stevvooe): Add support here for waiting until all + // statuses are flushed before shutting down. + return + } + for taskID, status := range sr.statuses { delete(sr.statuses, taskID) // delete the entry, while trying to send. sr.mu.Unlock() err := sr.reporter.UpdateTaskStatus(ctx, taskID, status) sr.mu.Lock() + // reporter might be closed during UpdateTaskStatus call + if sr.closed { + return + } + if err != nil { log.G(ctx).WithError(err).Error("failed reporting status to agent") diff --git a/vendor/src/github.com/docker/swarmkit/agent/resource.go b/vendor/src/github.com/docker/swarmkit/agent/resource.go new file mode 100644 index 0000000000..7744269712 --- /dev/null +++ b/vendor/src/github.com/docker/swarmkit/agent/resource.go @@ -0,0 +1,69 @@ +package agent + +import ( + "github.com/docker/swarmkit/api" + "golang.org/x/net/context" +) + +type resourceAllocator struct { + agent *Agent +} + +// ResourceAllocator is an interface to allocate resource such as +// network attachments from a worker node. +type ResourceAllocator interface { + // AttachNetwork creates a network attachment in the manager + // given a target network and a unique ID representing the + // connecting entity and optionally a list of ipv4/ipv6 + // addresses to be assigned to the attachment. AttachNetwork + // returns a unique ID for the attachment if successfull or an + // error in case of failure. + AttachNetwork(ctx context.Context, id, target string, addresses []string) (string, error) + + // DetachNetworks deletes a network attachment for the passed + // attachment ID. The attachment ID is obtained from a + // previous AttachNetwork call. + DetachNetwork(ctx context.Context, aID string) error +} + +// AttachNetwork creates a network attachment. +func (r *resourceAllocator) AttachNetwork(ctx context.Context, id, target string, addresses []string) (string, error) { + var taskID string + if err := r.agent.withSession(ctx, func(session *session) error { + client := api.NewResourceAllocatorClient(session.conn) + r, err := client.AttachNetwork(ctx, &api.AttachNetworkRequest{ + Config: &api.NetworkAttachmentConfig{ + Target: target, + Addresses: addresses, + }, + ContainerID: id, + }) + if err != nil { + return err + } + taskID = r.AttachmentID + return nil + }); err != nil { + return "", err + } + + return taskID, nil +} + +// DetachNetwork deletes a network attachment. +func (r *resourceAllocator) DetachNetwork(ctx context.Context, aID string) error { + return r.agent.withSession(ctx, func(session *session) error { + client := api.NewResourceAllocatorClient(session.conn) + _, err := client.DetachNetwork(ctx, &api.DetachNetworkRequest{ + AttachmentID: aID, + }) + + return err + }) +} + +// ResourceAllocator provides an interface to access resource +// allocation methods such as AttachNetwork and DetachNetwork. +func (a *Agent) ResourceAllocator() ResourceAllocator { + return &resourceAllocator{agent: a} +} diff --git a/vendor/src/github.com/docker/swarmkit/agent/session.go b/vendor/src/github.com/docker/swarmkit/agent/session.go index 50cd649d02..43c0dc881c 100644 --- a/vendor/src/github.com/docker/swarmkit/agent/session.go +++ b/vendor/src/github.com/docker/swarmkit/agent/session.go @@ -6,8 +6,8 @@ import ( "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/log" - "github.com/docker/swarmkit/picker" "github.com/docker/swarmkit/protobuf/ptypes" + "github.com/docker/swarmkit/remotes" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -307,7 +307,7 @@ func (s *session) close() error { return errSessionClosed default: if s.conn != nil { - s.agent.config.Managers.ObserveIfExists(api.Peer{Addr: s.addr}, -picker.DefaultObservationWeight) + s.agent.config.Managers.ObserveIfExists(api.Peer{Addr: s.addr}, -remotes.DefaultObservationWeight) s.conn.Close() } close(s.closed) diff --git a/vendor/src/github.com/docker/swarmkit/agent/worker.go b/vendor/src/github.com/docker/swarmkit/agent/worker.go index cbe276988d..80e9ab07ab 100644 --- a/vendor/src/github.com/docker/swarmkit/agent/worker.go +++ b/vendor/src/github.com/docker/swarmkit/agent/worker.go @@ -134,8 +134,6 @@ func (w *worker) Assign(ctx context.Context, tasks []*api.Task) error { if err := PutTaskStatus(tx, task.ID, &task.Status); err != nil { return err } - - status = &task.Status } else { task.Status = *status // overwrite the stale manager status with ours. } @@ -181,7 +179,7 @@ func (w *worker) Listen(ctx context.Context, reporter StatusReporter) { go func() { <-ctx.Done() w.mu.Lock() - defer w.mu.Lock() + defer w.mu.Unlock() delete(w.listeners, key) // remove the listener if the context is closed. }() diff --git a/vendor/src/github.com/docker/swarmkit/api/gen.go b/vendor/src/github.com/docker/swarmkit/api/gen.go index 1a9b0109d8..d0fb1ede1d 100644 --- a/vendor/src/github.com/docker/swarmkit/api/gen.go +++ b/vendor/src/github.com/docker/swarmkit/api/gen.go @@ -1,3 +1,3 @@ package api -//go:generate protoc -I.:../protobuf:../vendor:../vendor/github.com/gogo/protobuf --gogoswarm_out=plugins=grpc+deepcopy+raftproxy+authenticatedwrapper,import_path=github.com/docker/swarmkit/api,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto,Mtimestamp/timestamp.proto=github.com/docker/swarmkit/api/timestamp,Mduration/duration.proto=github.com/docker/swarmkit/api/duration,Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor,Mplugin/plugin.proto=github.com/docker/swarmkit/protobuf/plugin:. types.proto specs.proto objects.proto control.proto dispatcher.proto ca.proto snapshot.proto raft.proto health.proto +//go:generate protoc -I.:../protobuf:../vendor:../vendor/github.com/gogo/protobuf --gogoswarm_out=plugins=grpc+deepcopy+raftproxy+authenticatedwrapper,import_path=github.com/docker/swarmkit/api,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto,Mtimestamp/timestamp.proto=github.com/docker/swarmkit/api/timestamp,Mduration/duration.proto=github.com/docker/swarmkit/api/duration,Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor,Mplugin/plugin.proto=github.com/docker/swarmkit/protobuf/plugin:. types.proto specs.proto objects.proto control.proto dispatcher.proto ca.proto snapshot.proto raft.proto health.proto resource.proto diff --git a/vendor/src/github.com/docker/swarmkit/api/resource.pb.go b/vendor/src/github.com/docker/swarmkit/api/resource.pb.go new file mode 100644 index 0000000000..fd7416635e --- /dev/null +++ b/vendor/src/github.com/docker/swarmkit/api/resource.pb.go @@ -0,0 +1,1105 @@ +// Code generated by protoc-gen-gogo. +// source: resource.proto +// DO NOT EDIT! + +package api + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import _ "github.com/docker/swarmkit/protobuf/plugin" + +import strings "strings" +import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" +import sort "sort" +import strconv "strconv" +import reflect "reflect" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +import raftpicker "github.com/docker/swarmkit/manager/raftpicker" +import codes "google.golang.org/grpc/codes" +import metadata "google.golang.org/grpc/metadata" +import transport "google.golang.org/grpc/transport" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type AttachNetworkRequest struct { + Config *NetworkAttachmentConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"` + ContainerID string `protobuf:"bytes,2,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` +} + +func (m *AttachNetworkRequest) Reset() { *m = AttachNetworkRequest{} } +func (*AttachNetworkRequest) ProtoMessage() {} +func (*AttachNetworkRequest) Descriptor() ([]byte, []int) { return fileDescriptorResource, []int{0} } + +type AttachNetworkResponse struct { + AttachmentID string `protobuf:"bytes,1,opt,name=attachment_id,json=attachmentId,proto3" json:"attachment_id,omitempty"` +} + +func (m *AttachNetworkResponse) Reset() { *m = AttachNetworkResponse{} } +func (*AttachNetworkResponse) ProtoMessage() {} +func (*AttachNetworkResponse) Descriptor() ([]byte, []int) { return fileDescriptorResource, []int{1} } + +type DetachNetworkRequest struct { + AttachmentID string `protobuf:"bytes,1,opt,name=attachment_id,json=attachmentId,proto3" json:"attachment_id,omitempty"` +} + +func (m *DetachNetworkRequest) Reset() { *m = DetachNetworkRequest{} } +func (*DetachNetworkRequest) ProtoMessage() {} +func (*DetachNetworkRequest) Descriptor() ([]byte, []int) { return fileDescriptorResource, []int{2} } + +type DetachNetworkResponse struct { +} + +func (m *DetachNetworkResponse) Reset() { *m = DetachNetworkResponse{} } +func (*DetachNetworkResponse) ProtoMessage() {} +func (*DetachNetworkResponse) Descriptor() ([]byte, []int) { return fileDescriptorResource, []int{3} } + +func init() { + proto.RegisterType((*AttachNetworkRequest)(nil), "docker.swarmkit.v1.AttachNetworkRequest") + proto.RegisterType((*AttachNetworkResponse)(nil), "docker.swarmkit.v1.AttachNetworkResponse") + proto.RegisterType((*DetachNetworkRequest)(nil), "docker.swarmkit.v1.DetachNetworkRequest") + proto.RegisterType((*DetachNetworkResponse)(nil), "docker.swarmkit.v1.DetachNetworkResponse") +} + +type authenticatedWrapperResourceAllocatorServer struct { + local ResourceAllocatorServer + authorize func(context.Context, []string) error +} + +func NewAuthenticatedWrapperResourceAllocatorServer(local ResourceAllocatorServer, authorize func(context.Context, []string) error) ResourceAllocatorServer { + return &authenticatedWrapperResourceAllocatorServer{ + local: local, + authorize: authorize, + } +} + +func (p *authenticatedWrapperResourceAllocatorServer) AttachNetwork(ctx context.Context, r *AttachNetworkRequest) (*AttachNetworkResponse, error) { + + if err := p.authorize(ctx, []string{"swarm-worker", "swarm-manager"}); err != nil { + return nil, err + } + return p.local.AttachNetwork(ctx, r) +} + +func (p *authenticatedWrapperResourceAllocatorServer) DetachNetwork(ctx context.Context, r *DetachNetworkRequest) (*DetachNetworkResponse, error) { + + if err := p.authorize(ctx, []string{"swarm-worker", "swarm-manager"}); err != nil { + return nil, err + } + return p.local.DetachNetwork(ctx, r) +} + +func (m *AttachNetworkRequest) Copy() *AttachNetworkRequest { + if m == nil { + return nil + } + + o := &AttachNetworkRequest{ + Config: m.Config.Copy(), + ContainerID: m.ContainerID, + } + + return o +} + +func (m *AttachNetworkResponse) Copy() *AttachNetworkResponse { + if m == nil { + return nil + } + + o := &AttachNetworkResponse{ + AttachmentID: m.AttachmentID, + } + + return o +} + +func (m *DetachNetworkRequest) Copy() *DetachNetworkRequest { + if m == nil { + return nil + } + + o := &DetachNetworkRequest{ + AttachmentID: m.AttachmentID, + } + + return o +} + +func (m *DetachNetworkResponse) Copy() *DetachNetworkResponse { + if m == nil { + return nil + } + + o := &DetachNetworkResponse{} + + return o +} + +func (this *AttachNetworkRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&api.AttachNetworkRequest{") + if this.Config != nil { + s = append(s, "Config: "+fmt.Sprintf("%#v", this.Config)+",\n") + } + s = append(s, "ContainerID: "+fmt.Sprintf("%#v", this.ContainerID)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *AttachNetworkResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&api.AttachNetworkResponse{") + s = append(s, "AttachmentID: "+fmt.Sprintf("%#v", this.AttachmentID)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DetachNetworkRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&api.DetachNetworkRequest{") + s = append(s, "AttachmentID: "+fmt.Sprintf("%#v", this.AttachmentID)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DetachNetworkResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 4) + s = append(s, "&api.DetachNetworkResponse{") + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringResource(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} +func extensionToGoStringResource(e map[int32]github_com_gogo_protobuf_proto.Extension) string { + if e == nil { + return "nil" + } + s := "map[int32]proto.Extension{" + keys := make([]int, 0, len(e)) + for k := range e { + keys = append(keys, int(k)) + } + sort.Ints(keys) + ss := []string{} + for _, k := range keys { + ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString()) + } + s += strings.Join(ss, ",") + "}" + return s +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion2 + +// Client API for ResourceAllocator service + +type ResourceAllocatorClient interface { + AttachNetwork(ctx context.Context, in *AttachNetworkRequest, opts ...grpc.CallOption) (*AttachNetworkResponse, error) + DetachNetwork(ctx context.Context, in *DetachNetworkRequest, opts ...grpc.CallOption) (*DetachNetworkResponse, error) +} + +type resourceAllocatorClient struct { + cc *grpc.ClientConn +} + +func NewResourceAllocatorClient(cc *grpc.ClientConn) ResourceAllocatorClient { + return &resourceAllocatorClient{cc} +} + +func (c *resourceAllocatorClient) AttachNetwork(ctx context.Context, in *AttachNetworkRequest, opts ...grpc.CallOption) (*AttachNetworkResponse, error) { + out := new(AttachNetworkResponse) + err := grpc.Invoke(ctx, "/docker.swarmkit.v1.ResourceAllocator/AttachNetwork", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceAllocatorClient) DetachNetwork(ctx context.Context, in *DetachNetworkRequest, opts ...grpc.CallOption) (*DetachNetworkResponse, error) { + out := new(DetachNetworkResponse) + err := grpc.Invoke(ctx, "/docker.swarmkit.v1.ResourceAllocator/DetachNetwork", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for ResourceAllocator service + +type ResourceAllocatorServer interface { + AttachNetwork(context.Context, *AttachNetworkRequest) (*AttachNetworkResponse, error) + DetachNetwork(context.Context, *DetachNetworkRequest) (*DetachNetworkResponse, error) +} + +func RegisterResourceAllocatorServer(s *grpc.Server, srv ResourceAllocatorServer) { + s.RegisterService(&_ResourceAllocator_serviceDesc, srv) +} + +func _ResourceAllocator_AttachNetwork_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AttachNetworkRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceAllocatorServer).AttachNetwork(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/docker.swarmkit.v1.ResourceAllocator/AttachNetwork", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceAllocatorServer).AttachNetwork(ctx, req.(*AttachNetworkRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceAllocator_DetachNetwork_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DetachNetworkRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceAllocatorServer).DetachNetwork(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/docker.swarmkit.v1.ResourceAllocator/DetachNetwork", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceAllocatorServer).DetachNetwork(ctx, req.(*DetachNetworkRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ResourceAllocator_serviceDesc = grpc.ServiceDesc{ + ServiceName: "docker.swarmkit.v1.ResourceAllocator", + HandlerType: (*ResourceAllocatorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AttachNetwork", + Handler: _ResourceAllocator_AttachNetwork_Handler, + }, + { + MethodName: "DetachNetwork", + Handler: _ResourceAllocator_DetachNetwork_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, +} + +func (m *AttachNetworkRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AttachNetworkRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Config != nil { + data[i] = 0xa + i++ + i = encodeVarintResource(data, i, uint64(m.Config.Size())) + n1, err := m.Config.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if len(m.ContainerID) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintResource(data, i, uint64(len(m.ContainerID))) + i += copy(data[i:], m.ContainerID) + } + return i, nil +} + +func (m *AttachNetworkResponse) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AttachNetworkResponse) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.AttachmentID) > 0 { + data[i] = 0xa + i++ + i = encodeVarintResource(data, i, uint64(len(m.AttachmentID))) + i += copy(data[i:], m.AttachmentID) + } + return i, nil +} + +func (m *DetachNetworkRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *DetachNetworkRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.AttachmentID) > 0 { + data[i] = 0xa + i++ + i = encodeVarintResource(data, i, uint64(len(m.AttachmentID))) + i += copy(data[i:], m.AttachmentID) + } + return i, nil +} + +func (m *DetachNetworkResponse) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *DetachNetworkResponse) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func encodeFixed64Resource(data []byte, offset int, v uint64) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + data[offset+4] = uint8(v >> 32) + data[offset+5] = uint8(v >> 40) + data[offset+6] = uint8(v >> 48) + data[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Resource(data []byte, offset int, v uint32) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintResource(data []byte, offset int, v uint64) int { + for v >= 1<<7 { + data[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + data[offset] = uint8(v) + return offset + 1 +} + +type raftProxyResourceAllocatorServer struct { + local ResourceAllocatorServer + connSelector raftpicker.Interface + cluster raftpicker.RaftCluster + ctxMods []func(context.Context) (context.Context, error) +} + +func NewRaftProxyResourceAllocatorServer(local ResourceAllocatorServer, connSelector raftpicker.Interface, cluster raftpicker.RaftCluster, ctxMod func(context.Context) (context.Context, error)) ResourceAllocatorServer { + redirectChecker := func(ctx context.Context) (context.Context, error) { + s, ok := transport.StreamFromContext(ctx) + if !ok { + return ctx, grpc.Errorf(codes.InvalidArgument, "remote addr is not found in context") + } + addr := s.ServerTransport().RemoteAddr().String() + md, ok := metadata.FromContext(ctx) + if ok && len(md["redirect"]) != 0 { + return ctx, grpc.Errorf(codes.ResourceExhausted, "more than one redirect to leader from: %s", md["redirect"]) + } + if !ok { + md = metadata.New(map[string]string{}) + } + md["redirect"] = append(md["redirect"], addr) + return metadata.NewContext(ctx, md), nil + } + mods := []func(context.Context) (context.Context, error){redirectChecker} + mods = append(mods, ctxMod) + + return &raftProxyResourceAllocatorServer{ + local: local, + cluster: cluster, + connSelector: connSelector, + ctxMods: mods, + } +} +func (p *raftProxyResourceAllocatorServer) runCtxMods(ctx context.Context) (context.Context, error) { + var err error + for _, mod := range p.ctxMods { + ctx, err = mod(ctx) + if err != nil { + return ctx, err + } + } + return ctx, nil +} + +func (p *raftProxyResourceAllocatorServer) AttachNetwork(ctx context.Context, r *AttachNetworkRequest) (*AttachNetworkResponse, error) { + + if p.cluster.IsLeader() { + return p.local.AttachNetwork(ctx, r) + } + ctx, err := p.runCtxMods(ctx) + if err != nil { + return nil, err + } + conn, err := p.connSelector.Conn() + if err != nil { + return nil, err + } + + defer func() { + if err != nil { + errStr := err.Error() + if strings.Contains(errStr, grpc.ErrClientConnClosing.Error()) || + strings.Contains(errStr, grpc.ErrClientConnTimeout.Error()) || + strings.Contains(errStr, "connection error") || + grpc.Code(err) == codes.Internal { + p.connSelector.Reset() + } + } + }() + + return NewResourceAllocatorClient(conn).AttachNetwork(ctx, r) +} + +func (p *raftProxyResourceAllocatorServer) DetachNetwork(ctx context.Context, r *DetachNetworkRequest) (*DetachNetworkResponse, error) { + + if p.cluster.IsLeader() { + return p.local.DetachNetwork(ctx, r) + } + ctx, err := p.runCtxMods(ctx) + if err != nil { + return nil, err + } + conn, err := p.connSelector.Conn() + if err != nil { + return nil, err + } + + defer func() { + if err != nil { + errStr := err.Error() + if strings.Contains(errStr, grpc.ErrClientConnClosing.Error()) || + strings.Contains(errStr, grpc.ErrClientConnTimeout.Error()) || + strings.Contains(errStr, "connection error") || + grpc.Code(err) == codes.Internal { + p.connSelector.Reset() + } + } + }() + + return NewResourceAllocatorClient(conn).DetachNetwork(ctx, r) +} + +func (m *AttachNetworkRequest) Size() (n int) { + var l int + _ = l + if m.Config != nil { + l = m.Config.Size() + n += 1 + l + sovResource(uint64(l)) + } + l = len(m.ContainerID) + if l > 0 { + n += 1 + l + sovResource(uint64(l)) + } + return n +} + +func (m *AttachNetworkResponse) Size() (n int) { + var l int + _ = l + l = len(m.AttachmentID) + if l > 0 { + n += 1 + l + sovResource(uint64(l)) + } + return n +} + +func (m *DetachNetworkRequest) Size() (n int) { + var l int + _ = l + l = len(m.AttachmentID) + if l > 0 { + n += 1 + l + sovResource(uint64(l)) + } + return n +} + +func (m *DetachNetworkResponse) Size() (n int) { + var l int + _ = l + return n +} + +func sovResource(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozResource(x uint64) (n int) { + return sovResource(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *AttachNetworkRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AttachNetworkRequest{`, + `Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "NetworkAttachmentConfig", "NetworkAttachmentConfig", 1) + `,`, + `ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`, + `}`, + }, "") + return s +} +func (this *AttachNetworkResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AttachNetworkResponse{`, + `AttachmentID:` + fmt.Sprintf("%v", this.AttachmentID) + `,`, + `}`, + }, "") + return s +} +func (this *DetachNetworkRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DetachNetworkRequest{`, + `AttachmentID:` + fmt.Sprintf("%v", this.AttachmentID) + `,`, + `}`, + }, "") + return s +} +func (this *DetachNetworkResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DetachNetworkResponse{`, + `}`, + }, "") + return s +} +func valueToStringResource(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *AttachNetworkRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AttachNetworkRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AttachNetworkRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthResource + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Config == nil { + m.Config = &NetworkAttachmentConfig{} + } + if err := m.Config.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthResource + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainerID = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipResource(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthResource + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AttachNetworkResponse) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AttachNetworkResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AttachNetworkResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AttachmentID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthResource + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AttachmentID = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipResource(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthResource + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DetachNetworkRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DetachNetworkRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DetachNetworkRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AttachmentID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthResource + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AttachmentID = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipResource(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthResource + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DetachNetworkResponse) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowResource + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DetachNetworkResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DetachNetworkResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipResource(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthResource + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipResource(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowResource + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowResource + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowResource + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthResource + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowResource + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipResource(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthResource = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowResource = fmt.Errorf("proto: integer overflow") +) + +var fileDescriptorResource = []byte{ + // 373 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2b, 0x4a, 0x2d, 0xce, + 0x2f, 0x2d, 0x4a, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xc9, 0x4f, 0xce, + 0x4e, 0x2d, 0xd2, 0x2b, 0x2e, 0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x2b, 0x33, 0x94, 0xe2, + 0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x86, 0x28, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x33, 0xf5, + 0x41, 0x2c, 0xa8, 0xa8, 0x70, 0x41, 0x4e, 0x69, 0x7a, 0x66, 0x9e, 0x3e, 0x84, 0x82, 0x08, 0x2a, + 0xf5, 0x33, 0x72, 0x89, 0x38, 0x96, 0x94, 0x24, 0x26, 0x67, 0xf8, 0xa5, 0x96, 0x94, 0xe7, 0x17, + 0x65, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0x39, 0x73, 0xb1, 0x25, 0xe7, 0xe7, 0xa5, + 0x65, 0xa6, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b, 0x69, 0xeb, 0x61, 0xda, 0xaa, 0x07, 0xd5, + 0x03, 0x31, 0x20, 0x37, 0x35, 0xaf, 0xc4, 0x19, 0xac, 0x25, 0x08, 0xaa, 0x55, 0xc8, 0x88, 0x8b, + 0x27, 0x39, 0x3f, 0xaf, 0x24, 0x31, 0x33, 0x2f, 0xb5, 0x28, 0x3e, 0x33, 0x45, 0x82, 0x49, 0x81, + 0x51, 0x83, 0xd3, 0x89, 0xff, 0xd1, 0x3d, 0x79, 0x6e, 0x67, 0x98, 0xb8, 0xa7, 0x4b, 0x10, 0x37, + 0x5c, 0x91, 0x67, 0x8a, 0x92, 0x1f, 0x97, 0x28, 0x9a, 0x83, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, + 0x85, 0x4c, 0xb9, 0x78, 0x13, 0xe1, 0x16, 0x81, 0x4c, 0x63, 0x04, 0x9b, 0x26, 0xf0, 0xe8, 0x9e, + 0x3c, 0x0f, 0xc2, 0x05, 0x9e, 0x2e, 0x41, 0x3c, 0x08, 0x65, 0x9e, 0x29, 0x4a, 0xbe, 0x5c, 0x22, + 0x2e, 0xa9, 0x58, 0x3c, 0x48, 0xa6, 0x71, 0xe2, 0x5c, 0xa2, 0x68, 0xc6, 0x41, 0x9c, 0x67, 0xb4, + 0x9a, 0x89, 0x4b, 0x30, 0x08, 0x1a, 0x51, 0x8e, 0x39, 0x39, 0xf9, 0xc9, 0x89, 0x25, 0xf9, 0x45, + 0x42, 0x9d, 0x8c, 0x5c, 0xbc, 0x28, 0xde, 0x11, 0xd2, 0xc0, 0x16, 0x90, 0xd8, 0xa2, 0x40, 0x4a, + 0x93, 0x08, 0x95, 0x10, 0xcb, 0x95, 0x94, 0x4f, 0xad, 0x7b, 0x37, 0x83, 0x49, 0x96, 0x8b, 0x07, + 0xac, 0x54, 0x17, 0x24, 0x97, 0x5a, 0xc4, 0xc5, 0x0b, 0xe1, 0xe5, 0x26, 0xe6, 0x25, 0xa6, 0xa7, + 0x42, 0xdc, 0x82, 0xe2, 0x76, 0xec, 0x6e, 0xc1, 0x16, 0x5a, 0xd8, 0xdd, 0x82, 0x35, 0x20, 0x88, + 0x72, 0x8b, 0x93, 0xcc, 0x89, 0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, 0x7c, 0x78, 0x28, 0xc7, + 0xd8, 0xf0, 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, + 0x63, 0x4c, 0x62, 0x03, 0x27, 0x4e, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xef, 0x94, 0x58, + 0xde, 0xfa, 0x02, 0x00, 0x00, +} diff --git a/vendor/src/github.com/docker/swarmkit/api/resource.proto b/vendor/src/github.com/docker/swarmkit/api/resource.proto new file mode 100644 index 0000000000..402777fb22 --- /dev/null +++ b/vendor/src/github.com/docker/swarmkit/api/resource.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package docker.swarmkit.v1; + +import "types.proto"; +import "gogoproto/gogo.proto"; +import "plugin/plugin.proto"; + +// Allocator is the API provided by a manager group for agents to control the allocation of certain entities. +// +// API methods on this service are used only by agent nodes. +service ResourceAllocator { + rpc AttachNetwork(AttachNetworkRequest) returns (AttachNetworkResponse) { + option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-worker" roles: "swarm-manager" }; + }; + rpc DetachNetwork(DetachNetworkRequest) returns (DetachNetworkResponse) { + option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-worker" roles: "swarm-manager" }; + }; +} + +message AttachNetworkRequest { + NetworkAttachmentConfig config = 1; + string container_id = 2 [(gogoproto.customname) = "ContainerID"]; +} + +message AttachNetworkResponse { + string attachment_id = 1 [(gogoproto.customname) = "AttachmentID"]; +} + +message DetachNetworkRequest { + string attachment_id = 1 [(gogoproto.customname) = "AttachmentID"]; +} + +message DetachNetworkResponse {} diff --git a/vendor/src/github.com/docker/swarmkit/api/specs.pb.go b/vendor/src/github.com/docker/swarmkit/api/specs.pb.go index b83a16f85b..d5d2a00bf2 100644 --- a/vendor/src/github.com/docker/swarmkit/api/specs.pb.go +++ b/vendor/src/github.com/docker/swarmkit/api/specs.pb.go @@ -107,7 +107,7 @@ func (x EndpointSpec_ResolutionMode) String() string { return proto.EnumName(EndpointSpec_ResolutionMode_name, int32(x)) } func (EndpointSpec_ResolutionMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptorSpecs, []int{6, 0} + return fileDescriptorSpecs, []int{7, 0} } type NodeSpec struct { @@ -140,8 +140,8 @@ type ServiceSpec struct { // *ServiceSpec_Global Mode isServiceSpec_Mode `protobuf_oneof:"mode"` // UpdateConfig controls the rate and policy of updates. - Update *UpdateConfig `protobuf:"bytes,6,opt,name=update" json:"update,omitempty"` - Networks []*ServiceSpec_NetworkAttachmentConfig `protobuf:"bytes,7,rep,name=networks" json:"networks,omitempty"` + Update *UpdateConfig `protobuf:"bytes,6,opt,name=update" json:"update,omitempty"` + Networks []*NetworkAttachmentConfig `protobuf:"bytes,7,rep,name=networks" json:"networks,omitempty"` // Service endpoint specifies the user provided configuration // to properly discover and load balance a service. Endpoint *EndpointSpec `protobuf:"bytes,8,opt,name=endpoint" json:"endpoint,omitempty"` @@ -262,25 +262,6 @@ func _ServiceSpec_OneofSizer(msg proto.Message) (n int) { return n } -// NetworkAttachmentConfig specifies how a service should be attached to a particular network. -// -// For now, this is a simple struct, but this can include future information -// instructing Swarm on how this service should work on the particular -// network. -type ServiceSpec_NetworkAttachmentConfig struct { - // Target specifies the target network for attachment. This value may be a - // network name or identifier. Only identifiers are supported at this time. - Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` - // Aliases specifies a list of discoverable alternate names for the service on this Target. - Aliases []string `protobuf:"bytes,2,rep,name=aliases" json:"aliases,omitempty"` -} - -func (m *ServiceSpec_NetworkAttachmentConfig) Reset() { *m = ServiceSpec_NetworkAttachmentConfig{} } -func (*ServiceSpec_NetworkAttachmentConfig) ProtoMessage() {} -func (*ServiceSpec_NetworkAttachmentConfig) Descriptor() ([]byte, []int) { - return fileDescriptorSpecs, []int{1, 0} -} - // ReplicatedService sets the reconciliation target to certain number of replicas. type ReplicatedService struct { Replicas uint64 `protobuf:"varint,1,opt,name=replicas,proto3" json:"replicas,omitempty"` @@ -300,6 +281,7 @@ func (*GlobalService) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, type TaskSpec struct { // Types that are valid to be assigned to Runtime: + // *TaskSpec_Attachment // *TaskSpec_Container Runtime isTaskSpec_Runtime `protobuf_oneof:"runtime"` // Resource requirements for the container. @@ -311,6 +293,10 @@ type TaskSpec struct { // LogDriver specifies the log driver to use for the task. Any runtime will // direct logs into the specified driver for the duration of the task. LogDriver *Driver `protobuf:"bytes,6,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + // Networks specifies the list of network attachment + // configurations (which specify the network and per-network + // aliases) that this task spec is bound to. + Networks []*NetworkAttachmentConfig `protobuf:"bytes,7,rep,name=networks" json:"networks,omitempty"` } func (m *TaskSpec) Reset() { *m = TaskSpec{} } @@ -323,11 +309,15 @@ type isTaskSpec_Runtime interface { Size() int } +type TaskSpec_Attachment struct { + Attachment *NetworkAttachmentSpec `protobuf:"bytes,8,opt,name=attachment,oneof"` +} type TaskSpec_Container struct { Container *ContainerSpec `protobuf:"bytes,1,opt,name=container,oneof"` } -func (*TaskSpec_Container) isTaskSpec_Runtime() {} +func (*TaskSpec_Attachment) isTaskSpec_Runtime() {} +func (*TaskSpec_Container) isTaskSpec_Runtime() {} func (m *TaskSpec) GetRuntime() isTaskSpec_Runtime { if m != nil { @@ -336,6 +326,13 @@ func (m *TaskSpec) GetRuntime() isTaskSpec_Runtime { return nil } +func (m *TaskSpec) GetAttachment() *NetworkAttachmentSpec { + if x, ok := m.GetRuntime().(*TaskSpec_Attachment); ok { + return x.Attachment + } + return nil +} + func (m *TaskSpec) GetContainer() *ContainerSpec { if x, ok := m.GetRuntime().(*TaskSpec_Container); ok { return x.Container @@ -346,6 +343,7 @@ func (m *TaskSpec) GetContainer() *ContainerSpec { // XXX_OneofFuncs is for the internal use of the proto package. func (*TaskSpec) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _TaskSpec_OneofMarshaler, _TaskSpec_OneofUnmarshaler, _TaskSpec_OneofSizer, []interface{}{ + (*TaskSpec_Attachment)(nil), (*TaskSpec_Container)(nil), } } @@ -354,6 +352,11 @@ func _TaskSpec_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { m := msg.(*TaskSpec) // runtime switch x := m.Runtime.(type) { + case *TaskSpec_Attachment: + _ = b.EncodeVarint(8<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Attachment); err != nil { + return err + } case *TaskSpec_Container: _ = b.EncodeVarint(1<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Container); err != nil { @@ -369,6 +372,14 @@ func _TaskSpec_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { func _TaskSpec_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { m := msg.(*TaskSpec) switch tag { + case 8: // runtime.attachment + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(NetworkAttachmentSpec) + err := b.DecodeMessage(msg) + m.Runtime = &TaskSpec_Attachment{msg} + return true, err case 1: // runtime.container if wire != proto.WireBytes { return true, proto.ErrInternalBadWireType @@ -386,6 +397,11 @@ func _TaskSpec_OneofSizer(msg proto.Message) (n int) { m := msg.(*TaskSpec) // runtime switch x := m.Runtime.(type) { + case *TaskSpec_Attachment: + s := proto.Size(x.Attachment) + n += proto.SizeVarint(8<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s case *TaskSpec_Container: s := proto.Size(x.Container) n += proto.SizeVarint(1<<3 | proto.WireBytes) @@ -398,6 +414,18 @@ func _TaskSpec_OneofSizer(msg proto.Message) (n int) { return n } +// NetworkAttachmentSpec specifies runtime parameters required to attach +// a container to a network. +type NetworkAttachmentSpec struct { + // ContainerID spcifies a unique ID of the container for which + // this attachment is for. + ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` +} + +func (m *NetworkAttachmentSpec) Reset() { *m = NetworkAttachmentSpec{} } +func (*NetworkAttachmentSpec) ProtoMessage() {} +func (*NetworkAttachmentSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{5} } + // Container specifies runtime parameters for a container. type ContainerSpec struct { // image defines the image reference, as specified in the @@ -449,7 +477,7 @@ type ContainerSpec struct { func (m *ContainerSpec) Reset() { *m = ContainerSpec{} } func (*ContainerSpec) ProtoMessage() {} -func (*ContainerSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{5} } +func (*ContainerSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{6} } // PullOptions allows one to parameterize an image pull. type ContainerSpec_PullOptions struct { @@ -463,7 +491,7 @@ type ContainerSpec_PullOptions struct { func (m *ContainerSpec_PullOptions) Reset() { *m = ContainerSpec_PullOptions{} } func (*ContainerSpec_PullOptions) ProtoMessage() {} func (*ContainerSpec_PullOptions) Descriptor() ([]byte, []int) { - return fileDescriptorSpecs, []int{5, 1} + return fileDescriptorSpecs, []int{6, 1} } // EndpointSpec defines the properties that can be configured to @@ -477,7 +505,7 @@ type EndpointSpec struct { func (m *EndpointSpec) Reset() { *m = EndpointSpec{} } func (*EndpointSpec) ProtoMessage() {} -func (*EndpointSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{6} } +func (*EndpointSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7} } // NetworkSpec specifies user defined network parameters. type NetworkSpec struct { @@ -490,11 +518,19 @@ type NetworkSpec struct { // accomplished by disabling the default gateway or through other means. Internal bool `protobuf:"varint,4,opt,name=internal,proto3" json:"internal,omitempty"` IPAM *IPAMOptions `protobuf:"bytes,5,opt,name=ipam" json:"ipam,omitempty"` + // Attachable allows external(to swarm) entities to manually + // attach to this network. With this flag enabled, external + // entities such as containers running in an worker node in + // the cluster can manually attach to this network and access + // the services attached to this network. If this flag is not + // enabled(default case) no manual attachment to this network + // can happen. + Attachable bool `protobuf:"varint,6,opt,name=attachable,proto3" json:"attachable,omitempty"` } func (m *NetworkSpec) Reset() { *m = NetworkSpec{} } func (*NetworkSpec) ProtoMessage() {} -func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7} } +func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8} } // ClusterSpec specifies global cluster settings. type ClusterSpec struct { @@ -517,15 +553,15 @@ type ClusterSpec struct { func (m *ClusterSpec) Reset() { *m = ClusterSpec{} } func (*ClusterSpec) ProtoMessage() {} -func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8} } +func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} } func init() { proto.RegisterType((*NodeSpec)(nil), "docker.swarmkit.v1.NodeSpec") proto.RegisterType((*ServiceSpec)(nil), "docker.swarmkit.v1.ServiceSpec") - proto.RegisterType((*ServiceSpec_NetworkAttachmentConfig)(nil), "docker.swarmkit.v1.ServiceSpec.NetworkAttachmentConfig") proto.RegisterType((*ReplicatedService)(nil), "docker.swarmkit.v1.ReplicatedService") proto.RegisterType((*GlobalService)(nil), "docker.swarmkit.v1.GlobalService") proto.RegisterType((*TaskSpec)(nil), "docker.swarmkit.v1.TaskSpec") + proto.RegisterType((*NetworkAttachmentSpec)(nil), "docker.swarmkit.v1.NetworkAttachmentSpec") proto.RegisterType((*ContainerSpec)(nil), "docker.swarmkit.v1.ContainerSpec") proto.RegisterType((*ContainerSpec_PullOptions)(nil), "docker.swarmkit.v1.ContainerSpec.PullOptions") proto.RegisterType((*EndpointSpec)(nil), "docker.swarmkit.v1.EndpointSpec") @@ -564,7 +600,7 @@ func (m *ServiceSpec) Copy() *ServiceSpec { } if m.Networks != nil { - o.Networks = make([]*ServiceSpec_NetworkAttachmentConfig, 0, len(m.Networks)) + o.Networks = make([]*NetworkAttachmentConfig, 0, len(m.Networks)) for _, v := range m.Networks { o.Networks = append(o.Networks, v.Copy()) } @@ -588,25 +624,6 @@ func (m *ServiceSpec) Copy() *ServiceSpec { return o } -func (m *ServiceSpec_NetworkAttachmentConfig) Copy() *ServiceSpec_NetworkAttachmentConfig { - if m == nil { - return nil - } - - o := &ServiceSpec_NetworkAttachmentConfig{ - Target: m.Target, - } - - if m.Aliases != nil { - o.Aliases = make([]string, 0, len(m.Aliases)) - for _, v := range m.Aliases { - o.Aliases = append(o.Aliases, v) - } - } - - return o -} - func (m *ReplicatedService) Copy() *ReplicatedService { if m == nil { return nil @@ -641,7 +658,20 @@ func (m *TaskSpec) Copy() *TaskSpec { LogDriver: m.LogDriver.Copy(), } + if m.Networks != nil { + o.Networks = make([]*NetworkAttachmentConfig, 0, len(m.Networks)) + for _, v := range m.Networks { + o.Networks = append(o.Networks, v.Copy()) + } + } + switch m.Runtime.(type) { + case *TaskSpec_Attachment: + i := &TaskSpec_Attachment{ + Attachment: m.GetAttachment().Copy(), + } + + o.Runtime = i case *TaskSpec_Container: i := &TaskSpec_Container{ Container: m.GetContainer().Copy(), @@ -653,6 +683,18 @@ func (m *TaskSpec) Copy() *TaskSpec { return o } +func (m *NetworkAttachmentSpec) Copy() *NetworkAttachmentSpec { + if m == nil { + return nil + } + + o := &NetworkAttachmentSpec{ + ContainerID: m.ContainerID, + } + + return o +} + func (m *ContainerSpec) Copy() *ContainerSpec { if m == nil { return nil @@ -753,6 +795,7 @@ func (m *NetworkSpec) Copy() *NetworkSpec { Ipv6Enabled: m.Ipv6Enabled, Internal: m.Internal, IPAM: m.IPAM.Copy(), + Attachable: m.Attachable, } return o @@ -828,17 +871,6 @@ func (this *ServiceSpec_Global) GoString() string { `Global:` + fmt.Sprintf("%#v", this.Global) + `}`}, ", ") return s } -func (this *ServiceSpec_NetworkAttachmentConfig) GoString() string { - if this == nil { - return "nil" - } - s := make([]string, 0, 6) - s = append(s, "&api.ServiceSpec_NetworkAttachmentConfig{") - s = append(s, "Target: "+fmt.Sprintf("%#v", this.Target)+",\n") - s = append(s, "Aliases: "+fmt.Sprintf("%#v", this.Aliases)+",\n") - s = append(s, "}") - return strings.Join(s, "") -} func (this *ReplicatedService) GoString() string { if this == nil { return "nil" @@ -862,7 +894,7 @@ func (this *TaskSpec) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 9) + s := make([]string, 0, 11) s = append(s, "&api.TaskSpec{") if this.Runtime != nil { s = append(s, "Runtime: "+fmt.Sprintf("%#v", this.Runtime)+",\n") @@ -879,9 +911,20 @@ func (this *TaskSpec) GoString() string { if this.LogDriver != nil { s = append(s, "LogDriver: "+fmt.Sprintf("%#v", this.LogDriver)+",\n") } + if this.Networks != nil { + s = append(s, "Networks: "+fmt.Sprintf("%#v", this.Networks)+",\n") + } s = append(s, "}") return strings.Join(s, "") } +func (this *TaskSpec_Attachment) GoString() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&api.TaskSpec_Attachment{` + + `Attachment:` + fmt.Sprintf("%#v", this.Attachment) + `}`}, ", ") + return s +} func (this *TaskSpec_Container) GoString() string { if this == nil { return "nil" @@ -890,6 +933,16 @@ func (this *TaskSpec_Container) GoString() string { `Container:` + fmt.Sprintf("%#v", this.Container) + `}`}, ", ") return s } +func (this *NetworkAttachmentSpec) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&api.NetworkAttachmentSpec{") + s = append(s, "ContainerID: "+fmt.Sprintf("%#v", this.ContainerID)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func (this *ContainerSpec) GoString() string { if this == nil { return "nil" @@ -955,7 +1008,7 @@ func (this *NetworkSpec) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 9) + s := make([]string, 0, 10) s = append(s, "&api.NetworkSpec{") s = append(s, "Annotations: "+strings.Replace(this.Annotations.GoString(), `&`, ``, 1)+",\n") if this.DriverConfig != nil { @@ -966,6 +1019,7 @@ func (this *NetworkSpec) GoString() string { if this.IPAM != nil { s = append(s, "IPAM: "+fmt.Sprintf("%#v", this.IPAM)+",\n") } + s = append(s, "Attachable: "+fmt.Sprintf("%#v", this.Attachable)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -1152,45 +1206,6 @@ func (m *ServiceSpec_Global) MarshalTo(data []byte) (int, error) { } return i, nil } -func (m *ServiceSpec_NetworkAttachmentConfig) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *ServiceSpec_NetworkAttachmentConfig) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Target) > 0 { - data[i] = 0xa - i++ - i = encodeVarintSpecs(data, i, uint64(len(m.Target))) - i += copy(data[i:], m.Target) - } - if len(m.Aliases) > 0 { - for _, s := range m.Aliases { - data[i] = 0x12 - i++ - l = len(s) - for l >= 1<<7 { - data[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - data[i] = uint8(l) - i++ - i += copy(data[i:], s) - } - } - return i, nil -} - func (m *ReplicatedService) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -1294,6 +1309,18 @@ func (m *TaskSpec) MarshalTo(data []byte) (int, error) { } i += n13 } + if len(m.Networks) > 0 { + for _, msg := range m.Networks { + data[i] = 0x3a + i++ + i = encodeVarintSpecs(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -1311,6 +1338,44 @@ func (m *TaskSpec_Container) MarshalTo(data []byte) (int, error) { } return i, nil } +func (m *TaskSpec_Attachment) MarshalTo(data []byte) (int, error) { + i := 0 + if m.Attachment != nil { + data[i] = 0x42 + i++ + i = encodeVarintSpecs(data, i, uint64(m.Attachment.Size())) + n15, err := m.Attachment.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n15 + } + return i, nil +} +func (m *NetworkAttachmentSpec) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkAttachmentSpec) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ContainerID) > 0 { + data[i] = 0xa + i++ + i = encodeVarintSpecs(data, i, uint64(len(m.ContainerID))) + i += copy(data[i:], m.ContainerID) + } + return i, nil +} + func (m *ContainerSpec) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -1422,21 +1487,21 @@ func (m *ContainerSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x4a i++ i = encodeVarintSpecs(data, i, uint64(m.StopGracePeriod.Size())) - n15, err := m.StopGracePeriod.MarshalTo(data[i:]) + n16, err := m.StopGracePeriod.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n15 + i += n16 } if m.PullOptions != nil { data[i] = 0x52 i++ i = encodeVarintSpecs(data, i, uint64(m.PullOptions.Size())) - n16, err := m.PullOptions.MarshalTo(data[i:]) + n17, err := m.PullOptions.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n16 + i += n17 } if len(m.Groups) > 0 { for _, s := range m.Groups { @@ -1535,20 +1600,20 @@ func (m *NetworkSpec) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintSpecs(data, i, uint64(m.Annotations.Size())) - n17, err := m.Annotations.MarshalTo(data[i:]) + n18, err := m.Annotations.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n17 + i += n18 if m.DriverConfig != nil { data[i] = 0x12 i++ i = encodeVarintSpecs(data, i, uint64(m.DriverConfig.Size())) - n18, err := m.DriverConfig.MarshalTo(data[i:]) + n19, err := m.DriverConfig.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } if m.Ipv6Enabled { data[i] = 0x18 @@ -1574,11 +1639,21 @@ func (m *NetworkSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x2a i++ i = encodeVarintSpecs(data, i, uint64(m.IPAM.Size())) - n19, err := m.IPAM.MarshalTo(data[i:]) + n20, err := m.IPAM.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n19 + i += n20 + } + if m.Attachable { + data[i] = 0x30 + i++ + if m.Attachable { + data[i] = 1 + } else { + data[i] = 0 + } + i++ } return i, nil } @@ -1601,59 +1676,59 @@ func (m *ClusterSpec) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintSpecs(data, i, uint64(m.Annotations.Size())) - n20, err := m.Annotations.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n20 - data[i] = 0x12 - i++ - i = encodeVarintSpecs(data, i, uint64(m.AcceptancePolicy.Size())) - n21, err := m.AcceptancePolicy.MarshalTo(data[i:]) + n21, err := m.Annotations.MarshalTo(data[i:]) if err != nil { return 0, err } i += n21 - data[i] = 0x1a + data[i] = 0x12 i++ - i = encodeVarintSpecs(data, i, uint64(m.Orchestration.Size())) - n22, err := m.Orchestration.MarshalTo(data[i:]) + i = encodeVarintSpecs(data, i, uint64(m.AcceptancePolicy.Size())) + n22, err := m.AcceptancePolicy.MarshalTo(data[i:]) if err != nil { return 0, err } i += n22 - data[i] = 0x22 + data[i] = 0x1a i++ - i = encodeVarintSpecs(data, i, uint64(m.Raft.Size())) - n23, err := m.Raft.MarshalTo(data[i:]) + i = encodeVarintSpecs(data, i, uint64(m.Orchestration.Size())) + n23, err := m.Orchestration.MarshalTo(data[i:]) if err != nil { return 0, err } i += n23 - data[i] = 0x2a + data[i] = 0x22 i++ - i = encodeVarintSpecs(data, i, uint64(m.Dispatcher.Size())) - n24, err := m.Dispatcher.MarshalTo(data[i:]) + i = encodeVarintSpecs(data, i, uint64(m.Raft.Size())) + n24, err := m.Raft.MarshalTo(data[i:]) if err != nil { return 0, err } i += n24 - data[i] = 0x32 + data[i] = 0x2a i++ - i = encodeVarintSpecs(data, i, uint64(m.CAConfig.Size())) - n25, err := m.CAConfig.MarshalTo(data[i:]) + i = encodeVarintSpecs(data, i, uint64(m.Dispatcher.Size())) + n25, err := m.Dispatcher.MarshalTo(data[i:]) if err != nil { return 0, err } i += n25 - data[i] = 0x3a + data[i] = 0x32 i++ - i = encodeVarintSpecs(data, i, uint64(m.TaskDefaults.Size())) - n26, err := m.TaskDefaults.MarshalTo(data[i:]) + i = encodeVarintSpecs(data, i, uint64(m.CAConfig.Size())) + n26, err := m.CAConfig.MarshalTo(data[i:]) if err != nil { return 0, err } i += n26 + data[i] = 0x3a + i++ + i = encodeVarintSpecs(data, i, uint64(m.TaskDefaults.Size())) + n27, err := m.TaskDefaults.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n27 return i, nil } @@ -1747,22 +1822,6 @@ func (m *ServiceSpec_Global) Size() (n int) { } return n } -func (m *ServiceSpec_NetworkAttachmentConfig) Size() (n int) { - var l int - _ = l - l = len(m.Target) - if l > 0 { - n += 1 + l + sovSpecs(uint64(l)) - } - if len(m.Aliases) > 0 { - for _, s := range m.Aliases { - l = len(s) - n += 1 + l + sovSpecs(uint64(l)) - } - } - return n -} - func (m *ReplicatedService) Size() (n int) { var l int _ = l @@ -1800,6 +1859,12 @@ func (m *TaskSpec) Size() (n int) { l = m.LogDriver.Size() n += 1 + l + sovSpecs(uint64(l)) } + if len(m.Networks) > 0 { + for _, e := range m.Networks { + l = e.Size() + n += 1 + l + sovSpecs(uint64(l)) + } + } return n } @@ -1812,6 +1877,25 @@ func (m *TaskSpec_Container) Size() (n int) { } return n } +func (m *TaskSpec_Attachment) Size() (n int) { + var l int + _ = l + if m.Attachment != nil { + l = m.Attachment.Size() + n += 1 + l + sovSpecs(uint64(l)) + } + return n +} +func (m *NetworkAttachmentSpec) Size() (n int) { + var l int + _ = l + l = len(m.ContainerID) + if l > 0 { + n += 1 + l + sovSpecs(uint64(l)) + } + return n +} + func (m *ContainerSpec) Size() (n int) { var l int _ = l @@ -1920,6 +2004,9 @@ func (m *NetworkSpec) Size() (n int) { l = m.IPAM.Size() n += 1 + l + sovSpecs(uint64(l)) } + if m.Attachable { + n += 2 + } return n } @@ -1978,7 +2065,7 @@ func (this *ServiceSpec) String() string { `Task:` + strings.Replace(strings.Replace(this.Task.String(), "TaskSpec", "TaskSpec", 1), `&`, ``, 1) + `,`, `Mode:` + fmt.Sprintf("%v", this.Mode) + `,`, `Update:` + strings.Replace(fmt.Sprintf("%v", this.Update), "UpdateConfig", "UpdateConfig", 1) + `,`, - `Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "ServiceSpec_NetworkAttachmentConfig", "ServiceSpec_NetworkAttachmentConfig", 1) + `,`, + `Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "NetworkAttachmentConfig", "NetworkAttachmentConfig", 1) + `,`, `Endpoint:` + strings.Replace(fmt.Sprintf("%v", this.Endpoint), "EndpointSpec", "EndpointSpec", 1) + `,`, `}`, }, "") @@ -2004,17 +2091,6 @@ func (this *ServiceSpec_Global) String() string { }, "") return s } -func (this *ServiceSpec_NetworkAttachmentConfig) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ServiceSpec_NetworkAttachmentConfig{`, - `Target:` + fmt.Sprintf("%v", this.Target) + `,`, - `Aliases:` + fmt.Sprintf("%v", this.Aliases) + `,`, - `}`, - }, "") - return s -} func (this *ReplicatedService) String() string { if this == nil { return "nil" @@ -2044,6 +2120,7 @@ func (this *TaskSpec) String() string { `Restart:` + strings.Replace(fmt.Sprintf("%v", this.Restart), "RestartPolicy", "RestartPolicy", 1) + `,`, `Placement:` + strings.Replace(fmt.Sprintf("%v", this.Placement), "Placement", "Placement", 1) + `,`, `LogDriver:` + strings.Replace(fmt.Sprintf("%v", this.LogDriver), "Driver", "Driver", 1) + `,`, + `Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "NetworkAttachmentConfig", "NetworkAttachmentConfig", 1) + `,`, `}`, }, "") return s @@ -2058,6 +2135,26 @@ func (this *TaskSpec_Container) String() string { }, "") return s } +func (this *TaskSpec_Attachment) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TaskSpec_Attachment{`, + `Attachment:` + strings.Replace(fmt.Sprintf("%v", this.Attachment), "NetworkAttachmentSpec", "NetworkAttachmentSpec", 1) + `,`, + `}`, + }, "") + return s +} +func (this *NetworkAttachmentSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NetworkAttachmentSpec{`, + `ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`, + `}`, + }, "") + return s +} func (this *ContainerSpec) String() string { if this == nil { return "nil" @@ -2119,6 +2216,7 @@ func (this *NetworkSpec) String() string { `Ipv6Enabled:` + fmt.Sprintf("%v", this.Ipv6Enabled) + `,`, `Internal:` + fmt.Sprintf("%v", this.Internal) + `,`, `IPAM:` + strings.Replace(fmt.Sprintf("%v", this.IPAM), "IPAMOptions", "IPAMOptions", 1) + `,`, + `Attachable:` + fmt.Sprintf("%v", this.Attachable) + `,`, `}`, }, "") return s @@ -2496,7 +2594,7 @@ func (m *ServiceSpec) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Networks = append(m.Networks, &ServiceSpec_NetworkAttachmentConfig{}) + m.Networks = append(m.Networks, &NetworkAttachmentConfig{}) if err := m.Networks[len(m.Networks)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { return err } @@ -2555,114 +2653,6 @@ func (m *ServiceSpec) Unmarshal(data []byte) error { } return nil } -func (m *ServiceSpec_NetworkAttachmentConfig) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpecs - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: NetworkAttachmentConfig: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkAttachmentConfig: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpecs - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSpecs - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Target = string(data[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Aliases", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSpecs - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSpecs - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Aliases = append(m.Aliases, string(data[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSpecs(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthSpecs - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *ReplicatedService) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -2975,6 +2965,148 @@ func (m *TaskSpec) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Networks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Networks = append(m.Networks, &NetworkAttachmentConfig{}) + if err := m.Networks[len(m.Networks)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attachment", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &NetworkAttachmentSpec{} + if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + m.Runtime = &TaskSpec_Attachment{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpecs(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSpecs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkAttachmentSpec) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkAttachmentSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkAttachmentSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainerID = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(data[iNdEx:]) @@ -3801,6 +3933,26 @@ func (m *NetworkSpec) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Attachable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Attachable = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSpecs(data[iNdEx:]) @@ -4188,91 +4340,93 @@ var ( ) var fileDescriptorSpecs = []byte{ - // 1361 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x4d, 0x6f, 0x1b, 0xb7, - 0x16, 0xd5, 0xd8, 0x63, 0x59, 0xba, 0x23, 0x27, 0x0a, 0x91, 0x97, 0x4c, 0x94, 0x3c, 0x59, 0xd1, - 0xcb, 0x4b, 0xdd, 0x02, 0x95, 0x5b, 0xb5, 0xc8, 0x47, 0xd3, 0xa2, 0x95, 0x25, 0xd5, 0x71, 0x53, - 0x3b, 0x02, 0x9d, 0x04, 0xe8, 0x4a, 0xa0, 0x67, 0x68, 0x99, 0xf0, 0x68, 0x38, 0xe5, 0x70, 0x14, - 0x78, 0xd7, 0x65, 0xe0, 0x45, 0x77, 0x5d, 0x7a, 0x55, 0xa0, 0xcb, 0x2e, 0xfb, 0x1b, 0xb2, 0xec, - 0xa6, 0x40, 0x57, 0x41, 0xe3, 0x5f, 0x50, 0xa0, 0x7f, 0xa0, 0x20, 0x87, 0xfa, 0x6a, 0xc6, 0x49, - 0x17, 0xd9, 0x91, 0x57, 0xe7, 0x1c, 0xde, 0xb9, 0x3c, 0xbc, 0xa4, 0xc0, 0x89, 0x23, 0xea, 0xc5, - 0x8d, 0x48, 0x70, 0xc9, 0x11, 0xf2, 0xb9, 0x77, 0x48, 0x45, 0x23, 0x7e, 0x4a, 0xc4, 0xf0, 0x90, - 0xc9, 0xc6, 0xe8, 0xc3, 0x8a, 0x23, 0x8f, 0x22, 0x6a, 0x00, 0x95, 0x8b, 0x03, 0x3e, 0xe0, 0x7a, - 0xb8, 0xae, 0x46, 0x26, 0x7a, 0xd9, 0x4f, 0x04, 0x91, 0x8c, 0x87, 0xeb, 0xe3, 0x41, 0xfa, 0x43, - 0xfd, 0x7b, 0x1b, 0x0a, 0x3b, 0xdc, 0xa7, 0xbb, 0x11, 0xf5, 0xd0, 0x26, 0x38, 0x24, 0x0c, 0xb9, - 0xd4, 0x80, 0xd8, 0xb5, 0x6a, 0xd6, 0x9a, 0xd3, 0x5c, 0x6d, 0xbc, 0xba, 0x64, 0xa3, 0x35, 0x85, - 0x6d, 0xd8, 0xcf, 0x5f, 0xac, 0xe6, 0xf0, 0x2c, 0x13, 0x7d, 0x00, 0xb6, 0xe0, 0x01, 0x75, 0x17, - 0x6a, 0xd6, 0xda, 0xb9, 0xe6, 0xb5, 0x2c, 0x05, 0xb5, 0x28, 0xe6, 0x01, 0xc5, 0x1a, 0x89, 0x36, - 0x01, 0x86, 0x74, 0xb8, 0x47, 0x45, 0x7c, 0xc0, 0x22, 0x77, 0x51, 0xf3, 0xde, 0x39, 0x8b, 0xa7, - 0x92, 0x6d, 0x6c, 0x4f, 0xe0, 0x78, 0x86, 0x8a, 0xb6, 0xa1, 0x44, 0x46, 0x84, 0x05, 0x64, 0x8f, - 0x05, 0x4c, 0x1e, 0xb9, 0xb6, 0x96, 0x7a, 0xf7, 0xb5, 0x52, 0xad, 0x19, 0x02, 0x9e, 0xa3, 0xd7, - 0x7d, 0x80, 0xe9, 0x42, 0xe8, 0x26, 0x2c, 0xf7, 0xba, 0x3b, 0x9d, 0xad, 0x9d, 0xcd, 0x72, 0xae, - 0x72, 0xe5, 0xf8, 0xa4, 0xf6, 0x1f, 0xa5, 0x31, 0x05, 0xf4, 0x68, 0xe8, 0xb3, 0x70, 0x80, 0xd6, - 0xa0, 0xd0, 0x6a, 0xb7, 0xbb, 0xbd, 0x47, 0xdd, 0x4e, 0xd9, 0xaa, 0x54, 0x8e, 0x4f, 0x6a, 0x97, - 0xe6, 0x81, 0x2d, 0xcf, 0xa3, 0x91, 0xa4, 0x7e, 0xc5, 0x7e, 0xf6, 0x63, 0x35, 0x57, 0x7f, 0x66, - 0x41, 0x69, 0x36, 0x09, 0x74, 0x13, 0xf2, 0xad, 0xf6, 0xa3, 0xad, 0x27, 0xdd, 0x72, 0x6e, 0x4a, - 0x9f, 0x45, 0xb4, 0x3c, 0xc9, 0x46, 0x14, 0xdd, 0x80, 0xa5, 0x5e, 0xeb, 0xf1, 0x6e, 0xb7, 0x6c, - 0x4d, 0xd3, 0x99, 0x85, 0xf5, 0x48, 0x12, 0x6b, 0x54, 0x07, 0xb7, 0xb6, 0x76, 0xca, 0x0b, 0xd9, - 0xa8, 0x8e, 0x20, 0x2c, 0x34, 0xa9, 0xfc, 0x62, 0x83, 0xb3, 0x4b, 0xc5, 0x88, 0x79, 0x6f, 0xd9, - 0x13, 0xb7, 0xc0, 0x96, 0x24, 0x3e, 0xd4, 0x9e, 0x70, 0xb2, 0x3d, 0xf1, 0x88, 0xc4, 0x87, 0x6a, - 0x51, 0x43, 0xd7, 0x78, 0xe5, 0x0c, 0x41, 0xa3, 0x80, 0x79, 0x44, 0x52, 0x5f, 0x3b, 0xc3, 0x69, - 0xfe, 0x3f, 0x8b, 0x8d, 0x27, 0x28, 0x93, 0xff, 0xfd, 0x1c, 0x9e, 0xa1, 0xa2, 0x7b, 0x90, 0x1f, - 0x04, 0x7c, 0x8f, 0x04, 0xda, 0x13, 0x4e, 0xf3, 0x7a, 0x96, 0xc8, 0xa6, 0x46, 0x4c, 0x05, 0x0c, - 0x05, 0xdd, 0x81, 0x7c, 0x12, 0xf9, 0x44, 0x52, 0x37, 0xaf, 0xc9, 0xb5, 0x2c, 0xf2, 0x63, 0x8d, - 0x68, 0xf3, 0x70, 0x9f, 0x0d, 0xb0, 0xc1, 0xa3, 0x5d, 0x28, 0x84, 0x54, 0x3e, 0xe5, 0xe2, 0x30, - 0x76, 0x97, 0x6b, 0x8b, 0x6b, 0x4e, 0xf3, 0x76, 0x16, 0x77, 0xa6, 0xe6, 0x8d, 0x9d, 0x14, 0xdf, - 0x92, 0x92, 0x78, 0x07, 0x43, 0x1a, 0x4a, 0x23, 0x39, 0x11, 0x42, 0x9f, 0x42, 0x81, 0x86, 0x7e, - 0xc4, 0x59, 0x28, 0xdd, 0xc2, 0xd9, 0x09, 0x75, 0x0d, 0x46, 0xa9, 0xe2, 0x09, 0xa3, 0xf2, 0x00, - 0x2e, 0x9f, 0xb1, 0x04, 0xba, 0x04, 0x79, 0x49, 0xc4, 0x80, 0x4a, 0xbd, 0xd3, 0x45, 0x6c, 0x66, - 0xc8, 0x85, 0x65, 0x12, 0x30, 0x12, 0xd3, 0xd8, 0x5d, 0xa8, 0x2d, 0xae, 0x15, 0xf1, 0x78, 0xba, - 0x91, 0x07, 0x7b, 0xc8, 0x7d, 0x5a, 0x5f, 0x87, 0x0b, 0xaf, 0xec, 0x00, 0xaa, 0x40, 0xc1, 0xec, - 0x40, 0x6a, 0x1d, 0x1b, 0x4f, 0xe6, 0xf5, 0xf3, 0xb0, 0x32, 0x57, 0xed, 0xfa, 0x6f, 0x0b, 0x50, - 0x18, 0x5b, 0x00, 0xb5, 0xa0, 0xe8, 0xf1, 0x50, 0x12, 0x16, 0x52, 0x61, 0x5c, 0x97, 0xb9, 0x61, - 0xed, 0x31, 0x48, 0xb1, 0xee, 0xe7, 0xf0, 0x94, 0x85, 0xbe, 0x84, 0xa2, 0xa0, 0x31, 0x4f, 0x84, - 0xa7, 0xb3, 0x56, 0x12, 0x6b, 0xd9, 0xc6, 0x49, 0x41, 0x98, 0x7e, 0x9b, 0x30, 0x41, 0x55, 0x35, - 0x62, 0x3c, 0xa5, 0xa2, 0x7b, 0xb0, 0x2c, 0x68, 0x2c, 0x89, 0x90, 0xaf, 0x73, 0x0e, 0x4e, 0x21, - 0x3d, 0x1e, 0x30, 0xef, 0x08, 0x8f, 0x19, 0xe8, 0x1e, 0x14, 0xa3, 0x80, 0x78, 0x5a, 0xd5, 0x5d, - 0xd2, 0xf4, 0xff, 0x66, 0xd1, 0x7b, 0x63, 0x10, 0x9e, 0xe2, 0xd1, 0x5d, 0x80, 0x80, 0x0f, 0xfa, - 0xbe, 0x60, 0x23, 0x2a, 0x8c, 0xf3, 0x2a, 0x59, 0xec, 0x8e, 0x46, 0xe0, 0x62, 0xc0, 0x07, 0xe9, - 0x70, 0xa3, 0x08, 0xcb, 0x22, 0x09, 0x25, 0x1b, 0xd2, 0xfa, 0xcf, 0x36, 0xac, 0xcc, 0x95, 0x09, - 0x5d, 0x84, 0x25, 0x36, 0x24, 0x03, 0x6a, 0x36, 0x39, 0x9d, 0xa0, 0x2e, 0xe4, 0x03, 0xb2, 0x47, - 0x83, 0x74, 0x8b, 0x9d, 0xe6, 0xfb, 0x6f, 0xac, 0x77, 0xe3, 0x6b, 0x8d, 0xef, 0x86, 0x52, 0x1c, - 0x61, 0x43, 0x56, 0x56, 0xf1, 0xf8, 0x70, 0x48, 0x42, 0x75, 0x5a, 0xb5, 0x55, 0xcc, 0x14, 0x21, - 0xb0, 0x89, 0x18, 0xc4, 0xae, 0xad, 0xc3, 0x7a, 0x8c, 0xca, 0xb0, 0x48, 0xc3, 0x91, 0xbb, 0xa4, - 0x43, 0x6a, 0xa8, 0x22, 0x3e, 0x4b, 0xbf, 0xb6, 0x88, 0xd5, 0x50, 0xf1, 0x92, 0x98, 0x0a, 0x77, - 0x59, 0x87, 0xf4, 0x18, 0xdd, 0x86, 0xfc, 0x90, 0x27, 0xa1, 0x8c, 0xdd, 0x82, 0x4e, 0xf6, 0x4a, - 0x56, 0xb2, 0xdb, 0x0a, 0x61, 0xba, 0x89, 0x81, 0xa3, 0xfb, 0x70, 0x21, 0x96, 0x3c, 0xea, 0x0f, - 0x04, 0xf1, 0x68, 0x3f, 0xa2, 0x82, 0x71, 0xdf, 0x2d, 0x9e, 0xdd, 0x94, 0x3a, 0xe6, 0xc2, 0xc4, - 0xe7, 0x15, 0x6d, 0x53, 0xb1, 0x7a, 0x9a, 0x84, 0x7a, 0x50, 0x8a, 0x92, 0x20, 0xe8, 0xf3, 0x28, - 0xed, 0x8d, 0xa0, 0x45, 0xfe, 0x45, 0xd5, 0x7a, 0x49, 0x10, 0x3c, 0x4c, 0x49, 0xd8, 0x89, 0xa6, - 0x13, 0x75, 0xfa, 0x06, 0x82, 0x27, 0x51, 0xec, 0x3a, 0xba, 0x1e, 0x66, 0x56, 0xb9, 0x0b, 0xce, - 0x4c, 0xa5, 0x55, 0x85, 0x0e, 0xe9, 0x91, 0xd9, 0x3c, 0x35, 0x54, 0x1b, 0x3a, 0x22, 0x41, 0x92, - 0xde, 0xb8, 0x45, 0x9c, 0x4e, 0x3e, 0x59, 0xb8, 0x63, 0x55, 0x9a, 0xe0, 0xcc, 0x2c, 0x87, 0xfe, - 0x07, 0x2b, 0x82, 0x0e, 0x58, 0x2c, 0xc5, 0x51, 0x9f, 0x24, 0xf2, 0xc0, 0xfd, 0x42, 0x13, 0x4a, - 0xe3, 0x60, 0x2b, 0x91, 0x07, 0xf5, 0xbf, 0x2c, 0x28, 0xcd, 0xb6, 0x0e, 0xd4, 0x4e, 0xcf, 0xb8, - 0x5e, 0xf1, 0x5c, 0x73, 0xfd, 0x4d, 0xad, 0x46, 0x9f, 0xa8, 0x20, 0x51, 0x2b, 0x6e, 0xab, 0x6b, - 0x5e, 0x93, 0xd1, 0xc7, 0xb0, 0x14, 0x71, 0x21, 0xc7, 0xee, 0xaa, 0x66, 0x9e, 0x02, 0x2e, 0xc6, - 0xcd, 0x2e, 0x05, 0xd7, 0x0f, 0xe0, 0xdc, 0xbc, 0x1a, 0xba, 0x01, 0x8b, 0x4f, 0xb6, 0x7a, 0xe5, - 0x5c, 0xe5, 0xea, 0xf1, 0x49, 0xed, 0xf2, 0xfc, 0x8f, 0x4f, 0x98, 0x90, 0x09, 0x09, 0xb6, 0x7a, - 0xe8, 0x3d, 0x58, 0xea, 0xec, 0xec, 0x62, 0x5c, 0xb6, 0x2a, 0xab, 0xc7, 0x27, 0xb5, 0xab, 0xf3, - 0x38, 0xf5, 0x13, 0x4f, 0x42, 0x1f, 0xf3, 0xbd, 0xc9, 0xcd, 0xf7, 0xc3, 0x02, 0x38, 0xa6, 0x2d, - 0xbe, 0xdd, 0x9b, 0xef, 0x73, 0x58, 0x49, 0x4f, 0x70, 0xdf, 0xd3, 0x9f, 0x66, 0x7a, 0xd1, 0xeb, - 0x0e, 0x72, 0x29, 0x25, 0x98, 0xa6, 0x7c, 0x1d, 0x4a, 0x2c, 0x1a, 0xdd, 0xea, 0xd3, 0x90, 0xec, - 0x05, 0xe6, 0x12, 0x2c, 0x60, 0x47, 0xc5, 0xba, 0x69, 0x48, 0x35, 0x5a, 0x16, 0x4a, 0x2a, 0x42, - 0x73, 0xbd, 0x15, 0xf0, 0x64, 0x8e, 0x3e, 0x03, 0x9b, 0x45, 0x64, 0x68, 0xba, 0x4f, 0xe6, 0x17, - 0x6c, 0xf5, 0x5a, 0xdb, 0xc6, 0x22, 0x1b, 0x85, 0xd3, 0x17, 0xab, 0xb6, 0x0a, 0x60, 0x4d, 0xab, - 0xff, 0x64, 0x83, 0xd3, 0x0e, 0x92, 0x58, 0x9a, 0xe6, 0xf1, 0xd6, 0xea, 0xf2, 0x0d, 0x5c, 0x20, - 0xfa, 0x1d, 0x44, 0x42, 0x75, 0x12, 0x75, 0xe3, 0x34, 0xb5, 0xb9, 0x91, 0x29, 0x37, 0x01, 0xa7, - 0x4d, 0x76, 0x23, 0xaf, 0x34, 0x5d, 0x0b, 0x97, 0xc9, 0x3f, 0x7e, 0x41, 0xbb, 0xb0, 0xc2, 0x85, - 0x77, 0x40, 0x63, 0x99, 0x1e, 0x5e, 0xf3, 0x6e, 0xc8, 0x7c, 0x51, 0x3e, 0x9c, 0x05, 0xa6, 0x15, - 0x37, 0xd9, 0xce, 0x6b, 0xa0, 0x3b, 0x60, 0x0b, 0xb2, 0x3f, 0xbe, 0x04, 0x32, 0xfd, 0x8b, 0xc9, - 0xbe, 0x9c, 0x93, 0xd0, 0x0c, 0xf4, 0x15, 0x80, 0xcf, 0xe2, 0x88, 0x48, 0xef, 0x80, 0x0a, 0xb3, - 0x0f, 0x99, 0x9f, 0xd8, 0x99, 0xa0, 0xe6, 0x54, 0x66, 0xd8, 0xe8, 0x01, 0x14, 0x3d, 0x32, 0x76, - 0x52, 0xfe, 0xec, 0xbe, 0xd5, 0x6e, 0x19, 0x89, 0xb2, 0x92, 0x38, 0x7d, 0xb1, 0x5a, 0x18, 0x47, - 0x70, 0xc1, 0x23, 0xc6, 0x59, 0x0f, 0x60, 0x45, 0x3d, 0xb2, 0xfa, 0x3e, 0xdd, 0x27, 0x49, 0x20, - 0x63, 0xdd, 0x62, 0xcf, 0x78, 0x4c, 0xa8, 0xab, 0xb9, 0x63, 0x70, 0x26, 0xaf, 0x92, 0x9c, 0x8d, - 0x5d, 0x7b, 0xfe, 0xb2, 0x9a, 0xfb, 0xfd, 0x65, 0x35, 0xf7, 0xe7, 0xcb, 0xaa, 0xf5, 0xdd, 0x69, - 0xd5, 0x7a, 0x7e, 0x5a, 0xb5, 0x7e, 0x3d, 0xad, 0x5a, 0x7f, 0x9c, 0x56, 0xad, 0xbd, 0xbc, 0xfe, - 0xc3, 0xf1, 0xd1, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa4, 0x46, 0x7c, 0xf6, 0xcf, 0x0c, 0x00, - 0x00, + // 1397 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0xdb, 0xc6, + 0x12, 0x17, 0x6d, 0x5a, 0x96, 0x86, 0x72, 0xa2, 0x2c, 0xf2, 0x87, 0x51, 0xf2, 0x64, 0x45, 0x2f, + 0x2f, 0xcf, 0x79, 0x0f, 0xb5, 0x5b, 0xb5, 0x48, 0x93, 0xa6, 0x45, 0x2b, 0x4b, 0xaa, 0xa3, 0xba, + 0x76, 0x84, 0x75, 0x12, 0xa0, 0x27, 0x61, 0x4d, 0xae, 0x65, 0xc2, 0x14, 0x97, 0x5d, 0x2e, 0x15, + 0xf8, 0xd6, 0x63, 0xe0, 0x43, 0xbf, 0x81, 0x4f, 0x05, 0x7a, 0xec, 0xad, 0xdf, 0x21, 0xc7, 0x1e, + 0x7b, 0x32, 0x6a, 0x5f, 0x7b, 0x29, 0xd0, 0x2f, 0x50, 0xec, 0x72, 0x25, 0x51, 0x0d, 0x9d, 0x04, + 0x68, 0x6e, 0xbb, 0xc3, 0xdf, 0x6f, 0x76, 0x34, 0xf3, 0xdb, 0x99, 0x15, 0x58, 0x51, 0x48, 0x9d, + 0x68, 0x35, 0xe4, 0x4c, 0x30, 0x84, 0x5c, 0xe6, 0x1c, 0x50, 0xbe, 0x1a, 0x3d, 0x27, 0x7c, 0x78, + 0xe0, 0x89, 0xd5, 0xd1, 0x07, 0x15, 0x4b, 0x1c, 0x86, 0x54, 0x03, 0x2a, 0x97, 0x07, 0x6c, 0xc0, + 0xd4, 0x72, 0x4d, 0xae, 0xb4, 0xf5, 0x9a, 0x1b, 0x73, 0x22, 0x3c, 0x16, 0xac, 0x8d, 0x17, 0xc9, + 0x87, 0xfa, 0xf7, 0x26, 0x14, 0xb6, 0x99, 0x4b, 0x77, 0x42, 0xea, 0xa0, 0x0d, 0xb0, 0x48, 0x10, + 0x30, 0xa1, 0x00, 0x91, 0x6d, 0xd4, 0x8c, 0x15, 0xab, 0xb1, 0xbc, 0xfa, 0xea, 0x91, 0xab, 0xcd, + 0x29, 0x6c, 0xdd, 0x7c, 0x79, 0xb2, 0x9c, 0xc3, 0x69, 0x26, 0x7a, 0x1f, 0x4c, 0xce, 0x7c, 0x6a, + 0xcf, 0xd5, 0x8c, 0x95, 0x0b, 0x8d, 0x9b, 0x59, 0x1e, 0xe4, 0xa1, 0x98, 0xf9, 0x14, 0x2b, 0x24, + 0xda, 0x00, 0x18, 0xd2, 0xe1, 0x2e, 0xe5, 0xd1, 0xbe, 0x17, 0xda, 0xf3, 0x8a, 0xf7, 0xdf, 0xf3, + 0x78, 0x32, 0xd8, 0xd5, 0xad, 0x09, 0x1c, 0xa7, 0xa8, 0x68, 0x0b, 0x4a, 0x64, 0x44, 0x3c, 0x9f, + 0xec, 0x7a, 0xbe, 0x27, 0x0e, 0x6d, 0x53, 0xb9, 0xba, 0xfb, 0x5a, 0x57, 0xcd, 0x14, 0x01, 0xcf, + 0xd0, 0xeb, 0x2e, 0xc0, 0xf4, 0x20, 0x74, 0x07, 0x16, 0x7b, 0x9d, 0xed, 0x76, 0x77, 0x7b, 0xa3, + 0x9c, 0xab, 0x5c, 0x3f, 0x3a, 0xae, 0x5d, 0x91, 0x3e, 0xa6, 0x80, 0x1e, 0x0d, 0x5c, 0x2f, 0x18, + 0xa0, 0x15, 0x28, 0x34, 0x5b, 0xad, 0x4e, 0xef, 0x49, 0xa7, 0x5d, 0x36, 0x2a, 0x95, 0xa3, 0xe3, + 0xda, 0xd5, 0x59, 0x60, 0xd3, 0x71, 0x68, 0x28, 0xa8, 0x5b, 0x31, 0x5f, 0xfc, 0x50, 0xcd, 0xd5, + 0x5f, 0x18, 0x50, 0x4a, 0x07, 0x81, 0xee, 0x40, 0xbe, 0xd9, 0x7a, 0xd2, 0x7d, 0xd6, 0x29, 0xe7, + 0xa6, 0xf4, 0x34, 0xa2, 0xe9, 0x08, 0x6f, 0x44, 0xd1, 0x6d, 0x58, 0xe8, 0x35, 0x9f, 0xee, 0x74, + 0xca, 0xc6, 0x34, 0x9c, 0x34, 0xac, 0x47, 0xe2, 0x48, 0xa1, 0xda, 0xb8, 0xd9, 0xdd, 0x2e, 0xcf, + 0x65, 0xa3, 0xda, 0x9c, 0x78, 0x81, 0x0e, 0xe5, 0x74, 0x1e, 0xac, 0x1d, 0xca, 0x47, 0x9e, 0xf3, + 0x8e, 0x35, 0x71, 0x0f, 0x4c, 0x41, 0xa2, 0x03, 0xa5, 0x09, 0x2b, 0x5b, 0x13, 0x4f, 0x48, 0x74, + 0x20, 0x0f, 0xd5, 0x74, 0x85, 0x97, 0xca, 0xe0, 0x34, 0xf4, 0x3d, 0x87, 0x08, 0xea, 0x2a, 0x65, + 0x58, 0x8d, 0xff, 0x64, 0xb1, 0xf1, 0x04, 0xa5, 0xe3, 0x7f, 0x94, 0xc3, 0x29, 0x2a, 0x7a, 0x08, + 0xf9, 0x81, 0xcf, 0x76, 0x89, 0xaf, 0x34, 0x61, 0x35, 0x6e, 0x65, 0x39, 0xd9, 0x50, 0x88, 0xa9, + 0x03, 0x4d, 0x41, 0xf7, 0x21, 0x1f, 0x87, 0x2e, 0x11, 0xd4, 0xce, 0x2b, 0x72, 0x2d, 0x8b, 0xfc, + 0x54, 0x21, 0x5a, 0x2c, 0xd8, 0xf3, 0x06, 0x58, 0xe3, 0xd1, 0x26, 0x14, 0x02, 0x2a, 0x9e, 0x33, + 0x7e, 0x10, 0xd9, 0x8b, 0xb5, 0xf9, 0x15, 0xab, 0xf1, 0xff, 0x4c, 0x31, 0x26, 0x98, 0xa6, 0x10, + 0xc4, 0xd9, 0x1f, 0xd2, 0x40, 0x24, 0x6e, 0xd6, 0xe7, 0x6c, 0x03, 0x4f, 0x1c, 0xa0, 0x4f, 0xa1, + 0x40, 0x03, 0x37, 0x64, 0x5e, 0x20, 0xec, 0xc2, 0xf9, 0x81, 0x74, 0x34, 0x46, 0x26, 0x13, 0x4f, + 0x18, 0xeb, 0x79, 0x30, 0x87, 0xcc, 0xa5, 0xf5, 0x35, 0xb8, 0xf4, 0x4a, 0xb2, 0x50, 0x05, 0x0a, + 0x3a, 0x59, 0x49, 0x95, 0x4d, 0x3c, 0xd9, 0xd7, 0x2f, 0xc2, 0xd2, 0x4c, 0x62, 0xea, 0xbf, 0xcf, + 0x43, 0x61, 0x5c, 0x2d, 0xd4, 0x84, 0xa2, 0xc3, 0x02, 0x41, 0xbc, 0x80, 0x72, 0x2d, 0x90, 0xcc, + 0xdc, 0xb6, 0xc6, 0x20, 0xc9, 0x7a, 0x94, 0xc3, 0x53, 0x16, 0xfa, 0x12, 0x8a, 0x9c, 0x46, 0x2c, + 0xe6, 0x0e, 0x8d, 0xb4, 0x42, 0x56, 0xb2, 0x6b, 0x9c, 0x80, 0x30, 0xfd, 0x36, 0xf6, 0x38, 0x95, + 0x79, 0x8a, 0xf0, 0x94, 0x8a, 0x1e, 0xc2, 0x22, 0xa7, 0x91, 0x20, 0x5c, 0xbc, 0xae, 0xc8, 0x38, + 0x81, 0xf4, 0x98, 0xef, 0x39, 0x87, 0x78, 0xcc, 0x40, 0x0f, 0xa1, 0x18, 0xfa, 0xc4, 0x51, 0x5e, + 0xed, 0x05, 0x45, 0xff, 0x57, 0x16, 0xbd, 0x37, 0x06, 0xe1, 0x29, 0x1e, 0x3d, 0x00, 0xf0, 0xd9, + 0xa0, 0xef, 0x72, 0x6f, 0x44, 0xb9, 0x16, 0x49, 0x25, 0x8b, 0xdd, 0x56, 0x08, 0x5c, 0xf4, 0xd9, + 0x20, 0x59, 0xa2, 0x8d, 0x7f, 0xa4, 0x90, 0x94, 0x3a, 0x36, 0x01, 0xc8, 0xe4, 0xab, 0xd6, 0xc7, + 0xdd, 0xb7, 0x72, 0xa5, 0x2b, 0x92, 0xa2, 0xaf, 0x17, 0x61, 0x91, 0xc7, 0x81, 0xf0, 0x86, 0xb4, + 0xbe, 0x09, 0x57, 0x32, 0x19, 0xa8, 0x01, 0xa5, 0x49, 0x0d, 0xfb, 0x9e, 0xab, 0x8a, 0x5f, 0x5c, + 0xbf, 0x78, 0x76, 0xb2, 0x6c, 0x4d, 0x8a, 0xdd, 0x6d, 0x63, 0x6b, 0x02, 0xea, 0xba, 0xf5, 0x9f, + 0x4c, 0x58, 0x9a, 0x51, 0x02, 0xba, 0x0c, 0x0b, 0xde, 0x90, 0x0c, 0x68, 0x42, 0xc7, 0xc9, 0x06, + 0x75, 0x20, 0xef, 0x93, 0x5d, 0xea, 0x4b, 0x3d, 0xc8, 0x9c, 0xbc, 0xf7, 0x46, 0x49, 0xad, 0x7e, + 0xad, 0xf0, 0x9d, 0x40, 0xf0, 0x43, 0xac, 0xc9, 0xc8, 0x86, 0x45, 0x87, 0x0d, 0x87, 0x24, 0x90, + 0xbd, 0x63, 0x7e, 0xa5, 0x88, 0xc7, 0x5b, 0x84, 0xc0, 0x24, 0x7c, 0x10, 0xd9, 0xa6, 0x32, 0xab, + 0x35, 0x2a, 0xc3, 0x3c, 0x0d, 0x46, 0xf6, 0x82, 0x32, 0xc9, 0xa5, 0xb4, 0xb8, 0x5e, 0x52, 0xd0, + 0x22, 0x96, 0x4b, 0xc9, 0x8b, 0x23, 0xca, 0xed, 0x45, 0x65, 0x52, 0x6b, 0xf4, 0x31, 0xe4, 0x87, + 0x2c, 0x0e, 0x44, 0x64, 0x17, 0x54, 0xb0, 0xd7, 0xb3, 0x82, 0xdd, 0x92, 0x08, 0xdd, 0xdb, 0x34, + 0x1c, 0x3d, 0x82, 0x4b, 0x91, 0x60, 0x61, 0x7f, 0xc0, 0x89, 0x43, 0xfb, 0x21, 0xe5, 0x1e, 0x73, + 0xed, 0xe2, 0xf9, 0x2d, 0xb2, 0xad, 0xc7, 0x37, 0xbe, 0x28, 0x69, 0x1b, 0x92, 0xd5, 0x53, 0x24, + 0xd4, 0x83, 0x52, 0x18, 0xfb, 0x7e, 0x9f, 0x85, 0x49, 0xa7, 0x06, 0xe5, 0xe4, 0x2d, 0xb2, 0xd6, + 0x8b, 0x7d, 0xff, 0x71, 0x42, 0xc2, 0x56, 0x38, 0xdd, 0xa0, 0xab, 0x90, 0x1f, 0x70, 0x16, 0x87, + 0x91, 0x6d, 0xa9, 0x7c, 0xe8, 0x5d, 0xe5, 0x01, 0x58, 0xa9, 0x4c, 0xcb, 0x0c, 0x1d, 0xd0, 0x43, + 0x5d, 0x3c, 0xb9, 0x94, 0x05, 0x1d, 0x11, 0x3f, 0x4e, 0xe6, 0x7f, 0x11, 0x27, 0x9b, 0x4f, 0xe6, + 0xee, 0x1b, 0x95, 0x06, 0x58, 0xa9, 0xe3, 0xd0, 0xbf, 0x61, 0x89, 0xd3, 0x81, 0x17, 0x09, 0x7e, + 0xd8, 0x27, 0xb1, 0xd8, 0xb7, 0xbf, 0x50, 0x84, 0xd2, 0xd8, 0xd8, 0x8c, 0xc5, 0x7e, 0xfd, 0x4f, + 0x03, 0x4a, 0xe9, 0x86, 0x86, 0x5a, 0x49, 0x1b, 0x53, 0x27, 0x5e, 0x68, 0xac, 0xbd, 0xa9, 0x01, + 0xaa, 0xa6, 0xe1, 0xc7, 0xf2, 0xc4, 0x2d, 0xf9, 0xe8, 0x50, 0x64, 0xf4, 0x11, 0x2c, 0x84, 0x8c, + 0x8b, 0xb1, 0xba, 0xaa, 0x99, 0x17, 0x9d, 0xf1, 0xf1, 0x25, 0x4b, 0xc0, 0xf5, 0x7d, 0xb8, 0x30, + 0xeb, 0x0d, 0xdd, 0x86, 0xf9, 0x67, 0xdd, 0x5e, 0x39, 0x57, 0xb9, 0x71, 0x74, 0x5c, 0xbb, 0x36, + 0xfb, 0xf1, 0x99, 0xc7, 0x45, 0x4c, 0xfc, 0x6e, 0x0f, 0xfd, 0x0f, 0x16, 0xda, 0xdb, 0x3b, 0x18, + 0x97, 0x8d, 0xca, 0xf2, 0xd1, 0x71, 0xed, 0xc6, 0x2c, 0x4e, 0x7e, 0x62, 0x71, 0xe0, 0x62, 0xb6, + 0x3b, 0x99, 0xc3, 0x3f, 0xcf, 0x81, 0xa5, 0x2f, 0xdd, 0xbb, 0x9d, 0xc3, 0x9f, 0xc3, 0x52, 0xd2, + 0xa4, 0xfa, 0x8e, 0xfa, 0x69, 0xba, 0xdd, 0xbe, 0xae, 0x57, 0x95, 0x12, 0x42, 0x92, 0x0a, 0x74, + 0x0b, 0x4a, 0x5e, 0x38, 0xba, 0xd7, 0xa7, 0x01, 0xd9, 0xf5, 0xf5, 0x48, 0x2e, 0x60, 0x4b, 0xda, + 0x3a, 0x89, 0x49, 0xce, 0x12, 0x2f, 0x10, 0x94, 0x07, 0x7a, 0xd8, 0x16, 0xf0, 0x64, 0x8f, 0x3e, + 0x03, 0xd3, 0x0b, 0xc9, 0x50, 0x37, 0xd8, 0xcc, 0x5f, 0xd0, 0xed, 0x35, 0xb7, 0xb4, 0x44, 0xd6, + 0x0b, 0x67, 0x27, 0xcb, 0xa6, 0x34, 0x60, 0x45, 0x43, 0xd5, 0x71, 0x8f, 0x93, 0x27, 0xa9, 0x6b, + 0x59, 0xc0, 0x29, 0x4b, 0xfd, 0x47, 0x13, 0xac, 0x96, 0x1f, 0x47, 0x42, 0x37, 0x97, 0x77, 0x96, + 0xb7, 0x6f, 0xe0, 0x12, 0x51, 0xaf, 0x36, 0x12, 0xc8, 0x9b, 0xaa, 0x66, 0x87, 0xce, 0xdd, 0xed, + 0x4c, 0x77, 0x13, 0x70, 0x32, 0x67, 0xd6, 0xf3, 0xd2, 0xa7, 0x6d, 0xe0, 0x32, 0xf9, 0xdb, 0x17, + 0xb4, 0x03, 0x4b, 0x8c, 0x3b, 0xfb, 0x34, 0x12, 0xc9, 0xe5, 0xd6, 0xaf, 0x9c, 0xcc, 0xf7, 0xef, + 0xe3, 0x34, 0x50, 0xbf, 0x11, 0x92, 0x68, 0x67, 0x7d, 0xa0, 0xfb, 0x60, 0x72, 0xb2, 0x37, 0x9e, + 0x83, 0x99, 0xfa, 0xc6, 0x64, 0x4f, 0xcc, 0xb8, 0x50, 0x0c, 0xf4, 0x15, 0x80, 0xeb, 0x45, 0x21, + 0x11, 0xce, 0x3e, 0xe5, 0xba, 0x4e, 0x99, 0x3f, 0xb1, 0x3d, 0x41, 0xcd, 0x78, 0x49, 0xb1, 0xd1, + 0x26, 0x14, 0x1d, 0x32, 0x56, 0x5a, 0xfe, 0xfc, 0xbe, 0xd6, 0x6a, 0x6a, 0x17, 0x65, 0xe9, 0xe2, + 0xec, 0x64, 0xb9, 0x30, 0xb6, 0xe0, 0x82, 0x43, 0xb4, 0xf2, 0x36, 0x61, 0x49, 0x3e, 0x09, 0xfb, + 0x2e, 0xdd, 0x23, 0xb1, 0x2f, 0x22, 0xd5, 0x82, 0xcf, 0x79, 0x02, 0xc9, 0xd7, 0x49, 0x5b, 0xe3, + 0x74, 0x5c, 0x25, 0x91, 0xb6, 0xdd, 0x7c, 0x79, 0x5a, 0xcd, 0xfd, 0x7a, 0x5a, 0xcd, 0xfd, 0x71, + 0x5a, 0x35, 0xbe, 0x3b, 0xab, 0x1a, 0x2f, 0xcf, 0xaa, 0xc6, 0x2f, 0x67, 0x55, 0xe3, 0xb7, 0xb3, + 0xaa, 0xb1, 0x9b, 0x57, 0x7f, 0x8f, 0x3e, 0xfc, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x70, 0x4c, 0x36, + 0xfc, 0x7d, 0x0d, 0x00, 0x00, } diff --git a/vendor/src/github.com/docker/swarmkit/api/specs.proto b/vendor/src/github.com/docker/swarmkit/api/specs.proto index 73d3fe4279..9f51ec5979 100644 --- a/vendor/src/github.com/docker/swarmkit/api/specs.proto +++ b/vendor/src/github.com/docker/swarmkit/api/specs.proto @@ -72,19 +72,7 @@ message ServiceSpec { // UpdateConfig controls the rate and policy of updates. UpdateConfig update = 6; - // NetworkAttachmentConfig specifies how a service should be attached to a particular network. - // - // For now, this is a simple struct, but this can include future information - // instructing Swarm on how this service should work on the particular - // network. - message NetworkAttachmentConfig { - // Target specifies the target network for attachment. This value may be a - // network name or identifier. Only identifiers are supported at this time. - string target = 1; - // Aliases specifies a list of discoverable alternate names for the service on this Target. - repeated string aliases = 2; - } - repeated NetworkAttachmentConfig networks = 7; + repeated NetworkAttachmentConfig networks = 7 [deprecated=true]; // Service endpoint specifies the user provided configuration // to properly discover and load balance a service. @@ -103,6 +91,7 @@ message GlobalService { message TaskSpec { oneof runtime { + NetworkAttachmentSpec attachment = 8; ContainerSpec container = 1; } @@ -118,6 +107,19 @@ message TaskSpec { // LogDriver specifies the log driver to use for the task. Any runtime will // direct logs into the specified driver for the duration of the task. Driver log_driver = 6; + + // Networks specifies the list of network attachment + // configurations (which specify the network and per-network + // aliases) that this task spec is bound to. + repeated NetworkAttachmentConfig networks = 7; +} + +// NetworkAttachmentSpec specifies runtime parameters required to attach +// a container to a network. +message NetworkAttachmentSpec { + // ContainerID spcifies a unique ID of the container for which + // this attachment is for. + string container_id = 1 [(gogoproto.customname) = "ContainerID"]; } // Container specifies runtime parameters for a container. @@ -234,6 +236,15 @@ message NetworkSpec { bool internal = 4; IPAMOptions ipam = 5 [(gogoproto.customname) = "IPAM"]; + + // Attachable allows external(to swarm) entities to manually + // attach to this network. With this flag enabled, external + // entities such as containers running in an worker node in + // the cluster can manually attach to this network and access + // the services attached to this network. If this flag is not + // enabled(default case) no manual attachment to this network + // can happen. + bool attachable = 6; } // ClusterSpec specifies global cluster settings. diff --git a/vendor/src/github.com/docker/swarmkit/api/types.pb.go b/vendor/src/github.com/docker/swarmkit/api/types.pb.go index 5a8288a0b3..dbd8286cdc 100644 --- a/vendor/src/github.com/docker/swarmkit/api/types.pb.go +++ b/vendor/src/github.com/docker/swarmkit/api/types.pb.go @@ -15,6 +15,7 @@ snapshot.proto raft.proto health.proto + resource.proto It has these top-level messages: Version @@ -34,6 +35,7 @@ UpdateStatus ContainerStatus TaskStatus + NetworkAttachmentConfig IPAMConfig PortConfig Driver @@ -59,6 +61,7 @@ ReplicatedService GlobalService TaskSpec + NetworkAttachmentSpec ContainerSpec EndpointSpec NetworkSpec @@ -140,6 +143,10 @@ StoreAction HealthCheckRequest HealthCheckResponse + AttachNetworkRequest + AttachNetworkResponse + DetachNetworkRequest + DetachNetworkResponse */ package api @@ -473,7 +480,7 @@ func (x IPAMConfig_AddressFamily) String() string { return proto.EnumName(IPAMConfig_AddressFamily_name, int32(x)) } func (IPAMConfig_AddressFamily) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{17, 0} + return fileDescriptorTypes, []int{18, 0} } type PortConfig_Protocol int32 @@ -495,7 +502,7 @@ var PortConfig_Protocol_value = map[string]int32{ func (x PortConfig_Protocol) String() string { return proto.EnumName(PortConfig_Protocol_name, int32(x)) } -func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18, 0} } +func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19, 0} } type IssuanceStatus_State int32 @@ -525,7 +532,7 @@ var IssuanceStatus_State_value = map[string]int32{ func (x IssuanceStatus_State) String() string { return proto.EnumName(IssuanceStatus_State_name, int32(x)) } -func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23, 0} } +func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24, 0} } type ExternalCA_CAProtocol int32 @@ -544,7 +551,7 @@ func (x ExternalCA_CAProtocol) String() string { return proto.EnumName(ExternalCA_CAProtocol_name, int32(x)) } func (ExternalCA_CAProtocol) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{25, 0} + return fileDescriptorTypes, []int{26, 0} } // Encryption algorithm that can implemented using this key @@ -565,7 +572,7 @@ func (x EncryptionKey_Algorithm) String() string { return proto.EnumName(EncryptionKey_Algorithm_name, int32(x)) } func (EncryptionKey_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{35, 0} + return fileDescriptorTypes, []int{36, 0} } // Version tracks the last time an object in the store was updated. @@ -952,6 +959,27 @@ func _TaskStatus_OneofSizer(msg proto.Message) (n int) { return n } +// NetworkAttachmentConfig specifies how a service should be attached to a particular network. +// +// For now, this is a simple struct, but this can include future information +// instructing Swarm on how this service should work on the particular +// network. +type NetworkAttachmentConfig struct { + // Target specifies the target network for attachment. This value may be a + // network name or identifier. Only identifiers are supported at this time. + Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + // Aliases specifies a list of discoverable alternate names for the service on this Target. + Aliases []string `protobuf:"bytes,2,rep,name=aliases" json:"aliases,omitempty"` + // Addresses specifies a list of ipv4 and ipv6 addresses + // preferred. If these addresses are not available then the + // attachment might fail. + Addresses []string `protobuf:"bytes,3,rep,name=addresses" json:"addresses,omitempty"` +} + +func (m *NetworkAttachmentConfig) Reset() { *m = NetworkAttachmentConfig{} } +func (*NetworkAttachmentConfig) ProtoMessage() {} +func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } + // IPAMConfig specifies parameters for IP Address Management. type IPAMConfig struct { Family IPAMConfig_AddressFamily `protobuf:"varint,1,opt,name=family,proto3,enum=docker.swarmkit.v1.IPAMConfig_AddressFamily" json:"family,omitempty"` @@ -971,7 +999,7 @@ type IPAMConfig struct { func (m *IPAMConfig) Reset() { *m = IPAMConfig{} } func (*IPAMConfig) ProtoMessage() {} -func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } +func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } // PortConfig specifies an exposed port which can be // addressed using the given name. This can be later queried @@ -996,7 +1024,7 @@ type PortConfig struct { func (m *PortConfig) Reset() { *m = PortConfig{} } func (*PortConfig) ProtoMessage() {} -func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } +func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } // Driver is a generic driver type to be used throughout the API. For now, a // driver is simply a name and set of options. The field contents depend on the @@ -1009,7 +1037,7 @@ type Driver struct { func (m *Driver) Reset() { *m = Driver{} } func (*Driver) ProtoMessage() {} -func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } +func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } type IPAMOptions struct { Driver *Driver `protobuf:"bytes,1,opt,name=driver" json:"driver,omitempty"` @@ -1018,7 +1046,7 @@ type IPAMOptions struct { func (m *IPAMOptions) Reset() { *m = IPAMOptions{} } func (*IPAMOptions) ProtoMessage() {} -func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } +func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } // Peer should be used anywhere where we are describing a remote peer. type Peer struct { @@ -1028,7 +1056,7 @@ type Peer struct { func (m *Peer) Reset() { *m = Peer{} } func (*Peer) ProtoMessage() {} -func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } +func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } // WeightedPeer should be used anywhere where we are describing a remote peer // with a weight. @@ -1039,7 +1067,7 @@ type WeightedPeer struct { func (m *WeightedPeer) Reset() { *m = WeightedPeer{} } func (*WeightedPeer) ProtoMessage() {} -func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } +func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } type IssuanceStatus struct { State IssuanceStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.IssuanceStatus_State" json:"state,omitempty"` @@ -1051,7 +1079,7 @@ type IssuanceStatus struct { func (m *IssuanceStatus) Reset() { *m = IssuanceStatus{} } func (*IssuanceStatus) ProtoMessage() {} -func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } +func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } type AcceptancePolicy struct { Policies []*AcceptancePolicy_RoleAdmissionPolicy `protobuf:"bytes,1,rep,name=policies" json:"policies,omitempty"` @@ -1059,7 +1087,7 @@ type AcceptancePolicy struct { func (m *AcceptancePolicy) Reset() { *m = AcceptancePolicy{} } func (*AcceptancePolicy) ProtoMessage() {} -func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } +func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } type AcceptancePolicy_RoleAdmissionPolicy struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1074,7 +1102,7 @@ type AcceptancePolicy_RoleAdmissionPolicy struct { func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset() { *m = AcceptancePolicy_RoleAdmissionPolicy{} } func (*AcceptancePolicy_RoleAdmissionPolicy) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{24, 0} + return fileDescriptorTypes, []int{25, 0} } type AcceptancePolicy_RoleAdmissionPolicy_Secret struct { @@ -1089,7 +1117,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Reset() { } func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{24, 0, 0} + return fileDescriptorTypes, []int{25, 0, 0} } type ExternalCA struct { @@ -1104,7 +1132,7 @@ type ExternalCA struct { func (m *ExternalCA) Reset() { *m = ExternalCA{} } func (*ExternalCA) ProtoMessage() {} -func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } +func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } type CAConfig struct { // NodeCertExpiry is the duration certificates should be issued for @@ -1116,7 +1144,7 @@ type CAConfig struct { func (m *CAConfig) Reset() { *m = CAConfig{} } func (*CAConfig) ProtoMessage() {} -func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } +func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } // OrchestrationConfig defines cluster-level orchestration settings. type OrchestrationConfig struct { @@ -1127,7 +1155,7 @@ type OrchestrationConfig struct { func (m *OrchestrationConfig) Reset() { *m = OrchestrationConfig{} } func (*OrchestrationConfig) ProtoMessage() {} -func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } +func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } // TaskDefaults specifies default values for task creation. type TaskDefaults struct { @@ -1141,7 +1169,7 @@ type TaskDefaults struct { func (m *TaskDefaults) Reset() { *m = TaskDefaults{} } func (*TaskDefaults) ProtoMessage() {} -func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } +func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } // DispatcherConfig defines cluster-level dispatcher settings. type DispatcherConfig struct { @@ -1152,7 +1180,7 @@ type DispatcherConfig struct { func (m *DispatcherConfig) Reset() { *m = DispatcherConfig{} } func (*DispatcherConfig) ProtoMessage() {} -func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } +func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } // RaftConfig defines raft settings for the cluster. type RaftConfig struct { @@ -1174,7 +1202,7 @@ type RaftConfig struct { func (m *RaftConfig) Reset() { *m = RaftConfig{} } func (*RaftConfig) ProtoMessage() {} -func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } +func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } // Placement specifies task distribution constraints. type Placement struct { @@ -1184,7 +1212,7 @@ type Placement struct { func (m *Placement) Reset() { *m = Placement{} } func (*Placement) ProtoMessage() {} -func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } +func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } // JoinToken contains the join tokens for workers and managers. type JoinTokens struct { @@ -1196,7 +1224,7 @@ type JoinTokens struct { func (m *JoinTokens) Reset() { *m = JoinTokens{} } func (*JoinTokens) ProtoMessage() {} -func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } +func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } type RootCA struct { // CAKey is the root CA private key. @@ -1211,7 +1239,7 @@ type RootCA struct { func (m *RootCA) Reset() { *m = RootCA{} } func (*RootCA) ProtoMessage() {} -func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } +func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } type Certificate struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1224,7 +1252,7 @@ type Certificate struct { func (m *Certificate) Reset() { *m = Certificate{} } func (*Certificate) ProtoMessage() {} -func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } +func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } // Symmetric keys to encrypt inter-agent communication. type EncryptionKey struct { @@ -1240,7 +1268,7 @@ type EncryptionKey struct { func (m *EncryptionKey) Reset() { *m = EncryptionKey{} } func (*EncryptionKey) ProtoMessage() {} -func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } +func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } // ManagerStatus provides informations about the state of a manager in the cluster. type ManagerStatus struct { @@ -1257,7 +1285,7 @@ type ManagerStatus struct { func (m *ManagerStatus) Reset() { *m = ManagerStatus{} } func (*ManagerStatus) ProtoMessage() {} -func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } +func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } func init() { proto.RegisterType((*Version)(nil), "docker.swarmkit.v1.Version") @@ -1280,6 +1308,7 @@ func init() { proto.RegisterType((*UpdateStatus)(nil), "docker.swarmkit.v1.UpdateStatus") proto.RegisterType((*ContainerStatus)(nil), "docker.swarmkit.v1.ContainerStatus") proto.RegisterType((*TaskStatus)(nil), "docker.swarmkit.v1.TaskStatus") + proto.RegisterType((*NetworkAttachmentConfig)(nil), "docker.swarmkit.v1.NetworkAttachmentConfig") proto.RegisterType((*IPAMConfig)(nil), "docker.swarmkit.v1.IPAMConfig") proto.RegisterType((*PortConfig)(nil), "docker.swarmkit.v1.PortConfig") proto.RegisterType((*Driver)(nil), "docker.swarmkit.v1.Driver") @@ -1626,6 +1655,32 @@ func (m *TaskStatus) Copy() *TaskStatus { return o } +func (m *NetworkAttachmentConfig) Copy() *NetworkAttachmentConfig { + if m == nil { + return nil + } + + o := &NetworkAttachmentConfig{ + Target: m.Target, + } + + if m.Aliases != nil { + o.Aliases = make([]string, 0, len(m.Aliases)) + for _, v := range m.Aliases { + o.Aliases = append(o.Aliases, v) + } + } + + if m.Addresses != nil { + o.Addresses = make([]string, 0, len(m.Addresses)) + for _, v := range m.Addresses { + o.Addresses = append(o.Addresses, v) + } + } + + return o +} + func (m *IPAMConfig) Copy() *IPAMConfig { if m == nil { return nil @@ -2278,6 +2333,18 @@ func (this *TaskStatus_Container) GoString() string { `Container:` + fmt.Sprintf("%#v", this.Container) + `}`}, ", ") return s } +func (this *NetworkAttachmentConfig) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&api.NetworkAttachmentConfig{") + s = append(s, "Target: "+fmt.Sprintf("%#v", this.Target)+",\n") + s = append(s, "Aliases: "+fmt.Sprintf("%#v", this.Aliases)+",\n") + s = append(s, "Addresses: "+fmt.Sprintf("%#v", this.Addresses)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func (this *IPAMConfig) GoString() string { if this == nil { return "nil" @@ -3416,6 +3483,60 @@ func (m *TaskStatus_Container) MarshalTo(data []byte) (int, error) { } return i, nil } +func (m *NetworkAttachmentConfig) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkAttachmentConfig) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Target) > 0 { + data[i] = 0xa + i++ + i = encodeVarintTypes(data, i, uint64(len(m.Target))) + i += copy(data[i:], m.Target) + } + if len(m.Aliases) > 0 { + for _, s := range m.Aliases { + data[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + data[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + data[i] = uint8(l) + i++ + i += copy(data[i:], s) + } + } + if len(m.Addresses) > 0 { + for _, s := range m.Addresses { + data[i] = 0x1a + i++ + l = len(s) + for l >= 1<<7 { + data[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + data[i] = uint8(l) + i++ + i += copy(data[i:], s) + } + } + return i, nil +} + func (m *IPAMConfig) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -4609,6 +4730,28 @@ func (m *TaskStatus_Container) Size() (n int) { } return n } +func (m *NetworkAttachmentConfig) Size() (n int) { + var l int + _ = l + l = len(m.Target) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.Aliases) > 0 { + for _, s := range m.Aliases { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Addresses) > 0 { + for _, s := range m.Addresses { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + func (m *IPAMConfig) Size() (n int) { var l int _ = l @@ -5257,6 +5400,18 @@ func (this *TaskStatus_Container) String() string { }, "") return s } +func (this *NetworkAttachmentConfig) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NetworkAttachmentConfig{`, + `Target:` + fmt.Sprintf("%v", this.Target) + `,`, + `Aliases:` + fmt.Sprintf("%v", this.Aliases) + `,`, + `Addresses:` + fmt.Sprintf("%v", this.Addresses) + `,`, + `}`, + }, "") + return s +} func (this *IPAMConfig) String() string { if this == nil { return "nil" @@ -8286,6 +8441,143 @@ func (m *TaskStatus) Unmarshal(data []byte) error { } return nil } +func (m *NetworkAttachmentConfig) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkAttachmentConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkAttachmentConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Target = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Aliases", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Aliases = append(m.Aliases, string(data[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addresses = append(m.Addresses, string(data[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *IPAMConfig) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -11256,218 +11548,221 @@ var ( ) var fileDescriptorTypes = []byte{ - // 3398 bytes of a gzipped FileDescriptorProto + // 3442 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x59, 0x4d, 0x6c, 0x1b, 0x49, 0x76, 0x16, 0x7f, 0x45, 0x3e, 0x52, 0x72, 0xbb, 0xec, 0xf5, 0xc8, 0x1c, 0x8f, 0xc4, 0x69, 0x8f, 0x77, 0xbc, 0xb3, 0x13, 0xce, 0x8c, 0x66, 0x13, 0x78, 0xc7, 0xc9, 0xce, 0xb4, 0x48, 0xca, 0xe6, - 0x5a, 0xa2, 0x88, 0xa2, 0x68, 0x63, 0x10, 0x20, 0x44, 0xa9, 0xbb, 0x44, 0xf5, 0xa8, 0xd9, 0xc5, + 0x5a, 0xa2, 0x88, 0x22, 0x69, 0x63, 0x10, 0x20, 0x44, 0xa9, 0xbb, 0x44, 0xf6, 0xa8, 0xd9, 0xc5, 0x74, 0x17, 0x25, 0x33, 0x41, 0x00, 0x27, 0x97, 0x04, 0x3a, 0xe5, 0x1e, 0x08, 0x8b, 0x20, 0x41, 0x6e, 0x39, 0xe4, 0x14, 0x20, 0x27, 0x1f, 0xe7, 0xb8, 0x41, 0x80, 0x60, 0x91, 0x00, 0x42, 0x46, - 0x39, 0xe6, 0xb2, 0x40, 0x0e, 0x7b, 0x48, 0x0e, 0x41, 0xfd, 0x74, 0xb3, 0x49, 0xd3, 0x1a, 0x4f, - 0x76, 0x4f, 0xec, 0x7a, 0xf5, 0xbd, 0x57, 0xef, 0x55, 0xbd, 0x7a, 0xf5, 0x55, 0x11, 0x4a, 0x7c, - 0x32, 0xa2, 0x61, 0x6d, 0x14, 0x30, 0xce, 0x10, 0x72, 0x98, 0x7d, 0x4c, 0x83, 0x5a, 0x78, 0x4a, - 0x82, 0xe1, 0xb1, 0xcb, 0x6b, 0x27, 0x9f, 0x54, 0x6e, 0x73, 0x77, 0x48, 0x43, 0x4e, 0x86, 0xa3, - 0x8f, 0xe2, 0x2f, 0x05, 0xaf, 0xbc, 0xe5, 0x8c, 0x03, 0xc2, 0x5d, 0xe6, 0x7f, 0x14, 0x7d, 0xe8, - 0x8e, 0x9b, 0x03, 0x36, 0x60, 0xf2, 0xf3, 0x23, 0xf1, 0xa5, 0xa4, 0xe6, 0x06, 0x2c, 0x3f, 0xa5, - 0x41, 0xe8, 0x32, 0x1f, 0xdd, 0x84, 0x9c, 0xeb, 0x3b, 0xf4, 0xf9, 0x5a, 0xaa, 0x9a, 0xba, 0x9f, - 0xc5, 0xaa, 0x61, 0xfe, 0x75, 0x0a, 0x4a, 0x96, 0xef, 0x33, 0x2e, 0x6d, 0x85, 0x08, 0x41, 0xd6, - 0x27, 0x43, 0x2a, 0x41, 0x45, 0x2c, 0xbf, 0x51, 0x1d, 0xf2, 0x1e, 0x39, 0xa0, 0x5e, 0xb8, 0x96, - 0xae, 0x66, 0xee, 0x97, 0x36, 0x7f, 0x58, 0x7b, 0xd5, 0xe7, 0x5a, 0xc2, 0x48, 0x6d, 0x47, 0xa2, - 0x9b, 0x3e, 0x0f, 0x26, 0x58, 0xab, 0x56, 0x7e, 0x0c, 0xa5, 0x84, 0x18, 0x19, 0x90, 0x39, 0xa6, - 0x13, 0x3d, 0x8c, 0xf8, 0x14, 0xfe, 0x9d, 0x10, 0x6f, 0x4c, 0xd7, 0xd2, 0x52, 0xa6, 0x1a, 0x9f, - 0xa5, 0x1f, 0xa4, 0xcc, 0x2f, 0xa1, 0x88, 0x69, 0xc8, 0xc6, 0x81, 0x4d, 0x43, 0xf4, 0x03, 0x28, - 0xfa, 0xc4, 0x67, 0x7d, 0x7b, 0x34, 0x0e, 0xa5, 0x7a, 0x66, 0xab, 0x7c, 0x79, 0xb1, 0x51, 0x68, - 0x13, 0x9f, 0xd5, 0x3b, 0xbd, 0x10, 0x17, 0x44, 0x77, 0x7d, 0x34, 0x0e, 0xd1, 0xbb, 0x50, 0x1e, - 0xd2, 0x21, 0x0b, 0x26, 0xfd, 0x83, 0x09, 0xa7, 0xa1, 0x34, 0x9c, 0xc1, 0x25, 0x25, 0xdb, 0x12, - 0x22, 0xf3, 0x2f, 0x53, 0x70, 0x33, 0xb2, 0x8d, 0xe9, 0x1f, 0x8e, 0xdd, 0x80, 0x0e, 0xa9, 0xcf, - 0x43, 0xf4, 0xdb, 0x90, 0xf7, 0xdc, 0xa1, 0xcb, 0xd5, 0x18, 0xa5, 0xcd, 0x77, 0x16, 0xc5, 0x1c, - 0x7b, 0x85, 0x35, 0x18, 0x59, 0x50, 0x0e, 0x68, 0x48, 0x83, 0x13, 0x35, 0x13, 0x72, 0xc8, 0x6f, - 0x55, 0x9e, 0x51, 0x31, 0xb7, 0xa1, 0xd0, 0xf1, 0x08, 0x3f, 0x64, 0xc1, 0x10, 0x99, 0x50, 0x26, - 0x81, 0x7d, 0xe4, 0x72, 0x6a, 0xf3, 0x71, 0x10, 0xad, 0xca, 0x8c, 0x0c, 0xdd, 0x82, 0x34, 0x53, - 0x03, 0x15, 0xb7, 0xf2, 0x97, 0x17, 0x1b, 0xe9, 0xbd, 0x2e, 0x4e, 0xb3, 0xd0, 0x7c, 0x08, 0xd7, - 0x3b, 0xde, 0x78, 0xe0, 0xfa, 0x0d, 0x1a, 0xda, 0x81, 0x3b, 0x12, 0xd6, 0xc5, 0xf2, 0x8a, 0xe4, - 0x8b, 0x96, 0x57, 0x7c, 0xc7, 0x4b, 0x9e, 0x9e, 0x2e, 0xb9, 0xf9, 0xe7, 0x69, 0xb8, 0xde, 0xf4, - 0x07, 0xae, 0x4f, 0x93, 0xda, 0xf7, 0x60, 0x95, 0x4a, 0x61, 0xff, 0x44, 0x25, 0x95, 0xb6, 0xb3, - 0xa2, 0xa4, 0x51, 0xa6, 0xb5, 0xe6, 0xf2, 0xe5, 0x93, 0x45, 0xe1, 0xbf, 0x62, 0x7d, 0x51, 0xd6, - 0xa0, 0x26, 0x2c, 0x8f, 0x64, 0x10, 0xe1, 0x5a, 0x46, 0xda, 0xba, 0xb7, 0xc8, 0xd6, 0x2b, 0x71, - 0x6e, 0x65, 0xbf, 0xbe, 0xd8, 0x58, 0xc2, 0x91, 0xee, 0xaf, 0x93, 0x7c, 0xff, 0x99, 0x82, 0x6b, - 0x6d, 0xe6, 0xcc, 0xcc, 0x43, 0x05, 0x0a, 0x47, 0x2c, 0xe4, 0x89, 0x8d, 0x12, 0xb7, 0xd1, 0x03, - 0x28, 0x8c, 0xf4, 0xf2, 0xe9, 0xd5, 0xbf, 0xb3, 0xd8, 0x65, 0x85, 0xc1, 0x31, 0x1a, 0x3d, 0x84, - 0x62, 0x10, 0xe5, 0xc4, 0x5a, 0xe6, 0x4d, 0x12, 0x67, 0x8a, 0x47, 0xbf, 0x07, 0x79, 0xb5, 0x08, - 0x6b, 0x59, 0xa9, 0x79, 0xef, 0x8d, 0xe6, 0x1c, 0x6b, 0x25, 0xf3, 0x17, 0x29, 0x30, 0x30, 0x39, - 0xe4, 0xbb, 0x74, 0x78, 0x40, 0x83, 0x2e, 0x27, 0x7c, 0x1c, 0xa2, 0x5b, 0x90, 0xf7, 0x28, 0x71, - 0x68, 0x20, 0x83, 0x2c, 0x60, 0xdd, 0x42, 0x3d, 0x91, 0xe4, 0xc4, 0x3e, 0x22, 0x07, 0xae, 0xe7, - 0xf2, 0x89, 0x0c, 0x73, 0x75, 0xf1, 0x2a, 0xcf, 0xdb, 0xac, 0xe1, 0x84, 0x22, 0x9e, 0x31, 0x83, - 0xd6, 0x60, 0x79, 0x48, 0xc3, 0x90, 0x0c, 0xa8, 0x8c, 0xbe, 0x88, 0xa3, 0xa6, 0xf9, 0x10, 0xca, - 0x49, 0x3d, 0x54, 0x82, 0xe5, 0x5e, 0xfb, 0x49, 0x7b, 0xef, 0x59, 0xdb, 0x58, 0x42, 0xd7, 0xa0, - 0xd4, 0x6b, 0xe3, 0xa6, 0x55, 0x7f, 0x6c, 0x6d, 0xed, 0x34, 0x8d, 0x14, 0x5a, 0x81, 0xe2, 0xb4, - 0x99, 0x36, 0x7f, 0x96, 0x02, 0x10, 0x0b, 0xa8, 0x83, 0xfa, 0x0c, 0x72, 0x21, 0x27, 0x5c, 0x2d, - 0xdc, 0xea, 0xe6, 0x7b, 0x8b, 0xbc, 0x9e, 0xc2, 0x6b, 0xe2, 0x87, 0x62, 0xa5, 0x92, 0xf4, 0x30, - 0x3d, 0xef, 0x61, 0x4e, 0x22, 0x67, 0x5d, 0x2b, 0x40, 0xb6, 0x21, 0xbe, 0x52, 0xa8, 0x08, 0x39, - 0xdc, 0xb4, 0x1a, 0x5f, 0x1a, 0x69, 0x64, 0x40, 0xb9, 0xd1, 0xea, 0xd6, 0xf7, 0xda, 0xed, 0x66, - 0x7d, 0xbf, 0xd9, 0x30, 0x32, 0xe6, 0x3d, 0xc8, 0xb5, 0x86, 0x64, 0x40, 0xd1, 0x1d, 0x91, 0x01, - 0x87, 0x34, 0xa0, 0xbe, 0x1d, 0x25, 0xd6, 0x54, 0x60, 0xfe, 0xbc, 0x08, 0xb9, 0x5d, 0x36, 0xf6, - 0x39, 0xda, 0x4c, 0xec, 0xe2, 0xd5, 0xcd, 0xf5, 0x45, 0x21, 0x48, 0x60, 0x6d, 0x7f, 0x32, 0xa2, - 0x7a, 0x97, 0xdf, 0x82, 0xbc, 0xca, 0x15, 0xed, 0xba, 0x6e, 0x09, 0x39, 0x27, 0xc1, 0x80, 0x72, - 0x3d, 0xe9, 0xba, 0x85, 0xee, 0x43, 0x21, 0xa0, 0xc4, 0x61, 0xbe, 0x37, 0x91, 0x29, 0x55, 0x50, - 0x65, 0x16, 0x53, 0xe2, 0xec, 0xf9, 0xde, 0x04, 0xc7, 0xbd, 0xe8, 0x31, 0x94, 0x0f, 0x5c, 0xdf, - 0xe9, 0xb3, 0x91, 0xaa, 0x79, 0xb9, 0xd7, 0x27, 0xa0, 0xf2, 0x6a, 0xcb, 0xf5, 0x9d, 0x3d, 0x05, - 0xc6, 0xa5, 0x83, 0x69, 0x03, 0xb5, 0x61, 0xf5, 0x84, 0x79, 0xe3, 0x21, 0x8d, 0x6d, 0xe5, 0xa5, - 0xad, 0xf7, 0x5f, 0x6f, 0xeb, 0xa9, 0xc4, 0x47, 0xd6, 0x56, 0x4e, 0x92, 0x4d, 0xf4, 0x04, 0x56, - 0xf8, 0x70, 0x74, 0x18, 0xc6, 0xe6, 0x96, 0xa5, 0xb9, 0xef, 0x5f, 0x31, 0x61, 0x02, 0x1e, 0x59, - 0x2b, 0xf3, 0x44, 0xab, 0xf2, 0x67, 0x19, 0x28, 0x25, 0x3c, 0x47, 0x5d, 0x28, 0x8d, 0x02, 0x36, - 0x22, 0x03, 0x59, 0xb7, 0xf5, 0x5a, 0x7c, 0xf2, 0x46, 0x51, 0xd7, 0x3a, 0x53, 0x45, 0x9c, 0xb4, - 0x62, 0x9e, 0xa7, 0xa1, 0x94, 0xe8, 0x44, 0x1f, 0x40, 0x01, 0x77, 0x70, 0xeb, 0xa9, 0xb5, 0xdf, - 0x34, 0x96, 0x2a, 0x77, 0xce, 0xce, 0xab, 0x6b, 0xd2, 0x5a, 0xd2, 0x40, 0x27, 0x70, 0x4f, 0x44, - 0xea, 0xdd, 0x87, 0xe5, 0x08, 0x9a, 0xaa, 0xbc, 0x7d, 0x76, 0x5e, 0x7d, 0x6b, 0x1e, 0x9a, 0x40, - 0xe2, 0xee, 0x63, 0x0b, 0x37, 0x1b, 0x46, 0x7a, 0x31, 0x12, 0x77, 0x8f, 0x48, 0x40, 0x1d, 0xf4, - 0x7d, 0xc8, 0x6b, 0x60, 0xa6, 0x52, 0x39, 0x3b, 0xaf, 0xde, 0x9a, 0x07, 0x4e, 0x71, 0xb8, 0xbb, - 0x63, 0x3d, 0x6d, 0x1a, 0xd9, 0xc5, 0x38, 0xdc, 0xf5, 0xc8, 0x09, 0x45, 0xef, 0x41, 0x4e, 0xc1, - 0x72, 0x95, 0xdb, 0x67, 0xe7, 0xd5, 0xef, 0xbd, 0x62, 0x4e, 0xa0, 0x2a, 0x6b, 0x7f, 0xf1, 0x37, - 0xeb, 0x4b, 0xff, 0xf4, 0xb7, 0xeb, 0xc6, 0x7c, 0x77, 0xe5, 0x7f, 0x53, 0xb0, 0x32, 0xb3, 0xe4, - 0xc8, 0x84, 0xbc, 0xcf, 0x6c, 0x36, 0x52, 0xe5, 0xbc, 0xb0, 0x05, 0x97, 0x17, 0x1b, 0xf9, 0x36, - 0xab, 0xb3, 0xd1, 0x04, 0xeb, 0x1e, 0xf4, 0x64, 0xee, 0x40, 0xfa, 0xf4, 0x0d, 0xf3, 0x69, 0xe1, - 0x91, 0xf4, 0x39, 0xac, 0x38, 0x81, 0x7b, 0x42, 0x83, 0xbe, 0xcd, 0xfc, 0x43, 0x77, 0xa0, 0x4b, - 0x75, 0x65, 0x91, 0xcd, 0x86, 0x04, 0xe2, 0xb2, 0x52, 0xa8, 0x4b, 0xfc, 0xaf, 0x71, 0x18, 0x55, - 0x9e, 0x42, 0x39, 0x99, 0xa1, 0xe8, 0x1d, 0x80, 0xd0, 0xfd, 0x23, 0xaa, 0xf9, 0x8d, 0x64, 0x43, - 0xb8, 0x28, 0x24, 0x92, 0xdd, 0xa0, 0xf7, 0x21, 0x3b, 0x64, 0x8e, 0xb2, 0x93, 0xdb, 0xba, 0x21, - 0xce, 0xc4, 0x7f, 0xbb, 0xd8, 0x28, 0xb1, 0xb0, 0xb6, 0xed, 0x7a, 0x74, 0x97, 0x39, 0x14, 0x4b, - 0x80, 0x79, 0x02, 0x59, 0x51, 0x2a, 0xd0, 0xdb, 0x90, 0xdd, 0x6a, 0xb5, 0x1b, 0xc6, 0x52, 0xe5, - 0xfa, 0xd9, 0x79, 0x75, 0x45, 0x4e, 0x89, 0xe8, 0x10, 0xb9, 0x8b, 0x36, 0x20, 0xff, 0x74, 0x6f, - 0xa7, 0xb7, 0x2b, 0xd2, 0xeb, 0xc6, 0xd9, 0x79, 0xf5, 0x5a, 0xdc, 0xad, 0x26, 0x0d, 0xbd, 0x03, - 0xb9, 0xfd, 0xdd, 0xce, 0x76, 0xd7, 0x48, 0x57, 0xd0, 0xd9, 0x79, 0x75, 0x35, 0xee, 0x97, 0x3e, - 0x57, 0xae, 0xeb, 0x55, 0x2d, 0xc6, 0x72, 0xf3, 0x7f, 0xd2, 0xb0, 0x82, 0x05, 0xbf, 0x0d, 0x78, - 0x87, 0x79, 0xae, 0x3d, 0x41, 0x1d, 0x28, 0xda, 0xcc, 0x77, 0xdc, 0xc4, 0x9e, 0xda, 0x7c, 0xcd, - 0x21, 0x38, 0xd5, 0x8a, 0x5a, 0xf5, 0x48, 0x13, 0x4f, 0x8d, 0xa0, 0x4d, 0xc8, 0x39, 0xd4, 0x23, - 0x93, 0xab, 0x4e, 0xe3, 0x86, 0xe6, 0xd2, 0x58, 0x41, 0x25, 0x73, 0x24, 0xcf, 0xfb, 0x84, 0x73, - 0x3a, 0x1c, 0x71, 0x75, 0x1a, 0x67, 0x71, 0x69, 0x48, 0x9e, 0x5b, 0x5a, 0x84, 0x7e, 0x04, 0xf9, - 0x53, 0xd7, 0x77, 0xd8, 0xa9, 0x3e, 0x70, 0xaf, 0xb6, 0xab, 0xb1, 0xe6, 0x99, 0x38, 0x67, 0xe7, - 0x9c, 0x15, 0xb3, 0xde, 0xde, 0x6b, 0x37, 0xa3, 0x59, 0xd7, 0xfd, 0x7b, 0x7e, 0x9b, 0xf9, 0x62, - 0xc7, 0xc0, 0x5e, 0xbb, 0xbf, 0x6d, 0xb5, 0x76, 0x7a, 0x58, 0xcc, 0xfc, 0xcd, 0xb3, 0xf3, 0xaa, - 0x11, 0x43, 0xb6, 0x89, 0xeb, 0x09, 0x12, 0x78, 0x1b, 0x32, 0x56, 0xfb, 0x4b, 0x23, 0x5d, 0x31, - 0xce, 0xce, 0xab, 0xe5, 0xb8, 0xdb, 0xf2, 0x27, 0xd3, 0xcd, 0x34, 0x3f, 0xae, 0xf9, 0x5f, 0x29, - 0x28, 0xf7, 0x46, 0x0e, 0xe1, 0x54, 0x65, 0x26, 0xaa, 0x42, 0x69, 0x44, 0x02, 0xe2, 0x79, 0xd4, - 0x73, 0xc3, 0xa1, 0xbe, 0x28, 0x24, 0x45, 0xe8, 0xc1, 0x77, 0x98, 0x4c, 0x4d, 0xc2, 0xf4, 0x94, - 0xf6, 0x60, 0xf5, 0x50, 0x39, 0xdb, 0x27, 0xb6, 0x5c, 0xdd, 0x8c, 0x5c, 0xdd, 0xda, 0x22, 0x13, - 0x49, 0xaf, 0x6a, 0x3a, 0x46, 0x4b, 0x6a, 0xe1, 0x95, 0xc3, 0x64, 0xd3, 0xbc, 0x0f, 0x2b, 0x33, - 0xfd, 0xe2, 0xa4, 0xed, 0x58, 0xbd, 0x6e, 0xd3, 0x58, 0x42, 0x65, 0x28, 0xd4, 0xf7, 0xda, 0xfb, - 0xad, 0x76, 0xaf, 0x69, 0xa4, 0xcc, 0x7f, 0x48, 0x47, 0xd1, 0x6a, 0x26, 0xb0, 0x35, 0xcb, 0x04, - 0x3e, 0x7c, 0xbd, 0x23, 0x9a, 0x0b, 0x4c, 0x1b, 0x31, 0x23, 0xf8, 0x5d, 0x00, 0x39, 0xa9, 0xd4, - 0xe9, 0x13, 0x7e, 0x15, 0xdb, 0xdf, 0x8f, 0xee, 0x71, 0xb8, 0xa8, 0x15, 0x2c, 0x8e, 0xbe, 0x80, - 0xb2, 0xcd, 0x86, 0x23, 0x8f, 0x6a, 0xfd, 0xcc, 0x9b, 0xe8, 0x97, 0x62, 0x15, 0x8b, 0x27, 0x19, - 0x49, 0x76, 0x96, 0x91, 0xd4, 0xa1, 0x94, 0xf0, 0x77, 0x96, 0x97, 0x94, 0xa1, 0xd0, 0xeb, 0x34, - 0xac, 0xfd, 0x56, 0xfb, 0x91, 0x91, 0x42, 0x00, 0x79, 0x39, 0x63, 0x0d, 0x23, 0x2d, 0xb8, 0x53, - 0x7d, 0x6f, 0xb7, 0xb3, 0xd3, 0x54, 0xcc, 0xe4, 0x4f, 0xe0, 0x5a, 0x9d, 0xf9, 0x9c, 0xb8, 0x7e, - 0x4c, 0x0a, 0x37, 0x85, 0xcf, 0x5a, 0xd4, 0x77, 0x1d, 0x55, 0xb7, 0xb6, 0xae, 0x5d, 0x5e, 0x6c, - 0x94, 0x62, 0x68, 0xab, 0x21, 0xbc, 0x8c, 0x1a, 0x8e, 0xc8, 0xce, 0x91, 0xeb, 0xe8, 0x32, 0xb4, - 0x7c, 0x79, 0xb1, 0x91, 0xe9, 0xb4, 0x1a, 0x58, 0xc8, 0xd0, 0xdb, 0x50, 0xa4, 0xcf, 0x5d, 0xde, - 0xb7, 0x45, 0x9d, 0x12, 0xf1, 0xe7, 0x70, 0x41, 0x08, 0xea, 0xa2, 0x2c, 0xfd, 0x69, 0x1a, 0x60, - 0x9f, 0x84, 0xc7, 0x7a, 0xe8, 0x87, 0x50, 0x8c, 0xaf, 0xc3, 0x57, 0x5d, 0xcb, 0x12, 0x73, 0x1d, - 0xe3, 0xd1, 0xa7, 0xd1, 0x6a, 0x2b, 0xb6, 0xba, 0x58, 0x51, 0x8f, 0xb5, 0x88, 0xf0, 0xcd, 0x52, - 0x52, 0x51, 0xb5, 0x69, 0x10, 0xe8, 0x49, 0x17, 0x9f, 0xa8, 0x2e, 0x2b, 0x97, 0x8a, 0x59, 0x73, - 0xa0, 0xbb, 0x8b, 0x06, 0x99, 0x9b, 0xd0, 0xc7, 0x4b, 0x78, 0xaa, 0xb7, 0x65, 0xc0, 0x6a, 0x30, - 0xf6, 0x85, 0xd7, 0xfd, 0x50, 0x76, 0x9b, 0xff, 0x92, 0x06, 0x68, 0x75, 0xac, 0x5d, 0xbd, 0x45, - 0x1b, 0x90, 0x3f, 0x24, 0x43, 0xd7, 0x9b, 0x5c, 0x95, 0xb5, 0x53, 0x7c, 0xcd, 0x72, 0x9c, 0x80, - 0x86, 0xe1, 0xb6, 0xd4, 0xc1, 0x5a, 0x57, 0x92, 0xc1, 0xf1, 0x81, 0x4f, 0x79, 0x4c, 0x06, 0x65, - 0x4b, 0x9c, 0x3c, 0x01, 0xf1, 0xe3, 0x68, 0x55, 0x43, 0xcc, 0xc2, 0x80, 0x70, 0x7a, 0x4a, 0x26, - 0x51, 0x92, 0xe9, 0x26, 0x7a, 0x2c, 0x48, 0xa2, 0xb8, 0xbb, 0x52, 0x67, 0x2d, 0x27, 0x8f, 0xd6, - 0x6f, 0xf3, 0x07, 0x6b, 0xb8, 0x3a, 0x53, 0x63, 0xed, 0xca, 0x43, 0x79, 0x10, 0x4c, 0xbb, 0xbe, - 0xd3, 0x1d, 0xed, 0x63, 0x58, 0x99, 0x89, 0xf3, 0x15, 0x16, 0xde, 0xea, 0x3c, 0xfd, 0x91, 0x91, - 0xd5, 0x5f, 0xbf, 0x63, 0xe4, 0xcd, 0xff, 0x4e, 0x01, 0x74, 0x98, 0x2c, 0x86, 0x62, 0x56, 0x17, - 0xbf, 0x7a, 0x14, 0xe4, 0x1b, 0x8a, 0xcd, 0x3c, 0x9d, 0x33, 0x0b, 0x69, 0xe8, 0xd4, 0x8a, 0x60, - 0x75, 0x12, 0x8e, 0x63, 0x45, 0xb4, 0x01, 0x25, 0xc5, 0xa7, 0xfb, 0x23, 0x16, 0xa8, 0x0d, 0xbe, - 0x82, 0x41, 0x89, 0x84, 0xa6, 0xb8, 0x52, 0x8f, 0xc6, 0x07, 0x9e, 0x1b, 0x1e, 0x51, 0x47, 0x61, - 0xb2, 0x12, 0xb3, 0x12, 0x4b, 0x05, 0xcc, 0x6c, 0x40, 0x21, 0xb2, 0x8e, 0xd6, 0x20, 0xb3, 0x5f, - 0xef, 0x18, 0x4b, 0x95, 0x6b, 0x67, 0xe7, 0xd5, 0x52, 0x24, 0xde, 0xaf, 0x77, 0x44, 0x4f, 0xaf, - 0xd1, 0x31, 0x52, 0xb3, 0x3d, 0xbd, 0x46, 0xa7, 0x92, 0x15, 0x87, 0x80, 0xf9, 0x57, 0x29, 0xc8, - 0x2b, 0x4a, 0xb2, 0x30, 0x62, 0x0b, 0x96, 0x23, 0xa2, 0xac, 0x78, 0xd2, 0xfb, 0xaf, 0xe7, 0x34, - 0x35, 0x4d, 0x41, 0xd4, 0x3a, 0x46, 0x7a, 0x95, 0xcf, 0xa0, 0x9c, 0xec, 0xf8, 0x4e, 0xab, 0xf8, - 0xc7, 0x50, 0x12, 0x89, 0x12, 0x71, 0x9b, 0x4d, 0xc8, 0x2b, 0xda, 0xa4, 0xb7, 0xfa, 0x55, 0x04, - 0x4b, 0x23, 0xd1, 0x03, 0x58, 0x56, 0xa4, 0x2c, 0x7a, 0x2e, 0x58, 0xbf, 0x3a, 0x1d, 0x71, 0x04, - 0x37, 0x3f, 0x87, 0x6c, 0x87, 0xd2, 0x00, 0xdd, 0x85, 0x65, 0x9f, 0x39, 0x74, 0x5a, 0xd9, 0x34, - 0x9f, 0x74, 0x68, 0xab, 0x21, 0xf8, 0xa4, 0x43, 0x5b, 0x8e, 0x98, 0x3c, 0xe2, 0x38, 0x41, 0xf4, - 0x62, 0x22, 0xbe, 0xcd, 0x7d, 0x28, 0x3f, 0xa3, 0xee, 0xe0, 0x88, 0x53, 0x47, 0x1a, 0xfa, 0x10, - 0xb2, 0x23, 0x1a, 0x3b, 0xbf, 0xb6, 0x30, 0x75, 0x28, 0x0d, 0xb0, 0x44, 0x89, 0x0d, 0x79, 0x2a, - 0xb5, 0xf5, 0x23, 0x95, 0x6e, 0x99, 0x7f, 0x9f, 0x86, 0xd5, 0x56, 0x18, 0x8e, 0x89, 0x6f, 0x47, - 0xc7, 0xd6, 0x4f, 0x66, 0x8f, 0xad, 0xfb, 0x0b, 0x23, 0x9c, 0x51, 0x99, 0xbd, 0xc4, 0xea, 0xca, - 0x95, 0x8e, 0x2b, 0x97, 0xf9, 0x75, 0x2a, 0xba, 0xbd, 0xde, 0x4b, 0xec, 0x9b, 0xca, 0xda, 0xd9, - 0x79, 0xf5, 0x66, 0xd2, 0x12, 0xed, 0xf9, 0xc7, 0x3e, 0x3b, 0xf5, 0xd1, 0xbb, 0xe2, 0x36, 0xdb, - 0x6e, 0x3e, 0x33, 0x52, 0x95, 0x5b, 0x67, 0xe7, 0x55, 0x34, 0x03, 0xc2, 0xd4, 0xa7, 0xa7, 0xc2, - 0x52, 0xa7, 0xd9, 0x6e, 0x88, 0x13, 0x26, 0xbd, 0xc0, 0x52, 0x87, 0xfa, 0x8e, 0xeb, 0x0f, 0xd0, - 0x5d, 0xc8, 0xb7, 0xba, 0xdd, 0x9e, 0xbc, 0x5f, 0xbc, 0x75, 0x76, 0x5e, 0xbd, 0x31, 0x83, 0x12, - 0x0d, 0xea, 0x08, 0x90, 0xe0, 0x3f, 0xcd, 0x86, 0x91, 0x5d, 0x00, 0x12, 0xc7, 0x3f, 0x75, 0x74, - 0x86, 0xff, 0x7b, 0x1a, 0x0c, 0xcb, 0xb6, 0xe9, 0x88, 0x8b, 0x7e, 0xcd, 0x29, 0xf7, 0xa1, 0x30, - 0x12, 0x5f, 0xae, 0xe4, 0xc8, 0x22, 0x2d, 0x1e, 0x2c, 0x7c, 0xc1, 0x9c, 0xd3, 0xab, 0x61, 0xe6, - 0x51, 0xcb, 0x19, 0xba, 0x61, 0x28, 0xee, 0x4e, 0x52, 0x86, 0x63, 0x4b, 0x95, 0x5f, 0xa6, 0xe0, - 0xc6, 0x02, 0x04, 0xfa, 0x18, 0xb2, 0x01, 0xf3, 0xa2, 0xe5, 0xb9, 0xf3, 0xba, 0xf7, 0x05, 0xa1, - 0x8a, 0x25, 0x12, 0xad, 0x03, 0x90, 0x31, 0x67, 0x44, 0x8e, 0x2f, 0x17, 0xa6, 0x80, 0x13, 0x12, - 0xf4, 0x0c, 0xf2, 0x21, 0xb5, 0x03, 0x1a, 0x11, 0x84, 0xcf, 0xff, 0xbf, 0xde, 0xd7, 0xba, 0xd2, - 0x0c, 0xd6, 0xe6, 0x2a, 0x35, 0xc8, 0x2b, 0x89, 0xc8, 0x68, 0x87, 0x70, 0x22, 0x9d, 0x2e, 0x63, - 0xf9, 0x2d, 0x12, 0x85, 0x78, 0x83, 0x28, 0x51, 0x88, 0x37, 0x30, 0x7f, 0x96, 0x06, 0x68, 0x3e, - 0xe7, 0x34, 0xf0, 0x89, 0x57, 0xb7, 0x50, 0x33, 0x51, 0x21, 0x55, 0xb4, 0x3f, 0x58, 0xf8, 0xea, - 0x14, 0x6b, 0xd4, 0xea, 0xd6, 0x82, 0x1a, 0x79, 0x1b, 0x32, 0xe3, 0xc0, 0xd3, 0x2f, 0x98, 0x92, - 0x1d, 0xf4, 0xf0, 0x0e, 0x16, 0x32, 0xd4, 0x9c, 0x56, 0xa4, 0xcc, 0xeb, 0x9f, 0x9e, 0x13, 0x03, - 0xfc, 0xe6, 0xab, 0xd2, 0x87, 0x00, 0x53, 0xaf, 0xd1, 0x3a, 0xe4, 0xea, 0xdb, 0xdd, 0xee, 0x8e, - 0xb1, 0xa4, 0xae, 0x40, 0xd3, 0x2e, 0x29, 0x36, 0xff, 0x2e, 0x05, 0x85, 0xba, 0xa5, 0x4f, 0x95, - 0x6d, 0x30, 0x64, 0x2d, 0xb1, 0x69, 0xc0, 0xfb, 0xf4, 0xf9, 0xc8, 0x0d, 0x26, 0xba, 0x1c, 0x5c, - 0x7d, 0x59, 0x58, 0x15, 0x5a, 0x75, 0x1a, 0xf0, 0xa6, 0xd4, 0x41, 0x18, 0xca, 0x54, 0x87, 0xd8, - 0xb7, 0x49, 0x54, 0x9c, 0xd7, 0xaf, 0x9e, 0x0a, 0x45, 0xc9, 0xa6, 0xed, 0x10, 0x97, 0x22, 0x23, - 0x75, 0x12, 0x9a, 0x4f, 0xe1, 0xc6, 0x5e, 0x60, 0x1f, 0xd1, 0x90, 0xab, 0x41, 0xb5, 0xcb, 0x9f, - 0xc3, 0x1d, 0x4e, 0xc2, 0xe3, 0xfe, 0x91, 0x1b, 0x72, 0x16, 0x4c, 0xfa, 0x01, 0xe5, 0xd4, 0x17, - 0xfd, 0x7d, 0xf9, 0xc0, 0xad, 0xaf, 0x98, 0xb7, 0x05, 0xe6, 0xb1, 0x82, 0xe0, 0x08, 0xb1, 0x23, - 0x00, 0x66, 0x0b, 0xca, 0x82, 0x45, 0x35, 0xe8, 0x21, 0x19, 0x7b, 0x3c, 0x44, 0x3f, 0x06, 0xf0, - 0xd8, 0xa0, 0xff, 0xc6, 0x95, 0xbc, 0xe8, 0xb1, 0x81, 0xfa, 0x34, 0x7f, 0x1f, 0x8c, 0x86, 0x1b, - 0x8e, 0x08, 0xb7, 0x8f, 0xa2, 0xbb, 0x33, 0x7a, 0x04, 0xc6, 0x11, 0x25, 0x01, 0x3f, 0xa0, 0x84, - 0xf7, 0x47, 0x34, 0x70, 0x99, 0xf3, 0x46, 0x53, 0x7a, 0x2d, 0xd6, 0xea, 0x48, 0x25, 0xf3, 0x57, - 0x29, 0x00, 0x4c, 0x0e, 0x23, 0x02, 0xf0, 0x43, 0xb8, 0x1e, 0xfa, 0x64, 0x14, 0x1e, 0x31, 0xde, - 0x77, 0x7d, 0x4e, 0x83, 0x13, 0xe2, 0xe9, 0xfb, 0x8f, 0x11, 0x75, 0xb4, 0xb4, 0x1c, 0x7d, 0x08, - 0xe8, 0x98, 0xd2, 0x51, 0x9f, 0x79, 0x4e, 0x3f, 0xea, 0x54, 0x2f, 0xf0, 0x59, 0x6c, 0x88, 0x9e, - 0x3d, 0xcf, 0xe9, 0x46, 0x72, 0xb4, 0x05, 0xeb, 0x62, 0x06, 0xa8, 0xcf, 0x03, 0x97, 0x86, 0xfd, - 0x43, 0x16, 0xf4, 0x43, 0x8f, 0x9d, 0xf6, 0x0f, 0x99, 0xe7, 0xb1, 0x53, 0x1a, 0x44, 0xb7, 0xcb, - 0x8a, 0xc7, 0x06, 0x4d, 0x05, 0xda, 0x66, 0x41, 0xd7, 0x63, 0xa7, 0xdb, 0x11, 0x42, 0xb0, 0x84, - 0x69, 0xd8, 0xdc, 0xb5, 0x8f, 0x23, 0x96, 0x10, 0x4b, 0xf7, 0x5d, 0xfb, 0x18, 0xdd, 0x85, 0x15, - 0xea, 0x51, 0x79, 0x0f, 0x52, 0xa8, 0x9c, 0x44, 0x95, 0x23, 0xa1, 0x00, 0x99, 0xbf, 0x05, 0xc5, - 0x8e, 0x47, 0x6c, 0xf9, 0x3f, 0x87, 0xb8, 0xf1, 0xd9, 0xcc, 0x17, 0x49, 0xe0, 0xfa, 0x5c, 0x55, - 0xc7, 0x22, 0x4e, 0x8a, 0xcc, 0x9f, 0x00, 0xfc, 0x94, 0xb9, 0xfe, 0x3e, 0x3b, 0xa6, 0xbe, 0x7c, - 0x12, 0x3e, 0x65, 0xc1, 0xb1, 0x5e, 0xca, 0x22, 0xd6, 0x2d, 0x49, 0x94, 0x89, 0x4f, 0x06, 0x34, - 0x88, 0x5f, 0x46, 0x55, 0x53, 0x1c, 0x2e, 0x79, 0xcc, 0x18, 0xaf, 0x5b, 0xa8, 0x0a, 0x79, 0x9b, - 0xf4, 0xa3, 0x9d, 0x57, 0xde, 0x2a, 0x5e, 0x5e, 0x6c, 0xe4, 0xea, 0xd6, 0x13, 0x3a, 0xc1, 0x39, - 0x9b, 0x3c, 0xa1, 0x13, 0x71, 0xfa, 0xda, 0x44, 0xee, 0x17, 0x69, 0xa6, 0xac, 0x4e, 0xdf, 0xba, - 0x25, 0x36, 0x03, 0xce, 0xdb, 0x44, 0xfc, 0xa2, 0x8f, 0xa1, 0xac, 0x41, 0xfd, 0x23, 0x12, 0x1e, - 0x29, 0xae, 0xba, 0xb5, 0x7a, 0x79, 0xb1, 0x01, 0x0a, 0xf9, 0x98, 0x84, 0x47, 0x18, 0x14, 0x5a, - 0x7c, 0xa3, 0x26, 0x94, 0xbe, 0x62, 0xae, 0xdf, 0xe7, 0x32, 0x08, 0x7d, 0x61, 0x5f, 0xb8, 0x7f, - 0xa6, 0xa1, 0xea, 0xdb, 0x2b, 0x7c, 0x15, 0x4b, 0xcc, 0x7f, 0x4d, 0x41, 0x49, 0xd8, 0x74, 0x0f, - 0x5d, 0x5b, 0x9c, 0x96, 0xdf, 0xbd, 0xd2, 0xdf, 0x86, 0x8c, 0x1d, 0x06, 0x3a, 0x36, 0x59, 0xea, - 0xea, 0x5d, 0x8c, 0x85, 0x0c, 0x7d, 0x01, 0x79, 0xc5, 0xf8, 0x75, 0x91, 0x37, 0xbf, 0xfd, 0x5c, - 0xd7, 0x2e, 0x6a, 0x3d, 0xb9, 0x96, 0x53, 0xef, 0x64, 0x94, 0x65, 0x9c, 0x14, 0xa1, 0x5b, 0x90, - 0xb6, 0x7d, 0x99, 0x14, 0xfa, 0xaf, 0xa2, 0x7a, 0x1b, 0xa7, 0x6d, 0xdf, 0xfc, 0xe7, 0x14, 0xac, - 0x34, 0x7d, 0x3b, 0x98, 0xc8, 0x22, 0x29, 0x16, 0xe2, 0x0e, 0x14, 0xc3, 0xf1, 0x41, 0x38, 0x09, - 0x39, 0x1d, 0x46, 0x2f, 0xd1, 0xb1, 0x00, 0xb5, 0xa0, 0x48, 0xbc, 0x01, 0x0b, 0x5c, 0x7e, 0x34, - 0xd4, 0xdc, 0x78, 0x71, 0x61, 0x4e, 0xda, 0xac, 0x59, 0x91, 0x0a, 0x9e, 0x6a, 0x47, 0xa5, 0x38, - 0x23, 0x9d, 0x95, 0xa5, 0xf8, 0x5d, 0x28, 0x7b, 0x64, 0x28, 0xa8, 0x70, 0x5f, 0xdc, 0x83, 0x64, - 0x1c, 0x59, 0x5c, 0xd2, 0x32, 0x71, 0xb7, 0x33, 0x4d, 0x28, 0xc6, 0xc6, 0xd0, 0x35, 0x28, 0x59, - 0xcd, 0x6e, 0xff, 0x93, 0xcd, 0x07, 0xfd, 0x47, 0xf5, 0x5d, 0x63, 0x49, 0x33, 0x81, 0x7f, 0x4c, - 0xc1, 0xca, 0xae, 0xca, 0x41, 0x4d, 0x9c, 0xee, 0xc2, 0x72, 0x40, 0x0e, 0x79, 0x44, 0xed, 0xb2, - 0x2a, 0xb9, 0x44, 0x11, 0x10, 0xd4, 0x4e, 0x74, 0x2d, 0xa6, 0x76, 0x89, 0xff, 0x41, 0x32, 0x57, - 0xfe, 0x0f, 0x92, 0xfd, 0x8d, 0xfc, 0x0f, 0xf2, 0xc1, 0xaf, 0x32, 0x50, 0x8c, 0x6f, 0xa2, 0x22, - 0x65, 0x04, 0xd3, 0x5a, 0x52, 0x2f, 0x3b, 0xb1, 0xbc, 0x2d, 0x39, 0x56, 0xd1, 0xda, 0xd9, 0xd9, - 0xab, 0x5b, 0xe2, 0xb2, 0xfe, 0x85, 0xa2, 0x62, 0x31, 0xc0, 0xf2, 0x3c, 0x26, 0x16, 0xdd, 0x41, - 0xe6, 0x94, 0x8a, 0xbd, 0xd0, 0xef, 0x47, 0x31, 0x2a, 0xe2, 0x61, 0xef, 0x41, 0xc1, 0xea, 0x76, - 0x5b, 0x8f, 0xda, 0xcd, 0x86, 0xf1, 0x32, 0x55, 0xf9, 0xde, 0xd9, 0x79, 0xf5, 0xfa, 0xd4, 0x54, - 0x18, 0xba, 0x03, 0x9f, 0x3a, 0x12, 0x55, 0xaf, 0x37, 0x3b, 0x62, 0xbc, 0x17, 0xe9, 0x79, 0x94, - 0x24, 0x20, 0xf2, 0x2d, 0xb8, 0xd8, 0xc1, 0xcd, 0x8e, 0x85, 0xc5, 0x88, 0x2f, 0xd3, 0x73, 0x7e, - 0x75, 0x02, 0x3a, 0x22, 0x81, 0x18, 0x73, 0x3d, 0xfa, 0x4f, 0xe4, 0x45, 0x46, 0xbd, 0x17, 0x4e, - 0xaf, 0xdf, 0x94, 0x38, 0x13, 0x31, 0x5a, 0x77, 0xdf, 0xc2, 0xf2, 0x95, 0xe2, 0x65, 0x66, 0x6e, - 0xb4, 0x2e, 0x27, 0x01, 0x17, 0x56, 0x4c, 0x58, 0xc6, 0xbd, 0x76, 0x5b, 0x46, 0x97, 0x9d, 0x8b, - 0x0e, 0x8f, 0x7d, 0x5f, 0x60, 0xee, 0x41, 0x21, 0x7a, 0xd5, 0x30, 0x5e, 0x66, 0xe7, 0x1c, 0xaa, - 0x47, 0xcf, 0x29, 0x72, 0xc0, 0xc7, 0xbd, 0x7d, 0xf9, 0x97, 0xcd, 0x8b, 0xdc, 0xfc, 0x80, 0x47, - 0x63, 0xee, 0x08, 0xf2, 0x5b, 0x8d, 0xd9, 0xe8, 0xcb, 0x9c, 0x22, 0x01, 0x31, 0x46, 0x51, 0x51, - 0x61, 0x07, 0x37, 0x7f, 0xaa, 0xfe, 0xdd, 0x79, 0x91, 0x9f, 0xb3, 0x83, 0xe9, 0x57, 0xd4, 0xe6, - 0xd4, 0x99, 0x3e, 0x87, 0xc6, 0x5d, 0x1f, 0xfc, 0x01, 0x14, 0xa2, 0x82, 0x81, 0xd6, 0x21, 0xff, - 0x6c, 0x0f, 0x3f, 0x69, 0x62, 0x63, 0x49, 0xcd, 0x4e, 0xd4, 0xf3, 0x4c, 0x55, 0xdc, 0x2a, 0x2c, - 0xef, 0x5a, 0x6d, 0xeb, 0x51, 0x13, 0x47, 0xcf, 0xb1, 0x11, 0x40, 0x67, 0x7d, 0xc5, 0xd0, 0x03, - 0xc4, 0x36, 0xb7, 0xee, 0x7c, 0xfd, 0xcd, 0xfa, 0xd2, 0x2f, 0xbe, 0x59, 0x5f, 0xfa, 0xe5, 0x37, - 0xeb, 0xa9, 0x17, 0x97, 0xeb, 0xa9, 0xaf, 0x2f, 0xd7, 0x53, 0x3f, 0xbf, 0x5c, 0x4f, 0xfd, 0xc7, - 0xe5, 0x7a, 0xea, 0x20, 0x2f, 0x19, 0xd9, 0xa7, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x84, 0x8b, - 0x50, 0xe8, 0x9f, 0x20, 0x00, 0x00, + 0x39, 0xe6, 0xb2, 0x40, 0x0e, 0x7b, 0x48, 0x0e, 0x41, 0xfd, 0x74, 0xf3, 0xc7, 0xb4, 0xc6, 0x93, + 0xdd, 0x13, 0xbb, 0x5e, 0x7d, 0xef, 0xd5, 0xab, 0xaa, 0x57, 0xaf, 0xbe, 0x57, 0x84, 0x02, 0x9f, + 0x8c, 0x68, 0x58, 0x19, 0x05, 0x8c, 0x33, 0x84, 0x1c, 0x66, 0x1f, 0xd3, 0xa0, 0x12, 0x9e, 0x92, + 0x60, 0x78, 0xec, 0xf2, 0xca, 0xc9, 0x27, 0xa5, 0xdb, 0xdc, 0x1d, 0xd2, 0x90, 0x93, 0xe1, 0xe8, + 0xa3, 0xf8, 0x4b, 0xc1, 0x4b, 0x6f, 0x39, 0xe3, 0x80, 0x70, 0x97, 0xf9, 0x1f, 0x45, 0x1f, 0xba, + 0xe3, 0x66, 0x9f, 0xf5, 0x99, 0xfc, 0xfc, 0x48, 0x7c, 0x29, 0xa9, 0xb9, 0x05, 0xab, 0x4f, 0x69, + 0x10, 0xba, 0xcc, 0x47, 0x37, 0x21, 0xe3, 0xfa, 0x0e, 0x7d, 0xbe, 0x91, 0x28, 0x27, 0xee, 0xa7, + 0xb1, 0x6a, 0x98, 0x7f, 0x9d, 0x80, 0x82, 0xe5, 0xfb, 0x8c, 0x4b, 0x5b, 0x21, 0x42, 0x90, 0xf6, + 0xc9, 0x90, 0x4a, 0x50, 0x1e, 0xcb, 0x6f, 0x54, 0x85, 0xac, 0x47, 0x0e, 0xa9, 0x17, 0x6e, 0x24, + 0xcb, 0xa9, 0xfb, 0x85, 0xed, 0x1f, 0x56, 0x5e, 0xf5, 0xb9, 0x32, 0x63, 0xa4, 0xb2, 0x27, 0xd1, + 0x75, 0x9f, 0x07, 0x13, 0xac, 0x55, 0x4b, 0x3f, 0x86, 0xc2, 0x8c, 0x18, 0x19, 0x90, 0x3a, 0xa6, + 0x13, 0x3d, 0x8c, 0xf8, 0x14, 0xfe, 0x9d, 0x10, 0x6f, 0x4c, 0x37, 0x92, 0x52, 0xa6, 0x1a, 0x9f, + 0x25, 0x1f, 0x24, 0xcc, 0x2f, 0x21, 0x8f, 0x69, 0xc8, 0xc6, 0x81, 0x4d, 0x43, 0xf4, 0x03, 0xc8, + 0xfb, 0xc4, 0x67, 0x3d, 0x7b, 0x34, 0x0e, 0xa5, 0x7a, 0x6a, 0xa7, 0x78, 0x79, 0xb1, 0x95, 0x6b, + 0x12, 0x9f, 0x55, 0x5b, 0xdd, 0x10, 0xe7, 0x44, 0x77, 0x75, 0x34, 0x0e, 0xd1, 0xbb, 0x50, 0x1c, + 0xd2, 0x21, 0x0b, 0x26, 0xbd, 0xc3, 0x09, 0xa7, 0xa1, 0x34, 0x9c, 0xc2, 0x05, 0x25, 0xdb, 0x11, + 0x22, 0xf3, 0x2f, 0x13, 0x70, 0x33, 0xb2, 0x8d, 0xe9, 0x1f, 0x8e, 0xdd, 0x80, 0x0e, 0xa9, 0xcf, + 0x43, 0xf4, 0xdb, 0x90, 0xf5, 0xdc, 0xa1, 0xcb, 0xd5, 0x18, 0x85, 0xed, 0x77, 0x96, 0xcd, 0x39, + 0xf6, 0x0a, 0x6b, 0x30, 0xb2, 0xa0, 0x18, 0xd0, 0x90, 0x06, 0x27, 0x6a, 0x25, 0xe4, 0x90, 0xdf, + 0xaa, 0x3c, 0xa7, 0x62, 0xee, 0x42, 0xae, 0xe5, 0x11, 0x7e, 0xc4, 0x82, 0x21, 0x32, 0xa1, 0x48, + 0x02, 0x7b, 0xe0, 0x72, 0x6a, 0xf3, 0x71, 0x10, 0xed, 0xca, 0x9c, 0x0c, 0xdd, 0x82, 0x24, 0x53, + 0x03, 0xe5, 0x77, 0xb2, 0x97, 0x17, 0x5b, 0xc9, 0x83, 0x36, 0x4e, 0xb2, 0xd0, 0x7c, 0x08, 0xd7, + 0x5b, 0xde, 0xb8, 0xef, 0xfa, 0x35, 0x1a, 0xda, 0x81, 0x3b, 0x12, 0xd6, 0xc5, 0xf6, 0x8a, 0xe0, + 0x8b, 0xb6, 0x57, 0x7c, 0xc7, 0x5b, 0x9e, 0x9c, 0x6e, 0xb9, 0xf9, 0xe7, 0x49, 0xb8, 0x5e, 0xf7, + 0xfb, 0xae, 0x4f, 0x67, 0xb5, 0xef, 0xc1, 0x3a, 0x95, 0xc2, 0xde, 0x89, 0x0a, 0x2a, 0x6d, 0x67, + 0x4d, 0x49, 0xa3, 0x48, 0x6b, 0x2c, 0xc4, 0xcb, 0x27, 0xcb, 0xa6, 0xff, 0x8a, 0xf5, 0x65, 0x51, + 0x83, 0xea, 0xb0, 0x3a, 0x92, 0x93, 0x08, 0x37, 0x52, 0xd2, 0xd6, 0xbd, 0x65, 0xb6, 0x5e, 0x99, + 0xe7, 0x4e, 0xfa, 0xeb, 0x8b, 0xad, 0x15, 0x1c, 0xe9, 0xfe, 0x3a, 0xc1, 0xf7, 0x9f, 0x09, 0xb8, + 0xd6, 0x64, 0xce, 0xdc, 0x3a, 0x94, 0x20, 0x37, 0x60, 0x21, 0x9f, 0x39, 0x28, 0x71, 0x1b, 0x3d, + 0x80, 0xdc, 0x48, 0x6f, 0x9f, 0xde, 0xfd, 0x3b, 0xcb, 0x5d, 0x56, 0x18, 0x1c, 0xa3, 0xd1, 0x43, + 0xc8, 0x07, 0x51, 0x4c, 0x6c, 0xa4, 0xde, 0x24, 0x70, 0xa6, 0x78, 0xf4, 0x7b, 0x90, 0x55, 0x9b, + 0xb0, 0x91, 0x96, 0x9a, 0xf7, 0xde, 0x68, 0xcd, 0xb1, 0x56, 0x32, 0x7f, 0x91, 0x00, 0x03, 0x93, + 0x23, 0xbe, 0x4f, 0x87, 0x87, 0x34, 0x68, 0x73, 0xc2, 0xc7, 0x21, 0xba, 0x05, 0x59, 0x8f, 0x12, + 0x87, 0x06, 0x72, 0x92, 0x39, 0xac, 0x5b, 0xa8, 0x2b, 0x82, 0x9c, 0xd8, 0x03, 0x72, 0xe8, 0x7a, + 0x2e, 0x9f, 0xc8, 0x69, 0xae, 0x2f, 0xdf, 0xe5, 0x45, 0x9b, 0x15, 0x3c, 0xa3, 0x88, 0xe7, 0xcc, + 0xa0, 0x0d, 0x58, 0x1d, 0xd2, 0x30, 0x24, 0x7d, 0x2a, 0x67, 0x9f, 0xc7, 0x51, 0xd3, 0x7c, 0x08, + 0xc5, 0x59, 0x3d, 0x54, 0x80, 0xd5, 0x6e, 0xf3, 0x49, 0xf3, 0xe0, 0x59, 0xd3, 0x58, 0x41, 0xd7, + 0xa0, 0xd0, 0x6d, 0xe2, 0xba, 0x55, 0x7d, 0x6c, 0xed, 0xec, 0xd5, 0x8d, 0x04, 0x5a, 0x83, 0xfc, + 0xb4, 0x99, 0x34, 0x7f, 0x96, 0x00, 0x10, 0x1b, 0xa8, 0x27, 0xf5, 0x19, 0x64, 0x42, 0x4e, 0xb8, + 0xda, 0xb8, 0xf5, 0xed, 0xf7, 0x96, 0x79, 0x3d, 0x85, 0x57, 0xc4, 0x0f, 0xc5, 0x4a, 0x65, 0xd6, + 0xc3, 0xe4, 0xa2, 0x87, 0x19, 0x89, 0x9c, 0x77, 0x2d, 0x07, 0xe9, 0x9a, 0xf8, 0x4a, 0xa0, 0x3c, + 0x64, 0x70, 0xdd, 0xaa, 0x7d, 0x69, 0x24, 0x91, 0x01, 0xc5, 0x5a, 0xa3, 0x5d, 0x3d, 0x68, 0x36, + 0xeb, 0xd5, 0x4e, 0xbd, 0x66, 0xa4, 0xcc, 0x7b, 0x90, 0x69, 0x0c, 0x49, 0x9f, 0xa2, 0x3b, 0x22, + 0x02, 0x8e, 0x68, 0x40, 0x7d, 0x3b, 0x0a, 0xac, 0xa9, 0xc0, 0xfc, 0x79, 0x1e, 0x32, 0xfb, 0x6c, + 0xec, 0x73, 0xb4, 0x3d, 0x73, 0x8a, 0xd7, 0xb7, 0x37, 0x97, 0x4d, 0x41, 0x02, 0x2b, 0x9d, 0xc9, + 0x88, 0xea, 0x53, 0x7e, 0x0b, 0xb2, 0x2a, 0x56, 0xb4, 0xeb, 0xba, 0x25, 0xe4, 0x9c, 0x04, 0x7d, + 0xca, 0xf5, 0xa2, 0xeb, 0x16, 0xba, 0x0f, 0xb9, 0x80, 0x12, 0x87, 0xf9, 0xde, 0x44, 0x86, 0x54, + 0x4e, 0xa5, 0x59, 0x4c, 0x89, 0x73, 0xe0, 0x7b, 0x13, 0x1c, 0xf7, 0xa2, 0xc7, 0x50, 0x3c, 0x74, + 0x7d, 0xa7, 0xc7, 0x46, 0x2a, 0xe7, 0x65, 0x5e, 0x1f, 0x80, 0xca, 0xab, 0x1d, 0xd7, 0x77, 0x0e, + 0x14, 0x18, 0x17, 0x0e, 0xa7, 0x0d, 0xd4, 0x84, 0xf5, 0x13, 0xe6, 0x8d, 0x87, 0x34, 0xb6, 0x95, + 0x95, 0xb6, 0xde, 0x7f, 0xbd, 0xad, 0xa7, 0x12, 0x1f, 0x59, 0x5b, 0x3b, 0x99, 0x6d, 0xa2, 0x27, + 0xb0, 0xc6, 0x87, 0xa3, 0xa3, 0x30, 0x36, 0xb7, 0x2a, 0xcd, 0x7d, 0xff, 0x8a, 0x05, 0x13, 0xf0, + 0xc8, 0x5a, 0x91, 0xcf, 0xb4, 0x4a, 0x7f, 0x96, 0x82, 0xc2, 0x8c, 0xe7, 0xa8, 0x0d, 0x85, 0x51, + 0xc0, 0x46, 0xa4, 0x2f, 0xf3, 0xb6, 0xde, 0x8b, 0x4f, 0xde, 0x68, 0xd6, 0x95, 0xd6, 0x54, 0x11, + 0xcf, 0x5a, 0x31, 0xcf, 0x93, 0x50, 0x98, 0xe9, 0x44, 0x1f, 0x40, 0x0e, 0xb7, 0x70, 0xe3, 0xa9, + 0xd5, 0xa9, 0x1b, 0x2b, 0xa5, 0x3b, 0x67, 0xe7, 0xe5, 0x0d, 0x69, 0x6d, 0xd6, 0x40, 0x2b, 0x70, + 0x4f, 0x44, 0xe8, 0xdd, 0x87, 0xd5, 0x08, 0x9a, 0x28, 0xbd, 0x7d, 0x76, 0x5e, 0x7e, 0x6b, 0x11, + 0x3a, 0x83, 0xc4, 0xed, 0xc7, 0x16, 0xae, 0xd7, 0x8c, 0xe4, 0x72, 0x24, 0x6e, 0x0f, 0x48, 0x40, + 0x1d, 0xf4, 0x7d, 0xc8, 0x6a, 0x60, 0xaa, 0x54, 0x3a, 0x3b, 0x2f, 0xdf, 0x5a, 0x04, 0x4e, 0x71, + 0xb8, 0xbd, 0x67, 0x3d, 0xad, 0x1b, 0xe9, 0xe5, 0x38, 0xdc, 0xf6, 0xc8, 0x09, 0x45, 0xef, 0x41, + 0x46, 0xc1, 0x32, 0xa5, 0xdb, 0x67, 0xe7, 0xe5, 0xef, 0xbd, 0x62, 0x4e, 0xa0, 0x4a, 0x1b, 0x7f, + 0xf1, 0x37, 0x9b, 0x2b, 0xff, 0xf4, 0xb7, 0x9b, 0xc6, 0x62, 0x77, 0xe9, 0x7f, 0x13, 0xb0, 0x36, + 0xb7, 0xe5, 0xc8, 0x84, 0xac, 0xcf, 0x6c, 0x36, 0x52, 0xe9, 0x3c, 0xb7, 0x03, 0x97, 0x17, 0x5b, + 0xd9, 0x26, 0xab, 0xb2, 0xd1, 0x04, 0xeb, 0x1e, 0xf4, 0x64, 0xe1, 0x42, 0xfa, 0xf4, 0x0d, 0xe3, + 0x69, 0xe9, 0x95, 0xf4, 0x39, 0xac, 0x39, 0x81, 0x7b, 0x42, 0x83, 0x9e, 0xcd, 0xfc, 0x23, 0xb7, + 0xaf, 0x53, 0x75, 0x69, 0x99, 0xcd, 0x9a, 0x04, 0xe2, 0xa2, 0x52, 0xa8, 0x4a, 0xfc, 0xaf, 0x71, + 0x19, 0x95, 0x9e, 0x42, 0x71, 0x36, 0x42, 0xd1, 0x3b, 0x00, 0xa1, 0xfb, 0x47, 0x54, 0xf3, 0x1b, + 0xc9, 0x86, 0x70, 0x5e, 0x48, 0x24, 0xbb, 0x41, 0xef, 0x43, 0x7a, 0xc8, 0x1c, 0x65, 0x27, 0xb3, + 0x73, 0x43, 0xdc, 0x89, 0xff, 0x76, 0xb1, 0x55, 0x60, 0x61, 0x65, 0xd7, 0xf5, 0xe8, 0x3e, 0x73, + 0x28, 0x96, 0x00, 0xf3, 0x04, 0xd2, 0x22, 0x55, 0xa0, 0xb7, 0x21, 0xbd, 0xd3, 0x68, 0xd6, 0x8c, + 0x95, 0xd2, 0xf5, 0xb3, 0xf3, 0xf2, 0x9a, 0x5c, 0x12, 0xd1, 0x21, 0x62, 0x17, 0x6d, 0x41, 0xf6, + 0xe9, 0xc1, 0x5e, 0x77, 0x5f, 0x84, 0xd7, 0x8d, 0xb3, 0xf3, 0xf2, 0xb5, 0xb8, 0x5b, 0x2d, 0x1a, + 0x7a, 0x07, 0x32, 0x9d, 0xfd, 0xd6, 0x6e, 0xdb, 0x48, 0x96, 0xd0, 0xd9, 0x79, 0x79, 0x3d, 0xee, + 0x97, 0x3e, 0x97, 0xae, 0xeb, 0x5d, 0xcd, 0xc7, 0x72, 0xf3, 0x7f, 0x92, 0xb0, 0x86, 0x05, 0xbf, + 0x0d, 0x78, 0x8b, 0x79, 0xae, 0x3d, 0x41, 0x2d, 0xc8, 0xdb, 0xcc, 0x77, 0xdc, 0x99, 0x33, 0xb5, + 0xfd, 0x9a, 0x4b, 0x70, 0xaa, 0x15, 0xb5, 0xaa, 0x91, 0x26, 0x9e, 0x1a, 0x41, 0xdb, 0x90, 0x71, + 0xa8, 0x47, 0x26, 0x57, 0xdd, 0xc6, 0x35, 0xcd, 0xa5, 0xb1, 0x82, 0x4a, 0xe6, 0x48, 0x9e, 0xf7, + 0x08, 0xe7, 0x74, 0x38, 0xe2, 0xea, 0x36, 0x4e, 0xe3, 0xc2, 0x90, 0x3c, 0xb7, 0xb4, 0x08, 0xfd, + 0x08, 0xb2, 0xa7, 0xae, 0xef, 0xb0, 0x53, 0x7d, 0xe1, 0x5e, 0x6d, 0x57, 0x63, 0xcd, 0x33, 0x71, + 0xcf, 0x2e, 0x38, 0x2b, 0x56, 0xbd, 0x79, 0xd0, 0xac, 0x47, 0xab, 0xae, 0xfb, 0x0f, 0xfc, 0x26, + 0xf3, 0xc5, 0x89, 0x81, 0x83, 0x66, 0x6f, 0xd7, 0x6a, 0xec, 0x75, 0xb1, 0x58, 0xf9, 0x9b, 0x67, + 0xe7, 0x65, 0x23, 0x86, 0xec, 0x12, 0xd7, 0x13, 0x24, 0xf0, 0x36, 0xa4, 0xac, 0xe6, 0x97, 0x46, + 0xb2, 0x64, 0x9c, 0x9d, 0x97, 0x8b, 0x71, 0xb7, 0xe5, 0x4f, 0xa6, 0x87, 0x69, 0x71, 0x5c, 0xf3, + 0xbf, 0x12, 0x50, 0xec, 0x8e, 0x1c, 0xc2, 0xa9, 0x8a, 0x4c, 0x54, 0x86, 0xc2, 0x88, 0x04, 0xc4, + 0xf3, 0xa8, 0xe7, 0x86, 0x43, 0x5d, 0x28, 0xcc, 0x8a, 0xd0, 0x83, 0xef, 0xb0, 0x98, 0x9a, 0x84, + 0xe9, 0x25, 0xed, 0xc2, 0xfa, 0x91, 0x72, 0xb6, 0x47, 0x6c, 0xb9, 0xbb, 0x29, 0xb9, 0xbb, 0x95, + 0x65, 0x26, 0x66, 0xbd, 0xaa, 0xe8, 0x39, 0x5a, 0x52, 0x0b, 0xaf, 0x1d, 0xcd, 0x36, 0xcd, 0xfb, + 0xb0, 0x36, 0xd7, 0x2f, 0x6e, 0xda, 0x96, 0xd5, 0x6d, 0xd7, 0x8d, 0x15, 0x54, 0x84, 0x5c, 0xf5, + 0xa0, 0xd9, 0x69, 0x34, 0xbb, 0x75, 0x23, 0x61, 0xfe, 0x43, 0x32, 0x9a, 0xad, 0x66, 0x02, 0x3b, + 0xf3, 0x4c, 0xe0, 0xc3, 0xd7, 0x3b, 0xa2, 0xb9, 0xc0, 0xb4, 0x11, 0x33, 0x82, 0xdf, 0x05, 0x90, + 0x8b, 0x4a, 0x9d, 0x1e, 0xe1, 0x57, 0xb1, 0xfd, 0x4e, 0x54, 0xc7, 0xe1, 0xbc, 0x56, 0xb0, 0x38, + 0xfa, 0x02, 0x8a, 0x36, 0x1b, 0x8e, 0x3c, 0xaa, 0xf5, 0x53, 0x6f, 0xa2, 0x5f, 0x88, 0x55, 0x2c, + 0x3e, 0xcb, 0x48, 0xd2, 0xf3, 0x8c, 0xa4, 0x0a, 0x85, 0x19, 0x7f, 0xe7, 0x79, 0x49, 0x11, 0x72, + 0xdd, 0x56, 0xcd, 0xea, 0x34, 0x9a, 0x8f, 0x8c, 0x04, 0x02, 0xc8, 0xca, 0x15, 0xab, 0x19, 0x49, + 0xc1, 0x9d, 0xaa, 0x07, 0xfb, 0xad, 0xbd, 0xba, 0x62, 0x26, 0x7f, 0x02, 0xd7, 0xaa, 0xcc, 0xe7, + 0xc4, 0xf5, 0x63, 0x52, 0xb8, 0x2d, 0x7c, 0xd6, 0xa2, 0x9e, 0xeb, 0xa8, 0xbc, 0xb5, 0x73, 0xed, + 0xf2, 0x62, 0xab, 0x10, 0x43, 0x1b, 0x35, 0xe1, 0x65, 0xd4, 0x70, 0x44, 0x74, 0x8e, 0x5c, 0x47, + 0xa7, 0xa1, 0xd5, 0xcb, 0x8b, 0xad, 0x54, 0xab, 0x51, 0xc3, 0x42, 0x86, 0xde, 0x86, 0x3c, 0x7d, + 0xee, 0xf2, 0x9e, 0x2d, 0xf2, 0x94, 0x98, 0x7f, 0x06, 0xe7, 0x84, 0xa0, 0x2a, 0xd2, 0xd2, 0x9f, + 0x26, 0x01, 0x3a, 0x24, 0x3c, 0xd6, 0x43, 0x3f, 0x84, 0x7c, 0x5c, 0x0e, 0x5f, 0x55, 0x96, 0xcd, + 0xac, 0x75, 0x8c, 0x47, 0x9f, 0x46, 0xbb, 0xad, 0xd8, 0xea, 0x72, 0x45, 0x3d, 0xd6, 0x32, 0xc2, + 0x37, 0x4f, 0x49, 0x45, 0xd6, 0xa6, 0x41, 0xa0, 0x17, 0x5d, 0x7c, 0xa2, 0xaa, 0xcc, 0x5c, 0x6a, + 0xce, 0x9a, 0x03, 0xdd, 0x5d, 0x36, 0xc8, 0xc2, 0x82, 0x3e, 0x5e, 0xc1, 0x53, 0xbd, 0x1d, 0x03, + 0xd6, 0x83, 0xb1, 0x2f, 0xbc, 0xee, 0x85, 0xb2, 0xdb, 0x74, 0xe1, 0xad, 0x26, 0xe5, 0xa7, 0x2c, + 0x38, 0xb6, 0x38, 0x27, 0xf6, 0x40, 0x94, 0xa7, 0xfa, 0xb8, 0x4e, 0xa9, 0x5b, 0x62, 0x8e, 0xba, + 0x6d, 0xc0, 0x2a, 0xf1, 0x5c, 0x12, 0x52, 0x75, 0xdf, 0xe5, 0x71, 0xd4, 0x14, 0x04, 0x93, 0x38, + 0x4e, 0x40, 0xc3, 0x90, 0xaa, 0x82, 0x2a, 0x8f, 0xa7, 0x02, 0xf3, 0x5f, 0x92, 0x00, 0x8d, 0x96, + 0xb5, 0xaf, 0xcd, 0xd7, 0x20, 0x7b, 0x44, 0x86, 0xae, 0x37, 0xb9, 0xea, 0x80, 0x4c, 0xf1, 0x15, + 0x4b, 0x19, 0xda, 0x95, 0x3a, 0x58, 0xeb, 0x4a, 0xde, 0x39, 0x3e, 0xf4, 0x29, 0x8f, 0x79, 0xa7, + 0x6c, 0x89, 0x4b, 0x2e, 0x20, 0x7e, 0xbc, 0xb0, 0xaa, 0x21, 0x5c, 0xef, 0x13, 0x4e, 0x4f, 0xc9, + 0x24, 0x8a, 0x67, 0xdd, 0x44, 0x8f, 0x05, 0x1f, 0x15, 0x65, 0x32, 0x75, 0x36, 0x32, 0xf2, 0x16, + 0xff, 0x36, 0x7f, 0xb0, 0x86, 0xab, 0xeb, 0x3b, 0xd6, 0x2e, 0x3d, 0x94, 0x77, 0xce, 0xb4, 0xeb, + 0x3b, 0x95, 0x83, 0x1f, 0xc3, 0xda, 0xdc, 0x3c, 0x5f, 0x21, 0xfc, 0x8d, 0xd6, 0xd3, 0x1f, 0x19, + 0x69, 0xfd, 0xf5, 0x3b, 0x46, 0xd6, 0xfc, 0xef, 0x04, 0x40, 0x8b, 0x05, 0xd1, 0xa6, 0x2d, 0x7f, + 0x60, 0xc9, 0xc9, 0xe7, 0x1a, 0x9b, 0x79, 0x3a, 0x3c, 0x97, 0x32, 0xde, 0xa9, 0x15, 0x41, 0x20, + 0x25, 0x1c, 0xc7, 0x8a, 0x68, 0x0b, 0x0a, 0x6a, 0xff, 0x7b, 0x23, 0x16, 0xa8, 0x5c, 0xb2, 0x86, + 0x41, 0x89, 0x84, 0xa6, 0xa8, 0xde, 0x47, 0xe3, 0x43, 0xcf, 0x0d, 0x07, 0xd4, 0x51, 0x98, 0xb4, + 0xc4, 0xac, 0xc5, 0x52, 0x01, 0x33, 0x6b, 0x90, 0x8b, 0xac, 0xa3, 0x0d, 0x48, 0x75, 0xaa, 0x2d, + 0x63, 0xa5, 0x74, 0xed, 0xec, 0xbc, 0x5c, 0x88, 0xc4, 0x9d, 0x6a, 0x4b, 0xf4, 0x74, 0x6b, 0x2d, + 0x23, 0x31, 0xdf, 0xd3, 0xad, 0xb5, 0x4a, 0x69, 0x71, 0xdf, 0x98, 0x7f, 0x95, 0x80, 0xac, 0x62, + 0x3f, 0x4b, 0x67, 0x6c, 0xc1, 0x6a, 0xc4, 0xc9, 0x15, 0x25, 0x7b, 0xff, 0xf5, 0xf4, 0xa9, 0xa2, + 0xd9, 0x8e, 0xda, 0xc7, 0x48, 0xaf, 0xf4, 0x19, 0x14, 0x67, 0x3b, 0xbe, 0xd3, 0x2e, 0xfe, 0x31, + 0x14, 0x44, 0xa0, 0x44, 0x34, 0x6a, 0x1b, 0xb2, 0x8a, 0xa1, 0xe9, 0xac, 0x72, 0x15, 0x97, 0xd3, + 0x48, 0xf4, 0x00, 0x56, 0x15, 0xff, 0x8b, 0x5e, 0x26, 0x36, 0xaf, 0x0e, 0x47, 0x1c, 0xc1, 0xcd, + 0xcf, 0x21, 0xdd, 0xa2, 0x34, 0x40, 0x77, 0x61, 0xd5, 0x67, 0x0e, 0x9d, 0x26, 0x51, 0x4d, 0x5d, + 0x1d, 0xda, 0xa8, 0x09, 0xea, 0xea, 0xd0, 0x86, 0x23, 0x16, 0x4f, 0x1c, 0xd0, 0xe8, 0x71, 0x46, + 0x7c, 0x9b, 0x1d, 0x28, 0x3e, 0xa3, 0x6e, 0x7f, 0xc0, 0xa9, 0x23, 0x0d, 0x7d, 0x08, 0xe9, 0x11, + 0x8d, 0x9d, 0xdf, 0x58, 0x1a, 0x3a, 0x94, 0x06, 0x58, 0xa2, 0xc4, 0x81, 0x3c, 0x95, 0xda, 0xfa, + 0x3d, 0x4c, 0xb7, 0xcc, 0xbf, 0x4f, 0xc2, 0x7a, 0x23, 0x0c, 0xc7, 0xc4, 0xb7, 0xa3, 0x1b, 0xf2, + 0x27, 0xf3, 0x37, 0xe4, 0xfd, 0xa5, 0x33, 0x9c, 0x53, 0x99, 0xaf, 0x97, 0x75, 0x92, 0x4c, 0xc6, + 0x49, 0xd2, 0xfc, 0x3a, 0x11, 0x15, 0xca, 0xf7, 0x66, 0xce, 0x4d, 0x69, 0xe3, 0xec, 0xbc, 0x7c, + 0x73, 0xd6, 0x12, 0xed, 0xfa, 0xc7, 0x3e, 0x3b, 0xf5, 0xd1, 0xbb, 0xa2, 0x70, 0x6e, 0xd6, 0x9f, + 0x19, 0x89, 0xd2, 0xad, 0xb3, 0xf3, 0x32, 0x9a, 0x03, 0x61, 0xea, 0xd3, 0x53, 0x61, 0xa9, 0x55, + 0x6f, 0xd6, 0xc4, 0x65, 0x96, 0x5c, 0x62, 0xa9, 0x45, 0x7d, 0xc7, 0xf5, 0xfb, 0xe8, 0x2e, 0x64, + 0x1b, 0xed, 0x76, 0x57, 0x96, 0x32, 0x6f, 0x9d, 0x9d, 0x97, 0x6f, 0xcc, 0xa1, 0x44, 0x83, 0x3a, + 0x02, 0x24, 0xa8, 0x56, 0xbd, 0x66, 0xa4, 0x97, 0x80, 0x04, 0xd3, 0xa0, 0x8e, 0x8e, 0xf0, 0x7f, + 0x4f, 0x82, 0x61, 0xd9, 0x36, 0x1d, 0x71, 0xd1, 0xaf, 0xe9, 0x6b, 0x07, 0x72, 0x23, 0xf1, 0xe5, + 0x4a, 0x3a, 0x2e, 0xc2, 0xe2, 0xc1, 0xd2, 0xc7, 0xd2, 0x05, 0xbd, 0x0a, 0x66, 0x1e, 0xb5, 0x9c, + 0xa1, 0x1b, 0x86, 0xa2, 0x4c, 0x93, 0x32, 0x1c, 0x5b, 0x2a, 0xfd, 0x32, 0x01, 0x37, 0x96, 0x20, + 0xd0, 0xc7, 0x90, 0x0e, 0x98, 0x17, 0x6d, 0xcf, 0x9d, 0xd7, 0x3d, 0x65, 0x08, 0x55, 0x2c, 0x91, + 0x68, 0x13, 0x80, 0x8c, 0x39, 0x23, 0x72, 0x7c, 0xb9, 0x31, 0x39, 0x3c, 0x23, 0x41, 0xcf, 0x20, + 0x1b, 0x52, 0x3b, 0xa0, 0x11, 0x17, 0xf9, 0xfc, 0xff, 0xeb, 0x7d, 0xa5, 0x2d, 0xcd, 0x60, 0x6d, + 0xae, 0x54, 0x81, 0xac, 0x92, 0x88, 0x88, 0x76, 0x08, 0x27, 0xd2, 0xe9, 0x22, 0x96, 0xdf, 0x22, + 0x50, 0x88, 0xd7, 0x8f, 0x02, 0x85, 0x78, 0x7d, 0xf3, 0x67, 0x49, 0x80, 0xfa, 0x73, 0x4e, 0x03, + 0x9f, 0x78, 0x55, 0x0b, 0xd5, 0x67, 0x32, 0xa4, 0x9a, 0xed, 0x0f, 0x96, 0x3e, 0x70, 0xc5, 0x1a, + 0x95, 0xaa, 0xb5, 0x24, 0x47, 0xde, 0x86, 0xd4, 0x38, 0xf0, 0xf4, 0x63, 0xa9, 0x24, 0x22, 0x5d, + 0xbc, 0x87, 0x85, 0x0c, 0xd5, 0xa7, 0x19, 0x29, 0xf5, 0xfa, 0x57, 0xee, 0x99, 0x01, 0x7e, 0xf3, + 0x59, 0xe9, 0x43, 0x80, 0xa9, 0xd7, 0x68, 0x13, 0x32, 0xd5, 0xdd, 0x76, 0x7b, 0xcf, 0x58, 0x51, + 0xd5, 0xd6, 0xb4, 0x4b, 0x8a, 0xcd, 0xbf, 0x4b, 0x40, 0xae, 0x6a, 0xe9, 0x5b, 0x65, 0x17, 0x0c, + 0x99, 0x4b, 0x6c, 0x1a, 0xf0, 0x1e, 0x7d, 0x3e, 0x72, 0x83, 0x89, 0x4e, 0x07, 0x57, 0xd7, 0x25, + 0xeb, 0x42, 0xab, 0x4a, 0x03, 0x5e, 0x97, 0x3a, 0x08, 0x43, 0x91, 0xea, 0x29, 0xf6, 0x6c, 0x12, + 0x25, 0xe7, 0xcd, 0xab, 0x97, 0x42, 0xb1, 0xbf, 0x69, 0x3b, 0xc4, 0x85, 0xc8, 0x48, 0x95, 0x84, + 0xe6, 0x53, 0xb8, 0x71, 0x10, 0xd8, 0x03, 0x1a, 0x72, 0x35, 0xa8, 0x76, 0xf9, 0x73, 0xb8, 0xc3, + 0x49, 0x78, 0xdc, 0x1b, 0xb8, 0x21, 0x67, 0xc1, 0xa4, 0x17, 0x50, 0x4e, 0x7d, 0xd1, 0xdf, 0x93, + 0x6f, 0xe9, 0xba, 0x9a, 0xbd, 0x2d, 0x30, 0x8f, 0x15, 0x04, 0x47, 0x88, 0x3d, 0x01, 0x30, 0x1b, + 0x50, 0x14, 0x84, 0xad, 0x46, 0x8f, 0xc8, 0xd8, 0xe3, 0x21, 0xfa, 0x31, 0x80, 0xc7, 0xfa, 0xbd, + 0x37, 0xce, 0xe4, 0x79, 0x8f, 0xf5, 0xd5, 0xa7, 0xf9, 0xfb, 0x60, 0xd4, 0xdc, 0x70, 0x44, 0xb8, + 0x3d, 0x88, 0xca, 0x74, 0xf4, 0x08, 0x8c, 0x01, 0x25, 0x01, 0x3f, 0xa4, 0x84, 0xf7, 0x46, 0x34, + 0x70, 0x99, 0xf3, 0x46, 0x4b, 0x7a, 0x2d, 0xd6, 0x6a, 0x49, 0x25, 0xf3, 0x57, 0x09, 0x00, 0x4c, + 0x8e, 0x22, 0x02, 0xf0, 0x43, 0xb8, 0x1e, 0xfa, 0x64, 0x14, 0x0e, 0x18, 0xef, 0xb9, 0x3e, 0xa7, + 0xc1, 0x09, 0xf1, 0x74, 0xa9, 0x65, 0x44, 0x1d, 0x0d, 0x2d, 0x47, 0x1f, 0x02, 0x3a, 0xa6, 0x74, + 0xd4, 0x63, 0x9e, 0xd3, 0x8b, 0x3a, 0xd5, 0x63, 0x7f, 0x1a, 0x1b, 0xa2, 0xe7, 0xc0, 0x73, 0xda, + 0x91, 0x1c, 0xed, 0xc0, 0xa6, 0x58, 0x01, 0xea, 0xf3, 0xc0, 0xa5, 0x61, 0xef, 0x88, 0x05, 0xbd, + 0xd0, 0x63, 0xa7, 0xbd, 0x23, 0xe6, 0x79, 0xec, 0x94, 0x06, 0x51, 0x21, 0x5b, 0xf2, 0x58, 0xbf, + 0xae, 0x40, 0xbb, 0x2c, 0x68, 0x7b, 0xec, 0x74, 0x37, 0x42, 0x08, 0x96, 0x30, 0x9d, 0x36, 0x77, + 0xed, 0xe3, 0x88, 0x25, 0xc4, 0xd2, 0x8e, 0x6b, 0x1f, 0xa3, 0xbb, 0xb0, 0x46, 0x3d, 0x2a, 0x4b, + 0x2e, 0x85, 0xca, 0x48, 0x54, 0x31, 0x12, 0x0a, 0x90, 0xf9, 0x5b, 0x90, 0x6f, 0x79, 0xc4, 0x96, + 0x7f, 0xa9, 0x88, 0xe2, 0xd2, 0x66, 0xbe, 0x08, 0x02, 0xd7, 0xe7, 0x2a, 0x3b, 0xe6, 0xf1, 0xac, + 0xc8, 0xfc, 0x09, 0xc0, 0x4f, 0x99, 0xeb, 0x77, 0xd8, 0x31, 0xf5, 0xe5, 0xeb, 0xb3, 0x60, 0xbd, + 0x7a, 0x2b, 0xf3, 0x58, 0xb7, 0x24, 0x27, 0x27, 0x3e, 0xe9, 0xd3, 0x20, 0x7e, 0x84, 0x55, 0x4d, + 0x71, 0xb9, 0x64, 0x31, 0x63, 0xbc, 0x6a, 0xa1, 0x32, 0x64, 0x6d, 0xd2, 0x8b, 0x4e, 0x5e, 0x71, + 0x27, 0x7f, 0x79, 0xb1, 0x95, 0xa9, 0x5a, 0x4f, 0xe8, 0x04, 0x67, 0x6c, 0xf2, 0x84, 0x4e, 0xc4, + 0xed, 0x6b, 0x13, 0x79, 0x5e, 0xa4, 0x99, 0xa2, 0xba, 0x7d, 0xab, 0x96, 0x38, 0x0c, 0x38, 0x6b, + 0x13, 0xf1, 0x8b, 0x3e, 0x86, 0xa2, 0x06, 0xf5, 0x06, 0x24, 0x1c, 0x28, 0xae, 0xba, 0xb3, 0x7e, + 0x79, 0xb1, 0x05, 0x0a, 0xf9, 0x98, 0x84, 0x03, 0x0c, 0x0a, 0x2d, 0xbe, 0x51, 0x1d, 0x0a, 0x5f, + 0x31, 0xd7, 0xef, 0x71, 0x39, 0x09, 0xfd, 0x36, 0xb0, 0xf4, 0xfc, 0x4c, 0xa7, 0xaa, 0x0b, 0x65, + 0xf8, 0x2a, 0x96, 0x98, 0xff, 0x9a, 0x80, 0x82, 0xb0, 0xe9, 0x1e, 0xb9, 0xb6, 0xb8, 0x2d, 0xbf, + 0x7b, 0xa6, 0xbf, 0x0d, 0x29, 0x3b, 0x0c, 0xf4, 0xdc, 0x64, 0xaa, 0xab, 0xb6, 0x31, 0x16, 0x32, + 0xf4, 0x05, 0x64, 0x55, 0x71, 0xa1, 0x93, 0xbc, 0xf9, 0xed, 0xf7, 0xba, 0x76, 0x51, 0xeb, 0xc9, + 0xbd, 0x9c, 0x7a, 0x27, 0x67, 0x59, 0xc4, 0xb3, 0x22, 0x74, 0x0b, 0x92, 0xb6, 0x2f, 0x83, 0x42, + 0xff, 0x2b, 0x55, 0x6d, 0xe2, 0xa4, 0xed, 0x9b, 0xff, 0x9c, 0x80, 0xb5, 0xba, 0x6f, 0x07, 0x13, + 0x99, 0x24, 0xc5, 0x46, 0xdc, 0x81, 0x7c, 0x38, 0x3e, 0x0c, 0x27, 0x21, 0xa7, 0xc3, 0xe8, 0xd1, + 0x3b, 0x16, 0xa0, 0x06, 0xe4, 0x89, 0xd7, 0x67, 0x81, 0xcb, 0x07, 0x43, 0xcd, 0x8d, 0x97, 0x27, + 0xe6, 0x59, 0x9b, 0x15, 0x2b, 0x52, 0xc1, 0x53, 0xed, 0x28, 0x15, 0xa7, 0xa4, 0xb3, 0x32, 0x15, + 0xbf, 0x0b, 0x45, 0x8f, 0x0c, 0x05, 0x15, 0xee, 0x89, 0x92, 0x4b, 0xce, 0x23, 0x8d, 0x0b, 0x5a, + 0x26, 0xca, 0x48, 0xd3, 0x84, 0x7c, 0x6c, 0x0c, 0x5d, 0x83, 0x82, 0x55, 0x6f, 0xf7, 0x3e, 0xd9, + 0x7e, 0xd0, 0x7b, 0x54, 0xdd, 0x37, 0x56, 0x34, 0x13, 0xf8, 0xc7, 0x04, 0xac, 0xed, 0xab, 0x18, + 0xd4, 0xc4, 0xe9, 0x2e, 0xac, 0x06, 0xe4, 0x88, 0x47, 0xd4, 0x2e, 0xad, 0x82, 0x4b, 0x24, 0x01, + 0x41, 0xed, 0x44, 0xd7, 0x72, 0x6a, 0x37, 0xf3, 0x97, 0x4b, 0xea, 0xca, 0xbf, 0x5c, 0xd2, 0xbf, + 0x91, 0xbf, 0x5c, 0x3e, 0xf8, 0x55, 0x0a, 0xf2, 0x71, 0xd1, 0x2b, 0x42, 0x46, 0x30, 0xad, 0x15, + 0xf5, 0x88, 0x14, 0xcb, 0x9b, 0x92, 0x63, 0xe5, 0xad, 0xbd, 0xbd, 0x83, 0xaa, 0xd5, 0xa9, 0xd7, + 0x8c, 0x2f, 0x14, 0x15, 0x8b, 0x01, 0x96, 0xe7, 0x31, 0xb1, 0xe9, 0x0e, 0x32, 0xa7, 0x54, 0xec, + 0x85, 0x7e, 0xaa, 0x8a, 0x51, 0x11, 0x0f, 0x7b, 0x0f, 0x72, 0x56, 0xbb, 0xdd, 0x78, 0xd4, 0xac, + 0xd7, 0x8c, 0x97, 0x89, 0xd2, 0xf7, 0xce, 0xce, 0xcb, 0xd7, 0xa7, 0xa6, 0xc2, 0xd0, 0xed, 0xfb, + 0xd4, 0x91, 0xa8, 0x6a, 0xb5, 0xde, 0x12, 0xe3, 0xbd, 0x48, 0x2e, 0xa2, 0x24, 0x01, 0x91, 0xcf, + 0xce, 0xf9, 0x16, 0xae, 0xb7, 0x2c, 0x2c, 0x46, 0x7c, 0x99, 0x5c, 0xf0, 0xab, 0x15, 0xd0, 0x11, + 0x09, 0xc4, 0x98, 0x9b, 0xd1, 0xdf, 0x2f, 0x2f, 0x52, 0xea, 0x69, 0x72, 0x5a, 0xe9, 0x53, 0xe2, + 0x4c, 0xc4, 0x68, 0xed, 0x8e, 0x85, 0xe5, 0x83, 0xc8, 0xcb, 0xd4, 0xc2, 0x68, 0x6d, 0x4e, 0x02, + 0x2e, 0xac, 0x98, 0xb0, 0x8a, 0xbb, 0xcd, 0xa6, 0x9c, 0x5d, 0x7a, 0x61, 0x76, 0x78, 0xec, 0xfb, + 0x02, 0x73, 0x0f, 0x72, 0xd1, 0x03, 0x8a, 0xf1, 0x32, 0xbd, 0xe0, 0x50, 0x35, 0x7a, 0xb9, 0x91, + 0x03, 0x3e, 0xee, 0x76, 0xe4, 0xbf, 0x43, 0x2f, 0x32, 0x8b, 0x03, 0x0e, 0xc6, 0xdc, 0x11, 0xe4, + 0xb7, 0x1c, 0xb3, 0xd1, 0x97, 0x19, 0x45, 0x02, 0x62, 0x8c, 0xa2, 0xa2, 0xc2, 0x0e, 0xae, 0xff, + 0x54, 0xfd, 0x91, 0xf4, 0x22, 0xbb, 0x60, 0x07, 0xd3, 0xaf, 0xa8, 0xcd, 0xa9, 0x33, 0x7d, 0x79, + 0x8d, 0xbb, 0x3e, 0xf8, 0x03, 0xc8, 0x45, 0x09, 0x03, 0x6d, 0x42, 0xf6, 0xd9, 0x01, 0x7e, 0x52, + 0xc7, 0xc6, 0x8a, 0x5a, 0x9d, 0xa8, 0xe7, 0x99, 0xca, 0xb8, 0x65, 0x58, 0xdd, 0xb7, 0x9a, 0xd6, + 0xa3, 0x3a, 0x8e, 0x5e, 0x7e, 0x23, 0x80, 0x8e, 0xfa, 0x92, 0xa1, 0x07, 0x88, 0x6d, 0xee, 0xdc, + 0xf9, 0xfa, 0x9b, 0xcd, 0x95, 0x5f, 0x7c, 0xb3, 0xb9, 0xf2, 0xcb, 0x6f, 0x36, 0x13, 0x2f, 0x2e, + 0x37, 0x13, 0x5f, 0x5f, 0x6e, 0x26, 0x7e, 0x7e, 0xb9, 0x99, 0xf8, 0x8f, 0xcb, 0xcd, 0xc4, 0x61, + 0x56, 0x32, 0xb2, 0x4f, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x7d, 0xe8, 0x50, 0x18, 0x0a, 0x21, + 0x00, 0x00, } diff --git a/vendor/src/github.com/docker/swarmkit/api/types.proto b/vendor/src/github.com/docker/swarmkit/api/types.proto index 1a2743111e..61087ada38 100644 --- a/vendor/src/github.com/docker/swarmkit/api/types.proto +++ b/vendor/src/github.com/docker/swarmkit/api/types.proto @@ -407,6 +407,23 @@ message TaskStatus { } } +// NetworkAttachmentConfig specifies how a service should be attached to a particular network. +// +// For now, this is a simple struct, but this can include future information +// instructing Swarm on how this service should work on the particular +// network. +message NetworkAttachmentConfig { + // Target specifies the target network for attachment. This value may be a + // network name or identifier. Only identifiers are supported at this time. + string target = 1; + // Aliases specifies a list of discoverable alternate names for the service on this Target. + repeated string aliases = 2; + // Addresses specifies a list of ipv4 and ipv6 addresses + // preferred. If these addresses are not available then the + // attachment might fail. + repeated string addresses = 3; +} + // IPAMConfig specifies parameters for IP Address Management. message IPAMConfig { // TODO(stevvooe): It may make more sense to manage IPAM and network diff --git a/vendor/src/github.com/docker/swarmkit/ca/certificates.go b/vendor/src/github.com/docker/swarmkit/ca/certificates.go index 31b267527f..5b302bdd2c 100644 --- a/vendor/src/github.com/docker/swarmkit/ca/certificates.go +++ b/vendor/src/github.com/docker/swarmkit/ca/certificates.go @@ -28,7 +28,7 @@ import ( "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/identity" "github.com/docker/swarmkit/ioutils" - "github.com/docker/swarmkit/picker" + "github.com/docker/swarmkit/remotes" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -155,7 +155,7 @@ func (rca *RootCA) IssueAndSaveNewCertificates(paths CertPaths, cn, ou, org stri // RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is // available, or by requesting them from the remote server at remoteAddr. -func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, paths CertPaths, token string, picker *picker.Picker, transport credentials.TransportAuthenticator, nodeInfo chan<- api.IssueNodeCertificateResponse) (*tls.Certificate, error) { +func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, paths CertPaths, token string, remotes remotes.Remotes, transport credentials.TransportAuthenticator, nodeInfo chan<- api.IssueNodeCertificateResponse) (*tls.Certificate, error) { // Create a new key/pair and CSR for the new manager // Write the new CSR and the new key to a temporary location so we can survive crashes on rotation tempPaths := genTempPaths(paths) @@ -170,7 +170,7 @@ func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, paths Cert // responding properly (for example, it may have just been demoted). var signedCert []byte for i := 0; i != 5; i++ { - signedCert, err = GetRemoteSignedCertificate(ctx, csr, token, rca.Pool, picker, transport, nodeInfo) + signedCert, err = GetRemoteSignedCertificate(ctx, csr, token, rca.Pool, remotes, transport, nodeInfo) if err == nil { break } @@ -423,33 +423,38 @@ func GetLocalRootCA(baseDir string) (RootCA, error) { } // GetRemoteCA returns the remote endpoint's CA certificate -func GetRemoteCA(ctx context.Context, d digest.Digest, picker *picker.Picker) (RootCA, error) { - // We need a valid picker to be able to Dial to a remote CA - if picker == nil { - return RootCA{}, fmt.Errorf("valid remote address picker required") - } - +func GetRemoteCA(ctx context.Context, d digest.Digest, r remotes.Remotes) (RootCA, error) { // This TLS Config is intentionally using InsecureSkipVerify. Either we're // doing TOFU, in which case we don't validate the remote CA, or we're using // a user supplied hash to check the integrity of the CA certificate. insecureCreds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}) opts := []grpc.DialOption{ grpc.WithTransportCredentials(insecureCreds), - grpc.WithBackoffMaxDelay(10 * time.Second), - grpc.WithPicker(picker)} + grpc.WithTimeout(5 * time.Second), + grpc.WithBackoffMaxDelay(5 * time.Second), + } - firstAddr, err := picker.PickAddr() + peer, err := r.Select() if err != nil { return RootCA{}, err } - conn, err := grpc.Dial(firstAddr, opts...) + conn, err := grpc.Dial(peer.Addr, opts...) if err != nil { return RootCA{}, err } defer conn.Close() client := api.NewCAClient(conn) + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + defer func() { + if err != nil { + r.Observe(peer, -remotes.DefaultObservationWeight) + return + } + r.Observe(peer, remotes.DefaultObservationWeight) + }() response, err := client.GetRootCACertificate(ctx, &api.GetRootCACertificateRequest{}) if err != nil { return RootCA{}, err @@ -596,16 +601,12 @@ func GenerateAndWriteNewKey(paths CertPaths) (csr, key []byte, err error) { return } -// GetRemoteSignedCertificate submits a CSR to a remote CA server address -// available through a picker, and that is part of a CA identified by a -// specific certificate pool. -func GetRemoteSignedCertificate(ctx context.Context, csr []byte, token string, rootCAPool *x509.CertPool, picker *picker.Picker, creds credentials.TransportAuthenticator, nodeInfo chan<- api.IssueNodeCertificateResponse) ([]byte, error) { +// GetRemoteSignedCertificate submits a CSR to a remote CA server address, +// and that is part of a CA identified by a specific certificate pool. +func GetRemoteSignedCertificate(ctx context.Context, csr []byte, token string, rootCAPool *x509.CertPool, r remotes.Remotes, creds credentials.TransportAuthenticator, nodeInfo chan<- api.IssueNodeCertificateResponse) ([]byte, error) { if rootCAPool == nil { return nil, fmt.Errorf("valid root CA pool required") } - if picker == nil { - return nil, fmt.Errorf("valid remote address picker required") - } if creds == nil { // This is our only non-MTLS request, and it happens when we are boostraping our TLS certs @@ -613,17 +614,18 @@ func GetRemoteSignedCertificate(ctx context.Context, csr []byte, token string, r creds = credentials.NewTLS(&tls.Config{ServerName: CARole, RootCAs: rootCAPool}) } - opts := []grpc.DialOption{ - grpc.WithTransportCredentials(creds), - grpc.WithBackoffMaxDelay(10 * time.Second), - grpc.WithPicker(picker)} - - firstAddr, err := picker.PickAddr() + peer, err := r.Select() if err != nil { return nil, err } - conn, err := grpc.Dial(firstAddr, opts...) + opts := []grpc.DialOption{ + grpc.WithTransportCredentials(creds), + grpc.WithTimeout(5 * time.Second), + grpc.WithBackoffMaxDelay(5 * time.Second), + } + + conn, err := grpc.Dial(peer.Addr, opts...) if err != nil { return nil, err } @@ -655,8 +657,11 @@ func GetRemoteSignedCertificate(ctx context.Context, csr []byte, token string, r // Exponential backoff with Max of 30 seconds to wait for a new retry for { // Send the Request and retrieve the certificate + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() statusResponse, err := caClient.NodeCertificateStatus(ctx, statusRequest) if err != nil { + r.Observe(peer, -remotes.DefaultObservationWeight) return nil, err } @@ -672,6 +677,7 @@ func GetRemoteSignedCertificate(ctx context.Context, csr []byte, token string, r // retry until the certificate gets updated per our // current request. if bytes.Equal(statusResponse.Certificate.CSR, csr) { + r.Observe(peer, remotes.DefaultObservationWeight) return statusResponse.Certificate.Certificate, nil } } diff --git a/vendor/src/github.com/docker/swarmkit/ca/config.go b/vendor/src/github.com/docker/swarmkit/ca/config.go index 33002183e8..43e8f850f6 100644 --- a/vendor/src/github.com/docker/swarmkit/ca/config.go +++ b/vendor/src/github.com/docker/swarmkit/ca/config.go @@ -20,7 +20,7 @@ import ( "github.com/docker/distribution/digest" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/identity" - "github.com/docker/swarmkit/picker" + "github.com/docker/swarmkit/remotes" "golang.org/x/net/context" ) @@ -183,7 +183,7 @@ func getCAHashFromToken(token string) (digest.Digest, error) { // LoadOrCreateSecurityConfig encapsulates the security logic behind joining a cluster. // Every node requires at least a set of TLS certificates with which to join the cluster with. // In the case of a manager, these certificates will be used both for client and server credentials. -func LoadOrCreateSecurityConfig(ctx context.Context, baseCertDir, token, proposedRole string, picker *picker.Picker, nodeInfo chan<- api.IssueNodeCertificateResponse) (*SecurityConfig, error) { +func LoadOrCreateSecurityConfig(ctx context.Context, baseCertDir, token, proposedRole string, remotes remotes.Remotes, nodeInfo chan<- api.IssueNodeCertificateResponse) (*SecurityConfig, error) { paths := NewConfigPaths(baseCertDir) var ( @@ -217,7 +217,7 @@ func LoadOrCreateSecurityConfig(ctx context.Context, baseCertDir, token, propose // just been demoted, for example). for i := 0; i != 5; i++ { - rootCA, err = GetRemoteCA(ctx, d, picker) + rootCA, err = GetRemoteCA(ctx, d, remotes) if err == nil { break } @@ -267,7 +267,7 @@ func LoadOrCreateSecurityConfig(ctx context.Context, baseCertDir, token, propose } else { // There was an error loading our Credentials, let's get a new certificate issued // Last argument is nil because at this point we don't have any valid TLS creds - tlsKeyPair, err = rootCA.RequestAndSaveNewCertificates(ctx, paths.Node, token, picker, nil, nodeInfo) + tlsKeyPair, err = rootCA.RequestAndSaveNewCertificates(ctx, paths.Node, token, remotes, nil, nodeInfo) if err != nil { return nil, err } @@ -300,7 +300,7 @@ func LoadOrCreateSecurityConfig(ctx context.Context, baseCertDir, token, propose // RenewTLSConfig will continuously monitor for the necessity of renewing the local certificates, either by // issuing them locally if key-material is available, or requesting them from a remote CA. -func RenewTLSConfig(ctx context.Context, s *SecurityConfig, baseCertDir string, picker *picker.Picker, renew <-chan struct{}) <-chan CertificateUpdate { +func RenewTLSConfig(ctx context.Context, s *SecurityConfig, baseCertDir string, remotes remotes.Remotes, renew <-chan struct{}) <-chan CertificateUpdate { paths := NewConfigPaths(baseCertDir) updates := make(chan CertificateUpdate) @@ -344,7 +344,7 @@ func RenewTLSConfig(ctx context.Context, s *SecurityConfig, baseCertDir string, tlsKeyPair, err := rootCA.RequestAndSaveNewCertificates(ctx, paths.Node, "", - picker, + remotes, s.ClientTLSCreds, nil) if err != nil { diff --git a/vendor/src/github.com/docker/swarmkit/manager/allocator/network.go b/vendor/src/github.com/docker/swarmkit/manager/allocator/network.go index cdd07f9c39..3e21d425c1 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/allocator/network.go +++ b/vendor/src/github.com/docker/swarmkit/manager/allocator/network.go @@ -165,7 +165,7 @@ func (a *Allocator) doNetworkInit(ctx context.Context) error { nodes, err = store.FindNodes(tx, store.All) }) if err != nil { - return fmt.Errorf("error listing all services in store while trying to allocate during init: %v", err) + return fmt.Errorf("error listing all nodes in store while trying to allocate during init: %v", err) } for _, node := range nodes { @@ -420,9 +420,9 @@ func taskUpdateEndpoint(t *api.Task, endpoint *api.Endpoint) { } func (a *Allocator) taskCreateNetworkAttachments(t *api.Task, s *api.Service) { - // If service is nil or if task network attachments have - // already been filled in no need to do anything else. - if s == nil || len(t.Networks) != 0 { + // If task network attachments have already been filled in no + // need to do anything else. + if len(t.Networks) != 0 { return } @@ -431,19 +431,31 @@ func (a *Allocator) taskCreateNetworkAttachments(t *api.Task, s *api.Service) { // The service to which this task belongs is trying to expose // ports to the external world. Automatically attach the task // to the ingress network. - if s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0 { + if s != nil && s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0 { networks = append(networks, &api.NetworkAttachment{Network: a.netCtx.ingressNetwork}) } a.store.View(func(tx store.ReadTx) { - for _, na := range s.Spec.Networks { + // Always prefer NetworkAttachmentConfig in the TaskSpec + specNetworks := t.Spec.Networks + if len(specNetworks) == 0 && s != nil && len(s.Spec.Networks) != 0 { + specNetworks = s.Spec.Networks + } + + for _, na := range specNetworks { n := store.GetNetwork(tx, na.Target) if n != nil { var aliases []string + var addresses []string + for _, a := range na.Aliases { aliases = append(aliases, a) } - networks = append(networks, &api.NetworkAttachment{Network: n, Aliases: aliases}) + for _, a := range na.Addresses { + addresses = append(addresses, a) + } + + networks = append(networks, &api.NetworkAttachment{Network: n, Aliases: aliases, Addresses: addresses}) } } }) @@ -508,12 +520,12 @@ func (a *Allocator) doTaskAlloc(ctx context.Context, nc *networkContext, ev even return } } - - // Populate network attachments in the task - // based on service spec. - a.taskCreateNetworkAttachments(t, s) } + // Populate network attachments in the task + // based on service spec. + a.taskCreateNetworkAttachments(t, s) + nc.unallocatedTasks[t.ID] = t } diff --git a/vendor/src/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go b/vendor/src/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go index 14aad72ec8..3c352db972 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go +++ b/vendor/src/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go @@ -197,8 +197,14 @@ func (na *NetworkAllocator) ServiceAllocate(s *api.Service) (err error) { } } + // Always prefer NetworkAttachmentConfig in the TaskSpec + specNetworks := s.Spec.Task.Networks + if len(specNetworks) == 0 && s != nil && len(s.Spec.Networks) != 0 { + specNetworks = s.Spec.Networks + } + outer: - for _, nAttach := range s.Spec.Networks { + for _, nAttach := range specNetworks { for _, vip := range s.Endpoint.VirtualIPs { if vip.NetworkID == nAttach.Target { continue outer @@ -286,7 +292,7 @@ func (na *NetworkAllocator) IsTaskAllocated(t *api.Task) bool { func (na *NetworkAllocator) IsServiceAllocated(s *api.Service) bool { // If endpoint mode is VIP and allocator does not have the // service in VIP allocated set then it is not allocated. - if len(s.Spec.Networks) != 0 && + if (len(s.Spec.Task.Networks) != 0 || len(s.Spec.Networks) != 0) && (s.Spec.Endpoint == nil || s.Spec.Endpoint.Mode == api.ResolutionModeVirtualIP) { if _, ok := na.services[s.ID]; !ok { @@ -527,7 +533,11 @@ func (na *NetworkAllocator) allocateNetworkIPs(nAttach *api.NetworkAttachment) e var err error addr, _, err = net.ParseCIDR(rawAddr) if err != nil { - return err + addr = net.ParseIP(rawAddr) + + if addr == nil { + return fmt.Errorf("could not parse address string %s: %v", rawAddr, err) + } } } diff --git a/vendor/src/github.com/docker/swarmkit/manager/controlapi/network.go b/vendor/src/github.com/docker/swarmkit/manager/controlapi/network.go index ec5cfd82e0..953507c650 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/controlapi/network.go +++ b/vendor/src/github.com/docker/swarmkit/manager/controlapi/network.go @@ -171,7 +171,12 @@ func (s *Server) RemoveNetwork(ctx context.Context, request *api.RemoveNetworkRe } for _, s := range services { - for _, na := range s.Spec.Networks { + specNetworks := s.Spec.Task.Networks + if len(specNetworks) == 0 { + specNetworks = s.Spec.Networks + } + + for _, na := range specNetworks { if na.Target == request.NetworkID { return nil, grpc.Errorf(codes.FailedPrecondition, "network %s is in use", request.NetworkID) } diff --git a/vendor/src/github.com/docker/swarmkit/manager/controlapi/service.go b/vendor/src/github.com/docker/swarmkit/manager/controlapi/service.go index 415cdd9344..656533d970 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/controlapi/service.go +++ b/vendor/src/github.com/docker/swarmkit/manager/controlapi/service.go @@ -327,8 +327,20 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe return nil } // temporary disable network update - if request.Spec != nil && !reflect.DeepEqual(request.Spec.Networks, service.Spec.Networks) { - return errNetworkUpdateNotSupported + if request.Spec != nil { + requestSpecNetworks := request.Spec.Task.Networks + if len(requestSpecNetworks) == 0 { + requestSpecNetworks = request.Spec.Networks + } + + specNetworks := service.Spec.Task.Networks + if len(specNetworks) == 0 { + specNetworks = service.Spec.Networks + } + + if !reflect.DeepEqual(requestSpecNetworks, specNetworks) { + return errNetworkUpdateNotSupported + } } // orchestrator is designed to be stateless, so it should not deal diff --git a/vendor/src/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go b/vendor/src/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go index fca8f4c6e8..765651983f 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go +++ b/vendor/src/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go @@ -19,8 +19,8 @@ import ( "github.com/docker/swarmkit/manager/state" "github.com/docker/swarmkit/manager/state/store" "github.com/docker/swarmkit/manager/state/watch" - "github.com/docker/swarmkit/picker" "github.com/docker/swarmkit/protobuf/ptypes" + "github.com/docker/swarmkit/remotes" "golang.org/x/net/context" ) @@ -153,7 +153,7 @@ func getWeightedPeers(cluster Cluster) []*api.WeightedPeer { // TODO(stevvooe): Calculate weight of manager selection based on // cluster-level observations, such as number of connections and // load. - Weight: picker.DefaultObservationWeight, + Weight: remotes.DefaultObservationWeight, }) } return mgrs @@ -209,7 +209,7 @@ func (d *Dispatcher) Run(ctx context.Context) error { for _, p := range peers { mgrs = append(mgrs, &api.WeightedPeer{ Peer: p, - Weight: picker.DefaultObservationWeight, + Weight: remotes.DefaultObservationWeight, }) } d.mu.Lock() @@ -854,7 +854,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio for { // After each message send, we need to check the nodes sessionID hasn't - // changed. If it has, we will the stream and make the node + // changed. If it has, we will shut down the stream and make the node // re-register. node, err := d.nodes.GetWithSession(nodeID, sessionID) if err != nil { diff --git a/vendor/src/github.com/docker/swarmkit/manager/dispatcher/nodes.go b/vendor/src/github.com/docker/swarmkit/manager/dispatcher/nodes.go index aa962a01b1..8a0de558d6 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/dispatcher/nodes.go +++ b/vendor/src/github.com/docker/swarmkit/manager/dispatcher/nodes.go @@ -86,7 +86,7 @@ func (s *nodeStore) AddUnknown(n *api.Node, expireFunc func()) error { return nil } -// CheckRateLimit returs error if node with specified id is allowed to re-register +// CheckRateLimit returns error if node with specified id is allowed to re-register // again. func (s *nodeStore) CheckRateLimit(id string) error { s.mu.Lock() diff --git a/vendor/src/github.com/docker/swarmkit/manager/manager.go b/vendor/src/github.com/docker/swarmkit/manager/manager.go index 0a3332208e..6c95e8ada7 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/manager.go +++ b/vendor/src/github.com/docker/swarmkit/manager/manager.go @@ -24,6 +24,7 @@ import ( "github.com/docker/swarmkit/manager/keymanager" "github.com/docker/swarmkit/manager/orchestrator" "github.com/docker/swarmkit/manager/raftpicker" + "github.com/docker/swarmkit/manager/resourceapi" "github.com/docker/swarmkit/manager/scheduler" "github.com/docker/swarmkit/manager/state/raft" "github.com/docker/swarmkit/manager/state/store" @@ -275,9 +276,12 @@ func (m *Manager) Run(parent context.Context) error { } baseControlAPI := controlapi.NewServer(m.RaftNode.MemoryStore(), m.RaftNode, m.config.SecurityConfig.RootCA()) + baseResourceAPI := resourceapi.New(m.RaftNode.MemoryStore()) healthServer := health.NewHealthServer() + localHealthServer := health.NewHealthServer() authenticatedControlAPI := api.NewAuthenticatedWrapperControlServer(baseControlAPI, authorize) + authenticatedResourceAPI := api.NewAuthenticatedWrapperResourceAllocatorServer(baseResourceAPI, authorize) authenticatedDispatcherAPI := api.NewAuthenticatedWrapperDispatcherServer(m.Dispatcher, authorize) authenticatedCAAPI := api.NewAuthenticatedWrapperCAServer(m.caserver, authorize) authenticatedNodeCAAPI := api.NewAuthenticatedWrapperNodeCAServer(m.caserver, authorize) @@ -289,6 +293,7 @@ func (m *Manager) Run(parent context.Context) error { proxyCAAPI := api.NewRaftProxyCAServer(authenticatedCAAPI, cs, m.RaftNode, ca.WithMetadataForwardTLSInfo) proxyNodeCAAPI := api.NewRaftProxyNodeCAServer(authenticatedNodeCAAPI, cs, m.RaftNode, ca.WithMetadataForwardTLSInfo) proxyRaftMembershipAPI := api.NewRaftProxyRaftMembershipServer(authenticatedRaftMembershipAPI, cs, m.RaftNode, ca.WithMetadataForwardTLSInfo) + proxyResourceAPI := api.NewRaftProxyResourceAllocatorServer(authenticatedResourceAPI, cs, m.RaftNode, ca.WithMetadataForwardTLSInfo) // localProxyControlAPI is a special kind of proxy. It is only wired up // to receive requests from a trusted local socket, and these requests @@ -306,10 +311,13 @@ func (m *Manager) Run(parent context.Context) error { api.RegisterRaftServer(m.server, authenticatedRaftAPI) api.RegisterHealthServer(m.server, authenticatedHealthAPI) api.RegisterRaftMembershipServer(m.server, proxyRaftMembershipAPI) - api.RegisterControlServer(m.localserver, localProxyControlAPI) api.RegisterControlServer(m.server, authenticatedControlAPI) + api.RegisterResourceAllocatorServer(m.server, proxyResourceAPI) api.RegisterDispatcherServer(m.server, proxyDispatcherAPI) + api.RegisterControlServer(m.localserver, localProxyControlAPI) + api.RegisterHealthServer(m.localserver, localHealthServer) + errServe := make(chan error, 2) for proto, l := range m.listeners { go m.serveListener(ctx, errServe, proto, l) @@ -317,11 +325,14 @@ func (m *Manager) Run(parent context.Context) error { // Set the raft server as serving for the health server healthServer.SetServingStatus("Raft", api.HealthCheckResponse_SERVING) + localHealthServer.SetServingStatus("ControlAPI", api.HealthCheckResponse_SERVING) + + defer func() { + m.server.Stop() + m.localserver.Stop() + }() if err := m.RaftNode.JoinAndStart(); err != nil { - for _, lis := range m.listeners { - lis.Close() - } return fmt.Errorf("can't initialize raft node: %v", err) } @@ -336,13 +347,11 @@ func (m *Manager) Run(parent context.Context) error { }() if err := raft.WaitForLeader(ctx, m.RaftNode); err != nil { - m.server.Stop() return err } c, err := raft.WaitForCluster(ctx, m.RaftNode) if err != nil { - m.server.Stop() return err } raftConfig := c.Spec.Raft @@ -527,29 +536,31 @@ func (m *Manager) rotateRootCAKEK(ctx context.Context, clusterID string) error { } -// handleLeadershipEvents reads out and discards all of the messages when the manager is stopped, -// otherwise it handles the is leader event or is follower event. +// handleLeadershipEvents handles the is leader event or is follower event. func (m *Manager) handleLeadershipEvents(ctx context.Context, leadershipCh chan events.Event) { - for leadershipEvent := range leadershipCh { - // read out and discard all of the messages when we've stopped - // don't acquire the mutex yet. if stopped is closed, we don't need - // this stops this loop from starving Run()'s attempt to Lock + for { select { - case <-m.stopped: - continue - default: - // do nothing, we're not stopped - } - // we're not stopping so NOW acquire the mutex - m.mu.Lock() - newState := leadershipEvent.(raft.LeadershipState) + case leadershipEvent := <-leadershipCh: + m.mu.Lock() + select { + case <-m.stopped: + m.mu.Unlock() + return + default: + } + newState := leadershipEvent.(raft.LeadershipState) - if newState == raft.IsLeader { - m.becomeLeader(ctx) - } else if newState == raft.IsFollower { - m.becomeFollower() + if newState == raft.IsLeader { + m.becomeLeader(ctx) + } else if newState == raft.IsFollower { + m.becomeFollower() + } + m.mu.Unlock() + case <-m.stopped: + return + case <-ctx.Done(): + return } - m.mu.Unlock() } } @@ -609,7 +620,7 @@ func (m *Manager) becomeLeader(ctx context.Context) { m.globalOrchestrator = orchestrator.NewGlobalOrchestrator(s) m.taskReaper = orchestrator.NewTaskReaper(s) m.scheduler = scheduler.New(s) - m.keyManager = keymanager.New(m.RaftNode.MemoryStore(), keymanager.DefaultConfig()) + m.keyManager = keymanager.New(s, keymanager.DefaultConfig()) // TODO(stevvooe): Allocate a context that can be used to // shutdown underlying manager processes when leadership is diff --git a/vendor/src/github.com/docker/swarmkit/manager/orchestrator/updater.go b/vendor/src/github.com/docker/swarmkit/manager/orchestrator/updater.go index ba0b35dfc5..97cb2fe328 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/orchestrator/updater.go +++ b/vendor/src/github.com/docker/swarmkit/manager/orchestrator/updater.go @@ -288,16 +288,8 @@ func (u *Updater) updateTask(ctx context.Context, slot slot, updated *api.Task) return err } - u.removeOldTasks(ctx, batch, slot) - - for _, t := range slot { - if t.DesiredState == api.TaskStateRunning { - // Wait for the old task to stop or time out, and then set the new one - // to RUNNING. - delayStartCh = u.restarts.DelayStart(ctx, nil, t, updated.ID, 0, true) - break - } - } + oldTask := u.removeOldTasks(ctx, batch, slot) + delayStartCh = u.restarts.DelayStart(ctx, nil, oldTask, updated.ID, 0, true) return nil @@ -333,34 +325,29 @@ func (u *Updater) useExistingTask(ctx context.Context, slot slot, existing *api. } } if len(removeTasks) != 0 || existing.DesiredState != api.TaskStateRunning { + var delayStartCh <-chan struct{} _, err := u.store.Batch(func(batch *store.Batch) error { - u.removeOldTasks(ctx, batch, removeTasks) + oldTask := u.removeOldTasks(ctx, batch, removeTasks) if existing.DesiredState != api.TaskStateRunning { - err := batch.Update(func(tx store.Tx) error { - t := store.GetTask(tx, existing.ID) - if t == nil { - return fmt.Errorf("task %s not found while trying to start it", existing.ID) - } - if t.DesiredState >= api.TaskStateRunning { - return fmt.Errorf("task %s was already started when reached by updater", existing.ID) - } - t.DesiredState = api.TaskStateRunning - return store.UpdateTask(tx, t) - }) - if err != nil { - log.G(ctx).WithError(err).Errorf("starting task %s failed", existing.ID) - } + delayStartCh = u.restarts.DelayStart(ctx, nil, oldTask, existing.ID, 0, true) } return nil }) if err != nil { log.G(ctx).WithError(err).Error("updater batch transaction failed") } + + if delayStartCh != nil { + <-delayStartCh + } } } -func (u *Updater) removeOldTasks(ctx context.Context, batch *store.Batch, removeTasks []*api.Task) { +// removeOldTasks shuts down the given tasks and returns one of the tasks that +// was shut down, or nil. +func (u *Updater) removeOldTasks(ctx context.Context, batch *store.Batch, removeTasks []*api.Task) *api.Task { + var removedTask *api.Task for _, original := range removeTasks { err := batch.Update(func(tx store.Tx) error { t := store.GetTask(tx, original.ID) @@ -375,8 +362,12 @@ func (u *Updater) removeOldTasks(ctx context.Context, batch *store.Batch, remove }) if err != nil { log.G(ctx).WithError(err).Errorf("shutting down stale task %s failed", original.ID) + } else { + removedTask = original } } + + return removedTask } func (u *Updater) isTaskDirty(t *api.Task) bool { diff --git a/vendor/src/github.com/docker/swarmkit/manager/resourceapi/allocator.go b/vendor/src/github.com/docker/swarmkit/manager/resourceapi/allocator.go new file mode 100644 index 0000000000..87b01ebd3b --- /dev/null +++ b/vendor/src/github.com/docker/swarmkit/manager/resourceapi/allocator.go @@ -0,0 +1,124 @@ +package resourceapi + +import ( + "errors" + "time" + + "github.com/docker/swarmkit/api" + "github.com/docker/swarmkit/ca" + "github.com/docker/swarmkit/identity" + "github.com/docker/swarmkit/manager/state/store" + "github.com/docker/swarmkit/protobuf/ptypes" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" +) + +var ( + errInvalidArgument = errors.New("invalid argument") +) + +// ResourceAllocator handles resource allocation of cluster entities. +type ResourceAllocator struct { + store *store.MemoryStore +} + +// New returns an instance of the allocator +func New(store *store.MemoryStore) *ResourceAllocator { + return &ResourceAllocator{store: store} +} + +// AttachNetwork allows the node to request the resources +// allocation needed for a network attachment on the specific node. +// - Returns `InvalidArgument` if the Spec is malformed. +// - Returns `NotFound` if the Network is not found. +// - Returns `PermissionDenied` if the Network is not manually attachable. +// - Returns an error if the creation fails. +func (ra *ResourceAllocator) AttachNetwork(ctx context.Context, request *api.AttachNetworkRequest) (*api.AttachNetworkResponse, error) { + nodeInfo, err := ca.RemoteNode(ctx) + if err != nil { + return nil, err + } + + var network *api.Network + ra.store.View(func(tx store.ReadTx) { + network = store.GetNetwork(tx, request.Config.Target) + if network == nil { + if networks, err := store.FindNetworks(tx, store.ByName(request.Config.Target)); err == nil && len(networks) == 1 { + network = networks[0] + } + } + }) + if network == nil { + return nil, grpc.Errorf(codes.NotFound, "network %s not found", request.Config.Target) + } + + if !network.Spec.Attachable { + return nil, grpc.Errorf(codes.PermissionDenied, "network %s not manually attachable", request.Config.Target) + } + + t := &api.Task{ + ID: identity.NewID(), + NodeID: nodeInfo.NodeID, + Spec: api.TaskSpec{ + Runtime: &api.TaskSpec_Attachment{ + Attachment: &api.NetworkAttachmentSpec{ + ContainerID: request.ContainerID, + }, + }, + Networks: []*api.NetworkAttachmentConfig{ + { + Target: network.ID, + Addresses: request.Config.Addresses, + }, + }, + }, + Status: api.TaskStatus{ + State: api.TaskStateNew, + Timestamp: ptypes.MustTimestampProto(time.Now()), + Message: "created", + }, + DesiredState: api.TaskStateRunning, + // TODO: Add Network attachment. + } + + if err := ra.store.Update(func(tx store.Tx) error { + return store.CreateTask(tx, t) + }); err != nil { + return nil, err + } + + return &api.AttachNetworkResponse{AttachmentID: t.ID}, nil +} + +// DetachNetwork allows the node to request the release of +// the resources associated to the network attachment. +// - Returns `InvalidArgument` if attachment ID is not provided. +// - Returns `NotFound` if the attachment is not found. +// - Returns an error if the deletion fails. +func (ra *ResourceAllocator) DetachNetwork(ctx context.Context, request *api.DetachNetworkRequest) (*api.DetachNetworkResponse, error) { + if request.AttachmentID == "" { + return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error()) + } + + nodeInfo, err := ca.RemoteNode(ctx) + if err != nil { + return nil, err + } + + if err := ra.store.Update(func(tx store.Tx) error { + t := store.GetTask(tx, request.AttachmentID) + if t == nil { + return grpc.Errorf(codes.NotFound, "attachment %s not found", request.AttachmentID) + } + if t.NodeID != nodeInfo.NodeID { + return grpc.Errorf(codes.PermissionDenied, "attachment %s doesn't belong to this node", request.AttachmentID) + } + + return store.DeleteTask(tx, request.AttachmentID) + }); err != nil { + return nil, err + } + + return &api.DetachNetworkResponse{}, nil +} diff --git a/vendor/src/github.com/docker/swarmkit/manager/state/raft/membership/cluster.go b/vendor/src/github.com/docker/swarmkit/manager/state/raft/membership/cluster.go index 4b24b27be5..04b2f77a05 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/state/raft/membership/cluster.go +++ b/vendor/src/github.com/docker/swarmkit/manager/state/raft/membership/cluster.go @@ -33,7 +33,8 @@ type Cluster struct { // removed contains the list of removed Members, // those ids cannot be reused - removed map[uint64]bool + removed map[uint64]bool + heartbeatTicks int PeersBroadcast *watch.Queue } @@ -43,21 +44,40 @@ type Member struct { *api.RaftMember api.RaftClient - Conn *grpc.ClientConn + Conn *grpc.ClientConn + tick int + active bool } -// NewCluster creates a new Cluster neighbors -// list for a raft Member -func NewCluster() *Cluster { +// NewCluster creates a new Cluster neighbors list for a raft Member. +// Member marked as inactive if there was no call ReportActive for heartbeatInterval. +func NewCluster(heartbeatTicks int) *Cluster { // TODO(abronan): generate Cluster ID for federation return &Cluster{ members: make(map[uint64]*Member), removed: make(map[uint64]bool), + heartbeatTicks: heartbeatTicks, PeersBroadcast: watch.NewQueue(), } } +// Tick increases ticks for all members. After heartbeatTicks node marked as +// inactive. +func (c *Cluster) Tick() { + c.mu.Lock() + defer c.mu.Unlock() + for _, m := range c.members { + if !m.active { + continue + } + m.tick++ + if m.tick > c.heartbeatTicks { + m.active = false + } + } +} + // Members returns the list of raft Members in the Cluster. func (c *Cluster) Members() map[uint64]*Member { members := make(map[uint64]*Member) @@ -106,26 +126,42 @@ func (c *Cluster) AddMember(member *Member) error { if c.removed[member.RaftID] { return ErrIDRemoved } + member.active = true + member.tick = 0 c.members[member.RaftID] = member + c.broadcastUpdate() return nil } -// RemoveMember removes a node from the Cluster Memberlist. +// RemoveMember removes a node from the Cluster Memberlist, and adds it to +// the removed list. func (c *Cluster) RemoveMember(id uint64) error { c.mu.Lock() defer c.mu.Unlock() + c.removed[id] = true - if c.members[id] != nil { - conn := c.members[id].Conn - if conn != nil { - _ = conn.Close() + return c.clearMember(id) +} + +// ClearMember removes a node from the Cluster Memberlist, but does NOT add it +// to the removed list. +func (c *Cluster) ClearMember(id uint64) error { + c.mu.Lock() + defer c.mu.Unlock() + + return c.clearMember(id) +} + +func (c *Cluster) clearMember(id uint64) error { + m, ok := c.members[id] + if ok { + if m.Conn != nil { + m.Conn.Close() } delete(c.members, id) } - - c.removed[id] = true c.broadcastUpdate() return nil } @@ -152,7 +188,6 @@ func (c *Cluster) ReplaceMemberConnection(id uint64, oldConn *Member, newConn *M newMember := *oldMember newMember.Conn = newConn.Conn newMember.RaftClient = newConn.RaftClient - c.members[id] = &newMember return nil @@ -168,11 +203,40 @@ func (c *Cluster) IsIDRemoved(id uint64) bool { // Clear resets the list of active Members and removed Members. func (c *Cluster) Clear() { c.mu.Lock() + for _, member := range c.members { + if member.Conn != nil { + member.Conn.Close() + } + } + c.members = make(map[uint64]*Member) c.removed = make(map[uint64]bool) c.mu.Unlock() } +// ReportActive reports that member is acive (called ProcessRaftMessage), +func (c *Cluster) ReportActive(id uint64) { + c.mu.Lock() + defer c.mu.Unlock() + m, ok := c.members[id] + if !ok { + return + } + m.tick = 0 + m.active = true +} + +// Active returns true if node is active. +func (c *Cluster) Active(id uint64) bool { + c.mu.RLock() + defer c.mu.RUnlock() + m, ok := c.members[id] + if !ok { + return false + } + return m.active +} + // ValidateConfigurationChange takes a proposed ConfChange and // ensures that it is valid. func (c *Cluster) ValidateConfigurationChange(cc raftpb.ConfChange) error { @@ -223,8 +287,7 @@ func (c *Cluster) CanRemoveMember(from uint64, id uint64) bool { continue } - connState, err := m.Conn.State() - if err == nil && connState == grpc.Ready { + if c.Active(m.RaftID) { nreachable++ } } diff --git a/vendor/src/github.com/docker/swarmkit/manager/state/raft/raft.go b/vendor/src/github.com/docker/swarmkit/manager/state/raft/raft.go index 7cf954cafa..6dd338b742 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/state/raft/raft.go +++ b/vendor/src/github.com/docker/swarmkit/manager/state/raft/raft.go @@ -86,7 +86,6 @@ type Node struct { Address string StateDir string - Error error raftStore *raft.MemoryStorage memoryStore *store.MemoryStore @@ -119,6 +118,7 @@ type Node struct { leadershipBroadcast *watch.Queue // used to coordinate shutdown + // Lock should be used only in stop(), all other functions should use RLock. stopMu sync.RWMutex // used for membership management checks membershipLock sync.Mutex @@ -176,7 +176,7 @@ func NewNode(ctx context.Context, opts NewNodeOptions) *Node { n := &Node{ Ctx: ctx, cancel: cancel, - cluster: membership.NewCluster(), + cluster: membership.NewCluster(cfg.ElectionTick), tlsCredentials: opts.TLSCredentials, raftStore: raftStore, Address: opts.Addr, @@ -224,10 +224,15 @@ func NewNode(ctx context.Context, opts NewNodeOptions) *Node { } // JoinAndStart joins and starts the raft server -func (n *Node) JoinAndStart() error { +func (n *Node) JoinAndStart() (err error) { + defer func() { + if err != nil { + n.done() + } + }() + loadAndStartErr := n.loadAndStart(n.Ctx, n.opts.ForceNewCluster) if loadAndStartErr != nil && loadAndStartErr != errNoWAL { - n.ticker.Stop() return loadAndStartErr } @@ -270,6 +275,9 @@ func (n *Node) JoinAndStart() error { n.Node = raft.StartNode(n.Config, []raft.Peer{}) if err := n.registerNodes(resp.Members); err != nil { + if walErr := n.wal.Close(); err != nil { + n.Config.Logger.Errorf("raft: error closing WAL: %v", walErr) + } return err } } else { @@ -281,6 +289,9 @@ func (n *Node) JoinAndStart() error { } n.Node = raft.StartNode(n.Config, []raft.Peer{peer}) if err := n.Campaign(n.Ctx); err != nil { + if walErr := n.wal.Close(); err != nil { + n.Config.Logger.Errorf("raft: error closing WAL: %v", walErr) + } return err } } @@ -324,15 +335,24 @@ func (n *Node) MemoryStore() *store.MemoryStore { return n.memoryStore } +func (n *Node) done() { + n.cluster.Clear() + + n.ticker.Stop() + n.leadershipBroadcast.Close() + n.cluster.PeersBroadcast.Close() + n.memoryStore.Close() + + close(n.doneCh) +} + // Run is the main loop for a Raft node, it goes along the state machine, // acting on the messages received from other Raft nodes in the cluster. // // Before running the main loop, it first starts the raft node based on saved // cluster state. If no saved state exists, it starts a single-node cluster. func (n *Node) Run(ctx context.Context) error { - defer func() { - close(n.doneCh) - }() + defer n.done() wasLeader := false @@ -340,7 +360,7 @@ func (n *Node) Run(ctx context.Context) error { select { case <-n.ticker.C(): n.Tick() - + n.cluster.Tick() case rd := <-n.Ready(): raftConfig := DefaultRaftConfig() n.memoryStore.View(func(readTx store.ReadTx) { @@ -453,9 +473,6 @@ func (n *Node) Run(ctx context.Context) error { return ErrMemberRemoved case <-n.stopCh: n.stop() - n.leadershipBroadcast.Close() - n.cluster.PeersBroadcast.Close() - n.memoryStore.Close() return nil } } @@ -481,13 +498,6 @@ func (n *Node) stop() { n.waitProp.Wait() n.asyncTasks.Wait() - members := n.cluster.Members() - for _, member := range members { - if member.Conn != nil { - _ = member.Conn.Close() - } - } - n.Stop() n.ticker.Stop() if err := n.wal.Close(); err != nil { @@ -517,20 +527,26 @@ func (n *Node) IsLeader() bool { return n.isLeader() } -// leader returns the id of the leader, without the protection of lock +// leader returns the id of the leader, without the protection of lock and +// membership check, so it's caller task. func (n *Node) leader() uint64 { - if !n.IsMember() { - return 0 - } return n.Node.Status().Lead } // Leader returns the id of the leader, with the protection of lock -func (n *Node) Leader() uint64 { +func (n *Node) Leader() (uint64, error) { n.stopMu.RLock() defer n.stopMu.RUnlock() - return n.leader() + if !n.IsMember() { + return 0, ErrNoRaftMember + } + leader := n.leader() + if leader == 0 { + return 0, ErrNoClusterLeader + } + + return leader, nil } // ReadyForProposals returns true if the node has broadcasted a message @@ -760,6 +776,8 @@ func (n *Node) ProcessRaftMessage(ctx context.Context, msg *api.ProcessRaftMessa return nil, ErrMemberRemoved } + n.cluster.ReportActive(msg.Message.From) + if msg.Message.Type == raftpb.MsgProp { // We don't accepted forwarded proposals. Our // current architecture depends on only the leader @@ -923,15 +941,17 @@ func (n *Node) SubscribePeers() (q chan events.Event, cancel func()) { func (n *Node) GetMemberlist() map[uint64]*api.RaftMember { memberlist := make(map[uint64]*api.RaftMember) members := n.cluster.Members() - leaderID := n.Leader() + leaderID, err := n.Leader() + if err != nil { + leaderID = 0 + } for id, member := range members { reachability := api.RaftMemberStatus_REACHABLE leader := false if member.RaftID != n.Config.ID { - connState, err := member.Conn.State() - if err != nil || connState != grpc.Ready { + if !n.cluster.Active(member.RaftID) { reachability = api.RaftMemberStatus_UNREACHABLE } } @@ -1111,7 +1131,10 @@ func (n *Node) sendToMember(members map[uint64]*membership.Member, m raftpb.Mess if err != nil { n.Config.Logger.Errorf("could connect to member ID %x at %s: %v", m.To, conn.Addr, err) } else { - n.cluster.ReplaceMemberConnection(m.To, conn, newConn) + err = n.cluster.ReplaceMemberConnection(m.To, conn, newConn) + if err != nil { + newConn.Conn.Close() + } } } else if m.Type == raftpb.MsgSnap { n.ReportSnapshot(m.To, raft.SnapshotFinish) @@ -1129,12 +1152,14 @@ type applyResult struct { // an error or until the raft node finalizes all the proposals on node // shutdown. func (n *Node) processInternalRaftRequest(ctx context.Context, r *api.InternalRaftRequest, cb func()) (proto.Message, error) { - n.waitProp.Add(1) - defer n.waitProp.Done() - + n.stopMu.RLock() if !n.canSubmitProposal() { + n.stopMu.RUnlock() return nil, ErrStopped } + n.waitProp.Add(1) + defer n.waitProp.Done() + n.stopMu.RUnlock() r.ID = n.reqIDGen.Next() diff --git a/vendor/src/github.com/docker/swarmkit/manager/state/raft/storage.go b/vendor/src/github.com/docker/swarmkit/manager/state/raft/storage.go index f218b4631e..4a9d0d78be 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/state/raft/storage.go +++ b/vendor/src/github.com/docker/swarmkit/manager/state/raft/storage.go @@ -445,18 +445,24 @@ func (n *Node) restoreFromSnapshot(data []byte, forceNewCluster bool) error { return err } - n.cluster.Clear() + oldMembers := n.cluster.Members() if !forceNewCluster { for _, member := range snapshot.Membership.Members { if err := n.registerNode(&api.RaftMember{RaftID: member.RaftID, NodeID: member.NodeID, Addr: member.Addr}); err != nil { return err } + delete(oldMembers, member.RaftID) } } for _, removedMember := range snapshot.Membership.Removed { n.cluster.RemoveMember(removedMember) + delete(oldMembers, removedMember) + } + + for member := range oldMembers { + n.cluster.ClearMember(member) } return nil diff --git a/vendor/src/github.com/docker/swarmkit/manager/state/raft/util.go b/vendor/src/github.com/docker/swarmkit/manager/state/raft/util.go index e9ef3d34f0..5f069055ab 100644 --- a/vendor/src/github.com/docker/swarmkit/manager/state/raft/util.go +++ b/vendor/src/github.com/docker/swarmkit/manager/state/raft/util.go @@ -35,19 +35,19 @@ func Register(server *grpc.Server, node *Node) { // WaitForLeader waits until node observe some leader in cluster. It returns // error if ctx was cancelled before leader appeared. func WaitForLeader(ctx context.Context, n *Node) error { - l := n.Leader() - if l != 0 { + _, err := n.Leader() + if err == nil { return nil } ticker := time.NewTicker(50 * time.Millisecond) defer ticker.Stop() - for l == 0 { + for err != nil { select { case <-ticker.C: case <-ctx.Done(): return ctx.Err() } - l = n.Leader() + _, err = n.Leader() } return nil } diff --git a/vendor/src/github.com/docker/swarmkit/picker/picker.go b/vendor/src/github.com/docker/swarmkit/remotes/remotes.go similarity index 62% rename from vendor/src/github.com/docker/swarmkit/picker/picker.go rename to vendor/src/github.com/docker/swarmkit/remotes/remotes.go index afcb139412..9da0b7d494 100644 --- a/vendor/src/github.com/docker/swarmkit/picker/picker.go +++ b/vendor/src/github.com/docker/swarmkit/remotes/remotes.go @@ -1,4 +1,4 @@ -package picker +package remotes import ( "fmt" @@ -8,9 +8,6 @@ import ( "sync" "github.com/docker/swarmkit/api" - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/transport" ) var errRemotesUnavailable = fmt.Errorf("no remote hosts provided") @@ -204,134 +201,3 @@ func (mwr *remotesWeightedRandom) observe(peer api.Peer, weight float64) { mwr.remotes[peer] = int(math.Ceil(wn)) } - -// Picker implements a grpc Picker -type Picker struct { - r Remotes - peer api.Peer // currently selected remote peer - conn *grpc.Conn - mu sync.Mutex -} - -var _ grpc.Picker = &Picker{} - -// NewPicker returns a Picker -func NewPicker(r Remotes, initial ...string) *Picker { - var peer api.Peer - if len(initial) == 0 { - peer, _ = r.Select() // empty in case of error - } else { - peer = api.Peer{Addr: initial[0]} - } - return &Picker{r: r, peer: peer} -} - -// Init does initial processing for the Picker, e.g., initiate some connections. -func (p *Picker) Init(cc *grpc.ClientConn) error { - p.mu.Lock() - peer := p.peer - p.mu.Unlock() - - p.r.ObserveIfExists(peer, DefaultObservationWeight) - c, err := grpc.NewConn(cc) - if err != nil { - return err - } - - p.mu.Lock() - p.conn = c - p.mu.Unlock() - return nil -} - -// Pick blocks until either a transport.ClientTransport is ready for the upcoming RPC -// or some error happens. -func (p *Picker) Pick(ctx context.Context) (transport.ClientTransport, error) { - p.mu.Lock() - peer := p.peer - p.mu.Unlock() - transport, err := p.conn.Wait(ctx) - if err != nil { - p.r.ObserveIfExists(peer, -DefaultObservationWeight) - } - - return transport, err -} - -// PickAddr picks a peer address for connecting. This will be called repeated for -// connecting/reconnecting. -func (p *Picker) PickAddr() (string, error) { - p.mu.Lock() - peer := p.peer - p.mu.Unlock() - - p.r.ObserveIfExists(peer, -DefaultObservationWeight) // downweight the current addr - - var err error - peer, err = p.r.Select() - if err != nil { - return "", err - } - - p.mu.Lock() - p.peer = peer - p.mu.Unlock() - return peer.Addr, err -} - -// State returns the connectivity state of the underlying connections. -func (p *Picker) State() (grpc.ConnectivityState, error) { - return p.conn.State(), nil -} - -// WaitForStateChange blocks until the state changes to something other than -// the sourceState. It returns the new state or error. -func (p *Picker) WaitForStateChange(ctx context.Context, sourceState grpc.ConnectivityState) (grpc.ConnectivityState, error) { - p.mu.Lock() - conn := p.conn - peer := p.peer - p.mu.Unlock() - - state, err := conn.WaitForStateChange(ctx, sourceState) - if err != nil { - return state, err - } - - // TODO(stevvooe): We may want to actually score the transition by checking - // sourceState. - - // TODO(stevvooe): This is questionable, but we'll see how it works. - switch state { - case grpc.Idle: - p.r.ObserveIfExists(peer, DefaultObservationWeight) - case grpc.Connecting: - p.r.ObserveIfExists(peer, DefaultObservationWeight) - case grpc.Ready: - p.r.ObserveIfExists(peer, DefaultObservationWeight) - case grpc.TransientFailure: - p.r.ObserveIfExists(peer, -DefaultObservationWeight) - case grpc.Shutdown: - p.r.ObserveIfExists(peer, -DefaultObservationWeight) - } - - return state, err -} - -// Reset the current connection and force a reconnect to another address. -func (p *Picker) Reset() error { - p.mu.Lock() - conn := p.conn - p.mu.Unlock() - - conn.NotifyReset() - return nil -} - -// Close closes all the Conn's owned by this Picker. -func (p *Picker) Close() error { - p.mu.Lock() - conn := p.conn - p.mu.Unlock() - - return conn.Close() -} diff --git a/vendor/src/github.com/google/certificate-transparency/go/client/logclient.go b/vendor/src/github.com/google/certificate-transparency/go/client/logclient.go index 225b840f0f..3c568a50bf 100644 --- a/vendor/src/github.com/google/certificate-transparency/go/client/logclient.go +++ b/vendor/src/github.com/google/certificate-transparency/go/client/logclient.go @@ -17,7 +17,6 @@ import ( "time" "github.com/google/certificate-transparency/go" - "github.com/mreiferson/go-httpclient" "golang.org/x/net/context" ) @@ -25,6 +24,7 @@ import ( const ( AddChainPath = "/ct/v1/add-chain" AddPreChainPath = "/ct/v1/add-pre-chain" + AddJSONPath = "/ct/v1/add-json" GetSTHPath = "/ct/v1/get-sth" GetEntriesPath = "/ct/v1/get-entries" ) @@ -57,6 +57,12 @@ type addChainResponse struct { Signature string `json:"signature"` // Log signature for this SCT } +// addJSONRequest represents the JSON request body sent ot the add-json CT +// method. +type addJSONRequest struct { + Data interface{} `json:"data"` +} + // getSTHResponse respresents the JSON response to the get-sth CT method type getSTHResponse struct { TreeSize uint64 `json:"tree_size"` // Number of certs in the current tree @@ -102,18 +108,12 @@ type getEntryAndProofResponse struct { // New constructs a new LogClient instance. // |uri| is the base URI of the CT log instance to interact with, e.g. // http://ct.googleapis.com/pilot -func New(uri string) *LogClient { - var c LogClient - c.uri = uri - transport := &httpclient.Transport{ - ConnectTimeout: 10 * time.Second, - RequestTimeout: 30 * time.Second, - ResponseHeaderTimeout: 30 * time.Second, - MaxIdleConnsPerHost: 10, - DisableKeepAlives: false, +// |hc| is the underlying client to be used for HTTP requests to the CT log. +func New(uri string, hc *http.Client) *LogClient { + if hc == nil { + hc = new(http.Client) } - c.httpClient = &http.Client{Transport: transport} - return &c + return &LogClient{uri: uri, httpClient: hc} } // Makes a HTTP call to |uri|, and attempts to parse the response as a JSON @@ -154,7 +154,6 @@ func (c *LogClient) postAndParse(uri string, req interface{}, res interface{}) ( if err != nil { return nil, "", err } - httpReq.Header.Set("Keep-Alive", "timeout=15, max=100") httpReq.Header.Set("Content-Type", "application/json") resp, err := c.httpClient.Do(httpReq) // Read all of the body, if there is one, so that the http.Client can do @@ -277,6 +276,37 @@ func (c *LogClient) AddChainWithContext(ctx context.Context, chain []ct.ASN1Cert return c.addChainWithRetry(ctx, AddChainPath, chain) } +func (c *LogClient) AddJSON(data interface{}) (*ct.SignedCertificateTimestamp, error) { + req := addJSONRequest{ + Data: data, + } + var resp addChainResponse + _, _, err := c.postAndParse(c.uri+AddJSONPath, &req, &resp) + if err != nil { + return nil, err + } + rawLogID, err := base64.StdEncoding.DecodeString(resp.ID) + if err != nil { + return nil, err + } + rawSignature, err := base64.StdEncoding.DecodeString(resp.Signature) + if err != nil { + return nil, err + } + ds, err := ct.UnmarshalDigitallySigned(bytes.NewReader(rawSignature)) + if err != nil { + return nil, err + } + var logID ct.SHA256Hash + copy(logID[:], rawLogID) + return &ct.SignedCertificateTimestamp{ + SCTVersion: resp.SCTVersion, + LogID: logID, + Timestamp: resp.Timestamp, + Extensions: ct.CTExtensions(resp.Extensions), + Signature: *ds}, nil +} + // GetSTH retrieves the current STH from the log. // Returns a populated SignedTreeHead, or a non-nil error. func (c *LogClient) GetSTH() (sth *ct.SignedTreeHead, err error) { diff --git a/vendor/src/github.com/google/certificate-transparency/go/serialization.go b/vendor/src/github.com/google/certificate-transparency/go/serialization.go index aab3a3f20c..fd59040c6f 100644 --- a/vendor/src/github.com/google/certificate-transparency/go/serialization.go +++ b/vendor/src/github.com/google/certificate-transparency/go/serialization.go @@ -4,6 +4,7 @@ import ( "bytes" "container/list" "crypto" + "encoding/asn1" "encoding/binary" "errors" "fmt" @@ -23,6 +24,8 @@ const ( const ( MaxCertificateLength = (1 << 24) - 1 MaxExtensionsLength = (1 << 16) - 1 + MaxSCTInListLength = (1 << 16) - 1 + MaxSCTListLength = (1 << 16) - 1 ) func writeUint(w io.Writer, value uint64, numBytes int) error { @@ -80,13 +83,12 @@ func readVarBytes(r io.Reader, numLenBytes int) ([]byte, error) { return nil, err } data := make([]byte, l) - n, err := r.Read(data) - if err != nil { + if n, err := io.ReadFull(r, data); err != nil { + if err == io.EOF || err == io.ErrUnexpectedEOF { + return nil, fmt.Errorf("short read: expected %d but got %d", l, n) + } return nil, err } - if n != int(l) { - return nil, fmt.Errorf("short read: expected %d but got %d", l, n) - } return data, nil } @@ -510,3 +512,52 @@ func SerializeSTHSignatureInput(sth SignedTreeHead) ([]byte, error) { return nil, fmt.Errorf("unsupported STH version %d", sth.Version) } } + +// SCTListSerializedLength determines the length of the required buffer should a SCT List need to be serialized +func SCTListSerializedLength(scts []SignedCertificateTimestamp) (int, error) { + if len(scts) == 0 { + return 0, fmt.Errorf("SCT List empty") + } + + sctListLen := 0 + for i, sct := range scts { + n, err := sct.SerializedLength() + if err != nil { + return 0, fmt.Errorf("unable to determine length of SCT in position %d: %v", i, err) + } + if n > MaxSCTInListLength { + return 0, fmt.Errorf("SCT in position %d too large: %d", i, n) + } + sctListLen += 2 + n + } + + return sctListLen, nil +} + +// SerializeSCTList serializes the passed-in slice of SignedCertificateTimestamp into a +// byte slice as a SignedCertificateTimestampList (see RFC6962 Section 3.3) +func SerializeSCTList(scts []SignedCertificateTimestamp) ([]byte, error) { + size, err := SCTListSerializedLength(scts) + if err != nil { + return nil, err + } + fullSize := 2 + size // 2 bytes for length + size of SCT list + if fullSize > MaxSCTListLength { + return nil, fmt.Errorf("SCT List too large to serialize: %d", fullSize) + } + buf := new(bytes.Buffer) + buf.Grow(fullSize) + if err = writeUint(buf, uint64(size), 2); err != nil { + return nil, err + } + for _, sct := range scts { + serialized, err := SerializeSCT(sct) + if err != nil { + return nil, err + } + if err = writeVarBytes(buf, serialized, 2); err != nil { + return nil, err + } + } + return asn1.Marshal(buf.Bytes()) // transform to Octet String +} diff --git a/vendor/src/github.com/mreiferson/go-httpclient/.gitignore b/vendor/src/github.com/mreiferson/go-httpclient/.gitignore deleted file mode 100644 index dbec55fb6f..0000000000 --- a/vendor/src/github.com/mreiferson/go-httpclient/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.sw[op] diff --git a/vendor/src/github.com/mreiferson/go-httpclient/.travis.yml b/vendor/src/github.com/mreiferson/go-httpclient/.travis.yml deleted file mode 100644 index ba1b6b7f9f..0000000000 --- a/vendor/src/github.com/mreiferson/go-httpclient/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: go -go: - - 1.1 -install: - - go get github.com/bmizerany/assert -script: - - pushd $TRAVIS_BUILD_DIR - - go test - - popd -notifications: - email: false diff --git a/vendor/src/github.com/mreiferson/go-httpclient/README.md b/vendor/src/github.com/mreiferson/go-httpclient/README.md deleted file mode 100644 index 6d0dbff945..0000000000 --- a/vendor/src/github.com/mreiferson/go-httpclient/README.md +++ /dev/null @@ -1,41 +0,0 @@ -## go-httpclient - -**requires Go 1.1+** as of `v0.4.0` the API has been completely re-written for Go 1.1 (for a Go -1.0.x compatible release see [1adef50](https://github.com/mreiferson/go-httpclient/tree/1adef50)) - -[![Build -Status](https://secure.travis-ci.org/mreiferson/go-httpclient.png?branch=master)](http://travis-ci.org/mreiferson/go-httpclient) - -Provides an HTTP Transport that implements the `RoundTripper` interface and -can be used as a built in replacement for the standard library's, providing: - - * connection timeouts - * request timeouts - -This is a thin wrapper around `http.Transport` that sets dial timeouts and uses -Go's internal timer scheduler to call the Go 1.1+ `CancelRequest()` API. - -### Example - -```go -transport := &httpclient.Transport{ - ConnectTimeout: 1*time.Second, - RequestTimeout: 10*time.Second, - ResponseHeaderTimeout: 5*time.Second, -} -defer transport.Close() - -client := &http.Client{Transport: transport} -req, _ := http.NewRequest("GET", "http://127.0.0.1/test", nil) -resp, err := client.Do(req) -if err != nil { - return err -} -defer resp.Body.Close() -``` - -*Note:* you will want to re-use a single client object rather than creating one for each request, otherwise you will end up [leaking connections](https://code.google.com/p/go/issues/detail?id=4049#c3). - -### Reference Docs - -For API docs see [godoc](http://godoc.org/github.com/mreiferson/go-httpclient). diff --git a/vendor/src/github.com/mreiferson/go-httpclient/httpclient.go b/vendor/src/github.com/mreiferson/go-httpclient/httpclient.go deleted file mode 100644 index 89e018bffd..0000000000 --- a/vendor/src/github.com/mreiferson/go-httpclient/httpclient.go +++ /dev/null @@ -1,237 +0,0 @@ -/* -Provides an HTTP Transport that implements the `RoundTripper` interface and -can be used as a built in replacement for the standard library's, providing: - - * connection timeouts - * request timeouts - -This is a thin wrapper around `http.Transport` that sets dial timeouts and uses -Go's internal timer scheduler to call the Go 1.1+ `CancelRequest()` API. -*/ -package httpclient - -import ( - "crypto/tls" - "errors" - "io" - "net" - "net/http" - "net/url" - "sync" - "time" -) - -// returns the current version of the package -func Version() string { - return "0.4.1" -} - -// Transport implements the RoundTripper interface and can be used as a replacement -// for Go's built in http.Transport implementing end-to-end request timeouts. -// -// transport := &httpclient.Transport{ -// ConnectTimeout: 1*time.Second, -// ResponseHeaderTimeout: 5*time.Second, -// RequestTimeout: 10*time.Second, -// } -// defer transport.Close() -// -// client := &http.Client{Transport: transport} -// req, _ := http.NewRequest("GET", "http://127.0.0.1/test", nil) -// resp, err := client.Do(req) -// if err != nil { -// return err -// } -// defer resp.Body.Close() -// -type Transport struct { - // Proxy specifies a function to return a proxy for a given - // *http.Request. If the function returns a non-nil error, the - // request is aborted with the provided error. - // If Proxy is nil or returns a nil *url.URL, no proxy is used. - Proxy func(*http.Request) (*url.URL, error) - - // Dial specifies the dial function for creating TCP - // connections. This will override the Transport's ConnectTimeout and - // ReadWriteTimeout settings. - // If Dial is nil, a dialer is generated on demand matching the Transport's - // options. - Dial func(network, addr string) (net.Conn, error) - - // TLSClientConfig specifies the TLS configuration to use with - // tls.Client. If nil, the default configuration is used. - TLSClientConfig *tls.Config - - // DisableKeepAlives, if true, prevents re-use of TCP connections - // between different HTTP requests. - DisableKeepAlives bool - - // DisableCompression, if true, prevents the Transport from - // requesting compression with an "Accept-Encoding: gzip" - // request header when the Request contains no existing - // Accept-Encoding value. If the Transport requests gzip on - // its own and gets a gzipped response, it's transparently - // decoded in the Response.Body. However, if the user - // explicitly requested gzip it is not automatically - // uncompressed. - DisableCompression bool - - // MaxIdleConnsPerHost, if non-zero, controls the maximum idle - // (keep-alive) to keep per-host. If zero, - // http.DefaultMaxIdleConnsPerHost is used. - MaxIdleConnsPerHost int - - // ConnectTimeout, if non-zero, is the maximum amount of time a dial will wait for - // a connect to complete. - ConnectTimeout time.Duration - - // ResponseHeaderTimeout, if non-zero, specifies the amount of - // time to wait for a server's response headers after fully - // writing the request (including its body, if any). This - // time does not include the time to read the response body. - ResponseHeaderTimeout time.Duration - - // RequestTimeout, if non-zero, specifies the amount of time for the entire - // request to complete (including all of the above timeouts + entire response body). - // This should never be less than the sum total of the above two timeouts. - RequestTimeout time.Duration - - // ReadWriteTimeout, if non-zero, will set a deadline for every Read and - // Write operation on the request connection. - ReadWriteTimeout time.Duration - - // TCPWriteBufferSize, the size of the operating system's write - // buffer associated with the connection. - TCPWriteBufferSize int - - // TCPReadBuffserSize, the size of the operating system's read - // buffer associated with the connection. - TCPReadBufferSize int - - starter sync.Once - transport *http.Transport -} - -// Close cleans up the Transport, currently a no-op -func (t *Transport) Close() error { - return nil -} - -func (t *Transport) lazyStart() { - if t.Dial == nil { - t.Dial = func(netw, addr string) (net.Conn, error) { - c, err := net.DialTimeout(netw, addr, t.ConnectTimeout) - if err != nil { - return nil, err - } - - if t.TCPReadBufferSize != 0 || t.TCPWriteBufferSize != 0 { - if tcpCon, ok := c.(*net.TCPConn); ok { - if t.TCPWriteBufferSize != 0 { - if err = tcpCon.SetWriteBuffer(t.TCPWriteBufferSize); err != nil { - return nil, err - } - } - if t.TCPReadBufferSize != 0 { - if err = tcpCon.SetReadBuffer(t.TCPReadBufferSize); err != nil { - return nil, err - } - } - } else { - err = errors.New("Not Tcp Connection") - return nil, err - } - } - - if t.ReadWriteTimeout > 0 { - timeoutConn := &rwTimeoutConn{ - TCPConn: c.(*net.TCPConn), - rwTimeout: t.ReadWriteTimeout, - } - return timeoutConn, nil - } - return c, nil - } - } - - t.transport = &http.Transport{ - Dial: t.Dial, - Proxy: t.Proxy, - TLSClientConfig: t.TLSClientConfig, - DisableKeepAlives: t.DisableKeepAlives, - DisableCompression: t.DisableCompression, - MaxIdleConnsPerHost: t.MaxIdleConnsPerHost, - ResponseHeaderTimeout: t.ResponseHeaderTimeout, - } -} - -func (t *Transport) CancelRequest(req *http.Request) { - t.starter.Do(t.lazyStart) - - t.transport.CancelRequest(req) -} - -func (t *Transport) CloseIdleConnections() { - t.starter.Do(t.lazyStart) - - t.transport.CloseIdleConnections() -} - -func (t *Transport) RegisterProtocol(scheme string, rt http.RoundTripper) { - t.starter.Do(t.lazyStart) - - t.transport.RegisterProtocol(scheme, rt) -} - -func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) { - t.starter.Do(t.lazyStart) - - if t.RequestTimeout > 0 { - timer := time.AfterFunc(t.RequestTimeout, func() { - t.transport.CancelRequest(req) - }) - - resp, err = t.transport.RoundTrip(req) - if err != nil { - timer.Stop() - } else { - resp.Body = &bodyCloseInterceptor{ReadCloser: resp.Body, timer: timer} - } - } else { - resp, err = t.transport.RoundTrip(req) - } - - return -} - -type bodyCloseInterceptor struct { - io.ReadCloser - timer *time.Timer -} - -func (bci *bodyCloseInterceptor) Close() error { - bci.timer.Stop() - return bci.ReadCloser.Close() -} - -// A net.Conn that sets a deadline for every Read or Write operation -type rwTimeoutConn struct { - *net.TCPConn - rwTimeout time.Duration -} - -func (c *rwTimeoutConn) Read(b []byte) (int, error) { - err := c.TCPConn.SetDeadline(time.Now().Add(c.rwTimeout)) - if err != nil { - return 0, err - } - return c.TCPConn.Read(b) -} - -func (c *rwTimeoutConn) Write(b []byte) (int, error) { - err := c.TCPConn.SetDeadline(time.Now().Add(c.rwTimeout)) - if err != nil { - return 0, err - } - return c.TCPConn.Write(b) -}