[luci] Fix bits that went missing for the new "add user" functionality
by Ryan McCabe
commit bf744db30c9c1cd8e6611317092ab1c8983da67d
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Mon Jan 23 11:20:32 2012 -0500
Fix bits that went missing for the new "add user" functionality
luci/public/js/admin.js | 14 ++++++++++++++
luci/templates/admin.html | 3 ++-
2 files changed, 16 insertions(+), 1 deletions(-)
---
diff --git a/luci/public/js/admin.js b/luci/public/js/admin.js
new file mode 100644
index 0000000..b09672c
--- /dev/null
+++ b/luci/public/js/admin.js
@@ -0,0 +1,14 @@
+$(function() {
+ $('#add_user_dialog').dialog({
+ modal: true,
+ title: 'Add a User',
+ width: '720px',
+ autoOpen: false,
+ draggable: false,
+ resizable: true,
+ closeOnEscape: false,
+ open: function(event, ui) {
+ $(this).parent().children().children('.ui-dialog-titlebar-close').hide();
+ },
+ });
+})
diff --git a/luci/templates/admin.html b/luci/templates/admin.html
index 1380e0c..10a0d39 100644
--- a/luci/templates/admin.html
+++ b/luci/templates/admin.html
@@ -251,7 +251,7 @@
</div>
</div>
</div>
-
+ <div class="hidden">
<div id="add_user_dialog">
<form name="manage_create_user" method="post" action="${tg.url('admin_cmd' + '?command=create')}">
<div class="row">
@@ -265,5 +265,6 @@
</div>
</form>
</div>
+ </div>
</body>
</html>
12 years, 5 months
[luci] Bump version
by Ryan McCabe
commit 7e42e40fa14d62b06a29467c171d989bc2fd0490
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Mon Jan 23 10:28:24 2012 -0500
Bump version
luci.spec | 5 ++++-
luci/__init__.py | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
---
diff --git a/luci.spec b/luci.spec
index 2582682..0e1437a 100644
--- a/luci.spec
+++ b/luci.spec
@@ -51,7 +51,7 @@
## global alphatag 0.b9faf868074git
Name: luci
-Version: 0.25.0
+Version: 0.26.0
Release: 1%{?alphatag:.%{alphatag}}%{?dist}
Summary: Web-based high availability administration application
@@ -240,6 +240,9 @@ fi
%changelog
+* Mon Jan 23 2012 Ryan McCabe <rmccabe(a)redhat.com> - 0.26.0-1
+- New upstream release 0.26.0
+
* Mon Aug 01 2011 Ryan McCabe <rmccabe(a)redhat.com> - 0.25.0-1
- New upstream release 0.25.0
diff --git a/luci/__init__.py b/luci/__init__.py
index 8e80815..26c3f2b 100644
--- a/luci/__init__.py
+++ b/luci/__init__.py
@@ -26,7 +26,7 @@ Eve McGlynn
Jeremy Perry
"""
-__version__ = '0.25.0'
+__version__ = '0.26.0'
__licence__ = 'GPLv2'
__author__ = ", ".join(
[a.partition(' <')[0] for a in authors.strip().split('\n')]
12 years, 5 months
[luci] Fix typo
by Ryan McCabe
commit 9fc1c54fdc15bb3317e78b7cabdd1fd7d2fab052
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:53:03 2012 -0500
Fix typo
luci/templates/create_cluster.html | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
---
diff --git a/luci/templates/create_cluster.html b/luci/templates/create_cluster.html
index 5a0095c..e86203e 100644
--- a/luci/templates/create_cluster.html
+++ b/luci/templates/create_cluster.html
@@ -41,7 +41,7 @@
</div>
<div class="row">
<input type="checkbox" class="checkbox" name="reboot_nodes" />
- <label class="choice">Reboot Rodes Before Joining Cluster</label>
+ <label class="choice">Reboot Nodes Before Joining Cluster</label>
</div>
<div class="row">
<input type="checkbox" class="checkbox" name="shared_storage" />
12 years, 5 months
[luci] Add the display of "force_unmount" filesystem attribute which had been accidentally omitted.
by Ryan McCabe
commit f6f510ae0da9553dc9da1207771b8bbbb2f4ec75
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:36:31 2012 -0500
Add the display of "force_unmount" filesystem attribute which had been accidentally omitted.
luci/templates/resource_list.html | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
---
diff --git a/luci/templates/resource_list.html b/luci/templates/resource_list.html
index 387f275..9cb0828 100644
--- a/luci/templates/resource_list.html
+++ b/luci/templates/resource_list.html
@@ -198,6 +198,13 @@
</td>
</tr>
<tr>
+ <td>Force Unmount</td>
+ <td>
+ <input type="checkbox" class="checkbox" name="force_unmount"
+ py:attrs="{'checked':(res and res.getAttribute('force_unmount')) and 'checked' or None, 'disabled':global_resource and 'disabled' or None}" />
+ </td>
+ </tr>
+ <tr>
<td>Force fsck</td>
<td>
<input type="checkbox" class="checkbox" name="force_fsck"
12 years, 5 months
[luci] Add confirmation dialogs for the leave cluster and reboot node actions
by Ryan McCabe
commit 04bcf74b96a7caa9fbf99fd26793a043136a944c
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:34:29 2012 -0500
Add confirmation dialogs for the leave cluster and reboot node actions
luci/public/js/node.js | 49 +++++++++++++++++++++++++++++++++++++--------
luci/templates/node.html | 13 +++++------
2 files changed, 46 insertions(+), 16 deletions(-)
---
diff --git a/luci/public/js/node.js b/luci/public/js/node.js
index 3bd2bd2..3f98654 100644
--- a/luci/public/js/node.js
+++ b/luci/public/js/node.js
@@ -1,5 +1,10 @@
$(function() {
- $('#confirm_remove_node_dialog').dialog({
+ var message_list = new Array();
+ message_list['Delete'] = "Removing a cluster node from the cluster is a destructive operation that cannot be undone.";
+ message_list['Reboot'] = "Reboot the selected nodes?";
+ message_list['Leave Cluster'] = "Make the selected nodes leave the cluster?";
+
+ $('#confirm_vanilla_dialog').dialog({
modal: true,
autoOpen: false,
draggable: false,
@@ -21,8 +26,19 @@ $(function() {
$(".confirm_link").click(function(e) {
e.preventDefault();
var targetUrl = $(this).attr("href");
+ var trigger_elem_id = $(this).attr("id");
+ var cur_action = null;
+
+ if (trigger_elem_id == 'dh_delete')
+ cur_action = 'Delete';
+ else if (trigger_elem_id == 'dh_reboot')
+ cur_action = 'Reboot';
+ else if (trigger_elem_id == 'dh_leave')
+ cur_action = 'Leave Cluster';
+ else
+ return true;
- $("#confirm_remove_node_dialog").dialog({
+ $("#confirm_vanilla_dialog").dialog({
open: function(event, ui) {
$(this).parent().children().children('.ui-dialog-titlebar-close').hide();
},
@@ -37,7 +53,11 @@ $(function() {
}
}
});
- $("#confirm_remove_node_dialog").dialog("open");
+ try {
+ $('#vanilla_confirm_span').empty();
+ $('#vanilla_confirm_span').append(message_list[cur_action]);
+ } catch (e) {}
+ $("#confirm_vanilla_dialog").dialog("open");
});
$("[type=submit],[type=image]").bind("click", function(e) {
@@ -46,14 +66,20 @@ $(function() {
$(".confirm_form").submit(function(e) {
var cur_form = this;
+ var cur_action = null;
var trigger_elem = $("[trigger_elem=True]").get(0);
- if (trigger_elem.id != 'tb_delete') {
+ if (trigger_elem.id == 'tb_delete')
+ cur_action = 'Delete';
+ else if (trigger_elem.id == 'tb_reboot')
+ cur_action = 'Reboot';
+ else if (trigger_elem.id == 'tb_leave')
+ cur_action = 'Leave Cluster';
+ else
return true;
- }
-
+ trigger_elem.removeAttribute('trigger_elem');
e.preventDefault();
- var ret = $("#confirm_remove_node_dialog").dialog({
+ var ret = $("#confirm_vanilla_dialog").dialog({
closeOnEscape: false,
open: function(event, ui) {
$(this).parent().children().children('.ui-dialog-titlebar-close').hide();
@@ -61,7 +87,7 @@ $(function() {
buttons: {
"Proceed": function() {
$(this).dialog("close");
- $(cur_form).append('<input type="hidden" name="MultiAction" value="Delete"/>');
+ $(cur_form).append('<input type="hidden" name="MultiAction" value="' + cur_action + '"/>');
cur_form.submit();
return true;
},
@@ -71,7 +97,12 @@ $(function() {
}
}
});
- $("#confirm_remove_node_dialog").dialog("open");
+ try {
+ $('#vanilla_confirm_span').empty();
+ $('#vanilla_confirm_span').append(message_list[cur_action]);
+ } catch (e) {}
+ $("#confirm_vanilla_dialog").dialog("open");
+
});
});
diff --git a/luci/templates/node.html b/luci/templates/node.html
index bc90680..f749706 100644
--- a/luci/templates/node.html
+++ b/luci/templates/node.html
@@ -57,9 +57,9 @@
<xi:include href="submenu.html"/>
<div id="toolbar">
<a href="#" onclick="$('#add_nodes_dialog').dialog('open')" class="toolbar_button" id="tb_add">Add</a>
- <input type="submit" name="MultiAction" value="${_('Reboot')}" class="toolbar_button MultiAction" id="tb_reboot" disabled="disabled"/>
+ <input type="submit" name="MultiAction" value="${_('Reboot')}" class="confirm_form toolbar_button MultiAction" id="tb_reboot" disabled="disabled"/>
<input type="submit" name="MultiAction" value="${_('Join Cluster')}" class="toolbar_button MultiAction" id="tb_join" disabled="disabled"/>
- <input type="submit" name="MultiAction" value="${_('Leave Cluster')}" class="toolbar_button MultiAction" id="tb_leave" disabled="disabled"/>
+ <input type="submit" name="MultiAction" value="${_('Leave Cluster')}" class="confirm_form toolbar_button MultiAction" id="tb_leave" disabled="disabled"/>
<input type="submit" name="MultiAction" value="${_('Delete')}" class="confirm_form toolbar_button MultiAction" id="tb_delete" disabled="disabled"/>
</div>
@@ -230,9 +230,9 @@
<div id="details_header">
<h3 py:content="name"/>
<div id="details_header_buttons">
- <a href="${tg.url('%snodes_cmd?command=Reboot&name=%s' % (tmpl_context.cluster_url, name))}" id="dh_reboot" title="reboot"><span class="hide">reboot</span></a>
+ <a class="confirm_link" href="${tg.url('%snodes_cmd?command=Reboot&name=%s' % (tmpl_context.cluster_url, name))}" id="dh_reboot" title="reboot"><span class="hide">reboot</span></a>
<a href="${tg.url('%snodes_cmd?command=Join+Cluster&name=%s' % (tmpl_context.cluster_url, name))}" id="dh_join" title="join"><span class="hide">join</span></a>
- <a href="${tg.url('%snodes_cmd?command=Leave+Cluster&name=%s' % (tmpl_context.cluster_url, name))}" id="dh_leave" title="leave cluster"><span class="hide">leave cluster</span></a>
+ <a class="confirm_link" href="${tg.url('%snodes_cmd?command=Leave+Cluster&name=%s' % (tmpl_context.cluster_url, name))}" id="dh_leave" title="leave cluster"><span class="hide">leave cluster</span></a>
<py:if test="details['clustered'] != 'true'">
<a class="confirm_link" href="${tg.url('%snodes_cmd?command=Delete&name=%s' % (tmpl_context.cluster_url, name))}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
</py:if>
@@ -526,10 +526,9 @@
</div>
</div>
<div class="hidden">
- <div id="confirm_remove_node_dialog" title="Confirm deletion">
- <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>Removing a cluster node from the cluster is a destructive operation that cannot be undone.</p>
+ <div id="confirm_vanilla_dialog" title="Confirm Action">
+ <span id="vanilla_confirm_span"></span>
</div>
-
<div id="create_fencemethod_dialog">
<form name="create_fence_method" method="post" action="${tg.url('%snodes_fence_cmd?command=AddFenceMethod' % tmpl_context.cluster_url)}">
<input type="hidden" name="node" value="${name}"/>
12 years, 5 months
[luci] Swap out the reboot icon with the icon that was originally intended to be a fence action icon
by Ryan McCabe
commit cbfa5f4d2d199d19466f5bbe7d5f86128a288823
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:33:50 2012 -0500
Swap out the reboot icon with the icon that was originally intended to be a fence action icon
luci/public/css/shared.css | 16 ++++++++--------
luci/templates/service.html | 2 +-
2 files changed, 9 insertions(+), 9 deletions(-)
---
diff --git a/luci/public/css/shared.css b/luci/public/css/shared.css
index 501596a..a652652 100644
--- a/luci/public/css/shared.css
+++ b/luci/public/css/shared.css
@@ -185,24 +185,24 @@ td.icon, th.icon {
}
/* reboot */
-#tb_reboot {
+#tb_restart {
background: url('../images/reboot-blue.png') center left no-repeat;
padding-left: 18px;
font-size: inherit;
}
-#tb_reboot:hover {
+#tb_restart:hover {
background-image: url('../images/reboot-blue.png');
}
/* fence */
-#tb_fence {
+#tb_reboot {
background: url('../images/fence-blue.png') center left no-repeat;
padding-left: 20px;
font-size: inherit;
}
-#tb_fence:hover {
+#tb_reboot:hover {
background-image: url('../images/fence-blue.png');
}
@@ -422,24 +422,24 @@ td.icon, th.icon {
}
/* reboot */
-#dh_reboot {
+#dh_restart {
width: 20px;
height: 20px;
background: url('../images/reboot-blue.png') center left no-repeat;
}
-#dh_reboot:hover {
+#dh_restart:hover {
background-image: url('../images/reboot-blue.png');
}
/* fence */
-#dh_fence {
+#dh_reboot {
width: 20px;
height: 20px;
background: url('../images/fence-blue.png') center left no-repeat;
}
-#dh_fence:hover {
+#dh_reboot:hover {
background-image: url('../images/fence-blue.png');
}
diff --git a/luci/templates/service.html b/luci/templates/service.html
index 83f1f6d..a864505 100644
--- a/luci/templates/service.html
+++ b/luci/templates/service.html
@@ -25,7 +25,7 @@
<div id="toolbar">
<a href="#" class="toolbar_button" id="tb_add" onclick="$('#add_service_dialog').dialog('open');return false;">Add</a>
<input type="submit" name="MultiAction" value="${_('Start')}" class="toolbar_button MultiAction" id="tb_start" disabled="disabled"/>
- <input type="submit" name="MultiAction" value="${_('Restart')}" class="toolbar_button MultiAction" id="tb_reboot" disabled="disabled"/>
+ <input type="submit" name="MultiAction" value="${_('Restart')}" class="toolbar_button MultiAction" id="tb_restart" disabled="disabled"/>
<input type="submit" name="MultiAction" value="${_('Disable')}" class="toolbar_button MultiAction" id="tb_disable" disabled="disabled"/>
<input type="submit" name="MultiAction" value="${_('Delete')}" class="confirm_form toolbar_button MultiAction" id="tb_delete" disabled="disabled"/>
</div>
12 years, 5 months
[luci] Make the service consruction/edit for a little easier to follow: - Move the add child button to abo
by Ryan McCabe
commit a4aade7aed2267057bcada9b79cafc00eb8407e9
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:32:40 2012 -0500
Make the service consruction/edit for a little easier to follow:
- Move the add child button to above where the child will appear
- Jump to the top of the newly added resource when adding resource
to services
- Add a left border along the side of resource to make it easier
to follow the structure of the service
luci/public/css/shared.css | 2 ++
luci/public/js/service.js | 8 +++++---
luci/templates/resource_list.html | 10 +++++-----
3 files changed, 12 insertions(+), 8 deletions(-)
---
diff --git a/luci/public/css/shared.css b/luci/public/css/shared.css
index 4cebcf4..501596a 100644
--- a/luci/public/css/shared.css
+++ b/luci/public/css/shared.css
@@ -510,10 +510,12 @@ td.icon, th.icon {
}
.svc_res_table {
+ border-left: 1px solid #c4c4c4;
background-color: #f4f4f4;
}
.svc_padding {
+ border-left: 1px solid #c4c4c4;
background-color: #f4f4f4;
}
diff --git a/luci/public/js/service.js b/luci/public/js/service.js
index 2a82395..d409388 100644
--- a/luci/public/js/service.js
+++ b/luci/public/js/service.js
@@ -135,8 +135,9 @@ function insert_resource(res_id, container_id, form, parent_id) {
var cur_id_str = 'res_' + num_res;
var td_id_str = 'td_' + cur_id_str;
var table_id_str = 'table_' + cur_id_str;
+ var res_anchor_name = 'anchor_' + cur_id_str;
- var svc_tables = $('<table class="detailstable" id="' + table_id_str + '"><thead class="svc_padding"><tr class="svc_padding"><th class="svc_padding" width="5"/><th class="svc_padding" width="98%"/><th class="svc_padding" colspan="3"/></tr></thead><tbody><tr class="svc_res_table"><td></td><td align="right" class="svc_padding" colspan="4"><a href="#" onclick="$(\'#' + table_id_str + '\').remove();return false;">Remove</a></td></tr><tr><td class="svc_padding"></td><td colspan="4" class="svc_content" id="' + td_id_str + '"></td></tr></tbody></table>');
+ var svc_tables = $('<a name="' + res_anchor_name + '" id="' + res_anchor_name + '"/><table class="detailstable" id="' + table_id_str + '"><thead class="svc_padding"><tr class="svc_padding"><th class="svc_padding" width="5"/><th class="svc_padding" width="98%"/><th class="svc_padding" colspan="3"/></tr></thead><tbody><tr class="svc_res_table"><td></td><td align="right" class="svc_padding" colspan="4"><a href="#" onclick="$(\'#' + table_id_str + '\').remove();return false;">Remove</a></td></tr><tr><td class="svc_padding"></td><td colspan="4" class="svc_content" id="' + td_id_str + '"></td></tr></tbody></table>');
var containing_div = $('<div class="reslevel"></div>');
$(containing_div).attr('id', cur_id_str);
@@ -145,7 +146,7 @@ function insert_resource(res_id, container_id, form, parent_id) {
var cntrl_div = $('<div class="row rescntrl"></div>');
if (!is_vm) {
- var cntrl_button = $('<input type="button" class="button small silver" value="Add a child resource" onclick="insert_resource_dialog(form, \'children_res_' + num_res + '\', \'' + cur_id_str + '\');"></input>');
+ var cntrl_button = $('<input type="button" class="button small silver" value="Add Child Resource" onclick="insert_resource_dialog(form, \'children_res_' + num_res + '\', \'' + cur_id_str + '\');"></input>');
$(cntrl_button).appendTo($(cntrl_div));
}
@@ -176,10 +177,11 @@ function insert_resource(res_id, container_id, form, parent_id) {
$(tree_level_elem).val(0);
$(form_jelem).appendTo($(containing_div));
- $(child_div).appendTo($(containing_div));
$(cntrl_div).appendTo($(containing_div));
+ $(child_div).appendTo($(containing_div));
$(svc_tables).appendTo($(dest_jelem));
$(containing_div).appendTo($(document.getElementById(td_id_str)));
+ window.location.href = '#' + res_anchor_name;
}
function submit_svc_form(form) {
diff --git a/luci/templates/resource_list.html b/luci/templates/resource_list.html
index fb37f65..387f275 100644
--- a/luci/templates/resource_list.html
+++ b/luci/templates/resource_list.html
@@ -1941,16 +1941,16 @@ ${vm_resource(None,None,None,0)}
${cur_res_fn(cur_res, cur_id_str, parentid, 0)}
</py:otherwise>
</py:choose>
- <div class="reschild" id="${'children_%s' % cur_id_str}">
- <py:if test="cur_res.getChildren()">
- ${print_svc_children(model, cur_res.getChildren(), cur_id_str)}
- </py:if>
- </div>
<div class="row rescntrl" py:if="cur_res_type != 'vm'">
<input type="button" class="button small silver"
value="Add Child Resource"
onclick="${'insert_resource_dialog(this.form, \'children_%s\', \'%s\')' % (cur_id_str, cur_id_str)}"/>
</div>
+ <div class="reschild" id="${'children_%s' % cur_id_str}">
+ <py:if test="cur_res.getChildren()">
+ ${print_svc_children(model, cur_res.getChildren(), cur_id_str)}
+ </py:if>
+ </div>
</div>
</td>
</tr>
12 years, 5 months
[luci] Add an interface in the config tab for configuring RRP
by Ryan McCabe
commit b82cfdd9b6521b3f3509280b2c9bf62cffd1e306
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:30:33 2012 -0500
Add an interface in the config tab for configuring RRP
luci/lib/ClusterConf/Altmulticast.py | 42 ++++++++++++++
luci/lib/ClusterConf/Altname.py | 21 +++++--
luci/lib/ClusterConf/ModelBuilder.py | 45 +++++++++++++++-
luci/templates/configure.html | 86 ++++++++++++++++++++++++------
luci/validation/validate_cluster_prop.py | 54 +++++++++++++++++++
5 files changed, 224 insertions(+), 24 deletions(-)
---
diff --git a/luci/lib/ClusterConf/Altmulticast.py b/luci/lib/ClusterConf/Altmulticast.py
new file mode 100644
index 0000000..bac0612
--- /dev/null
+++ b/luci/lib/ClusterConf/Altmulticast.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute
+# it and/or modify it under the terms of version 2 of the
+# GNU General Public License as published by the
+# Free Software Foundation.
+
+from TagObject import TagObject
+
+TAG_NAME = 'altmulticast'
+
+class Altmulticast(TagObject):
+ def __init__(self):
+ TagObject.__init__(self)
+ self.TAG_NAME = TAG_NAME
+
+ def getAddr(self):
+ return self.attr_hash.get('addr')
+
+ def setAddr(self, val):
+ return self.addAttribute('addr', val)
+
+ def delAddr(self):
+ return self.attr_hash.get('addr')
+
+ def getPort(self):
+ return self.getAttribute('port')
+
+ def setPort(self, val):
+ return self.addIntegerAttribute('port', val, (1, 0xffff))
+
+ def delPort(self):
+ return self.removeAttribute('port')
+
+ def getTTL(self):
+ return self.getAttribute('ttl')
+
+ def setTTL(self, val):
+ return self.addIntegerAttribute('ttl', val, (1, 255))
+
+ def delTTL(self):
+ return self.removeAttribute('ttl')
diff --git a/luci/lib/ClusterConf/Altname.py b/luci/lib/ClusterConf/Altname.py
index e0be390..c435f8f 100644
--- a/luci/lib/ClusterConf/Altname.py
+++ b/luci/lib/ClusterConf/Altname.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2010 Red Hat, Inc.
+# Copyright (C) 2007-2012 Red Hat, Inc.
#
# This program is free software; you can redistribute
# it and/or modify it under the terms of version 2 of the
@@ -14,14 +14,14 @@ class Altname(TagObject):
TagObject.__init__(self)
self.TAG_NAME = TAG_NAME
- def getAddr(self):
- return self.attr_hash.get('name')
+ def getName(self):
+ return self.getAttribute('name')
- def setAddr(self, val):
+ def setName(self, val):
return self.addAttribute('name', val)
- def delAddr(self):
- return self.attr_hash.get('name')
+ def delName(self):
+ return self.removeAttribute('name')
def getPort(self):
return self.getAttribute('port')
@@ -40,3 +40,12 @@ class Altname(TagObject):
def delMcast(self):
return self.removeAttribute('mcast')
+
+ def getTTL(self):
+ return self.getAttribute('ttl')
+
+ def setTTL(self, val):
+ return self.addAttribute('ttl', (1, 255))
+
+ def delTTL(self):
+ return self.removeAttribute('ttl')
diff --git a/luci/lib/ClusterConf/ModelBuilder.py b/luci/lib/ClusterConf/ModelBuilder.py
index 14b769d..9f8a939 100644
--- a/luci/lib/ClusterConf/ModelBuilder.py
+++ b/luci/lib/ClusterConf/ModelBuilder.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2011 Red Hat, Inc.
+# Copyright (C) 2006-2012 Red Hat, Inc.
#
# This program is free software; you can redistribute
# it and/or modify it under the terms of version 2 of the
@@ -16,7 +16,7 @@ import Cman, Totem, QuorumD, FenceDaemon, FenceXVMd, DLM, GFSControld, \
Group, Logging, ClusterNodes, FenceDevices, Rm, Clvmd
# Children of <cman>
-import Multicast
+import Multicast, Altmulticast
# Children of <totem>
import Interface
@@ -75,6 +75,7 @@ TAGNAMES = {
Interface.TAG_NAME: Interface.Interface,
Cman.TAG_NAME: Cman.Cman,
Multicast.TAG_NAME: Multicast.Multicast,
+ Altmulticast.TAG_NAME: Altmulticast.Altmulticast,
Group.TAG_NAME: Group.Group,
Clvmd.TAG_NAME: Clvmd.Clvmd,
GFSControld.TAG_NAME: GFSControld.GFSControld,
@@ -162,6 +163,7 @@ class ModelBuilder:
self.events_ptr = None
self.resources_ptr = None
self.mcast_ptr = None
+ self.altmcast_ptr = None
self.lockspace_ptr = None
self.unknown_elements = list()
(self.cluster_version, self.cluster_os, self.os_version) = cluster_version
@@ -265,6 +267,8 @@ class ModelBuilder:
self.resources_ptr = new_object
elif parent_node.nodeName == Multicast.TAG_NAME:
self.mcast_ptr = new_object
+ elif parent_node.nodeName == Altmulticast.TAG_NAME:
+ self.altmcast_ptr = new_object
elif parent_node.nodeName == Lockspace.TAG_NAME:
self.lockspace_ptr = new_object
elif parent_node.nodeName == Events.TAG_NAME:
@@ -725,6 +729,35 @@ class ModelBuilder:
return self.mcast_ptr.getAddr()
return None
+ def getAltmcastPtr(self):
+ return self.altmcast_ptr
+
+ def addAltmcastPtr(self):
+ if self.altmcast_ptr is None:
+ self.altmcast_ptr = Altmulticast.Altmulticast()
+ self.cman_ptr.addChild(self.altmcast_ptr)
+ return self.altmcast_ptr
+
+ def updateRRPConfig(self):
+ if not self.get_cluster_multicast():
+ return
+ if self.altmcast_ptr is None:
+ return
+
+ altmcast_addr = self.altmcast_ptr.getAddr()
+ altmcast_port = self.altmcast_ptr.getPort()
+ altmcast_ttl = self.altmcast_ptr.getTTL()
+
+ for node in self.getNodes():
+ an = node.getAltname()
+ if an:
+ if altmcast_addr and an.getName() == altmcast_addr:
+ an.delName()
+ if altmcast_port and an.getPort() == altmcast_port:
+ an.delPort()
+ if altmcast_ttl and an.getTTL() == altmcast_ttl:
+ an.delTTL()
+
def setQuorumd(self, qd):
cp = self.getClusterPtr()
cp.addChild(qd)
@@ -957,6 +990,9 @@ class ModelBuilder:
if self.mcast_ptr is not None:
self.cman_ptr.removeChild(self.mcast_ptr)
self.mcast_ptr = None
+ if self.altmcast_ptr is not None:
+ self.cman_ptr.removeChild(self.altmcast_ptr)
+ self.altmcast_ptr = None
return True
def set_cluster_multicast(self, mcast_addr=None):
@@ -984,6 +1020,11 @@ class ModelBuilder:
def del_cluster_udpu(self):
self.cman_ptr.delTransport()
+ def get_cluster_multicast(self):
+ if not self.get_cluster_udpu() and not self.get_cluster_broadcast():
+ return True
+ return False
+
def check_fence_daemon(self):
if self.fence_daemon_ptr is None:
self.fence_daemon_ptr = FenceDaemon.FenceDaemon()
diff --git a/luci/templates/configure.html b/luci/templates/configure.html
index ff20fe4..85412b8 100644
--- a/luci/templates/configure.html
+++ b/luci/templates/configure.html
@@ -49,15 +49,16 @@
<li><a href="#tabs-1">General</a></li>
<li><a href="#tabs-2">Fence Daemon</a></li>
<li><a href="#tabs-3">Network</a></li>
- <li><a href="#tabs-4">QDisk</a></li>
- <li><a href="#tabs-5">Logging</a></li>
+ <li py:if="cluster_os != 'RHEL' or os_version > 6.2"><a href="#tabs-4">Redundant Ring</a></li>
+ <li><a href="#tabs-5">QDisk</a></li>
+ <li><a href="#tabs-6">Logging</a></li>
<py:if test="expertMode">
- <li><a href="#tabs-6">CMAN</a></li>
- <li><a href="#tabs-7">rgmanager</a></li>
- <li><a href="#tabs-8">DLM</a></li>
- <li><a href="#tabs-9">gfs_controld</a></li>
- <li><a href="#tabs-10">groupd</a></li>
- <li><a href="#tabs-11">clvmd</a></li>
+ <li><a href="#tabs-7">CMAN</a></li>
+ <li><a href="#tabs-8">rgmanager</a></li>
+ <li><a href="#tabs-9">DLM</a></li>
+ <li><a href="#tabs-10">gfs_controld</a></li>
+ <li><a href="#tabs-11">groupd</a></li>
+ <li><a href="#tabs-12">clvmd</a></li>
</py:if>
</ul>
<div id="tabs-1">
@@ -182,11 +183,64 @@
</div>
</form>
</div>
+ <div id="tabs-4" py:if="cluster_os != 'RHEL' or os_version > 6.2">
+ <form action="${tg.url(configure_cmd)}" method="post">
+ <input py:if="expertMode" type="hidden" name="expert_mode" value="1"/>
+ <input type="hidden" name="page" value="RRP"/>
+ <h2>Redundant Ring Protocol Configuration</h2>
+ <div class="row">
+ <div py:if="cluster_data and not cluster_data.get_cluster_multicast()">
+ <p><em>Note: RRP configuration is available only when the cluster is using multicast as its network transport.</em></p>
+ </div>
+ <table>
+ <tr>
+ <td>Alternate Ring Multicast Address</td>
+ <td>
+ <input name="altmcast_addr" type="text" class="text"
+ py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastPtr() and cluster_data.getAltmcastPtr().getAddr() } or {}"/>
+ </td>
+ </tr>
+ <tr>
+ <td>Alternate Ring CMAN Port</td>
+ <td>
+ <input name="altmcast_port" type="text" class="text"
+ py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastPtr() and cluster_data.getAltmcastPtr().getPort() } or {}"/>
+ </td>
+ </tr>
+ <tr>
+ <td>Alternate Ring Multicast Packet TTL</td>
+ <td>
+ <input name="altmcast_ttl" type="text" class="text"
+ py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastPtr() and cluster_data.getAltmcastPtr().getTTL() } or {}"/>
+ </td>
+ </tr>
+
+ </table>
+ <h4>Redundant Ring Cluster Node Configuration</h4>
+ <table py:if="cluster_data">
+ <tr>
+ <th>Cluster Node</th>
+ <th>Alternate Name</th>
+ </tr>
+ <tr py:for="i in cluster_data.getNodes()">
+ <td>${i.getName()}</td>
+ <td>
+ <input type="text" class="text" name="altmcast_${i.getName()}" value="${i.getAltname() and i.getAltname().getName()}" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="row">
+ <input type="submit" class="button formsubmit blue" value="Apply"
+ py:attrs="{'disabled': (cluster_data and not cluster_data.get_cluster_multicast()) and 'disabled' or None }"/>
+ </div>
+ </form>
+ </div>
<?python
from luci.lib.ClusterConf.QuorumD import QuorumD
from luci.lib.ClusterConf.Logging import Logging
?>
- <div id="tabs-4" py:with="quorumd_ptr = cluster_data and cluster_data.quorumd_ptr or QuorumD();
+ <div id="tabs-5" py:with="quorumd_ptr = cluster_data and cluster_data.quorumd_ptr or QuorumD();
qdisk_found, qdisk_supported = cluster_data and cluster_data.getClusterPtr().doesClusterUseQuorumDisk() or (None, None);
qdisk_used = qdisk_found and qdisk_supported">
<form action="${tg.url(configure_cmd)}" method="post">
@@ -399,7 +453,7 @@
</form>
</div>
- <div id="tabs-5" py:with="default_log_obj = Logging()">
+ <div id="tabs-6" py:with="default_log_obj = Logging()">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="global_log=(cluster_data and cluster_data.getLoggingPtr()) or default_log_obj">
<input py:if="expertMode" type="hidden" name="expert_mode" value="1"/>
@@ -2501,7 +2555,7 @@
</form>
</div>
- <div py:if="expertMode" id="tabs-6">
+ <div py:if="expertMode" id="tabs-7">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="cman_ptr = cluster_data and cluster_data.getCMANPtr()">
<input type="hidden" name="expert_mode" value="1"/>
@@ -2567,7 +2621,7 @@
</form>
</div>
- <div py:if="expertMode" id="tabs-7">
+ <div py:if="expertMode" id="tabs-8">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="rm_ptr = cluster_data and cluster_data.getResourceManagerPtr()">
<input type="hidden" name="expert_mode" value="1"/>
@@ -2598,7 +2652,7 @@
</form>
</div>
- <div py:if="expertMode" id="tabs-8">
+ <div py:if="expertMode" id="tabs-9">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="dlm_ptr = cluster_data and cluster_data.getDLMPtr()">
<input type="hidden" name="expert_mode" value="1"/>
@@ -2680,7 +2734,7 @@
</form>
</div>
- <div py:if="expertMode" id="tabs-9">
+ <div py:if="expertMode" id="tabs-10">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="gfscontrold_ptr = cluster_data and cluster_data.getGFSControldPtr()">
<input type="hidden" name="expert_mode" value="1"/>
@@ -2731,7 +2785,7 @@
</form>
</div>
- <div py:if="expertMode" id="tabs-10">
+ <div py:if="expertMode" id="tabs-11">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="group_ptr = cluster_data and cluster_data.getGroupPtr()">
<input type="hidden" name="expert_mode" value="1"/>
@@ -2747,7 +2801,7 @@
</form>
</div>
- <div py:if="expertMode" id="tabs-11">
+ <div py:if="expertMode" id="tabs-12">
<form action="${tg.url(configure_cmd)}" method="post"
py:with="clvmd_ptr = cluster_data and cluster_data.getClvmdPtr()">
<input type="hidden" name="expert_mode" value="1"/>
diff --git a/luci/validation/validate_cluster_prop.py b/luci/validation/validate_cluster_prop.py
index 853fb0f..fe4624c 100644
--- a/luci/validation/validate_cluster_prop.py
+++ b/luci/validation/validate_cluster_prop.py
@@ -14,6 +14,7 @@ from luci.lib.ClusterConf.Heuristic import Heuristic
from luci.lib.ClusterConf.Method import Method
from luci.lib.ClusterConf.Logging import Logging
from luci.lib.ClusterConf.LoggingDaemon import LoggingDaemon
+from luci.lib.ClusterConf.Altname import Altname
from luci.lib.db_helpers import create_cluster_obj, get_node_by_name, get_cluster_db_obj, create_user_db_obj
from luci.lib.ricci_communicator import RicciCommunicator
@@ -623,6 +624,57 @@ def validate_network_config(model, **kw):
totem.setSecAuth(kw.get('secauth') is not None)
return (len(errors) < 1, {'errors': errors})
+def validate_rrp_config(model, **kw):
+ errors = []
+
+ altmcast_ptr = model.getAltmcastPtr()
+ if not altmcast_ptr:
+ altmcast_ptr = model.addAltmcastPtr()
+
+ altmcast_addr = kw.get('altmcast_addr')
+ if altmcast_addr and not altmcast_addr.isspace():
+ try:
+ altmcast_ptr.setAddr(altmcast_addr)
+ except:
+ errors.append(_('Invalid alternate ring multicast address: %s') % altmcast_addr)
+ else:
+ altmcast_ptr.delAddr()
+
+ altmcast_port = kw.get('altmcast_port')
+ if altmcast_port and not altmcast_port.isspace():
+ try:
+ altmcast_ptr.setPort(altmcast_port)
+ except:
+ errors.append(_('Invalid alternate ring CMAN port: %s') % altmcast_port)
+ else:
+ altmcast_ptr.delPort()
+
+ altmcast_ttl = kw.get('altmcast_ttl')
+ if altmcast_ttl and not altmcast_ttl.isspace():
+ try:
+ altmcast_ptr.setTTL(altmcast_ttl)
+ except:
+ errors.append(_('Invalid alternate ring multicast packet TTL: %s') % altmcast_ttl)
+ else:
+ altmcast_ptr.delTTL()
+
+ for i in model.getNodes():
+ cur_node_conf = kw.get('altmcast_%s' % i.getName())
+ if cur_node_conf:
+ # Since we only want the addr attribute, create a new object
+ # to replace an existing altname that may contain old-style config
+ try:
+ cur_an = Altname()
+ cur_an.setName(cur_node_conf)
+ i.setAltname(cur_an)
+ except Exception, e:
+ errors.append(_('Error setting alternate address for %s: %s')
+ % (i.getName(), str(e)))
+
+ # Clean up any old-style config that may still be around
+ model.updateRRPConfig()
+ return (len(errors) < 1, {'errors': errors})
+
def validate_log_config(model, **kw):
new_conf = False
@@ -941,6 +993,8 @@ def validate_cluster_config_form(model, **kw):
return validate_general_config(model, **kw)
elif conf_page == 'Network':
return validate_network_config(model, **kw)
+ elif conf_page == 'RRP':
+ return validate_rrp_config(model, **kw)
elif conf_page == 'Logging':
return validate_log_config(model, **kw)
elif conf_page == 'QDisk':
12 years, 5 months
[luci] Set the root logger before others when changing log levels
by Ryan McCabe
commit ad451df39a06ca5bd81885d5a66da4fca17f1012
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:28:30 2012 -0500
Set the root logger before others when changing log levels
luci/validation/validate_cluster_prop.py | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
---
diff --git a/luci/validation/validate_cluster_prop.py b/luci/validation/validate_cluster_prop.py
index 9a44023..853fb0f 100644
--- a/luci/validation/validate_cluster_prop.py
+++ b/luci/validation/validate_cluster_prop.py
@@ -1257,18 +1257,6 @@ def validate_user_perms(name, **kw):
def validate_luci_log_levels(**kw):
errors = []
- log_tg_i18n = kw.get('log_level_tg.i18n')
- if log_tg_i18n:
- log_tg_i18n = log_tg_i18n.upper()
- cur_logger = logging.getLogger('tg.i18n')
- try:
- cur_logger.setLevel(log_tg_i18n)
- except ValueError:
- errors.append(_("Invalid log level for tg.i18n: %s") % log_tg_i18n)
- except:
- log.exception("Setting log level for tg.i18n")
- errors.append(_("Unable to set log level for tg.i18n to %s") % log_tg_i18n)
-
log_root = kw.get('log_level_root')
if log_root:
log_root = log_root.upper()
@@ -1281,6 +1269,18 @@ def validate_luci_log_levels(**kw):
log.exception("Setting log level for root")
errors.append(_("Unable to set log level for root to %s") % log_root)
+ log_tg_i18n = kw.get('log_level_tg.i18n')
+ if log_tg_i18n:
+ log_tg_i18n = log_tg_i18n.upper()
+ cur_logger = logging.getLogger('tg.i18n')
+ try:
+ cur_logger.setLevel(log_tg_i18n)
+ except ValueError:
+ errors.append(_("Invalid log level for tg.i18n: %s") % log_tg_i18n)
+ except:
+ log.exception("Setting log level for tg.i18n")
+ errors.append(_("Unable to set log level for tg.i18n to %s") % log_tg_i18n)
+
log_sqlalchemy = kw.get('log_level_sqlalchemy')
if log_sqlalchemy:
log_sqlalchemy = log_sqlalchemy.upper()
@@ -1288,7 +1288,7 @@ def validate_luci_log_levels(**kw):
try:
cur_logger.setLevel(log_sqlalchemy)
try:
- # Change child loggers to match
+ # Change child and related loggers to match
log_manager = cur_logger.manager
for i in log_manager.loggerDict.keys():
if i[:11] == "sqlalchemy." or i in ('txn'):
12 years, 5 months
[luci] Add a confirmation before deleting service groups
by Ryan McCabe
commit e02ffdf91d34041dd653f910f2b8ae86f2753c52
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Sun Jan 22 21:27:58 2012 -0500
Add a confirmation before deleting service groups
luci/public/js/service.js | 77 +++++++++++++++++++++++++++++++++++++++++++
luci/templates/service.html | 9 +++--
2 files changed, 83 insertions(+), 3 deletions(-)
---
diff --git a/luci/public/js/service.js b/luci/public/js/service.js
index 7ce3739..2a82395 100644
--- a/luci/public/js/service.js
+++ b/luci/public/js/service.js
@@ -1,4 +1,81 @@
$(function() {
+ $('#confirm_remove_service_dialog').dialog({
+ modal: true,
+ autoOpen: false,
+ draggable: false,
+ resizable: false,
+ closeOnEscape: false,
+ open: function(event, ui) {
+ $(this).parent().children().children('.ui-dialog-titlebar-close').hide();
+ },
+ buttons: {
+ "Proceed": function() {
+ $(this).dialog("close");
+ },
+ "Cancel": function() {
+ $(this).dialog("close");
+ }
+ }
+ });
+
+ $(".confirm_link").click(function(e) {
+ e.preventDefault();
+ var targetUrl = $(this).attr("href");
+
+ $("#confirm_remove_service_dialog").dialog({
+ open: function(event, ui) {
+ $(this).parent().children().children('.ui-dialog-titlebar-close').hide();
+ },
+ closeOnEscape: false,
+ buttons: {
+ "Proceed": function() {
+ window.location.href = targetUrl;
+ $(this).dialog("close");
+ },
+ "Cancel" : function() {
+ $(this).dialog("close");
+ }
+ }
+ });
+ $("#confirm_remove_service_dialog").dialog("open");
+ });
+
+ $("[type=submit],[type=image]").bind("click", function(e) {
+ $(this).attr("trigger_elem", "True");
+ });
+
+ $(".confirm_form").submit(function(e) {
+ var cur_form = this;
+
+ var trigger_elem = $("[trigger_elem=True]").get(0);
+ if (trigger_elem.id != 'tb_delete') {
+ return true;
+ }
+
+ e.preventDefault();
+ var ret = $("#confirm_remove_service_dialog").dialog({
+ closeOnEscape: false,
+ open: function(event, ui) {
+ $(this).parent().children().children('.ui-dialog-titlebar-close').hide();
+ },
+ buttons: {
+ "Proceed": function() {
+ $(this).dialog("close");
+ $(cur_form).append('<input type="hidden" name="MultiAction" value="Delete"/>');
+ cur_form.submit();
+ return true;
+ },
+ "Cancel" : function() {
+ $(this).dialog("close");
+ return false;
+ }
+ }
+ });
+ $("#confirm_remove_service_dialog").dialog("open");
+ });
+});
+
+$(function() {
$('#add_service_dialog').dialog({
modal: true,
title: 'Add Service Group to Cluster',
diff --git a/luci/templates/service.html b/luci/templates/service.html
index 9eecbc6..83f1f6d 100644
--- a/luci/templates/service.html
+++ b/luci/templates/service.html
@@ -19,7 +19,7 @@
<xi:include href="resource_list.html" />
${resource_container(cluster_data)}
- <form action="${tg.url(services_cmd)}" method="post">
+ <form action="${tg.url(services_cmd)}" method="post" class="confirm_form">
<div class="sectionblock">
<xi:include href="submenu.html"/>
<div id="toolbar">
@@ -27,7 +27,7 @@
<input type="submit" name="MultiAction" value="${_('Start')}" class="toolbar_button MultiAction" id="tb_start" disabled="disabled"/>
<input type="submit" name="MultiAction" value="${_('Restart')}" class="toolbar_button MultiAction" id="tb_reboot" disabled="disabled"/>
<input type="submit" name="MultiAction" value="${_('Disable')}" class="toolbar_button MultiAction" id="tb_disable" disabled="disabled"/>
- <input type="submit" name="MultiAction" value="${_('Delete')}" class="toolbar_button MultiAction" id="tb_delete" disabled="disabled"/>
+ <input type="submit" name="MultiAction" value="${_('Delete')}" class="confirm_form toolbar_button MultiAction" id="tb_delete" disabled="disabled"/>
</div>
<!--! OVERVIEW SECTION. -->
@@ -165,7 +165,7 @@
<h3 py:content="name"/>
<form style="display: inline; padding-left: 24px; ">
<div id="details_header_buttons">
- <a href="${tg.url(services_cmd + '?command=Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
+ <a class="confirm_link" href="${tg.url(services_cmd + '?command=Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
<a href="${tg.url(services_cmd + '?command=Disable' + '&name=' + name)}" id="dh_stop" title="stop (disable)"><span class="hide">stop</span></a>
<a href="${tg.url(services_cmd + '?command=Restart' + '&name=' + name)}" id="dh_update" title="restart"><span class="hide">restart</span></a>
<a href="#" onclick="move_service_group('${tg.url(services_cmd + '?command=Start' + '&name=' + name)}')" id="dh_start" title="start"><span class="hide">start</span></a>
@@ -268,6 +268,9 @@
</div>
<div class="hidden">
+ <div id="confirm_remove_service_dialog" title="Confirm deletion">
+ <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>Removing a service group will cause the resources that comprise it to be stopped on any cluster nodes on which they may be running. If unintended, this will result in service interruption. This operation cannot be undone.</p>
+ </div>
<div id="insert_resource_dialog">
<div class="row resource_selector">
${resource_selector(cluster_data, '', '')}
12 years, 5 months