diff --git a/src/oca/ruby/opennebula/marketplaceapp_ext.rb b/src/oca/ruby/opennebula/marketplaceapp_ext.rb index 94b4363464..bb2bc788ac 100644 --- a/src/oca/ruby/opennebula/marketplaceapp_ext.rb +++ b/src/oca/ruby/opennebula/marketplaceapp_ext.rb @@ -185,9 +185,34 @@ module OpenNebula::MarketPlaceAppExt #--------------------------------------------------------------- # Created an associated VMTemplate if needed #--------------------------------------------------------------- - if (self['TEMPLATE/VMTEMPLATE64'].nil? && !is_vcenter) || - options[:notemplate] || - options[:template] == -1 + if is_vcenter + ret = create_vcenter_template(ds) + + tmpl = <<-EOT + NAME = "#{options[:vmtemplate_name] || options[:name]}" + DISK = [ IMAGE_ID = "#{image.id}" ] + CPU = "1" + VCPU = "1" + MEMORY = "128" + HYPERVISOR = "vcenter" + EOT + + ret.each do |key, value| + tmpl << "#{key}=\"#{value}\"\n" + end + + vmtpl = Template.new(Template.build_xml, @client) + + rc = vmtpl.allocate(tmpl) + rc = vmtpl.id unless OpenNebula.is_error?(rc) + + rc_info[:vmtemplate] = [rc] + return rc_info + end + + if self['TEMPLATE/VMTEMPLATE64'].nil? || + options[:notemplate] || + options[:template] == -1 return rc_info end @@ -286,6 +311,88 @@ module OpenNebula::MarketPlaceAppExt rc end + # Create a VM template in vCenter in order to use it when + # deploying an app from the marketplace + # + # @param ds [OpenNebula::Datastore] Datastore information + def create_vcenter_template(ds) + ret = {} + keys = %w[VCENTER_TEMPLATE_REF + VCENTER_CCR_REF + VCENTER_INSTANCE_ID] + + if ds['//VCENTER_TEMPLATE_REF'] + keys.each do |key| + ret[key] = ds["//#{key}"] + end + + return ret + end + + require 'vcenter_driver' + + # Get vi client for current datastore + vi_client = VCenterDriver::VIClient.new_from_datastore(ds.id) + + # Get datastore object + ds_ref = ds['//VCENTER_DS_REF'] + datastore = VCenterDriver::Datastore.new_from_ref( + ds_ref, + vi_client + ) + + # Get resource pool + host_ref = datastore['host'].first.key.parent._ref + vi_client.ccr_ref = host_ref + + host = VCenterDriver::ClusterComputeResource.new_from_ref( + host_ref, + vi_client + ) + + rp = host.resource_pools.first + + # Get vCentrer instance ID + uuid = vi_client.vim.serviceContent.about.instanceUuid + + # Create VM folder it not exists + dc = datastore.obtain_dc.item + vm_folder = dc.find_folder('one_default_template') + + if vm_folder.nil? + dc.vmFolder.CreateFolder(:name => 'one_default_template') + vm_folder = dc.find_folder('one_default_template') + end + + # Define default VM config + vm_cfg = { :name => "one_app_template-#{ds.id}", + :guestId => 'otherGuest', + :numCPUs => 1, + :memoryMB => 128, + :files => { + :vmPathName => "[#{datastore.item.name}]" + } } + + # Create the VM + vm = vm_folder.CreateVM_Task( + :config => vm_cfg, + :pool => rp + ).wait_for_completion + + # Create the VM template + vm.MarkAsTemplate + + ret['VCENTER_TEMPLATE_REF'] = vm._ref + ret['VCENTER_CCR_REF'] = host_ref + ret['VCENTER_INSTANCE_ID'] = uuid + + ret.each do |key, value| + ds.update("#{key}=\"#{value}\"", true) + end + + ret + end + def update_options_with_template(options, _validate = false) vcenterrc_path = "#{VAR_LOCATION}/remotes/etc/vmm/vcenter/vcenterrc"