1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

Feature #4464: Allow migration between clusters that share datastores/vnets

(cherry picked from commit f789d500f4005d00c63657ebed8d1b87b066dde6)
This commit is contained in:
Carlos Martín 2016-08-18 16:18:59 +02:00
parent ee77deb2f7
commit b836ad30c0
3 changed files with 118 additions and 93 deletions

View File

@ -1208,6 +1208,16 @@ public:
void get_requirements (int& cpu, int& memory, int& disk,
vector<VectorAttribute *>& pci_dev);
/**
* Returns the list of Cluster IDs where the VM can be deployed, based
* on the Datastores and VirtualNetworks requested
*
* @param cluster_ids set of Cluster IDs
* @param error_str Returns the error reason, if any
* @return 0 on success
*/
int get_cluster_requirements(set<int>& cluster_ids, string& error_str);
/**
* Checks if the resize parameters are valid
* @param cpu New CPU. 0 means unchanged.

View File

@ -990,12 +990,15 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
PoolObjectAuth * auth_ds_perms;
int c_hid;
int c_cluster_id;
int c_ds_id;
string c_tm_mad, tm_mad;
bool c_is_public_cloud;
set<int> cluster_ids;
string tmp_str;
bool auth = false;
bool ds_migr;
string error;
@ -1153,9 +1156,11 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
vm->get_cluster_requirements(cluster_ids, tmp_str);
vm->unlock();
// Check we are in the same cluster
// Check we are migrating to a compatible cluster
Host * host = nd.get_hpool()->get(c_hid, true);
if (host == 0)
@ -1165,20 +1170,17 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
failure_response(NO_EXISTS, att);
}
c_cluster_id = host->get_cluster_id();
c_is_public_cloud = host->is_public_cloud();
host->unlock();
if ( c_cluster_id != cluster_id )
if (cluster_ids.count(cluster_id) == 0)
{
ostringstream oss;
oss << "Cannot migrate to a different cluster. VM running in a host"
<< " in " << object_name(PoolObjectSQL::CLUSTER) << " ["
<< c_cluster_id << "] , and new host is in "
<< object_name(PoolObjectSQL::CLUSTER) << " [" << cluster_id << "]";
oss << "Cannot migrate to host [" << hid << "]. Host is in cluster ["
<< cluster_id << "], and VM requires to be placed on cluster ["
<< one_util::join(cluster_ids, ',') << "]";
att.resp_msg = oss.str();
failure_response(ACTION, att);
@ -1196,8 +1198,6 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
if (ds_id != -1)
{
bool ds_migr;
if ( c_ds_id != ds_id && live )
{
att.resp_msg = "A migration to a different system datastore "
@ -1218,22 +1218,6 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
if (ds_cluster_ids.count(c_cluster_id) == 0)
{
ostringstream oss;
oss << "Cannot migrate to a different cluster. VM running in a host"
<< " in " << object_name(PoolObjectSQL::CLUSTER)
<< " [" << c_cluster_id << "] , and new system datastore is in "
<< object_name(PoolObjectSQL::CLUSTER)
<< " [" << one_util::join(ds_cluster_ids, ',') << "]";
att.resp_msg = oss.str();
failure_response(ACTION, att);
return;
}
if (c_tm_mad != tm_mad)
{
att.resp_msg = "Cannot migrate to a system datastore with a different TM driver";
@ -1245,7 +1229,25 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
else
{
ds_id = c_ds_id;
tm_mad = c_tm_mad;
if (get_ds_information(ds_id, ds_cluster_ids, tm_mad, att, ds_migr) != 0)
{
return;
}
}
if (ds_cluster_ids.count(cluster_id) == 0)
{
ostringstream oss;
oss << "Cannot migrate to host [" << hid << "] and system datastore [" << ds_id << "]. Host is in cluster ["
<< cluster_id << "], and the datastore is in cluster ["
<< one_util::join(ds_cluster_ids, ',') << "]";
att.resp_msg = oss.str();
failure_response(ACTION, att);
return;
}
// ------------------------------------------------------------------------

View File

@ -1475,18 +1475,11 @@ static int check_and_set_cluster_id(
/* ------------------------------------------------------------------------ */
int VirtualMachine::automatic_requirements(string& error_str)
int VirtualMachine::get_cluster_requirements(set<int>& cluster_ids, string& error_str)
{
int num_vatts;
vector<const VectorAttribute *> vatts;
ostringstream oss;
string requirements;
set<int> cluster_ids;
set<string> clouds;
int num_public = get_public_clouds(clouds);
int num_vatts;
vector<const VectorAttribute *> vatts;
int incomp_id;
int rc;
@ -1562,61 +1555,6 @@ int VirtualMachine::automatic_requirements(string& error_str)
}
}
if ( !cluster_ids.empty() )
{
set<int>::iterator i = cluster_ids.begin();
oss << "(CLUSTER_ID = " << *i;
for (++i; i != cluster_ids.end(); i++)
{
oss << " | CLUSTER_ID = " << *i;
}
oss << ") & !(PUBLIC_CLOUD = YES)";
}
else
{
oss << "!(PUBLIC_CLOUD = YES)";
}
if (num_public != 0)
{
set<string>::iterator it = clouds.begin();
oss << " | (PUBLIC_CLOUD = YES & (";
oss << "HYPERVISOR = " << *it ;
for (++it; it != clouds.end() ; ++it)
{
oss << " | HYPERVISOR = " << *it;
}
oss << "))";
}
obj_template->add("AUTOMATIC_REQUIREMENTS", oss.str());
// Set automatic System DS requirements
if ( !cluster_ids.empty() )
{
oss.str("");
set<int>::iterator i = cluster_ids.begin();
oss << "\"CLUSTERS/ID\" @> " << *i;
for (++i; i != cluster_ids.end(); i++)
{
oss << " | \"CLUSTERS/ID\" @> " << *i;
}
obj_template->add("AUTOMATIC_DS_REQUIREMENTS", oss.str());
}
return 0;
error_disk:
@ -1699,6 +1637,81 @@ error_common:
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VirtualMachine::automatic_requirements(string& error_str)
{
ostringstream oss;
set<int> cluster_ids;
set<string> clouds;
int rc = get_cluster_requirements(cluster_ids, error_str);
if (rc != 0)
{
return -1;
}
if ( !cluster_ids.empty() )
{
set<int>::iterator i = cluster_ids.begin();
oss << "(CLUSTER_ID = " << *i;
for (++i; i != cluster_ids.end(); i++)
{
oss << " | CLUSTER_ID = " << *i;
}
oss << ") & !(PUBLIC_CLOUD = YES)";
}
else
{
oss << "!(PUBLIC_CLOUD = YES)";
}
int num_public = get_public_clouds(clouds);
if (num_public != 0)
{
set<string>::iterator it = clouds.begin();
oss << " | (PUBLIC_CLOUD = YES & (";
oss << "HYPERVISOR = " << *it ;
for (++it; it != clouds.end() ; ++it)
{
oss << " | HYPERVISOR = " << *it;
}
oss << "))";
}
obj_template->add("AUTOMATIC_REQUIREMENTS", oss.str());
// Set automatic System DS requirements
if ( !cluster_ids.empty() )
{
oss.str("");
set<int>::iterator i = cluster_ids.begin();
oss << "\"CLUSTERS/ID\" @> " << *i;
for (++i; i != cluster_ids.end(); i++)
{
oss << " | \"CLUSTERS/ID\" @> " << *i;
}
obj_template->add("AUTOMATIC_DS_REQUIREMENTS", oss.str());
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str)
{
ostringstream oss;