1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +03:00

feature #1712: Deployment and Migration API calls accept target system DS

This commit is contained in:
Ruben S. Montero 2013-08-21 13:20:09 +02:00
parent 9b223bb6d5
commit cad0fc8903
2 changed files with 228 additions and 110 deletions

View File

@ -56,15 +56,22 @@ protected:
PoolObjectAuth * ds_perm,
AuthRequest::Operation op);
int get_host_information(int hid,
string& name,
string& vmm,
string& vnm,
string& tm,
string& ds_location,
int& ds_id,
RequestAttributes& att,
PoolObjectAuth& host_perms);
int get_host_information(
int hid,
string& name,
string& vmm,
string& vnm,
int& cluster_id,
int& default_ds_id,
string& ds_location,
PoolObjectAuth& host_perms,
RequestAttributes& att);
int get_ds_information(
int ds_id,
int& ds_cluster_id,
string& tm_mad,
RequestAttributes& att);
bool check_host(int hid,
int cpu,
@ -112,7 +119,7 @@ public:
VirtualMachineDeploy():
RequestManagerVirtualMachine("VirtualMachineDeploy",
"Deploys a virtual machine",
"A:siib")
"A:siibi")
{
auth_op = AuthRequest::ADMIN;
};

View File

@ -96,26 +96,71 @@ bool RequestManagerVirtualMachine::vm_authorization(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RequestManagerVirtualMachine::get_host_information(int hid,
string& name,
string& vmm,
string& vnm,
string& tm,
string& ds_location,
int& ds_id,
RequestAttributes& att,
PoolObjectAuth& host_perms)
int RequestManagerVirtualMachine::get_ds_information(int ds_id,
int& ds_cluster_id,
string& tm_mad,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
Datastore * ds = nd.get_dspool()->get(ds_id, true);
ds_cluster_id = -1;
if ( ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
att);
return -1;
}
if ( ds->get_type() != Datastore::SYSTEM_DS )
{
ostringstream oss;
oss << "Trying to use " << object_name(PoolObjectSQL::DATASTORE)
<< " [" << ds_id << "], to deploy VM but it is not of type "
<< " system datastore.";
failure_response(INTERNAL, request_error(oss.str(),""), att);
ds->unlock();
return -1;
}
ds_cluster_id = ds->get_cluster_id();
tm_mad = ds->get_tm_mad();
ds->unlock();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RequestManagerVirtualMachine::get_host_information(
int hid,
string& name,
string& vmm,
string& vnm,
int& cluster_id,
int& default_ds_id,
string& ds_location,
PoolObjectAuth& host_perms,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
HostPool * hpool = nd.get_hpool();
Host * host;
Cluster * cluster;
Datastore * ds;
int cluster_id;
host = hpool->get(hid,true);
Host * host = hpool->get(hid,true);
if ( host == 0 )
{
@ -130,15 +175,15 @@ int RequestManagerVirtualMachine::get_host_information(int hid,
vmm = host->get_vmm_mad();
vnm = host->get_vnm_mad();
host->get_permissions(host_perms);
cluster_id = host->get_cluster_id();
host->get_permissions(host_perms);
host->unlock();
if ( cluster_id != -1 )
if ( cluster_id != -1 ) //Default System DS from a cluster
{
cluster = nd.get_clpool()->get(cluster_id, true);
Cluster * cluster = nd.get_clpool()->get(cluster_id, true);
if ( cluster == 0 )
{
@ -149,52 +194,19 @@ int RequestManagerVirtualMachine::get_host_information(int hid,
return -1;
}
ds_id = cluster->get_ds_id();
default_ds_id = cluster->get_ds_id();
cluster->get_ds_location(ds_location);
cluster->unlock();
}
else
else //Default System DS
{
ds_id = DatastorePool::SYSTEM_DS_ID;
default_ds_id = DatastorePool::SYSTEM_DS_ID;
nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location);
}
ds = nd.get_dspool()->get(ds_id, true);
if ( ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE),ds_id),
att);
return -1;
}
if ( ds->get_type() != Datastore::SYSTEM_DS )
{
ostringstream oss;
ds->unlock();
oss << object_name(PoolObjectSQL::CLUSTER)
<< " [" << cluster_id << "] has its SYSTEM_DS set to "
<< object_name(PoolObjectSQL::DATASTORE)
<< " [" << ds_id << "], but it is not a system one.";
failure_response(INTERNAL,
request_error(oss.str(),""),
att);
return -1;
}
tm = ds->get_tm_mad();
ds->unlock();
return 0;
}
@ -451,39 +463,97 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
DispatchManager * dm = nd.get_dm();
VirtualMachine * vm;
PoolObjectAuth host_perms;
string hostname;
string vmm_mad;
string vnm_mad;
string tm_mad;
int cluster_id;
int default_ds_id;
string ds_location;
int ds_id;
PoolObjectAuth host_perms;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int hid = xmlrpc_c::value_int(paramList.getInt(2));
bool enforce = false;
string tm_mad;
bool auth = false;
// ------------------------------------------------------------------------
// Get request parameters and information about the target host
// ------------------------------------------------------------------------
int id = xmlrpc_c::value_int(paramList.getInt(1));
int hid = xmlrpc_c::value_int(paramList.getInt(2));
bool enforce = false;
int ds_id = -1;
if ( paramList.size() > 3 )
{
enforce = xmlrpc_c::value_boolean(paramList.getBoolean(3));
}
if ( paramList.size() > 4 )
{
ds_id = xmlrpc_c::value_int(paramList.getInt(4));
}
if (get_host_information(hid,
hostname,
vmm_mad,
vnm_mad,
tm_mad,
cluster_id,
default_ds_id,
ds_location,
ds_id,
att,
host_perms) != 0)
host_perms,
att) != 0)
{
return;
}
// ------------------------------------------------------------------------
// Get information about the system DS to use (tm_mad)
// ------------------------------------------------------------------------
if ( ds_id == -1 ) //Use default system DS for cluster
{
int ds_cluster_id;
ds_id = default_ds_id;
if (get_ds_information(ds_id, ds_cluster_id, tm_mad, att) != 0)
{
return;
}
}
else //Get information from user selected system DS
{
int ds_cluster_id;
if (get_ds_information(ds_id, ds_cluster_id, tm_mad, att) != 0)
{
return;
}
if ( ds_cluster_id != cluster_id )
{
ostringstream oss;
oss << "Trying to use " << object_name(PoolObjectSQL::DATASTORE)
<< " [" << ds_id << "], to deploy VM but it is not part of "
<< object_name(PoolObjectSQL::CLUSTER) << " [" << cluster_id
<<"] as " << object_name(PoolObjectSQL::HOST) << " [" << hid
<<"] ";
failure_response(ACTION,
request_error(oss.str(),""),
att);
return;
}
}
// ------------------------------------------------------------------------
// Authorize request
// ------------------------------------------------------------------------
auth = vm_authorization(id, 0, 0, att, &host_perms, 0, auth_op);
if (auth == false)
@ -491,6 +561,12 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
// ------------------------------------------------------------------------
// Check request consistency:
// - VM States are right
// - Host capacity if required
// ------------------------------------------------------------------------
if ((vm = get_vm(id, att)) == 0)
{
return;
@ -528,6 +604,10 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
}
}
// ------------------------------------------------------------------------
// Add a new history record and deploy the VM
// ------------------------------------------------------------------------
if (add_history(vm,
hid,
hostname,
@ -559,19 +639,25 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
DispatchManager * dm = nd.get_dm();
VirtualMachine * vm;
PoolObjectAuth host_perms;
string hostname;
string vmm_mad;
string vnm_mad;
string tm_mad;
int cluster_id;
int default_ds_id;
string ds_location;
int ds_id;
PoolObjectAuth host_perms;
PoolObjectAuth aux_perms;
int current_ds_id;
string aux_st;
int current_hid;
int c_hid;
int c_cluster_id;
int c_ds_id;
string c_tm_mad;
bool auth = false;
// ------------------------------------------------------------------------
// Get request parameters and information about the target host
// ------------------------------------------------------------------------
int id = xmlrpc_c::value_int(paramList.getInt(1));
int hid = xmlrpc_c::value_int(paramList.getInt(2));
@ -583,21 +669,23 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
enforce = xmlrpc_c::value_boolean(paramList.getBoolean(4));
}
bool auth = false;
if (get_host_information(hid,
hostname,
vmm_mad,
vnm_mad,
tm_mad,
cluster_id,
default_ds_id,
ds_location,
ds_id,
att,
host_perms) != 0)
host_perms,
att) != 0)
{
return;
}
// ------------------------------------------------------------------------
// Authorize request
// ------------------------------------------------------------------------
auth = vm_authorization(id, 0, 0, att, &host_perms, 0, auth_op);
if (auth == false)
@ -605,6 +693,14 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
// ------------------------------------------------------------------------
// Check request consistency:
// - VM States are right and there is at least a history record
// - New host is not the current one
// - Host capacity if required
// - New host and current one are in the same cluster
// ------------------------------------------------------------------------
if ((vm = get_vm(id, att)) == 0)
{
return;
@ -622,14 +718,16 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
current_hid = vm->get_hid();
// Check we are not migrating to the same host
if (current_hid == hid)
c_hid = vm->get_hid();
if (c_hid == hid)
{
ostringstream oss;
oss << "VM is already running on "
<< object_name(PoolObjectSQL::HOST) << " [" << current_hid << "]";
<< object_name(PoolObjectSQL::HOST) << " [" << c_hid << "]";
failure_response(ACTION,
request_error(oss.str(),""),
@ -639,6 +737,14 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
// Get System DS information from current History record
istringstream iss(vm->get_ds_id());
iss >> c_ds_id;
c_tm_mad = vm->get_tm_mad();
if (enforce)
{
int cpu, mem, disk;
@ -659,28 +765,29 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
vm->unlock();
}
if (get_host_information(current_hid,
aux_st,
aux_st,
aux_st,
aux_st,
aux_st,
current_ds_id,
att,
aux_perms) != 0)
// Check we are in the same cluster
Host * host = nd.get_hpool()->get(c_hid, true);
if (host == 0)
{
return;
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::HOST), c_hid),
att);
}
if ( current_ds_id != ds_id )
c_cluster_id = host->get_cluster_id();
host->unlock();
if ( c_cluster_id != cluster_id )
{
ostringstream oss;
oss << "Cannot migrate to a different cluster with different system "
<< "datastore. Current " << object_name(PoolObjectSQL::HOST)
<< " [" << current_hid << "] uses system datastore [" << current_ds_id
<< "], new " << object_name(PoolObjectSQL::HOST) << " [" << hid
<< "] uses system datastore [" << ds_id << "]";
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 << "]";
failure_response(ACTION,
request_error(oss.str(),""),
@ -689,6 +796,10 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
// ------------------------------------------------------------------------
// Add a new history record and migrate the VM
// ------------------------------------------------------------------------
if ( (vm = get_vm(id, att)) == 0 )
{
return;
@ -699,9 +810,9 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
hostname,
vmm_mad,
vnm_mad,
tm_mad,
c_tm_mad,
ds_location,
ds_id,
c_ds_id,
att) != 0)
{
vm->unlock();