bosh_vcloud_cpi 0.7.10 → 0.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb7cda14ebdb11a1c818ce26c463bc7fd9605bd3
4
- data.tar.gz: 7a6e5455d43ccd766749289d04592e9d61c630cd
3
+ metadata.gz: c4d97d94d84c1a9a705a9ba642388c1f47b34cf7
4
+ data.tar.gz: 34d48cd6dfe0feb24ed2e726b4787f852c50b4c8
5
5
  SHA512:
6
- metadata.gz: d644a6ecb8f31d59a23e18c11bd479233a1bd48420b449816d751c5f8d1bbf01836d8dbd12c630da58a383f75fd0af3dab8f2be2dfbb4da70365bacb9adc6998
7
- data.tar.gz: e5f5d04c699e5f7e56068be8f7c54c2add73396e8e12e77fbaffa4b1c45f446a7770b5f0c3c873345840c42730e27bb9b30472684e765e44ef4378645998bf4e
6
+ metadata.gz: 33d7e13c598313b197ee41be1979e3d86ad3de71c5584575f192708fa6b7840c5193dd98579a6b3e4e7e3a4a95a60c92cf111bbf889b1a2f76fd8ec89bb2a7be
7
+ data.tar.gz: d2d62fa77096ee532349c274d64f9e8ec3425cc34dba3771e43a55f5969b5b1d6b36b2903ebd1d211445eb96f0dd3bb52c6651b2dc119022f2de172bdba16825
@@ -29,10 +29,15 @@ module VCloudCloud
29
29
  def create_stemcell(image, _)
30
30
  (steps "create_stemcell(#{image}, _)" do |s|
31
31
  s.next Steps::StemcellInfo, image
32
- s.next Steps::CreateTemplate, "sc-#{unique_name}"
33
- s.next Steps::UploadTemplateFiles
34
- s.next Steps::AddCatalog, @client.catalog_name(:vapp)
35
- s.next Steps::AddCatalogItem, :vapp, s.state[:vapp_template]
32
+ catalog_type = :vapp
33
+ s.next Steps::AddCatalog, @client.catalog_name(catalog_type)
34
+ s.next Steps::CreateTemplate, "sc-#{unique_name}", catalog_type
35
+
36
+ # Retry upload template file in case of timeout
37
+ errors = [Timeout::Error]
38
+ Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: cpi_retries, on: errors) do |tries, error|
39
+ s.next Steps::UploadTemplateFiles
40
+ end
36
41
  end)[:catalog_item].urn
37
42
  end
38
43
 
@@ -60,6 +65,10 @@ module VCloudCloud
60
65
  2
61
66
  end
62
67
 
68
+ def cpi_retries
69
+ 10
70
+ end
71
+
63
72
  def create_vm(agent_id, catalog_vapp_id, resource_pool, networks, disk_locality = nil, environment = nil)
64
73
  (steps "create_vm(#{agent_id}, #{catalog_vapp_id}, #{resource_pool}, ...)" do |s|
65
74
  # disk_locality should be an array of disk ids
@@ -92,7 +101,7 @@ module VCloudCloud
92
101
  container_vapp = nil
93
102
 
94
103
  errors = [RuntimeError]
95
- Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: 10, on: errors) do
104
+ Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: cpi_retries, on: errors) do |tries, error|
96
105
  begin
97
106
  begin
98
107
  @logger.debug "Requesting container vApp: #{requested_name}"
@@ -152,7 +161,7 @@ module VCloudCloud
152
161
  # TODO refact this
153
162
  if requested_name
154
163
  errors = [RuntimeError]
155
- Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: 20, on: errors) do
164
+ Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: cpi_retries, on: errors) do |tries, error|
156
165
  begin
157
166
  save_agent_env s
158
167
  s.next Steps::PowerOn, :vm
@@ -177,7 +186,7 @@ module VCloudCloud
177
186
  vm = s.state[:vm] = client.resolve_entity(vm_id)
178
187
 
179
188
  errors = [RuntimeError]
180
- Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: 20, on: errors) do
189
+ Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: cpi_retries, on: errors) do |tries, error|
181
190
  begin
182
191
  if vm['status'] == VCloudSdk::Xml::RESOURCE_ENTITY_STATUS[:SUSPENDED].to_s
183
192
  s.next Steps::DiscardSuspendedState, :vm
@@ -219,18 +228,8 @@ module VCloudCloud
219
228
 
220
229
  # poweroff vm before we are able to delete it
221
230
  s.next Steps::PowerOff, :vm, true
222
-
223
- vapp = s.state[:vapp] = client.resolve_link vm.container_vapp_link
224
- if vapp.vms.size == 1
225
- # Hack: if vApp is running, and the last VM is deleted, it is no longer stoppable and removable
226
- # even from dashboard. So if there's only one VM, just stop and delete the vApp
227
- s.next Steps::PowerOff, :vapp, true
228
- s.next Steps::Undeploy, :vapp
229
- s.next Steps::Delete, s.state[:vapp], true
230
- else
231
- s.next Steps::Undeploy, :vm
232
- s.next Steps::Delete, s.state[:vm], true
233
- end
231
+ s.next Steps::Undeploy, :vm
232
+ s.next Steps::Delete, s.state[:vm], true
234
233
 
235
234
  s.next Steps::DeleteCatalogMedia, vm.name
236
235
  rescue RestClient::Forbidden, ObjectNotFoundError => e
@@ -264,7 +263,7 @@ module VCloudCloud
264
263
  s.state[:disk] = client.resolve_entity disk_id
265
264
 
266
265
  errors = [RuntimeError]
267
- Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: 20, on: errors) do
266
+ Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: cpi_retries, on: errors) do |tries, error|
268
267
  begin
269
268
  s.next Steps::AttachDetachDisk, :attach
270
269
 
@@ -293,7 +292,7 @@ module VCloudCloud
293
292
  next unless vm.find_attached_disk s.state[:disk]
294
293
 
295
294
  errors = [RuntimeError]
296
- Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: 20, on: errors) do
295
+ Bosh::Common.retryable(sleep: cpi_call_wait_time, tries: cpi_retries, on: errors) do |tries, error|
297
296
  begin
298
297
  if vm['status'] == VCloudSdk::Xml::RESOURCE_ENTITY_STATUS[:SUSPENDED].to_s
299
298
  s.next Steps::DiscardSuspendedState, :vm
@@ -1,7 +1,7 @@
1
1
  module VCloudCloud
2
2
  module Steps
3
3
  class CreateDisk < Step
4
- def perform(name, size_mb, vm, storage_profile, &block)
4
+ def perform(name, size_mb, vm, storage_profile, &_block)
5
5
  params = VCloudSdk::Xml::WrapperFactory.create_instance 'DiskCreateParams'
6
6
  params.name = name
7
7
  params.size_bytes = size_mb << 20 # VCD expects bytes
@@ -1,12 +1,23 @@
1
1
  module VCloudCloud
2
2
  module Steps
3
3
  class CreateTemplate < Step
4
- def perform(name, &block)
4
+ def perform(name, catalog_type, &block)
5
+ catalog = client.catalog catalog_type
6
+
5
7
  params = VCloudSdk::Xml::WrapperFactory.create_instance 'UploadVAppTemplateParams'
6
8
  params.name = name
7
- template = client.invoke :post, client.vdc.upload_link, :payload => params
9
+ upload_link = catalog.add_vapp_template_link
10
+ catalog_item = client.invoke(
11
+ :post,
12
+ upload_link,
13
+ :payload => params,
14
+ :headers => {:content_type => upload_link.type}
15
+ )
16
+
17
+ template = client.invoke :get, catalog_item.entity.href
8
18
 
9
19
  # commit states
20
+ state[:catalog_item] = catalog_item
10
21
  state[:vapp_template] = template
11
22
  end
12
23
 
@@ -21,6 +21,31 @@ module VCloudCloud
21
21
  end
22
22
  state[:vm] = client.reload vm
23
23
  end
24
+
25
+ def rollback
26
+ vm = state[:vm]
27
+ name = vm.name
28
+
29
+ catalog_media = client.catalog_item :media, name, VCloudSdk::Xml::MEDIA_TYPE[:MEDIA]
30
+ # return if doesn't exist
31
+ return unless catalog_media
32
+ media = client.resolve_link catalog_media.entity
33
+ params = VCloudSdk::Xml::WrapperFactory.create_instance 'MediaInsertOrEjectParams'
34
+ params.media_href = media.href
35
+ vm = state[:vm]
36
+ client.timed_loop do
37
+ media = client.reload media
38
+ vm = client.reload vm
39
+ if media.running_tasks.empty?
40
+ client.invoke_and_wait :post, vm.eject_media_link,
41
+ :payload => params,
42
+ :headers => { :content_type => VCloudSdk::Xml::MEDIA_TYPE[:MEDIA_INSERT_EJECT_PARAMS] }
43
+ break
44
+ else
45
+ media = client.wait_entity media
46
+ end
47
+ end
48
+ end
24
49
  end
25
50
  end
26
51
  end
@@ -16,9 +16,11 @@ module VCloudCloud
16
16
  env_path = File.join tmpdir, 'env'
17
17
  iso_path = File.join tmpdir, 'env.iso'
18
18
  File.open(env_path, 'w') { |f| f.write env_json }
19
- output = `#{genisoimage} -o #{iso_path} #{env_path} 2>&1`
20
- @logger.debug "GENISOIMAGE #{output}"
21
- raise "genisoimage: #{$?.exitstatus}: #{output}" unless $?.success?
19
+ command = "#{create_iso_cmd} -o #{iso_path} #{env_path} 2>&1"
20
+ output = `#{command}`
21
+ message = "command `#{command}`: exited with stats: `#{$?.exitstatus}`: and output `#{output}`"
22
+ @logger.debug message
23
+ raise message unless $?.success?
22
24
 
23
25
  metadata = VCloudSdk::Xml::WrapperFactory.create_instance 'MetadataValue'
24
26
  metadata.value = env_json
@@ -35,8 +37,13 @@ module VCloudCloud
35
37
 
36
38
  private
37
39
 
38
- def genisoimage # TODO: this should exist in bosh_common, eventually
39
- @genisoimage ||= Bosh::Common.which(%w{genisoimage mkisofs})
40
+ def create_iso_cmd # TODO: this should exist in bosh_common, eventually
41
+ @create_iso_cmd ||= begin
42
+ possibilities = %w{genisoimage mkisofs}
43
+ cmd = Bosh::Common.which(possibilities)
44
+ raise("Unable to find a iso creation utility `#{possibilities.inspect}`") unless cmd
45
+ cmd
46
+ end
40
47
  end
41
48
  end
42
49
  end
@@ -12,7 +12,7 @@ module VCloudCloud
12
12
  class VCloudClient
13
13
  attr_reader :logger
14
14
 
15
- VCLOUD_VERSION_NUMBER = '5.1'
15
+ VCLOUD_VERSION_NUMBER = '5.5'
16
16
 
17
17
  def initialize(vcd_settings, logger)
18
18
  @logger = logger
@@ -144,7 +144,7 @@ module VCloudCloud
144
144
  return task if status == VCloudSdk::Xml::TASK_STATUS[:SUCCESS]
145
145
  if [:ABORTED, :ERROR, :CANCELED].any? { |s| status == VCloudSdk::Xml::TASK_STATUS[s] }
146
146
  return task if accept_failure
147
- raise "Task #{task.urn} #{task.operation} completed unsuccessfully"
147
+ raise "Task #{task.urn} #{task.operation} completed unsuccessfully, Details:#{task.details}"
148
148
  end
149
149
  end
150
150
  task
@@ -164,12 +164,14 @@ module VCloudCloud
164
164
  entity = reload entity
165
165
 
166
166
  # verify all tasks succeeded
167
- unless accept_failure || entity.tasks.nil? || entity.tasks.empty?
167
+ unless entity.tasks.nil? || entity.tasks.empty?
168
168
  failed_tasks = entity.tasks.find_all { |task| task.status.downcase != VCloudSdk::Xml::TASK_STATUS[:SUCCESS] }
169
169
  unless failed_tasks.empty?
170
- @logger.error "Failed tasks: #{failed_tasks}"
171
- failed_tasks_info = failed_tasks.map {|t| "Task #{t.urn} #{t.operation}"}
172
- raise "Some tasks failed: #{failed_tasks_info.join('; ')}"
170
+ @logger.debug "Failed tasks: #{failed_tasks}"
171
+ unless accept_failure
172
+ failed_tasks_info = failed_tasks.map { |t| "Task #{t.urn} #{t.operation}, Details:#{t.details}" }
173
+ raise "Some tasks failed: #{failed_tasks_info.join('; ')}"
174
+ end
173
175
  end
174
176
  end
175
177
 
@@ -247,13 +249,14 @@ module VCloudCloud
247
249
  params = {
248
250
  :method => method,
249
251
  :url => if path.start_with?('/')
250
- @url + path
251
- else
252
- path
253
- end,
252
+ @url + path
253
+ else
254
+ path
255
+ end,
254
256
  :headers => {
255
- :Accept => "application/*+xml;version=#{VCLOUD_VERSION_NUMBER}",
256
- :content_type => '*/*'
257
+ :Accept => "application/*+xml;version=#{VCLOUD_VERSION_NUMBER}",
258
+ :content_type => '*/*',
259
+ 'X-VMWARE-VCLOUD-CLIENT-REQUEST-ID' => SecureRandom.uuid
257
260
  }
258
261
  }
259
262
  params[:headers][:x_vcloud_authorization] = @auth_token if !options[:login] && @auth_token
@@ -280,11 +283,20 @@ module VCloudCloud
280
283
  def session
281
284
  unless cookie_available?
282
285
  auth = "#{@user}@#{@entities['organization']}:#{@pass}"
283
- auth_header = "Basic #{Base64.encode64(auth)}"
284
- response = send_request :post, login_url,
285
- :headers => { :Authorization => auth_header, :content_type => 'application/x-www-form-urlencoded' },
286
- :payload => URI.encode_www_form({ :Authorization => auth_header, :Accept => "application/*+xml;version=#{VCLOUD_VERSION_NUMBER}" }),
287
- :with_response => true
286
+ auth_header = "Basic #{Base64.strict_encode64(auth)}"
287
+ response = send_request(
288
+ :post,
289
+ login_url,
290
+ :headers => {
291
+ :Authorization => auth_header,
292
+ :content_type => 'application/x-www-form-urlencoded'
293
+ },
294
+ :payload => URI.encode_www_form({
295
+ :Authorization => auth_header,
296
+ :Accept => "application/*+xml;version=#{VCLOUD_VERSION_NUMBER}"
297
+ }),
298
+ :with_response => true
299
+ )
288
300
 
289
301
  @auth_token = response.headers[:x_vcloud_authorization]
290
302
  @cookie = response.cookies
@@ -1,9 +1,7 @@
1
1
  module Bosh
2
2
  module Clouds
3
-
4
3
  class VCloud
5
- VERSION = '0.5.5'
4
+ VERSION = '0.9.0'
6
5
  end
7
-
8
6
  end
9
7
  end
@@ -35,8 +35,7 @@ module VCloudSdk
35
35
  end
36
36
  end
37
37
 
38
- def create_instance(type_name, ns = nil, namespace_defintions = nil,
39
- *args)
38
+ def create_instance(type_name, ns = nil, namespace_defintions = nil, *args)
40
39
  xml = @@xml_dictionary[type_name]
41
40
  if (xml)
42
41
  wrap_document(xml, ns, namespace_defintions, *args)
@@ -7,6 +7,11 @@ module VCloudSdk
7
7
  "rel"=>"add"}).first
8
8
  end
9
9
 
10
+ def add_vapp_template_link
11
+ get_nodes("Link", {"type" => MEDIA_TYPE[:UPLOAD_VAPP_TEMPLATE_PARAMS],
12
+ "rel"=>"add"}).first
13
+ end
14
+
10
15
  def catalog_items(name = nil)
11
16
  if name
12
17
  get_nodes("CatalogItem", {"name" => name})
@@ -15,6 +15,12 @@ module VCloudSdk
15
15
  self["operation"]
16
16
  end
17
17
 
18
+ def details
19
+ details = get_nodes("Details")
20
+ return nil if details.nil?
21
+ return details.collect {|d| d.content}.join
22
+ end
23
+
18
24
  # Short form name of the operation
19
25
  def operation_name
20
26
  self["operationName"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_vcloud_cpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.10
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2015-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bosh_common
@@ -124,7 +124,7 @@ dependencies:
124
124
  version: '0'
125
125
  description: |-
126
126
  BOSH vCloud CPI
127
- dc1c42
127
+ b1e960
128
128
  email: support@cloudfoundry.com
129
129
  executables: []
130
130
  extensions: []