summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Vieux <vieux@docker.com>2016-06-12 07:07:10 -0700
committerTonis Tiigi <tonistiigi@gmail.com>2016-06-13 18:22:35 -0700
commit95ff9f41d8bfd0a0e4dc36fe83341b551e8f3508 (patch)
tree059340927d23539ecfadd0454f22ef935d5c19d5
parent3af6ddc099477fc01e4cf9aa21a90194ebde0a17 (diff)
downloaddocker-95ff9f41d8bfd0a0e4dc36fe83341b551e8f3508.tar.gz
backend
Signed-off-by: Victor Vieux <vieux@docker.com>
-rw-r--r--api/server/router/swarm/backend.go4
-rw-r--r--api/server/router/swarm/cluster_routes.go20
-rw-r--r--daemon/cluster/cluster.go36
-rw-r--r--daemon/cluster/convert/container.go4
-rw-r--r--daemon/cluster/convert/network.go2
-rw-r--r--daemon/cluster/convert/node.go29
-rw-r--r--daemon/cluster/convert/service.go4
-rw-r--r--daemon/cluster/convert/swarm.go26
-rw-r--r--daemon/cluster/convert/task.go2
-rw-r--r--daemon/cluster/executor/container/container.go6
-rw-r--r--integration-cli/daemon_swarm.go13
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)))
}