bosh_cli 1.5.0.pre.1332 → 1.5.0.pre.1333
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/commands/stemcell.rb +57 -59
- data/lib/cli/download_with_progress.rb +36 -0
- data/lib/cli/public_stemcell.rb +34 -0
- data/lib/cli/public_stemcell_index.rb +41 -0
- data/lib/cli/public_stemcell_presenter.rb +49 -0
- data/lib/cli/version.rb +1 -1
- metadata +10 -6
@@ -1,121 +1,119 @@
|
|
1
|
-
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
-
|
3
1
|
module Bosh::Cli::Command
|
4
2
|
class Stemcell < Base
|
5
3
|
include Bosh::Cli::VersionCalc
|
6
4
|
|
7
5
|
# The filename of the public stemcell index.
|
8
|
-
PUBLIC_STEMCELL_INDEX =
|
6
|
+
PUBLIC_STEMCELL_INDEX = 'public_stemcells_index.yml'
|
9
7
|
|
10
8
|
# The URL of the public stemcell index.
|
11
9
|
PUBLIC_STEMCELL_INDEX_URL =
|
12
|
-
|
10
|
+
'https://s3.amazonaws.com/blob.cfblob.com/stemcells/public_stemcells_index.yml'
|
13
11
|
|
14
|
-
DEFAULT_PUB_STEMCELL_TAG =
|
15
|
-
ALL_STEMCELLS_TAG =
|
12
|
+
DEFAULT_PUB_STEMCELL_TAG = 'stable'
|
13
|
+
ALL_STEMCELLS_TAG = 'all'
|
16
14
|
|
17
|
-
usage
|
18
|
-
desc
|
15
|
+
usage 'verify stemcell'
|
16
|
+
desc 'Verify stemcell'
|
19
17
|
def verify(tarball_path)
|
20
18
|
stemcell = Bosh::Cli::Stemcell.new(tarball_path)
|
21
19
|
|
22
20
|
nl
|
23
|
-
say(
|
21
|
+
say('Verifying stemcell...')
|
24
22
|
stemcell.validate
|
25
23
|
nl
|
26
24
|
|
27
25
|
if stemcell.valid?
|
28
26
|
say("`#{tarball_path}' is a valid stemcell".make_green)
|
29
27
|
else
|
30
|
-
say(
|
28
|
+
say('Validation errors:'.make_red)
|
31
29
|
stemcell.errors.each do |error|
|
32
|
-
say(
|
30
|
+
say('- %s' % [error])
|
33
31
|
end
|
34
32
|
err("`#{tarball_path}' is not a valid stemcell")
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
36
|
# bosh upload stemcell
|
39
|
-
usage
|
40
|
-
desc
|
37
|
+
usage 'upload stemcell'
|
38
|
+
desc 'Upload stemcell (stemcell_location can be a local file or a remote URI)'
|
41
39
|
def upload(stemcell_location)
|
42
40
|
auth_required
|
43
41
|
|
44
|
-
stemcell_type = stemcell_location =~ /^#{URI::regexp}$/ ?
|
45
|
-
if stemcell_type ==
|
42
|
+
stemcell_type = stemcell_location =~ /^#{URI::regexp}$/ ? 'remote' : 'local'
|
43
|
+
if stemcell_type == 'local'
|
46
44
|
stemcell = Bosh::Cli::Stemcell.new(stemcell_location)
|
47
45
|
|
48
46
|
nl
|
49
|
-
say(
|
47
|
+
say('Verifying stemcell...')
|
50
48
|
stemcell.validate
|
51
49
|
nl
|
52
50
|
|
53
51
|
unless stemcell.valid?
|
54
|
-
err(
|
52
|
+
err('Stemcell is invalid, please fix, verify and upload again')
|
55
53
|
end
|
56
|
-
|
57
|
-
say(
|
58
|
-
name = stemcell.manifest[
|
59
|
-
version = stemcell.manifest[
|
54
|
+
|
55
|
+
say('Checking if stemcell already exists...')
|
56
|
+
name = stemcell.manifest['name']
|
57
|
+
version = stemcell.manifest['version']
|
60
58
|
|
61
59
|
if exists?(name, version)
|
62
60
|
err("Stemcell `#{name}/#{version}' already exists, " +
|
63
|
-
|
61
|
+
'increment the version if it has changed')
|
64
62
|
else
|
65
|
-
say(
|
63
|
+
say('No')
|
66
64
|
end
|
67
65
|
|
68
66
|
stemcell_location = stemcell.stemcell_file
|
69
67
|
|
70
68
|
nl
|
71
|
-
say(
|
69
|
+
say('Uploading stemcell...')
|
72
70
|
nl
|
73
71
|
else
|
74
72
|
nl
|
75
73
|
say("Using remote stemcell `#{stemcell_location}'")
|
76
74
|
end
|
77
75
|
|
78
|
-
if stemcell_type ==
|
76
|
+
if stemcell_type == 'local'
|
79
77
|
status, task_id = director.upload_stemcell(stemcell_location)
|
80
78
|
else
|
81
79
|
status, task_id = director.upload_remote_stemcell(stemcell_location)
|
82
80
|
end
|
83
81
|
|
84
|
-
task_report(status, task_id,
|
82
|
+
task_report(status, task_id, 'Stemcell uploaded and created')
|
85
83
|
end
|
86
84
|
|
87
85
|
# bosh stemcells
|
88
|
-
usage
|
89
|
-
desc
|
86
|
+
usage 'stemcells'
|
87
|
+
desc 'Show the list of available stemcells'
|
90
88
|
def list
|
91
89
|
auth_required
|
92
90
|
stemcells = director.list_stemcells.sort do |sc1, sc2|
|
93
|
-
sc1[
|
94
|
-
version_cmp(sc1[
|
95
|
-
sc1[
|
91
|
+
sc1['name'] == sc2['name'] ?
|
92
|
+
version_cmp(sc1['version'], sc2['version']) :
|
93
|
+
sc1['name'] <=> sc2['name']
|
96
94
|
end
|
97
95
|
|
98
|
-
err(
|
96
|
+
err('No stemcells') if stemcells.empty?
|
99
97
|
|
100
98
|
stemcells_table = table do |t|
|
101
|
-
t.headings =
|
99
|
+
t.headings = 'Name', 'Version', 'CID'
|
102
100
|
stemcells.each do |sc|
|
103
|
-
t << [sc[
|
101
|
+
t << [sc['name'], sc['version'], sc['cid']]
|
104
102
|
end
|
105
103
|
end
|
106
104
|
|
107
105
|
nl
|
108
106
|
say(stemcells_table)
|
109
107
|
nl
|
110
|
-
say(
|
108
|
+
say('Stemcells total: %d' % stemcells.size)
|
111
109
|
end
|
112
110
|
|
113
111
|
# Prints out the publicly available stemcells.
|
114
|
-
usage
|
115
|
-
desc
|
116
|
-
option
|
117
|
-
option
|
118
|
-
option
|
112
|
+
usage 'public stemcells'
|
113
|
+
desc 'Show the list of publicly available stemcells for download.'
|
114
|
+
option '--full', 'show the full download url'
|
115
|
+
option '--tags tag1,tag2...', Array, 'filter by tag'
|
116
|
+
option '--all', 'show all stemcells'
|
119
117
|
def list_public
|
120
118
|
full = !!options[:full]
|
121
119
|
tags = options[:tags] || [DEFAULT_PUB_STEMCELL_TAG]
|
@@ -123,14 +121,14 @@ module Bosh::Cli::Command
|
|
123
121
|
|
124
122
|
yaml = get_public_stemcell_list
|
125
123
|
stemcells_table = table do |t|
|
126
|
-
t.headings = full ? [
|
124
|
+
t.headings = full ? ['Name', 'Url', 'Tags'] : ['Name', 'Tags']
|
127
125
|
yaml.keys.sort.each do |key|
|
128
126
|
if key != PUBLIC_STEMCELL_INDEX
|
129
|
-
url = yaml[key][
|
130
|
-
yaml_tags = yaml[key][
|
127
|
+
url = yaml[key]['url']
|
128
|
+
yaml_tags = yaml[key]['tags']
|
131
129
|
next if skip_this_tag?(yaml_tags, tags)
|
132
130
|
|
133
|
-
yaml_tags = yaml_tags ? yaml_tags.join(
|
131
|
+
yaml_tags = yaml_tags ? yaml_tags.join(', ') : ''
|
134
132
|
t << (full ? [key, url, yaml_tags] : [key, yaml_tags])
|
135
133
|
end
|
136
134
|
end
|
@@ -139,12 +137,12 @@ module Bosh::Cli::Command
|
|
139
137
|
say(stemcells_table)
|
140
138
|
|
141
139
|
say("To download use `bosh download public stemcell <stemcell_name>'. " +
|
142
|
-
|
140
|
+
'For full url use --full.')
|
143
141
|
end
|
144
142
|
|
145
143
|
# Downloads one of the publicly available stemcells.
|
146
|
-
usage
|
147
|
-
desc
|
144
|
+
usage 'download public stemcell'
|
145
|
+
desc 'Downloads a stemcell from the public blobstore'
|
148
146
|
# @param [String] stemcell_name The name of the stemcell, as seen in the
|
149
147
|
# public stemcell index file.
|
150
148
|
def download_public(stemcell_name)
|
@@ -152,7 +150,7 @@ module Bosh::Cli::Command
|
|
152
150
|
yaml.delete(PUBLIC_STEMCELL_INDEX) if yaml.has_key?(PUBLIC_STEMCELL_INDEX)
|
153
151
|
|
154
152
|
unless yaml.has_key?(stemcell_name)
|
155
|
-
available_stemcells = yaml.map { |k| k }.join(
|
153
|
+
available_stemcells = yaml.map { |k| k }.join(', ')
|
156
154
|
err("'#{stemcell_name}' not found in '#{available_stemcells}'.")
|
157
155
|
end
|
158
156
|
|
@@ -161,13 +159,13 @@ module Bosh::Cli::Command
|
|
161
159
|
err("File `#{stemcell_name}' already exists")
|
162
160
|
end
|
163
161
|
|
164
|
-
url = yaml[stemcell_name][
|
165
|
-
size = yaml[stemcell_name][
|
166
|
-
sha1 = yaml[stemcell_name][
|
162
|
+
url = yaml[stemcell_name]['url']
|
163
|
+
size = yaml[stemcell_name]['size']
|
164
|
+
sha1 = yaml[stemcell_name]['sha']
|
167
165
|
progress_bar = ProgressBar.new(stemcell_name, size)
|
168
166
|
progress_bar.file_transfer_mode
|
169
167
|
|
170
|
-
File.open("#{stemcell_name}",
|
168
|
+
File.open("#{stemcell_name}", 'w') do |file|
|
171
169
|
@http_client.get(url) do |chunk|
|
172
170
|
file.write(chunk)
|
173
171
|
progress_bar.inc(chunk.size)
|
@@ -180,19 +178,19 @@ module Bosh::Cli::Command
|
|
180
178
|
err("The downloaded file sha1 `#{file_sha1}' does not match the " +
|
181
179
|
"expected sha1 `#{sha1}'")
|
182
180
|
else
|
183
|
-
say(
|
181
|
+
say('Download complete'.make_green)
|
184
182
|
end
|
185
183
|
end
|
186
184
|
|
187
185
|
# bosh delete stemcell
|
188
|
-
usage
|
189
|
-
desc
|
190
|
-
option
|
186
|
+
usage 'delete stemcell'
|
187
|
+
desc 'Delete stemcell'
|
188
|
+
option '--force', 'ignore errors while deleting the stemcell'
|
191
189
|
def delete(name, version)
|
192
190
|
auth_required
|
193
191
|
force = !!options[:force]
|
194
192
|
|
195
|
-
say(
|
193
|
+
say('Checking if stemcell exists...')
|
196
194
|
|
197
195
|
unless exists?(name, version)
|
198
196
|
err("Stemcell `#{name}/#{version}' does not exist")
|
@@ -201,7 +199,7 @@ module Bosh::Cli::Command
|
|
201
199
|
say("You are going to delete stemcell `#{name}/#{version}'".make_red)
|
202
200
|
|
203
201
|
unless confirmed?
|
204
|
-
say(
|
202
|
+
say('Canceled deleting stemcell'.make_green)
|
205
203
|
return
|
206
204
|
end
|
207
205
|
|
@@ -229,7 +227,7 @@ module Bosh::Cli::Command
|
|
229
227
|
|
230
228
|
def exists?(name, version)
|
231
229
|
existing = director.list_stemcells.select do |sc|
|
232
|
-
sc[
|
230
|
+
sc['name'] == name && sc['version'] == version
|
233
231
|
end
|
234
232
|
|
235
233
|
!existing.empty?
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Bosh::Cli
|
2
|
+
class DownloadWithProgress
|
3
|
+
def initialize(url, size)
|
4
|
+
@url = url
|
5
|
+
@size = size
|
6
|
+
@filename = File.basename(@url)
|
7
|
+
end
|
8
|
+
|
9
|
+
def perform
|
10
|
+
progress_bar = ProgressBar.new(@filename, @size)
|
11
|
+
progress_bar.file_transfer_mode
|
12
|
+
download_in_chunks { |chunk| progress_bar.inc(chunk.size) }
|
13
|
+
progress_bar.finish
|
14
|
+
end
|
15
|
+
|
16
|
+
def sha1?(sha1)
|
17
|
+
self.sha1 == sha1
|
18
|
+
end
|
19
|
+
|
20
|
+
def sha1
|
21
|
+
Digest::SHA1.file(@filename).hexdigest
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def download_in_chunks
|
27
|
+
File.open(@filename, 'w') do |file|
|
28
|
+
http_client = HTTPClient.new
|
29
|
+
http_client.get(@url) do |chunk|
|
30
|
+
file.write(chunk)
|
31
|
+
yield chunk
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Bosh::Cli
|
2
|
+
class PublicStemcell
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def initialize(name, properties)
|
6
|
+
@name = name
|
7
|
+
@properties = properties
|
8
|
+
end
|
9
|
+
|
10
|
+
def url
|
11
|
+
@properties['url']
|
12
|
+
end
|
13
|
+
|
14
|
+
def size
|
15
|
+
@properties['size']
|
16
|
+
end
|
17
|
+
|
18
|
+
def sha1
|
19
|
+
@properties['sha1']
|
20
|
+
end
|
21
|
+
|
22
|
+
def tags
|
23
|
+
@properties['tags']
|
24
|
+
end
|
25
|
+
|
26
|
+
def tag_names
|
27
|
+
tags ? tags.join(', ') : ''
|
28
|
+
end
|
29
|
+
|
30
|
+
def tagged?(requested_tags)
|
31
|
+
tags.nil? || (requested_tags - tags).empty?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'cli/public_stemcell'
|
2
|
+
|
3
|
+
module Bosh::Cli
|
4
|
+
class PublicStemcellIndex
|
5
|
+
def self.download(ui)
|
6
|
+
index_url = 'https://s3.amazonaws.com/blob.cfblob.com/stemcells/public_stemcells_index.yml'
|
7
|
+
|
8
|
+
http_client = HTTPClient.new
|
9
|
+
response = http_client.get(index_url)
|
10
|
+
status_code = response.http_header.status_code
|
11
|
+
|
12
|
+
if status_code == HTTP::Status::OK
|
13
|
+
index = Psych.load(response.body)
|
14
|
+
index.delete('public_stemcells_index.yml') if index.has_key?('public_stemcells_index.yml')
|
15
|
+
new(index)
|
16
|
+
else
|
17
|
+
ui.err("Received HTTP #{status_code} from #{index_url}.")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(index)
|
22
|
+
@index = index
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_stemcell?(stemcell_name)
|
26
|
+
@index.has_key?(stemcell_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def names
|
30
|
+
@index.keys.sort
|
31
|
+
end
|
32
|
+
|
33
|
+
def find(stemcell_name)
|
34
|
+
PublicStemcell.new(stemcell_name, @index[stemcell_name])
|
35
|
+
end
|
36
|
+
|
37
|
+
def each
|
38
|
+
names.map { |stemcell_name| yield find(stemcell_name) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'cli/public_stemcell_index'
|
2
|
+
require 'cli/download_with_progress'
|
3
|
+
|
4
|
+
module Bosh::Cli
|
5
|
+
class PublicStemcellPresenter
|
6
|
+
def initialize(ui)
|
7
|
+
@ui = ui
|
8
|
+
@public_stemcell_index = PublicStemcellIndex.download(@ui)
|
9
|
+
end
|
10
|
+
|
11
|
+
def list(options)
|
12
|
+
full = !!options[:full]
|
13
|
+
requested_tags = options[:tags] || %w(stable)
|
14
|
+
|
15
|
+
stemcells_table = @ui.table do |t|
|
16
|
+
t.headings = full ? %w(Name Url Tags) : %w(Name Tags)
|
17
|
+
|
18
|
+
@public_stemcell_index.each do |stemcell|
|
19
|
+
if options[:all] || stemcell.tagged?(requested_tags)
|
20
|
+
t << (full ? [stemcell.name, stemcell.url, stemcell.tag_names] : [stemcell.name, stemcell.tag_names])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@ui.say(stemcells_table.render)
|
26
|
+
@ui.say("To download use `bosh download public stemcell <stemcell_name>'. For full url use --full.")
|
27
|
+
end
|
28
|
+
|
29
|
+
def download(stemcell_name)
|
30
|
+
unless @public_stemcell_index.has_stemcell?(stemcell_name)
|
31
|
+
@ui.err("'#{stemcell_name}' not found in '#{@public_stemcell_index.names.join(',')}'.")
|
32
|
+
end
|
33
|
+
|
34
|
+
if File.exists?(stemcell_name) && !@ui.confirmed?("Overwrite existing file `#{stemcell_name}'?")
|
35
|
+
@ui.err("File `#{stemcell_name}' already exists")
|
36
|
+
end
|
37
|
+
|
38
|
+
stemcell = @public_stemcell_index.find(stemcell_name)
|
39
|
+
download_with_progress = DownloadWithProgress.new(stemcell.size, stemcell.url)
|
40
|
+
download_with_progress.perform
|
41
|
+
|
42
|
+
if download_with_progress.sha1?(stemcell.sha1)
|
43
|
+
@ui.say('Download complete'.make_green)
|
44
|
+
else
|
45
|
+
@ui.err("The downloaded file sha1 `#{download_with_progress.sha1}' does not match the expected sha1 `#{stemcell.sha1}'")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/cli/version.rb
CHANGED
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.5.0.pre.
|
4
|
+
version: 1.5.0.pre.1333
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.5.0.pre.
|
21
|
+
version: 1.5.0.pre.1333
|
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.5.0.pre.
|
29
|
+
version: 1.5.0.pre.1333
|
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.5.0.pre.
|
117
|
+
version: 1.5.0.pre.1333
|
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.5.0.pre.
|
125
|
+
version: 1.5.0.pre.1333
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: net-ssh
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,7 +221,7 @@ dependencies:
|
|
221
221
|
version: '0'
|
222
222
|
description: ! 'BOSH CLI
|
223
223
|
|
224
|
-
|
224
|
+
063aca'
|
225
225
|
email: support@cloudfoundry.com
|
226
226
|
executables:
|
227
227
|
- bosh
|
@@ -270,6 +270,7 @@ files:
|
|
270
270
|
- lib/cli/deployment_manifest.rb
|
271
271
|
- lib/cli/deployment_manifest_compiler.rb
|
272
272
|
- lib/cli/director_task.rb
|
273
|
+
- lib/cli/download_with_progress.rb
|
273
274
|
- lib/cli/errors.rb
|
274
275
|
- lib/cli/event_log_renderer.rb
|
275
276
|
- lib/cli/file_with_progress_bar.rb
|
@@ -283,6 +284,9 @@ files:
|
|
283
284
|
- lib/cli/null_renderer.rb
|
284
285
|
- lib/cli/package_builder.rb
|
285
286
|
- lib/cli/packaging_helper.rb
|
287
|
+
- lib/cli/public_stemcell.rb
|
288
|
+
- lib/cli/public_stemcell_index.rb
|
289
|
+
- lib/cli/public_stemcell_presenter.rb
|
286
290
|
- lib/cli/release.rb
|
287
291
|
- lib/cli/release_builder.rb
|
288
292
|
- lib/cli/release_compiler.rb
|