Revision 347968ad

View differences:

install.sh
651 651

  
652 652
VMM_EXEC_LIB_VCENTER_FILES="src/vmm_mad/remotes/lib/vcenter_driver/datastore.rb
653 653
                    src/vmm_mad/remotes/lib/vcenter_driver/vi_client.rb \
654
                    src/vmm_mad/remotes/lib/vcenter_driver/importer.rb \
654 655
                    src/vmm_mad/remotes/lib/vcenter_driver/file_helper.rb \
655 656
                    src/vmm_mad/remotes/lib/vcenter_driver/host.rb \
656 657
                    src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb \
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
src/vmm_mad/remotes/lib/vcenter_driver/datacenter.rb
33 33

  
34 34
        @items[ref.to_sym]
35 35
    end
36

  
37
    def get_vcenter_instance_uuid
38
        @vi_client.vim.serviceContent.about.instanceUuid
39
    end
40

  
41
    def get_clusters
42

  
43
        clusters = {}
44

  
45
        vcenter_uuid = get_vcenter_instance_uuid
46

  
47
        pool = VCenterDriver::VIHelper.one_pool(OpenNebula::HostPool, false)
48
        if pool.respond_to?(:message)
49
            raise "Could not get OpenNebula Pool: #{pool.message}"
50
        end
51

  
52
        fetch! if @items.empty? #Get datacenters
53

  
54
        # Add datacenter to hash and store in an array all clusters
55
        @items.values.each do |dc|
56
            dc_name = dc.item.name
57
            clusters[dc_name] = []
58

  
59
            host_folder = dc.host_folder
60
            host_folder.fetch_clusters!
61

  
62
            host_folder.items.values.each do |ccr|
63
                cluster = {}
64
                cluster[:ref]  = ccr['_ref']
65
                cluster[:name] = ccr['name']
66
                attribute = "TEMPLATE/VCENTER_CCR_REF"
67
                one_host = VCenterDriver::VIHelper.find_by_ref(OpenNebula::HostPool,
68
                                                               attribute,
69
                                                               ccr['_ref'],
70
                                                               vcenter_uuid,
71
                                                               pool)
72

  
73
                next if one_host.nil? #Cluster hasn't been imported'
74

  
75
                cluster[:host_id] = one_host['ID']
76
                clusters[dc_name] << cluster
77
            end
78
        end
79

  
80
        clusters
81
    end
82

  
83
    def get_unimported_datastores
84
        ds_objects = {}
85

  
86
        vcenter_uuid = get_vcenter_instance_uuid
87

  
88
        pool = VCenterDriver::VIHelper.one_pool(OpenNebula::DatastorePool, false)
89

  
90
        if pool.respond_to?(:message)
91
            raise "Could not get OpenNebula DatastorePool: #{pool.message}"
92
        end
93

  
94
        fetch! if @items.empty? #Get datacenters
95

  
96
        one_clusters = get_clusters
97

  
98
        @items.values.each do |dc|
99
            dc_name = dc.item.name
100
            ds_objects[dc_name] = []
101

  
102
            datastore_folder = dc.datastore_folder
103
            datastore_folder.fetch!
104
            datastore_folder.items.values.each do |ds|
105

  
106
                if ds.instance_of? VCenterDriver::Datastore
107
                    hosts_in_ds = ds['host']
108
                    clusters_in_ds = {}
109

  
110
                    hosts_in_ds.each do |host|
111
                        if !clusters_in_ds[host.key.parent._ref.to_s]
112
                            clusters_in_ds[host.key.parent._ref.to_s] = host.key.parent.name
113
                        end
114
                    end
115

  
116
                    clusters_in_ds.each do |ccr_ref, ccr_name|
117
                        already_image_ds = VCenterDriver::Storage.exists_one_by_ref_ccr_and_type?(ds["_ref"], ccr_ref, vcenter_uuid, "IMAGE_DS", pool)
118

  
119
                        if !already_image_ds
120
                            object = ds.to_one_template(one_clusters[dc_name], ccr_ref, ccr_name, "IMAGE_DS", vcenter_uuid)
121
                            ds_objects[dc_name] << object if !object.nil?
122
                        end
123

  
124
                        already_system_ds = VCenterDriver::Storage.exists_one_by_ref_ccr_and_type?(ds["_ref"], ccr_ref, vcenter_uuid, "SYSTEM_DS", pool)
125

  
126
                        if !already_system_ds
127
                            object = ds.to_one_template(one_clusters[dc_name], ccr_ref, ccr_name, "SYSTEM_DS", vcenter_uuid)
128
                            ds_objects[dc_name] << object if !object.nil?
129
                        end
130
                    end
131
                end
132

  
133
                if ds.instance_of? VCenterDriver::StoragePod
134
                    clusters_in_spod = {}
135
                    ds_in_spod = ds['children']
136

  
137
                    ds_in_spod.each do |sp_ds|
138
                        hosts_in_ds = sp_ds.host
139
                        hosts_in_ds.each do |host|
140
                            if !clusters_in_spod[host.key.parent._ref.to_s]
141
                                clusters_in_spod[host.key.parent._ref.to_s] = host.key.parent.name
142
                            end
143
                        end
144
                    end
145

  
146
                    clusters_in_spod.each do |ccr_ref, ccr_name|
147
                        already_system_ds = VCenterDriver::Storage.exists_one_by_ref_ccr_and_type?(ds["_ref"], ccr_ref, vcenter_uuid, "SYSTEM_DS", pool)
148

  
149
                        if !already_system_ds
150
                            object = ds.to_one_template(one_clusters[dc_name], ccr_ref, ccr_name, "SYSTEM_DS", vcenter_uuid)
151
                            ds_objects[dc_name] << object if !object.nil?
152
                        end
153
                    end
154
                end
155
            end
156
        end
157

  
158
        ds_objects
159
    end
160

  
161
    def get_unimported_templates(vi_client)
162
        template_objects = {}
163
        vcenter_uuid = get_vcenter_instance_uuid
164
        tpool = VCenterDriver::VIHelper.one_pool(OpenNebula::TemplatePool, false)
165

  
166
        if tpool.respond_to?(:message)
167
            raise "Could not get OpenNebula TemplatePool: #{tpool.message}"
168
        end
169

  
170
        fetch! if @items.empty? #Get datacenters
171

  
172
        @items.values.each do |dc|
173

  
174
            dc_name = dc.item.name
175
            template_objects[dc_name] = []
176

  
177
            #Get datastores available in a datacenter
178
            ds_list = []
179
            datastore_folder = dc.datastore_folder
180
            datastore_folder.fetch!
181
            datastore_folder.items.values.each do |ds|
182
                ds_hash = {}
183
                ds_hash[:name] = ds["name"]
184
                ds_hash[:ref] = ds["_ref"]
185
                ds_list << ds_hash
186
            end
187

  
188
            #Get templates defined in a datacenter
189
            vm_folder = dc.vm_folder
190
            vm_folder.fetch_templates!
191
            vm_folder.items.values.each do |template|
192
                one_template = VCenterDriver::VIHelper.find_by_ref(OpenNebula::TemplatePool,
193
                                                                   "TEMPLATE/VCENTER_TEMPLATE_REF",
194
                                                                   template['_ref'],
195
                                                                   vcenter_uuid,
196
                                                                   tpool)
197
                next if one_template #If the template has been already imported
198

  
199
                template_name = template['name']
200
                template_ref  = template['_ref']
201
                template_ccr  = template['runtime.host.parent']
202
                cluster_name  = template['runtime.host.parent.name']
203

  
204
                #Get DS list
205
                ds = ""
206
                default_ds = nil
207
                if !ds_list.empty?
208
                    ds_name_list = []
209
                    ds_list.each do |ds_hash|
210
                        ds_name_list << ds_hash[:name]
211
                    end
212
                    ds =  "M|list|Which datastore you want this VM to run in? "
213
                    ds << "|#{ds_name_list.join(",")}" #List of DS
214
                    ds << "|#{ds_name_list.first}" #Default DS
215
                    default_ds = ds_name_list.first
216
                end
217

  
218
                #Get resource pools
219
                rp_cache = {}
220
                if !rp_cache[template_ccr.name.to_s]
221
                    tmp_cluster = VCenterDriver::ClusterComputeResource.new_from_ref(template_ccr._ref, vi_client)
222
                    rp_list = tmp_cluster.get_resource_pool_list
223
                    rp = ""
224
                    if !rp_list.empty?
225
                        rp_name_list = []
226
                        rp_list.each do |rp_hash|
227
                            rp_name_list << rp_hash[:name]
228
                        end
229
                        rp =  "M|list|Which resource pool you want this VM to run in? "
230
                        rp << "|#{rp_name_list.join(",")}" #List of RP
231
                        rp << "|#{rp_name_list.first}" #Default RP
232
                    end
233
                    rp_cache[template_ccr.name.to_s] = rp
234
                end
235
                rp = rp_cache[template_ccr.name.to_s]
236

  
237
                object = template.to_one_template(template_name,
238
                                                  template_ref,
239
                                                  template_ccr._ref,
240
                                                  cluster_name,
241
                                                  ds,
242
                                                  ds_list,
243
                                                  default_ds,
244
                                                  rp,
245
                                                  rp_list,
246
                                                  vcenter_uuid)
247

  
248
                template_objects[dc_name] << object if !object.nil?
249
            end #template loop
250
        end #datacenter loop
251
        return template_objects
252
    end
253

  
254
    def get_unimported_networks
255

  
256
        network_objects = {}
257
        vcenter_uuid = get_vcenter_instance_uuid
258
        npool = VCenterDriver::VIHelper.one_pool(OpenNebula::VirtualNetworkPool, false)
259

  
260
        if npool.respond_to?(:message)
261
            raise "Could not get OpenNebula VirtualNetworkPool: #{npool.message}"
262
        end
263

  
264
        fetch! if @items.empty? #Get datacenters
265

  
266
        @items.values.each do |dc|
267

  
268
            dc_name = dc.item.name
269
            network_objects[dc_name] = []
270

  
271
            #Get networks defined in a datacenter
272
            network_folder = dc.network_folder
273
            network_folder.fetch!
274
            network_folder.items.values.each do |network|
275

  
276
                one_network = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualNetworkPool,
277
                                                                  "TEMPLATE/VCENTER_NET_REF",
278
                                                                  network['_ref'],
279
                                                                  vcenter_uuid,
280
                                                                  npool)
281
                next if one_network #If the network has been already imported
282

  
283
                network_name = network['name']
284
                network_ref  = network['_ref']
285

  
286
                # TODO slow VLAN_ID retrieve for portgroups! set to nil
287
                vlan_id = ""
288
                if network.class == VCenterDriver::DistributedPortGroup
289
                    vlan_id = network.vlan_id
290
                end
291

  
292
                network.clusters.each do |ccr_ref, ccr_name|
293
                    one_vnet = VCenterDriver::Network.to_one_template(network_name,
294
                                                                      network_ref,
295
                                                                      network.network_type,
296
                                                                      vlan_id,
297
                                                                      ccr_ref,
298
                                                                      ccr_name,
299
                                                                      vcenter_uuid)
300
                    network_objects[dc_name] << one_vnet
301
                end #network clusters loop
302
            end # network loop
303
        end #datacenters loop
304

  
305
        return network_objects
306

  
307
    end
308

  
36 309
end # class DatatacenterFolder
37 310

  
38 311
class Datacenter
src/vmm_mad/remotes/lib/vcenter_driver/datastore.rb
77 77

  
78 78
        "USED_MB=#{used_mb}\nFREE_MB=#{free_mb} \nTOTAL_MB=#{total_mb}"
79 79
    end
80

  
81
    def self.exists_one_by_ref_ccr_and_type?(ref, ccr_ref, vcenter_uuid, type, pool = nil)
82
        pool = VCenterDriver::VIHelper.one_pool(OpenNebula::DatastorePool, false) if pool.nil?
83
        elements = pool.select{|e|
84
            e["TEMPLATE/TYPE"] == type &&
85
            e["TEMPLATE/VCENTER_DS_REF"] == ref &&
86
            e["TEMPLATE/VCENTER_CCR_REF"] == ccr_ref &&
87
            e["TEMPLATE/VCENTER_INSTANCE_ID"] == vcenter_uuid}
88

  
89
        return elements.size == 1
90
    end
91

  
92
    def to_one(ds_name, vcenter_uuid, ccr_ref, host_id)
93
        one = ""
94
        one << "NAME=\"#{ds_name}\"\n"
95
        one << "TM_MAD=vcenter\n"
96
        one << "VCENTER_INSTANCE_ID=\"#{vcenter_uuid}\"\n"
97
        one << "VCENTER_CCR_REF=\"#{ccr_ref}\"\n"
98
        one << "VCENTER_DS_REF=\"#{self['_ref']}\"\n"
99
        one << "VCENTER_ONE_HOST_ID=\"#{host_id}\"\n"
100

  
101
        return one
102
    end
103

  
104
    def to_one_template(one_clusters, ccr_ref, ccr_name, type, vcenter_uuid, one)
105

  
106
        one_cluster = one_clusters.select { |ccr| ccr[:ref] == ccr_ref }.first rescue nil
107

  
108
        return nil if one_cluster.nil?
109

  
110
        ds_name = ""
111

  
112
        if type == "IMAGE_DS"
113
            ds_name = "#{self['name']} - #{ccr_name} (IMG)"
114
        else
115
            ds_name = "#{self['name']} - #{ccr_name} (SYS)"
116
        end
117

  
118
        one_tmp = {
119
            :name     => ds_name,
120
            :total_mb => ((self['summary.capacity'].to_i / 1024) / 1024),
121
            :free_mb  => ((self['summary.freeSpace'].to_i / 1024) / 1024),
122
            :cluster  => ccr_name,
123
            :one  => to_one(ds_name, vcenter_uuid, ccr_ref, one_cluster[:host_id])
124
        }
125

  
126
        if type == "SYSTEM_DS"
127
            one_tmp[:one] << "TYPE=SYSTEM_DS\n"
128
        else
129
            one_tmp[:one] << "DS_MAD=vcenter\n"
130
            one_tmp[:one] << "TYPE=IMAGE_DS\n"
131
        end
132

  
133
        return one_tmp
134
    end
135

  
136

  
80 137
end # class Storage
81 138

  
82 139
class StoragePod < Storage
......
215 272
    # Get file size for image handling
216 273
    def stat(img_str)
217 274
        ds_name = self['name']
218

  
219 275
        img_path = File.dirname img_str
220 276
        img_name = File.basename img_str
221 277

  
222 278
        # Create Search Spec
223
        spec         = RbVmomi::VIM::HostDatastoreBrowserSearchSpec.new
224
        spec.query   = [RbVmomi::VIM::VmDiskFileQuery.new,
225
                        RbVmomi::VIM::IsoImageFileQuery.new]
226
        spec.details = RbVmomi::VIM::FileQueryFlags(:fileOwner    => true,
227
                                                    :fileSize     => true,
228
                                                    :fileType     => true,
229
                                                    :modification => true)
230
        spec.matchPattern=[img_name]
231

  
232
        search_params = {'datastorePath' => "[#{ds_name}] #{img_path}",
233
                         'searchSpec'    => spec}
279
        search_params = get_search_params(ds_name, img_path, img_name)
234 280

  
235 281
        # Perform search task and return results
236 282
        begin
......
250 296
        end
251 297
    end
252 298

  
299
    def get_search_params(ds_name, img_path=nil, img_name=nil)
300
        spec         = RbVmomi::VIM::HostDatastoreBrowserSearchSpec.new
301
        spec.query   = [RbVmomi::VIM::VmDiskFileQuery.new,
302
                        RbVmomi::VIM::IsoImageFileQuery.new]
303
        spec.details = RbVmomi::VIM::FileQueryFlags(:fileOwner    => true,
304
                                                    :fileSize     => true,
305
                                                    :fileType     => true,
306
                                                    :modification => true)
307

  
308

  
309
        spec.matchPattern = img_name.nil? ? [] : [img_name]
310

  
311
        datastore_path = "[#{ds_name}]"
312
        datastore_path << " #{img_path}" if !img_path.nil?
313

  
314
        search_params = {'datastorePath' => datastore_path,
315
                         'searchSpec'    => spec}
316

  
317
        return search_params
318
    end
319

  
253 320
    def get_fm
254 321
        self['_connection.serviceContent.fileManager']
255 322
    end
......
347 414
        return output
348 415
    end
349 416

  
417
    def get_images(vcenter_uuid)
418
        img_templates = []
419
        ds_id = nil
420
        ds_name = self['name']
421

  
422
        img_types = ["FloppyImageFileInfo",
423
                     "IsoImageFileInfo",
424
                     "VmDiskFileInfo"]
425

  
426
        ipool = VCenterDriver::VIHelper.one_pool(OpenNebula::ImagePool, false)
427
        if ipool.respond_to?(:message)
428
            raise "Could not get OpenNebula ImagePool: #{pool.message}"
429
        end
430

  
431
        dpool = VCenterDriver::VIHelper.one_pool(OpenNebula::DatastorePool, false)
432
        if dpool.respond_to?(:message)
433
            raise "Could not get OpenNebula DatastorePool: #{pool.message}"
434
        end
435

  
436
        begin
437
            one_ds = VCenterDriver::VIHelper.find_by_ref(OpenNebula::DatastorePool,
438
                                                        "TEMPLATE/VCENTER_DS_REF",
439
                                                        self["_ref"],
440
                                                        vcenter_uuid,
441
                                                        dpool)
442
            raise "Could not find OpenNebula Datastore" if one_ds.nil?
443
            ds_id = one_ds["ID"]
444
        rescue Exception => e
445
            raise "Error: #{e.message}"
446
        end
447

  
448
        begin
449
            # Create Search Spec
450
            search_params = get_search_params(ds_name)
451

  
452
            # Perform search task and return results
453
            search_task = self['browser'].
454
                SearchDatastoreSubFolders_Task(search_params)
455
            search_task.wait_for_completion
456

  
457
            search_task.info.result.each { |image|
458
                folderpath = ""
459
                if image.folderPath[-1] != "]"
460
                    folderpath = image.folderPath.sub(/^\[#{ds_name}\] /, "")
461
                end
462

  
463
                image = image.file.first
464

  
465
                # Skip not relevant files
466
                next if !img_types.include? image.class.to_s
467

  
468
                # Get image path and name
469
                image_path = folderpath
470
                image_path << image.path
471
                image_name = File.basename(image.path).reverse.sub("kdmv.","").reverse
472

  
473
                # Get image and disk type
474
                image_type = image.class.to_s == "VmDiskFileInfo" ? "OS" : "CDROM"
475
                disk_type = image.class.to_s == "VmDiskFileInfo" ? image.diskType : nil
476

  
477
                #Set template
478
                one_image =  "NAME=\"#{image_name} - #{ds_name}\"\n"
479
                one_image << "PATH=\"vcenter://#{image_path}\"\n"
480
                one_image << "PERSISTENT=\"YES\"\n"
481
                one_image << "TYPE=\"#{image_type}\"\n"
482
                one_image << "DISK_TYPE=\"#{disk_type}\"\n" if disk_type
483

  
484
                if VCenterDriver::VIHelper.find_by_name(OpenNebula::ImagePool,
485
                                                        "#{image_name} - #{ds_name}",
486
                                                        ipool,
487
                                                        false).nil?
488
                    img_templates << {
489
                        :name        => "#{image_name} - #{ds_name}",
490
                        :path        => image_path,
491
                        :size        => (image.fileSize / 1024).to_s,
492
                        :type        => image.class.to_s,
493
                        :dsid        => ds_id,
494
                        :one         => one_image
495
                    }
496
                end
497
            }
498

  
499
        rescue
500
            raise "Could not find images."
501
        end
502

  
503
        return img_templates
504
    end
505

  
350 506
    # This is never cached
351 507
    def self.new_from_ref(ref, vi_client)
352 508
        self.new(RbVmomi::VIM::Datastore.new(vi_client.vim, ref), vi_client)
src/vmm_mad/remotes/lib/vcenter_driver/host.rb
1 1
module VCenterDriver
2 2

  
3 3
class HostFolder
4
    attr_accessor :item, :clusters
4
    attr_accessor :item, :items
5 5

  
6 6
    def initialize(item)
7 7
        @item = item
8
        @clusters = {}
8
        @items = {}
9 9
    end
10 10

  
11 11
    def fetch_clusters!
12 12
        VIClient.get_entities(@item, 'ClusterComputeResource').each do |item|
13 13
            item_name = item._ref
14
            @clusters[item_name.to_sym] = ClusterComputeResource.new(item)
14
            @items[item_name.to_sym] = ClusterComputeResource.new(item)
15 15
        end
16 16
    end
17 17

  
18 18
    def get_cluster(ref)
19
        if !@clusters[ref.to_sym]
19
        if !@items[ref.to_sym]
20 20
            rbvmomi_dc = RbVmomi::VIM::ClusterComputeResource.new(@item._connection, ref)
21
            @clusters[ref.to_sym] = ClusterComputeResource.new(rbvmomi_dc)
21
            @items[ref.to_sym] = ClusterComputeResource.new(rbvmomi_dc)
22 22
        end
23 23

  
24
        @clusters[ref.to_sym]
24
        @items[ref.to_sym]
25 25
    end
26 26
end # class HostFolder
27 27

  
......
53 53
        @resource_pools
54 54
    end
55 55

  
56
    def get_resource_pool_list(rp = nil, parent_prefix = "", rp_array = [])
57

  
58
        current_rp = ""
59

  
60
        if rp.nil?
61
            rp = @item.resourcePool
62
        else
63
            if !parent_prefix.empty?
64
                current_rp << parent_prefix
65
                current_rp << "/"
66
            end
67
            current_rp << rp.name
68
        end
69

  
70
        if rp.resourcePool.size == 0
71
            rp_info = {}
72
            rp_info[:name] = current_rp
73
            rp_info[:ref]  = rp._ref
74
            rp_array << rp_info
75
        else
76
            rp.resourcePool.each do |child_rp|
77
                get_resource_pool_list(child_rp, current_rp, rp_array)
78
            end
79
            rp_info = {}
80
            rp_info[:name] = current_rp
81
            rp_info[:ref]  = rp._ref
82
            rp_array << rp_info if !current_rp.empty?
83
        end
84

  
85
        rp_array
86
    end
87

  
56 88
    def monitor
57 89
        #Load the host systems
58 90
        summary = @item.summary
......
236 268
                }
237 269

  
238 270
                if number == -1
239
                    vm_template_64 = Base64.encode64(vm.to_one(ccr_host)).gsub("\n","")
271
                    vm_template_64 = Base64.encode64(vm.to_one).gsub("\n","")
240 272

  
241 273
                    str_info << "IMPORT_TEMPLATE=\"#{vm_template_64}\","
242 274
                end
......
281 313
        Datacenter.new(item)
282 314
    end
283 315

  
316
    def self.to_one(name, host, user, pass, ref, vc_uuid)
317

  
318
        one_host = VCenterDriver::VIHelper.one_item(OpenNebula::Host)
319

  
320
        if OpenNebula.is_error?(one_host)
321
            raise "Could not create host: #{one_host.message}"
322
        end
323

  
324
        rc = one_host.allocate(name, 'vcenter', 'vcenter',
325
                ::OpenNebula::ClusterPool::NONE_CLUSTER_ID)
326

  
327
        if OpenNebula.is_error?(rc)
328
            raise "Could not allocate host: #{rc.message}"
329
        end
330

  
331
        template = "VCENTER_HOST=\"#{host}\"\n"\
332
                   "VCENTER_PASSWORD=\"#{pass}\"\n"\
333
                   "VCENTER_USER=\"#{user}\"\n"\
334
                   "VCENTER_CCR_REF=\"#{ref}\"\n"\
335
                   "VCENTER_INSTANCE_ID=\"#{vc_uuid}\"\n"
336

  
337
        rc = one_host.update(template, false)
338

  
339
        if OpenNebula.is_error?(rc)
340
            update_error = rc.message
341
            rc = one_host.delete
342
            if OpenNebula.is_error?(rc)
343
                raise "Could not update host: #{update_error} "\
344
                      "and could not delete host: #{rc.message}"
345
            else
346
                raise "Could not update host: #{rc.message}"
347
            end
348
        end
349

  
350
        return one_host
351
    end
352

  
284 353
    def self.new_from_ref(ref, vi_client)
285 354
        self.new(RbVmomi::VIM::ClusterComputeResource.new(vi_client.vim, ref), vi_client)
286 355
    end
src/vmm_mad/remotes/lib/vcenter_driver/importer.rb
1
module VCenterDriver
2

  
3
class Importer
4

  
5
def self.import_clusters(con_ops, options)
6
    begin
7
        STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
8

  
9
        vi_client = VCenterDriver::VIClient.new(con_ops)
10

  
11
        STDOUT.print "done!\n\n"
12

  
13
        STDOUT.print "Exploring vCenter resources..."
14

  
15
        dc_folder = VCenterDriver::DatacenterFolder.new(vi_client)
16

  
17
        # Get vcenter intance uuid as moref is unique for each vcenter
18
        vc_uuid = dc_folder.get_vcenter_instance_uuid
19

  
20
        rs = dc_folder.get_unimported_objects(OpenNebula::HostPool, vc_uuid)
21

  
22
        STDOUT.print "done!\n\n"
23

  
24
        rs.each {|dc, cluster|
25
            STDOUT.print "Do you want to process datacenter #{dc} (y/[n])? "
26

  
27
            next if STDIN.gets.strip.downcase != 'y'
28

  
29
            if cluster.empty?
30
                STDOUT.puts "    No new clusters found in #{dc}..."
31
                next
32
            end
33

  
34
            cluster.each{ |c|
35
                imported_name = "#{c["name"]}"
36
                STDOUT.print "  * Import cluster #{imported_name} (y/[n])? "
37

  
38
                next if STDIN.gets.strip.downcase != 'y'
39

  
40

  
41
                one_host = VCenterDriver::ClusterComputeResource
42
                                                    .to_one(imported_name,
43
                                                            con_ops[:host],
44
                                                            con_ops[:user],
45
                                                            con_ops[:password],
46
                                                            c['_ref'],
47
                                                            vc_uuid)
48

  
49
                STDOUT.puts "    OpenNebula host #{imported_name} with "\
50
                            " id #{one_host.id} successfully created."
51

  
52

  
53
                STDOUT.puts
54
            }
55
        }
56
    rescue Interrupt => e
57
        puts "\n"
58
        exit 0 #Ctrl+C
59
    rescue Exception => e
60
        STDOUT.puts "    Error: #{e.message}/\n#{e.backtrace}"
61
    ensure
62
        vi_client.close_connection if vi_client
63
    end
64

  
65
end
66

  
67
def self.import_templates(con_ops, options)
68
    begin
69
        STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
70

  
71
        vi_client = VCenterDriver::VIClient.new(con_ops)
72

  
73
        STDOUT.print "done!\n\n"
74

  
75
        STDOUT.print "Looking for VM Templates..."
76

  
77
        dc_folder = VCenterDriver::DatacenterFolder.new(vi_client)
78

  
79
        rs = dc_folder.get_unimported_templates(vi_client)
80

  
81
        STDOUT.print "done!\n"
82

  
83
        rs.each {|dc, tmps|
84
            STDOUT.print "\nDo you want to process datacenter #{dc}"\
85
                            " (y/[n])? "
86

  
87
            next if STDIN.gets.strip.downcase != 'y'
88

  
89
            if tmps.empty?
90
                STDOUT.print "    No new VM Templates found in #{dc}...\n\n"
91
                next
92
            end
93

  
94
            tmps.each{ |t|
95

  
96
                STDOUT.print "\n  * VM Template found:\n"\
97
                                "      - Name   : #{t[:name]}\n"\
98
                                "      - Moref  : #{t[:vcenter_ref]}\n"\
99
                                "      - Cluster: #{t[:cluster_name]}\n"\
100
                                "    Import this VM template (y/[n])? "
101

  
102
                next if STDIN.gets.strip.downcase != 'y'
103

  
104

  
105
                ds_input = ""
106

  
107
                STDOUT.print "\n    This template is currently set to be "\
108
                                "deployed in datastore #{t[:default_ds]}."\
109
                            "\n    Press y to keep the default, n to select"\
110
                            " a new default datastore or d to delegate "\
111
                            " the choice to the user ([y]/n/d)? "
112

  
113
                answer =  STDIN.gets.strip.downcase
114

  
115
                case answer
116
                when 'd'
117
                    ds_split     = t[:ds].split("|")
118
                    list_of_ds   = ds_split[-2]
119
                    default_ds   = ds_split[-1]
120
                    ds_input     = ds_split[0] + "|" + ds_split[1] + "|" +
121
                                    ds_split[2] + "|"
122

  
123
                    # Available list of datastores
124

  
125
                    input_str = "    The list of available datastores to be"\
126
                                " presented to the user are \"#{list_of_ds}\""
127
                    input_str+= "\n    Press y to agree, or input a comma"\
128
                                " separated list of datastores to edit "\
129
                                "[y/comma separated list] "
130
                    STDOUT.print input_str
131

  
132
                    answer = STDIN.gets.strip
133

  
134
                    if answer.downcase == 'y'
135
                        ds_input += ds_split[3] + "|"
136
                    else
137
                        ds_input += answer + "|"
138
                    end
139

  
140
                    # Default
141
                    input_str   = "    The default datastore presented to "\
142
                                "the end user is set to \"#{default_ds}\"."
143
                    input_str+= "\n    Press y to agree, or input a new "\
144
                                "datastore [y/datastore name] "
145
                    STDOUT.print input_str
146

  
147
                    answer = STDIN.gets.strip
148

  
149
                    if answer.downcase == 'y'
150
                        ds_input += ds_split[4]
151
                    else
152
                        ds_input += answer
153
                    end
154
                when 'n'
155
                    ds_split     = t[:ds].split("|")
156
                    list_of_ds   = ds_split[-2]
157

  
158
                    input_str = "    The list of available datastores is:\n"
159

  
160
                    STDOUT.print input_str
161

  
162
                    dashes = ""
163
                    100.times do
164
                        dashes << "-"
165
                    end
166

  
167
                    list_str = "\n    [Index] Datastore :"\
168
                                "\n    #{dashes}\n"
169

  
170
                    STDOUT.print list_str
171

  
172
                    index = 1
173
                    t[:ds_list].each do |ds|
174
                        list_str = "    [#{index}] #{ds[:name]}\n"
175
                        index += 1
176
                        STDOUT.print list_str
177
                    end
178

  
179
                    input_str = "\n    Please input the new default"\
180
                                " datastore index in the list (e.g 1): "
181

  
182
                    STDOUT.print input_str
183

  
184
                    answer = STDIN.gets.strip
185

  
186
                    t[:one] += "VCENTER_DS_REF=\"#{t[:ds_list][answer.to_i - 1][:ref]}\"\n"
187
                end
188

  
189
                # Resource Pools
190
                rp_input = ""
191
                rp_split = t[:rp].split("|")
192

  
193
                if rp_split.size > 3
194
                    STDOUT.print "\n    This template is currently set to "\
195
                        "launch VMs in the default resource pool."\
196
                        "\n    Press y to keep this behaviour, n to select"\
197
                        " a new resource pool or d to delegate the choice"\
198
                        " to the user ([y]/n/d)? "
199

  
200
                    answer =  STDIN.gets.strip.downcase
201

  
202
                    case answer
203
                    when 'd'
204
                        list_of_rp   = rp_split[-2]
205
                        default_rp   = rp_split[-1]
206
                        rp_input     = rp_split[0] + "|" + rp_split[1] + "|" +
207
                                        rp_split[2] + "|"
208

  
209
                        # Available list of resource pools
210
                        input_str = "    The list of available resource pools "\
211
                                    "to be presented to the user are "\
212
                                    "\"#{list_of_rp}\""
213
                        input_str+= "\n    Press y to agree, or input a comma"\
214
                                    " separated list of resource pools to edit "\
215
                                    "[y/comma separated list] "
216
                        STDOUT.print input_str
217

  
218
                        answer = STDIN.gets.strip
219

  
220
                        if answer.downcase == 'y'
221
                            rp_input += rp_split[3] + "|"
222
                        else
223
                            rp_input += answer + "|"
224
                        end
225

  
226
                        # Default
227
                        input_str   = "    The default resource pool presented "\
228
                                        "to the end user is set to"\
229
                                        " \"#{default_rp}\"."
230
                        input_str+= "\n    Press y to agree, or input a new "\
231
                                    "resource pool [y/resource pool name] "
232
                        STDOUT.print input_str
233

  
234
                        answer = STDIN.gets.strip
235

  
236
                        if answer.downcase == 'y'
237
                            rp_input += rp_split[4]
238
                        else
239
                            rp_input += answer
240
                        end
241
                    when 'n'
242

  
243
                        list_of_rp   = rp_split[-2]
244

  
245
                        input_str = "    The list of available resource pools is:\n"
246

  
247
                        STDOUT.print input_str
248

  
249
                        dashes = ""
250
                        100.times do
251
                            dashes << "-"
252
                        end
253

  
254
                        list_str = "\n    [Index] Resource pool :"\
255
                                    "\n    #{dashes}\n"
256

  
257
                        STDOUT.print list_str
258

  
259
                        index = 1
260
                        t[:rp_list].each do |rp|
261
                            list_str = "    [#{index}] #{rp[:name]}\n"
262
                            index += 1
263
                            STDOUT.print list_str
264
                        end
265

  
266
                        input_str = "\n    Please input the new default"\
267
                                    " resource pool index in the list (e.g 1): "
268

  
269
                        STDOUT.print input_str
270

  
271
                        answer = STDIN.gets.strip
272

  
273
                        t[:one] << "VCENTER_RP_REF=\"#{t[:rp_list][answer.to_i - 1][:ref]}\"\n"
274
                    end
275
                end
276

  
277
                if !ds_input.empty? || !rp_input.empty?
278
                    t[:one] << "USER_INPUTS=["
279
                    t[:one] << "VCENTER_DS_LIST=\"#{ds_input}\"," if !ds_input.empty?
280
                    t[:one] << "VCENTER_RP_LIST=\"#{rp_input}\"," if !rp_input.empty?
281
                    t[:one] = t[:one][0..-2]
282
                    t[:one] << "]"
283
                end
284

  
285
                one_t = VCenterDriver::VIHelper.new_one_item(OpenNebula::Template)
286

  
287
                rc = one_t.allocate(t[:one])
288

  
289
                if ::OpenNebula.is_error?(rc)
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff