Author: eallen
Date: 2009-08-14 16:05:40 -0400 (Fri, 14 Aug 2009)
New Revision: 3581
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 ability to show/edit user.group config settings.
Modified: mgmt/trunk/cumin/python/cumin/grid/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/main.py 2009-08-14 20:03:08 UTC (rev 3580)
+++ mgmt/trunk/cumin/python/cumin/grid/main.py 2009-08-14 20:05:40 UTC (rev 3581)
@@ -42,7 +42,9 @@
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_user_prio_factor = NegotiatorUserPrioFactorTask(app, negotiator)
self.negotiator_edit_regroup = NegotiatorEditRegroupTask(app, negotiator)
+ self.negotiator_user_regroup = NegotiatorUserRegroupTask(app, negotiator)
self.negotiator_add_group = NegotiatorAddGroupTask(app, negotiator)
self.frame = GridFrame(app, "grid")
Modified: mgmt/trunk/cumin/python/cumin/grid/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/model.py 2009-08-14 20:03:08 UTC (rev 3580)
+++ mgmt/trunk/cumin/python/cumin/grid/model.py 2009-08-14 20:05:40 UTC (rev 3581)
@@ -396,3 +396,30 @@
def get_title(self, session):
return "Edit Static Quota"
+
+class NegotiatorUserTask(NegotiatorGroupTask):
+ def do_enter(self, session, ng):
+ try:
+ negotiator, group = ng
+ except:
+ raise Exception("Must supply group for user forms")
+ super(NegotiatorUserTask, self).do_enter(session, negotiator)
+ self.form.group.set(session, group)
+
+class NegotiatorUserPrioFactorTask(NegotiatorUserTask):
+ def __init__(self, app, cls):
+ super(NegotiatorUserPrioFactorTask, self).__init__(app, cls)
+
+ self.form = UserPrioFactorForm(self.app, "negotiator_user_prio_factor",
self)
+
+ def get_title(self, session):
+ return "Edit Priority Factor"
+
+class NegotiatorUserRegroupTask(NegotiatorUserTask):
+ def __init__(self, app, cls):
+ super(NegotiatorUserRegroupTask, self).__init__(app, cls)
+
+ self.form = UserRegroupForm(self.app, "negotiator_user_regroup", self)
+
+ def get_title(self, session):
+ return "Edit Autoregroup"
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.py 2009-08-14 20:03:08 UTC (rev 3580)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.py 2009-08-14 20:05:40 UTC (rev 3581)
@@ -10,6 +10,7 @@
from cumin.formats import *
from cumin.util import *
+from submitter import SubmitterSet
import main
strings = StringCatalog(__file__)
@@ -93,72 +94,101 @@
self.__tabs.add_tab(details)
class QmfGroupColumn(ItemTableColumn):
- def __init__(self, app, name, getter, button):
+ def __init__(self, app, name, getter, negotiator, task):
super(QmfGroupColumn, self).__init__(app, name)
+ self.header_class = TopTableColumnHeader
+
self.title = None
self.getter = getter
self.alignment = "right"
- self.button = button
+ self.user = False
+ self.negotiator = negotiator
+ self.task = task
+ self.user_task = None
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)
- elif group == self.parent.empty_row:
- return ""
-
data = self.getter(session)
for x in data:
if x[0] == group:
- return self.render_data(x)
+ return self.render_data(session, x)
+ if self.user:
+ data = self.getter(session, [group], True)
+ for x in data:
+ if x[0] == group:
+ return self.render_data(session, x)
+
+ return ""
+
+ def render_data(self, session, data):
+ # is user
+ if "." in data[0] and self.user_task:
+ href = "%s" % self.user_task.get_href(session,
(self.negotiator.get(session), data[0]))
+ else:
+ href = self.task.get_href(session, self.negotiator.get(session))
+ content = data[2][2] and str(data[1]) or "NOT SET"
+ return fmt_link(href, content, "", "",
self.fmt_hover(data[0]))
+
+ def fmt_hover(self, group):
+ return "Edit the %s" % self.title
+
class NegotiatorOverviewTab(ItemTable):
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.expand = self.ExpandSwitch(app, "expand")
+ self.add_child(self.expand)
+
+ self.buttons = WidgetSet(app, "buttons")
+ self.buttons.html_class = "buttons"
+ self.add_child(self.buttons)
+
+ task = main.module.negotiator_add_group
+ button = EditButton(app, "add_group_button", task, negotiator)
+ self.buttons.add_child(button)
+
+ col = self.ExpandColumn(app, "expand_col")
+ col.header_class = TopTableColumnHeader
self.add_column(col)
+
+ col = self.GroupColumn(app, "group")
+ 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 = self.DynamicColumn(app, "dynamic",
self.group_helper.get_dyn_quota, negotiator, task)
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 = QmfGroupColumn(app, "static", self.group_helper.get_static_quota,
negotiator, task)
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 = QmfGroupColumn(app, "factor",
self.group_helper.get_priority_factor, negotiator, task)
col.title = "Priority Factor"
+ col.user = True
+ col.user_task = main.module.negotiator_user_prio_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 = QmfGroupColumn(app, "regroup", self.group_helper.get_regroups,
negotiator, task)
col.title = "Auto Regroup"
+ col.user = True
+ col.user_task = main.module.negotiator_user_regroup
self.add_column(col)
- self.buttons_row = "__buttons__"
- self.empty_row = "__empty__"
-
def render_title(self, session):
return "Group Configuration"
@@ -170,49 +200,82 @@
def do_get_items(self, session, *args):
groups = self.group_helper.get_group_names(session)
- items = list(groups)
+ users = self.group_helper.get_users(session, groups)
+ self.expand.initialize(session, groups, users)
+
+ names = list(groups)
if self.reversed.get(session):
- items = reversed(items)
+ names = reversed(names)
- if len(items):
- items.append(self.buttons_row)
- else:
- items.append(self.empty_row)
+ # if current expanded group has users
+ expanded = self.expand.get(session)
+ if expanded in users:
+ self.group_helper.get_priority_factor(session, users[expanded], True)
+ self.group_helper.get_regroups(session, users[expanded], True)
+
+ # insert the users into the list
+ items = list()
+ for name in names:
+ items.append(name)
+ if name == expanded and expanded in users:
+ items.extend(users[expanded])
+
return items
- class GroupColumn(ItemTableColumn):
- def __init__(self, app, name, negotiator):
- super(NegotiatorOverviewTab.GroupColumn, self).__init__(app, name)
+ class ExpandColumn(ItemTableColumn):
+ def render_title(self, session, *args):
+ return ""
- task = main.module.negotiator_add_group
- self.button = EditButton(app, "add_group_button", negotiator,
task)
- self.add_child(self.button)
+ def get_class_list(self, session):
+ return ["expand"]
+ def render_content(self, session, group):
+ if self.parent.expand.get_title(session, group):
+ return self.parent.expand.render_item_link(session, group)
+ else:
+ return ""
+
+ class GroupColumn(ItemTableColumn):
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)
+ # if a user
+ if "." in group:
+ (g, sep, user) = group.partition(".")
+ return "<span style='padding-left:
2em;'>%s</span>" % user
return group
class DynamicColumn(QmfGroupColumn):
- def render_data(self, data):
- return round(float(data[1]) * 100.0, 2)
+ def render_data(self, session, data):
+ href = self.task.get_href(session, self.negotiator.get(session))
+ content = "%s%%" % str(round(float(data[1]) * 100.0, 2))
+ return fmt_link(href, content, "", "",
self.fmt_hover(data[0]))
- class StaticColumn(QmfGroupColumn):
- def render_data(self, data):
- return data[2][2] and data[1] or "-"
+ class ExpandSwitch(DynamicSwitch):
+ def render_item_link(self, session, state):
+ branch = session.branch()
+ expanded = self.get(session) == state
- class FactorColumn(QmfGroupColumn):
- def render_data(self, data):
- return data[2][2] and data[1] or "-"
+ if expanded:
+ self.set(branch, "")
+ else:
+ self.set(branch, state)
- class RegroupColumn(QmfGroupColumn):
- def render_data(self, data):
- return data[1]
+ content = expanded and "[-]" or "[+]"
+ verb = expanded and "Hide" or "Show"
+ hover = self.get_hover(session, state) % verb
+ return fmt_link(branch.marshal(), content, "", link_title=hover)
+
+ def initialize(self, session, groups, users):
+ if len(self.get_items(session)) == 0:
+ for group in groups:
+ if group in users:
+ self.add_state(session, group, "+", hover="%%s
users for %s" % group)
+ self.param.default = None
+
class GroupHelper(Widget):
def __init__(self, app, name, negotiator):
super(GroupHelper, self).__init__(app, name)
@@ -229,14 +292,24 @@
self.group_autoregroups = self.GroupAttribute(app,
"group_autoregroups")
self.add_attribute(self.group_autoregroups)
+ self.user_autoregroups = self.GroupAttribute(app, "user_autoregroups")
+ self.add_attribute(self.user_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.user_factors = self.GroupAttribute(app, "user_factors")
+ self.add_attribute(self.user_factors)
+
self.negotiator = negotiator
+ self.users = self.Users(app, "users")
+ self.users.update_enabled = False
+ self.add_child(self.users)
+
def get_group_names(self, session):
groups = self.groups.get(session)
if len(groups) == 0:
@@ -262,8 +335,8 @@
groups.append(group)
return groups
- def get_group_raw_config(self, session, config, attrib, groups=None):
- configs = attrib.get(session)
+ def get_group_raw_config(self, session, config, param, groups=None):
+ configs = param.get(session)
if len(configs) == 0:
if groups is None:
@@ -274,7 +347,7 @@
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)
+ param.set(session, configs)
return configs
@@ -287,21 +360,27 @@
return self.get_group_raw_config(session,
"GROUP_QUOTA_DYNAMIC_",
self.group_dyn_quotas)
- def get_priority_factor(self, session):
+
+ def get_priority_factor(self, session, groups=None, user=False):
+ param = user and self.user_factors or self.group_factors
return self.get_group_raw_config(session,
"GROUP_PRIO_FACTOR_",
- self.group_factors)
+ param, groups)
- def get_regroups(self, session):
+ def get_regroups(self, session, groups=None, user=False):
+ param = user and self.user_autoregroups or self.group_autoregroups
return self.get_group_raw_config(session,
"GROUP_AUTOREGROUP_",
- self.group_autoregroups)
+ param, groups)
def get_autoregroup(self, session):
return self.get_group_raw_config(session,
"GROUP_AUTOREGROUP",
self.autoregroup, [""])
+ def get_users(self, session, groups):
+ return self.users.get(session, groups)
+
def append_unclaimed_dyn_quota(self, session, quotas, force=False):
total = 0.0
for [group, value, status] in quotas:
@@ -321,6 +400,27 @@
def get_default(self, session):
return list()
+ class Users(SubmitterSet):
+ def get(self, session, groups):
+ #returns {group: [user, user], group: [user, user], ...}
+ users = self.items.get(session)
+ if not users:
+ items = self.get_items(session)
+ user_names = [x[1] for x in items]
+ users = dict()
+ for group in groups:
+ for user_name in user_names:
+ if user_name.startswith("%s." % group):
+ if not group in users:
+ users[group] = list()
+ users[group].append(user_name)
+
+ self.items.set(session, users)
+ return users
+
+ def render_sql_limit(self, session, *args):
+ return ""
+
class AddGroupForm(CuminTaskForm):
def __init__(self, app, name, task):
super(AddGroupForm, self).__init__(app, name, task)
@@ -393,6 +493,9 @@
def render_original_value_path(self, session, group):
return self.original_values.path
+ def render_form_class(self, session):
+ return ""
+
class EditPrioFactorForm(GroupForm):
def __init__(self, app, name, task):
super(EditPrioFactorForm, self).__init__(app, name, task)
@@ -455,6 +558,45 @@
return False
return factor >= 1.0
+class UserPrioFactorForm(EditPrioFactorForm):
+ def __init__(self, app, name, task):
+ super(UserPrioFactorForm, self).__init__(app, name, task)
+
+ self.group = Parameter(app, "group")
+ self.add_parameter(self.group)
+
+ def render_title(self, session):
+ return "Edit User Priority Factor"
+
+ def render_groups(self, session):
+ writer = Writer()
+
+ group = self.group.get(session)
+ users = list(self.group_helper.get_priority_factor(session, [group], True))
+ for user in users:
+ self.field_tmpl.render(writer, session, user)
+
+ return writer.to_string()
+
+ def render_form_class(self, session):
+ return "UserPrioFactorForm"
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ factors = self.factors.get(session)
+ group = self.group.get(session)
+ original_values = self.original_values.get(session)
+
+ changed = False
+ for user, new_value, original_value in zip([group], factors, original_values):
+ if new_value != original_value:
+ if self.is_valid_factor(new_value):
+ self.task.invoke(session, negotiator,
"GROUP_PRIO_FACTOR_"+user, new_value)
+ changed = True
+ if changed:
+ self.task.invoke(session, negotiator, "Reconfig", None)
+ self.task.exit_with_redirect(session, negotiator)
+
class EditDynamicQuotaForm(GroupForm):
def __init__(self, app, name, task):
super(EditDynamicQuotaForm, self).__init__(app, name, task)
@@ -675,6 +817,41 @@
self.task.invoke(session, negotiator, "Reconfig", None)
self.task.exit_with_redirect(session, negotiator)
+class UserRegroupForm(EditRegroupForm):
+ def __init__(self, app, name, task):
+ super(UserRegroupForm, self).__init__(app, name, task)
+
+ self.group = Parameter(app, "group")
+ self.add_parameter(self.group)
+
+ def render_groups(self, session):
+ writer = Writer()
+
+ group = self.group.get(session)
+ regroups = list(self.group_helper.get_regroups(session, [group], True))
+ for regroup in regroups:
+ self.field_tmpl.render(writer, session, regroup)
+
+ return writer.to_string()
+
+ def render_form_class(self, session):
+ return "UserRegroupForm"
+
+ def process_submit(self, session):
+ negotiator = self.object.get(session)
+ regroup = self.regroup.get(session)
+ group = self.group.get(session)
+ original_regroups = self.original_regroups.get(session)
+
+ changed = False
+ for user, original_value in zip([group], original_regroups):
+ if regroup[user] != original_value:
+ self.task.invoke(session, negotiator,
"GROUP_AUTOREGROUP_"+user, regroup[user])
+ 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)
@@ -740,7 +917,7 @@
self.add_parameter(self.object)
class EditButton(ActionSet):
- def __init__(self, app, name, negotiator, task):
+ def __init__(self, app, name, task, negotiator):
super(EditButton, self).__init__(app, name)
link = TaskLink(app, "edit", task, negotiator)
Modified: mgmt/trunk/cumin/python/cumin/grid/negotiator.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-08-14 20:03:08 UTC (rev
3580)
+++ mgmt/trunk/cumin/python/cumin/grid/negotiator.strings 2009-08-14 20:05:40 UTC (rev
3581)
@@ -16,6 +16,26 @@
left outer join negotiator_stats as c on c.id = n.stats_curr_id
{sql_where}
+[NegotiatorOverviewTab.css]
+div.GroupTable ul.actions {
+ display: inline;
+}
+div.GroupTable div.sactions {
+ padding: 0.75em;
+}
+
+[NegotiatorOverviewTab.html]
+<div id="{id}" class="CuminTable GroupTable">
+ <div class="sactions">
+ <h2>Actions:</h2>
+ {buttons}
+ </div>
+<table {class}>
+ <thead><tr>{headers}</tr></thead>
+ <tbody>{items}</tbody>
+</table>
+</div>
+
[GroupForm.css]
div.deferredSpacer {
height: 10em;
@@ -277,6 +297,13 @@
form.mform.PrioFactorForm {
width: 32em;
}
+form.mform.UserPrioFactorForm {
+ width: 40em;
+}
+form.mform.UserRegroupForm {
+ width: 48em;
+}
+
[EditPrioFactorForm.field_html]
<tr>
<td>
@@ -416,3 +443,8 @@
<li>{edit}</li>
</ul>
+[ExpandColumn.css]
+th.expand {
+ width: 1em;
+ padding: 0;
+}