nomade 0.0.2 → 0.0.3

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: 158ef957259ed3df2c6de748751d4e3561a21fc0
4
- data.tar.gz: 06101a19896eba831d43a09aa6de5ac03b49d8ad
3
+ metadata.gz: 66623cdf7c89395ba7cd5ec0e44da3f7f528acb9
4
+ data.tar.gz: 74babd5bdb5d5defa0f8d43c48b58122d0e9ed62
5
5
  SHA512:
6
- metadata.gz: a5c2a3828cfaab475a92deea886c11088d55a8ad5560279964bdbf339c8f3835e6c6b6a62f31a28ae4e5a979b1ff75eaf6bfb519896a3660ecd4ea4d792dc118
7
- data.tar.gz: c2a1b9d62c7a98c1e010ec63714314958c4f269cd2c802063da5191e5c8b8024a651e76bdfae2290acf59b251d339438c735cc5b40d6a176f144ba74a85a78f8
6
+ metadata.gz: c82745d63012c33c98e7e23f178deb9caeb071189aa9b6e317c2251efdc10bebae3bbf96c6f4d89861492f9bc88c081d7947f27d7c70dd6993965fc56dcb50ff
7
+ data.tar.gz: 29da63fc9823646b42605d759c989b7bc30d19c1677acb9d38b11c8fe444f817a1302df7d7cb024f8674ec3ccddabe9ed9bfa7548cbf3b06d249d8c09a27ff94
@@ -1,64 +1,65 @@
1
1
  module Nomade
2
2
  class Deployer
3
- def initialize(nomad_endpoint, nomad_job)
3
+ def initialize(nomad_endpoint, nomad_job, opts = {})
4
4
  @nomad_job = nomad_job
5
5
  @evaluation_id = nil
6
6
  @deployment_id = nil
7
7
  @timeout = Time.now.utc + 60 * 9 # minutes
8
8
  @nomad_endpoint = nomad_endpoint
9
9
  @http = Nomade::Http.new(@nomad_endpoint)
10
+ @logger = opts.fetch(:logger, Nomade.logger)
10
11
  end
11
12
 
12
13
  def deploy!
13
14
  deploy
14
15
  rescue Nomade::NoModificationsError => e
15
- Nomade.logger.warn "No modifications to make, exiting!"
16
+ @logger.warn "No modifications to make, exiting!"
16
17
  exit(0)
17
18
  rescue Nomade::GeneralError => e
18
- Nomade.logger.warn e.message
19
- Nomade.logger.warn "GeneralError hit, exiting!"
19
+ @logger.warn e.message
20
+ @logger.warn "GeneralError hit, exiting!"
20
21
  exit(1)
21
22
  rescue Nomade::PlanningError => e
22
- Nomade.logger.warn "Couldn't make a plan, maybe a bad connection to Nomad server, exiting!"
23
+ @logger.warn "Couldn't make a plan, maybe a bad connection to Nomad server, exiting!"
23
24
  exit(2)
24
25
  rescue Nomade::AllocationFailedError => e
25
- Nomade.logger.warn "Allocation failed with errors, exiting!"
26
+ @logger.warn "Allocation failed with errors, exiting!"
26
27
  exit(3)
27
28
  rescue Nomade::UnsupportedDeploymentMode => e
28
- Nomade.logger.warn e.message
29
- Nomade.logger.warn "Deployment failed with errors, exiting!"
29
+ @logger.warn e.message
30
+ @logger.warn "Deployment failed with errors, exiting!"
30
31
  exit(4)
31
32
  end
32
33
 
33
34
  private
34
35
 
35
36
  def deploy
36
- Nomade.logger.info "Deploying #{@nomad_job.job_name} (#{@nomad_job.job_type}) with #{@nomad_job.image_name_and_version}"
37
- Nomade.logger.info "URL: #{@nomad_endpoint}/ui/jobs/#{@nomad_job.job_name}"
37
+ @logger.info "Deploying #{@nomad_job.job_name} (#{@nomad_job.job_type}) with #{@nomad_job.image_name_and_version}"
38
+ @logger.info "URL: #{@nomad_endpoint}/ui/jobs/#{@nomad_job.job_name}"
38
39
 
39
- Nomade.logger.info "Checking cluster for connectivity and capacity.."
40
+ @logger.info "Checking cluster for connectivity and capacity.."
40
41
  @http.plan_job(@nomad_job)
41
42
 
42
43
  @evaluation_id = if @http.check_if_job_exists?(@nomad_job)
43
- Nomade.logger.info "Updating existing job"
44
+ @logger.info "Updating existing job"
44
45
  @http.update_job(@nomad_job)
45
46
  else
46
- Nomade.logger.info "Creating new job"
47
+ @logger.info "Creating new job"
47
48
  @http.create_job(@nomad_job)
48
49
  end
49
50
 
50
- Nomade.logger.info "EvaluationID: #{@evaluation_id}"
51
- Nomade.logger.info "#{@evaluation_id} Waiting until evaluation is complete"
51
+ @logger.info "EvaluationID: #{@evaluation_id}"
52
+ @logger.info "#{@evaluation_id} Waiting until evaluation is complete"
52
53
  eval_status = nil
53
54
  while(eval_status != "complete") do
54
55
  evaluation = @http.evaluation_request(@evaluation_id)
55
56
  @deployment_id ||= evaluation["DeploymentID"]
56
57
  eval_status = evaluation["Status"]
57
- Nomade.logger.info "."
58
+ @logger.info "."
58
59
  sleep(1)
59
60
  end
60
61
 
61
- Nomade.logger.info "Waiting until allocations are complete"
62
+ @logger.info "Waiting until allocations are complete"
62
63
  case @nomad_job.job_type
63
64
  when "service"
64
65
  service_deploy
@@ -72,28 +73,28 @@ module Nomade
72
73
  allocation["TaskStates"].sort.each do |task_name, task_data|
73
74
  pretty_state = Nomade::Decorator.task_state_decorator(task_data["State"], task_data["Failed"])
74
75
 
75
- Nomade.logger.info ""
76
- Nomade.logger.info "#{allocation["ID"]} #{allocation["Name"]} #{task_name}: #{pretty_state}"
76
+ @logger.info ""
77
+ @logger.info "#{allocation["ID"]} #{allocation["Name"]} #{task_name}: #{pretty_state}"
77
78
  unless task_data["Failed"]
78
- Nomade.logger.info "Task \"#{task_name}\" was succesfully run, skipping log-printing because it isn't relevant!"
79
+ @logger.info "Task \"#{task_name}\" was succesfully run, skipping log-printing because it isn't relevant!"
79
80
  next
80
81
  end
81
82
 
82
83
  stdout = @http.get_allocation_logs(allocation["ID"], task_name, "stdout")
83
84
  if stdout != ""
84
- Nomade.logger.info
85
- Nomade.logger.info "stdout:"
85
+ @logger.info
86
+ @logger.info "stdout:"
86
87
  stdout.lines do |logline|
87
- Nomade.logger.info(logline.strip)
88
+ @logger.info(logline.strip)
88
89
  end
89
90
  end
90
91
 
91
92
  stderr = @http.get_allocation_logs(allocation["ID"], task_name, "stderr")
92
93
  if stderr != ""
93
- Nomade.logger.info
94
- Nomade.logger.info "stderr:"
94
+ @logger.info
95
+ @logger.info "stderr:"
95
96
  stderr.lines do |logline|
96
- Nomade.logger.info(logline.strip)
97
+ @logger.info(logline.strip)
97
98
  end
98
99
  end
99
100
 
@@ -107,7 +108,7 @@ module Nomade
107
108
  "(#{dts})"
108
109
  end
109
110
 
110
- Nomade.logger.info "[#{event_time}] #{event_type}: #{event_message} #{event_details}"
111
+ @logger.info "[#{event_time}] #{event_type}: #{event_message} #{event_details}"
111
112
  end
112
113
  end
113
114
  end
@@ -116,21 +117,21 @@ module Nomade
116
117
  end
117
118
 
118
119
  def service_deploy
119
- Nomade.logger.info "Waiting until tasks are placed"
120
- Nomade.logger.info ".. deploy timeout is #{@timeout}"
120
+ @logger.info "Waiting until tasks are placed"
121
+ @logger.info ".. deploy timeout is #{@timeout}"
121
122
 
122
123
  json = @http.deployment_request(@deployment_id)
123
- Nomade.logger.info "#{json["JobID"]} version #{json["JobVersion"]}"
124
+ @logger.info "#{json["JobID"]} version #{json["JobVersion"]}"
124
125
 
125
126
  need_manual_promotion = json["TaskGroups"].values.any?{|tg| tg["DesiredCanaries"] > 0 && tg["AutoPromote"] == false}
126
127
  need_manual_rollback = json["TaskGroups"].values.any?{|tg| tg["DesiredCanaries"] > 0 && tg["AutoRevert"] == false}
127
128
 
128
129
  manual_work_required = case [need_manual_promotion, need_manual_rollback]
129
130
  when [true, true]
130
- Nomade.logger.info "Job needs manual promotion/rollback, we'll take care of that!"
131
+ @logger.info "Job needs manual promotion/rollback, we'll take care of that!"
131
132
  true
132
133
  when [false, false]
133
- Nomade.logger.info "Job manages its own promotion/rollback, we will just monitor in a hands-off mode!"
134
+ @logger.info "Job manages its own promotion/rollback, we will just monitor in a hands-off mode!"
134
135
  false
135
136
  when [false, true]
136
137
  raise UnsupportedDeploymentMode.new("Unsupported deployment-mode, manual-promotion=#{need_manual_promotion}, manual-rollback=#{need_manual_rollback}")
@@ -155,37 +156,41 @@ module Nomade
155
156
  unhealthy_allocations = task_data["UnhealthyAllocs"]
156
157
 
157
158
  if manual_work_required
158
- Nomade.logger.info "#{json["ID"]} #{task_name}: #{healthy_allocations}/#{desired_canaries}/#{desired_total} (Healthy/WantedCanaries/Total)"
159
+ @logger.info "#{json["ID"]} #{task_name}: #{healthy_allocations}/#{desired_canaries}/#{desired_total} (Healthy/WantedCanaries/Total)"
159
160
  announced_completed << task_name if healthy_allocations == desired_canaries
160
161
  else
161
- Nomade.logger.info "#{json["ID"]} #{task_name}: #{healthy_allocations}/#{desired_total} (Healthy/Total)"
162
+ @logger.info "#{json["ID"]} #{task_name}: #{healthy_allocations}/#{desired_total} (Healthy/Total)"
162
163
  announced_completed << task_name if healthy_allocations == desired_total
163
164
  end
164
165
  end
165
166
 
166
167
  if manual_work_required
167
168
  if json["Status"] == "failed"
168
- Nomade.logger.info "#{json["Status"]}: #{json["StatusDescription"]}"
169
+ @logger.info "#{json["Status"]}: #{json["StatusDescription"]}"
169
170
  succesful_deployment = false
170
171
  end
171
172
 
172
173
  if succesful_deployment == nil && Time.now.utc > @timeout
173
- Nomade.logger.info "Timeout hit, rolling back deploy!"
174
+ @logger.info "Timeout hit, rolling back deploy!"
174
175
  @http.fail_deployment(@deployment_id)
175
176
  succesful_deployment = false
176
177
  end
177
178
 
178
179
  if succesful_deployment == nil && json["TaskGroups"].values.all?{|tg| tg["HealthyAllocs"] >= tg["DesiredCanaries"]}
179
180
  if !promoted
180
- Nomade.logger.info "Promoting #{@deployment_id} (version #{json["JobVersion"]})"
181
+ random_linger = rand(60..185)
182
+ @logger.info "Lingering around for #{random_linger} seconds before deployment.."
183
+ sleep(random_linger)
184
+
185
+ @logger.info "Promoting #{@deployment_id} (version #{json["JobVersion"]})"
181
186
  @http.promote_deployment(@deployment_id)
182
187
  promoted = true
183
- Nomade.logger.info ".. promoted!"
188
+ @logger.info ".. promoted!"
184
189
  else
185
190
  if json["Status"] == "successful"
186
191
  succesful_deployment = true
187
192
  else
188
- Nomade.logger.info "Waiting for promotion to complete #{@deployment_id} (version #{json["JobVersion"]})"
193
+ @logger.info "Waiting for promotion to complete #{@deployment_id} (version #{json["JobVersion"]})"
189
194
  end
190
195
  end
191
196
  end
@@ -194,10 +199,10 @@ module Nomade
194
199
  when "running"
195
200
  # no-op
196
201
  when "failed"
197
- Nomade.logger.info "#{json["Status"]}: #{json["StatusDescription"]}"
202
+ @logger.info "#{json["Status"]}: #{json["StatusDescription"]}"
198
203
  succesful_deployment = false
199
204
  when "successful"
200
- Nomade.logger.info "#{json["Status"]}: #{json["StatusDescription"]}"
205
+ @logger.info "#{json["Status"]}: #{json["StatusDescription"]}"
201
206
  succesful_deployment = true
202
207
  end
203
208
  end
@@ -206,11 +211,11 @@ module Nomade
206
211
  end
207
212
 
208
213
  if succesful_deployment
209
- Nomade.logger.info ""
210
- Nomade.logger.info "#{@deployment_id} (version #{json["JobVersion"]}) was succesfully deployed!"
214
+ @logger.info ""
215
+ @logger.info "#{@deployment_id} (version #{json["JobVersion"]}) was succesfully deployed!"
211
216
  else
212
- Nomade.logger.warn ""
213
- Nomade.logger.warn "#{@deployment_id} (version #{json["JobVersion"]}) deployment _failed_!"
217
+ @logger.warn ""
218
+ @logger.warn "#{@deployment_id} (version #{json["JobVersion"]}) deployment _failed_!"
214
219
  end
215
220
  end
216
221
 
@@ -227,7 +232,7 @@ module Nomade
227
232
  pretty_state = Nomade::Decorator.task_state_decorator(task_data["State"], task_data["Failed"])
228
233
 
229
234
  unless announced_dead.include?(full_task_address)
230
- Nomade.logger.info "#{allocation["ID"]} #{allocation["Name"]} #{task_name}: #{pretty_state}"
235
+ @logger.info "#{allocation["ID"]} #{allocation["Name"]} #{task_name}: #{pretty_state}"
231
236
 
232
237
  if task_data["State"] == "dead"
233
238
  announced_dead << full_task_address
@@ -246,30 +251,30 @@ module Nomade
246
251
  raise Nomade::AllocationFailedError.new(@evaluation_id, allocations)
247
252
  end
248
253
 
249
- Nomade.logger.info "Deployment complete"
254
+ @logger.info "Deployment complete"
250
255
 
251
256
  allocations.each do |allocation|
252
257
  allocation["TaskStates"].sort.each do |task_name, task_data|
253
258
  pretty_state = Nomade::Decorator.task_state_decorator(task_data["State"], task_data["Failed"])
254
259
 
255
- Nomade.logger.info ""
256
- Nomade.logger.info "#{allocation["ID"]} #{allocation["Name"]} #{task_name}: #{pretty_state}"
260
+ @logger.info ""
261
+ @logger.info "#{allocation["ID"]} #{allocation["Name"]} #{task_name}: #{pretty_state}"
257
262
 
258
263
  stdout = @http.get_allocation_logs(allocation["ID"], task_name, "stdout")
259
264
  if stdout != ""
260
- Nomade.logger.info
261
- Nomade.logger.info "stdout:"
265
+ @logger.info
266
+ @logger.info "stdout:"
262
267
  stdout.lines do |logline|
263
- Nomade.logger.info(logline.strip)
268
+ @logger.info(logline.strip)
264
269
  end
265
270
  end
266
271
 
267
272
  stderr = @http.get_allocation_logs(allocation["ID"], task_name, "stderr")
268
273
  if stderr != ""
269
- Nomade.logger.info
270
- Nomade.logger.info "stderr:"
274
+ @logger.info
275
+ @logger.info "stderr:"
271
276
  stderr.lines do |logline|
272
- Nomade.logger.info(logline.strip)
277
+ @logger.info(logline.strip)
273
278
  end
274
279
  end
275
280
  end
data/lib/nomade/http.rb CHANGED
@@ -16,8 +16,10 @@ module Nomade
16
16
  uri = URI("#{@nomad_endpoint}/v1/jobs#{search_prefix}")
17
17
 
18
18
  http = Net::HTTP.new(uri.host, uri.port)
19
- http.use_ssl = true
20
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
19
+ if @nomad_endpoint.include?("https://")
20
+ http.use_ssl = true
21
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
22
+ end
21
23
 
22
24
  req = Net::HTTP::Get.new(uri)
23
25
  req.add_field "Content-Type", "application/json"
@@ -37,8 +39,10 @@ module Nomade
37
39
  uri = URI("#{@nomad_endpoint}/v1/evaluation/#{evaluation_id}")
38
40
 
39
41
  http = Net::HTTP.new(uri.host, uri.port)
40
- http.use_ssl = true
41
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
42
+ if @nomad_endpoint.include?("https://")
43
+ http.use_ssl = true
44
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
45
+ end
42
46
 
43
47
  req = Net::HTTP::Get.new(uri)
44
48
  req.add_field "Content-Type", "application/json"
@@ -58,8 +62,10 @@ module Nomade
58
62
  uri = URI("#{@nomad_endpoint}/v1/evaluation/#{evaluation_id}/allocations")
59
63
 
60
64
  http = Net::HTTP.new(uri.host, uri.port)
61
- http.use_ssl = true
62
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
65
+ if @nomad_endpoint.include?("https://")
66
+ http.use_ssl = true
67
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
68
+ end
63
69
 
64
70
  req = Net::HTTP::Get.new(uri)
65
71
  req.add_field "Content-Type", "application/json"
@@ -79,8 +85,10 @@ module Nomade
79
85
  uri = URI("#{@nomad_endpoint}/v1/deployment/#{deployment_id}")
80
86
 
81
87
  http = Net::HTTP.new(uri.host, uri.port)
82
- http.use_ssl = true
83
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
88
+ if @nomad_endpoint.include?("https://")
89
+ http.use_ssl = true
90
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
91
+ end
84
92
 
85
93
  req = Net::HTTP::Get.new(uri)
86
94
  req.add_field "Content-Type", "application/json"
@@ -105,8 +113,10 @@ module Nomade
105
113
  uri = URI("#{@nomad_endpoint}/v1/jobs")
106
114
 
107
115
  http = Net::HTTP.new(uri.host, uri.port)
108
- http.use_ssl = true
109
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
116
+ if @nomad_endpoint.include?("https://")
117
+ http.use_ssl = true
118
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
119
+ end
110
120
 
111
121
  req = Net::HTTP::Post.new(uri)
112
122
  req.add_field "Content-Type", "application/json"
@@ -126,8 +136,10 @@ module Nomade
126
136
  uri = URI("#{@nomad_endpoint}/v1/job/#{nomad_job.job_name}")
127
137
 
128
138
  http = Net::HTTP.new(uri.host, uri.port)
129
- http.use_ssl = true
130
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
139
+ if @nomad_endpoint.include?("https://")
140
+ http.use_ssl = true
141
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
142
+ end
131
143
 
132
144
  req = Net::HTTP::Post.new(uri)
133
145
  req.add_field "Content-Type", "application/json"
@@ -147,8 +159,10 @@ module Nomade
147
159
  uri = URI("#{@nomad_endpoint}/v1/deployment/promote/#{deployment_id}")
148
160
 
149
161
  http = Net::HTTP.new(uri.host, uri.port)
150
- http.use_ssl = true
151
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
162
+ if @nomad_endpoint.include?("https://")
163
+ http.use_ssl = true
164
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
165
+ end
152
166
 
153
167
  req = Net::HTTP::Post.new(uri)
154
168
  req.add_field "Content-Type", "application/json"
@@ -171,8 +185,10 @@ module Nomade
171
185
  uri = URI("#{@nomad_endpoint}/v1/deployment/fail/#{deployment_id}")
172
186
 
173
187
  http = Net::HTTP.new(uri.host, uri.port)
174
- http.use_ssl = true
175
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
188
+ if @nomad_endpoint.include?("https://")
189
+ http.use_ssl = true
190
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
191
+ end
176
192
 
177
193
  req = Net::HTTP::Post.new(uri)
178
194
  req.add_field "Content-Type", "application/json"
@@ -191,8 +207,10 @@ module Nomade
191
207
  uri = URI("#{@nomad_endpoint}/v1/client/fs/logs/#{allocation_id}?task=#{task_name}&type=#{logtype}&plain=true&origin=end")
192
208
 
193
209
  http = Net::HTTP.new(uri.host, uri.port)
194
- http.use_ssl = true
195
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
210
+ if @nomad_endpoint.include?("https://")
211
+ http.use_ssl = true
212
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
213
+ end
196
214
 
197
215
  req = Net::HTTP::Get.new(uri)
198
216
  res = http.request(req)
data/lib/nomade/job.rb CHANGED
@@ -5,14 +5,15 @@ module Nomade
5
5
  class Job
6
6
  class FormattingError < StandardError; end
7
7
 
8
- def initialize(template_file, image_full_name, environment_variables = {})
8
+ def initialize(template_file, image_full_name, template_variables = {})
9
9
  @image_full_name = image_full_name
10
- @environment_variables = environment_variables
10
+ @template_variables = template_variables
11
11
 
12
12
  # image_full_name should be in the form of:
13
13
  # redis:4.0.1
14
14
  # kaspergrubbe/secretimage:latest
15
- unless @image_full_name.match(/\A[a-zA-Z0-9\/]+\:[a-zA-Z0-9\.\-\_]+\z/)
15
+ # billetto/billetto-rails:4.2.24
16
+ unless @image_full_name.match(/\A[a-zA-Z0-9\/\-\_]+\:[a-zA-Z0-9\.\-\_]+\z/)
16
17
  raise Nomade::Job::FormattingError.new("Image-format wrong: #{@image_full_name}")
17
18
  end
18
19
 
@@ -52,8 +53,8 @@ module Nomade
52
53
  image_name_and_version.split(":").last
53
54
  end
54
55
 
55
- def environment_variables
56
- @environment_variables
56
+ def template_variables
57
+ @template_variables
57
58
  end
58
59
 
59
60
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nomade
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kasper Grubbe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-09 00:00:00.000000000 Z
11
+ date: 2019-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yell