bosh_cli 1.3115.0 → 1.3120.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfd2d53b788b054d99bd8d7708453c81396f7c85
4
- data.tar.gz: c3137783a4253dcaa07585072913d86884df6070
3
+ metadata.gz: a07bebb24e591343dc294c015139dd6819ccb421
4
+ data.tar.gz: b0deb9dd65fa416dc36019a8b1d2d8a6014b7232
5
5
  SHA512:
6
- metadata.gz: 508628bc1637eb908b4b6b2c0e0150ab4dfaee34d7a5f8ec27a6960a3802b071901caa77339bba42daaca0cb14615e8e36b7f66b177bc56b5a870c102ae6bc23
7
- data.tar.gz: a2585a85ad0c31c0f11554d439dd36e0b81557a7eb7414fed3d54ad6ec33e67b5b45344769712d004e2ee04c4ce8b42d7af16ae414279216f06521c6d394c43f
6
+ metadata.gz: 40aec8117537c126aa07018ce826d30b17bc5cce82e395368f3df64c2c035aa52cda137094eb457c353c93c5a5f3dea2902d4f8af5e5bc43e956a64b6d71cfcb
7
+ data.tar.gz: e6dfd1f9188ae86ef0913d278692132572e7fc7f4e8408816065fc7a609166be4a11da322096b2096b895c6b43d337e5726f64795e2a730a6251f38fc84d98eb
@@ -4,7 +4,7 @@ module Bosh::Cli
4
4
  extend Bosh::Cli::CommandDiscovery
5
5
  include Bosh::Cli::DeploymentHelper
6
6
 
7
- attr_accessor :options, :out, :args
7
+ attr_accessor :options, :out, :args, :info
8
8
  attr_reader :work_dir, :exit_code, :runner
9
9
 
10
10
  DEFAULT_DIRECTOR_PORT = 25555
@@ -18,6 +18,7 @@ module Bosh::Cli
18
18
  @exit_code = 0
19
19
  @out = nil
20
20
  @args = []
21
+ @info = {}
21
22
  end
22
23
 
23
24
  # @return [Bosh::Cli::Config] Current configuration
@@ -87,6 +88,10 @@ module Bosh::Cli
87
88
  Bosh::Cli::Runner.new(args, @options).run
88
89
  end
89
90
 
91
+ def run_nested_command(*args)
92
+ Bosh::Cli::Runner.new(args, @options).run(false)
93
+ end
94
+
90
95
  def confirmed?(question = 'Are you sure?')
91
96
  return true if non_interactive?
92
97
  ask("#{question} (type 'yes' to continue): ") == 'yes'
@@ -96,6 +96,7 @@ module Bosh
96
96
  def upload_remote_stemcell(stemcell_location, options = {})
97
97
  options = options.dup
98
98
  payload = { 'location' => stemcell_location }
99
+ payload[:sha1] = options[:sha1] if options[:sha1]
99
100
  options[:payload] = JSON.generate(payload)
100
101
  options[:content_type] = 'application/json'
101
102
 
@@ -641,6 +642,7 @@ module Bosh
641
642
  def releases_path(options = {})
642
643
  path = '/releases'
643
644
  params = [:rebase, :skip_if_exists].select { |p| options[p] }.map { |p| "#{p}=true" }
645
+ params.push "sha1=#{options[:sha1]}" unless options[:sha1].blank?
644
646
  path << "?#{params.join('&')}" unless params.empty?
645
647
  path
646
648
  end
@@ -55,7 +55,7 @@ module Bosh::Cli
55
55
 
56
56
  begin
57
57
  command.send(@method.name, *args)
58
- command.exit_code
58
+ [command.exit_code, command.info]
59
59
  rescue ArgumentError => ex
60
60
  err("#{ex.message}.\n\nUsage: #{usage_with_params}")
61
61
  end
@@ -88,6 +88,54 @@ module Bosh::Cli::Command
88
88
  recreate = !!options[:recreate]
89
89
  redact_diff = !!options[:redact_diff]
90
90
 
91
+ manifest = build_manifest
92
+ if manifest.hash['releases']
93
+ manifest.hash['releases'].each do |release|
94
+ if release['url'].blank?
95
+ if release['version'] == 'create'
96
+ err("Expected URL when specifying release version `create'")
97
+ end
98
+ else
99
+ parsed_uri = URI.parse(release['url'])
100
+ case parsed_uri.scheme
101
+ when 'file'
102
+ if release['version'] == 'create'
103
+ path_is_reasonable!(parsed_uri.path)
104
+ _, info = run_nested_command "create", "release", "--name", release['name'], "--dir", parsed_uri.path, "--timestamp-version", "--force"
105
+ release['version'] = info[:generated_version]
106
+ run_nested_command "upload", "release", "--dir", parsed_uri.path, info[:generated_manifest_path]
107
+ else
108
+ run_nested_command "upload", "release", parsed_uri.path, '--name', release['name'], '--version', release['version'].to_s
109
+ end
110
+ when 'http', 'https'
111
+ err('Path must be a local release directory when version is `create\'') if release['version'] == 'create'
112
+ err("Expected SHA1 when specifying remote URL for release `#{release["name"]}'") if release['sha1'].blank?
113
+ run_nested_command "upload", "release", release['url'], "--sha1", release['sha1'], "--name", release['name'], "--version", release['version'].to_s
114
+ else
115
+ err("Invalid URL format for release `#{release['name']}' with URL `#{release['url']}'. Supported schemes: file, http, https.")
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ if manifest.hash['resource_pools']
122
+ manifest.hash['resource_pools'].each do |resource_pool|
123
+ unless resource_pool['stemcell']['url'].blank?
124
+ parsed_uri = URI.parse(resource_pool['stemcell']['url'])
125
+ case parsed_uri.scheme
126
+ when 'file'
127
+ run_nested_command "upload", "stemcell", parsed_uri.path, "--name", resource_pool['stemcell']['name'], "--version", resource_pool['stemcell']['version'].to_s, "--skip-if-exists"
128
+ when 'http', 'https'
129
+ err("Expected SHA1 when specifying remote URL for stemcell `#{resource_pool['stemcell']['name']}'") if resource_pool['stemcell']['sha1'].blank?
130
+ run_nested_command "upload", "stemcell", resource_pool['stemcell']['url'], "--sha1", resource_pool['stemcell']['sha1'],
131
+ "--name", resource_pool['stemcell']['name'], "--version", resource_pool['stemcell']['version'].to_s, "--skip-if-exists"
132
+ else
133
+ err("Invalid URL format for stemcell `#{resource_pool['stemcell']['name']}' with URL `#{resource_pool['stemcell']['url']}'. Supported schemes: file, http, https.")
134
+ end
135
+ end
136
+ end
137
+ end
138
+
91
139
  manifest = prepare_deployment_manifest(resolve_properties: true, show_state: true)
92
140
 
93
141
  inspect_deployment_changes(
@@ -275,11 +323,19 @@ module Bosh::Cli::Command
275
323
 
276
324
  [deployment["name"], releases.join("\n"), stemcells.join("\n"), deployment.fetch("cloud_config", "none")]
277
325
  end
278
-
326
+
279
327
  def names_and_versions_from(arr)
280
328
  arr.map { |hash|
281
329
  hash.values_at("name", "version").join("/")
282
330
  }.sort
283
331
  end
332
+
333
+ def path_is_reasonable!(path)
334
+ #path is actually to a directory, not a file
335
+ unless File.directory?(path)
336
+ err "Path must be a release directory when version is `create'"
337
+ end
338
+ end
339
+
284
340
  end
285
341
  end
@@ -8,6 +8,7 @@ module Bosh::Cli::Command
8
8
  option '--dns', 'Return instance DNS A records'
9
9
  option '--vitals', 'Return instance vitals information'
10
10
  option '--ps', "Return instance process information"
11
+ option '--failing', "Only show failing ones"
11
12
  def list()
12
13
  auth_required
13
14
  deployment_required
@@ -44,6 +45,7 @@ module Bosh::Cli::Command
44
45
  s
45
46
  end
46
47
 
48
+ row_count = 0
47
49
  has_disk_cid = instances[0].has_key?('disk_cid')
48
50
 
49
51
  instances_table = table do |t|
@@ -65,9 +67,19 @@ module Bosh::Cli::Command
65
67
  headings += ["System\nDisk Usage", "Ephemeral\nDisk Usage", "Persistent\nDisk Usage"]
66
68
  end
67
69
  t.headings = headings
68
-
69
- s = instances.size
70
70
  sorted.each do |instance|
71
+ if options[:failing]
72
+ if options[:ps]
73
+ instance['processes'].keep_if { |p| p['state'] != 'running' }
74
+ next if instance['processes'].size == 0 && instance['job_state'] != 'failing'
75
+ else
76
+ next if instance['job_state'] != 'failing'
77
+ end
78
+ end
79
+
80
+ row_count += 1
81
+ t << :separator if row_count.between?(2, sorted.size)
82
+
71
83
  job = "#{instance['job_name'] || 'unknown'}/#{instance['index'] || 'unknown'}"
72
84
  ips = Array(instance['ips']).join("\n")
73
85
  dns_records = Array(instance['dns']).join("\n")
@@ -117,7 +129,6 @@ module Bosh::Cli::Command
117
129
  end
118
130
 
119
131
  t << row
120
- s -= 1
121
132
  if options[:ps] && instance['processes']
122
133
  instance['processes'].each do |process|
123
134
  name = process['name']
@@ -126,16 +137,20 @@ module Bosh::Cli::Command
126
137
  (headings.size - 2).times { process_row << '' }
127
138
  t << process_row
128
139
  end
129
- t << :separator if s > 0
130
140
  end
131
141
  end
132
142
  end
133
143
 
144
+ if options[:failing] && row_count == 0
145
+ nl
146
+ say('No failing instances')
147
+ nl
148
+ return
149
+ end
134
150
  nl
135
151
  say(instances_table)
136
152
  nl
137
- say('Instances total: %d' % instances.size)
153
+ say('Instances total: %d' % row_count )
138
154
  end
139
-
140
155
  end
141
156
  end
@@ -17,6 +17,7 @@ module Bosh::Cli::Command
17
17
  option '--name NAME', 'specify a custom release name'
18
18
  option '--version VERSION', 'specify a custom version number (ex: 1.0.0 or 1.0-beta.2+dev.10)'
19
19
  option '--dir RELEASE_DIRECTORY', 'path to release directory'
20
+ option '--timestamp-version', 'create release with the timestamp as the dev version (ex: 1+dev.TIMESTAMP)'
20
21
 
21
22
  def create(manifest_file = nil)
22
23
  switch_to_release_dir
@@ -29,12 +30,23 @@ module Bosh::Cli::Command
29
30
  err('Cannot specify a custom version number when creating from a manifest. The manifest already specifies a version.'.make_red)
30
31
  end
31
32
 
33
+ if options[:'timestamp_version']
34
+ err('Cannot specify timestamp-version when creating from a manifest. The manifest already specifies a version.'.make_red)
35
+ end
36
+
32
37
  say('Recreating release from the manifest')
33
38
  Bosh::Cli::ReleaseCompiler.compile(manifest_file, cache_dir, release.blobstore, [], release.dir)
34
39
  release_filename = manifest_file
35
40
  else
36
- version = options[:version]
37
- version = Bosh::Common::Version::ReleaseVersion.parse(version).to_s unless version.nil?
41
+ if options[:version] && options[:'timestamp_version']
42
+ err('Cannot specify both timestamp-version and version when creating a release.')
43
+ end
44
+
45
+ version = nil
46
+ if options[:version]
47
+ version = options[:version]
48
+ version = Bosh::Common::Version::ReleaseVersion.parse(version).to_s unless version.nil?
49
+ end
38
50
 
39
51
  release_filename = create_from_spec(version)
40
52
  end
@@ -99,6 +111,8 @@ module Bosh::Cli::Command
99
111
 
100
112
  header('Building release')
101
113
  release_builder = build_release(job_artifacts, manifest_only, package_artifacts, license_artifacts, name, version)
114
+ info[:generated_version] = release_builder.version
115
+ info[:generated_manifest_path] = release_builder.manifest_path
102
116
 
103
117
  header('Release summary')
104
118
  show_summary(release_builder)
@@ -150,7 +164,8 @@ module Bosh::Cli::Command
150
164
  final: final,
151
165
  commit_hash: commit_hash,
152
166
  version: version,
153
- uncommitted_changes: dirty_state?
167
+ uncommitted_changes: dirty_state?,
168
+ timestamp_version: options[:'timestamp_version']
154
169
  )
155
170
 
156
171
  unless dry_run
@@ -3,13 +3,17 @@ module Bosh::Cli::Command
3
3
  class UploadRelease < Base
4
4
 
5
5
  usage 'upload release'
6
- desc 'Upload release (release_file can be a local file or a remote URI)'
6
+ desc "Upload release (release_file can be a local file or a remote URI). \
7
+ If --name & --version are provided, they will be used for checking if release exists & upload will be skipped if it exists (for both local and remote)"
7
8
  option '--rebase',
8
9
  'Rebases this release onto the latest version',
9
10
  'known by director (discards local job/package',
10
11
  'versions in favor of versions assigned by director)'
11
12
  option '--skip-if-exists', 'no-op; retained for backward compatibility'
12
13
  option '--dir RELEASE_DIRECTORY', 'path to release directory'
14
+ option '--sha1 SHA1', 'SHA1 of the remote release'
15
+ option '--name NAME', 'name of the release'
16
+ option '--version VERSION', 'version of the release'
13
17
 
14
18
  def upload(release_file = nil)
15
19
  auth_required
@@ -19,6 +23,7 @@ module Bosh::Cli::Command
19
23
  upload_options = {
20
24
  :rebase => options[:rebase],
21
25
  :repack => true,
26
+ :sha1 => options[:sha1]
22
27
  }
23
28
 
24
29
  #only check release_dir if not compiled release tarball
@@ -38,12 +43,22 @@ module Bosh::Cli::Command
38
43
  end
39
44
  end
40
45
 
46
+ if options[:name] && options[:version]
47
+ director.list_releases.each do |release|
48
+ if release['name'] == options[:name]
49
+ release['release_versions'].each do |version|
50
+ return if version['version'] == options[:version]
51
+ end
52
+ end
53
+ end
54
+ end
55
+
41
56
  if release_file =~ /^#{URI::regexp}$/
42
57
  upload_remote_release(release_file, upload_options)
58
+
43
59
  else
44
- unless File.exist?(release_file)
45
- err("Release file doesn't exist")
46
- end
60
+ err("Option '--sha1' is not supported for uploading local release") unless options[:sha1].nil?
61
+ err("Release file doesn't exist") unless File.exist?(release_file)
47
62
 
48
63
  file_type = `file --mime-type -b '#{release_file}'` # duplicate? Already done on line 23
49
64
 
@@ -146,7 +161,6 @@ module Bosh::Cli::Command
146
161
  end
147
162
 
148
163
  def upload_remote_release(release_location, upload_options = {})
149
- nl
150
164
  if upload_options[:rebase]
151
165
  say("Using remote release `#{release_location}' (#{'will be rebased'.make_yellow})")
152
166
  report = 'Release rebased'
@@ -158,6 +172,7 @@ module Bosh::Cli::Command
158
172
  status, task_id = director.upload_remote_release(
159
173
  release_location,
160
174
  rebase: upload_options[:rebase],
175
+ sha1: upload_options[:sha1]
161
176
  )
162
177
  task_report(status, task_id, report)
163
178
  end
@@ -28,9 +28,13 @@ module Bosh::Cli
28
28
 
29
29
  usage 'upload stemcell'
30
30
  desc "Upload stemcell (stemcell_location can be a local file or a remote URI). \
31
- Note that --skip-if-exists and --fix can not be used together."
31
+ Note that --skip-if-exists and --fix can not be used together. \
32
+ If --name & --version are provided, they will be used for checking if stemcell exists & upload will be skipped if it exists (for both local and remote)"
32
33
  option '--skip-if-exists', 'skips upload if stemcell already exists'
33
34
  option '--fix', 'replaces the stemcell if already exists'
35
+ option '--sha1 SHA1', 'SHA1 of the remote stemcell'
36
+ option '--name NAME', 'name of the stemcell'
37
+ option '--version VERSION', 'version of the stemcell'
34
38
  def upload(stemcell_location)
35
39
  auth_required
36
40
  show_current_state
@@ -39,9 +43,19 @@ Note that --skip-if-exists and --fix can not be used together."
39
43
  err("Option '--skip-if-exists' and option '--fix' should not be used together")
40
44
  end
41
45
 
46
+ if options[:fix] && (options[:name] || options[:version])
47
+ err("Options '--name' and '--version' should not be used together with option '--fix'")
48
+ end
49
+
42
50
  stemcell_type = stemcell_location =~ /^#{URI::regexp}$/ ? 'remote' : 'local'
43
51
 
52
+ if options[:name] && options[:version]
53
+ return if exists?(options[:name], options[:version])
54
+ end
55
+
44
56
  if stemcell_type == 'local'
57
+ err("Option '--sha1' is not supported for uploading local stemcell") unless options[:sha1].nil?
58
+
45
59
  stemcell = Bosh::Cli::Stemcell.new(stemcell_location)
46
60
 
47
61
  nl
@@ -75,7 +89,10 @@ Note that --skip-if-exists and --fix can not be used together."
75
89
  say("Using remote stemcell `#{stemcell_location}'")
76
90
  end
77
91
 
78
- status, task_id = apply_upload_stemcell_strategy(stemcell_type, stemcell_location, options[:fix]?{fix: true}:{})
92
+ selected_options = {}
93
+ selected_options[:fix] = options[:fix] if options[:fix]
94
+ selected_options[:sha1] = options[:sha1] if options[:sha1]
95
+ status, task_id = apply_upload_stemcell_strategy(stemcell_type, stemcell_location, selected_options)
79
96
  success_message = 'Stemcell uploaded and created.'
80
97
 
81
98
  if status == :error && options[:skip_if_exists] && last_event(task_id)['error']['code'] == STEMCELL_EXISTS_ERROR_CODE
@@ -1,9 +1,15 @@
1
1
  module Bosh::Cli
2
2
  module DeploymentHelper
3
- def prepare_deployment_manifest(options = {})
3
+ def build_manifest
4
4
  deployment_required
5
- manifest = Manifest.new(deployment, director)
6
- manifest.load
5
+ return @manifest if @manifest
6
+ @manifest = Manifest.new(deployment, director)
7
+ @manifest.load
8
+ @manifest
9
+ end
10
+
11
+ def prepare_deployment_manifest(options = {})
12
+ manifest = build_manifest
7
13
  if options.fetch(:show_state, false)
8
14
  show_current_state(manifest.name)
9
15
  end
@@ -29,7 +29,7 @@ module Bosh::Cli
29
29
  end
30
30
 
31
31
  if options[:resolve_properties]
32
- compiler = DeploymentManifestCompiler.new(File.read(@deployment_file))
32
+ compiler = DeploymentManifestCompiler.new(Psych.dump(@hash))
33
33
  properties = {}
34
34
 
35
35
  begin
@@ -29,6 +29,7 @@ module Bosh::Cli
29
29
  @name = name
30
30
  raise 'Release name is blank' if name.blank?
31
31
 
32
+ @timestamp_version = options.fetch(:'timestamp_version', false)
32
33
  @version = options.fetch(:version, nil)
33
34
 
34
35
  @final_index = Versions::VersionsIndex.new(final_releases_dir)
@@ -195,6 +196,10 @@ module Bosh::Cli
195
196
 
196
197
  if @final
197
198
  # Drop pre-release and post-release segments, and increment the release segment
199
+ if @timestamp_version
200
+ raise ReleaseVersionError.new('Release version cannot be set to a timestamp for a final release')
201
+ end
202
+
198
203
  latest_final_version.increment_release
199
204
  else
200
205
  # Increment or Reset the post-release segment
@@ -202,13 +207,19 @@ module Bosh::Cli
202
207
  latest_dev_version = dev_versions.latest_with_pre_release(latest_final_version)
203
208
 
204
209
  if latest_dev_version
205
- if latest_dev_version.version.post_release.nil?
210
+ if @timestamp_version
211
+ latest_dev_version.timestamp_release
212
+ elsif latest_dev_version.version.post_release.nil?
206
213
  latest_dev_version.default_post_release
207
214
  else
208
215
  latest_dev_version.increment_post_release
209
216
  end
210
217
  else
211
- latest_final_version.default_post_release
218
+ if @timestamp_version
219
+ latest_final_version.timestamp_release
220
+ else
221
+ latest_final_version.default_post_release
222
+ end
212
223
  end
213
224
  end
214
225
  end
@@ -32,7 +32,7 @@ module Bosh::Cli
32
32
 
33
33
  # Find and run CLI command
34
34
  # @return [void]
35
- def run
35
+ def run(exit_on_success=true)
36
36
  Config.interactive = !@options[:non_interactive]
37
37
  Config.poll_interval = @options[:poll_interval]
38
38
 
@@ -53,8 +53,9 @@ module Bosh::Cli
53
53
 
54
54
  command.runner = self
55
55
  begin
56
- exit_code = command.run(@args, @options)
57
- exit(exit_code)
56
+ exit_code, info = command.run(@args, @options)
57
+ exit(exit_code) if exit_on_success || exit_code != 0
58
+ [exit_code, info]
58
59
  rescue OptionParser::ParseError => e
59
60
  say_err(e.message)
60
61
  nl
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Cli
3
- VERSION = '1.3115.0'
3
+ VERSION = '1.3120.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3115.0
4
+ version: 1.3120.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-23 00:00:00.000000000 Z
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3115.0
19
+ version: 1.3120.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.3115.0
26
+ version: 1.3120.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bosh-template
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.3115.0
33
+ version: 1.3120.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.3115.0
40
+ version: 1.3120.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cf-uaa-lib
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.3115.0
131
+ version: 1.3120.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.3115.0
138
+ version: 1.3120.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: net-ssh
141
141
  requirement: !ruby/object:Gem::Requirement