diff options
author | Victor Vieux <vieux@docker.com> | 2016-06-12 07:07:10 -0700 |
---|---|---|
committer | Tonis Tiigi <tonistiigi@gmail.com> | 2016-06-13 18:22:35 -0700 |
commit | 95ff9f41d8bfd0a0e4dc36fe83341b551e8f3508 (patch) | |
tree | 059340927d23539ecfadd0454f22ef935d5c19d5 | |
parent | 3af6ddc099477fc01e4cf9aa21a90194ebde0a17 (diff) | |
download | docker-95ff9f41d8bfd0a0e4dc36fe83341b551e8f3508.tar.gz |
backend
Signed-off-by: Victor Vieux <vieux@docker.com>
-rw-r--r-- | api/server/router/swarm/backend.go | 4 | ||||
-rw-r--r-- | api/server/router/swarm/cluster_routes.go | 20 | ||||
-rw-r--r-- | daemon/cluster/cluster.go | 36 | ||||
-rw-r--r-- | daemon/cluster/convert/container.go | 4 | ||||
-rw-r--r-- | daemon/cluster/convert/network.go | 2 | ||||
-rw-r--r-- | daemon/cluster/convert/node.go | 29 | ||||
-rw-r--r-- | daemon/cluster/convert/service.go | 4 | ||||
-rw-r--r-- | daemon/cluster/convert/swarm.go | 26 | ||||
-rw-r--r-- | daemon/cluster/convert/task.go | 2 | ||||
-rw-r--r-- | daemon/cluster/executor/container/container.go | 6 | ||||
-rw-r--r-- | integration-cli/daemon_swarm.go | 13 |
11 files changed, 83 insertions, 63 deletions
diff --git a/api/server/router/swarm/backend.go b/api/server/router/swarm/backend.go index 6a1997a6e6..05fe00a0c2 100644 --- a/api/server/router/swarm/backend.go +++ b/api/server/router/swarm/backend.go @@ -11,7 +11,7 @@ type Backend interface { Join(req types.JoinRequest) error Leave(force bool) error Inspect() (types.Swarm, error) - Update(types.Swarm) error + Update(uint64, types.Spec) error GetServices(basictypes.ServiceListOptions) ([]types.Service, error) GetService(string) (types.Service, error) CreateService(types.ServiceSpec) (string, error) @@ -19,7 +19,7 @@ type Backend interface { RemoveService(string) error GetNodes(basictypes.NodeListOptions) ([]types.Node, error) GetNode(string) (types.Node, error) - UpdateNode(string, types.Node) error + UpdateNode(string, uint64, types.NodeSpec) error RemoveNode(string) error GetTasks(basictypes.TaskListOptions) ([]types.Task, error) GetTask(string) (types.Task, error) diff --git a/api/server/router/swarm/cluster_routes.go b/api/server/router/swarm/cluster_routes.go index 9fe1526183..50f823e07e 100644 --- a/api/server/router/swarm/cluster_routes.go +++ b/api/server/router/swarm/cluster_routes.go @@ -55,12 +55,18 @@ func (sr *swarmRouter) inspectCluster(ctx context.Context, w http.ResponseWriter } func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - var swarm types.Swarm + var swarm types.Spec if err := json.NewDecoder(r.Body).Decode(&swarm); err != nil { return err } - if err := sr.backend.Update(swarm); err != nil { + rawVersion := r.URL.Query().Get("version") + version, err := strconv.ParseUint(rawVersion, 10, 64) + if err != nil { + return fmt.Errorf("Invalid swarm version '%s': %s", rawVersion, err.Error()) + } + + if err := sr.backend.Update(version, swarm); err != nil { logrus.Errorf("Error configuring swarm: %v", err) return err } @@ -168,12 +174,18 @@ func (sr *swarmRouter) getNode(ctx context.Context, w http.ResponseWriter, r *ht } func (sr *swarmRouter) updateNode(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - var node types.Node + var node types.NodeSpec if err := json.NewDecoder(r.Body).Decode(&node); err != nil { return err } - if err := sr.backend.UpdateNode(vars["id"], node); err != nil { + rawVersion := r.URL.Query().Get("version") + version, err := strconv.ParseUint(rawVersion, 10, 64) + if err != nil { + return fmt.Errorf("Invalid node version '%s': %s", rawVersion, err.Error()) + } + + if err := sr.backend.UpdateNode(vars["id"], version, node); err != nil { logrus.Errorf("Error updating node %s: %v", vars["id"], err) return err } diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index e4236112bf..c7d40eb348 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -305,7 +305,10 @@ func (c *Cluster) Join(req types.JoinRequest) error { return ErrSwarmExists } // todo: check current state existing - n, ctx, err := c.startNewNode(false, req.ListenAddr, req.RemoteAddr, req.Secret, req.CACertHash, req.Manager) + if len(req.RemoteAddrs) == 0 { + return fmt.Errorf("at least 1 RemoteAddr is required to join") + } + n, ctx, err := c.startNewNode(false, req.ListenAddr, req.RemoteAddrs[0], req.Secret, req.CACertHash, req.Manager) if err != nil { c.Unlock() return err @@ -429,7 +432,7 @@ func (c *Cluster) Inspect() (types.Swarm, error) { } // Update updates configuration of a managed swarm cluster. -func (c *Cluster) Update(swarm types.Swarm) error { +func (c *Cluster) Update(version uint64, spec types.Spec) error { c.RLock() defer c.RUnlock() @@ -437,7 +440,12 @@ func (c *Cluster) Update(swarm types.Swarm) error { return ErrNoManager } - swarmSpec, err := convert.SwarmSpecToGRPC(swarm) + swarmSpec, err := convert.SwarmSpecToGRPC(spec) + if err != nil { + return err + } + + swarm, err := getSwarm(c.getRequestContext(), c.client) if err != nil { return err } @@ -448,7 +456,7 @@ func (c *Cluster) Update(swarm types.Swarm) error { ClusterID: swarm.ID, Spec: &swarmSpec, ClusterVersion: &swarmapi.Version{ - Index: swarm.Meta.Version.Index, + Index: version, }, }, ) @@ -535,7 +543,7 @@ func (c *Cluster) Info() types.Info { if r, err := c.client.ListNodes(c.getRequestContext(), &swarmapi.ListNodesRequest{}); err == nil { info.Nodes = len(r.Nodes) for _, n := range r.Nodes { - if n.Manager != nil { + if n.ManagerStatus != nil { info.Managers = info.Managers + 1 } } @@ -635,7 +643,7 @@ func (c *Cluster) GetService(input string) (types.Service, error) { } // UpdateService updates existing service to match new properties. -func (c *Cluster) UpdateService(serviceID string, version uint64, service types.ServiceSpec) error { +func (c *Cluster) UpdateService(serviceID string, version uint64, spec types.ServiceSpec) error { c.RLock() defer c.RUnlock() @@ -643,7 +651,7 @@ func (c *Cluster) UpdateService(serviceID string, version uint64, service types. return ErrNoManager } - serviceSpec, err := convert.ServiceSpecToGRPC(service) + serviceSpec, err := convert.ServiceSpecToGRPC(spec) if err != nil { return err } @@ -726,7 +734,7 @@ func (c *Cluster) GetNode(input string) (types.Node, error) { } // UpdateNode updates existing nodes properties. -func (c *Cluster) UpdateNode(input string, node types.Node) error { +func (c *Cluster) UpdateNode(nodeID string, version uint64, spec types.NodeSpec) error { c.RLock() defer c.RUnlock() @@ -734,7 +742,7 @@ func (c *Cluster) UpdateNode(input string, node types.Node) error { return ErrNoManager } - nodeSpec, err := convert.NodeSpecToGRPC(node) + nodeSpec, err := convert.NodeSpecToGRPC(spec) if err != nil { return err } @@ -742,10 +750,10 @@ func (c *Cluster) UpdateNode(input string, node types.Node) error { _, err = c.client.UpdateNode( c.getRequestContext(), &swarmapi.UpdateNodeRequest{ - NodeID: node.ID, + NodeID: nodeID, Spec: &nodeSpec, NodeVersion: &swarmapi.Version{ - Index: node.Version.Index, + Index: version, }, }, ) @@ -977,14 +985,14 @@ func (c *Cluster) managerStats() (current bool, reachable int, unreachable int, return false, 0, 0, err } for _, n := range nodes.Nodes { - if n.Manager != nil { - if n.Manager.Raft.Status.Reachability == swarmapi.RaftMemberStatus_REACHABLE { + if n.ManagerStatus != nil { + if n.ManagerStatus.Raft.Status.Reachability == swarmapi.RaftMemberStatus_REACHABLE { reachable++ if n.ID == c.node.NodeID() { current = true } } - if n.Manager.Raft.Status.Reachability == swarmapi.RaftMemberStatus_UNREACHABLE { + if n.ManagerStatus.Raft.Status.Reachability == swarmapi.RaftMemberStatus_UNREACHABLE { unreachable++ } } diff --git a/daemon/cluster/convert/container.go b/daemon/cluster/convert/container.go index ad2141ac2c..c943537ad4 100644 --- a/daemon/cluster/convert/container.go +++ b/daemon/cluster/convert/container.go @@ -41,7 +41,7 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) types.ContainerSpec { Labels: m.VolumeOptions.Labels, } if m.VolumeOptions.DriverConfig != nil { - mount.VolumeOptions.DriverConfig = types.Driver{ + mount.VolumeOptions.DriverConfig = &types.Driver{ Name: m.VolumeOptions.DriverConfig.Name, Options: m.VolumeOptions.DriverConfig.Options, } @@ -101,7 +101,7 @@ func containerToGRPC(c types.ContainerSpec) (*swarmapi.ContainerSpec, error) { Populate: m.VolumeOptions.Populate, Labels: m.VolumeOptions.Labels, } - if m.VolumeOptions.DriverConfig.Name != "" || m.VolumeOptions.DriverConfig.Options != nil { + if m.VolumeOptions.DriverConfig != nil { mount.VolumeOptions.DriverConfig = &swarmapi.Driver{ Name: m.VolumeOptions.DriverConfig.Name, Options: m.VolumeOptions.DriverConfig.Options, diff --git a/daemon/cluster/convert/network.go b/daemon/cluster/convert/network.go index a86740a0fa..53b952427a 100644 --- a/daemon/cluster/convert/network.go +++ b/daemon/cluster/convert/network.go @@ -108,7 +108,7 @@ func endpointFromGRPC(e *swarmapi.Endpoint) types.Endpoint { } for _, portState := range e.Ports { - endpoint.ExposedPorts = append(endpoint.ExposedPorts, types.PortConfig{ + endpoint.Ports = append(endpoint.Ports, types.PortConfig{ Name: portState.Name, Protocol: types.PortConfigProtocol(strings.ToLower(swarmapi.PortConfig_Protocol_name[int32(portState.Protocol)])), TargetPort: portState.TargetPort, diff --git a/daemon/cluster/convert/node.go b/daemon/cluster/convert/node.go index c6601880f3..fb15b2b5fa 100644 --- a/daemon/cluster/convert/node.go +++ b/daemon/cluster/convert/node.go @@ -54,42 +54,41 @@ func NodeFromGRPC(n swarmapi.Node) types.Node { } //Manager - if n.Manager != nil { + if n.ManagerStatus != nil { node.ManagerStatus = &types.ManagerStatus{ - Leader: n.Manager.Raft.Status.Leader, - Reachability: types.Reachability(strings.ToLower(n.Manager.Raft.Status.Reachability.String())), - Message: n.Manager.Raft.Status.Message, - Addr: n.Manager.Raft.Addr, + Leader: n.ManagerStatus.Raft.Status.Leader, + Reachability: types.Reachability(strings.ToLower(n.ManagerStatus.Raft.Status.Reachability.String())), + Addr: n.ManagerStatus.Raft.Addr, } } return node } -// NodeSpecToGRPC converts a Node to a grpc NodeSpec. -func NodeSpecToGRPC(n types.Node) (swarmapi.NodeSpec, error) { +// NodeSpecToGRPC converts a NodeSpec to a grpc NodeSpec. +func NodeSpecToGRPC(s types.NodeSpec) (swarmapi.NodeSpec, error) { spec := swarmapi.NodeSpec{ Annotations: swarmapi.Annotations{ - Name: n.Spec.Name, - Labels: n.Spec.Labels, + Name: s.Name, + Labels: s.Labels, }, } - if role, ok := swarmapi.NodeRole_value[strings.ToUpper(string(n.Spec.Role))]; ok { + if role, ok := swarmapi.NodeRole_value[strings.ToUpper(string(s.Role))]; ok { spec.Role = swarmapi.NodeRole(role) } else { - return swarmapi.NodeSpec{}, fmt.Errorf("invalid Role: %q", n.Spec.Role) + return swarmapi.NodeSpec{}, fmt.Errorf("invalid Role: %q", s.Role) } - if membership, ok := swarmapi.NodeSpec_Membership_value[strings.ToUpper(string(n.Spec.Membership))]; ok { + if membership, ok := swarmapi.NodeSpec_Membership_value[strings.ToUpper(string(s.Membership))]; ok { spec.Membership = swarmapi.NodeSpec_Membership(membership) } else { - return swarmapi.NodeSpec{}, fmt.Errorf("invalid Membership: %q", n.Spec.Membership) + return swarmapi.NodeSpec{}, fmt.Errorf("invalid Membership: %q", s.Membership) } - if availability, ok := swarmapi.NodeSpec_Availability_value[strings.ToUpper(string(n.Spec.Availability))]; ok { + if availability, ok := swarmapi.NodeSpec_Availability_value[strings.ToUpper(string(s.Availability))]; ok { spec.Availability = swarmapi.NodeSpec_Availability(availability) } else { - return swarmapi.NodeSpec{}, fmt.Errorf("invalid Availability: %q", n.Spec.Availability) + return swarmapi.NodeSpec{}, fmt.Errorf("invalid Availability: %q", s.Availability) } return spec, nil diff --git a/daemon/cluster/convert/service.go b/daemon/cluster/convert/service.go index b2c3c13441..60df93a59e 100644 --- a/daemon/cluster/convert/service.go +++ b/daemon/cluster/convert/service.go @@ -17,7 +17,7 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service { networks := make([]types.NetworkAttachmentConfig, 0, len(spec.Networks)) for _, n := range spec.Networks { - networks = append(networks, types.NetworkAttachmentConfig{Target: n.Target}) + networks = append(networks, types.NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) } service := types.Service{ ID: s.ID, @@ -76,7 +76,7 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) { networks := make([]*swarmapi.ServiceSpec_NetworkAttachmentConfig, 0, len(s.Networks)) for _, n := range s.Networks { - networks = append(networks, &swarmapi.ServiceSpec_NetworkAttachmentConfig{Target: n.Target}) + networks = append(networks, &swarmapi.ServiceSpec_NetworkAttachmentConfig{Target: n.Target, Aliases: n.Aliases}) } spec := swarmapi.ServiceSpec{ diff --git a/daemon/cluster/convert/swarm.go b/daemon/cluster/convert/swarm.go index e3c313ad23..cb9d7d0821 100644 --- a/daemon/cluster/convert/swarm.go +++ b/daemon/cluster/convert/swarm.go @@ -57,32 +57,32 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm { return swarm } -// SwarmSpecToGRPC converts a Swarm to a grpc ClusterSpec. -func SwarmSpecToGRPC(s types.Swarm) (swarmapi.ClusterSpec, error) { +// SwarmSpecToGRPC converts a Spec to a grpc ClusterSpec. +func SwarmSpecToGRPC(s types.Spec) (swarmapi.ClusterSpec, error) { spec := swarmapi.ClusterSpec{ Annotations: swarmapi.Annotations{ - Name: s.Spec.Name, - Labels: s.Spec.Labels, + Name: s.Name, + Labels: s.Labels, }, Orchestration: swarmapi.OrchestrationConfig{ - TaskHistoryRetentionLimit: s.Spec.Orchestration.TaskHistoryRetentionLimit, + TaskHistoryRetentionLimit: s.Orchestration.TaskHistoryRetentionLimit, }, Raft: swarmapi.RaftConfig{ - SnapshotInterval: s.Spec.Raft.SnapshotInterval, - KeepOldSnapshots: s.Spec.Raft.KeepOldSnapshots, - LogEntriesForSlowFollowers: s.Spec.Raft.LogEntriesForSlowFollowers, - HeartbeatTick: s.Spec.Raft.HeartbeatTick, - ElectionTick: s.Spec.Raft.ElectionTick, + SnapshotInterval: s.Raft.SnapshotInterval, + KeepOldSnapshots: s.Raft.KeepOldSnapshots, + LogEntriesForSlowFollowers: s.Raft.LogEntriesForSlowFollowers, + HeartbeatTick: s.Raft.HeartbeatTick, + ElectionTick: s.Raft.ElectionTick, }, Dispatcher: swarmapi.DispatcherConfig{ - HeartbeatPeriod: s.Spec.Dispatcher.HeartbeatPeriod, + HeartbeatPeriod: s.Dispatcher.HeartbeatPeriod, }, CAConfig: swarmapi.CAConfig{ - NodeCertExpiry: ptypes.DurationProto(s.Spec.CAConfig.NodeCertExpiry), + NodeCertExpiry: ptypes.DurationProto(s.CAConfig.NodeCertExpiry), }, } - if err := SwarmSpecUpdateAcceptancePolicy(&spec, s.Spec.AcceptancePolicy); err != nil { + if err := SwarmSpecUpdateAcceptancePolicy(&spec, s.AcceptancePolicy); err != nil { return swarmapi.ClusterSpec{}, err } return spec, nil diff --git a/daemon/cluster/convert/task.go b/daemon/cluster/convert/task.go index f91514da4a..b701ae36cf 100644 --- a/daemon/cluster/convert/task.go +++ b/daemon/cluster/convert/task.go @@ -15,7 +15,7 @@ func TaskFromGRPC(t swarmapi.Task) types.Task { task := types.Task{ ID: t.ID, ServiceID: t.ServiceID, - Instance: int(t.Instance), + Slot: int(t.Slot), NodeID: t.NodeID, Spec: types.TaskSpec{ ContainerSpec: containerSpecFromGRPC(containerConfig), diff --git a/daemon/cluster/executor/container/container.go b/daemon/cluster/executor/container/container.go index df62c04b2c..1326bf1a8b 100644 --- a/daemon/cluster/executor/container/container.go +++ b/daemon/cluster/executor/container/container.go @@ -74,8 +74,8 @@ func (c *containerConfig) name() string { return c.task.Annotations.Name } - // fallback to service.instance.id. - return strings.Join([]string{c.task.ServiceAnnotations.Name, fmt.Sprint(c.task.Instance), c.task.ID}, ".") + // fallback to service.slot.id. + return strings.Join([]string{c.task.ServiceAnnotations.Name, fmt.Sprint(c.task.Slot), c.task.ID}, ".") } func (c *containerConfig) image() string { @@ -132,7 +132,7 @@ func (c *containerConfig) labels() map[string]string { system = map[string]string{ "task": "", // mark as cluster task "task.id": c.task.ID, - "task.name": fmt.Sprintf("%v.%v", c.task.ServiceAnnotations.Name, c.task.Instance), + "task.name": fmt.Sprintf("%v.%v", c.task.ServiceAnnotations.Name, c.task.Slot), "node.id": c.task.NodeID, "service.id": c.task.ServiceID, "service.name": c.task.ServiceAnnotations.Name, diff --git a/integration-cli/daemon_swarm.go b/integration-cli/daemon_swarm.go index e743f40ac4..0b553d34f8 100644 --- a/integration-cli/daemon_swarm.go +++ b/integration-cli/daemon_swarm.go @@ -50,11 +50,11 @@ func (d *SwarmDaemon) Init(autoAccept map[string]bool, secret string) error { // Join joins a current daemon with existing cluster. func (d *SwarmDaemon) Join(remoteAddr, secret, cahash string, manager bool) error { status, out, err := d.SockRequest("POST", "/swarm/join", swarm.JoinRequest{ - ListenAddr: d.listenAddr, - RemoteAddr: remoteAddr, - Manager: manager, - Secret: secret, - CACertHash: cahash, + ListenAddr: d.listenAddr, + RemoteAddrs: []string{remoteAddr}, + Manager: manager, + Secret: secret, + CACertHash: cahash, }) if status != http.StatusOK { return fmt.Errorf("joining swarm: invalid statuscode %v, %q", status, out) @@ -161,7 +161,8 @@ func (d *SwarmDaemon) updateNode(c *check.C, node *swarm.Node, f ...nodeConstruc for _, fn := range f { fn(node) } - status, out, err := d.SockRequest("POST", "/nodes/"+node.ID+"/update", node) + url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index) + status, out, err := d.SockRequest("POST", url, node.Spec) c.Assert(err, checker.IsNil) c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out))) } |