Author: eallen
Date: 2009-08-12 14:47:08 -0400 (Wed, 12 Aug 2009)
New Revision: 3571
Modified:
mgmt/trunk/cumin/python/cumin/grid/main.py
mgmt/trunk/cumin/python/cumin/grid/model.py
mgmt/trunk/cumin/python/cumin/grid/negotiator.py
mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
Log:
Added tasks to negotiator to get/set config variables.
Modified: mgmt/trunk/cumin/python/cumin/grid/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/main.py 2009-08-12 18:44:22 UTC (rev 3570)
+++ mgmt/trunk/cumin/python/cumin/grid/main.py 2009-08-12 18:47:08 UTC (rev 3571)
@@ -39,6 +39,11 @@
self.negotiator_stop = NegotiatorStopTask(app, negotiator)
self.negotiator_set_start = NegotiatorSetStartTask(app, negotiator)
self.negotiator_set_stop = NegotiatorSetStopTask(app, negotiator)
+ self.negotiator_edit_dynamic_quota = NegotiatorEditDynamicQuotaTask(app,
negotiator)
+ self.negotiator_edit_static_quota = NegotiatorEditStaticQuotaTask(app,
negotiator)
+ self.negotiator_edit_prio_factor = NegotiatorEditPrioFactorTask(app, negotiator)
+ self.negotiator_edit_regroup = NegotiatorEditRegroupTask(app, negotiator)
+ self.negotiator_add_group = NegotiatorAddGroupTask(app, negotiator)
self.frame = GridFrame(app, "grid")
app.main_page.main.grid = self.frame
Modified: mgmt/trunk/cumin/python/cumin/grid/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/model.py 2009-08-12 18:44:22 UTC (rev 3570)
+++ mgmt/trunk/cumin/python/cumin/grid/model.py 2009-08-12 18:47:08 UTC (rev 3571)
@@ -331,3 +331,68 @@
self.form = JobSetTaskForm(app, "job_set_remove", self,
"Remove")
self.item_task = JobRemoveTask(app, cls)
+
+class NegotiatorGroupTask(QmfTask):
+ def __init__(self, app, cls):
+ super(NegotiatorGroupTask, self).__init__(app, cls)
+
+ self.navigable = False
+
+ def do_enter(self, session, negotiator):
+ self.form.object.set(session, negotiator)
+
+ def do_exit(self, session, negotiator):
+ self.app.main_page.main.grid.pool.negotiator.view.show(session)
+
+ def do_invoke(self, completion, session, negotiator, group, value):
+ assert isinstance(negotiator, Negotiator)
+
+ if group == "Reconfig":
+ negotiator.Reconfig(self.app.model.mint.model, completion)
+ else:
+ negotiator.SetRawConfig(self.app.model.mint.model, completion, group, value)
+
+class NegotiatorAddGroupTask(NegotiatorGroupTask):
+ def __init__(self, app, cls):
+ super(NegotiatorAddGroupTask, self).__init__(app, cls)
+
+ self.form = AddGroupForm(self.app, "negotiator_add_group", self)
+
+ def get_title(self, session):
+ return "Add Group"
+
+class NegotiatorEditRegroupTask(NegotiatorGroupTask):
+ def __init__(self, app, cls):
+ super(NegotiatorEditRegroupTask, self).__init__(app, cls)
+
+ self.form = EditRegroupForm(self.app, "negotiator_edit_regroup", self)
+
+ def get_title(self, session):
+ return "Edit Autoregroup"
+
+class NegotiatorEditPrioFactorTask(NegotiatorGroupTask):
+ def __init__(self, app, cls):
+ super(NegotiatorEditPrioFactorTask, self).__init__(app, cls)
+
+ self.form = EditPrioFactorForm(self.app, "negotiator_edit_prio_factor",
self)
+
+ def get_title(self, session):
+ return "Edit Priority Factor"
+
+class NegotiatorEditDynamicQuotaTask(NegotiatorGroupTask):
+ def __init__(self, app, cls):
+ super(NegotiatorEditDynamicQuotaTask, self).__init__(app, cls)
+
+ self.form = EditDynamicQuotaForm(self.app,
"negotiator_edit_dynamic_quota", self)
+
+ def get_title(self, session):
+ return "Edit Dynamic Quota"
+
+class NegotiatorEditStaticQuotaTask(NegotiatorGroupTask):
+ def __init__(self, app, cls):
+ super(NegotiatorEditStaticQuotaTask, self).__init__(app, cls)
+
+ self.form = EditStaticQuotaForm(self.app,
"negotiator_edit_static_quota", self)
+
+ def get_title(self, session):
+ return "Edit Static Quota"
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.py 2009-08-12 18:44:22 UTC (rev 3570)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.py 2009-08-12 18:47:08 UTC (rev 3571)
@@ -1,4 +1,3 @@
-import logging
from wooly import *
from wooly.widgets import *
@@ -77,42 +76,645 @@
self.object = NegotiatorParameter(app, "id")
self.add_parameter(self.object)
- self.view = NegotiatorView(app, "view")
+ self.view = NegotiatorView(app, "view", self.object)
self.add_mode(self.view)
class NegotiatorView(CuminView):
- def __init__(self, app, name):
+ def __init__(self, app, name, negotiator):
super(NegotiatorView, self).__init__(app, name)
self.__tabs = TabbedModeSet(app, "tabs")
self.add_child(self.__tabs)
- overview = NegotiatorOverview(app, "overview")
+ overview = NegotiatorOverviewTab(app, "overview", negotiator)
self.__tabs.add_tab(overview)
details = CuminDetails(app, "details")
self.__tabs.add_tab(details)
-class NegotiatorOverview(Widget):
- def __init__(self, app, name):
- super(NegotiatorOverview, self).__init__(app, name)
+class QmfGroupColumn(ItemTableColumn):
+ def __init__(self, app, name, getter, button):
+ super(QmfGroupColumn, self).__init__(app, name)
- chart = self.PriorityPieChart(app, "chart")
- self.add_child(chart)
+ self.title = None
+ self.getter = getter
+ self.alignment = "right"
+ self.button = button
+ def render_title(self, session, *args):
+ return self.title
+
+ def render_content(self, session, group):
+ if group == self.parent.buttons_row:
+ return self.button.render(session)
+
+ data = self.getter(session)
+ for x in data:
+ if x[0] == group:
+ return self.render_data(x)
+
+class NegotiatorOverviewTab(CuminItemTable):
+ def __init__(self, app, name, negotiator):
+ super(NegotiatorOverviewTab, self).__init__(app, name)
+
+ self.update_enabled = False
+ self.defer_enabled = True
+
+ self.group_helper = GroupHelper(app, "groups", negotiator)
+ self.add_child(self.group_helper)
+
+ col = self.GroupColumn(app, "group", negotiator)
+ self.add_column(col)
+ self.set_default_column(col)
+
+ task = main.module.negotiator_edit_dynamic_quota
+ button = EditButton(app, "dynamic_button", negotiator, task)
+ self.add_child(button)
+ col = self.DynamicColumn(app, "dynamic",
self.group_helper.get_dyn_quota, button)
+ col.title = "Dynamic Quota"
+ self.add_column(col)
+
+ task = main.module.negotiator_edit_static_quota
+ button = EditButton(app, "static_button", negotiator, task)
+ self.add_child(button)
+ col = self.StaticColumn(app, "static",
self.group_helper.get_static_quota, button)
+ col.title = "Static Quota"
+ self.add_column(col)
+
+ task = main.module.negotiator_edit_prio_factor
+ button = EditButton(app, "prio_button", negotiator, task)
+ self.add_child(button)
+ col = self.FactorColumn(app, "factor",
self.group_helper.get_priority_factor, button)
+ col.title = "Priority Factor"
+ self.add_column(col)
+
+ task = main.module.negotiator_edit_regroup
+ button = EditButton(app, "regroup_button", negotiator, task)
+ self.add_child(button)
+ col = self.RegroupColumn(app, "regroup",
self.group_helper.get_regroups, button)
+ col.title = "Auto Regroup"
+ self.add_column(col)
+
+ self.buttons_row = "__buttons__"
+ self.empty_row = "__empty__"
+
def render_title(self, session):
- return "Overview"
+ return "Group Configuration"
- class PriorityPieChart(PieFlashChart):
- def __init__(self, app, name):
- super(NegotiatorOverview.PriorityPieChart, self).__init__(app, name)
+ def render_class(self, session, *args):
+ return "class=\"mobjects\""
- self.chart_type = "pie"
- self.stats = ("priority",)
+ def render_deferred_content(self, session, *args):
+ return "Loading..."
- def render_title(self, session, sched):
- return "Group Priority"
+ def do_get_items(self, session, *args):
+ groups = self.group_helper.get_group_names(session)
+ items = list(groups)
+ if self.reversed.get(session):
+ items = reversed(items)
+ if len(items):
+ items.append(self.buttons_row)
+ else:
+ items.append(self.empty_row)
+ return items
+
+ class GroupColumn(ItemTableColumn):
+ def __init__(self, app, name, negotiator):
+ super(NegotiatorOverviewTab.GroupColumn, self).__init__(app, name)
+
+ task = main.module.negotiator_add_group
+ self.button = EditButton(app, "add_group_button", negotiator,
task)
+ self.add_child(self.button)
+
+ def render_title(self, session, *args):
+ return "Group"
+
+ def render_content(self, session, group):
+ if group == self.parent.buttons_row or group == self.parent.empty_row:
+ return self.button.render(session)
+
+ return group
+
+ class DynamicColumn(QmfGroupColumn):
+ def render_data(self, data):
+ return round(float(data[1]) * 100.0, 2)
+
+ class StaticColumn(QmfGroupColumn):
+ def render_data(self, data):
+ return data[2][2] and data[1] or "-"
+
+ class FactorColumn(QmfGroupColumn):
+ def render_data(self, data):
+ return data[2][2] and data[1] or "-"
+
+ class RegroupColumn(QmfGroupColumn):
+ def render_data(self, data):
+ return data[1]
+
+class GroupHelper(Widget):
+ def __init__(self, app, name, negotiator):
+ super(GroupHelper, self).__init__(app, name)
+
+ self.groups = self.GroupAttribute(app, "groups")
+ self.add_attribute(self.groups)
+
+ self.group_dyn_quotas = self.GroupAttribute(app,
"group_dynamic_quotas")
+ self.add_attribute(self.group_dyn_quotas)
+
+ self.group_static_quotas = self.GroupAttribute(app,
"group_static_quotas")
+ self.add_attribute(self.group_static_quotas)
+
+ self.group_autoregroups = self.GroupAttribute(app,
"group_autoregroups")
+ self.add_attribute(self.group_autoregroups)
+
+ self.autoregroup = self.GroupAttribute(app, "autoregroup")
+ self.add_attribute(self.autoregroup)
+
+ self.group_factors = self.GroupAttribute(app, "group_factors")
+ self.add_attribute(self.group_factors)
+
+ self.negotiator = negotiator
+
+ def get_group_names(self, session):
+ groups = self.groups.get(session)
+ if len(groups) == 0:
+ negotiator = self.negotiator.get(session)
+ action = self.app.model.negotiator.GetRawConfig
+ groups = action.do_invoke(negotiator, "GROUP_NAMES", 10)
+ try:
+ groups = self.split_group_names(groups['Value'])
+ except Exception, e:
+ groups = []
+ if len(groups):
+ self.groups.set(session, groups)
+ return groups
+
+ def split_group_names(self, group_string):
+ groups = []
+ gsplit = group_string.split()
+ if len(gsplit) < 2:
+ gsplit = group_string.split(",")
+ for group in gsplit:
+ group = group.replace(",", "")
+ group = group.replace(" ", "")
+ groups.append(group)
+ return groups
+
+ def get_group_raw_config(self, session, config, attrib, groups=None):
+ configs = attrib.get(session)
+
+ if len(configs) == 0:
+ if groups is None:
+ groups = self.get_group_names(session)
+ negotiator = self.negotiator.get(session)
+ action = self.app.model.negotiator.GetConfigSet
+
+ raw_configs = action.do_invoke(negotiator, groups, config,
"GetRawConfig", timeout=15)
+ for [group, data, status] in raw_configs:
+ configs.append([group, data['Value'], status])
+ attrib.set(session, configs)
+
+ return configs
+
+ def get_static_quota(self, session):
+ return self.get_group_raw_config(session,
+ "GROUP_QUOTA_",
+ self.group_static_quotas)
+
+ def get_dyn_quota(self, session):
+ return self.get_group_raw_config(session,
+ "GROUP_QUOTA_DYNAMIC_",
+ self.group_dyn_quotas)
+ def get_priority_factor(self, session):
+ return self.get_group_raw_config(session,
+ "GROUP_PRIO_FACTOR_",
+ self.group_factors)
+
+ def get_regroups(self, session):
+ return self.get_group_raw_config(session,
+ "GROUP_AUTOREGROUP_",
+ self.group_autoregroups)
+
+ def get_autoregroup(self, session):
+ return self.get_group_raw_config(session,
+ "GROUP_AUTOREGROUP",
+ self.autoregroup, [""])
+
+ def append_unclaimed_dyn_quota(self, session, quotas, force=False):
+ total = 0.0
+ for [group, value, status] in quotas:
+ try:
+ total = total + float(value)
+ except:
+ pass
+ if (total < 1.0) or force:
+ val = 1.0 - total
+ appended = list(quotas)
+ appended.append(['Unclaimed', str(val), ("OK", False,
True)])
+ return appended
+ else:
+ return quotas
+
+ class GroupAttribute(Attribute):
+ def get_default(self, session):
+ return list()
+
+class AddGroupForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(AddGroupForm, self).__init__(app, name, task)
+
+ self.defer_enabled = True
+
+ self.object = NegotiatorParameter(app, "negotiator")
+ self.add_parameter(self.object)
+
+ self.group_helper = GroupHelper(app, "groups", self.object)
+ self.add_child(self.group_helper)
+
+ self.group_name = Parameter(app, "name")
+ self.add_parameter(self.group_name)
+
+ def render_title(self, session):
+ return "Add Group"
+
+ def render_group_name_path(self, session):
+ return self.group_name.path
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ group_name = self.group_name.get(session)
+ original_groups = self.group_helper.get_group_names(session)
+
+ if self.is_valid(group_name):
+ original_groups.append(group_name)
+ new_groups = ", ".join(original_groups)
+ self.task.invoke(session, negotiator, "GROUP_NAMES", new_groups)
+ self.task.invoke(session, negotiator, "Reconfig", None)
+ self.task.exit_with_redirect(session, negotiator)
+
+ def is_valid(self, group):
+ ret = False
+ if len(group) and not "." in group and not " " in group:
+ ret = True
+ return ret
+
+class GroupForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(GroupForm, self).__init__(app, name, task)
+
+ self.defer_enabled = True
+
+ self.object = NegotiatorParameter(app, "negotiator")
+ self.add_parameter(self.object)
+
+ self.group_helper = GroupHelper(app, "groups", self.object)
+ self.add_child(self.group_helper)
+
+ group_name = Parameter(app, "gn")
+ self.add_parameter(group_name)
+
+ self.group_names = ListParameter(app, "group_names", group_name)
+ self.add_parameter(self.group_names)
+
+ original_value = Parameter(app, "ov")
+ self.add_parameter(original_value)
+
+ self.original_values = ListParameter(app, "original_values",
original_value)
+ self.add_parameter(self.original_values)
+
+ def render_group_name(self, session, group):
+ return group[0]
+
+ def render_group_name_path(self, session, group):
+ return self.group_names.path
+
+ def render_original_value_path(self, session, group):
+ return self.original_values.path
+
+class EditPrioFactorForm(GroupForm):
+ def __init__(self, app, name, task):
+ super(EditPrioFactorForm, self).__init__(app, name, task)
+
+ self.field_tmpl = Template(self, "field_html")
+
+ factor = Parameter(app, "factor")
+ self.add_parameter(factor)
+
+ self.factors = ListParameter(app, "factors", factor)
+ self.add_parameter(self.factors)
+
+ def render_title(self, session):
+ return "Edit Group Priority Factor"
+
+ def render_form_class(self, session):
+ return "PrioFactorForm"
+
+ def render_data_col_header(self, session):
+ return "Priority Factor"
+
+ def render_chart(self, session):
+ return None
+
+ def render_groups(self, session):
+ writer = Writer()
+
+ groups = self.group_helper.get_priority_factor(session)
+ for group in groups:
+ self.field_tmpl.render(writer, session, group)
+
+ return writer.to_string()
+
+ def render_factor_name(self, session, group):
+ return self.factors.path
+
+ def render_factor_value(self, session, group):
+ return group[2][2] and group[1] or "--NOT SET--"
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ factors = self.factors.get(session)
+ group_names = self.group_names.get(session)
+ original_values = self.original_values.get(session)
+
+ changed = False
+ for group, new_value, original_value in zip(group_names, factors,
original_values):
+ if new_value != original_value:
+ if self.is_valid_factor(new_value):
+ self.task.invoke(session, negotiator,
"GROUP_PRIO_FACTOR_"+group, new_value)
+ changed = True
+ if changed:
+ self.task.invoke(session, negotiator, "Reconfig", None)
+ self.task.exit_with_redirect(session, negotiator)
+
+ def is_valid_factor(self, value):
+ try:
+ factor = float(value)
+ except:
+ return False
+ return factor >= 1.0
+
+class EditDynamicQuotaForm(GroupForm):
+ def __init__(self, app, name, task):
+ super(EditDynamicQuotaForm, self).__init__(app, name, task)
+
+ self.field_tmpl = Template(self, "field_html")
+ self.unclaimed_tmpl = Template(self, "unclaimed_html")
+
+ quota = Parameter(app, "quota")
+ self.add_parameter(quota)
+
+ self.quotas = ListParameter(app, "quotas", quota)
+ self.add_parameter(self.quotas)
+
+ self.chart = PriorityPieChart(app, "chart", self.group_helper)
+ self.add_child(self.chart)
+
+ def render_title(self, session):
+ return "Edit Dynamic Group Quota"
+
+ def render_submit_content(self, session):
+ return "Change percentage"
+
+ def render_form_class(self, session):
+ return "priorityForm"
+
+ def render_data_col_header(self, session):
+ return "Percent of Slots"
+
+ def render_groups(self, session):
+ writer = Writer()
+
+ groups = self.group_helper.get_dyn_quota(session)
+ groups = self.group_helper.append_unclaimed_dyn_quota(session, groups,
force=True)
+ for group in groups:
+ if group[0] == "Unclaimed":
+ self.unclaimed_tmpl.render(writer, session, group)
+ else:
+ self.field_tmpl.render(writer, session, group)
+
+ return writer.to_string()
+
+ def render_quota_name(self, session, group):
+ return self.quotas.path
+
+ def render_quota_value(self, session, group):
+ return round(float(group[1]) * 100.0, 2)
+
+ def render_chart_id(self, session):
+ return self.chart.render_id(session)
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ quotas = self.quotas.get(session)
+ group_names = self.group_names.get(session)
+ original_values = self.original_values.get(session)
+
+ changed = False
+ for group, new_value, original_value in zip(group_names, quotas,
original_values):
+ if group == "Unclaimed":
+ continue
+ quota = self.check_quota(new_value, original_value)
+ if quota:
+ self.task.invoke(session, negotiator,
"GROUP_QUOTA_DYNAMIC_"+group, quota)
+ changed = True
+ if changed:
+ self.task.invoke(session, negotiator, "Reconfig", None)
+ self.task.exit_with_redirect(session, negotiator)
+
+ def check_quota(self, quota, original):
+ try:
+ pri = float(quota)
+ except:
+ return None
+ if pri < 0.0 or pri > 100.0:
+ return '0'
+
+ try:
+ original = float(original)
+ except:
+ original = 0
+ if pri == original:
+ return None
+
+ return str(pri / 100)
+
+class EditStaticQuotaForm(GroupForm):
+ def __init__(self, app, name, task):
+ super(EditStaticQuotaForm, self).__init__(app, name, task)
+
+ self.field_tmpl = Template(self, "field_html")
+
+ quota = Parameter(app, "quota")
+ self.add_parameter(quota)
+
+ self.quotas = ListParameter(app, "quotas", quota)
+ self.add_parameter(self.quotas)
+
+ def render_title(self, session):
+ return "Edit Static Group Quota"
+
+ def render_submit_content(self, session):
+ return "Change quota"
+
+ def render_form_class(self, session):
+ return "StaticQuotaForm"
+
+ def render_data_col_header(self, session):
+ return "Slots"
+
+ def render_chart(self, session):
+ return None
+
+ def render_groups(self, session):
+ writer = Writer()
+
+ groups = self.group_helper.get_static_quota(session)
+ for group in groups:
+ self.field_tmpl.render(writer, session, group)
+
+ return writer.to_string()
+
+ def render_quota_name(self, session, group):
+ return self.quotas.path
+
+ def render_quota_value(self, session, group):
+ return group[1]
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ quotas = self.quotas.get(session)
+ group_names = self.group_names.get(session)
+ original_values = self.original_values.get(session)
+
+ changed = False
+ for group, new_value, original_value in zip(group_names, quotas,
original_values):
+ if new_value != original_value:
+ self.task.invoke(session, negotiator, "GROUP_QUOTA_"+group,
new_value)
+ changed = True
+ if changed:
+ self.task.invoke(session, negotiator, "Reconfig", None)
+ self.task.exit_with_redirect(session, negotiator)
+
+class EditRegroupForm(GroupForm):
+ def __init__(self, app, name, task):
+ super(EditRegroupForm, self).__init__(app, name, task)
+
+ self.field_tmpl = Template(self, "field_html")
+
+ self.regroup = DictParameter(app, "regroup")
+ self.add_parameter(self.regroup)
+
+ original_regroup = Parameter(app, "or")
+ self.add_parameter(original_regroup)
+
+ self.original_regroups = ListParameter(app, "original_regroups",
original_regroup)
+ self.add_parameter(self.original_regroups)
+
+ def render_title(self, session):
+ return "Edit Autoregroup"
+
+ def render_form_class(self, session):
+ return "StaticQuotaForm"
+
+ def render_data_col_header(self, session):
+ return "Autoregroup"
+
+ def render_chart(self, session):
+ return None
+
+ def render_groups(self, session):
+ writer = Writer()
+
+ regroups = list(self.group_helper.get_regroups(session))
+ autoregroup = self.group_helper.get_autoregroup(session)
+ autoregroup[0][0] = "Default"
+ regroups.append(autoregroup[0])
+ for regroup in regroups:
+ self.field_tmpl.render(writer, session, regroup)
+
+ return writer.to_string()
+
+ def render_regroup_selected_TRUE(self, session, regroup):
+ if regroup[2][2]:
+ return (regroup[1] == 'TRUE') and
"checked=\"checked\"" or ""
+
+ def render_regroup_selected_FALSE(self, session, regroup):
+ if regroup[2][2]:
+ return (regroup[1] == 'FALSE') and
"checked=\"checked\"" or ""
+
+ def render_regroup_selected_UNDEFINED(self, session, regroup):
+ if not regroup[2][2]:
+ return "checked=\"checked\""
+
+ def render_regroup_path(self, session, regroup):
+ return self.regroup.get_instance_key(regroup[0])
+
+ def render_original_regroup_path(self, session, regroup):
+ return self.original_regroups.path
+
+ def render_regroup_value(self, session, regroup):
+ return regroup[2][2] and regroup[1] or "UNDEFINED"
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ regroup = self.regroup.get(session)
+ group_names = self.group_names.get(session)
+ original_regroups = self.original_regroups.get(session)
+
+ changed = False
+ for group, original_value in zip(group_names, original_regroups):
+ if regroup[group] != original_value:
+ if group == "Default":
+ self.task.invoke(session, negotiator, "AUTOREGROUP",
regroup[group])
+ else:
+ self.task.invoke(session, negotiator,
"GROUP_AUTOREGROUP_"+group, regroup[group])
+ changed = True
+ if changed:
+ self.task.invoke(session, negotiator, "Reconfig", None)
+ self.task.exit_with_redirect(session, negotiator)
+
+class PriorityPieChart(StatFlashChart):
+ def __init__(self, app, name, groups):
+ super(PriorityPieChart, self).__init__(app, name)
+
+ self.chart_type = "pie"
+ self.fullpageable = False
+ self.update_enabled = False
+
+ self.groups = groups
+
+ def get_args(self, session):
+ return (self.frame.object.get(session),)
+
+ def render_title(self, session, object):
+ pass
+
+ def render_duration(self, session, *args):
+ pass
+
+ def render_width(self, session, *args):
+ return 360
+
+ def render_height(self, session, *args):
+ return 210
+
+
+ def get_href_params(self, session, object):
+ params = super(PriorityPieChart, self).get_href_params(session, object)
+ params.append("width=%i" % self.render_width(session))
+ params.append("height=%i" % self.render_height(session))
+
+ # send the group names and values to the chart page so we
+ # don't have to get them again
+ values = self.groups.get_dyn_quota(session)
+ values = self.groups.append_unclaimed_dyn_quota(session, values)
+ names = ["name=%s" % x[0] for x in values]
+ params.extend(names)
+ vals = ["value=%s" % str(x[1]) for x in values]
+ params.extend(vals)
+ return params
+
class NegotiatorStartForm(CuminTaskForm):
def __init__(self, app, name, task):
super(NegotiatorStartForm, self).__init__(app, name, task)
@@ -135,3 +737,11 @@
self.object = ListParameter(app, "negotiator", item)
self.add_parameter(self.object)
+
+class EditButton(ActionSet):
+ def __init__(self, app, name, negotiator, task):
+ super(EditButton, self).__init__(app, name)
+
+ link = TaskLink(app, "edit", task, negotiator)
+ self.add_child(link)
+
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-08-12 18:44:22 UTC (rev
3570)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-08-12 18:47:08 UTC (rev
3571)
@@ -15,3 +15,404 @@
select count(1) from negotiator as n
left outer join negotiator_stats as c on c.id = n.stats_curr_id
{sql_where}
+
+[GroupForm.css]
+div.deferredSpacer {
+ height: 10em;
+ background-color: #FFFFFF;
+ padding: 1em;
+}
+
+div.invalid {
+ font-size: .8em;
+ color: red;
+}
+
+[GroupForm.html]
+<form id="{id}" class="mform {form_class}" method="post"
action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <table class="PropertySet GroupPriorities">
+ <thead>
+ <tr>
+ <th>Group</th> <th>{data_col_header}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {groups}
+ </tbody>
+ </table>
+ {chart}<div style="clear:left;"><!-- --></div>
+ </div>
+ <div class="foot">
+ {submit}
+ {cancel}
+ </div>
+ <div>{hidden_inputs}</div>
+</form>
+<script type="text/javascript">
+<![CDATA[
+(function() {
+wooly.addPageUpdateListener( cumin.initializeGroupForm );
+}())
+]]>
+</script>
+
+[EditDynamicQuotaForm.css]
+form.priorityForm {
+ width: 60em !important;
+}
+form.priorityForm table, form.priorityForm div.StatValueChart {
+ float: left;
+}
+form.priorityForm table.GroupPriorities {
+ width: 50%;
+}
+form.priorityForm div.priorityChart {
+ margin-left: 2em;
+}
+form.priorityForm input {
+ text-align: right;
+}
+table.GroupPriorities input.disabled {
+ background-color: #FFF;
+ color: #555;
+ border: 0px solid #FFF;
+}
+
+div.slider {
+ width: 200px;
+ height: 2px;
+ background: #eee;
+ position: relative;
+ top: 8px;
+ border: 1px solid #000;
+}
+div.slider div.knob {
+ background: #000;
+ width: 8px;
+ height: 16px;
+ top: -7px;
+}
+
+.validation-failed {
+ border: 1px solid #f00;
+}
+
+[EditDynamicQuotaForm.javascript]
+cumin.init_sliders = function(priority_chart_id){
+ $$('div.slider').each(function(el, i){
+ var input = el.getParent("tr").getElement("input");
+ var val = input.value.toFloat();
+ var initial_knob = val * 100;
+ var slider = new Slider(el, el.getElement('.knob'), {
+ steps: 10000, // Steps from 0 to 100
+ range: [0, 10000], // min and max value
+ onChange: function (pos) {
+ var new_values = new Array();
+ var changedEl = this.element;
+ var changedInp =
changedEl.getParent("tr").getElement("input");
+ changedInp.value = (Math.round(pos) / 100) + "";
+ // get the new total percent
+ var sum = 0.0;
+ var changedIndex = 0;
+ $$('div.slider').each(function (el, i) {
+ var inp =
el.getParent("tr").getElement("input");
+ var val = parseFloat(inp.value);
+ sum += val;
+ new_values[new_values.length] = {'value': val,
'label': el.id, 'on-show': false };
+ if (el == changedEl)
+ changedIndex = new_values.length - 1;
+ });
+ if (sum > 100) {
+ var mySlider = changedEl.retrieve("myslider");
+ var val = pos - (sum - 100) * 100;
+ mySlider.set(val);
+ changedInp.value = (Math.round(val) / 100) + "";
+ new_values[changedIndex] = {'value': val / 100,
'label': changedEl.id, 'on-show': false };
+ }
+
+ var unclaimed = document.getElementById('Unclaimed');
+ if (unclaimed) {
+ if (sum < 100.0) {
+ var val = (100.0 - sum);
+ unclaimed.value = (Math.round(val * 100) / 100) + "";
+ new_values[new_values.length] = {'value': val,
'label': 'Unclaimed', 'on-show': false };
+ } else {
+ unclaimed.value = "0.0";
+ }
+ }
+
+ var chart = cumin.getFlashChart(priority_chart_id);
+ if (chart) {
+ var obj = {'values': new_values};
+ var myJson = JSON.encode(obj);
+ chart.setpieslice(changedEl.id, myJson);
+ }
+ }
+ }).set(initial_knob, false);
+ el.store('myslider', slider);
+ });
+}
+
+[EditDynamicQuotaForm.field_html]
+<tr>
+ <td>
+ {group_name}
+ </td>
+ <td>
+ <input class="validate-numeric IsPercent" type="text"
name="{quota_name}" value="{quota_value}"
+ size="6" tabindex="100"/>
+ <!-- these are here so we don't need to reget the groups and values after a
submit -->
+ <input type="hidden" name="{group_name_path}"
value="{group_name}" />
+ <input type="hidden" name="{original_value_path}"
value="{quota_value}" />
+ </td>
+ <td>
+ <div id="{group_name}" class="slider"><div
class="knob"></div></div>
+ </td>
+</tr>
+
+[EditDynamicQuotaForm.unclaimed_html]
+<tr>
+ <td>
+ {group_name}
+ </td>
+ <td>
+ <input id="{group_name}" class="disabled"
disabled="disabled" type="text" name="{quota_name}"
value="{quota_value}"
+ size="6" tabindex="100"/>
+ <!-- these are here so we don't need to reget the groups and values after a
submit -->
+ <input type="hidden" name="{group_name_path}"
value="{group_name}" />
+ <input type="hidden" name="{original_value_path}"
value="{quota_value}" />
+ </td>
+</tr>
+
+[EditDynamicQuotaForm.deferred_html]
+<form id="{id}" class="mform priorityForm" method="post"
action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <div class="deferredSpacer">Loading...</div>
+ </div>
+</form>
+<script type="text/javascript">
+<![CDATA[
+cumin.initializeGroupForm = function () {
+ var elem = $("{id}").elements[0];
+ elem.focus();
+ cumin.init_sliders("{chart_id}");
+
+ var myFormValidator = new FormValidator($('{id}'), {
+ onElementPass: function (el) {
+ var val = el.value.toFloat();
+ var sliderDiv =
el.getParent("tr").getElement(".slider");
+ if (sliderDiv) {
+ var myslider = sliderDiv.retrieve('myslider');
+ if (myslider)
+ myslider.set(val * 100);
+ }
+ },
+ onElementFail: function (el, validators) {
+ //alert('failed');
+ },
+ evaluateOnSubmit: false,
+ evaluateFieldsOnBlur: false
+ });
+ myFormValidator.add('IsPercent', {
+ errorMsg: 'Values must be between 0 and 100.',
+ test: function(element) {
+ var val = element.get('value').toFloat();
+ return ((val >= 0) && (val <= 100))
+ }
+ });
+}
+]]>
+</script>
+
+[EditStaticQuotaForm.css]
+form.StaticQuotaForm {
+ width: 30em;
+}
+
+[EditStaticQuotaForm.field_html]
+<tr>
+ <td>
+ {group_name}
+ </td>
+ <td>
+ <input class="validate-numeric" type="text"
name="{quota_name}" value="{quota_value}"
+ size="6" tabindex="100"/>
+ <!-- these are here so we don't need to reget the groups and values after a
submit -->
+ <input type="hidden" name="{group_name_path}"
value="{group_name}" />
+ <input type="hidden" name="{original_value_path}"
value="{quota_value}" />
+ </td>
+</tr>
+
+[EditStaticQuotaForm.deferred_html]
+<form id="{id}" class="mform StaticQuotaForm"
method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <div class="deferredSpacer">Loading...</div>
+ </div>
+</form>
+<script type="text/javascript">
+<![CDATA[
+cumin.initializeGroupForm = function () {
+ var elem = $("{id}").elements[0];
+ elem.focus();
+
+ var myFormValidator = new FormValidator($('{id}'), {
+ evaluateOnSubmit: false,
+ evaluateFieldsOnBlur: false
+ });
+}
+]]>
+</script>
+
+[EditPrioFactorForm.css]
+form.mform.PrioFactorForm {
+ width: 32em;
+}
+[EditPrioFactorForm.field_html]
+<tr>
+ <td>
+ {group_name}
+ </td>
+ <td>
+ <input class="validate-numeric OneOrMore" type="text"
name="{factor_name}" value="{factor_value}"
+ size="10" tabindex="100"/> <div
class="invalid"></div>
+ <!-- these are here so we don't need to reget the groups and values after a
submit -->
+ <input type="hidden" name="{group_name_path}"
value="{group_name}" />
+ <input type="hidden" name="{original_value_path}"
value="{factor_value}" />
+ </td>
+</tr>
+
+[EditPrioFactorForm.deferred_html]
+<form id="{id}" class="mform PrioFactorForm"
method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <div class="deferredSpacer">Loading...</div>
+ </div>
+</form>
+<script type="text/javascript">
+<![CDATA[
+cumin.initializeGroupForm = function () {
+ var elem = $("{id}").elements[0];
+ elem.focus();
+
+ var myFormValidator = new FormValidator($('{id}'), {
+ evaluateOnSubmit: false,
+ evaluateFieldsOnBlur: false,
+ onElementFail: function (el, validators) {
+ var span = el.getParent("td").getElement("div");
+ if (validators[0] == "validate-numeric")
+ span.set('text', "Must be a number.");
+ else
+ span.set('text', "Must be 1.0 or greater.");
+ },
+ onElementPass: function (el) {
+ el.getParent("td").getElement("div").set('text',
"");
+ }
+ });
+
+ myFormValidator.add('OneOrMore', {
+ errorMsg: 'Values must be 1 or greater.',
+ test: function(element) {
+ var val = element.get('value').toFloat();
+ return (val >= 1);
+ }
+ });
+}
+]]>
+</script>
+
+[EditRegroupForm.field_html]
+<tr>
+ <td>
+ {group_name}
+ <input type="hidden" name="{group_name_path}"
value="{group_name}" />
+ </td>
+ <td>
+ <input type="radio" name="{regroup_path}"
{regroup_selected_TRUE} id="regroup_{group_name}_TRUE" value="TRUE"
/> <label for="regroup_{group_name}_TRUE">TRUE</label>
+ <input type="radio" name="{regroup_path}"
{regroup_selected_FALSE} id="regroup_{group_name}_FALSE" value="FALSE"
/> <label for="regroup_{group_name}_FALSE">FALSE</label>
+ <input type="radio" name="{regroup_path}"
{regroup_selected_UNDEFINED} id="regroup_{group_name}_UNDEFINED"
value="UNDEFINED" /> <label
for="regroup_{group_name}_UNDEFINED">NOT SET</label>
+ <input type="hidden" name="{original_regroup_path}"
value="{regroup_value}" />
+ </td>
+</tr>
+
+[EditRegroupForm.deferred_html]
+<form id="{id}" class="mform StaticQuotaForm"
method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <div class="deferredSpacer">Loading...</div>
+ </div>
+</form>
+
+[AddGroupForm.css]
+form.mform.AddForm {
+ width: 30em;
+}
+form.mform.AddForm div.label, form.mform.AddForm input {
+ float: left;
+ margin: 1em 0 1em 1em;
+}
+
+[AddGroupForm.html]
+<form id="{id}" class="mform AddForm" method="post"
action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <div class="label">Group Name</div>
+ <input class="validate-nodot" type="text"
name="{group_name_path}" value="" size="20"
maxlength="40" />
+ <div style="clear: left;"><!-- --></div>
+ <div class="invalid"></div>
+ </div>
+ <div class="foot">
+ {submit}
+ {cancel}
+ </div>
+ <div>{hidden_inputs}</div>
+</form>
+<script type="text/javascript">
+<![CDATA[
+window.addEvent('domready', function () {
+ var elem = $("{id}").elements[0];
+ elem.focus();
+
+ var myFormValidator = new FormValidator($('{id}'), {
+ evaluateOnSubmit: false,
+ evaluateFieldsOnBlur: false,
+ onElementFail: function (el, validators) {
+ var span =
el.getParent("div").getElement("div.invalid");
+ span.set('text', "Must not contain a .");
+ },
+ onElementPass: function (el) {
+
el.getParent("div").getElement("div.invalid").set('text',
"");
+ }
+ });
+
+ myFormValidator.add('validate-nodot', {
+ errorMsg: '',
+ test: function(element) {
+ var bool = element.get('value').test(/\./,'i');
+ return !bool;
+ }
+ });
+});
+]]>
+</script>
+
+[EditButton.html]
+<ul class="actions">
+ <li>{edit}</li>
+</ul>
+