bosh_cli 1.2579.0 → 1.2596.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|