docker-swarm-api 1.0 → 1.1
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/README.md +13 -9
- data/lib/docker/swarm/node.rb +19 -18
- data/lib/docker/swarm/service.rb +4 -20
- data/lib/docker/swarm/swarm.rb +125 -28
- data/lib/docker/swarm/task.rb +2 -13
- data/lib/docker/swarm/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04b3f0bbdfe51472c479d55d01b295dd1fbd700a
|
4
|
+
data.tar.gz: ea9e5330f567696ad9e3feae4fd49c809502cb5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 605b03b067f0762243ff3cd7942c48313918550ec7589b2c0a43c0644ec08cbd46f6b56c77183643d5bbb4033ab660b3256b26f03ee6e5420eca6e4d494c9f42
|
7
|
+
data.tar.gz: 01d83aaa468cfc32fcadc2e570407565ce26affec0983ce579c3eb47cb14945e2546973cd23b66012bdf34b41a1656a4063107677a6ebc8406b0941402cd64fe
|
data/README.md
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
Sample Usage
|
4
4
|
------------
|
5
5
|
```ruby
|
6
|
-
|
6
|
+
# Create a Swarm cluster
|
7
|
+
master_connection = Docker::Swarm::Connection.new('http://10.20.30.1:2375')
|
7
8
|
|
8
9
|
# Manager node intializes swarm
|
9
10
|
swarm_init_options = {
|
@@ -17,14 +18,17 @@ nodes = Docker::Swarm::Node.all({}, master_connection)
|
|
17
18
|
expect(nodes.length).to eq 1
|
18
19
|
|
19
20
|
# Worker joins swarm
|
20
|
-
worker_connection = Docker::Swarm::Connection.new('http://10.20.30.2')
|
21
|
+
worker_connection = Docker::Swarm::Connection.new('http://10.20.30.2:2375')
|
21
22
|
swarm.join(worker_ip, worker_connection)
|
22
23
|
|
23
24
|
# Gather all nodes of swarm
|
24
|
-
nodes =
|
25
|
+
nodes = swarm.nodes
|
25
26
|
|
26
27
|
# Create a network which connect services
|
27
|
-
network =
|
28
|
+
network = swarm.create_network(network_name)
|
29
|
+
|
30
|
+
# Find all networks in swarm cluster
|
31
|
+
networks = swarm.networks
|
28
32
|
|
29
33
|
# Create a service with 5 replicas
|
30
34
|
service_create_options = {
|
@@ -83,7 +87,7 @@ service_create_options = {
|
|
83
87
|
}
|
84
88
|
}
|
85
89
|
|
86
|
-
service =
|
90
|
+
service = swarm.create_service(service_create_options)
|
87
91
|
|
88
92
|
# Retrieve all manager nodes of swarm
|
89
93
|
manager_nodes = swarm.manager_nodes
|
@@ -96,15 +100,15 @@ worker_node = worker_nodes.first
|
|
96
100
|
worker_node.drain
|
97
101
|
|
98
102
|
# Gather all tasks (containers for service) being hosted by the swarm cluster
|
99
|
-
tasks =
|
103
|
+
tasks = swarm.tasks
|
100
104
|
|
101
105
|
# Scale up or down the number of replicas on a service
|
102
106
|
service.scale(20)
|
103
|
-
|
104
107
|
|
105
108
|
# Worker leaves the swarm - no forcing
|
106
|
-
|
109
|
+
swarm.leave(false, worker_connection)
|
107
110
|
|
108
111
|
# Manager leaves the swarm - forced because manager's need to force the issue.
|
109
|
-
|
112
|
+
swarm.leave(true, master_connection)
|
113
|
+
|
110
114
|
```
|
data/lib/docker/swarm/node.rb
CHANGED
@@ -2,15 +2,21 @@
|
|
2
2
|
class Docker::Swarm::Node
|
3
3
|
#include Docker::Base
|
4
4
|
attr_reader :hash
|
5
|
+
attr_accessor :connection
|
5
6
|
AVAILABILITY = {
|
6
7
|
active: "active",
|
7
8
|
drain: "drain"
|
8
9
|
}
|
9
10
|
|
10
|
-
def initialize(
|
11
|
+
def initialize(swarm, hash)
|
11
12
|
@hash = hash
|
12
|
-
@
|
13
|
-
|
13
|
+
@swarm = swarm
|
14
|
+
end
|
15
|
+
|
16
|
+
def refresh
|
17
|
+
query = {}
|
18
|
+
response = @swarm.connection.get("/nodes/#{id}", query, expects: [200])
|
19
|
+
@hash = JSON.parse(response)
|
14
20
|
end
|
15
21
|
|
16
22
|
def id
|
@@ -47,26 +53,21 @@ class Docker::Swarm::Node
|
|
47
53
|
change_availability(:active)
|
48
54
|
end
|
49
55
|
|
56
|
+
def remove
|
57
|
+
Docker::Swarm::Node.remove(id(), @connection)
|
58
|
+
end
|
59
|
+
|
50
60
|
def change_availability(availability)
|
51
61
|
raise "Bad availability param: #{availability}" if (!AVAILABILITY[availability])
|
52
62
|
@hash['Spec']['Availability'] = AVAILABILITY[availability]
|
53
63
|
query = {version: @hash['Version']['Index']}
|
54
|
-
response = @connection.post("/nodes/#{self.id}/update", query, :body => @hash['Spec'].to_json)
|
64
|
+
response = @swarm.connection.post("/nodes/#{self.id}/update", query, :body => @hash['Spec'].to_json)
|
55
65
|
end
|
56
|
-
|
57
|
-
|
58
|
-
def self.all(opts = {}, conn = Docker.connection)
|
59
|
-
raise "opts needs to be hash" if (opts.class != Hash)
|
66
|
+
|
67
|
+
def remove
|
60
68
|
query = {}
|
61
|
-
|
62
|
-
hashes = JSON.parse(resp)
|
63
|
-
nodes = []
|
64
|
-
hashes.each do |node_hash|
|
65
|
-
nodes << Docker::Swarm::Node.new(node_hash, conn)
|
66
|
-
end
|
67
|
-
return nodes
|
69
|
+
response = @swarm.connection.delete("/nodes/#{self.id}", query, expects: [200, 406])
|
68
70
|
end
|
69
|
-
|
70
|
-
|
71
|
-
# private_class_method :new
|
71
|
+
|
72
|
+
|
72
73
|
end
|
data/lib/docker/swarm/service.rb
CHANGED
@@ -4,8 +4,8 @@ class Docker::Swarm::Service
|
|
4
4
|
#include Docker::Base
|
5
5
|
attr_reader :hash
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(swarm, hash)
|
8
|
+
@swarm = swarm
|
9
9
|
@hash = hash
|
10
10
|
end
|
11
11
|
|
@@ -15,36 +15,20 @@ class Docker::Swarm::Service
|
|
15
15
|
|
16
16
|
def remove(opts = {})
|
17
17
|
query = {}
|
18
|
-
@connection.delete("/services/#{self.id}", query, :body => opts.to_json)
|
18
|
+
@swarm.connection.delete("/services/#{self.id}", query, :body => opts.to_json)
|
19
19
|
end
|
20
20
|
|
21
21
|
def update(opts)
|
22
22
|
query = {}
|
23
23
|
version = @hash['Version']['Index']
|
24
|
-
response = @connection.post("/services/#{self.id}/update?version=#{version}", query, :body => opts.to_json)
|
24
|
+
response = @swarm.connection.post("/services/#{self.id}/update?version=#{version}", query, :body => opts.to_json)
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
27
|
def scale(count)
|
29
28
|
@hash['Spec']['Mode']['Replicated']['Replicas'] = count
|
30
29
|
self.update(@hash['Spec'])
|
31
30
|
end
|
32
31
|
|
33
|
-
def self.create(opts = {}, conn = Docker.connection)
|
34
|
-
query = {}
|
35
|
-
response = conn.post('/services/create', query, :body => opts.to_json)
|
36
|
-
info = JSON.parse(response)
|
37
|
-
service_id = info['ID']
|
38
|
-
return self.find(service_id, conn)
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.find(id, conn = Docker.connection)
|
42
|
-
query = {}
|
43
|
-
opts = {}
|
44
|
-
response = conn.get("/services/#{id}", query, :body => opts.to_json)
|
45
|
-
hash = JSON.parse(response)
|
46
|
-
return Docker::Swarm::Service.new(hash, conn)
|
47
|
-
end
|
48
32
|
|
49
33
|
|
50
34
|
end
|
data/lib/docker/swarm/swarm.rb
CHANGED
@@ -2,74 +2,171 @@ require 'docker-api'
|
|
2
2
|
|
3
3
|
# This class represents a Docker Swarm Node.
|
4
4
|
class Docker::Swarm::Swarm
|
5
|
-
|
5
|
+
include Docker
|
6
|
+
attr_reader :worker_join_token, :manager_join_token, :id, :hash, :node_hash
|
6
7
|
|
7
|
-
def initialize(hash,
|
8
|
-
@connection = connection
|
8
|
+
def initialize(hash, manager_connection)
|
9
9
|
@hash = hash
|
10
10
|
@id = hash['ID']
|
11
11
|
@worker_join_token = hash['JoinTokens']['Worker']
|
12
12
|
@manager_join_token = hash['JoinTokens']['Manager']
|
13
|
-
|
13
|
+
manager_node = nodes(manager_connection).first
|
14
|
+
@node_hash = {}
|
15
|
+
@node_hash[manager_node.id] = {hash: manager_node.hash, connection: manager_connection}
|
14
16
|
end
|
15
17
|
|
16
|
-
def join(
|
18
|
+
def join(node_connection, join_token)
|
19
|
+
node_ids_before = nodes().collect {|n| n.id}
|
17
20
|
query = {}
|
18
|
-
master_ip =
|
21
|
+
master_ip = self.connection.url.split("//").last.split(":").first
|
22
|
+
new_node_ip = node_connection.url.split("//").last.split(":").first
|
19
23
|
join_options = {
|
20
24
|
"ListenAddr" => "0.0.0.0:2377",
|
21
|
-
"AdvertiseAddr" => "#{
|
25
|
+
"AdvertiseAddr" => "#{new_node_ip}:2377",
|
22
26
|
"RemoteAddrs" => ["#{master_ip}:2377"],
|
23
|
-
"JoinToken" =>
|
27
|
+
"JoinToken" => join_token
|
24
28
|
}
|
25
|
-
resp =
|
26
|
-
|
29
|
+
resp = node_connection.post('/swarm/join', query, :body => join_options.to_json, expects: [200])
|
30
|
+
nodes.each do |node|
|
31
|
+
if (!node_ids_before.include? node.id)
|
32
|
+
@node_hash[node.id] = {hash: node.hash, connection: node_connection}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def connection
|
38
|
+
@node_hash.keys.each do |node_id|
|
39
|
+
node_info = @node_hash[node_id]
|
40
|
+
if (node_info[:hash]['ManagerStatus'])
|
41
|
+
return node_info[:connection]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
raise "No manager connection found for swarm"
|
45
|
+
end
|
46
|
+
|
47
|
+
def join_worker(node_connection)
|
48
|
+
join(node_connection, @worker_join_token)
|
49
|
+
end
|
50
|
+
|
51
|
+
def join_manager(manager_connection)
|
52
|
+
join(node_connection, @manager_join_token)
|
27
53
|
end
|
28
54
|
|
55
|
+
def remove
|
56
|
+
worker_nodes.each do |node|
|
57
|
+
leave(node, true)
|
58
|
+
end
|
59
|
+
manager_nodes.each do |node|
|
60
|
+
leave(node, true)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def tasks
|
65
|
+
items = []
|
66
|
+
query = {}
|
67
|
+
opts = {}
|
68
|
+
resp = self.connection.get('/tasks', query, :body => opts.to_json)
|
69
|
+
hashes = JSON.parse(resp)
|
70
|
+
items = []
|
71
|
+
hashes.each do |hash|
|
72
|
+
items << Swarm::Task.new(self, hash)
|
73
|
+
end
|
74
|
+
return items
|
75
|
+
end
|
76
|
+
|
77
|
+
def leave(node, force = false)
|
78
|
+
node.connection = self.connection
|
79
|
+
node_info = @node_hash[node.id]
|
80
|
+
if (node_info)
|
81
|
+
Docker::Swarm::Swarm.leave(force, node_info[:connection])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def remove_node(worker_node)
|
86
|
+
Swarm::Node.remove(worker_node.id, self.connection)
|
87
|
+
end
|
88
|
+
|
29
89
|
def manager_nodes
|
30
|
-
nodes
|
31
|
-
nodes.select { |node|
|
32
|
-
node.role == :manager
|
33
|
-
}
|
90
|
+
return nodes.select { |node| node.role == :manager} || []
|
34
91
|
end
|
35
92
|
|
36
93
|
def worker_nodes
|
37
|
-
nodes
|
38
|
-
|
39
|
-
|
40
|
-
|
94
|
+
return nodes.select { |node| node.role == :worker} || []
|
95
|
+
end
|
96
|
+
|
97
|
+
def networks
|
98
|
+
networks = Docker::Network.all({}, self.connection)
|
99
|
+
end
|
100
|
+
|
101
|
+
def create_network(network_name)
|
102
|
+
return Docker::Swarm::Network.create(network_name, opts = {}, self.connection)
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_network_by_name(network_name)
|
106
|
+
return Docker::Swarm::Network::find_by_name(network_name, self.connection)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return all of the Nodes.
|
110
|
+
def nodes(conn = self.connection)
|
111
|
+
opts = {}
|
112
|
+
query = {}
|
113
|
+
response = conn.get('/nodes', query, :body => opts.to_json, expects: [200, 406], full_response: true)
|
114
|
+
if (response.status == 200)
|
115
|
+
hashes = JSON.parse(response.body)
|
116
|
+
nodes = []
|
117
|
+
hashes.each do |node_hash|
|
118
|
+
nodes << Docker::Swarm::Node.new(self, node_hash)
|
119
|
+
end
|
120
|
+
return nodes || []
|
121
|
+
else
|
122
|
+
return []
|
123
|
+
end
|
41
124
|
end
|
42
125
|
|
43
|
-
def
|
44
|
-
|
126
|
+
def create_service(opts = {})
|
127
|
+
query = {}
|
128
|
+
response = self.connection.post('/services/create', query, :body => opts.to_json)
|
129
|
+
info = JSON.parse(response)
|
130
|
+
service_id = info['ID']
|
131
|
+
return self.find_service(service_id)
|
132
|
+
end
|
133
|
+
|
134
|
+
def find_service(id)
|
135
|
+
query = {}
|
136
|
+
opts = {}
|
137
|
+
response = self.connection.get("/services/#{id}", query, :body => opts.to_json)
|
138
|
+
hash = JSON.parse(response)
|
139
|
+
return Docker::Swarm::Service.new(self, hash)
|
45
140
|
end
|
46
141
|
|
142
|
+
|
47
143
|
# Initialize Swarm
|
48
|
-
def self.init(opts,
|
144
|
+
def self.init(opts, connection)
|
49
145
|
query = {}
|
50
|
-
resp =
|
51
|
-
return Docker::Swarm::Swarm.swarm(opts,
|
146
|
+
resp = connection.post('/swarm/init', query, :body => opts.to_json, full_response: true)
|
147
|
+
return Docker::Swarm::Swarm.swarm(opts, connection)
|
52
148
|
end
|
53
149
|
|
54
150
|
# docker swarm join-token -q worker
|
55
|
-
def self.swarm(opts,
|
151
|
+
def self.swarm(opts, connection)
|
56
152
|
query = {}
|
57
|
-
resp =
|
153
|
+
resp = connection.get('/swarm', query, :body => opts.to_json, expects: [200, 406], full_response: true)
|
58
154
|
if (resp.status == 406)
|
59
155
|
return nil
|
60
156
|
elsif (resp.status == 200)
|
61
157
|
hash = JSON.parse(resp.body)
|
62
|
-
return Docker::Swarm::Swarm.new(hash,
|
158
|
+
return Docker::Swarm::Swarm.new(hash, connection)
|
63
159
|
else
|
64
160
|
raise "Bad response: #{resp.status} #{resp.body}"
|
65
161
|
end
|
66
162
|
end
|
67
163
|
|
68
|
-
def self.leave(force,
|
164
|
+
def self.leave(force, connection)
|
69
165
|
query = {}
|
70
166
|
query['force'] = force
|
71
|
-
|
167
|
+
connection.post('/swarm/leave', query, expects: [200, 406])
|
72
168
|
end
|
73
169
|
|
170
|
+
|
74
171
|
|
75
172
|
end
|
data/lib/docker/swarm/task.rb
CHANGED
@@ -3,8 +3,9 @@ class Docker::Swarm::Task
|
|
3
3
|
#include Docker::Base
|
4
4
|
attr_reader :hash
|
5
5
|
|
6
|
-
def initialize(hash)
|
6
|
+
def initialize(swarm, hash)
|
7
7
|
@hash = hash
|
8
|
+
@swarm = swarm
|
8
9
|
end
|
9
10
|
|
10
11
|
def id
|
@@ -31,17 +32,5 @@ class Docker::Swarm::Task
|
|
31
32
|
@hash['Status']['State'].to_sym
|
32
33
|
end
|
33
34
|
|
34
|
-
# Return all of the Nodes.
|
35
|
-
def self.all(opts = {}, conn = Docker.connection)
|
36
|
-
raise "opts needs to be hash" if (opts.class != Hash)
|
37
|
-
query = {}
|
38
|
-
resp = conn.get('/tasks', query, :body => opts.to_json)
|
39
|
-
hashes = JSON.parse(resp)
|
40
|
-
items = []
|
41
|
-
hashes.each do |hash|
|
42
|
-
items << Docker::Swarm::Task.new(hash)
|
43
|
-
end
|
44
|
-
return items
|
45
|
-
end
|
46
35
|
|
47
36
|
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.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Moore / Rogue Wave Software
|
@@ -53,19 +53,19 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '6.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: retry_block
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|