mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-22 13:33:52 +03:00
F #2671: Add oned search functionality. Add an index column to perform FTS searches server-side. New parameter has been added to the one.vmpool.info call, and --search option to CLI onevm list. This commits adds support for JAVA and migrator.
Co-authored-by: Christian González <cgonzalez@opennebula.systems>
This commit is contained in:
parent
f3995775cc
commit
5f7fb402aa
@ -83,7 +83,11 @@ public:
|
||||
* by the calling function.
|
||||
* @return a string (allocated in the heap) holding the attribute value.
|
||||
*/
|
||||
virtual string * to_xml() const = 0;
|
||||
virtual void to_xml(std::ostringstream& s) const = 0;
|
||||
|
||||
virtual void to_json(std::ostringstream& s) const = 0;
|
||||
|
||||
virtual void to_token(std::ostringstream& s) const = 0;
|
||||
|
||||
/**
|
||||
* Builds a new attribute from a string.
|
||||
@ -158,17 +162,31 @@ public:
|
||||
*
|
||||
* <attribute_name>attribute_value</attribute_name>
|
||||
*
|
||||
* The string MUST be freed by the calling function.
|
||||
* @return a string (allocated in the heap) holding the attribute value.
|
||||
* @paran s the stream to write the attribute.
|
||||
*/
|
||||
string * to_xml() const
|
||||
void to_xml(std::ostringstream& s) const
|
||||
{
|
||||
string * xml = new string;
|
||||
s << "<" << attribute_name << ">" << one_util::escape_xml(attribute_value)
|
||||
<< "</"<< attribute_name << ">";
|
||||
|
||||
*xml = "<" + name() + ">" + one_util::escape_xml(attribute_value) +
|
||||
"</"+ name() + ">";
|
||||
}
|
||||
|
||||
return xml;
|
||||
void to_json(std::ostringstream& s) const
|
||||
{
|
||||
one_util::escape_json(attribute_value, s);
|
||||
}
|
||||
|
||||
void to_token(std::ostringstream& s) const
|
||||
{
|
||||
if (attribute_name.empty() || attribute_value.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
one_util::escape_token(attribute_name, s);
|
||||
s << "=";
|
||||
one_util::escape_token(attribute_value, s);
|
||||
s << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,12 +368,11 @@ public:
|
||||
* The string MUST be freed by the calling function.
|
||||
* @return a string (allocated in the heap) holding the attribute value.
|
||||
*/
|
||||
string * to_xml() const;
|
||||
void to_xml(std::ostringstream& s) const;
|
||||
|
||||
/**
|
||||
* Same as above but the attribute is written in an string stream;
|
||||
*/
|
||||
void to_xml(ostringstream &oss) const;
|
||||
void to_json(std::ostringstream& s) const;
|
||||
|
||||
void to_token(std::ostringstream& s) const;
|
||||
|
||||
/**
|
||||
* Builds a new attribute from a string of the form:
|
||||
|
@ -92,9 +92,19 @@ protected:
|
||||
return va->marshall(_sep);
|
||||
};
|
||||
|
||||
string * to_xml() const
|
||||
void to_xml(std::ostringstream& s) const
|
||||
{
|
||||
return va->to_xml();
|
||||
return va->to_xml(s);
|
||||
};
|
||||
|
||||
void to_json(std::ostringstream& s) const
|
||||
{
|
||||
return va->to_json(s);
|
||||
};
|
||||
|
||||
void to_token(std::ostringstream& s) const
|
||||
{
|
||||
return va->to_token(s);
|
||||
};
|
||||
|
||||
void unmarshall(const std::string& sattr, const char * _sep = 0)
|
||||
|
@ -258,6 +258,10 @@ private:
|
||||
*/
|
||||
string& to_xml(string& xml, bool database) const;
|
||||
|
||||
string& to_json(string& json) const;
|
||||
|
||||
string& to_token(string& text) const;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml node
|
||||
* @param node The xml node pointer
|
||||
|
@ -371,7 +371,7 @@ public:
|
||||
*/
|
||||
static string shared_db_version()
|
||||
{
|
||||
return "5.7.80";
|
||||
return "5.6.0";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -578,6 +578,15 @@ public:
|
||||
return nebula_configuration->to_xml(xml);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the database backend type
|
||||
* @return database backend type
|
||||
*/
|
||||
string get_db_backend() const
|
||||
{
|
||||
return db_backend_type;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Default Quotas
|
||||
// -----------------------------------------------------------------------
|
||||
@ -695,7 +704,7 @@ private:
|
||||
"/DEFAULT_GROUP_QUOTAS/NETWORK_QUOTA",
|
||||
"/DEFAULT_GROUP_QUOTAS/IMAGE_QUOTA",
|
||||
"/DEFAULT_GROUP_QUOTAS/VM_QUOTA"),
|
||||
system_db(0), logdb(0), fed_logdb(0),
|
||||
system_db(0), db_backend_type("sqlite"), logdb(0), fed_logdb(0),
|
||||
vmpool(0), hpool(0), vnpool(0), upool(0), ipool(0), gpool(0), tpool(0),
|
||||
dspool(0), clpool(0), docpool(0), zonepool(0), secgrouppool(0),
|
||||
vdcpool(0), vrouterpool(0), marketpool(0), apppool(0), vmgrouppool(0),
|
||||
@ -819,6 +828,7 @@ private:
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
SystemDB * system_db;
|
||||
string db_backend_type;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Nebula Pools
|
||||
|
@ -208,6 +208,11 @@ namespace one_util
|
||||
{
|
||||
return escape(v, "'", "'");
|
||||
}
|
||||
|
||||
void escape_json(const std::string& str, std::ostringstream& s);
|
||||
|
||||
void escape_token(const std::string& str, std::ostringstream& s);
|
||||
|
||||
/**
|
||||
* Checks if a strings matches a regular expression
|
||||
*
|
||||
@ -236,7 +241,8 @@ namespace one_util
|
||||
const std::string& replacement);
|
||||
|
||||
template <class T>
|
||||
std::set<T> set_intersection(const std::set<T> &first, const std::set<T> &second)
|
||||
std::set<T> set_intersection(const std::set<T> &first, const std::set<T>
|
||||
&second)
|
||||
{
|
||||
std::set<T> output;
|
||||
|
||||
@ -247,48 +253,48 @@ namespace one_util
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Compress the input string unsing zlib
|
||||
* @param in input string
|
||||
* @param bool64 true to base64 encode output
|
||||
* @return pointer to the compressed sting (must be freed) or 0 in case
|
||||
* of error
|
||||
*/
|
||||
std::string * zlib_compress(const std::string& in, bool base64);
|
||||
std::string * zlib_compress(const std::string& in, bool base64);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Decompress the input string unsing zlib
|
||||
* @param in input string
|
||||
* @param base64 true if the input is base64 encoded
|
||||
* @return pointer to the decompressed sting (must be freed) or 0 in case
|
||||
* of error
|
||||
*/
|
||||
std::string * zlib_decompress(const std::string& in, bool base64);
|
||||
std::string * zlib_decompress(const std::string& in, bool base64);
|
||||
|
||||
extern "C" void sslmutex_lock_callback(int mode, int type, char *file,
|
||||
int line);
|
||||
extern "C" void sslmutex_lock_callback(int mode, int type, char *file,
|
||||
int line);
|
||||
|
||||
extern "C" unsigned long sslmutex_id_callback();
|
||||
extern "C" unsigned long sslmutex_id_callback();
|
||||
|
||||
class SSLMutex
|
||||
{
|
||||
public:
|
||||
static void initialize();
|
||||
class SSLMutex
|
||||
{
|
||||
public:
|
||||
static void initialize();
|
||||
|
||||
static void finalize();
|
||||
static void finalize();
|
||||
|
||||
private:
|
||||
friend void sslmutex_lock_callback(int mode, int type, char *file,
|
||||
int line);
|
||||
private:
|
||||
friend void sslmutex_lock_callback(int mode, int type, char *file,
|
||||
int line);
|
||||
|
||||
SSLMutex();
|
||||
SSLMutex();
|
||||
|
||||
~SSLMutex();
|
||||
~SSLMutex();
|
||||
|
||||
static SSLMutex * ssl_mutex;
|
||||
static SSLMutex * ssl_mutex;
|
||||
|
||||
static std::vector<pthread_mutex_t *> vmutex;
|
||||
};
|
||||
static std::vector<pthread_mutex_t *> vmutex;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* _NEBULA_UTIL_H_ */
|
||||
|
@ -251,6 +251,28 @@ public:
|
||||
static void oid_filter(int start_id,
|
||||
int end_id,
|
||||
string& filter);
|
||||
|
||||
/**
|
||||
* This function returns a legal SQL string that can be used in an SQL
|
||||
* statement. The string is encoded to an escaped SQL string, taking into
|
||||
* account the current character set of the connection.
|
||||
* @param str the string to be escaped
|
||||
* @return a valid SQL string or NULL in case of failure
|
||||
*/
|
||||
char * escape_str(const string& str)
|
||||
{
|
||||
return db->escape_str(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a previously scaped string
|
||||
* @param str pointer to the str
|
||||
*/
|
||||
void free_str(char * str)
|
||||
{
|
||||
db->free_str(str);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
VirtualMachinePoolInfo():
|
||||
RequestManagerPoolInfoFilter("one.vmpool.info",
|
||||
"Returns the virtual machine instances pool",
|
||||
"A:siiii")
|
||||
"A:siiiis")
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmpool();
|
||||
|
@ -170,6 +170,10 @@ public:
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
string& to_json(string& xml) const;
|
||||
|
||||
string& to_token(string& xml) const;
|
||||
|
||||
/**
|
||||
* Writes the template in a plain text string
|
||||
* @param str string that hold the template representation
|
||||
|
@ -1884,6 +1884,10 @@ private:
|
||||
*/
|
||||
string& to_xml_extended(string& xml, int n_history) const;
|
||||
|
||||
string& to_json(string& json) const;
|
||||
|
||||
string& to_token(string& text) const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Attribute Parser
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -1458,8 +1458,7 @@ ONEDB_SHARED_MIGRATOR_FILES="src/onedb/shared/2.0_to_2.9.80.rb \
|
||||
src/onedb/shared/5.3.80_to_5.4.0.rb \
|
||||
src/onedb/shared/5.4.0_to_5.4.1.rb \
|
||||
src/onedb/shared/5.4.1_to_5.5.80.rb \
|
||||
src/onedb/shared/5.5.80_to_5.6.0.rb \
|
||||
src/onedb/shared/5.6.0_to_5.7.80.rb"
|
||||
src/onedb/shared/5.5.80_to_5.6.0.rb"
|
||||
|
||||
ONEDB_LOCAL_MIGRATOR_FILES="src/onedb/local/4.5.80_to_4.7.80.rb \
|
||||
src/onedb/local/4.7.80_to_4.9.80.rb \
|
||||
|
@ -198,6 +198,13 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
:format => String
|
||||
}
|
||||
|
||||
SEARCH = {
|
||||
:name => "search",
|
||||
:large => "--search search",
|
||||
:description=> "query in KEY=VALUE format",
|
||||
:format => String
|
||||
}
|
||||
|
||||
def self.rname
|
||||
"VM"
|
||||
end
|
||||
|
@ -1047,8 +1047,28 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command :list, list_desc, [:filterflag, nil],
|
||||
:options => CLIHelper::OPTIONS + OpenNebulaHelper::OPTIONS +
|
||||
[OpenNebulaHelper::DESCRIBE] do
|
||||
helper.list_pool(options, false, args[0])
|
||||
[OpenNebulaHelper::DESCRIBE] + [OneVMHelper::SEARCH] do
|
||||
if !options[:search]
|
||||
helper.list_pool(options, false, args[0])
|
||||
else
|
||||
table = helper.format_pool(options)
|
||||
pool = OpenNebula::VirtualMachinePool.new(OneVMHelper.get_client)
|
||||
|
||||
rc = pool.info_search(:query => options[:search])
|
||||
|
||||
if rc != nil
|
||||
puts rc.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
if options[:xml]
|
||||
puts pool.to_xml
|
||||
else
|
||||
table.show(pool.to_hash, options)
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
show_desc = <<-EOT.unindent
|
||||
|
@ -30,7 +30,6 @@ $LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
|
||||
require 'command_parser'
|
||||
require 'one_helper/onevntemplate_helper'
|
||||
require 'one_helper/onevnet_helper'
|
||||
require 'pry'
|
||||
|
||||
CommandParser::CmdParser.new(ARGV) do
|
||||
usage '`onevntemplate` <command> [<args>] [<options>]'
|
||||
|
@ -65,25 +65,9 @@ string * VectorAttribute::marshall(const char * _sep) const
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string * VectorAttribute::to_xml() const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
to_xml(oss);
|
||||
|
||||
string * xml = new string;
|
||||
|
||||
*xml = oss.str();
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VectorAttribute::to_xml(ostringstream &oss) const
|
||||
{
|
||||
map<string,string>::const_iterator it;
|
||||
map<string,string>::const_iterator it;
|
||||
|
||||
oss << "<" << name() << ">";
|
||||
|
||||
@ -102,6 +86,60 @@ void VectorAttribute::to_xml(ostringstream &oss) const
|
||||
oss << "</"<< name() << ">";
|
||||
}
|
||||
|
||||
void VectorAttribute::to_json(std::ostringstream& s) const
|
||||
{
|
||||
if ( attribute_value.empty() )
|
||||
{
|
||||
s << "{}";
|
||||
return;
|
||||
}
|
||||
|
||||
map<string,string>::const_iterator it = attribute_value.begin();
|
||||
bool is_first = true;
|
||||
|
||||
s << "{";
|
||||
|
||||
for (++it; it!=attribute_value.end(); it++)
|
||||
{
|
||||
if ( it->first.empty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !is_first )
|
||||
{
|
||||
s << ",";
|
||||
}
|
||||
else
|
||||
{
|
||||
is_first = false;
|
||||
}
|
||||
|
||||
s << "\"" << it->first << "\": ";
|
||||
one_util::escape_json(it->second, s);
|
||||
}
|
||||
|
||||
s << "}";
|
||||
}
|
||||
|
||||
void VectorAttribute::to_token(std::ostringstream& s) const
|
||||
{
|
||||
map<string,string>::const_iterator it;
|
||||
|
||||
for (it=attribute_value.begin(); it!=attribute_value.end(); it++)
|
||||
{
|
||||
if (it->first.empty() || it->second.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
one_util::escape_token(it->first, s);
|
||||
s << "=";
|
||||
one_util::escape_token(it->second, s);
|
||||
s << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -380,6 +380,57 @@ std::string one_util::gsub(const std::string& st, const std::string& sfind,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void one_util::escape_json(const std::string& str, std::ostringstream& s)
|
||||
{
|
||||
std::string::const_iterator it;
|
||||
|
||||
s << "\"";
|
||||
|
||||
for (it = str.begin(); it != str.end(); ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '\\': s << "\\\\"; break;
|
||||
case '"' : s << "\\\""; break;
|
||||
case '/' : s << "\\/"; break;
|
||||
case '\b': s << "\\b"; break;
|
||||
case '\f': s << "\\f"; break;
|
||||
case '\n': s << "\\n"; break;
|
||||
case '\r': s << "\\r"; break;
|
||||
case '\t': s << "\\t"; break;
|
||||
default : s << *it;
|
||||
}
|
||||
}
|
||||
|
||||
s << "\"";
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void one_util::escape_token(const std::string& str, std::ostringstream& s)
|
||||
{
|
||||
std::string::const_iterator it;
|
||||
|
||||
for (it = str.begin(); it != str.end(); ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '-':
|
||||
case '_':
|
||||
case '.':
|
||||
case ':':
|
||||
s << '_';
|
||||
break;
|
||||
default :
|
||||
s << *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
namespace one_util
|
||||
{
|
||||
template<>
|
||||
|
@ -252,8 +252,6 @@ void Nebula::start(bool bootstrap_only)
|
||||
// -----------------------------------------------------------
|
||||
try
|
||||
{
|
||||
bool db_is_sqlite = true;
|
||||
|
||||
string server;
|
||||
int port;
|
||||
string user;
|
||||
@ -265,12 +263,7 @@ void Nebula::start(bool bootstrap_only)
|
||||
|
||||
if ( _db != 0 )
|
||||
{
|
||||
string value = _db->vector_value("BACKEND");
|
||||
|
||||
if (value == "mysql")
|
||||
{
|
||||
db_is_sqlite = false;
|
||||
}
|
||||
db_backend_type = _db->vector_value("BACKEND");
|
||||
|
||||
if (_db->vector_value("SERVER", server) == -1)
|
||||
{
|
||||
@ -303,7 +296,7 @@ void Nebula::start(bool bootstrap_only)
|
||||
}
|
||||
}
|
||||
|
||||
if ( db_is_sqlite )
|
||||
if ( db_backend_type == "sqlite" )
|
||||
{
|
||||
db_backend = new SqliteDB(var_location + "one.db");
|
||||
}
|
||||
|
@ -177,6 +177,36 @@ public class VirtualMachinePool extends Pool implements Iterable<VirtualMachine>
|
||||
return client.call(INFO_METHOD, filter, startId, endId, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all or part of the Virtual Machines in the pool. The
|
||||
* Virtual Machines to retrieve can be also filtered by Id, specifying the
|
||||
* first and last Id to include; and by state.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param filter Filter flag to use. Possible values:
|
||||
* <ul>
|
||||
* <li>{@link Pool#ALL}: All Virtual Machines</li>
|
||||
* <li>{@link Pool#MINE}: Connected user's Virtual Machines</li>
|
||||
* <li>{@link Pool#MINE_GROUP}: Connected user's Virtual Machines, and the ones in
|
||||
* his group</li>
|
||||
* <li>{@link Pool#GROUP}: User's primary group Virtual Machines</li>
|
||||
* <li>>= 0 UID User's Virtual Machines</li>
|
||||
* </ul>
|
||||
* @param startId Lowest Id to retrieve
|
||||
* @param endId Biggest Id to retrieve
|
||||
* @param state Numeric state of the Virtual Machines wanted, or one
|
||||
* of {@link VirtualMachinePool#ALL_VM} or
|
||||
* {@link VirtualMachinePool#NOT_DONE}
|
||||
* @param query query for FTS
|
||||
* @return If successful the message contains the string
|
||||
* with the information returned by OpenNebula.
|
||||
*/
|
||||
public static OneResponse info_search(Client client, int filter,
|
||||
int startId, int endId, int state, String query)
|
||||
{
|
||||
return client.call(INFO_METHOD, filter, startId, endId, state, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the monitoring data for all or part of the Virtual
|
||||
* Machines in the pool.
|
||||
|
@ -115,6 +115,23 @@ module OpenNebula
|
||||
INFO_NOT_DONE)
|
||||
end
|
||||
|
||||
def info_search(args = {})
|
||||
default_args = {
|
||||
:who => INFO_ALL,
|
||||
:start_id => -1,
|
||||
:end_id => -1,
|
||||
:state => INFO_NOT_DONE,
|
||||
:query => ""
|
||||
}.merge!(args)
|
||||
|
||||
return info_filter(VM_POOL_METHODS[:info],
|
||||
default_args[:who],
|
||||
default_args[:start_id],
|
||||
default_args[:end_id],
|
||||
default_args[:state],
|
||||
default_args[:query])
|
||||
end
|
||||
|
||||
alias_method :info!, :info
|
||||
alias_method :info_all!, :info_all
|
||||
alias_method :info_mine!, :info_mine
|
||||
@ -458,8 +475,8 @@ module OpenNebula
|
||||
data_hash
|
||||
end
|
||||
|
||||
def info_filter(xml_method, who, start_id, end_id, state)
|
||||
return xmlrpc_info(xml_method, who, start_id, end_id, state)
|
||||
def info_filter(xml_method, who, start_id, end_id, state, query="")
|
||||
return xmlrpc_info(xml_method, who, start_id, end_id, state, query)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -91,8 +91,15 @@ class OneDBBacKEnd
|
||||
vm_pool: "oid INTEGER PRIMARY KEY, name VARCHAR(128), " <<
|
||||
"body MEDIUMTEXT, uid INTEGER, gid INTEGER, " <<
|
||||
"last_poll INTEGER, state INTEGER, lcm_state INTEGER, " <<
|
||||
"owner_u INTEGER, group_u INTEGER, other_u INTEGER, short_body MEDIUMTEXT",
|
||||
|
||||
"owner_u INTEGER, group_u INTEGER, other_u INTEGER, short_body MEDIUMTEXT, " <<
|
||||
"search_token MEDIUMTEXT, FULLTEXT ftidx(search_token)",
|
||||
|
||||
vm_pool_sqlite: "oid INTEGER PRIMARY KEY, name VARCHAR(128), " <<
|
||||
"body MEDIUMTEXT, uid INTEGER, gid INTEGER, " <<
|
||||
"last_poll INTEGER, state INTEGER, lcm_state INTEGER, " <<
|
||||
"owner_u INTEGER, group_u INTEGER, other_u INTEGER, short_body MEDIUMTEXT, " <<
|
||||
"search_token MEDIUMTEXT",
|
||||
|
||||
vn_template_pool: "oid INTEGER PRIMARY KEY, name VARCHAR(128), " <<
|
||||
"body MEDIUMTEXT, uid INTEGER, gid INTEGER," <<
|
||||
"owner_u INTEGER, group_u INTEGER, other_u INTEGER"
|
||||
|
@ -52,7 +52,7 @@ require 'fsck/template'
|
||||
require 'fsck/quotas'
|
||||
|
||||
module OneDBFsck
|
||||
VERSION = "5.7.80"
|
||||
VERSION = "5.6.0"
|
||||
LOCAL_VERSION = "5.7.80"
|
||||
|
||||
def db_version
|
||||
|
@ -38,7 +38,7 @@ module Migrator
|
||||
def up
|
||||
bug_2687 # MUST be run before 2489, which generates short body
|
||||
feature_2253
|
||||
feature_2489
|
||||
feature_2489_2671
|
||||
feature_826
|
||||
true
|
||||
end
|
||||
@ -104,10 +104,15 @@ module Migrator
|
||||
@db.run 'DROP TABLE old_vm_pool;'
|
||||
end
|
||||
|
||||
def feature_2489
|
||||
def feature_2489_2671
|
||||
@db.run 'DROP TABLE IF EXISTS old_vm_pool;'
|
||||
@db.run 'ALTER TABLE vm_pool RENAME TO old_vm_pool;'
|
||||
create_table(:vm_pool, nil, db_version)
|
||||
|
||||
if @backend.class == BackEndSQLite
|
||||
create_table(:vm_pool_sqlite, nil, db_version)
|
||||
elsif
|
||||
create_table(:vm_pool, nil, db_version)
|
||||
end
|
||||
|
||||
@db.transaction do
|
||||
@db.fetch('SELECT * FROM old_vm_pool') do |row|
|
||||
@ -116,6 +121,7 @@ module Migrator
|
||||
end
|
||||
|
||||
row[:short_body] = gen_short_body(doc)
|
||||
row[:search_token] = gen_search_body(doc)
|
||||
|
||||
@db[:vm_pool].insert(row)
|
||||
end
|
||||
@ -135,6 +141,67 @@ module Migrator
|
||||
end
|
||||
end
|
||||
|
||||
def gen_search_body(body)
|
||||
|
||||
search_body = "UNAME=" + escape_token(body.root.xpath('UNAME').text) + "\n" +
|
||||
"GNAME=" + escape_token(body.root.xpath('GNAME').text) + "\n" +
|
||||
"NAME=" + escape_token(body.root.xpath('NAME').text) + "\n" +
|
||||
"LAST_POLL=" + escape_token(body.root.xpath('LAST_POLL').text) + "\n" +
|
||||
"PREV_STATE=" + escape_token(body.root.xpath('PREV_STATE').text) + "\n" +
|
||||
"PREV_LCM_STATE=" + escape_token(body.root.xpath('PREV_LCM_STATE').text) + "\n" +
|
||||
"RESCHED=" + escape_token(body.root.xpath('RESCHED').text) + "\n" +
|
||||
"STIME=" + escape_token(body.root.xpath('STIME').text) + "\n" +
|
||||
"ETIME=" + escape_token(body.root.xpath('ETIME').text) + "\n" +
|
||||
"DEPLOY_ID=" + escape_token(body.root.xpath('DEPLOY_ID').text) + "\n"
|
||||
|
||||
body.root.xpath("//TEMPLATE/*").each do |node|
|
||||
search_body += to_token(node)
|
||||
end
|
||||
|
||||
node = Nokogiri::XML(body.root.xpath("//HISTORY_RECORDS/HISTORY[last()]").to_s)
|
||||
|
||||
if !node.root.nil?
|
||||
search_body += history_to_token(node)
|
||||
end
|
||||
|
||||
return search_body
|
||||
end
|
||||
|
||||
def to_token(node)
|
||||
search_body = ""
|
||||
if node.children.size > 1
|
||||
node.children.each do |child|
|
||||
search_body += to_token(child)
|
||||
end
|
||||
elsif
|
||||
search_body += node.name + "=" + escape_token(node.children.text) + "\n"
|
||||
end
|
||||
|
||||
return search_body
|
||||
end
|
||||
|
||||
def history_to_token(hr)
|
||||
hr_token = "HOSTNAME=" + escape_token(hr.xpath("//HOSTNAME").text) + "\n" +
|
||||
"HID=" + hr.xpath("//HID").text + "\n" +
|
||||
"CID=" + hr.xpath("//CID").text + "\n" +
|
||||
"DS_ID=" + hr.xpath("//DS_ID").text + "\n"
|
||||
end
|
||||
|
||||
def escape_token(str)
|
||||
str_scaped = ""
|
||||
|
||||
str.split("").each do |c|
|
||||
case c
|
||||
when '-', '_', '.', ':'
|
||||
str_scaped += '_'
|
||||
else
|
||||
str_scaped += c
|
||||
end
|
||||
end
|
||||
|
||||
return str_scaped
|
||||
end
|
||||
|
||||
def gen_short_body(body)
|
||||
short_body = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
||||
xml.VM{
|
||||
|
@ -96,12 +96,30 @@ void VirtualMachinePoolInfo::request_execute(
|
||||
int end_id = xmlrpc_c::value_int(paramList.getInt(3));
|
||||
int state = xmlrpc_c::value_int(paramList.getInt(4));
|
||||
|
||||
ostringstream state_filter;
|
||||
std::string fts_query;
|
||||
|
||||
if (paramList.size() > 5)
|
||||
{
|
||||
fts_query = xmlrpc_c::value_string(paramList.getString(5));
|
||||
|
||||
std::string backend = Nebula::instance().get_db_backend();
|
||||
|
||||
if (!fts_query.empty() && backend == "sqlite")
|
||||
{
|
||||
att.resp_msg = "Full text search is not allowed with sqlite backend";
|
||||
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ostringstream and_filter;
|
||||
|
||||
if (( state < VirtualMachinePoolInfo::ALL_VM ) ||
|
||||
( state > VirtualMachine::CLONING_FAILURE ))
|
||||
{
|
||||
att.resp_msg = "Incorrect filter_flag, state";
|
||||
|
||||
failure_response(XML_RPC_API, att);
|
||||
return;
|
||||
}
|
||||
@ -112,15 +130,39 @@ void VirtualMachinePoolInfo::request_execute(
|
||||
break;
|
||||
|
||||
case VirtualMachinePoolInfo::NOT_DONE:
|
||||
state_filter << "state <> " << VirtualMachine::DONE;
|
||||
and_filter << "state <> " << VirtualMachine::DONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
state_filter << "state = " << state;
|
||||
and_filter << "state = " << state;
|
||||
break;
|
||||
}
|
||||
|
||||
dump(att, filter_flag, start_id, end_id, state_filter.str(), "");
|
||||
if (!fts_query.empty())
|
||||
{
|
||||
char * _fts_query = pool->escape_str(fts_query);
|
||||
|
||||
if ( _fts_query == 0 )
|
||||
{
|
||||
att.resp_msg = "Error building search query";
|
||||
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!and_filter.str().empty())
|
||||
{
|
||||
and_filter << " AND ";
|
||||
}
|
||||
|
||||
and_filter << "MATCH(search_token) AGAINST ('+\"";
|
||||
one_util::escape_token(_fts_query, and_filter);
|
||||
and_filter << "\"' in boolean mode)";
|
||||
|
||||
pool->free_str(_fts_query);
|
||||
}
|
||||
|
||||
dump(att, filter_flag, start_id, end_id, and_filter.str(), "");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -471,7 +513,7 @@ void RequestManagerPoolInfoFilter::dump(
|
||||
limit_clause = oss.str();
|
||||
}
|
||||
|
||||
Nebula::instance().get_configuration_attribute(att.uid, att.gid,
|
||||
Nebula::instance().get_configuration_attribute(att.uid, att.gid,
|
||||
"API_LIST_ORDER", desc);
|
||||
|
||||
rc = pool->dump(str, where_string, limit_clause,
|
||||
|
@ -386,19 +386,14 @@ bool Template::get(const string& name, bool& value) const
|
||||
|
||||
string& Template::to_xml(string& xml) const
|
||||
{
|
||||
multimap<string,Attribute *>::const_iterator it;
|
||||
ostringstream oss;
|
||||
string * s;
|
||||
multimap<string,Attribute *>::const_iterator it;
|
||||
ostringstream oss;
|
||||
|
||||
oss << "<" << xml_root << ">";
|
||||
|
||||
for ( it = attributes.begin(); it!=attributes.end(); it++)
|
||||
{
|
||||
s = it->second->to_xml();
|
||||
|
||||
oss << *s;
|
||||
|
||||
delete s;
|
||||
it->second->to_xml(oss);
|
||||
}
|
||||
|
||||
oss << "</" << xml_root << ">";
|
||||
@ -407,6 +402,81 @@ string& Template::to_xml(string& xml) const
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
string& Template::to_json(string& json) const
|
||||
{
|
||||
multimap<string, Attribute *>::const_iterator it;
|
||||
ostringstream oss;
|
||||
|
||||
bool is_first = true;
|
||||
|
||||
oss << "\"" << xml_root << "\": {";
|
||||
|
||||
for ( it = attributes.begin(); it!=attributes.end(); )
|
||||
{
|
||||
if (!is_first)
|
||||
{
|
||||
oss << ",";
|
||||
}
|
||||
else
|
||||
{
|
||||
is_first = false;
|
||||
}
|
||||
|
||||
oss << "\"" << it->first << "\": ";
|
||||
|
||||
if ( attributes.count(it->first) == 1 )
|
||||
{
|
||||
it->second->to_json(oss);
|
||||
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string jelem = it->first;
|
||||
bool is_array_first = true;
|
||||
|
||||
oss << "[ ";
|
||||
|
||||
for ( ; it->first == jelem && it != attributes.end() ; ++it )
|
||||
{
|
||||
if ( !is_array_first )
|
||||
{
|
||||
oss << ",";
|
||||
}
|
||||
else
|
||||
{
|
||||
is_array_first = false;
|
||||
}
|
||||
|
||||
it->second->to_json(oss);
|
||||
}
|
||||
|
||||
oss << "]";
|
||||
}
|
||||
}
|
||||
|
||||
oss << "}";
|
||||
|
||||
json = oss.str();
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
string& Template::to_token(string& str) const
|
||||
{
|
||||
ostringstream os;
|
||||
multimap<string,Attribute *>::const_iterator it;
|
||||
|
||||
for ( it = attributes.begin(); it!=attributes.end(); it++)
|
||||
{
|
||||
it->second->to_token(os);
|
||||
}
|
||||
|
||||
str = os.str();
|
||||
return str;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -341,6 +341,62 @@ string& History::to_xml(string& xml, bool database) const
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& History::to_json(string& json) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "\"HISTORY\": {" <<
|
||||
"\"OID\": \"" << oid << "\"," <<
|
||||
"\"SEQ\": \"" << seq << "\"," <<
|
||||
"\"HOSTNAME\": \"" << hostname << "\"," <<
|
||||
"\"HID\": \"" << hid << "\"," <<
|
||||
"\"CID\": \"" << cid << "\"," <<
|
||||
"\"STIME\": \"" << stime << "\"," <<
|
||||
"\"ETIME\": \"" << etime << "\"," <<
|
||||
"\"VM_MAD\": \"" << vmm_mad_name << "\"," <<
|
||||
"\"TM_MAD\": \"" << tm_mad_name << "\"," <<
|
||||
"\"DS_ID\": \"" << ds_id << "\"," <<
|
||||
"\"PSTIME\": \"" << prolog_stime << "\"," <<
|
||||
"\"PETIME\": \"" << prolog_etime << "\"," <<
|
||||
"\"RSTIME\": \"" << running_stime << "\"," <<
|
||||
"\"RETIME\": \"" << running_etime << "\"," <<
|
||||
"\"ESTIME\": \"" << epilog_stime << "\"," <<
|
||||
"\"EETIME\": \"" << epilog_etime << "\"," <<
|
||||
"\"ACTION\": \"" << action << "\"," <<
|
||||
"\"UID\": \"" << uid << "\"," <<
|
||||
"\"GID\": \"" << gid << "\"," <<
|
||||
"\"REQUEST_ID\": \"" << req_id << "\",";
|
||||
|
||||
oss << "}";
|
||||
|
||||
json = oss.str();
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& History::to_token(string& text) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "HOSTNAME=";
|
||||
one_util::escape_token(hostname, oss);
|
||||
oss << "\n";
|
||||
|
||||
oss << "HID=" << hid << "\n" <<
|
||||
"CID=" << cid << "\n" <<
|
||||
"DS_ID=" << ds_id << "\n";
|
||||
|
||||
text = oss.str();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& History::to_xml_short(string& xml) const
|
||||
{
|
||||
ostringstream oss;
|
||||
|
@ -457,13 +457,13 @@ const char * VirtualMachine::table = "vm_pool";
|
||||
|
||||
const char * VirtualMachine::db_names =
|
||||
"oid, name, body, uid, gid, last_poll, state, lcm_state, "
|
||||
"owner_u, group_u, other_u, short_body";
|
||||
"owner_u, group_u, other_u, short_body, search_token";
|
||||
|
||||
const char * VirtualMachine::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
|
||||
"vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, "
|
||||
"gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, "
|
||||
"owner_u INTEGER, group_u INTEGER, other_u INTEGER, short_body MEDIUMTEXT)";
|
||||
|
||||
"vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, "
|
||||
"uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, "
|
||||
"lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, "
|
||||
"short_body MEDIUMTEXT, search_token MEDIUMTEXT";
|
||||
|
||||
const char * VirtualMachine::monit_table = "vm_monitoring";
|
||||
|
||||
@ -489,7 +489,21 @@ int VirtualMachine::bootstrap(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ostringstream oss_vm(VirtualMachine::db_bootstrap);
|
||||
string backend = Nebula::instance().get_db_backend();
|
||||
|
||||
ostringstream oss_vm;
|
||||
|
||||
oss_vm << VirtualMachine::db_bootstrap;
|
||||
|
||||
if (backend == "mysql")
|
||||
{
|
||||
oss_vm << ", FULLTEXT ftidx(search_token))";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss_vm << ")";
|
||||
}
|
||||
|
||||
ostringstream oss_monit(VirtualMachine::monit_db_bootstrap);
|
||||
ostringstream oss_hist(History::db_bootstrap);
|
||||
ostringstream oss_showback(VirtualMachine::showback_db_bootstrap);
|
||||
@ -1662,10 +1676,12 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
string xml_body, short_xml_body;
|
||||
string xml_body, short_xml_body, text;
|
||||
|
||||
char * sql_name;
|
||||
char * sql_xml;
|
||||
char * sql_short_xml;
|
||||
char * sql_text;
|
||||
|
||||
sql_name = db->escape_str(name.c_str());
|
||||
|
||||
@ -1698,6 +1714,13 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
goto error_xml_short;
|
||||
}
|
||||
|
||||
sql_text = db->escape_str(to_token(text).c_str());
|
||||
|
||||
if ( sql_text == 0 )
|
||||
{
|
||||
goto error_text;
|
||||
}
|
||||
|
||||
if(replace)
|
||||
{
|
||||
oss << "REPLACE";
|
||||
@ -1719,17 +1742,21 @@ int VirtualMachine::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
<< owner_u << ","
|
||||
<< group_u << ","
|
||||
<< other_u << ","
|
||||
<< "'" << sql_short_xml << "'"
|
||||
<< "'" << sql_short_xml << "',"
|
||||
<< "'" << sql_text << "'"
|
||||
<< ")";
|
||||
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_xml);
|
||||
db->free_str(sql_short_xml);
|
||||
db->free_str(sql_text);
|
||||
|
||||
rc = db->exec_wr(oss);
|
||||
|
||||
return rc;
|
||||
|
||||
error_text:
|
||||
db->free_str(sql_text);
|
||||
error_xml_short:
|
||||
db->free_str(sql_short_xml);
|
||||
error_xml:
|
||||
@ -2145,7 +2172,7 @@ string& VirtualMachine::to_xml_extended(string& xml, int n_history) const
|
||||
string snap_xml;
|
||||
string lock_str;
|
||||
|
||||
ostringstream oss;
|
||||
ostringstream oss;
|
||||
|
||||
oss << "<VM>"
|
||||
<< "<ID>" << oid << "</ID>"
|
||||
@ -2215,6 +2242,91 @@ string& VirtualMachine::to_xml_extended(string& xml, int n_history) const
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& VirtualMachine::to_json(string& json) const
|
||||
{
|
||||
string template_json;
|
||||
string user_template_json;
|
||||
string history_json;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
oss << "{\"VM\":{"
|
||||
<< "\"ID\": \""<< oid << "\","
|
||||
<< "\"UID\": \""<< uid << "\","
|
||||
<< "\"GID\": \""<< gid << "\","
|
||||
<< "\"UNAME\": \""<< uname << "\","
|
||||
<< "\"GNAME\": \""<< gname << "\","
|
||||
<< "\"NAME\": \""<< name << "\","
|
||||
<< "\"LAST_POLL\": \""<< last_poll << "\","
|
||||
<< "\"STATE\": \""<< state << "\","
|
||||
<< "\"LCM_STATE\": \""<< lcm_state << "\","
|
||||
<< "\"PREV_STATE\": \""<< prev_state << "\","
|
||||
<< "\"PREV_LCM_STATE\": \""<< prev_lcm_state << "\","
|
||||
<< "\"RESCHED\": \""<< resched << "\","
|
||||
<< "\"STIME\": \""<< stime << "\","
|
||||
<< "\"ETIME\": \""<< etime << "\","
|
||||
<< "\"DEPLOY_ID\": \""<< deploy_id << "\","
|
||||
<< obj_template->to_json(template_json) << ","
|
||||
<< user_obj_template->to_json(user_template_json);
|
||||
|
||||
if ( hasHistory() )
|
||||
{
|
||||
oss << ",\"HISTORY_RECORDS\": [";
|
||||
|
||||
oss << history->to_json(history_json);
|
||||
|
||||
oss << "]";
|
||||
}
|
||||
|
||||
oss << "}}";
|
||||
|
||||
|
||||
json = oss.str();
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& VirtualMachine::to_token(string& text) const
|
||||
{
|
||||
string template_text;
|
||||
string user_template_text;
|
||||
string history_text;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
oss << "UNAME="<< uname << "\n"
|
||||
<< "GNAME="<< gname << "\n";
|
||||
|
||||
oss << "NAME=";
|
||||
one_util::escape_token(name, oss);
|
||||
oss << "\n";
|
||||
|
||||
oss << "LAST_POLL="<< last_poll << "\n"
|
||||
<< "PREV_STATE="<< prev_state << "\n"
|
||||
<< "PREV_LCM_STATE="<< prev_lcm_state << "\n"
|
||||
<< "RESCHED="<< resched << "\n"
|
||||
<< "STIME="<< stime << "\n"
|
||||
<< "ETIME="<< etime << "\n"
|
||||
<< "DEPLOY_ID="<< deploy_id << "\n"
|
||||
<< obj_template->to_token(template_text) << "\n"
|
||||
<< user_obj_template->to_token(user_template_text);
|
||||
|
||||
if ( hasHistory() )
|
||||
{
|
||||
oss << "\n" << history->to_token(history_text);
|
||||
}
|
||||
|
||||
text = oss.str();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& VirtualMachine::to_xml_short(string& xml)
|
||||
{
|
||||
string disks_xml, monitoring_xml, user_template_xml, history_xml, nics_xml;
|
||||
|
@ -26,13 +26,13 @@
|
||||
|
||||
int AddressRangeIPAM::from_vattr(VectorAttribute * attr, std::string& error_msg)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
IPAMManager * ipamm = Nebula::instance().get_ipamm();
|
||||
|
||||
std::string * ar_xml = attr->to_xml();
|
||||
attr->to_xml(oss);
|
||||
|
||||
IPAMRequest ir(*ar_xml);
|
||||
|
||||
free(ar_xml);
|
||||
IPAMRequest ir(oss.str());
|
||||
|
||||
ipamm->trigger(IPMAction::REGISTER_ADDRESS_RANGE, &ir);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user