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
|
error 404, error.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
#ctemplates = templates.select{|t| t[:host] == params[:name]}
|
|
||||||
[200, templates.to_json]
|
[200, templates.to_json]
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
logger.error("[vCenter] " + e.message)
|
logger.error("[vCenter] " + e.message)
|
||||||
@ -108,6 +107,50 @@ get '/vcenter/templates' do
|
|||||||
end
|
end
|
||||||
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
|
get '/vcenter/networks' do
|
||||||
begin
|
begin
|
||||||
dc_folder = VCenterDriver::DatacenterFolder.new(vcenter_client)
|
dc_folder = VCenterDriver::DatacenterFolder.new(vcenter_client)
|
||||||
|
@ -236,6 +236,21 @@ class DatacenterFolder
|
|||||||
|
|
||||||
template_ccr = template['runtime.host.parent']
|
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
|
#Get resource pools
|
||||||
rp_cache = {}
|
rp_cache = {}
|
||||||
if !rp_cache[template_ccr.name.to_s]
|
if !rp_cache[template_ccr.name.to_s]
|
||||||
@ -256,6 +271,7 @@ class DatacenterFolder
|
|||||||
rp = rp_cache[template_ccr.name.to_s]
|
rp = rp_cache[template_ccr.name.to_s]
|
||||||
|
|
||||||
object = template.to_one_template(template,
|
object = template.to_one_template(template,
|
||||||
|
has_nics_and_disks,
|
||||||
rp,
|
rp,
|
||||||
rp_list,
|
rp_list,
|
||||||
vcenter_uuid)
|
vcenter_uuid)
|
||||||
|
@ -112,6 +112,13 @@ class Storage
|
|||||||
return element
|
return element
|
||||||
end
|
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
|
def monitor
|
||||||
summary = self['summary']
|
summary = self['summary']
|
||||||
|
@ -119,12 +119,12 @@ def self.import_templates(con_ops, options)
|
|||||||
|
|
||||||
template = t[:template]
|
template = t[:template]
|
||||||
|
|
||||||
error, template_disks_and_nics = template.import_vcenter_disks(vc_uuid,
|
error, template_disks = template.import_vcenter_disks(vc_uuid,
|
||||||
dpool,
|
dpool,
|
||||||
ipool)
|
ipool)
|
||||||
|
|
||||||
if error.empty?
|
if error.empty?
|
||||||
t[:one] << template_disks_and_nics
|
t[:one] << template_disks
|
||||||
else
|
else
|
||||||
STDOUT.puts error
|
STDOUT.puts error
|
||||||
next
|
next
|
||||||
|
@ -61,6 +61,12 @@ class Network
|
|||||||
@item = item
|
@item = item
|
||||||
end
|
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,
|
def self.to_one_template(network_name, network_ref, network_type,
|
||||||
ccr_ref, ccr_name, vcenter_uuid)
|
ccr_ref, ccr_name, vcenter_uuid)
|
||||||
|
@ -59,6 +59,22 @@ class VirtualMachine
|
|||||||
def initialize(item=nil, vi_client=nil)
|
def initialize(item=nil, vi_client=nil)
|
||||||
@item = item
|
@item = item
|
||||||
@vi_client = vi_client
|
@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
|
end
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
@ -1351,51 +1367,25 @@ class VirtualMachine
|
|||||||
disk_info = ""
|
disk_info = ""
|
||||||
error = ""
|
error = ""
|
||||||
|
|
||||||
ccr_ref = self["runtime.host.parent._ref"]
|
begin
|
||||||
|
lock #Lock import operation, to avoid concurrent creation of images
|
||||||
|
|
||||||
#Get disks and info required
|
ccr_ref = self["runtime.host.parent._ref"]
|
||||||
vc_disks = get_vcenter_disks
|
|
||||||
|
|
||||||
# Track allocated images
|
#Get disks and info required
|
||||||
allocated_images = []
|
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,
|
vc_disks.each do |disk|
|
||||||
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
|
datastore_found = VCenterDriver::Storage.get_one_image_ds_by_ref_and_ccr(disk[:datastore]._ref,
|
||||||
allocated_images.each do |i|
|
ccr_ref,
|
||||||
i.delete
|
vc_uuid,
|
||||||
end
|
dpool)
|
||||||
|
if datastore_found.nil?
|
||||||
break
|
error = " Error datastore #{disk[:datastore].name}: has to be imported first as an image datastore!\n"
|
||||||
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"
|
|
||||||
|
|
||||||
#Rollback delete disk images
|
#Rollback delete disk images
|
||||||
allocated_images.each do |i|
|
allocated_images.each do |i|
|
||||||
@ -1405,14 +1395,49 @@ class VirtualMachine
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
#Add info for One template
|
image_import = VCenterDriver::Datastore.get_image_import_template(disk[:datastore].name,
|
||||||
one_i.info
|
disk[:path],
|
||||||
disk_info << "DISK=[\n"
|
disk[:type], ipool)
|
||||||
disk_info << "IMAGE_ID=\"#{one_i["ID"]}\",\n"
|
#Image is already in the datastore
|
||||||
disk_info << "IMAGE_UNAME=\"#{one_i["UNAME"]}\",\n"
|
if image_import[:one]
|
||||||
disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
|
# This is the disk info
|
||||||
disk_info << "]\n"
|
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
|
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
|
end
|
||||||
|
|
||||||
return error, disk_info
|
return error, disk_info
|
||||||
@ -1479,69 +1504,78 @@ class VirtualMachine
|
|||||||
nic_info = ""
|
nic_info = ""
|
||||||
error = ""
|
error = ""
|
||||||
|
|
||||||
ccr_ref = self["runtime.host.parent._ref"]
|
begin
|
||||||
ccr_name = self["runtime.host.parent.name"]
|
lock #Lock import operation, to avoid concurrent creation of images
|
||||||
|
|
||||||
#Get disks and info required
|
ccr_ref = self["runtime.host.parent._ref"]
|
||||||
vc_nics = get_vcenter_nics
|
ccr_name = self["runtime.host.parent.name"]
|
||||||
|
|
||||||
# Track allocated networks
|
#Get disks and info required
|
||||||
allocated_networks = []
|
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],
|
vc_nics.each do |nic|
|
||||||
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)
|
|
||||||
|
|
||||||
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],
|
allocated_networks << one_vn
|
||||||
nic[:net_ref],
|
|
||||||
nic[:pg_type],
|
|
||||||
ccr_ref,
|
|
||||||
ccr_name,
|
|
||||||
vc_uuid)
|
|
||||||
|
|
||||||
# By default add an ethernet range to network size 255
|
one_vnet = VCenterDriver::Network.to_one_template(nic[:net_name],
|
||||||
ar_str = ""
|
nic[:net_ref],
|
||||||
ar_str << "AR=[\n"
|
nic[:pg_type],
|
||||||
ar_str << "TYPE=\"ETHER\",\n"
|
ccr_ref,
|
||||||
ar_str << "SIZE=\"255\"\n"
|
ccr_name,
|
||||||
ar_str << "]\n"
|
vc_uuid)
|
||||||
one_vnet[:one] << ar_str
|
|
||||||
|
|
||||||
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)
|
rc = one_vn.allocate(one_vnet[:one])
|
||||||
error = " Error creating virtual network from template: #{rc.message}. Cannot import the template\n"
|
|
||||||
|
|
||||||
#Rollback, delete virtual networks
|
if ::OpenNebula.is_error?(rc)
|
||||||
allocated_networks.each do |n|
|
error = " Error creating virtual network from template: #{rc.message}. Cannot import the template\n"
|
||||||
n.delete
|
|
||||||
|
#Rollback, delete virtual networks
|
||||||
|
allocated_networks.each do |n|
|
||||||
|
n.delete
|
||||||
|
end
|
||||||
|
|
||||||
|
break
|
||||||
end
|
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
|
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
|
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
|
end
|
||||||
|
|
||||||
return error, nic_info
|
return error, nic_info
|
||||||
@ -1880,7 +1914,7 @@ class VirtualMachine
|
|||||||
return str
|
return str
|
||||||
end
|
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_name = template['name']
|
||||||
template_ref = template['_ref']
|
template_ref = template['_ref']
|
||||||
@ -1898,6 +1932,7 @@ class VirtualMachine
|
|||||||
one_tmp[:rp] = rp
|
one_tmp[:rp] = rp
|
||||||
one_tmp[:rp_list] = rp_list
|
one_tmp[:rp_list] = rp_list
|
||||||
one_tmp[:template] = template
|
one_tmp[:template] = template
|
||||||
|
one_tmp[:import_disks_and_nics] = has_nics_and_disks
|
||||||
return one_tmp
|
return one_tmp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user