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 +4 -4
- data/lib/docker/swarm/network.rb +4 -13
- data/lib/docker/swarm/node.rb +84 -4
- data/lib/docker/swarm/service.rb +0 -1
- data/lib/docker/swarm/swarm.rb +72 -49
- data/lib/docker/swarm/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df2548b509bebf94428c7bdbfbfc43ea3d2f3311
|
4
|
+
data.tar.gz: 0381001594e826d6b621d2598b96b52b2e2db15c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fed1ac9841af1977852dd9d609ddda922987d0e1d45abe03cbe075923ab411e3da863f5b1260cfe72c14592602a3d6218e6a7c94eb71ecb14b87356998c42ac8
|
7
|
+
data.tar.gz: 8458904be3f28de9125ba98a8f596ea1382bdcf6248761de7125c0b59998e082cfbbfe0daccdaf9298521b3102398ebd318421fd20ca7046e15000f066d7bd3b
|
data/lib/docker/swarm/network.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
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:
|
data/lib/docker/swarm/node.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# This class represents a Docker Swarm Node.
|
2
2
|
class Docker::Swarm::Node
|
3
|
-
|
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
|
|
data/lib/docker/swarm/service.rb
CHANGED
data/lib/docker/swarm/swarm.rb
CHANGED
@@ -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,
|
151
|
-
|
145
|
+
subnet_16_parts = [10, 10, 0, 0]
|
152
146
|
max_vxlanid = 200
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
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
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
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"
|
196
|
-
"Gateway"
|
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(
|
291
|
+
def self.swarm(options, connection)
|
300
292
|
query = {}
|
301
|
-
resp = connection.get('/swarm', query, :body =>
|
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
|
-
|
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
|
-
|
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
|
data/lib/docker/swarm/version.rb
CHANGED
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
|
+
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.
|
191
|
+
rubygems_version: 2.4.8
|
192
192
|
signing_key:
|
193
193
|
specification_version: 4
|
194
194
|
summary: Ruby API for Docker Swarm
|