* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2006-10-09 17:12 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2006-10-09 17:12 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2006-10-09 17:12:29
Modified files:
luci/cluster : form-chooser form-macros
luci/site/luci/Extensions: cluster_adapters.py
luci/storage : index_html
Log message:
more page title labels and miscellaneous other small fixes
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.78&r2=1.79
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.85&r2=1.86
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/index_html.diff?cvsroot=cluster&r1=1.6&r2=1.7
--- conga/luci/cluster/form-chooser 2006/10/09 16:16:11 1.9
+++ conga/luci/cluster/form-chooser 2006/10/09 17:12:26 1.10
@@ -14,10 +14,7 @@
<span tal:omit-tag="" tal:condition="python: not ptype">
<div metal:use-macro="here/form-macros/macros/entry-form"/>
</span>
- <span tal:omit-tag="" tal:condition="python: ptype == '0'">
- <div metal:use-macro="here/form-macros/macros/entry-form"/>
- </span>
- <span tal:omit-tag="" tal:condition="python: ptype == '3'">
+ <span tal:omit-tag="" tal:condition="python: ptype == '0' or ptype == '1' or ptype == '2' or ptype == '3'">
<div metal:use-macro="here/form-macros/macros/clusters-form"/>
</span>
<span tal:omit-tag="" tal:condition="python: ptype == '4'">
--- conga/luci/cluster/form-macros 2006/10/09 16:16:11 1.78
+++ conga/luci/cluster/form-macros 2006/10/09 17:12:28 1.79
@@ -25,6 +25,9 @@
</div>
<div metal:define-macro="clusters-form">
+ <script type="text/javascript">
+ set_page_title('Luci ??? cluster ??? cluster list');
+ </script>
<div id="cluster_list">
<div class="cluster" tal:repeat="clu clusystems">
<tal:block tal:define="global ragent python: here.getRicciAgent(clu)" />
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2006/10/06 20:45:26 1.85
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2006/10/09 17:12:28 1.86
@@ -1,5 +1,6 @@
import socket
from ModelBuilder import ModelBuilder
+from xml.dom import minidom
from ZPublisher import HTTPRequest
import AccessControl
from conga_constants import *
@@ -287,7 +288,21 @@
return (True, {'errors': errors, 'messages': messages})
def validateServiceEdit(self, request):
- return (True, {})
+ try:
+ form_xml = request['form_xml']
+ if not form_xml:
+ raise KeyError('form_xml must not be blank')
+ except KeyError, e:
+ return (False, {errors: ['No resource data was supplied for this service.']})
+
+ try:
+ doc = minidom.parseString(form_xml)
+ if not doc.firstChild:
+ raise
+ except:
+ return (False, {'errors': ['The resource data submitted for this service is not properly formed.']})
+
+ return (True, {'messages': ['OK']})
def validateServiceAdd(self, request):
return (True, {})
@@ -588,7 +603,7 @@
try:
pagetype = request[PAGETYPE]
except KeyError, e:
- pagetype = "0"
+ pagetype = '3'
cldata = {}
@@ -667,7 +682,7 @@
try:
pagetype = request[PAGETYPE]
except KeyError, e:
- pagetype = "0"
+ pagetype = '3'
try:
url = request['URL']
--- conga/luci/storage/index_html 2006/08/03 18:56:09 1.6
+++ conga/luci/storage/index_html 2006/10/09 17:12:28 1.7
@@ -49,6 +49,7 @@
<!-- async helper functions -->
+<script type="text/javascript" src="/luci/conga.js"></script>
<script language="javascript" type="text/javascript">
var xmlHttp_object = false;
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2006-11-10 19:44 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2006-11-10 19:44 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2006-11-10 19:44:57
Modified files:
luci/cluster : form-chooser form-macros portlet_cluconfig
resource-form-macros resource_form_handlers.js
luci/site/luci/Extensions: cluster_adapters.py
Log message:
- fix the redirection upon completion of async ricci tasks
- fix a bug that caused adding nfs mount resources to fail
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.102&r2=1.103
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/portlet_cluconfig.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource-form-macros.diff?cvsroot=cluster&r1=1.23&r2=1.24
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource_form_handlers.js.diff?cvsroot=cluster&r1=1.21&r2=1.22
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.160&r2=1.161
--- conga/luci/cluster/form-chooser 2006/10/16 20:25:33 1.12
+++ conga/luci/cluster/form-chooser 2006/11/10 19:44:57 1.13
@@ -12,7 +12,7 @@
<span tal:condition="not: busywaiting">
<span tal:omit-tag="" tal:define="global ptype request/pagetype |nothing"/>
<span tal:omit-tag="" tal:condition="python: not ptype">
- <div metal:use-macro="here/form-macros/macros/entry-form"/>
+ <div metal:use-macro="here/form-macros/macros/clusters-form"/>
</span>
<span tal:omit-tag="" tal:condition="python: ptype == '0' or ptype == '1' or ptype == '2' or ptype == '3'">
<div metal:use-macro="here/form-macros/macros/clusters-form"/>
--- conga/luci/cluster/form-macros 2006/11/09 20:32:02 1.102
+++ conga/luci/cluster/form-macros 2006/11/10 19:44:57 1.103
@@ -7,7 +7,6 @@
<body>
<div metal:define-macro="entry-form">
- <h2>Entry Form</h2>
</div>
<div metal:define-macro="busywaitpage">
--- conga/luci/cluster/portlet_cluconfig 2006/09/27 22:24:11 1.2
+++ conga/luci/cluster/portlet_cluconfig 2006/11/10 19:44:57 1.3
@@ -10,7 +10,7 @@
<dl class="portlet" id="portlet-cluconfig-tree">
<dt class="portletHeader">
- <a href="#">
+ <a href="/luci/cluster/index_html?pagetype=3">
Clusters
</a>
</dt>
@@ -36,7 +36,8 @@
<dl class="portlet" id="portlet-cluconfig-tree">
<dt class="portletHeader">
- <a href="#" tal:attributes="href python:here.getClusterURL(request,modelb)">
+ <a href="/luci/cluster/index_html?pagetype=3"
+ tal:attributes="href python:here.getClusterURL(request,modelb)">
<div tal:omit-tag="" tal:content="python: here.getClusterAlias(modelb)" />
</a>
</dt>
--- conga/luci/cluster/resource-form-macros 2006/11/07 21:33:52 1.23
+++ conga/luci/cluster/resource-form-macros 2006/11/10 19:44:57 1.24
@@ -684,14 +684,12 @@
<input type="radio" name="nfstype" value="nfs"
tal:attributes="
disabled python: editDisabled;
- content string: NFS (version 3);
- checked python: nfstype == 'nfs' and 'checked'" />
+ checked python: nfstype != 'nfs4' and 'checked'" />NFS3
<br/>
<input type="radio" name="nfstype" value="nfs4"
tal:attributes="
disabled python: editDisabled;
- content string: NFS4;
- checked python: nfstype == 'nfs4' and 'checked'" />
+ checked python: nfstype == 'nfs4' and 'checked'" />NFS4
</td>
</tr>
--- conga/luci/cluster/resource_form_handlers.js 2006/10/30 21:21:16 1.21
+++ conga/luci/cluster/resource_form_handlers.js 2006/11/10 19:44:57 1.22
@@ -101,7 +101,7 @@
function validate_nfs_mount(form) {
var errors = new Array();
- if (!form.mountpoint || str_is_blank(form.mounpoint.value)) {
+ if (!form.mountpoint || str_is_blank(form.mountpoint.value)) {
errors.push('No mount point was given.');
set_form_err(form.mountpoint);
} else
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2006/11/10 18:18:09 1.160
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2006/11/10 19:44:57 1.161
@@ -901,13 +901,13 @@
cname = None
try:
cname = request[CLUNAME]
- except KeyError, e:
+ except:
cname = ""
try:
url = request['URL']
- except KeyError, e:
- url = "."
+ except:
+ url = "/luci/cluster/index_html"
try:
pagetype = request[PAGETYPE]
@@ -998,13 +998,13 @@
#There should be a positive page type
try:
pagetype = request[PAGETYPE]
- except KeyError, e:
+ except:
pagetype = '3'
try:
url = request['URL']
except KeyError, e:
- url = "."
+ url = "/luci/cluster/index_html"
#The only way this method can run is if there exists
#a clustername query var
@@ -1444,7 +1444,7 @@
else:
selectedtab = "homebase"
except KeyError, e:
- pass
+ selectedtab = None
htab = { 'Title':"homebase",
'Description':"Home base for this luci server",
@@ -1457,7 +1457,7 @@
ctab = { 'Title':"cluster",
'Description':"Cluster configuration page",
- 'Taburl':"/luci/cluster?pagetype=3"}
+ 'Taburl':"/luci/cluster/index_html?pagetype=3"}
if selectedtab == "cluster":
ctab['isSelected'] = True
else:
@@ -1633,18 +1633,18 @@
baseurl = req['URL']
if not baseurl:
raise KeyError, 'is blank'
- except KeyError, e:
- baseurl = '.'
+ except:
+ baseurl = '/luci/cluster/index_html'
try:
cluname = req['clustername']
if not cluname:
raise KeyError, 'is blank'
- except KeyError, e:
+ except:
try:
cluname = req.form['clusterName']
if not cluname:
- raise
+ raise KeyError, 'is blank'
except:
cluname = '[error retrieving cluster name]'
@@ -1678,8 +1678,8 @@
baseurl = req['URL']
if not baseurl:
raise KeyError, 'is blank'
- except KeyError, e:
- baseurl = '.'
+ except:
+ baseurl = '/luci/cluster/index_html'
try:
cluname = req['clustername']
@@ -1835,7 +1835,7 @@
luci_log.debug_verbose('startService4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
response = req.RESPONSE
- response.redirect(req['HTTP_REFERER'] + "&busyfirst=true")
+ response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
def serviceRestart(self, rc, req):
svcname = None
@@ -1875,7 +1875,7 @@
luci_log.debug_verbose('serviceRestart3: error setting flags for service %s for cluster %s' % (svcname, cluname))
response = req.RESPONSE
- response.redirect(req['HTTP_REFERER'] + "&busyfirst=true")
+ response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
def serviceStop(self, rc, req):
svcname = None
@@ -1915,7 +1915,7 @@
luci_log.debug_verbose('serviceStop3: error setting flags for service %s for cluster %s' % (svcname, cluname))
response = req.RESPONSE
- response.redirect(req['HTTP_REFERER'] + "&busyfirst=true")
+ response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
def getFdomsInfo(self, modelb, request, clustatus):
slist = list()
@@ -2031,7 +2031,7 @@
response = request.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], CLUSTER, model.getClusterName()))
+ % (request['URL'], NODES, model.getClusterName()))
def getClusterInfo(self, model, req):
try:
@@ -2638,39 +2638,35 @@
luci_log.debug_verbose('NTP: nodeLeave failed')
return None
- #Is this correct? Should we re-direct to the cluster page?
response = request.RESPONSE
- response.redirect(request['URL'] + "?pagetype=" + CLUSTER_CONFIG + "&clustername=" + clustername)
+ response.redirect(request['URL'] + "?pagetype=" + NODE_LIST + "&clustername=" + clustername + '&busyfirst=true')
elif task == NODE_JOIN_CLUSTER:
if nodeJoin(self, rc, clustername, nodename_resolved) is None:
luci_log.debug_verbose('NTP: nodeJoin failed')
return None
- #Once again, is this correct? Should we re-direct to the cluster page?
response = request.RESPONSE
- response.redirect(request['URL'] + "?pagetype=" + CLUSTER_CONFIG + "&clustername=" + clustername)
+ response.redirect(request['URL'] + "?pagetype=" + NODE_LIST + "&clustername=" + clustername + '&busyfirst=true')
elif task == NODE_REBOOT:
if forceNodeReboot(self, rc, clustername, nodename_resolved) is None:
luci_log.debug_verbose('NTP: nodeReboot failed')
return None
- #Once again, is this correct? Should we re-direct to the cluster page?
response = request.RESPONSE
- response.redirect(request['URL'] + "?pagetype=" + CLUSTER_CONFIG + "&clustername=" + clustername)
+ response.redirect(request['URL'] + "?pagetype=" + NODE_LIST + "&clustername=" + clustername + '&busyfirst=true')
elif task == NODE_FENCE:
if forceNodeFence(self, clustername, nodename, nodename_resolved) is None:
luci_log.debug_verbose('NTP: nodeFencefailed')
return None
- #Once again, is this correct? Should we re-direct to the cluster page?
response = request.RESPONSE
- response.redirect(request['URL'] + "?pagetype=" + CLUSTER_CONFIG + "&clustername=" + clustername)
+ response.redirect(request['URL'] + "?pagetype=" + NODE_LIST + "&clustername=" + clustername + '&busyfirst=true')
elif task == NODE_DELETE:
if nodeDelete(self, rc, model, clustername, nodename, nodename_resolved) is None:
luci_log.debug_verbose('NTP: nodeDelete failed')
return None
response = request.RESPONSE
- response.redirect(request['HTTP_REFERER'] + "&busyfirst=true")
+ response.redirect(request['URL'] + "?pagetype=" + NODE_LIST + "&clustername=" + clustername + '&busyfirst=true')
def getNodeInfo(self, model, status, request):
infohash = {}
@@ -3360,7 +3356,7 @@
luci_log.debug('ICB5: An error occurred while looking for cluster %s flags at path %s' % (cluname, path))
return map
- luci_log.debug_verbose('ICB6: isClusterBusy: %s is busy: %d flags' \
+ luci_log.debug_verbose('ICB6: %s is busy: %d flags' \
% (cluname, len(items)))
map['busy'] = "true"
#Ok, here is what is going on...if there is an item,
@@ -3541,7 +3537,7 @@
try:
clusterfolder.manage_delObjects(item[0])
except Exception, e:
- luci_log.info('Unable to delete %s: %s' % (item[0], str(e)))
+ luci_log.info('ICB16: Unable to delete %s: %s' % (item[0], str(e)))
else:
node_report = {}
map['busy'] = "true"
@@ -3563,7 +3559,12 @@
map['refreshurl'] = "5; url=" + wholeurl
req['specialpagetype'] = "1"
else:
- map['refreshurl'] = '5; url=\".\"'
+ try:
+ query = req['QUERY_STRING'].replace('&busyfirst=true', '')
+ map['refreshurl'] = '5; url=' + req['ACTUAL_URL'] + '?' + query
+ except:
+ map['refreshurl'] = '5; url=/luci/cluster?pagetype=3'
+ luci_log.debug_verbose('ICB17: refreshurl is \"%s\"' % map['refreshurl'])
return map
def getClusterOS(self, rc):
@@ -3739,7 +3740,7 @@
luci_log.debug_verbose('delResource7: failed to set flags: %s' % str(e))
response = request.RESPONSE
- response.redirect(request['HTTP_REFERER'] + "&busyfirst=true")
+ response.redirect(request['URL'] + "?pagetype=" + RESOURCES + "&clustername=" + clustername + '&busyfirst=true')
def addIp(request, form=None):
if form is None:
@@ -4452,7 +4453,7 @@
luci_log.debug_verbose('addResource7: failed to set flags: %s' % str(e))
response = request.RESPONSE
- response.redirect(request['HTTP_REFERER'] + "&busyfirst=true")
+ response.redirect(request['URL'] + "?pagetype=" + RESOURCES + "&clustername=" + clustername + '&busyfirst=true')
def getResourceForEdit(modelb, name):
resPtr = modelb.getResourcesPtr()
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2006-12-06 18:38 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2006-12-06 18:38 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2006-12-06 18:38:55
Modified files:
luci/cluster : form-chooser form-macros
luci/site/luci/Extensions: cluster_adapters.py
conga_constants.py
Log message:
The service delete option was doing nothing. Make it work, but only when the service is not running.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.13&r2=1.14
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.121&r2=1.122
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.172&r2=1.173
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&r1=1.27&r2=1.28
--- conga/luci/cluster/form-chooser 2006/11/10 19:44:57 1.13
+++ conga/luci/cluster/form-chooser 2006/12/06 18:38:53 1.14
@@ -80,6 +80,9 @@
<span tal:omit-tag="" tal:condition="python: ptype == '25'">
<div metal:use-macro="here/form-macros/macros/serviceprocess-form"/>
</span>
+ <tal:block tal:condition="python: ptype == '56'">
+ <div metal:use-macro="here/form-macros/macros/servicedelete-form" />
+ </tal:block>
<span tal:omit-tag="" tal:condition="python: ptype == '26'">
<div metal:use-macro="here/form-macros/macros/servicestart"/>
</span>
--- conga/luci/cluster/form-macros 2006/12/05 23:32:34 1.121
+++ conga/luci/cluster/form-macros 2006/12/06 18:38:54 1.122
@@ -2775,9 +2775,31 @@
<form method="post" onSubmit="return dropdown(this.gourl)">
<select name="gourl">
<option value="">Choose a Task...</option>
- <option value="" tal:attributes="value svc/cfgurl">Configure</option>
+ <option
+ tal:attributes="value svc/cfgurl | nothing"
+ tal:content="string:Configure this service" />
+
<option value="">----------</option>
- <option value="">Delete</option>
+
+ <option
+ tal:condition="running"
+ tal:attributes="value svc/retstarturl| nothing"
+ tal:content="string:Restart this service" />
+
+ <option
+ tal:condition="running"
+ tal:attributes="value svc/disableurl | nothing"
+ tal:content="string:Stop this service" />
+
+ <option
+ tal:condition="not: running"
+ tal:attributes="value svc/enableurl | nothing"
+ tal:content="string:Start this service" />
+
+ <option
+ tal:condition="not: running"
+ tal:attributes="value svc/delurl | nothing"
+ tal:content="string:Delete this service" />
</select>
<input type="submit" value="Go"/>
</form>
@@ -3047,14 +3069,15 @@
<option value="" tal:attributes="value innermap/disableurl">Disable this service</option>
<option value="">----------</option>
<option tal:repeat="starturl innermap/links" value="" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
- <option value="">----------</option>
- <option value="">Delete this service</option>
</tal:block>
<tal:block tal:condition="not: running">
<option value="">----------</option>
<option value="" tal:attributes="value innermap/enableurl">Enable this service</option>
<option value="">----------</option>
+ <option
+ tal:attributes="value innermap/delurl | nothing"
+ tal:content="string:Delete this service" />
</tal:block>
</select>
<input type="submit" value="Go"/>
@@ -3152,6 +3175,11 @@
<h2>Service Process Form</h2>
</div>
+<div metal:define-macro="servicedelete-form">
+ <h2>Service Delete Form</h2>
+ <tal:block tal:define="dummy python: here.delService(request)" />
+</div>
+
<div metal:define-macro="resources-form">
<h2>Resources Form</h2>
</div>
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2006/12/05 23:32:35 1.172
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2006/12/06 18:38:54 1.173
@@ -404,7 +404,6 @@
form_xml = request['form_xml']
if not form_xml:
raise KeyError, 'form_xml must not be blank'
- luci_log.debug_verbose('VSAXML DUMP: %s' % form_xml)
except Exception, e:
luci_log.debug_verbose('vSA0: no form_xml: %s' % str(e))
return (False, {'errors': ['No resource data was supplied for this service.']})
@@ -1920,6 +1919,7 @@
itemmap['nodename'] = item['nodename']
itemmap['autostart'] = item['autostart']
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE
+ itemmap['delurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE_DELETE
svc = modelb.retrieveServiceByName(item['name'])
dom = svc.getAttribute("domain")
@@ -1980,6 +1980,8 @@
innermap['current'] = "This service is currently running on %s" % nodename
innermap['disableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_STOP
innermap['restarturl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_RESTART
+ innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+
nodes = modelb.getNodes()
for node in nodes:
starturl = {}
@@ -2026,16 +2028,18 @@
if parent is not None:
rc_map['parent'] = parent
rc_map['name'] = child.getName()
+
+ #Note: Final version needs all resource attrs
if child.isRefObject() == True:
rc_map['ref_object'] = True
rc_map['type'] = child.getObj().getResourceType()
+ rc_map['attrs'] = child.getObj().getAttributes()
else:
rc_map['type'] = child.getResourceType()
+ rc_map['attrs'] = child.getAttributes()
rc_map['indent_ctr'] = indent_ctr
- #Note: Final version needs all resource attrs
- rc_map['attrs'] = child.getAttributes()
rc_map['uuid'] = make_uuid('resource')
rc_map['parent_uuid'] = parent_uuid
@@ -3985,6 +3989,82 @@
except:
continue
+def delService(self, request):
+ errstr = 'An error occurred while attempting to set the new cluster.conf'
+
+ try:
+ modelb = request.SESSION.get('model')
+ except Exception, e:
+ luci_log.debug_verbose('delService0: no model: %s' % str(e))
+ return (False, {'errors': [ errstr ] })
+
+ name = None
+ try:
+ name = request['servicename']
+ except:
+ try:
+ name = request.form['servicename']
+ except:
+ pass
+
+ if name is None:
+ luci_log.debug_verbose('delService1: no service name')
+ return (False, {'errors': [ '%s: no service name was provided.' % errstr ]})
+
+ clustername = None
+ try:
+ clustername = request['clustername']
+ except:
+ try:
+ clustername = request.form['clustername']
+ except:
+ pass
+
+ if clustername is None:
+ luci_log.debug_verbose('delService2: no cluster name for %s' % name)
+ return (False, {'errors': [ '%s: no cluster name was provided.' % errstr ]})
+
+ rc = getRicciAgent(self, clustername)
+ if not rc:
+ luci_log.debug_verbose('delService3: unable to get ricci agent for cluster %s' % clustername)
+ return (False, {'errors': [ '%s: unable to find a Ricci agent for this cluster.' % errstr ]})
+
+ try:
+ ragent = rc.hostname()
+ if not ragent:
+ raise Exception, 'unable to determine the hostname of the ricci agent'
+ except Exception, e:
+ luci_log.debug_verbose('delService4: %s: %s' % (errstr, str(e)))
+ return (False, {'errors': [ '%s: unable to find a Ricci agent for this cluster.' % errstr ]})
+
+ try:
+ modelb.deleteService(name)
+ except Exception, e:
+ luci_log.debug_verbose('delService5: Unable to find a service named %s for cluster %s' % (name, clustername))
+ return (False, {'errors': [ '%s: error removing service %s.' % (errstr, name) ]})
+
+ try:
+ conf = modelb.exportModelAsString()
+ if not conf:
+ raise Exception, 'model string is blank'
+ except Exception, e:
+ luci_log.debug_verbose('delService6: exportModelAsString failed: %s' \
+ % str(e))
+ return (False, {'errors': [ '%s: error removing service %s.' % (errstr, name) ]})
+
+ batch_number, result = setClusterConf(rc, str(conf))
+ if batch_number is None or result is None:
+ luci_log.debug_verbose('delService7: missing batch and/or result')
+ return (False, {'errors': [ '%s: error removing service %s.' % (errstr, name) ]})
+
+ try:
+ set_node_flag(self, clustername, ragent, str(batch_number), SERVICE_DELETE, "Removing service \'%s\'" % name)
+ except Exception, e:
+ luci_log.debug_verbose('delService8: failed to set flags: %s' % str(e))
+
+ response = request.RESPONSE
+ response.redirect(request['URL'] + "?pagetype=" + SERVICES + "&clustername=" + clustername + '&busyfirst=true')
+
def delResource(self, rc, request):
errstr = 'An error occurred while attempting to set the new cluster.conf'
@@ -4068,9 +4148,6 @@
if form is None:
form = request.form
- if form is not None:
- luci_log.debug_verbose('addIp DUMP: %s' % str(form.items()))
-
if not form:
luci_log.debug_verbose('addIp error: form is missing')
return None
--- conga/luci/site/luci/Extensions/conga_constants.py 2006/11/27 20:06:53 1.27
+++ conga/luci/site/luci/Extensions/conga_constants.py 2006/12/06 18:38:55 1.28
@@ -43,6 +43,7 @@
FENCEDEV_CONFIG="53"
FENCEDEV="54"
CLUSTER_DAEMON="55"
+SERVICE_DELETE = '56'
#Cluster tasks
CLUSTER_STOP = '1000'
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2006-12-07 17:54 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2006-12-07 17:54 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Branch: RHEL5
Changes by: rmccabe at sourceware.org 2006-12-07 17:54:31
Modified files:
luci/cluster : form-chooser form-macros index_html
resource-form-macros resource_form_handlers.js
luci/homebase : luci_homebase.css
luci/site/luci/Extensions: ClusterNode.py FenceDevice.py
LuciSyslog.py cluster_adapters.py
conga_constants.py ricci_bridge.py
Log message:
Related: bz217387, bz218040, bz212021
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.12.2.1&r2=1.12.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.90.2.6&r2=1.90.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/index_html.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.20.2.4&r2=1.20.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource-form-macros.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.21.2.2&r2=1.21.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource_form_handlers.js.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.20.2.2&r2=1.20.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/luci_homebase.css.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.28.2.1&r2=1.28.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ClusterNode.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/FenceDevice.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciSyslog.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2.2.3&r2=1.2.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.120.2.12&r2=1.120.2.13
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.19.2.2&r2=1.19.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.30.2.10&r2=1.30.2.11
--- conga/luci/cluster/form-chooser 2006/11/16 19:34:52 1.12.2.1
+++ conga/luci/cluster/form-chooser 2006/12/07 17:54:31 1.12.2.2
@@ -80,6 +80,9 @@
<span tal:omit-tag="" tal:condition="python: ptype == '25'">
<div metal:use-macro="here/form-macros/macros/serviceprocess-form"/>
</span>
+ <tal:block tal:condition="python: ptype == '56'">
+ <div metal:use-macro="here/form-macros/macros/servicedelete-form" />
+ </tal:block>
<span tal:omit-tag="" tal:condition="python: ptype == '26'">
<div metal:use-macro="here/form-macros/macros/servicestart"/>
</span>
--- conga/luci/cluster/form-macros 2006/11/30 22:31:59 1.90.2.6
+++ conga/luci/cluster/form-macros 2006/12/07 17:54:31 1.90.2.7
@@ -77,7 +77,7 @@
<tal:block tal:condition="python: ricci_agent">
<tal:block tal:define="
- global stat python: here.getClusterStatus(ricci_agent);
+ global stat python: here.getClusterStatus(request, ricci_agent);
global cstatus python: here.getClustersInfo(stat, request);
global cluster_status python: 'cluster ' + (('running' in cstatus and cstatus['running'] == 'true') and 'running' or 'stopped');"
/>
@@ -122,14 +122,22 @@
</td>
</tr>
+ <tr class="cluster">
+ <td tal:condition="exists: cstatus/error" class="cluster">
+ <span class="errmsgs">
+ An error occurred while attempting to get status information for this cluster. The information shown may be out of date.
+ </span>
+ </td>
+ </tr>
+
<tr class="cluster info_middle">
<td colspan="2" class="cluster cluster_quorum">
<ul class="cluster_quorum"
tal:condition="exists: cstatus/status">
- <li><strong class="cluster">Status</strong>: <span tal:replace="cstatus/status"/></li>
- <li><strong class="cluster">Total Cluster Votes</strong>: <span tal:replace="cstatus/votes"/></li>
- <li><strong class="cluster">Minimum Required Quorum</strong>: <span tal:replace="cstatus/minquorum"/></li>
+ <li><strong class="cluster">Status</strong>: <span tal:replace="cstatus/status | string:[unknown]"/></li>
+ <li><strong class="cluster">Total Cluster Votes</strong>: <span tal:replace="cstatus/votes | string:[unknown]"/></li>
+ <li><strong class="cluster">Minimum Required Quorum</strong>: <span tal:replace="cstatus/minquorum | string:[unknown]"/></li>
</ul>
</td>
</tr>
@@ -1141,7 +1149,7 @@
<div id="fence_apc" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>APC Power Switch</td>
</tr>
@@ -1174,6 +1182,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-apc" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_apc" />
</div>
</div>
@@ -1183,7 +1205,7 @@
<div id="fence_mcdata" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>McData SAN Switch</td>
</tr>
@@ -1216,6 +1238,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-mcdata" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_mcdata" />
</div>
</div>
@@ -1225,7 +1261,7 @@
<div id="fence_wti" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>WTI Power Switch</td>
</tr>
@@ -1251,6 +1287,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-wti" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_wti" />
</div>
</div>
@@ -1260,7 +1310,7 @@
<div id="fence_ilo" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>HP iLO</td>
</tr>
@@ -1293,6 +1343,11 @@
</td>
</tr>
</table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
<input type="hidden" name="fence_type" value="fence_ilo" />
</div>
</div>
@@ -1302,7 +1357,7 @@
<div id="fence_drac" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Dell Drac</td>
</tr>
@@ -1334,6 +1389,11 @@
tal:attributes="value cur_fencedev/passwd | nothing" />
</td>
</table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
<input type="hidden" name="fence_type" value="fence_drac" />
</div>
</div>
@@ -1343,7 +1403,7 @@
<div id="fence_rsa" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>IBM RSA II</td>
</tr>
@@ -1376,6 +1436,11 @@
</td>
</tr>
</table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
<input type="hidden" name="fence_type" value="fence_rsa" />
</div>
</div>
@@ -1385,7 +1450,7 @@
<div id="fence_brocade" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Brocade Fabric Switch</td>
</tr>
@@ -1418,6 +1483,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-brocade" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_brocade" />
</div>
</div>
@@ -1427,7 +1506,7 @@
<div id="fence_sanbox2" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>QLogic SANbox2</td>
</tr>
@@ -1457,6 +1536,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-sanbox2" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_sanbox2" />
</div>
</div>
@@ -1466,7 +1559,7 @@
<div id="fence_vixel" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Vixel SAN Switch</td>
</tr>
@@ -1492,6 +1585,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-brocade" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_vixel" />
</div>
</div>
@@ -1501,7 +1608,7 @@
<div id="fence_gnbd" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>GNBD</td>
</tr>
@@ -1520,6 +1627,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-gnbd" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_gnbd" />
</div>
</div>
@@ -1529,7 +1650,7 @@
<div id="fence_egenera" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Egenera SAN Controller</td>
</tr>
@@ -1555,6 +1676,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-egenera" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_egenera" />
</div>
</div>
@@ -1564,7 +1699,7 @@
<div id="fence_bladecenter" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>IBM Blade Center</td>
</tr>
@@ -1597,6 +1732,11 @@
</td>
</tr>
</table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
<input type="hidden" name="fence_type" value="fence_bladecenter" />
</div>
</div>
@@ -1606,7 +1746,7 @@
<div id="fence_bullpap" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Bull PAP</td>
</tr>
@@ -1639,6 +1779,20 @@
</td>
</tr>
</table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-bullpap" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
<input type="hidden" name="fence_type" value="fence_bullpap" />
</div>
</div>
@@ -1648,7 +1802,7 @@
<div id="fence_rps10" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>RPS10 Serial Switch</td>
</tr>
@@ -1670,11 +1824,16 @@
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value cur_fencedev/port| nothing" />
+ tal:attributes="value cur_fencedev/port | nothing" />
</td>
</tr>
</table>
- <input type="hidden" name="fence_type" value="fence_rps10"/>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="fence_type" value="fence_rps10" />
</div>
</div>
@@ -1682,8 +1841,8 @@
tal:attributes="id cur_fencedev/name | nothing">
<div id="fence_xvm" class="fencedev">
- <table>
- <tr tal:condition="exists: cur_fence_type">
+ <table>
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Virtual Machine Fencing</td>
</tr>
@@ -1694,7 +1853,22 @@
tal:attributes="value cur_fencedev/name | nothing" />
</td>
</tr>
- </table>
+ </table>
+ <div name="instances">
+ <tal:block tal:condition="exists: cur_fence_instances">
+ <tal:block tal:repeat="cur_fence_instance cur_fence_instances">
+ <tal:block
+ metal:use-macro="here/form-macros/macros/fence-instance-form-xvm" />
+ </tal:block>
+ </tal:block>
+ </div>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
+ <input type="hidden" name="fence_type" value="xvm" />
</div>
</div>
@@ -1702,8 +1876,8 @@
tal:attributes="id cur_fencedev/name | nothing">
<div id="fence_scsi" class="fencedev">
- <table>
- <tr tal:condition="exists: cur_fence_type">
+ <table>
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>SCSI Reservation Fencing</td>
</tr>
@@ -1714,7 +1888,14 @@
tal:attributes="value cur_fencedev/name | nothing" />
</td>
</tr>
- </table>
+ </table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="sharable" value="1" />
+ <input type="hidden" name="fence_type" value="scsi" />
</div>
</div>
@@ -1723,7 +1904,7 @@
<div id="fence_ipmilan" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>IPMI Lan</td>
</tr>
@@ -1760,6 +1941,11 @@
<td><input name="auth_type" type="text" Title="Options are to leave blank for none, password, md2, or md5"/></td>
</tr>
</table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
<input type="hidden" name="fence_type" value="fence_ipmilan" />
</div>
</div>
@@ -1769,7 +1955,7 @@
<div id="fence_manual" class="fencedev">
<table>
- <tr tal:condition="exists: cur_fence_type">
+ <tr>
<td><strong class="cluster">Fence Type</strong></td>
<td>Manual Fencing</td>
</tr>
@@ -1780,8 +1966,13 @@
tal:attributes="value cur_fencedev/name | nothing" />
</td>
</tr>
- <input type="hidden" name="fence_type" value="fence_manual" />
</table>
+ <tal:block tal:condition="exists: cur_fencedev">
+ <input type="hidden" name="existing_device" value="1" />
+ <input type="hidden" name="old_name"
+ tal:attributes="value cur_fencedev/name | nothing" />
+ </tal:block>
+ <input type="hidden" name="fence_type" value="fence_manual" />
</div>
</div>
@@ -1863,172 +2054,206 @@
</div>
<div metal:define-macro="fence-instance-form-apc">
- <div id="fence_apc_instance" class="fencedev">
+ <div id="fence_apc_instance" name="fence_apc" class="fencedev_instance">
<table>
<tr>
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/port | nothing" />
</td>
</tr>
<tr>
<td>Switch</td>
<td>
<input name="switch" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/switch | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-egenera">
- <div id="fence_egenera_instance" class="fencedev">
+ <div id="fence_egenera_instance" name="fence_egenera" class="fencedev_instance">
<table>
<tr>
<td>lpan</td>
<td>
<input name="lpan" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/lpan | nothing" />
</td>
</tr>
<tr>
<td>pserver</td>
<td>
<input name="pserver" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/pserver | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-wti">
- <div id="fence_wti_instance" class="fencedev">
+ <div id="fence_wti_instance" name="fence_wti" class="fencedev_instance">
<table>
<tr>
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/port | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-brocade">
- <div id="fence_brocade_instance" class="fencedev">
+ <div id="fence_brocade_instance" name="fence_brocade" class="fencedev_instance">
<table>
<tr>
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/port | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-vixel">
- <div id="fence_vixel_instance" class="fencedev">
+ <div id="fence_vixel_instance" name="fence_vixel" class="fencedev_instance">
<table>
<tr>
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/port | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-sanbox2">
- <div id="fence_sanbox2_instance" class="fencedev">
+ <div id="fence_sanbox2_instance" name="fence_sanbox2" class="fencedev_instance">
<table>
<tr>
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/port | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-mcdata">
- <div id="fence_mcdata_instance" class="fencedev">
+ <div id="fence_mcdata_instance" name="fence_mcdata" class="fencedev_instance">
<table>
<tr>
<td>Port</td>
<td>
<input name="port" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/port | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-gndb">
- <div id="fence_gnbd_instance" class="fencedev">
+ <div id="fence_gnbd_instance" name="fence_gnbd" class="fencedev_instance">
<table>
<tr>
<td>IP Address</td>
<td>
<input name="ipaddress" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/ipaddress | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-bladecenter">
- <div id="fence_bladecenter_instance" class="fencedev">
+ <div id="fence_bladecenter_instance" name="fence_bladecenter" class="fencedev_instance">
<table>
<tr>
<td>Blade</td>
<td>
<input name="ipaddress" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/ipaddress | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-bullpap">
- <div id="fence_bullpap_instance" class="fencedev">
+ <div id="fence_bullpap_instance" name="fence_bullpap" class="fencedev_instance">
<table>
<tr>
<td>Domain</td>
<td>
<input name="domain" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/domain | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
<div metal:define-macro="fence-instance-form-xvm">
- <div id="fence_xvm_instance" class="fencedev">
+ <div id="fence_xvm_instance" name="fence_xvm" class="fencedev_instance">
<table>
<tr>
<td>Domain</td>
<td>
<input name="domain" type="text"
- tal:attributes="value nothing" />
+ tal:attributes="value cur_instance/domain | nothing" />
</td>
</tr>
+ <input tal:condition="exists: cur_instance"
+ type="hidden" name="existing_instance" value="1" />
+ <input type="hidden" name="parent_fencedev" value="" />
</table>
</div>
</div>
+
<div metal:define-macro="fence-instance-form-list">
<tal:block
metal:use-macro="here/form-macros/macros/fence-instance-form-apc" />
@@ -2071,7 +2296,7 @@
global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
<tal:block tal:define="
- global nodestatus python: here.getClusterStatus(ricci_agent);
+ global nodestatus python: here.getClusterStatus(request, ricci_agent);
global nodeinfo python: here.getNodeInfo(modelb, nodestatus, request);
global status_class python: 'node_' + (nodeinfo['nodestate'] == '0' and 'active' or (nodeinfo['nodestate'] == '1' and 'inactive' or 'unknown'));
global cluster_node_status_str python: (nodeinfo['nodestate'] == '0' and 'Cluster member' or (nodeinfo['nodestate'] == '1' and 'Currently not a cluster participant' or 'This node is not responding'));
@@ -2214,79 +2439,91 @@
<hr/>
- <div id="invisible" class="invisible">
+ <div class="invisible" id="fence_device_list">
<tal:block metal:use-macro="here/form-macros/macros/fence-form-list" />
</div>
- <table id="fence_devices" class="cluster node fencedev">
- <tfoot class="fencedev">
- <tr class="cluster node fencedev"><td class="cluster node fencedev">
- <input type="button" value="Update fence properties"
- onClick="validate_fence_properties('fence_devices')" />
- </td></tr>
+ <div class="invisible" id="shared_fence_devices">
+ <tal:block tal:repeat="cur_fencedev fencedevinfo/fencedevs">
+ <tal:block metal:use-macro="here/form-macros/macros/shared-fence-device-list" />
+ </tal:block>
+ </div>
+
+ <div class="invisible" id="fence_instances">
+ <tal:block metal:use-macro="here/form-macros/macros/fence-instance-form-list" />
+ </div>
+
+ <div id="fence_selection_block" class="invisible">
+ <form name="main_fence_form">
+ <select name="select_div">
+ <option value="fence-form-new-device">------ Use an existing Fence Device ------</option>
+ <tal:block tal:repeat="f fencedevinfo/fencedevs">
+ <option class="shared_fencedev"
+ tal:attributes="value f/name"
+ tal:content="python: f['name'] + ' (' + f['pretty_name'] + ')'"
+ />
+ </tal:block>
+ <option value="fence-form-new-instance">------ Create a new Fence Device ------</option>
+ <tal:block metal:use-macro="here/form-macros/macros/fence-option-list" />
+ </select>
+ <input type="hidden" name="fence_level" value="" />
+ <input type="hidden" name="fence_num" value="" />
+ </form>
+ </div>
+
+ <table id="fence_devices" class="cluster node fence">
+ <tfoot class="fence">
+ <tr class="cluster node fence"><td class="cluster node fence">
+ <input type="button" value="Update fence properties"
+ onClick="validate_fence_properties('fence_devices')" />
+ </td></tr>
</tfoot>
- <tbody class="fencedev">
- <tr class="cluster node info_top fencedev">
- <td class="cluster node fencedev">
- <span class="fencedev">
+
+ <tbody class="fence">
+ <tr class="cluster node info_top fence">
+ <td class="cluster node fence">
+ <span class="fence">
<strong class="cluster node">Main Fencing Method</strong>
</span>
</td>
<td class="cluster node fence_backup">
- <span class="fencedev">
+ <span class="fence">
<strong class="cluster node">Backup Fencing Method</strong>
</span>
</td>
</tr>
- <tr class="cluster node info_top fencedev">
- <td class="cluster node fence_main fencedev">
- <tal:block tal:repeat="cur_fencedev fencedevinfo/fencedevs">
- <div class="invisible" id="shared_fence_devices">
- <tal:block metal:use-macro="here/form-macros/macros/shared-fence-device-list" />
- </div>
- </tal:block>
+ <tr class="cluster node info_top fence">
+ <td class="cluster node fence_main fence"><div class="fence_container">
+ <div id="fence_list_level1">
+ <tal:comment tal:replace="nothing">
+ XXX - fill in any existing fence devices for this node
+ and update the counter number for this level
+ </tal:comment>
+ </div>
- <form name="main_fence_form">
- <select name="select_div"
- onChange="swap_fence_div('fence_container',
- this.options[this.selectedIndex].value)">
- <option value="fence-form-new-device">------ Use an existing Fence Device ------</option>
- <tal:block tal:repeat="f fencedevinfo/fencedevs">
- <option class="shared_fencedev"
- tal:attributes="value f/name"
- tal:content="python: f['name'] + ' (' + f['pretty_name'] + ')'"
- />
- </tal:block>
- <option value="fence-form-new-instance">------ Create a new Fence Device ------</option>
- <tal:block metal:use-macro="here/form-macros/macros/fence-option-list" />
- </select>
- </form>
- <div id="fence_container">
+ <div class="fence_control">
+ <input type="button" value="Add a fence to this level"
+ onclick="add_node_fence_device(1);" />
</div>
- </td>
- <td class="cluster node fence_main fencedev">
- <form name="backup_fence_form">
- <select name="select_div"
- onChange="swap_fence_div('fence_container_backup',
- this.options[this.selectedIndex].value)">
- <option value="fence-form-new-device">------ Use an existing Fence Device ------</option>
- <option value="fence-form-new-instance">------ Create a new Fence Device ------</option>
- <tal:block metal:use-macro="here/form-macros/macros/fence-option-list" />
- </select>
- </form>
- <div id="fence_container_backup">
+ </div></td>
+
+ <td class="cluster node fence_main fence"><div class="fence_container">
+ <div id="fence_list_level2">
+ <tal:comment tal:replace="nothing">
+ XXX - fill in any existing fence devices for this node
+ and update the counter number for this level
+ </tal:comment>
</div>
- </td>
+
+ <div class="fence_control">
+ <input type="button" value="Add a fence to this level"
+ onclick="add_node_fence_device(2)" />
+ </div>
+ </div></td>
</tr>
</tbody>
</table>
- <script type="text/javascript">
- swap_fence_div('fence_container',
- document.main_fence_form.select_div.options[document.main_fence_form.select_div.selectedIndex].value);
- swap_fence_div('fence_container_backup',
- document.backup_fence_form.select_div.options[document.backup_fence_form.select_div.selectedIndex].value);
- </script>
</div>
<div metal:define-macro="nodes-form">
@@ -2302,7 +2539,7 @@
global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
<tal:block tal:define="
- global status python: here.getClusterStatus(ricci_agent);
+ global status python: here.getClusterStatus(request, ricci_agent);
global nds python: here.getNodesInfo(modelb, status, request)" />
<div tal:repeat="nd nds">
@@ -2523,7 +2760,7 @@
global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
<tal:block tal:define="
- global svcstatus python: here.getClusterStatus(ricci_agent);
+ global svcstatus python: here.getClusterStatus(request, ricci_agent);
global svcinf python: here.getServicesInfo(svcstatus,modelb,request);
global svcs svcinf/services" />
@@ -2546,9 +2783,31 @@
<form method="post" onSubmit="return dropdown(this.gourl)">
<select name="gourl">
<option value="">Choose a Task...</option>
- <option value="" tal:attributes="value svc/cfgurl">Configure</option>
+ <option
+ tal:attributes="value svc/cfgurl | nothing"
+ tal:content="string:Configure this service" />
+
<option value="">----------</option>
- <option value="">Delete</option>
+
+ <option
+ tal:condition="running"
+ tal:attributes="value svc/retstarturl| nothing"
+ tal:content="string:Restart this service" />
+
+ <option
+ tal:condition="running"
+ tal:attributes="value svc/disableurl | nothing"
+ tal:content="string:Stop this service" />
+
+ <option
+ tal:condition="not: running"
+ tal:attributes="value svc/enableurl | nothing"
+ tal:content="string:Start this service" />
+
+ <option
+ tal:condition="not: running"
+ tal:attributes="value svc/delurl | nothing"
+ tal:content="string:Delete this service" />
</select>
<input type="submit" value="Go"/>
</form>
@@ -2566,7 +2825,7 @@
This service is stopped
</tal:block>
</div>
- <p>Autostart is <span tal:condition="not: autostart" tal:replace="string:not" /> enabled for this service</p>
+ <p>Autostart is <span tal:condition="python: autostart.lower() == 'false'" tal:replace="string:not" /> enabled for this service</p>
</td>
</tr>
@@ -2628,6 +2887,14 @@
<input type="text" length="20" name="service_name" value="" />
</td>
</tr>
+ <tr class="systemsTable">
+ <td class="systemsTable">
+ Automatically start this service
+ </td>
+ <td class="systemsTable">
+ <input type="checkbox" name="autostart" checked="checked" />
+ </td>
+ </tr>
</table>
</form>
</div>
@@ -2650,7 +2917,10 @@
<input type="hidden" name="uuid" value="toplevel" />
<input type="hidden" name="parent_uuid" value="_toplevel" />
<input type="hidden" name="tree_level" value="-1" />
+ <input type="hidden" name="svc_name" value="" />
+ <input type="hidden" name="autostart" value="-1" />
<input type="hidden" name="form_xml" />
+ <input type="hidden" name="action" value="add" />
</form>
</div>
@@ -2710,30 +2980,46 @@
</div>
<div metal:define-macro="serviceconfig-type-macro" tal:omit-tag="">
- <span tal:omit-tag="" tal:condition="python: type == 'ip'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/ip_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'fs'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/fs_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'gfs'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/gfs_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'nfsm'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/nfsm_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'nfsx'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/nfsx_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'nfsc'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/nfsc_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'smb'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/smb_macro" />
- </span>
- <span tal:omit-tag="" tal:condition="python: type == 'script'">
- <tal:block metal:use-macro="here/resource-form-macros/macros/scr_macro" />
- </span>
+ <tal:block tal:condition="python: type == 'ip' or type == 'IP Address: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/ip_macro" />
+ </tal:block>
+
+ <tal:block tal:condition="python: type == 'fs' or type == 'File System: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/fs_macro" />
+ </tal:block>
+
+ <tal:block tal:condition="python: type == 'gfs' or type == 'GFS: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/gfs_macro" />
+ </tal:block>
+
+ <tal:block tal:condition="python: type == 'nfsm' or type == 'NFS Mount: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/nfsm_macro" />
+ </tal:block>
+
+ <tal:block tal:condition="python: type == 'nfsx' or type == 'NFS Export: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/nfsx_macro" />
+ </tal:block>
+
+ <tal:block tal:condition="python: type == 'nfsc' or type == 'NFS Client: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/nfsc_macro" />
+ </tal:block>
+
+ <tal:block
+ tal:condition="python: type == 'smb' or type == 'Samba Service: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/smb_macro" />
+ </tal:block>
+
+ <tal:block tal:condition="python: type == 'script' or type == 'Script: '">
+ <tal:block
+ metal:use-macro="here/resource-form-macros/macros/scr_macro" />
+ </tal:block>
</div>
<div metal:define-macro="service-config-head-macro" tal:omit-tag="">
@@ -2749,7 +3035,7 @@
<tal:block tal:define="
global global_resources python: here.getResourcesInfo(modelb, request);
- global sstat python: here.getClusterStatus(ricci_agent);
+ global sstat python: here.getClusterStatus(request, ricci_agent);
global sinfo python: here.getServiceInfo(sstat, modelb, request);
global running sinfo/running | nothing;" />
@@ -2775,7 +3061,8 @@
tal:content="sinfo/name | nothing"
tal:attributes="class python: running and 'running' or 'stopped'" />
</td>
- <td class="cluster service service_action">
+ <td class="cluster service service_action"
+ tal:condition="python: sinfo and 'innermap' in sinfo">
<form method="post" onSubmit="return dropdown(this.gourl)">
<input type="hidden" name="pagetype" tal:attributes="
value request/pagetype | request/form/pagetype | nothing" />
@@ -2790,14 +3077,15 @@
<option value="" tal:attributes="value innermap/disableurl">Disable this service</option>
<option value="">----------</option>
<option tal:repeat="starturl innermap/links" value="" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
- <option value="">----------</option>
- <option value="">Delete this service</option>
</tal:block>
<tal:block tal:condition="not: running">
<option value="">----------</option>
<option value="" tal:attributes="value innermap/enableurl">Enable this service</option>
<option value="">----------</option>
+ <option
+ tal:attributes="value innermap/delurl | nothing"
+ tal:content="string:Delete this service" />
</tal:block>
</select>
<input type="submit" value="Go"/>
@@ -2842,6 +3130,18 @@
</div>
</div>
<div class="service_comp_list">
+ <form name="service_name_form">
+ <table class="rescfg">
+ <tr><td>
+ Automatically start this service
+ </td>
+ <td><input type="checkbox" name="autostart"
+ tal:attributes="checked python: ('autostart' in sinfo and sinfo['autostart'].lower() != 'false') and 'checked'" /></td></tr>
+ </table>
+ <input type="hidden" name="service_name"
+ tal:attributes="value sinfo/name | string:1" />
+ </form>
+
<form name="master" method="post">
<tal:block
tal:define="global clusterinfo python: here.getClusterInfo(modelb, request)" />
@@ -2857,7 +3157,10 @@
<input type="hidden" name="uuid" value="toplevel" />
<input type="hidden" name="parent_uuid" value="_toplevel" />
<input type="hidden" name="tree_level" value="-1" />
+ <input type="hidden" name="svc_name" value="" />
+ <input type="hidden" name="autostart" value="-1" />
<input type="hidden" name="form_xml" />
+ <input type="hidden" name="action" value="edit" />
</form>
</div>
@@ -2881,6 +3184,11 @@
<h2>Service Process Form</h2>
</div>
+<div metal:define-macro="servicedelete-form">
+ <h2>Service Delete Form</h2>
+ <tal:block tal:define="dummy python: here.delService(request)" />
+</div>
+
<div metal:define-macro="resources-form">
<h2>Resources Form</h2>
</div>
@@ -2918,7 +3226,7 @@
global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
<tal:block tal:define="
- global sta python: here.getClusterStatus(ricci_agent);
+ global sta python: here.getClusterStatus(request, ricci_agent);
global fdominfo python: here.getFdomsInfo(modelb, request, sta);" />
<div class="cluster fdom" tal:repeat="fdom fdominfo">
@@ -3051,23 +3359,23 @@
<tal:block metal:use-macro="here/form-macros/macros/shared-fence-form-list" />
</div>
- <table id="fence_devices" class="cluster node fencedev">
- <tfoot class="fencedev">
- <tr class="cluster node fencedev"><td class="cluster node fencedev">
+ <table id="fence_devices" class="cluster node fence">
+ <tfoot class="fence">
+ <tr class="cluster node fence"><td class="cluster node fence">
<input type="button" value="Add this shared fence device"
onClick="validate_fence_properties('fence_devices')" />
</td></tr>
</tfoot>
- <tbody class="fencedev">
- <tr class="cluster node info_top fencedev">
- <td class="cluster node fencedev">
- <span class="fencedev">
+ <tbody class="fence">
+ <tr class="cluster node info_top fence">
+ <td class="cluster node fence">
+ <span class="fence">
<strong class="cluster node">Fencing Type</strong>
</span>
</td>
</tr>
- <tr class="cluster node info_top fencedev">
- <td class="cluster node fence_main fencedev">
+ <tr class="cluster node info_top fence">
+ <td class="cluster node fence_main fence">
<form name="main_fence_form">
<select name="select_div"
onChange="swap_fence_div('fence_container',
@@ -3208,7 +3516,7 @@
<tal:block metal:use-macro="here/form-macros/macros/fence-form-manual" />
</tal:block>
- <div class="fencedev">
+ <div class="fence_submit">
<input class="hbInput" type="button" value="Submit" name="Submit" />
</div>
</div>
--- conga/luci/cluster/index_html 2006/11/16 19:34:52 1.20.2.4
+++ conga/luci/cluster/index_html 2006/12/07 17:54:31 1.20.2.5
@@ -100,25 +100,6 @@
window.open(href, windowname, 'width=500,height=500,scrollbars=yes');
return false;
}
-
- function swap_fence_div(container_id, element_id) {
- var container_element = document.getElementById(container_id)
- if (!container_element) {
- alert('Can\'t find element with id = ' + container_id);
- return (-1);
- }
-
- var child_element = document.getElementById(element_id);
- if (!child_element) {
- alert('Can\'t find element with id = ' + element_id);
- return (-1);
- }
- if (container_element.firstChild)
- container_element.removeChild(container_element.firstChild);
- var target = child_element.cloneNode(1);
- target.id = null;
- container_element.appendChild(target);
- }
//-->
</SCRIPT>
<metal:javascriptslot define-slot="javascript_head_slot" />
--- conga/luci/cluster/resource-form-macros 2006/11/16 19:34:53 1.21.2.2
+++ conga/luci/cluster/resource-form-macros 2006/12/07 17:54:31 1.21.2.3
@@ -271,7 +271,7 @@
<div metal:use-macro="here/resource-form-macros/macros/fs_macro" />
</tal:block>
- <tal:block tal:condition="python: type == 'gfs'">
+ <tal:block tal:condition="python: type == 'gfs' or type == 'clusterfs'">
<div metal:use-macro="here/resource-form-macros/macros/gfs_macro" />
</tal:block>
@@ -307,7 +307,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -368,7 +371,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -507,7 +513,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -609,7 +618,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -727,7 +739,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -799,7 +814,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -851,7 +869,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
@@ -913,7 +934,10 @@
tal:attributes="name res/parent_uuid | nothing"
tal:define="editDisabled resourceIsRef | nothing">
- <input name="edit" type="hidden"
+ <input name="immutable" type="hidden" value="true"
+ tal:condition="editDisabled" />
+
+ <input name="edit" type="hidden" value="true"
tal:condition="python: ptype == '33' and True or False" />
<input name="pagetype" type="hidden"
--- conga/luci/cluster/resource_form_handlers.js 2006/11/16 19:34:53 1.20.2.2
+++ conga/luci/cluster/resource_form_handlers.js 2006/12/07 17:54:31 1.20.2.3
@@ -380,21 +380,61 @@
function forms_to_xml(master_form) {
var errors = new Array();
var form_xml = '';
+ var svc_name = null;
+ var autostart = 1;
var form = document.getElementsByTagName('form');
for (var i = 0 ; i < form.length ; i++) {
+ if (form[i].name == 'service_name_form') {
+ if (!form[i].service_name ||
+ str_is_blank(form[i].service_name.value))
+ {
+ set_form_err(form[i].service_name);
+ } else {
+ clr_form_err(form[i].service_name);
+ svc_name = form[i].service_name.value;
+ }
+ if (!form[i].autostart.checked)
+ autostart = 0;
+ continue;
+ }
+
if (form[i].name == 'master' || !form[i].uuid || !form[i].uuid.value)
continue;
+
var err = check_form(form[i]);
if (err)
- errors.concat(err);
- var temp = form[i].innerHTML.match(/<input [^>]+>/ig).toString().replace(/>(,|$)/g, '/>');
- if (!temp)
- continue;
+ errors = errors.concat(err);
+ var temp = '';
+
+ var input_elem = form[i].getElementsByTagName('input');
+ for (var j = 0 ; j < input_elem.length ; j++) {
+ var res_type = input_elem[j].type;
+ if (res_type == 'hidden' || res_type == 'text' ||
+ res_type == 'password')
+ {
+ temp += '<input type="' + res_type + '" name="' + input_elem[j].name + '" value="' + input_elem[j].value + '" />';
+ } else if (res_type == 'checkbox' || res_type == 'radio') {
+ if (input_elem[j].checked)
+ temp += '<input type="' + res_type + '" name="' + input_elem[j].name + '" checked="checked"';
+ if (res_type == 'radio')
+ temp += ' value="' + input_elem[j].value + '"';
+ temp += ' />';
+ }
+ }
+
+ var select_elem = form[i].getElementsByTagName('select');
+ for (var j = 0 ; j < select_elem.length ; j++) {
+ temp += '<input type="text" name="' + select_elem[j].name + '" value="' + select_elem[j].options[select_elem[j].options.selectedIndex].value + '" />';
+ }
+
form_xml += '<form id="' + form[i].uuid.value + '" parent="' +
form[i].parent_uuid.value + '">' + temp + '</form>';
}
+ if (!svc_name)
+ errors.push('No name was given for this service.');
+
if (!form_xml)
errors.push('No resource information was submitted.');
@@ -403,7 +443,15 @@
/* sort this out in the backend */
master_form.form_xml.value = '<formlist>' + form_xml + '</formlist>';
- if (confirm('Save changes to this service?'))
+ master_form.svc_name.value = svc_name;
+ master_form.autostart.value = autostart;
+
+ var confirm_msg = null;
+ if (master_form.action.value == 'add')
+ confirm_msg = 'Create this service?';
+ else
+ confirm_msg = 'Save changes to this service?';
+ if (confirm(confirm_msg))
master_form.submit();
return (0);
}
--- conga/luci/homebase/luci_homebase.css 2006/11/16 19:34:53 1.28.2.1
+++ conga/luci/homebase/luci_homebase.css 2006/12/07 17:54:31 1.28.2.2
@@ -14,27 +14,27 @@
background: #dee7ec;
}
-div.fencedev {
+div.fence {
max-width: 700px;
padding: .5em;
}
-*.fencedev {
+*.fence {
background: #dee7ec;
}
-table.fencedev {
+table.fence {
padding: .618em;
width: 700px;
}
-div.fencedev,
-td.fencedev {
+div.fence,
+td.fence {
padding-top: .309em;
padding-bottom: .309em;
}
-td.fencedev {
+td.fence {
width: 50%;
}
@@ -438,6 +438,21 @@
margin-bottom: .25em ! important;
}
+div.fence_add {
+ margin-top: .25em ! important;
+ margin-bottom: .25em ! important;
+}
+
+div.fence_container {
+ border: thin solid #c9c9c9;
+}
+
+div.fence_control {
+ margin-top: 2em;
+ margin-bottom: .75em;
+ margin-left: .33em;
+}
+
div.service_comp_list {
background: #dee7ec;
max-width: 700px;
--- conga/luci/site/luci/Extensions/ClusterNode.py 2006/05/30 20:17:21 1.1
+++ conga/luci/site/luci/Extensions/ClusterNode.py 2006/12/07 17:54:31 1.1.2.1
@@ -96,3 +96,10 @@
except KeyError, e:
return ""
+ def getVotes(self):
+ try:
+ return self.getAttribute('votes')
+ except KeyError, e:
+ return "1"
+ except:
+ return None
--- conga/luci/site/luci/Extensions/FenceDevice.py 2006/10/04 15:11:10 1.2
+++ conga/luci/site/luci/Extensions/FenceDevice.py 2006/12/07 17:54:31 1.2.2.1
@@ -19,7 +19,12 @@
def getAgentType(self):
- return self.attr_hash["agent"]
+ agent = self.attr_hash["agent"]
+ try:
+ return agent[agent.rfind('/') + 1:]
+ except:
+ pass
+ return agent
def isShared(self):
agent = self.getAgentType()
--- conga/luci/site/luci/Extensions/LuciSyslog.py 2006/11/16 19:34:53 1.2.2.3
+++ conga/luci/site/luci/Extensions/LuciSyslog.py 2006/12/07 17:54:31 1.2.2.4
@@ -78,6 +78,7 @@
def close(self):
try:
+ self.__init = 0
closelog()
except:
pass
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2006/11/30 20:12:38 1.120.2.12
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2006/12/07 17:54:31 1.120.2.13
@@ -12,8 +12,10 @@
from Ip import Ip
from Clusterfs import Clusterfs
from Fs import Fs
+from RefObject import RefObject
from NFSClient import NFSClient
from NFSExport import NFSExport
+from Service import Service
from Netfs import Netfs
from Vm import Vm
from Script import Script
@@ -396,19 +398,31 @@
response.redirect(request['URL'] + "?pagetype=" + CLUSTER_CONFIG + "&clustername=" + clusterName + '&busyfirst=true')
def validateServiceAdd(self, request):
+ errors = list()
+
try:
form_xml = request['form_xml']
if not form_xml:
- raise KeyError('form_xml must not be blank')
- except KeyError, e:
+ raise KeyError, 'form_xml must not be blank'
+ except Exception, e:
+ luci_log.debug_verbose('vSA0: no form_xml: %s' % str(e))
return (False, {'errors': ['No resource data was supplied for this service.']})
try:
+ model = request.SESSION.get('model')
+ if not model:
+ raise Exception, 'model is None'
+ except Exception, e:
+ luci_log.debug_verbose('vSA0a: %s' % str(e))
+ return (False, {'errors': [ 'The cluster model is missing from the session object.' ]})
+
+ try:
doc = minidom.parseString(form_xml)
forms = doc.getElementsByTagName('form')
if len(forms) < 1:
raise
- except:
+ except Exception, e:
+ luci_log.debug_verbose('vSA1: error: %s' % str(e))
return (False, {'errors': ['The resource data submitted for this service is not properly formed.']})
form_hash = {}
@@ -440,27 +454,145 @@
try:
dummy_form[str(i.getAttribute('name'))] = str(i.getAttribute('value'))
except Exception, e:
- luci_log.debug_verbose('Error parsing service XML: %s' % str(e))
+ luci_log.debug_verbose('vSA2: parsing XML: %s' % str(e))
pass
try:
res_type = dummy_form['type'].strip()
- if not res_type or not res_type in resourceAddHandler:
- raise
- except:
- return (False, {'errors': ['An invalid resource type was specified: ' + res_type]})
+ if not res_type:
+ raise Exception, 'no resource type was given'
+ if not res_type in resourceAddHandler:
+ raise Exception, 'invalid resource type: %s' % res_type
+ except Exception, e:
+ luci_log.debug_verbose('vSA3: %s' % str(e))
+ return (False, {'errors': [ 'An invalid resource type was specified' ]})
try:
- resObj = resourceAddHandler[res_type](request, dummy_form)
- except:
- luci_log('res type %d is invalid' % res_type)
+ if res_type == 'ip':
+ dummy_form['resourceName'] = dummy_form['ip_address']
+ except Exception, e:
+ luci_log.debug_verbose('vSA3a: type is ip but no addr: %s' % str(e))
+ return (False, {'errors': [ 'No IP address was given.' ]})
+
+ try:
+ if dummy_form.has_key('immutable'):
+ newRes = getResource(model, dummy_form['resourceName'])
+ resObj = RefObject(newRes)
+ resObj.setRef(newRes.getName())
+ else:
+ resObj = resourceAddHandler[res_type](request, dummy_form)[0]
+ except Exception, e:
resObj = None
+ luci_log.debug_verbose('vSA4: type %s: %s' % (res_type, str(e)))
if resObj is None:
- return (False, {'errors': ['An error occurred while adding ' + res_type]})
+ return (False, {'errors': [ 'An error occurred while adding %s' % res_type ]})
form_hash[form_id]['obj'] = resObj
-
- return (True, {'messages': ['This service has been updated.']})
+
+ if len(errors) > 0:
+ return (False, {'errors': errors})
+
+ try:
+ service_name = request.form['svc_name'].strip()
+ except Exception, e:
+ luci_log.debug_verbose('vSA5: no service name: %s' % str(e))
+ return (False, {'errors': [ 'No service name was given.' ]})
+
+ autostart = "1"
+ try:
+ if not request.form.has_key('autostart') or request.form['autostart'] == "0":
+ autostart = "0"
+ except Exception, e:
+ autostart = None
+ luci_log.debug_verbose('vSA5a: error getting autostart: %s' % str(e))
+
+ try:
+ cur_service = model.retrieveServiceByName(service_name)
+ except GeneralError, e:
+ luci_log.debug_verbose('vSA5b: no service named %s found' % service_name)
+ cur_service = None
+ except Exception, e:
+ luci_log.debug_verbose('vSA5c: no service named %s found: %s' % (service_name, str(e)))
+ cur_service = None
+
+ try:
+ if request.form['action'] == 'edit':
+ if cur_service is None:
+ return (False, {'errors': [ 'The service %s could not be found for editing.' % service_name ]})
+ model.deleteService(service_name)
+ elif request.form['action'] == 'add':
+ if cur_service is not None:
+ return (False, {'errors': [ 'A service with the name %s already exists.' % service_name ]})
+ else:
+ luci_log.debug_verbose('vSA4a: unknown action %s' % request.form['action'])
+ return (False, {'errors': [ 'An unknown action was specified.' ]})
+ except Exception, e:
+ luci_log.debug_verbose('vSA5: no action type: %s' % str(e))
+
+ def buildSvcTree(parent, child_id_list):
+ for i in child_id_list:
+ try:
+ child = form_hash[i]['obj']
+ if not child:
+ raise Exception, 'No object for %s' % i
+ except Exception, e:
+ luci_log.debug_verbose('bST0: %s' % str(e))
+ continue
+ parent.addChild(child)
+ if 'kids' in form_hash[i]:
+ buildSvcTree(child, form_hash[i]['kids'])
+
+ new_service = Service()
+ new_service.addAttribute('name', service_name)
+ if autostart is not None:
+ new_service.attr_hash['autostart'] = autostart
+
+ buildSvcTree(new_service, form_hash['toplevel']['kids'])
+ model.resourcemanager_ptr.addChild(new_service)
+
+ clustername = model.getClusterName()
+ if not clustername:
+ luci_log.debug_verbose('vAS6: no cluname from mb')
+ return (False, {'errors': [ 'Unable to determine cluster name' ]})
+
+ try:
+ conf = model.exportModelAsString()
+ if not conf:
+ raise Exception, 'model string for %s is blank' % clustername
+ except Exception, e:
+ luci_log.debug_verbose('vAS6a: exportModelAsString : %s' \
+ % str(e))
+ return (False, {'errors': [ 'An error occurred while adding this service.' ]})
+
+ rc = getRicciAgent(self, clustername)
+ if not rc:
+ luci_log.debug_verbose('vAS6b: unable to find a ricci agent for cluster %s' % clustername)
+ return 'Unable to find a ricci agent for the %s cluster' % clustername
+
+ try:
+ ragent = rc.hostname()
+ if not ragent:
+ luci_log.debug_verbose('vAS7: missing ricci hostname')
+ raise Exception, 'unknown ricci agent hostname'
+
+ batch_number, result = setClusterConf(rc, str(conf))
+ if batch_number is None or result is None:
+ luci_log.debug_verbose('vAS8: missing batch_number or result')
+ raise Exception, 'unable to save the new cluster configuration.'
+ except Exception, e:
+ luci_log.debug_verbose('vAS9: %s' % str(e))
+ return 'An error occurred while propagating the new cluster.conf: %s' % str(e)
+
+ try:
+ if request.form['action'] == 'edit':
+ set_node_flag(self, clustername, ragent, str(batch_number), SERVICE_CONFIG, "Configuring service \'%s\'" % service_name)
+ else:
+ set_node_flag(self, clustername, ragent, str(batch_number), SERVICE_ADD, "Adding new service \'%s\'" % service_name)
+ except Exception, e:
+ luci_log.debug_verbose('vAS10: failed to set flags: %s' % str(e))
+
+ response = request.RESPONSE
+ response.redirect(request['URL'] + "?pagetype=" + SERVICES + "&clustername=" + clustername + '&busyfirst=true')
def validateResourceAdd(self, request):
try:
@@ -1712,23 +1844,133 @@
return None
return getRicciAgent(self, clustername)
-def getClusterStatus(self, rc):
+def getClusterStatusModel(model):
+ results = list()
+ vals = {}
+
+ try:
+ clustername = model.getClusterName()
+ clusteralias = model.getClusterAlias()
+ vals['type'] = 'cluster'
+ vals['alias'] = clusteralias
+ vals['name'] = clustername
+ vals['error'] = True
+ vals['votes'] = '[unknown]'
+ vals['quorate'] = '[unknown]'
+ vals['minQuorum'] = '[unknown]'
+ results.append(vals)
+ except Exception, e:
+ luci_log.debug_verbose('GCSM0: %s' % str(e))
+ return None
+
+ try:
+ nodelist = model.getNodes()
+ except Exception, e:
+ luci_log.debug_verbose('GCSM1: %s' % str(e))
+ return None
+
+ for node in nodelist:
+ node_val = {}
+ node_val['type'] = 'node'
+ try:
+ node_name = node.getName()
+ if not node_name:
+ raise Exception, 'cluster node name is unknown'
+ except:
+ node_name = '[unknown]'
+
+ node_val['name'] = node_name
+ node_val['clustered'] = '[unknown]'
+ node_val['online'] = '[unknown]'
+ node_val['error'] = True
+
+ try:
+ votes = node.getVotes()
+ if not votes:
+ raise Exception, 'unknown unmber of votes'
+ except:
+ votes = '[unknown]'
+
+ node_val['votes'] = votes
+ results.append(node_val)
+ return results
+
+def getClusterStatusDB(self, clustername):
+ results = list()
+ vals = {}
+
+ vals['type'] = 'cluster'
+ vals['alias'] = clustername
+ vals['name'] = clustername
+ vals['error'] = True
+ vals['quorate'] = '[unknown]'
+ vals['votes'] = '[unknown]'
+ vals['minQuorum'] = '[unknown]'
+ results.append(vals)
+
+ try:
+ cluster_path = '%s/luci/systems/cluster/%s' % (CLUSTER_FOLDER_PATH, clustername)
+ nodelist = self.restrictedTraverse(cluster_path).objectItems('Folder')
+ except Exception, e:
+ luci_log.debug_verbose('GCSDB0: %s: %s' % (clustername, str(e)))
+ return results
+
+ for node in nodelist:
+ try:
+ node_val = {}
+ node_val['type'] = 'node'
+ node_val['name'] = node[0]
+ node_val['clustered'] = '[unknown]'
+ node_val['online'] = '[unknown]'
+ node_val['error'] = True
+ results.append(node_val)
+ except Exception, e:
+ luci_log.debug_verbose('GCSDB1: %s' % str(e))
+ return results
+
+def getClusterStatus(self, request, rc):
try:
doc = getClusterStatusBatch(rc)
+ if not doc:
+ raise Exception, 'doc is None'
except Exception, e:
luci_log.debug_verbose('GCS0: error: %s' % str(e))
doc = None
+ if doc is None:
+ try:
+ model = request.SESSION.get('model')
+ cinfo = getClusterStatusModel(model)
+ if not cinfo or len(cinfo) < 1:
+ raise Exception, 'cinfo is None'
+ return cinfo
+ except Exception, e:
+ luci_log.debug_verbose('GCS1: %s' % str(e))
+ doc = None
+
if not doc:
try:
- luci_log.debug_verbose('GCS1: returned None for %s/%s' % rc.cluster_info())
- except:
- pass
+ clustername = None
+ try:
+ clustername = request['clustername']
+ except:
+ try:
+ clustername = request.form['clustername']
+ except:
+ pass
- return {}
+ if not clustername:
+ raise Exception, 'unable to determine cluster name'
- results = list()
+ cinfo = getClusterStatusDB(self, clustername)
+ if not cinfo or len(cinfo) < 1:
+ raise Exception, 'cinfo is None'
+ return cinfo
+ except Exception, e:
+ luci_log.debug_verbose('GCS1a: unable to get cluster info from DB: %s' % str(e))
+ return []
+ results = list()
vals = {}
vals['type'] = "cluster"
@@ -1796,6 +2038,7 @@
itemmap['nodename'] = item['nodename']
itemmap['autostart'] = item['autostart']
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE
+ itemmap['delurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE_DELETE
svc = modelb.retrieveServiceByName(item['name'])
dom = svc.getAttribute("domain")
@@ -1847,6 +2090,7 @@
if item['name'] == servicename:
hmap['name'] = servicename
starturls = list()
+ hmap['autostart'] = item['autostart']
if item['running'] == "true":
hmap['running'] = "true"
#In this case, determine where it can run...
@@ -1855,6 +2099,8 @@
innermap['current'] = "This service is currently running on %s" % nodename
innermap['disableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_STOP
innermap['restarturl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_RESTART
+ innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+
nodes = modelb.getNodes()
for node in nodes:
starturl = {}
@@ -1901,16 +2147,18 @@
if parent is not None:
rc_map['parent'] = parent
rc_map['name'] = child.getName()
+
+ #Note: Final version needs all resource attrs
if child.isRefObject() == True:
rc_map['ref_object'] = True
rc_map['type'] = child.getObj().getResourceType()
+ rc_map['attrs'] = child.getObj().getAttributes()
else:
rc_map['type'] = child.getResourceType()
+ rc_map['attrs'] = child.getAttributes()
rc_map['indent_ctr'] = indent_ctr
- #Note: Final version needs all resource attrs
- rc_map['attrs'] = child.getAttributes()
rc_map['uuid'] = make_uuid('resource')
rc_map['parent_uuid'] = parent_uuid
@@ -2186,39 +2434,31 @@
return {}
if model is None:
- rc = getRicciAgent(self, cluname)
- if not rc:
- luci_log.debug_verbose('GCI1: unable to find a ricci agent for the %s cluster' % cluname)
- return {}
try:
- model = getModelBuilder(None, rc, rc.dom0())
+ model = getModelForCluster(self, cluname)
if not model:
raise Exception, 'model is none'
-
- try:
- req.SESSION.set('model', model)
- except Exception, e2:
- luci_log.debug_verbose('GCI2 unable to set model in session: %s' % str(e2))
+ req.SESSION.set('model', model)
except Exception, e:
- luci_log.debug_verbose('GCI3: unable to get model for cluster %s: %s' % (cluname, str(e)))
+ luci_log.debug_verbose('GCI1: unable to get model for cluster %s: %s' % (cluname, str(e)))
return {}
prop_baseurl = req['URL'] + '?' + PAGETYPE + '=' + CLUSTER_CONFIG + '&' + CLUNAME + '=' + cluname + '&'
- map = {}
+ clumap = {}
basecluster_url = prop_baseurl + PROPERTIES_TAB + "=" + PROP_GENERAL_TAB
#needed:
- map['basecluster_url'] = basecluster_url
+ clumap['basecluster_url'] = basecluster_url
#name field
- map['clustername'] = model.getClusterAlias()
+ clumap['clustername'] = model.getClusterAlias()
#config version
cp = model.getClusterPtr()
- map['config_version'] = cp.getConfigVersion()
+ clumap['config_version'] = cp.getConfigVersion()
#-------------
#new cluster params - if rhel5
#-------------
#Fence Daemon Props
fencedaemon_url = prop_baseurl + PROPERTIES_TAB + "=" + PROP_FENCE_TAB
- map['fencedaemon_url'] = fencedaemon_url
+ clumap['fencedaemon_url'] = fencedaemon_url
fdp = model.getFenceDaemonPtr()
pjd = fdp.getAttribute('post_join_delay')
if pjd is None:
@@ -2227,35 +2467,35 @@
if pfd is None:
pfd = "0"
#post join delay
- map['pjd'] = pjd
+ clumap['pjd'] = pjd
#post fail delay
- map['pfd'] = pfd
+ clumap['pfd'] = pfd
#-------------
#if multicast
multicast_url = prop_baseurl + PROPERTIES_TAB + "=" + PROP_MCAST_TAB
- map['multicast_url'] = multicast_url
+ clumap['multicast_url'] = multicast_url
#mcast addr
is_mcast = model.isMulticast()
- #map['is_mcast'] = is_mcast
+ #clumap['is_mcast'] = is_mcast
if is_mcast:
- map['mcast_addr'] = model.getMcastAddr()
- map['is_mcast'] = "True"
+ clumap['mcast_addr'] = model.getMcastAddr()
+ clumap['is_mcast'] = "True"
else:
- map['is_mcast'] = "False"
- map['mcast_addr'] = "1.2.3.4"
+ clumap['is_mcast'] = "False"
+ clumap['mcast_addr'] = "1.2.3.4"
#-------------
#quorum disk params
quorumd_url = prop_baseurl + PROPERTIES_TAB + "=" + PROP_QDISK_TAB
- map['quorumd_url'] = quorumd_url
+ clumap['quorumd_url'] = quorumd_url
is_quorumd = model.isQuorumd()
- map['is_quorumd'] = is_quorumd
- map['interval'] = ""
- map['tko'] = ""
- map['votes'] = ""
- map['min_score'] = ""
- map['device'] = ""
- map['label'] = ""
+ clumap['is_quorumd'] = is_quorumd
+ clumap['interval'] = ""
+ clumap['tko'] = ""
+ clumap['votes'] = ""
+ clumap['min_score'] = ""
+ clumap['device'] = ""
+ clumap['label'] = ""
#list struct for heuristics...
hlist = list()
@@ -2264,27 +2504,27 @@
qdp = model.getQuorumdPtr()
interval = qdp.getAttribute('interval')
if interval is not None:
- map['interval'] = interval
+ clumap['interval'] = interval
tko = qdp.getAttribute('tko')
if tko is not None:
- map['tko'] = tko
+ clumap['tko'] = tko
votes = qdp.getAttribute('votes')
if votes is not None:
- map['votes'] = votes
+ clumap['votes'] = votes
min_score = qdp.getAttribute('min_score')
if min_score is not None:
- map['min_score'] = min_score
+ clumap['min_score'] = min_score
device = qdp.getAttribute('device')
if device is not None:
- map['device'] = device
+ clumap['device'] = device
label = qdp.getAttribute('label')
if label is not None:
- map['label'] = label
+ clumap['label'] = label
heuristic_kids = qdp.getChildren()
h_ctr = 0
@@ -2313,9 +2553,9 @@
else:
hmap['hinterval'] = ""
hlist.append(hmap)
- map['hlist'] = hlist
+ clumap['hlist'] = hlist
- return map
+ return clumap
def getClustersInfo(self, status, req):
map = {}
@@ -2335,6 +2575,10 @@
if len(clulist) < 1:
return {}
clu = clulist[0]
+ cluerror = False
+ if 'error' in clu:
+ cluerror = True
+ map['error'] = True
clustername = clu['name']
if clu['alias'] != "":
map['clusteralias'] = clu['alias']
@@ -2349,6 +2593,7 @@
map['running'] = "false"
map['votes'] = clu['votes']
map['minquorum'] = clu['minQuorum']
+
map['clucfg'] = baseurl + "?" + PAGETYPE + "=" + CLUSTER_CONFIG + "&" + CLUNAME + "=" + clustername
map['restart_url'] = baseurl + "?" + PAGETYPE + "=" + CLUSTER_PROCESS + "&" + CLUNAME + "=" + clustername + '&task=' + CLUSTER_RESTART
@@ -2370,6 +2615,7 @@
map['currentservices'] = svc_dict_list
node_dict_list = list()
for item in nodelist:
+ node_error = 'error' in item
nmap = {}
name = item['name']
nmap['nodename'] = name
@@ -2872,15 +3118,16 @@
infohash['currentservices'] = svc_dict_list
- #next is faildoms
- fdoms = model.getFailoverDomainsForNode(nodename)
fdom_dict_list = list()
- for fdom in fdoms:
- fdom_dict = {}
- fdom_dict['name'] = fdom.getName()
- fdomurl = baseurl + "?" + PAGETYPE + "=" + FDOM_CONFIG + "&" + CLUNAME + "=" + clustername + "&fdomname=" + fdom.getName()
- fdom_dict['fdomurl'] = fdomurl
- fdom_dict_list.append(fdom_dict)
+ if model:
+ #next is faildoms
+ fdoms = model.getFailoverDomainsForNode(nodename)
+ for fdom in fdoms:
+ fdom_dict = {}
+ fdom_dict['name'] = fdom.getName()
+ fdomurl = baseurl + "?" + PAGETYPE + "=" + FDOM_CONFIG + "&" + CLUNAME + "=" + clustername + "&fdomname=" + fdom.getName()
+ fdom_dict['fdomurl'] = fdomurl
+ fdom_dict_list.append(fdom_dict)
infohash['fdoms'] = fdom_dict_list
@@ -2911,7 +3158,6 @@
infohash['logurl'] = '/luci/logs/?nodename=' + nodename_resolved + '&clustername=' + clustername
return infohash
- #get list of faildoms for node
def getNodesInfo(self, model, status, req):
resultlist = list()
@@ -3015,6 +3261,10 @@
return resultlist
def getFence(self, model, request):
+ if not model:
+ luci_log.debug_verbose('getFence0: model is None')
+ return {}
+
map = {}
fencename = request['fencename']
fencedevs = model.getFenceDevices()
@@ -3061,6 +3311,10 @@
raise
def getFenceInfo(self, model, request):
+ if not model:
+ luci_log.debug_verbose('getFenceInfo00: model is None')
+ return {}
+
try:
clustername = request['clustername']
except:
@@ -3311,9 +3565,14 @@
return map
def getFencesInfo(self, model, request):
+ map = {}
+ if not model:
+ luci_log.debug_verbose('getFencesInfo0: model is None')
+ map['fencedevs'] = list()
+ return map
+
clustername = request['clustername']
baseurl = request['URL']
- map = {}
fencedevs = list() #This is for the fencedev list page
#Get list of fence devices
@@ -3798,6 +4057,7 @@
for item in modelb.getResources():
itemmap = {}
itemmap['name'] = item.getName()
+ itemmap['attrs'] = item.attr_hash
itemmap['type'] = item.resource_type
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&resourcename=" + item.getName() + "&pagetype=" + RESOURCE_CONFIG
itemmap['url'] = baseurl + "?" + "clustername=" + cluname + "&resourcename=" + item.getName() + "&pagetype=" + RESOURCE
@@ -3859,6 +4119,82 @@
except:
continue
+def delService(self, request):
+ errstr = 'An error occurred while attempting to set the new cluster.conf'
+
+ try:
+ modelb = request.SESSION.get('model')
+ except Exception, e:
+ luci_log.debug_verbose('delService0: no model: %s' % str(e))
+ return (False, {'errors': [ errstr ] })
+
+ name = None
+ try:
+ name = request['servicename']
+ except:
+ try:
+ name = request.form['servicename']
+ except:
+ pass
+
+ if name is None:
+ luci_log.debug_verbose('delService1: no service name')
+ return (False, {'errors': [ '%s: no service name was provided.' % errstr ]})
+
+ clustername = None
+ try:
+ clustername = request['clustername']
+ except:
+ try:
+ clustername = request.form['clustername']
+ except:
+ pass
+
+ if clustername is None:
+ luci_log.debug_verbose('delService2: no cluster name for %s' % name)
+ return (False, {'errors': [ '%s: no cluster name was provided.' % errstr ]})
+
+ rc = getRicciAgent(self, clustername)
+ if not rc:
+ luci_log.debug_verbose('delService3: unable to get ricci agent for cluster %s' % clustername)
+ return (False, {'errors': [ '%s: unable to find a Ricci agent for this cluster.' % errstr ]})
+
+ try:
+ ragent = rc.hostname()
+ if not ragent:
+ raise Exception, 'unable to determine the hostname of the ricci agent'
+ except Exception, e:
+ luci_log.debug_verbose('delService4: %s: %s' % (errstr, str(e)))
+ return (False, {'errors': [ '%s: unable to find a Ricci agent for this cluster.' % errstr ]})
+
+ try:
+ modelb.deleteService(name)
+ except Exception, e:
+ luci_log.debug_verbose('delService5: Unable to find a service named %s for cluster %s' % (name, clustername))
+ return (False, {'errors': [ '%s: error removing service %s.' % (errstr, name) ]})
+
+ try:
+ conf = modelb.exportModelAsString()
+ if not conf:
+ raise Exception, 'model string is blank'
+ except Exception, e:
+ luci_log.debug_verbose('delService6: exportModelAsString failed: %s' \
+ % str(e))
+ return (False, {'errors': [ '%s: error removing service %s.' % (errstr, name) ]})
+
+ batch_number, result = setClusterConf(rc, str(conf))
+ if batch_number is None or result is None:
+ luci_log.debug_verbose('delService7: missing batch and/or result')
+ return (False, {'errors': [ '%s: error removing service %s.' % (errstr, name) ]})
+
+ try:
+ set_node_flag(self, clustername, ragent, str(batch_number), SERVICE_DELETE, "Removing service \'%s\'" % name)
+ except Exception, e:
+ luci_log.debug_verbose('delService8: failed to set flags: %s' % str(e))
+
+ response = request.RESPONSE
+ response.redirect(request['URL'] + "?pagetype=" + SERVICES + "&clustername=" + clustername + '&busyfirst=true')
+
def delResource(self, rc, request):
errstr = 'An error occurred while attempting to set the new cluster.conf'
@@ -4516,7 +4852,7 @@
'gfs': addGfs,
'nfsm': addNfsm,
'nfsx': addNfsx,
- 'nfsc': addNfsx,
+ 'nfsc': addNfsc,
'scr': addScr,
'smb': addSmb
}
@@ -4651,6 +4987,17 @@
response = request.RESPONSE
response.redirect(request['URL'] + "?pagetype=" + RESOURCES + "&clustername=" + clustername + '&busyfirst=true')
+def getResource(modelb, name):
+ resPtr = modelb.getResourcesPtr()
+ resources = resPtr.getChildren()
+
+ for res in resources:
+ if res.getName() == name:
+ return res
+
+ luci_log.debug_verbose('getResource: unable to find resource \"%s\"' % name)
+ raise KeyError, name
+
def getResourceForEdit(modelb, name):
resPtr = modelb.getResourcesPtr()
resources = resPtr.getChildren()
@@ -4660,7 +5007,7 @@
resPtr.removeChild(res)
return res
- luci_log.debug_verbose('unable to find resource \"%s\"' % name)
+ luci_log.debug_verbose('GRFE0: unable to find resource \"%s\"' % name)
raise KeyError, name
def appendModel(request, model):
--- conga/luci/site/luci/Extensions/conga_constants.py 2006/11/16 19:34:53 1.19.2.2
+++ conga/luci/site/luci/Extensions/conga_constants.py 2006/12/07 17:54:31 1.19.2.3
@@ -43,6 +43,7 @@
FENCEDEV_CONFIG="53"
FENCEDEV="54"
CLUSTER_DAEMON="55"
+SERVICE_DELETE = '56'
#Cluster tasks
CLUSTER_STOP = '1000'
@@ -119,7 +120,7 @@
PRE_JOIN = "Packages are installed and configuration has been distributed, but the node has not yet joined the cluster."
-POSSIBLE_REBOOT_MESSAGE = "This node is not currently responding and is probably<br/>rebooting as planned. This state should persist for 5 minutes or so..."
+POSSIBLE_REBOOT_MESSAGE = "This node is not currently responding and is probably rebooting as planned. This state should persist for 5 minutes or so..."
REDIRECT_MSG = " You will be redirected in 5 seconds. Please fasten your safety restraints."
--- conga/luci/site/luci/Extensions/ricci_bridge.py 2006/11/20 23:36:12 1.30.2.10
+++ conga/luci/site/luci/Extensions/ricci_bridge.py 2006/12/07 17:54:31 1.30.2.11
@@ -63,7 +63,7 @@
batch += '</function_call>'
batch += '</request>'
batch += '</module>'
-
+
need_reboot = install_base or install_services or install_shared_storage or install_LVS
if need_reboot:
batch += '<module name="service">'
@@ -96,7 +96,7 @@
batch += '<function_call name="install"/>'
batch += '</request>'
batch += '</module>'
-
+
batch += '<module name="cluster">'
batch += '<request API_version="1.0">'
batch += '<function_call name="set_cluster.conf">'
@@ -236,7 +236,7 @@
batch += '<cman expected_votes="1" two_node="1"/>'
else:
batch += '<cman/>'
-
+
batch += '<fencedevices/>'
batch += '<rm/>'
batch += '</cluster>'
@@ -298,66 +298,39 @@
pass
return (None, None)
-
-def getPayload(bt_node):
- if not bt_node:
- return None
-
- mod_node = None
- for node in bt_node.childNodes:
- if node.nodeType == xml.dom.Node.ELEMENT_NODE and node.nodeName == 'module':
- mod_node = node
- if not mod_node:
- return None
-
- resp_node = None
- for node in mod_node.childNodes:
- if node.nodeType == xml.dom.Node.ELEMENT_NODE:
- resp_node = node
- if not resp_node:
- return None
+def getClusterStatusBatch(rc):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="status"/></request></module>'
+ ricci_xml = rc.batch_run(batch_str, async=False)
- fr_node = None
- for node in resp_node.childNodes:
- if node.nodeType == xml.dom.Node.ELEMENT_NODE:
- fr_node = node
- if not fr_node:
+ try:
+ cluster_tags = ricci_xml.getElementsByTagName('cluster')
+ except Exception, e:
+ luci_log.debug_verbose('getClusterStatusBatch0: %s' % str(e))
return None
- varnode = None
- for node in fr_node.childNodes:
- if node.nodeName == 'var':
- varnode = node
- break
- if not varnode:
- return None
+ if len(cluster_tags) < 1:
+ luci_log.debug_verbose('getClusterStatusBatch1: %d entries - expecting 1' \
+ % len(cluster_tags))
+ elif len(cluster_tags) > 1:
+ luci_log.debug_verbose('getClusterStatusBatch2: %d entries - expecting 1, using the first' % len(cluster_tags))
- cl_node = None
- for node in varnode.childNodes:
- if node.nodeName == 'cluster':
- cl_node = node
- break
- if not cl_node:
+ try:
+ cluster_node = cluster_tags[0]
+ if not cluster_node:
+ raise Exception, 'element 0 is None'
+ except Exception, e:
+ luci_log.debug_verbose('getClusterStatusBatch3: %s' % str(e))
return None
- doc = minidom.Document()
- doc.appendChild(cl_node)
- return doc
-
-def getClusterStatusBatch(rc):
- batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="status"/></request></module>'
- ricci_xml = rc.batch_run(batch_str, async=False)
-
- if not ricci_xml or not ricci_xml.firstChild:
- luci_log.debug_verbose('ricci_xml is None from batch_run')
-
- doc = getPayload(ricci_xml.firstChild)
- if not doc or not doc.firstChild:
- luci_log.debug_verbose('doc is None from getPayload: %s' % ricci_xml.toxml())
- return None
+ try:
+ doc = minidom.Document()
+ doc.appendChild(cluster_node)
+ return doc
+ except Exception, e:
+ luci_log.debug_verbose('getClusterStatusBatch4: %s' % str(e))
- return doc
+ return None
def setClusterConf(rc, clusterconf, propagate=True):
if propagate == True:
@@ -490,7 +463,7 @@
return None, None
ricci_xml = rc.batch_run(batch)
return batchAttemptResult(ricci_xml)
-
+
def restartService(rc, servicename):
batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="restart_service"><var mutable="false" name="servicename" type="string" value=\"' + servicename + '\"/></function_call></request></module>'
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2006-12-21 21:26 kupcevic
0 siblings, 0 replies; 10+ messages in thread
From: kupcevic @ 2006-12-21 21:26 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: kupcevic at sourceware.org 2006-12-21 21:26:20
Modified files:
luci/cluster : form-chooser form-macros
luci/site/luci/Extensions: cluster_adapters.py
conga_constants.py
Log message:
luci: cluster.conf editor
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.14&r2=1.15
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.136&r2=1.137
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.191&r2=1.192
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&r1=1.31&r2=1.32
--- conga/luci/cluster/form-chooser 2006/12/06 18:38:53 1.14
+++ conga/luci/cluster/form-chooser 2006/12/21 21:26:20 1.15
@@ -152,6 +152,11 @@
<span tal:omit-tag="" tal:condition="python: ptype == '55'">
<div metal:use-macro="here/form-macros/macros/fencedevprocess-form"/>
</span>
+
+ <span tal:omit-tag="" tal:condition="python: ptype == '80'">
+ <div metal:use-macro="here/form-macros/macros/conf_editor-form"/>
+ </span>
+
</span>
</metal:choose-form>
</body>
--- conga/luci/cluster/form-macros 2006/12/21 05:08:48 1.136
+++ conga/luci/cluster/form-macros 2006/12/21 21:26:20 1.137
@@ -825,7 +825,8 @@
<tbody class="systemsTable">
<tr class="systemsTable">
- <td class="systemsTable">Post Fail Delay</td>
+ <td class="systemsTable">Post Fail <span tal:attributes="onclick python:'window.location.assign(\'./?pagetype=80&clustername=' + request['clustername'] + '\')'">Delay</span>
+ </td>
<td class="systemsTable">
<input type="text" name="post_fail_delay"
tal:attributes="value clusterinfo/pfd" />
@@ -3871,6 +3872,28 @@
<h2>Fence Device Process Form</h2>
</div>
+<div metal:define-macro="conf_editor-form">
+ <h2>Edit cluster.conf</h2>
+ <form method="post"
+ tal:attributes="action python: './?' + request['QUERY_STRING']"
+ tal:define="ret python: here.process_cluster_conf_editor(request)">
+ <span tal:content="structure python: ret['msg'].replace('\n', '<br/>')"/>
+ <textarea name="new_cluster_conf"
+ rows="80"
+ tal:content="structure ret/cluster_conf"></textarea>
+ <input tal:attributes="type string:hidden;
+ name string:pagetype;
+ value python:request['pagetype']"/>
+ <input tal:attributes="type string:hidden;
+ name string:clustername;
+ value python:request['clustername']"/>
+ <input type="button"
+ value="Reset"
+ tal:attributes="onclick python:'window.location.assign(\'./?pagetype=' + request['pagetype'] + '&clustername=' + request['clustername'] + '\')'"/>
+ <input type="submit" value="Propagate"/>
+ </form>
+</div>
+
</body>
</html>
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2006/12/21 05:08:49 1.191
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2006/12/21 21:26:20 1.192
@@ -5799,3 +5799,68 @@
% (batch_id, task, desc, objpath, str(e))
luci_log.debug_verbose(errmsg)
raise Exception, errmsg
+
+
+
+
+
+
+
+
+
+
+
+def process_cluster_conf_editor(self, req):
+ clustername = req['clustername']
+ msg = '\n'
+ cc = ''
+ if 'new_cluster_conf' in req:
+ cc = req['new_cluster_conf']
+ msg += 'Checking if valid XML - '
+ cc_xml = None
+ try:
+ cc_xml = minidom.parseString(cc)
+ except:
+ pass
+ if cc_xml == None:
+ msg += 'FAILED\n'
+ msg += 'Fix the error and try again:\n'
+ else:
+ msg += 'PASSED\n'
+
+ msg += 'Making sure no clustername change has accured - '
+ new_name = cc_xml.firstChild.getAttribute('name')
+ if new_name != clustername:
+ msg += 'FAILED\n'
+ msg += 'Fix the error and try again:\n'
+ else:
+ msg += 'PASSED\n'
+
+ msg += 'Increasing cluster version number - '
+ version = cc_xml.firstChild.getAttribute('config_version')
+ version = int(version) + 1
+ cc_xml.firstChild.setAttribute('config_version', str(version))
+ msg += 'DONE\n'
+
+ msg += 'Propagating new cluster.conf'
+ rc = getRicciAgent(self, clustername)
+ if not rc:
+ luci_log.debug_verbose('VFA: unable to find a ricci agent for the %s cluster' % clustername)
+ msg += '\nUnable to contact a ricci agent for cluster ' + clustername + '\n\n'
+ else:
+ batch_id, result = setClusterConf(rc, cc_xml.toxml())
+ if batch_id is None or result is None:
+ luci_log.debug_verbose('VFA: setClusterConf: batchid or result is None')
+ msg += '\nUnable to propagate the new cluster configuration for ' + clustername + '\n\n'
+ else:
+ msg += ' - DONE\n'
+ cc = cc_xml.toxml()
+ msg += '\n\nALL DONE\n\n'
+ else:
+ if getClusterInfo(self, None, req) == {}:
+ msg = 'invalid cluster'
+ else:
+ model = req.SESSION.get('model')
+ cc = model.exportModelAsString()
+ return {'msg' : msg,
+ 'cluster_conf' : cc}
--- conga/luci/site/luci/Extensions/conga_constants.py 2006/12/21 03:42:49 1.31
+++ conga/luci/site/luci/Extensions/conga_constants.py 2006/12/21 21:26:20 1.32
@@ -46,6 +46,8 @@
SERVICE_DELETE = '56'
FENCEDEV_DELETE = "57"
+CONF_EDITOR = '80'
+
#Cluster tasks
CLUSTER_STOP = '1000'
CLUSTER_START = '1001'
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2007-02-23 22:07 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2007-02-23 22:07 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2007-02-23 22:07:45
Modified files:
luci/cluster : form-chooser form-macros
luci/homebase : luci_homebase.css
luci/site/luci/Extensions: cluster_adapters.py
conga_constants.py ricci_bridge.py
Added files:
luci/cluster : validate_sys_svc.js
luci/plone-custom: conga_ajax.js svc_reload.png
svc_reload_active.png svc_reload_disabled.png
svc_start.png svc_start_active.png
svc_start_disabled.png svc_stop.png
svc_stop_active.png svc_stop_disabled.png
luci/site/luci/Extensions: system_adapters.py
Log message:
- System service management interface (chkconfig / service start/stop/restart)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_sys_svc.js.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.192&r2=1.193
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/luci_homebase.css.diff?cvsroot=cluster&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/conga_ajax.js.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_reload.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_reload_active.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_reload_disabled.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_start.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_start_active.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_start_disabled.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_stop.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_stop_active.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_stop_disabled.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/system_adapters.py.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.243&r2=1.244
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&r1=1.36&r2=1.37
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&r1=1.58&r2=1.59
/cvs/cluster/conga/luci/cluster/validate_sys_svc.js,v --> standard output
revision 1.1
--- conga/luci/cluster/validate_sys_svc.js
+++ - 2007-02-23 22:07:45.984856000 +0000
@@ -0,0 +1,22 @@
+function svc_callback() {
+ if (xmlHttp_object.readyState == 4) {
+ if (xmlHttp_object.status == 200) {
+ var response = xmlHttp_object.responseXML;
+ if (response) {
+ req_status = response.getAttribute('success');
+ req_op = response.getAttribute('operation');
+ req_svc = response.getAttribute('service');
+ req_msg = response.getAttribute('message');
+ //alert(req_msg + ' / ' + req_status + ' / ' + req_op + ' / ' + req_svc);
+ } else {
+ alert(xmlHttp_object.responseText);
+ }
+ } else {
+ //alert('Error retrieving data from server: ' + xmlHttp_object.status);
+ }
+ }
+}
+
+function update_sys_svc(url) {
+ initiate_async_get(url, svc_callback);
+}
--- conga/luci/cluster/form-chooser 2007/02/01 20:27:33 1.16
+++ conga/luci/cluster/form-chooser 2007/02/23 22:07:45 1.17
@@ -149,11 +149,15 @@
<span tal:omit-tag="" tal:condition="python: ptype == '55'">
<div metal:use-macro="here/form-macros/macros/fencedevprocess-form"/>
</span>
-
<span tal:omit-tag="" tal:condition="python: ptype == '80'">
<div metal:use-macro="here/form-macros/macros/conf_editor-form"/>
</span>
-
+ <span tal:omit-tag="" tal:condition="python: ptype == '90'">
+ <div metal:use-macro="here/form-macros/macros/system-svc-form"/>
+ </span>
+ <span tal:omit-tag="" tal:condition="python: ptype == '91'">
+ <div metal:use-macro="here/form-macros/macros/system-svc-update-form"/>
+ </span>
</span>
</metal:choose-form>
</body>
--- conga/luci/cluster/form-macros 2007/02/20 23:06:59 1.192
+++ conga/luci/cluster/form-macros 2007/02/23 22:07:45 1.193
@@ -5022,10 +5022,110 @@
</div>
</div>
+
<div metal:define-macro="fencedevprocess-form">
<h2>Fence Device Process Form</h2>
</div>
+<div metal:define-macro="system-svc-form">
+ <script type="text/javascript"
+ src="conga_ajax.js">
+ </script>
+ <script type="text/javascript"
+ src="/luci/cluster/validate_sys_svc.js">
+ </script>
+ <h2>Configure System Services</h2>
+
+ <form name="svcform" method="post" action="">
+
+ <input type="hidden" name="pagetype"
+ tal:attributes="value request/pagetype | nothing" />
+
+ <input type="hidden" name="systemname"
+ tal:attributes="value request/systemname | nothing" />
+
+ <table class="systemsTable"
+ tal:define="svcinfo python:'systemname' in request and here.get_sys_svc_list(request, request['systemname']) or []">
+ <tr class="systemsTable">
+ <th class="systemsTable">Name</th>
+ <th class="systemsTable">State</th>
+ <th class="systemsTable">Enabled at boot</th>
+ <th></th>
+ </tr>
+
+ <tr tal:repeat="s svcinfo">
+ <td class="systemsTable">
+ <span tal:content="s/name |string:[unknown]"
+ tal:attributes="title s/desc | nothing" />
+ </td>
+
+ <td class="systemsTable">
+ <span
+ tal:content="s/state |string:[unknown]"
+ tal:attributes="id python: '__STATUS__:' + s['name']" />
+ </td>
+
+ <td class="systemsTable">
+ <input type="checkbox"
+ tal:attributes="
+ name s/name;
+ id s/name;
+ checked python: s['enabled'] and 'checked' or ''"
+ />
+ </td>
+
+ <td class="systemsTable"
+ tal:define="
+ restart_disabled python:not s['running'] and 'disabled' or '';
+ start_disabled python:s['running'] and 'disabled' or '';
+ stop_disabled python:not s['running'] and 'disabled' or ''">
+
+ <input type="button"
+ title="start this service"
+ class="svc_control svc_control_start"
+ onfocus="if (this.blur) this.blur()"
+ tal:attributes="
+ onclick python: 'update_sys_svc(\'' + s['starturl'] + '\')';
+ id python: '__START__' + s['name'];
+ name python: '__START__' + s['name'];
+ disabled start_disabled" />
+
+ <input type="button"
+ title="restart this service"
+ class="svc_control svc_control_restart"
+ onfocus="if (this.blur) this.blur()"
+ tal:attributes="
+ onclick python: 'update_sys_svc(\'' + s['restarturl'] + '\')';
+ id python: '__RESTART__' + s['name'];
+ name python: '__RESTART__' + s['name'];
+ disabled restart_disabled" />
+
+ <input type="button"
+ title="stop this service"
+ class="svc_control svc_control_stop"
+ onfocus="if (this.blur) this.blur()"
+ tal:attributes="
+ onclick python: 'update_sys_svc(\'' + s['stopurl'] + '\')';
+ id python: '__STOP__' + s['name'];
+ name python: '__STOP__' + s['name'];
+ disabled stop_disabled" />
+ </td>
+ </tr>
+ <tr class="systemsTable">
+ <td>
+ <div class="hbSubmit">
+ <input type="submit" value="Update" />
+ </div>
+ </td>
+ </tr>
+ </table>
+ </form>
+</div>
+
+<div metal:define-macro="system-svc-update-form">
+ <tal:block tal:define="ret python: here.validate_manage_svc(request)" />
+</div>
+
<div metal:define-macro="conf_editor-form">
<h2>Edit cluster.conf</h2>
<form method="post"
--- conga/luci/homebase/luci_homebase.css 2007/02/08 05:05:22 1.39
+++ conga/luci/homebase/luci_homebase.css 2007/02/23 22:07:45 1.40
@@ -8,6 +8,60 @@
font-size: 12px;
}
+input[type=image] {
+ border: 0;
+ background: transparent;
+ padding-left: +.3333em;
+ padding-right: +.3333em;
+}
+
+input[type=image]:disabled {
+ cursor: url('cursor-disabled.png'), default;
+}
+
+input.svc_control {
+ color: transparent ! important;
+ border: none ! important;
+ outline: hidden ! important;
+ background-color: transparent ! important;
+ background-repeat: no-repeat ! important;
+ cursor: pointer;
+}
+
+.svc_control_start {
+ background-image: url(svc_start.png);
+}
+
+input.svc_control_start:hover, input.svc_control_start:active {
+ background-image: url(svc_start_active.png) ! important;
+}
+input.svc_control_start:disabled {
+ background-image: url(svc_start_disabled.png) ! important;
+ cursor: url('cursor-disabled.png'), default;
+}
+
+input.svc_control_restart {
+ background-image: url(svc_reload.png);
+}
+input.svc_control_restart:hover, input.svc_control_restart:active {
+ background-image: url(svc_reload_active.png) ! important;
+}
+input.svc_control_restart:disabled {
+ background-image: url(svc_reload_disabled.png) ! important;
+ cursor: url('cursor-disabled.png'), default;
+}
+
+input.svc_control_stop {
+ background-image: url(svc_stop.png);
+}
+input.svc_control_stop:hover, input.svc_control_stop:active {
+ background-image: url(svc_stop_active.png) ! important;
+}
+input.svc_control_stop:disabled {
+ background-image: url(svc_stop_disabled.png) ! important;
+ cursor: url('cursor-disabled.png'), default;
+}
+
input[type=checkbox], input[type=radio] {
float: left ! important;
vertical-align: middle;
/cvs/cluster/conga/luci/plone-custom/conga_ajax.js,v --> standard output
revision 1.1
--- conga/luci/plone-custom/conga_ajax.js
+++ - 2007-02-23 22:07:46.355394000 +0000
@@ -0,0 +1,29 @@
+var xmlHttp_object = false;
+
+function initiate_async_get(url, callback_function) {
+ xmlHttp_object = false;
+
+ if (!xmlHttp_object && typeof XMLHttpRequest != 'undefined') {
+ try {
+ xmlHttp_object = new XMLHttpRequest();
+ } catch (e0) {
+ try {
+ xmlHttp_object = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ xmlHttp_object = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (e2) {
+ xmlHttp_object = false;
+ }
+ }
+ }
+ }
+
+ if (xmlHttp_object) {
+ xmlHttp_object.open("GET", url, true);
+ xmlHttp_object.onreadystatechange = callback_function;
+ xmlHttp_object.send(null);
+ } else {
+ alert("Unable to communicate with the luci server.");
+ }
+}
/cvs/cluster/conga/luci/plone-custom/svc_reload.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_reload.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_reload_active.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_reload_active.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_reload_disabled.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_reload_disabled.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_start.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_start.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_start_active.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_start_active.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_start_disabled.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_start_disabled.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_stop.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_stop.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_stop_active.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_stop_active.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_stop_disabled.png,v --> standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_stop_disabled.png and - differ
/cvs/cluster/conga/luci/site/luci/Extensions/system_adapters.py,v --> standard output
revision 1.1
--- conga/luci/site/luci/Extensions/system_adapters.py
+++ - 2007-02-23 22:07:47.286199000 +0000
@@ -0,0 +1,134 @@
+from ricci_communicator import RicciCommunicator
+from ricci_bridge import list_services, updateServices, svc_manage
+from LuciSyslog import LuciSyslog
+
+try:
+ luci_log = LuciSyslog()
+except:
+ pass
+
+def get_sys_svc_list(self, request, hostname):
+ try:
+ rc = RicciCommunicator(hostname)
+ if not rc:
+ raise Exception, 'None'
+ except Exception, e:
+ luci_log.debug_verbose('GSSL0: %s: %s' % (hostname, str(e)))
+ return []
+
+ service_list = list_services(rc)
+ if not service_list:
+ return []
+
+ svc_ret = list()
+ for i in service_list:
+ s = {}
+ try:
+ name = str(i.getAttribute('name'))
+ except:
+ name = None
+ s['name'] = name
+
+ try:
+ desc = i.getAttribute('description')
+ except:
+ desc = None
+ s['desc'] = desc
+
+ try:
+ enabled = i.getAttribute('enabled').lower()
+ if enabled == 'true':
+ s['enabled'] = True
+ else:
+ raise Exception, 'not enabled'
+ except:
+ s['enabled'] = False
+
+ try:
+ running = i.getAttribute('running').lower()
+ if running == 'true':
+ s['running'] = True
+ s['state'] = 'Running'
+ else:
+ raise Exception, 'not running'
+ except Exception, e:
+ s['running'] = False
+ s['state'] = 'Stopped'
+
+ s['starturl'] = '%s?pagetype=91&svcname=%s&systemname=%s&operation=start' % (request['URL'], s['name'], hostname)
+ s['stopurl'] = '%s?pagetype=91&svcname=%s&systemname=%s&operation=stop' % (request['URL'], s['name'], hostname)
+ s['restarturl'] = '%s?pagetype=91&svcname=%s&systemname=%s&operation=restart' % (request['URL'], s['name'], hostname)
+ svc_ret.append(s)
+
+ return svc_ret
+
+def validate_svc_update(self, request):
+ try:
+ form = request.form
+ hostname = form['systemname'].strip()
+ if not hostname:
+ raise Exception, 'blank'
+ except Exception, e:
+ return (False, {'errors': [ 'No system name was given.' ]})
+
+ try:
+ rc = RicciCommunicator(hostname)
+ if not rc:
+ raise Exception, 'unknown error'
+ except Exception, e:
+ luci_log.debug_verbose('VSU0: %s: %s' % (hostname, str(e)))
+ return (False, {'errors': [ 'Unable to connect to the ricci agent on %s: %s' % (hostname, str(e)) ]})
+
+ sys_svc_list = list()
+ sys_svc_hash = dict()
+
+ try:
+ for i in list_services(rc):
+ svc_name = str(i.getAttribute('name'))
+ sys_svc_hash[svc_name] = i
+ sys_svc_list.append(svc_name)
+ except Exception, e:
+ luci_log.debug_verbose('VSU1: %s: %s' % (hostname, str(e)))
+ return (False, {'errors': [ 'Unable to retrieve the list of services from %s' % hostname ]})
+
+ try:
+ del form['pagetype']
+ del form['systemname']
+ except:
+ pass
+
+ disable_list = filter(lambda x: not form.has_key(x) and sys_svc_hash[x].getAttribute('enabled').lower() == 'true', sys_svc_list)
+ enable_list = filter(lambda x: form.has_key(x) and sys_svc_hash[x].getAttribute('enabled').lower() != 'true', sys_svc_list)
+
+ updateServices(rc, enable_list, disable_list)
+ request.RESPONSE.redirect(request['URL'] + '?pagetype=90&systemname=' + hostname)
+
+def validate_manage_svc(self, request):
+ try:
+ hostname = request['systemname'].strip()
+ except:
+ return None
+
+ servicename = None
+ op = None
+ try:
+ servicename = request['svcname'].strip()
+ op = request['operation'].strip()
+ except:
+ pass
+
+ try:
+ rc = RicciCommunicator(hostname)
+ if not rc:
+ raise Exception, 'none'
+ except Exception, e:
+ return None
+
+ ret = None
+ try:
+ ret = svc_manage(rc, hostname, servicename, op)
+ luci_log.debug_verbose('VMC0: returning %s' % str(ret.toxml()))
+ except:
+ pass
+
+ return ret
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2007/02/22 20:52:51 1.243
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2007/02/23 22:07:45 1.244
@@ -41,6 +41,7 @@
from GeneralError import GeneralError
from homebase_adapters import manageCluster, createClusterSystems, havePermCreateCluster, setNodeFlag, delNodeFlag, userAuthenticated, getStorageNode, getClusterNode, delCluster, parseHostForm
from LuciSyslog import LuciSyslog
+from system_adapters import validate_svc_update
#Policy for showing the cluster chooser menu:
#1) If there are no clusters in the ManagedClusterSystems
@@ -2453,7 +2454,8 @@
54: validateFenceEdit,
55: validateDaemonProperties,
57: deleteFenceDevice,
- 58: validateNodeFenceConfig
+ 58: validateNodeFenceConfig,
+ 90: validate_svc_update
}
def validatePost(self, request):
--- conga/luci/site/luci/Extensions/conga_constants.py 2007/02/01 20:49:08 1.36
+++ conga/luci/site/luci/Extensions/conga_constants.py 2007/02/23 22:07:45 1.37
@@ -48,6 +48,8 @@
FENCEDEV_NODE_CONFIG = '58'
CONF_EDITOR = '80'
+SYS_SERVICE_MANAGE = '90'
+SYS_SERVICE_UPDATE = '91'
#Cluster tasks
CLUSTER_STOP = '1000'
--- conga/luci/site/luci/Extensions/ricci_bridge.py 2007/02/22 20:52:51 1.58
+++ conga/luci/site/luci/Extensions/ricci_bridge.py 2007/02/23 22:07:45 1.59
@@ -486,6 +486,70 @@
ricci_xml = rc.batch_run(batch_str)
return batchAttemptResult(ricci_xml)
+def svc_manage(rc, hostname, servicename, op):
+ svc_func = None
+
+ doc = minidom.Document()
+ elem = doc.createElement('result')
+
+ if not servicename:
+ elem.setAttribute('service', 'No service name was specified.')
+ elem.setAttribute('message', 'No service name was specified.')
+ elem.setAttribute('success', '0')
+
+ if not op:
+ elem.setAttribute('operation', 'No operation was specified.')
+ elem.setAttribute('message', 'No operation was specified.')
+ elem.setAttribute('success', '0')
+
+ if not servicename or not op:
+ doc.appendChild(elem)
+ return doc
+
+ elem.setAttribute('service', servicename)
+ elem.setAttribute('operation', op)
+ elem.setAttribute('hostname', hostname)
+
+ try:
+ op = op.strip().lower()
+ if op == 'restart' or op == 'start' or op == 'stop':
+ svc_func = op
+ else:
+ raise Exception, op
+ except Exception, e:
+ elem.setAttribute('success', '0');
+ elem.setAttribute('message', 'Unknown operation')
+ doc.appendChild(elem)
+ return doc
+
+ batch_str = '<module name="service"><request API_version="1.0"><function_call name="%s"><var mutable="false" name="services" type="list_xml"><service name="%s"/></var></function_call></request></module>' % (svc_func, servicename)
+
+ ricci_xml = rc.batch_run(batch_str, async=False)
+ if not ricci_xml or not ricci_xml.firstChild:
+ luci_log.debug_verbose('SVCM0: None returned')
+ elem.setAttribute('success', '0')
+ elem.setAttribute('message', 'operation failed')
+ doc.appendChild(elem)
+ return doc
+
+ elem.setAttribute('success', '0')
+ elem.setAttribute('message', str(ricci_xml.toxml()))
+ doc.appendChild(elem)
+ return doc
+
+def list_services(rc):
+ batch_str = '<module name="service"><request API_version="1.0"><function_call name="list"><var mutable="false" name="description" type="boolean" value="true"/></function_call></request></module>'
+ ricci_xml = rc.batch_run(batch_str, async=False)
+ if not ricci_xml or not ricci_xml.firstChild:
+ luci_log.debug_verbose('LS0: None returned')
+ return None
+ try:
+ service_tags = ricci_xml.getElementsByTagName('service')
+ return service_tags
+ except Exception, e:
+ luci_log.debug_verbose('LS1: %s' % str(e))
+ return None
+
def nodeIsVirtual(rc):
batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="virt_guest"/></request></module>'
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2007-03-12 4:22 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2007-03-12 4:22 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Branch: RHEL5
Changes by: rmccabe at sourceware.org 2007-03-12 04:22:26
Modified files:
luci/cluster : form-chooser form-macros
luci/site/luci/Extensions: cluster_adapters.py
conga_constants.py ricci_bridge.py
Log message:
Frontend support for virtual service live migration
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.12.2.4&r2=1.12.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.90.2.20&r2=1.90.2.21
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.120.2.23&r2=1.120.2.24
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.19.2.8&r2=1.19.2.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.30.2.18&r2=1.30.2.19
--- conga/luci/cluster/form-chooser 2007/03/01 00:31:08 1.12.2.4
+++ conga/luci/cluster/form-chooser 2007/03/12 04:22:25 1.12.2.5
@@ -92,6 +92,9 @@
<span tal:omit-tag="" tal:condition="python: ptype == '28'">
<div metal:use-macro="here/form-macros/macros/servicerestart"/>
</span>
+ <span tal:omit-tag="" tal:condition="python: ptype == '59'">
+ <div metal:use-macro="here/form-macros/macros/servicemigrate"/>
+ </span>
<span tal:omit-tag="" tal:condition="python: ptype == '30'">
<div metal:use-macro="here/resource-form-macros/macros/resources-form"/>
</span>
--- conga/luci/cluster/form-macros 2007/03/05 16:50:09 1.90.2.20
+++ conga/luci/cluster/form-macros 2007/03/12 04:22:25 1.90.2.21
@@ -3876,12 +3876,12 @@
<tr class="cluster service info_top">
<td class="cluster service service_name">
- <strong class="cluster service">Service Name:</strong>
+ <strong class="cluster service">Service Name</strong>
<a tal:attributes="
href svc/cfgurl;
class python: 'cluster service ' + (running and 'running' or 'stopped')"
tal:content="svc/name" />
- <tal:block tal:condition="exists:svc/virt">
+ <tal:block tal:condition="exists:svc/is_vm">
(virtual service)
</tal:block>
</td>
@@ -3898,7 +3898,7 @@
<option
tal:condition="running"
- tal:attributes="value svc/retstarturl| nothing"
+ tal:attributes="value svc/restarturl | nothing"
tal:content="string:Restart this service" />
<option
@@ -3909,14 +3909,40 @@
<option
tal:condition="not: running"
tal:attributes="value svc/enableurl | nothing"
- tal:content="string:Start this service" />
+ tal:content="string:Enable this service" />
<option
tal:condition="not: running"
tal:attributes="value svc/delurl | nothing"
tal:content="string:Delete this service" />
+
<option value="">----------</option>
- <option tal:repeat="starturl svc/links" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+ <tal:block tal:condition="not: running">
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
+
+ <tal:block tal:condition="running">
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+
+ <tal:block tal:condition="svc/is_vm | nothing">
+ <option value="">----------</option>
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="exists: starturl/migrate"
+ tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
+ </tal:block>
+
</select>
<input type="button" value="Go"
onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
@@ -4227,10 +4253,19 @@
<tal:block tal:define="
result python: here.serviceStart(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
+<div metal:define-macro="servicemigrate">
+ <script type="text/javascript">
+ set_page_title('Luci ??? cluster ??? services ??? Migrate a virtual service');
+ </script>
+
+ <tal:block tal:define="
+ global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
+
+ <tal:block tal:define="
+ result python: here.serviceMigrate(ricci_agent, request)" />
+</div>
<div metal:define-macro="servicerestart">
<script type="text/javascript">
@@ -4242,8 +4277,6 @@
<tal:block tal:define="
result python: here.serviceRestart(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
<div metal:define-macro="servicestop">
@@ -4256,8 +4289,6 @@
<span tal:define="
result python: here.serviceStop(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
<div metal:define-macro="serviceconfig-type-macro" tal:omit-tag="">
@@ -4367,22 +4398,51 @@
<option value="">Choose a Task...</option>
<tal:block tal:condition="running">
+ <option
+ tal:attributes="value innermap/restarturl">Restart this service</option>
+
+ <option
+ tal:attributes="value innermap/disableurl">Disable this service</option>
+
<option value="">----------</option>
- <option value="" tal:attributes="value innermap/restarturl">Restart this service</option>
- <option value="" tal:attributes="value innermap/disableurl">Disable this service</option>
- <option value="">----------</option>
- <option tal:repeat="starturl innermap/links" value="" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" />
+ </option>
+ </tal:block>
+
+ <tal:block tal:condition="svc/is_vm | nothing">
+ <option value="">----------</option>
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="exists: starturl/migrate"
+ tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
</tal:block>
<tal:block tal:condition="not: running">
+ <option
+ tal:attributes="value innermap/enableurl">Enable this service</option>
<option value="">----------</option>
- <option value="" tal:attributes="value innermap/enableurl">Enable this service</option>
+
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" />
+ </option>
+ </tal:block>
+
<option value="">----------</option>
+
<option
tal:attributes="value innermap/delurl | nothing"
tal:content="string:Delete this service" />
</tal:block>
</select>
+
<input type="button" value="Go"
onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
</form>
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2007/03/05 16:50:09 1.120.2.23
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2007/03/12 04:22:26 1.120.2.24
@@ -3439,15 +3439,6 @@
itemmap['autostart'] = item['autostart']
- starturls = list()
- for node in nodes:
- starturl = {}
- if node.getName() != cur_node:
- starturl['nodename'] = node.getName()
- starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
- starturls.append(starturl)
- itemmap['links'] = starturls
-
try:
svc = model.retrieveServiceByName(item['name'])
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE
@@ -3455,11 +3446,29 @@
except:
try:
svc = model.retrieveVMsByName(item['name'])
- itemmap['virt'] = True
+ itemmap['is_vm'] = True
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
itemmap['delurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
except:
continue
+
+ starturls = list()
+ for node in nodes:
+ if node.getName() != cur_node:
+ starturl = {}
+ cur_nodename = node.getName()
+ starturl['nodename'] = cur_nodename
+ starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
+ starturls.append(starturl)
+
+ if itemmap.has_key('is_vm') and itemmap['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['migrate'] = True
+ migrate_url['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_MIGRATE + '&nodename=' + node.getName()
+ starturls.append(migrate_url)
+
+ itemmap['links'] = starturls
+
dom = svc.getAttribute("domain")
if dom is not None:
itemmap['faildom'] = dom
@@ -3513,42 +3522,59 @@
return hmap
for item in status:
- if item['type'] == "service":
+ innermap = {}
+ if item['type'] == 'service':
if item['name'] == servicename:
hmap['name'] = servicename
- starturls = list()
hmap['autostart'] = item['autostart']
- if item['running'] == "true":
- hmap['running'] = "true"
- #In this case, determine where it can run...
- innermap = {}
+
+ starturls = list()
+ if item['running'] == 'true':
+ hmap['running'] = 'true'
nodename = item['nodename']
- innermap['current'] = "This service is currently running on %s" % nodename
+ innermap['current'] = 'This service is currently running on %s' % nodename
+
innermap['disableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_STOP
innermap['restarturl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_RESTART
innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+ #In this case, determine where it can run...
nodes = model.getNodes()
for node in nodes:
- starturl = {}
if node.getName() != nodename:
- starturl['nodename'] = node.getName()
+ starturl = {}
+ cur_nodename = node.getName()
+ starturl['nodename'] = cur_nodename
starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
innermap['links'] = starturls
else:
#Do not set ['running'] in this case...ZPT will detect it is missing
- #In this case, determine where it can run...
- innermap = {}
innermap['current'] = "This service is currently stopped"
innermap['enableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START
+ innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+
nodes = model.getNodes()
starturls = list()
for node in nodes:
starturl = {}
- starturl['nodename'] = node.getName()
+ cur_nodename = node.getName()
+
+ starturl['nodename'] = cur_nodename
starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
innermap['links'] = starturls
hmap['innermap'] = innermap
@@ -3659,14 +3685,72 @@
batch_number, result = startService(rc, svcname, nodename)
if batch_number is None or result is None:
- luci_log.debug_verbose('startService3: SS(%s,%s,%s) call failed' \
+ luci_log.debug_verbose('serviceStart3: SS(%s,%s,%s) call failed' \
+ % (svcname, cluname, nodename))
+ return None
+
+ try:
+ status_msg = "Starting service \'%s\'" % svcname
+ if nodename:
+ status_msg += " on node \'%s\'" % nodename
+ set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, status_msg)
+ except Exception, e:
+ luci_log.debug_verbose('serviceStart4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+
+ response = req.RESPONSE
+ response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
+
+def serviceMigrate(self, rc, req):
+ svcname = None
+ try:
+ svcname = req['servicename']
+ except:
+ try:
+ svcname = req.form['servicename']
+ except:
+ pass
+
+ if svcname is None:
+ luci_log.debug_verbose('serviceMigrate0: no service name')
+ return None
+
+ nodename = None
+ try:
+ nodename = req['nodename']
+ except:
+ try:
+ nodename = req.form['nodename']
+ except:
+ pass
+
+ if nodename is None:
+ luci_log.debug_verbose('serviceMigrate1: no target node name')
+ return None
+
+ cluname = None
+ try:
+ cluname = req['clustername']
+ except KeyError, e:
+ try:
+ cluname = req.form['clustername']
+ except:
+ pass
+
+ if cluname is None:
+ luci_log.debug_verbose('serviceMigrate2: no cluster name for svc %s' \
+ % svcname)
+ return None
+
+ batch_number, result = migrateService(rc, svcname, nodename)
+ if batch_number is None or result is None:
+ luci_log.debug_verbose('serviceMigrate3: SS(%s,%s,%s) call failed' \
% (svcname, cluname, nodename))
return None
try:
- set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Starting service \'%s\'" % svcname)
+ set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Migrating service \'%s\' to node \'%s\'" % (svcname, nodename))
except Exception, e:
- luci_log.debug_verbose('startService4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+ luci_log.debug_verbose('serviceMigrate4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
response = req.RESPONSE
response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
--- conga/luci/site/luci/Extensions/conga_constants.py 2007/03/01 00:31:08 1.19.2.8
+++ conga/luci/site/luci/Extensions/conga_constants.py 2007/03/12 04:22:26 1.19.2.9
@@ -44,8 +44,9 @@
FENCEDEV="54"
CLUSTER_DAEMON="55"
SERVICE_DELETE = '56'
-FENCEDEV_DELETE = "57"
+FENCEDEV_DELETE = '57'
FENCEDEV_NODE_CONFIG = '58'
+SERVICE_MIGRATE = '59'
CONF_EDITOR = '80'
--- conga/luci/site/luci/Extensions/ricci_bridge.py 2007/03/01 00:31:08 1.30.2.18
+++ conga/luci/site/luci/Extensions/ricci_bridge.py 2007/03/12 04:22:26 1.30.2.19
@@ -454,6 +454,12 @@
ricci_xml = rc.batch_run(batch_str)
return batchAttemptResult(ricci_xml)
+def migrateService(rc, servicename, preferrednode):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="migrate_service"><var mutable="false" name="servicename" type="string" value=\"' + servicename + '\"/><var mutable="false" name="nodename" type="string" value=\"' + preferrednode + '\" /></function_call></request></module>'
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
def updateServices(rc, enable_list, disable_list):
batch = ''
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2007-03-12 4:24 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2007-03-12 4:24 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Branch: RHEL4
Changes by: rmccabe at sourceware.org 2007-03-12 04:24:34
Modified files:
luci/cluster : form-chooser form-macros
luci/site/luci/Extensions: cluster_adapters.py
conga_constants.py ricci_bridge.py
Log message:
Frontend support for virtual service live migration
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.16&r2=1.16.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.176.2.15&r2=1.176.2.16
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.227.2.13&r2=1.227.2.14
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.36.2.1&r2=1.36.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.56.2.4&r2=1.56.2.5
--- conga/luci/cluster/form-chooser 2007/02/01 20:27:33 1.16
+++ conga/luci/cluster/form-chooser 2007/03/12 04:24:33 1.16.2.1
@@ -92,6 +92,9 @@
<span tal:omit-tag="" tal:condition="python: ptype == '28'">
<div metal:use-macro="here/form-macros/macros/servicerestart"/>
</span>
+ <span tal:omit-tag="" tal:condition="python: ptype == '59'">
+ <div metal:use-macro="here/form-macros/macros/servicemigrate"/>
+ </span>
<span tal:omit-tag="" tal:condition="python: ptype == '30'">
<div metal:use-macro="here/resource-form-macros/macros/resources-form"/>
</span>
--- conga/luci/cluster/form-macros 2007/03/05 16:49:42 1.176.2.15
+++ conga/luci/cluster/form-macros 2007/03/12 04:24:33 1.176.2.16
@@ -3876,12 +3876,12 @@
<tr class="cluster service info_top">
<td class="cluster service service_name">
- <strong class="cluster service">Service Name:</strong>
+ <strong class="cluster service">Service Name</strong>
<a tal:attributes="
href svc/cfgurl;
class python: 'cluster service ' + (running and 'running' or 'stopped')"
tal:content="svc/name" />
- <tal:block tal:condition="exists:svc/virt">
+ <tal:block tal:condition="exists:svc/is_vm">
(virtual service)
</tal:block>
</td>
@@ -3898,7 +3898,7 @@
<option
tal:condition="running"
- tal:attributes="value svc/retstarturl| nothing"
+ tal:attributes="value svc/restarturl | nothing"
tal:content="string:Restart this service" />
<option
@@ -3909,14 +3909,40 @@
<option
tal:condition="not: running"
tal:attributes="value svc/enableurl | nothing"
- tal:content="string:Start this service" />
+ tal:content="string:Enable this service" />
<option
tal:condition="not: running"
tal:attributes="value svc/delurl | nothing"
tal:content="string:Delete this service" />
+
<option value="">----------</option>
- <option tal:repeat="starturl svc/links" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+ <tal:block tal:condition="not: running">
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
+
+ <tal:block tal:condition="running">
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+
+ <tal:block tal:condition="svc/is_vm | nothing">
+ <option value="">----------</option>
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="exists: starturl/migrate"
+ tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
+ </tal:block>
+
</select>
<input type="button" value="Go"
onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
@@ -4227,10 +4253,19 @@
<tal:block tal:define="
result python: here.serviceStart(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
+<div metal:define-macro="servicemigrate">
+ <script type="text/javascript">
+ set_page_title('Luci ??? cluster ??? services ??? Migrate a virtual service');
+ </script>
+
+ <tal:block tal:define="
+ global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
+
+ <tal:block tal:define="
+ result python: here.serviceMigrate(ricci_agent, request)" />
+</div>
<div metal:define-macro="servicerestart">
<script type="text/javascript">
@@ -4242,8 +4277,6 @@
<tal:block tal:define="
result python: here.serviceRestart(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
<div metal:define-macro="servicestop">
@@ -4256,8 +4289,6 @@
<span tal:define="
result python: here.serviceStop(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
<div metal:define-macro="serviceconfig-type-macro" tal:omit-tag="">
@@ -4367,22 +4398,51 @@
<option value="">Choose a Task...</option>
<tal:block tal:condition="running">
+ <option
+ tal:attributes="value innermap/restarturl">Restart this service</option>
+
+ <option
+ tal:attributes="value innermap/disableurl">Disable this service</option>
+
<option value="">----------</option>
- <option value="" tal:attributes="value innermap/restarturl">Restart this service</option>
- <option value="" tal:attributes="value innermap/disableurl">Disable this service</option>
- <option value="">----------</option>
- <option tal:repeat="starturl innermap/links" value="" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" />
+ </option>
+ </tal:block>
+
+ <tal:block tal:condition="svc/is_vm | nothing">
+ <option value="">----------</option>
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="exists: starturl/migrate"
+ tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
</tal:block>
<tal:block tal:condition="not: running">
+ <option
+ tal:attributes="value innermap/enableurl">Enable this service</option>
<option value="">----------</option>
- <option value="" tal:attributes="value innermap/enableurl">Enable this service</option>
+
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" />
+ </option>
+ </tal:block>
+
<option value="">----------</option>
+
<option
tal:attributes="value innermap/delurl | nothing"
tal:content="string:Delete this service" />
</tal:block>
</select>
+
<input type="button" value="Go"
onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
</form>
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2007/03/05 16:49:42 1.227.2.13
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2007/03/12 04:24:34 1.227.2.14
@@ -3439,15 +3439,6 @@
itemmap['autostart'] = item['autostart']
- starturls = list()
- for node in nodes:
- starturl = {}
- if node.getName() != cur_node:
- starturl['nodename'] = node.getName()
- starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
- starturls.append(starturl)
- itemmap['links'] = starturls
-
try:
svc = model.retrieveServiceByName(item['name'])
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE
@@ -3455,11 +3446,29 @@
except:
try:
svc = model.retrieveVMsByName(item['name'])
- itemmap['virt'] = True
+ itemmap['is_vm'] = True
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
itemmap['delurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
except:
continue
+
+ starturls = list()
+ for node in nodes:
+ if node.getName() != cur_node:
+ starturl = {}
+ cur_nodename = node.getName()
+ starturl['nodename'] = cur_nodename
+ starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
+ starturls.append(starturl)
+
+ if itemmap.has_key('is_vm') and itemmap['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['migrate'] = True
+ migrate_url['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_MIGRATE + '&nodename=' + node.getName()
+ starturls.append(migrate_url)
+
+ itemmap['links'] = starturls
+
dom = svc.getAttribute("domain")
if dom is not None:
itemmap['faildom'] = dom
@@ -3513,42 +3522,59 @@
return hmap
for item in status:
- if item['type'] == "service":
+ innermap = {}
+ if item['type'] == 'service':
if item['name'] == servicename:
hmap['name'] = servicename
- starturls = list()
hmap['autostart'] = item['autostart']
- if item['running'] == "true":
- hmap['running'] = "true"
- #In this case, determine where it can run...
- innermap = {}
+
+ starturls = list()
+ if item['running'] == 'true':
+ hmap['running'] = 'true'
nodename = item['nodename']
- innermap['current'] = "This service is currently running on %s" % nodename
+ innermap['current'] = 'This service is currently running on %s' % nodename
+
innermap['disableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_STOP
innermap['restarturl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_RESTART
innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+ #In this case, determine where it can run...
nodes = model.getNodes()
for node in nodes:
- starturl = {}
if node.getName() != nodename:
- starturl['nodename'] = node.getName()
+ starturl = {}
+ cur_nodename = node.getName()
+ starturl['nodename'] = cur_nodename
starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
innermap['links'] = starturls
else:
#Do not set ['running'] in this case...ZPT will detect it is missing
- #In this case, determine where it can run...
- innermap = {}
innermap['current'] = "This service is currently stopped"
innermap['enableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START
+ innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+
nodes = model.getNodes()
starturls = list()
for node in nodes:
starturl = {}
- starturl['nodename'] = node.getName()
+ cur_nodename = node.getName()
+
+ starturl['nodename'] = cur_nodename
starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
innermap['links'] = starturls
hmap['innermap'] = innermap
@@ -3659,14 +3685,72 @@
batch_number, result = startService(rc, svcname, nodename)
if batch_number is None or result is None:
- luci_log.debug_verbose('startService3: SS(%s,%s,%s) call failed' \
+ luci_log.debug_verbose('serviceStart3: SS(%s,%s,%s) call failed' \
+ % (svcname, cluname, nodename))
+ return None
+
+ try:
+ status_msg = "Starting service \'%s\'" % svcname
+ if nodename:
+ status_msg += " on node \'%s\'" % nodename
+ set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, status_msg)
+ except Exception, e:
+ luci_log.debug_verbose('serviceStart4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+
+ response = req.RESPONSE
+ response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
+
+def serviceMigrate(self, rc, req):
+ svcname = None
+ try:
+ svcname = req['servicename']
+ except:
+ try:
+ svcname = req.form['servicename']
+ except:
+ pass
+
+ if svcname is None:
+ luci_log.debug_verbose('serviceMigrate0: no service name')
+ return None
+
+ nodename = None
+ try:
+ nodename = req['nodename']
+ except:
+ try:
+ nodename = req.form['nodename']
+ except:
+ pass
+
+ if nodename is None:
+ luci_log.debug_verbose('serviceMigrate1: no target node name')
+ return None
+
+ cluname = None
+ try:
+ cluname = req['clustername']
+ except KeyError, e:
+ try:
+ cluname = req.form['clustername']
+ except:
+ pass
+
+ if cluname is None:
+ luci_log.debug_verbose('serviceMigrate2: no cluster name for svc %s' \
+ % svcname)
+ return None
+
+ batch_number, result = migrateService(rc, svcname, nodename)
+ if batch_number is None or result is None:
+ luci_log.debug_verbose('serviceMigrate3: SS(%s,%s,%s) call failed' \
% (svcname, cluname, nodename))
return None
try:
- set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Starting service \'%s\'" % svcname)
+ set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Migrating service \'%s\' to node \'%s\'" % (svcname, nodename))
except Exception, e:
- luci_log.debug_verbose('startService4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+ luci_log.debug_verbose('serviceMigrate4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
response = req.RESPONSE
response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
--- conga/luci/site/luci/Extensions/conga_constants.py 2007/03/01 00:39:18 1.36.2.1
+++ conga/luci/site/luci/Extensions/conga_constants.py 2007/03/12 04:24:34 1.36.2.2
@@ -44,8 +44,9 @@
FENCEDEV="54"
CLUSTER_DAEMON="55"
SERVICE_DELETE = '56'
-FENCEDEV_DELETE = "57"
+FENCEDEV_DELETE = '57'
FENCEDEV_NODE_CONFIG = '58'
+SERVICE_MIGRATE = '59'
CONF_EDITOR = '80'
--- conga/luci/site/luci/Extensions/ricci_bridge.py 2007/03/01 00:40:53 1.56.2.4
+++ conga/luci/site/luci/Extensions/ricci_bridge.py 2007/03/12 04:24:34 1.56.2.5
@@ -454,6 +454,12 @@
ricci_xml = rc.batch_run(batch_str)
return batchAttemptResult(ricci_xml)
+def migrateService(rc, servicename, preferrednode):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="migrate_service"><var mutable="false" name="servicename" type="string" value=\"' + servicename + '\"/><var mutable="false" name="nodename" type="string" value=\"' + preferrednode + '\" /></function_call></request></module>'
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
def updateServices(rc, enable_list, disable_list):
batch = ''
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2007-03-12 4:25 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2007-03-12 4:25 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2007-03-12 04:25:41
Modified files:
luci/cluster : form-chooser form-macros
luci/site/luci/Extensions: cluster_adapters.py
conga_constants.py ricci_bridge.py
Log message:
Frontend support for virtual service live migration
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.17&r2=1.18
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.196&r2=1.197
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.247&r2=1.248
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&r1=1.37&r2=1.38
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&r1=1.60&r2=1.61
--- conga/luci/cluster/form-chooser 2007/02/23 22:07:45 1.17
+++ conga/luci/cluster/form-chooser 2007/03/12 04:25:41 1.18
@@ -92,6 +92,9 @@
<span tal:omit-tag="" tal:condition="python: ptype == '28'">
<div metal:use-macro="here/form-macros/macros/servicerestart"/>
</span>
+ <span tal:omit-tag="" tal:condition="python: ptype == '59'">
+ <div metal:use-macro="here/form-macros/macros/servicemigrate"/>
+ </span>
<span tal:omit-tag="" tal:condition="python: ptype == '30'">
<div metal:use-macro="here/resource-form-macros/macros/resources-form"/>
</span>
--- conga/luci/cluster/form-macros 2007/03/05 16:50:43 1.196
+++ conga/luci/cluster/form-macros 2007/03/12 04:25:41 1.197
@@ -3876,12 +3876,12 @@
<tr class="cluster service info_top">
<td class="cluster service service_name">
- <strong class="cluster service">Service Name:</strong>
+ <strong class="cluster service">Service Name</strong>
<a tal:attributes="
href svc/cfgurl;
class python: 'cluster service ' + (running and 'running' or 'stopped')"
tal:content="svc/name" />
- <tal:block tal:condition="exists:svc/virt">
+ <tal:block tal:condition="exists:svc/is_vm">
(virtual service)
</tal:block>
</td>
@@ -3898,7 +3898,7 @@
<option
tal:condition="running"
- tal:attributes="value svc/retstarturl| nothing"
+ tal:attributes="value svc/restarturl | nothing"
tal:content="string:Restart this service" />
<option
@@ -3909,14 +3909,40 @@
<option
tal:condition="not: running"
tal:attributes="value svc/enableurl | nothing"
- tal:content="string:Start this service" />
+ tal:content="string:Enable this service" />
<option
tal:condition="not: running"
tal:attributes="value svc/delurl | nothing"
tal:content="string:Delete this service" />
+
<option value="">----------</option>
- <option tal:repeat="starturl svc/links" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+ <tal:block tal:condition="not: running">
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
+
+ <tal:block tal:condition="running">
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+
+ <tal:block tal:condition="svc/is_vm | nothing">
+ <option value="">----------</option>
+ <tal:block tal:repeat="starturl svc/links">
+ <option
+ tal:condition="exists: starturl/migrate"
+ tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
+ </tal:block>
+
</select>
<input type="button" value="Go"
onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
@@ -4227,10 +4253,19 @@
<tal:block tal:define="
result python: here.serviceStart(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
+<div metal:define-macro="servicemigrate">
+ <script type="text/javascript">
+ set_page_title('Luci ??? cluster ??? services ??? Migrate a virtual service');
+ </script>
+
+ <tal:block tal:define="
+ global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
+
+ <tal:block tal:define="
+ result python: here.serviceMigrate(ricci_agent, request)" />
+</div>
<div metal:define-macro="servicerestart">
<script type="text/javascript">
@@ -4242,8 +4277,6 @@
<tal:block tal:define="
result python: here.serviceRestart(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
<div metal:define-macro="servicestop">
@@ -4256,8 +4289,6 @@
<span tal:define="
result python: here.serviceStop(ricci_agent, request)" />
-
- <!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
</div>
<div metal:define-macro="serviceconfig-type-macro" tal:omit-tag="">
@@ -4367,22 +4398,51 @@
<option value="">Choose a Task...</option>
<tal:block tal:condition="running">
+ <option
+ tal:attributes="value innermap/restarturl">Restart this service</option>
+
+ <option
+ tal:attributes="value innermap/disableurl">Disable this service</option>
+
<option value="">----------</option>
- <option value="" tal:attributes="value innermap/restarturl">Restart this service</option>
- <option value="" tal:attributes="value innermap/disableurl">Disable this service</option>
- <option value="">----------</option>
- <option tal:repeat="starturl innermap/links" value="" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" />
+ </option>
+ </tal:block>
+
+ <tal:block tal:condition="svc/is_vm | nothing">
+ <option value="">----------</option>
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="exists: starturl/migrate"
+ tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+ </tal:block>
+ </tal:block>
</tal:block>
<tal:block tal:condition="not: running">
+ <option
+ tal:attributes="value innermap/enableurl">Enable this service</option>
<option value="">----------</option>
- <option value="" tal:attributes="value innermap/enableurl">Enable this service</option>
+
+ <tal:block tal:repeat="starturl innermap/links">
+ <option
+ tal:condition="not:exists: starturl/migrate"
+ tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" />
+ </option>
+ </tal:block>
+
<option value="">----------</option>
+
<option
tal:attributes="value innermap/delurl | nothing"
tal:content="string:Delete this service" />
</tal:block>
</select>
+
<input type="button" value="Go"
onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
</form>
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2007/03/06 22:48:19 1.247
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2007/03/12 04:25:41 1.248
@@ -3441,15 +3441,6 @@
itemmap['autostart'] = item['autostart']
- starturls = list()
- for node in nodes:
- starturl = {}
- if node.getName() != cur_node:
- starturl['nodename'] = node.getName()
- starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
- starturls.append(starturl)
- itemmap['links'] = starturls
-
try:
svc = model.retrieveServiceByName(item['name'])
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE
@@ -3457,11 +3448,29 @@
except:
try:
svc = model.retrieveVMsByName(item['name'])
- itemmap['virt'] = True
+ itemmap['is_vm'] = True
itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
itemmap['delurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
except:
continue
+
+ starturls = list()
+ for node in nodes:
+ if node.getName() != cur_node:
+ starturl = {}
+ cur_nodename = node.getName()
+ starturl['nodename'] = cur_nodename
+ starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
+ starturls.append(starturl)
+
+ if itemmap.has_key('is_vm') and itemmap['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['migrate'] = True
+ migrate_url['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_MIGRATE + '&nodename=' + node.getName()
+ starturls.append(migrate_url)
+
+ itemmap['links'] = starturls
+
dom = svc.getAttribute("domain")
if dom is not None:
itemmap['faildom'] = dom
@@ -3515,42 +3524,59 @@
return hmap
for item in status:
- if item['type'] == "service":
+ innermap = {}
+ if item['type'] == 'service':
if item['name'] == servicename:
hmap['name'] = servicename
- starturls = list()
hmap['autostart'] = item['autostart']
- if item['running'] == "true":
- hmap['running'] = "true"
- #In this case, determine where it can run...
- innermap = {}
+
+ starturls = list()
+ if item['running'] == 'true':
+ hmap['running'] = 'true'
nodename = item['nodename']
- innermap['current'] = "This service is currently running on %s" % nodename
+ innermap['current'] = 'This service is currently running on %s' % nodename
+
innermap['disableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_STOP
innermap['restarturl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_RESTART
innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+ #In this case, determine where it can run...
nodes = model.getNodes()
for node in nodes:
- starturl = {}
if node.getName() != nodename:
- starturl['nodename'] = node.getName()
+ starturl = {}
+ cur_nodename = node.getName()
+ starturl['nodename'] = cur_nodename
starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
innermap['links'] = starturls
else:
#Do not set ['running'] in this case...ZPT will detect it is missing
- #In this case, determine where it can run...
- innermap = {}
innermap['current'] = "This service is currently stopped"
innermap['enableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START
+ innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+
nodes = model.getNodes()
starturls = list()
for node in nodes:
starturl = {}
- starturl['nodename'] = node.getName()
+ cur_nodename = node.getName()
+
+ starturl['nodename'] = cur_nodename
starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
innermap['links'] = starturls
hmap['innermap'] = innermap
@@ -3661,14 +3687,72 @@
batch_number, result = startService(rc, svcname, nodename)
if batch_number is None or result is None:
- luci_log.debug_verbose('startService3: SS(%s,%s,%s) call failed' \
+ luci_log.debug_verbose('serviceStart3: SS(%s,%s,%s) call failed' \
+ % (svcname, cluname, nodename))
+ return None
+
+ try:
+ status_msg = "Starting service \'%s\'" % svcname
+ if nodename:
+ status_msg += " on node \'%s\'" % nodename
+ set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, status_msg)
+ except Exception, e:
+ luci_log.debug_verbose('serviceStart4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+
+ response = req.RESPONSE
+ response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
+
+def serviceMigrate(self, rc, req):
+ svcname = None
+ try:
+ svcname = req['servicename']
+ except:
+ try:
+ svcname = req.form['servicename']
+ except:
+ pass
+
+ if svcname is None:
+ luci_log.debug_verbose('serviceMigrate0: no service name')
+ return None
+
+ nodename = None
+ try:
+ nodename = req['nodename']
+ except:
+ try:
+ nodename = req.form['nodename']
+ except:
+ pass
+
+ if nodename is None:
+ luci_log.debug_verbose('serviceMigrate1: no target node name')
+ return None
+
+ cluname = None
+ try:
+ cluname = req['clustername']
+ except KeyError, e:
+ try:
+ cluname = req.form['clustername']
+ except:
+ pass
+
+ if cluname is None:
+ luci_log.debug_verbose('serviceMigrate2: no cluster name for svc %s' \
+ % svcname)
+ return None
+
+ batch_number, result = migrateService(rc, svcname, nodename)
+ if batch_number is None or result is None:
+ luci_log.debug_verbose('serviceMigrate3: SS(%s,%s,%s) call failed' \
% (svcname, cluname, nodename))
return None
try:
- set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Starting service \'%s\'" % svcname)
+ set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Migrating service \'%s\' to node \'%s\'" % (svcname, nodename))
except Exception, e:
- luci_log.debug_verbose('startService4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+ luci_log.debug_verbose('serviceMigrate4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
response = req.RESPONSE
response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
--- conga/luci/site/luci/Extensions/conga_constants.py 2007/02/23 22:07:45 1.37
+++ conga/luci/site/luci/Extensions/conga_constants.py 2007/03/12 04:25:41 1.38
@@ -44,8 +44,9 @@
FENCEDEV="54"
CLUSTER_DAEMON="55"
SERVICE_DELETE = '56'
-FENCEDEV_DELETE = "57"
+FENCEDEV_DELETE = '57'
FENCEDEV_NODE_CONFIG = '58'
+SERVICE_MIGRATE = '59'
CONF_EDITOR = '80'
SYS_SERVICE_MANAGE = '90'
--- conga/luci/site/luci/Extensions/ricci_bridge.py 2007/02/24 07:02:42 1.60
+++ conga/luci/site/luci/Extensions/ricci_bridge.py 2007/03/12 04:25:41 1.61
@@ -454,6 +454,12 @@
ricci_xml = rc.batch_run(batch_str)
return batchAttemptResult(ricci_xml)
+def migrateService(rc, servicename, preferrednode):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="migrate_service"><var mutable="false" name="servicename" type="string" value=\"' + servicename + '\"/><var mutable="false" name="nodename" type="string" value=\"' + preferrednode + '\" /></function_call></request></module>'
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
def updateServices(rc, enable_list, disable_list):
batch = ''
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...
@ 2007-09-25 22:47 rmccabe
0 siblings, 0 replies; 10+ messages in thread
From: rmccabe @ 2007-09-25 22:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2007-09-25 22:47:05
Modified files:
luci/cluster : form-chooser form-macros resource-form-macros
luci/homebase : form-chooser form-macros luci_homebase.css
luci/plone-custom: sys_svc.css
luci/storage : cylinder_select.js form-macros
storage_probing.js storage_utils.js
storage_validation.js validate_html
Log message:
More cleanup and fix some javascript bugs
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.19&r2=1.20
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.213&r2=1.214
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource-form-macros.diff?cvsroot=cluster&r1=1.42&r2=1.43
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/form-chooser.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/form-macros.diff?cvsroot=cluster&r1=1.61&r2=1.62
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/luci_homebase.css.diff?cvsroot=cluster&r1=1.43&r2=1.44
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/sys_svc.css.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/cylinder_select.js.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-macros.diff?cvsroot=cluster&r1=1.28&r2=1.29
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/storage_probing.js.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/storage_utils.js.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/storage_validation.js.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/validate_html.diff?cvsroot=cluster&r1=1.6&r2=1.7
--- conga/luci/cluster/form-chooser 2007/08/08 21:00:06 1.19
+++ conga/luci/cluster/form-chooser 2007/09/25 22:47:05 1.20
@@ -1,3 +1,12 @@
+<tal:comment tal:replace="nothing">
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+</tal:comment>
+
<html>
<head>
<title tal:content="string:"></title>
--- conga/luci/cluster/form-macros 2007/09/25 03:51:02 1.213
+++ conga/luci/cluster/form-macros 2007/09/25 22:47:05 1.214
@@ -1,3 +1,12 @@
+<tal:comment tal:replace="nothing">
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+</tal:comment>
+
<html>
<head>
--- conga/luci/cluster/resource-form-macros 2007/09/25 03:51:02 1.42
+++ conga/luci/cluster/resource-form-macros 2007/09/25 22:47:05 1.43
@@ -1,3 +1,12 @@
+<tal:comment tal:replace="nothing">
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+</tal:comment>
+
<html>
<head>
<title tal:content="template/title">The title</title>
--- conga/luci/homebase/form-chooser 2006/11/01 23:04:17 1.11
+++ conga/luci/homebase/form-chooser 2007/09/25 22:47:05 1.12
@@ -1,3 +1,12 @@
+<tal:comment tal:replace="nothing">
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+</tal:comment>
+
<html>
<head>
--- conga/luci/homebase/form-macros 2007/09/25 03:51:21 1.61
+++ conga/luci/homebase/form-macros 2007/09/25 22:47:05 1.62
@@ -1,3 +1,12 @@
+<tal:comment tal:replace="nothing">
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+</tal:comment>
+
<html>
<head>
--- conga/luci/homebase/luci_homebase.css 2007/09/25 03:51:21 1.43
+++ conga/luci/homebase/luci_homebase.css 2007/09/25 22:47:05 1.44
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
input[type=text], input[type=password] {
padding: .2em ! important;
font-family: "Bitstream Vera Sans Mono", "DejaVu Sans Mono", monospace;
--- conga/luci/plone-custom/sys_svc.css 2007/06/28 16:02:50 1.1
+++ conga/luci/plone-custom/sys_svc.css 2007/09/25 22:47:05 1.2
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
input[type=image] {
border: 0;
background: transparent;
--- conga/luci/storage/cylinder_select.js 2007/09/25 18:55:13 1.3
+++ conga/luci/storage/cylinder_select.js 2007/09/25 22:47:05 1.4
@@ -58,12 +58,12 @@
}
}
- parent = top.document.getElementById(properties_span_id);
+ var parent_elem = top.document.getElementById(properties_span_id);
- for (var i = 0 ; i < parent.childNodes.length ; i++) {
- var item = parent.childNodes[i];
+ for (var i = 0 ; i < parent_elem.childNodes.length ; i++) {
+ var item = parent_elem.childNodes[i];
var item_type = item.nodeName.toLowerCase();
- if (item_type == 'span' || item.type == 'div') {
+ if (item_type == 'span' || item_type == 'div') {
if (item.id == current_selection) {
item.className = 'visible';
} else if (item.className == 'visible') {
@@ -86,7 +86,7 @@
var id = elem[0];
var beg = elem[1][0];
var end = elem[1][1];
- if (x > beg && x < end) {
+ if (x >= beg && x <= end) {
select_subcyl(id, h_data);
}
}
--- conga/luci/storage/form-macros 2007/09/25 18:55:13 1.28
+++ conga/luci/storage/form-macros 2007/09/25 22:47:05 1.29
@@ -21,17 +21,18 @@
<div metal:define-macro="commit-changes">
<script type="text/javascript" src="storage_utils.js"></script>
- <span tal:omit-tag=""
- tal:define="batch_id python:here.apply_storage_changes(ricci, storage_report, request);
- check_URL context/storage/check-batch/absolute_url;
- check_url python:check_URL + '?storagename=' + storagename + '&batch_id=' + batch_id">
+ <tal:block tal:define="
+ batch_id python:here.apply_storage_changes(ricci, storage_report, request);
+ check_URL context/storage/check-batch/absolute_url;
+ check_url python:check_URL + '?storagename=' + storagename + '&batch_id=' + batch_id">
<div metal:use-macro="here/form-macros/macros/display-committing-changes" />
+
<form id="urls_form">
<input type="hidden" name="check_url"
tal:attributes="value check_url" />
</form>
- </span>
+ </tal:block>
</div>
<div metal:define-macro="display-committing-changes">
@@ -378,9 +379,9 @@
</div>
<div metal:define-macro="view-mapper-form">
- <div metal:use-macro="here/form-macros/macros/content-scripts"/>
- <div metal:use-macro="here/form-macros/macros/form-scripts"/>
- <div metal:use-macro="here/form-macros/macros/single-visible-span"/>
+ <div metal:use-macro="here/form-macros/macros/content-scripts" />
+ <div metal:use-macro="here/form-macros/macros/form-scripts" />
+ <div metal:use-macro="here/form-macros/macros/single-visible-span" />
<tal:block tal:define="
mapper python:here.get_mapper_data(storage_report, request['mapper_id']);
@@ -401,7 +402,7 @@
<input type="checkbox" id="graphics_checkbox_id"
tal:attributes="
checked mapper/graphical_view"
- onchange="var s = (this.checked)?'graphical_view':'textual_view'; singleVisibleSpan('mappings_view', s);" />
+ onchange="var s = (this.checked) ? 'graphical_view' : 'textual_view'; singleVisibleSpan('mappings_view', s);" />
Graphical View <small>(Uncheck if volumes are too small to select)</small>
<span id="mappings_view"
tal:define="
@@ -412,8 +413,9 @@
tal:define="global bd_path request/bd_path|nothing">
<tal:block tal:condition="not: bd_path">
- <tal:block tal:define="global bd_path python:''"/>
+ <tal:block tal:define="global bd_path python:''" />
</tal:block>
+
<iframe style="border: none;"
tal:attributes="
src python:'mappings_provider?storagename=' + storagename + '&mapper_id=' + mapper['mapper_id'] + '&selected_path=' + bd_path;
@@ -545,138 +547,119 @@
<div metal:use-macro="here/form-macros/macros/form-scripts" />
<form method="get" tal:attributes="id mapper_template_form_id">
- <input tal:attributes="type string:hidden;
- name string:pagetype;
- value string:commit_changes"/>
-
- <input tal:attributes="type string:hidden;
- name string:object_type;
- value string:mapper_template"/>
- <input tal:attributes="type string:hidden;
- name string:mapper_type;
- value mapper/mapper_type"/>
-
- <input tal:attributes="type string:hidden;
- name string:mapper_id;
- value python:''"/>
+ <input type="hidden" name="pagetype"
+ tal:attributes="value string:commit_changes" />
- <input tal:attributes="type string:hidden;
- name string:storagename;
- value storagename"/>
+ <input type="hidden" name="object_type" value="mapper_template" />
+ <input type="hidden" name="mapper_type"
+ tal:attributes="value mapper/mapper_type" />
+ <input type="hidden" name="mapper_id" value="" />
+
+ <input type="hidden" name="storagename"
+ tal:attributes="value storagename" />
+
+ <table class="props-form-table">
+ <tr class="props-form-header">
+ <th colspan="2" tal:attributes="
+ style python:here.add_commas('font-size: large', 'color: ' + mapper['color'])">
+ <table>
+ <tr>
+ <td style="min-width: 30px;">
+ <img tal:condition="mapper/icon"
+ tal:attributes="src mapper/icon"
+ height="29px"
+ width="29px" />
+ </td>
+ <td style="width: 100%;">
+ Creating New <span tal:replace="mapper/pretty_type" />
+ </td>
+ <td style="min-width: 30px;"> </td>
+ </tr>
+ </table>
+ </th>
+ </tr>
+ <tr class="props-form-body">
+ <td>
+ <table class="props-inner-table"
+ tal:define="props mapper/props_ordered">
- <table class="props-form-table">
- <tr class="props-form-header">
- <th colspan="2"
- tal:attributes="style python:here.add_commas('font-size: large', 'color: ' + mapper['color'])">
- <table>
- <tr>
- <td style="min-width: 30px;">
- <img tal:condition="mapper/icon"
- tal:attributes="src mapper/icon"
- height="29px"
- width="29px"/>
- </td>
- <td style="width: 100%;">
- Creating New <span tal:replace="mapper/pretty_type"/>
- </td>
- <td style="min-width: 30px;">
-
- </td>
- </tr>
- </table>
- </th>
- </tr>
- <tr class="props-form-body">
- <td>
- <table class="props-inner-table"
- tal:define="props mapper/props_ordered">
- <div metal:use-macro="here/form-macros/macros/display-props-tableless"/>
- </table>
- </td>
- <td style="height: 100%;">
- <table class="props-form-table"
- style="height: 100%;">
- <tr class="props-form-header">
- <th>
- <span tal:condition="python:mapper['min_sources'] == mapper['max_sources']">
- Select <span tal:replace="mapper/min_sources"/> <span tal:replace="mapper/pretty_source_name"/>
- </span>
- <span tal:condition="python:mapper['min_sources'] != mapper['max_sources']">
- Select <span tal:replace="mapper/min_sources"/> to <span tal:replace="mapper/max_sources"/> <span tal:replace="mapper/pretty_sources_name"/>
- </span>
- </th>
- </tr>
- <tr class="props-form-body">
- <td>
- <table class="props-inner-table">
- <span tal:omit-tag=""
- tal:define="bds mapper/new_sources"
- tal:repeat="bd bds">
- <tr>
- <td>
- <input tal:attributes="type string:checkbox;
- name python:'source_bd_' + bd['path']"/>
- </td>
- <td tal:define="bytes bd/props/size/value;
- dummy python:here.bytes_to_value_units(bytes);
- size python:dummy[0];
- units python:dummy[1]">
- <span tal:replace="bd/path"/> (<span tal:replace="size"/> <span tal:replace="units"/> - <span tal:replace="bd/pretty_type"/>)
- </td>
- </tr>
- </span>
- <tr>
- <td colspan="2"
- style="height: 100%;">
-
- </td>
- </tr>
- </table>
- </td>
- </tr>
- <tr class="props-form-footer">
- <td>
-
- </td>
- </tr>
- </table>
- </td>
- </tr>
- <tr class="props-form-footer">
- <td colspan="2">
- <table style="width: 100%;">
- <tr>
- <td align="left">
-
- </td>
- <td align="right">
- <input type="button"
- name="action_type"
- value="Reset"
- onclick="return reset_form(this.form)"
- class="form_button"/>
- <input tal:define="prompt_msg python:'Do you really want to create new ' + mapper['pretty_type'] + '?';
- validate_url context/validate_html/absolute_url"
- tal:attributes="id create_mapper_button_id;
- type string:button;
- name string:action_type;
- value string:Create;
- onclick python:'return validate_and_submit_form(\'' + validate_url + '\', \'' + mapper_template_form_id + '\', \'' + create_mapper_button_id + '\', \'' + prompt_msg + '\')'"
- class="form_button"/>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </table>
- </form>
+ <div metal:use-macro="here/form-macros/macros/display-props-tableless" />
+ </table>
+ </td>
+ <td style="height: 100%;">
+ <table class="props-form-table" style="height: 100%;">
+ <tr class="props-form-header">
+ <th>
+ <span tal:condition="python:mapper['min_sources'] == mapper['max_sources']">
+ Select <span tal:replace="mapper/min_sources"/> <span tal:replace="mapper/pretty_source_name" />
+ </span>
+ <span tal:condition="python:mapper['min_sources'] != mapper['max_sources']">
+ Select <span tal:replace="mapper/min_sources" /> to <span tal:replace="mapper/max_sources" /> <span tal:replace="mapper/pretty_sources_name" />
+ </span>
+ </th>
+ </tr>
+ <tr class="props-form-body">
+ <td>
+ <table class="props-inner-table">
+ <tr tal:repeat="bd mapper/new_sources">
+ <td>
+ <input type="checkbox"
+ tal:attributes="name python:'source_bd_' + bd['path']" />
+ </td>
+ <td tal:define="
+ bytes bd/props/size/value;
+ dummy python:here.bytes_to_value_units(bytes);
+ size python:dummy[0];
+ units python:dummy[1]">
+ <span tal:replace="bd/path" /> (<span tal:replace="size" /> <span tal:replace="units" /> - <span tal:replace="bd/pretty_type" />)
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" style="height: 100%;">
+
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr class="props-form-footer">
+ <td>
+
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr class="props-form-footer">
+ <td colspan="2">
+ <table style="width: 100%;">
+ <tr>
+ <td align="left">
+
+ </td>
+ <td align="right">
+ <input type="button" name="action_type" value="Reset"
+ onclick="return reset_form(this.form)"
+ class="form_button" />
+
+ <input type="button" name="action_type"
+ value="Create" class="form_button"
+ tal:define="
+ prompt_msg python:'Do you really want to create new ' + mapper['pretty_type'] + '?';
+ validate_url context/validate_html/absolute_url"
+ tal:attributes="
+ id create_mapper_button_id;
+ onclick python:'return validate_and_submit_form(\'' + validate_url + '\', \'' + mapper_template_form_id + '\', \'' + create_mapper_button_id + '\', \'' + prompt_msg + '\')'" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </form>
</div>
-
-
-
-
<div metal:define-macro="add-sources-form" tal:define="
mapper python:here.get_mapper_data(storage_report, request['mapper_id']);
prefix python:'add_sources_to_' + mapper['mapper_id'] + '_';
@@ -688,249 +671,241 @@
<div metal:use-macro="here/form-macros/macros/forms-css" />
<div metal:use-macro="here/form-macros/macros/form-scripts" />
- <span tal:omit-tag=""
- tal:condition="not: mapper/new_sources">
- There are no available <span tal:replace="mapper/pretty_sources_name"/> to be added to <span tal:replace="mapper/pretty_type"/> '<span tal:replace="mapper/pretty_name"/>'.
- <br/>
- <br/>
- <a tal:define="go_to_mapper_url python:'./?pagetype=52&mapper_type=' + mapper['mapper_type'] + '&mapper_id=' + mapper['mapper_id'] + '&storagename=' + storagename"
- tal:attributes="href go_to_mapper_url">
- Go Back to <span tal:replace="mapper/pretty_type"/>
- </a>
- </span>
- <form tal:condition="mapper/new_sources"
- tal:attributes="id add_sources_form_id;
- method string:get">
-
- <input tal:attributes="type string:hidden;
- name string:pagetype;
- value string:commit_changes"/>
+ <tal:block tal:condition="not: mapper/new_sources">
+ There are no available <span tal:replace="mapper/pretty_sources_name" /> to be added to <span tal:replace="mapper/pretty_type" /> '<span tal:replace="mapper/pretty_name" />'.
+ <br/>
+ <br/>
+ <a tal:define="
+ go_to_mapper_url python:'./?pagetype=52&mapper_type=' + mapper['mapper_type'] + '&mapper_id=' + mapper['mapper_id'] + '&storagename=' + storagename"
+ tal:attributes="href go_to_mapper_url">
+ Go Back to <span tal:replace="mapper/pretty_type" />
+ </a>
+ </tal:block>
- <input tal:attributes="type string:hidden;
- name string:object_type;
- value string:add_sources"/>
+ <form method="get" tal:condition="mapper/new_sources"
+ tal:attributes="id add_sources_form_id">
- <input tal:attributes="type string:hidden;
- name string:mapper_type;
- value mapper/mapper_type"/>
+ <input type="hidden" name="pagetype" value="commit_changes" />
+ <input type="hidden" name="object_type" value="add_sources" />
- <input tal:attributes="type string:hidden;
- name string:mapper_id;
- value mapper/mapper_id"/>
+ <input type="hidden" name="mapper_type"
+ tal:attributes="value mapper/mapper_type"/>
- <input tal:attributes="type string:hidden;
- name string:storagename;
- value storagename"/>
+ <input type="hidden" name="mapper_id"
+ tal:attributes="value mapper/mapper_id" />
+
+ <input type="hidden" name="storagename"
+ tal:attributes="value storagename" />
+
+ <table class="props-form-table">
+ <tr class="props-form-header">
+ <th colspan="2" tal:attributes="
+ style python:here.add_commas('font-size: large', 'color: ' + mapper['color'])">
+ <table>
+ <tr>
+ <td style="min-width: 30px;">
+ <img tal:condition="mapper/icon"
+ height="29px" width="29px"
+ tal:attributes="src mapper/icon" />
+ </td>
+ <td style="width: 100%;">
+ Adding new <span tal:replace="mapper/pretty_sources_name" /> to <span tal:replace="mapper/pretty_type" /> '<span tal:replace="mapper/pretty_name" />'
+ </td>
+ <td style="min-width: 30px;">
+
+ </td>
+ </tr>
+ </table>
+ </th>
+ </tr>
- <table class="props-form-table">
- <tr class="props-form-header">
- <th colspan="2"
- tal:attributes="style python:here.add_commas('font-size: large', 'color: ' + mapper['color'])">
- <table>
- <tr>
- <td style="min-width: 30px;">
- <img tal:condition="mapper/icon"
- tal:attributes="src mapper/icon"
- height="29px"
- width="29px"/>
- </td>
- <td style="width: 100%;">
- Adding new <span tal:replace="mapper/pretty_sources_name"/> to <span tal:replace="mapper/pretty_type"/> '<span tal:replace="mapper/pretty_name"/>'
- </td>
- <td style="min-width: 30px;">
-
- </td>
- </tr>
- </table>
- </th>
- </tr>
- <tr class="props-form-body">
- <td style="height: 100%;">
- <table class="props-inner-table">
- <th colspan="2">
- <span tal:condition="python:len(mapper['new_sources']) == 1">
- Select <span tal:replace="mapper/pretty_source_name"/> to add
- </span>
- <span tal:condition="python:len(mapper['new_sources']) > 1">
- Select one or more <span tal:replace="mapper/pretty_sources_name"/> to add
- </span>
- </th>
- <span tal:omit-tag=""
- tal:define="bds mapper/new_sources"
- tal:repeat="bd bds">
- <tr>
- <td>
- <input tal:attributes="type string:checkbox;
- name python:'source_bd_' + bd['path']"/>
- </td>
- <td tal:define="bytes bd/props/size/value;
- dummy python:here.bytes_to_value_units(bytes);
- size python:dummy[0];
- units python:dummy[1]">
- <span tal:replace="bd/path"/> (<span tal:replace="size"/> <span tal:replace="units"/> - <span tal:replace="bd/pretty_type"/>)
- </td>
- </tr>
- </span>
- <tr>
- <td colspan="2"
- style="height: 100%;">
-
- </td>
- </tr>
- </table>
- </td>
- <td>
-
- </td>
- </tr>
- <tr class="props-form-footer">
- <td colspan="2">
- <table style="width: 100%;">
- <tr>
- <td align="left">
-
- </td>
- <td align="right">
- <input tal:define="go_to_mapper_url python:'./?pagetype=52&mapper_type=' + mapper['mapper_type'] + '&mapper_id=' + mapper['mapper_id'] + '&storagename=' + storagename"
- tal:attributes="type string:button;
- name string:cancel_button;
- value string:Cancel;
- onclick python:'window.location.assign(\'' + go_to_mapper_url + '\')'"
- class="form_button"/>
- <input tal:define="prompt_msg python:'Do you really want to add selected ' + mapper['pretty_sources_name'] + ' to \\\'' + mapper['pretty_name'] + '\\\'?';
- validate_url context/validate_html/absolute_url"
- tal:attributes="id add_sources_button_id;
- type string:button;
- name string:action_type;
- value string:Add;
- onclick python:'return validate_and_submit_form(\'' + validate_url + '\', \'' + add_sources_form_id + '\', \'' + add_sources_button_id + '\', \'' + prompt_msg + '\')'"
- class="form_button"/>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </table>
- </form>
+ <tr class="props-form-body">
+ <td style="height: 100%;">
+ <table class="props-inner-table">
+ <th colspan="2">
+ <span tal:condition="python:len(mapper['new_sources']) == 1">
+ Select <span tal:replace="mapper/pretty_source_name"/> to add
+ </span>
+ <span tal:condition="python:len(mapper['new_sources']) > 1">
+ Select one or more <span tal:replace="mapper/pretty_sources_name"/> to add
+ </span>
+ </th>
+ <tr tal:repeat="bd mapper/new_sources">
+ <td>
+ <input type="checkbox"
+ tal:attributes="name python:'source_bd_' + bd['path']" />
+ </td>
+ <td tal:define="
+ bytes bd/props/size/value;
+ dummy python:here.bytes_to_value_units(bytes);
+ size python:dummy[0];
+ units python:dummy[1]">
+
+ <span tal:replace="bd/path" /> (<span tal:replace="size" /> <span tal:replace="units" /> - <span tal:replace="bd/pretty_type" />)
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" style="height: 100%;">
+
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ <tr class="props-form-footer">
+ <td colspan="2">
+ <table style="width: 100%;">
+ <tr>
+ <td align="left">
+
+ </td>
+ <td align="right">
+ <input type="button" name="cancel_button"
+ value="Cancel" class="form_button"
+ tal:define="
+ go_to_mapper_url python:'./?pagetype=52&mapper_type=' + mapper['mapper_type'] + '&mapper_id=' + mapper['mapper_id'] + '&storagename=' + storagename"
+ tal:attributes="
+ onclick python:'window.location.assign(\'' + go_to_mapper_url + '\')'" />
+
+ <input type="button" name="action_type"
+ value="Add" class="form_button"
+ tal:define="
+ prompt_msg python:'Do you really want to add selected ' + mapper['pretty_sources_name'] + ' to \\\'' + mapper['pretty_name'] + '\\\'?';
+ validate_url context/validate_html/absolute_url"
+ tal:attributes="
+ id add_sources_button_id;
+ onclick python:'return validate_and_submit_form(\'' + validate_url + '\', \'' + add_sources_form_id + '\', \'' + add_sources_button_id + '\', \'' + prompt_msg + '\')'" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </form>
</div>
<div tal:omit-tag="" metal:define-macro="display-props-tableless">
- <span tal:omit-tag=""
- tal:repeat="prop props">
- <tr tal:define="p prop/name;
- prop_pr_name prop/pretty_name"
- tal:condition="not: prop/hidden">
- <td tal:content="prop_pr_name"/>
- <td tal:define="prop_type prop/type;
- prop_units prop/units">
- <table>
- <tr>
- <td>
- <span tal:condition="python:prop_type == 'label'">
- <span tal:omit-tag=""
- tal:condition="prop/replacements|nothing">
- <input tal:attributes="type string:hidden;
- name p;
- value prop/value"/>
- <select tal:define="repls prop/replacements;
- select_id python:prefix + '_select_replace_block_' + p"
- tal:attributes="id select_id;
- onfocus python:'replace_properties_block__old_select_value = this.value';
- onchange python:'replace_properties_block(\'' + properties_span_id + '\', \'' + select_id + '\')'">
- <span tal:omit-tag=""
- tal:repeat="repl_name repls/repl_names">
- <option tal:attributes="value python:repls[repl_name]['path']"/><span tal:replace="repl_name"/>
- </span>
- </select>
- </span>
- <span tal:omit-tag=""
- tal:condition="not: prop/replacements|nothing">
- <span tal:condition="python: prop_units == 'bytes'">
- <span tal:define="dummy python: here.bytes_to_value_units(prop['value']);
- value python: str(dummy[0]) + ' ' + str(dummy[1])"
- tal:replace="value"/>
- </span>
- <span tal:condition="python: prop_units != 'bytes'"
- tal:replace="prop/value"/>
- </span>
- </span>
-
-
-
- <input tal:condition="python:prop_type == 'text'"
- tal:attributes="name p;
- type string:text;
- value prop/value;
- onkeypress python:'return validate_text_keypress(this, event, 2, \'' + prop['validation']['illegal_chars'] + '\', ' + str(prop['validation']['max_length']) + ')';
- onchange python:'validate_text(this, 2, \'' + prop['validation']['illegal_chars'] + '\', \'' + prop['validation']['reserved_words'] + '\', ' + str(prop['validation']['min_length']) + ', ' + str(prop['validation']['max_length']) + ', \'' + form_submit_button_id + '\')'"/>
-
-
+ <tal:block tal:repeat="prop props">
+ <tr tal:condition="not: prop/hidden"
+ tal:define="
+ p prop/name;
+ prop_pr_name prop/pretty_name">
+ <td tal:content="prop_pr_name" />
+ <td tal:define="
+ prop_type prop/type;
+ prop_units prop/units">
+ <table>
+ <tr>
+ <td>
+ <span tal:condition="python:prop_type == 'label'">
+ <tal:block tal:condition="prop/replacements|nothing">
+ <input type="hidden"
+ tal:attributes="
+ name p;
+ value prop/value" />
+ <select
+ tal:define="
+ repls prop/replacements;
+ select_id python:prefix + '_select_replace_block_' + p"
+ tal:attributes="
+ id select_id;
+ onfocus python:'replace_properties_block__old_select_value = this.value';
+ onchange python:'replace_properties_block(\'' + properties_span_id + '\', \'' + select_id + '\')'">
+ <tal:block tal:repeat="repl_name repls/repl_names">
+ <option tal:attributes="
+ value python:repls[repl_name]['path']" />
+ <span tal:replace="repl_name" />
+ </tal:block>
+ </select>
+ </tal:block>
+
+ <tal:block tal:condition="not: prop/replacements|nothing">
+ <span tal:condition="python: prop_units == 'bytes'">
+ <span tal:define="
+ dummy python: here.bytes_to_value_units(prop['value']);
+ value python: str(dummy[0]) + ' ' + str(dummy[1])"
+ tal:replace="value" />
+ </span>
+ <span tal:condition="python: prop_units != 'bytes'"
+ tal:replace="prop/value" />
+ </tal:block>
+ </span>
- <span tal:omit-tag=""
- tal:condition="python:prop_type == 'int' and prop_units != 'bytes'">
- <input tal:attributes="name p;
- type string:text;
- size string:15;
- value prop/value;
- onchange python:'validate_int(this, 2, ' + str(prop['validation']['min']) + ', ' + str(prop['validation']['max']) + ', ' + str(prop['validation']['step']) + ', \'' + prop_units + '\', \'' + form_submit_button_id + '\')'"
- onkeypress="return validate_int_keypress(this, event, 2)"/>
- (<span tal:replace="prop/validation/min"/> - <span tal:replace="prop/validation/max"/>)
- <span tal:replace="prop_units"/>
- </span>
- <span tal:omit-tag=""
- tal:condition="python:prop_type == 'int' and prop_units == 'bytes'">
- <span tal:define="bytes prop/value;
- dummy python:here.bytes_to_value_prefunits(bytes);
- value python:dummy[0];
- units python:dummy[1];
- minim python:here.convert_bytes(prop['validation']['min'], units);
- maxim python:here.convert_bytes(prop['validation']['max'], units);
- step python:here.convert_bytes(prop['validation']['step'], units)">
- <input tal:attributes="name p;
- type string:text;
- size string:15;
- value value;
- onchange python:'validate_float(this, 2, ' + str(minim) + ', ' + str(maxim) + ', ' + str(step) + ', \'' + units + '\', \'' + form_submit_button_id + '\')'"
- onkeypress="return validate_float_keypress(this, event, 2)"/>
- (<span tal:replace="minim"/> - <span tal:replace="maxim"/>)
- <span tal:replace="units"/>
- </span>
- </span>
+ <input type="text"
+ tal:condition="python:prop_type == 'text'"
+ tal:attributes="
+ name p;
+ value prop/value;
+ onkeypress python:'return validate_text_keypress(this, event, 2, \'' + prop['validation']['illegal_chars'] + '\', ' + str(prop['validation']['max_length']) + ')';
+ onchange python:'validate_text(this, 2, \'' + prop['validation']['illegal_chars'] + '\', \'' + prop['validation']['reserved_words'] + '\', ' + str(prop['validation']['min_length']) + ', ' + str(prop['validation']['max_length']) + ', \'' + form_submit_button_id + '\')'" />
+
+ <tal:block tal:condition="python:prop_type == 'int' and prop_units != 'bytes'">
+ <input type="text" size="15"
+ tal:attributes="
+ name p;
+ value prop/value;
+ onchange python:'validate_int(this, 2, ' + str(prop['validation']['min']) + ', ' + str(prop['validation']['max']) + ', ' + str(prop['validation']['step']) + ', \'' + prop_units + '\', \'' + form_submit_button_id + '\')'"
+ onkeypress="return validate_int_keypress(this, event, 2)" />
+ (<span tal:replace="prop/validation/min" /> - <span tal:replace="prop/validation/max" />) <span tal:replace="prop_units" />
+ </tal:block>
+ <tal:block tal:condition="python:prop_type == 'int' and prop_units == 'bytes'">
+ <span tal:define="
+ bytes prop/value;
+ dummy python:here.bytes_to_value_prefunits(bytes);
+ value python:dummy[0];
+ units python:dummy[1];
+ minim python:here.convert_bytes(prop['validation']['min'], units);
+ maxim python:here.convert_bytes(prop['validation']['max'], units);
+ step python:here.convert_bytes(prop['validation']['step'], units)">
+ <input type="string" size="15"
+ tal:attributes="
+ name p;
+ value value;
+ onchange python:'validate_float(this, 2, ' + str(minim) + ', ' + str(maxim) + ', ' + str(step) + ', \'' + units + '\', \'' + form_submit_button_id + '\')'"
+ onkeypress="return validate_float_keypress(this, event, 2)" />
+ (<span tal:replace="minim" /> - <span tal:replace="maxim" />) <span tal:replace="units" />
+ </span>
+ </tal:block>
- <span tal:condition="python:prop_type == 'select'">
- <select tal:define="prop_options prop/value"
- tal:attributes="name p">
- <span tal:omit-tag=""
- tal:condition="python: prop_units != 'bytes'"
- tal:repeat="prop_opt prop_options">
- <option tal:attributes="value prop_opt"/><span tal:replace="prop_opt"/>
- </span>
- <span tal:omit-tag=""
- tal:condition="python: prop_units == 'bytes'"
- tal:repeat="prop_opt prop_options">
- <option tal:attributes="value prop_opt"/><span tal:define="dummy python: here.bytes_to_value_units(prop_opt);
- value python: str(dummy[0]) + ' ' + str(dummy[1])"
- tal:replace="value"/>
- </span>
- </select>
- </span>
- </td>
- <td>
- <span tal:condition="python: prop_units != 'bytes'"
- tal:replace="prop_units"/>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </span>
- <tr>
- <td colspan="2" style="height: 100%;">
-
- </td>
- </tr>
+ <tal:block tal:condition="python:prop_type == 'select'">
+ <select tal:define="prop_options prop/value" tal:attributes="name p">
+ <tal:block
+ tal:condition="python: prop_units != 'bytes'"
+ tal:repeat="prop_opt prop_options">
+ <option tal:attributes="value prop_opt" />
+ <span tal:replace="prop_opt" />
+ </tal:block>
+ <tal:block
+ tal:condition="python: prop_units == 'bytes'"
+ tal:repeat="prop_opt prop_options">
+ <option tal:attributes="value prop_opt" />
+ <span
+ tal:define="
+ dummy python: here.bytes_to_value_units(prop_opt);
+ value python: str(dummy[0]) + ' ' + str(dummy[1])"
+ tal:replace="value" />
+ </tal:block>
+ </select>
+ </tal:block>
+ </td>
+ <td>
+ <span tal:condition="python: prop_units != 'bytes'" tal:replace="prop_units" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </tal:block>
+ <tr>
+ <td colspan="2" style="height: 100%;">
+
+ </td>
+ </tr>
</div>
<div tal:omit-tag="" metal:define-macro="display-props">
@@ -968,7 +943,7 @@
<div metal:define-macro="display-BD">
<div metal:use-macro="here/form-macros/macros/forms-css" />
- <span tal:omit-tag=""
+ <span tal:omit-tag=""
tal:define="mapper string:;
conts python:bd_data['contents'];
prefix prefix|bd_data/path;
@@ -978,9 +953,8 @@
apply_button_id python:prefix + 'apply_button_id';
form_submit_button_id apply_button_id;
content_span_id python:prefix + 'content_span_id'">
- <form tal:attributes="id bd_form_id;
- method string:get">
+ <form method="get" tal:attributes="id bd_form_id">
<input tal:attributes="type string:hidden;
name string:pagetype;
value string:commit_changes"/>
@@ -1089,11 +1063,11 @@
tal:attributes="id select_content_id;
name string:content_id;
onchange funct">
- <span tal:omit-tag=""
- tal:repeat="cont conts">
+ <span tal:omit-tag="" tal:repeat="cont conts">
<option tal:attributes="value cont/id"/><span tal:replace="cont/name"/>
</span>
</select>
+
<span tal:define="cont python:conts[0]"
tal:condition="python:len(conts) == 1">
<input tal:attributes="id select_content_id;
@@ -1338,8 +1312,10 @@
value="Reset"
onclick="return reset_form(this.form)"
class="form_button"/>
- <input tal:define="prompt_msg python:'Do you really want to apply changes to ' + mapper['pretty_type'] + ' \\\'' + mapper['pretty_name'] + '\\\'?';
- validate_url context/validate_html/absolute_url"
+
+ <input tal:define="
+ prompt_msg python:'Do you really want to apply changes to ' + mapper['pretty_type'] + ' \\\'' + mapper['pretty_name'] + '\\\'?';
+ validate_url context/validate_html/absolute_url"
tal:attributes="id apply_button_id;
type string:button;
name string:action_type;
--- conga/luci/storage/storage_probing.js 2007/09/25 16:49:36 1.1
+++ conga/luci/storage/storage_probing.js 2007/09/25 22:47:05 1.2
@@ -9,7 +9,9 @@
function strip_left(txt) {
for (var i = 0 ; i < txt.length ; i++) {
- if (txt[i] == " " || txt[i] == "\n") {
+ if (txt[i] == ' ' || txt[i] == '\n' ||
+ txt[i] == '\r' || txt[i] == '\t')
+ {
continue;
}
return txt.substr(i);
--- conga/luci/storage/storage_utils.js 2007/09/25 16:49:36 1.1
+++ conga/luci/storage/storage_utils.js 2007/09/25 22:47:05 1.2
@@ -9,7 +9,9 @@
function strip_left(txt) {
for (var i = 0 ; i < txt.length ; i++) {
- if (txt[i] == " " || txt[i] == "\n") {
+ if (txt[i] == ' ' || txt[i] == '\n' ||
+ txt[i] == '\r' || txt[i] == '\t')
+ {
continue;
}
return txt.substr(i);
--- conga/luci/storage/storage_validation.js 2007/09/25 16:49:36 1.1
+++ conga/luci/storage/storage_validation.js 2007/09/25 22:47:05 1.2
@@ -305,7 +305,9 @@
function strip_left(txt) {
for (var i = 0 ; i < txt.length ; i++) {
- if (txt[i] == " " || txt[i] == "\n") {
+ if (txt[i] == ' ' || txt[i] == '\n' ||
+ txt[i] == '\r' || txt[i] == '\t')
+ {
continue;
}
return txt.substr(i);
@@ -346,7 +348,7 @@
}
}
- alert(err_msg);
+ alert(err_msg || 'An unknown error occurred');
}
} else {
alert("Error retrieving data from server");
--- conga/luci/storage/validate_html 2007/09/25 18:55:13 1.6
+++ conga/luci/storage/validate_html 2007/09/25 22:47:05 1.7
@@ -31,7 +31,7 @@
<tal:block tal:condition="access_to_host_allowed">
<span tal:condition="python:action_type == 'Validate'"
- tal:content="python:here.validate(storage_report, request)" />
+ tal:replace="python:here.validate(storage_report, request)" />
<tal:block tal:condition="python:action_type != 'Validate'">
This form is to be used for validation only
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-09-25 22:47 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-09 17:12 [Cluster-devel] conga/luci cluster/form-chooser cluster/form-m rmccabe
-- strict thread matches above, loose matches on Subject: below --
2006-11-10 19:44 rmccabe
2006-12-06 18:38 rmccabe
2006-12-07 17:54 rmccabe
2006-12-21 21:26 kupcevic
2007-02-23 22:07 rmccabe
2007-03-12 4:22 rmccabe
2007-03-12 4:24 rmccabe
2007-03-12 4:25 rmccabe
2007-09-25 22:47 rmccabe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).