From ce388212f50f71deb7759fc84477321502cd49b6 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 1 Apr 2020 10:43:21 +0200 Subject: [PATCH] F #2340: Add support for sched disk snapshots co-authored-by: Alejandro Huertas Herrero --- src/cli/one_helper/onevm_helper.rb | 5 + src/cli/onevm | 98 ++++++-- src/scheduler/include/VirtualMachinePoolXML.h | 6 +- .../src/pool/VirtualMachinePoolXML.cc | 215 +++++++++++++++++- src/scheduler/src/pool/VirtualMachineXML.cc | 5 + src/scheduler/src/sched/Scheduler.cc | 5 +- 6 files changed, 314 insertions(+), 20 deletions(-) diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index cd06d5284f..c513bc0efa 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -457,6 +457,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper tmp_str << "\nSCHED_ACTION = " tmp_str << "[ID = #{id}, ACTION = #{action}, " + tmp_str << "ARGS = \"#{options[:args]}\"," if options[:args] tmp_str << "TIME = #{options[:schedule].to_i}" tmp_str << str_periodic << ']' @@ -1151,6 +1152,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper d['ACTION'] unless d.nil? end + column :ARGS, '', :left, :size => 15 do |d| + d['ARGS'] ? d['ARGS'] : '-' + end + column :SCHEDULED, '', :size => 12 do |d| OpenNebulaHelper.time_to_str(d['TIME'], false) \ unless d.nil? diff --git a/src/cli/onevm b/src/cli/onevm index b3bbc3c15a..17f59dcb3c 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -927,6 +927,9 @@ CommandParser::CmdParser.new(ARGV) do OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if !options[:schedule].nil? + # add name as an argument + options[:args] = args[1] + helper.schedule_actions(args[0], options, @comm_name) else helper.perform_actions(args[0], options, 'snapshot created') do |o| @@ -940,9 +943,22 @@ CommandParser::CmdParser.new(ARGV) do Reverts a VM to a saved snapshot EOT - command :"snapshot-revert", snapshot_revert_desc, :vmid, :snapshot_id do - helper.perform_action(args[0], options, 'snapshot reverted') do |o| - o.snapshot_revert(args[1].to_i) + command :"snapshot-revert", snapshot_revert_desc, :vmid, :snapshot_id, + :options => [OneVMHelper::SCHEDULE, + OneVMHelper::WEEKLY, + OneVMHelper::MONTHLY, + OneVMHelper::YEARLY, + OneVMHelper::HOURLY, + OneVMHelper::END_TIME] do + if !options[:schedule].nil? + # add snap ID as an argument + options[:args] = args[1] + + helper.schedule_actions([args[0]], options, @comm_name) + else + helper.perform_action(args[0], options, 'snapshot reverted') do |o| + o.snapshot_revert(args[1].to_i) + end end end @@ -951,9 +967,22 @@ CommandParser::CmdParser.new(ARGV) do Delets a snapshot of a VM EOT - command :"snapshot-delete", snapshot_delete_desc, :vmid, :snapshot_id do - helper.perform_action(args[0], options, 'snapshot deleted') do |o| - o.snapshot_delete(args[1]) + command :"snapshot-delete", snapshot_delete_desc, :vmid, :snapshot_id, + :options => [OneVMHelper::SCHEDULE, + OneVMHelper::WEEKLY, + OneVMHelper::MONTHLY, + OneVMHelper::YEARLY, + OneVMHelper::HOURLY, + OneVMHelper::END_TIME] do + if !options[:schedule].nil? + # add snap ID as an argument + options[:args] = args[1] + + helper.schedule_actions([args[0]], options, @comm_name) + else + helper.perform_action(args[0], options, 'snapshot deleted') do |o| + o.snapshot_delete(args[1]) + end end end @@ -965,9 +994,22 @@ CommandParser::CmdParser.new(ARGV) do EOT command :"disk-snapshot-create", disk_snapshot_create_desc, - :vmid, :diskid, :name do - helper.perform_action(args[0], options, 'disk snapshot created') do |o| - o.disk_snapshot_create(args[1].to_i, args[2]) + :vmid, :diskid, :name, + :options => [OneVMHelper::SCHEDULE, + OneVMHelper::WEEKLY, + OneVMHelper::MONTHLY, + OneVMHelper::YEARLY, + OneVMHelper::HOURLY, + OneVMHelper::END_TIME] do + if !options[:schedule].nil? + # add disk ID and name as arguments + options[:args] = "#{args[1]},#{args[2]}" + + helper.schedule_actions([args[0]], options, @comm_name) + else + helper.perform_action(args[0], options, 'disk snapshot created') do |o| + o.disk_snapshot_create(args[1].to_i, args[2]) + end end end @@ -978,9 +1020,22 @@ CommandParser::CmdParser.new(ARGV) do EOT command :"disk-snapshot-revert", disk_snapshot_revert_desc, - :vmid, :diskid, :disk_snapshot_id do - helper.perform_action(args[0], options, 'disk snapshot reverted') do |o| - o.disk_snapshot_revert(args[1].to_i, args[2].to_i) + :vmid, :diskid, :disk_snapshot_id, + :options => [OneVMHelper::SCHEDULE, + OneVMHelper::WEEKLY, + OneVMHelper::MONTHLY, + OneVMHelper::YEARLY, + OneVMHelper::HOURLY, + OneVMHelper::END_TIME] do + if !options[:schedule].nil? + # add disk ID and snap ID as arguments + options[:args] = "#{args[1]},#{args[2]}" + + helper.schedule_actions([args[0]], options, @comm_name) + else + helper.perform_action(args[0], options, 'disk snapshot reverted') do |o| + o.disk_snapshot_revert(args[1].to_i, args[2].to_i) + end end end @@ -991,9 +1046,22 @@ CommandParser::CmdParser.new(ARGV) do EOT command :"disk-snapshot-delete", disk_snapshot_delete_desc, - :vmid, :diskid, :disk_snapshot_id do - helper.perform_action(args[0], options, 'disk snapshot deleted') do |o| - o.disk_snapshot_delete(args[1].to_i, args[2].to_i) + :vmid, :diskid, :disk_snapshot_id, + :options => [OneVMHelper::SCHEDULE, + OneVMHelper::WEEKLY, + OneVMHelper::MONTHLY, + OneVMHelper::YEARLY, + OneVMHelper::HOURLY, + OneVMHelper::END_TIME] do + if !options[:schedule].nil? + # add disk ID and snap ID as arguments + options[:args] = "#{args[1]},#{args[2]}" + + helper.schedule_actions([args[0]], options, @comm_name) + else + helper.perform_action(args[0], options, 'disk snapshot deleted') do |o| + o.disk_snapshot_delete(args[1].to_i, args[2].to_i) + end end end diff --git a/src/scheduler/include/VirtualMachinePoolXML.h b/src/scheduler/include/VirtualMachinePoolXML.h index 35411a207f..3d54e44b6a 100644 --- a/src/scheduler/include/VirtualMachinePoolXML.h +++ b/src/scheduler/include/VirtualMachinePoolXML.h @@ -153,11 +153,15 @@ public: * * @param vid The VM id * @param action Action argument (terminate, hold, release...) + * @param args Action arguments * @param error_msg Error reason, if any * * @return 0 on success, -1 otherwise */ - int action(int vid, const string &action, string &error_msg) const; + int action(int vid, + const string &action, + const string &args, + string &error_msg) const; protected: diff --git a/src/scheduler/src/pool/VirtualMachinePoolXML.cc b/src/scheduler/src/pool/VirtualMachinePoolXML.cc index 37c3183385..68a73f23b1 100644 --- a/src/scheduler/src/pool/VirtualMachinePoolXML.cc +++ b/src/scheduler/src/pool/VirtualMachinePoolXML.cc @@ -17,6 +17,99 @@ #include "VirtualMachinePoolXML.h" #include #include +#include + +/* -------------------------------------------------------------------------- */ +/** + * Parses value from string to given type + * + * @param val_s string value + * @param val parsed value + * + * @return 0 on success, -1 otherwise + */ +/* -------------------------------------------------------------------------- */ +template +static int from_str(const string& val_s, T& val) +{ + if (val_s.empty()) + { + return -1; + } + + istringstream iss(val_s); + + iss >> val; + + if (iss.fail() || !iss.eof()) + { + return -1; + } + + return 0; +} + +template<> +int from_str(const string& val_s, string& val) +{ + if (val_s.empty()) + { + return -1; + } + + val = val_s; + return 0; +} + +/* -------------------------------------------------------------------------- */ +/** + * Parses tokens to scpecific value with given type + * + * @param tokens values to parse + * @param value given type to parse it + * + * @return 0 on success, -1 otherwise + */ +/* -------------------------------------------------------------------------- */ +template +static int parse_args(queue& tokens, T& value) +{ + if (tokens.empty()) + { + return -1; + } + + int rc = from_str(tokens.front(), value); + + tokens.pop(); + + return rc; +} + +/* -------------------------------------------------------------------------- */ + +template +static int parse_args(queue& tokens, T& value, Args&... args) +{ + if (tokens.empty()) + { + return -1; + } + + int rc = from_str(tokens.front(), value); + + tokens.pop(); + + if ( rc != 0 ) + { + return -1; + } + + return parse_args(tokens, args...); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int VirtualMachinePoolXML::set_up() { @@ -38,7 +131,7 @@ int VirtualMachinePoolXML::set_up() for ( it = objects.begin(); it != objects.end(); ++it ) { vm_resources.add_resource(it->first); - } + } if (NebulaLog::log_level() >= Log::DDDEBUG) { @@ -282,16 +375,133 @@ int VirtualMachineActionsPoolXML::set_up() int VirtualMachineActionsPoolXML::action( int vid, const string& action, + const string& args, string& error_msg) const { xmlrpc_c::value result; bool success; + queue sargs; + string tmp_arg; + + stringstream ss(args); + + while (getline(ss, tmp_arg, ',')) + { + sargs.push(tmp_arg); + } + try { if (action == "snapshot-create") { - client->call("one.vm.snapshotcreate", "is", &result, vid, ""); + string name = ""; + + int rc = parse_args(sargs, name); + + if (rc != 0) + { + error_msg = "Missing or malformed ARGS for: snapshot-create." + " Format: snapshot-name"; + return -1; + } + + client->call("one.vm.snapshotcreate", + "is", + &result, + vid, + name.c_str()); + } + else if (action == "snapshot-revert") + { + int snapid = 0; + + int rc = parse_args(sargs, snapid); + + if (rc != 0) + { + error_msg = "Missing or malformed ARGS for: snapshot-revert." + " Format: snapshot-id"; + return -1; + } + + client->call("one.vm.snapshotrevert", "ii", &result, vid, snapid); + } + else if (action == "snapshot-delete") + { + int snapid = 0; + + int rc = parse_args(sargs, snapid); + + if (rc != 0) + { + error_msg = "Missing or malformed ARGS for: snapshot-delete." + " Format: snapshot-id"; + return -1; + } + + client->call("one.vm.snapshotdelete", "ii", &result, vid, snapid); + } + else if (action == "disk-snapshot-create") + { + int diskid = 0; + string name = ""; + + int rc = parse_args(sargs, diskid, name); + + if (rc != 0) + { + error_msg = "Missing or malformed ARGS for: disk-snapshot-create." + " Format: disk-id, snapshot-name"; + return -1; + } + + client->call("one.vm.disksnapshotcreate", + "iis", + &result, + vid, + diskid, + name.c_str()); + } + else if (action == "disk-snapshot-revert") + { + int diskid = 0, snapid = 0; + + int rc = parse_args(sargs, diskid, snapid); + + if (rc != 0) + { + error_msg = "Missing or malformed ARGS for: disk-snapshot-revert." + " Format: disk-id, snapshot-id"; + return -1; + } + + client->call("one.vm.disksnapshotrevert", + "iii", + &result, + vid, + diskid, + snapid); + } + else if (action == "disk-snapshot-delete") + { + int diskid = 0, snapid = 0; + + int rc = parse_args(sargs, diskid, snapid); + + if (rc != 0) + { + error_msg = "Missing or malformed ARGS for: disk-snapshot-delete." + " Format: disk-id, snapshot-id"; + return -1; + } + + client->call("one.vm.disksnapshotdelete", + "iii", + &result, + vid, + diskid, + snapid); } else { @@ -318,6 +528,7 @@ int VirtualMachineActionsPoolXML::action( return 0; } + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 34b947d363..edea972338 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -657,6 +657,11 @@ int VirtualMachineXML::parse_action_name(string& action_st) && action_st != "poweroff" && action_st != "poweroff-hard" && action_st != "snapshot-create" + && action_st != "snapshot-revert" + && action_st != "snapshot-delete" + && action_st != "disk-snapshot-create" + && action_st != "disk-snapshot-revert" + && action_st != "disk-snapshot-delete" // Compatibility with 4.x && action_st != "shutdown" diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 3c182cf36c..dcf1634931 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -1714,7 +1714,7 @@ int Scheduler::do_scheduled_actions() const map vms = vmapool->get_objects(); map::const_iterator vm_it; - string action_st, error_msg; + string action_st, args_st, error_msg; string time_str = one_util::log_time(time(0)); @@ -1736,6 +1736,7 @@ int Scheduler::do_scheduled_actions() } action_st = (*action)->vector_value("ACTION"); + args_st = (*action)->vector_value("ARGS"); int rc = VirtualMachineXML::parse_action_name(action_st); @@ -1748,7 +1749,7 @@ int Scheduler::do_scheduled_actions() } else { - rc = vmapool->action(vm->get_oid(), action_st, error_msg); + rc = vmapool->action(vm->get_oid(), action_st, args_st, error_msg); if (rc == 0) {