From e77b1adbe83e15c100c8ce9281e8d8a80ee00806 Mon Sep 17 00:00:00 2001 From: juanmont Date: Fri, 16 Feb 2018 14:30:39 +0100 Subject: [PATCH 01/28] F #1548: Added code to opennebula --- include/VMTemplate.h | 2 +- src/scheduler/include/VirtualMachineXML.h | 48 ++++++++++ src/scheduler/src/pool/VirtualMachineXML.cc | 100 ++++++++++++++++++++ src/scheduler/src/sched/Scheduler.cc | 4 +- src/vm_template/VMTemplate.cc | 74 ++++++++++++++- 5 files changed, 222 insertions(+), 6 deletions(-) diff --git a/include/VMTemplate.h b/include/VMTemplate.h index b6a1452f30..866265c954 100644 --- a/include/VMTemplate.h +++ b/include/VMTemplate.h @@ -170,7 +170,7 @@ private: /** * This method removes sched_action DONE/MESSAGE attributes */ - void parse_sched_action(); + int parse_sched_action(); protected: diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index aeea53bbb0..edf0173068 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -332,6 +332,13 @@ public: user_template->remove("SCHED_ACTION", attributes); } + /** + * Generate new action + * + * @param attributes to hold the VM actions + */ + int next_action(VectorAttribute& vatt); + /** * Sets an attribute in the VM Template, it must be allocated in the heap * @@ -369,6 +376,47 @@ public: */ bool clear_log(); +private: + + void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor_day, int max_day, int comparative){ + if (mayor_day >= 0 && minor_day < max_day) + { + if( mayor_day < comparative ) //next + { + next->tm_mday = next->tm_mday + ((max_day-1) - comparative + minor_day); + } + else // same + { + next->tm_mday = next->tm_mday + (mayor_day - comparative); + } + } + } + + void generate_next_day(int rep, int mayor_day, int minor_day, struct tm * next, struct tm * now) + { + if ( rep == 0 ) //Repeat every weeks + { + sum_days(next, now, mayor_day, minor_day, 7, next->tm_wday); + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + } + + if ( rep == 1 ) //Repeat every months + { + cout << next->tm_mday << endl; + sum_days(next, now, mayor_day, minor_day, 32, next->tm_mday); + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + } + + if ( rep == 2 ) //Repeat every months + { + sum_days(next, now, mayor_day, minor_day, 366, next->tm_yday); + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + } + } + protected: /** diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 8681ede717..2b6da8e81b 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -499,3 +499,103 @@ bool VirtualMachineXML::is_only_public_cloud() const { return only_public_cloud; } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachineXML::next_action(VectorAttribute& vatt) +{ + string days; + int rep_mode, end_mode; + int end_value; + int mayor_day = -1; + int minor_day = 366; + int start_day; + time_t action_time; + time_t done_time; + vector v_days; + set s_days; + + vatt.vector_value("DAYS", days); + vatt.vector_value("REP", rep_mode); + vatt.vector_value("END_TYPE", end_mode); + vatt.vector_value("END_VALUE", end_value); + vatt.vector_value("TIME", action_time); + vatt.vector_value("DONE", done_time); + + v_days = one_util::split(days, ',', true); + for(vector::iterator it = v_days.begin(); it != v_days.end(); ++it) { + s_days.insert(atoi((*it).c_str())); + } + + time_t t_next = time(0); + struct tm next; + struct tm start_tm; + localtime_r(&t_next, &next); + localtime_r(&action_time, &start_tm); + + start_day = start_tm.tm_wday; + if (rep_mode == 1) + { + start_day = start_tm.tm_mday; + } + else if (rep_mode == 2) + { + start_day = start_tm.tm_yday; + } + std::set::iterator it; + std::pair::iterator,bool> ret; + + it = s_days.begin(); + minor_day = *it; + + ret = s_days.insert(start_day); + if ( ret.second == false ) + { + mayor_day = *(ret.first); + + if ( ret.first++ != s_days.end() ) + { + mayor_day = *ret.first; + } + } + else + { + mayor_day = *((ret.first)++); + it = s_days.find(start_day); + s_days.erase (it); + } + + if ( end_mode == 1 ) + { + int num_rep = end_value; + if (num_rep <= 0) + { + cout << "Finished scheduling actions" << endl; + return -1; + } + end_value = num_rep-1; + vatt.replace("END_VALUE", end_value); + } + else if ( end_mode == 2 ) + { + time_t t_end = end_value; + if ( time(0) > t_end ) + { + cout << "Finished scheduling actions" << endl; + return -1; + } + } + + generate_next_day(rep_mode, mayor_day, minor_day, &next, &start_tm); + action_time = mktime (&next); + if (action_time != -1) + { + vatt.replace("TIME", action_time); + } + else + { + return -1; + } + return 0; +} \ No newline at end of file diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 44d7afa3aa..5c915140a2 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -1417,7 +1417,7 @@ int Scheduler::do_scheduled_actions() has_done = vatt->vector_value("DONE", done_time); action_st = vatt->vector_value("ACTION"); - if (has_time == 0 && has_done == -1 && action_time < the_time) + if (has_time == 0 && (has_done == -1 || (has_done == 0 && done_time < action_time)) && action_time < the_time) { ostringstream oss; @@ -1439,7 +1439,7 @@ int Scheduler::do_scheduled_actions() { vatt->remove("MESSAGE"); vatt->replace("DONE", static_cast(the_time)); - + vm->next_action(*vatt); oss << "Success."; } else diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc index 45a5f6ed2b..d8defe01e5 100644 --- a/src/vm_template/VMTemplate.cc +++ b/src/vm_template/VMTemplate.cc @@ -167,18 +167,86 @@ error_common: return -1; } -void VMTemplate::parse_sched_action() +int VMTemplate::parse_sched_action() { vector _sched_actions; vector::iterator i; + set::const_iterator it_set; + VectorAttribute* vatt; + int rep_mode, end_mode; + int has_mode, has_end_mode, has_days, has_end_value; + int end_value; + int first_day, last_day; + string days; + vector v_days; + set s_days; get_template_attribute("SCHED_ACTION", _sched_actions); for ( i = _sched_actions.begin(); i != _sched_actions.end() ; ++i) { - (*i)->remove("DONE"); - (*i)->remove("MESSAGE"); + vatt = dynamic_cast(*i); + + has_mode = vatt->vector_value("REP", rep_mode); + has_days = vatt->vector_value("DAYS", days); + + if (has_mode == 0 && has_days == 0) + { + v_days = one_util::split(days, ',', true); + for(vector::iterator it = v_days.begin(); it != v_days.end(); ++it) { + s_days.insert(atoi((*it).c_str())); + } + first_day = *s_days.cbegin(); + last_day = *s_days.cend(); + + if (!(rep_mode == 0 && first_day > 0 && last_day < 7)) //WEEK + { + return -1; + } + else if (!(rep_mode == 1 && first_day > 0 && last_day < 32)) //MONTH + { + return -1; + } + else if (!(rep_mode == 2 && first_day > 0 && last_day < 366)) //YEAR + { + return -1; + } + } + // else + // { + // return -1; + // } + + has_end_mode = vatt->vector_value("END_TYPE", end_mode); + has_end_value = vatt->vector_value("END_VALUE", end_value); + + if (has_end_mode == 0 && has_end_value == 0) + { + // if (end_mode == 1 && end_value < 0) //N_REP + // { + // return -1; + // } + else if ( end_mode == 2 ) //DATE + { + time_t value = end_value; + struct tm val_tm; + localtime_r(&value, &val_tm); + time_t out = mktime(&val_tm); + if (out == -1) + { + return -1; + } + } + } + else + { + return -1; + } + + vatt->remove("DONE"); + vatt->remove("MESSAGE"); } + return 0; } /* ------------------------------------------------------------------------ */ From a0305c353a4db28b8ac9c0d0bb48ec5360ded6ee Mon Sep 17 00:00:00 2001 From: juanmont Date: Mon, 19 Feb 2018 14:23:35 +0100 Subject: [PATCH 02/28] F #1548: Introduced relative actions into scheduler --- include/VMTemplate.h | 2 +- src/scheduler/include/VirtualMachineXML.h | 41 --------------- src/scheduler/src/pool/VirtualMachineXML.cc | 57 +++++++++++++++++++-- src/vm_template/VMTemplate.cc | 45 ++++++++++------ 4 files changed, 83 insertions(+), 62 deletions(-) diff --git a/include/VMTemplate.h b/include/VMTemplate.h index 866265c954..5d474898d4 100644 --- a/include/VMTemplate.h +++ b/include/VMTemplate.h @@ -170,7 +170,7 @@ private: /** * This method removes sched_action DONE/MESSAGE attributes */ - int parse_sched_action(); + int parse_sched_action(string& error_str); protected: diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index edf0173068..2cecf9a920 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -376,47 +376,6 @@ public: */ bool clear_log(); -private: - - void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor_day, int max_day, int comparative){ - if (mayor_day >= 0 && minor_day < max_day) - { - if( mayor_day < comparative ) //next - { - next->tm_mday = next->tm_mday + ((max_day-1) - comparative + minor_day); - } - else // same - { - next->tm_mday = next->tm_mday + (mayor_day - comparative); - } - } - } - - void generate_next_day(int rep, int mayor_day, int minor_day, struct tm * next, struct tm * now) - { - if ( rep == 0 ) //Repeat every weeks - { - sum_days(next, now, mayor_day, minor_day, 7, next->tm_wday); - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - } - - if ( rep == 1 ) //Repeat every months - { - cout << next->tm_mday << endl; - sum_days(next, now, mayor_day, minor_day, 32, next->tm_mday); - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - } - - if ( rep == 2 ) //Repeat every months - { - sum_days(next, now, mayor_day, minor_day, 366, next->tm_yday); - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - } - } - protected: /** diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 2b6da8e81b..dbde2d6887 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -503,6 +503,50 @@ bool VirtualMachineXML::is_only_public_cloud() const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor_day, int max_day, int comparative){ + if (mayor_day >= 0 && minor_day < max_day) + { + if( mayor_day <= comparative ) //next + { + next->tm_mday = next->tm_mday + ((max_day) - comparative + minor_day); + } + else // same + { + next->tm_mday = next->tm_mday + (mayor_day - comparative); + } + } +} + +/* -------------------------------------------------------------------------- */ + +static void generate_next_day(int rep, int mayor_day, int minor_day, struct tm * next, struct tm * now) +{ + if ( rep == 0 ) //Repeat every weeks + { + sum_days(next, now, mayor_day, minor_day, 7, next->tm_wday); + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + } + + if ( rep == 1 ) //Repeat every months + { + cout << next->tm_mday << endl; + sum_days(next, now, mayor_day, minor_day, 32, next->tm_mday); + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + } + + if ( rep == 2 ) //Repeat every months + { + sum_days(next, now, mayor_day, minor_day, 366, next->tm_yday); + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VirtualMachineXML::next_action(VectorAttribute& vatt) { string days; @@ -528,11 +572,10 @@ int VirtualMachineXML::next_action(VectorAttribute& vatt) s_days.insert(atoi((*it).c_str())); } - time_t t_next = time(0); struct tm next; struct tm start_tm; - localtime_r(&t_next, &next); localtime_r(&action_time, &start_tm); + next = start_tm; start_day = start_tm.tm_wday; if (rep_mode == 1) @@ -552,16 +595,20 @@ int VirtualMachineXML::next_action(VectorAttribute& vatt) ret = s_days.insert(start_day); if ( ret.second == false ) { - mayor_day = *(ret.first); + mayor_day = *ret.first; - if ( ret.first++ != s_days.end() ) + if ( ++ret.first != s_days.end() ) { mayor_day = *ret.first; } } else { - mayor_day = *((ret.first)++); + mayor_day = minor_day; + if ( ++ret.first != s_days.end() ) + { + mayor_day = *ret.first; + } it = s_days.find(start_day); s_days.erase (it); } diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc index d8defe01e5..72963a3552 100644 --- a/src/vm_template/VMTemplate.cc +++ b/src/vm_template/VMTemplate.cc @@ -74,9 +74,13 @@ int VMTemplate::insert(SqlDB *db, string& error_str) erase_template_attribute("NAME", name); // --------------------------------------------------------------------- - // Remove DONE/MESSAGE from SCHED_ACTION + // Remove DONE/MESSAGE from SCHED_ACTION and check rest attributes // --------------------------------------------------------------------- - parse_sched_action(); + int rc = parse_sched_action(error_str); + if (rc == -1) + { + return rc; + } // ------------------------------------------------------------------------ // Insert the Template @@ -167,7 +171,7 @@ error_common: return -1; } -int VMTemplate::parse_sched_action() +int VMTemplate::parse_sched_action(string& error_str) { vector _sched_actions; vector::iterator i; @@ -199,33 +203,38 @@ int VMTemplate::parse_sched_action() first_day = *s_days.cbegin(); last_day = *s_days.cend(); - if (!(rep_mode == 0 && first_day > 0 && last_day < 7)) //WEEK + if (!(rep_mode == 0 && first_day >= 0 && last_day < 7)) //WEEK [0,6] { + error_str = "Error parsing days of the week. [0,6]"; return -1; } - else if (!(rep_mode == 1 && first_day > 0 && last_day < 32)) //MONTH + else if (!(rep_mode == 1 && first_day >= 1 && last_day < 32)) //MONTH [1,31] { + error_str = "Error parsing days of the month. [1,31]"; return -1; } - else if (!(rep_mode == 2 && first_day > 0 && last_day < 366)) //YEAR + else if (!(rep_mode == 2 && first_day >= 0 && last_day < 366)) //YEAR [0,365] { + error_str = "Error parsing days of the year. [0,365]"; return -1; } } - // else - // { - // return -1; - // } + else + { + error_str = "Error parsing DAYS and REP."; + return -1; + } has_end_mode = vatt->vector_value("END_TYPE", end_mode); has_end_value = vatt->vector_value("END_VALUE", end_value); if (has_end_mode == 0 && has_end_value == 0) { - // if (end_mode == 1 && end_value < 0) //N_REP - // { - // return -1; - // } + if (end_mode == 1 && end_value < 0) //N_REP + { + error_str = "Error parsing END_VALUE of type N_REP."; + return -1; + } else if ( end_mode == 2 ) //DATE { time_t value = end_value; @@ -234,12 +243,14 @@ int VMTemplate::parse_sched_action() time_t out = mktime(&val_tm); if (out == -1) { + error_str = "Error parsing END_VALUE of type DATE."; return -1; } } } else { + error_str = "Error parsing END_TYPE and END_VALUE."; return -1; } @@ -254,7 +265,11 @@ int VMTemplate::parse_sched_action() int VMTemplate::post_update_template(string& error) { - parse_sched_action(); + int rc = parse_sched_action(error); + if (rc == -1) + { + return rc; + } return 0; } From 00268c02c98709bbf538396787cc423141fe822b Mon Sep 17 00:00:00 2001 From: juanmont Date: Mon, 26 Feb 2018 16:07:08 +0100 Subject: [PATCH 03/28] F #1548: Only one day and not rep attribute --- src/scheduler/src/sched/Scheduler.cc | 8 +++++++- src/vm_template/VMTemplate.cc | 27 ++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 5c915140a2..c910b2b6db 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -1387,6 +1387,8 @@ int Scheduler::do_scheduled_actions() int action_time; int done_time; + int rep_time; + int has_rep; int has_time; int has_done; @@ -1415,6 +1417,7 @@ int Scheduler::do_scheduled_actions() has_time = vatt->vector_value("TIME", action_time); has_done = vatt->vector_value("DONE", done_time); + has_rep = vatt->vector_value("REP", rep_time); action_st = vatt->vector_value("ACTION"); if (has_time == 0 && (has_done == -1 || (has_done == 0 && done_time < action_time)) && action_time < the_time) @@ -1439,7 +1442,10 @@ int Scheduler::do_scheduled_actions() { vatt->remove("MESSAGE"); vatt->replace("DONE", static_cast(the_time)); - vm->next_action(*vatt); + if ( has_rep == 0 ) + { + vm->next_action(*vatt); + } oss << "Success."; } else diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc index 72963a3552..1d1e62f26f 100644 --- a/src/vm_template/VMTemplate.cc +++ b/src/vm_template/VMTemplate.cc @@ -197,33 +197,35 @@ int VMTemplate::parse_sched_action(string& error_str) if (has_mode == 0 && has_days == 0) { v_days = one_util::split(days, ',', true); - for(vector::iterator it = v_days.begin(); it != v_days.end(); ++it) { - s_days.insert(atoi((*it).c_str())); + if ( !v_days.empty() ) + { + for(vector::iterator it = v_days.begin(); it != v_days.end(); ++it) { + s_days.insert(atoi((*it).c_str())); + } + } + else + { + s_days.insert(atoi((days).c_str())); } first_day = *s_days.cbegin(); last_day = *s_days.cend(); - if (!(rep_mode == 0 && first_day >= 0 && last_day < 7)) //WEEK [0,6] + if (rep_mode == 0 && !(first_day >= 0 && last_day < 7)) //WEEK [0,6] { error_str = "Error parsing days of the week. [0,6]"; return -1; } - else if (!(rep_mode == 1 && first_day >= 1 && last_day < 32)) //MONTH [1,31] + else if (rep_mode == 1 && !(first_day >= 1 && last_day < 32)) //MONTH [1,31] { error_str = "Error parsing days of the month. [1,31]"; return -1; } - else if (!(rep_mode == 2 && first_day >= 0 && last_day < 366)) //YEAR [0,365] + else if (rep_mode == 2 && !(first_day >= 0 && last_day < 366)) //YEAR [0,365] { error_str = "Error parsing days of the year. [0,365]"; return -1; } } - else - { - error_str = "Error parsing DAYS and REP."; - return -1; - } has_end_mode = vatt->vector_value("END_TYPE", end_mode); has_end_value = vatt->vector_value("END_VALUE", end_value); @@ -248,11 +250,6 @@ int VMTemplate::parse_sched_action(string& error_str) } } } - else - { - error_str = "Error parsing END_TYPE and END_VALUE."; - return -1; - } vatt->remove("DONE"); vatt->remove("MESSAGE"); From f18eaefed73d0df4696b9fd17b99cbaa10a8d6ed Mon Sep 17 00:00:00 2001 From: juanmont Date: Mon, 26 Feb 2018 16:08:17 +0100 Subject: [PATCH 04/28] F #1548: New utility to manage Schedule actions on Sunstone --- .../public/app/utils/schedule_action.js | 317 ++++++++++++++++++ .../public/app/utils/schedule_action/html.hbs | 73 ++++ .../app/utils/schedule_action/table.hbs | 29 ++ 3 files changed, 419 insertions(+) create mode 100644 src/sunstone/public/app/utils/schedule_action.js create mode 100644 src/sunstone/public/app/utils/schedule_action/html.hbs create mode 100644 src/sunstone/public/app/utils/schedule_action/table.hbs diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js new file mode 100644 index 0000000000..011a445c44 --- /dev/null +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -0,0 +1,317 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2018, 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. */ +/* -------------------------------------------------------------------------- */ + +define(function (require) { + var Config = require('sunstone-config'); + var Locale = require('utils/locale'); + var Humanize = require('utils/humanize'); + var TemplateUtils = require('utils/template-utils'); + + var TemplateHTML = require('hbs!./schedule_action/html'); + var TemplateTableHTML = require('hbs!./schedule_action/table'); + + function _html(resource) { + this.res = resource; + return TemplateTableHTML({ + res: resource + }); + } + + function _htmlNewAction(actions, context) { + var options = ""; + var that = this; + $.each(actions, function (key, action) { + var actionAux = action.replace("-", "_"); + if (Config.isTabActionEnabled("vms-tab", "VM." + actionAux)) { + options += ''; + } + }); + $("#scheduling_"+this.res+"_actions_table", context).append(TemplateHTML({ + "actions": options, + "res": that.res + })); + } + + function _setup(context) { + var today = new Date(); + var dd = today.getDate(); + var mm = today.getMonth() + 1; + var yyyy = today.getFullYear(); + if (dd < 10) { + dd = '0' + dd + } + if (mm < 10) { + mm = '0' + mm + } + today = yyyy + '-' + mm + '-' + dd; + $("#date_input", context).attr("min", today); + $("#date_input", context).attr("value", today); + + $(".periodic", context).hide(); + + $("input#schedule_type", context).on("change", function () { + var periodic = $(this).prop('checked'); + + if (periodic) { + $(".periodic", context).show(); + $(".non-periodic", context).hide(); + } else { + $(".periodic", context).hide(); + $(".non-periodic", context).show(); + } + }); + var that = this; + $("input[name='rep']", context).change(function () { + var value = $(this).val(); + that.rep = value; + var input_html = ""; + switch (value) { + case "week": + input_html = '
\ + \ + \ + \ + \ + \ + \ + \ +
'; + break; + case "month": + input_html = ''; + break; + case "year": + input_html = ''; + break; + } + $("#td_days").html(input_html); + }); + + $("input[name='end_type']", context).change(function () { + var value = $(this).val(); + that.end_type = value; + var input_html = ""; + var min; + switch (value) { + case "n_rep": + input_html = ''; + min = 1; + break; + case "date": + input_html = ''; + var today = new Date(); + var dd = today.getDate(); + var mm = today.getMonth() + 1; + var yyyy = today.getFullYear(); + if (dd < 10) { + dd = '0' + dd + } + if (mm < 10) { + mm = '0' + mm + } + min = yyyy + '-' + mm + '-' + dd; + break; + } + $("#td_end_value", context).html(input_html); + $("#end_value_" + value, context).attr("min", min); + }); + + context.on("focusout", "#time_input", function () { + $("#time_input").removeAttr("data-invalid"); + $("#time_input").removeAttr("class"); + }); + + } + + function _retrieve(context){ + var actionsJSON = []; + $("#scheduling_"+this.res+"_actions_table tbody tr").each(function(index){ + var first = $(this).children("td")[0]; + if(!$('select', first).html()){ + var actionJSON = {}; + actionJSON = JSON.parse($(this).attr('data')); + actionJSON.ID = index; + } + if (!$.isEmptyObject(actionJSON)) {actionsJSON.push(actionJSON)}; + }); + return actionsJSON; + } + + function _retrieveNewAction(context) { + var periodic = $("input#schedule_type", context).prop('checked'); + var time_input_value = $("#time_input", context).val(); + var date_input_value = $("#date_input", context).val(); + var new_action = $("#select_new_action", context).val(); + var rep = 0; + var end_type = 1; + var days = ""; + var end_value = 1; + + if (time_input_value == "" || date_input_value == "") { + return false; + } + + if (periodic) { + + if (!this.rep || !this.end_type) { + return false + } + + if (this.rep == "week") { + $("input[name='days']:checked").each(function () { + days = days + (this).value + ","; + }); + days = days.slice(0, -1); + } else if (this.rep == "month") { + rep = 1; + days = $("#days_month_value", context).val(); + } else { + rep = 2; + days = $("#days_year_value", context).val(); + } + + if (days == "") { + return false; + } + + if (this.end_type == "ever") { + end_type = 0; + } else if (this.end_type == "n_rep") { + end_value = $("#end_value_n_rep", context).val(); + if (end_value == "") { + return false; + } + } else if (this.end_type == "date") { + end_type = 2; + end_date = $("#end_value_date", context).val(); + var time_value = end_date + ' ' + time_input_value; + var epoch_str = new Date(time_value); + end_value = parseInt(epoch_str.getTime()) / 1000; + if (end_value == "") { + return false; + } + } + } + + var time_value = date_input_value + ' ' + time_input_value; + var epoch_str = new Date(time_value); + var time = parseInt(epoch_str.getTime()) / 1000; + + var sched_action = {}; + sched_action.ACTION = new_action; + sched_action.TIME = time; + sched_action.DAYS = days; + sched_action.REP = rep; + sched_action.END_TYPE = end_type; + sched_action.END_VALUE = end_value; + + $("#scheduling_"+this.res+"_actions_table tbody tr.create", context).html(""); + $("#add_scheduling_"+this.res+"_action", context).removeAttr("disabled"); + return sched_action; + } + + function _fromJSONtoActionsTable(actions_array, action_id, minus) { + var str = "" + + if (!actions_array) { + return ""; + } + + if (!$.isArray(actions_array)) { + var tmp_array = new Array(); + tmp_array[0] = actions_array; + actions_array = tmp_array; + } + + if (!actions_array.length) { + return ""; + } + + $.each(actions_array, function (index, scheduling_action) { + str += _fromJSONtoActionRow(scheduling_action, action_id, minus); + }); + + return str; + } + + function _fromJSONtoActionRow(scheduling_action, action_id, minus) { + var time_str = Humanize.prettyTime(scheduling_action.TIME); + var rep_str = ""; + var end_str = ""; + + if (scheduling_action.REP != undefined) { + if ( scheduling_action.REP == 0) { + rep_str = "Weekly "; + } else if ( scheduling_action.REP == 1) { + rep_str = "Monthly "; + } else if ( scheduling_action.REP == 2) { + rep_str = "Yearly "; + } + + if ( scheduling_action.REP != 0 ) { + rep_str += scheduling_action.DAYS; + } else { + rep_str += Humanize.week_days(scheduling_action.DAYS); + } + } else { + rep_str = "None" + } + + if (scheduling_action.END_TYPE != undefined) { + if ( scheduling_action.END_TYPE == 0) { + end_str = "None"; + } else if ( scheduling_action.END_TYPE == 1) { + end_str = "After " + scheduling_action.END_VALUE + " times"; + } else if ( scheduling_action.END_TYPE == 2) { + end_str = "on " + Humanize.prettyTime(scheduling_action.END_VALUE); + } + } + + var str = ""; + if (action_id == undefined){ + str += ""; + } + str += "" + TemplateUtils.htmlEncode(scheduling_action.ACTION) + "\ + " + time_str + "\ + " + rep_str + "\ + " + end_str + ""; + if (minus == undefined) { + str += "\ +
\ + \ +
\ + \ + "; + } + + return str; + } + + function convertDate(date_string){ + date_string = date_string.split('/'); + return date_string[2] + "-" + date_string[1] + "-" + date_string[0]; + } + + return { + 'fromJSONtoActionRow': _fromJSONtoActionRow, + 'fromJSONtoActionsTable': _fromJSONtoActionsTable, + 'htmlNewAction': _htmlNewAction, + 'setup': _setup, + 'htmlTable': _html, + 'retrieveNewAction': _retrieveNewAction, + 'retrieve': _retrieve + } +}) \ No newline at end of file diff --git a/src/sunstone/public/app/utils/schedule_action/html.hbs b/src/sunstone/public/app/utils/schedule_action/html.hbs new file mode 100644 index 0000000000..6de2b53fe6 --- /dev/null +++ b/src/sunstone/public/app/utils/schedule_action/html.hbs @@ -0,0 +1,73 @@ +{{! -------------------------------------------------------------------------- }} +{{! Copyright 2002-2018, 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. }} +{{! -------------------------------------------------------------------------- }} + + +
+ + +
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/src/sunstone/public/app/utils/schedule_action/table.hbs b/src/sunstone/public/app/utils/schedule_action/table.hbs new file mode 100644 index 0000000000..b7ec263157 --- /dev/null +++ b/src/sunstone/public/app/utils/schedule_action/table.hbs @@ -0,0 +1,29 @@ +{{! -------------------------------------------------------------------------- }} +{{! Copyright 2002-2018, 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. }} +{{! -------------------------------------------------------------------------- }} + + + + + + + + + + + + + +
{{tr "Action"}} {{tr "Time"}} {{tr "Rep"}} {{tr "End"}} {{tr "Actions"}}
\ No newline at end of file From ef6afd333527fdd60d9e2355c26925daafc3f06a Mon Sep 17 00:00:00 2001 From: juanmont Date: Mon, 26 Feb 2018 16:11:49 +0100 Subject: [PATCH 05/28] F #1548: Use new Utility for Schedule actions --- .../form-panels/create/wizard-tabs/actions.js | 90 +++--------------- .../create/wizard-tabs/actions/html.hbs | 12 +-- .../templates-tab/form-panels/instantiate.js | 83 +++------------- .../form-panels/instantiate/templateRow.hbs | 12 +-- .../public/app/tabs/vms-tab/panels/actions.js | 94 +++++-------------- 5 files changed, 52 insertions(+), 239 deletions(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js index 3ebcb74f60..d02c9baf5e 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js @@ -20,6 +20,7 @@ define(function(require) { */ var Config = require('sunstone-config'); + var ScheduleActions = require('utils/schedule_action'); var Locale = require('utils/locale'); var Tips = require('utils/tips'); var WizardFields = require('utils/wizard-fields'); @@ -59,7 +60,9 @@ define(function(require) { return WizardTab; function _html() { - return TemplateHTML(); + return TemplateHTML({ + 'table_sched_actions': ScheduleActions.htmlTable("temp") + }); } function _onShow(context, panelForm) { @@ -68,103 +71,40 @@ define(function(require) { function _setup(context) { var that = this; var actions = ["terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume", "reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard", "snapshot-create"]; + context.off('click', '#add_scheduling_temp_action'); context.on('click', '#add_scheduling_temp_action', function() { $("#add_scheduling_temp_action", context).attr("disabled", "disabled"); - var html = '\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - '; - $("#scheduling_temp_actions_table").append(html); + ScheduleActions.htmlNewAction(actions, context); + ScheduleActions.setup(context) return false; }); context.off("click", "#add_temp_action_json"); context.on("click" , "#add_temp_action_json", function(){ - var date_input_value = $("#date_input", context).val(); - var time_input_value = $("#time_input", context).val(); - - if (date_input_value == "" || time_input_value == ""){ - return false; + var sched_action = ScheduleActions.retrieveNewAction(context) + if (sched_action != false) { + $("#sched_temp_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); } - var time_value = date_input_value + ' ' + time_input_value; - var epoch_str = new Date(time_value); - var time = parseInt(epoch_str.getTime()) / 1000; - - var new_action = $("#select_new_action", context).val(); - var sched_action = {}; - sched_action.ACTION = new_action; - sched_action.TIME = time; - - $(this).parents('tr').remove(); - $("#add_scheduling_temp_action", context).removeAttr("disabled"); - - $("#sched_temp_actions_body").append(Actions.fromJSONtoActionsTable(sched_action)); - return false; }); - context.on("focusout" , "#time_input", function(){ - $("#time_input").removeAttr("data-invalid"); - $("#time_input").removeAttr("class"); + context.off("click", ".remove_action_x"); + context.on("click", ".remove_action_x", function () { + $(this).parents('tr').remove(); }); - context.off("click", ".remove_action_x"); - context.on("click", ".remove_action_x", function(){ - $(this).parents('tr').remove(); - }); } function _retrieve(context) { var templateJSON = {}; - var actionsJSON = []; - - $("#scheduling_temp_actions_table tbody tr").each(function(index){ - var first = $(this).children("td")[0]; - if(!$('select', first).html()){ - var actionJSON = {}; - actionJSON.ID = index; - $(this).children("td").each(function(index2){ - if(index2 == 0) - actionJSON.ACTION = $(this).text(); - else if (index2 == 1){ - var pretty_time = $(this).text(); - pretty_time = pretty_time.split(' '); - var date = Actions.convertDate(pretty_time[1]); - var time_value = date + ' ' + pretty_time[0]; - var epoch_str = new Date(time_value); - var time = parseInt(epoch_str.getTime()) / 1000; - actionJSON.TIME = time; - } - }); - } - if (!$.isEmptyObject(actionJSON)) {actionsJSON.push(actionJSON)}; - }); - - templateJSON['SCHED_ACTION'] = actionsJSON; + templateJSON['SCHED_ACTION'] = ScheduleActions.retrieve(context); return templateJSON; } function _fill(context, templateJSON) { - var actions = Actions.fromJSONtoActionsTable(templateJSON.SCHED_ACTION); + var actions = ScheduleActions.fromJSONtoActionsTable(templateJSON.SCHED_ACTION); $("#sched_temp_actions_body").append(actions); delete templateJSON['SCHED_ACTION']; } diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions/html.hbs index f5a2c06e58..9ec25858f3 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions/html.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions/html.hbs @@ -1,15 +1,5 @@
- - - - - - - - - - -
{{tr "Action"}} {{tr "Time"}} {{tr "Actions"}}
+ {{{table_sched_actions}}}
diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js index c53927333a..612fd4dda0 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js @@ -41,7 +41,7 @@ define(function(require) { var Humanize = require('utils/humanize'); var TemplateUtils = require('utils/template-utils'); var UniqueId = require('utils/unique-id'); - var Actions = require('utils/actions'); + var ScheduleActions = require('utils/schedule_action'); /* CONSTANTS @@ -125,54 +125,18 @@ define(function(require) { context.on('click', '#add_scheduling_inst_action', function() { var actions = ["terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume", "reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard", "snapshot-create"]; $("#add_scheduling_inst_action", context).attr("disabled", "disabled"); - var html = '\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - '; - $("#scheduling_inst_actions_table").append(html); + ScheduleActions.htmlNewAction(actions, context); + ScheduleActions.setup(context) return false; }); context.off("click", "#add_inst_action_json"); context.on("click" , "#add_inst_action_json", function(){ - var date_input_value = $("#date_input", context).val(); - var time_input_value = $("#time_input", context).val(); - - if (date_input_value == "" || time_input_value == ""){ - return false; + var sched_action = ScheduleActions.retrieveNewAction(context) + if (sched_action != false) { + $("#sched_inst_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); } - var time_value = date_input_value + ' ' + time_input_value; - var epoch_str = new Date(time_value); - var time = parseInt(epoch_str.getTime()) / 1000; - - var new_action = $("#select_new_action", context).val(); - var sched_action = {}; - sched_action.ACTION = new_action; - sched_action.TIME = time; - - $(this).parents('tr').remove(); - $("#add_scheduling_inst_action", context).removeAttr("disabled"); - - $("#sched_inst_actions_body").append(Actions.fromJSONtoActionsTable(sched_action)); - return false; }); @@ -325,32 +289,10 @@ define(function(require) { } } - var templateJSON = {}; - var actionsJSON = []; - - $("#scheduling_inst_actions_table tbody tr").each(function(index){ - var first = $(this).children("td")[0]; - if(!$('select', first).html()){ - var actionJSON = {}; - actionJSON.ID = index; - $(this).children("td").each(function(index2){ - if(index2 == 0) - actionJSON.ACTION = $(this).text(); - else if (index2 == 1){ - var pretty_time = $(this).text(); - pretty_time = pretty_time.split(' '); - var date = Actions.convertDate(pretty_time[1]); - var time_value = date + ' ' + pretty_time[0]; - var epoch_str = new Date(time_value); - var time = parseInt(epoch_str.getTime()) / 1000; - actionJSON.TIME = time; - } - }); - } - if (!$.isEmptyObject(actionJSON)) {actionsJSON.push(actionJSON)}; - }); - - tmp_json['SCHED_ACTION'] = actionsJSON; + tmp_json['SCHED_ACTION'] = ScheduleActions.retrieve(context); + if (tmp_json['SCHED_ACTION'].length == 0) { + delete tmp_json['SCHED_ACTION']; + } capacityContext = $(".capacityContext" + template_id, context); $.extend(tmp_json, CapacityInputs.retrieveChanges(capacityContext)); @@ -418,13 +360,14 @@ define(function(require) { { element: template_json.VMTEMPLATE, capacityInputsHTML: CapacityInputs.html(), hostsDatatable: that.hostsTable.dataTableHTML, - dsDatatable: that.datastoresTable.dataTableHTML + dsDatatable: that.datastoresTable.dataTableHTML, + table_sched_actions: ScheduleActions.htmlTable("inst") }) ); $(".provision_host_selector" + template_json.VMTEMPLATE.ID, context).data("hostsTable", that.hostsTable); $(".provision_ds_selector" + template_json.VMTEMPLATE.ID, context).data("dsTable", that.datastoresTable); - var actions = Actions.fromJSONtoActionsTable(template_json.VMTEMPLATE.TEMPLATE.SCHED_ACTION); + var actions = ScheduleActions.fromJSONtoActionsTable(template_json.VMTEMPLATE.TEMPLATE.SCHED_ACTION); $("#sched_inst_actions_body").append(actions); var selectOptions = { diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs index c43bed0004..caba965487 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs @@ -105,17 +105,7 @@ {{tr "Actions"}} - - - - - - - - - - -
{{tr "Action"}} {{tr "Time"}} {{tr "Actions"}}
+ {{{table_sched_actions}}} diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js index a64c76ab99..ba912e3e7d 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js @@ -24,6 +24,7 @@ define(function(require) { var Humanize = require('utils/humanize'); var TemplateUtils = require('utils/template-utils'); var Config = require('sunstone-config'); + var ScheduleActions = require('utils/schedule_action'); /* CONSTANTS @@ -62,99 +63,50 @@ define(function(require) { var that = this; var html = '
\
\ - \ +
\ \ \ \ \ \ + \ + \ \ \ \ - \ + \ \ ' + - fromJSONtoActionsTable(that.element.USER_TEMPLATE.SCHED_ACTION) + + vmsfromJSONtoActionsTable(that.element.USER_TEMPLATE.SCHED_ACTION) + '
' + Locale.tr("ID") + '' + Locale.tr("Action") + '' + Locale.tr("Time") + '' + Locale.tr("Rep") + '' + Locale.tr("End") + '' + Locale.tr("Done") + '' + Locale.tr("Message") + '' + Locale.tr("Actions") + '
\
\
'; + ScheduleActions.htmlTable("vms") //only charge the resource attribute return html; } function _setup(context) { var that = this; var actions = ["terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume", "reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard", "snapshot-create"]; - context.off('click', '#add_scheduling_action'); - context.on('click', '#add_scheduling_action', function() { - $("#add_scheduling_action", context).attr("disabled", "disabled"); - var html = '\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - '; - $("#scheduling_actions_table").append(html); + context.off('click', '#add_scheduling_vms_action'); + context.on('click', '#add_scheduling_vms_action', function() { + $("#add_scheduling_vms_action", context).attr("disabled", "disabled"); + ScheduleActions.htmlNewAction(actions, context); + ScheduleActions.setup(context) return false; }); context.off("click", "#submit_scheduling_action"); context.on("click", "#submit_scheduling_action", function() { - var date_input_value = $("#date_input", context).val(); - var time_input_value = $("#time_input", context).val(); - if (date_input_value == "" || time_input_value == "") - return false; - - var time_value = date_input_value + ' ' + time_input_value - - // Calculate MAX_ID - var max_id = -1; - - if (that.element.USER_TEMPLATE.SCHED_ACTION) { - if (!that.element.USER_TEMPLATE.SCHED_ACTION.length) { - var tmp_element = that.element.USER_TEMPLATE.SCHED_ACTION; - that.element.USER_TEMPLATE.SCHED_ACTION = new Array(); - that.element.USER_TEMPLATE.SCHED_ACTION.push(tmp_element); - } - - $.each(that.element.USER_TEMPLATE.SCHED_ACTION, function(i, element) { - if (max_id < element.ID) - max_id = element.ID - }) - } else { - that.element.USER_TEMPLATE.SCHED_ACTION = new Array(); - } - - var new_action = {}; - new_action.ID = parseInt(max_id) + 1; - new_action.ACTION = $("#select_new_action", context).val(); - var epoch_str = new Date(time_value); - - new_action.TIME = parseInt(epoch_str.getTime()) / 1000; - - that.element.USER_TEMPLATE.SCHED_ACTION.push(new_action); + that.element.USER_TEMPLATE.SCHED_ACTION = ScheduleActions.retrieve(context); // Let OpenNebula know var template_str = TemplateUtils.templateToString(that.element.USER_TEMPLATE); Sunstone.runAction("VM.update_template", that.element.ID, template_str); - $("#add_scheduling_action", context).removeAttr("disabled"); + $("#add_schedulingvms_action", context).removeAttr("disabled"); return false; }); @@ -179,7 +131,7 @@ define(function(require) { } // Returns an HTML string with the json keys and values - function fromJSONtoActionsTable(actions_array) { + function vmsfromJSONtoActionsTable(actions_array) { var str = "" var empty = '\ \ @@ -201,24 +153,22 @@ define(function(require) { } $.each(actions_array, function(index, scheduling_action) { - str += fromJSONtoActionRow(scheduling_action); + str += ""; + str += '' + TemplateUtils.htmlEncode(scheduling_action.ID) + '' + var actions = ScheduleActions.fromJSONtoActionsTable([scheduling_action], scheduling_action.ID, true); + str += actions; + str += vmsfromJSONtoActionRow(scheduling_action); }); return str; } // Helper for fromJSONtoHTMLTable function - function fromJSONtoActionRow(scheduling_action) { + function vmsfromJSONtoActionRow(scheduling_action) { var done_str = scheduling_action.DONE ? (Humanize.prettyTime(scheduling_action.DONE)) : ""; var message_str = scheduling_action.MESSAGE ? scheduling_action.MESSAGE : ""; - var time_str = Humanize.prettyTime(scheduling_action.TIME); - var str = ""; - str += '\ - ' + TemplateUtils.htmlEncode(scheduling_action.ID) + '\ - ' + TemplateUtils.htmlEncode(scheduling_action.ACTION) + '\ - ' + time_str + '\ - ' + done_str + '\ + var str = '' + done_str + '\ ' + TemplateUtils.htmlEncode(message_str) + '\ \
\ From 500fd5ce40472f81f008adb131cac18ed2eba317 Mon Sep 17 00:00:00 2001 From: juanmont Date: Mon, 26 Feb 2018 16:12:28 +0100 Subject: [PATCH 06/28] F #1548: Humanize days of the week --- src/sunstone/public/app/utils/humanize.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sunstone/public/app/utils/humanize.js b/src/sunstone/public/app/utils/humanize.js index b63fe548a1..714d1014bd 100644 --- a/src/sunstone/public/app/utils/humanize.js +++ b/src/sunstone/public/app/utils/humanize.js @@ -62,6 +62,8 @@ define(function(require) { } }; + var week_days_str = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + /* CONSTRUCTOR */ @@ -80,7 +82,8 @@ define(function(require) { 'prettyTimeAgo': _format_date, 'prettyTimeDatatable': _prettyTimeDatatable, 'lock_to_str': _lock_to_str, - 'state_lock_to_color': _state_lock_to_color + 'state_lock_to_color': _state_lock_to_color, + 'week_days': _week_days } /* @@ -392,4 +395,13 @@ define(function(require) { return '' } + + function _week_days(days){ + var days = days.split(","); + var str = ""; + days.forEach(function(day){ + str += week_days_str[day] + ","; + }); + return str.slice(0, -1); + } }) From 1565d1aaf8492b423dcb0b44a55e6816b4d804c4 Mon Sep 17 00:00:00 2001 From: juanmont Date: Wed, 28 Feb 2018 09:53:33 +0100 Subject: [PATCH 07/28] F #1548: Added new map to obtain days of the month --- src/scheduler/src/pool/VirtualMachineXML.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index dbde2d6887..7fabbc549a 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -22,6 +22,8 @@ #include "NebulaUtil.h" #include "History.h" +map m_months_days = {{0, 31}, {1, 28}, {2, 30}, {3, 31}, {4, 30}, {5, 31}, {6, 30}, {7, 31}, {8, 30}, {9, 31}, {10, 30}, {11, 31}}; + void VirtualMachineXML::init_attributes() { vector nodes; @@ -531,14 +533,14 @@ static void generate_next_day(int rep, int mayor_day, int minor_day, struct tm * if ( rep == 1 ) //Repeat every months { cout << next->tm_mday << endl; - sum_days(next, now, mayor_day, minor_day, 32, next->tm_mday); + sum_days(next, now, mayor_day, minor_day, m_months_days[next->tm_mon] , next->tm_mday); next->tm_min = now->tm_min; next->tm_hour = now->tm_hour; } if ( rep == 2 ) //Repeat every months { - sum_days(next, now, mayor_day, minor_day, 366, next->tm_yday); + sum_days(next, now, mayor_day, minor_day, 365, next->tm_yday); next->tm_min = now->tm_min; next->tm_hour = now->tm_hour; } @@ -611,6 +613,10 @@ int VirtualMachineXML::next_action(VectorAttribute& vatt) } it = s_days.find(start_day); s_days.erase (it); + if (*--it > mayor_day) + { + mayor_day = *it; + } } if ( end_mode == 1 ) From 72112e0f4d81b77898d78cbedd2eca7b062d2b35 Mon Sep 17 00:00:00 2001 From: abelCoronado93 Date: Wed, 28 Feb 2018 15:10:39 +0100 Subject: [PATCH 08/28] F #1548: Scheduled actions makeover --- .../public/app/utils/schedule_action.js | 514 +++++++++--------- .../public/app/utils/schedule_action/html.hbs | 88 ++- .../app/utils/schedule_action/table.hbs | 33 +- 3 files changed, 321 insertions(+), 314 deletions(-) diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index 011a445c44..b51b1d0232 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -15,303 +15,303 @@ /* -------------------------------------------------------------------------- */ define(function (require) { - var Config = require('sunstone-config'); - var Locale = require('utils/locale'); - var Humanize = require('utils/humanize'); - var TemplateUtils = require('utils/template-utils'); + var Config = require("sunstone-config"); + var Locale = require("utils/locale"); + var Humanize = require("utils/humanize"); + var TemplateUtils = require("utils/template-utils"); - var TemplateHTML = require('hbs!./schedule_action/html'); - var TemplateTableHTML = require('hbs!./schedule_action/table'); + var TemplateHTML = require("hbs!./schedule_action/html"); + var TemplateTableHTML = require("hbs!./schedule_action/table"); - function _html(resource) { - this.res = resource; - return TemplateTableHTML({ - res: resource - }); - } + function _html(resource) { + this.res = resource; + return TemplateTableHTML({ + res: resource + }); + } - function _htmlNewAction(actions, context) { - var options = ""; - var that = this; - $.each(actions, function (key, action) { - var actionAux = action.replace("-", "_"); - if (Config.isTabActionEnabled("vms-tab", "VM." + actionAux)) { - options += ''; - } - }); - $("#scheduling_"+this.res+"_actions_table", context).append(TemplateHTML({ - "actions": options, - "res": that.res - })); - } + function _htmlNewAction(actions, context) { + var options = ""; + var that = this; + $.each(actions, function (key, action) { + var actionAux = action.replace("-", "_"); + if (Config.isTabActionEnabled("vms-tab", "VM." + actionAux)) { + options += ""; + } + }); + $("#scheduling_" + this.res + "_actions_table", context).append(TemplateHTML({ + "actions": options, + "res": that.res + })); + } - function _setup(context) { - var today = new Date(); - var dd = today.getDate(); - var mm = today.getMonth() + 1; - var yyyy = today.getFullYear(); - if (dd < 10) { - dd = '0' + dd - } - if (mm < 10) { - mm = '0' + mm - } - today = yyyy + '-' + mm + '-' + dd; - $("#date_input", context).attr("min", today); - $("#date_input", context).attr("value", today); + function _setup(context) { + var today = new Date(); + var dd = today.getDate(); + var mm = today.getMonth() + 1; + var yyyy = today.getFullYear(); + if (dd < 10) { + dd = "0" + dd; + } + if (mm < 10) { + mm = "0" + mm; + } + today = yyyy + "-" + mm + "-" + dd; + $("#date_input", context).attr("min", today); + $("#date_input", context).attr("value", today); - $(".periodic", context).hide(); + $(".periodic", context).hide(); - $("input#schedule_type", context).on("change", function () { - var periodic = $(this).prop('checked'); + $("input#schedule_type", context).on("change", function () { + var periodic = $(this).prop("checked"); - if (periodic) { - $(".periodic", context).show(); - $(".non-periodic", context).hide(); - } else { - $(".periodic", context).hide(); - $(".non-periodic", context).show(); - } - }); - var that = this; - $("input[name='rep']", context).change(function () { - var value = $(this).val(); - that.rep = value; - var input_html = ""; - switch (value) { - case "week": - input_html = '
\ - \ - \ - \ - \ - \ - \ - \ -
'; - break; - case "month": - input_html = ''; - break; - case "year": - input_html = ''; - break; - } - $("#td_days").html(input_html); - }); + if (periodic) { + $(".periodic", context).show(); + $(".non-periodic", context).hide(); + } else { + $(".periodic", context).hide(); + $(".non-periodic", context).show(); + } + }); + var that = this; + $("input[name='rep']", context).change(function () { + var value = $(this).val(); + that.rep = value; + var input_html = ""; + switch (value) { + case "week": + input_html = "
\ + \ + \ + \ + \ + \ + \ + \ +
"; + break; + case "month": + input_html = ""; + break; + case "year": + input_html = ""; + break; + } + $("#td_days").html(input_html); + }); - $("input[name='end_type']", context).change(function () { - var value = $(this).val(); - that.end_type = value; - var input_html = ""; - var min; - switch (value) { - case "n_rep": - input_html = ''; - min = 1; - break; - case "date": - input_html = ''; - var today = new Date(); - var dd = today.getDate(); - var mm = today.getMonth() + 1; - var yyyy = today.getFullYear(); - if (dd < 10) { - dd = '0' + dd - } - if (mm < 10) { - mm = '0' + mm - } - min = yyyy + '-' + mm + '-' + dd; - break; - } - $("#td_end_value", context).html(input_html); - $("#end_value_" + value, context).attr("min", min); - }); + $("input[name='end_type']", context).change(function () { + var value = $(this).val(); + that.end_type = value; + var input_html = ""; + var min; + switch (value) { + case "n_rep": + input_html = ""; + min = 1; + break; + case "date": + input_html = ""; + var today = new Date(); + var dd = today.getDate(); + var mm = today.getMonth() + 1; + var yyyy = today.getFullYear(); + if (dd < 10) { + dd = "0" + dd + } + if (mm < 10) { + mm = "0" + mm + } + min = yyyy + "-" + mm + "-" + dd; + break; + } + $("#td_end_value", context).html(input_html); + $("#end_value_" + value, context).attr("min", min); + }); - context.on("focusout", "#time_input", function () { - $("#time_input").removeAttr("data-invalid"); - $("#time_input").removeAttr("class"); - }); + context.on("focusout", "#time_input", function () { + $("#time_input").removeAttr("data-invalid"); + $("#time_input").removeAttr("class"); + }); - } + } - function _retrieve(context){ - var actionsJSON = []; - $("#scheduling_"+this.res+"_actions_table tbody tr").each(function(index){ - var first = $(this).children("td")[0]; - if(!$('select', first).html()){ - var actionJSON = {}; - actionJSON = JSON.parse($(this).attr('data')); - actionJSON.ID = index; - } - if (!$.isEmptyObject(actionJSON)) {actionsJSON.push(actionJSON)}; - }); - return actionsJSON; - } + function _retrieve(context) { + var actionsJSON = []; + $("#scheduling_" + this.res + "_actions_table tbody tr").each(function (index) { + var first = $(this).children("td")[0]; + if (!$("select", first).html()) { + var actionJSON = {}; + actionJSON = JSON.parse($(this).attr("data")); + actionJSON.ID = index; + } + if (!$.isEmptyObject(actionJSON)) { actionsJSON.push(actionJSON) }; + }); + return actionsJSON; + } - function _retrieveNewAction(context) { - var periodic = $("input#schedule_type", context).prop('checked'); - var time_input_value = $("#time_input", context).val(); - var date_input_value = $("#date_input", context).val(); - var new_action = $("#select_new_action", context).val(); - var rep = 0; - var end_type = 1; - var days = ""; - var end_value = 1; + function _retrieveNewAction(context) { + var periodic = $("input#schedule_type", context).prop("checked"); + var time_input_value = $("#time_input", context).val(); + var date_input_value = $("#date_input", context).val(); + var new_action = $("#select_new_action", context).val(); + var rep = 0; + var end_type = 1; + var days = ""; + var end_value = 1; - if (time_input_value == "" || date_input_value == "") { - return false; - } + if (time_input_value == "" || date_input_value == "") { + return false; + } - if (periodic) { + if (periodic) { - if (!this.rep || !this.end_type) { - return false - } + if (!this.rep || !this.end_type) { + return false; + } - if (this.rep == "week") { - $("input[name='days']:checked").each(function () { - days = days + (this).value + ","; - }); - days = days.slice(0, -1); - } else if (this.rep == "month") { - rep = 1; - days = $("#days_month_value", context).val(); - } else { - rep = 2; - days = $("#days_year_value", context).val(); - } + if (this.rep == "week") { + $("input[name='days']:checked").each(function () { + days = days + (this).value + ","; + }); + days = days.slice(0, -1); + } else if (this.rep == "month") { + rep = 1; + days = $("#days_month_value", context).val(); + } else { + rep = 2; + days = $("#days_year_value", context).val(); + } - if (days == "") { - return false; - } + if (days == "") { + return false; + } - if (this.end_type == "ever") { - end_type = 0; - } else if (this.end_type == "n_rep") { - end_value = $("#end_value_n_rep", context).val(); - if (end_value == "") { - return false; - } - } else if (this.end_type == "date") { - end_type = 2; - end_date = $("#end_value_date", context).val(); - var time_value = end_date + ' ' + time_input_value; - var epoch_str = new Date(time_value); - end_value = parseInt(epoch_str.getTime()) / 1000; - if (end_value == "") { - return false; - } - } - } + if (this.end_type == "ever") { + end_type = 0; + } else if (this.end_type == "n_rep") { + end_value = $("#end_value_n_rep", context).val(); + if (end_value == "") { + return false; + } + } else if (this.end_type == "date") { + end_type = 2; + end_date = $("#end_value_date", context).val(); + var time_value = end_date + " " + time_input_value; + var epoch_str = new Date(time_value); + end_value = parseInt(epoch_str.getTime()) / 1000; + if (end_value == "") { + return false; + } + } + } - var time_value = date_input_value + ' ' + time_input_value; - var epoch_str = new Date(time_value); - var time = parseInt(epoch_str.getTime()) / 1000; + var time_value = date_input_value + " " + time_input_value; + var epoch_str = new Date(time_value); + var time = parseInt(epoch_str.getTime()) / 1000; - var sched_action = {}; - sched_action.ACTION = new_action; - sched_action.TIME = time; - sched_action.DAYS = days; - sched_action.REP = rep; - sched_action.END_TYPE = end_type; - sched_action.END_VALUE = end_value; + var sched_action = {}; + sched_action.ACTION = new_action; + sched_action.TIME = time; + sched_action.DAYS = days; + sched_action.REP = rep; + sched_action.END_TYPE = end_type; + sched_action.END_VALUE = end_value; - $("#scheduling_"+this.res+"_actions_table tbody tr.create", context).html(""); - $("#add_scheduling_"+this.res+"_action", context).removeAttr("disabled"); - return sched_action; - } + $("#scheduling_" + this.res + "_actions_table tbody tr.create", context).html(""); + $("#add_scheduling_" + this.res + "_action", context).removeAttr("disabled"); + return sched_action; + } - function _fromJSONtoActionsTable(actions_array, action_id, minus) { - var str = "" + function _fromJSONtoActionsTable(actions_array, action_id, minus) { + var str = ""; - if (!actions_array) { - return ""; - } + if (!actions_array) { + return ""; + } - if (!$.isArray(actions_array)) { - var tmp_array = new Array(); - tmp_array[0] = actions_array; - actions_array = tmp_array; - } + if (!$.isArray(actions_array)) { + var tmp_array = new Array(); + tmp_array[0] = actions_array; + actions_array = tmp_array; + } - if (!actions_array.length) { - return ""; - } + if (!actions_array.length) { + return ""; + } - $.each(actions_array, function (index, scheduling_action) { - str += _fromJSONtoActionRow(scheduling_action, action_id, minus); - }); + $.each(actions_array, function (index, scheduling_action) { + str += _fromJSONtoActionRow(scheduling_action, action_id, minus); + }); - return str; - } + return str; + } - function _fromJSONtoActionRow(scheduling_action, action_id, minus) { - var time_str = Humanize.prettyTime(scheduling_action.TIME); - var rep_str = ""; - var end_str = ""; + function _fromJSONtoActionRow(scheduling_action, action_id, minus) { + var time_str = Humanize.prettyTime(scheduling_action.TIME); + var rep_str = ""; + var end_str = ""; - if (scheduling_action.REP != undefined) { - if ( scheduling_action.REP == 0) { - rep_str = "Weekly "; - } else if ( scheduling_action.REP == 1) { - rep_str = "Monthly "; - } else if ( scheduling_action.REP == 2) { - rep_str = "Yearly "; - } + if (scheduling_action.REP != undefined) { + if (scheduling_action.REP == 0) { + rep_str = "Weekly "; + } else if (scheduling_action.REP == 1) { + rep_str = "Monthly "; + } else if (scheduling_action.REP == 2) { + rep_str = "Yearly "; + } - if ( scheduling_action.REP != 0 ) { - rep_str += scheduling_action.DAYS; - } else { - rep_str += Humanize.week_days(scheduling_action.DAYS); - } - } else { - rep_str = "None" - } + if (scheduling_action.REP != 0) { + rep_str += scheduling_action.DAYS; + } else { + rep_str += Humanize.week_days(scheduling_action.DAYS); + } + } else { + rep_str = "None"; + } - if (scheduling_action.END_TYPE != undefined) { - if ( scheduling_action.END_TYPE == 0) { - end_str = "None"; - } else if ( scheduling_action.END_TYPE == 1) { - end_str = "After " + scheduling_action.END_VALUE + " times"; - } else if ( scheduling_action.END_TYPE == 2) { - end_str = "on " + Humanize.prettyTime(scheduling_action.END_VALUE); - } - } + if (scheduling_action.END_TYPE != undefined) { + if (scheduling_action.END_TYPE == 0) { + end_str = "None"; + } else if (scheduling_action.END_TYPE == 1) { + end_str = "After " + scheduling_action.END_VALUE + " times"; + } else if (scheduling_action.END_TYPE == 2) { + end_str = "on " + Humanize.prettyTime(scheduling_action.END_VALUE); + } + } - var str = ""; - if (action_id == undefined){ - str += ""; - } - str += "" + TemplateUtils.htmlEncode(scheduling_action.ACTION) + "\ + var str = ""; + if (action_id == undefined) { + str += ""; + } + str += "" + TemplateUtils.htmlEncode(scheduling_action.ACTION) + "\ " + time_str + "\ " + rep_str + "\ " + end_str + ""; - if (minus == undefined) { - str += "\ + if (minus == undefined) { + str += "\
\ \
\ \ "; - } + } - return str; - } + return str; + } - function convertDate(date_string){ - date_string = date_string.split('/'); - return date_string[2] + "-" + date_string[1] + "-" + date_string[0]; - } + function convertDate(date_string) { + date_string = date_string.split("/"); + return date_string[2] + "-" + date_string[1] + "-" + date_string[0]; + } - return { - 'fromJSONtoActionRow': _fromJSONtoActionRow, - 'fromJSONtoActionsTable': _fromJSONtoActionsTable, - 'htmlNewAction': _htmlNewAction, - 'setup': _setup, - 'htmlTable': _html, - 'retrieveNewAction': _retrieveNewAction, - 'retrieve': _retrieve - } -}) \ No newline at end of file + return { + "fromJSONtoActionRow": _fromJSONtoActionRow, + "fromJSONtoActionsTable": _fromJSONtoActionsTable, + "htmlNewAction": _htmlNewAction, + "setup": _setup, + "htmlTable": _html, + "retrieveNewAction": _retrieveNewAction, + "retrieve": _retrieve + }; +}); \ No newline at end of file diff --git a/src/sunstone/public/app/utils/schedule_action/html.hbs b/src/sunstone/public/app/utils/schedule_action/html.hbs index 6de2b53fe6..9ba815f9cf 100644 --- a/src/sunstone/public/app/utils/schedule_action/html.hbs +++ b/src/sunstone/public/app/utils/schedule_action/html.hbs @@ -13,61 +13,57 @@ {{! See the License for the specific language governing permissions and }} {{! limitations under the License. }} {{! -------------------------------------------------------------------------- }} - - -
- - -
- - - + - - - - - - - - - + + + + + + + + + + + + + - -
- - - - - - -
- + +
+ + + + + + +
+ - - - + + - -
- - - - - - -
- + +
+ + + + + + +
+ - - + + +
- - - + + + \ No newline at end of file diff --git a/src/sunstone/public/app/utils/schedule_action/table.hbs b/src/sunstone/public/app/utils/schedule_action/table.hbs index b7ec263157..8dc1440a4b 100644 --- a/src/sunstone/public/app/utils/schedule_action/table.hbs +++ b/src/sunstone/public/app/utils/schedule_action/table.hbs @@ -14,16 +14,27 @@ {{! limitations under the License. }} {{! -------------------------------------------------------------------------- }} + + - - - - - - - - - - - + + + + + + + + + + +
{{tr "Action"}} {{tr "Time"}} {{tr "Rep"}} {{tr "End"}} {{tr "Actions"}}
{{tr "Action"}} {{tr "Time"}} {{tr "Rep"}} {{tr "End"}} {{tr "Actions"}} + +
\ No newline at end of file From 5bd6d7d771e06056c71e7ee92fbbe6f728cb1334 Mon Sep 17 00:00:00 2001 From: abelCoronado93 Date: Wed, 28 Feb 2018 16:15:21 +0100 Subject: [PATCH 09/28] Solved bug when add new action --- .../templates-tab/form-panels/create/wizard-tabs/actions.js | 4 ++-- .../public/app/tabs/templates-tab/form-panels/instantiate.js | 3 ++- src/sunstone/public/app/utils/schedule_action.js | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js index d02c9baf5e..7397a99a6e 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js @@ -82,11 +82,11 @@ define(function(require) { context.off("click", "#add_temp_action_json"); context.on("click" , "#add_temp_action_json", function(){ - var sched_action = ScheduleActions.retrieveNewAction(context) + var sched_action = ScheduleActions.retrieveNewAction(context); if (sched_action != false) { $("#sched_temp_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); + $(".create", context).remove(); } - return false; }); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js index 612fd4dda0..5665c03029 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js @@ -132,9 +132,10 @@ define(function(require) { context.off("click", "#add_inst_action_json"); context.on("click" , "#add_inst_action_json", function(){ - var sched_action = ScheduleActions.retrieveNewAction(context) + var sched_action = ScheduleActions.retrieveNewAction(context); if (sched_action != false) { $("#sched_inst_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); + $(".create", context).remove(); } return false; diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index b51b1d0232..1ccbd9c315 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -220,6 +220,7 @@ define(function (require) { $("#scheduling_" + this.res + "_actions_table tbody tr.create", context).html(""); $("#add_scheduling_" + this.res + "_action", context).removeAttr("disabled"); + return sched_action; } From 13a2caa84887b7d91416e510978e10747d201c5c Mon Sep 17 00:00:00 2001 From: juanmont Date: Thu, 1 Mar 2018 09:26:47 +0100 Subject: [PATCH 10/28] F #1548: Fixed bug when try to add new schedule action within vms section --- .../form-panels/create/wizard-tabs/actions.js | 1 - .../templates-tab/form-panels/instantiate.js | 1 - .../public/app/tabs/vms-tab/panels/actions.js | 20 +++++++++++++------ .../public/app/utils/schedule_action.js | 4 ++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js index 7397a99a6e..7b6a125271 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js @@ -85,7 +85,6 @@ define(function(require) { var sched_action = ScheduleActions.retrieveNewAction(context); if (sched_action != false) { $("#sched_temp_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); - $(".create", context).remove(); } return false; }); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js index 5665c03029..71ea539f79 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js @@ -135,7 +135,6 @@ define(function(require) { var sched_action = ScheduleActions.retrieveNewAction(context); if (sched_action != false) { $("#sched_inst_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); - $(".create", context).remove(); } return false; diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js index ba912e3e7d..7e1584fba8 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js @@ -63,7 +63,7 @@ define(function(require) { var that = this; var html = '
\
\ - \ +
\ \ \ \ @@ -76,9 +76,11 @@ define(function(require) { \ \ \ - ' + + \ + '+ vmsfromJSONtoActionsTable(that.element.USER_TEMPLATE.SCHED_ACTION) + - '
' + Locale.tr("ID") + '' + Locale.tr("Actions") + '
\ + '\ + \
\
'; @@ -97,8 +99,14 @@ define(function(require) { return false; }); - context.off("click", "#submit_scheduling_action"); - context.on("click", "#submit_scheduling_action", function() { + context.off("click", "#add_vms_action_json"); + context.on("click" , "#add_vms_action_json", function(){ + var sched_action = ScheduleActions.retrieveNewAction(context); + if (sched_action != false) { + $("#sched_vms_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); + } else { + return false; + } that.element.USER_TEMPLATE.SCHED_ACTION = ScheduleActions.retrieve(context); @@ -106,7 +114,7 @@ define(function(require) { var template_str = TemplateUtils.templateToString(that.element.USER_TEMPLATE); Sunstone.runAction("VM.update_template", that.element.ID, template_str); - $("#add_schedulingvms_action", context).removeAttr("disabled"); + $("#add_scheduling_vms_action", context).removeAttr("disabled"); return false; }); diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index 1ccbd9c315..13efda7ea2 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -39,7 +39,7 @@ define(function (require) { options += ""; } }); - $("#scheduling_" + this.res + "_actions_table", context).append(TemplateHTML({ + $("#scheduling_" + this.res + "_actions_table tbody", context).append(TemplateHTML({ "actions": options, "res": that.res })); @@ -218,7 +218,7 @@ define(function (require) { sched_action.END_TYPE = end_type; sched_action.END_VALUE = end_value; - $("#scheduling_" + this.res + "_actions_table tbody tr.create", context).html(""); + $("#scheduling_" + this.res + "_actions_table .create", context).remove(); $("#add_scheduling_" + this.res + "_action", context).removeAttr("disabled"); return sched_action; From 6aefef0638b5c6dec91de4a0f413ebe087db2d25 Mon Sep 17 00:00:00 2001 From: abelCoronado93 Date: Thu, 1 Mar 2018 10:20:37 +0100 Subject: [PATCH 11/28] F #1548: Don't send periodic attrs if it's not checked --- src/sunstone/public/app/addons.js | 3 +++ src/sunstone/public/app/addons/opennebula/invoices.js | 1 + src/sunstone/public/app/addons/opennebula/payments.js | 1 + .../public/app/addons/tabs/billing-top-tab.js | 1 + src/sunstone/public/app/addons/tabs/invoices-tab | 1 + src/sunstone/public/app/addons/tabs/invoices-tab.js | 1 + src/sunstone/public/app/addons/tabs/payments-tab | 1 + src/sunstone/public/app/addons/tabs/payments-tab.js | 1 + src/sunstone/public/app/addons/tabs/utils | 1 + src/sunstone/public/app/utils/schedule_action.js | 11 ++++++----- 10 files changed, 17 insertions(+), 5 deletions(-) create mode 120000 src/sunstone/public/app/addons/opennebula/invoices.js create mode 120000 src/sunstone/public/app/addons/opennebula/payments.js create mode 120000 src/sunstone/public/app/addons/tabs/billing-top-tab.js create mode 120000 src/sunstone/public/app/addons/tabs/invoices-tab create mode 120000 src/sunstone/public/app/addons/tabs/invoices-tab.js create mode 120000 src/sunstone/public/app/addons/tabs/payments-tab create mode 120000 src/sunstone/public/app/addons/tabs/payments-tab.js create mode 120000 src/sunstone/public/app/addons/tabs/utils diff --git a/src/sunstone/public/app/addons.js b/src/sunstone/public/app/addons.js index 7f1c0fe369..ea0f2ad878 100644 --- a/src/sunstone/public/app/addons.js +++ b/src/sunstone/public/app/addons.js @@ -1,5 +1,8 @@ siteMap = { addons: [ + "billing-top-tab", + "payments-tab", + "invoices-tab" ] }; diff --git a/src/sunstone/public/app/addons/opennebula/invoices.js b/src/sunstone/public/app/addons/opennebula/invoices.js new file mode 120000 index 0000000000..d673bb0c14 --- /dev/null +++ b/src/sunstone/public/app/addons/opennebula/invoices.js @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/opennebula/invoices.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/opennebula/payments.js b/src/sunstone/public/app/addons/opennebula/payments.js new file mode 120000 index 0000000000..f5e5e5e8f5 --- /dev/null +++ b/src/sunstone/public/app/addons/opennebula/payments.js @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/opennebula/payments.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/billing-top-tab.js b/src/sunstone/public/app/addons/tabs/billing-top-tab.js new file mode 120000 index 0000000000..eb378623d8 --- /dev/null +++ b/src/sunstone/public/app/addons/tabs/billing-top-tab.js @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/billing-top-tab.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/invoices-tab b/src/sunstone/public/app/addons/tabs/invoices-tab new file mode 120000 index 0000000000..1e95fd6ce7 --- /dev/null +++ b/src/sunstone/public/app/addons/tabs/invoices-tab @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/invoices-tab \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/invoices-tab.js b/src/sunstone/public/app/addons/tabs/invoices-tab.js new file mode 120000 index 0000000000..8f10035eb8 --- /dev/null +++ b/src/sunstone/public/app/addons/tabs/invoices-tab.js @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/invoices-tab.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/payments-tab b/src/sunstone/public/app/addons/tabs/payments-tab new file mode 120000 index 0000000000..6fda1092ce --- /dev/null +++ b/src/sunstone/public/app/addons/tabs/payments-tab @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/payments-tab \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/payments-tab.js b/src/sunstone/public/app/addons/tabs/payments-tab.js new file mode 120000 index 0000000000..8af77f41ee --- /dev/null +++ b/src/sunstone/public/app/addons/tabs/payments-tab.js @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/payments-tab.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/utils b/src/sunstone/public/app/addons/tabs/utils new file mode 120000 index 0000000000..209db0a203 --- /dev/null +++ b/src/sunstone/public/app/addons/tabs/utils @@ -0,0 +1 @@ +/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/utils \ No newline at end of file diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index 13efda7ea2..2c151e121a 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -159,6 +159,7 @@ define(function (require) { var end_type = 1; var days = ""; var end_value = 1; + var sched_action = {}; if (time_input_value == "" || date_input_value == "") { return false; @@ -204,19 +205,19 @@ define(function (require) { return false; } } + + sched_action.DAYS = days; + sched_action.REP = rep; + sched_action.END_TYPE = end_type; + sched_action.END_VALUE = end_value; } var time_value = date_input_value + " " + time_input_value; var epoch_str = new Date(time_value); var time = parseInt(epoch_str.getTime()) / 1000; - var sched_action = {}; sched_action.ACTION = new_action; sched_action.TIME = time; - sched_action.DAYS = days; - sched_action.REP = rep; - sched_action.END_TYPE = end_type; - sched_action.END_VALUE = end_value; $("#scheduling_" + this.res + "_actions_table .create", context).remove(); $("#add_scheduling_" + this.res + "_action", context).removeAttr("disabled"); From 6a9be099ed94919d3cd95edcb8d3283e15983116 Mon Sep 17 00:00:00 2001 From: juanmont Date: Thu, 1 Mar 2018 10:19:23 +0100 Subject: [PATCH 12/28] F #1548: Fixed bug with multiple tables --- .../templates-tab/form-panels/create/wizard-tabs/actions.js | 2 +- .../public/app/tabs/templates-tab/form-panels/instantiate.js | 2 +- src/sunstone/public/app/tabs/vms-tab/panels/actions.js | 2 +- src/sunstone/public/app/utils/schedule_action.js | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js index 7b6a125271..fc1abf8e45 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/actions.js @@ -75,7 +75,7 @@ define(function(require) { context.off('click', '#add_scheduling_temp_action'); context.on('click', '#add_scheduling_temp_action', function() { $("#add_scheduling_temp_action", context).attr("disabled", "disabled"); - ScheduleActions.htmlNewAction(actions, context); + ScheduleActions.htmlNewAction(actions, context, "temp"); ScheduleActions.setup(context) return false; }); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js index 71ea539f79..c728623aeb 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js @@ -125,7 +125,7 @@ define(function(require) { context.on('click', '#add_scheduling_inst_action', function() { var actions = ["terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume", "reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard", "snapshot-create"]; $("#add_scheduling_inst_action", context).attr("disabled", "disabled"); - ScheduleActions.htmlNewAction(actions, context); + ScheduleActions.htmlNewAction(actions, context, "inst"); ScheduleActions.setup(context) return false; }); diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js index 7e1584fba8..0c1cab7dca 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js @@ -94,7 +94,7 @@ define(function(require) { context.off('click', '#add_scheduling_vms_action'); context.on('click', '#add_scheduling_vms_action', function() { $("#add_scheduling_vms_action", context).attr("disabled", "disabled"); - ScheduleActions.htmlNewAction(actions, context); + ScheduleActions.htmlNewAction(actions, context, "vms"); ScheduleActions.setup(context) return false; }); diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index 2c151e121a..b71daa33e0 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -30,7 +30,7 @@ define(function (require) { }); } - function _htmlNewAction(actions, context) { + function _htmlNewAction(actions, context, res) { var options = ""; var that = this; $.each(actions, function (key, action) { @@ -39,7 +39,7 @@ define(function (require) { options += ""; } }); - $("#scheduling_" + this.res + "_actions_table tbody", context).append(TemplateHTML({ + $("#scheduling_" + res + "_actions_table tbody", context).append(TemplateHTML({ "actions": options, "res": that.res })); From aedee51e67f4ead9b88a160eb9df2a7c31db3270 Mon Sep 17 00:00:00 2001 From: juanmont Date: Thu, 1 Mar 2018 10:23:46 +0100 Subject: [PATCH 13/28] F #1548: Added options to manage relative actions from CLI --- src/cli/one_helper/onevm_helper.rb | 56 +++++++++++++++++++++++++++++- src/cli/onevm | 20 +++++------ 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index 6969dd6db0..b2cdedc14c 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -114,6 +114,37 @@ class OneVMHelper < OpenNebulaHelper::OneHelper :format => Time } + WEEKLY = { + :name => "weekly", + :large => "--weekly days", + :description => "Schedules this action to be executed after" \ + "the given time. For example: onevm resume 0 --schedule \"09/23 14:15\"", + :format => String + } + + MONTHLY = { + :name => "monthly", + :large => "--monthly days", + :description => "Schedules this action to be executed after" \ + "the given time. For example: onevm resume 0 --schedule \"09/23 14:15\"", + :format => String + } + + YEARLY = { + :name => "yearly", + :large => "--yearly days", + :description => "Schedules this action to be executed after" \ + "the given time. For example: onevm resume 0 --schedule \"09/23 14:15\"", + :format => String + } + + END_TIME = { + :name => "end", + :large => "--end number|TIME", + :description => "----", + :format => String + } + ALL_TEMPLATE = { :name => "all", :large => "--all", @@ -314,6 +345,29 @@ class OneVMHelper < OpenNebulaHelper::OneHelper ids, options, "#{action} scheduled at #{options[:schedule]}") do |vm| + str_periodic = "" + + if options.key?(:weekly) + str_periodic << ", REP = 0, DAYS = \"#{options[:weekly]}\"" + elsif options.key?(:monthly) + str_periodic << ", REP = 1, DAYS = \"#{options[:monthly]}\"" + elsif options.key?(:yearly) + str_periodic << ", REP = 2, DAYS = \"#{options[:yearly]}\"" + end + + if options.key?(:end) + begin + end_date = Date.parse(options[:end]) + str_periodic << ", END_TYPE = 2, END_VALUE = #{end_date.to_time.to_i}" + rescue ArgumentError + if options[:end].to_i > 0 + str_periodic << ", END_TYPE = 1, END_VALUE = #{options[:end].to_i}" + end + end + elsif str_periodic != "" + str_periodic << ", END_TYPE = 0" + end + rc = vm.info if OpenNebula.is_error?(rc) @@ -331,7 +385,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper tmp_str = vm.user_template_str - tmp_str << "\nSCHED_ACTION = [ID = #{id}, ACTION = #{action}, TIME = #{options[:schedule].to_i}]" + tmp_str << "\nSCHED_ACTION = [ID = #{id}, ACTION = #{action}, TIME = #{options[:schedule].to_i}" << str_periodic << "]" vm.update(tmp_str) end diff --git a/src/cli/onevm b/src/cli/onevm index d6b52b8576..51764a8b0f 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -316,7 +316,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :hold, hold_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -333,7 +333,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :release, release_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -391,7 +391,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :terminate, terminate_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='terminate' command_name<<'-hard' if options[:hard] @@ -414,7 +414,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :undeploy, undeploy_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='undeploy' command_name<<'-hard' if options[:hard] @@ -436,7 +436,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :poweroff, poweroff_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='poweroff' command_name<<'-hard' if options[:hard] @@ -460,7 +460,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :reboot, reboot_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='reboot' command_name<<'-hard' if options[:hard] @@ -525,7 +525,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :stop, stop_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -545,7 +545,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :suspend, suspend_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -562,7 +562,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :resume, resume_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -804,7 +804,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :"snapshot-create", snapshot_create_desc, [:range,:vmid_list], - [:name, nil], :options => [OneVMHelper::SCHEDULE] do + [:name, nil], :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) From 442d347e020b432bce5d3dcb94c53c4582fc373c Mon Sep 17 00:00:00 2001 From: juanmont Date: Thu, 1 Mar 2018 11:03:44 +0100 Subject: [PATCH 14/28] F #1548: Added new attribute to table --- src/cli/one_helper.rb | 24 ++++++++++++++++++++---- src/cli/one_helper/onevm_helper.rb | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index 9b786703b7..aecb22a4d1 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -814,15 +814,31 @@ EOT end end - def OpenNebulaHelper.time_to_str(time, print_seconds=true) + def OpenNebulaHelper.time_to_str(time, print_seconds=true, print_hours=true, print_years=false) value=time.to_i if value==0 value='-' else - if print_seconds - value=Time.at(value).strftime("%m/%d %H:%M:%S") + if print_hours + if print_seconds + if print_years + value=Time.at(value).strftime("%m/%d/%y %H:%M:%S") + else + value=Time.at(value).strftime("%m/%d %H:%M:%S") + end + else + if print_years + value=Time.at(value).strftime("%m/%d/%y %H:%M") + else + value=Time.at(value).strftime("%m/%d %H:%M") + end + end else - value=Time.at(value).strftime("%m/%d %H:%M") + if print_years + value=Time.at(value).strftime("%m/%d/%y") + else + value=Time.at(value).strftime("%m/%d") + end end end diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index b2cdedc14c..f13486c28e 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -1052,6 +1052,35 @@ in the frontend machine. OpenNebulaHelper.time_to_str(d["TIME"], false) if !d.nil? end + column :"REP", "", :size=>20 do |d| + str_rep = "" + if !d.nil? && d.key?("REP") + if d["REP"] == "0" + str_rep << "Weekly " + elsif d["REP"] == "1" + str_rep << "Monthly " + elsif d["REP"] == "2" + str_rep << "Yearly " + end + str_rep << d["DAYS"] + end + str_rep if !d.nil? + end + + column :"END", "", :size=>20 do |d| + str_end = "" + if !d.nil? && d.key?("END_TYPE") + if d["END_TYPE"] == "0" + str_end << "None" + elsif d["END_TYPE"] == "1" + str_end << "After " << d["END_VALUE"] << " times" + elsif d["END_TYPE"] == "2" + str_end << "On " << OpenNebulaHelper.time_to_str(d["END_VALUE"], false, false, true) + end + end + str_end if !d.nil? + end + column :"DONE", "", :size=>12 do |d| OpenNebulaHelper.time_to_str(d["DONE"], false) if !d.nil? end From a2824e02b2e45aae9e368bdcb0d2d2068affbaaf Mon Sep 17 00:00:00 2001 From: abelCoronado93 Date: Thu, 1 Mar 2018 12:36:34 +0100 Subject: [PATCH 15/28] Highlight the diff between periodic action and not --- src/sunstone/public/app/utils/schedule_action.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index b71daa33e0..e39f93d171 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -268,8 +268,6 @@ define(function (require) { } else { rep_str += Humanize.week_days(scheduling_action.DAYS); } - } else { - rep_str = "None"; } if (scheduling_action.END_TYPE != undefined) { From ca7b23f9d120e1035eba66d2001d93d6f3d33faf Mon Sep 17 00:00:00 2001 From: abelCoronado93 Date: Thu, 1 Mar 2018 13:25:58 +0100 Subject: [PATCH 16/28] F #1548: Deleted addons --- src/sunstone/public/app/addons.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sunstone/public/app/addons.js b/src/sunstone/public/app/addons.js index ea0f2ad878..7f1c0fe369 100644 --- a/src/sunstone/public/app/addons.js +++ b/src/sunstone/public/app/addons.js @@ -1,8 +1,5 @@ siteMap = { addons: [ - "billing-top-tab", - "payments-tab", - "invoices-tab" ] }; From 701e40620405075bc79ca99a22ad7a9418ded2a4 Mon Sep 17 00:00:00 2001 From: juanmont Date: Thu, 1 Mar 2018 13:33:14 +0100 Subject: [PATCH 17/28] F #1548: Removed unnecesary files --- src/sunstone/public/app/addons/opennebula/invoices.js | 1 - src/sunstone/public/app/addons/opennebula/payments.js | 1 - src/sunstone/public/app/addons/tabs/billing-top-tab.js | 1 - src/sunstone/public/app/addons/tabs/invoices-tab | 1 - src/sunstone/public/app/addons/tabs/invoices-tab.js | 1 - src/sunstone/public/app/addons/tabs/payments-tab | 1 - src/sunstone/public/app/addons/tabs/payments-tab.js | 1 - src/sunstone/public/app/addons/tabs/utils | 1 - 8 files changed, 8 deletions(-) delete mode 120000 src/sunstone/public/app/addons/opennebula/invoices.js delete mode 120000 src/sunstone/public/app/addons/opennebula/payments.js delete mode 120000 src/sunstone/public/app/addons/tabs/billing-top-tab.js delete mode 120000 src/sunstone/public/app/addons/tabs/invoices-tab delete mode 120000 src/sunstone/public/app/addons/tabs/invoices-tab.js delete mode 120000 src/sunstone/public/app/addons/tabs/payments-tab delete mode 120000 src/sunstone/public/app/addons/tabs/payments-tab.js delete mode 120000 src/sunstone/public/app/addons/tabs/utils diff --git a/src/sunstone/public/app/addons/opennebula/invoices.js b/src/sunstone/public/app/addons/opennebula/invoices.js deleted file mode 120000 index d673bb0c14..0000000000 --- a/src/sunstone/public/app/addons/opennebula/invoices.js +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/opennebula/invoices.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/opennebula/payments.js b/src/sunstone/public/app/addons/opennebula/payments.js deleted file mode 120000 index f5e5e5e8f5..0000000000 --- a/src/sunstone/public/app/addons/opennebula/payments.js +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/opennebula/payments.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/billing-top-tab.js b/src/sunstone/public/app/addons/tabs/billing-top-tab.js deleted file mode 120000 index eb378623d8..0000000000 --- a/src/sunstone/public/app/addons/tabs/billing-top-tab.js +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/billing-top-tab.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/invoices-tab b/src/sunstone/public/app/addons/tabs/invoices-tab deleted file mode 120000 index 1e95fd6ce7..0000000000 --- a/src/sunstone/public/app/addons/tabs/invoices-tab +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/invoices-tab \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/invoices-tab.js b/src/sunstone/public/app/addons/tabs/invoices-tab.js deleted file mode 120000 index 8f10035eb8..0000000000 --- a/src/sunstone/public/app/addons/tabs/invoices-tab.js +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/invoices-tab.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/payments-tab b/src/sunstone/public/app/addons/tabs/payments-tab deleted file mode 120000 index 6fda1092ce..0000000000 --- a/src/sunstone/public/app/addons/tabs/payments-tab +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/payments-tab \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/payments-tab.js b/src/sunstone/public/app/addons/tabs/payments-tab.js deleted file mode 120000 index 8af77f41ee..0000000000 --- a/src/sunstone/public/app/addons/tabs/payments-tab.js +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/payments-tab.js \ No newline at end of file diff --git a/src/sunstone/public/app/addons/tabs/utils b/src/sunstone/public/app/addons/tabs/utils deleted file mode 120000 index 209db0a203..0000000000 --- a/src/sunstone/public/app/addons/tabs/utils +++ /dev/null @@ -1 +0,0 @@ -/home/opennebula/Desktop/billing/src/sunstone/public/app/addons/tabs/utils \ No newline at end of file From 08539c1db617ad929911756650f8920bbc47d733 Mon Sep 17 00:00:00 2001 From: juanmont Date: Thu, 1 Mar 2018 15:19:42 +0100 Subject: [PATCH 18/28] F #1548: Resolved some bugs --- src/scheduler/src/pool/VirtualMachineXML.cc | 5 +++++ src/sunstone/public/app/tabs/vms-tab/panels/actions.js | 1 + 2 files changed, 6 insertions(+) diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 7fabbc549a..5493af0d58 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -517,6 +517,11 @@ static void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor next->tm_mday = next->tm_mday + (mayor_day - comparative); } } + if (next->tm_mday > m_months_days[next->tm_mon]) + { + next->tm_mday = next->tm_mday - m_months_days[next->tm_mon]; + next->tm_mon++; + } } /* -------------------------------------------------------------------------- */ diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js index 0c1cab7dca..e6a1a21662 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/actions.js @@ -103,6 +103,7 @@ define(function(require) { context.on("click" , "#add_vms_action_json", function(){ var sched_action = ScheduleActions.retrieveNewAction(context); if (sched_action != false) { + $("#no_actions_tr", context).remove(); $("#sched_vms_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action)); } else { return false; From e68b218a55f3b8da9b061e79d1e25ccf7031065d Mon Sep 17 00:00:00 2001 From: juanmont Date: Fri, 2 Mar 2018 12:06:58 +0100 Subject: [PATCH 19/28] F #1548: remodeling the Suntone view --- .../public/app/utils/schedule_action.js | 37 ++++--- .../public/app/utils/schedule_action/html.hbs | 98 ++++++++++++------- .../app/utils/schedule_action/table.hbs | 10 +- 3 files changed, 90 insertions(+), 55 deletions(-) diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index e39f93d171..f0a2e3e5fc 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -19,6 +19,7 @@ define(function (require) { var Locale = require("utils/locale"); var Humanize = require("utils/humanize"); var TemplateUtils = require("utils/template-utils"); + var Tips = require('utils/tips'); var TemplateHTML = require("hbs!./schedule_action/html"); var TemplateTableHTML = require("hbs!./schedule_action/table"); @@ -43,6 +44,12 @@ define(function (require) { "actions": options, "res": that.res })); + + if (res === "vms"){ + $("#title", context).prop("colspan", "2"); + $("#td_days", context).prop("colspan", "5"); + + } } function _setup(context) { @@ -74,30 +81,33 @@ define(function (require) { } }); var that = this; - $("input[name='rep']", context).change(function () { + $("select[name='rep']", context).change(function () { var value = $(this).val(); that.rep = value; var input_html = ""; switch (value) { case "week": - input_html = "
\ - \ - \ - \ - \ - \ - \ - \ + input_html = "
\ + \ + \ + \ + \ + \ + \ + \
"; break; case "month": - input_html = ""; + input_html = "
\ + "+Locale.tr("Comma separated list of days of the month to repeat the action on. Ex: 1,15,25 repeats the action every first, 15th and 25th day of the month")+"
"; break; case "year": - input_html = ""; + input_html = "
\ + "+Locale.tr("Comma separated list of days of the year to repeat the action on. Ex: 1,30,330 repeats the action every first, 30th and 330th day of the year")+"
"; break; } $("#td_days").html(input_html); + Tips.setup(context); }); $("input[name='end_type']", context).change(function () { @@ -105,13 +115,12 @@ define(function (require) { that.end_type = value; var input_html = ""; var min; + $(".end_input", context).prop('disabled', true); switch (value) { case "n_rep": - input_html = ""; min = 1; break; case "date": - input_html = ""; var today = new Date(); var dd = today.getDate(); var mm = today.getMonth() + 1; @@ -125,8 +134,8 @@ define(function (require) { min = yyyy + "-" + mm + "-" + dd; break; } - $("#td_end_value", context).html(input_html); $("#end_value_" + value, context).attr("min", min); + $("#end_value_" + value, context).prop('disabled', false); }); context.on("focusout", "#time_input", function () { diff --git a/src/sunstone/public/app/utils/schedule_action/html.hbs b/src/sunstone/public/app/utils/schedule_action/html.hbs index 9ba815f9cf..7f0e286211 100644 --- a/src/sunstone/public/app/utils/schedule_action/html.hbs +++ b/src/sunstone/public/app/utils/schedule_action/html.hbs @@ -1,19 +1,16 @@ -{{! -------------------------------------------------------------------------- }} -{{! Copyright 2002-2018, 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. }} -{{! -------------------------------------------------------------------------- }} +{{! -------------------------------------------------------------------------- }} {{! Copyright 2002-2018, 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. }} {{! -------------------------------------------------------------------------- +}} + + +
{{tr "New scheduled action"}}:
+ + @@ -25,40 +22,71 @@ - + - -
- - - - - - + + + + + + + +
+ + + + + + + + + + + + + +
- + + + + + + + + + - -
- - - - - - -
+ + + + + + - + + + + + + + + +
diff --git a/src/sunstone/public/app/utils/schedule_action/table.hbs b/src/sunstone/public/app/utils/schedule_action/table.hbs index 8dc1440a4b..87b0051030 100644 --- a/src/sunstone/public/app/utils/schedule_action/table.hbs +++ b/src/sunstone/public/app/utils/schedule_action/table.hbs @@ -15,11 +15,9 @@ {{! -------------------------------------------------------------------------- }} @@ -29,7 +27,7 @@ {{tr "Action"}} {{tr "Time"}} {{tr "Rep"}} - {{tr "End"}} + {{tr "Ends"}} {{tr "Actions"}} From 10a516803ec54cd92e483cb0b64fe4ea090a9cc7 Mon Sep 17 00:00:00 2001 From: juanmont Date: Fri, 2 Mar 2018 14:59:27 +0100 Subject: [PATCH 20/28] F #1548: Added possibility to schedule action by hours --- src/cli/one_helper/onevm_helper.rb | 16 ++++- src/cli/onevm | 20 +++--- src/scheduler/src/pool/VirtualMachineXML.cc | 77 ++++++++++++++------- src/vm_template/VMTemplate.cc | 5 ++ 4 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index f13486c28e..73573ffacc 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -138,6 +138,14 @@ class OneVMHelper < OpenNebulaHelper::OneHelper :format => String } + HOURLY = { + :name => "hourly", + :large => "--hourly hour", + :description => "Schedules this action to be executed after" \ + "the given time. For example: onevm resume 0 --schedule \"09/23 14:15\"", + :format => Numeric + } + END_TIME = { :name => "end", :large => "--end number|TIME", @@ -353,6 +361,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper str_periodic << ", REP = 1, DAYS = \"#{options[:monthly]}\"" elsif options.key?(:yearly) str_periodic << ", REP = 2, DAYS = \"#{options[:yearly]}\"" + elsif options.key?(:hourly) + str_periodic << ", REP = 3, DAYS = \"#{options[:hourly].to_s}\"" end if options.key?(:end) @@ -1061,8 +1071,12 @@ in the frontend machine. str_rep << "Monthly " elsif d["REP"] == "2" str_rep << "Yearly " + elsif d["REP"] == "3" + str_rep << "Each " << d['DAYS'] << " hours" + end + if d["REP"] != "3" + str_rep << d["DAYS"] end - str_rep << d["DAYS"] end str_rep if !d.nil? end diff --git a/src/cli/onevm b/src/cli/onevm index 51764a8b0f..66bcc38bab 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -316,7 +316,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :hold, hold_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -333,7 +333,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :release, release_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -391,7 +391,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :terminate, terminate_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='terminate' command_name<<'-hard' if options[:hard] @@ -414,7 +414,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :undeploy, undeploy_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='undeploy' command_name<<'-hard' if options[:hard] @@ -436,7 +436,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :poweroff, poweroff_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='poweroff' command_name<<'-hard' if options[:hard] @@ -460,7 +460,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :reboot, reboot_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME, OneVMHelper::HARD] do command_name='reboot' command_name<<'-hard' if options[:hard] @@ -525,7 +525,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :stop, stop_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -545,7 +545,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :suspend, suspend_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -562,7 +562,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :resume, resume_desc, [:range,:vmid_list], - :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do + :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) else @@ -804,7 +804,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :"snapshot-create", snapshot_create_desc, [:range,:vmid_list], - [:name, nil], :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::END_TIME] do + [:name, nil], :options => [OneVMHelper::SCHEDULE, OneVMHelper::WEEKLY, OneVMHelper::MONTHLY, OneVMHelper::YEARLY, OneVMHelper::HOURLY, OneVMHelper::END_TIME] do if (!options[:schedule].nil?) helper.schedule_actions(args[0], options, @comm_name) diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 5493af0d58..9ac6283fb6 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -505,6 +505,22 @@ bool VirtualMachineXML::is_only_public_cloud() const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static void check_months(struct tm * next){ + int days_month = m_months_days[next->tm_mon]; + if(next->tm_year+1900 % 4 == 0 && (next->tm_year+1900 % 100 != 0 || next->tm_year+1900 % 400 == 0) && next->tm_mon == 1) + { + days_month++; + } + if (next->tm_mday > days_month) + { + next->tm_mday = next->tm_mday - m_months_days[next->tm_mon]; + next->tm_mon++; + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + static void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor_day, int max_day, int comparative){ if (mayor_day >= 0 && minor_day < max_day) { @@ -517,11 +533,7 @@ static void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor next->tm_mday = next->tm_mday + (mayor_day - comparative); } } - if (next->tm_mday > m_months_days[next->tm_mon]) - { - next->tm_mday = next->tm_mday - m_months_days[next->tm_mon]; - next->tm_mon++; - } + check_months(next); } /* -------------------------------------------------------------------------- */ @@ -595,32 +607,34 @@ int VirtualMachineXML::next_action(VectorAttribute& vatt) } std::set::iterator it; std::pair::iterator,bool> ret; - - it = s_days.begin(); - minor_day = *it; - - ret = s_days.insert(start_day); - if ( ret.second == false ) + if (rep_mode != 3) { - mayor_day = *ret.first; + it = s_days.begin(); + minor_day = *it; - if ( ++ret.first != s_days.end() ) + ret = s_days.insert(start_day); + if ( ret.second == false ) { mayor_day = *ret.first; + + if ( ++ret.first != s_days.end() ) + { + mayor_day = *ret.first; + } } - } - else - { - mayor_day = minor_day; - if ( ++ret.first != s_days.end() ) + else { - mayor_day = *ret.first; - } - it = s_days.find(start_day); - s_days.erase (it); - if (*--it > mayor_day) - { - mayor_day = *it; + mayor_day = minor_day; + if ( ++ret.first != s_days.end() ) + { + mayor_day = *ret.first; + } + it = s_days.find(start_day); + s_days.erase (it); + if (*--it > mayor_day) + { + mayor_day = *it; + } } } @@ -645,7 +659,18 @@ int VirtualMachineXML::next_action(VectorAttribute& vatt) } } - generate_next_day(rep_mode, mayor_day, minor_day, &next, &start_tm); + if (rep_mode == 3) + { + it = s_days.begin(); + int hours = *it; + next.tm_min = start_tm.tm_min; + next.tm_hour = start_tm.tm_hour + hours; + check_months(&next); + } + else + { + generate_next_day(rep_mode, mayor_day, minor_day, &next, &start_tm); + } action_time = mktime (&next); if (action_time != -1) { diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc index 1d1e62f26f..b0256ea100 100644 --- a/src/vm_template/VMTemplate.cc +++ b/src/vm_template/VMTemplate.cc @@ -225,6 +225,11 @@ int VMTemplate::parse_sched_action(string& error_str) error_str = "Error parsing days of the year. [0,365]"; return -1; } + else if (rep_mode == 3 && (first_day != last_day || s_days.size() > 1)) //YEAR [0,365] + { + error_str = "Error parsing hour."; + return -1; + } } has_end_mode = vatt->vector_value("END_TYPE", end_mode); From 9cace59933f9c07dc5e30813c29dba8642689726 Mon Sep 17 00:00:00 2001 From: juanmont Date: Fri, 2 Mar 2018 16:42:00 +0100 Subject: [PATCH 21/28] F #1548: Added new functionality of hours in Sunstone --- .../public/app/utils/schedule_action.js | 28 +++++++++++++++---- .../public/app/utils/schedule_action/html.hbs | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index f0a2e3e5fc..775a8b776d 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -81,6 +81,8 @@ define(function (require) { } }); var that = this; + this.rep = "week"; + this.end_type = "never"; $("select[name='rep']", context).change(function () { var value = $(this).val(); that.rep = value; @@ -105,6 +107,13 @@ define(function (require) { input_html = "
\ "+Locale.tr("Comma separated list of days of the year to repeat the action on. Ex: 1,30,330 repeats the action every first, 30th and 330th day of the year")+"
"; break; + case "hour": + input_html = "
\ + \ + \ + \ +
"; + break; } $("#td_days").html(input_html); Tips.setup(context); @@ -188,16 +197,19 @@ define(function (require) { } else if (this.rep == "month") { rep = 1; days = $("#days_month_value", context).val(); - } else { + } else if (this.rep == "year"){ rep = 2; days = $("#days_year_value", context).val(); + } else { + rep = 3; + days = $("#days_hour_value", context).val(); } if (days == "") { return false; } - if (this.end_type == "ever") { + if (this.end_type == "never") { end_type = 0; } else if (this.end_type == "n_rep") { end_value = $("#end_value_n_rep", context).val(); @@ -270,12 +282,16 @@ define(function (require) { rep_str = "Monthly "; } else if (scheduling_action.REP == 2) { rep_str = "Yearly "; + } else if (scheduling_action.REP == 3) { + rep_str = "Each " + scheduling_action.DAYS + " hours"; } - if (scheduling_action.REP != 0) { - rep_str += scheduling_action.DAYS; - } else { - rep_str += Humanize.week_days(scheduling_action.DAYS); + if (scheduling_action.REP != 3) { + if (scheduling_action.REP != 0) { + rep_str += scheduling_action.DAYS; + } else { + rep_str += Humanize.week_days(scheduling_action.DAYS); + } } } diff --git a/src/sunstone/public/app/utils/schedule_action/html.hbs b/src/sunstone/public/app/utils/schedule_action/html.hbs index 7f0e286211..48e353a3f3 100644 --- a/src/sunstone/public/app/utils/schedule_action/html.hbs +++ b/src/sunstone/public/app/utils/schedule_action/html.hbs @@ -35,6 +35,7 @@ the License for the specific language governing permissions and }} {{! limitatio + From 6e48575a1a5757bf4b960b42989be432e74a0284 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 7 May 2018 00:54:47 +0200 Subject: [PATCH 22/28] F #1548: SchedAction logic moved to its own class --- include/ScheduledAction.h | 193 ++++++++ src/scheduler/src/pool/VirtualMachineXML.cc | 181 +------- src/scheduler/src/sched/SConstruct | 1 + src/vm_template/SConstruct | 3 +- src/vm_template/ScheduledAction.cc | 471 ++++++++++++++++++++ src/vm_template/VMTemplate.cc | 92 +--- 6 files changed, 677 insertions(+), 264 deletions(-) create mode 100644 include/ScheduledAction.h create mode 100644 src/vm_template/ScheduledAction.cc diff --git a/include/ScheduledAction.h b/include/ScheduledAction.h new file mode 100644 index 0000000000..132c2278c5 --- /dev/null +++ b/include/ScheduledAction.h @@ -0,0 +1,193 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2018, 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 SCHED_ACTION_ATTRIBUTE_H_ +#define SCHED_ACTION_ATTRIBUTE_H_ + +#include + +#include "VirtualMachineAttribute.h" + +/** + * The VirtualMachine SCHED_ACTION attribute + */ +class SchedAction: public VirtualMachineAttribute +{ +public: + enum Repeat + { + NONE = -1, + WEEKLY = 0, + MONTHLY = 1, + YEARLY = 2, + HOURLY = 3 + }; + + enum EndOn + { + END_NONE = -1, + TIMES = 1, + DATE = 2 + }; + + SchedAction(VectorAttribute *va, int id):VirtualMachineAttribute(va, id){}; + + virtual ~SchedAction(){}; + + /** + * Returns the REPEAT value of the SCHED_ACTION + * @param r repeat WEEKLY, MONTHLY, YEARLY or HOURLY + * @return -1 if REPEAT not found or in wrong format 0 on success + */ + int repeat(Repeat& r); + + /** + * Returns the END_TYPE value of the SCHED_ACTION + * @param eo ends on TIMES WEEKLY, MONTHLY, YEARLY or HOURLY + * @return -1 if REPEAT not found or in wrong format 0 on success + */ + int endon(EndOn& eo); + + /** + * Parse the DAYS attribute of the sched action + * @param d set of days (unique) + * @return -1 if not found (d will be empty) 0 otherwise + */ + int days(std::set& _d); + + /** + * This function checks that the DAYS attributes are in range + * according to the Repeat value: + * @param r repeat type (hourly, weekly...) + * @param error in case of error + * + * @return true if days are in range false (error) if not + */ + bool days_in_range(Repeat r, std::string& error); + + /** + * This function checks that END_VALUE is properly defined for the + * associated END_TYPE + * @param eo end type (date, times) + * @param error in case of error + * + * @return true if days are in range false (error) if not + */ + bool ends_in_range(EndOn eo, std::string& error); + + /** + * This function parse and checks the sched action attributes: REPEAT, DAYS + * , END_TYPE, END_DATE. It also removed DONE and MESSAGE. + * @param error + * @return 0 if success -1 otherwise + */ + int parse(std::string& error); + + /** + * Compute the next action, updating the TIME attribute for this action + * @return -1 if action ended 0 otherwise + */ + int next_action(); +}; + +/** + * Set of VirtualMachine SCHED_ACTION attributes + */ +class SchedActions : public VirtualMachineAttributeSet +{ +public: + /* ---------------------------------------------------------------------- */ + /* Constructor and Initialization functions */ + /* ---------------------------------------------------------------------- */ + /** + * Creates the SchedAction set from a Template with SCHED_ACTION=[...] + * attributes, id's are auto-assigned for internal use + * @param tmpl template with DISK + */ + SchedActions(Template * tmpl): VirtualMachineAttributeSet(false) + { + std::vector vas; + + tmpl->get("SCHED_ACTION", vas); + + init_attribute_map("", vas); + }; + + virtual ~SchedActions(){}; + + /* ---------------------------------------------------------------------- */ + + /** + * Parse the ScheduleActions of a template + * @param error + * @return -1 in case of error 0 otherwise + */ + int parse(std::string& error) + { + for ( schedaction_iterator action = begin(); action != end(); ++action) + { + if ( (*action)->parse(error) == -1 ) + { + return -1; + } + } + + return 0; + } + + /* ---------------------------------------------------------------------- */ + /* Iterators */ + /* ---------------------------------------------------------------------- */ + /** + * Generic iterator for the SchedActions set. + */ + class SchedActionIterator : public AttributeIterator + { + public: + SchedActionIterator():AttributeIterator(){}; + SchedActionIterator(const AttributeIterator& i):AttributeIterator(i){}; + virtual ~SchedActionIterator(){}; + + SchedAction * operator*() const + { + return static_cast(map_it->second); + } + }; + + SchedActionIterator begin() + { + SchedActionIterator it(ExtendedAttributeSet::begin()); + return it; + } + + SchedActionIterator end() + { + SchedActionIterator it(ExtendedAttributeSet::end()); + return it; + } + + typedef class SchedActionIterator schedaction_iterator; + +protected: + VirtualMachineAttribute * attribute_factory(VectorAttribute * va, + int id) const + { + return new SchedAction(va, id); + }; +}; + +#endif /*SCHED_ACTION_ATTRIBUTE_H_*/ + diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 9ac6283fb6..80a43e034b 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -17,13 +17,12 @@ #include #include "VirtualMachineXML.h" +#include "ScheduledAction.h" #include "DatastoreXML.h" #include "DatastorePoolXML.h" #include "NebulaUtil.h" #include "History.h" -map m_months_days = {{0, 31}, {1, 28}, {2, 30}, {3, 31}, {4, 30}, {5, 31}, {6, 30}, {7, 31}, {8, 30}, {9, 31}, {10, 30}, {11, 31}}; - void VirtualMachineXML::init_attributes() { vector nodes; @@ -505,180 +504,12 @@ bool VirtualMachineXML::is_only_public_cloud() const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -static void check_months(struct tm * next){ - int days_month = m_months_days[next->tm_mon]; - if(next->tm_year+1900 % 4 == 0 && (next->tm_year+1900 % 100 != 0 || next->tm_year+1900 % 400 == 0) && next->tm_mon == 1) - { - days_month++; - } - if (next->tm_mday > days_month) - { - next->tm_mday = next->tm_mday - m_months_days[next->tm_mon]; - next->tm_mon++; - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -static void sum_days(struct tm * next, struct tm * now, int mayor_day, int minor_day, int max_day, int comparative){ - if (mayor_day >= 0 && minor_day < max_day) - { - if( mayor_day <= comparative ) //next - { - next->tm_mday = next->tm_mday + ((max_day) - comparative + minor_day); - } - else // same - { - next->tm_mday = next->tm_mday + (mayor_day - comparative); - } - } - check_months(next); -} - -/* -------------------------------------------------------------------------- */ - -static void generate_next_day(int rep, int mayor_day, int minor_day, struct tm * next, struct tm * now) -{ - if ( rep == 0 ) //Repeat every weeks - { - sum_days(next, now, mayor_day, minor_day, 7, next->tm_wday); - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - } - - if ( rep == 1 ) //Repeat every months - { - cout << next->tm_mday << endl; - sum_days(next, now, mayor_day, minor_day, m_months_days[next->tm_mon] , next->tm_mday); - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - } - - if ( rep == 2 ) //Repeat every months - { - sum_days(next, now, mayor_day, minor_day, 365, next->tm_yday); - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - int VirtualMachineXML::next_action(VectorAttribute& vatt) { - string days; - int rep_mode, end_mode; - int end_value; - int mayor_day = -1; - int minor_day = 366; - int start_day; - time_t action_time; - time_t done_time; - vector v_days; - set s_days; + SchedAction action(&vatt, -1); - vatt.vector_value("DAYS", days); - vatt.vector_value("REP", rep_mode); - vatt.vector_value("END_TYPE", end_mode); - vatt.vector_value("END_VALUE", end_value); - vatt.vector_value("TIME", action_time); - vatt.vector_value("DONE", done_time); + return action.next_action(); +} - v_days = one_util::split(days, ',', true); - for(vector::iterator it = v_days.begin(); it != v_days.end(); ++it) { - s_days.insert(atoi((*it).c_str())); - } - - struct tm next; - struct tm start_tm; - localtime_r(&action_time, &start_tm); - next = start_tm; - - start_day = start_tm.tm_wday; - if (rep_mode == 1) - { - start_day = start_tm.tm_mday; - } - else if (rep_mode == 2) - { - start_day = start_tm.tm_yday; - } - std::set::iterator it; - std::pair::iterator,bool> ret; - if (rep_mode != 3) - { - it = s_days.begin(); - minor_day = *it; - - ret = s_days.insert(start_day); - if ( ret.second == false ) - { - mayor_day = *ret.first; - - if ( ++ret.first != s_days.end() ) - { - mayor_day = *ret.first; - } - } - else - { - mayor_day = minor_day; - if ( ++ret.first != s_days.end() ) - { - mayor_day = *ret.first; - } - it = s_days.find(start_day); - s_days.erase (it); - if (*--it > mayor_day) - { - mayor_day = *it; - } - } - } - - if ( end_mode == 1 ) - { - int num_rep = end_value; - if (num_rep <= 0) - { - cout << "Finished scheduling actions" << endl; - return -1; - } - end_value = num_rep-1; - vatt.replace("END_VALUE", end_value); - } - else if ( end_mode == 2 ) - { - time_t t_end = end_value; - if ( time(0) > t_end ) - { - cout << "Finished scheduling actions" << endl; - return -1; - } - } - - if (rep_mode == 3) - { - it = s_days.begin(); - int hours = *it; - next.tm_min = start_tm.tm_min; - next.tm_hour = start_tm.tm_hour + hours; - check_months(&next); - } - else - { - generate_next_day(rep_mode, mayor_day, minor_day, &next, &start_tm); - } - action_time = mktime (&next); - if (action_time != -1) - { - vatt.replace("TIME", action_time); - } - else - { - return -1; - } - return 0; -} \ No newline at end of file +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/src/scheduler/src/sched/SConstruct b/src/scheduler/src/sched/SConstruct index 7da4bdd5b8..90d9963cd2 100644 --- a/src/scheduler/src/sched/SConstruct +++ b/src/scheduler/src/sched/SConstruct @@ -39,6 +39,7 @@ sched_env.Prepend(LIBS=[ 'nebula_common', 'nebula_core', 'nebula_template', + 'nebula_vmtemplate', 'nebula_vm', 'nebula_host', 'crypto', diff --git a/src/vm_template/SConstruct b/src/vm_template/SConstruct index ea7361b4e2..0987c527e4 100644 --- a/src/vm_template/SConstruct +++ b/src/vm_template/SConstruct @@ -23,7 +23,8 @@ lib_name='nebula_vmtemplate' # Sources to generate the library source_files=[ 'VMTemplate.cc', - 'VMTemplatePool.cc' + 'VMTemplatePool.cc', + 'ScheduledAction.cc' ] # Build library diff --git a/src/vm_template/ScheduledAction.cc b/src/vm_template/ScheduledAction.cc new file mode 100644 index 0000000000..57ed2ef826 --- /dev/null +++ b/src/vm_template/ScheduledAction.cc @@ -0,0 +1,471 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2018, 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 "ScheduledAction.h" +#include "NebulaUtil.h" + +int SchedAction::repeat(Repeat& r) +{ + r = NONE; + + std::string rep_s = vector_value("REP"); + + if ( rep_s.empty() ) + { + return 0; + } + + std::istringstream iss(rep_s); + int v_r; + + iss >> v_r; + + if (iss.fail() || !iss.eof()) + { + return -1; + } + + if ( v_r < WEEKLY || v_r > HOURLY ) + { + return -1; + } + + r = static_cast(v_r); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int SchedAction::endon(EndOn& eo) +{ + eo = END_NONE; + + std::string et_s = vector_value("END_TYPE"); + + if ( et_s.empty() ) + { + return 0; + } + + std::istringstream iss(et_s); + int v_eo; + + iss >> v_eo; + + if (iss.fail() || !iss.eof()) + { + return -1; + } + + if ( v_eo < TIMES || v_eo > DATE ) + { + return -1; + } + + eo = static_cast(v_eo); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int SchedAction::days(std::set& _d) +{ + std::string st; + + int rc = vector_value("DAYS", st); + + if ( rc != 0 ) + { + return 0; + } + + one_util::split_unique(st, ',', _d); + + if ( _d.empty() ) + { + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool SchedAction::days_in_range(Repeat r, std::string& error) +{ + static const char * e[] = { + "Days in a week have to be in [0,6] range", //WEEKLY - 0 + "Days in a month have to be in [0,31] range", // MONTHLY - 1 + "Days in a year have to be in [0,365] range", // YEARLY - 2 + "Hours have to be in [0,23] range" // HOURLY - 3 + }; + + static int fday[] = {0,1,0,1}; + static int lday[] = {7,32,366,24}; + + bool extra_check; + + std::set _d; + + if ( days(_d) == -1 ) + { + error = "Wrong format of DAYS attribute"; + return false; + } + else if ( _d.empty() ) + { + return true; + } + + int _fday = *(_d.cbegin()); + int _lday = *(_d.cend()); + + switch(r) + { + case WEEKLY: + case MONTHLY: + case YEARLY: + extra_check = false; + break; + case HOURLY: + extra_check = _d.size() != 1; + break; + case NONE: + return false; + } + + if ( _fday < fday[r] || _lday >= lday[r] || extra_check ) + { + error = e[r]; + return false; + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool SchedAction::ends_in_range(EndOn eo, std::string& error) +{ + int end_value; + int rc = vector_value("END_VALUE", end_value); + + if ( rc == -1 ) + { + error = "Missing END_VALUE"; + return false; + } + + if ( eo == TIMES && end_value <= 0 ) + { + error = "Error parsing END_VALUE, times has to be greater than 0"; + return false; + } + else if ( eo == DATE ) + { + struct tm val_tm; + + time_t value = end_value; + + localtime_r(&value, &val_tm); + + time_t out = mktime(&val_tm); + + if (out == -1) + { + error = "Error parsing END_VALUE, wrong format for date."; + return false; + } + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int SchedAction::parse(std::string& error) +{ + Repeat r; + EndOn eo; + + if ( repeat(r) == -1 ) + { + error = "Error parsing REPEAT attribute"; + return -1; + } + + if ( endon(eo) == -1 ) + { + error = "Error parsing END_TYPE attribute"; + return -1; + } + + if ( !days_in_range(r, error) ) + { + return -1; + } + + if ( !ends_in_range(eo, error) ) + { + return -1; + } + + remove("DONE"); + remove("MESSAGE"); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +map MONTHS_DAYS = {{0, 31}, {1, 28}, {2, 30}, {3, 31}, {4, 30}, + {5, 31}, {6, 30}, {7, 31}, {8, 30}, {9, 31}, {10, 30}, {11, 31}}; + +/* -------------------------------------------------------------------------- */ + +static void check_months(struct tm * next) +{ + int days_month = MONTHS_DAYS[next->tm_mon]; + + if ( next->tm_year+1900 % 4 == 0 && ( next->tm_year+1900 % 100 != 0 || + next->tm_year+1900 % 400 == 0) && next->tm_mon == 1) + { + days_month++; + } + + if ( next->tm_mday > days_month) + { + next->tm_mday = next->tm_mday - MONTHS_DAYS[next->tm_mon]; + next->tm_mon++; + } +} + +/* -------------------------------------------------------------------------- */ + +static void sum_days(struct tm * next, struct tm * now, int mayor_day, + int minor_day, int max_day, int comparative) +{ + if (mayor_day >= 0 && minor_day < max_day) + { + if( mayor_day <= comparative ) //next + { + next->tm_mday = next->tm_mday + (max_day - comparative + minor_day); + } + else // same + { + next->tm_mday = next->tm_mday + (mayor_day - comparative); + } + } + + check_months(next); +} + +/* -------------------------------------------------------------------------- */ + +static void generate_next_day(int rep, int mayor_day, int minor_day, + struct tm * next, struct tm * now) +{ + SchedAction::Repeat r = static_cast(rep); + + switch(r) + { + case SchedAction::WEEKLY: + sum_days(next, now, mayor_day, minor_day, 7, next->tm_wday); + + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + break; + + case SchedAction::MONTHLY: + sum_days(next, now, mayor_day, minor_day, MONTHS_DAYS[next->tm_mon], + next->tm_mday); + + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + break; + + case SchedAction::YEARLY: + sum_days(next, now, mayor_day, minor_day, 365, next->tm_yday); + + next->tm_min = now->tm_min; + next->tm_hour = now->tm_hour; + break; + + case SchedAction::HOURLY: + case SchedAction::NONE: + break; + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int SchedAction::next_action() +{ + Repeat r; + EndOn eo; + + if ( repeat(r) == -1 ) + { + return -1; + } + + if ( endon(eo) == -1 ) + { + return -1; + } + + std::set _days; + + if ( days(_days) == -1 ) + { + return -1; + } + else if ( _days.empty() ) + { + return -1; + } + + /* --------------------------------------------------------------------- */ + /* Check if action is already finished */ + /* --------------------------------------------------------------------- */ + int end_value; + int rc = vector_value("END_VALUE", end_value); + + if ( rc == -1 ) + { + return -1; + } + + if ( eo == TIMES ) + { + if (end_value <= 0) + { + return -1; + } + + replace("END_VALUE", end_value - 1); + } + else if ( eo == DATE ) + { + if ( time(0) > end_value ) + { + return -1; + } + } + + /* --------------------------------------------------------------------- */ + /* Compute next event for the action */ + /* --------------------------------------------------------------------- */ + + time_t action_time; + struct tm start_tm; + + localtime_r(&action_time, &start_tm); + + struct tm next = start_tm; + int start_day; + + switch(r) + { + case WEEKLY: + start_day = start_tm.tm_wday; + break; + + case MONTHLY: + start_day = start_tm.tm_mday; + break; + + case YEARLY: + start_day = start_tm.tm_yday; + break; + + case HOURLY: + case NONE: + break; + } + + std::set::iterator it = _days.begin(); + + if ( r != HOURLY ) //WEEKLY, MONTHLY, YEARLY + { + + int minor_day = *it; + int mayor_day; + + std::pair::iterator, bool> ret = _days.insert(start_day); + + if ( ret.second == false ) + { + mayor_day = *(ret.first); + + if ( ++ret.first != _days.end() ) + { + mayor_day = *(ret.first); + } + } + else + { + mayor_day = minor_day; + + if ( ++ret.first != _days.end() ) + { + mayor_day = *(ret.first); + } + + it = _days.find(start_day); + + _days.erase(it); + + if (*(--it) > mayor_day) + { + mayor_day = *it; + } + } + + generate_next_day(r, mayor_day, minor_day, &next, &start_tm); + } + else //HOURLY + { + int hours = *it; + + next.tm_min = start_tm.tm_min; + next.tm_hour = start_tm.tm_hour + hours; + + check_months(&next); + } + + action_time = mktime(&next); + + if (action_time != -1) + { + replace("TIME", action_time); + } + else + { + return -1; + } + + return 0; +} diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc index b0256ea100..52880cc47f 100644 --- a/src/vm_template/VMTemplate.cc +++ b/src/vm_template/VMTemplate.cc @@ -15,8 +15,7 @@ /* ------------------------------------------------------------------------ */ #include "VMTemplate.h" - -#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) +#include "ScheduledAction.h" /* ************************************************************************ */ /* VMTemplate :: Constructor/Destructor */ @@ -77,6 +76,7 @@ int VMTemplate::insert(SqlDB *db, string& error_str) // Remove DONE/MESSAGE from SCHED_ACTION and check rest attributes // --------------------------------------------------------------------- int rc = parse_sched_action(error_str); + if (rc == -1) { return rc; @@ -173,93 +173,9 @@ error_common: int VMTemplate::parse_sched_action(string& error_str) { - vector _sched_actions; - vector::iterator i; - set::const_iterator it_set; - VectorAttribute* vatt; - int rep_mode, end_mode; - int has_mode, has_end_mode, has_days, has_end_value; - int end_value; - int first_day, last_day; - string days; - vector v_days; - set s_days; + SchedActions sactions(obj_template); - get_template_attribute("SCHED_ACTION", _sched_actions); - - for ( i = _sched_actions.begin(); i != _sched_actions.end() ; ++i) - { - vatt = dynamic_cast(*i); - - has_mode = vatt->vector_value("REP", rep_mode); - has_days = vatt->vector_value("DAYS", days); - - if (has_mode == 0 && has_days == 0) - { - v_days = one_util::split(days, ',', true); - if ( !v_days.empty() ) - { - for(vector::iterator it = v_days.begin(); it != v_days.end(); ++it) { - s_days.insert(atoi((*it).c_str())); - } - } - else - { - s_days.insert(atoi((days).c_str())); - } - first_day = *s_days.cbegin(); - last_day = *s_days.cend(); - - if (rep_mode == 0 && !(first_day >= 0 && last_day < 7)) //WEEK [0,6] - { - error_str = "Error parsing days of the week. [0,6]"; - return -1; - } - else if (rep_mode == 1 && !(first_day >= 1 && last_day < 32)) //MONTH [1,31] - { - error_str = "Error parsing days of the month. [1,31]"; - return -1; - } - else if (rep_mode == 2 && !(first_day >= 0 && last_day < 366)) //YEAR [0,365] - { - error_str = "Error parsing days of the year. [0,365]"; - return -1; - } - else if (rep_mode == 3 && (first_day != last_day || s_days.size() > 1)) //YEAR [0,365] - { - error_str = "Error parsing hour."; - return -1; - } - } - - has_end_mode = vatt->vector_value("END_TYPE", end_mode); - has_end_value = vatt->vector_value("END_VALUE", end_value); - - if (has_end_mode == 0 && has_end_value == 0) - { - if (end_mode == 1 && end_value < 0) //N_REP - { - error_str = "Error parsing END_VALUE of type N_REP."; - return -1; - } - else if ( end_mode == 2 ) //DATE - { - time_t value = end_value; - struct tm val_tm; - localtime_r(&value, &val_tm); - time_t out = mktime(&val_tm); - if (out == -1) - { - error_str = "Error parsing END_VALUE of type DATE."; - return -1; - } - } - } - - vatt->remove("DONE"); - vatt->remove("MESSAGE"); - } - return 0; + return sactions.parse(error_str); } /* ------------------------------------------------------------------------ */ From 546921fc13745b3ab7a81781dd727c359e94cc2e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 7 May 2018 17:43:52 +0200 Subject: [PATCH 23/28] F #1548: Simplify next_action logic. Fix some errors. Set hourly limit for events to 1 week --- src/vm_template/ScheduledAction.cc | 189 ++++++++++------------------- 1 file changed, 63 insertions(+), 126 deletions(-) diff --git a/src/vm_template/ScheduledAction.cc b/src/vm_template/ScheduledAction.cc index 57ed2ef826..38c7e64755 100644 --- a/src/vm_template/ScheduledAction.cc +++ b/src/vm_template/ScheduledAction.cc @@ -115,11 +115,11 @@ bool SchedAction::days_in_range(Repeat r, std::string& error) "Days in a week have to be in [0,6] range", //WEEKLY - 0 "Days in a month have to be in [0,31] range", // MONTHLY - 1 "Days in a year have to be in [0,365] range", // YEARLY - 2 - "Hours have to be in [0,23] range" // HOURLY - 3 + "Hours have to be in [0,168] range" // HOURLY - 3 }; static int fday[] = {0,1,0,1}; - static int lday[] = {7,32,366,24}; + static int lday[] = {7,32,366,168}; bool extra_check; @@ -135,8 +135,8 @@ bool SchedAction::days_in_range(Repeat r, std::string& error) return true; } - int _fday = *(_d.cbegin()); - int _lday = *(_d.cend()); + int _fday = *(_d.begin()); + int _lday = *(_d.rbegin()); switch(r) { @@ -184,9 +184,7 @@ bool SchedAction::ends_in_range(EndOn eo, std::string& error) { struct tm val_tm; - time_t value = end_value; - - localtime_r(&value, &val_tm); + localtime_r((time_t *)&end_value, &val_tm); time_t out = mktime(&val_tm); @@ -239,83 +237,45 @@ int SchedAction::parse(std::string& error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -map MONTHS_DAYS = {{0, 31}, {1, 28}, {2, 30}, {3, 31}, {4, 30}, - {5, 31}, {6, 30}, {7, 31}, {8, 30}, {9, 31}, {10, 30}, {11, 31}}; - -/* -------------------------------------------------------------------------- */ - -static void check_months(struct tm * next) +static int days_in_period(SchedAction::Repeat& r, int month, int year) { - int days_month = MONTHS_DAYS[next->tm_mon]; + static map MONTHS_DAYS = {{0, 31}, {1, 28}, {2, 31}, {3, 30}, + {4, 31}, {5, 30}, {6, 31}, {7, 31}, {8, 30}, {9, 31}, {10, 30}, + {11, 31}}; - if ( next->tm_year+1900 % 4 == 0 && ( next->tm_year+1900 % 100 != 0 || - next->tm_year+1900 % 400 == 0) && next->tm_mon == 1) + int leap_year = 0; + int leap_month = 0; + + year += 1900; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) { - days_month++; - } + leap_year = 1; - if ( next->tm_mday > days_month) - { - next->tm_mday = next->tm_mday - MONTHS_DAYS[next->tm_mon]; - next->tm_mon++; - } -} - -/* -------------------------------------------------------------------------- */ - -static void sum_days(struct tm * next, struct tm * now, int mayor_day, - int minor_day, int max_day, int comparative) -{ - if (mayor_day >= 0 && minor_day < max_day) - { - if( mayor_day <= comparative ) //next + if ( month == 1 ) { - next->tm_mday = next->tm_mday + (max_day - comparative + minor_day); - } - else // same - { - next->tm_mday = next->tm_mday + (mayor_day - comparative); + leap_month = 1; } } - check_months(next); -} - -/* -------------------------------------------------------------------------- */ - -static void generate_next_day(int rep, int mayor_day, int minor_day, - struct tm * next, struct tm * now) -{ - SchedAction::Repeat r = static_cast(rep); - switch(r) { case SchedAction::WEEKLY: - sum_days(next, now, mayor_day, minor_day, 7, next->tm_wday); - - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - break; + return 7; + //Return value for months assume month day starts in 0 case SchedAction::MONTHLY: - sum_days(next, now, mayor_day, minor_day, MONTHS_DAYS[next->tm_mon], - next->tm_mday); - - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - break; + return MONTHS_DAYS[month] + leap_month; case SchedAction::YEARLY: - sum_days(next, now, mayor_day, minor_day, 365, next->tm_yday); - - next->tm_min = now->tm_min; - next->tm_hour = now->tm_hour; - break; + return 365 + leap_year; case SchedAction::HOURLY: case SchedAction::NONE: - break; + return 0; } + + return 0; } /* -------------------------------------------------------------------------- */ @@ -376,29 +336,44 @@ int SchedAction::next_action() } /* --------------------------------------------------------------------- */ - /* Compute next event for the action */ + /* Compute next event for the action - HOURLY */ /* --------------------------------------------------------------------- */ - time_t action_time; - struct tm start_tm; - localtime_r(&action_time, &start_tm); + vector_value("TIME", action_time); - struct tm next = start_tm; - int start_day; + if ( r == HOURLY ) + { + action_time += *(_days.begin()) * 3600; + + replace("TIME", action_time); + + return 0; + } + + /* --------------------------------------------------------------------- */ + /* Compute next event for the action - WEEKLY, MONTHLY & YEARLY */ + /* --------------------------------------------------------------------- */ + time_t current = time(0); + + struct tm current_tm; + + int cday; + + localtime_r(¤t, ¤t_tm); switch(r) { case WEEKLY: - start_day = start_tm.tm_wday; + cday = current_tm.tm_wday; break; case MONTHLY: - start_day = start_tm.tm_mday; + cday = current_tm.tm_mday; break; case YEARLY: - start_day = start_tm.tm_yday; + cday = current_tm.tm_yday; break; case HOURLY: @@ -406,66 +381,28 @@ int SchedAction::next_action() break; } - std::set::iterator it = _days.begin(); + std::set::iterator it = _days.lower_bound(cday); - if ( r != HOURLY ) //WEEKLY, MONTHLY, YEARLY + int delta = 0; + + if (it == _days.end()) //after last day in range { + int pdays = days_in_period(r, current_tm.tm_mon, current_tm.tm_year); - int minor_day = *it; - int mayor_day; - - std::pair::iterator, bool> ret = _days.insert(start_day); - - if ( ret.second == false ) - { - mayor_day = *(ret.first); - - if ( ++ret.first != _days.end() ) - { - mayor_day = *(ret.first); - } - } - else - { - mayor_day = minor_day; - - if ( ++ret.first != _days.end() ) - { - mayor_day = *(ret.first); - } - - it = _days.find(start_day); - - _days.erase(it); - - if (*(--it) > mayor_day) - { - mayor_day = *it; - } - } - - generate_next_day(r, mayor_day, minor_day, &next, &start_tm); + delta = pdays - cday + *(_days.begin()); //assume start day is 0 } - else //HOURLY + else if (cday < *(_days.begin())) //before first day in range { - int hours = *it; - - next.tm_min = start_tm.tm_min; - next.tm_hour = start_tm.tm_hour + hours; - - check_months(&next); + delta = *(_days.begin()) - cday; + } + else if (*it != cday ) //is not today + { + delta = *it - cday; } - action_time = mktime(&next); + action_time += delta * 24 * 3600; - if (action_time != -1) - { - replace("TIME", action_time); - } - else - { - return -1; - } + replace("TIME", action_time); return 0; } From 35ed08fc8266774c6f126d3e88cddca05c161c3b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 7 May 2018 18:31:32 +0200 Subject: [PATCH 24/28] F 1548: Updated scheduler logic to SchedAction class --- include/ScheduledAction.h | 12 ++- src/scheduler/include/VirtualMachineXML.h | 14 +-- src/scheduler/src/pool/VirtualMachineXML.cc | 10 -- src/scheduler/src/sched/Scheduler.cc | 109 +++++++++----------- src/vm_template/ScheduledAction.cc | 14 +++ 5 files changed, 74 insertions(+), 85 deletions(-) diff --git a/include/ScheduledAction.h b/include/ScheduledAction.h index 132c2278c5..cc0fec6741 100644 --- a/include/ScheduledAction.h +++ b/include/ScheduledAction.h @@ -96,6 +96,11 @@ public: */ int parse(std::string& error); + /** + * @return true if the action needs to be executed. + */ + bool is_due(); + /** * Compute the next action, updating the TIME attribute for this action * @return -1 if action ended 0 otherwise @@ -123,7 +128,7 @@ public: tmpl->get("SCHED_ACTION", vas); - init_attribute_map("", vas); + init_attribute_map("TIME", vas); }; virtual ~SchedActions(){}; @@ -148,6 +153,11 @@ public: return 0; } + bool empty() + { + return a_set.empty(); + } + /* ---------------------------------------------------------------------- */ /* Iterators */ /* ---------------------------------------------------------------------- */ diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index 2cecf9a920..729934ce4c 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -25,6 +25,7 @@ #include "Resource.h" #include "VirtualMachineTemplate.h" +#include "ScheduledAction.h" class ImageDatastorePoolXML; @@ -325,20 +326,11 @@ public: * * @param attributes to hold the VM actions */ - void get_actions(vector& attributes) const + SchedActions * get_actions() { - attributes.clear(); - - user_template->remove("SCHED_ACTION", attributes); + return new SchedActions(user_template); } - /** - * Generate new action - * - * @param attributes to hold the VM actions - */ - int next_action(VectorAttribute& vatt); - /** * Sets an attribute in the VM Template, it must be allocated in the heap * diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 80a43e034b..afe29c2bce 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -503,13 +503,3 @@ bool VirtualMachineXML::is_only_public_cloud() const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ - -int VirtualMachineXML::next_action(VectorAttribute& vatt) -{ - SchedAction action(&vatt, -1); - - return action.next_action(); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ \ No newline at end of file diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index c910b2b6db..fa9cc0ad74 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -34,6 +34,7 @@ #include "NebulaLog.h" #include "PoolObjectAuth.h" #include "NebulaUtil.h" +#include "ScheduledAction.h" using namespace std; @@ -1094,7 +1095,7 @@ void Scheduler::dispatch() const vector vm_rs = vmpool->get_vm_resources(); //-------------------------------------------------------------------------- - dss << "Dispatching VMs to hosts:\n" + dss << "Dispatching VMs to hosts:\n" << "\tVMID\tPriority\tHost\tSystem DS\n" << "\t--------------------------------------------------------------\n"; //-------------------------------------------------------------------------- @@ -1380,92 +1381,74 @@ int Scheduler::do_scheduled_actions() const map vms = vmapool->get_objects(); map::const_iterator vm_it; - vector attributes; - vector::iterator it; - - VectorAttribute* vatt; - - int action_time; - int done_time; - int rep_time; - int has_rep; - int has_time; - int has_done; - string action_st, error_msg; - time_t the_time = time(0); - string time_str = one_util::log_time(the_time); + string time_str = one_util::log_time(time(0)); for (vm_it=vms.begin(); vm_it != vms.end(); vm_it++) { - vm = static_cast(vm_it->second); + SchedActions::schedaction_iterator action; - vm->get_actions(attributes); + vm = static_cast(vm_it->second); - // TODO: Sort actions by TIME - for (it=attributes.begin(); it != attributes.end(); it++) + SchedActions * sas = vm->get_actions(); + + for ( action = sas->begin(); action != sas->end(); ++action) { - vatt = dynamic_cast(*it); + ostringstream oss; - if (vatt == 0) + if (!(*action)->is_due()) { - delete *it; - continue; } - has_time = vatt->vector_value("TIME", action_time); - has_done = vatt->vector_value("DONE", done_time); - has_rep = vatt->vector_value("REP", rep_time); - action_st = vatt->vector_value("ACTION"); + action_st = (*action)->vector_value("ACTION"); - if (has_time == 0 && (has_done == -1 || (has_done == 0 && done_time < action_time)) && action_time < the_time) + int rc = VirtualMachineXML::parse_action_name(action_st); + + oss << "Executing action '" << action_st << "' for VM " + << vm->get_oid() << " : "; + + if ( rc != 0 ) { - ostringstream oss; - - int rc = VirtualMachineXML::parse_action_name(action_st); - - oss << "Executing action '" << action_st << "' for VM " - << vm->get_oid() << " : "; - - if ( rc != 0 ) - { - error_msg = "This action is not supported."; - } - else - { - rc = vmapool->action(vm->get_oid(), action_st, error_msg); - } + error_msg = "This action is not supported."; + } + else + { + rc = vmapool->action(vm->get_oid(), action_st, error_msg); if (rc == 0) { - vatt->remove("MESSAGE"); - vatt->replace("DONE", static_cast(the_time)); - if ( has_rep == 0 ) - { - vm->next_action(*vatt); - } + (*action)->remove("MESSAGE"); + + (*action)->replace("DONE", time(0)); + + (*action)->next_action(); + oss << "Success."; } - else - { - ostringstream oss_aux; - - oss_aux << time_str << " : " << error_msg; - - vatt->replace("MESSAGE", oss_aux.str()); - - oss << "Failure. " << error_msg; - } - - NebulaLog::log("VM", Log::INFO, oss); } - vm->set_attribute(vatt); + if ( rc != 0 ) + { + ostringstream oss_aux; + + oss_aux << time_str << " : " << error_msg; + + (*action)->replace("MESSAGE", oss_aux.str()); + + oss << "Failure. " << error_msg; + } + + NebulaLog::log("VM", Log::INFO, oss); } - vmpool->update(vm); + if ( sas->empty() != 0 ) //Do not update VMs without SCHED_ACTION + { + vmpool->update(vm); + } + + delete sas; } return 0; diff --git a/src/vm_template/ScheduledAction.cc b/src/vm_template/ScheduledAction.cc index 38c7e64755..beb57517c6 100644 --- a/src/vm_template/ScheduledAction.cc +++ b/src/vm_template/ScheduledAction.cc @@ -281,6 +281,20 @@ static int days_in_period(SchedAction::Repeat& r, int month, int year) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +bool SchedAction::is_due() +{ + time_t action_time, done_time; + + bool has_done = vector_value("DONE", done_time) == 0; + + vector_value("TIME", action_time); + + return ((!has_done || done_time < action_time) && action_time < time(0)); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int SchedAction::next_action() { Repeat r; From 056a0d2dcd7768662c04a08bcf65a4e690a81af9 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 7 May 2018 18:35:46 +0200 Subject: [PATCH 25/28] F #1548: "REP"->"REPEAT" in oned TIMES, DATE -> [0,1] in oned --- include/ScheduledAction.h | 4 ++-- src/vm_template/ScheduledAction.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/ScheduledAction.h b/include/ScheduledAction.h index cc0fec6741..9786383e69 100644 --- a/include/ScheduledAction.h +++ b/include/ScheduledAction.h @@ -39,8 +39,8 @@ public: enum EndOn { END_NONE = -1, - TIMES = 1, - DATE = 2 + TIMES = 0, + DATE = 1 }; SchedAction(VectorAttribute *va, int id):VirtualMachineAttribute(va, id){}; diff --git a/src/vm_template/ScheduledAction.cc b/src/vm_template/ScheduledAction.cc index beb57517c6..8c0b15bb0c 100644 --- a/src/vm_template/ScheduledAction.cc +++ b/src/vm_template/ScheduledAction.cc @@ -21,7 +21,7 @@ int SchedAction::repeat(Repeat& r) { r = NONE; - std::string rep_s = vector_value("REP"); + std::string rep_s = vector_value("REPEAT"); if ( rep_s.empty() ) { From 6c01c4902bbdda586ed2d08809c2f3d6527a0255 Mon Sep 17 00:00:00 2001 From: juanmont Date: Tue, 8 May 2018 11:55:50 +0200 Subject: [PATCH 26/28] F #1548: Added new END_TYPE -> NEVER = 0 --- include/ScheduledAction.h | 6 +++--- src/vm_template/ScheduledAction.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/ScheduledAction.h b/include/ScheduledAction.h index 9786383e69..f73edb6f12 100644 --- a/include/ScheduledAction.h +++ b/include/ScheduledAction.h @@ -38,9 +38,9 @@ public: enum EndOn { - END_NONE = -1, - TIMES = 0, - DATE = 1 + NEVER = 0, + TIMES = 1, + DATE = 2 }; SchedAction(VectorAttribute *va, int id):VirtualMachineAttribute(va, id){}; diff --git a/src/vm_template/ScheduledAction.cc b/src/vm_template/ScheduledAction.cc index 8c0b15bb0c..a8d418091c 100644 --- a/src/vm_template/ScheduledAction.cc +++ b/src/vm_template/ScheduledAction.cc @@ -53,7 +53,7 @@ int SchedAction::repeat(Repeat& r) int SchedAction::endon(EndOn& eo) { - eo = END_NONE; + eo = NEVER; std::string et_s = vector_value("END_TYPE"); From 06fb2373df89a49d3ab2cdb7a3f3a72c4640d3d9 Mon Sep 17 00:00:00 2001 From: juanmont Date: Tue, 8 May 2018 11:56:24 +0200 Subject: [PATCH 27/28] F #1548: Changed CLI, REP -> REPEAT --- src/cli/one_helper/onevm_helper.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index 73573ffacc..b8eeecb11c 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -356,13 +356,13 @@ class OneVMHelper < OpenNebulaHelper::OneHelper str_periodic = "" if options.key?(:weekly) - str_periodic << ", REP = 0, DAYS = \"#{options[:weekly]}\"" + str_periodic << ", REPEAT = 0, DAYS = \"#{options[:weekly]}\"" elsif options.key?(:monthly) - str_periodic << ", REP = 1, DAYS = \"#{options[:monthly]}\"" + str_periodic << ", REPEAT = 1, DAYS = \"#{options[:monthly]}\"" elsif options.key?(:yearly) - str_periodic << ", REP = 2, DAYS = \"#{options[:yearly]}\"" + str_periodic << ", REPEAT = 2, DAYS = \"#{options[:yearly]}\"" elsif options.key?(:hourly) - str_periodic << ", REP = 3, DAYS = \"#{options[:hourly].to_s}\"" + str_periodic << ", REPEAT = 3, DAYS = \"#{options[:hourly].to_s}\"" end if options.key?(:end) @@ -1062,19 +1062,19 @@ in the frontend machine. OpenNebulaHelper.time_to_str(d["TIME"], false) if !d.nil? end - column :"REP", "", :size=>20 do |d| + column :"REPEAT", "", :size=>20 do |d| str_rep = "" - if !d.nil? && d.key?("REP") - if d["REP"] == "0" + if !d.nil? && d.key?("REPEAT") + if d["REPEAT"] == "0" str_rep << "Weekly " - elsif d["REP"] == "1" + elsif d["REPEAT"] == "1" str_rep << "Monthly " - elsif d["REP"] == "2" + elsif d["REPEAT"] == "2" str_rep << "Yearly " - elsif d["REP"] == "3" + elsif d["REPEAT"] == "3" str_rep << "Each " << d['DAYS'] << " hours" end - if d["REP"] != "3" + if d["REPEAT"] != "3" str_rep << d["DAYS"] end end From f9440f933cd5b0becaf485a4f9df620671bc9907 Mon Sep 17 00:00:00 2001 From: juanmont Date: Tue, 8 May 2018 11:57:25 +0200 Subject: [PATCH 28/28] F #1548: Changed Sunstonte , REP -> REPEAT and limit of hours --- .../public/app/utils/schedule_action.js | 30 +++++++++---------- .../public/app/utils/schedule_action/html.hbs | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sunstone/public/app/utils/schedule_action.js b/src/sunstone/public/app/utils/schedule_action.js index 775a8b776d..bd9187bc05 100644 --- a/src/sunstone/public/app/utils/schedule_action.js +++ b/src/sunstone/public/app/utils/schedule_action.js @@ -83,9 +83,9 @@ define(function (require) { var that = this; this.rep = "week"; this.end_type = "never"; - $("select[name='rep']", context).change(function () { + $("select[name='repeat']", context).change(function () { var value = $(this).val(); - that.rep = value; + that.repeat = value; var input_html = ""; switch (value) { case "week": @@ -110,7 +110,7 @@ define(function (require) { case "hour": input_html = "
\ \ - \ + \ \
"; break; @@ -185,19 +185,19 @@ define(function (require) { if (periodic) { - if (!this.rep || !this.end_type) { + if (!this.repeat || !this.end_type) { return false; } - if (this.rep == "week") { + if (this.repeat == "week") { $("input[name='days']:checked").each(function () { days = days + (this).value + ","; }); days = days.slice(0, -1); - } else if (this.rep == "month") { + } else if (this.repeat == "month") { rep = 1; days = $("#days_month_value", context).val(); - } else if (this.rep == "year"){ + } else if (this.repeat == "year"){ rep = 2; days = $("#days_year_value", context).val(); } else { @@ -228,7 +228,7 @@ define(function (require) { } sched_action.DAYS = days; - sched_action.REP = rep; + sched_action.REPEAT = rep; sched_action.END_TYPE = end_type; sched_action.END_VALUE = end_value; } @@ -275,19 +275,19 @@ define(function (require) { var rep_str = ""; var end_str = ""; - if (scheduling_action.REP != undefined) { - if (scheduling_action.REP == 0) { + if (scheduling_action.REPEAT != undefined) { + if (scheduling_action.REPEAT == 0) { rep_str = "Weekly "; - } else if (scheduling_action.REP == 1) { + } else if (scheduling_action.REPEAT == 1) { rep_str = "Monthly "; - } else if (scheduling_action.REP == 2) { + } else if (scheduling_action.REPEAT == 2) { rep_str = "Yearly "; - } else if (scheduling_action.REP == 3) { + } else if (scheduling_action.REPEAT == 3) { rep_str = "Each " + scheduling_action.DAYS + " hours"; } - if (scheduling_action.REP != 3) { - if (scheduling_action.REP != 0) { + if (scheduling_action.REPEAT != 3) { + if (scheduling_action.REPEAT != 0) { rep_str += scheduling_action.DAYS; } else { rep_str += Humanize.week_days(scheduling_action.DAYS); diff --git a/src/sunstone/public/app/utils/schedule_action/html.hbs b/src/sunstone/public/app/utils/schedule_action/html.hbs index 48e353a3f3..cda766f4cb 100644 --- a/src/sunstone/public/app/utils/schedule_action/html.hbs +++ b/src/sunstone/public/app/utils/schedule_action/html.hbs @@ -31,7 +31,7 @@ the License for the specific language governing permissions and }} {{! limitatio -