diff --git a/include/HostPool.h b/include/HostPool.h index 4fbd9cf9c1..4c20eadf9c 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -36,8 +36,9 @@ using namespace std; class HostPool : public PoolSQL { public: - - HostPool(SqlDB * db); + HostPool(SqlDB * db, + vector hook_mads, + const string& hook_location); ~HostPool(){}; diff --git a/share/etc/oned.conf b/share/etc/oned.conf index a0acdd2e30..2ea6725036 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -294,6 +294,22 @@ TM_MAD = [ # - YES, The hook is executed in the host where the VM was # allocated # - NO, The hook is executed in the OpenNebula server (default) +# +# +# Host Hooks (HOST_HOOK) defined by: +# name : for the hook, useful to track the hook (OPTIONAL) +# on : when the hook should be executed, +# - CREATE, when the Host is created (onehost create) +# - ERROR, when the Host enters the error state +# - DISABLE, when the Host is disable +# command : path can be absolute or relative to $ONE_LOCATION/share/hooks +# case of self-contained installation or relative to +# /usr/share/one/hooks in case of system-wide installation +# arguments : for the hook. You can use the Host ID with $HID to pass it as +# argument for the hook +# remote : values, +# - YES, The hook is executed in the host +# - NO, The hook is executed in the OpenNebula server (default) #------------------------------------------------------------------------------- HM_MAD = [ @@ -311,6 +327,19 @@ VM_HOOK = [ #------------------------------------------------------------------------------- +#-------------------------------- Host Hook ----------------------------------- +# This hook is used to perform recovery actions when a host fails. The VMs +# running in the host can be deleted (use -d option) or resubmitted (-r) in +# other host + +HOST_HOOK = [ + name = "error", + on = "ERROR", + command = "error.rb", + arguments = "-r $HID", + remote = no ] +#------------------------------------------------------------------------------- + #-------------------------------- Hook Examples -------------------------------- #VM_HOOK = [ # name = "dhcp", @@ -325,11 +354,11 @@ VM_HOOK = [ # arguments = '$NIC[MAC, Network = "Private"]', # remote = "yes" ] #------------------------------------------------------------------------------- -#VM_HOOK = [ -# name = "mail", -# on = "running", -# command = "/usr/local/one/bin/send_mail", -# arguments = "$VMID $NAME", +#HOST_HOOK = [ +# name = "bootstrap", +# on = "create", +# command = "set_up_host", +# arguments = "$HID", # remote = "no" ] #------------------------------------------------------------------------------ diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 96771cf2e1..1a889c3d74 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -15,12 +15,13 @@ /* -------------------------------------------------------------------------- */ /* ************************************************************************** */ -/* Host Pool */ +/* Host Pool */ /* ************************************************************************** */ #include #include "HostPool.h" +#include "HostHook.h" #include "ClusterPool.h" #include "NebulaLog.h" @@ -41,8 +42,13 @@ int HostPool::init_cb(void *nil, int num, char **values, char **names) /* -------------------------------------------------------------------------- */ -HostPool::HostPool(SqlDB* db):PoolSQL(db,Host::table) +HostPool::HostPool(SqlDB* db, + vector hook_mads, + const string& hook_location) + : PoolSQL(db,Host::table) { + // ------------------ Initialize Cluster Array ---------------------- + ostringstream sql; set_callback(static_cast(&HostPool::init_cb)); @@ -63,6 +69,103 @@ HostPool::HostPool(SqlDB* db):PoolSQL(db,Host::table) throw runtime_error("Could not create default cluster HostPool"); } } + + // ------------------ Initialize Hooks fot the pool ---------------------- + + const VectorAttribute * vattr; + + string name; + string on; + string cmd; + string arg; + string rmt; + bool remote; + + bool state_hook = false; + + for (unsigned int i = 0 ; i < hook_mads.size() ; i++ ) + { + vattr = static_cast(hook_mads[i]); + + name = vattr->vector_value("NAME"); + on = vattr->vector_value("ON"); + cmd = vattr->vector_value("COMMAND"); + arg = vattr->vector_value("ARGUMENTS"); + rmt = vattr->vector_value("REMOTE"); + + transform (on.begin(),on.end(),on.begin(),(int(*)(int))toupper); + + if ( on.empty() || cmd.empty() ) + { + ostringstream oss; + + oss << "Empty ON or COMMAND attribute in HOST_HOOK. Hook " + << "not registered!"; + NebulaLog::log("VM",Log::WARNING,oss); + + continue; + } + + if ( name.empty() ) + { + name = cmd; + } + + remote = false; + + if ( !rmt.empty() ) + { + transform(rmt.begin(),rmt.end(),rmt.begin(),(int(*)(int))toupper); + + if ( rmt == "YES" ) + { + remote = true; + } + } + + if (cmd[0] != '/') + { + cmd = hook_location + cmd; + } + + if ( on == "CREATE" ) + { + HostAllocateHook * hook; + + hook = new HostAllocateHook(name,cmd,arg,remote); + + add_hook(hook); + } + else if ( on == "DISABLE" ) + { + HostStateHook * hook; + + hook = new HostStateHook(name, cmd, arg, remote, Host::DISABLED); + + add_hook(hook); + + state_hook = true; + } + else if ( on == "ERROR" ) + { + HostStateHook * hook; + + hook = new HostStateHook(name, cmd, arg, remote, Host::ERROR); + + add_hook(hook); + + state_hook = true; + } + } + + if ( state_hook ) + { + HostUpdateStateHook * hook; + + hook = new HostUpdateStateHook(); + + add_hook(hook); + } } /* -------------------------------------------------------------------------- */ diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 6871a80ec0..548d6fcfd1 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -249,11 +249,13 @@ void Nebula::start() string default_device_prefix; vector vm_hooks; + vector host_hooks; nebula_configuration->get("VM_HOOK", vm_hooks); + nebula_configuration->get("HOST_HOOK", host_hooks); - vmpool = new VirtualMachinePool(db, vm_hooks,hook_location); - hpool = new HostPool(db); + vmpool = new VirtualMachinePool(db, vm_hooks, hook_location); + hpool = new HostPool(db, host_hooks, hook_location); nebula_configuration->get("MAC_PREFIX", mac_prefix); nebula_configuration->get("NETWORK_SIZE", size);