docker-swarm-api 1.2.4 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bd5f9e395b5a9eeb81a49a3cb64346ba973e706
4
- data.tar.gz: b8d22beaefe635920fdc9e0d5cba0944f439c001
3
+ metadata.gz: df2548b509bebf94428c7bdbfbfc43ea3d2f3311
4
+ data.tar.gz: 0381001594e826d6b621d2598b96b52b2e2db15c
5
5
  SHA512:
6
- metadata.gz: f303af9181d8eb976b1db9a973c2824dd4b3da3e9a64386c16e67a151ddb6f47d63a9053f9ea4c123f78566998f522ec2a841e40e0348ccc096ae7aac672d84a
7
- data.tar.gz: d62b8b6e3921bbeafb9ca58ad864c7e3e72dcd60968d4d2d80a1da6e58551b98bb2186315a7042bd645f3dda392f5f08b87ff24396d8c05b5da501e45f9bb65d
6
+ metadata.gz: fed1ac9841af1977852dd9d609ddda922987d0e1d45abe03cbe075923ab411e3da863f5b1260cfe72c14592602a3d6218e6a7c94eb71ecb14b87356998c42ac8
7
+ data.tar.gz: 8458904be3f28de9125ba98a8f596ea1382bdcf6248761de7125c0b59998e082cfbbfe0daccdaf9298521b3102398ebd318421fd20ca7046e15000f066d7bd3b
@@ -30,24 +30,15 @@ class Docker::Swarm::Network
30
30
  end
31
31
  return []
32
32
  end
33
-
34
33
 
35
34
  def remove
36
- network_name = name
37
- response = @swarm.connection.delete("/networks/#{id()}", {}, expects: [200, 204, 500], full_response: true)
38
- if (response.status > 204)
39
- raise "Error deleting network (#{name}) HTTP-#{response.status} #{response.body}"
40
- end
41
-
42
- attempts = 0
43
- while (@swarm.find_network_by_name(network_name) != nil)
44
- sleep 1
45
- attempts += 1
46
- if (attempts > 30)
47
- raise "Failed to remove network: #{network_name}, operation timed out. Response: HTTP#{response.status} #{response.body}"
35
+ if (@swarm)
36
+ @swarm.nodes.each do |node|
37
+ node.remove_network(self)
48
38
  end
49
39
  end
50
40
  end
41
+
51
42
  end
52
43
 
53
44
  # EXAMPLE INSPECT OF OVERLAY NETWORK:
@@ -1,8 +1,6 @@
1
1
  # This class represents a Docker Swarm Node.
2
2
  class Docker::Swarm::Node
3
- #include Docker::Base
4
- attr_reader :hash
5
- attr_accessor :connection
3
+ attr_reader :hash, :swarm
6
4
  AVAILABILITY = {
7
5
  active: "active",
8
6
  drain: "drain"
@@ -27,6 +25,14 @@ class Docker::Swarm::Node
27
25
  return @hash['Description']['Hostname']
28
26
  end
29
27
 
28
+ def connection
29
+ if (@swarm) && (@swarm.node_hash[id()])
30
+ return @swarm.node_hash[id()][:connection]
31
+ else
32
+ return nil
33
+ end
34
+ end
35
+
30
36
  def role
31
37
  if (@hash['Spec']['Role'] == "worker")
32
38
  return :worker
@@ -55,6 +61,15 @@ class Docker::Swarm::Node
55
61
  end
56
62
  end
57
63
 
64
+ def swarm_connection
65
+ node_hash = @swarm.node_hash[self.id]
66
+ if (node_hash)
67
+ return node_hash[:connection]
68
+ end
69
+ return nil
70
+ end
71
+
72
+
58
73
  def running_tasks
59
74
  return tasks.select {|t| t.status == 'running'}
60
75
  end
@@ -80,6 +95,33 @@ class Docker::Swarm::Node
80
95
  Docker::Swarm::Node.remove(self.id, @swarm.connection)
81
96
  end
82
97
 
98
+
99
+ def remove_network_with_name(network_name)
100
+ network = find_network_by_name(network_name)
101
+ self.remove_network(network) if (network)
102
+ end
103
+
104
+ def remove_network(network)
105
+ attempts = 0
106
+ if (self.connection == nil)
107
+ puts "Warning: node asked to remove network, but no connection for node: #{self.id} #{self.host_name}"
108
+ else
109
+ while (self.find_network_by_id(network.id) != nil)
110
+ response = self.connection.delete("/networks/#{network.id}", {}, expects: [204, 404, 500], full_response: true)
111
+ if (response.status == 500)
112
+ puts "Warning: Deleting network (#{network.name}) from #{self.host_name} returned HTTP-#{response.status} #{response.body}"
113
+ end
114
+
115
+ sleep 1
116
+ attempts += 1
117
+ if (attempts > 30)
118
+ raise "Failed to remove network: #{network.name} from #{self.host_name}, operation timed out. Response: HTTP#{response.status} #{response.body}"
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+
83
125
  def leave(force = true)
84
126
  drain(wait_for_drain: true, wait_seconds: 60)
85
127
  # change_availability(:active)
@@ -99,12 +141,50 @@ class Docker::Swarm::Node
99
141
  end
100
142
  end
101
143
 
144
+ def networks()
145
+ if (connection)
146
+ return Docker::Swarm::Node.networks_on_host(connection, @swarm)
147
+ else
148
+ debugger
149
+ raise "No connection set for node: #{self.host_name}, ID: #{self.id}"
150
+ end
151
+ end
152
+
153
+ def find_network_by_name(network_name)
154
+ networks.each do |network|
155
+ if (network.name == network_name)
156
+ return network
157
+ end
158
+ end
159
+ return nil
160
+ end
161
+
162
+ def find_network_by_id(network_id)
163
+ networks.each do |network|
164
+ if (network.id == network_id)
165
+ return network
166
+ end
167
+ end
168
+ return nil
169
+ end
170
+
171
+
102
172
  def self.remove(node_id, connection)
103
173
  query = {}
104
174
  response = connection.delete("/nodes/#{node_id}", query, expects: [200, 406, 500], full_response: true)
105
175
  if (response.status != 200)
106
- raise "Error deleting node: #{response.body}"
176
+ raise "Error deleting node: HTTP-#{response.status} #{response.body}"
177
+ end
178
+ end
179
+
180
+ def self.networks_on_host(connection, swarm)
181
+ networks = []
182
+ response = connection.get("/networks", {}, full_response: true, expects: [200])
183
+ network_hashes = JSON.parse(response.body)
184
+ network_hashes.each do |network_hash|
185
+ networks << Docker::Swarm::Network.new(swarm, network_hash)
107
186
  end
187
+ return networks
108
188
  end
109
189
 
110
190
 
@@ -49,7 +49,6 @@ class Docker::Swarm::Service
49
49
  self.update(@hash['Spec'])
50
50
  end
51
51
 
52
-
53
52
  def self.DEFAULT_OPTIONS
54
53
  default_service_create_options = {
55
54
  "Name" => "<<Required>>",
@@ -7,15 +7,6 @@ class Docker::Swarm::Swarm
7
7
  include Docker
8
8
  attr_reader :worker_join_token, :manager_join_token, :id, :hash, :node_hash
9
9
 
10
- def initialize(hash, manager_connection, options = {})
11
- @hash = hash
12
- @id = hash['ID']
13
- @worker_join_token = hash['JoinTokens']['Worker']
14
- @manager_join_token = hash['JoinTokens']['Manager']
15
- @node_hash = {}
16
- @manager_connection = manager_connection
17
- end
18
-
19
10
  def store_manager(manager_connection, listen_address_and_port)
20
11
  node = nodes.find {|n|
21
12
  (n.hash['ManagerStatus']) && (n.hash['ManagerStatus']['Leader'] == true) && (n.hash['ManagerStatus']['Addr'] == listen_address_and_port)
@@ -24,6 +15,11 @@ class Docker::Swarm::Swarm
24
15
  @node_hash[node.id] = {hash: node.hash, connection: manager_connection}
25
16
  end
26
17
 
18
+ def update_data(hash)
19
+ @hash = hash
20
+ end
21
+
22
+
27
23
  def join(node_connection, join_token = nil, listen_address = "0.0.0.0:2377")
28
24
  join_token = @worker_join_token
29
25
  node_ids_before = nodes().collect {|n| n.id}
@@ -100,7 +96,6 @@ class Docker::Swarm::Swarm
100
96
  end
101
97
 
102
98
  def leave(node, force = false)
103
- node.connection = self.connection
104
99
  node_info = @node_hash[node.id]
105
100
  if (node_info)
106
101
  Docker::Swarm::Swarm.leave(force, node_info[:connection])
@@ -147,41 +142,46 @@ class Docker::Swarm::Swarm
147
142
  end
148
143
 
149
144
  def create_network_overlay(network_name)
150
- subnet_16_parts = [10, 11, 0, 0]
151
-
145
+ subnet_16_parts = [10, 10, 0, 0]
152
146
  max_vxlanid = 200
153
- networks.each do |network|
154
- if (network.driver == 'overlay')
155
- if (network.hash['Options'])
156
- vxlanid = network.hash['Options']["com.docker.network.driver.overlay.vxlanid_list"]
157
- if (vxlanid) && (vxlanid.to_i > max_vxlanid)
158
- max_vxlanid = vxlanid.to_i
147
+
148
+ # Sometimes nodes have leftover networks not on other nodes, that have subnets that can't be duplicated in
149
+ # the new overlay network.
150
+ nodes.each do |node|
151
+ node.networks.each do |network|
152
+ if (network.driver == 'overlay')
153
+ if (network.hash['Options'])
154
+ vxlanid = network.hash['Options']["com.docker.network.driver.overlay.vxlanid_list"]
155
+ if (vxlanid) && (vxlanid.to_i > max_vxlanid)
156
+ max_vxlanid = vxlanid.to_i
157
+ end
159
158
  end
160
159
  end
161
- end
162
160
 
163
- # Make sure our new network doesn't duplicate subnet of other network.
164
- if (network.hash['IPAM']) && (network.hash['IPAM']['Config'])
165
- network.hash['IPAM']['Config'].each do |subnet_config|
166
- if (subnet_config['Subnet'])
167
- subnet = subnet_config['Subnet']
168
- subnet = subnet.split(".")
169
- if (subnet[0] == '10') && (subnet[1] == '255')
170
- else
171
- if (subnet[0].to_i == subnet_16_parts[0])
172
- if (subnet[1].to_i >= subnet_16_parts[1])
173
- subnet_16_parts[1] = subnet[1].to_i + 1
174
- if (subnet_16_parts[1] >= 255)
175
- raise "Ran out of subnets"
161
+ # Make sure our new network doesn't duplicate subnet of other network.
162
+ if (network.hash['IPAM']) && (network.hash['IPAM']['Config'])
163
+ network.hash['IPAM']['Config'].each do |subnet_config|
164
+ if (subnet_config['Subnet'])
165
+ subnet = subnet_config['Subnet']
166
+ subnet = subnet.split(".")
167
+ if (subnet[0] == '10') && (subnet[1] == '255')
168
+ else
169
+ if (subnet[0].to_i == subnet_16_parts[0])
170
+ if (subnet[1].to_i >= subnet_16_parts[1])
171
+ subnet_16_parts[1] = subnet[1].to_i + 1
172
+ if (subnet_16_parts[1] >= 255)
173
+ raise "Ran out of subnets"
174
+ end
176
175
  end
177
176
  end
178
177
  end
178
+ # subnet_config['Gateway']
179
179
  end
180
- # subnet_config['Gateway']
181
180
  end
182
181
  end
183
182
  end
184
183
  end
184
+
185
185
 
186
186
  options = {
187
187
  "Name" => network_name,
@@ -192,8 +192,8 @@ class Docker::Swarm::Swarm
192
192
  "Driver" => "default",
193
193
  "Config" => [
194
194
  {
195
- "Subnet": "#{subnet_16_parts.join(".")}/16",
196
- "Gateway": "#{subnet_16_parts[0, 3].join('.')}.1"
195
+ "Subnet" => "#{subnet_16_parts.join(".")}/16",
196
+ "Gateway"=> "#{subnet_16_parts[0, 3].join('.')}.1"
197
197
  }
198
198
  ],
199
199
  "Options" => {
@@ -211,15 +211,6 @@ class Docker::Swarm::Swarm
211
211
  create_network(options)
212
212
  end
213
213
 
214
- def find_network_by_name(network_name)
215
- networks.each do |network|
216
- if (network.name == network_name)
217
- return network
218
- end
219
- end
220
- return nil
221
- end
222
-
223
214
  # Return all of the Nodes.
224
215
  def nodes
225
216
  opts = {}
@@ -278,10 +269,11 @@ class Docker::Swarm::Swarm
278
269
  return items
279
270
  end
280
271
 
272
+
281
273
  # Initialize Swarm
282
274
  def self.init(opts, connection)
283
275
  query = {}
284
- resp = connection.post('/swarm/init', query, :body => opts.to_json, full_response: true, expects: [200, 404, 500])
276
+ resp = connection.post('/swarm/init', query, :body => opts.to_json, full_response: true, expects: [200, 404, 406, 500])
285
277
  if (resp.status == 200)
286
278
  swarm = Docker::Swarm::Swarm.swarm(opts, connection)
287
279
  manager_node = swarm.nodes.find {|n|
@@ -296,14 +288,19 @@ class Docker::Swarm::Swarm
296
288
  end
297
289
 
298
290
  # docker swarm join-token -q worker
299
- def self.swarm(opts, connection)
291
+ def self.swarm(options, connection)
300
292
  query = {}
301
- resp = connection.get('/swarm', query, :body => opts.to_json, expects: [200, 404, 406], full_response: true)
293
+ resp = connection.get('/swarm', query, :body => options.to_json, expects: [200, 404, 406], full_response: true)
302
294
  if (resp.status == 406) || (resp.status == 404)
303
295
  return nil
304
296
  elsif (resp.status == 200)
305
297
  hash = JSON.parse(resp.body)
306
- return Docker::Swarm::Swarm.new(hash, connection)
298
+ swarm = self.find_swarm_for_id(hash['ID'])
299
+ if (swarm)
300
+ swarm.update_data(hash)
301
+ else
302
+ swarm = Docker::Swarm::Swarm.new(hash, connection, options)
303
+ end
307
304
  else
308
305
  raise "Bad response: #{resp.status} #{resp.body}"
309
306
  end
@@ -322,7 +319,13 @@ class Docker::Swarm::Swarm
322
319
  query = {}
323
320
  response = connection.get('/swarm', query, expects: [200, 404, 406], full_response: true)
324
321
  if (response.status == 200)
325
- swarm = Docker::Swarm::Swarm.new(JSON.parse(response.body), connection, options)
322
+ hash = JSON.parse(response.body)
323
+ swarm = self.find_swarm_for_id(hash['ID'])
324
+ if (swarm)
325
+ swarm.update_data(hash)
326
+ else
327
+ swarm = Docker::Swarm::Swarm.new(hash, connection, options)
328
+ end
326
329
  manager_node = swarm.nodes.find {|n|
327
330
  (n.hash['ManagerStatus']) && (n.hash['ManagerStatus']['Leader'] == true)
328
331
  }
@@ -336,5 +339,25 @@ class Docker::Swarm::Swarm
336
339
  end
337
340
  end
338
341
 
342
+
343
+ private
344
+ @@swarms = {}
345
+
346
+ def self.find_swarm_for_id(swarm_id)
347
+ return @@swarms[swarm_id]
348
+ end
349
+
350
+ def initialize(hash, manager_connection, options = {})
351
+ @hash = hash
352
+ @id = hash['ID']
353
+ @worker_join_token = hash['JoinTokens']['Worker']
354
+ @manager_join_token = hash['JoinTokens']['Manager']
355
+ @node_hash = {}
356
+ @manager_connection = manager_connection
357
+ @@swarms[@id] = self
358
+ end
359
+
360
+
361
+
339
362
 
340
363
  end
@@ -1,7 +1,7 @@
1
1
  module Docker
2
2
  module Swarm
3
3
  # The version of the docker-api gem.
4
- VERSION = '1.2.4'
4
+ VERSION = '1.2.5'
5
5
 
6
6
  # The version of the compatible Docker remote API.
7
7
  API_VERSION = '1.24'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-swarm-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore / Rogue Wave Software
@@ -188,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  version: '0'
189
189
  requirements: []
190
190
  rubyforge_project:
191
- rubygems_version: 2.4.5.1
191
+ rubygems_version: 2.4.8
192
192
  signing_key:
193
193
  specification_version: 4
194
194
  summary: Ruby API for Docker Swarm