1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-08 05:57:23 +03:00

Merge branch 'feature-3383'

This commit is contained in:
Ruben S. Montero 2015-02-12 18:21:36 +01:00
commit 3ecbdad163
12 changed files with 711 additions and 12 deletions

View File

@ -94,6 +94,15 @@ public:
int deploy (
VirtualMachine * vm);
/**
* Sets an imported VM to RUNNING state, a history record MUST be added,
* and the VM MUST be locked.
* @param vm pointer to a VirtualMachine with its mutex locked.
* @return 0 on success
*/
int import (
VirtualMachine * vm);
/**
* Migrates a VM. The following actions must be performed before calling
* this function:

View File

@ -104,6 +104,15 @@ public:
return static_cast<VirtualMachine *>(PoolSQL::get(oid,lock));
};
/**
* Gets a VM ID by its deploy_id, the dedploy_id - VM id mapping is keep
* in the import_table.
* @param deploy_id to search the id for
* @return -1 if not found or VMID
*
*/
int get_vmid(const string& deploy_id);
/**
* Function to get the IDs of running VMs
* @param oids a vector that contains the IDs
@ -199,8 +208,14 @@ public:
* @return 0 on success
*/
static int bootstrap(SqlDB * _db)
{
return VirtualMachine::bootstrap(_db);
{
int rc;
ostringstream oss_import(import_db_bootstrap);
rc = VirtualMachine::bootstrap(_db);
rc += _db->exec(oss_import);
return rc;
};
/**
@ -334,9 +349,30 @@ private:
static float _default_mem_cost;
/**
* Callback used in calculate_showback
* Callback used to get an int in the DB it is used by VM Pool in:
* - calculate_showback (min_stime)
* - get_vmid (vmid)
*/
int min_stime_cb(void * _min_stime, int num, char **values, char **names);
int db_int_cb(void * _min_stime, int num, char **values, char **names);
// -------------------------------------------------------------------------
// Virtual Machine ID - Deploy ID index for imported VMs
// The index is managed by the VirtualMachinePool
// -------------------------------------------------------------------------
static const char * import_table;
static const char * import_db_names;
static const char * import_db_bootstrap;
/**
* Insert deploy_id - vmid index.
* @param replace will replace and not insert
* @return 0 on success
*/
int insert_index(const string& deploy_id, int vm_id, bool replace);
void drop_index(const string& deploy_id);
};
#endif /*VIRTUAL_MACHINE_POOL_H_*/

View File

@ -215,6 +215,87 @@ cmd=CommandParser::CmdParser.new(ARGV) do
exit 0
end
vms_desc = <<-EOT.unindent
Import vCenter running Virtual Machines into OpenNebula
EOT
command :vms, vms_desc, :options=>[ VCENTER, USER, PASS ] do
if options[:vuser].nil? ||
options[:vpass].nil? ||
options[:vcenter].nil?
STDERR.puts "vCenter connection parameters are mandatory to import"\
" VM templates:\n"\
"\t --vcenter vCenter hostname\n"\
"\t --vuser username to login in vcenter\n"\
"\t --vpass password for the user"
exit -1
end
begin
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
vc = VCenterDriver::VIClient.new_connection(
:user => options[:vuser],
:password => options[:vpass],
:host => options[:vcenter])
STDOUT.print "done!\n\n"
STDOUT.print "Looking for running Virtual Machines..."
rs = vc.running_vms
STDOUT.print "done!\n"
rs.each {|dc, tmps|
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
if tmps.empty?
STDOUT.print " No new running Virtual Machines found in"\
" #{dc}...\n\n"
next
end
tmps.each{ |v|
STDOUT.print "\n * Running Virtual Machine found:\n"\
" - Name : #{v[:name]}\n"\
" - UUID : #{v[:uuid]}\n"\
" - Cluster: #{v[:host]}\n"\
" Import this Virtual Machine [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
one_v = ::OpenNebula::VirtualMachine.new(
::OpenNebula::VirtualMachine.build_xml, vc.one)
rc = one_v.allocate(v[:one])
if ::OpenNebula.is_error?(rc)
STDOUT.puts " Error creating Virtual Machine: "\
"#{rc.message}\n"
end
rc = one_v.deploy v[:host_id]
if ::OpenNebula.is_error?(rc)
STDOUT.puts " Error creating Virtual Machine: "\
"#{rc.message}\n"
else
STDOUT.puts " OpenNebula VM #{one_v.id} "\
"created!\n"
end
}
}
rescue Exception => e
STDOUT.puts "error: #{e.message}"
exit -1
end
exit 0
end
network_desc = <<-EOT.unindent
Import vCenter networks into OpenNebula
EOT

View File

@ -74,6 +74,62 @@ error:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::import (
VirtualMachine * vm)
{
ostringstream oss;
int vid;
if ( vm == 0 )
{
return -1;
}
vid = vm->get_oid();
if ( vm->get_state() != VirtualMachine::PENDING &&
vm->get_state() != VirtualMachine::HOLD )
{
return -1;
}
Nebula& nd = Nebula::instance();
HostPool * hpool = nd.get_hpool();
time_t the_time = time(0);
int cpu, mem, disk;
vm->get_requirements(cpu, mem, disk);
hpool->add_capacity(vm->get_hid(), vm->get_oid(), cpu, mem, disk);
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->set_stime(the_time);
vm->set_prolog_stime(the_time);
vm->set_prolog_etime(the_time);
vm->set_running_stime(the_time);
vm->set_last_poll(0);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is RUNNING");
vm->unlock();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::migrate(
VirtualMachine * vm)
{

View File

@ -345,6 +345,14 @@ int Host::update_info(Template &tmpl,
rc = vatt->vector_value("ID", vmid);
if (rc == 0 && vmid == -1) //Check if it is an imported
{
Nebula& nd = Nebula::instance();
VirtualMachinePool * vmpool = nd.get_vmpool();
vmid = vmpool->get_vmid(vatt->vector_value("DEPLOY_ID"));
}
if (rc == 0 && vmid != -1)
{
if (tmp_lost_vms.erase(vmid) == 1) //Good, known
@ -358,23 +366,41 @@ int Host::update_info(Template &tmpl,
// Reported as zombie at least 2 times?
if (prev_tmp_zombie.count(vmid) == 1)
{
string zname;
if (num_zombies++ > 0)
{
zombie << ", ";
}
zombie << vatt->vector_value("DEPLOY_ID");
zname = vatt->vector_value("VM_NAME");
if (zname.empty())
{
zname = vatt->vector_value("DEPLOY_ID");
}
zombie << zname;
}
}
}
else if (rc == 0) //not ours
{
string wname;
if (num_wilds++ > 0)
{
wild << ", ";
}
wild << vatt->vector_value("DEPLOY_ID");
wname = vatt->vector_value("VM_NAME");
if (wname.empty())
{
wname = vatt->vector_value("DEPLOY_ID");
}
wild << wname;
}
delete *it;

View File

@ -640,6 +640,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
int id = xmlrpc_c::value_int(paramList.getInt(1));
int hid = xmlrpc_c::value_int(paramList.getInt(2));
bool enforce = false;
bool imported= false;
int ds_id = -1;
if ( paramList.size() > 3 )
@ -688,6 +689,10 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
{
ds_id = vm->get_ds_id();
}
else if (!vm->get_deploy_id().empty()) //deploy_id && not a Stopped VM
{
imported = true;
}
vm->unlock();
@ -795,7 +800,14 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
dm->deploy(vm);
if (!imported)
{
dm->deploy(vm);
}
else
{
dm->import(vm);
}
vm->unlock();

View File

@ -154,6 +154,10 @@ var create_host_tmpl =
<div class="vcenter_templates">\
</div>\
<br>\
<br>\
<div class="vcenter_vms">\
</div>\
<br>\
<div class="vcenter_networks">\
</div>\
<div class="row import_vcenter_clusters_div hidden">\
@ -1149,6 +1153,112 @@ function fillVCenterTemplates(opts) {
return false;
}
/*
Retrieve the list of running VMs from vCenter and fill the container with them
opts = {
datacenter: "Datacenter Name",
cluster: "Cluster Name",
container: Jquery div to inject the html,
vcenter_user: vCenter Username,
vcenter_password: vCenter Password,
vcenter_host: vCenter Host
}
*/
function fillVCenterVMs(opts) {
var path = '/vcenter/vms';
opts.container.html(generateAdvancedSection({
html_id: path,
title: tr("Running VMs"),
content: '<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>'
}))
$('a', opts.container).trigger("click")
$.ajax({
url: path,
type: "GET",
data: {timeout: false},
dataType: "json",
headers: {
"X_VCENTER_USER": opts.vcenter_user,
"X_VCENTER_PASSWORD": opts.vcenter_password,
"X_VCENTER_HOST": opts.vcenter_host
},
success: function(response){
$(".content", opts.container).html("");
$('<div class="row">' +
'<div class="large-12 columns">' +
'<p style="color: #999">' + tr("Please select the vCenter running VMs to be imported to OpenNebula.") + '</p>' +
'</div>' +
'</div>').appendTo($(".content", opts.container))
$.each(response, function(datacenter_name, vms){
$('<div class="row">' +
'<div class="large-12 columns">' +
'<h5>' +
datacenter_name + ' ' + tr("DataCenter") +
'</h5>' +
'</div>' +
'</div>').appendTo($(".content", opts.container))
if (vms.length == 0) {
$('<div class="row">' +
'<div class="large-12 columns">' +
'<label>' +
tr("No new running VMs found in this DataCenter") +
'</label>' +
'</div>' +
'</div>').appendTo($(".content", opts.container))
} else {
$.each(vms, function(id, vm){
if (vm.host_id === parseInt(vm.host_id, 10)) {
var trow = $('<div class="vcenter_vm">' +
'<div class="row">' +
'<div class="large-10 columns">' +
'<label>' +
'<input type="checkbox" class="vm_name" checked/> ' +
vm.name + '&emsp;<span style="color: #999">' + vm.host + '</span>' +
'</vm>' +
'<div class="large-12 columns vcenter_vm_response">'+
'</div>'+
'</div>' +
'<div class="large-2 columns vcenter_vm_result">'+
'</div>'+
'</div>'+
'</div>').appendTo($(".content", opts.container))
$(".vm_name", trow).data("vm_name", vm.name)
$(".vm_name", trow).data("one_vm", vm.one)
$(".vm_name", trow).data("vm_to_host", vm.host_id)
}
});
if ($(".vcenter_vm").length == 0) {
$('<div class="row">' +
'<div class="large-12 columns">' +
'<label>' +
tr("No new running VMs found in this DataCenter") +
'</label>' +
'</div>' +
'</div>').appendTo($(".content", opts.container))
}
};
});
},
error: function(response){
opts.container.html("");
onError({}, OpenNebula.Error(response));
}
});
return false;
}
/*
Retrieve the list of networks from vCenter and fill the container with them
@ -1443,6 +1553,7 @@ function setupCreateHostDialog(){
});
var templates_container = $(".vcenter_templates", $create_host_dialog);
var vms_container = $(".vcenter_vms", $create_host_dialog);
var networks_container = $(".vcenter_networks", $create_host_dialog);
var vcenter_user = $("#vcenter_user", $create_host_dialog).val();
@ -1456,6 +1567,13 @@ function setupCreateHostDialog(){
vcenter_host: vcenter_host
});
fillVCenterVMs({
container: vms_container,
vcenter_user: vcenter_user,
vcenter_password: vcenter_password,
vcenter_host: vcenter_host
});
fillVCenterNetworks({
container: networks_container,
vcenter_user: vcenter_user,
@ -1576,6 +1694,60 @@ function setupCreateHostDialog(){
});
})
$.each($(".vm_name:checked", $create_host_dialog), function(){
var vm_context = $(this).closest(".vcenter_vm");
$(".vcenter_vm_result:not(.success)", vm_context).html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>');
var vm_json = {
"vm": {
"vm_raw": $(this).data("one_vm")
}
};
var host_id_to_deploy = $(this).data("vm_to_host");
OpenNebula.VM.create({
timeout: true,
data: vm_json,
success: function(request, response) {
OpenNebula.Helper.clear_cache("VM");
var extra_info = {};
extra_info['host_id'] = host_id_to_deploy;
extra_info['ds_id'] = -1;
extra_info['enforce'] = false;
Sunstone.runAction("VM.deploy_action", response.VM.ID, extra_info);
$(".vcenter_vm_result", vm_context).addClass("success").html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-check fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_vm_response", vm_context).html('<p style="font-size:12px" class="running-color">'+
tr("VM imported successfully")+' ID:'+response.VM.ID+
'</p>');
},
error: function (request, error_json){
$(".vcenter_vm_response", vm_context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-warning fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_vm_response", vm_context).html('<p style="font-size:12px" class="error-color">'+
(error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+
'</p>');
}
});
})
$.each($(".network_name:checked", $create_host_dialog), function(){
var network_context = $(this).closest(".vcenter_network");

View File

@ -1831,6 +1831,43 @@ function getName(id,dataTable,name_col){
return name;
};
function getHostIdFromName(hostName) {
getColumnValue({
dataTable: dataTable_hosts,
columnFilterIndex: 2, // Name
columnFilterValue: hostName,
columnResultIndex: 1 // ID
});
}
/*
Returns the value of the columnResultIndex column of the row
whose columnFilterIndex column has the columnFilterValue value
opts = {
dataTable: datatable to get the info from
columnFilterIndex: column that will be filtered
columnFilterValue: value to filter
columnResultIndex: value to be returned
}
*/
function getColumnValue(opts) {
if (typeof(opts.dataTable) == "undefined") {
return false;
};
var result = false;
$.each(opts.dataTable.fnGetData(), function(){
if (opts.columnFilterValue == this[opts.columnFilterIndex]) {
result = this[opts.columnResultIndex];
return false;
}
});
return result;
}
// A more general version of the above.
// Search a datatable record matching the filter_str in the filter_col. Returns
// the value of that record in the desired value column.

View File

@ -87,6 +87,26 @@ get '/vcenter/templates' do
end
end
get '/vcenter/vms' do
begin
vms = vcenter_client.running_vms(
$cloud_auth.client(session[:user], session[:active_zone_endpoint]))
if vms.nil?
msg = "No datacenter found"
logger.error("[vCenter] " + msg)
error = Error.new(msg)
error 404, error.to_json
end
[200, vms.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
networks = vcenter_client.vcenter_networks(

View File

@ -438,6 +438,21 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
goto error_graphics;
}
// -------------------------------------------------------------------------
// Get and set DEPLOY_ID for imported VMs
// -------------------------------------------------------------------------
user_obj_template->get("IMPORT_VM_ID", value);
user_obj_template->erase("IMPORT_VM_ID");
if (!value.empty())
{
deploy_id = value;
obj_template->add("IMPORTED", "YES");
}
// ------------------------------------------------------------------------
parse_well_known_attributes();
// ------------------------------------------------------------------------

View File

@ -18,6 +18,7 @@
#include "VirtualMachineHook.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include <sstream>
@ -29,6 +30,16 @@ bool VirtualMachinePool::_submit_on_hold;
float VirtualMachinePool::_default_cpu_cost;
float VirtualMachinePool::_default_mem_cost;
const char * VirtualMachinePool::import_table = "vm_import";
const char * VirtualMachinePool::import_db_names = "deploy_id, vmid";
const char * VirtualMachinePool::import_db_bootstrap =
"CREATE TABLE IF NOT EXISTS vm_import "
"(deploy_id VARCHAR(128), vmid INTEGER, PRIMARY KEY(deploy_id))";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -246,6 +257,54 @@ VirtualMachinePool::VirtualMachinePool(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePool::insert_index(const string& deploy_id, int vmid,
bool replace)
{
ostringstream oss;
char * deploy_name = db->escape_str(deploy_id.c_str());
if (deploy_name == 0)
{
return -1;
}
if (replace)
{
oss << "REPLACE ";
}
else
{
oss << "INSERT ";
}
oss << "INTO " << import_table << " ("<< import_db_names <<") "
<< " VALUES ('" << deploy_name << "'," << vmid << ")";
db->free_str(deploy_name);
return db->exec(oss);
};
/* -------------------------------------------------------------------------- */
void VirtualMachinePool::drop_index(const string& deploy_id)
{
ostringstream oss;
char * deploy_name = db->escape_str(deploy_id.c_str());
if (deploy_name == 0)
{
return;
}
oss << "DELETE FROM " << import_table << " WHERE deploy_id='"
<< deploy_name << "'";
db->exec(oss);
}
/* -------------------------------------------------------------------------- */
int VirtualMachinePool::allocate (
int uid,
int gid,
@ -258,12 +317,14 @@ int VirtualMachinePool::allocate (
bool on_hold)
{
VirtualMachine * vm;
string deploy_id;
// ------------------------------------------------------------------------
// Build a new Virtual Machine object
// ------------------------------------------------------------------------
vm = new VirtualMachine(-1, uid, gid, uname, gname, umask, vm_template);
if ( _submit_on_hold == true || on_hold )
{
vm->state = VirtualMachine::HOLD;
@ -273,12 +334,43 @@ int VirtualMachinePool::allocate (
vm->state = VirtualMachine::PENDING;
}
vm->user_obj_template->get("IMPORT_VM_ID", deploy_id);
if (!deploy_id.empty())
{
vm->state = VirtualMachine::HOLD;
if (insert_index(deploy_id, -1, false) == -1) //Set import in progress
{
delete vm;
error_str = "Virtual Machine " + deploy_id + " already imported.";
return -1;
}
}
// ------------------------------------------------------------------------
// Insert the Object in the pool
// ------------------------------------------------------------------------
*oid = PoolSQL::allocate(vm, error_str);
// ------------------------------------------------------------------------
// Insert the deploy_id - vmid index for imported VMs
// ------------------------------------------------------------------------
if (!deploy_id.empty())
{
if (*oid >= 0)
{
insert_index(deploy_id, *oid, true);
}
else
{
drop_index(deploy_id);
}
}
return *oid;
}
@ -466,14 +558,14 @@ int VirtualMachinePool::dump_monitoring(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePool::min_stime_cb(void * _min_stime, int num, char **values, char **names)
int VirtualMachinePool::db_int_cb(void * _int_output, int num, char **values, char **names)
{
if ( num == 0 || values == 0 || values[0] == 0 )
{
return -1;
}
*static_cast<int*>(_min_stime) = atoi(values[0]);
*static_cast<int*>(_int_output) = atoi(values[0]);
return 0;
}
@ -481,6 +573,33 @@ int VirtualMachinePool::min_stime_cb(void * _min_stime, int num, char **values,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePool::get_vmid (const string& deploy_id)
{
int rc;
int vmid = -1;
ostringstream oss;
set_callback(static_cast<Callbackable::Callback>(&VirtualMachinePool::db_int_cb),
static_cast<void *>(&vmid));
oss << "SELECT vmid FROM " << import_table
<< " WHERE deploy_id = '" << db->escape_str(deploy_id.c_str()) << "'";
rc = db->exec(oss, this);
unset_callback();
if (rc != 0 )
{
return -1;
}
return vmid;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifdef SBDEBUG
static string put_time(tm tmp_tm)
{
@ -603,7 +722,7 @@ int VirtualMachinePool::calculate_showback(
{
// Set start time to the lowest stime from the history records
set_callback(static_cast<Callbackable::Callback>(&VirtualMachinePool::min_stime_cb),
set_callback(static_cast<Callbackable::Callback>(&VirtualMachinePool::db_int_cb),
static_cast<void *>(&start_time));
oss << "SELECT MIN(stime) FROM " << History::table;
@ -905,3 +1024,6 @@ int VirtualMachinePool::calculate_showback(
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -246,6 +246,87 @@ class VIClient
return vm_templates
end
########################################################################
# Builds a hash with the Datacenter / Virtual Machines for this VCenter
# @param one_client [OpenNebula::Client] Use this client instead of @one
# @return [Hash] in the form
# { dc_name [String] => }
########################################################################
def running_vms(one_client=nil)
running_vms = {}
vmpool = OpenNebula::VirtualMachinePool.new(
(one_client||@one), OpenNebula::Pool::INFO_ALL)
rc = vmpool.info
hostpool = OpenNebula::HostPool.new((one_client||@one))
rc = hostpool.info
# TODO check error
datacenters = get_entities(@root, 'Datacenter')
datacenters.each { |dc|
vms = get_entities(dc.vmFolder, 'VirtualMachine')
ccrs = get_entities(dc.hostFolder, 'ClusterComputeResource')
tmp = vms.select { |v|
# Get rid of VM Templates and VMs not in running state
v.config &&
v.config.template != true &&
v.summary.runtime.powerState == "poweredOn"
}
one_tmp = []
tmp.each { |v|
vi_tmp = VCenterVm.new(self, v)
container_hostname = vi_tmp.vm.runtime.host.parent.name
cluster_name = ccrs.collect { |c|
found_host=c.host.select {|h|
h.parent.name == container_hostname}
found_host.first.parent.name if found_host.size > 0
}.first
if !vmpool["VM/USER_TEMPLATE/PUBLIC_CLOUD[\
TYPE=\"vcenter\" \
and VM_TEMPLATE=\"#{vi_tmp.vm.config.uuid}\"]"]
host_id = name_to_id(container_hostname,hostpool,"HOST")[1]
one_tmp << {
:name => vi_tmp.vm.name,
:uuid => vi_tmp.vm.config.uuid,
:host => container_hostname,
:host_id => host_id,
:one => vi_tmp.vm_to_one
}
end
}
running_vms[dc.name] = one_tmp
}
return running_vms
end
def name_to_id(name, pool, ename)
objects=pool.select {|object| object.name==name }
if objects.length>0
if objects.length>1
return -1, "There are multiple #{ename}s with name #{name}."
else
result = objects.first.id
end
else
return -1, "#{ename} named #{name} not found."
end
return 0, result
end
########################################################################
# Builds a hash with the Datacenter / CCR (Distributed)Networks
# for this VCenter
@ -541,9 +622,12 @@ class VCenterHost < ::OpenNebula::Host
vm = VCenterVm.new(@client, v)
vm.monitor
next if !vm.vm.config
str_info << "\nVM = ["
str_info << "ID=#{number},"
str_info << "DEPLOY_ID=\"#{name}\","
str_info << "DEPLOY_ID=\"#{vm.vm.config.uuid}\","
str_info << "VM_NAME=\"#{name}\","
str_info << "POLL=\"#{vm.info}\"]"
}
@ -948,6 +1032,35 @@ class VCenterVm
return str
end
########################################################################
# Generates an OpenNebula VirtualMachine for this VCenterVm
#
#
########################################################################
def vm_to_one
str = "NAME = \"#{@vm.name}\"\n"\
"CPU = \"#{@vm.config.hardware.numCPU}\"\n"\
"vCPU = \"#{@vm.config.hardware.numCPU}\"\n"\
"MEMORY = \"#{@vm.config.hardware.memoryMB}\"\n"\
"HYPERVISOR = \"vcenter\"\n"\
"PUBLIC_CLOUD = [\n"\
" TYPE =\"vcenter\",\n"\
" VM_TEMPLATE =\"#{@vm.config.uuid}\"\n"\
"]\n"\
"IMPORT_VM_ID = \"#{@vm.config.uuid}\"\n"\
"SCHED_REQUIREMENTS=\"NAME=\\\"#{@vm.runtime.host.parent.name}\\\"\"\n"
if @vm.config.annotation.nil? || @vm.config.annotation.empty?
str << "DESCRIPTION = \"vCenter Virtual Machine imported by OpenNebula"\
" from Cluster #{@vm.runtime.host.parent.name}\"\n"
else
notes = @vm.config.annotation.gsub("\\", "\\\\").gsub("\"", "\\\"")
str << "DESCRIPTION = \"#{notes}\"\n"
end
return str
end
private
########################################################################