1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

Merge branch 'feature-360'

This commit is contained in:
Ruben S. Montero 2012-01-02 03:02:53 +01:00
commit 8f160525cd
15 changed files with 448 additions and 183 deletions

View File

@ -407,7 +407,7 @@ private:
// Configuration
// ---------------------------------------------------------------
NebulaTemplate * nebula_configuration;
OpenNebulaTemplate * nebula_configuration;
// ---------------------------------------------------------------
// Nebula Pools

View File

@ -20,16 +20,25 @@
#include "Template.h"
#include <map>
/**
* This class provides the basic abstraction for OpenNebula configuration files
*/
class NebulaTemplate : public Template
{
{
public:
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
NebulaTemplate(string& etc_location, string& var_location);
NebulaTemplate(const string& etc_location, const char * _conf_name)
{
conf_file = etc_location + _conf_name;
}
~NebulaTemplate(){};
virtual ~NebulaTemplate(){};
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
static const char * conf_name;
int get(const char * name, vector<const Attribute*>& values) const
{
string _name(name);
@ -50,41 +59,95 @@ public:
Template::get(_name,values);
};
void get(const char *name, unsigned int& values) const
{
int ival;
NebulaTemplate::get(name, ival);
values = static_cast<unsigned int>(ival);
};
void get(const char * name, time_t& values) const
{
const SingleAttribute * sattr;
vector<const Attribute *> attr;
const SingleAttribute * sattr;
vector<const Attribute *> attr;
string _name(name);
string _name(name);
if ( Template::get(_name,attr) == 0 )
{
values = 0;
return;
values = 0;
return;
}
sattr = dynamic_cast<const SingleAttribute *>(attr[0]);
if ( sattr != 0 )
{
istringstream is;
is.str(sattr->value());
is >> values;
istringstream is;
is.str(sattr->value());
is >> values;
}
else
values = 0;
values = 0;
};
private:
friend class Nebula;
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
/**
* Parse and loads the configuration in the template
*/
int load_configuration();
protected:
/**
* Full path to the configuration file
*/
string conf_file;
/**
* Defaults for the configuration file
*/
map<string, Attribute*> conf_default;
/**
* Sets the defaults value for the template
*/
virtual void set_conf_default() = 0;
};
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class OpenNebulaTemplate : public NebulaTemplate
{
public:
OpenNebulaTemplate(const string& etc_location, const string& _var_location):
NebulaTemplate(etc_location, conf_name), var_location(_var_location)
{};
int load_configuration();
~OpenNebulaTemplate(){};
private:
/**
* Name for the configuration file, oned.conf
*/
static const char * conf_name;
/**
* Path for the var directory, for defaults
*/
string var_location;
/**
* Sets the defaults value for the template
*/
void set_conf_default();
};

View File

@ -761,6 +761,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \
ETC_FILES="share/etc/oned.conf \
share/etc/defaultrc \
src/scheduler/etc/sched.conf \
src/cli/etc/group.default"
VMWARE_ETC_FILES="src/vmm_mad/remotes/vmware/vmwarerc"

View File

@ -43,18 +43,10 @@ fi
KILL_9_SECONDS=5
#------------------------------------------------------------------------------
# Function that checks for running daemons and gets PORT from conf
# Function that checks for running daemons
#------------------------------------------------------------------------------
setup()
{
PORT=$(sed -n '/^[ \t]*PORT/s/^.*PORT\s*=\s*\([0-9]\+\)\s*.*$/\1/p' \
$ONE_CONF)
if [ $? -ne 0 ]; then
echo "Can not find PORT in $ONE_CONF."
exit 1
fi
if [ -f $LOCK_FILE ]; then
if [ -f $ONE_PID ]; then
ONEPID=`cat $ONE_PID`
@ -150,17 +142,7 @@ start()
fi
# Start the scheduler
# The following command line arguments are supported by mm_shed:
# [-p port] to connect to oned - default: 2633
# [-t timer] seconds between two scheduling actions - default: 30
# [-m machines limit] max number of VMs managed in each scheduling action
# - default: 300
# [-d dispatch limit] max number of VMs dispatched in each scheduling action
# - default: 30
# [-h host dispatch] max number of VMs dispatched to a given host in each
# scheduling action - default: 1
$ONE_SCHEDULER -p $PORT -t 30 -m 300 -d 30 -h 1&
$ONE_SCHEDULER&
LASTRC=$?
LASTPID=$!

View File

@ -56,7 +56,7 @@ void Nebula::start()
// Configuration
// -----------------------------------------------------------
nebula_configuration = new NebulaTemplate(etc_location, var_location);
nebula_configuration = new OpenNebulaTemplate(etc_location, var_location);
rc = nebula_configuration->load_configuration();

View File

@ -15,33 +15,75 @@
/* -------------------------------------------------------------------------- */
#include "NebulaTemplate.h"
#include "Nebula.h"
using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * NebulaTemplate::conf_name="oned.conf";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location)
int NebulaTemplate::load_configuration()
{
char * error = 0;
int rc;
string aname;
Attribute * attr;
map<string, Attribute *>::iterator iter, j;
set_conf_default();
rc = parse(conf_file.c_str(), &error);
if ( rc != 0 && error != 0)
{
cout << "\nError while parsing configuration file:\n" << error << endl;
free(error);
return -1;
}
for(iter=conf_default.begin();iter!=conf_default.end();)
{
aname = iter->first;
attr = iter->second;
j = attributes.find(aname);
if ( j == attributes.end() )
{
attributes.insert(make_pair(aname,attr));
iter++;
}
else
{
delete iter->second;
conf_default.erase(iter++);
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * OpenNebulaTemplate::conf_name="oned.conf";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void OpenNebulaTemplate::set_conf_default()
{
ostringstream os;
SingleAttribute * attribute;
VectorAttribute * vattribute;
string value;
conf_file = etc_location + conf_name;
// MANAGER_TIMER
value = "15";
attribute = new SingleAttribute("MANAGER_TIMER",value);
conf_default.insert(make_pair(attribute->name(),attribute));
/*
#*******************************************************************************
# Daemon configuration attributes
@ -170,49 +212,3 @@ NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location)
conf_default.insert(make_pair(attribute->name(),attribute));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int NebulaTemplate::load_configuration()
{
char * error = 0;
map<string, Attribute *>::iterator iter, j;
int rc;
string aname;
Attribute * attr;
rc = parse(conf_file.c_str(), &error);
if ( rc != 0 && error != 0)
{
cout << "\nError while parsing configuration file:\n" << error << endl;
free(error);
return -1;
}
for(iter=conf_default.begin();iter!=conf_default.end();)
{
aname = iter->first;
attr = iter->second;
j = attributes.find(aname);
if ( j == attributes.end() )
{
attributes.insert(make_pair(aname,attr));
iter++;
}
else
{
delete iter->second;
conf_default.erase(iter++);
}
}
return 0;
}

View File

@ -0,0 +1,51 @@
#*******************************************************************************
# OpenNebula Configuration file
#*******************************************************************************
#*******************************************************************************
# Daemon configuration attributes
#-------------------------------------------------------------------------------
# ONED_PORT: Port to connect to the OpenNebula daemon (oned)
#
# SCHED_INTERVAL: Seconds between two scheduling actions
#
# MAX_VM: Maximum number of Virtual Machines scheduled in each scheduling
# action
#
# MAX_DISPATCH: Maximum number of Virtual Machines actually dispatched to a
# host in each scheduling action
#
# MAX_HOST: Maximum number of Virtual Machines dispatched to a given host in
# each scheduling action
#
# DEFAULT_SCHED: Definition of the default scheduling algorithm
# - policy:
# 0 = Packing. Heuristic that minimizes the number of hosts in use by
# packing the VMs in the hosts to reduce VM fragmentation
# 1 = Striping. Heuristic that tries to maximize resources available for
# the VMs by spreading the VMs in the hosts
# 2 = Load-aware. Heuristic that tries to maximize resources available for
# the VMs by usingthose nodes with less load
# 3 = Custom.
# - rank: Custom arithmetic exprission to rank suitable hosts based in their
# attributes
#*******************************************************************************
ONED_PORT = 2633
SCHED_INTERVAL = 30
MAX_VM = 300
MAX_DISPATCH = 30
MAX_HOST = 1
DEFAULT_SCHED = [
policy = 1
]
#DEFAULT_SCHED = [
# policy = 3,
# rank = "- (RUNNING_VMS * 50 + FREE_CPU)"
#]

View File

@ -29,12 +29,16 @@ public:
RankPolicy(
VirtualMachinePoolXML * vmpool,
HostPoolXML * hpool,
float w=1.0):SchedulerHostPolicy(vmpool,hpool,w){};
const string& dr,
float w = 1.0)
:SchedulerHostPolicy(vmpool,hpool,w), default_rank(dr){};
~RankPolicy(){};
private:
string default_rank;
void policy(
VirtualMachineXML * vm)
{
@ -53,10 +57,10 @@ private:
srank = vm->get_rank();
if (srank == "")
if (srank.empty())
{
NebulaLog::log("RANK",Log::WARNING,"No rank defined for VM");
}
srank = default_rank;
}
for (i=0;i<hids.size();i++)
{

View File

@ -30,7 +30,7 @@ using namespace std;
/* -------------------------------------------------------------------------- */
extern "C" void * scheduler_action_loop(void *arg);
class SchedulerTemplate;
/**
* The Scheduler class. It represents the scheduler ...
*/
@ -41,20 +41,19 @@ public:
void start();
virtual void register_policies() = 0;
virtual void register_policies(const SchedulerTemplate& conf) = 0;
protected:
Scheduler(string& _url, time_t _timer,
int _machines_limit, int _dispatch_limit, int _host_dispatch_limit):
Scheduler():
hpool(0),
vmpool(0),
acls(0),
timer(_timer),
url(_url),
machines_limit(_machines_limit),
dispatch_limit(_dispatch_limit),
host_dispatch_limit(_host_dispatch_limit),
timer(0),
url(""),
machines_limit(0),
dispatch_limit(0),
host_dispatch_limit(0),
threshold(0.9),
client(0)
{

View File

@ -0,0 +1,47 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, 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. */
/* -------------------------------------------------------------------------- */
#ifndef SCHEDULER_TEMPLATE_H_
#define SCHEDULER_TEMPLATE_H_
#include "NebulaTemplate.h"
class SchedulerTemplate : public NebulaTemplate
{
public:
SchedulerTemplate(const string& etc_location):
NebulaTemplate(etc_location, conf_name)
{};
~SchedulerTemplate(){};
string get_policy() const;
private:
/**
* Name for the configuration file, oned.conf
*/
static const char * conf_name;
/**
* Sets the defaults value for the template
*/
void set_conf_default();
};
#endif /*SCHEDULER_TEMPLATE_H_*/

View File

@ -21,7 +21,7 @@ import os
lib_name='scheduler_sched'
source_files=['Scheduler.cc']
source_files=['Scheduler.cc' , 'SchedulerTemplate.cc']
# Build library
sched_env.StaticLibrary(lib_name, source_files)
@ -35,6 +35,8 @@ sched_env.Prepend(LIBS=[
'nebula_acl',
'nebula_xml',
'nebula_common',
'nebula_core',
'nebula_template',
'crypto',
])

View File

@ -30,6 +30,7 @@
#include <cmath>
#include "Scheduler.h"
#include "SchedulerTemplate.h"
#include "RankPolicy.h"
#include "NebulaLog.h"
@ -64,33 +65,44 @@ extern "C" void * scheduler_action_loop(void *arg)
void Scheduler::start()
{
int rc;
ifstream file;
ifstream file;
ostringstream oss;
string etc_path;
int oned_port;
pthread_attr_t pattr;
// -----------------------------------------------------------
// Log system
// Log system & Configuration File
// -----------------------------------------------------------
try
{
ostringstream oss;
string log_file;
const char * nl = getenv("ONE_LOCATION");
if (nl == 0) //OpenNebula installed under root directory
{
oss << "/var/log/one/";
log_file = "/var/log/one/sched.log";
etc_path = "/etc/one/";
}
else
{
oss << nl << "/var/";
}
oss << nl << "/var/sched.log";
oss << "sched.log";
log_file = oss.str();
oss.str("");
oss << nl << "/etc/";
etc_path = oss.str();
}
NebulaLog::init_log_system(NebulaLog::FILE,
Log::DEBUG,
oss.str().c_str());
log_file.c_str());
NebulaLog::log("SCHED", Log::INFO, "Init Scheduler Log system");
}
@ -99,6 +111,42 @@ void Scheduler::start()
throw;
}
// -----------------------------------------------------------
// Configuration File
// -----------------------------------------------------------
SchedulerTemplate conf(etc_path);
if ( conf.load_configuration() != 0 )
{
throw runtime_error("Error reading configuration file.");
}
conf.get("ONED_PORT", oned_port);
oss.str("");
oss << "http://localhost:" << oned_port << "/RPC2";
url = oss.str();
conf.get("SCHED_INTERVAL", timer);
conf.get("MAX_VM", machines_limit);
conf.get("MAX_DISPATCH", dispatch_limit);
conf.get("MAX_HOST", host_dispatch_limit);
oss.str("");
oss << "Starting Scheduler Daemon" << endl;
oss << "----------------------------------------\n";
oss << " Scheduler Configuration File \n";
oss << "----------------------------------------\n";
oss << conf;
oss << "----------------------------------------";
NebulaLog::log("SCHED", Log::INFO, oss);
// -----------------------------------------------------------
// XML-RPC Client
// -----------------------------------------------------------
@ -128,7 +176,7 @@ void Scheduler::start()
// Load scheduler policies
// -----------------------------------------------------------
register_policies();
register_policies(conf);
// -----------------------------------------------------------
// Close stds, we no longer need them

View File

@ -0,0 +1,126 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, 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 "SchedulerTemplate.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const char * SchedulerTemplate::conf_name="sched.conf";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void SchedulerTemplate::set_conf_default()
{
SingleAttribute * attribute;
VectorAttribute * vattribute;
string value;
/*
#*******************************************************************************
# Daemon configuration attributes
#-------------------------------------------------------------------------------
# ONED_PORT
# SCHED_INTERVAL
# MAX_VM
# MAX_DISPATCH
# MAX_HOST
# DEFAULT_SCHED
#-------------------------------------------------------------------------------
*/
// ONED_PORT
value = "2633";
attribute = new SingleAttribute("ONED_PORT",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// SCHED_INTERVAL
value = "30";
attribute = new SingleAttribute("SCHED_INTERVAL",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// MAX_VM
value = "300";
attribute = new SingleAttribute("MAX_VM",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// MAX_DISPATCH
value = "30";
attribute = new SingleAttribute("MAX_DISPATCH",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//MAX_HOST
value = "1";
attribute = new SingleAttribute("MAX_HOST",value);
conf_default.insert(make_pair(attribute->name(),attribute));
//DEFAULT_SCHED
map<string,string> vvalue;
vvalue.insert(make_pair("POLICY","1"));
vattribute = new VectorAttribute("DEFAULT_SCHED",vvalue);
conf_default.insert(make_pair(attribute->name(),vattribute));
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string SchedulerTemplate::get_policy() const
{
int policy;
string rank;
istringstream iss;
vector<const Attribute *> vsched;
const VectorAttribute * sched;
get("DEFAULT_SCHED", vsched);
sched = static_cast<const VectorAttribute *> (vsched[0]);
iss.str(sched->vector_value("POLICY"));
iss >> policy;
switch (policy)
{
case 0: //Packing
rank = "RUNNING_VMS";
break;
case 1: //Striping
rank = "- RUNNING_VMS";
break;
case 2: //Load-aware
rank = "FREE_CPU";
break;
case 3: //Custom
rank = sched->vector_value("RANK");
break;
default:
rank = "";
}
return rank;
}

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "Scheduler.h"
#include "SchedulerTemplate.h"
#include "RankPolicy.h"
#include <unistd.h>
#include <sys/types.h>
@ -31,16 +32,7 @@ class RankScheduler : public Scheduler
{
public:
RankScheduler(string url,
time_t timer,
unsigned int machines_limit,
unsigned int dispatch_limit,
unsigned int host_dispatch_limit
):Scheduler(url,
timer,
machines_limit,
dispatch_limit,
host_dispatch_limit),rp(0){};
RankScheduler():Scheduler(),rp(0){};
~RankScheduler()
{
@ -50,9 +42,9 @@ public:
}
};
void register_policies()
void register_policies(const SchedulerTemplate& conf)
{
rp = new RankPolicy(vmpool,hpool,1.0);
rp = new RankPolicy(vmpool, hpool, conf.get_policy(), 1.0);
add_host_policy(rp);
};
@ -64,56 +56,11 @@ private:
int main(int argc, char **argv)
{
RankScheduler * ss;
int port = 2633;
time_t timer= 30;
unsigned int machines_limit = 300;
unsigned int dispatch_limit = 30;
unsigned int host_dispatch_limit = 1;
char opt;
ostringstream oss;
while((opt = getopt(argc,argv,"p:t:m:d:h:")) != -1)
{
switch(opt)
{
case 'p':
port = atoi(optarg);
break;
case 't':
timer = atoi(optarg);
break;
case 'm':
machines_limit = atoi(optarg);
break;
case 'd':
dispatch_limit = atoi(optarg);
break;
case 'h':
host_dispatch_limit = atoi(optarg);
break;
default:
cerr << "usage: " << argv[0] << " [-p port] [-t timer] ";
cerr << "[-m machines limit] [-d dispatch limit] [-h host_dispatch_limit]\n";
exit(-1);
break;
}
};
/* ---------------------------------------------------------------------- */
oss << "http://localhost:" << port << "/RPC2";
ss = new RankScheduler(oss.str(),
timer,
machines_limit,
dispatch_limit,
host_dispatch_limit);
RankScheduler ss;
try
{
ss->start();
ss.start();
}
catch (exception &e)
{
@ -122,7 +69,5 @@ int main(int argc, char **argv)
return -1;
}
delete ss;
return 0;
}

View File

@ -24,7 +24,8 @@ const string VirtualMachineTemplate::RESTRICTED_ATTRIBUTES[] = {
"CONTEXT/FILES",
"DISK/SOURCE",
"NIC/MAC",
"NIC/VLAN_ID"
"NIC/VLAN_ID",
"RANK"
};
const int VirtualMachineTemplate::RS_ATTRS_LENGTH = 3;