bosh_cli 1.2579.0 → 1.2596.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.rb +4 -2
- data/lib/cli/client/director.rb +10 -11
- data/lib/cli/command_handler.rb +4 -4
- data/lib/cli/commands/maintenance.rb +22 -11
- data/lib/cli/commands/release.rb +180 -122
- data/lib/cli/commands/stemcell.rb +5 -4
- data/lib/cli/deployment_helper.rb +8 -2
- data/lib/cli/errors.rb +30 -28
- data/lib/cli/release_builder.rb +26 -20
- data/lib/cli/release_tarball.rb +20 -0
- data/lib/cli/stemcell.rb +1 -1
- data/lib/cli/version.rb +1 -1
- data/lib/cli/versions_index.rb +7 -18
- metadata +9 -10
- data/lib/cli/version_calc.rb +0 -38
data/lib/cli.rb
CHANGED
@@ -37,12 +37,15 @@ end
|
|
37
37
|
|
38
38
|
require 'common/common'
|
39
39
|
require 'common/exec'
|
40
|
+
require 'common/version/release_version'
|
41
|
+
require 'common/version/bosh_version'
|
42
|
+
require 'common/version/stemcell_version'
|
43
|
+
require 'common/properties'
|
40
44
|
|
41
45
|
require 'cli/config'
|
42
46
|
require 'cli/core_ext'
|
43
47
|
require 'cli/errors'
|
44
48
|
require 'cli/yaml_helper'
|
45
|
-
require 'cli/version_calc'
|
46
49
|
require 'cli/dependency_helper'
|
47
50
|
require 'cli/deployment_manifest'
|
48
51
|
require 'cli/manifest_warnings'
|
@@ -72,7 +75,6 @@ require 'cli/blob_manager'
|
|
72
75
|
|
73
76
|
require 'cli/logs_downloader'
|
74
77
|
|
75
|
-
require 'common/properties'
|
76
78
|
require 'cli/job_property_collection'
|
77
79
|
require 'cli/job_property_validator'
|
78
80
|
|
data/lib/cli/client/director.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
-
require 'cli/version_calc'
|
3
2
|
require 'cli/core_ext'
|
4
3
|
require 'cli/errors'
|
5
4
|
|
@@ -12,7 +11,6 @@ module Bosh
|
|
12
11
|
module Cli
|
13
12
|
module Client
|
14
13
|
class Director
|
15
|
-
include Bosh::Cli::VersionCalc
|
16
14
|
|
17
15
|
DIRECTOR_HTTP_ERROR_CODES = [400, 403, 404, 500]
|
18
16
|
|
@@ -124,7 +122,8 @@ module Bosh
|
|
124
122
|
end
|
125
123
|
|
126
124
|
def list_running_tasks(verbose = 1)
|
127
|
-
|
125
|
+
|
126
|
+
if Bosh::Common::Version::BoshVersion.parse(get_version) < Bosh::Common::Version::BoshVersion.parse('0.3.5')
|
128
127
|
get_json('/tasks?state=processing')
|
129
128
|
else
|
130
129
|
get_json('/tasks?state=processing,cancelling,queued' +
|
@@ -199,7 +198,7 @@ module Bosh
|
|
199
198
|
url = "/stemcells/#{name}/#{version}"
|
200
199
|
|
201
200
|
extras = []
|
202
|
-
extras << 'force
|
201
|
+
extras << ['force', 'true'] if force
|
203
202
|
|
204
203
|
request_and_track(:delete, add_query_string(url, extras), options)
|
205
204
|
end
|
@@ -211,7 +210,7 @@ module Bosh
|
|
211
210
|
url = "/deployments/#{name}"
|
212
211
|
|
213
212
|
extras = []
|
214
|
-
extras << 'force
|
213
|
+
extras << ['force', 'true'] if force
|
215
214
|
|
216
215
|
request_and_track(:delete, add_query_string(url, extras), options)
|
217
216
|
end
|
@@ -224,8 +223,8 @@ module Bosh
|
|
224
223
|
url = "/releases/#{name}"
|
225
224
|
|
226
225
|
extras = []
|
227
|
-
extras << 'force
|
228
|
-
extras <<
|
226
|
+
extras << ['force', 'true'] if force
|
227
|
+
extras << ['version', version] if version
|
229
228
|
|
230
229
|
request_and_track(:delete, add_query_string(url, extras), options)
|
231
230
|
end
|
@@ -240,7 +239,7 @@ module Bosh
|
|
240
239
|
url = '/deployments'
|
241
240
|
|
242
241
|
extras = []
|
243
|
-
extras << 'recreate
|
242
|
+
extras << ['recreate', 'true'] if recreate
|
244
243
|
|
245
244
|
request_and_track(:post, add_query_string(url, extras), options)
|
246
245
|
end
|
@@ -325,8 +324,8 @@ module Bosh
|
|
325
324
|
url = "/deployments/#{deployment_name}/jobs/#{old_name}"
|
326
325
|
|
327
326
|
extras = []
|
328
|
-
extras <<
|
329
|
-
extras << 'force
|
327
|
+
extras << ['new_name', new_name]
|
328
|
+
extras << ['force', 'true'] if force
|
330
329
|
|
331
330
|
options[:content_type] = 'text/yaml'
|
332
331
|
options[:payload] = manifest_yaml
|
@@ -730,7 +729,7 @@ module Bosh
|
|
730
729
|
|
731
730
|
def add_query_string(url, parts)
|
732
731
|
if parts.size > 0
|
733
|
-
"#{url}?#{
|
732
|
+
"#{url}?#{URI.encode_www_form(parts)}"
|
734
733
|
else
|
735
734
|
url
|
736
735
|
end
|
data/lib/cli/command_handler.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
-
|
3
1
|
module Bosh::Cli
|
4
2
|
class CommandHandler
|
5
3
|
|
@@ -15,6 +13,8 @@ module Bosh::Cli
|
|
15
13
|
# @return [Bosh::Cli::Runner]
|
16
14
|
attr_accessor :runner
|
17
15
|
|
16
|
+
attr_reader :options
|
17
|
+
|
18
18
|
# @param [Class] klass
|
19
19
|
# @param [UnboundMethod] method
|
20
20
|
# @param [String] usage
|
@@ -56,7 +56,7 @@ module Bosh::Cli
|
|
56
56
|
begin
|
57
57
|
command.send(@method.name, *args)
|
58
58
|
command.exit_code
|
59
|
-
rescue ArgumentError =>
|
59
|
+
rescue ArgumentError => _
|
60
60
|
err("Usage: #{usage_with_params}")
|
61
61
|
end
|
62
62
|
end
|
@@ -131,4 +131,4 @@ module Bosh::Cli
|
|
131
131
|
end
|
132
132
|
|
133
133
|
end
|
134
|
-
end
|
134
|
+
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module Bosh::Cli::Command
|
4
4
|
class Maintenance < Base
|
5
|
-
include Bosh::Cli::VersionCalc
|
6
5
|
|
7
6
|
RELEASES_TO_KEEP = 2
|
8
7
|
STEMCELLS_TO_KEEP = 2
|
@@ -57,12 +56,13 @@ module Bosh::Cli::Command
|
|
57
56
|
|
58
57
|
delete_list = []
|
59
58
|
say('Deleting old stemcells')
|
60
|
-
|
61
|
-
|
62
|
-
stemcells.sort
|
63
|
-
|
59
|
+
stemcells_by_name.each_pair do |_, stemcells|
|
60
|
+
stemcells.reject! { |stemcell| !stemcell['deployments'].empty? }
|
61
|
+
sorted_stemcells = stemcells.sort do |sc1, sc2|
|
62
|
+
Bosh::Common::Version::StemcellVersion.parse(sc1['version']) <=> Bosh::Common::Version::StemcellVersion.parse(sc2['version'])
|
64
63
|
end
|
65
|
-
|
64
|
+
|
65
|
+
delete_list += sorted_stemcells[0...(-n_to_keep)]
|
66
66
|
end
|
67
67
|
|
68
68
|
if delete_list.size > 0
|
@@ -84,16 +84,27 @@ module Bosh::Cli::Command
|
|
84
84
|
|
85
85
|
director.list_releases.each do |release|
|
86
86
|
name = release['name']
|
87
|
-
|
88
|
-
|
87
|
+
if release['release_versions']
|
88
|
+
# reverse compatibility with old director response format
|
89
|
+
versions = release['release_versions'].map { |release_version| release_version['version'] }
|
90
|
+
currently_deployed = release['release_versions'].
|
91
|
+
select { |release_version| release_version['currently_deployed'] }.
|
92
|
+
map{ |release_version| release_version['version'] }
|
89
93
|
else
|
90
|
-
|
94
|
+
versions = release['versions']
|
95
|
+
currently_deployed = release['in_use']
|
91
96
|
end
|
92
97
|
|
93
|
-
versions.
|
98
|
+
version_tuples = versions.map do |v|
|
99
|
+
{
|
100
|
+
provided: v,
|
101
|
+
parsed: Bosh::Common::Version::ReleaseVersion.parse(v)
|
102
|
+
}
|
103
|
+
end
|
104
|
+
versions = version_tuples.sort_by { |v| v[:parsed] }.map { |v| v[:provided] }
|
94
105
|
|
95
106
|
versions[0...(-n_to_keep)].each do |version|
|
96
|
-
delete_list << [name, version]
|
107
|
+
delete_list << [name, version] unless currently_deployed.include?(version)
|
97
108
|
end
|
98
109
|
end
|
99
110
|
|
data/lib/cli/commands/release.rb
CHANGED
@@ -1,23 +1,20 @@
|
|
1
|
-
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
-
|
3
1
|
module Bosh::Cli::Command
|
4
2
|
class Release < Base
|
5
|
-
DEFAULT_RELEASE_NAME =
|
3
|
+
DEFAULT_RELEASE_NAME = 'bosh-release'
|
6
4
|
|
7
5
|
include Bosh::Cli::DependencyHelper
|
8
|
-
include Bosh::Cli::VersionCalc
|
9
6
|
|
10
7
|
# bosh init release
|
11
|
-
usage
|
12
|
-
desc
|
13
|
-
option
|
8
|
+
usage 'init release'
|
9
|
+
desc 'Initialize release directory'
|
10
|
+
option '--git', 'initialize git repository'
|
14
11
|
def init(base = nil)
|
15
12
|
if base
|
16
13
|
FileUtils.mkdir_p(base)
|
17
14
|
Dir.chdir(base)
|
18
15
|
end
|
19
16
|
|
20
|
-
err(
|
17
|
+
err('Release already initialized') if in_release_dir?
|
21
18
|
git_init if options[:git]
|
22
19
|
|
23
20
|
%w[config jobs packages src blobs].each do |dir|
|
@@ -25,50 +22,64 @@ module Bosh::Cli::Command
|
|
25
22
|
end
|
26
23
|
|
27
24
|
# Initialize an empty blobs index
|
28
|
-
File.open(File.join(
|
25
|
+
File.open(File.join('config', 'blobs.yml'), 'w') do |f|
|
29
26
|
Psych.dump({}, f)
|
30
27
|
end
|
31
28
|
|
32
|
-
say(
|
29
|
+
say('Release directory initialized'.make_green)
|
33
30
|
end
|
34
31
|
|
35
32
|
# bosh create release
|
36
|
-
usage
|
37
|
-
desc
|
38
|
-
option
|
39
|
-
option
|
40
|
-
option
|
41
|
-
option
|
33
|
+
usage 'create release'
|
34
|
+
desc 'Create release (assumes current directory to be a release repository)'
|
35
|
+
option '--force', 'bypass git dirty state check'
|
36
|
+
option '--final', 'create final release'
|
37
|
+
option '--with-tarball', 'create release tarball'
|
38
|
+
option '--dry-run', 'stop before writing release manifest'
|
39
|
+
option '--version VERSION', 'specify a custom version number (ex: 1.0.0 or 1.0-beta.2+dev.10)'
|
42
40
|
def create(manifest_file = nil)
|
43
41
|
check_if_release_dir
|
44
42
|
|
45
43
|
if manifest_file && File.file?(manifest_file)
|
46
|
-
|
44
|
+
if options[:version]
|
45
|
+
err('Cannot specify a custom version number when creating from a manifest. The manifest already specifies a version.'.make_red)
|
46
|
+
end
|
47
|
+
|
48
|
+
say('Recreating release from the manifest')
|
49
|
+
Bosh::Cli::ReleaseCompiler.compile(manifest_file, release.blobstore)
|
50
|
+
release_filename = manifest_file
|
47
51
|
else
|
48
|
-
|
52
|
+
version = options[:version]
|
53
|
+
version = Bosh::Common::Version::ReleaseVersion.parse(version).to_s unless version.nil?
|
54
|
+
|
55
|
+
release_filename = create_from_spec(version)
|
49
56
|
end
|
50
57
|
|
51
58
|
if release_filename
|
52
59
|
release.latest_release_filename = release_filename
|
53
60
|
release.save_config
|
54
61
|
end
|
62
|
+
rescue SemiSemantic::ParseError
|
63
|
+
err("Invalid version: `#{version}'. Please specify a valid version (ex: 1.0.0 or 1.0-beta.2+dev.10).".make_red)
|
64
|
+
rescue Bosh::Cli::ReleaseVersionError => e
|
65
|
+
err(e.message.make_red)
|
55
66
|
end
|
56
67
|
|
57
68
|
# bosh verify release
|
58
|
-
usage
|
59
|
-
desc
|
69
|
+
usage 'verify release'
|
70
|
+
desc 'Verify release'
|
60
71
|
def verify(tarball_path)
|
61
72
|
tarball = Bosh::Cli::ReleaseTarball.new(tarball_path)
|
62
73
|
|
63
74
|
nl
|
64
|
-
say(
|
75
|
+
say('Verifying release...')
|
65
76
|
tarball.validate
|
66
77
|
nl
|
67
78
|
|
68
79
|
if tarball.valid?
|
69
80
|
say("`#{tarball_path}' is a valid release".make_green)
|
70
81
|
else
|
71
|
-
say(
|
82
|
+
say('Validation errors:'.make_red)
|
72
83
|
tarball.errors.each do |error|
|
73
84
|
say("- #{error}")
|
74
85
|
end
|
@@ -76,13 +87,13 @@ module Bosh::Cli::Command
|
|
76
87
|
end
|
77
88
|
end
|
78
89
|
|
79
|
-
usage
|
80
|
-
desc
|
81
|
-
option
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
option
|
90
|
+
usage 'upload release'
|
91
|
+
desc 'Upload release (release_file can be a local file or a remote URI)'
|
92
|
+
option '--rebase',
|
93
|
+
'Rebases this release onto the latest version',
|
94
|
+
'known by director (discards local job/package',
|
95
|
+
'versions in favor of versions assigned by director)'
|
96
|
+
option '--skip-if-exists', 'skips upload if release already exists'
|
86
97
|
def upload(release_file = nil)
|
87
98
|
auth_required
|
88
99
|
|
@@ -96,10 +107,10 @@ module Bosh::Cli::Command
|
|
96
107
|
check_if_release_dir
|
97
108
|
release_file = release.latest_release_filename
|
98
109
|
if release_file.nil?
|
99
|
-
err(
|
110
|
+
err('The information about latest generated release is missing, please provide release filename')
|
100
111
|
end
|
101
112
|
unless confirmed?("Upload release `#{File.basename(release_file).make_green}' to `#{target_name.make_green}'")
|
102
|
-
err(
|
113
|
+
err('Canceled upload')
|
103
114
|
end
|
104
115
|
end
|
105
116
|
|
@@ -120,55 +131,60 @@ module Bosh::Cli::Command
|
|
120
131
|
end
|
121
132
|
end
|
122
133
|
|
123
|
-
usage
|
124
|
-
desc
|
134
|
+
usage 'reset release'
|
135
|
+
desc 'Reset dev release'
|
125
136
|
def reset
|
126
137
|
check_if_release_dir
|
127
138
|
|
128
|
-
say(
|
139
|
+
say('Your dev release environment will be completely reset'.make_red)
|
129
140
|
if confirmed?
|
130
|
-
say(
|
131
|
-
FileUtils.rm_rf(
|
132
|
-
say(
|
141
|
+
say('Removing dev_builds index...')
|
142
|
+
FileUtils.rm_rf('.dev_builds')
|
143
|
+
say('Clearing dev name...')
|
133
144
|
release.dev_name = nil
|
134
145
|
release.save_config
|
135
|
-
say(
|
136
|
-
FileUtils.rm_rf(
|
146
|
+
say('Removing dev tarballs...')
|
147
|
+
FileUtils.rm_rf('dev_releases')
|
137
148
|
|
138
|
-
say(
|
149
|
+
say('Release has been reset'.make_green)
|
139
150
|
else
|
140
|
-
say(
|
151
|
+
say('Canceled')
|
141
152
|
end
|
142
153
|
end
|
143
154
|
|
144
|
-
usage
|
145
|
-
desc
|
146
|
-
option
|
155
|
+
usage 'releases'
|
156
|
+
desc 'Show the list of available releases'
|
157
|
+
option '--jobs', 'include job templates'
|
147
158
|
def list
|
148
159
|
auth_required
|
149
160
|
releases = director.list_releases.sort do |r1, r2|
|
150
|
-
r1[
|
161
|
+
r1['name'] <=> r2['name']
|
151
162
|
end
|
152
163
|
|
153
|
-
err(
|
164
|
+
err('No releases') if releases.empty?
|
154
165
|
|
155
|
-
|
166
|
+
currently_deployed = false
|
167
|
+
uncommited_changes = false
|
168
|
+
if releases.first.has_key? 'release_versions'
|
156
169
|
releases_table = build_releases_table(releases, options)
|
157
|
-
|
170
|
+
currently_deployed, uncommited_changes = release_version_details(releases)
|
171
|
+
elsif releases.first.has_key? 'versions'
|
158
172
|
releases_table = build_releases_table_for_old_director(releases)
|
173
|
+
currently_deployed, uncommited_changes = release_version_details_for_old_director(releases)
|
159
174
|
end
|
160
175
|
|
161
176
|
nl
|
162
177
|
say(releases_table.render)
|
163
|
-
|
164
|
-
say(
|
178
|
+
|
179
|
+
say('(*) Currently deployed') if currently_deployed
|
180
|
+
say('(+) Uncommitted changes') if uncommited_changes
|
165
181
|
nl
|
166
|
-
say(
|
182
|
+
say('Releases total: %d' % releases.size)
|
167
183
|
end
|
168
184
|
|
169
|
-
usage
|
170
|
-
desc
|
171
|
-
option
|
185
|
+
usage 'delete release'
|
186
|
+
desc 'Delete release (or a particular release version)'
|
187
|
+
option '--force', 'ignore errors during deletion'
|
172
188
|
def delete(name, version = nil)
|
173
189
|
auth_required
|
174
190
|
force = !!options[:force]
|
@@ -186,12 +202,11 @@ module Bosh::Cli::Command
|
|
186
202
|
status, task_id = director.delete_release(name, force: force, version: version)
|
187
203
|
task_report(status, task_id, "Deleted `#{desc}'")
|
188
204
|
else
|
189
|
-
say(
|
205
|
+
say('Canceled deleting release'.make_green)
|
190
206
|
end
|
191
207
|
end
|
192
208
|
|
193
|
-
|
194
|
-
protected
|
209
|
+
private
|
195
210
|
|
196
211
|
def upload_manifest(manifest_path, upload_options = {})
|
197
212
|
package_matches = match_remote_packages(File.read(manifest_path))
|
@@ -205,7 +220,7 @@ module Bosh::Cli::Command
|
|
205
220
|
need_repack = true
|
206
221
|
|
207
222
|
unless compiler.exists?
|
208
|
-
compiler.tarball_path = File.join(tmpdir,
|
223
|
+
compiler.tarball_path = File.join(tmpdir, 'release.tgz')
|
209
224
|
compiler.compile
|
210
225
|
need_repack = false
|
211
226
|
end
|
@@ -225,17 +240,27 @@ module Bosh::Cli::Command
|
|
225
240
|
nl
|
226
241
|
|
227
242
|
unless tarball.valid?
|
228
|
-
err(
|
243
|
+
err('Release is invalid, please fix, verify and upload again')
|
244
|
+
end
|
245
|
+
|
246
|
+
if should_convert_to_old_format?(tarball.version)
|
247
|
+
msg = "You are using CLI > 1.2579.0 with a director that doesn't support" +
|
248
|
+
'the new version format you are using. Upgrade your ' +
|
249
|
+
'director to match the version of your CLI or downgrade your ' +
|
250
|
+
'CLI to 1.2579.0 to avoid versioning mismatch issues.'
|
251
|
+
|
252
|
+
say(msg.make_yellow)
|
253
|
+
tarball_path = tarball.convert_to_old_format
|
229
254
|
end
|
230
255
|
|
231
256
|
remote_release = get_remote_release(tarball.release_name) rescue nil
|
232
257
|
if remote_release && !rebase
|
233
|
-
if remote_release[
|
258
|
+
if remote_release['versions'].include?(tarball.version)
|
234
259
|
if upload_options[:skip_if_exists]
|
235
260
|
say("Release `#{tarball.release_name}/#{tarball.version}' already exists. Skipping upload.")
|
236
261
|
return
|
237
262
|
else
|
238
|
-
err(
|
263
|
+
err('This release version has already been uploaded')
|
239
264
|
end
|
240
265
|
end
|
241
266
|
end
|
@@ -244,11 +269,11 @@ module Bosh::Cli::Command
|
|
244
269
|
if repack
|
245
270
|
package_matches = match_remote_packages(tarball.manifest)
|
246
271
|
|
247
|
-
say(
|
272
|
+
say('Checking if can repack release for faster upload...')
|
248
273
|
repacked_path = tarball.repack(package_matches)
|
249
274
|
|
250
275
|
if repacked_path.nil?
|
251
|
-
say(
|
276
|
+
say('Uploading the whole release'.make_green)
|
252
277
|
else
|
253
278
|
say("Release repacked (new size is #{pretty_size(repacked_path)})".make_green)
|
254
279
|
tarball_path = repacked_path
|
@@ -260,36 +285,30 @@ module Bosh::Cli::Command
|
|
260
285
|
end
|
261
286
|
|
262
287
|
if rebase
|
263
|
-
say("Uploading release (#{
|
288
|
+
say("Uploading release (#{'will be rebased'.make_yellow})")
|
264
289
|
status, task_id = director.rebase_release(tarball_path)
|
265
|
-
task_report(status, task_id,
|
290
|
+
task_report(status, task_id, 'Release rebased')
|
266
291
|
else
|
267
292
|
say("\nUploading release\n")
|
268
293
|
status, task_id = director.upload_release(tarball_path)
|
269
|
-
task_report(status, task_id,
|
294
|
+
task_report(status, task_id, 'Release uploaded')
|
270
295
|
end
|
271
296
|
end
|
272
297
|
|
273
298
|
def upload_remote_release(release_location, upload_options = {})
|
274
299
|
nl
|
275
300
|
if upload_options[:rebase]
|
276
|
-
say("Using remote release `#{release_location}' (#{
|
301
|
+
say("Using remote release `#{release_location}' (#{'will be rebased'.make_yellow})")
|
277
302
|
status, task_id = director.rebase_remote_release(release_location)
|
278
|
-
task_report(status, task_id,
|
303
|
+
task_report(status, task_id, 'Release rebased')
|
279
304
|
else
|
280
305
|
say("Using remote release `#{release_location}'")
|
281
306
|
status, task_id = director.upload_remote_release(release_location)
|
282
|
-
task_report(status, task_id,
|
307
|
+
task_report(status, task_id, 'Release uploaded')
|
283
308
|
end
|
284
309
|
end
|
285
|
-
|
286
|
-
def create_from_manifest(manifest_file)
|
287
|
-
say("Recreating release from the manifest")
|
288
|
-
Bosh::Cli::ReleaseCompiler.compile(manifest_file, release.blobstore)
|
289
|
-
manifest_file
|
290
|
-
end
|
291
310
|
|
292
|
-
def create_from_spec
|
311
|
+
def create_from_spec(version)
|
293
312
|
final = options[:final]
|
294
313
|
force = options[:force]
|
295
314
|
manifest_only = !options[:with_tarball]
|
@@ -304,22 +323,22 @@ module Bosh::Cli::Command
|
|
304
323
|
if final
|
305
324
|
confirm_final_release(dry_run)
|
306
325
|
save_final_release_name if release.final_name.blank?
|
307
|
-
header(
|
326
|
+
header('Building FINAL release'.make_green)
|
308
327
|
else
|
309
328
|
save_dev_release_name if release.dev_name.blank?
|
310
|
-
header(
|
329
|
+
header('Building DEV release'.make_green)
|
311
330
|
end
|
312
331
|
|
313
|
-
header(
|
332
|
+
header('Building packages')
|
314
333
|
packages = build_packages(dry_run, final)
|
315
334
|
|
316
|
-
header(
|
335
|
+
header('Building jobs')
|
317
336
|
jobs = build_jobs(packages.map(&:name), dry_run, final)
|
318
337
|
|
319
|
-
header(
|
320
|
-
release_builder = build_release(dry_run, final, jobs, manifest_only, packages)
|
338
|
+
header('Building release')
|
339
|
+
release_builder = build_release(dry_run, final, jobs, manifest_only, packages, version)
|
321
340
|
|
322
|
-
header(
|
341
|
+
header('Release summary')
|
323
342
|
show_summary(release_builder)
|
324
343
|
nl
|
325
344
|
|
@@ -341,7 +360,7 @@ module Bosh::Cli::Command
|
|
341
360
|
def confirm_final_release(dry_run)
|
342
361
|
confirmed = non_interactive? || agree("Are you sure you want to generate #{'final'.make_red} version? ")
|
343
362
|
if !dry_run && !confirmed
|
344
|
-
say(
|
363
|
+
say('Canceled release generation'.make_green)
|
345
364
|
exit(1)
|
346
365
|
end
|
347
366
|
end
|
@@ -378,10 +397,10 @@ module Bosh::Cli::Command
|
|
378
397
|
index
|
379
398
|
end
|
380
399
|
sorted_packages = tsort_packages(package_index)
|
381
|
-
header(
|
382
|
-
say(
|
400
|
+
header('Resolving dependencies')
|
401
|
+
say('Dependencies resolved, correct build order is:')
|
383
402
|
sorted_packages.each do |package_name|
|
384
|
-
say(
|
403
|
+
say('- %s' % [package_name])
|
385
404
|
end
|
386
405
|
nl
|
387
406
|
end
|
@@ -389,9 +408,10 @@ module Bosh::Cli::Command
|
|
389
408
|
packages
|
390
409
|
end
|
391
410
|
|
392
|
-
def build_release(dry_run, final, jobs, manifest_only, packages)
|
411
|
+
def build_release(dry_run, final, jobs, manifest_only, packages, version)
|
393
412
|
release_builder = Bosh::Cli::ReleaseBuilder.new(release, packages, jobs, final: final,
|
394
|
-
commit_hash: commit_hash,
|
413
|
+
commit_hash: commit_hash, version: version,
|
414
|
+
uncommitted_changes: dirty_state?)
|
395
415
|
|
396
416
|
unless dry_run
|
397
417
|
if manifest_only
|
@@ -425,18 +445,18 @@ module Bosh::Cli::Command
|
|
425
445
|
def save_final_release_name
|
426
446
|
release.final_name = DEFAULT_RELEASE_NAME
|
427
447
|
if interactive?
|
428
|
-
release.final_name = ask(
|
429
|
-
err(
|
448
|
+
release.final_name = ask('Please enter final release name: ').to_s
|
449
|
+
err('Canceled release creation, no name given') if release.final_name.blank?
|
430
450
|
end
|
431
451
|
release.save_config
|
432
452
|
end
|
433
453
|
|
434
454
|
def save_dev_release_name
|
435
455
|
if interactive?
|
436
|
-
release.dev_name = ask(
|
456
|
+
release.dev_name = ask('Please enter development release name: ') do |q|
|
437
457
|
q.default = release.final_name if release.final_name
|
438
458
|
end.to_s
|
439
|
-
err(
|
459
|
+
err('Canceled release creation, no name given') if release.dev_name.blank?
|
440
460
|
else
|
441
461
|
release.dev_name = release.final_name ? release.final_name : DEFAULT_RELEASE_NAME
|
442
462
|
end
|
@@ -448,7 +468,7 @@ module Bosh::Cli::Command
|
|
448
468
|
if $? != 0
|
449
469
|
say("error running 'git init':\n#{out}")
|
450
470
|
else
|
451
|
-
File.open(
|
471
|
+
File.open('.gitignore', 'w') do |f|
|
452
472
|
f << <<-EOS.gsub(/^\s{10}/, '')
|
453
473
|
config/dev.yml
|
454
474
|
config/private.yml
|
@@ -472,14 +492,11 @@ module Bosh::Cli::Command
|
|
472
492
|
say("Unable to run 'git init'".make_red)
|
473
493
|
end
|
474
494
|
|
475
|
-
|
476
|
-
private
|
477
|
-
|
478
495
|
# if we aren't already in a release directory, try going up two levels
|
479
496
|
# to see if that is a release directory, and then use that as the base
|
480
497
|
def find_release_dir(manifest_path)
|
481
498
|
unless in_release_dir?
|
482
|
-
dir = File.expand_path(
|
499
|
+
dir = File.expand_path('../..', manifest_path)
|
483
500
|
Dir.chdir(dir)
|
484
501
|
if in_release_dir?
|
485
502
|
@release = Bosh::Cli::Release.new(dir)
|
@@ -503,17 +520,17 @@ module Bosh::Cli::Command
|
|
503
520
|
end
|
504
521
|
end
|
505
522
|
|
506
|
-
say(
|
523
|
+
say('Packages')
|
507
524
|
say(packages_table)
|
508
525
|
nl
|
509
|
-
say(
|
526
|
+
say('Jobs')
|
510
527
|
say(jobs_table)
|
511
528
|
|
512
529
|
affected_jobs = builder.affected_jobs
|
513
530
|
|
514
531
|
if affected_jobs.size > 0
|
515
532
|
nl
|
516
|
-
say(
|
533
|
+
say('Jobs affected by changes in this release')
|
517
534
|
|
518
535
|
affected_jobs_table = table do |t|
|
519
536
|
t.headings = %w(Name Version)
|
@@ -530,7 +547,7 @@ module Bosh::Cli::Command
|
|
530
547
|
result = []
|
531
548
|
result << artefact.name
|
532
549
|
result << artefact.version
|
533
|
-
result << artefact.notes.join(
|
550
|
+
result << artefact.notes.join(', ')
|
534
551
|
result
|
535
552
|
end
|
536
553
|
|
@@ -538,10 +555,10 @@ module Bosh::Cli::Command
|
|
538
555
|
release = director.get_release(name)
|
539
556
|
|
540
557
|
unless release.is_a?(Hash) &&
|
541
|
-
release.has_key?(
|
542
|
-
release.has_key?(
|
558
|
+
release.has_key?('jobs') &&
|
559
|
+
release.has_key?('packages')
|
543
560
|
raise Bosh::Cli::DirectorError,
|
544
|
-
|
561
|
+
'Cannot find version, jobs and packages info in the director response, maybe old director?'
|
545
562
|
end
|
546
563
|
|
547
564
|
release
|
@@ -553,7 +570,7 @@ module Bosh::Cli::Command
|
|
553
570
|
msg = "You are using CLI >= 0.20 with director that doesn't support " +
|
554
571
|
"package matches.\nThis will result in uploading all packages " +
|
555
572
|
"and jobs to your director.\nIt is recommended to update your " +
|
556
|
-
|
573
|
+
'director or downgrade your CLI to 0.19.6'
|
557
574
|
|
558
575
|
say(msg.make_yellow)
|
559
576
|
exit(1) unless confirmed?
|
@@ -561,13 +578,13 @@ module Bosh::Cli::Command
|
|
561
578
|
|
562
579
|
def build_releases_table_for_old_director(releases)
|
563
580
|
table do |t|
|
564
|
-
t.headings =
|
581
|
+
t.headings = 'Name', 'Versions'
|
565
582
|
releases.each do |release|
|
566
|
-
versions = release[
|
567
|
-
|
568
|
-
}.map { |v| ((release[
|
583
|
+
versions = release['versions'].sort { |v1, v2|
|
584
|
+
Bosh::Common::Version::ReleaseVersion.parse_and_compare(v1, v2)
|
585
|
+
}.map { |v| ((release['in_use'] || []).include?(v)) ? "#{v}*" : v }
|
569
586
|
|
570
|
-
t << [release[
|
587
|
+
t << [release['name'], versions.join(', ')]
|
571
588
|
end
|
572
589
|
end
|
573
590
|
end
|
@@ -578,11 +595,11 @@ module Bosh::Cli::Command
|
|
578
595
|
def build_releases_table(releases, options = {})
|
579
596
|
show_jobs = options[:jobs]
|
580
597
|
table do |t|
|
581
|
-
t.headings =
|
582
|
-
t.headings <<
|
598
|
+
t.headings = 'Name', 'Versions', 'Commit Hash'
|
599
|
+
t.headings << 'Jobs' if show_jobs
|
583
600
|
releases.each do |release|
|
584
601
|
versions, commit_hashes = formatted_versions(release).transpose
|
585
|
-
row = [release[
|
602
|
+
row = [release['name'], versions.join("\n"), commit_hashes.join("\n")]
|
586
603
|
if show_jobs
|
587
604
|
jobs = formatted_jobs(release).transpose
|
588
605
|
row << jobs.join("\n")
|
@@ -593,25 +610,25 @@ module Bosh::Cli::Command
|
|
593
610
|
end
|
594
611
|
|
595
612
|
def formatted_versions(release)
|
596
|
-
sort_versions(release[
|
613
|
+
sort_versions(release['release_versions']).map { |v| formatted_version_and_commit_hash(v) }
|
597
614
|
end
|
598
615
|
|
599
616
|
def sort_versions(versions)
|
600
|
-
versions.sort { |v1, v2|
|
617
|
+
versions.sort { |v1, v2| Bosh::Common::Version::ReleaseVersion.parse_and_compare(v1['version'], v2['version']) }
|
601
618
|
end
|
602
619
|
|
603
620
|
def formatted_version_and_commit_hash(version)
|
604
|
-
version_number = version[
|
605
|
-
commit_hash = version[
|
621
|
+
version_number = version['version'] + (version['currently_deployed'] ? '*' : '')
|
622
|
+
commit_hash = version['commit_hash'] + (version['uncommitted_changes'] ? '+' : '')
|
606
623
|
[version_number, commit_hash]
|
607
624
|
end
|
608
625
|
|
609
626
|
def formatted_jobs(release)
|
610
|
-
sort_versions(release[
|
611
|
-
if job_names = v[
|
612
|
-
[job_names.join(
|
627
|
+
sort_versions(release['release_versions']).map do |v|
|
628
|
+
if job_names = v['job_names']
|
629
|
+
[job_names.join(', ')]
|
613
630
|
else
|
614
|
-
[
|
631
|
+
['n/a '] # with enough whitespace to match "Jobs" header
|
615
632
|
end
|
616
633
|
end
|
617
634
|
end
|
@@ -622,5 +639,46 @@ module Bosh::Cli::Command
|
|
622
639
|
rescue Bosh::Exec::Error => e
|
623
640
|
'00000000'
|
624
641
|
end
|
642
|
+
|
643
|
+
def release_version_details(releases)
|
644
|
+
currently_deployed = false
|
645
|
+
uncommitted_changes = false
|
646
|
+
releases.each do |release|
|
647
|
+
release['release_versions'].each do |version|
|
648
|
+
currently_deployed ||= version['currently_deployed']
|
649
|
+
uncommitted_changes ||= version['uncommitted_changes']
|
650
|
+
if currently_deployed && uncommitted_changes
|
651
|
+
return true, true
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
return currently_deployed, uncommitted_changes
|
656
|
+
end
|
657
|
+
|
658
|
+
def release_version_details_for_old_director(releases)
|
659
|
+
currently_deployed = false
|
660
|
+
# old director did not support uncommitted changes
|
661
|
+
uncommitted_changes = false
|
662
|
+
releases.each do |release|
|
663
|
+
currently_deployed ||= release['in_use'].any?
|
664
|
+
if currently_deployed
|
665
|
+
return true, uncommitted_changes
|
666
|
+
end
|
667
|
+
end
|
668
|
+
return currently_deployed, uncommitted_changes
|
669
|
+
end
|
670
|
+
|
671
|
+
def should_convert_to_old_format?(version)
|
672
|
+
director_version = director.get_status['version']
|
673
|
+
new_format_director_version = '1.2580.0'
|
674
|
+
if Bosh::Common::Version::BoshVersion.parse(director_version) >=
|
675
|
+
Bosh::Common::Version::BoshVersion.parse(new_format_director_version)
|
676
|
+
return false
|
677
|
+
end
|
678
|
+
|
679
|
+
old_format = Bosh::Common::Version::ReleaseVersion.parse(version).to_old_format
|
680
|
+
old_format && version != old_format
|
681
|
+
end
|
682
|
+
|
625
683
|
end
|
626
684
|
end
|
@@ -3,7 +3,6 @@ require 'cli/public_stemcells'
|
|
3
3
|
|
4
4
|
module Bosh::Cli
|
5
5
|
class Command::Stemcell < Command::Base
|
6
|
-
include Bosh::Cli::VersionCalc
|
7
6
|
STEMCELL_EXISTS_ERROR_CODE = 50002
|
8
7
|
|
9
8
|
usage 'verify stemcell'
|
@@ -87,9 +86,11 @@ module Bosh::Cli
|
|
87
86
|
def list
|
88
87
|
auth_required
|
89
88
|
stemcells = director.list_stemcells.sort do |sc1, sc2|
|
90
|
-
sc1['name'] == sc2['name']
|
91
|
-
|
92
|
-
|
89
|
+
if sc1['name'] == sc2['name']
|
90
|
+
Bosh::Common::Version::StemcellVersion.parse_and_compare(sc1['version'], sc2['version'])
|
91
|
+
else
|
92
|
+
sc1['name'] <=> sc2['name']
|
93
|
+
end
|
93
94
|
end
|
94
95
|
|
95
96
|
err('No stemcells') if stemcells.empty?
|
@@ -200,7 +200,13 @@ module Bosh::Cli
|
|
200
200
|
director.list_releases.inject({}) do |hash, release|
|
201
201
|
name = release['name']
|
202
202
|
versions = release['versions'] || release['release_versions'].map { |release_version| release_version['version'] }
|
203
|
-
|
203
|
+
parsed_versions = versions.map do |version|
|
204
|
+
{
|
205
|
+
original: version,
|
206
|
+
parsed: Bosh::Common::Version::ReleaseVersion.parse(version)
|
207
|
+
}
|
208
|
+
end
|
209
|
+
latest_version = parsed_versions.sort_by {|v| v[:parsed] }.last[:original]
|
204
210
|
hash[name] = latest_version.to_s
|
205
211
|
hash
|
206
212
|
end
|
@@ -368,7 +374,7 @@ module Bosh::Cli
|
|
368
374
|
end
|
369
375
|
|
370
376
|
stemcells.inject({}) do |hash, (name, versions)|
|
371
|
-
hash[name] =
|
377
|
+
hash[name] = Bosh::Common::Version::StemcellVersion.parse_list(versions).latest.to_s
|
372
378
|
hash
|
373
379
|
end
|
374
380
|
end
|
data/lib/cli/errors.rb
CHANGED
@@ -18,33 +18,35 @@ module Bosh::Cli
|
|
18
18
|
error_code(42)
|
19
19
|
end
|
20
20
|
|
21
|
-
class UnknownCommand
|
22
|
-
class ConfigError
|
23
|
-
class DirectorMissing
|
24
|
-
class DirectorInaccessible
|
25
|
-
|
26
|
-
class DirectorError
|
27
|
-
class AuthError
|
28
|
-
class MissingTask
|
29
|
-
class TaskTrackError
|
30
|
-
class ResourceNotFound
|
31
|
-
|
32
|
-
class CliExit
|
33
|
-
class GracefulExit
|
34
|
-
|
35
|
-
class InvalidPackage
|
36
|
-
class InvalidJob
|
37
|
-
class InvalidRelease
|
38
|
-
class MissingDependency
|
39
|
-
class CircularDependency
|
40
|
-
class InvalidIndex
|
41
|
-
class BlobstoreError
|
42
|
-
class PackagingError
|
43
|
-
class UndefinedProperty
|
44
|
-
class MalformedManifest
|
45
|
-
class MissingTarget
|
46
|
-
class InvalidProperty
|
47
|
-
class InvalidManifest
|
48
|
-
class PropertyMismatch
|
21
|
+
class UnknownCommand < CliError; error_code(100); end
|
22
|
+
class ConfigError < CliError; error_code(101); end
|
23
|
+
class DirectorMissing < CliError; error_code(102); end
|
24
|
+
class DirectorInaccessible < CliError; error_code(103); end
|
25
|
+
|
26
|
+
class DirectorError < CliError; error_code(201); end
|
27
|
+
class AuthError < DirectorError; error_code(202); end
|
28
|
+
class MissingTask < DirectorError; error_code(203); end
|
29
|
+
class TaskTrackError < DirectorError; error_code(204); end
|
30
|
+
class ResourceNotFound < DirectorError; error_code(205); end
|
31
|
+
|
32
|
+
class CliExit < CliError; error_code(400); end
|
33
|
+
class GracefulExit < CliExit; error_code(401); end
|
34
|
+
|
35
|
+
class InvalidPackage < CliError; error_code(500); end
|
36
|
+
class InvalidJob < CliError; error_code(501); end
|
37
|
+
class InvalidRelease < CliError; error_code(503); end
|
38
|
+
class MissingDependency < CliError; error_code(504); end
|
39
|
+
class CircularDependency < CliError; error_code(505); end
|
40
|
+
class InvalidIndex < CliError; error_code(506); end
|
41
|
+
class BlobstoreError < CliError; error_code(507); end
|
42
|
+
class PackagingError < CliError; error_code(508); end
|
43
|
+
class UndefinedProperty < CliError; error_code(509); end
|
44
|
+
class MalformedManifest < CliError; error_code(511); end
|
45
|
+
class MissingTarget < CliError; error_code(512); end
|
46
|
+
class InvalidProperty < CliError; error_code(513); end
|
47
|
+
class InvalidManifest < CliError; error_code(514); end
|
48
|
+
class PropertyMismatch < CliError; error_code(515); end
|
49
49
|
class InvalidPropertyMapping < CliError; error_code(516); end
|
50
|
+
|
51
|
+
class ReleaseVersionError < CliError; error_code(600); end
|
50
52
|
end
|
data/lib/cli/release_builder.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
|
-
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
-
|
3
1
|
module Bosh::Cli
|
4
2
|
class ReleaseBuilder
|
5
3
|
include Bosh::Cli::DependencyHelper
|
6
|
-
include Bosh::Cli::VersionCalc
|
7
4
|
|
8
5
|
DEFAULT_RELEASE_NAME = "bosh_release"
|
9
6
|
|
@@ -20,11 +17,16 @@ module Bosh::Cli
|
|
20
17
|
@uncommitted_changes = options.fetch(:uncommitted_changes, true)
|
21
18
|
@packages = packages
|
22
19
|
@jobs = jobs
|
20
|
+
@version = options.fetch(:version, nil)
|
21
|
+
|
22
|
+
raise ReleaseVersionError.new('Version numbers cannot be specified for dev releases') if (@version && !@final)
|
23
23
|
|
24
24
|
@final_index = VersionsIndex.new(final_releases_dir, release_name)
|
25
25
|
@dev_index = VersionsIndex.new(dev_releases_dir, release_name)
|
26
26
|
@index = @final ? @final_index : @dev_index
|
27
27
|
|
28
|
+
raise ReleaseVersionError.new('Release version already exists') if (@version && @index.version_exists?(@version))
|
29
|
+
|
28
30
|
@build_dir = Dir.mktmpdir
|
29
31
|
|
30
32
|
in_build_dir do
|
@@ -41,7 +43,7 @@ module Bosh::Cli
|
|
41
43
|
|
42
44
|
# @return [String] Release version
|
43
45
|
def version
|
44
|
-
@version ||= assign_version
|
46
|
+
@version ||= assign_version.to_s
|
45
47
|
end
|
46
48
|
|
47
49
|
# @return [Boolean] Is release final?
|
@@ -145,11 +147,10 @@ module Bosh::Cli
|
|
145
147
|
say("This version is no different from version #{old_version}")
|
146
148
|
@version = old_version
|
147
149
|
else
|
148
|
-
@version
|
149
|
-
@index.add_version(fingerprint, { "version" => @version })
|
150
|
+
@index.add_version(fingerprint, { "version" => version })
|
150
151
|
end
|
151
152
|
|
152
|
-
manifest["version"] =
|
153
|
+
manifest["version"] = version
|
153
154
|
manifest_yaml = Psych.dump(manifest)
|
154
155
|
|
155
156
|
say("Writing manifest...")
|
@@ -166,7 +167,7 @@ module Bosh::Cli
|
|
166
167
|
|
167
168
|
def generate_tarball
|
168
169
|
generate_manifest unless @manifest_generated
|
169
|
-
return if @index.version_exists?(
|
170
|
+
return if @index.version_exists?(version)
|
170
171
|
|
171
172
|
unless @jobs_copied
|
172
173
|
header("Copying jobs...")
|
@@ -224,27 +225,32 @@ module Bosh::Cli
|
|
224
225
|
|
225
226
|
private
|
226
227
|
|
227
|
-
def version=(version)
|
228
|
-
@version = version
|
229
|
-
end
|
230
|
-
|
231
228
|
def assign_version
|
232
|
-
latest_final_version = @final_index.
|
233
|
-
|
229
|
+
latest_final_version = Bosh::Common::Version::ReleaseVersion.parse_list(@final_index.versions).latest
|
230
|
+
latest_final_version ||= Bosh::Common::Version::ReleaseVersion.parse('0')
|
234
231
|
|
235
232
|
if @final
|
236
|
-
|
233
|
+
# Drop pre-release and post-release segments, and increment the release segment
|
234
|
+
latest_final_version.increment_release
|
237
235
|
else
|
238
|
-
|
239
|
-
|
240
|
-
|
236
|
+
# Increment or Reset the post-release segment
|
237
|
+
dev_versions = Bosh::Common::Version::ReleaseVersion.parse_list(@dev_index.versions)
|
238
|
+
latest_dev_version = dev_versions.latest_with_pre_release(latest_final_version)
|
239
|
+
|
240
|
+
if latest_dev_version
|
241
|
+
if latest_dev_version.version.post_release.nil?
|
242
|
+
latest_dev_version.default_post_release
|
243
|
+
else
|
244
|
+
latest_dev_version.increment_post_release
|
245
|
+
end
|
246
|
+
else
|
247
|
+
latest_final_version.default_post_release
|
248
|
+
end
|
241
249
|
end
|
242
250
|
end
|
243
251
|
|
244
252
|
def in_build_dir(&block)
|
245
253
|
Dir.chdir(build_dir) { yield }
|
246
254
|
end
|
247
|
-
|
248
255
|
end
|
249
|
-
|
250
256
|
end
|
data/lib/cli/release_tarball.rb
CHANGED
@@ -30,6 +30,26 @@ module Bosh::Cli
|
|
30
30
|
File.read(File.join(@unpack_dir, "release.MF"))
|
31
31
|
end
|
32
32
|
|
33
|
+
def convert_to_old_format
|
34
|
+
step('Converting to old format',
|
35
|
+
"Cannot extract tarball #{@tarball_path}", :fatal) do
|
36
|
+
unpack
|
37
|
+
end
|
38
|
+
|
39
|
+
manifest_file = File.expand_path('release.MF', @unpack_dir)
|
40
|
+
manifest = load_yaml_file(manifest_file)
|
41
|
+
old_format_version = Bosh::Common::Version::ReleaseVersion.parse(manifest['version']).to_old_format
|
42
|
+
manifest['version'] = old_format_version
|
43
|
+
write_yaml(manifest, manifest_file)
|
44
|
+
tmpdir = Dir.mktmpdir
|
45
|
+
repacked_path = File.join(tmpdir, 'release-reformat.tgz')
|
46
|
+
|
47
|
+
Dir.chdir(@unpack_dir) do
|
48
|
+
`tar -czf #{repacked_path} . 2>&1`
|
49
|
+
return repacked_path if $? == 0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
33
53
|
# Repacks tarball according to the structure of remote release
|
34
54
|
# Return path to repackaged tarball or nil if repack has failed
|
35
55
|
def repack(package_matches = [])
|
data/lib/cli/stemcell.rb
CHANGED
@@ -23,7 +23,7 @@ module Bosh::Cli
|
|
23
23
|
tar = nil
|
24
24
|
step("Read tarball",
|
25
25
|
"Cannot read tarball #{@stemcell_file}", :fatal) do
|
26
|
-
tgz = Zlib::GzipReader.new(File.open(@stemcell_file))
|
26
|
+
tgz = Zlib::GzipReader.new(File.open(@stemcell_file,'rb'))
|
27
27
|
tar = Minitar.open(tgz)
|
28
28
|
!!tar
|
29
29
|
end
|
data/lib/cli/version.rb
CHANGED
data/lib/cli/versions_index.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Bosh::Cli
|
2
2
|
class VersionsIndex
|
3
|
-
include VersionCalc
|
4
3
|
|
5
4
|
def initialize(storage_dir, name_prefix = nil)
|
6
5
|
@storage_dir = File.expand_path(storage_dir)
|
@@ -25,26 +24,13 @@ module Bosh::Cli
|
|
25
24
|
@data["builds"][fingerprint]
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
# Return the last version from the version index file
|
30
|
-
# as jobs and packages have a non-numeric versioning
|
31
|
-
# scheme based on their fingerprint. This function relies
|
32
|
-
# on hash insertion order being preserved. While this
|
33
|
-
# is the behavior for Ruby 1.9.X and 2.X we should
|
34
|
-
# remember that this implementation is
|
35
|
-
# a little brittle.
|
36
|
-
def latest_version(major = nil)
|
27
|
+
def latest_version
|
37
28
|
builds = @data["builds"].values
|
38
29
|
|
39
|
-
if major
|
40
|
-
builds = builds.select do |build|
|
41
|
-
major_version(build["version"]) == major
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
30
|
return nil if builds.empty?
|
46
31
|
|
47
|
-
builds.
|
32
|
+
version_strings = builds.map { |b| b["version"] }
|
33
|
+
Bosh::Common::Version::ReleaseVersion.parse_list(version_strings).latest.to_s
|
48
34
|
end
|
49
35
|
|
50
36
|
def version_exists?(version)
|
@@ -91,6 +77,10 @@ module Bosh::Cli
|
|
91
77
|
File.join(@storage_dir, name)
|
92
78
|
end
|
93
79
|
|
80
|
+
def versions
|
81
|
+
@data['builds'].map { |_, build| build['version'] }
|
82
|
+
end
|
83
|
+
|
94
84
|
private
|
95
85
|
|
96
86
|
def create_directories
|
@@ -115,7 +105,6 @@ module Bosh::Cli
|
|
115
105
|
"#{data.class} given, Hash expected"
|
116
106
|
end
|
117
107
|
@data = data
|
118
|
-
@data.delete("latest_version") # Indices used to track latest versions
|
119
108
|
@data["builds"] ||= {}
|
120
109
|
end
|
121
110
|
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.
|
4
|
+
version: 1.2596.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-
|
12
|
+
date: 2014-06-07 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.
|
21
|
+
version: 1.2596.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.
|
29
|
+
version: 1.2596.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.
|
117
|
+
version: 1.2596.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.
|
125
|
+
version: 1.2596.0
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: net-ssh
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -205,7 +205,7 @@ dependencies:
|
|
205
205
|
version: 0.5.4
|
206
206
|
description: ! 'BOSH CLI
|
207
207
|
|
208
|
-
|
208
|
+
3c1470'
|
209
209
|
email: support@cloudfoundry.com
|
210
210
|
executables:
|
211
211
|
- bosh
|
@@ -292,7 +292,6 @@ files:
|
|
292
292
|
- lib/cli/task_tracking/total_duration.rb
|
293
293
|
- lib/cli/validation.rb
|
294
294
|
- lib/cli/version.rb
|
295
|
-
- lib/cli/version_calc.rb
|
296
295
|
- lib/cli/versions_index.rb
|
297
296
|
- lib/cli/vm_state.rb
|
298
297
|
- lib/cli/yaml_helper.rb
|
@@ -318,10 +317,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
318
317
|
version: '0'
|
319
318
|
segments:
|
320
319
|
- 0
|
321
|
-
hash:
|
320
|
+
hash: 1028233858032773438
|
322
321
|
requirements: []
|
323
322
|
rubyforge_project:
|
324
|
-
rubygems_version: 1.8.23
|
323
|
+
rubygems_version: 1.8.23.2
|
325
324
|
signing_key:
|
326
325
|
specification_version: 3
|
327
326
|
summary: BOSH CLI
|
data/lib/cli/version_calc.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'common/version_number'
|
2
|
-
|
3
|
-
##
|
4
|
-
# This module is in general unsafe to use as packages and jobs
|
5
|
-
# use their fingerprints as versions and therefore are not numerically
|
6
|
-
# comparable. At the moment releases retain a numerically comparable
|
7
|
-
# version which necessitates this code
|
8
|
-
module Bosh::Cli
|
9
|
-
module VersionCalc
|
10
|
-
|
11
|
-
# Returns 0 if two versions are the same,
|
12
|
-
# 1 if v1 > v2
|
13
|
-
# -1 if v1 < v2
|
14
|
-
def version_cmp(v1 = "0", v2 = "0")
|
15
|
-
Bosh::Common::VersionNumber.new(v1) <=> Bosh::Common::VersionNumber.new(v2)
|
16
|
-
end
|
17
|
-
|
18
|
-
def version_greater(v1, v2)
|
19
|
-
version_cmp(v1, v2) > 0
|
20
|
-
end
|
21
|
-
|
22
|
-
def version_less(v1, v2)
|
23
|
-
version_cmp(v1, v2) < 0
|
24
|
-
end
|
25
|
-
|
26
|
-
def version_same(v1, v2)
|
27
|
-
version_cmp(v1, v2) == 0
|
28
|
-
end
|
29
|
-
|
30
|
-
def major_version(v)
|
31
|
-
Bosh::Common::VersionNumber.new(v).major
|
32
|
-
end
|
33
|
-
|
34
|
-
def minor_version(v)
|
35
|
-
Bosh::Common::VersionNumber.new(v).minor
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|