[Cluster-devel] conga/luci cluster/form-macros site/luci/Exten ...
rmccabe at sourceware.org
rmccabe at sourceware.org
Tue Jun 19 15:54:11 UTC 2007
CVSROOT: /cvs/cluster
Module name: conga
Branch: RHEL5
Changes by: rmccabe at sourceware.org 2007-06-19 15:54:10
Modified files:
luci/cluster : form-macros
luci/site/luci/Extensions: LuciClusterActions.py
LuciClusterInfo.py
cluster_adapters.py
conga_constants.py
Removed files:
luci/python/Extensions: .cvsignore
Log message:
Fix bz238726: Conga provides no way to remove a dead node from a cluster (depends on 244867)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.90.2.23&r2=1.90.2.24
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/python/Extensions/.cvsignore.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1&r2=NONE
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciClusterActions.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1.4.1&r2=1.1.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciClusterInfo.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1.4.1&r2=1.1.4.2
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.30&r2=1.120.2.31
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.10&r2=1.19.2.11
--- conga/luci/cluster/form-macros 2007/06/18 18:39:31 1.90.2.23
+++ conga/luci/cluster/form-macros 2007/06/19 15:54:09 1.90.2.24
@@ -3117,7 +3117,11 @@
<option tal:attributes="value nodeinfo/delete_url"
tal:condition="python: not 'ricci_error' in nodeinfo">
Delete this node</option>
+ <option tal:attributes="value nodeinfo/force_delete_url"
+ tal:condition="python: 'ricci_error' in nodeinfo">
+ Force the deletion of this node</option>
</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>
@@ -3129,6 +3133,7 @@
<select name="gourl">
<option value="">Choose a Task...</option>
<option tal:attributes="value nodeinfo/fence_url | nothing">Fence this node</option>
+ <option tal:attributes="value nodeinfo/force_delete_url | nothing">Force the deletion of this node</option>
</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)" />
@@ -3537,6 +3542,7 @@
<select class="node" name="gourl">
<option value="">Choose a Task...</option>
<option tal:attributes="value nd/fence_it_url | nothing">Fence this node</option>
+ <option tal:attributes="value nd/force_delete_url| nothing">Force the deletion of this node</option>
</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)" />
--- conga/luci/site/luci/Extensions/Attic/LuciClusterActions.py 2007/06/18 18:39:32 1.1.4.1
+++ conga/luci/site/luci/Extensions/Attic/LuciClusterActions.py 2007/06/19 15:54:10 1.1.4.2
@@ -17,7 +17,7 @@
CLUSTER_NODE_NEED_AUTH
from conga_constants import CLUSTER_CONFIG, LUCI_DEBUG_MODE, \
- NODE_DELETE, CLUSTER_DELETE, CLUSTERLIST, \
+ NODE_DELETE, NODE_FORCE_DELETE, CLUSTER_DELETE, CLUSTERLIST, \
NODE_FENCE, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, NODE_REBOOT, \
RESOURCE_ADD, RESOURCE_CONFIG, RESOURCE_REMOVE, \
SERVICE_DELETE, SERVICE_RESTART, SERVICE_START, SERVICE_STOP
@@ -283,6 +283,64 @@
% (nodename_resolved, e, str(e)))
return True
+def NodeForceDeleteFromCluster(self, model, clustername, nodename, nodename_resolved):
+ rc = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved, nodename ], exclude_busy=True)
+
+ if rc is None:
+ rc = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved, nodename ])
+
+ if rc is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC0: no agent to delete node %s "%s"' \
+ % (nodename_resolved, clustername))
+ return None
+
+ try:
+ model.deleteNodeByName(nodename.lower())
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC1: deleteNode %s: %r %s' \
+ % (nodename, e, str(e)))
+ return None
+
+ try:
+ model.setModified(True)
+ str_buf = str(model.exportModelAsString())
+ if not str_buf:
+ raise Exception, 'model string is blank'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC2: exportModelAsString: %r %s' \
+ % (e, str(e)))
+ return None
+
+ batch_number, result = rq.setClusterConf(rc, str_buf)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC3: batch number is None')
+ return None
+
+ try:
+ ret = delClusterSystem(self, clustername, nodename_resolved)
+ if ret is not None:
+ raise Exception, ret
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC4: error deleting %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), NODE_FORCE_DELETE,
+ 'Forcing the deletion of node "%s"' % nodename)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC5: failed to set flags: %r %s' \
+ % (e, str(e)))
+ return True
+
def NodeDeleteFromCluster( self,
rc,
model,
@@ -354,7 +412,7 @@
batch_number, result = rq.setClusterConf(rc2, str_buf)
if batch_number is None:
if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('ND8: batch number is None after del node in NTP')
+ luci_log.debug_verbose('ND8: batch number is None')
return None
try:
--- conga/luci/site/luci/Extensions/Attic/LuciClusterInfo.py 2007/06/18 18:39:32 1.1.4.1
+++ conga/luci/site/luci/Extensions/Attic/LuciClusterInfo.py 2007/06/19 15:54:10 1.1.4.2
@@ -17,7 +17,7 @@
from conga_constants import CLUSTER_CONFIG, CLUSTER_DELETE, \
CLUSTER_PROCESS, CLUSTER_RESTART, CLUSTER_START, CLUSTER_STOP, \
- FDOM, FENCEDEV, NODE, NODE_ACTIVE, \
+ NODE_FORCE_DELETE, FDOM, FENCEDEV, NODE, NODE_ACTIVE, \
NODE_ACTIVE_STR, NODE_DELETE, NODE_FENCE, NODE_INACTIVE, \
NODE_INACTIVE_STR, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, \
NODE_PROCESS, NODE_REBOOT, NODE_UNKNOWN, NODE_UNKNOWN_STR, \
@@ -149,18 +149,10 @@
if not doc:
try:
from LuciDB import getClusterStatusDB
+ fvars = GetReqVars(request, [ 'clustername' ])
- clustername = cluname
+ clustername = fvars['clustername']
if clustername is None:
- try:
- clustername = request['clustername']
- except:
- try:
- clustername = request.form['clustername']
- except:
- pass
-
- if not clustername:
raise Exception, 'unable to determine cluster name'
cinfo = getClusterStatusDB(self, clustername)
@@ -860,6 +852,8 @@
else:
infohash['fence_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
% (baseurl, NODE_PROCESS, NODE_FENCE, nodename, clustername)
+ infohash['force_delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FORCE_DELETE, nodename, clustername)
# figure out current services running on this node
svc_dict_list = list()
@@ -1021,6 +1015,8 @@
else:
nl_map['fence_it_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
% (baseurl, NODE_PROCESS, NODE_FENCE, name, clustername)
+ nl_map['force_delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FORCE_DELETE, name, clustername)
# figure out current services running on this node
svc_dict_list = list()
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2007/06/18 18:39:32 1.120.2.30
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2007/06/19 15:54:10 1.120.2.31
@@ -35,12 +35,12 @@
DISABLE_SVC_TASK, ENABLE_SVC_TASK, FDOM, FDOM_ADD, FENCEDEV, \
FENCEDEV_NODE_CONFIG, FENCEDEVS, FLAG_DESC, INSTALL_TASK, \
LAST_STATUS, LUCI_DEBUG_MODE, NODE, NODE_ADD, NODE_DELETE, \
- NODE_FENCE, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, NODE_REBOOT, \
- NODES, POSSIBLE_REBOOT_MESSAGE, PRE_CFG, PRE_INSTALL, PRE_JOIN, \
- REBOOT_TASK, REDIRECT_MSG, RESOURCES, RICCI_CONNECT_FAILURE, \
+ NODE_FENCE, NODE_FORCE_DELETE, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, \
+ NODE_REBOOT, NODES, POSSIBLE_REBOOT_MESSAGE, PRE_CFG, PRE_INSTALL, \
+ PRE_JOIN, REBOOT_TASK, REDIRECT_MSG, RESOURCES, RICCI_CONNECT_FAILURE, \
RICCI_CONNECT_FAILURE_MSG, SEND_CONF, SERVICE_ADD, SERVICE_CONFIG, \
SERVICE_LIST, SERVICES, START_NODE, TASKTYPE, VM_ADD, VM_CONFIG, \
- REDIRECT_SEC
+ REDIRECT_SEC, LUCI_CLUSTER_BASE_URL
from FenceHandler import validateNewFenceDevice, \
validateFenceDevice, validate_fenceinstance, \
@@ -718,7 +718,7 @@
errors = list()
try:
- form_xml = request['form_xml']
+ form_xml = request['form_xml'].strip()
if not form_xml:
raise KeyError, 'form_xml must not be blank'
except Exception, e:
@@ -740,7 +740,7 @@
doc = minidom.parseString(form_xml)
forms = doc.getElementsByTagName('form')
if len(forms) < 1:
- raise
+ raise Exception, 'invalid XML'
except Exception, e:
if LUCI_DEBUG_MODE is True:
luci_log.debug_verbose('vSA1: error: %r %s' % (e, str(e)))
@@ -1681,7 +1681,7 @@
errors = list()
try:
- form_xml = request['fence_xml']
+ form_xml = request['fence_xml'].strip()
if not form_xml:
raise KeyError, 'form_xml must not be blank'
except Exception, e:
@@ -2637,7 +2637,9 @@
return getRicciAgent(self, clustername)
def clusterTaskProcess(self, model, request):
- fvar = GetReqVars(request, [ 'task', 'clustername' ])
+ fvar = GetReqVars(request, [ 'task', 'clustername', 'URL' ])
+
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
task = fvar['task']
if task is None:
@@ -2646,7 +2648,7 @@
return 'No cluster task was given'
if not model:
- cluname = fvar['cluname']
+ cluname = fvar['clustername']
if cluname is None:
if LUCI_DEBUG_MODE is True:
luci_log.debug('CTP1: no cluster name')
@@ -2684,7 +2686,7 @@
response = request.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], redirect_page, model.getClusterName()))
+ % (baseurl, redirect_page, model.getClusterName()))
def nodeTaskProcess(self, model, request):
fvar = GetReqVars(request, [ 'task', 'clustername', 'nodename', 'URL' ])
@@ -2692,6 +2694,7 @@
task = fvar['task']
clustername = fvar['clustername']
nodename = fvar['nodename']
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
if clustername is None:
if LUCI_DEBUG_MODE is True:
@@ -2711,10 +2714,9 @@
nodename_resolved = resolve_nodename(self, clustername, nodename)
response = request.RESPONSE
- if task != NODE_FENCE:
- # Fencing is the only task for which we don't
- # want to talk to the node on which the action is
- # to be performed.
+ if task != NODE_FENCE and task != NODE_FORCE_DELETE:
+ # Fencing and forced deletion are the only tasks
+ # for which we don't want to talk to the target node.
try:
rc = RicciCommunicator(nodename_resolved)
if not rc:
@@ -2773,7 +2775,7 @@
return (False, {'errors': [ 'Node "%s" failed to leave cluster "%s"' % (nodename_resolved, clustername) ]})
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], NODES, clustername))
+ % (baseurl, NODES, clustername))
elif task == NODE_JOIN_CLUSTER:
from LuciClusterActions import NodeJoinCluster
if NodeJoinCluster(self, rc, clustername, nodename_resolved) is None:
@@ -2782,7 +2784,7 @@
return (False, {'errors': [ 'Node "%s" failed to join cluster "%s"' % (nodename_resolved, clustername) ]})
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], NODES, clustername))
+ % (baseurl, NODES, clustername))
elif task == NODE_REBOOT:
from LuciClusterActions import NodeReboot
if NodeReboot(self, rc, clustername, nodename_resolved) is None:
@@ -2792,7 +2794,7 @@
% nodename_resolved ]})
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], NODES, clustername))
+ % (baseurl, NODES, clustername))
elif task == NODE_FENCE:
from LuciClusterActions import NodeFence
if NodeFence(self, clustername, nodename, nodename_resolved) is None:
@@ -2801,7 +2803,7 @@
return (False, {'errors': [ 'Fencing of node "%s" failed' \
% nodename_resolved]})
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], NODES, clustername))
+ % (baseurl, NODES, clustername))
elif task == NODE_DELETE:
from LuciClusterActions import NodeDeleteFromCluster
if NodeDeleteFromCluster(self, rc, model, clustername, nodename, nodename_resolved) is None:
@@ -2810,7 +2812,16 @@
return (False, {'errors': [ 'Deletion of node "%s" from cluster "%s" failed' % (nodename_resolved, clustername) ]})
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (request['URL'], NODES, clustername))
+ % (baseurl, NODES, clustername))
+ elif task == NODE_FORCE_DELETE:
+ from LuciClusterActions import NodeForceDeleteFromCluster
+ if NodeForceDeleteFromCluster(self, model, clustername, nodename, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NTP13: nodeForceDelete failed')
+ return (False, {'errors': [ 'Deletion of node "%s" from cluster "%s" failed' % (nodename_resolved, clustername) ]})
+
+ response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, NODES, clustername))
def isClusterBusy(self, req):
items = None
@@ -3178,11 +3189,13 @@
fvars = GetReqVars(req,
[ 'clustername', 'servicename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
ret = RestartCluSvc(self, rc, fvars)
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (fvars['URL'], SERVICE_LIST, fvars['clustername']))
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
else:
return ret
@@ -3191,11 +3204,13 @@
fvars = GetReqVars(req,
[ 'clustername', 'servicename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
ret = StopCluSvc(self, rc, fvars)
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (fvars['URL'], SERVICE_LIST, fvars['clustername']))
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
else:
return ret
@@ -3204,11 +3219,13 @@
fvars = GetReqVars(req,
[ 'clustername', 'servicename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
ret = StartCluSvc(self, rc, fvars)
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (fvars['URL'], SERVICE_LIST, fvars['clustername']))
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
else:
return ret
@@ -3217,6 +3234,8 @@
fvars = GetReqVars(req,
[ 'clustername', 'servicename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
try:
model = LuciExtractCluModel(self, req,
cluster_name=fvars['clustername'])
@@ -3229,7 +3248,7 @@
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (fvars['URL'], SERVICES, fvars['clustername']))
+ % (baseurl, SERVICES, fvars['clustername']))
else:
return ret
@@ -3238,11 +3257,13 @@
fvars = GetReqVars(req,
[ 'clustername', 'servicename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
ret = MigrateCluSvc(self, rc, fvars)
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (fvars['URL'], SERVICE_LIST, fvars['clustername']))
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
else:
return ret
@@ -3251,6 +3272,8 @@
fvars = GetReqVars(req,
[ 'clustername', 'resourcename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
try:
model = LuciExtractCluModel(self, req,
cluster_name=fvars['clustername'])
@@ -3265,12 +3288,14 @@
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (fvars['URL'], RESOURCES, fvars['clustername']))
+ % (baseurl, RESOURCES, fvars['clustername']))
else:
return ret
def resourceAdd(self, req, model, res):
from LuciClusterActions import AddResource, EditResource
+ fvars = GetReqVars(req, [ 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
try:
cluname = model.getClusterName()
@@ -3291,7 +3316,7 @@
if ret is None:
response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (req['URL'], RESOURCES, cluname))
+ % (baseurl, RESOURCES, cluname))
else:
return ret
--- conga/luci/site/luci/Extensions/conga_constants.py 2007/06/18 18:39:33 1.19.2.10
+++ conga/luci/site/luci/Extensions/conga_constants.py 2007/06/19 15:54:10 1.19.2.11
@@ -59,17 +59,18 @@
SYS_SERVICE_UPDATE = '91'
# Cluster tasks
-CLUSTER_STOP = '1000'
-CLUSTER_START = '1001'
-CLUSTER_RESTART = '1002'
-CLUSTER_DELETE = '1003'
+CLUSTER_STOP = '1000'
+CLUSTER_START = '1001'
+CLUSTER_RESTART = '1002'
+CLUSTER_DELETE = '1003'
# Node tasks
-NODE_LEAVE_CLUSTER = '100'
-NODE_JOIN_CLUSTER = '101'
-NODE_REBOOT = '102'
-NODE_FENCE = '103'
-NODE_DELETE = '104'
+NODE_LEAVE_CLUSTER = '100'
+NODE_JOIN_CLUSTER = '101'
+NODE_REBOOT = '102'
+NODE_FENCE = '103'
+NODE_DELETE = '104'
+NODE_FORCE_DELETE = '105'
# General tasks
BASECLUSTER = '201'
More information about the Cluster-devel
mailing list