bosh_cli 0.19.6 → 1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/bin/bosh +3 -0
  2. data/lib/cli.rb +15 -5
  3. data/lib/cli/{commands/base.rb → base_command.rb} +38 -44
  4. data/lib/cli/command_discovery.rb +40 -0
  5. data/lib/cli/command_handler.rb +135 -0
  6. data/lib/cli/commands/biff.rb +16 -12
  7. data/lib/cli/commands/blob_management.rb +10 -3
  8. data/lib/cli/commands/cloudcheck.rb +13 -11
  9. data/lib/cli/commands/complete.rb +29 -0
  10. data/lib/cli/commands/deployment.rb +137 -28
  11. data/lib/cli/commands/help.rb +96 -0
  12. data/lib/cli/commands/job.rb +4 -1
  13. data/lib/cli/commands/job_management.rb +36 -23
  14. data/lib/cli/commands/job_rename.rb +11 -12
  15. data/lib/cli/commands/log_management.rb +28 -32
  16. data/lib/cli/commands/maintenance.rb +6 -1
  17. data/lib/cli/commands/misc.rb +129 -87
  18. data/lib/cli/commands/package.rb +6 -65
  19. data/lib/cli/commands/property_management.rb +20 -8
  20. data/lib/cli/commands/release.rb +211 -206
  21. data/lib/cli/commands/ssh.rb +178 -188
  22. data/lib/cli/commands/stemcell.rb +114 -51
  23. data/lib/cli/commands/task.rb +74 -56
  24. data/lib/cli/commands/user.rb +6 -3
  25. data/lib/cli/commands/vms.rb +17 -15
  26. data/lib/cli/config.rb +27 -1
  27. data/lib/cli/core_ext.rb +27 -1
  28. data/lib/cli/deployment_helper.rb +47 -0
  29. data/lib/cli/director.rb +18 -9
  30. data/lib/cli/errors.rb +6 -0
  31. data/lib/cli/job_builder.rb +75 -23
  32. data/lib/cli/job_property_collection.rb +87 -0
  33. data/lib/cli/job_property_validator.rb +130 -0
  34. data/lib/cli/package_builder.rb +32 -5
  35. data/lib/cli/release.rb +2 -0
  36. data/lib/cli/release_builder.rb +9 -13
  37. data/lib/cli/release_compiler.rb +5 -34
  38. data/lib/cli/release_tarball.rb +4 -19
  39. data/lib/cli/runner.rb +118 -694
  40. data/lib/cli/version.rb +1 -1
  41. data/spec/assets/config/swift-hp/config/final.yml +6 -0
  42. data/spec/assets/config/swift-hp/config/private.yml +7 -0
  43. data/spec/assets/config/swift-rackspace/config/final.yml +6 -0
  44. data/spec/assets/config/swift-rackspace/config/private.yml +6 -0
  45. data/spec/spec_helper.rb +0 -5
  46. data/spec/unit/base_command_spec.rb +32 -37
  47. data/spec/unit/biff_spec.rb +11 -10
  48. data/spec/unit/cli_commands_spec.rb +96 -88
  49. data/spec/unit/core_ext_spec.rb +1 -1
  50. data/spec/unit/deployment_manifest_spec.rb +36 -0
  51. data/spec/unit/director_spec.rb +17 -3
  52. data/spec/unit/job_builder_spec.rb +2 -2
  53. data/spec/unit/job_property_collection_spec.rb +111 -0
  54. data/spec/unit/job_property_validator_spec.rb +7 -0
  55. data/spec/unit/job_rename_spec.rb +7 -6
  56. data/spec/unit/package_builder_spec.rb +2 -2
  57. data/spec/unit/release_builder_spec.rb +33 -0
  58. data/spec/unit/release_spec.rb +54 -0
  59. data/spec/unit/release_tarball_spec.rb +2 -7
  60. data/spec/unit/runner_spec.rb +1 -151
  61. data/spec/unit/ssh_spec.rb +15 -9
  62. metadata +41 -12
  63. data/lib/cli/command_definition.rb +0 -52
  64. data/lib/cli/templates/help_message.erb +0 -80
@@ -3,36 +3,8 @@
3
3
  module Bosh::Cli::Command
4
4
  class Package < Base
5
5
 
6
- def create_all
7
- specs_glob = File.join(work_dir, "packages", "*", "spec")
8
-
9
- Dir[specs_glob].each do |spec|
10
- create(spec)
11
- end
12
- end
13
-
14
- def create(name_or_path)
15
- if name_or_path == "--all"
16
- redirect(:package, :create_all)
17
- end
18
-
19
- spec = read_spec(name_or_path)
20
-
21
- unless spec.is_a?(Hash) && spec.has_key?("name") && spec.has_key?("files")
22
- err("Sorry, '#{name_or_path}' doesn't look like a valid package spec")
23
- end
24
-
25
- package_name = spec["name"]
26
- header("Found '#{package_name}' spec")
27
- print_spec(spec)
28
- header("Building package...")
29
-
30
- builder = Bosh::Cli::PackageBuilder.new(spec, work_dir,
31
- false, release.blobstore)
32
- builder.build
33
- builder
34
- end
35
-
6
+ usage "generate package"
7
+ desc "Generate package template"
36
8
  def generate(name)
37
9
  check_if_release_dir
38
10
 
@@ -50,11 +22,13 @@ module Bosh::Cli::Command
50
22
  FileUtils.mkdir_p(package_dir)
51
23
 
52
24
  generate_file(package_dir, "packaging") do
53
- "# abort script on any command that exit with a non zero value\nset -e\n"
25
+ "# abort script on any command that exit " +
26
+ "with a non zero value\nset -e\n"
54
27
  end
55
28
 
56
29
  generate_file(package_dir, "pre_packaging") do
57
- "# abort script on any command that exit with a non zero value\nset -e\n"
30
+ "# abort script on any command that exit " +
31
+ "with a non zero value\nset -e\n"
58
32
  end
59
33
 
60
34
  generate_file(package_dir, "spec") do
@@ -75,38 +49,5 @@ module Bosh::Cli::Command
75
49
  end
76
50
  end
77
51
 
78
- def print_spec(spec)
79
- say("Package name: #{spec["name"]}")
80
- say("Files:")
81
- for file in spec["files"]
82
- say(" - #{file}")
83
- end
84
- end
85
-
86
- def read_spec(name)
87
- load_yaml_file(find_spec(name))
88
- end
89
-
90
- def find_spec(name)
91
- if File.directory?(name)
92
- spec_path = File.join(name, "spec")
93
- if File.exists?(spec_path)
94
- spec_path
95
- else
96
- err("Cannot find spec file in '#{name}' directory")
97
- end
98
- elsif File.file?(name)
99
- name
100
- else
101
- package_dir = File.join(work_dir, "packages", name)
102
- if File.directory?(package_dir)
103
- find_spec(package_dir)
104
- else
105
- err("Cannot find package '#{name}' (tried '#{package_dir}')")
106
- end
107
-
108
- end
109
- end
110
-
111
52
  end
112
53
  end
@@ -4,6 +4,9 @@ module Bosh::Cli::Command
4
4
  class PropertyManagement < Base
5
5
  include Bosh::Cli::DeploymentHelper
6
6
 
7
+ # bosh set property
8
+ usage "set property"
9
+ desc "Set deployment property"
7
10
  def set(name, value)
8
11
  prepare
9
12
  show_header
@@ -23,10 +26,9 @@ module Bosh::Cli::Command
23
26
  end
24
27
 
25
28
  prompt = "Are you sure you want to set property" +
26
- " `#{name.green}' to `#{format_property(value).green}'? " +
27
- "(type yes to proceed): "
29
+ " `#{name.green}' to `#{format_property(value).green}'?"
28
30
 
29
- if interactive? && ask(prompt) != "yes"
31
+ unless confirmed?(prompt)
30
32
  err("Canceled")
31
33
  end
32
34
 
@@ -43,14 +45,17 @@ module Bosh::Cli::Command
43
45
  end
44
46
  end
45
47
 
48
+ # bosh unset property
49
+ usage "unset property"
50
+ desc "Unset deployment property"
46
51
  def unset(name)
47
52
  prepare
48
53
  show_header
49
54
 
50
55
  prompt = "Are you sure you want to unset property " +
51
- "`#{name.green}'? (type yes to proceed): "
56
+ "`#{name.green}'?"
52
57
 
53
- if interactive? && ask(prompt) != "yes"
58
+ unless confirmed?(prompt)
54
59
  err("Canceled")
55
60
  end
56
61
 
@@ -63,6 +68,9 @@ module Bosh::Cli::Command
63
68
  end
64
69
  end
65
70
 
71
+ # bosh get property
72
+ usage "get property"
73
+ desc "Get deployment property"
66
74
  def get(name)
67
75
  prepare
68
76
  show_header
@@ -76,9 +84,13 @@ module Bosh::Cli::Command
76
84
  end
77
85
  end
78
86
 
79
- def list(*args)
87
+ # bosh properties
88
+ usage "properties"
89
+ desc "List deployment properties"
90
+ option "--terse", "easy to parse output"
91
+ def list
80
92
  prepare
81
- terse = args.include?("--terse")
93
+ terse = options[:terse]
82
94
  show_header unless terse
83
95
 
84
96
  properties = director.list_properties(@deployment_name)
@@ -97,7 +109,7 @@ module Bosh::Cli::Command
97
109
  else
98
110
  if output.size > 0
99
111
  properties_table = table do |t|
100
- t.headings = ["Name", "Value"]
112
+ t.headings = %w(Name Value)
101
113
  output.each { |row| t << [row[0], row[1].truncate(40)] }
102
114
  end
103
115
  say(properties_table)
@@ -7,21 +7,18 @@ module Bosh::Cli::Command
7
7
  include Bosh::Cli::DependencyHelper
8
8
  include Bosh::Cli::VersionCalc
9
9
 
10
- def init(base=nil, *options)
11
- if base[0..0] == "-"
12
- # TODO: need to add some option parsing helpers to avoid that
13
- options.unshift(base)
14
- base = nil
15
- end
16
- git = options.include?("--git")
17
-
10
+ # bosh init release
11
+ usage "init release"
12
+ desc "Initialize release directory"
13
+ option "--git", "initialize git repository"
14
+ def init(base = nil)
18
15
  if base
19
- FileUtils.mkdir_p(base) unless Dir.exist?(base)
16
+ FileUtils.mkdir_p(base)
20
17
  Dir.chdir(base)
21
18
  end
22
19
 
23
20
  err("Release already initialized") if in_release_dir?
24
- git_init if git
21
+ git_init if options[:git]
25
22
 
26
23
  %w[config jobs packages src blobs].each do |dir|
27
24
  FileUtils.mkdir(dir)
@@ -35,55 +32,65 @@ module Bosh::Cli::Command
35
32
  say("Release directory initialized".green)
36
33
  end
37
34
 
38
- def git_init
39
- out = %x{git init 2>&1}
40
- if $? != 0
41
- say("error running 'git init':\n#{out}")
35
+ # bosh create release
36
+ usage "create release"
37
+ desc "Create release (assumes current directory " +
38
+ "to be a release repository)"
39
+ option "--force", "bypass git dirty state check"
40
+ option "--final", "create final release"
41
+ option "--with-tarball", "create release tarball"
42
+ option "--dry-run", "stop before writing release manifest"
43
+ def create(manifest_file = nil)
44
+ check_if_release_dir
45
+
46
+ if manifest_file && File.file?(manifest_file)
47
+ release_filename = create_from_manifest(manifest_file)
42
48
  else
43
- File.open(".gitignore", "w") do |f|
44
- f << <<-EOS.gsub(/^\s{10}/, '')
45
- config/dev.yml
46
- config/private.yml
47
- releases/*.tgz
48
- dev_releases
49
- .blobs
50
- blobs
51
- .dev_builds
52
- .idea
53
- .DS_Store
54
- .final_builds/jobs/**/*.tgz
55
- .final_builds/packages/**/*.tgz
56
- *.swp
57
- *~
58
- *#
59
- #*
60
- EOS
61
- end
49
+ release_filename = create_from_spec
50
+ end
51
+
52
+ if release_filename
53
+ release.latest_release_filename = release_filename
54
+ release.save_config
62
55
  end
63
- rescue Errno::ENOENT
64
- say("Unable to run 'git init'".red)
65
56
  end
66
57
 
67
- def verify(tarball_path, *options)
58
+ # bosh verify release
59
+ usage "verify release"
60
+ desc "Verify release"
61
+ def verify(tarball_path)
68
62
  tarball = Bosh::Cli::ReleaseTarball.new(tarball_path)
69
63
 
70
- say("\nVerifying release...")
64
+ nl
65
+ say("Verifying release...")
71
66
  tarball.validate
72
67
  nl
73
68
 
74
69
  if tarball.valid?
75
- say("'%s' is a valid release" % [tarball_path] )
70
+ say("`#{tarball_path}' is a valid release".green)
76
71
  else
77
- say("'%s' is not a valid release:" % [tarball_path] )
78
- for error in tarball.errors
79
- say("- %s" % [error])
72
+ say("Validation errors:".red)
73
+ tarball.errors.each do |error|
74
+ say("- #{error}")
80
75
  end
76
+ err("`#{tarball_path}' is not a valid release".red)
81
77
  end
82
78
  end
83
79
 
80
+ usage "upload release"
81
+ desc "Upload release"
82
+ option "--rebase",
83
+ "Rebases this release onto the latest version",
84
+ "known by director (discards local job/package",
85
+ "versions in favor of versions assigned by director)"
84
86
  def upload(release_file = nil)
85
87
  auth_required
86
88
 
89
+ upload_options = {
90
+ :rebase => options[:rebase],
91
+ :repack => true
92
+ }
93
+
87
94
  if release_file.nil?
88
95
  check_if_release_dir
89
96
  release_file = release.latest_release_filename
@@ -98,18 +105,95 @@ module Bosh::Cli::Command
98
105
  end
99
106
  end
100
107
 
108
+ unless File.exist?(release_file)
109
+ err("Release file doesn't exist")
110
+ end
111
+
101
112
  file_type = `file --mime-type -b '#{release_file}'`
102
113
 
103
114
  if file_type =~ /text\/(plain|yaml)/
104
- upload_manifest(release_file)
105
- else # Just assume tarball
106
- upload_tarball(release_file)
115
+ upload_manifest(release_file, upload_options)
116
+ else
117
+ upload_tarball(release_file, upload_options)
118
+ end
119
+ end
120
+
121
+ usage "reset release"
122
+ desc "Reset dev release"
123
+ def reset
124
+ check_if_release_dir
125
+
126
+ say("Your dev release environment will be completely reset".red)
127
+ if confirmed?
128
+ say("Removing dev_builds index...")
129
+ FileUtils.rm_rf(".dev_builds")
130
+ say("Clearing dev name...")
131
+ release.dev_name = nil
132
+ release.save_config
133
+ say("Removing dev tarballs...")
134
+ FileUtils.rm_rf("dev_releases")
135
+
136
+ say("Release has been reset".green)
137
+ else
138
+ say("Canceled")
139
+ end
140
+ end
141
+
142
+ usage "releases"
143
+ desc "Show the list of available releases"
144
+ def list
145
+ auth_required
146
+ releases = director.list_releases.sort do |r1, r2|
147
+ r1["name"] <=> r2["name"]
148
+ end
149
+
150
+ err("No releases") if releases.empty?
151
+
152
+ releases_table = table do |t|
153
+ t.headings = "Name", "Versions"
154
+ releases.each do |r|
155
+ versions = r["versions"].sort do |v1, v2|
156
+ version_cmp(v1, v2)
157
+ end
158
+
159
+ t << [r["name"], versions.join(", ")]
160
+ end
107
161
  end
162
+
163
+ nl
164
+ say(releases_table)
165
+ nl
166
+ say("Releases total: %d" % releases.size)
108
167
  end
109
168
 
110
- def upload_manifest(manifest_path)
111
- manifest = load_yaml_file(manifest_path)
112
- remote_release = get_remote_release(manifest["name"]) rescue nil
169
+ usage "delete release"
170
+ desc "Delete release (or a particular release version)"
171
+ option "--force", "ignore errors during deletion"
172
+ def delete(name, version = nil)
173
+ auth_required
174
+ force = !!options[:force]
175
+
176
+ desc = "#{name}"
177
+ desc << "/#{version}" if version
178
+
179
+ if force
180
+ say("Deleting `#{desc}' (FORCED DELETE, WILL IGNORE ERRORS)".red)
181
+ else
182
+ say("Deleting `#{desc}'".red)
183
+ end
184
+
185
+ if confirmed?
186
+ status, _ = director.delete_release(
187
+ name, :force => force, :version => version)
188
+ task_report(status, "Deleted `#{desc}'")
189
+ else
190
+ say("Canceled deleting release".green)
191
+ end
192
+ end
193
+
194
+ protected
195
+
196
+ def upload_manifest(manifest_path, upload_options = {})
113
197
  package_matches = match_remote_packages(File.read(manifest_path))
114
198
 
115
199
  find_release_dir(manifest_path)
@@ -117,11 +201,8 @@ module Bosh::Cli::Command
117
201
  blobstore = release.blobstore
118
202
  tmpdir = Dir.mktmpdir
119
203
 
120
- at_exit { FileUtils.rm_rf(tmpdir) }
121
-
122
- compiler =
123
- Bosh::Cli::ReleaseCompiler.new(manifest_path, blobstore,
124
- remote_release, package_matches)
204
+ compiler = Bosh::Cli::ReleaseCompiler.new(
205
+ manifest_path, blobstore, package_matches)
125
206
  need_repack = true
126
207
 
127
208
  unless compiler.exists?
@@ -129,13 +210,16 @@ module Bosh::Cli::Command
129
210
  compiler.compile
130
211
  need_repack = false
131
212
  end
132
- upload_tarball(compiler.tarball_path, :repack => need_repack)
213
+
214
+ upload_options[:repack] = need_repack
215
+ upload_tarball(compiler.tarball_path, upload_options)
133
216
  end
134
217
 
135
- def upload_tarball(tarball_path, options = {})
218
+ def upload_tarball(tarball_path, upload_options = {})
136
219
  tarball = Bosh::Cli::ReleaseTarball.new(tarball_path)
137
220
  # Trying to repack release by default
138
- repack = options.has_key?(:repack) ? !!options[:repack] : true
221
+ repack = upload_options[:repack]
222
+ rebase = upload_options[:rebase]
139
223
 
140
224
  say("\nVerifying release...")
141
225
  tarball.validate(:allow_sparse => true)
@@ -148,7 +232,7 @@ module Bosh::Cli::Command
148
232
  begin
149
233
  remote_release = get_remote_release(tarball.release_name) rescue nil
150
234
 
151
- if remote_release &&
235
+ if remote_release && !rebase &&
152
236
  remote_release["versions"].include?(tarball.version)
153
237
  err("This release version has already been uploaded")
154
238
  end
@@ -157,7 +241,7 @@ module Bosh::Cli::Command
157
241
  package_matches = match_remote_packages(tarball.manifest)
158
242
 
159
243
  say("Checking if can repack release for faster upload...")
160
- repacked_path = tarball.repack(remote_release, package_matches)
244
+ repacked_path = tarball.repack(package_matches)
161
245
  if repacked_path.nil?
162
246
  say("Uploading the whole release".green)
163
247
  else
@@ -171,49 +255,31 @@ module Bosh::Cli::Command
171
255
  # a release info (think new releases)
172
256
  end
173
257
 
174
- say("\nUploading release...\n")
175
- status, _ = director.upload_release(tarball_path)
176
-
177
- task_report(status, "Release uploaded")
178
- end
179
-
180
- def create(*options)
181
- check_if_release_dir
182
- if options.size == 1 && File.file?(options[0])
183
- create_from_manifest(options[0])
184
- release_filename = options[0]
258
+ if rebase
259
+ say("Uploading release (#{"will be rebased".yellow})")
260
+ status, _ = director.rebase_release(tarball_path)
261
+ task_report(status, "Release rebased")
185
262
  else
186
- release_filename = create_from_spec(*options)
187
- end
188
-
189
- if release_filename
190
- release.latest_release_filename = release_filename
191
- release.save_config
263
+ say("\nUploading release\n")
264
+ status, _ = director.upload_release(tarball_path)
265
+ task_report(status, "Release uploaded")
192
266
  end
193
267
  end
194
268
 
195
269
  def create_from_manifest(manifest_file)
196
270
  say("Recreating release from the manifest")
197
271
  Bosh::Cli::ReleaseCompiler.compile(manifest_file, release.blobstore)
272
+ manifest_file
198
273
  end
199
274
 
200
- def create_from_spec(*options)
201
- flags = options.inject({}) { |h, option| h[option] = true; h }
202
-
203
- final = flags.delete("--final")
204
- force = flags.delete("--force")
205
- manifest_only = !flags.delete("--with-tarball")
206
- dry_run = flags.delete("--dry-run")
275
+ def create_from_spec
276
+ final = options[:final]
277
+ force = options[:force]
278
+ manifest_only = !options[:with_tarball]
279
+ dry_run = options[:dry_run]
207
280
 
208
281
  if final && !release.has_blobstore_secret?
209
- say("Can't create final release without blobstore secret".red)
210
- exit(1)
211
- end
212
-
213
- if flags.size > 0
214
- say("Unknown flags: #{flags.keys.join(", ")}".red)
215
- show_usage
216
- exit(1)
282
+ err("Can't create final release without blobstore secret")
217
283
  end
218
284
 
219
285
  blob_manager.sync
@@ -229,16 +295,13 @@ module Bosh::Cli::Command
229
295
  check_if_dirty_state unless force
230
296
 
231
297
  confirmation = "Are you sure you want to " +
232
- "generate #{'final'.red} version? "
298
+ "generate #{'final'.red} version? "
233
299
 
234
300
  if final && !dry_run && !confirmed?(confirmation)
235
301
  say("Canceled release generation".green)
236
302
  exit(1)
237
303
  end
238
304
 
239
- packages = []
240
- jobs = []
241
-
242
305
  if final
243
306
  header("Building FINAL release".green)
244
307
  release_name = release.final_name
@@ -249,12 +312,12 @@ module Bosh::Cli::Command
249
312
 
250
313
  if version_greater(release.min_cli_version, Bosh::Cli::VERSION)
251
314
  err("You should use CLI >= #{release.min_cli_version} " +
252
- "with this release, you have #{Bosh::Cli::VERSION}")
315
+ "with this release, you have #{Bosh::Cli::VERSION}")
253
316
  end
254
317
 
255
318
  if release_name.blank?
256
319
  confirmation = "Please enter %s release name: " % [
257
- final ? "final" : "development"]
320
+ final ? "final" : "development"]
258
321
  name = interactive? ? ask(confirmation).to_s : DEFAULT_RELEASE_NAME
259
322
  err("Canceled release creation, no name given") if name.blank?
260
323
  if final
@@ -266,23 +329,17 @@ module Bosh::Cli::Command
266
329
  end
267
330
 
268
331
  header("Building packages")
269
- Dir[File.join(work_dir, "packages", "*")].each do |package_dir|
270
- next unless File.directory?(package_dir)
271
- package_dirname = File.basename(package_dir)
272
- package_spec = load_yaml_file(File.join(package_dir, "spec"))
273
-
274
- if package_spec["name"] != package_dirname
275
- err("Found `#{package_spec["name"]}' package in " +
276
- "`#{package_dirname}' directory, please fix it")
277
- end
278
332
 
279
- package = Bosh::Cli::PackageBuilder.new(package_spec, work_dir,
280
- final, release.blobstore)
281
- package.dry_run = true if dry_run
333
+ packages = Bosh::Cli::PackageBuilder.discover(
334
+ work_dir,
335
+ :final => final,
336
+ :blobstore => release.blobstore,
337
+ :dry_run => dry_run
338
+ )
282
339
 
340
+ packages.each do |package|
283
341
  say("Building #{package.name.green}...")
284
342
  package.build
285
- packages << package
286
343
  nl
287
344
  end
288
345
 
@@ -294,7 +351,7 @@ module Bosh::Cli::Command
294
351
  sorted_packages = tsort_packages(package_index)
295
352
  header("Resolving dependencies")
296
353
  say("Dependencies resolved, correct build order is:")
297
- for package_name in sorted_packages
354
+ sorted_packages.each do |package_name|
298
355
  say("- %s" % [package_name])
299
356
  end
300
357
  nl
@@ -303,28 +360,17 @@ module Bosh::Cli::Command
303
360
  built_package_names = packages.map { |package| package.name }
304
361
 
305
362
  header("Building jobs")
306
- Dir[File.join(work_dir, "jobs", "*")].each do |job_dir|
307
- next unless File.directory?(job_dir)
308
- job_dirname = File.basename(job_dir)
309
-
310
- prepare_script = File.join(job_dir, "prepare")
311
- if File.exists?(prepare_script)
312
- say("Found prepare script in `#{File.basename(job_dir)}'")
313
- Bosh::Cli::JobBuilder.run_prepare_script(prepare_script)
314
- end
315
-
316
- job_spec = load_yaml_file(File.join(job_dir, "spec"))
317
- if job_spec["name"] != job_dirname
318
- err("Found `#{job_spec["name"]}' job in " +
319
- "`#{job_dirname}' directory, please fix it")
320
- end
321
-
322
- job = Bosh::Cli::JobBuilder.new(job_spec, work_dir, final,
323
- release.blobstore, built_package_names)
324
- job.dry_run = dry_run
363
+ jobs = Bosh::Cli::JobBuilder.discover(
364
+ work_dir,
365
+ :final => final,
366
+ :blobstore => release.blobstore,
367
+ :dry_run => dry_run,
368
+ :package_names => built_package_names
369
+ )
370
+
371
+ jobs.each do |job|
325
372
  say("Building #{job.name.green}...")
326
373
  job.build
327
- jobs << job
328
374
  nl
329
375
  end
330
376
 
@@ -350,7 +396,7 @@ module Bosh::Cli::Command
350
396
 
351
397
  unless manifest_only
352
398
  say("Release tarball (#{pretty_size(builder.tarball_path)}): " +
353
- builder.tarball_path.green)
399
+ builder.tarball_path.green)
354
400
  end
355
401
 
356
402
  release.min_cli_version = Bosh::Cli::VERSION
@@ -359,74 +405,33 @@ module Bosh::Cli::Command
359
405
  builder.manifest_path
360
406
  end
361
407
 
362
- def reset
363
- check_if_release_dir
364
-
365
- say("Your dev release environment will be completely reset".red)
366
- if confirmed?
367
- say("Removing dev_builds index...")
368
- FileUtils.rm_rf(".dev_builds")
369
- say("Clearing dev name...")
370
- release.dev_name = nil
371
- release.save_config
372
- say("Removing dev tarballs...")
373
- FileUtils.rm_rf("dev_releases")
374
-
375
- say("Release has been reset".green)
408
+ def git_init
409
+ out = %x{git init 2>&1}
410
+ if $? != 0
411
+ say("error running 'git init':\n#{out}")
376
412
  else
377
- say("Canceled")
378
- end
379
- end
380
-
381
- def list
382
- auth_required
383
- releases = director.list_releases.sort do |r1, r2|
384
- r1["name"] <=> r2["name"]
385
- end
386
-
387
- err("No releases") if releases.empty?
388
-
389
- releases_table = table do |t|
390
- t.headings = "Name", "Versions"
391
- releases.each do |r|
392
- versions = r["versions"].sort do |v1, v2|
393
- version_cmp(v1, v2)
394
- end
395
-
396
- t << [r["name"], versions.join(", ")]
413
+ File.open(".gitignore", "w") do |f|
414
+ f << <<-EOS.gsub(/^\s{10}/, '')
415
+ config/dev.yml
416
+ config/private.yml
417
+ releases/*.tgz
418
+ dev_releases
419
+ .blobs
420
+ blobs
421
+ .dev_builds
422
+ .idea
423
+ .DS_Store
424
+ .final_builds/jobs/**/*.tgz
425
+ .final_builds/packages/**/*.tgz
426
+ *.swp
427
+ *~
428
+ *#
429
+ #*
430
+ EOS
397
431
  end
398
432
  end
399
-
400
- nl
401
- say(releases_table)
402
- nl
403
- say("Releases total: %d" % releases.size)
404
- end
405
-
406
- def delete(name, *options)
407
- auth_required
408
- force = options.include?("--force")
409
- options.delete("--force")
410
- version = options.shift
411
-
412
- desc = "release `#{name}'"
413
- desc << " version #{version}" if version
414
-
415
- if force
416
- say("Deleting #{desc} (FORCED DELETE, WILL IGNORE ERRORS)".red)
417
- elsif options.size > 0
418
- err("Unknown option, currently only '--force' is supported")
419
- else
420
- say("Deleting #{desc}".red)
421
- end
422
-
423
- if confirmed?
424
- status, _ = director.delete_release(name, :force => force,
425
- :version => version)
426
- task_report(status, "Deleted #{desc}")
427
- else
428
- say("Canceled deleting release".green)
429
- end
433
+ rescue Errno::ENOENT
434
+ say("Unable to run 'git init'".red)
430
435
  end
431
436
 
432
437
  private
@@ -446,14 +451,14 @@ module Bosh::Cli::Command
446
451
 
447
452
  def show_summary(builder)
448
453
  packages_table = table do |t|
449
- t.headings = %w(Name Version Notes Fingerprint)
454
+ t.headings = %w(Name Version Notes)
450
455
  builder.packages.each do |package|
451
456
  t << artefact_summary(package)
452
457
  end
453
458
  end
454
459
 
455
460
  jobs_table = table do |t|
456
- t.headings = %w(Name Version Notes Fingerprint)
461
+ t.headings = %w(Name Version Notes)
457
462
  builder.jobs.each do |job|
458
463
  t << artefact_summary(job)
459
464
  end
@@ -487,7 +492,6 @@ module Bosh::Cli::Command
487
492
  result << artefact.name
488
493
  result << artefact.version
489
494
  result << artefact.notes.join(", ")
490
- result << artefact.fingerprint
491
495
  result
492
496
  end
493
497
 
@@ -506,14 +510,15 @@ module Bosh::Cli::Command
506
510
  end
507
511
 
508
512
  def match_remote_packages(manifest_yaml)
509
- # Catch exceptions to be friendly to old directors
510
- result = director.match_packages(manifest_yaml) rescue []
511
-
512
- unless result.is_a?(Array)
513
- say("Cannot find existing packages info " +
514
- "in the director response, maybe old director?")
515
- end
516
- result
513
+ director.match_packages(manifest_yaml)
514
+ rescue Bosh::Cli::DirectorError
515
+ msg = "You are using CLI >= 0.20 with director that doesn't support " +
516
+ "package matches.\nThis will result in uploading all packages " +
517
+ "and jobs to your director.\nIt is recommended to update your " +
518
+ "director or downgrade your CLI to 0.19.6"
519
+
520
+ say(msg.yellow)
521
+ exit(1) unless confirmed?
517
522
  end
518
523
  end
519
524
  end