mirror of
https://github.com/OpenNebula/one.git
synced 2025-02-28 17:57:22 +03:00
F #4913: Add code required by Sunstone to import existing disks and nics in vcenter templates
This commit is contained in:
parent
212673429c
commit
fe8e9886bb
@ -99,7 +99,6 @@ get '/vcenter/templates' do
|
||||
error 404, error.to_json
|
||||
end
|
||||
|
||||
#ctemplates = templates.select{|t| t[:host] == params[:name]}
|
||||
[200, templates.to_json]
|
||||
rescue Exception => e
|
||||
logger.error("[vCenter] " + e.message)
|
||||
@ -108,6 +107,50 @@ get '/vcenter/templates' do
|
||||
end
|
||||
end
|
||||
|
||||
get '/vcenter/template/:vcenter_ref' do
|
||||
begin
|
||||
t = {}
|
||||
t[:one] = ""
|
||||
|
||||
template = VCenterDriver::VirtualMachine.new_from_ref(params[:vcenter_ref], vcenter_client)
|
||||
|
||||
vc_uuid = vcenter_client.vim.serviceContent.about.instanceUuid
|
||||
dpool = VCenterDriver::VIHelper.one_pool(OpenNebula::DatastorePool)
|
||||
ipool = VCenterDriver::VIHelper.one_pool(OpenNebula::ImagePool)
|
||||
npool = VCenterDriver::VIHelper.one_pool(OpenNebula::VirtualNetworkPool)
|
||||
|
||||
# Create images or get disks information for template
|
||||
error, template_disks = template.import_vcenter_disks(vc_uuid, dpool, ipool)
|
||||
|
||||
if !error.empty?
|
||||
msg = error
|
||||
logger.error("[vCenter] " + msg)
|
||||
error = Error.new(msg)
|
||||
error 404, error.to_json
|
||||
end
|
||||
|
||||
t[:one] << template_disks
|
||||
|
||||
# Create images or get nics information for template
|
||||
error, template_nics = template.import_vcenter_nics(vc_uuid, npool)
|
||||
|
||||
if !error.empty?
|
||||
msg = error
|
||||
logger.error("[vCenter] " + msg)
|
||||
error = Error.new(msg)
|
||||
error 404, error.to_json
|
||||
end
|
||||
|
||||
t[:one] << template_nics
|
||||
|
||||
[200, t.to_json]
|
||||
rescue Exception => e
|
||||
logger.error("[vCenter] " + e.message)
|
||||
error = Error.new(e.message)
|
||||
error 403, error.to_json
|
||||
end
|
||||
end
|
||||
|
||||
get '/vcenter/networks' do
|
||||
begin
|
||||
dc_folder = VCenterDriver::DatacenterFolder.new(vcenter_client)
|
||||
|
@ -236,6 +236,21 @@ class DatacenterFolder
|
||||
|
||||
template_ccr = template['runtime.host.parent']
|
||||
|
||||
# Check if template has nics or disks to be imported later
|
||||
has_nics_and_disks = false
|
||||
|
||||
template["config.hardware.device"].each do |device|
|
||||
if VCenterDriver::Storage.is_disk_or_iso?(device)
|
||||
has_nics_and_disks = true
|
||||
break
|
||||
end
|
||||
|
||||
if VCenterDriver::Network.is_nic?(device)
|
||||
has_nics_and_disks = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
#Get resource pools
|
||||
rp_cache = {}
|
||||
if !rp_cache[template_ccr.name.to_s]
|
||||
@ -256,6 +271,7 @@ class DatacenterFolder
|
||||
rp = rp_cache[template_ccr.name.to_s]
|
||||
|
||||
object = template.to_one_template(template,
|
||||
has_nics_and_disks,
|
||||
rp,
|
||||
rp_list,
|
||||
vcenter_uuid)
|
||||
|
@ -112,6 +112,13 @@ class Storage
|
||||
return element
|
||||
end
|
||||
|
||||
# Checks if a RbVmomi::VIM::VirtualDevice is a disk or an iso file
|
||||
def self.is_disk_or_iso?(device)
|
||||
is_disk = !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
|
||||
is_iso = device.backing.is_a? RbVmomi::VIM::VirtualCdromIsoBackingInfo
|
||||
is_disk || is_iso
|
||||
end
|
||||
|
||||
|
||||
def monitor
|
||||
summary = self['summary']
|
||||
|
@ -119,12 +119,12 @@ def self.import_templates(con_ops, options)
|
||||
|
||||
template = t[:template]
|
||||
|
||||
error, template_disks_and_nics = template.import_vcenter_disks(vc_uuid,
|
||||
error, template_disks = template.import_vcenter_disks(vc_uuid,
|
||||
dpool,
|
||||
ipool)
|
||||
|
||||
if error.empty?
|
||||
t[:one] << template_disks_and_nics
|
||||
t[:one] << template_disks
|
||||
else
|
||||
STDOUT.puts error
|
||||
next
|
||||
|
@ -61,6 +61,12 @@ class Network
|
||||
@item = item
|
||||
end
|
||||
|
||||
# Checks if a RbVmomi::VIM::VirtualDevice is a network interface
|
||||
def self.is_nic?(device)
|
||||
!device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil?
|
||||
end
|
||||
|
||||
|
||||
|
||||
def self.to_one_template(network_name, network_ref, network_type,
|
||||
ccr_ref, ccr_name, vcenter_uuid)
|
||||
|
@ -59,6 +59,22 @@ class VirtualMachine
|
||||
def initialize(item=nil, vi_client=nil)
|
||||
@item = item
|
||||
@vi_client = vi_client
|
||||
@locking = true
|
||||
end
|
||||
|
||||
# Locking function. Similar to flock
|
||||
def lock
|
||||
if @locking
|
||||
@locking_file = File.open("/tmp/vcenter-importer-lock","w")
|
||||
@locking_file.flock(File::LOCK_EX)
|
||||
end
|
||||
end
|
||||
|
||||
# Unlock driver execution mutex
|
||||
def unlock
|
||||
if @locking
|
||||
@locking_file.close
|
||||
end
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -1351,51 +1367,25 @@ class VirtualMachine
|
||||
disk_info = ""
|
||||
error = ""
|
||||
|
||||
ccr_ref = self["runtime.host.parent._ref"]
|
||||
begin
|
||||
lock #Lock import operation, to avoid concurrent creation of images
|
||||
|
||||
#Get disks and info required
|
||||
vc_disks = get_vcenter_disks
|
||||
ccr_ref = self["runtime.host.parent._ref"]
|
||||
|
||||
# Track allocated images
|
||||
allocated_images = []
|
||||
#Get disks and info required
|
||||
vc_disks = get_vcenter_disks
|
||||
|
||||
vc_disks.each do |disk|
|
||||
# Track allocated images
|
||||
allocated_images = []
|
||||
|
||||
datastore_found = VCenterDriver::Storage.get_one_image_ds_by_ref_and_ccr(disk[:datastore]._ref,
|
||||
ccr_ref,
|
||||
vc_uuid,
|
||||
dpool)
|
||||
if datastore_found.nil?
|
||||
error = " Error datastore #{disk[:datastore].name}: has to be imported first as an image datastore!\n"
|
||||
vc_disks.each do |disk|
|
||||
|
||||
#Rollback delete disk images
|
||||
allocated_images.each do |i|
|
||||
i.delete
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
|
||||
image_import = VCenterDriver::Datastore.get_image_import_template(disk[:datastore].name,
|
||||
disk[:path],
|
||||
disk[:type], ipool)
|
||||
#Image is already in the datastore
|
||||
if image_import[:one]
|
||||
# This is the disk info
|
||||
disk_info << "DISK=[\n"
|
||||
disk_info << "IMAGE_ID=\"#{image_import[:one]["ID"]}\",\n"
|
||||
disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
disk_info << "]\n"
|
||||
elsif !image_import[:template].empty?
|
||||
# Then the image is created as it's not in the datastore
|
||||
one_i = VCenterDriver::VIHelper.new_one_item(OpenNebula::Image)
|
||||
|
||||
allocated_images << one_i
|
||||
|
||||
rc = one_i.allocate(image_import[:template], datastore_found['ID'].to_i)
|
||||
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
error = " Error creating disk from template: #{rc.message}. Cannot import the template\n"
|
||||
datastore_found = VCenterDriver::Storage.get_one_image_ds_by_ref_and_ccr(disk[:datastore]._ref,
|
||||
ccr_ref,
|
||||
vc_uuid,
|
||||
dpool)
|
||||
if datastore_found.nil?
|
||||
error = " Error datastore #{disk[:datastore].name}: has to be imported first as an image datastore!\n"
|
||||
|
||||
#Rollback delete disk images
|
||||
allocated_images.each do |i|
|
||||
@ -1405,14 +1395,49 @@ class VirtualMachine
|
||||
break
|
||||
end
|
||||
|
||||
#Add info for One template
|
||||
one_i.info
|
||||
disk_info << "DISK=[\n"
|
||||
disk_info << "IMAGE_ID=\"#{one_i["ID"]}\",\n"
|
||||
disk_info << "IMAGE_UNAME=\"#{one_i["UNAME"]}\",\n"
|
||||
disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
disk_info << "]\n"
|
||||
image_import = VCenterDriver::Datastore.get_image_import_template(disk[:datastore].name,
|
||||
disk[:path],
|
||||
disk[:type], ipool)
|
||||
#Image is already in the datastore
|
||||
if image_import[:one]
|
||||
# This is the disk info
|
||||
disk_info << "DISK=[\n"
|
||||
disk_info << "IMAGE_ID=\"#{image_import[:one]["ID"]}\",\n"
|
||||
disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
disk_info << "]\n"
|
||||
elsif !image_import[:template].empty?
|
||||
# Then the image is created as it's not in the datastore
|
||||
one_i = VCenterDriver::VIHelper.new_one_item(OpenNebula::Image)
|
||||
|
||||
allocated_images << one_i
|
||||
|
||||
rc = one_i.allocate(image_import[:template], datastore_found['ID'].to_i)
|
||||
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
error = " Error creating disk from template: #{rc.message}. Cannot import the template\n"
|
||||
|
||||
#Rollback delete disk images
|
||||
allocated_images.each do |i|
|
||||
i.delete
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
|
||||
#Add info for One template
|
||||
one_i.info
|
||||
disk_info << "DISK=[\n"
|
||||
disk_info << "IMAGE_ID=\"#{one_i["ID"]}\",\n"
|
||||
disk_info << "IMAGE_UNAME=\"#{one_i["UNAME"]}\",\n"
|
||||
disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
disk_info << "]\n"
|
||||
end
|
||||
end
|
||||
|
||||
rescue Exception => e
|
||||
error = "There was an error trying to create an image for disk in vcenter template. Reason: #{e.message}"
|
||||
ensure
|
||||
unlock
|
||||
end
|
||||
|
||||
return error, disk_info
|
||||
@ -1479,69 +1504,78 @@ class VirtualMachine
|
||||
nic_info = ""
|
||||
error = ""
|
||||
|
||||
ccr_ref = self["runtime.host.parent._ref"]
|
||||
ccr_name = self["runtime.host.parent.name"]
|
||||
begin
|
||||
lock #Lock import operation, to avoid concurrent creation of images
|
||||
|
||||
#Get disks and info required
|
||||
vc_nics = get_vcenter_nics
|
||||
ccr_ref = self["runtime.host.parent._ref"]
|
||||
ccr_name = self["runtime.host.parent.name"]
|
||||
|
||||
# Track allocated networks
|
||||
allocated_networks = []
|
||||
#Get disks and info required
|
||||
vc_nics = get_vcenter_nics
|
||||
|
||||
vc_nics.each do |nic|
|
||||
# Track allocated networks
|
||||
allocated_networks = []
|
||||
|
||||
network_found = VCenterDriver::Network.get_one_vnet_ds_by_ref_and_ccr(nic[:net_ref],
|
||||
ccr_ref,
|
||||
vc_uuid,
|
||||
npool)
|
||||
#Network is already in the datastore
|
||||
if network_found
|
||||
# This is the existing nic info
|
||||
nic_info << "NIC=[\n"
|
||||
nic_info << "NETWORK_ID=\"#{network_found["ID"]}\",\n"
|
||||
nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
nic_info << "]\n"
|
||||
else
|
||||
# Then the network has to be created as it's not in OpenNebula
|
||||
one_vn = VCenterDriver::VIHelper.new_one_item(OpenNebula::VirtualNetwork)
|
||||
vc_nics.each do |nic|
|
||||
|
||||
allocated_networks << one_vn
|
||||
network_found = VCenterDriver::Network.get_one_vnet_ds_by_ref_and_ccr(nic[:net_ref],
|
||||
ccr_ref,
|
||||
vc_uuid,
|
||||
npool)
|
||||
#Network is already in the datastore
|
||||
if network_found
|
||||
# This is the existing nic info
|
||||
nic_info << "NIC=[\n"
|
||||
nic_info << "NETWORK_ID=\"#{network_found["ID"]}\",\n"
|
||||
nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
nic_info << "]\n"
|
||||
else
|
||||
# Then the network has to be created as it's not in OpenNebula
|
||||
one_vn = VCenterDriver::VIHelper.new_one_item(OpenNebula::VirtualNetwork)
|
||||
|
||||
one_vnet = VCenterDriver::Network.to_one_template(nic[:net_name],
|
||||
nic[:net_ref],
|
||||
nic[:pg_type],
|
||||
ccr_ref,
|
||||
ccr_name,
|
||||
vc_uuid)
|
||||
allocated_networks << one_vn
|
||||
|
||||
# By default add an ethernet range to network size 255
|
||||
ar_str = ""
|
||||
ar_str << "AR=[\n"
|
||||
ar_str << "TYPE=\"ETHER\",\n"
|
||||
ar_str << "SIZE=\"255\"\n"
|
||||
ar_str << "]\n"
|
||||
one_vnet[:one] << ar_str
|
||||
one_vnet = VCenterDriver::Network.to_one_template(nic[:net_name],
|
||||
nic[:net_ref],
|
||||
nic[:pg_type],
|
||||
ccr_ref,
|
||||
ccr_name,
|
||||
vc_uuid)
|
||||
|
||||
rc = one_vn.allocate(one_vnet[:one])
|
||||
# By default add an ethernet range to network size 255
|
||||
ar_str = ""
|
||||
ar_str << "AR=[\n"
|
||||
ar_str << "TYPE=\"ETHER\",\n"
|
||||
ar_str << "SIZE=\"255\"\n"
|
||||
ar_str << "]\n"
|
||||
one_vnet[:one] << ar_str
|
||||
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
error = " Error creating virtual network from template: #{rc.message}. Cannot import the template\n"
|
||||
rc = one_vn.allocate(one_vnet[:one])
|
||||
|
||||
#Rollback, delete virtual networks
|
||||
allocated_networks.each do |n|
|
||||
n.delete
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
error = " Error creating virtual network from template: #{rc.message}. Cannot import the template\n"
|
||||
|
||||
#Rollback, delete virtual networks
|
||||
allocated_networks.each do |n|
|
||||
n.delete
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
|
||||
break
|
||||
#Add info for One template
|
||||
one_vn.info
|
||||
nic_info << "NIC=[\n"
|
||||
nic_info << "NETWORK_ID=\"#{one_vn["ID"]}\",\n"
|
||||
nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
nic_info << "]\n"
|
||||
end
|
||||
|
||||
#Add info for One template
|
||||
one_vn.info
|
||||
nic_info << "NIC=[\n"
|
||||
nic_info << "NETWORK_ID=\"#{one_vn["ID"]}\",\n"
|
||||
nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
||||
nic_info << "]\n"
|
||||
end
|
||||
|
||||
rescue Exception => e
|
||||
error = "There was an error trying to create a virtual network for network in vcenter template. Reason: #{e.message}"
|
||||
ensure
|
||||
unlock
|
||||
end
|
||||
|
||||
return error, nic_info
|
||||
@ -1880,7 +1914,7 @@ class VirtualMachine
|
||||
return str
|
||||
end
|
||||
|
||||
def to_one_template(template, rp, rp_list, vcenter_uuid)
|
||||
def to_one_template(template, has_nics_and_disks, rp, rp_list, vcenter_uuid)
|
||||
|
||||
template_name = template['name']
|
||||
template_ref = template['_ref']
|
||||
@ -1898,6 +1932,7 @@ class VirtualMachine
|
||||
one_tmp[:rp] = rp
|
||||
one_tmp[:rp_list] = rp_list
|
||||
one_tmp[:template] = template
|
||||
one_tmp[:import_disks_and_nics] = has_nics_and_disks
|
||||
return one_tmp
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user