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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d963d1a5f11dc79f4f59209b15831f5de846fba
4
- data.tar.gz: 0cd84643a8db6339b35b9ac57cc43089dc2d3113
3
+ metadata.gz: 04b3f0bbdfe51472c479d55d01b295dd1fbd700a
4
+ data.tar.gz: ea9e5330f567696ad9e3feae4fd49c809502cb5a
5
5
  SHA512:
6
- metadata.gz: 3011ab70801130ee1b0f5267a31d0ad497fc5bd6797be0cf5021aa2bf52ea3c44b891dd4806347758037f94cacba805e5841c77a5b920308c1bdc6bbfd1679ff
7
- data.tar.gz: f95c92b052331db406d6d933053471c79fa7fdcda46e5ad9321c50921c605498703cfc4e78f4f1255daa9857f8bf9100f95134f3f7ebad885234ab0ebda4c71a
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
- master_connection = Docker::Swarm::Connection.new('http://10.20.30.1')
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 = Docker::Swarm::Node.all({}, master_connection)
25
+ nodes = swarm.nodes
25
26
 
26
27
  # Create a network which connect services
27
- network = Docker::Swarm::Network.create(network_name, opts = {}, master_connection)
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 = Docker::Swarm::Service.create(service_create_options, master_connection)
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 = Docker::Swarm::Task.all({}, master_connection)
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
- Docker::Swarm::Swarm.leave(false, worker_connection)
109
+ swarm.leave(false, worker_connection)
107
110
 
108
111
  # Manager leaves the swarm - forced because manager's need to force the issue.
109
- Docker::Swarm::Swarm.leave(true, master_connection)
112
+ swarm.leave(true, master_connection)
113
+
110
114
  ```
@@ -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(hash, connection)
11
+ def initialize(swarm, hash)
11
12
  @hash = hash
12
- @connection = connection
13
- hash['Description']['Hostname']
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
- # Return all of the Nodes.
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
- resp = conn.get('/nodes', query, :body => opts.to_json)
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
- # private :path_for
71
- # private_class_method :new
71
+
72
+
72
73
  end
@@ -4,8 +4,8 @@ class Docker::Swarm::Service
4
4
  #include Docker::Base
5
5
  attr_reader :hash
6
6
 
7
- def initialize(hash, connection)
8
- @connection = connection
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
@@ -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
- attr_reader :worker_join_token, :manager_join_token, :id, :hash
5
+ include Docker
6
+ attr_reader :worker_join_token, :manager_join_token, :id, :hash, :node_hash
6
7
 
7
- def initialize(hash, connection)
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
- @workers = []
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(worker_ip, worker_connection)
18
+ def join(node_connection, join_token)
19
+ node_ids_before = nodes().collect {|n| n.id}
17
20
  query = {}
18
- master_ip = @connection.url.split("//").last.split(":").first
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" => "#{worker_ip}:2377",
25
+ "AdvertiseAddr" => "#{new_node_ip}:2377",
22
26
  "RemoteAddrs" => ["#{master_ip}:2377"],
23
- "JoinToken" => @worker_join_token
27
+ "JoinToken" => join_token
24
28
  }
25
- resp = worker_connection.post('/swarm/join', query, :body => join_options.to_json)
26
- @workers << {address: worker_ip, connection: worker_connection}
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 = Docker::Swarm::Node.all({}, @connection)
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 = Docker::Swarm::Node.all({}, @connection)
38
- nodes.select { |node|
39
- node.role == :worker
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 leave(force = true)
44
- Docker::Swarm::Swarm.leave(force, @connection)
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, conn = Docker.connection)
144
+ def self.init(opts, connection)
49
145
  query = {}
50
- resp = conn.post('/swarm/init', query, :body => opts.to_json, full_response: true)
51
- return Docker::Swarm::Swarm.swarm(opts, conn)
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, conn = Docker.connection)
151
+ def self.swarm(opts, connection)
56
152
  query = {}
57
- resp = conn.get('/swarm', query, :body => opts.to_json, expects: [200, 406], full_response: true)
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, conn)
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, conn = Docker.connection)
164
+ def self.leave(force, connection)
69
165
  query = {}
70
166
  query['force'] = force
71
- conn.post('/swarm/leave', query, expects: [200, 406])
167
+ connection.post('/swarm/leave', query, expects: [200, 406])
72
168
  end
73
169
 
170
+
74
171
 
75
172
  end
@@ -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
@@ -1,7 +1,7 @@
1
1
  module Docker
2
2
  module Swarm
3
3
  # The version of the docker-api gem.
4
- VERSION = '1.0'
4
+ VERSION = '1.1'
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.0'
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: retries
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.0.5
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.0.5
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement