bosh_cli 1.1761.0 → 1.1777.0

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/lib/cli/runner.rb CHANGED
@@ -56,20 +56,24 @@ module Bosh::Cli
56
56
  exit_code = command.run(@args, @options)
57
57
  exit(exit_code)
58
58
  rescue OptionParser::ParseError => e
59
- say_err e.message
60
- say_err "Usage: bosh #{command.usage_with_params.columnize(60, 7)}"
59
+ say_err(e.message)
60
+ nl
61
+ say_err("Usage: bosh #{command.usage_with_params.columnize(60, 7)}")
62
+ nl
61
63
  if command.has_options?
62
64
  say(command.options_summary.indent(7))
63
65
  end
66
+ exit(1)
64
67
  end
65
68
 
66
69
  rescue OptionParser::ParseError => e
67
- say_err e.message
68
- say_err @option_parser.to_s
70
+ say_err(e.message)
71
+ say_err(@option_parser.to_s)
69
72
  exit(1)
73
+
70
74
  rescue Bosh::Cli::CliError => e
71
- say_err e.message
72
- puts ""
75
+ say_err(e.message)
76
+ nl
73
77
  exit(e.exit_code)
74
78
  end
75
79
 
@@ -3,6 +3,7 @@ module Bosh::Cli
3
3
  end
4
4
 
5
5
  require 'cli/task_tracking/task_tracker'
6
+ require 'cli/task_tracking/total_duration'
6
7
  require 'cli/task_tracking/task_log_renderer'
7
8
  require 'cli/task_tracking/null_task_log_renderer'
8
9
  require 'cli/task_tracking/stage_progress_bar'
@@ -2,25 +2,14 @@ module Bosh::Cli::TaskTracking
2
2
  class EventLogRenderer < TaskLogRenderer
3
3
  class InvalidEvent < StandardError; end
4
4
 
5
- class Task
6
- attr_accessor :name
7
- attr_accessor :progress
8
- attr_accessor :start_time
9
- attr_accessor :finish_time
10
-
11
- def initialize(name)
12
- @name = name
13
- @progress = 0
14
- @start_time = nil
15
- @finish_time = nil
16
- end
17
- end
5
+ extend Forwardable
6
+ def_delegators :@total_duration, :duration, :duration_known?, :started_at, :finished_at
18
7
 
19
8
  attr_reader :current_stage
20
9
  attr_reader :events_count
21
- attr_reader :started_at, :finished_at
22
10
 
23
11
  def initialize(options={})
12
+ @total_duration = TotalDuration.new
24
13
  @lock = Monitor.new
25
14
  @events_count = 0
26
15
  @seen_stages = Set.new
@@ -42,7 +31,7 @@ module Bosh::Cli::TaskTracking
42
31
 
43
32
  @lock.synchronize do
44
33
  # Handling the special "error" event
45
- if event["error"]
34
+ if event['error']
46
35
  done_with_stage if @current_stage
47
36
  add_error(event)
48
37
  return
@@ -66,11 +55,11 @@ module Bosh::Cli::TaskTracking
66
55
  # resuming the older stages rendering if we feel
67
56
  # that it's valuable.
68
57
 
69
- tags = event["tags"].is_a?(Array) ? event["tags"] : []
70
- stage_header = event["stage"]
58
+ tags = event['tags'].is_a?(Array) ? event['tags'] : []
59
+ stage_header = event['stage']
71
60
 
72
61
  if tags.size > 0
73
- stage_header += " " + tags.sort.join(", ").make_green
62
+ stage_header += ' ' + tags.sort.join(', ').make_green
74
63
  end
75
64
 
76
65
  unless @seen_stages.include?(stage_header)
@@ -91,7 +80,7 @@ module Bosh::Cli::TaskTracking
91
80
  @current_stage = header
92
81
  @seen_stages << @current_stage
93
82
 
94
- @stage_start_time = Time.at(event["time"]) rescue Time.now
83
+ @stage_start_time = Time.at(event['time']) rescue Time.now
95
84
  @local_start_time = adjusted_time(@stage_start_time)
96
85
 
97
86
  @tasks = {}
@@ -120,11 +109,11 @@ module Bosh::Cli::TaskTracking
120
109
  end
121
110
 
122
111
  def add_error(event)
123
- error = event["error"] || {}
124
- code = error["code"]
125
- message = error["message"]
112
+ error = event['error'] || {}
113
+ code = error['code']
114
+ message = error['message']
126
115
 
127
- error = "Error"
116
+ error = 'Error'
128
117
  error += " #{code}" if code
129
118
  error += ": #{message}" if message
130
119
 
@@ -153,15 +142,6 @@ module Bosh::Cli::TaskTracking
153
142
  end
154
143
  end
155
144
 
156
- def duration_known?
157
- @started_at && @finished_at
158
- end
159
-
160
- def duration
161
- return unless duration_known?
162
- @finished_at - @started_at
163
- end
164
-
165
145
  private
166
146
 
167
147
  def append_stage_header
@@ -172,23 +152,23 @@ module Bosh::Cli::TaskTracking
172
152
  return unless @in_progress
173
153
 
174
154
  if @last_event
175
- completion_time = Time.at(@last_event["time"]) rescue Time.now
155
+ completion_time = Time.at(@last_event['time']) rescue Time.now
176
156
  else
177
157
  completion_time = Time.now
178
158
  end
179
159
 
180
160
  if state.nil?
181
- state = @stage_has_error ? "error" : "done"
161
+ state = @stage_has_error ? 'error' : 'done'
182
162
  end
183
163
 
184
164
  case state.to_s
185
- when "done"
186
- progress_bar.title = "Done".make_green
165
+ when 'done'
166
+ progress_bar.title = 'Done'.make_green
187
167
  progress_bar.finished_steps = progress_bar.total
188
- when "error"
189
- progress_bar.title = "Error".make_red
168
+ when 'error'
169
+ progress_bar.title = 'Error'.make_red
190
170
  else
191
- progress_bar.title = "Not done".make_yellow
171
+ progress_bar.title = 'Not done'.make_yellow
192
172
  end
193
173
 
194
174
  progress_bar.bar_visible = false
@@ -208,34 +188,34 @@ module Bosh::Cli::TaskTracking
208
188
  validate_event(event)
209
189
 
210
190
  progress = 0
211
- total = event["total"].to_i
191
+ total = event['total'].to_i
212
192
 
213
- if event["state"] == "started"
214
- task = Task.new(event["task"])
193
+ if event['state'] == 'started'
194
+ task = Task.new(event['task'])
215
195
  else
216
- task = @tasks[event["index"]]
196
+ task = @tasks[event['index']]
217
197
  end
218
198
 
219
- event_data = event["data"] || {}
199
+ event_data = event['data'] || {}
220
200
  # Ignoring out-of-order events
221
201
  return if task.nil?
222
202
 
223
203
  @events_count += 1
224
204
  @last_event = event
225
205
 
226
- case event["state"]
227
- when "started"
206
+ case event['state']
207
+ when 'started'
208
+ @total_duration.started_at = event['time']
209
+
228
210
  begin
229
- task.start_time = Time.at(event["time"])
230
- # Treat first "started" event as task start time
231
- @started_at = task.start_time if @started_at.nil?
211
+ task.start_time = Time.at(event['time'])
232
212
  rescue
233
213
  task.start_time = Time.now
234
214
  end
235
215
 
236
216
  task.progress = 0
237
217
 
238
- @tasks[event["index"]] = task
218
+ @tasks[event['index']] = task
239
219
 
240
220
  if @tasks.size > @tasks_batch_size
241
221
  # Heuristics here: we assume that local maximum of
@@ -249,12 +229,14 @@ module Bosh::Cli::TaskTracking
249
229
  @batches_count = ((total - @done_tasks.size) / @tasks_batch_size.to_f).ceil
250
230
  end
251
231
 
252
- when "finished", "failed"
253
- @tasks.delete(event["index"])
232
+ when 'finished', 'failed'
233
+ @tasks.delete(event['index'])
254
234
  @done_tasks << task
255
235
 
236
+ @total_duration.finished_at = event['time']
237
+
256
238
  begin
257
- task.finish_time = @finished_at = Time.at(event["time"])
239
+ task.finish_time = Time.at(event['time'])
258
240
  rescue
259
241
  task.finish_time = Time.now
260
242
  end
@@ -274,16 +256,16 @@ module Bosh::Cli::TaskTracking
274
256
  task_name = task_name[0..0].to_s.downcase + task_name[1..-1].to_s
275
257
  end
276
258
 
277
- if event["state"] == "failed"
278
- status = [task_name.make_red, event_data["error"]].compact.join(": ")
259
+ if event['state'] == 'failed'
260
+ status = [task_name.make_red, event_data['error']].compact.join(': ')
279
261
  @stage_has_error = true
280
262
  else
281
263
  status = task_name.make_yellow
282
264
  end
283
265
  @buffer.puts(" #{status} (#{format_time(task_time)})")
284
266
 
285
- when "in_progress"
286
- progress = [event["progress"].to_f / 100, 1].min
267
+ when 'in_progress'
268
+ progress = [event['progress'].to_f / 100, 1].min
287
269
  end
288
270
 
289
271
  if @batches_count > 0 && @non_canary_event_start_time
@@ -294,7 +276,7 @@ module Bosh::Cli::TaskTracking
294
276
  task.progress = progress
295
277
 
296
278
  progress_bar.total = total
297
- progress_bar.title = @tasks.values.map { |t| t.name }.sort.join(", ")
279
+ progress_bar.title = @tasks.values.map { |t| t.name }.sort.join(', ')
298
280
 
299
281
  progress_bar.current += progress_bar_gain
300
282
  progress_bar.refresh
@@ -309,20 +291,20 @@ module Bosh::Cli::TaskTracking
309
291
  end
310
292
  event
311
293
  rescue JSON::JSONError
312
- raise InvalidEvent, "Cannot parse event, invalid JSON"
294
+ raise InvalidEvent, 'Cannot parse event, invalid JSON'
313
295
  end
314
296
 
315
297
  def validate_event(event)
316
- unless event["time"] && event["stage"] && event["task"] &&
317
- event["index"] && event["total"] && event["state"]
318
- raise InvalidEvent, "Invalid event structure: stage, time, task, " +
319
- "index, total, state are all required"
298
+ unless event['time'] && event['stage'] && event['task'] &&
299
+ event['index'] && event['total'] && event['state']
300
+ raise InvalidEvent, 'Invalid event structure: stage, time, task, ' +
301
+ 'index, total, state are all required'
320
302
  end
321
303
  end
322
304
 
323
305
  def time_with_eta(time, eta)
324
306
  time_fmt = format_time(time)
325
- eta_fmt = eta && eta > Time.now ? format_time(eta - Time.now) : "--:--:--"
307
+ eta_fmt = eta && eta > Time.now ? format_time(eta - Time.now) : '--:--:--'
326
308
  "#{time_fmt} ETA: #{eta_fmt}"
327
309
  end
328
310
 
@@ -331,28 +313,44 @@ module Bosh::Cli::TaskTracking
331
313
  end
332
314
 
333
315
  def can_handle_event_without_progress_bar?(event)
334
- @stages_without_progress_bar.include?(event["stage"])
316
+ @stages_without_progress_bar.include?(event['stage'])
335
317
  end
336
318
 
337
319
  def handle_event_without_progress_bar(event)
338
- event_header = "#{event["stage"].downcase}#{header_for_tags(event["tags"])}: #{event["task"]}"
320
+ event_header = "#{event['stage'].downcase}#{header_for_tags(event['tags'])}: #{event['task']}"
339
321
 
340
- case event["state"]
341
- when "started"
322
+ case event['state']
323
+ when 'started'
324
+ @total_duration.started_at = event['time']
342
325
  @buffer.print(" Started #{event_header}\n")
343
- when "finished"
326
+ when 'finished'
327
+ @total_duration.finished_at = event['time']
344
328
  @buffer.print(" Done #{event_header}\n")
345
- when "failed"
346
- event_data = event["data"] || {}
347
- data_error = event_data["error"]
348
- error_msg = data_error ? ": #{data_error.make_red}" : ""
329
+ when 'failed'
330
+ event_data = event['data'] || {}
331
+ data_error = event_data['error']
332
+ error_msg = data_error ? ": #{data_error.make_red}" : ''
349
333
  @buffer.print(" Failed #{event_header}#{error_msg}\n")
350
334
  end
351
335
  end
352
336
 
353
337
  def header_for_tags(tags)
354
338
  tags = Array(tags)
355
- tags.size > 0 ? " " + tags.sort.join(", ").make_green : ""
339
+ tags.size > 0 ? ' ' + tags.sort.join(', ').make_green : ''
340
+ end
341
+
342
+ class Task
343
+ attr_accessor :name
344
+ attr_accessor :progress
345
+ attr_accessor :start_time
346
+ attr_accessor :finish_time
347
+
348
+ def initialize(name)
349
+ @name = name
350
+ @progress = 0
351
+ @start_time = nil
352
+ @finish_time = nil
353
+ end
356
354
  end
357
355
  end
358
356
  end
@@ -14,14 +14,14 @@ module Bosh::Cli::TaskTracking
14
14
  @total = 100
15
15
  @bar_visible = true
16
16
  @finished_steps = 0
17
- @filler = "o"
17
+ @filler = 'o'
18
18
  @terminal_width = calculate_terminal_width
19
19
  @bar_width = (0.24 * @terminal_width).to_i # characters
20
20
  end
21
21
 
22
22
  def refresh
23
23
  clear_line
24
- bar_repr = @bar_visible ? bar : ""
24
+ bar_repr = @bar_visible ? bar : ''
25
25
  title_width = (0.35 * @terminal_width).to_i
26
26
  title = @title.truncate(title_width).ljust(title_width)
27
27
  @output.print "#{title} #{bar_repr} #{@finished_steps}/#{@total}"
@@ -33,20 +33,20 @@ module Bosh::Cli::TaskTracking
33
33
  (@current.to_f / @total.to_f)).floor, 0].max
34
34
 
35
35
  fillers = "#{@filler}" * n_fillers
36
- spaces = " " * [(@bar_width - n_fillers), 0].max
36
+ spaces = ' ' * [(@bar_width - n_fillers), 0].max
37
37
  "|#{fillers}#{spaces}|"
38
38
  end
39
39
 
40
40
  def clear_line
41
41
  @output.print("\r")
42
- @output.print(" " * @terminal_width)
42
+ @output.print(' ' * @terminal_width)
43
43
  @output.print("\r")
44
44
  end
45
45
 
46
46
  def calculate_terminal_width
47
- if ENV["COLUMNS"].to_s =~ /^\d+$/
48
- ENV["COLUMNS"].to_i
49
- elsif !ENV["TERM"].blank?
47
+ if ENV['COLUMNS'].to_s =~ /^\d+$/
48
+ ENV['COLUMNS'].to_i
49
+ elsif !ENV['TERM'].blank?
50
50
  width = `tput cols`
51
51
  $?.exitstatus == 0 ? [width.to_i, 100].min : 80
52
52
  else
@@ -6,10 +6,10 @@ module Bosh::Cli::TaskTracking
6
6
  ]
7
7
 
8
8
  def self.create_for_log_type(log_type)
9
- if log_type == "event"
9
+ if log_type == 'event'
10
10
  EventLogRenderer.new(stages_without_progress_bar:
11
11
  EVENT_LOG_STAGES_WITHOUT_PROGRESS_BAR)
12
- elsif log_type == "result" || log_type == "none"
12
+ elsif log_type == 'result' || log_type == 'none'
13
13
  NullTaskLogRenderer.new
14
14
  else
15
15
  TaskLogRenderer.new
@@ -23,7 +23,7 @@ module Bosh::Cli::TaskTracking
23
23
  @out = Bosh::Cli::Config.output || $stdout
24
24
  @out.sync = true
25
25
  @lock = Mutex.new
26
- @output = ""
26
+ @output = ''
27
27
  @time_adjustment = 0
28
28
  @duration = nil
29
29
  end
@@ -38,7 +38,7 @@ module Bosh::Cli::TaskTracking
38
38
 
39
39
  def refresh
40
40
  @out.print(@output)
41
- @output = ""
41
+ @output = ''
42
42
  end
43
43
 
44
44
  def finish(state)
@@ -16,7 +16,7 @@ module Bosh::Cli::TaskTracking
16
16
  @options = options
17
17
 
18
18
  @quiet = !!options[:quiet]
19
- default_log_type = @quiet ? "none" : "event"
19
+ default_log_type = @quiet ? 'none' : 'event'
20
20
 
21
21
  @log_type = options[:log_type] || default_log_type
22
22
 
@@ -77,14 +77,14 @@ module Bosh::Cli::TaskTracking
77
77
  def prompt_for_debug_log
78
78
  return unless interactive?
79
79
  nl
80
- confirm = ask("The task has returned an error status, " +
81
- "do you want to see debug log? [Yn]: ")
80
+ confirm = ask('The task has returned an error status, ' +
81
+ 'do you want to see debug log? [Yn]: ')
82
82
  if confirm.empty? || confirm =~ /y(es)?/i
83
83
  self.class.new(@director, @task_id,
84
- @options.merge(:log_type => "debug")).track
84
+ @options.merge(:log_type => 'debug')).track
85
85
  else
86
86
  say("Please use 'bosh task #{@task_id}' command ".make_red +
87
- "to see the debug log".make_red)
87
+ 'to see the debug log'.make_red)
88
88
  end
89
89
  end
90
90
 
@@ -92,7 +92,7 @@ module Bosh::Cli::TaskTracking
92
92
  return unless interactive?
93
93
  nl
94
94
  confirm = ask("Do you want to cancel task #{@task_id}? [yN] " +
95
- "(^C again to detach): ")
95
+ '(^C again to detach): ')
96
96
 
97
97
  if confirm =~ /y(es)?/i
98
98
  say("Cancelling task #{@task_id}...")
@@ -113,6 +113,7 @@ module Bosh::Cli::TaskTracking
113
113
  say("Task #{@task_id} #{task_status.to_s.make_yellow}")
114
114
 
115
115
  if task_status == :done && @renderer.duration_known?
116
+ nl
116
117
  say("Started\t\t#{@renderer.started_at.utc.to_s}")
117
118
  say("Finished\t#{@renderer.finished_at.utc.to_s}")
118
119
  say("Duration\t#{format_time(@renderer.duration).make_yellow}")
@@ -132,13 +133,13 @@ module Bosh::Cli::TaskTracking
132
133
  # @param [String] output Output received from director task
133
134
  def output_received(output)
134
135
  return if output.nil?
135
- @output ||= ""
136
+ @output ||= ''
136
137
  @output << output
137
138
  @renderer.add_output(output)
138
139
  end
139
140
 
140
141
  def finished?(state)
141
- %(done error cancelled).include?(state)
142
+ 'done error cancelled'.include?(state)
142
143
  end
143
144
 
144
145
  def interactive?
@@ -0,0 +1,23 @@
1
+ module Bosh::Cli::TaskTracking
2
+ class TotalDuration
3
+ attr_reader :started_at, :finished_at
4
+
5
+ def started_at=(time)
6
+ if !@started_at
7
+ @started_at = Time.at(time) rescue nil
8
+ end
9
+ end
10
+
11
+ def finished_at=(time)
12
+ (@finished_at = Time.at(time)) rescue nil
13
+ end
14
+
15
+ def duration
16
+ @finished_at - @started_at if duration_known?
17
+ end
18
+
19
+ def duration_known?
20
+ !!(@finished_at && @started_at)
21
+ end
22
+ end
23
+ end
data/lib/cli/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Cli
3
- VERSION = '1.1761.0'
3
+ VERSION = '1.1777.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1761.0
4
+ version: 1.1777.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-10 00:00:00.000000000 Z
12
+ date: 2014-01-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bosh_common
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.1761.0
21
+ version: 1.1777.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.1761.0
29
+ version: 1.1777.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: json_pure
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +114,7 @@ dependencies:
114
114
  requirements:
115
115
  - - ~>
116
116
  - !ruby/object:Gem::Version
117
- version: 1.1761.0
117
+ version: 1.1777.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
@@ -122,7 +122,7 @@ dependencies:
122
122
  requirements:
123
123
  - - ~>
124
124
  - !ruby/object:Gem::Version
125
- version: 1.1761.0
125
+ version: 1.1777.0
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: net-ssh
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -269,7 +269,7 @@ dependencies:
269
269
  version: '0'
270
270
  description: ! 'BOSH CLI
271
271
 
272
- 826c69'
272
+ 0308a9'
273
273
  email: support@cloudfoundry.com
274
274
  executables:
275
275
  - bosh
@@ -346,6 +346,7 @@ files:
346
346
  - lib/cli/task_tracking/stage_progress_bar.rb
347
347
  - lib/cli/task_tracking/task_log_renderer.rb
348
348
  - lib/cli/task_tracking/task_tracker.rb
349
+ - lib/cli/task_tracking/total_duration.rb
349
350
  - lib/cli/validation.rb
350
351
  - lib/cli/version.rb
351
352
  - lib/cli/version_calc.rb
@@ -374,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
374
375
  version: '0'
375
376
  segments:
376
377
  - 0
377
- hash: -459032974552856888
378
+ hash: 4248709114918295253
378
379
  requirements: []
379
380
  rubyforge_project:
380
381
  rubygems_version: 1.8.23