[luci] Added support for processing form information from cluster configuration.
by Chris Feist
commit c95375f0e0f369a1337190976e9cf57119259178
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Dec 17 16:18:09 2009 -0600
Added support for processing form information from cluster configuration.
luci/controllers/cluster.py | 18 ++++-
luci/templates/configure.html | 193 ++++++++++++++++-------------------------
2 files changed, 93 insertions(+), 118 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 7069019..18ac876 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -218,7 +218,23 @@ class IndividualClusterController(BaseController):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = "/cluster/" + self.name + '/'
- return dict(page='nodes',name='configure', base_url = '/cluster/' + self.name + '/configure')
+ configure_cmd = '/cluster/' + self.name + '/configure_cmd'
+ return dict(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):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/configure'
+ print command
+ print kw
+ print args
+ print "Configure Command"
+ flash ("Applying Settings: (but not really)")
+ if command == 'Update':
+ flash ("Updating: (but not really)")
+ redirect (tmpl_context.cluster_url)
@expose()
def lookup(self, nodename, *args):
diff --git a/luci/templates/configure.html b/luci/templates/configure.html
index 5d38d12..5439a5c 100644
--- a/luci/templates/configure.html
+++ b/luci/templates/configure.html
@@ -14,7 +14,6 @@
<body py:with="cluster_data = tmpl_context.cluster_data;
form_utils = app_globals.form_utils">
- <form action="${tg.url('apply')}" method="post">
<div class="sectionblock">
<div id="toolbar">
</div>
@@ -49,132 +48,92 @@
<li><a href="#tabs-4">Quorum Partition</a></li>
</ul>
<div id="tabs-1">
- <table>
- <tr>
- <td>
- <b>General Properties</b><br/>
- </td>
- </tr>
- <tr>
- <td>
- Cluster Name
- </td>
- <td>
- <input type="text" value="${tmpl_context.cluster_name}"/>
- </td>
- </tr>
- <tr>
- <td>
- Configuration Version
- </td>
- <td>
- <input type="text"/>
- </td>
- </tr>
- <tr>
- <td>
- <div id="button"><b><button>Show advanced cluster properties</button></b></div>
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <div id="advanced">
- <table>
- <tr>
- <td>
- Token Timeout (ms)
- </td>
- <td>
- <input type="text"/>
- </td>
- </tr>
- <tr>
- <td>
- Number of token retransmits
- </td>
- <td>
- <input type="text"/>
- </td>
- </tr>
- <tr>
- <td>
- Join Timeout (ms)
- </td>
- <td>
- <input type="text"/>
- </td>
- </tr>
- <tr>
- <td>
- Consensus Timeout (ms)
- </td>
- <td>
- <input type="text"/>
- </td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <input type="submit" value="Apply"/>
- </td>
- </tr>
- </table>
+ <form action="${tg.url(configure_cmd)}" method="post">
+ <input type="hidden" name="page" value="General"/>
+ <table>
+ <tr><td><b>General Properties</b><br/></td></tr>
+ <tr><td>Cluster Name</td>
+ <td>
+ <input name="ClusterName" type="text" value="${tmpl_context.cluster_name}"/>
+ </td>
+ </tr>
+ <tr><td>Configuration Version</td><td><input type="text"/></td></tr>
+ <tr><td><div id="button"><b><button>Show advanced cluster properties</button></b></div></td></tr>
+ <tr><td colspan="2">
+ <div id="advanced">
+ <table>
+ <tr><td>Token Timeout (ms)</td><td><input type="text"/></td></tr>
+ <tr><td>Number of token retransmits</td><td><input type="text"/></td></tr>
+ <tr><td>Join Timeout (ms)</td><td><input type="text"/></td></tr>
+ <tr><td>Consensus Timeout (ms)</td><td><input type="text"/></td></tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+ <tr><td><input type="submit" value="Apply"/></td></tr>
+ </table>
+ </form>
</div>
<div id="tabs-2">
- <table>
- <tr><td><b>Fence Daemon Properties</b></td></tr>
- <tr><td>Post Fail Delay</td><td><input type="text"/></td></tr>
- <tr><td>Post Join Delay</td><td><input type="text"/></td></tr>
- <tr><td>Run XVM fence daemon</td><td><input type="checkbox"/></td></tr>
- <tr><td></td></tr>
- <tr><td><b>XVM fence dameon key distribution</b></td></tr>
- <tr><td>Enter a node hostname from the host cluster</td><td><input type="text"/></td></tr>
- <tr><td>Enter a node hostname from the hosted (virtual) cluster</td><td><input type="text"/></td></tr>
- <tr><td><input type="submit" value="Retrieve cluster nodes"/></td></tr>
- <tr><td><input type="submit" value="Apply"/></td></tr>
- </table>
+ <form action="${tg.url(configure_cmd)}" method="post">
+ <input type="hidden" name="page" value="Fence"/>
+ <table>
+ <tr><td><b>Fence Daemon Properties</b></td></tr>
+ <tr><td>Post Fail Delay</td><td><input type="text"/></td></tr>
+ <tr><td>Post Join Delay</td><td><input type="text"/></td></tr>
+ <tr><td>Run XVM fence daemon</td><td><input type="checkbox"/></td></tr>
+ <tr><td></td></tr>
+ <tr><td><b>XVM fence dameon key distribution</b></td></tr>
+ <tr><td>Enter a node hostname from the host cluster</td><td><input type="text"/></td></tr>
+ <tr><td>Enter a node hostname from the hosted (virtual) cluster</td><td><input type="text"/></td></tr>
+ <tr><td><input type="submit" value="Retrieve cluster nodes"/></td></tr>
+ <tr><td><input type="submit" value="Apply"/></td></tr>
+ </table>
+ </form>
</div>
<div id="tabs-3">
- <table>
- <tr><td><b>Multicast Configuration</b></td></tr>
- <tr><td><input name="multicast" type="radio"/> Let cluster choose the multicast address</td></tr>
- <tr><td><input name="multicast" type="radio"/> Specify the multicast address manually</td></tr>
- <tr><td>Multicast address</td><td><input type="text"/></td></tr>
- <tr><td>Multicast network interface (optional)</td><td><input type="text"/></td></tr>
- <tr><td><input type="submit" value="Apply"/></td></tr>
- </table>
+ <form action="${tg.url(configure_cmd)}" method="post">
+ <input type="hidden" name="page" value="Multicast"/>
+ <table>
+ <tr><td><b>Multicast Configuration</b></td></tr>
+ <tr><td><input name="multicast" type="radio"/> Let cluster choose the multicast address</td></tr>
+ <tr><td><input name="multicast" type="radio"/> Specify the multicast address manually</td></tr>
+ <tr><td>Multicast address</td><td><input type="text"/></td></tr>
+ <tr><td>Multicast network interface (optional)</td><td><input type="text"/></td></tr>
+ <tr><td><input type="submit" value="Apply"/></td></tr>
+ </table>
+ </form>
</div>
<div id="tabs-4">
- <table>
- <tr><td><b>Quorum Partition Configuration</b></td></tr>
- <tr><td><input name="quorum" type="radio"/> Do not use a Quorum Partition</td></tr>
- <tr><td><input name="quorum" type="radio"/> Use a Quorum Partition</td></tr>
- <tr><td>Internal</td><td><input type="text"/></td></tr>
- <tr><td>Votes</td><td><input type="text"/></td></tr>
- <tr><td>TKO</td><td><input type="text"/></td></tr>
- <tr><td>Minimum Score</td><td><input type="text"/></td></tr>
- <tr><td><input name="labeldev" type="radio"/> Label</td></tr>
- <tr><td><input name="labeldev" type="radio"/> Device (deprecated)</td></tr>
- </table>
- <table>
- <tr><td><b>Heuristics</b></td></tr>
- <tr><td><b>Path to Program</b></td><td><b>Interval</b></td><td><b>Score</b></td></tr>
- <tr>
- <td><input type="text"/></td>
- <td><input type="text" size="5"/></td>
- <td><input type="text" size="5"/></td>
- </tr>
- <tr><td><input type="submit" value="Add another heuristic"/></td></tr>
- <tr><td><input type="submit" value="Apply"/></td></tr>
- </table>
+ <form action="${tg.url(configure_cmd)}" method="post">
+ <input type="hidden" name="page" value="Quorum Partition"/>
+ <table>
+ <tr><td><b>Quorum Partition Configuration</b></td></tr>
+ <tr><td><input name="quorum" type="radio"/> Do not use a Quorum Partition</td></tr>
+ <tr><td><input name="quorum" type="radio"/> Use a Quorum Partition</td></tr>
+ <tr><td>Internal</td><td><input type="text"/></td></tr>
+ <tr><td>Votes</td><td><input type="text"/></td></tr>
+ <tr><td>TKO</td><td><input type="text"/></td></tr>
+ <tr><td>Minimum Score</td><td><input type="text"/></td></tr>
+ <tr><td><input name="labeldev" type="radio"/> Label</td></tr>
+ <tr><td><input name="labeldev" type="radio"/> Device (deprecated)</td></tr>
+ </table>
+ <table>
+ <tr><td><b>Heuristics</b></td></tr>
+ <tr><td><b>Path to Program</b></td><td><b>Interval</b></td><td><b>Score</b></td></tr>
+ <tr>
+ <td><input type="text"/></td>
+ <td><input type="text" size="5"/></td>
+ <td><input type="text" size="5"/></td>
+ </tr>
+ <tr><td><input type="submit" value="Add another heuristic"/></td></tr>
+ <tr><td><input type="submit" value="Apply"/></td></tr>
+ </table>
+ </form>
</div>
</div>
</div>
</div>
- </form>
<!--! DETAILS SECTION. -->
<div class="sectionblock">
14 years, 5 months
[luci] Added support for processing form information for fences.
by Chris Feist
commit 0310307b7f0a6c9ba7200f53f01b6e5914db6714
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Dec 17 15:33:15 2009 -0600
Added support for processing form information for fences.
luci/controllers/cluster.py | 31 ++++++++++++++++++++++++++++++-
luci/templates/fence.html | 12 ++++++------
2 files changed, 36 insertions(+), 7 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 6a283cc..7069019 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -182,7 +182,36 @@ class IndividualClusterController(BaseController):
fencename = args[0]
else:
fencename = None
- return dict(page='nodes',name=fencename, base_url = '/cluster/' + self.name + '/fences')
+
+ fences_cmd = '/cluster/' + self.name + '/fences_cmd'
+ 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):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/fences'
+ # If we're using the checkboxes, we control multiple nodes at once
+ if "MultiAction" in kw:
+ print "MAction!"
+ kw["name"] = ""
+ nodelist = ""
+ command = kw["MultiAction"]
+ for key,element in kw.items():
+ if element == "on":
+ nodelist = nodelist + " " + key
+ if command == 'Delete':
+ flash ("Deleting Fences: " + nodelist)
+ if command == 'Update':
+ flash ("Updating Fences: " + nodelist)
+ redirect (tmpl_context.cluster_url)
+ else:
+ if command == 'Delete':
+ flash ("Deleting: " + kw["name"] + " (but not really)")
+ if command == 'Update':
+ flash ("Updating: " + kw["name"] + " (but not really)")
+ redirect (tmpl_context.cluster_url + '/' + kw["name"])
@expose("luci.templates.configure")
def configure(self,*args):
diff --git a/luci/templates/fence.html b/luci/templates/fence.html
index 4c243cb..97693c1 100644
--- a/luci/templates/fence.html
+++ b/luci/templates/fence.html
@@ -14,11 +14,11 @@
<body py:with="cluster_data = tmpl_context.cluster_data;
form_utils = app_globals.form_utils">
- <form action="${tg.url('apply')}" method="post">
+ <form action="${tg.url(fences_cmd)}" method="post">
<div class="sectionblock">
<div id="toolbar">
- <input type="submit" name="Update" value="${_('Update')}" class="toolbar_button" id="tb_update"/>
- <input type="submit" name="Delete" value="${_('Delete')}" class="toolbar_button" id="tb_delete"/>
+ <input type="submit" name="MultiAction" value="${_('Update')}" class="toolbar_button" id="tb_update"/>
+ <input type="submit" name="MultiAction" value="${_('Delete')}" class="toolbar_button" id="tb_delete"/>
<a href="${tg.url('add')}" class="toolbar_button" id="tb_add">Add</a>
</div>
@@ -40,7 +40,7 @@
<!--! List all the fences. -->
<tr py:for="i, (entity_name, fence_data) in enumerate(cluster_data.fences.iteritems())"
py:attrs="entity_name==name and {'class': 'chosen'} or (not i%2 and {'class': 'even'} or None)"
- py:with="identifier = form_utils.string2Id(entity_name);
+ py:with="identifier = entity_name;
local_fence = len(fence_data['nodes']) == 1">
<td class="checkbox"><input type="checkbox" name="${identifier}"/></td>
<!--! If the fence is shared, display appropriate icon. -->
@@ -89,8 +89,8 @@
<div id="details_header">
<h3 py:content="name">Fence A</h3>
<div id="details_header_buttons">
- <a href="${tg.url('apply?' + 'Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
- <a href="${tg.url('apply?' + 'Update' + '&name=' + name)}" id="dh_update" title="update"><span class="hide">update</span></a>
+ <a href="${tg.url(fences_cmd + '?command=Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
+ <a href="${tg.url(fences_cmd + '?command=Update' + '&name=' + name)}" id="dh_update" title="update"><span class="hide">update</span></a>
<!-- TODO: remove? <a href="${tg.url(request.path_qs)}" id="dh_update" title="refresh"><span class="hide">refresh</span></a> -->
</div>
<span class="details_header_info_label">Type</span> <span class="details_header_info">${details['type']}</span>
14 years, 5 months
[luci] Added support for processing form information for failovers.
by Chris Feist
commit 0d6996f091c1341af198f0f13e2c7e2d31ca2ca4
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Dec 17 15:27:07 2009 -0600
Added support for processing form information for failovers.
luci/controllers/cluster.py | 28 +++++++++++++++++++++++++++-
luci/templates/failover.html | 12 ++++++------
2 files changed, 33 insertions(+), 7 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index f47cb21..6a283cc 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -145,7 +145,33 @@ class IndividualClusterController(BaseController):
failovername = args[0]
else:
failovername = None
- return dict(page='nodes',name=failovername, base_url = '/cluster/' + self.name + '/failovers')
+ failovers_cmd = '/cluster/' + self.name + '/failovers_cmd'
+ 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):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/failovers'
+ # If we're using the checkboxes, we control multiple nodes at once
+ if "MultiAction" in kw:
+ print "MAction!"
+ kw["name"] = ""
+ nodelist = ""
+ command = kw["MultiAction"]
+ for key,element in kw.items():
+ if element == "on":
+ nodelist = nodelist + " " + key
+ if command == 'Delete':
+ flash ("Deleting Failover: " + nodelist)
+ redirect (tmpl_context.cluster_url)
+ else:
+ if command == 'Delete':
+ flash ("Deleting: " + kw["name"] + " (but not really)")
+ if command == 'update_properties':
+ flash ("Updating Properties...")
+ redirect (tmpl_context.cluster_url + '/' + kw["name"])
@expose("luci.templates.fence")
def fences(self,*args):
diff --git a/luci/templates/failover.html b/luci/templates/failover.html
index 470b28f..c148115 100644
--- a/luci/templates/failover.html
+++ b/luci/templates/failover.html
@@ -16,10 +16,10 @@
py:with="cluster_data = tmpl_context.cluster_data;
form_utils = app_globals.form_utils">
- <form action="${tg.url('apply')}" method="post">
+ <form action="${tg.url(failovers_cmd)}" method="post">
<div class="sectionblock">
<div id="toolbar">
- <input type="submit" name="Delete" value="${_('Delete')}" class="toolbar_button" id="tb_delete"/>
+ <input type="submit" name="MultiAction" value="${_('Delete')}" class="toolbar_button" id="tb_delete"/>
<a href="${tg.url('add')}" class="toolbar_button" id="tb_add">Add</a>
</div>
@@ -41,7 +41,7 @@
<!--! List all the failover domains. -->
<tr py:for="i, (entity_name, failover_data) in enumerate(cluster_data.failovers.iteritems())"
py:attrs="entity_name==name and {'class': 'chosen'} or (not i%2 and {'class': 'even'} or None)"
- py:with="identifier=form_utils.string2Id(entity_name)">
+ py:with="identifier=entity_name">
<td class="checkbox"><input type="checkbox" name="${identifier}"/></td>
<td class="icon"></td>
<td class="main_id"><a href="${tg.url(base_url + '/' + entity_name)}">${entity_name}</a></td>
@@ -78,15 +78,15 @@
<div id="details_header">
<h3 py:content="name">Failover name</h3>
<div id="details_header_buttons">
- <a href="${tg.url('apply?' + 'Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">Delete</span></a>
+ <a href="${tg.url(failovers_cmd + '?command=Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">Delete</span></a>
</div>
</div>
<!--! DETAILS - attributes section. -->
<div class="details_section">
<div class="details_inner">
- <form action="${tg.url('update_properties')}" method="post">
- <input type="hidden" name="name" value="${form_utils.string2Id(name)}"/>
+ <form action="${tg.url(failovers_cmd + '?command=update_properties')}" method="post">
+ <input type="hidden" name="name" value="${name}"/>
<input type="submit" value="Update Properties" class="float_button"/>
<table id="fdom_tattr">
<tr>
14 years, 5 months
[luci] Added support for processing service commands (reboot and delete).
by Chris Feist
commit c88420f499352fcaee8c39789596558ebfd3cf5e
Author: Chris Feist <cfeist(a)redhat.com>
Date: Wed Dec 16 18:16:42 2009 -0600
Added support for processing service commands (reboot and delete).
luci/controllers/cluster.py | 38 ++++++++++++++++++++++++++++++++++----
luci/templates/service.html | 12 ++++++------
2 files changed, 40 insertions(+), 10 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 515a28a..f47cb21 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -39,9 +39,9 @@ class ClusterController(BaseController):
class IndividualClusterController(BaseController):
def __init__(self,name,data,nodename=None):
- self.name = name
- self.data = data
- self.nodename = nodename
+ self.name = name
+ self.data = data
+ self.nodename = nodename
@expose("luci.templates.node")
def default(self):
@@ -102,9 +102,39 @@ class IndividualClusterController(BaseController):
tmpl_context.cluster_url = "/cluster/" + self.name + '/'
if (len(args) == 1):
servicename = args[0]
+ print "Servicename: " + servicename
else:
servicename = None
- return dict(page='nodes',name=servicename, base_url = '/cluster/' + self.name + '/services')
+ print "No service name"
+ base_url = '/cluster/' + self.name + '/services'
+ services_cmd = '/cluster/' + self.name + '/services_cmd'
+ 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):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/services'
+ # If we're using the checkboxes, we control multiple nodes at once
+ if "MultiAction" in kw:
+ print "MAction!"
+ kw["name"] = ""
+ nodelist = ""
+ command = kw["MultiAction"]
+ for key,element in kw.items():
+ if element == "on":
+ nodelist = nodelist + " " + key
+ if command == 'Reboot':
+ flash ("Rebooting Service: " + nodelist)
+ if command == 'Delete':
+ flash ("Deleting Service: " + nodelist)
+ redirect (tmpl_context.cluster_url)
+ else:
+ if command == 'Delete':
+ flash ("Deleting: " + kw["name"] + " (but not really)")
+ if command == 'Reboot':
+ flash ("Rebooting: " + kw["name"] + " (but not really)")
+ redirect (tmpl_context.cluster_url + '/' + kw["name"])
@expose("luci.templates.failover")
def failovers(self,*args):
diff --git a/luci/templates/service.html b/luci/templates/service.html
index 8bd6f77..9ac866b 100644
--- a/luci/templates/service.html
+++ b/luci/templates/service.html
@@ -14,11 +14,11 @@
<body py:with="cluster_data = tmpl_context.cluster_data;
form_utils = app_globals.form_utils">
- <form action="${tg.url('/apply')}" method="post">
+ <form action="${tg.url(services_cmd)}" method="post">
<div class="sectionblock">
<div id="toolbar">
- <input type="submit" name="Reboot" value="${_('Reboot')}" class="toolbar_button" id="tb_reboot" />
- <input type="submit" name="Delete" value="${_('Delete')}" class="toolbar_button" id="tb_delete" />
+ <input type="submit" name="MultiAction" value="${_('Reboot')}" class="toolbar_button" id="tb_reboot" />
+ <input type="submit" name="MultiAction" value="${_('Delete')}" class="toolbar_button" id="tb_delete" />
<a href="${tg.url('/add')}" class="toolbar_button" id="tb_add">Add</a>
</div>
@@ -40,7 +40,7 @@
<!--! List all the services. -->
<tr py:for="i, (entity_name, service_data) in enumerate(cluster_data.services.iteritems())"
py:attrs="entity_name==name and {'class': 'chosen'} or (not i%2 and {'class': 'even'} or None)"
- py:with="identifier=form_utils.string2Id(entity_name)">
+ py:with="identifier=entity_name">
<td class="checkbox"><input type="checkbox" name="${identifier}"/></td>
<!--! Branch according to the status of the service. -->
<py:choose test="service_data['running']">
@@ -108,8 +108,8 @@
<div id="details_header">
<h3 py:content="name">Service A</h3>
<div id="details_header_buttons">
- <a href="${tg.url('/apply?' + 'Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
- <a href="${tg.url('/apply?' + 'Reboot' + '&name=' + name)}" id="dh_update" title="reboot"><span class="hide">reboot</span></a>
+ <a 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=Reboot' + '&name=' + name)}" id="dh_update" title="reboot"><span class="hide">reboot</span></a>
<!-- TODO: remove? <a href="${tg.url(request.path_qs)}" id="dh_update" title="refresh"><span class="hide">refresh</span></a> -->
</div>
<span class="details_header_info_label">Status</span> <span class="details_header_info">${tmpl_context.current_service_status}</span>
14 years, 5 months
[luci] Added support for performing actions on multiple nodes.
by Chris Feist
commit e046668ff640b15009360784e1ba788764058f8d
Author: Chris Feist <cfeist(a)redhat.com>
Date: Tue Dec 8 16:33:32 2009 -0600
Added support for performing actions on multiple nodes.
luci/controllers/cluster.py | 16 +++++++++++++++-
luci/templates/node.html | 11 +++++------
2 files changed, 20 insertions(+), 7 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 77c40d2..515a28a 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -64,9 +64,23 @@ class IndividualClusterController(BaseController):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
tmpl_context.cluster_url = "/cluster/" + self.name + '/'
+ # If we're using the checkboxes, we control multiple nodes at once
if "MultiAction" in kw:
print "MAction!"
kw["name"] = ""
+ nodelist = ""
+ command = kw["MultiAction"]
+ for key,element in kw.items():
+ if element == "on":
+ nodelist = nodelist + " " + key
+ if command == 'Reboot':
+ flash ("Rebooting: " + nodelist)
+ if command == 'Fence':
+ flash ("Fencing: " + nodelist)
+ if command == 'Leave Cluster':
+ flash ("Removing from Cluster: " + nodelist)
+ if command == 'Delete':
+ flash ("Deleting: " + nodelist)
else:
if command == 'add':
flash ("Adding node on " + tmpl_context.cluster_name)
@@ -91,7 +105,7 @@ class IndividualClusterController(BaseController):
else:
servicename = None
return dict(page='nodes',name=servicename, base_url = '/cluster/' + self.name + '/services')
-
+
@expose("luci.templates.failover")
def failovers(self,*args):
tmpl_context.cluster_data=data.clusters[self.name]
diff --git a/luci/templates/node.html b/luci/templates/node.html
index 758c02b..2ea2a26 100644
--- a/luci/templates/node.html
+++ b/luci/templates/node.html
@@ -17,11 +17,10 @@
<form action="${tg.url('nodes_cmd')}" method="post">
<div class="sectionblock">
<div id="toolbar">
- <input type="hidden" name="MultiAction" />
- <input type="submit" name="Reboot" value="${_('Reboot')}" class="toolbar_button" id="tb_reboot" />
- <input type="submit" name="Fence" value="${_('Fence')}" class="toolbar_button" id="tb_fence" />
- <input type="submit" name="Leave" value="${_('Leave Cluster')}" class="toolbar_button" id="tb_leave" />
- <input type="submit" name="Delete" value="${_('Delete')}" class="toolbar_button" id="tb_delete" />
+ <input type="submit" name="MultiAction" value="${_('Reboot')}" class="toolbar_button" id="tb_reboot" />
+ <input type="submit" name="MultiAction" value="${_('Fence')}" class="toolbar_button" id="tb_fence" />
+ <input type="submit" name="MultiAction" value="${_('Leave Cluster')}" class="toolbar_button" id="tb_leave" />
+ <input type="submit" name="MultiAction" value="${_('Delete')}" class="toolbar_button" id="tb_delete" />
<a href="${tg.url(tmpl_context.cluster_url + base_url + '_cmd/add')}" class="toolbar_button" id="tb_add">Add</a>
</div>
@@ -43,7 +42,7 @@
<!--! List all the nodes. -->
<tr py:for="i, (entity_name, node_data) in enumerate(cluster_data.nodes.iteritems())"
py:attrs="entity_name==name and {'class': 'chosen'} or (not i%2 and {'class': 'even'} or None)"
- py:with="identifier=form_utils.string2Id(entity_name)">
+ py:with="identifier=entity_name">
<td class="checkbox"><input type="checkbox" name="${identifier}"/></td>
<!--! Branch according to the status of the node. -->
<py:choose test="node_data['status']">
14 years, 5 months
[luci] Added controller code to respond to fence/reboot/etc. requests for nodes
by Chris Feist
commit 1353014cf009c2bc79b14225353884d82c4fb4b8
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Dec 3 16:18:46 2009 -0600
Added controller code to respond to fence/reboot/etc. requests for nodes
luci/controllers/cluster.py | 42 ++++++++++++++++++++++++++++++++++--------
luci/templates/master.html | 10 +++++-----
luci/templates/node.html | 19 ++++++++++---------
3 files changed, 49 insertions(+), 22 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 9eac578..77c40d2 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -24,6 +24,8 @@ class ClusterController(BaseController):
@expose()
def lookup(self, name, *args):
+ print name
+ print args
if name in data.clusters.iterkeys():
icc = IndividualClusterController(name,data)
return icc, args
@@ -45,21 +47,45 @@ class IndividualClusterController(BaseController):
def default(self):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
return dict(page='nodes',name=self.nodename, base_url = '/nodes')
@expose("luci.templates.node")
def nodes(self):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
return dict(page='nodes',name=self.nodename, base_url = '/nodes')
+# This processes all of the commands that we can apply to a node
+ @expose("luci.templates.node")
+ def nodes_cmd(self, command=None, **kw):
+ print kw
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
+ if "MultiAction" in kw:
+ print "MAction!"
+ kw["name"] = ""
+ else:
+ if command == 'add':
+ flash ("Adding node on " + tmpl_context.cluster_name)
+ if command == 'Delete':
+ flash ("Deleting: " + kw["name"] + " (but not really)")
+ if command == 'Fence':
+ flash ("Fencing: " + kw["name"] + " (but not really)")
+ if command == 'Leave':
+ flash ("Leaving: " + kw["name"] + " (but not really)")
+ if command == 'Reboot':
+ flash ("Rebooting: " + kw["name"] + " (but not really)")
+ redirect (tmpl_context.cluster_url + kw["name"])
+
+
@expose("luci.templates.service")
def services(self,*args):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
if (len(args) == 1):
servicename = args[0]
else:
@@ -70,7 +96,7 @@ class IndividualClusterController(BaseController):
def failovers(self,*args):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
if (len(args) == 1):
failovername = args[0]
else:
@@ -81,7 +107,7 @@ class IndividualClusterController(BaseController):
def fences(self,*args):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
if (len(args) == 1):
fencename = args[0]
else:
@@ -92,7 +118,7 @@ class IndividualClusterController(BaseController):
def configure(self,*args):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
return dict(page='nodes',name='configure', base_url = '/cluster/' + self.name + '/configure')
@expose()
@@ -100,7 +126,7 @@ class IndividualClusterController(BaseController):
clustername = self.name
tmpl_context.cluster_data=data.clusters[clustername]
tmpl_context.cluster_name = clustername
- tmpl_context.cluster_url = "/cluster/" + clustername
+ tmpl_context.cluster_url = "/cluster/" + clustername + '/'
inc = IndividualNodeController(clustername,self.data,nodename)
return inc, args
@@ -114,7 +140,7 @@ class IndividualNodeController(BaseController):
def default(self):
tmpl_context.cluster_data=data.clusters[self.name]
tmpl_context.cluster_name = self.name
- tmpl_context.cluster_url = "/cluster/" + self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name + '/'
return dict(page='nodes',name=self.nodename, base_url = '/nodes')
@expose()
diff --git a/luci/templates/master.html b/luci/templates/master.html
index f4224c4..c0ac5c7 100644
--- a/luci/templates/master.html
+++ b/luci/templates/master.html
@@ -37,11 +37,11 @@
</py:with>
<py:if test="'cluster_url' in dir(tmpl_context)">
<ul class="submenu">
- <li><a href="${tg.url(tmpl_context.cluster_url + '/nodes')}" class="${('', 'active')[base_url.endswith('/nodes')]}">Nodes</a></li>
- <li><a href="${tg.url(tmpl_context.cluster_url + '/services')}" class="${('', 'active')[base_url.endswith('/services')]}">Services</a></li>
- <li><a href="${tg.url(tmpl_context.cluster_url + '/failovers')}" class="${('', 'active')[base_url.endswith('/failovers')]}">Failovers</a></li>
- <li><a href="${tg.url(tmpl_context.cluster_url +'/fences')}" class="${('', 'active')[base_url.endswith('/fences')]}">Fences</a></li>
- <li><a href="${tg.url(tmpl_context.cluster_url +'/configure')}" class="${('', 'active')[base_url.endswith('/configure')]}">Configure</a></li>
+ <li><a href="${tg.url(tmpl_context.cluster_url + 'nodes')}" class="${('', 'active')[base_url.endswith('/nodes')]}">Nodes</a></li>
+ <li><a href="${tg.url(tmpl_context.cluster_url + 'services')}" class="${('', 'active')[base_url.endswith('/services')]}">Services</a></li>
+ <li><a href="${tg.url(tmpl_context.cluster_url + 'failovers')}" class="${('', 'active')[base_url.endswith('/failovers')]}">Failovers</a></li>
+ <li><a href="${tg.url(tmpl_context.cluster_url +'fences')}" class="${('', 'active')[base_url.endswith('/fences')]}">Fences</a></li>
+ <li><a href="${tg.url(tmpl_context.cluster_url +'configure')}" class="${('', 'active')[base_url.endswith('/configure')]}">Configure</a></li>
</ul>
</py:if>
<py:if test="defined('page')">
diff --git a/luci/templates/node.html b/luci/templates/node.html
index 01874d9..758c02b 100644
--- a/luci/templates/node.html
+++ b/luci/templates/node.html
@@ -14,14 +14,15 @@
<body py:with="cluster_data = tmpl_context.cluster_data;
form_utils = app_globals.form_utils">
- <form action="${tg.url('apply')}" method="post">
+ <form action="${tg.url('nodes_cmd')}" method="post">
<div class="sectionblock">
<div id="toolbar">
+ <input type="hidden" name="MultiAction" />
<input type="submit" name="Reboot" value="${_('Reboot')}" class="toolbar_button" id="tb_reboot" />
<input type="submit" name="Fence" value="${_('Fence')}" class="toolbar_button" id="tb_fence" />
<input type="submit" name="Leave" value="${_('Leave Cluster')}" class="toolbar_button" id="tb_leave" />
<input type="submit" name="Delete" value="${_('Delete')}" class="toolbar_button" id="tb_delete" />
- <a href="${tg.url('add')}" class="toolbar_button" id="tb_add">Add</a>
+ <a href="${tg.url(tmpl_context.cluster_url + base_url + '_cmd/add')}" class="toolbar_button" id="tb_add">Add</a>
</div>
<!--! OVERVIEW SECTION. -->
@@ -50,7 +51,7 @@
<py:when test="cluster_data.NODE_ACTIVE">
<td class="icon"></td>
<td class="main_id">
- <a href="${tg.url(entity_name)}">
+ <a href="${tmpl_context.cluster_url + entity_name}">
<span class="entity_ok">${entity_name}</span>
</a>
</td>
@@ -62,7 +63,7 @@
<img src="${tg.url('/images/exclamation.png')}" alt="Node has a problem." />
</td>
<td class="main_id">
- <a href="${tg.url(entity_name)}">
+ <a href="${tmpl_context.cluster_url + entity_name}">
<span class="entity_fail">${entity_name}</span>
</a>
</td>
@@ -74,7 +75,7 @@
<img src="${tg.url('/images/question.png')}" alt="Status of the node is unknown." />
</td>
<td class="main_id">
- <a href="${tg.url(entity_name)}">
+ <a href="${tmpl_context.cluster_url + entity_name}">
<span class="entity_unknown">${entity_name}</span>
</a>
</td>
@@ -110,10 +111,10 @@
<div id="details_header">
<h3 py:content="name">Node A</h3>
<div id="details_header_buttons">
- <a href="${tg.url('apply?' + 'Delete' + '&name=' + name)}" id="dh_reboot" title="reboot"><span class="hide">reboot</span></a>
- <a href="${tg.url('apply?' + 'Fence' + '&name=' + name)}" id="dh_fence" title="fence"><span class="hide">fence</span></a>
- <a href="${tg.url('apply?' + 'Leave' + '&name=' + name)}" id="dh_leave" title="leave cluster"><span class="hide">leave cluster</span></a>
- <a href="${tg.url('apply?' + 'Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
+ <a href="${tg.url('nodes_cmd?command=Reboot' + '&name=' + name)}" id="dh_reboot" title="reboot"><span class="hide">reboot</span></a>
+ <a href="${tg.url('nodes_cmd?command=Fence' + '&name=' + name)}" id="dh_fence" title="fence"><span class="hide">fence</span></a>
+ <a href="${tg.url('nodes_cmd?command=Leave' + '&name=' + name)}" id="dh_leave" title="leave cluster"><span class="hide">leave cluster</span></a>
+ <a href="${tg.url('nodes_cmd?command=Delete' + '&name=' + name)}" id="dh_delete" title="delete"><span class="hide">delete</span></a>
</div>
<span class="details_header_info_label">Status</span>
<span class="details_header_info" py:choose="details['status']">
14 years, 5 months
[luci] Removed all references to scheme
by Chris Feist
commit dc0df94453a05dd5d34749949cb7a85cf634a9c6
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Dec 3 13:55:06 2009 -0600
Removed all references to scheme
luci/controllers/decorators.py | 4 ++--
luci/controllers/root.py | 4 +---
luci/lib/app_globals.py | 2 --
.../validate_create_cluster_form.py | 1 -
4 files changed, 3 insertions(+), 8 deletions(-)
---
diff --git a/luci/controllers/decorators.py b/luci/controllers/decorators.py
index e54d9c3..76ef1c6 100644
--- a/luci/controllers/decorators.py
+++ b/luci/controllers/decorators.py
@@ -14,8 +14,8 @@ __all__ = ['mountSubControllers',
# Imports into module's namespace.
-APP_PREFIX = app_globals.scheme.APP_PREFIX
-base2CmdCtrl = app_globals.scheme.base2CmdCtrl
+APP_PREFIX = '/'
+base2CmdCtrl = '/'
def mountSubControllers(ctrls_dict=None, **ctrls_kwargs):
diff --git a/luci/controllers/root.py b/luci/controllers/root.py
index b4afec3..7bda783 100644
--- a/luci/controllers/root.py
+++ b/luci/controllers/root.py
@@ -28,10 +28,8 @@ __all__ = ['RootController']
# Imports into module's namespace.
-scheme = app_globals.scheme
-#(a)mountSubControllers(scheme.mounts())
class RootController(BaseController):
"""
The root controller for the luci application.
@@ -87,7 +85,7 @@ class RootController(BaseController):
elif homebasepage == 'managesystems':
tmpl_context.form = create_manage_systems_form
- app_url = scheme.APP_PREFIX + u'/'
+ app_url = u'/'
return dict(page='homebase',homebasepage=homebasepage,args=args,
base_url=app_url + 'cluster')
diff --git a/luci/lib/app_globals.py b/luci/lib/app_globals.py
index 0975673..b464e11 100644
--- a/luci/lib/app_globals.py
+++ b/luci/lib/app_globals.py
@@ -3,7 +3,6 @@
"""The application's Globals object"""
from luci.lib.form_utils import FormUtils
-from luci.controllers.scheme import LuciScheme
from luci.lib.demo_data import ClusterData
__all__ = ['Globals']
@@ -20,5 +19,4 @@ class Globals(object):
def __init__(self):
"""Prepare some common static functions, constants etc."""
self.form_utils = FormUtils
- self.scheme = LuciScheme
self.data = ClusterData()
diff --git a/luci/widget_validators/validate_create_cluster_form.py b/luci/widget_validators/validate_create_cluster_form.py
index 7142861..c977279 100644
--- a/luci/widget_validators/validate_create_cluster_form.py
+++ b/luci/widget_validators/validate_create_cluster_form.py
@@ -18,7 +18,6 @@ import luci.lib.ricci_queries as rq
from luci.widgets.create_cluster_form import create_cluster_form
# Imports into module's namespace.
-scheme = app_globals.scheme
data = app_globals.data
def validate_create_cluster_form(self, **kw):
14 years, 5 months
[luci] Cleanup and remove debugging
by Chris Feist
commit e8e9d944117c7ac6158deafdbb340d29cd866b11
Author: Chris Feist <cfeist(a)redhat.com>
Date: Thu Dec 3 13:42:53 2009 -0600
Cleanup and remove debugging
- Removed old cluster.py and replaced with the newer cluster2.py to simplify
debugging, etc.
- Removed unneeded debuging information.
luci/controllers/cluster.py | 362 +++++++++++++-----------------------------
luci/controllers/cluster2.py | 133 ---------------
luci/controllers/root.py | 4 +-
3 files changed, 114 insertions(+), 385 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index ce7e7fe..9eac578 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -1,264 +1,126 @@
# -*- coding: utf-8 -*-
+"""Sample controller module"""
-"""Controller API for `clusters' part.
+# turbogears imports
+from tg import expose, redirect, validate, flash, app_globals, validate, tmpl_context
- Functionality description:
+# third party imports
+#from pylons.i18n import ugettext as _
+#from repoze.what import predicates
- Let's have the main subcontroller (ClusterController) available through
- 'clusters' identifier of the root controller and subcontroller handling
- related commands (ClusterCmdController) through 'clusters_cmd' identifier.
+# project specific imports
+from luci.lib.base import BaseController
+#from luci.model import DBSession, metadata
- Luci application is accessible via http://example.com. Clusters
- in the system are ClusterOne, ClusterTwo and ClusterThree.
-
- Accessing following URLs has following consequences (some cases omitted):
-
- 1) <http://example.com/clusters> OR <http://example.com/clusters/>
- - displaying list of the clusters with some information about them.
-
- 2) <http://example.com/clusters/ClusterOne>
- OR <http://example.com/clusters/ClusterOne/>
- - redirection to nodes listing related to cluster called `ClusterOne'
- (<http://example.com/clusters/ClusterOne/nodes>) because there is no
- general page for certain cluster, only a few pages with further
- information about it (and the `nodes' is probably the most important).
-
- 3) <http://example.com/clusters/NonExistingCluster>
- OR <http://example.com/clusters/NonExistingCluster/>
- OR <http://example.com/clusters/NonExistingCluster/something_more>
- - redirection back to base `clusters' page and displaying information
- about the request of non-existing cluster.
-
- ---
-
- 4) <http://example.com/clusters_cmd/create>
- - display form for cluster creation.
-
- 5) <http://example.com/clusters_cmd/add>
- - display form for existing cluster addition.
-
-"""
-
-from tg import flash, request, redirect, expose, tmpl_context, app_globals, validate
-from pylons.i18n import ugettext as _, lazy_ugettext as l_
-
-from luci.lib.base import Subcontroller, SubcontrollerApplyMixin
-from luci.controllers.decorators import *
-from luci.lib.strings import TitleStrings
-from luci.lib.helpers import urlList2String
-
-from luci.widgets.create_cluster_form import create_cluster_form
-
-__all__ = ['ClusterController', 'ClusterCmdController']
-
-
-# Imports into module's namespace.
-scheme = app_globals.scheme
-cluster_scheme = app_globals.scheme.ClusterScheme
data = app_globals.data
-base2CmdCtrl = app_globals.scheme.base2CmdCtrl
-
-
-#
-# ITEMS LISTING.
-#
-class ClusterController(Subcontroller):
- """Subcontroller handling basic requests related with `clusters' part."""
-
- @forPageShowWithUrlCorrection('luci.templates.cluster_list')
- def default(self):
- """Handle simple cluster listing.
-
- E.g. <http://example.com/clusters> for situation described
- in the module's doc.
-
- """
- page = 'clusters'
- tmpl_context.title_list.append(TitleStrings.CLUSTERS)
-
- app_url = scheme.APP_PREFIX + u'/'
-
- return dict(base_url=app_url + scheme.CLUSTERS,
- cmd_url=app_url + base2CmdCtrl(scheme.CLUSTERS),
- apply_cmds=ClusterApplyCommands,page=page)
+class ClusterController(BaseController):
+ #Uncomment this line if your controller requires an authenticated user
+ #allow_only = authorize.not_anonymous()
+
+ @expose('luci.templates.cluster_list')
+ def index(self):
+ return dict(page='cluster',clusterpage='clusterpage')
@expose()
def lookup(self, name, *args):
- """Dynamic dispatching to subcontrollers according to cluster's name.
-
- E.g. <http://example.com/clusters/ClusterOne> for situation described
- in the module's doc.
-
- The request is dynamically delegated to _CertainClusterController
- object.
-
- Keyword arguments:
- name Name of the cluster to be taken as a context for
- nested subcontrollers (NodeController, etc.).
-
- """
if name in data.clusters.iterkeys():
- # Following 3 lines necessary because of strange(?) behavior of TG.
- if not tmpl_context.already_used.get('cluster'):
- tmpl_context.title_list.append(TitleStrings.CERTAIN_CLUSTER \
- % name)
- tmpl_context.cluster_name = name
- tmpl_context.cluster_data = data.clusters[name]
- tmpl_context.cluster_url = \
- urlList2String(scheme.APP_PREFIX, scheme.CLUSTERS, name)
- tmpl_context.already_used['cluster'] = True
- dynamic_ctrl = _CertainClusterController()
- return dynamic_ctrl, args
- else:
- msg = l_('Bad cluster name: %s') % name
- status = 'error'
-
- flash(msg, status=status)
- redirect(urlList2String(scheme.APP_PREFIX, scheme.CLUSTERS))
-
-
-(a)mountSubControllers(cluster_scheme.mounts())
-class _CertainClusterController(Subcontroller):
- """Subcontroller preparing subcontrollers for certain cluster."""
-
- @forImmediateRedirect(allowed_methods='GET', use_referrer=False)
- def default(self, *args, **kwargs):
- """Handle request for displaying details of certain cluster.
-
- E.g. <http://example.com/clusters/ClusterOne> for situation described
- in the module's doc.
-
- Redirect to `nodes' part in the context the cluster.
+ icc = IndividualClusterController(name,data)
+ return icc, args
+ cc = ClusterController
+ status = 'error'
+ msg = "Bad cluster name"
+ flash (msg, status=status)
+ redirect('/cluster')
+ return (cc,args)
+
+
+class IndividualClusterController(BaseController):
+ def __init__(self,name,data,nodename=None):
+ self.name = name
+ self.data = data
+ self.nodename = nodename
+
+ @expose("luci.templates.node")
+ def default(self):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ return dict(page='nodes',name=self.nodename, base_url = '/nodes')
+
+ @expose("luci.templates.node")
+ def nodes(self):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ return dict(page='nodes',name=self.nodename, base_url = '/nodes')
+
+ @expose("luci.templates.service")
+ def services(self,*args):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ if (len(args) == 1):
+ servicename = args[0]
+ else:
+ servicename = None
+ return dict(page='nodes',name=servicename, base_url = '/cluster/' + self.name + '/services')
- """
- return dict(redir_target= urlList2String(tmpl_context.cluster_url,
- cluster_scheme.NODES))
-
- # 'lookup' method not necessary, 'default' method above is enough even for
- # such cases.
-
-
-#
-# COMMANDS HANDLING.
-#
-
-class ClusterApplyCommands:
- """Encapsulation of available commands to apply over selected cluster(s)."""
-
- DELETE = 'cmd_delete'
-
-
- def _delete(which):
- clusters = app_globals.data.clusters
- msg = l_('Deleting selected cluster(s)... %s') \
- % (', '.join(which))
- status = 'info'
- for cluster in which:
- if clusters.has_key(cluster):
- del clusters[cluster]
- else:
- # If Luci's data are consistent, this should never happen.
- msg = l_('Internal error.'),
- status = 'error'
- break
- return msg, status, False
-
-
- # Mapping.
- cmds = {DELETE: _delete}
-
- # Set methods as static (but only after they are referenced
- # in 'cmds' dict).
- _delete = staticmethod(_delete)
-
-
-class ClusterCmdController(Subcontroller, SubcontrollerApplyMixin):
- """Subcontroller handling commands related with `clusters' part."""
-
- _apply_cmds = ClusterApplyCommands
-
- @forPageShowWithUrlCorrection('luci.templates.create')
- def create(self, name=""):
- """Display form for cluster creation."""
- return dict(cmd_url= \
- scheme.APP_PREFIX + u'/' + base2CmdCtrl(scheme.CLUSTERS))
-
+ @expose("luci.templates.failover")
+ def failovers(self,*args):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ if (len(args) == 1):
+ failovername = args[0]
+ else:
+ failovername = None
+ return dict(page='nodes',name=failovername, base_url = '/cluster/' + self.name + '/failovers')
+
+ @expose("luci.templates.fence")
+ def fences(self,*args):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ if (len(args) == 1):
+ fencename = args[0]
+ else:
+ fencename = None
+ return dict(page='nodes',name=fencename, base_url = '/cluster/' + self.name + '/fences')
+
+ @expose("luci.templates.configure")
+ def configure(self,*args):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ return dict(page='nodes',name='configure', base_url = '/cluster/' + self.name + '/configure')
- @forImmediateRedirect(allowed_methods = 'GET')
- def add(self):
- """Handle addition of a new cluster."""
-
- flash('It should be a dialog to add new cluster here instead,'
- 'but not implemented yet...', status='info')
- # following code is only my experiment, how to continue:
- #tmpl_context.form = create_fdom_add_form
- #return dict()
-
-
- @forImmediateRedirect(allowed_methods='POST')
- def cluster_create(self, **kw):
- """Handle the process of cluster creation."""
-
- from sys import stderr
- from luci.lib.ricci_helpers import send_batch_to_hosts
- from luci.lib.ricci_communicator import RicciCommunicator, RicciError
- import luci.lib.ricci_queries as rq
-
- redir_target = urlList2String(scheme.APP_PREFIX,
- base2CmdCtrl(scheme.CLUSTERS),
- 'create')
-
- errors = []
- cluster_name = kw.get('clustername')
- enable_storage = kw.get('enable_storage')
- reboot_nodes = kw.get('reboot_nodes')
- download_pkgs = kw.get('download_pkgs')
-
- nodes = [
- [ kw.get('__SYSTEM0_addr'), kw.get('__SYSTEM0_passwd') ],
- [ kw.get('__SYSTEM1_addr'), kw.get('__SYSTEM1_passwd') ],
- [ kw.get('__SYSTEM2_addr'), kw.get('__SYSTEM2_passwd') ]
- ]
- node_list = [ i[0] for i in nodes ]
- stderr.write('nodes: %s\n' % str(node_list))
-
- if not cluster_name:
- flash(_('No cluster name was given'))
- return dict(redir_target=redir_target)
-
- if len(cluster_name) > 15:
- flash(_('Cluster names must be less than 16 characters long'))
- return dict(redir_target=redir_target)
-
- for node in nodes:
- try:
- rc = RicciCommunicator(node[0], enforce_trust=False)
- except RicciError, errmsg:
- errors.append(str(errmsg))
- else:
- rc.trust()
- rc.auth(node[1])
- if not rc.authed():
- errors.append('Authentication to node %s failed' % node[0])
- break
- else:
- rc = RicciCommunicator(node[0])
-
- cur_cluster_name = rc.cluster_info()[0]
- if cur_cluster_name:
- errors.append('%s is already a member of a cluster %s' \
- % (node[0], cur_cluster_name))
- break
-
- if len(errors) > 0:
- flash('The following errors occurred: %s' % str(errors))
- return dict(redir_target=redir_target)
-
- ret = send_batch_to_hosts(node_list, 10, rq.create_cluster,
- 'rhel5', cluster_name, cluster_name,
- node_list, True, True, enable_storage, False,
- download_pkgs, None, reboot_nodes)
+ @expose()
+ def lookup(self, nodename, *args):
+ clustername = self.name
+ tmpl_context.cluster_data=data.clusters[clustername]
+ tmpl_context.cluster_name = clustername
+ tmpl_context.cluster_url = "/cluster/" + clustername
+ inc = IndividualNodeController(clustername,self.data,nodename)
+ return inc, args
+
+class IndividualNodeController(BaseController):
+ def __init__(self,name,data,nodename):
+ self.name = name
+ self.data = data
+ self.nodename = nodename
+
+ @expose("luci.templates.node")
+ def default(self):
+ tmpl_context.cluster_data=data.clusters[self.name]
+ tmpl_context.cluster_name = self.name
+ tmpl_context.cluster_url = "/cluster/" + self.name
+ return dict(page='nodes',name=self.nodename, base_url = '/nodes')
- base_url_str = urlList2String(scheme.APP_PREFIX, self.base_name)
- return dict(use_referrer=False, redir_target=base_url_str)
+ @expose()
+ def lookup(self, nodename, *args):
+ clustername = self.name
+ tmpl_context.cluster_data=data.clusters[clustername]
+ tmpl_context.cluster_name = clustername
+ icc = IndividualClusterController(clustername,self.data,nodename)
+ return icc, args
diff --git a/luci/controllers/root.py b/luci/controllers/root.py
index d7dcbc1..b4afec3 100644
--- a/luci/controllers/root.py
+++ b/luci/controllers/root.py
@@ -12,7 +12,7 @@ from luci.lib.base import BaseController
from luci.controllers.error import ErrorController
from luci.controllers.secure import SecureController
-from luci.controllers.cluster2 import Cluster2Controller
+from luci.controllers.cluster import ClusterController
from luci.model import DBSession, metadata
from luci import model
@@ -59,7 +59,7 @@ class RootController(BaseController):
secc = SecureController()
admin = Catwalk(model, DBSession)
error = ErrorController()
- cluster = Cluster2Controller()
+ cluster = ClusterController()
# METHODS OF THE ROOT CONTROLLER
14 years, 5 months