docker-swarm-api 1.2.4 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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