[luci] Fixed display on fence page so Node names show up properly (bz#600060)
by Chris Feist
commit 0ee83efd610a0bfb84e6030dd992fc8553ccc894
Author: Chris Feist <cfeist(a)redhat.com>
Date: Fri Jun 18 13:52:28 2010 -0500
Fixed display on fence page so Node names show up properly (bz#600060)
- Also removed Primary/Secondary display since this will soon be
phased out
luci/public/css/fence.css | 3 +--
luci/templates/fence.html | 11 +++--------
2 files changed, 4 insertions(+), 10 deletions(-)
---
diff --git a/luci/public/css/fence.css b/luci/public/css/fence.css
index fec8402..e609e30 100644
--- a/luci/public/css/fence.css
+++ b/luci/public/css/fence.css
@@ -45,7 +45,6 @@ th.fence_tlist_ip {
}
th.fence_tnodes_name {
- width: 20%;
min-width: 20%;
}
@@ -83,4 +82,4 @@ th.fence_tnodes_level {
#fence_form_area {
min-height: 6em;
-}
\ No newline at end of file
+}
diff --git a/luci/templates/fence.html b/luci/templates/fence.html
index 55345b7..ac2264b 100644
--- a/luci/templates/fence.html
+++ b/luci/templates/fence.html
@@ -126,10 +126,9 @@
<table id="fence_tnodes" class="detailstable">
<thead>
<tr class="grid_row">
- <th class="icon"></th>
- <th class="fence_tnodes_name"></th>
- <th class="fence_tnodes_status">status</th>
- <th class="fence_tnodes_level">level</th>
+ <th class="icon">!</th>
+ <th class="fence_tnodes_name">Node Name</th>
+ <th class="fence_tnodes_status">Status</th>
</tr>
</thead>
<tbody>
@@ -160,10 +159,6 @@
<td class="fence_tnodes_status">${node_dict.get('msg', _('Status uknown'))}</td>
</py:when>
</py:choose>
- <py:choose test="'0'">
- <td py:when="1" class="fence_tnodes_level">${_('Primary Fence')}</td>
- <td py:when="2" class="fence_tnodes_level">${_('Secondary Fence')}</td>
- </py:choose>
</tr>
</tbody>
</table>
13 years, 10 months
[luci] Fixed missing reference to database nodes in controller for node.html
by Chris Feist
commit 30407ff23dee8de61eecc3e4d127f2115e881c64
Author: Chris Feist <cfeist(a)redhat.com>
Date: Fri Jun 18 12:51:42 2010 -0500
Fixed missing reference to database nodes in controller for node.html
luci/controllers/cluster.py | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index b355481..5ac310d 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -94,7 +94,9 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.node")
def default(self):
- return dict(page='nodes', name=self.nodename, base_url='/nodes')
+ db = get_cluster_db_obj(self.name)
+
+ return dict(page='nodes', name=self.nodename, base_url='/nodes', nodes=db.nodes)
@expose("luci.templates.node")
def nodes(self):
@@ -104,7 +106,9 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.node")
def add_nodes_cmd(self, command=None, **kw):
- return dict(use_referrer=False, page='nodes', name=self.nodename, base_url='/nodes')
+ db = get_cluster_db_obj(self.name)
+
+ return dict(use_referrer=False, page='nodes', name=self.nodename, base_url='/nodes', nodes=db.nodes)
@expose("luci.templates.node")
def nodes_fence_cmd(self, command=None, **kw):
13 years, 10 months
[luci] Nodes now show up even in the nodes interface even if they can't be contacted
by Chris Feist
commit e4a9dbf059deed4d697849a6350fdb189ab7a8d6
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Jun 17 15:24:14 2010 -0500
Nodes now show up even in the nodes interface even if they can't be contacted
luci/controllers/cluster.py | 6 ++++--
luci/templates/node.html | 17 +++++++++++++++++
2 files changed, 21 insertions(+), 2 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index e2ac444..b355481 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -17,7 +17,7 @@ from pylons.i18n import ugettext as _
# project specific imports
from luci.lib.base import BaseController
-from luci.lib.db_helpers import get_cluster_list, get_model_for_cluster, get_status_for_cluster, db_remove_cluster, get_agent_for_cluster
+from luci.lib.db_helpers import get_cluster_list, get_model_for_cluster, get_status_for_cluster, db_remove_cluster, get_agent_for_cluster, get_cluster_db_obj
import luci.lib.ricci_helpers as rh
import luci.widget_validators.validate_cluster_prop as vcp
from luci.widget_validators.validate_create_cluster_form import validate_create_cluster_form
@@ -98,7 +98,9 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.node")
def nodes(self):
- return dict(use_referrer=False, page='nodes', name=self.nodename, base_url='/nodes')
+ db = get_cluster_db_obj(self.name)
+
+ return dict(use_referrer=False, page='nodes', name=self.nodename, base_url='/nodes', nodes=db.nodes)
@expose("luci.templates.node")
def add_nodes_cmd(self, command=None, **kw):
diff --git a/luci/templates/node.html b/luci/templates/node.html
index c45ba4c..a6d1bc8 100644
--- a/luci/templates/node.html
+++ b/luci/templates/node.html
@@ -119,6 +119,23 @@
<td class="node_tlist_ip">${nodedbobj.hostname}</td>
</tr>
</py:if>
+ <py:if test="not cluster_status or not cluster_status.nodes">
+ <tr py:for="i in nodes"
+ py:with="hostname = i.hostname">
+ <td class="checkbox"><input type="checkbox" name="${hostname}"/></td>
+ <td class="icon">
+ <img src="${tg.url('/images/question.png')}" alt="Status of the node is unknown." />
+ </td>
+ <td class="main_id">
+ <a href="${tmpl_context.cluster_url + hostname}">
+ <span class="entity_unknown">${hostname}</span>
+ </a>
+ </td>
+ <td class="node_tlist_id"></td>
+ <td class="node_tlist_votes"></td>
+ <td class="node_tlist_status">${_('The status of this node is unknown')}</td>
+ </tr>
+ </py:if>
</tbody>
</table>
</div>
13 years, 10 months
[luci] Moved DEFAULT_CLUSTER_VERSION into Globals object to prevent errors
by Chris Feist
commit 59b4a52e5aa93a86e66cd3475bc42bb8392a9013
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Jun 17 14:03:06 2010 -0500
Moved DEFAULT_CLUSTER_VERSION into Globals object to prevent errors
luci/lib/app_globals.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
---
diff --git a/luci/lib/app_globals.py b/luci/lib/app_globals.py
index 8913d74..5b4c120 100644
--- a/luci/lib/app_globals.py
+++ b/luci/lib/app_globals.py
@@ -15,7 +15,6 @@ from luci.lib.ClusterConf.Totem import Totem
__all__ = ['Globals']
-DEFAULT_CLUSTER_VERSION = 3
class Globals(object):
"""Container for objects available throughout the life of the application.
@@ -24,6 +23,7 @@ class Globals(object):
is available during requests via the 'app_globals' variable.
"""
+ DEFAULT_CLUSTER_VERSION = 3
def __init__(self):
"""Prepare some common static functions, constants etc."""
13 years, 10 months
[luci] Fixed the "Nodes Joined" in the Homebase/Manage Clusters page
by Chris Feist
commit 627b3d6cc6ab04bc88aa20e5be1f97fc0a871c63
Author: Chris Feist <cfeist(a)redhat.com>
Date: Mon Jun 14 15:07:55 2010 -0500
Fixed the "Nodes Joined" in the Homebase/Manage Clusters page
- Added the nodesClustered variable to the ClusterStatus class which looks at
the 'clustered' status of a node (as opposed to the online status of a node).
luci/lib/cluster_status.py | 3 +++
luci/templates/cluster_list.html | 4 ++--
luci/templates/homebase.html | 2 +-
3 files changed, 6 insertions(+), 3 deletions(-)
---
diff --git a/luci/lib/cluster_status.py b/luci/lib/cluster_status.py
index ca403d7..4bb9000 100644
--- a/luci/lib/cluster_status.py
+++ b/luci/lib/cluster_status.py
@@ -60,6 +60,7 @@ class ClusterStatus:
self.votes = 'Unknown'
self.minQuorum = 'Unknown'
self.nodesJoined = 0
+ self.nodesClustered = 0
if not status_xml:
return
@@ -79,6 +80,8 @@ class ClusterStatus:
ns = NodeStatus(node)
if ns.online.lower() == 'true':
self.nodesJoined += 1
+ if ns.clustered.lower() == 'true':
+ self.nodesClustered += 1
self.nodes[ns.name] = ns
except Exception, e:
log.exception('Error parsing node list')
diff --git a/luci/templates/cluster_list.html b/luci/templates/cluster_list.html
index 4dec657..26399e3 100644
--- a/luci/templates/cluster_list.html
+++ b/luci/templates/cluster_list.html
@@ -65,7 +65,7 @@
<td class="cluster_tlist_votes">${sum(map(lambda n: int(n.getVotes()), cluster_data['model'].getNodes()))}</td>
<td class="cluster_tlist_votes">${cluster_data['status'].votes}</td>
<td class="cluster_tlist_quorum">${cluster_data['status'].minQuorum}</td>
- <td class="cluster_tlist_votes">${cluster_data['status'].nodesJoined}</td>
+ <td class="cluster_tlist_votes">${cluster_data['status'].nodesClustered}</td>
</py:when>
<!--! 2) Cluster is not OK. -->
<py:when test="'false'">
@@ -78,7 +78,7 @@
<td class="cluster_tlist_votes">${sum(map(lambda n: int(n.getVotes()), cluster_data['model'].getNodes()))}</td>
<td class="cluster_tlist_votes">${cluster_data['status'].votes}</td>
<td class="cluster_tlist_quorum">${cluster_data['status'].minQuorum}</td>
- <td class="cluster_tlist_votes">${cluster_data['status'].nodesJoined}</td>
+ <td class="cluster_tlist_votes">${cluster_data['status'].nodesClustered}</td>
</py:when>
<!--! 3) Status of the cluster is unknown. -->
<py:when test="">
diff --git a/luci/templates/homebase.html b/luci/templates/homebase.html
index 0a9b916..3705e2c 100644
--- a/luci/templates/homebase.html
+++ b/luci/templates/homebase.html
@@ -68,7 +68,7 @@
</py:choose>
<py:choose test="cluster_data and cluster_data.get('model') and cluster_data.get('status') and True">
<py:when test="True">
- <td class="cluster_tlist_votes">${cluster_data['status'].nodesJoined} of ${len(cluster_data['model'].getNodes())}</td>
+ <td class="cluster_tlist_votes">${cluster_data['status'].nodesClustered} of ${len(cluster_data['model'].getNodes())}</td>
</py:when>
<py:otherwise>
<td class="cluster_tlist_votes">-</td>
13 years, 10 months
[luci] Show only the fence device types that are available for RHEL5 clusters
by Ryan McCabe
commit 54e0a9f39ab3fe601dc783f428f5c50cea06c22a
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Fri Jun 11 15:03:25 2010 -0400
Show only the fence device types that are available for RHEL5 clusters
luci/templates/fence_devices.html | 123 ++++++++++++++++++++-----------------
1 files changed, 67 insertions(+), 56 deletions(-)
---
diff --git a/luci/templates/fence_devices.html b/luci/templates/fence_devices.html
index 0ad1a8b..11b0418 100644
--- a/luci/templates/fence_devices.html
+++ b/luci/templates/fence_devices.html
@@ -846,7 +846,7 @@
<td>
<input type="checkbox" class="checkbox" name="aptpl"
py:attrs="cur_fencedev and cur_fencedev.getAttribute('aptpl') and {'checked': 'checked'}"/>
- <label class="choice">Use APTPL flag</label>
+ <label class="choice">Use APTPL flag</label>
</td>
</tr>
</table>
@@ -1282,21 +1282,21 @@
py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('passwd_script')} or {}"/>
</td>
</tr>
- <tr>
- <td>SSH</td>
- <td>
- <input type="checkbox" class="checkbox" name="secure"
+ <tr>
+ <td>SSH</td>
+ <td>
+ <input type="checkbox" class="checkbox" name="secure"
py:attrs="cur_fencedev and cur_fencedev.getAttribute('secure') and {'checked': 'checked'}"/>
- <label class="choice">Use SSH</label>
- </td>
- </tr>
+ <label class="choice">Use SSH</label>
+ </td>
+ </tr>
<tr>
- <td>Path to SSH identity file</td>
- <td>
- <input type="text" class="text" name="identity_file"
- py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('identity_file')} or {}"/>
- </td>
- </tr>
+ <td>Path to SSH identity file</td>
+ <td>
+ <input type="text" class="text" name="identity_file"
+ py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('identity_file')} or {}"/>
+ </td>
+ </tr>
<tr>
<td>Force command prompt</td>
<td>
@@ -1800,21 +1800,21 @@
py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('passwd_script')} or {}"/>
</td>
</tr>
- <tr>
- <td>SSH</td>
- <td>
- <input type="checkbox" class="checkbox" name="secure"
+ <tr>
+ <td>SSH</td>
+ <td>
+ <input type="checkbox" class="checkbox" name="secure"
py:attrs="cur_fencedev and cur_fencedev.getAttribute('secure') and {'checked': 'checked'}"/>
- <label class="choice">Use SSH</label>
- </td>
- </tr>
+ <label class="choice">Use SSH</label>
+ </td>
+ </tr>
<tr>
- <td>Path to SSH identity file</td>
- <td>
- <input type="text" class="text" name="identity_file"
- py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('identity_file')} or {}"/>
- </td>
- </tr>
+ <td>Path to SSH identity file</td>
+ <td>
+ <input type="text" class="text" name="identity_file"
+ py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('identity_file')} or {}"/>
+ </td>
+ </tr>
<tr>
<td>Module name</td>
<td>
@@ -2101,21 +2101,21 @@
py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('passwd_script')} or {}"/>
</td>
</tr>
- <tr>
- <td>SSH</td>
- <td>
- <input type="checkbox" class="checkbox" name="secure"
+ <tr>
+ <td>SSH</td>
+ <td>
+ <input type="checkbox" class="checkbox" name="secure"
py:attrs="cur_fencedev and cur_fencedev.getAttribute('secure') and {'checked': 'checked'}"/>
- <label class="choice">Use SSH</label>
- </td>
- </tr>
+ <label class="choice">Use SSH</label>
+ </td>
+ </tr>
<tr>
- <td>Path to SSH identity file</td>
- <td>
- <input type="text" class="text" name="identity_file"
- py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('identity_file')} or {}"/>
- </td>
- </tr>
+ <td>Path to SSH identity file</td>
+ <td>
+ <input type="text" class="text" name="identity_file"
+ py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('identity_file')} or {}"/>
+ </td>
+ </tr>
<tr>
<td>Force command prompt</td>
<td>
@@ -2719,10 +2719,10 @@ ${fence_virsh(None,0)}
<option name="fence_drac" value="fence_drac">Dell DRAC</option>
<option name="fence_drac5" value="fence_drac5">Dell DRAC 5</option> <!-- needs work -->
<option name="fence_egenera" value="fence_egenera">Egenera SAN Controller</option>
- <option name="fence_eps" value="fence_eps">ePowerSwitch</option>
<py:choose test="tmpl_context.cluster_version">
<py:when test="3">
+ <option name="fence_eps" value="fence_eps">ePowerSwitch</option>
<option name="fence_virt" value="fence_virt">Fence virt</option>
<option name="fence_xvm" value="fence_xvm">Fence virt (Multicast Mode)</option>
</py:when>
@@ -2731,31 +2731,42 @@ ${fence_virsh(None,0)}
</py:otherwise>
</py:choose>
- <option name="fence_rsb" value="fence_rsb">Fujitsu Siemens RemoteView Service Board</option>
+ <option name="fence_rsb" value="fence_rsb">Fujitsu Siemens RemoteView Service Board</option>
<option name="fence_ilo" value="fence_ilo">HP iLO Device</option>
<option name="fence_ilo_mp" value="fence_ilo_mp">HP iLO MP</option> <!-- needs work -->
<option name="fence_bladecenter" value="fence_bladecenter">IBM BladeCenter</option>
- <option name="fence_ibmblade" value="fence_ibmblade">IBM BladeCenter SNMP</option>
- <option name="fence_rsa" value="fence_rsa">IBM RSA II Device</option> <!-- needs work -->
- <option name="fence_cpint" value="fence_cpint">IBM S/390 cpint</option>
- <option name="fence_zvm" value="fence_zvm">IBM S/390 z/VM</option>
- <option name="fence_ifmib" value="fence_ifmib">IF MIB</option>
- <option name="fence_intelmodular" value="fence_intelmodular">Intel Modular</option>
+ <option py:if="tmpl_context.cluster_version == 3" name="fence_ibmblade" value="fence_ibmblade">IBM BladeCenter SNMP</option>
+ <option name="fence_rsa" value="fence_rsa">IBM RSA II Device</option> <!-- needs work -->
+
+ <py:if test="tmpl_context.cluster_version == 3">
+ <option name="fence_cpint" value="fence_cpint">IBM S/390 cpint</option>
+ <option name="fence_zvm" value="fence_zvm">IBM S/390 z/VM</option>
+ <option name="fence_ifmib" value="fence_ifmib">IF MIB</option>
+ <option name="fence_intelmodular" value="fence_intelmodular">Intel Modular</option>
+ </py:if>
+
<option name="fence_ipmilan" value="fence_ipmilan">IPMI Lan</option>
<option name="fence_lpar" value="fence_lpar">LPAR Fencing</option>
- <option name="fence_mcdata" value="fence_mcdata">McData SAN Switch</option>
+ <option name="fence_mcdata" value="fence_mcdata">McData SAN Switch</option>
<option name="fence_sanbox2" value="fence_sanbox2">QLogic SANbox2</option>
- <option name="fence_rackswitch" value="fence_rackswitch">RackSaver RackSwitch</option>
- <option name="fence_rps10" value="fence_rps10">RPS10 Serial Switch</option>
+ <option py:if="tmpl_context.cluster_version == 3" name="fence_rackswitch" value="fence_rackswitch">RackSaver RackSwitch</option>
+ <option py:if="tmpl_context.cluster_version != 3" name="fence_rps10" value="fence_rps10">RPS10 Serial Switch</option>
<option name="fence_scsi" value="fence_scsi">SCSI Reservation Fencing</option>
- <option name="fence_alom" value="fence_alom">Sun ALOM</option>
- <option name="fence_ldom" value="fence_ldom">Sun LDOM</option>
+
+ <py:if test="tmpl_context.cluster_version == 3">
+ <option name="fence_alom" value="fence_alom">Sun ALOM</option>
+ <option name="fence_ldom" value="fence_ldom">Sun LDOM</option>
+ </py:if>
+
<option name="fence_virsh" value="fence_virsh">virsh fence agent</option>
<option name="fence_vixel" value="fence_vixel">Vixel SAN Switch</option>
<option name="fence_vmware" value="fence_vmware">VMware Fencing</option>
- <option name="fence_wti" value="fence_wti">WTI Power Switch</option>
- <option name="fence_xcat" value="fence_xcat">xCAT</option>
- <option name="fence_zvm" value="fence_zvm">s390 z/VM</option>
+ <option name="fence_wti" value="fence_wti">WTI Power Switch</option>
+
+ <py:if test="tmpl_context.cluster_version == 3">
+ <option name="fence_xcat" value="fence_xcat">xCAT</option>
+ <option name="fence_zvm" value="fence_zvm">s390 z/VM</option>
+ </py:if>
</select>
</div>
</div>
13 years, 11 months
[luci] Make the current cluster version available globally
by Ryan McCabe
commit a75055c99e1262f924c4c7047b516a71c56fa476
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Fri Jun 11 14:51:25 2010 -0400
Make the current cluster version available globally
luci/controllers/cluster.py | 309 ++++++-----------------
luci/lib/app_globals.py | 2 +
luci/templates/configure.html | 2 +-
luci/templates/fence_devices.html | 7 +-
luci/templates/resource_list.html | 5 +-
luci/widget_validators/validate_cluster_prop.py | 2 +-
6 files changed, 88 insertions(+), 239 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index f227600..e2ac444 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -52,7 +52,6 @@ class ClusterController(BaseController):
for key, element in kw.items():
if element == "on":
db_remove_cluster(key)
-
redirect('/cluster/')
@expose()
@@ -76,64 +75,43 @@ class IndividualClusterController(BaseController):
identity = request.environ.get('repoze.who.identity')
self.username = identity['repoze.who.userid']
tmpl_context.show_sidebar = True
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = '/cluster/%s/' % self.name
- @expose("luci.templates.node")
- def default(self):
try:
rc = get_agent_for_cluster(self.name)
except:
rc = None
- cmodel = get_model_for_cluster(self.name)
- tmpl_context.cluster_data = cmodel
+
+ self.model = get_model_for_cluster(self.name, rc)
+ tmpl_context.cluster_data = self.model
+
+ if self.model:
+ tmpl_context.cluster_version = self.model.getClusterVersion()
+ else:
+ tmpl_context.cluster_version = app_globals.DEFAULT_CLUSTER_VERSION
tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
+
+ @expose("luci.templates.node")
+ def default(self):
return dict(page='nodes', name=self.nodename, base_url='/nodes')
@expose("luci.templates.node")
def nodes(self):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
return dict(use_referrer=False, page='nodes', name=self.nodename, base_url='/nodes')
@expose("luci.templates.node")
def add_nodes_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
return dict(use_referrer=False, page='nodes', name=self.nodename, base_url='/nodes')
@expose("luci.templates.node")
def nodes_fence_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
-
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
- vret = vcp.validate_node_fence_form(cmodel, **kw)
+ vret = vcp.validate_node_fence_form(self.model, **kw)
if vret[0] is True:
log.info('User "%s" updated the fence properties for cluster "%s" node "%s"'
% (self.username, self.name, kw.get('node')))
@@ -141,8 +119,8 @@ class IndividualClusterController(BaseController):
msgs = vret[1].get('flash')
if msgs:
flash(', '.join(msgs))
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -152,17 +130,7 @@ class IndividualClusterController(BaseController):
# This processes all of the commands that we can apply to a node
@expose("luci.templates.node")
def nodes_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
-
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
@@ -210,42 +178,24 @@ class IndividualClusterController(BaseController):
flash(_('An unknown command "%s" was given for nodes "%s"')
% (command, ', '.join(cur_list)),
status='error')
- redirect(tmpl_context.cluster_url + kw["name"])
+ redirect(tmpl_context.cluster_url + kw.get('name'))
@expose("luci.templates.resource")
def resources(self, *args):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
+ base_url = '/cluster/%s/resources' % self.name
+ resources_cmd = '/cluster/%s/resources_cmd' % self.name
if (len(args) == 1):
resourcename = args[0]
else:
resourcename = None
-
- base_url = '/cluster/%s/resources' % self.name
- resources_cmd = '/cluster/%s/resources_cmd' % self.name
return dict(page='nodes', name=resourcename, base_url=base_url, resources_cmd=resources_cmd)
@expose("luci.templates.resource")
def resources_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = '/cluster/%s/resources' % self.name
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
@@ -266,17 +216,16 @@ class IndividualClusterController(BaseController):
redirect(tmpl_context.cluster_url)
if command == 'Delete':
errors = []
- res_ptr = cmodel.getResourcesPtr()
+ res_ptr = self.model.getResourcesPtr()
for i in cur_list:
try:
- cur_res = cmodel.getResourceByName(i)
+ cur_res = self.model.getResourceByName(i)
if cur_res.getRefcount() > 1:
errors.append(_('Global resource "%s" is in use so cannot be removed') % i)
else:
res_ptr.removeChild(cur_res)
except:
pass
-
if len(errors) != 0:
flash(_('%s') % ', '.join(errors), status='error')
else:
@@ -285,21 +234,21 @@ class IndividualClusterController(BaseController):
flash(_("Deleting resources %s") % ', '.join(cur_list),
status='info')
- cmodel.setModified()
- rh.update_cluster_conf(cmodel)
+ self.model.setModified()
+ rh.update_cluster_conf(self.model)
elif command in ("Create", "Edit"):
if command == 'Create':
cur_action = _('Created')
else:
cur_action = _('Edited')
- vret = validate_resource_form(cmodel, **kw)
+ vret = validate_resource_form(self.model, **kw)
if vret[0] is True:
res_name = kw.get('resourcename')
log.info('User "%s" %s global resource "%s" in cluster "%s"'
% (self.username, cur_action, res_name, self.name))
flash(_('%s global resource "%s"') % (cur_action, res_name))
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
redirect('%s/%s' % (tmpl_context.cluster_url, res_name))
else:
msgs = vret[1].get('errors')
@@ -315,38 +264,20 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.service")
def services(self, *args):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
+ base_url = '/cluster/%s/services' % self.name
+ services_cmd = '/cluster/%s/services_cmd' % self.name
if (len(args) == 1):
servicename = args[0]
else:
servicename = None
-
- base_url = '/cluster/%s/services' % self.name
- services_cmd = '/cluster/%s/services_cmd' % self.name
return dict(page='nodes', name=servicename, base_url=base_url, services_cmd=services_cmd)
@expose("luci.templates.service")
def services_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = '/cluster/%s/services' % self.name
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
@@ -374,10 +305,10 @@ class IndividualClusterController(BaseController):
flash(_("Deleting services %s") % ', '.join(cur_list),
status='info')
for i in cur_list:
- cmodel.deleteService(i)
+ self.model.deleteService(i)
- cmodel.setModified()
- rh.update_cluster_conf(cmodel)
+ self.model.setModified()
+ rh.update_cluster_conf(self.model)
redirect(tmpl_context.cluster_url)
if command == 'Start':
log.info('User "%s" started service "%s" in cluster "%s"'
@@ -405,15 +336,15 @@ class IndividualClusterController(BaseController):
cur_action = _('Created')
else:
cur_action = _('Edited')
- vret = validate_clusvc_form(cmodel, **kw)
+ vret = validate_clusvc_form(self.model, **kw)
kw['name'] = ''
if vret[0] is True:
svc_name = kw.get('svc_name')
log.info('User "%s" %s cluster service "%s" in cluster "%s"'
% (self.username, cur_action, svc_name, self.name))
flash(_('%s cluster service "%s"') % (cur_action, svc_name))
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -431,37 +362,19 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.qdisk")
def qdisk(self, *args):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
qdisk_cmd = '/cluster/%s/qdisk_cmd' % self.name
return dict(page='nodes', base_url = '/cluster/' + self.name + '/qdisk', qdisk_cmd = qdisk_cmd)
@expose("luci.templates.qdisk")
def qdisk_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
qdisk_cmd = '/cluster/%s/qdisk_cmd' % self.name
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
return dict(use_referrer=False, page='nodes', base_url = '/cluster/' + self.name + '/qdisk', qdisk_cmd=qdisk_cmd)
- vret = vcp.validate_qdisk_prop_form(cmodel, **kw)
+ vret = vcp.validate_qdisk_prop_form(self.model, **kw)
if vret[0] is True:
log.info('User "%s" updated the quorum disk properties for cluster "%s"'
% (self.username, self.name))
@@ -470,8 +383,8 @@ class IndividualClusterController(BaseController):
if msgs:
flash(', '.join(msgs))
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -480,35 +393,19 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.failover")
def failovers(self, *args):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
+ failovers_cmd = '/cluster/%s/failovers_cmd' % self.name
+
if len(args) == 1:
failovername = args[0]
else:
failovername = None
- failovers_cmd = '/cluster/%s/failovers_cmd' % self.name
return dict(page='nodes', name=failovername, base_url = '/cluster/' + self.name + '/failovers', failovers_cmd=failovers_cmd)
@expose("luci.templates.failover")
def failovers_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = '/cluster/%s/failovers' % self.name
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
@@ -533,9 +430,9 @@ class IndividualClusterController(BaseController):
% (self.username, ', '.join(cur_list), self.name))
flash(_('Deleting failover domains %s') % ', '.join(cur_list))
for i in cur_list:
- cmodel.deleteFailoverDomain(i)
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.deleteFailoverDomain(i)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
redirect(tmpl_context.cluster_url)
@@ -547,40 +444,40 @@ class IndividualClusterController(BaseController):
redirect(tmpl_context.cluster_url)
if command == 'update_settings':
- vret = vcp.validate_fdom_prop_settings_form(cmodel, **kw)
+ vret = vcp.validate_fdom_prop_settings_form(self.model, **kw)
if vret[0] is True:
log.info('User "%s" updated the settings of failover domain "%s" in cluster "%s"'
% (self.username, cur_list[0], self.name))
flash(_('Updating settings for failover domain "%s"') % cur_list[0])
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
flash(', '.join(msgs), status="error")
- redirect(tmpl_context.cluster_url + '/' + kw["name"])
+ redirect(tmpl_context.cluster_url + '/' + kw.get('name'))
elif command == 'update_properties':
- vret = vcp.validate_fdom_prop_form(cmodel, **kw)
+ vret = vcp.validate_fdom_prop_form(self.model, **kw)
if vret[0] is True:
log.info('User "%s" updated the properties of failover domain "%s" in cluster "%s"'
% (self.username, cur_list[0], self.name))
flash(_('Updating properties for failover domain "%s"') % cur_list[0])
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
flash(', '.join(msgs), status="error")
- redirect(tmpl_context.cluster_url + '/' + kw["name"])
+ redirect(tmpl_context.cluster_url + '/' + kw.get('name'))
elif command == 'create':
- vret = vcp.validate_fdom_create_form(cmodel, **kw)
+ vret = vcp.validate_fdom_create_form(self.model, **kw)
if vret[0] is True:
log.info('User "%s" created failover domain "%s" in cluster "%s"'
% (self.username, kw.get('fdom_name'), self.name))
flash(_('Creating failover domain "%s"') % kw.get('fdom_name'))
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -596,37 +493,19 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.fence")
def fences(self, *args):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
+ fences_cmd = '/cluster/%s/fences_cmd' % self.name
if len(args) == 1:
fencename = args[0]
else:
fencename = None
-
- fences_cmd = '/cluster/%s/fences_cmd' % self.name
return dict(page='nodes', name=fencename, base_url='/cluster/' + self.name + '/fences', fences_cmd=fences_cmd)
@expose("luci.templates.fence")
def fences_cmd(self, command=None, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = '/cluster/%s/fences' % self.name
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
@@ -647,10 +526,10 @@ class IndividualClusterController(BaseController):
redirect(tmpl_context.cluster_url)
if command == 'Create':
- fret = validateNewFenceDevice(cmodel, **kw)
+ fret = validateNewFenceDevice(self.model, **kw)
if fret[0] is True:
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
log.info('User "%s" created fence devices "%s" in cluster "%s"'
% (self.username, ', '.join(cur_list), self.name))
else:
@@ -663,15 +542,18 @@ class IndividualClusterController(BaseController):
flash(_('Deleting fence devices ') + ', '.join(cur_list))
updated = False
for i in cur_list:
- updated |= cmodel.deleteFenceDevice(i)
+ cur_fencedev = self.model.getFenceDeviceByName(i)
+ if not cur_fencedev:
+ continue
+ updated |= self.model.deleteFenceDevice(cur_fencedev)
if updated:
- cmodel.setModified()
- rh.update_cluster_conf(cmodel)
+ self.model.setModified()
+ rh.update_cluster_conf(self.model)
elif command == 'Update':
- fret = validateFenceDevice(cmodel, **kw)
+ fret = validateFenceDevice(self.model, **kw)
if fret[0] is True:
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
log.info('User "%s" created fence device "%s" in cluster "%s"'
% (self.username, ', '.join(cur_list), self.name))
else:
@@ -688,42 +570,25 @@ class IndividualClusterController(BaseController):
@expose("luci.templates.configure")
def configure(self, *args):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
configure_cmd = '/cluster/%s/configure_cmd' % self.name
return dict(use_referrer=False, page='nodes', name='configure', base_url='/cluster/' + self.name + '/configure', configure_cmd=configure_cmd)
@expose("luci.templates.configure")
def configure_cmd(self, command=None, *args, **kw):
- try:
- rc = get_agent_for_cluster(self.name)
- except:
- rc = None
- cmodel = get_model_for_cluster(self.name, rc)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name, rc)
- tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = '/cluster/%s/configure' % self.name
- if not cmodel:
+ if not self.model:
flash(_('Unable to contact any nodes in this cluster'),
status="error")
redirect(tmpl_context.cluster_url)
- vret = vcp.validate_cluster_config_form(cmodel, **kw)
+ vret = vcp.validate_cluster_config_form(self.model, **kw)
if vret[0] is True:
log.info('User "%s" updated the cluster properties for cluster "%s"'
% (self.username, self.name))
flash("Applying Settings")
- cmodel.setModified(True)
- rh.update_cluster_conf(cmodel)
+ self.model.setModified(True)
+ rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -732,13 +597,7 @@ class IndividualClusterController(BaseController):
@expose()
def lookup(self, nodename, *args):
- clustername = self.name
- cmodel = get_model_for_cluster(self.name)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name)
- tmpl_context.cluster_name = clustername
- tmpl_context.cluster_url = '/cluster/%s/' % clustername
- inc = IndividualNodeController(clustername, self.data, nodename)
+ inc = IndividualNodeController(self.name, self.data, nodename)
return inc, args
class IndividualNodeController(BaseController):
@@ -750,19 +609,9 @@ class IndividualNodeController(BaseController):
@expose("luci.templates.node")
def default(self):
- cmodel = get_model_for_cluster(self.name)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name)
- tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = '/cluster/%s/' % self.name
return dict(page='nodes', name=self.nodename, base_url='/nodes')
@expose()
def lookup(self, nodename, *args):
- clustername = self.name
- cmodel = get_model_for_cluster(self.name)
- tmpl_context.cluster_data = cmodel
- tmpl_context.cluster_status = get_status_for_cluster(self.name)
- tmpl_context.cluster_name = clustername
- icc = IndividualClusterController(clustername, self.data, nodename)
+ icc = IndividualClusterController(self.name, self.data, nodename)
return icc, args
diff --git a/luci/lib/app_globals.py b/luci/lib/app_globals.py
index 8d28523..8913d74 100644
--- a/luci/lib/app_globals.py
+++ b/luci/lib/app_globals.py
@@ -15,6 +15,8 @@ from luci.lib.ClusterConf.Totem import Totem
__all__ = ['Globals']
+DEFAULT_CLUSTER_VERSION = 3
+
class Globals(object):
"""Container for objects available throughout the life of the application.
diff --git a/luci/templates/configure.html b/luci/templates/configure.html
index 8f9ec38..eda6592 100644
--- a/luci/templates/configure.html
+++ b/luci/templates/configure.html
@@ -77,7 +77,7 @@
<div class="row"><label>Post Join Delay</label>
<input type="text" class="text" name="post_join_delay" value="${cluster_data and cluster_data.getFenceDaemonPtr().getAttribute('post_join_delay')}"/>
</div>
- <div class="row" py:if="(cluster_data and cluster_data.getClusterVersion()) == 2">
+ <div class="row" py:if="tmpl_context.cluster_version == 2">
<input type="checkbox" class="checkbox" name="fence_xvmd"
py:attrs="cluster_data and cluster_data.hasFenceXVM() and { 'checked': 'checked' } or {}"/>
<label class="choice">Run XVM fence daemon</label>
diff --git a/luci/templates/fence_devices.html b/luci/templates/fence_devices.html
index 85b377e..0ad1a8b 100644
--- a/luci/templates/fence_devices.html
+++ b/luci/templates/fence_devices.html
@@ -2697,8 +2697,7 @@ ${fence_virsh(None,0)}
<div py:def="fence_device_select(model, cont_id)" class="hidden" py:strip="">
<div class="row">
- <div name="fence_select_area"
- py:with="cluster_version = model and model.getClusterVersion() or '3'">
+ <div name="fence_select_area">
<select name="select_div"
onchange="swap_fence_form(this.options[this.selectedIndex].value, '${cont_id}');this.selectedIndex=0">
<option>-- Select a fence device --</option>
@@ -2722,8 +2721,8 @@ ${fence_virsh(None,0)}
<option name="fence_egenera" value="fence_egenera">Egenera SAN Controller</option>
<option name="fence_eps" value="fence_eps">ePowerSwitch</option>
- <py:choose test="cluster_version">
- <py:when test="'3'">
+ <py:choose test="tmpl_context.cluster_version">
+ <py:when test="3">
<option name="fence_virt" value="fence_virt">Fence virt</option>
<option name="fence_xvm" value="fence_xvm">Fence virt (Multicast Mode)</option>
</py:when>
diff --git a/luci/templates/resource_list.html b/luci/templates/resource_list.html
index 943cbed..ff13a86 100644
--- a/luci/templates/resource_list.html
+++ b/luci/templates/resource_list.html
@@ -1300,7 +1300,6 @@ ${vm_resource(None,None,None,0)}
<div py:def="resource_selector(model, dest, parentid)" id="resource_select_area">
<select name="res_select" id="resource_selector" class="resource_selector"
py:with="
- cluster_version = model and model.getClusterVersion() or '3';
svc_onchange_fn = 'insert_resource(this.options[this.selectedIndex].value, \'%s\', this.form, \'%s\');this.selectedIndex=0' % (dest, parentid);
res_onchange_fn = 'swap_resource_form(this.options[this.selectedIndex].value);this.selectedIndex=0'"
py:attrs="{'onchange': model and svc_onchange_fn or res_onchange_fn}">
@@ -1318,8 +1317,8 @@ ${vm_resource(None,None,None,0)}
<option>-- Select a resource type --</option>
<option name="apache_resource" value="apache_resource">Apache</option>
<option name="fs_resource" value="fs_resource">Filesystem</option>
- <py:choose test="cluster_version">
- <py:when test="'3'">
+ <py:choose test="tmpl_context.cluster_version">
+ <py:when test="3">
<option name="clusterfs_resource" value="clusterfs_resource">GFS2</option>
</py:when>
<py:otherwise>
diff --git a/luci/widget_validators/validate_cluster_prop.py b/luci/widget_validators/validate_cluster_prop.py
index ab61735..dab2542 100644
--- a/luci/widget_validators/validate_cluster_prop.py
+++ b/luci/widget_validators/validate_cluster_prop.py
@@ -371,7 +371,7 @@ def validate_cluster_config_form(model, **kw):
model.delFenceXVM()
else:
xvm_obj = FenceXVMd()
- model.addFenceXVM(xvm_obj)
+ model.addFenceXVM(xvm_obj)
return (len(errors) < 1, {'errors': errors})
elif conf_page == 'General':
config_version = kw.get('config_version')
13 years, 11 months
[luci] Proper defaults now show up in Advanced Properties of network page
by Chris Feist
commit 3218e361962dc4de92c80537f9a4b6ab803778b9
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Jun 10 17:35:58 2010 -0500
Proper defaults now show up in Advanced Properties of network page
Also, when defaults are entered in the advanced properties they do
not show up in the cluster.conf file.
luci/lib/ClusterConf/Totem.py | 30 +++++++++++++++++++---
luci/lib/app_globals.py | 2 +
luci/templates/configure.html | 12 ++++----
luci/widget_validators/validate_cluster_prop.py | 23 ++++++++++++++---
4 files changed, 53 insertions(+), 14 deletions(-)
---
diff --git a/luci/lib/ClusterConf/Totem.py b/luci/lib/ClusterConf/Totem.py
index 9ef2306..cd033cd 100644
--- a/luci/lib/ClusterConf/Totem.py
+++ b/luci/lib/ClusterConf/Totem.py
@@ -7,37 +7,59 @@
from TagObject import TagObject
+
TAG_NAME = 'totem'
class Totem(TagObject):
+ TOKEN_RETRANSMITS_BEFORE_LOSS = 4
+ TOKEN_TIMEOUT = 1000
+ JOIN_TIMEOUT = 50
+ CONSENSUS_TIMEOUT = 1200
+
def __init__(self):
TagObject.__init__(self)
self.TAG_NAME = TAG_NAME
def getJoinTimeout(self):
try:
- return self.getAttribute('join')
+ join_timeout = self.getAttribute('join')
+ if join_timeout == None:
+ return self.JOIN_TIMEOUT
+ else:
+ return join_timeout
except:
pass
return None
def getTokenTimeout(self):
try:
- return self.getAttribute('token')
+ token_timeout = self.getAttribute('token')
+ if token_timeout == None:
+ return self.TOKEN_TIMEOUT
+ else:
+ return token_timeout
except:
pass
return None
def getTokenRetransmits(self):
try:
- return self.getAttribute('token_retransmits_before_loss_const')
+ token_retrans = self.getAttribute('token_retransmits_before_loss_const')
+ if token_retrans == None:
+ return self.TOKEN_RETRANSMITS_BEFORE_LOSS
+ else:
+ return token_retrans
except:
pass
return None
def getConsensusTimeout(self):
try:
- return self.getAttribute('consensus')
+ consensus_timeout = self.getAttribute('consensus')
+ if consensus_timeout == None:
+ return self.CONSENSUS_TIMEOUT
+ else:
+ return consensus_timeout
except:
pass
return None
diff --git a/luci/lib/app_globals.py b/luci/lib/app_globals.py
index 09fa724..8d28523 100644
--- a/luci/lib/app_globals.py
+++ b/luci/lib/app_globals.py
@@ -10,6 +10,7 @@
from luci.controllers.scheme import LuciScheme
from luci.lib.form_utils import FormUtils
+from luci.lib.ClusterConf.Totem import Totem
__all__ = ['Globals']
@@ -26,5 +27,6 @@ class Globals(object):
"""Prepare some common static functions, constants etc."""
self.form_utils = FormUtils
self.scheme = LuciScheme
+ self.totem = Totem
self.data = None
diff --git a/luci/templates/configure.html b/luci/templates/configure.html
index 490fae3..8f9ec38 100644
--- a/luci/templates/configure.html
+++ b/luci/templates/configure.html
@@ -12,8 +12,8 @@
</head>
<body py:with="cluster_data = tmpl_context.cluster_data;
- form_utils = app_globals.form_utils">
-
+ form_utils = app_globals.form_utils;
+ totem_defaults = app_globals.totem;">
<div class="sectionblock">
<xi:include href="submenu.html"/>
<div style="clear:both;"></div>
@@ -110,10 +110,10 @@
<div id="advanced"
py:with="totem=cluster_data and cluster_data.getTotemPtr()">
- <div class="row"><label>Token Timeout (ms)</label><input name="token_timeout" class="text" type="text" py:attrs="totem and { 'value': totem.getTokenTimeout() } or {}"/></div>
- <div class="row"><label>Number of token retransmits</label><input name="token_retransmits" class="text" type="text" py:attrs="totem and { 'value': totem.getTokenRetransmits() } or {}"/></div>
- <div class="row"><label>Join Timeout (ms)</label><input name="join_timeout" class="text" type="text" py:attrs="totem and { 'value': totem.getJoinTimeout() } or {}"/></div>
- <div class="row"><label>Consensus Timeout (ms)</label><input name="consensus_timeout" class="text" type="text" py:attrs="totem and { 'value': totem.getConsensusTimeout() } or {}"/></div>
+ <div class="row"><label>Token Timeout (ms)</label><input name="token_timeout" class="text" type="text" py:attrs="totem and { 'value': totem.getTokenTimeout() } or {'value': totem_defaults.TOKEN_TIMEOUT}"/></div>
+ <div class="row"><label>Number of token retransmits</label><input name="token_retransmits" class="text" type="text" py:attrs="totem and { 'value': totem.getTokenRetransmits() } or {'value': totem_defaults.TOKEN_RETRANSMITS_BEFORE_LOSS}"/></div>
+ <div class="row"><label>Join Timeout (ms)</label><input name="join_timeout" class="text" type="text" py:attrs="totem and { 'value': totem.getJoinTimeout() } or {'value': totem_defaults.JOIN_TIMEOUT}"/></div>
+ <div class="row"><label>Consensus Timeout (ms)</label><input name="consensus_timeout" class="text" type="text" py:attrs="totem and { 'value': totem.getConsensusTimeout() } or {'value': totem_defaults.CONSENSUS_TIMEOUT}"/></div>
</div>
<div class="row"><input type="submit" class="button formsubmit blue" value="Apply"/>
</div>
diff --git a/luci/widget_validators/validate_cluster_prop.py b/luci/widget_validators/validate_cluster_prop.py
index 16481b9..ab61735 100644
--- a/luci/widget_validators/validate_cluster_prop.py
+++ b/luci/widget_validators/validate_cluster_prop.py
@@ -18,6 +18,8 @@ from luci.lib.ClusterConf.Method import Method
from luci.lib.db_helpers import create_cluster_obj
from luci.lib.ricci_communicator import RicciCommunicator
from luci.lib.ricci_helpers import send_batch_parallel
+from luci.lib.ClusterConf.Totem import Totem
+
from validate_fence import validateFenceDevice, validateNewFenceDevice, validate_fenceinstance
from xml.dom import minidom
@@ -404,7 +406,10 @@ def validate_cluster_config_form(model, **kw):
except:
errors.append(_('Invalid value for totem join timeout : %s') % join_timeout)
else:
- totem.addAttribute('join', join_timeout)
+ if int(join_timeout) != Totem.JOIN_TIMEOUT:
+ totem.addAttribute('join', join_timeout)
+ else:
+ totem.removeAttribute('join')
token_timeout = kw.get('token_timeout')
if token_timeout:
@@ -415,7 +420,10 @@ def validate_cluster_config_form(model, **kw):
except:
errors.append(_('Invalid value for totem token timeout : %s') % token_timeout)
else:
- totem.addAttribute('token', token_timeout)
+ if int(token_timeout) != Totem.TOKEN_TIMEOUT:
+ totem.addAttribute('token', token_timeout)
+ else:
+ totem.removeAttribute('token')
token_retransmits = kw.get('token_retransmits')
if token_retransmits:
@@ -426,7 +434,10 @@ def validate_cluster_config_form(model, **kw):
except:
errors.append(_('Invalid value for totem token retransmits before loss: %s') % token_retransmits)
else:
- totem.addAttribute('token_retransmits_before_loss_const', token_retransmits)
+ if int(token_retransmits) != Totem.TOKEN_RETRANSMITS_BEFORE_LOSS:
+ totem.addAttribute('token_retransmits_before_loss_const', token_retransmits)
+ else:
+ totem.removeAttribute('token_retransmits_before_loss_const')
consensus_timeout = kw.get('consensus_timeout')
if consensus_timeout:
@@ -437,7 +448,11 @@ def validate_cluster_config_form(model, **kw):
except:
errors.append(_('Invalid value for totem consensus timeout : %s') % consensus_timeout)
else:
- totem.addAttribute('consensus', consensus_timeout)
+ if int(consensus_timeout) != Totem.CONSENSUS_TIMEOUT:
+ totem.addAttribute('consensus', consensus_timeout)
+ else:
+ totem.removeAttribute('consensus')
+
return (len(errors) < 1, {'errors': errors})
else:
return (False, {'errors':
13 years, 11 months
[luci] Fix rhbz #600074: Display error on the resource list page
by Ryan McCabe
commit edaf98f0b32b8981f41f14e7a6f92fccac976dd2
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Thu Jun 10 02:52:39 2010 -0400
Fix rhbz #600074: Display error on the resource list page
luci/templates/resource.html | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
---
diff --git a/luci/templates/resource.html b/luci/templates/resource.html
index 585537a..14df59d 100644
--- a/luci/templates/resource.html
+++ b/luci/templates/resource.html
@@ -31,9 +31,9 @@
<tr>
<th class="checkbox"></th>
<th class="main_id">Name/IP</th>
- <th class="main_id">Type</th>
- <th class="main_id">In Use</th>
- </tr>
+ <th class="resource_tlist_type">Type</th>
+ <th class="resource_tlist_used">In Use</th>
+ </tr>
</thead>
<tbody>
<!--! List all the resources. -->
@@ -49,10 +49,10 @@
<td class="main_id">
<a href="${tg.url(base_url + '/' + entity_name + '.html')}"><span class="entity_ok">${entity_name}</span></a>
</td>
- <td class="main_id">
- <a href="${tg.url(base_url + '/' + entity_name + '.html')}"><span class="entity_ok">${resource_data.getResourceType()}</span></a>
+ <td class="resource_tlist_type">
+ ${resource_data.getResourceType()}
</td>
- <td>
+ <td class="resource_tlist_used">
<py:choose test="refcount">
<py:when test="1">
No
13 years, 11 months
[luci] Fix rhbz #600047: luci allows deletion of global resources that are used by services
by Ryan McCabe
commit 5c4874ea60c9b5e76c463ac57bf0c92eb1274bfe
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Thu Jun 10 02:40:53 2010 -0400
Fix rhbz #600047: luci allows deletion of global resources that are used by services
luci/controllers/cluster.py | 28 +++++++++++++++-----
luci/lib/ClusterConf/BaseResource.py | 10 +++++++
luci/lib/ClusterConf/RefObject.py | 12 ++++++++
luci/templates/resource.html | 48 +++++++++++++++++++---------------
4 files changed, 70 insertions(+), 28 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 601b79f..f227600 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -265,14 +265,28 @@ class IndividualClusterController(BaseController):
status='error')
redirect(tmpl_context.cluster_url)
if command == 'Delete':
- log.info('User "%s" deleted resource "%s" in cluster "%s"'
- % (self.username, ', '.join(cur_list), self.name))
- flash(_("Deleting resources %s") % ', '.join(cur_list),
- status='info')
+ errors = []
+ res_ptr = cmodel.getResourcesPtr()
for i in cur_list:
- cmodel.deleteResource(i)
- cmodel.setModified()
- rh.update_cluster_conf(cmodel)
+ try:
+ cur_res = cmodel.getResourceByName(i)
+ if cur_res.getRefcount() > 1:
+ errors.append(_('Global resource "%s" is in use so cannot be removed') % i)
+ else:
+ res_ptr.removeChild(cur_res)
+ except:
+ pass
+
+ if len(errors) != 0:
+ flash(_('%s') % ', '.join(errors), status='error')
+ else:
+ log.info('User "%s" deleted resource "%s" in cluster "%s"'
+ % (self.username, ', '.join(cur_list), self.name))
+ flash(_("Deleting resources %s") % ', '.join(cur_list),
+ status='info')
+
+ cmodel.setModified()
+ rh.update_cluster_conf(cmodel)
elif command in ("Create", "Edit"):
if command == 'Create':
cur_action = _('Created')
diff --git a/luci/lib/ClusterConf/BaseResource.py b/luci/lib/ClusterConf/BaseResource.py
index 17db412..265cd59 100644
--- a/luci/lib/ClusterConf/BaseResource.py
+++ b/luci/lib/ClusterConf/BaseResource.py
@@ -15,6 +15,16 @@ class BaseResource(TagObject):
self.TAG_NAME = TAG_NAME
self.resource_type = ""
self.deny_all_children = False
+ self.refcount = 1
+
+ def ref(self):
+ self.refcount += 1
+
+ def unref(self):
+ self.refcount -= 1
+
+ def getRefcount(self):
+ return self.refcount
def getResourceType(self):
return self.resource_type
diff --git a/luci/lib/ClusterConf/RefObject.py b/luci/lib/ClusterConf/RefObject.py
index fc0fa37..4e6e75a 100644
--- a/luci/lib/ClusterConf/RefObject.py
+++ b/luci/lib/ClusterConf/RefObject.py
@@ -14,11 +14,23 @@ class RefObject(TagObject):
TagObject.__init__(self)
self.obj_ptr = obj
self.TAG_NAME = self.obj_ptr.getTagName()
+
+ try:
+ obj.ref()
+ except:
+ pass
+
if self.TAG_NAME == "ip":
self.addAttribute("ref", self.obj_ptr.getAttribute("address"))
else:
self.addAttribute("ref", self.obj_ptr.getName())
+ def __del__(self):
+ try:
+ self.obj_ptr.unref()
+ except:
+ pass
+
def getObj(self):
return self.obj_ptr
diff --git a/luci/templates/resource.html b/luci/templates/resource.html
index 47e721c..585537a 100644
--- a/luci/templates/resource.html
+++ b/luci/templates/resource.html
@@ -36,27 +36,34 @@
</tr>
</thead>
<tbody>
- <!--! List all the resources. -->
- <py:if test="cluster_data">
+ <!--! List all the resources. -->
+ <py:if test="cluster_data">
<tr py:for="(i, resource_data) in enumerate(cluster_data.getResources())"
- py:with="entity_name = resource_data.getName()"
- py:attrs="entity_name==name and {'class': 'chosen'} or (not i%2 and {'class': 'even'} or None)">
- <td class="checkbox"><input type="checkbox" name="${entity_name}"/></td>
- <!--! Branch according to the status of the service. -->
- <td class="main_id">
- <a href="${tg.url(base_url + '/' + entity_name + '.html')}">
- <span class="entity_ok">${entity_name}</span>
- </a>
- </td>
- <td class="main_id">
- <a href="${tg.url(base_url + '/' + entity_name + '.html')}">
- <span class="entity_ok">${resource_data.getResourceType()}</span>
- </a>
- </td>
- <td>
- </td>
+ py:with="entity_name = resource_data.getName();
+ refcount = resource_data.getRefcount()"
+ py:attrs="entity_name==name and {'class': 'chosen'} or (not i%2 and {'class': 'even'} or None)">
+ <td class="checkbox">
+ <input type="checkbox" name="${entity_name}"
+ py:attrs="refcount != 1 and {'disabled':'disabled'} or {}"/>
+ </td>
+ <td class="main_id">
+ <a href="${tg.url(base_url + '/' + entity_name + '.html')}"><span class="entity_ok">${entity_name}</span></a>
+ </td>
+ <td class="main_id">
+ <a href="${tg.url(base_url + '/' + entity_name + '.html')}"><span class="entity_ok">${resource_data.getResourceType()}</span></a>
+ </td>
+ <td>
+ <py:choose test="refcount">
+ <py:when test="1">
+ No
+ </py:when>
+ <py:otherwise>
+ <img src="${tg.url('/images/check-11.png')}" alt="Yes" />
+ </py:otherwise>
+ </py:choose>
+ </td>
</tr>
- </py:if>
+ </py:if>
</tbody>
</table>
</div>
@@ -83,7 +90,7 @@
<!--! DETAILS - header section. -->
<div id="details_header">
- <h3 py:content="name">Service A</h3>
+ <h3 py:content="name"/>
<div id="details_header_buttons">
<a href="${tg.url(resources_cmd + '?command=Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
</div>
@@ -91,7 +98,6 @@
<!--! DETAILS - resources. -->
<div class="details_section">
- <!--a href="${tg.url(cmd_url + '/service')}" class="float_button">Create New Resource in this Service</a-->
<div class="details_inner">
<form name="add_resource_dialog" method="post" action="${tg.url(resources_cmd + '?command=Edit')}">
<input type="hidden" name="edit" value="1"/>
13 years, 11 months