bosh_cli 0.19.1 → 0.19.2

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.
@@ -15,6 +15,7 @@ module Bosh::Cli
15
15
  config_file = @options[:config] || Bosh::Cli::DEFAULT_CONFIG_PATH
16
16
  @config = Config.new(config_file)
17
17
  @cache = Config.cache
18
+ @exit_code = 0
18
19
  end
19
20
 
20
21
  class << self
@@ -106,6 +107,42 @@ module Bosh::Cli
106
107
  ret + " %s" % target_version if ret
107
108
  end
108
109
 
110
+ # Sets or returns command exit code
111
+ # @param [optional,Integer] code If param is given, sets exit code. If
112
+ # it's nil, returns previously set exit_code
113
+ def exit_code(code = nil)
114
+ if code
115
+ @exit_code = code
116
+ else
117
+ @exit_code
118
+ end
119
+ end
120
+
121
+ # Prints director task completion report. Note that event log usually
122
+ # contains pretty detailed error report and other UI niceties, so most
123
+ # of the time this could just do nothing
124
+ # @param [Symbol] status Task status
125
+ def task_report(status, success_msg = nil, error_msg = nil)
126
+ case status
127
+ when :non_trackable
128
+ report = "Can't track director task".red
129
+ when :track_timeout
130
+ report = "Task tracking timeout".red
131
+ when :error
132
+ report = error_msg
133
+ when :done
134
+ report = success_msg
135
+ else
136
+ report = nil
137
+ end
138
+
139
+ if status != :done
140
+ exit_code(1)
141
+ end
142
+
143
+ say("\n#{report}") if report
144
+ end
145
+
109
146
  protected
110
147
 
111
148
  def auth_required
@@ -28,8 +28,12 @@ module Bosh::Cli::Command
28
28
  manifest = prepare_deployment_manifest
29
29
  deployment_name = manifest["name"]
30
30
 
31
- status, body = director.perform_cloud_scan(deployment_name)
32
- scan_failed(status, body) if status != :done
31
+ status, _ = director.perform_cloud_scan(deployment_name)
32
+
33
+ if status != :done
34
+ task_report(status)
35
+ exit(1)
36
+ end
33
37
 
34
38
  nl
35
39
  say("Scan is complete, checking if any problems found...")
@@ -69,36 +73,17 @@ module Bosh::Cli::Command
69
73
  hash
70
74
  end
71
75
 
72
- status, body = director.apply_resolutions(deployment_name, action_map)
73
- resolution_failed(status, body) if status != :done
74
- say("Cloudcheck is finished".green)
75
- end
76
-
77
- private
76
+ status, _ = director.apply_resolutions(deployment_name, action_map)
78
77
 
79
- def scan_failed(status, response)
80
- responses = {
81
- :non_trackable => "Unable to track cloud scan progress, " +
82
- "please update your director",
83
- :track_timeout => "Timed out while tracking cloud scan progress",
84
- :error => "Cloud scan error",
85
- :invalid => "Invalid cloud scan request"
86
- }
78
+ if status != :done
79
+ task_report(status)
80
+ exit(1)
81
+ end
87
82
 
88
- err(responses[status] || "Cloud scan failed: #{response}")
83
+ say("Cloudcheck is finished".green)
89
84
  end
90
85
 
91
- def resolution_failed(status, response)
92
- responses = {
93
- :non_trackable => "Unable to track problem resolution progress, " +
94
- "please update your director",
95
- :track_timeout => "Timed out while tracking problem resolution progress",
96
- :error => "Problem resolution error",
97
- :invalid => "Invalid problem resolution request"
98
- }
99
-
100
- err(responses[status] || "Problem resolution failed: #{response}")
101
- end
86
+ private
102
87
 
103
88
  def verify_problems
104
89
  err("Invalid problem list format") unless @problems.kind_of?(Enumerable)
@@ -150,7 +135,6 @@ module Bosh::Cli::Command
150
135
  nl
151
136
 
152
137
  @problems.each_with_index do |problem, index|
153
- description = problem["description"]
154
138
  plan = @resolutions[problem["id"]]["plan"]
155
139
  padding = " " * ((index+1).to_s.size + 4)
156
140
  say(" #{index+1}. #{problem["description"]}")
@@ -85,20 +85,9 @@ module Bosh::Cli::Command
85
85
  cancel_deployment
86
86
  end
87
87
 
88
- status, body = director.deploy(manifest_yaml, :recreate => recreate)
89
-
90
- responses = {
91
- :done => "Deployed #{desc}",
92
- :non_trackable => "Started deployment but director at `#{target}' " +
93
- "doesn't support deployment tracking",
94
- :track_timeout => "Started deployment but timed out out " +
95
- "while tracking status",
96
- :error => "Started deployment but received an error " +
97
- "while tracking status",
98
- :invalid => "Deployment is invalid, please fix it and deploy again"
99
- }
100
-
101
- say(responses[status] || "Cannot deploy: #{body}")
88
+ status, _ = director.deploy(manifest_yaml, :recreate => recreate)
89
+
90
+ task_report(status, "Deployed #{desc}")
102
91
  end
103
92
 
104
93
  def delete(name, *options)
@@ -113,19 +102,9 @@ module Bosh::Cli::Command
113
102
  return
114
103
  end
115
104
 
116
- status, message = director.delete_deployment(name, :force => force)
117
-
118
- responses = {
119
- :done => "Deleted deployment '#{name}'",
120
- :non_trackable => "Deployment delete in progress but director " +
121
- "at '#{target}' doesn't support task tracking",
122
- :track_timeout => "Timed out out while tracking deployment " +
123
- "deletion progress",
124
- :error => "Attempted to delete deployment but received " +
125
- "an error while tracking status",
126
- }
105
+ status, _ = director.delete_deployment(name, :force => force)
127
106
 
128
- say(responses[status] || "Cannot delete deployment: #{message}")
107
+ task_report(status, "Deleted deployment `#{name}'")
129
108
  end
130
109
 
131
110
  def list
@@ -136,7 +115,7 @@ module Bosh::Cli::Command
136
115
  err("No deployments") if deployments.size == 0
137
116
 
138
117
  deployments_table = table do |t|
139
- t.headings = ["Name"]
118
+ t.headings = %w(Name)
140
119
  deployments.each do |r|
141
120
  t << [r["name"]]
142
121
  end
@@ -45,9 +45,12 @@ module Bosh::Cli::Command
45
45
 
46
46
  job = args.shift
47
47
  index = args.shift
48
- deployment_desc = "`#{deployment.green}' to `#{target_name.green}'"
49
48
  job_desc = index ? "#{job}(#{index})" : "#{job}"
50
49
 
50
+ op_desc = nil
51
+ new_state = nil
52
+ completion_desc = nil
53
+
51
54
  case operation
52
55
  when :start
53
56
  op_desc = "start #{job_desc}"
@@ -73,6 +76,8 @@ module Bosh::Cli::Command
73
76
  op_desc = "recreate #{job_desc}"
74
77
  new_state = "recreate"
75
78
  completion_desc = "#{job_desc.green} has been recreated"
79
+ else
80
+ err("Unknown operation: `#{operation}'")
76
81
  end
77
82
 
78
83
  say("You are about to #{op_desc.green}")
@@ -95,22 +100,12 @@ module Bosh::Cli::Command
95
100
 
96
101
  say("Performing `#{op_desc}'...")
97
102
 
98
- status, body = director.change_job_state(manifest["name"],
99
- manifest_yaml,
100
- job, index, new_state)
101
-
102
- responses = {
103
- :done => completion_desc,
104
- :non_trackable => "Started deployment but director at '#{target}' " +
105
- "doesn't support deployment tracking",
106
- :track_timeout => "Started deployment but timed out out "+
107
- "while tracking status",
108
- :error => "Started deployment but received an error " +
109
- "while tracking status",
110
- :invalid => "Deployment is invalid, please fix it and deploy again"
111
- }
112
-
113
- say(responses[status] || "Cannot deploy: #{body}")
103
+ status, _ =
104
+ director.change_job_state(manifest["name"],
105
+ manifest_yaml,
106
+ job, index, new_state)
107
+
108
+ task_report(status, completion_desc)
114
109
  end
115
110
 
116
111
  end
@@ -14,25 +14,20 @@ module Bosh::Cli::Command
14
14
  old_name = args.shift
15
15
  new_name = args.shift
16
16
 
17
+ say("You are about to rename #{old_name.green} to #{new_name.green}")
18
+
19
+ unless confirmed?
20
+ nl
21
+ say("Job rename canceled".green)
22
+ return
23
+ end
24
+
17
25
  sanity_check_job_rename(manifest_yaml, old_name, new_name)
18
26
 
19
- say("You are about to rename #{old_name.green} to " +
20
- "#{new_name.green} #{force}")
21
-
22
- status, body = director.rename_job(manifest["name"], manifest_yaml,
23
- old_name, new_name, force)
24
- responses = {
25
- :done => "Rename successful",
26
- :non_trackable => "Started deployment but director at '#{target}' " +
27
- "doesn't support deployment tracking",
28
- :track_timeout => "Started deployment but timed out out "+
29
- "while tracking status",
30
- :error => "Started deployment but received an error " +
31
- "while tracking status",
32
- :invalid => "Deployment is invalid, please fix it and deploy again"
33
- }
34
-
35
- say(responses[status] || "Cannot deploy: #{body}")
27
+ status, _ = director.rename_job(manifest["name"], manifest_yaml,
28
+ old_name, new_name, force)
29
+
30
+ task_report(status, "Rename successful")
36
31
  end
37
32
 
38
33
  def sanity_check_job_rename(manifest_yaml, old_name, new_name)
@@ -41,55 +36,55 @@ module Bosh::Cli::Command
41
36
  manifest = YAML.load(manifest_yaml)
42
37
  new_jobs = manifest["jobs"].map { |job| job["name"] }
43
38
  unless new_jobs.include?(new_name)
44
- err "Please update your deployment manifest to include the " +
45
- "new job name #{new_name.green}"
39
+ err("Please update your deployment manifest to include the " +
40
+ "new job name `#{new_name}'")
46
41
  end
47
42
 
48
43
  if new_jobs.include?(old_name)
49
- err "Old name #{old_name.green} is still being used in the " +
50
- "deployment file"
44
+ err("Old name `#{old_name}' is still being used in the " +
45
+ "deployment file")
51
46
  end
52
47
 
53
48
  # Make sure that the old deployment manifest contains the old job
54
49
  current_deployment = director.get_deployment(manifest["name"])
55
50
  if current_deployment["manifest"].nil?
56
- err "Director could not find manifest for deployment " +
57
- "#{manifest["name"]}"
51
+ err("Director could not find manifest for deployment " +
52
+ "`#{manifest["name"]}'")
58
53
  end
59
54
 
60
55
  current_manifest = YAML.load(current_deployment["manifest"])
61
56
  jobs = current_manifest["jobs"].map { |job| job["name"] }
62
57
  unless jobs.include?(old_name)
63
- err "Trying to rename a non existent job #{old_name}"
58
+ err("Trying to rename a non existent job `#{old_name}'")
64
59
  end
65
60
 
66
61
  # Technically we could allow this
67
62
  if jobs.include?(new_name)
68
- err "Trying to reuse an existing job name #{new_name} " +
69
- "to rename job #{old_name}"
63
+ err("Trying to reuse an existing job name `#{new_name}' " +
64
+ "to rename job `#{old_name}'")
70
65
  end
71
66
 
72
67
  # Make sure that only one job has been renamed
73
68
  added_jobs = new_jobs - jobs
74
69
 
75
70
  if added_jobs.size > 1
76
- err "Cannot rename more than one job, you are trying to " +
77
- "add #{added_jobs.inspect}"
71
+ err("Cannot rename more than one job, you are trying to " +
72
+ "add #{added_jobs.inspect}")
78
73
  end
79
74
 
80
75
  if added_jobs.first != new_name
81
- err "Manifest does not include new job #{new_name}"
76
+ err("Manifest does not include new job `#{new_name}'")
82
77
  end
83
78
 
84
79
  renamed_jobs = jobs - new_jobs
85
80
 
86
81
  if renamed_jobs.size > 1
87
- err "Cannot rename more than one job, you have changes to " +
88
- "#{renamed_jobs}"
82
+ err("Cannot rename more than one job, you have changes to " +
83
+ "#{renamed_jobs}")
89
84
  end
90
85
 
91
86
  if renamed_jobs.first != old_name
92
- err "Manifest does not rename old job #{old_name}"
87
+ err("Manifest does not rename old job `#{old_name}'")
93
88
  end
94
89
 
95
90
 
@@ -107,8 +102,8 @@ module Bosh::Cli::Command
107
102
  # Now the manifests should be the same
108
103
  manifest = YAML.load(manifest_yaml)
109
104
  if deployment_changed?(current_manifest.dup, manifest.dup)
110
- err "You cannot have any other changes to your manifest during " +
111
- "rename. Please revert the above changes and retry."
105
+ err("You cannot have any other changes to your manifest during " +
106
+ "rename. Please revert the above changes and retry.")
112
107
  end
113
108
  end
114
109
 
@@ -11,6 +11,7 @@ module Bosh::Cli::Command
11
11
  job = args.shift
12
12
  index = args.shift
13
13
  filters = nil
14
+ log_type = nil
14
15
 
15
16
  for_job = args.delete("--job")
16
17
  for_agent = args.delete("--agent")
@@ -120,8 +120,8 @@ module Bosh::Cli::Command
120
120
  refresh(" #{desc.yellow.ljust(40)}#{responses[status]}\n")
121
121
 
122
122
  if status == :error
123
- task = director.get_task(task_id)
124
- say(" #{task["result"].red}")
123
+ result = director.get_task_result(task_id)
124
+ say(" #{result.to_s.red}")
125
125
  end
126
126
 
127
127
  status == :done
@@ -53,16 +53,16 @@ module Bosh::Cli::Command
53
53
  File.join(work_dir, "releases")).latest_version
54
54
 
55
55
  say("Dev name: %s" % [dev_name ? dev_name.green : "not set".red])
56
- say("Dev version: %s" % [dev_version && dev_version > 0 ?
57
- dev_version.to_s.green : "
58
- no versions yet".red])
56
+ say("Dev version: %s" % [dev_version ?
57
+ dev_version.to_s.green :
58
+ "no versions yet".red])
59
59
  say("\n")
60
60
  say("Final name: %s" % [final_name ?
61
61
  final_name.green :
62
62
  "not set".red])
63
- say("Final version: %s" % [final_version && final_version > 0 ?
64
- final_version.to_s.green :
65
- "no versions yet".red])
63
+ say("Final version: %s" % [final_version ?
64
+ final_version.to_s.green :
65
+ "no versions yet".red])
66
66
 
67
67
  say("\n")
68
68
  say("Packages")
@@ -110,13 +110,16 @@ module Bosh::Cli::Command
110
110
  def upload_manifest(manifest_path)
111
111
  manifest = load_yaml_file(manifest_path)
112
112
  remote_release = get_remote_release(manifest["name"]) rescue nil
113
+ remote_jobs = remote_release["jobs"] if remote_release
114
+ remote_packages_sha1 = match_remote_packages(File.read(manifest_path))
113
115
  blobstore = release.blobstore
114
116
  tmpdir = Dir.mktmpdir
115
117
 
116
118
  at_exit { FileUtils.rm_rf(tmpdir) }
117
119
 
118
- compiler = Bosh::Cli::ReleaseCompiler.new(manifest_path,
119
- blobstore, remote_release)
120
+ compiler = Bosh::Cli::ReleaseCompiler.new(manifest_path, blobstore,
121
+ remote_jobs,
122
+ remote_packages_sha1)
120
123
  need_repack = true
121
124
 
122
125
  unless compiler.exists?
@@ -141,14 +144,19 @@ module Bosh::Cli::Command
141
144
  end
142
145
 
143
146
  begin
144
- remote_release = get_remote_release(tarball.release_name)
145
- if remote_release["versions"].include?(tarball.version)
146
- err("This release version has already been uploaded")
147
+ remote_release = get_remote_release(tarball.release_name) rescue nil
148
+ if remote_release
149
+ if remote_release["versions"].include?(tarball.version)
150
+ err("This release version has already been uploaded")
151
+ end
152
+ remote_jobs = remote_release["jobs"]
147
153
  end
148
154
 
149
155
  if repack
156
+ remote_packages_sha1 = match_remote_packages(tarball.manifest)
157
+
150
158
  say("Checking if can repack release for faster upload...")
151
- repacked_path = tarball.repack(remote_release)
159
+ repacked_path = tarball.repack(remote_jobs, remote_packages_sha1)
152
160
  if repacked_path.nil?
153
161
  say("Uploading the whole release".green)
154
162
  else
@@ -163,18 +171,9 @@ module Bosh::Cli::Command
163
171
  end
164
172
 
165
173
  say("\nUploading release...\n")
166
- status, message = director.upload_release(tarball_path)
167
-
168
- responses = {
169
- :done => "Release uploaded and updated",
170
- :non_trackable => "Uploaded release but director at #{target} " +
171
- "doesn't support update tracking",
172
- :track_timeout => "Uploaded release but timed out out " +
173
- "while tracking status",
174
- :error => "Uploaded release but received an error while tracking status"
175
- }
176
-
177
- say(responses[status] || "Cannot upload release: #{message}")
174
+ status, _ = director.upload_release(tarball_path)
175
+
176
+ task_report(status, "Release uploaded")
178
177
  end
179
178
 
180
179
  def create(*options)
@@ -200,10 +199,10 @@ module Bosh::Cli::Command
200
199
  def create_from_spec(*options)
201
200
  flags = options.inject({}) { |h, option| h[option] = true; h }
202
201
 
203
- final = flags.delete("--final")
204
- force = flags.delete("--force")
202
+ final = flags.delete("--final")
203
+ force = flags.delete("--force")
205
204
  manifest_only = !flags.delete("--with-tarball")
206
- dry_run = flags.delete("--dry-run")
205
+ dry_run = flags.delete("--dry-run")
207
206
 
208
207
  if final && !release.has_blobstore_secret?
209
208
  say("Can't create final release without blobstore secret".red)
@@ -405,20 +404,9 @@ module Bosh::Cli::Command
405
404
  end
406
405
 
407
406
  if confirmed?
408
- status, body = director.delete_release(name, :force => force,
407
+ status, _ = director.delete_release(name, :force => force,
409
408
  :version => version)
410
- responses = {
411
- :done => "Deleted #{desc}",
412
- :non_trackable => "Started deleting release but director " +
413
- "at '#{target}' doesn't support " +
414
- "deployment tracking",
415
- :track_timeout => "Started deleting release but timed out out " +
416
- "while tracking status",
417
- :error => "Started deleting release but received an error " +
418
- "while tracking status",
419
- }
420
-
421
- say(responses[status] || "Cannot delete release: #{body}")
409
+ task_report(status, "Deleted #{desc}")
422
410
  else
423
411
  say("Canceled deleting release".green)
424
412
  end
@@ -486,5 +474,16 @@ module Bosh::Cli::Command
486
474
 
487
475
  release
488
476
  end
477
+
478
+ def match_remote_packages(manifest_yaml)
479
+ # Catch exceptions to be friendly to old directors
480
+ result = director.match_packages(manifest_yaml) rescue []
481
+
482
+ unless result.is_a?(Array)
483
+ say("Cannot find existing packages info " +
484
+ "in the director response, maybe old director?")
485
+ end
486
+ result
487
+ end
489
488
  end
490
489
  end