Revision 347968ad src/cli/onevcenter
src/cli/onevcenter | ||
---|---|---|
1 | 1 |
#!/usr/bin/env ruby |
2 | 2 |
|
3 | 3 |
# -------------------------------------------------------------------------- # |
4 |
# Copyright 2002-2016, OpenNebula Project, OpenNebula Systems #
|
|
4 |
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
|
|
5 | 5 |
# # |
6 | 6 |
# Licensed under the Apache License, Version 2.0 (the "License"); you may # |
7 | 7 |
# not use this file except in compliance with the License. You may obtain # |
... | ... | |
65 | 65 |
helper.set_client(options) |
66 | 66 |
end |
67 | 67 |
|
68 |
######################################################################## |
|
68 |
############################################################################
|
|
69 | 69 |
# Global Options |
70 |
######################################################################## |
|
70 |
############################################################################
|
|
71 | 71 |
cmd_options=CommandParser::OPTIONS-[CommandParser::VERBOSE] |
72 | 72 |
set :option, cmd_options+OpenNebulaHelper::CLIENT_OPTIONS |
73 | 73 |
|
... | ... | |
103 | 103 |
command :hosts, hosts_desc, :options=>[ VCENTER, USER, PASS ] do |
104 | 104 |
con_ops = connection_options("Hosts", options) |
105 | 105 |
|
106 |
begin |
|
107 |
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." |
|
108 |
|
|
109 |
vc = VCenterDriver::VIClient.new_connection(con_ops) |
|
110 |
|
|
111 |
STDOUT.print "done!\n\n" |
|
112 |
|
|
113 |
STDOUT.print "Exploring vCenter resources..." |
|
114 |
|
|
115 |
rs = vc.hierarchy |
|
116 |
|
|
117 |
STDOUT.print "done!\n\n" |
|
118 |
|
|
119 |
rs.each {|dc, cluster| |
|
120 |
STDOUT.print "Do you want to process datacenter #{dc} [y/n]? " |
|
121 |
|
|
122 |
next if STDIN.gets.strip.downcase != 'y' |
|
123 |
|
|
124 |
if cluster.empty? |
|
125 |
STDOUT.puts " No new clusters found in #{dc}..." |
|
126 |
next |
|
127 |
end |
|
128 |
|
|
129 |
cluster.each{ |c| |
|
130 |
STDOUT.print " * Import cluster #{c} [y/n]? " |
|
131 |
|
|
132 |
next if STDIN.gets.strip.downcase != 'y' |
|
133 |
|
|
134 |
r, m = VCenterDriver::VCenterHost.to_one(c, vc) |
|
135 |
|
|
136 |
if r == 0 |
|
137 |
STDOUT.puts " OpenNebula host #{c} with id #{m}"\ |
|
138 |
" successfully created." |
|
139 |
else |
|
140 |
STDOUT.puts " Error: #{m}" |
|
141 |
end |
|
142 |
|
|
143 |
STDOUT.puts |
|
144 |
} |
|
145 |
} |
|
146 |
rescue Exception => e |
|
147 |
STDOUT.puts "error: #{e.message}" |
|
148 |
exit -1 |
|
149 |
end |
|
106 |
VCenterDriver::Importer.import_clusters(con_ops, options) |
|
150 | 107 |
|
151 | 108 |
exit 0 |
152 | 109 |
end |
153 | 110 |
|
111 |
############################################################################ |
|
112 |
# Import templates |
|
113 |
############################################################################ |
|
154 | 114 |
templates_desc = <<-EOT.unindent |
155 | 115 |
Import vCenter VM Templates into OpenNebula |
156 | 116 |
EOT |
... | ... | |
158 | 118 |
command :templates, templates_desc, :options=>[ VCENTER, USER, PASS ] do |
159 | 119 |
con_ops = connection_options("VM Templates", options) |
160 | 120 |
|
161 |
begin |
|
162 |
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." |
|
163 |
|
|
164 |
vc = VCenterDriver::VIClient.new_connection(con_ops) |
|
165 |
|
|
166 |
STDOUT.print "done!\n\n" |
|
167 |
|
|
168 |
STDOUT.print "Looking for VM Templates..." |
|
169 |
|
|
170 |
rs = vc.vm_templates |
|
171 |
|
|
172 |
STDOUT.print "done!\n" |
|
173 |
|
|
174 |
rs.each {|dc, tmps| |
|
175 |
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? " |
|
176 |
|
|
177 |
next if STDIN.gets.strip.downcase != 'y' |
|
178 |
|
|
179 |
if tmps.empty? |
|
180 |
STDOUT.print " No new VM Templates found in #{dc}...\n\n" |
|
181 |
next |
|
182 |
end |
|
183 |
|
|
184 |
tmps.each{ |t| |
|
185 |
STDOUT.print "\n * VM Template found:\n"\ |
|
186 |
" - Name : #{t[:name]}\n"\ |
|
187 |
" - UUID : #{t[:uuid]}\n"\ |
|
188 |
" - Cluster: #{t[:host]}\n"\ |
|
189 |
" Import this VM template [y/n]? " |
|
190 |
|
|
191 |
next if STDIN.gets.strip.downcase != 'y' |
|
192 |
|
|
193 |
ds_input = "" |
|
194 |
rp_input = "" |
|
195 |
|
|
196 |
# Datastores |
|
197 |
|
|
198 |
STDOUT.print "\n This template is currently set to be "\ |
|
199 |
"deployed in datastore #{t[:default_ds]}."\ |
|
200 |
"\n Press y to keep the default, n to select"\ |
|
201 |
" a new datastore or d to delegate the choice"\ |
|
202 |
" to the user [y/n/d]? " |
|
203 |
|
|
204 |
answer = STDIN.gets.strip.downcase |
|
205 |
|
|
206 |
case answer |
|
207 |
when 'd' |
|
208 |
ds_split = t[:ds].split("|") |
|
209 |
list_of_ds = ds_split[-2] |
|
210 |
default_ds = ds_split[-1] |
|
211 |
ds_input = ds_split[0] + "|" + ds_split[1] + "|" + |
|
212 |
ds_split[2] + "|" |
|
213 |
|
|
214 |
# Available list of datastores |
|
215 |
|
|
216 |
input_str = " The list of available datastores to be"\ |
|
217 |
" presented to the user are \"#{list_of_ds}\"" |
|
218 |
input_str+= "\n Press y to agree, or input a comma"\ |
|
219 |
" separated list of datastores to edit "\ |
|
220 |
"[y/comma separated list] " |
|
221 |
STDOUT.print input_str |
|
222 |
|
|
223 |
answer = STDIN.gets.strip |
|
224 |
|
|
225 |
if answer.downcase == 'y' |
|
226 |
ds_input += ds_split[3] + "|" |
|
227 |
else |
|
228 |
ds_input += answer + "|" |
|
229 |
end |
|
230 |
|
|
231 |
# Default |
|
232 |
input_str = " The default datastore presented to "\ |
|
233 |
"the end user is set to \"#{default_ds}\"." |
|
234 |
input_str+= "\n Press y to agree, or input a new "\ |
|
235 |
"datastore [y/datastore name] " |
|
236 |
STDOUT.print input_str |
|
237 |
|
|
238 |
answer = STDIN.gets.strip |
|
239 |
|
|
240 |
if answer.downcase == 'y' |
|
241 |
ds_input += ds_split[4] |
|
242 |
else |
|
243 |
ds_input += answer |
|
244 |
end |
|
245 |
when 'n' |
|
246 |
ds_split = t[:ds].split("|") |
|
247 |
list_of_ds = ds_split[-2] |
|
248 |
|
|
249 |
input_str = " The list of available datastores is"\ |
|
250 |
" \"#{list_of_ds}\"." |
|
251 |
input_str+= "\n Please input the new default datastore: " |
|
252 |
STDOUT.print input_str |
|
253 |
|
|
254 |
answer = STDIN.gets.strip |
|
255 |
|
|
256 |
t[:one] += "VCENTER_DATASTORE=\"#{answer}\"\n" |
|
257 |
end |
|
258 |
|
|
259 |
# Resource Pools |
|
260 |
|
|
261 |
rp_split = t[:rp].split("|") |
|
262 |
|
|
263 |
if rp_split.size > 3 |
|
264 |
STDOUT.print "\n This template is currently set to "\ |
|
265 |
"launch VMs in the default resource pool."\ |
|
266 |
"\n Press y to keep this behaviour, n to select"\ |
|
267 |
" a new resource pool or d to delegate the choice"\ |
|
268 |
" to the user [y/n/d]? " |
|
269 |
|
|
270 |
answer = STDIN.gets.strip.downcase |
|
271 |
|
|
272 |
case answer |
|
273 |
when 'd' |
|
274 |
list_of_rp = rp_split[-2] |
|
275 |
default_rp = rp_split[-1] |
|
276 |
rp_input = rp_split[0] + "|" + rp_split[1] + "|" + |
|
277 |
rp_split[2] + "|" |
|
278 |
|
|
279 |
# Available list of resource pools |
|
280 |
|
|
281 |
input_str = " The list of available resource pools "\ |
|
282 |
"to be presented to the user are "\ |
|
283 |
"\"#{list_of_rp}\"" |
|
284 |
input_str+= "\n Press y to agree, or input a comma"\ |
|
285 |
" separated list of resource pools to edit "\ |
|
286 |
"[y/comma separated list] " |
|
287 |
STDOUT.print input_str |
|
288 |
|
|
289 |
answer = STDIN.gets.strip |
|
290 |
|
|
291 |
if answer.downcase == 'y' |
|
292 |
rp_input += rp_split[3] + "|" |
|
293 |
else |
|
294 |
rp_input += answer + "|" |
|
295 |
end |
|
296 |
|
|
297 |
# Default |
|
298 |
input_str = " The default resource pool presented "\ |
|
299 |
"to the end user is set to"\ |
|
300 |
" \"#{default_rp}\"." |
|
301 |
input_str+= "\n Press y to agree, or input a new "\ |
|
302 |
"resource pool [y/resource pool name] " |
|
303 |
STDOUT.print input_str |
|
304 |
|
|
305 |
answer = STDIN.gets.strip |
|
306 |
|
|
307 |
if answer.downcase == 'y' |
|
308 |
rp_input += rp_split[4] |
|
309 |
else |
|
310 |
rp_input += answer |
|
311 |
end |
|
312 |
when 'n' |
|
313 |
list_of_rp = rp_split[-2] |
|
314 |
|
|
315 |
input_str = " The list of available resource pools is"\ |
|
316 |
" \"#{list_of_rp}\"." |
|
317 |
input_str+= "\n Please input the new default resource pool: " |
|
318 |
STDOUT.print input_str |
|
319 |
|
|
320 |
answer = STDIN.gets.strip |
|
321 |
|
|
322 |
t[:one] += "RESOURCE_POOL=\"#{answer}\"\n" |
|
323 |
end |
|
324 |
end |
|
325 |
|
|
326 |
if ds_input != "" || |
|
327 |
rp_input != "" |
|
328 |
t[:one] += "USER_INPUTS=[" |
|
329 |
t[:one] += "VCENTER_DATASTORE=\"#{ds_input}\"," if ds_input != "" |
|
330 |
t[:one] += "RESOURCE_POOL=\"#{rp_input}\"," if rp_input != "" |
|
331 |
t[:one] = t[:one][0..-2] |
|
332 |
t[:one] += "]" |
|
333 |
end |
|
334 |
|
|
335 |
one_t = ::OpenNebula::Template.new( |
|
336 |
::OpenNebula::Template.build_xml, vc.one) |
|
337 |
|
|
338 |
rc = one_t.allocate(t[:one]) |
|
339 |
|
|
340 |
if ::OpenNebula.is_error?(rc) |
|
341 |
STDOUT.puts " Error creating template: #{rc.message}\n" |
|
342 |
else |
|
343 |
STDOUT.puts " OpenNebula template #{one_t.id} created!\n" |
|
344 |
end |
|
345 |
} |
|
346 |
} |
|
347 |
rescue Exception => e |
|
348 |
STDOUT.puts "error: #{e.message}" |
|
349 |
exit -1 |
|
350 |
end |
|
121 |
VCenterDriver::Importer.import_templates(con_ops, options) |
|
351 | 122 |
|
352 | 123 |
exit 0 |
353 | 124 |
end |
354 | 125 |
|
126 |
############################################################################ |
|
127 |
# Import vms (deprecated) |
|
128 |
############################################################################ |
|
355 | 129 |
vms_desc = <<-EOT.unindent |
356 | 130 |
Deprecated action in onevcenter, please use onehost importvm instead |
357 | 131 |
EOT |
... | ... | |
359 | 133 |
command :vms, vms_desc, :options=>[ VCENTER, USER, PASS ] do |
360 | 134 |
STDERR.puts "Deprecated action in onevcenter, please use onehost "\ |
361 | 135 |
"importvm instead" |
362 |
|
|
363 | 136 |
exit -1 |
364 | 137 |
end |
365 | 138 |
|
139 |
############################################################################ |
|
140 |
# Import networks |
|
141 |
############################################################################ |
|
366 | 142 |
network_desc = <<-EOT.unindent |
367 | 143 |
Import vCenter networks into OpenNebula |
368 | 144 |
EOT |
... | ... | |
370 | 146 |
command :networks, network_desc, :options=>[ VCENTER, USER, PASS ] do |
371 | 147 |
con_ops = connection_options("Networks", options) |
372 | 148 |
|
373 |
begin |
|
374 |
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." |
|
375 |
|
|
376 |
vc = VCenterDriver::VIClient.new_connection(con_ops) |
|
377 |
|
|
378 |
STDOUT.print "done!\n\n" |
|
379 |
|
|
380 |
STDOUT.print "Looking for vCenter networks..." |
|
381 |
|
|
382 |
rs = vc.vcenter_networks |
|
383 |
|
|
384 |
STDOUT.print "done!\n" |
|
385 |
|
|
386 |
rs.each {|dc, tmps| |
|
387 |
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? " |
|
388 |
|
|
389 |
next if STDIN.gets.strip.downcase != 'y' |
|
390 |
|
|
391 |
if tmps.empty? |
|
392 |
STDOUT.print " No new Networks found in #{dc}...\n\n" |
|
393 |
next |
|
394 |
end |
|
395 |
|
|
396 |
tmps.each{ |n| |
|
397 |
print_str = "\n * Network found:\n"\ |
|
398 |
" - Name : #{n[:name]}\n"\ |
|
399 |
" - Type : #{n[:type]}\n" |
|
400 |
print_str += " - VLAN ID : #{n[:vlan]}\n" if n[:vlan] |
|
401 |
print_str += " - Cluster : #{n[:cluster]}\n" |
|
402 |
print_str += " Import this Network [y/n]? " |
|
403 |
|
|
404 |
STDOUT.print print_str |
|
405 |
|
|
406 |
next if STDIN.gets.strip.downcase != 'y' |
|
407 |
|
|
408 |
# Size |
|
409 |
|
|
410 |
STDOUT.print " How many VMs are you planning"\ |
|
411 |
" to fit into this network [255]? " |
|
412 |
|
|
413 |
size = STDIN.gets.strip |
|
414 |
|
|
415 |
size = "255" if size.to_i.to_s != size |
|
416 |
|
|
417 |
# Type |
|
418 |
|
|
419 |
STDOUT.print " What type of Virtual Network"\ |
|
420 |
" do you want to create (IPv[4],IPv[6]"\ |
|
421 |
",[E]thernet) ?" |
|
422 |
|
|
423 |
type = STDIN.gets.strip |
|
424 |
|
|
425 |
ar_str = "\nAR=[TYPE=\"" |
|
426 |
|
|
427 |
case type.downcase |
|
428 |
when "4" |
|
429 |
ar_str += "IP4\"" |
|
430 |
STDOUT.print " Please input the first IP "\ |
|
431 |
"in the range: " |
|
432 |
ip = STDIN.gets.strip |
|
433 |
ar_str += ",IP=" + ip |
|
434 |
|
|
435 |
STDOUT.print " Please input the first MAC "\ |
|
436 |
"in the range [Enter for default]: " |
|
437 |
mac = STDIN.gets.strip |
|
438 |
ar_str += ",MAC=" + mac if !mac.empty? |
|
439 |
when "6" |
|
440 |
ar_str += "IP6\"" |
|
441 |
STDOUT.print " Please input the first MAC "\ |
|
442 |
"in the range [Enter for default]: " |
|
443 |
mac = STDIN.gets.strip |
|
444 |
ar_str += ",MAC=" + mac if !mac.empty? |
|
445 |
|
|
446 |
STDOUT.print " Please input the GLOBAL PREFIX "\ |
|
447 |
"[Enter for default]: " |
|
448 |
gp = STDIN.gets.strip |
|
449 |
ar_str += ",GLOBAL_PREFIX=" + gp if !gp.empty? |
|
450 |
|
|
451 |
STDOUT.print " Please input the ULA PREFIX "\ |
|
452 |
"[Enter for default]: " |
|
453 |
up = STDIN.gets.strip |
|
454 |
ar_str += ",ULA_PREFIX=" + up if !up.empty? |
|
455 |
when "e" |
|
456 |
ar_str += "ETHER\"" |
|
457 |
STDOUT.print " Please input the first MAC "\ |
|
458 |
"in the range [Enter for default]: " |
|
459 |
mac = STDIN.gets.strip |
|
460 |
ar_str += ",MAC=" + mac if !mac.empty? |
|
461 |
else |
|
462 |
STDOUT.puts " Type [#{type}] not supported,"\ |
|
463 |
" defaulting to Ethernet." |
|
464 |
ar_str += "ETHER\"" |
|
465 |
STDOUT.print " Please input the first MAC "\ |
|
466 |
"in the range [Enter for default]: " |
|
467 |
mac = STDIN.gets.strip |
|
468 |
ar_str += ",MAC=" + mac if !mac.empty? |
|
469 |
end |
|
470 |
|
|
471 |
ar_str += ",SIZE = \"#{size}\"]" |
|
472 |
|
|
473 |
one_vn = ::OpenNebula::VirtualNetwork.new( |
|
474 |
::OpenNebula::Template.build_xml, vc.one) |
|
475 |
|
|
476 |
vnet_template = n[:one] + ar_str |
|
477 |
|
|
478 |
rc = one_vn.allocate(vnet_template) |
|
479 |
|
|
480 |
if ::OpenNebula.is_error?(rc) |
|
481 |
STDOUT.puts " Error creating virtual network: " + |
|
482 |
" #{rc.message}\n" |
|
483 |
else |
|
484 |
STDOUT.puts " OpenNebula virtual network " + |
|
485 |
"#{one_vn.id} created with size #{size}!\n" |
|
486 |
end |
|
487 |
} |
|
488 |
} |
|
489 |
rescue Exception => e |
|
490 |
STDOUT.puts "error: #{e.message}" |
|
491 |
exit -1 |
|
492 |
end |
|
149 |
VCenterDriver::Importer.import_networks(con_ops, options) |
|
493 | 150 |
|
494 | 151 |
exit 0 |
495 | 152 |
end |
496 | 153 |
|
154 |
############################################################################ |
|
155 |
# Import datastores |
|
156 |
############################################################################ |
|
497 | 157 |
datastores_desc = <<-EOT.unindent |
498 | 158 |
Import vCenter Datastores into OpenNebula |
499 | 159 |
EOT |
... | ... | |
501 | 161 |
command :datastores, datastores_desc, :options=>[ VCENTER, USER, PASS ] do |
502 | 162 |
con_ops = connection_options("Datastores", options) |
503 | 163 |
|
504 |
begin |
|
505 |
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." |
|
506 |
|
|
507 |
vc = VCenterDriver::VIClient.new_connection(con_ops) |
|
508 |
|
|
509 |
STDOUT.print "done!\n\n" |
|
510 |
|
|
511 |
STDOUT.print "Looking for Datastores..." |
|
512 |
|
|
513 |
rs = vc.vcenter_datastores |
|
514 |
|
|
515 |
STDOUT.print "done!\n" |
|
516 |
|
|
517 |
rs.each {|dc, tmps| |
|
518 |
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? " |
|
519 |
|
|
520 |
next if STDIN.gets.strip.downcase != 'y' |
|
521 |
|
|
522 |
if tmps.empty? |
|
523 |
STDOUT.print " No new Datastores found in #{dc}...\n\n" |
|
524 |
next |
|
525 |
end |
|
526 |
|
|
527 |
tmps.each{ |d| |
|
528 |
STDOUT.print "\n * Datastore found:\n"\ |
|
529 |
" - Name : #{d[:name]}\n"\ |
|
530 |
" - Total MB : #{d[:total_mb]}\n"\ |
|
531 |
" - Free MB : #{d[:free_mb]}\n"\ |
|
532 |
" - Cluster : #{d[:cluster]}\n"\ |
|
533 |
" Import this Datastore [y/n]? " |
|
534 |
|
|
535 |
next if STDIN.gets.strip.downcase != 'y' |
|
536 |
|
|
537 |
one_d = ::OpenNebula::Datastore.new( |
|
538 |
::OpenNebula::Datastore.build_xml, vc.one) |
|
539 |
|
|
540 |
rc = one_d.allocate(d[:one]) |
|
541 |
|
|
542 |
if ::OpenNebula.is_error?(rc) |
|
543 |
STDOUT.puts " Error creating datastore: #{rc.message}\n"\ |
|
544 |
" One datastore can exist only once, and "\ |
|
545 |
"can be used in any vCenter Cluster that "\ |
|
546 |
"has access to it. Also, no spaces allowed "\ |
|
547 |
"in datastore name (rename it in vCenter "\ |
|
548 |
"and try again)" |
|
549 |
else |
|
550 |
STDOUT.puts " OpenNebula datastore #{one_d.id} created!\n" |
|
551 |
end |
|
552 |
} |
|
553 |
} |
|
554 |
rescue Exception => e |
|
555 |
STDOUT.puts "error: #{e.message}" |
|
556 |
exit -1 |
|
557 |
end |
|
164 |
VCenterDriver::Importer.import_datastore(con_ops, options) |
|
558 | 165 |
|
559 | 166 |
exit 0 |
560 | 167 |
end |
561 | 168 |
|
169 |
############################################################################ |
|
170 |
# Import images |
|
171 |
############################################################################ |
|
562 | 172 |
images_desc = <<-EOT.unindent |
563 | 173 |
Import vCenter Images into OpenNebula |
564 | 174 |
EOT |
... | ... | |
573 | 183 |
|
574 | 184 |
con_ops = connection_options("Images", options) |
575 | 185 |
|
576 |
begin |
|
577 |
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." |
|
578 |
|
|
579 |
vc = VCenterDriver::VIClient.new_connection(con_ops) |
|
580 |
|
|
581 |
STDOUT.print "done!\n\n" |
|
582 |
|
|
583 |
STDOUT.print "Looking for Images..." |
|
584 |
|
|
585 |
images = vc.vcenter_images(ds_name) |
|
586 |
|
|
587 |
STDOUT.print "done!\n" |
|
588 |
|
|
589 |
images.each{ |i| |
|
590 |
STDOUT.print "\n * Image found:\n"\ |
|
591 |
" - Name : #{i[:name]}\n"\ |
|
592 |
" - Path : #{i[:path]}\n"\ |
|
593 |
" - Type : #{i[:type]}\n"\ |
|
594 |
" Import this Image [y/n]? " |
|
595 |
|
|
596 |
next if STDIN.gets.strip.downcase != 'y' |
|
597 |
|
|
598 |
one_i = ::OpenNebula::Image.new( |
|
599 |
::OpenNebula::Image.build_xml, vc.one) |
|
600 |
|
|
601 |
rc = one_i.allocate(i[:one], i[:dsid].to_i) |
|
602 |
|
|
603 |
if ::OpenNebula.is_error?(rc) |
|
604 |
STDOUT.puts "Error creating image: #{rc.message}\n" |
|
605 |
if rc.message == "[ImageAllocate] Not enough space "\ |
|
606 |
"in datastore" |
|
607 |
STDOUT.puts "Please disable DATASTORE_CAPACITY_"\ |
|
608 |
"CHECK in /etc/one/oned.conf and "\ |
|
609 |
"restart OpenNebula." |
|
610 |
end |
|
611 |
else |
|
612 |
STDOUT.puts " OpenNebula image #{one_i.id} created!\n" |
|
613 |
end |
|
614 |
} |
|
615 |
rescue Exception => e |
|
616 |
STDOUT.puts "error: #{e.message}" |
|
617 |
exit -1 |
|
618 |
end |
|
186 |
VCenterDriver::Importer.import_images(con_ops, ds_name, options) |
|
619 | 187 |
|
620 | 188 |
exit 0 |
621 | 189 |
end |
Also available in: Unified diff