mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-11 04:58:16 +03:00
F #5289: New api for sched actions
SchedActions are now a complete managed type. It is in in /TEMPLATE and not /USER_TEMPLATE and includes dedicated API Calls to manage the entries: - one.vm.schedadd (add new sched_action) - one.vm.schedupdate (update an exiting sched_action) - one.vm.scheddelete (delete an action) The scheduler now use this API. This will prevent race conditions between update operations from different processes. co-authored-by: Pavel Czerný <pczerny@opennebula.systems>
This commit is contained in:
parent
bde16dcdcc
commit
3f171f3b5b
@ -70,20 +70,6 @@ public:
|
||||
va->merge(vattr, replace);
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates the attribute with a reference to a VectorAttribute. The object
|
||||
* is shared and WILL BE modified through this interface.
|
||||
* @param va pointer to the VectorAttribute.
|
||||
*/
|
||||
ExtendedAttribute(VectorAttribute *_va):
|
||||
Attribute(_va->name()) ,va(_va), id(-1) {};
|
||||
|
||||
ExtendedAttribute(VectorAttribute *_va, int _id):
|
||||
Attribute(_va->name()) ,va(_va), id(_id) {};
|
||||
|
||||
virtual ~ExtendedAttribute(){};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Attribute Interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -107,6 +93,23 @@ protected:
|
||||
return va->to_token(s);
|
||||
};
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates the attribute with a reference to a VectorAttribute. The object
|
||||
* is shared and WILL BE modified through this interface.
|
||||
* @param va pointer to the VectorAttribute.
|
||||
*/
|
||||
ExtendedAttribute(VectorAttribute *_va):
|
||||
Attribute(_va->name()) ,va(_va), id(-1) {};
|
||||
|
||||
ExtendedAttribute(VectorAttribute *_va, int _id):
|
||||
Attribute(_va->name()) ,va(_va), id(_id) {};
|
||||
|
||||
virtual ~ExtendedAttribute(){};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Attribute Interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
void unmarshall(const std::string& sattr, const char * _sep = 0)
|
||||
{
|
||||
va->unmarshall(sattr, _sep);
|
||||
|
82
include/RequestManagerSchedAction.h
Normal file
82
include/RequestManagerSchedAction.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 REQUEST_MANAGER_SCHED_H_
|
||||
#define REQUEST_MANAGER_SCHED_H_
|
||||
|
||||
#include "Request.h"
|
||||
#include "Nebula.h"
|
||||
#include "VirtualMachinePool.h"
|
||||
|
||||
|
||||
class RequestManagerSchedAdd : public Request
|
||||
{
|
||||
public:
|
||||
RequestManagerSchedAdd()
|
||||
: Request("one.vm.schedadd", "A:is", "Add scheduled action")
|
||||
{
|
||||
auth_object = PoolObjectSQL::VM;
|
||||
auth_op = AuthRequest::MANAGE;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmpool();
|
||||
}
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att) override;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class RequestManagerSchedDelete : public Request
|
||||
{
|
||||
public:
|
||||
RequestManagerSchedDelete()
|
||||
: Request("one.vm.scheddelete", "A:ii", "Delete scheduled action")
|
||||
{
|
||||
auth_object = PoolObjectSQL::VM;
|
||||
auth_op = AuthRequest::MANAGE;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmpool();
|
||||
}
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att) override;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class RequestManagerSchedUpdate : public Request
|
||||
{
|
||||
public:
|
||||
RequestManagerSchedUpdate()
|
||||
: Request("one.vm.schedupdate", "A:iis", "Update scheduled action")
|
||||
{
|
||||
auth_object = PoolObjectSQL::VM;
|
||||
auth_op = AuthRequest::MANAGE;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_vmpool();
|
||||
}
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att) override;
|
||||
};
|
||||
|
||||
#endif
|
@ -131,13 +131,11 @@ public:
|
||||
|
||||
tmpl->get("SCHED_ACTION", vas);
|
||||
|
||||
init_attribute_map("TIME", vas);
|
||||
init_attribute_map("ID", vas);
|
||||
};
|
||||
|
||||
virtual ~SchedActions(){};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Parse the ScheduleActions of a template
|
||||
* @param error
|
||||
@ -162,6 +160,39 @@ public:
|
||||
return a_set.empty();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Raw VectorAttribute helpers */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/**
|
||||
* Parse a set of scheduled actions and optionally assign them a valid id
|
||||
* @param vas the vector of SCHED_ACTION
|
||||
* @param err string in case of error
|
||||
* @param clean remove DONE and MESSAGE attributes
|
||||
* @param set_id to set ID for each action
|
||||
*
|
||||
* @return 0 on success -1 if error
|
||||
*/
|
||||
static int parse(std::vector<VectorAttribute *>& vas, std::string& err,
|
||||
bool clean, bool set_id);
|
||||
|
||||
/**
|
||||
* Adds a new SchedAction based on the provided VectorAttribute. The new
|
||||
* attribute is check and parsed
|
||||
* @param va VectorAttribute with the action
|
||||
* @param err with description
|
||||
*
|
||||
* @return pointer to new attribute nullptr on error
|
||||
*/
|
||||
static VectorAttribute * new_action(
|
||||
const std::vector<const VectorAttribute *>& vas,
|
||||
VectorAttribute * va, std::string &err);
|
||||
|
||||
static VectorAttribute * get_action(
|
||||
const std::vector<VectorAttribute *>& sched_actions, int id);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Iterators */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -989,18 +989,6 @@ public:
|
||||
*/
|
||||
void clear_template_error_message() override;
|
||||
|
||||
/**
|
||||
* Sets an error message with timestamp in the template (ERROR_MONITOR)
|
||||
* @param message Message string
|
||||
*/
|
||||
void set_template_monitor_error(const std::string& message);
|
||||
|
||||
/**
|
||||
* Deletes the error message from the template (ERROR_MONITOR)
|
||||
* @param message Message string
|
||||
*/
|
||||
void clear_template_monitor_error();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Timers & Requirements
|
||||
// ------------------------------------------------------------------------
|
||||
@ -1694,6 +1682,35 @@ public:
|
||||
*/
|
||||
int check_shareable_disks(const std::string& vmm_mad, std::string& error);
|
||||
|
||||
/**
|
||||
* Add scheduled actions
|
||||
* @param sched_template Teplate with scheduled actions
|
||||
* @param error Error string in case of failure
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int sched_action_add(const std::string& sched_template,
|
||||
std::string& error);
|
||||
|
||||
/**
|
||||
* Update one scheduled action
|
||||
* @param sched_id ID of the scheduled action to delete
|
||||
* @param error Error string in case of failure
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int sched_action_delete(int sched_id,
|
||||
std::string& error);
|
||||
|
||||
/**
|
||||
* Update one scheduled action
|
||||
* @param sched_id ID of the scheduled action to update
|
||||
* @param sched_template New value of scheduled action
|
||||
* @param error Error string in case of failure
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int sched_action_update(int sched_id,
|
||||
const std::string& sched_template,
|
||||
std::string& error);
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -2171,6 +2188,11 @@ private:
|
||||
*/
|
||||
int parse_sched_action(std::string& error_str);
|
||||
|
||||
/**
|
||||
* Assign id to sched actions without id
|
||||
*/
|
||||
void assign_sched_ids();
|
||||
|
||||
/**
|
||||
* Encrypt all secret attributes
|
||||
*/
|
||||
|
@ -439,21 +439,6 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
str_periodic << ', END_TYPE = 0'
|
||||
end
|
||||
|
||||
rc = vm.info
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
puts rc.message
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
ids = vm.retrieve_elements('USER_TEMPLATE/SCHED_ACTION/ID')
|
||||
|
||||
id = 0
|
||||
if !ids.nil? && !ids.empty?
|
||||
ids.map! {|e| e.to_i }
|
||||
id = ids.max + 1
|
||||
end
|
||||
|
||||
sched = options[:schedule]
|
||||
|
||||
# If the action is set to be executed from VM start to an specific
|
||||
@ -463,16 +448,14 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
sched = sched.to_i
|
||||
end
|
||||
|
||||
tmp_str = vm.user_template_str
|
||||
|
||||
tmp_str << "\nSCHED_ACTION = "
|
||||
tmp_str << "[ID = #{id}, ACTION = #{action}, "
|
||||
tmp_str = "SCHED_ACTION = ["
|
||||
tmp_str << "ACTION = #{action}, "
|
||||
tmp_str << "WARNING = #{warning}," if warning
|
||||
tmp_str << "ARGS = \"#{options[:args]}\"," if options[:args]
|
||||
tmp_str << "TIME = #{sched}"
|
||||
tmp_str << str_periodic << ']'
|
||||
|
||||
vm.update(tmp_str)
|
||||
vm.sched_action_add(tmp_str)
|
||||
end
|
||||
end
|
||||
|
||||
@ -490,7 +473,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
xpath = "USER_TEMPLATE/SCHED_ACTION[ID=#{action_id}]"
|
||||
xpath = "TEMPLATE/SCHED_ACTION[ID=#{action_id}]"
|
||||
|
||||
unless vm.retrieve_elements(xpath)
|
||||
STDERR.puts "Sched action #{action_id} not found"
|
||||
@ -508,12 +491,11 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
vm.delete_element(xpath)
|
||||
|
||||
# Add the modified sched action
|
||||
tmp_str = vm.user_template_str
|
||||
tmp_str << "\nSCHED_ACTION = ["
|
||||
tmp_str = "\nSCHED_ACTION = ["
|
||||
tmp_str << str.split("\n").join(',')
|
||||
tmp_str << ']'
|
||||
|
||||
rc = vm.update(tmp_str)
|
||||
rc = vm.sched_action_update(action_id, tmp_str)
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts "Error updating: #{rc.message}"
|
||||
@ -1227,7 +1209,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
format_history(vm)
|
||||
end
|
||||
|
||||
if vm.has_elements?('/VM/USER_TEMPLATE/SCHED_ACTION')
|
||||
if vm.has_elements?('/VM/TEMPLATE/SCHED_ACTION')
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % 'SCHEDULED ACTIONS', false)
|
||||
|
||||
@ -1318,12 +1300,12 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
show
|
||||
end
|
||||
end
|
||||
end.show([vm_hash['VM']['USER_TEMPLATE']['SCHED_ACTION']].flatten,
|
||||
end.show([vm_hash['VM']['TEMPLATE']['SCHED_ACTION']].flatten,
|
||||
{})
|
||||
end
|
||||
|
||||
if !options[:all]
|
||||
vm.delete_element('/VM/USER_TEMPLATE/SCHED_ACTION')
|
||||
vm.delete_element('/VM/TEMPLATE/SCHED_ACTION')
|
||||
end
|
||||
|
||||
if vm.has_elements?('/VM/USER_TEMPLATE')
|
||||
|
@ -1411,22 +1411,7 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command :'delete-chart', delete_chart_desc, :vmid, :sched_id do
|
||||
helper.perform_action(args[0], {}, 'Charter deleted') do |vm|
|
||||
rc = vm.info
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts "Error #{rc.message}"
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
xpath = "USER_TEMPLATE/SCHED_ACTION[ID=#{args[1]}]"
|
||||
|
||||
unless vm.retrieve_elements(xpath)
|
||||
STDERR.puts "Sched action #{args[1]} not found"
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
vm.delete_element(xpath)
|
||||
rc = vm.update(vm.user_template_str)
|
||||
rc = vm.sched_action_delete(args[1])
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
STDERR.puts "Error deleting: #{rc.message}"
|
||||
|
@ -583,7 +583,7 @@ module OpenNebula
|
||||
|
||||
@service.log_error(msg)
|
||||
else
|
||||
ids = vm.retrieve_elements('USER_TEMPLATE/SCHED_ACTION/ID')
|
||||
ids = vm.retrieve_elements('TEMPLATE/SCHED_ACTION/ID')
|
||||
|
||||
id = 0
|
||||
if !ids.nil? && !ids.empty?
|
||||
@ -591,20 +591,18 @@ module OpenNebula
|
||||
id = ids.max + 1
|
||||
end
|
||||
|
||||
tmp_str = vm.user_template_str
|
||||
|
||||
if do_offset
|
||||
offset = (index / vms_per_period.to_i).floor
|
||||
time_offset = offset * period.to_i
|
||||
end
|
||||
|
||||
tmp_str << "\nSCHED_ACTION = ["
|
||||
tmp_str = "SCHED_ACTION = ["
|
||||
tmp_str << "ID = #{id},"
|
||||
tmp_str << "ACTION = #{action},"
|
||||
tmp_str << "ARGS = \"#{args}\"," if args
|
||||
tmp_str << "TIME = #{now + time_offset}]"
|
||||
|
||||
rc = vm.update(tmp_str)
|
||||
rc = vm.sched_action_add(tmp_str)
|
||||
if OpenNebula.is_error?(rc)
|
||||
msg = "Role #{name} : VM #{vm_id} error scheduling "\
|
||||
"action; #{rc.message}"
|
||||
|
@ -50,8 +50,11 @@ module OpenNebula
|
||||
:disksnapshotrename => "vm.disksnapshotrename",
|
||||
:diskresize => "vm.diskresize",
|
||||
:updateconf => "vm.updateconf",
|
||||
:lock => "vm.lock",
|
||||
:unlock => "vm.unlock"
|
||||
:lock => "vm.lock",
|
||||
:unlock => "vm.unlock",
|
||||
:schedadd => "vm.schedadd",
|
||||
:scheddelete => "vm.scheddelete",
|
||||
:schedupdate => "vm.schedupdate"
|
||||
}
|
||||
|
||||
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
|
||||
@ -724,6 +727,35 @@ module OpenNebula
|
||||
return call(VM_METHODS[:updateconf], @pe_id, new_conf)
|
||||
end
|
||||
|
||||
# Add sched actions
|
||||
#
|
||||
# @param sched_template [String] Template with SCHED_ACTIONs
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def sched_action_add(sched_template)
|
||||
return call(VM_METHODS[:schedadd], @pe_id, sched_template)
|
||||
end
|
||||
|
||||
# Delete sched action
|
||||
#
|
||||
# @param sched_id [Int] id of the SCHED_ACTION
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def sched_action_delete(sched_id)
|
||||
return call(VM_METHODS[:scheddelete], @pe_id, sched_id.to_i)
|
||||
end
|
||||
|
||||
# Update sched_action
|
||||
#
|
||||
# @param sched_id [Int] id of the SCHED_ACTION
|
||||
# @param sched_template [String] Template containing a SCHED_ACTION
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def sched_action_update(sched_id, sched_template)
|
||||
return call(VM_METHODS[:schedupdate], @pe_id, sched_id.to_i,
|
||||
sched_template)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Helpers to get VirtualMachine information
|
||||
########################################################################
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "RequestManagerVNTemplate.h"
|
||||
#include "RequestManagerHook.h"
|
||||
#include "RequestManagerMarketPlace.h"
|
||||
#include "RequestManagerSchedAction.h"
|
||||
|
||||
#include "RequestManagerSystem.h"
|
||||
#include "RequestManagerProxy.h"
|
||||
@ -339,6 +340,9 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr vm_recover(new VirtualMachineRecover());
|
||||
xmlrpc_c::methodPtr vm_updateconf(new VirtualMachineUpdateConf());
|
||||
xmlrpc_c::methodPtr vm_disk_resize(new VirtualMachineDiskResize());
|
||||
xmlrpc_c::methodPtr vm_sched_add(new RequestManagerSchedAdd());
|
||||
xmlrpc_c::methodPtr vm_sched_delete(new RequestManagerSchedDelete());
|
||||
xmlrpc_c::methodPtr vm_sched_update(new RequestManagerSchedUpdate());
|
||||
|
||||
xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting());
|
||||
xmlrpc_c::methodPtr vm_pool_monitoring(new VirtualMachinePoolMonitoring());
|
||||
@ -570,6 +574,9 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.vm.lock", vm_lock);
|
||||
RequestManagerRegistry.addMethod("one.vm.unlock", vm_unlock);
|
||||
RequestManagerRegistry.addMethod("one.vm.diskresize", vm_disk_resize);
|
||||
RequestManagerRegistry.addMethod("one.vm.schedadd", vm_sched_add);
|
||||
RequestManagerRegistry.addMethod("one.vm.scheddelete", vm_sched_delete);
|
||||
RequestManagerRegistry.addMethod("one.vm.schedupdate", vm_sched_update);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
|
||||
RequestManagerRegistry.addMethod("one.vmpool.infoextended", vm_pool_info_extended);
|
||||
|
126
src/rm/RequestManagerSchedAction.cc
Normal file
126
src/rm/RequestManagerSchedAction.cc
Normal file
@ -0,0 +1,126 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 "RequestManagerSchedAction.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void RequestManagerSchedAdd::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int oid = paramList.getInt(1);
|
||||
string template_str = paramList.getString(2);
|
||||
|
||||
if ( basic_authorization(oid, att) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto vm = pool->get<VirtualMachine>(oid);
|
||||
|
||||
if ( !vm )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vm->sched_action_add(template_str, att.resp_msg) != 0 )
|
||||
{
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
}
|
||||
|
||||
pool->update(vm.get());
|
||||
|
||||
success_response(oid, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManagerSchedDelete::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int oid = paramList.getInt(1);
|
||||
int sched_id = paramList.getInt(2);
|
||||
|
||||
if ( basic_authorization(oid, att) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto vm = pool->get<VirtualMachine>(oid);
|
||||
|
||||
if ( !vm )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vm->sched_action_delete(sched_id, att.resp_msg) != 0 )
|
||||
{
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
}
|
||||
|
||||
pool->update(vm.get());
|
||||
|
||||
success_response(oid, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManagerSchedUpdate::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int oid = paramList.getInt(1);
|
||||
int sched_id = paramList.getInt(2);
|
||||
string template_str = paramList.getString(3);
|
||||
|
||||
if ( basic_authorization(oid, att) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto vm = pool->get<VirtualMachine>(oid);
|
||||
|
||||
if ( !vm )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vm->sched_action_update(sched_id, template_str, att.resp_msg) != 0 )
|
||||
{
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
}
|
||||
|
||||
pool->update(vm.get());
|
||||
|
||||
success_response(oid, att);
|
||||
|
||||
return;
|
||||
}
|
@ -53,7 +53,8 @@ source_files=[
|
||||
'RequestManagerVirtualRouter.cc',
|
||||
'RequestManagerSecurityGroup.cc',
|
||||
'RequestManagerVNTemplate.cc',
|
||||
'RequestManagerHook.cc'
|
||||
'RequestManagerHook.cc',
|
||||
'RequestManagerSchedAction.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
|
@ -82,6 +82,7 @@ public:
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
[[deprecated("This method may cause race condition issues")]]
|
||||
int update(VirtualMachineXML * vm) const
|
||||
{
|
||||
std::string xml;
|
||||
@ -175,7 +176,7 @@ protected:
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "/VM_POOL/VM/USER_TEMPLATE/SCHED_ACTION[(TIME < " << time(0)
|
||||
oss << "/VM_POOL/VM/TEMPLATE/SCHED_ACTION[(TIME < " << time(0)
|
||||
<< " and (not(DONE > 0) or boolean(REPEAT))) or ( TIME[starts-with(text(),\"+\")] and not(DONE>0) ) ]/../..";
|
||||
|
||||
return get_nodes(oss.str().c_str(), content);
|
||||
|
@ -406,9 +406,16 @@ public:
|
||||
*/
|
||||
SchedActions get_actions() const
|
||||
{
|
||||
return SchedActions(user_template.get());
|
||||
return SchedActions(vm_template.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update scheduled action of the VM
|
||||
*
|
||||
* @param action sched action to update
|
||||
*/
|
||||
bool update_sched_action(SchedAction* action);
|
||||
|
||||
/**
|
||||
* Sets an attribute in the VM Template, it must be allocated in the heap
|
||||
*
|
||||
|
@ -681,6 +681,39 @@ int VirtualMachineXML::parse_action_name(string& action_st)
|
||||
return 0;
|
||||
};
|
||||
|
||||
//******************************************************************************
|
||||
// Updates to oned
|
||||
//******************************************************************************
|
||||
|
||||
bool VirtualMachineXML::update_sched_action(SchedAction* action)
|
||||
{
|
||||
xmlrpc_c::value result;
|
||||
|
||||
try
|
||||
{
|
||||
string action_id_str = action->vector_value("ID");
|
||||
int action_id = std::stoi(action_id_str);
|
||||
|
||||
ostringstream oss;
|
||||
oss << "<TEMPLATE>";
|
||||
action->to_xml(oss);
|
||||
oss << "</TEMPLATE>";
|
||||
|
||||
Client::client()->call("one.vm.schedupdate", "iis", &result, oid,
|
||||
action_id,
|
||||
oss.str().c_str());
|
||||
}
|
||||
catch (exception const& e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<xmlrpc_c::value> values =
|
||||
xmlrpc_c::value_array(result).vectorValueValue();
|
||||
|
||||
return xmlrpc_c::value_boolean(values[0]);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -1741,12 +1741,15 @@ int Scheduler::do_scheduled_actions()
|
||||
oss << "Failure. " << error_msg;
|
||||
}
|
||||
|
||||
NebulaLog::log("VM", Log::INFO, oss);
|
||||
}
|
||||
if (!vm->update_sched_action(action))
|
||||
{
|
||||
ostringstream oss;
|
||||
action->to_xml(oss);
|
||||
NebulaLog::warn("SCHED", string("Unable to update sched action: ")
|
||||
+ oss.str());
|
||||
}
|
||||
|
||||
if ( !sas.empty() ) //Do not update VMs without SCHED_ACTION
|
||||
{
|
||||
vmpool->update(vm);
|
||||
NebulaLog::log("VM", Log::INFO, oss);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2604,17 +2604,6 @@ int VirtualMachine::replace_template(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Parse attributes in USER_TEMPLATE: */
|
||||
/* - SCHED_ACTION */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
SchedActions sactions(new_tmpl.get());
|
||||
|
||||
if ( sactions.parse(error, false) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Replace new_tmpl to the current user_template */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -2674,17 +2663,6 @@ int VirtualMachine::append_template(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Parse attributes in USER_TEMPLATE: */
|
||||
/* - SCHED_ACTION */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
SchedActions sactions(new_tmpl.get());
|
||||
|
||||
if ( sactions.parse(error, false) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Append new_tmpl to the current user_template */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -3556,9 +3534,18 @@ void VirtualMachine::release_vmgroup()
|
||||
|
||||
int VirtualMachine::parse_sched_action(string& error_str)
|
||||
{
|
||||
SchedActions sactions(user_obj_template.get());
|
||||
vector<VectorAttribute*> vas;
|
||||
|
||||
return sactions.parse(error_str, false);
|
||||
if (user_obj_template->remove("SCHED_ACTION", vas) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rc = SchedActions::parse(vas, error_str, true, true);
|
||||
|
||||
obj_template->set(vas);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -3624,6 +3611,118 @@ int VirtualMachine::check_shareable_disks(const string& vmm_mad, string& error)
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int VirtualMachine::sched_action_add(const string& sched_template,
|
||||
std::string& error)
|
||||
{
|
||||
// Read and verify SCHED_ACTION in incoming string
|
||||
VirtualMachineTemplate new_tmpl(false, '=', "TEMPLATE");
|
||||
|
||||
if (new_tmpl.parse_str_or_xml(sched_template, error) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vector<VectorAttribute*> sa;
|
||||
|
||||
if (new_tmpl.remove("SCHED_ACTION", sa) == 0 || sa.empty())
|
||||
{
|
||||
error = "Cannot read SCHED_ACTION from the template: " + sched_template;
|
||||
return -1;
|
||||
}
|
||||
|
||||
vector<const VectorAttribute*> vm_sa;
|
||||
|
||||
obj_template->get("SCHED_ACTION", vm_sa);
|
||||
|
||||
VectorAttribute * new_sa = SchedActions::new_action(vm_sa, sa[0], error);
|
||||
|
||||
if (!new_sa)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
obj_template->set(new_sa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int VirtualMachine::sched_action_delete(int sched_id, std::string& error)
|
||||
{
|
||||
vector<VectorAttribute*> sched_actions;
|
||||
|
||||
obj_template->get("SCHED_ACTION", sched_actions);
|
||||
|
||||
VectorAttribute* sa = SchedActions::get_action(sched_actions, sched_id);
|
||||
|
||||
if (!sa)
|
||||
{
|
||||
error = "Sched action with id = " + to_string(sched_id) +
|
||||
"doesn't exist";
|
||||
return -1;
|
||||
}
|
||||
|
||||
obj_template->remove(sa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int VirtualMachine::sched_action_update(int sched_id,
|
||||
const string& sched_template,
|
||||
std::string& error)
|
||||
{
|
||||
// Get SchedAction with ID = sched_id
|
||||
vector<VectorAttribute*> sched_actions;
|
||||
|
||||
obj_template->get("SCHED_ACTION", sched_actions);
|
||||
|
||||
VectorAttribute* sa = SchedActions::get_action(sched_actions, sched_id);
|
||||
|
||||
if (!sa)
|
||||
{
|
||||
error = "Sched action with id = " + to_string(sched_id) +
|
||||
"doesn't exist";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read and verify SCHED_ACTION in incoming string
|
||||
VirtualMachineTemplate new_tmpl(false, '=', "TEMPLATE");
|
||||
|
||||
if (new_tmpl.parse_str_or_xml(sched_template, error) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vector<VectorAttribute*> new_sa_v;
|
||||
|
||||
if (new_tmpl.remove("SCHED_ACTION", new_sa_v) == 0 || new_sa_v.empty())
|
||||
{
|
||||
error = "Cannot read SCHED_ACTION from the template: " + sched_template;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SchedAction new_sa(new_sa_v[0], sched_id);
|
||||
|
||||
if ( new_sa.parse(error, false) == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_sa_v[0]->replace("ID", sched_id);
|
||||
|
||||
sa->replace(new_sa_v[0]->value());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void VirtualMachine::encrypt()
|
||||
{
|
||||
std::string one_key;
|
||||
|
@ -455,3 +455,99 @@ time_t SchedAction::next_action()
|
||||
|
||||
return action_time;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int SchedActions::parse(std::vector<VectorAttribute *>& vas,
|
||||
std::string& error, bool clean, bool set_id)
|
||||
{
|
||||
unsigned int sched_id = 0;
|
||||
|
||||
std::string err;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
for (auto it = vas.begin(); it != vas.end(); )
|
||||
{
|
||||
if ( (*it)->type() != Attribute::VECTOR )
|
||||
{
|
||||
delete *it;
|
||||
it = vas.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (set_id)
|
||||
{
|
||||
(*it)->replace("ID", sched_id++);
|
||||
}
|
||||
|
||||
SchedAction sa(*it, sched_id);
|
||||
|
||||
if ( sa.parse(err, clean) == -1 )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << " SCHED_ACTION: " << sched_id << ". Parse error: "<< err;
|
||||
error += oss.str();
|
||||
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VectorAttribute * SchedActions::new_action(
|
||||
const std::vector<const VectorAttribute *>& vas,
|
||||
VectorAttribute * va, std::string &err)
|
||||
{
|
||||
int max_id = -1;
|
||||
|
||||
for(auto const *_va : vas)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
if (_va->vector_value("ID", id) == 0)
|
||||
{
|
||||
max_id = std::max(max_id, id);
|
||||
}
|
||||
}
|
||||
|
||||
SchedAction sched_action(va, max_id + 1);
|
||||
|
||||
if (sched_action.parse(err, true) == -1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VectorAttribute * new_sa = new VectorAttribute(va);
|
||||
|
||||
new_sa->replace("ID", max_id + 1);
|
||||
|
||||
return new_sa;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VectorAttribute * SchedActions::get_action(
|
||||
const std::vector<VectorAttribute *>& sched_actions, int id)
|
||||
{
|
||||
for (auto *va : sched_actions)
|
||||
{
|
||||
int _id;
|
||||
|
||||
if (va->vector_value("ID", _id) == 0 && _id == id)
|
||||
{
|
||||
return va;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -188,9 +188,18 @@ int VMTemplate::bootstrap(SqlDB * db)
|
||||
|
||||
int VMTemplate::parse_sched_action(string& error_str)
|
||||
{
|
||||
SchedActions sactions(obj_template.get());
|
||||
vector<VectorAttribute*> vas;
|
||||
|
||||
return sactions.parse(error_str, true);
|
||||
if (obj_template->remove("SCHED_ACTION", vas) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rc = SchedActions::parse(vas, error_str, true, false);
|
||||
|
||||
obj_template->set(vas);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user