1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-03 13:47:01 +03:00

Merge branch 'bug-1694'

This commit is contained in:
Ruben S. Montero 2012-12-24 14:25:41 +01:00
commit c9dc8c47da
11 changed files with 380 additions and 79 deletions

View File

@ -32,20 +32,13 @@ class Cluster : public PoolObjectSQL
public:
/**
* Returns the SYSTEM_DS attribute, or the system DS id if it is not defined
* Returns the SYSTEM_DS attribute
*
* @return the SYSTEM_DS attribute, or the system DS id if it is not defined
* @return the SYSTEM_DS attribute
*/
int get_ds_id()
{
int ds_id;
if ( obj_template->get("SYSTEM_DS", ds_id) == false )
{
ds_id = DatastorePool::SYSTEM_DS_ID;
}
return ds_id;
return system_ds;
}
/**
@ -100,32 +93,11 @@ public:
/**
* Adds this datastore ID to the set.
* @param id to be added to the cluster
* @param ds_type Datastore type
* @param error_msg Error message, if any
* @return 0 on success
*/
int add_datastore(int id, string& error_msg)
{
// TODO: should fail for any system DS?
if ( id == DatastorePool::SYSTEM_DS_ID )
{
ostringstream oss;
oss << "Datastore '"<< DatastorePool::SYSTEM_DS_NAME
<< "' cannot be added to any cluster.";
error_msg = oss.str();
return -1;
}
int rc = datastores.add_collection_id(id);
if ( rc < 0 )
{
error_msg = "Datastore ID is already in the cluster set.";
}
return rc;
}
int add_datastore(int id, Datastore::DatastoreType ds_type, string& error_msg);
/**
* Deletes this datastore ID from the set.
@ -133,17 +105,7 @@ public:
* @param error_msg Error message, if any
* @return 0 on success
*/
int del_datastore(int id, string& error_msg)
{
int rc = datastores.del_collection_id(id);
if ( rc < 0 )
{
error_msg = "Datastore ID is not part of the cluster set.";
}
return rc;
}
int del_datastore(int id, string& error_msg);
/**
* Adds this vnet ID to the set.
@ -219,13 +181,18 @@ private:
virtual ~Cluster(){};
// *************************************************************************
// Object Collections (Private)
// Attributes (Private)
// *************************************************************************
ObjectCollection hosts;
ObjectCollection datastores;
ObjectCollection vnets;
/**
* System datastore id
*/
int system_ds;
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************

View File

@ -86,11 +86,20 @@ protected:
return ClusterPool::NONE_CLUSTER_ID;
};
virtual int add_to_cluster(Cluster* cluster, int id, string& error_msg)
virtual int add_to_cluster(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return -1;
};
virtual Datastore::DatastoreType get_ds_type(int oid)
{
return Datastore::FILE_DS;
};
protected:
ClusterPool * clpool;
@ -176,7 +185,11 @@ public:
return xmlrpc_c::value_int(paramList.getInt(2));
};
int add_to_cluster(Cluster* cluster, int id, string& error_msg)
int add_to_cluster(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return cluster->add_vnet(id, error_msg);
};
@ -274,7 +287,11 @@ public:
return xmlrpc_c::value_int(paramList.getInt(5));
};
int add_to_cluster(Cluster* cluster, int id, string& error_msg)
int add_to_cluster(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return cluster->add_host(id, error_msg);
};
@ -376,9 +393,27 @@ public:
return xmlrpc_c::value_int(paramList.getInt(2));
};
int add_to_cluster(Cluster* cluster, int id, string& error_msg)
virtual Datastore::DatastoreType get_ds_type(int oid)
{
return cluster->add_datastore(id, error_msg);
Datastore::DatastoreType ds_type = Datastore::FILE_DS;
Datastore *ds = static_cast<DatastorePool*>(pool)->get(oid, true);
if ( ds != 0 )
{
ds_type = ds->get_type();
ds->unlock();
}
return ds_type;
};
int add_to_cluster(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return cluster->add_datastore(id, ds_type, error_msg);
};
};

View File

@ -65,7 +65,24 @@ protected:
PoolSQL * pool,
PoolObjectSQL::ObjectType type);
virtual int add_object(Cluster* cluster, int id, string& error_msg) = 0;
virtual Datastore::DatastoreType get_ds_type(PoolObjectSQL *obj)
{
return Datastore::FILE_DS;
};
/**
* Add object to cluster id collection
* @param cluster where to add the object
* @param id of the object
* @param ds_type Datastore type, will be ignored for different objects
* @param error_msg Error reason, if any
* @return 0 on success
*/
virtual int add_object(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg) = 0;
virtual int del_object(Cluster* cluster, int id, string& error_msg) = 0;
@ -86,7 +103,11 @@ public:
~RequestManagerClusterHost(){};
virtual int add_object(Cluster* cluster, int id, string& error_msg)
virtual int add_object(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return cluster->add_host(id, error_msg);
};
@ -169,9 +190,18 @@ public:
~RequestManagerClusterDatastore(){};
virtual int add_object(Cluster* cluster, int id, string& error_msg)
virtual Datastore::DatastoreType get_ds_type(PoolObjectSQL *obj)
{
return cluster->add_datastore(id, error_msg);
return static_cast<Datastore*>(obj)->get_type();
};
virtual int add_object(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return cluster->add_datastore(id, ds_type, error_msg);
};
virtual int del_object(Cluster* cluster, int id, string& error_msg)
@ -253,7 +283,11 @@ public:
~RequestManagerClusterVNet(){};
virtual int add_object(Cluster* cluster, int id, string& error_msg)
virtual int add_object(
Cluster* cluster,
int id,
Datastore::DatastoreType ds_type,
string& error_msg)
{
return cluster->add_vnet(id, error_msg);
};

View File

@ -96,12 +96,13 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper
end
def format_resource(cluster)
str="%-15s: %-20s"
str="%-18s: %-20s"
str_h1="%-80s"
CLIHelper.print_header(str_h1 % "CLUSTER #{cluster['ID']} INFORMATION")
puts str % ["ID", cluster.id.to_s]
puts str % ["NAME", cluster.name]
puts str % ["SYSTEM DS", cluster['SYSTEM_DS']]
puts
CLIHelper.print_header(str_h1 % "CLUSTER TEMPLATE", false)

View File

@ -45,7 +45,8 @@ Cluster::Cluster(
PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table),
hosts("HOSTS"),
datastores("DATASTORES"),
vnets("VNETS")
vnets("VNETS"),
system_ds(DatastorePool::SYSTEM_DS_ID)
{
if (cl_template != 0)
{
@ -113,6 +114,69 @@ string& Cluster::get_ds_location(string &ds_location)
return ds_location;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Cluster::add_datastore(int id, Datastore::DatastoreType ds_type, string& error_msg)
{
if ( id == DatastorePool::SYSTEM_DS_ID )
{
ostringstream oss;
oss << "Datastore "<< DatastorePool::SYSTEM_DS_ID
<< " cannot be added to any cluster.";
error_msg = oss.str();
return -1;
}
if ( ds_type == Datastore::SYSTEM_DS )
{
if ( system_ds != DatastorePool::SYSTEM_DS_ID )
{
ostringstream oss;
oss << "Cluster " << oid << " already contains the System Datastore "
<< system_ds << ".";
error_msg = oss.str();
return -1;
}
}
int rc = datastores.add_collection_id(id);
if ( rc < 0 )
{
error_msg = "Datastore ID is already in the cluster set.";
}
else if ( ds_type == Datastore::SYSTEM_DS )
{
system_ds = id;
}
return rc;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Cluster::del_datastore(int id, string& error_msg)
{
int rc = datastores.del_collection_id(id);
if ( rc < 0 )
{
error_msg = "Datastore ID is not part of the cluster set.";
}
else if ( system_ds == id )
{
system_ds = DatastorePool::SYSTEM_DS_ID;
}
return rc;
}
/* ************************************************************************ */
/* Cluster :: Database Access Functions */
/* ************************************************************************ */
@ -215,8 +279,9 @@ string& Cluster::to_xml(string& xml) const
oss <<
"<CLUSTER>" <<
"<ID>" << oid << "</ID>" <<
"<NAME>" << name << "</NAME>" <<
"<ID>" << oid << "</ID>" <<
"<NAME>" << name << "</NAME>" <<
"<SYSTEM_DS>" << system_ds << "</SYSTEM_DS>" <<
hosts.to_xml(host_collection_xml) <<
datastores.to_xml(ds_collection_xml) <<
@ -241,8 +306,9 @@ int Cluster::from_xml(const string& xml)
update_from_str(xml);
// Get class base attributes
rc += xpath(oid, "/CLUSTER/ID", -1);
rc += xpath(name,"/CLUSTER/NAME", "not_found");
rc += xpath(oid, "/CLUSTER/ID", -1);
rc += xpath(name, "/CLUSTER/NAME", "not_found");
rc += xpath(system_ds, "/CLUSTER/SYSTEM_DS", -1);
// Set oneadmin as the owner
set_user(0,"");

View File

@ -411,18 +411,67 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str)
string new_tm_mad;
string s_ds_type;
int rc;
DatastoreType new_ds_type;
Template * new_tmpl = new DatastoreTemplate;
rc = PoolObjectSQL::replace_template(tmpl_str, error_str);
if ( rc != 0 )
if ( new_tmpl == 0 )
{
return rc;
error_str = "Cannot allocate a new template";
return -1;
}
get_template_attribute("DS_MAD", new_ds_mad);
get_template_attribute("TYPE", s_ds_type);
if ( new_tmpl->parse_str_or_xml(tmpl_str, error_str) != 0 )
{
delete new_tmpl;
return -1;
}
/* ---------------------------------------------------------------------- */
/* Set the TYPE of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */
new_tmpl->get("TYPE", s_ds_type);
if (!s_ds_type.empty())
{
new_ds_type = str_to_type(s_ds_type);
if (get_cluster_id() != ClusterPool::NONE_CLUSTER_ID)//It's in a cluster
{
if (type == SYSTEM_DS && new_ds_type != SYSTEM_DS)
{
error_str = "Datastore is associated to a cluster, and it is "
"the SYSTEM_DS, remove it from cluster first to "
"update its type.";
delete new_tmpl;
return -1;
}
else if (new_ds_type == SYSTEM_DS && type != SYSTEM_DS)
{
error_str = "Datastore is associated to a cluster, cannot set "
"type to SYSTEM_DS. Remove it from cluster first "
"to update its type.";
delete new_tmpl;
return -1;
}
}
}
else //No TYPE in the new Datastore template
{
new_ds_type = type;
}
/* --- Update the Datastore template --- */
delete obj_template;
obj_template = new_tmpl;
/* ---------------------------------------------------------------------- */
/* Set the TYPE of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */
if ( oid == DatastorePool::SYSTEM_DS_ID )
{
@ -430,15 +479,23 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str)
}
else
{
type = str_to_type(s_ds_type);
replace_template_attribute("TYPE", type_to_str(type));
type = new_ds_type;
}
replace_template_attribute("TYPE", type_to_str(type));
/* ---------------------------------------------------------------------- */
/* Set the DS_MAD of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */
if ( type == SYSTEM_DS )
{
new_ds_mad = "-";
}
else
{
get_template_attribute("DS_MAD", new_ds_mad);
}
if ( !new_ds_mad.empty() )
{
@ -447,6 +504,10 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str)
replace_template_attribute("DS_MAD", ds_mad);
/* ---------------------------------------------------------------------- */
/* Set the TM_MAD of the Datastore (class & template) */
/* ---------------------------------------------------------------------- */
get_template_attribute("TM_MAD", new_tm_mad);
if ( !new_tm_mad.empty() )

View File

@ -259,6 +259,92 @@ module Migrator
@db.run "DROP TABLE old_group_pool;"
########################################################################
# Bug #1694: SYSTEM_DS is now set with the method adddatastore
########################################################################
@db.run "ALTER TABLE cluster_pool RENAME TO old_cluster_pool;"
@db.run "CREATE TABLE cluster_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));"
@db.fetch("SELECT * FROM old_cluster_pool") do |row|
doc = Document.new(row[:body])
system_ds = 0
doc.root.each_element("TEMPLATE") do |e|
elem = e.delete_element("SYSTEM_DS")
if !elem.nil?
system_ds = elem.text.to_i
end
end
if system_ds != 0
updated_body = nil
@db.fetch("SELECT body FROM datastore_pool WHERE oid=#{system_ds}") do |ds_row|
ds_doc = Document.new(ds_row[:body])
type = "0" # IMAGE_DS
ds_doc.root.each_element("TYPE") do |e|
type = e.text
end
if type != "1"
puts " > Cluster #{row[:oid]} has the "<<
"System Datastore set to Datastore #{system_ds}, "<<
"but its type is not SYSTEM_DS. The System Datastore "<<
"for this Cluster will be set to 0"
system_ds = 0
else
cluster_id = "-1"
ds_doc.root.each_element("CLUSTER_ID") do |e|
cluster_id = e.text
end
if row[:oid] != cluster_id.to_i
puts " > Cluster #{row[:oid]} has the "<<
"System Datastore set to Datastore #{system_ds}, "<<
"but it is not part of the Cluster. It will be added now."
ds_doc.root.each_element("CLUSTER_ID") do |e|
e.text = row[:oid]
end
ds_doc.root.each_element("CLUSTER") do |e|
e.text = row[:name]
end
updated_body = ds_doc.root.to_s
end
end
end
if !updated_body.nil?
@db[:datastore_pool].where(:oid => system_ds).update(
:body => updated_body)
end
end
doc.root.add_element("SYSTEM_DS").text = system_ds.to_s
@db[:cluster_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_cluster_pool;"
########################################################################
#
# Banner for the new /var/lib/one/vms directory

View File

@ -249,6 +249,7 @@ module OneDBFsck
########################################################################
# Clusters
#
# CLUSTER/SYSTEM_DS
# CLUSTER/HOSTS/ID
# CLUSTER/DATASTORES/ID
# CLUSTER/VNETS/ID
@ -277,6 +278,8 @@ module OneDBFsck
cluster[row[:oid]][:hosts] = []
cluster[row[:oid]][:datastores] = []
cluster[row[:oid]][:vnets] = []
cluster[row[:oid]][:system_ds] = 0
end
hosts_fix = {}
@ -331,7 +334,26 @@ module OneDBFsck
datastores_fix[row[:oid]] = doc.to_s
else
cluster[cluster_id][:datastores] << row[:oid]
if doc.root.get_text('TYPE').to_s != "1"
cluster[cluster_id][:datastores] << row[:oid]
else
if cluster[cluster_id][:system_ds] == 0
cluster[cluster_id][:datastores] << row[:oid]
cluster[cluster_id][:system_ds] = row[:oid]
else
log_error("System Datastore #{row[:oid]} is in Cluster #{cluster_id}, but it already contains System Datastore #{cluster[cluster_id][:system_ds]}")
doc.root.each_element('CLUSTER_ID') do |e|
e.text = "-1"
end
doc.root.each_element('CLUSTER') do |e|
e.text = ""
end
datastores_fix[row[:oid]] = doc.to_s
end
end
end
end
end
@ -401,6 +423,16 @@ module OneDBFsck
ds_new_elem = doc.root.add_element("DATASTORES")
doc.root.each_element("SYSTEM_DS") do |e|
system_ds = e.text.to_i
if system_ds != cluster[cluster_id][:system_ds]
log_error("Cluster #{cluster_id} has System Datastore set to #{system_ds}, but it should be #{cluster[cluster_id][:system_ds]}")
e.text = cluster[cluster_id][:system_ds].to_s
end
end
cluster[cluster_id][:datastores].each do |id|
id_elem = ds_elem.elements.delete("ID[.=#{id}]")

View File

@ -24,11 +24,11 @@
string& PoolObjectSQL::to_xml64(string &xml64)
{
string *str64;
to_xml(xml64);
str64 = SSLTools::base64_encode(xml64);
xml64 = *str64;
delete str64;
@ -138,7 +138,7 @@ void PoolObjectSQL::set_template_error_message(const string& message)
{
VectorAttribute * attr;
map<string,string> error_value;
char str[26];
time_t the_time;
@ -175,9 +175,10 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
error = "Cannot allocate a new template";
return -1;
}
if ( new_tmpl->parse_str_or_xml(tmpl_str, error) != 0 )
{
delete new_tmpl;
return -1;
}
@ -186,7 +187,7 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
obj_template = new_tmpl;
return 0;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -189,6 +189,8 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
if ( cluster_id != ClusterPool::NONE_CLUSTER_ID )
{
Datastore::DatastoreType ds_type = get_ds_type(id);
cluster = clpool->get(cluster_id, true);
if ( cluster == 0 )
@ -200,7 +202,7 @@ void RequestManagerAllocate::request_execute(xmlrpc_c::paramList const& params,
return;
}
rc = add_to_cluster(cluster, id, error_str);
rc = add_to_cluster(cluster, id, ds_type, error_str);
if ( rc < 0 )
{

View File

@ -45,6 +45,8 @@ void RequestManagerCluster::add_generic(
int old_cluster_id;
string old_cluster_name;
Datastore::DatastoreType ds_type;
if ( cluster_id != ClusterPool::NONE_CLUSTER_ID )
{
rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att, c_perms, cluster_name);
@ -102,6 +104,8 @@ void RequestManagerCluster::add_generic(
old_cluster_id = cluster_obj->get_cluster_id();
old_cluster_name = cluster_obj->get_cluster_name();
ds_type = get_ds_type(object);
if ( old_cluster_id == cluster_id )
{
object->unlock();
@ -141,7 +145,7 @@ void RequestManagerCluster::add_generic(
return;
}
if ( add_object(cluster, object_id, err_msg) < 0 )
if ( add_object(cluster, object_id, ds_type, err_msg) < 0 )
{
cluster->unlock();
@ -149,6 +153,18 @@ void RequestManagerCluster::add_generic(
request_error("Cannot add object to cluster", err_msg),
att);
// Rollback
get(object_id, true, &object, &cluster_obj);
if ( object != 0 )
{
cluster_obj->set_cluster(old_cluster_id, old_cluster_name);
pool->update(object);
object->unlock();
}
return;
}