vagrant-vcloud 0.1.2 → 0.2.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 +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +34 -0
- data/README.md +19 -2
- data/Rakefile +1 -1
- data/lib/vagrant-vcloud.rb +11 -13
- data/lib/vagrant-vcloud/action.rb +74 -47
- data/lib/vagrant-vcloud/action/announce_ssh_exec.rb +4 -2
- data/lib/vagrant-vcloud/action/build_vapp.rb +134 -110
- data/lib/vagrant-vcloud/action/connect_vcloud.rb +31 -42
- data/lib/vagrant-vcloud/action/destroy.rb +34 -29
- data/lib/vagrant-vcloud/action/disconnect_vcloud.rb +7 -5
- data/lib/vagrant-vcloud/action/forward_ports.rb +42 -35
- data/lib/vagrant-vcloud/action/handle_nat_port_collisions.rb +26 -22
- data/lib/vagrant-vcloud/action/inventory_check.rb +79 -52
- data/lib/vagrant-vcloud/action/is_bridged.rb +30 -0
- data/lib/vagrant-vcloud/action/is_created.rb +13 -14
- data/lib/vagrant-vcloud/action/is_paused.rb +0 -2
- data/lib/vagrant-vcloud/action/is_running.rb +0 -2
- data/lib/vagrant-vcloud/action/message_already_running.rb +1 -1
- data/lib/vagrant-vcloud/action/message_cannot_suspend.rb +1 -1
- data/lib/vagrant-vcloud/action/message_not_created.rb +1 -1
- data/lib/vagrant-vcloud/action/message_will_not_destroy.rb +6 -1
- data/lib/vagrant-vcloud/action/power_off.rb +16 -21
- data/lib/vagrant-vcloud/action/power_on.rb +64 -28
- data/lib/vagrant-vcloud/action/read_ssh_info.rb +44 -28
- data/lib/vagrant-vcloud/action/read_state.rb +16 -23
- data/lib/vagrant-vcloud/action/resume.rb +5 -13
- data/lib/vagrant-vcloud/action/suspend.rb +5 -13
- data/lib/vagrant-vcloud/action/sync_folders.rb +82 -48
- data/lib/vagrant-vcloud/action/unmap_port_forwardings.rb +27 -29
- data/lib/vagrant-vcloud/command.rb +186 -0
- data/lib/vagrant-vcloud/config.rb +41 -20
- data/lib/vagrant-vcloud/driver/base.rb +170 -121
- data/lib/vagrant-vcloud/driver/meta.rb +64 -70
- data/lib/vagrant-vcloud/driver/version_5_1.rb +1038 -716
- data/lib/vagrant-vcloud/errors.rb +4 -4
- data/lib/vagrant-vcloud/model/forwarded_port.rb +4 -2
- data/lib/vagrant-vcloud/plugin.rb +30 -20
- data/lib/vagrant-vcloud/provider.rb +6 -6
- data/lib/vagrant-vcloud/util/compile_forwarded_ports.rb +1 -1
- data/lib/vagrant-vcloud/version.rb +1 -1
- data/locales/en.yml +6 -5
- data/vagrant-vcloud.gemspec +10 -7
- metadata +35 -4
@@ -1,9 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require 'vagrant'
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module VCloud
|
5
5
|
class Config < Vagrant.plugin('2', :config)
|
6
|
-
|
7
6
|
# login attributes
|
8
7
|
|
9
8
|
# The vCloud Director hostname
|
@@ -38,6 +37,11 @@ module VagrantPlugins
|
|
38
37
|
# @return [String]
|
39
38
|
attr_accessor :catalog_item_name
|
40
39
|
|
40
|
+
# Chunksize for upload in bytes (default 1048576 == 1M)
|
41
|
+
#
|
42
|
+
# @return [Integer]
|
43
|
+
attr_accessor :upload_chunksize
|
44
|
+
|
41
45
|
# Virtual Data Center to be used
|
42
46
|
#
|
43
47
|
# @return [String]
|
@@ -68,6 +72,11 @@ module VagrantPlugins
|
|
68
72
|
# @return [Array]
|
69
73
|
attr_accessor :ip_dns
|
70
74
|
|
75
|
+
# Bridge Mode
|
76
|
+
#
|
77
|
+
# @return [Bool]
|
78
|
+
attr_accessor :network_bridge
|
79
|
+
|
71
80
|
# Port forwarding rules
|
72
81
|
#
|
73
82
|
# @return [Hash]
|
@@ -78,21 +87,22 @@ module VagrantPlugins
|
|
78
87
|
# @return [String]
|
79
88
|
attr_accessor :vdc_edge_gateway
|
80
89
|
|
81
|
-
# Public IP of the edge gateway [optional, required if :vdc_edge_gateway
|
90
|
+
# Public IP of the edge gateway [optional, required if :vdc_edge_gateway
|
91
|
+
# is specified]
|
82
92
|
#
|
83
93
|
# @return [String]
|
84
94
|
attr_accessor :vdc_edge_gateway_ip
|
85
|
-
|
95
|
+
|
86
96
|
##
|
87
97
|
## vCloud Director config runtime values
|
88
|
-
##
|
98
|
+
##
|
89
99
|
|
90
100
|
# connection handle
|
91
101
|
attr_accessor :vcloud_cnx
|
92
|
-
|
102
|
+
|
93
103
|
# org object (Hash)
|
94
104
|
attr_accessor :org
|
95
|
-
|
105
|
+
|
96
106
|
# org id (String)
|
97
107
|
attr_accessor :org_id
|
98
108
|
|
@@ -106,10 +116,10 @@ module VagrantPlugins
|
|
106
116
|
attr_accessor :catalog
|
107
117
|
|
108
118
|
# catalog id (String)
|
109
|
-
attr_accessor :catalog_id
|
119
|
+
attr_accessor :catalog_id
|
110
120
|
|
111
121
|
# catalog item object (Hash)
|
112
|
-
attr_accessor :catalog_item
|
122
|
+
attr_accessor :catalog_item
|
113
123
|
|
114
124
|
# vApp Name (String)
|
115
125
|
attr_accessor :vAppName
|
@@ -121,19 +131,30 @@ module VagrantPlugins
|
|
121
131
|
errors = _detected_errors
|
122
132
|
|
123
133
|
# TODO: add blank?
|
124
|
-
errors << I18n.t(
|
125
|
-
errors << I18n.t(
|
126
|
-
errors << I18n.t(
|
127
|
-
errors << I18n.t(
|
128
|
-
|
129
|
-
|
130
|
-
|
134
|
+
errors << I18n.t('vagrant_vcloud.config.hostname') if hostname.nil?
|
135
|
+
errors << I18n.t('vagrant_vcloud.config.org_name') if org_name.nil?
|
136
|
+
errors << I18n.t('vagrant_vcloud.config.username') if username.nil?
|
137
|
+
errors << I18n.t('vagrant_vcloud.config.password') if password.nil?
|
138
|
+
|
139
|
+
unless ip_dns.nil?
|
140
|
+
unless ip_dns.kind_of?(Array)
|
141
|
+
errors << I18n.t('vagrant_vcloud.config.ip_dns')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
if catalog_name.nil?
|
146
|
+
errors << I18n.t('vagrant_vcloud.config.catalog_name')
|
147
|
+
end
|
148
|
+
|
149
|
+
if vdc_name.nil?
|
150
|
+
errors << I18n.t('vagrant_vcloud.config.vdc_name')
|
151
|
+
end
|
152
|
+
|
153
|
+
if vdc_network_name.nil?
|
154
|
+
errors << I18n.t('vagrant_vcloud.config.vdc_network_name')
|
131
155
|
end
|
132
|
-
errors << I18n.t("vagrant_vcloud.config.catalog_name") if catalog_name.nil?
|
133
|
-
errors << I18n.t("vagrant_vcloud.config.vdc_name") if vdc_name.nil?
|
134
|
-
errors << I18n.t("vagrant_vcloud.config.vdc_network_name") if vdc_network_name.nil?
|
135
156
|
|
136
|
-
{
|
157
|
+
{ 'vCloud Provider' => errors }
|
137
158
|
end
|
138
159
|
end
|
139
160
|
end
|
@@ -15,12 +15,12 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
#
|
17
17
|
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
|
18
|
+
require 'log4r'
|
19
|
+
require 'vagrant/util/busy'
|
20
|
+
require 'vagrant/util/platform'
|
21
|
+
require 'vagrant/util/retryable'
|
22
|
+
require 'vagrant/util/subprocess'
|
23
|
+
require 'awesome_print'
|
24
24
|
|
25
25
|
module VagrantPlugins
|
26
26
|
module VCloud
|
@@ -37,7 +37,7 @@ module VagrantPlugins
|
|
37
37
|
include Vagrant::Util::Retryable
|
38
38
|
|
39
39
|
def initialize
|
40
|
-
@logger = Log4r::Logger.new(
|
40
|
+
@logger = Log4r::Logger.new('vagrant::provider::vcloud::base')
|
41
41
|
end
|
42
42
|
|
43
43
|
##
|
@@ -61,7 +61,6 @@ module VagrantPlugins
|
|
61
61
|
def get_organization_id_by_name(name)
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
64
|
##
|
66
65
|
# friendly helper method to fetch an Organization by name
|
67
66
|
# - name (this isn't case sensitive)
|
@@ -73,26 +72,26 @@ module VagrantPlugins
|
|
73
72
|
# - catalogs
|
74
73
|
# - vdcs
|
75
74
|
# - networks
|
76
|
-
def get_organization(
|
75
|
+
def get_organization(org_id)
|
77
76
|
end
|
78
77
|
|
79
78
|
##
|
80
79
|
# Fetch details about a given catalog
|
81
|
-
def get_catalog(
|
80
|
+
def get_catalog(catalog_id)
|
82
81
|
end
|
83
82
|
|
84
83
|
##
|
85
84
|
# Friendly helper method to fetch an catalog id by name
|
86
85
|
# - organization hash (from get_organization/get_organization_by_name)
|
87
86
|
# - catalog name
|
88
|
-
def get_catalog_id_by_name(organization,
|
87
|
+
def get_catalog_id_by_name(organization, catalog_name)
|
89
88
|
end
|
90
89
|
|
91
90
|
##
|
92
91
|
# Friendly helper method to fetch an catalog by name
|
93
92
|
# - organization hash (from get_organization/get_organization_by_name)
|
94
93
|
# - catalog name
|
95
|
-
def get_catalog_by_name(organization,
|
94
|
+
def get_catalog_by_name(organization, catalog_name)
|
96
95
|
end
|
97
96
|
|
98
97
|
##
|
@@ -100,36 +99,36 @@ module VagrantPlugins
|
|
100
99
|
# - description
|
101
100
|
# - vapps
|
102
101
|
# - networks
|
103
|
-
def get_vdc(
|
102
|
+
def get_vdc(vdc_id)
|
104
103
|
end
|
105
104
|
|
106
105
|
##
|
107
106
|
# Friendly helper method to fetch a Organization VDC Id by name
|
108
107
|
# - Organization object
|
109
108
|
# - Organization VDC Name
|
110
|
-
def get_vdc_id_by_name(organization,
|
109
|
+
def get_vdc_id_by_name(organization, vdc_name)
|
111
110
|
end
|
112
111
|
|
113
112
|
##
|
114
113
|
# Friendly helper method to fetch a Organization VDC by name
|
115
114
|
# - Organization object
|
116
115
|
# - Organization VDC Name
|
117
|
-
def get_vdc_by_name(organization,
|
116
|
+
def get_vdc_by_name(organization, vdc_name)
|
118
117
|
end
|
119
118
|
|
120
119
|
##
|
121
120
|
# Fetch details about a given catalog item:
|
122
121
|
# - description
|
123
122
|
# - vApp templates
|
124
|
-
def get_catalog_item(
|
123
|
+
def get_catalog_item(catalog_item_id)
|
125
124
|
end
|
126
125
|
|
127
126
|
##
|
128
127
|
# friendly helper method to fetch an catalogItem by name
|
129
128
|
# - catalogId (use get_catalog_name(org, name))
|
130
|
-
# - catalagItemName
|
131
|
-
def get_catalog_item_by_name(
|
132
|
-
end
|
129
|
+
# - catalagItemName
|
130
|
+
def get_catalog_item_by_name(catalog_id, catalog_item_name)
|
131
|
+
end
|
133
132
|
|
134
133
|
##
|
135
134
|
# Fetch details about a given vapp:
|
@@ -141,18 +140,18 @@ module VagrantPlugins
|
|
141
140
|
# -- IP addresses
|
142
141
|
# -- status
|
143
142
|
# -- ID
|
144
|
-
def get_vapp(
|
143
|
+
def get_vapp(vapp_id)
|
145
144
|
end
|
146
145
|
|
147
146
|
##
|
148
147
|
# Delete a given vapp
|
149
148
|
# NOTE: It doesn't verify that the vapp is shutdown
|
150
|
-
def delete_vapp(
|
149
|
+
def delete_vapp(vapp_id)
|
151
150
|
end
|
152
151
|
|
153
152
|
##
|
154
153
|
# Suspend a given vapp
|
155
|
-
def suspend_vapp(
|
154
|
+
def suspend_vapp(vapp_id)
|
156
155
|
end
|
157
156
|
|
158
157
|
##
|
@@ -160,19 +159,19 @@ module VagrantPlugins
|
|
160
159
|
# This will basically initial a guest OS reboot, and will only work if
|
161
160
|
# VMware-tools are installed on the underlying VMs.
|
162
161
|
# vShield Edge devices are not affected
|
163
|
-
def reboot_vapp(
|
162
|
+
def reboot_vapp(vapp_id)
|
164
163
|
end
|
165
164
|
|
166
165
|
##
|
167
166
|
# reset a given vapp
|
168
167
|
# This will basically reset the VMs within the vApp
|
169
168
|
# vShield Edge devices are not affected.
|
170
|
-
def reset_vapp(
|
169
|
+
def reset_vapp(vapp_id)
|
171
170
|
end
|
172
171
|
|
173
172
|
##
|
174
173
|
# Boot a given vapp
|
175
|
-
def poweron_vapp(
|
174
|
+
def poweron_vapp(vapp_id)
|
176
175
|
end
|
177
176
|
|
178
177
|
##
|
@@ -183,7 +182,8 @@ module VagrantPlugins
|
|
183
182
|
# - vapp_name: name of the target vapp
|
184
183
|
# - vapp_description: description of the target vapp
|
185
184
|
# - vapp_templateid: ID of the vapp template
|
186
|
-
def create_vapp_from_template(vdc, vapp_name, vapp_description,
|
185
|
+
def create_vapp_from_template(vdc, vapp_name, vapp_description,
|
186
|
+
vapp_templateid, poweron = false)
|
187
187
|
end
|
188
188
|
|
189
189
|
##
|
@@ -193,9 +193,10 @@ module VagrantPlugins
|
|
193
193
|
# - vdc: the associated VDC
|
194
194
|
# - vapp_name: name of the target vapp
|
195
195
|
# - vapp_description: description of the target vapp
|
196
|
-
# - vm_list: hash with IDs of the VMs
|
196
|
+
# - vm_list: hash with IDs of the VMs used in the composing process
|
197
197
|
# - network_config: hash of the network configuration for the vapp
|
198
|
-
def compose_vapp_from_vm(vdc, vapp_name, vapp_description,
|
198
|
+
def compose_vapp_from_vm(vdc, vapp_name, vapp_description,
|
199
|
+
vm_list = {}, network_config = {})
|
199
200
|
end
|
200
201
|
|
201
202
|
# Fetch details about a given vapp template:
|
@@ -203,7 +204,7 @@ module VagrantPlugins
|
|
203
204
|
# - description
|
204
205
|
# - Children VMs:
|
205
206
|
# -- ID
|
206
|
-
def get_vapp_template(
|
207
|
+
def get_vapp_template(vapp_id)
|
207
208
|
end
|
208
209
|
|
209
210
|
##
|
@@ -211,15 +212,16 @@ module VagrantPlugins
|
|
211
212
|
#
|
212
213
|
# - vappid: id of the vapp to be modified
|
213
214
|
# - network_name: name of the vapp network to be modified
|
214
|
-
# - config: hash with network configuration specifications, must contain
|
215
|
-
|
215
|
+
# - config: hash with network configuration specifications, must contain
|
216
|
+
# an array inside :nat_rules with the nat rules to be applied.
|
217
|
+
def set_vapp_port_forwarding_rules(vapp_id, network_name, config = {})
|
216
218
|
end
|
217
219
|
|
218
220
|
##
|
219
221
|
# Get vApp port forwarding rules
|
220
222
|
#
|
221
223
|
# - vappid: id of the vApp
|
222
|
-
def get_vapp_port_forwarding_rules(
|
224
|
+
def get_vapp_port_forwarding_rules(vapp_id)
|
223
225
|
end
|
224
226
|
|
225
227
|
##
|
@@ -228,8 +230,8 @@ module VagrantPlugins
|
|
228
230
|
# - vApp needs to be poweredOn
|
229
231
|
# - FenceMode is set to "natRouted"
|
230
232
|
# - NatType" is set to "portForwarding
|
231
|
-
# This will be required to know how to connect to VMs behind the Edge
|
232
|
-
def get_vapp_edge_public_ip(
|
233
|
+
# This will be required to know how to connect to VMs behind the Edge.
|
234
|
+
def get_vapp_edge_public_ip(vapp_id)
|
233
235
|
end
|
234
236
|
|
235
237
|
##
|
@@ -240,58 +242,57 @@ module VagrantPlugins
|
|
240
242
|
# - ovfFile
|
241
243
|
# - catalogId
|
242
244
|
# - uploadOptions {}
|
243
|
-
def upload_ovf(
|
245
|
+
def upload_ovf(vdc_id, vapp_name, vapp_description, ovf_file,
|
246
|
+
catalog_id, upload_options = {})
|
244
247
|
end
|
245
248
|
|
246
249
|
##
|
247
250
|
# Fetch information for a given task
|
248
|
-
def get_task(
|
251
|
+
def get_task(task_id)
|
249
252
|
end
|
250
253
|
|
251
254
|
##
|
252
255
|
# Poll a given task until completion
|
253
|
-
def wait_task_completion(
|
256
|
+
def wait_task_completion(task_id)
|
254
257
|
end
|
255
258
|
|
256
259
|
##
|
257
260
|
# Set vApp Network Config
|
258
|
-
def set_vapp_network_config(
|
261
|
+
def set_vapp_network_config(vapp_id, network_name, config = {})
|
259
262
|
end
|
260
263
|
|
261
264
|
##
|
262
265
|
# Set VM Network Config
|
263
|
-
def set_vm_network_config(
|
266
|
+
def set_vm_network_config(vm_id, network_name, config = {})
|
264
267
|
end
|
265
268
|
|
266
|
-
|
267
269
|
##
|
268
270
|
# Set VM Guest Customization Config
|
269
|
-
def set_vm_guest_customization(
|
271
|
+
def set_vm_guest_customization(vm_id, computer_name, config = {})
|
270
272
|
end
|
271
273
|
|
272
274
|
##
|
273
275
|
# Fetch details about a given VM
|
274
|
-
def get_vm(
|
276
|
+
def get_vm(vm_Id)
|
275
277
|
end
|
276
278
|
|
277
279
|
private
|
278
280
|
|
279
281
|
##
|
280
|
-
# Sends a synchronous request to the vCloud API and returns the
|
281
|
-
|
282
|
-
|
282
|
+
# Sends a synchronous request to the vCloud API and returns the
|
283
|
+
# response as parsed XML + headers using HTTPClient.
|
284
|
+
def send_request(params, payload = nil, content_type = nil)
|
283
285
|
# Create a new HTTP client
|
284
286
|
clnt = HTTPClient.new
|
285
287
|
|
286
288
|
# Disable SSL cert verification
|
287
|
-
clnt.ssl_config.verify_mode=(OpenSSL::SSL::VERIFY_NONE)
|
289
|
+
clnt.ssl_config.verify_mode = (OpenSSL::SSL::VERIFY_NONE)
|
288
290
|
|
289
291
|
# Suppress SSL depth message
|
290
|
-
clnt.ssl_config.verify_callback=proc{ |ok, ctx|; true }
|
291
|
-
|
292
|
-
extheader = {}
|
292
|
+
clnt.ssl_config.verify_callback = proc { |ok, ctx|; true }
|
293
293
|
|
294
|
-
extheader
|
294
|
+
extheader = {}
|
295
|
+
extheader['accept'] = "application/*+xml;version=#{@api_version}"
|
295
296
|
|
296
297
|
if !content_type.nil?
|
297
298
|
extheader['Content-Type'] = content_type
|
@@ -305,135 +306,183 @@ module VagrantPlugins
|
|
305
306
|
|
306
307
|
url = "#{@api_url}#{params['command']}"
|
307
308
|
|
309
|
+
# Massive debug when LOG=DEBUG
|
310
|
+
# Using awesome_print to get nice XML output for better readability
|
311
|
+
if @logger.level == 1
|
312
|
+
ap "SEND #{url}"
|
313
|
+
if payload
|
314
|
+
payload_xml = Nokogiri.XML(payload)
|
315
|
+
ap payload_xml
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
308
319
|
begin
|
309
|
-
response = clnt.request(
|
320
|
+
response = clnt.request(
|
321
|
+
params['method'],
|
322
|
+
url,
|
323
|
+
nil,
|
324
|
+
payload,
|
325
|
+
extheader
|
326
|
+
)
|
327
|
+
|
310
328
|
if !response.ok?
|
311
|
-
raise "Warning: unattended code #{response.status}
|
329
|
+
raise "Warning: unattended code #{response.status}" +
|
330
|
+
" #{response.reason}"
|
312
331
|
end
|
313
332
|
|
314
|
-
|
333
|
+
nicexml = Nokogiri.XML(response.body)
|
315
334
|
|
335
|
+
# Massive debug when LOG=DEBUG
|
336
|
+
# Using awesome_print to get nice XML output for readability
|
337
|
+
if @logger.level == 1
|
338
|
+
ap "RECV #{response.status}"
|
339
|
+
# Just avoid the task spam.
|
340
|
+
if !url.index('/task/')
|
341
|
+
ap nicexml
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
[Nokogiri.parse(response.body), response.headers]
|
316
346
|
rescue SocketError
|
317
|
-
raise
|
347
|
+
raise 'Impossible to connect, verify endpoint'
|
318
348
|
rescue Errno::EADDRNOTAVAIL
|
319
|
-
raise
|
349
|
+
raise 'Impossible to connect, verify endpoint'
|
320
350
|
end
|
321
|
-
|
322
|
-
|
323
351
|
end
|
324
352
|
|
325
|
-
|
326
353
|
##
|
327
|
-
# Upload a large file in configurable chunks, output an optional
|
328
|
-
|
329
|
-
|
330
|
-
# Set chunksize to
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
354
|
+
# Upload a large file in configurable chunks, output an optional
|
355
|
+
# progressbar
|
356
|
+
def upload_file(upload_url, upload_file, vapp_template, config = {})
|
357
|
+
# Set chunksize to 1M if not specified otherwise
|
358
|
+
chunk_size = (config[:chunksize] || 1_048_576)
|
359
|
+
@logger.debug("Set chunksize to #{chunk_size} bytes")
|
360
|
+
|
361
|
+
# Set progressbar to default format if not specified otherwise
|
362
|
+
progressbar_format = (
|
363
|
+
config[:progressbar_format] || '%t Progress: %p%% %e'
|
364
|
+
)
|
338
365
|
|
339
366
|
# Open our file for upload
|
340
|
-
|
341
|
-
|
367
|
+
upload_file_handle = File.new(upload_file, 'rb')
|
368
|
+
file_name = File.basename(upload_file_handle)
|
342
369
|
|
343
|
-
|
370
|
+
# FIXME: I removed the filename below because I recall a weird issue
|
371
|
+
# of upload failing because if a too long filename
|
372
|
+
# (tsugliani)
|
373
|
+
progressbar_title = 'Uploading Box...'
|
344
374
|
|
345
375
|
# Create a progressbar object if progress bar is enabled
|
346
|
-
if config[:progressbar_enable] == true &&
|
376
|
+
if config[:progressbar_enable] == true &&
|
377
|
+
upload_file_handle.size.to_i > chunk_size
|
347
378
|
progressbar = ProgressBar.create(
|
348
|
-
:title
|
349
|
-
:starting_at
|
350
|
-
:total
|
351
|
-
|
352
|
-
:format => progressBarFormat
|
379
|
+
:title => progressbar_title,
|
380
|
+
:starting_at => 0,
|
381
|
+
:total => upload_file_handle.size.to_i,
|
382
|
+
:format => progressbar_format
|
353
383
|
)
|
354
384
|
else
|
355
|
-
puts
|
385
|
+
puts progressbar_title
|
356
386
|
end
|
357
387
|
# Create a new HTTP client
|
358
388
|
clnt = HTTPClient.new
|
359
389
|
|
360
390
|
# Disable SSL cert verification
|
361
|
-
clnt.ssl_config.verify_mode=(OpenSSL::SSL::VERIFY_NONE)
|
391
|
+
clnt.ssl_config.verify_mode = (OpenSSL::SSL::VERIFY_NONE)
|
362
392
|
|
363
393
|
# Suppress SSL depth message
|
364
|
-
clnt.ssl_config.verify_callback=proc{ |ok, ctx|; true }
|
394
|
+
clnt.ssl_config.verify_callback = proc { |ok, ctx|; true }
|
365
395
|
|
366
396
|
# Perform ranged upload until the file reaches its end
|
367
|
-
until
|
397
|
+
until upload_file_handle.eof?
|
368
398
|
|
369
399
|
# Create ranges for this chunk upload
|
370
|
-
|
371
|
-
|
400
|
+
range_start = upload_file_handle.pos
|
401
|
+
range_stop = upload_file_handle.pos.to_i + chunk_size
|
372
402
|
|
373
403
|
# Read current chunk
|
374
|
-
|
404
|
+
file_content = upload_file_handle.read(chunk_size)
|
375
405
|
|
376
406
|
# If statement to handle last chunk transfer if is > than filesize
|
377
|
-
if
|
378
|
-
|
379
|
-
|
407
|
+
if range_stop.to_i > upload_file_handle.size.to_i
|
408
|
+
content_range = "bytes #{range_start.to_s}-" +
|
409
|
+
"#{upload_file_handle.size.to_s}/" +
|
410
|
+
"#{upload_file_handle.size.to_s}"
|
411
|
+
range_len = upload_file_handle.size.to_i - range_start.to_i
|
380
412
|
else
|
381
|
-
|
382
|
-
|
413
|
+
content_range = "bytes #{range_start.to_s}-" +
|
414
|
+
"#{range_stop.to_s}/" +
|
415
|
+
"#{upload_file_handle.size.to_s}"
|
416
|
+
range_len = range_stop.to_i - range_start.to_i
|
383
417
|
end
|
384
418
|
|
385
419
|
# Build headers
|
386
420
|
extheader = {
|
387
|
-
'x-vcloud-authorization'
|
388
|
-
'Content-Range'
|
389
|
-
'Content-Length'
|
421
|
+
'x-vcloud-authorization' => @auth_key,
|
422
|
+
'Content-Range' => content_range,
|
423
|
+
'Content-Length' => range_len.to_s
|
390
424
|
}
|
391
425
|
|
392
426
|
begin
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
427
|
+
upload_request = "#{@host_url}#{upload_url}"
|
428
|
+
# FIXME: Add debug on the return status of "connection"
|
429
|
+
# to enhance troubleshooting for this upload process.
|
430
|
+
# (tsugliani)
|
431
|
+
_connection = clnt.request(
|
432
|
+
'PUT',
|
433
|
+
upload_request,
|
434
|
+
nil,
|
435
|
+
file_content,
|
436
|
+
extheader
|
437
|
+
)
|
438
|
+
|
439
|
+
if config[:progressbar_enable] == true &&
|
440
|
+
upload_file_handle.size.to_i > chunk_size
|
397
441
|
params = {
|
398
|
-
'method'
|
399
|
-
'command' => "/vAppTemplate/vappTemplate-#{
|
442
|
+
'method' => :get,
|
443
|
+
'command' => "/vAppTemplate/vappTemplate-#{vapp_template}"
|
400
444
|
}
|
401
|
-
response,
|
445
|
+
response, _headers = send_request(params)
|
402
446
|
|
403
|
-
response.css(
|
404
|
-
|
447
|
+
response.css(
|
448
|
+
"Files File [name='#{file_name}']"
|
449
|
+
).each do |file|
|
450
|
+
progressbar.progress = file[:bytesTransferred].to_i
|
405
451
|
end
|
406
452
|
end
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
453
|
+
|
454
|
+
rescue
|
455
|
+
# FIXME: HUGE FIXME!!!!
|
456
|
+
# DO SOMETHING WITH THIS, IT'S JUST STUPID AS IT IS NOW!!!
|
457
|
+
retry_time = (config[:retry_time] || 5)
|
458
|
+
puts "Range #{content_range} failed to upload, " +
|
459
|
+
"retrying the chunk in #{retry_time.to_s} seconds, " +
|
460
|
+
'to stop this task press CTRL+C.'
|
461
|
+
sleep retry_time.to_i
|
411
462
|
retry
|
412
463
|
end
|
413
464
|
end
|
414
|
-
|
465
|
+
upload_file_handle.close
|
415
466
|
end
|
416
467
|
|
417
|
-
|
418
468
|
##
|
419
469
|
# Convert vApp status codes into human readable description
|
420
470
|
def convert_vapp_status(status_code)
|
421
471
|
case status_code.to_i
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
472
|
+
when 0
|
473
|
+
'suspended'
|
474
|
+
when 3
|
475
|
+
'paused'
|
476
|
+
when 4
|
477
|
+
'running'
|
478
|
+
when 8
|
479
|
+
'stopped'
|
480
|
+
when 10
|
481
|
+
'mixed'
|
482
|
+
else
|
483
|
+
"Unknown #{status_code}"
|
434
484
|
end
|
435
485
|
end
|
436
|
-
|
437
486
|
end # class
|
438
487
|
end
|
439
488
|
end
|