bosh_cli 0.18 → 0.19
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.
- data/bin/bosh +7 -4
- data/lib/cli.rb +2 -0
- data/lib/cli/commands/base.rb +1 -18
- data/lib/cli/commands/biff.rb +3 -7
- data/lib/cli/commands/cloudcheck.rb +1 -0
- data/lib/cli/commands/deployment.rb +10 -6
- data/lib/cli/commands/job_rename.rb +116 -0
- data/lib/cli/commands/stemcell.rb +3 -3
- data/lib/cli/commands/task.rb +52 -143
- data/lib/cli/commands/vms.rb +2 -2
- data/lib/cli/config.rb +1 -0
- data/lib/cli/deployment_helper.rb +62 -22
- data/lib/cli/director.rb +85 -196
- data/lib/cli/director_task.rb +4 -4
- data/lib/cli/event_log_renderer.rb +5 -1
- data/lib/cli/null_renderer.rb +19 -0
- data/lib/cli/package_builder.rb +91 -62
- data/lib/cli/packaging_helper.rb +1 -1
- data/lib/cli/release_builder.rb +47 -13
- data/lib/cli/runner.rb +21 -39
- data/lib/cli/task_log_renderer.rb +9 -0
- data/lib/cli/task_tracker.rb +168 -0
- data/lib/cli/templates/help_message.erb +1 -0
- data/lib/cli/version.rb +1 -1
- data/lib/cli/versions_index.rb +3 -3
- data/spec/unit/biff_spec.rb +5 -0
- data/spec/unit/director_spec.rb +96 -192
- data/spec/unit/job_rename_spec.rb +195 -0
- data/spec/unit/package_builder_spec.rb +188 -186
- data/spec/unit/release_builder_spec.rb +27 -9
- data/spec/unit/runner_spec.rb +0 -25
- data/spec/unit/task_tracker_spec.rb +154 -0
- metadata +11 -4
data/lib/cli/commands/vms.rb
CHANGED
@@ -16,7 +16,7 @@ module Bosh::Cli::Command
|
|
16
16
|
name = manifest["name"]
|
17
17
|
end
|
18
18
|
|
19
|
-
say("Deployment
|
19
|
+
say("Deployment #{name.green}")
|
20
20
|
|
21
21
|
vms = director.fetch_vm_state(name)
|
22
22
|
err("No VMs") if vms.size == 0
|
@@ -30,7 +30,7 @@ module Bosh::Cli::Command
|
|
30
30
|
|
31
31
|
vms_table = table do |t|
|
32
32
|
headings = ["Job/index", "State", "Resource Pool", "IPs"]
|
33
|
-
headings += ["
|
33
|
+
headings += ["CID", "Agent ID"] if show_full_stats
|
34
34
|
|
35
35
|
t.headings = headings
|
36
36
|
|
data/lib/cli/config.rb
CHANGED
@@ -45,15 +45,40 @@ module Bosh::Cli
|
|
45
45
|
manifest = YAML.load(manifest_yaml)
|
46
46
|
end
|
47
47
|
|
48
|
-
if manifest["name"].blank? || manifest["
|
49
|
-
manifest["director_uuid"].blank?
|
48
|
+
if manifest["name"].blank? || manifest["director_uuid"].blank?
|
50
49
|
err("Invalid manifest `#{File.basename(deployment)}': " +
|
51
|
-
|
50
|
+
"name and director UUID are required")
|
51
|
+
end
|
52
|
+
|
53
|
+
if manifest["release"].blank? && manifest["releases"].blank?
|
54
|
+
err("Deployment manifest doesn't have release information: '" +
|
55
|
+
"please add 'release' or 'releases' section")
|
52
56
|
end
|
53
57
|
|
54
58
|
options[:yaml] ? manifest_yaml : manifest
|
55
59
|
end
|
56
60
|
|
61
|
+
# Check if the 2 deployments are different.
|
62
|
+
# Print out a summary if "show" is true.
|
63
|
+
def deployment_changed?(current_manifest, manifest, show=true)
|
64
|
+
diff = Bosh::Cli::HashChangeset.new
|
65
|
+
diff.add_hash(normalize_deployment_manifest(manifest), :new)
|
66
|
+
diff.add_hash(normalize_deployment_manifest(current_manifest), :old)
|
67
|
+
changed = diff.changed?
|
68
|
+
|
69
|
+
if changed && show
|
70
|
+
@_diff_key_visited = { }
|
71
|
+
diff.keys.each do |key|
|
72
|
+
unless @_diff_key_visited[key]
|
73
|
+
print_summary(diff, key)
|
74
|
+
nl
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
changed
|
80
|
+
end
|
81
|
+
|
57
82
|
# Interactive walkthrough of deployment changes,
|
58
83
|
# expected to bail out of CLI using 'cancel_deployment'
|
59
84
|
# if something goes wrong, so it doesn't need to have
|
@@ -94,23 +119,19 @@ module Bosh::Cli
|
|
94
119
|
return false
|
95
120
|
end
|
96
121
|
|
97
|
-
|
122
|
+
if diff[:release]
|
123
|
+
print_summary(diff, :release)
|
124
|
+
warn_about_release_changes(diff[:release])
|
125
|
+
nl
|
126
|
+
end
|
98
127
|
|
99
|
-
if diff[:
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
"change. ARE YOU SURE YOU WANT TO DO IT?")
|
104
|
-
cancel_deployment
|
105
|
-
end
|
106
|
-
elsif diff[:release][:version].changed?
|
107
|
-
say("Release version has changed: %s -> %s".yellow % [
|
108
|
-
diff[:release][:version].old, diff[:release][:version].new])
|
109
|
-
unless confirmed?("Are you sure you want to deploy this version?")
|
110
|
-
cancel_deployment
|
128
|
+
if diff[:releases]
|
129
|
+
print_summary(diff, :releases)
|
130
|
+
diff[:releases].each do |release_diff|
|
131
|
+
warn_about_release_changes(release_diff)
|
111
132
|
end
|
133
|
+
nl
|
112
134
|
end
|
113
|
-
nl
|
114
135
|
|
115
136
|
print_summary(diff, :compilation)
|
116
137
|
nl
|
@@ -125,12 +146,12 @@ module Bosh::Cli
|
|
125
146
|
|
126
147
|
diff[:resource_pools].each do |pool|
|
127
148
|
old_stemcells << {
|
128
|
-
|
129
|
-
|
149
|
+
:name => pool[:stemcell][:name].old,
|
150
|
+
:version => pool[:stemcell][:version].old
|
130
151
|
}
|
131
152
|
new_stemcells << {
|
132
|
-
|
133
|
-
|
153
|
+
:name => pool[:stemcell][:name].new,
|
154
|
+
:version => pool[:stemcell][:version].new
|
134
155
|
}
|
135
156
|
end
|
136
157
|
|
@@ -214,7 +235,9 @@ module Bosh::Cli
|
|
214
235
|
def normalize_deployment_manifest(manifest)
|
215
236
|
normalized = manifest.dup
|
216
237
|
|
217
|
-
%w(networks jobs resource_pools).each do |section|
|
238
|
+
%w(releases networks jobs resource_pools).each do |section|
|
239
|
+
normalized[section] ||= []
|
240
|
+
|
218
241
|
unless normalized[section].kind_of?(Array)
|
219
242
|
manifest_error("#{section} is expected to be an array")
|
220
243
|
end
|
@@ -259,5 +282,22 @@ module Bosh::Cli
|
|
259
282
|
normalized
|
260
283
|
end
|
261
284
|
|
285
|
+
def warn_about_release_changes(release_diff)
|
286
|
+
if release_diff[:name].changed?
|
287
|
+
say("Release name has changed: %s -> %s".red % [
|
288
|
+
release_diff[:name].old, release_diff[:name].new])
|
289
|
+
unless confirmed?("This is very serious and potentially destructive " +
|
290
|
+
"change. ARE YOU SURE YOU WANT TO DO IT?")
|
291
|
+
cancel_deployment
|
292
|
+
end
|
293
|
+
elsif release_diff[:version].changed?
|
294
|
+
say("Release version has changed: %s -> %s".yellow % [
|
295
|
+
release_diff[:version].old, release_diff[:version].new])
|
296
|
+
unless confirmed?("Are you sure you want to deploy this version?")
|
297
|
+
cancel_deployment
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
262
302
|
end
|
263
303
|
end
|
data/lib/cli/director.rb
CHANGED
@@ -3,29 +3,27 @@
|
|
3
3
|
module Bosh
|
4
4
|
module Cli
|
5
5
|
class Director
|
6
|
-
include VersionCalc
|
6
|
+
include Bosh::Cli::VersionCalc
|
7
7
|
|
8
8
|
DIRECTOR_HTTP_ERROR_CODES = [400, 403, 500]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
API_TIMEOUT = 86400 * 3
|
13
|
-
CONNECT_TIMEOUT = 30
|
10
|
+
API_TIMEOUT = 86400 * 3
|
11
|
+
CONNECT_TIMEOUT = 30
|
14
12
|
|
15
13
|
attr_reader :director_uri
|
16
14
|
|
17
|
-
# The current task number. An accessor so it can be used in tests.
|
18
|
-
# @return [String] The task number.
|
19
|
-
attr_accessor :current_running_task
|
20
|
-
|
21
15
|
def initialize(director_uri, user = nil, password = nil)
|
22
16
|
if director_uri.nil? || director_uri =~ /^\s*$/
|
23
17
|
raise DirectorMissing, "no director URI given"
|
24
18
|
end
|
25
19
|
|
26
20
|
@director_uri = director_uri
|
27
|
-
@user
|
28
|
-
@password
|
21
|
+
@user = user
|
22
|
+
@password = password
|
23
|
+
end
|
24
|
+
|
25
|
+
def uuid
|
26
|
+
@uuid ||= get_status["uuid"]
|
29
27
|
end
|
30
28
|
|
31
29
|
def exists?
|
@@ -54,8 +52,7 @@ module Bosh
|
|
54
52
|
end
|
55
53
|
|
56
54
|
def upload_stemcell(filename)
|
57
|
-
upload_and_track("/stemcells", "application/x-compressed",
|
58
|
-
filename, :log_type => "event")
|
55
|
+
upload_and_track("/stemcells", "application/x-compressed", filename)
|
59
56
|
end
|
60
57
|
|
61
58
|
def get_version
|
@@ -112,15 +109,11 @@ module Bosh
|
|
112
109
|
end
|
113
110
|
|
114
111
|
def upload_release(filename)
|
115
|
-
upload_and_track("/releases", "application/x-compressed",
|
116
|
-
filename, :log_type => "event")
|
112
|
+
upload_and_track("/releases", "application/x-compressed", filename)
|
117
113
|
end
|
118
114
|
|
119
115
|
def delete_stemcell(name, version, options = {})
|
120
|
-
|
121
|
-
track_options[:quiet] = options[:quiet] if options.has_key?(:quiet)
|
122
|
-
request_and_track(:delete, "/stemcells/%s/%s" % [name, version],
|
123
|
-
nil, nil, track_options)
|
116
|
+
request_and_track(:delete, "/stemcells/#{name}/#{version}")
|
124
117
|
end
|
125
118
|
|
126
119
|
def delete_deployment(name, options = {})
|
@@ -129,7 +122,7 @@ module Bosh
|
|
129
122
|
query_params << "force=true" if options[:force]
|
130
123
|
url += "?#{query_params.join("&")}" if query_params.size > 0
|
131
124
|
|
132
|
-
request_and_track(:delete, url
|
125
|
+
request_and_track(:delete, url)
|
133
126
|
end
|
134
127
|
|
135
128
|
def delete_release(name, options = {})
|
@@ -141,57 +134,56 @@ module Bosh
|
|
141
134
|
|
142
135
|
url += "?#{query_params.join("&")}" if query_params.size > 0
|
143
136
|
|
144
|
-
|
145
|
-
track_options[:quiet] = options[:quiet] if options.has_key?(:quiet)
|
146
|
-
|
147
|
-
request_and_track(:delete, url, nil, nil, track_options)
|
137
|
+
request_and_track(:delete, url)
|
148
138
|
end
|
149
139
|
|
150
140
|
def deploy(manifest_yaml, options = {})
|
151
141
|
url = "/deployments"
|
152
142
|
url += "?recreate=true" if options[:recreate]
|
153
|
-
request_and_track(:post, url, "text/yaml",
|
154
|
-
manifest_yaml, :log_type => "event")
|
143
|
+
request_and_track(:post, url, "text/yaml", manifest_yaml)
|
155
144
|
end
|
156
145
|
|
157
146
|
def setup_ssh(deployment_name, job, index, user, public_key, password)
|
158
147
|
url = "/deployments/#{deployment_name}/ssh"
|
159
|
-
payload =
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
148
|
+
payload = {
|
149
|
+
"command" => "setup",
|
150
|
+
"deployment_name" => deployment_name,
|
151
|
+
"target" => {
|
152
|
+
"job" => job,
|
153
|
+
"indexes" => [index].compact
|
154
|
+
},
|
155
|
+
"params" => {
|
156
|
+
"user" => user,
|
157
|
+
"public_key" => public_key,
|
158
|
+
"password" => password
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
status, task_id, output =
|
163
|
+
request_and_track(:post, url, "application/json",
|
164
|
+
JSON.generate(payload), :log_type => "result")
|
175
165
|
|
176
|
-
status, task_id = request_and_track(:post, url, "application/json",
|
177
|
-
payload, :log_type => "result",
|
178
|
-
:output_stream => output_stream)
|
179
166
|
return nil if status != :done || task_id.nil?
|
180
|
-
|
167
|
+
|
168
|
+
JSON.parse(output)
|
181
169
|
end
|
182
170
|
|
183
171
|
def cleanup_ssh(deployment_name, job, user_regex, indexes)
|
184
172
|
indexes ||= []
|
185
173
|
url = "/deployments/#{deployment_name}/ssh"
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
174
|
+
|
175
|
+
payload = {
|
176
|
+
"command" => "cleanup",
|
177
|
+
"deployment_name" => deployment_name,
|
178
|
+
"target" => {
|
179
|
+
"job" => job,
|
180
|
+
"indexes" => indexes.compact
|
181
|
+
},
|
182
|
+
"params" => { "user_regex" => user_regex }
|
183
|
+
}
|
184
|
+
|
193
185
|
request_and_track(:post, url, "application/json",
|
194
|
-
payload
|
186
|
+
JSON.generate(payload))
|
195
187
|
end
|
196
188
|
|
197
189
|
def change_job_state(deployment_name, manifest_yaml,
|
@@ -199,38 +191,43 @@ module Bosh
|
|
199
191
|
url = "/deployments/#{deployment_name}/jobs/#{job_name}"
|
200
192
|
url += "/#{index}" if index
|
201
193
|
url += "?state=#{new_state}"
|
194
|
+
request_and_track(:put, url, "text/yaml", manifest_yaml)
|
195
|
+
end
|
196
|
+
|
197
|
+
def rename_job(deployment_name, manifest_yaml, old_name, new_name,
|
198
|
+
force = nil)
|
199
|
+
url = "/deployments/#{deployment_name}/jobs/#{old_name}"
|
200
|
+
|
201
|
+
rename_params = ["new_name=#{new_name}"]
|
202
|
+
rename_params << "force=true" if force
|
203
|
+
|
204
|
+
url += "?#{rename_params.join("&")}" if rename_params.size > 0
|
202
205
|
request_and_track(:put, url, "text/yaml",
|
203
206
|
manifest_yaml, :log_type => "event")
|
204
207
|
end
|
205
208
|
|
206
209
|
def fetch_logs(deployment_name, job_name, index, log_type, filters = nil)
|
207
|
-
url = "/deployments/#{deployment_name}/jobs/#{job_name}"
|
208
|
-
|
209
|
-
|
210
|
-
|
210
|
+
url = "/deployments/#{deployment_name}/jobs/#{job_name}"
|
211
|
+
url += "/#{index}/logs?type=#{log_type}&filters=#{filters}"
|
212
|
+
|
213
|
+
status, task_id = request_and_track(:get, url)
|
211
214
|
return nil if status != :done || task_id.nil?
|
212
215
|
get_task_result(task_id)
|
213
216
|
end
|
214
217
|
|
215
218
|
def fetch_vm_state(deployment_name)
|
216
219
|
url = "/deployments/#{deployment_name}/vms?format=full"
|
217
|
-
vms = []
|
218
|
-
# CLEANUP TODO output stream only being used for side effects
|
219
|
-
output_stream = lambda do |vm_states|
|
220
|
-
vm_states.to_s.split("\n").each do |vm_state|
|
221
|
-
vms << JSON.parse(vm_state)
|
222
|
-
end
|
223
|
-
""
|
224
|
-
end
|
225
220
|
|
226
|
-
status, task_id
|
227
|
-
|
228
|
-
|
229
|
-
:quiet => true)
|
221
|
+
status, task_id, output =
|
222
|
+
request_and_track(:get, url, nil, nil, :log_type => "result")
|
223
|
+
|
230
224
|
if status != :done || task_id.nil?
|
231
225
|
raise DirectorError, "Failed to fetch VMs information from director"
|
232
226
|
end
|
233
|
-
|
227
|
+
|
228
|
+
output.to_s.split("\n").map do |vm_state|
|
229
|
+
JSON.parse(vm_state)
|
230
|
+
end
|
234
231
|
end
|
235
232
|
|
236
233
|
def download_resource(id)
|
@@ -241,7 +238,7 @@ module Bosh
|
|
241
238
|
tmp_file
|
242
239
|
else
|
243
240
|
raise DirectorError, "Cannot download resource `#{id}': " +
|
244
|
-
|
241
|
+
"HTTP status #{status}"
|
245
242
|
end
|
246
243
|
end
|
247
244
|
|
@@ -274,8 +271,7 @@ module Bosh
|
|
274
271
|
|
275
272
|
def perform_cloud_scan(deployment_name)
|
276
273
|
url = "/deployments/#{deployment_name}/scans"
|
277
|
-
request_and_track(:post, url
|
278
|
-
:log_type => "event", :log_only => true)
|
274
|
+
request_and_track(:post, url)
|
279
275
|
end
|
280
276
|
|
281
277
|
def list_problems(deployment_name)
|
@@ -286,8 +282,7 @@ module Bosh
|
|
286
282
|
def apply_resolutions(deployment_name, resolutions)
|
287
283
|
url = "/deployments/#{deployment_name}/problems"
|
288
284
|
request_and_track(:put, url, "application/json",
|
289
|
-
JSON.generate("resolutions" => resolutions)
|
290
|
-
:log_type => "event", :log_only => true)
|
285
|
+
JSON.generate("resolutions" => resolutions))
|
291
286
|
end
|
292
287
|
|
293
288
|
def get_current_time
|
@@ -296,7 +291,7 @@ module Bosh
|
|
296
291
|
end
|
297
292
|
|
298
293
|
def get_time_difference
|
299
|
-
# This includes the
|
294
|
+
# This includes the round-trip to director
|
300
295
|
ctime = get_current_time
|
301
296
|
ctime ? Time.now - ctime : 0
|
302
297
|
end
|
@@ -308,13 +303,13 @@ module Bosh
|
|
308
303
|
|
309
304
|
if response_code != 200
|
310
305
|
raise TaskTrackError, "Got HTTP #{response_code} " +
|
311
|
-
|
306
|
+
"while tracking task state"
|
312
307
|
end
|
313
308
|
|
314
309
|
JSON.parse(body)
|
315
310
|
rescue JSON::ParserError
|
316
311
|
raise TaskTrackError, "Cannot parse task JSON, " +
|
317
|
-
|
312
|
+
"incompatible director version"
|
318
313
|
end
|
319
314
|
|
320
315
|
def get_task_state(task_id)
|
@@ -333,7 +328,7 @@ module Bosh
|
|
333
328
|
response_code, body, headers = get(uri, nil, nil, headers)
|
334
329
|
|
335
330
|
if response_code == 206 &&
|
336
|
-
|
331
|
+
headers[:content_range].to_s =~ /bytes \d+-(\d+)\/\d+/
|
337
332
|
new_offset = $1.to_i + 1
|
338
333
|
else
|
339
334
|
new_offset = nil
|
@@ -348,45 +343,26 @@ module Bosh
|
|
348
343
|
[body, response_code]
|
349
344
|
end
|
350
345
|
|
351
|
-
##
|
352
|
-
# Cancels the task currently running.
|
353
|
-
def cancel_current
|
354
|
-
body, response_code = cancel_task(@current_running_task)
|
355
|
-
if (200..299).include?(response_code)
|
356
|
-
say("Cancelling task ##{@current_running_task}.".red)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
##
|
361
|
-
# Returns whether there is a task currently running.
|
362
|
-
#
|
363
|
-
# @return [Boolean] Whether there is a task currently running.
|
364
|
-
def has_current?
|
365
|
-
unless @current_running_task
|
366
|
-
return false
|
367
|
-
end
|
368
|
-
task_state = get_task_state(@current_running_task)
|
369
|
-
task_state == "queued" || task_state == "processing"
|
370
|
-
end
|
371
|
-
|
372
346
|
[:post, :put, :get, :delete].each do |method_name|
|
373
347
|
define_method method_name do |*args|
|
374
348
|
request(method_name, *args)
|
375
349
|
end
|
376
350
|
end
|
377
351
|
|
378
|
-
def request_and_track(method, uri, content_type,
|
379
|
-
|
352
|
+
def request_and_track(method, uri, content_type = nil,
|
353
|
+
payload = nil,options = {})
|
380
354
|
http_status, body, headers = request(method, uri, content_type, payload)
|
381
|
-
location
|
355
|
+
location = headers[:location]
|
382
356
|
redirected = http_status == 302
|
383
|
-
task_id
|
357
|
+
task_id = nil
|
358
|
+
output = nil
|
384
359
|
|
385
360
|
if redirected
|
386
361
|
if location =~ /\/tasks\/(\d+)\/?$/ # Looks like we received task URI
|
387
362
|
task_id = $1
|
388
|
-
|
389
|
-
status =
|
363
|
+
tracker = Bosh::Cli::TaskTracker.new(self, task_id, options)
|
364
|
+
status = tracker.track
|
365
|
+
output = tracker.output
|
390
366
|
else
|
391
367
|
status = :non_trackable
|
392
368
|
end
|
@@ -394,7 +370,7 @@ module Bosh
|
|
394
370
|
status = :failed
|
395
371
|
end
|
396
372
|
|
397
|
-
[status, task_id]
|
373
|
+
[status, task_id, output]
|
398
374
|
end
|
399
375
|
|
400
376
|
def upload_and_track(uri, content_type, filename, options = {})
|
@@ -405,95 +381,8 @@ module Bosh
|
|
405
381
|
file.stop_progress_bar if file
|
406
382
|
end
|
407
383
|
|
408
|
-
def poll_task(task_id, options = {})
|
409
|
-
polls = 0
|
410
|
-
|
411
|
-
log_type = options[:log_type]
|
412
|
-
poll_interval = options[:poll_interval] || DEFAULT_POLL_INTERVAL
|
413
|
-
max_polls = options[:max_polls] || DEFAULT_MAX_POLLS
|
414
|
-
start_time = Time.now
|
415
|
-
quiet = options[:quiet]
|
416
|
-
output_stream = options[:output_stream]
|
417
|
-
log_only = options[:log_only]
|
418
|
-
|
419
|
-
task = DirectorTask.new(self, task_id, log_type)
|
420
|
-
|
421
|
-
unless quiet || log_only
|
422
|
-
say("Tracking task output for task##{task_id}...")
|
423
|
-
end
|
424
|
-
|
425
|
-
renderer = Bosh::Cli::TaskLogRenderer.create_for_log_type(log_type)
|
426
|
-
renderer.time_adjustment = get_time_difference
|
427
|
-
|
428
|
-
no_output_yet = true
|
429
|
-
|
430
|
-
while true
|
431
|
-
polls += 1
|
432
|
-
state, output = task.state, task.output
|
433
|
-
|
434
|
-
if output
|
435
|
-
no_output_yet = false
|
436
|
-
output = output_stream.call(output) unless output_stream.nil?
|
437
|
-
renderer.add_output(output) unless quiet
|
438
|
-
end
|
439
|
-
|
440
|
-
if no_output_yet && polls % 10 == 0 && !quiet && !log_only
|
441
|
-
say("Task state is '#{state}', waiting for output...")
|
442
|
-
end
|
443
|
-
|
444
|
-
renderer.refresh
|
445
|
-
|
446
|
-
if state == "done"
|
447
|
-
result = :done
|
448
|
-
break
|
449
|
-
elsif state == "error"
|
450
|
-
result = :error
|
451
|
-
break
|
452
|
-
elsif state == "cancelled"
|
453
|
-
result = :cancelled
|
454
|
-
break
|
455
|
-
elsif !max_polls.nil? && polls >= max_polls
|
456
|
-
result = :track_timeout
|
457
|
-
break
|
458
|
-
end
|
459
|
-
|
460
|
-
sleep(poll_interval)
|
461
|
-
end
|
462
|
-
|
463
|
-
unless quiet
|
464
|
-
renderer.add_output(task.flush_output)
|
465
|
-
renderer.finish(state)
|
466
|
-
end
|
467
|
-
|
468
|
-
return result if quiet
|
469
|
-
return result if log_only && result == :done
|
470
|
-
|
471
|
-
if Bosh::Cli::Config.interactive &&
|
472
|
-
log_type != "debug" && result == :error
|
473
|
-
confirm = ask("\nThe task has returned an error status, " +
|
474
|
-
"do you want to see debug log? [Yn]: ")
|
475
|
-
if confirm.empty? || confirm =~ /y(es)?/i
|
476
|
-
options.delete(:output_stream)
|
477
|
-
poll_task(task_id, options.merge(:log_type => "debug"))
|
478
|
-
else
|
479
|
-
say("Please use 'bosh task #{task_id}' command " +
|
480
|
-
"to see the debug log".red)
|
481
|
-
result
|
482
|
-
end
|
483
|
-
else
|
484
|
-
nl
|
485
|
-
status = "Task #{task_id}: state is '#{state}'"
|
486
|
-
duration = renderer.duration || (Time.now - start_time)
|
487
|
-
if result == :done
|
488
|
-
status += ", took #{format_time(duration).green} to complete"
|
489
|
-
end
|
490
|
-
say(status)
|
491
|
-
result
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
384
|
def request(method, uri, content_type = nil, payload = nil,
|
496
|
-
|
385
|
+
headers = {}, options = {})
|
497
386
|
headers = headers.dup
|
498
387
|
headers["Content-Type"] = content_type if content_type
|
499
388
|
|