mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-30 22:50:10 +03:00
Merge branch 'feature-407' of dsa-research.org:one into feature-407. Restored previous UserPool tests.
Conflicts: include/UserPool.h
This commit is contained in:
commit
6246c89df9
@ -251,16 +251,6 @@ private:
|
||||
* @return 0 on success
|
||||
*/
|
||||
int discover_cb(void * _map, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get output the host pool in XML format
|
||||
* (Host::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*HOST_POOL_H_*/
|
||||
|
@ -188,16 +188,6 @@ private:
|
||||
{
|
||||
return new Image(-1,"",0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the image pool in XML format
|
||||
* (Image::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*IMAGE_POOL_H_*/
|
||||
|
@ -143,99 +143,21 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int select(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int boid;
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));
|
||||
|
||||
oss << "SELECT body FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
virtual int select(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Reads the PoolObjectSQL (identified by its OID) from the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int select(SqlDB *db, const string& _name, int _uid)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
char * sql_name;
|
||||
|
||||
sql_name = db->escape_str(_name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));
|
||||
|
||||
oss << "SELECT body FROM " << table << " WHERE name = '" <<_name << "'";
|
||||
|
||||
if ( _uid != -1 )
|
||||
{
|
||||
oss << " AND uid = " << _uid;
|
||||
}
|
||||
|
||||
name = "";
|
||||
uid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
db->free_str(sql_name);
|
||||
|
||||
if ((rc != 0) || (_name != name) || (_uid != uid))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
virtual int select(SqlDB *db, const string& _name, int _uid);
|
||||
|
||||
/**
|
||||
* Drops object from the database
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual int drop(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
set_valid(false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
};
|
||||
virtual int drop(SqlDB *db);
|
||||
|
||||
/**
|
||||
* Function to output a pool object into a stream in XML format
|
||||
|
@ -151,6 +151,19 @@ protected:
|
||||
*/
|
||||
SqlDB * db;
|
||||
|
||||
/**
|
||||
* Dumps the pool in XML format. A filter can be also added to the
|
||||
* query
|
||||
* @param oss the output stream to dump the pool contents
|
||||
* @param elem_name Name of the root xml pool name
|
||||
* @param table Pool table name
|
||||
* @param where filter for the objects, defaults to all
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& elem_name,
|
||||
const char * table, const string& where);
|
||||
|
||||
private:
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
@ -249,6 +262,15 @@ private:
|
||||
* Callback to store the IDs of pool objects (PoolSQL::search)
|
||||
*/
|
||||
int search_cb(void *_oids, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get output in XML format
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*POOL_SQL_H_*/
|
||||
|
@ -136,17 +136,6 @@ private:
|
||||
{
|
||||
return new User(-1,"","",true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the user pool in XML format
|
||||
* (User::dump)
|
||||
* @param _oss pointer to the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*USER_POOL_H_*/
|
||||
|
@ -161,16 +161,6 @@ private:
|
||||
{
|
||||
return new VirtualMachine(-1,-1,"", 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the vm pool in XML format
|
||||
* (VirtualMachinePool::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_MACHINE_POOL_H_*/
|
||||
|
@ -153,16 +153,6 @@ private:
|
||||
{
|
||||
return new VirtualNetwork(0,"",0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the virtual network pool in XML format
|
||||
* (VirtualNetworkPool::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_NETWORK_POOL_H_*/
|
||||
|
@ -250,41 +250,9 @@ int HostPool::discover(map<int, string> * discovered_hosts, int host_limit)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int HostPool::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return Host::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int HostPool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<HOST_POOL>";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&HostPool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << Host::table;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
oss << "</HOST_POOL>";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
return PoolSQL::dump(oss, "HOST_POOL", Host::table, where);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -103,42 +103,9 @@ int ImagePool::allocate (
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return Image::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<IMAGE_POOL>";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&ImagePool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << Image::table;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
oss << "</IMAGE_POOL>";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
return PoolSQL::dump(oss, "IMAGE_POOL", Image::table, where);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
110
src/pool/PoolObjectSQL.cc
Normal file
110
src/pool/PoolObjectSQL.cc
Normal file
@ -0,0 +1,110 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "PoolObjectSQL.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolObjectSQL::select(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
int boid;
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));
|
||||
|
||||
oss << "SELECT body FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolObjectSQL::select(SqlDB *db, const string& _name, int _uid)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int rc;
|
||||
char * sql_name;
|
||||
|
||||
sql_name = db->escape_str(_name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));
|
||||
|
||||
oss << "SELECT body FROM " << table << " WHERE name = '" <<_name << "'";
|
||||
|
||||
if ( _uid != -1 )
|
||||
{
|
||||
oss << " AND uid = " << _uid;
|
||||
}
|
||||
|
||||
name = "";
|
||||
uid = -1;
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
db->free_str(sql_name);
|
||||
|
||||
if ((rc != 0) || (_name != name) || (_uid != uid))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolObjectSQL::drop(SqlDB *db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
set_valid(false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
@ -351,6 +351,55 @@ void PoolSQL::clean()
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
if ( (!values[0]) || (num != 1) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*oss << values[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL::dump(ostringstream& oss,
|
||||
const string& elem_name,
|
||||
const char * table,
|
||||
const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<" << elem_name << ">";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&PoolSQL::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << table;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
oss << "</" << elem_name << ">";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL:: search_cb(void * _oids, int num, char **values, char **names)
|
||||
{
|
||||
vector<int> * oids;
|
||||
|
@ -22,7 +22,8 @@ lib_name='nebula_pool'
|
||||
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'PoolSQL.cc'
|
||||
'PoolSQL.cc',
|
||||
'PoolObjectSQL.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
|
@ -296,39 +296,7 @@ int UserPool::authorize(AuthRequest& ar)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int UserPool::dump_cb(void * _oss, int num, char **values, char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return User::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int UserPool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<USER_POOL>";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&UserPool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << User::table;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd, this);
|
||||
|
||||
unset_callback();
|
||||
|
||||
oss << "</USER_POOL>";
|
||||
|
||||
return rc;
|
||||
return PoolSQL::dump(oss, "USER_POOL", User::table, where);
|
||||
}
|
||||
|
@ -57,18 +57,18 @@ class UserPoolTest : public PoolTest
|
||||
|
||||
// Not all tests from PoolTest can be used. Because
|
||||
// of the initial user added to the DB, the oid_assignment would fail.
|
||||
// CPPUNIT_TEST (get_from_cache);
|
||||
// CPPUNIT_TEST (get_from_db);
|
||||
// CPPUNIT_TEST (wrong_get);
|
||||
// CPPUNIT_TEST (drop_and_get);
|
||||
CPPUNIT_TEST (get_from_cache);
|
||||
CPPUNIT_TEST (get_from_db);
|
||||
CPPUNIT_TEST (wrong_get);
|
||||
CPPUNIT_TEST (drop_and_get);
|
||||
|
||||
// CPPUNIT_TEST (sha1_digest);
|
||||
// CPPUNIT_TEST (split_secret);
|
||||
// CPPUNIT_TEST (initial_user);
|
||||
// CPPUNIT_TEST (authenticate);
|
||||
// CPPUNIT_TEST (get_using_name);
|
||||
// CPPUNIT_TEST (wrong_get_name);
|
||||
// CPPUNIT_TEST (update);
|
||||
CPPUNIT_TEST (sha1_digest);
|
||||
CPPUNIT_TEST (split_secret);
|
||||
CPPUNIT_TEST (initial_user);
|
||||
CPPUNIT_TEST (authenticate);
|
||||
CPPUNIT_TEST (get_using_name);
|
||||
CPPUNIT_TEST (wrong_get_name);
|
||||
CPPUNIT_TEST (update);
|
||||
CPPUNIT_TEST (duplicates);
|
||||
CPPUNIT_TEST (dump);
|
||||
CPPUNIT_TEST (dump_where);
|
||||
@ -266,9 +266,9 @@ public:
|
||||
CPPUNIT_ASSERT( oid == rc );
|
||||
|
||||
// Try again, with different password
|
||||
// rc = up->allocate(&oid, usernames[0], passwords[1], true, err);
|
||||
// CPPUNIT_ASSERT( rc == -1 );
|
||||
// CPPUNIT_ASSERT( oid == rc );
|
||||
rc = up->allocate(&oid, usernames[0], passwords[1], true, err);
|
||||
CPPUNIT_ASSERT( rc == -1 );
|
||||
CPPUNIT_ASSERT( oid == rc );
|
||||
}
|
||||
|
||||
void dump()
|
||||
|
@ -239,54 +239,27 @@ int VirtualMachinePool::get_pending(
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePool::dump_cb(void * _oss,int num,char **values,char **names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return VirtualMachine::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePool::dump( ostringstream& oss,
|
||||
int state,
|
||||
const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<VM_POOL>";
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualMachinePool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << VirtualMachine::table;
|
||||
ostringstream where_oss;
|
||||
|
||||
if ( state != -1 )
|
||||
{
|
||||
cmd << " WHERE " << VirtualMachine::table << ".state = " << state;
|
||||
where_oss << VirtualMachine::table << ".state = " << state;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd << " WHERE " << VirtualMachine::table << ".state <> 6";
|
||||
where_oss << VirtualMachine::table << ".state <> 6";
|
||||
}
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " AND " << where;
|
||||
where_oss << " AND " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd,this);
|
||||
|
||||
oss << "</VM_POOL>";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
return PoolSQL::dump(oss, "VM_POOL", VirtualMachine::table,where_oss.str());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -108,45 +108,9 @@ int VirtualNetworkPool::allocate (
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetworkPool::dump_cb(void * _oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return VirtualNetwork::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetworkPool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<VNET_POOL>";
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualNetworkPool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT body FROM " << VirtualNetwork::table;
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
rc = db->exec(cmd,this);
|
||||
|
||||
oss << "</VNET_POOL>";
|
||||
|
||||
unset_callback();
|
||||
|
||||
return rc;
|
||||
return PoolSQL::dump(oss, "VNET_POOL", VirtualNetwork::table,where);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
Loading…
x
Reference in New Issue
Block a user