From: rmccabe@sourceware.org <rmccabe@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] conga/luci/site/luci/Extensions cluster_adapte ...
Date: 12 Dec 2007 15:45:27 -0000 [thread overview]
Message-ID: <20071212154527.2580.qmail@sourceware.org> (raw)
CVSROOT: /cvs/cluster
Module name: conga
Changes by: rmccabe at sourceware.org 2007-12-12 15:45:27
Modified files:
luci/site/luci/Extensions: cluster_adapters.py
Log message:
Use new form validation routines
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.275&r2=1.276
--- conga/luci/site/luci/Extensions/cluster_adapters.py 2007/11/06 23:05:07 1.275
+++ conga/luci/site/luci/Extensions/cluster_adapters.py 2007/12/12 15:45:27 1.276
@@ -7,44 +7,34 @@
from xml.dom import minidom
-from ClusterModel.FailoverDomain import FailoverDomain
-from ClusterModel.FailoverDomainNode import FailoverDomainNode
-from ClusterModel.RefObject import RefObject
from ClusterModel.ClusterNode import ClusterNode
-from ClusterModel.Service import Service
-from ClusterModel.Lockserver import Lockserver
-from ClusterModel.Vm import Vm
-from ClusterModel.FenceXVMd import FenceXVMd
-from ClusterModel.QuorumD import QuorumD
-from ClusterModel.Heuristic import Heuristic
-from ClusterModel.Fence import Fence
-from ClusterModel.Method import Method
import RicciQueries as rq
from HelperFunctions import resolveOSType, send_batch_to_hosts
from LuciSyslog import get_logger
-from ResourceHandler import create_resource
from homebase_adapters import parseHostForm
from LuciClusterActions import propagateClusterConfAsync
+from LuciZopeAsync import validate_clusvc_async
+
from LuciClusterInfo import getClusterInfo, \
getModelBuilder, LuciExtractCluModel
from conga_constants import BATCH_ID, CLUNODE_CREATE_ERRORS, \
CLUSTER_ADD, CLUSTER_CONFIG, CLUSTER_DAEMON, CLUSTER_DELETE, \
CLUSTER_FOLDER_PATH, CLUSTER_RESTART, CLUSTER_START, CLUSTER_STOP, \
- DISABLE_SVC_TASK, ENABLE_SVC_TASK, FDOM, FDOM_ADD, FENCEDEV, \
+ DISABLE_SVC_TASK, ENABLE_SVC_TASK, FDOM, FENCEDEV, \
FENCEDEV_NODE_CONFIG, FENCEDEVS, FLAG_DESC, INSTALL_TASK, CLUSTER_PROCESS, \
LAST_STATUS, LUCI_DEBUG_MODE, NODE, NODE_ADD, NODE_DELETE, \
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, \
+ RICCI_CONNECT_FAILURE_MSG, SEND_CONF, \
+ SERVICE_LIST, SERVICES, START_NODE, TASKTYPE, \
REDIRECT_SEC, LUCI_CLUSTER_BASE_URL, FENCE_XVM_KEY_CREATE
from FenceHandler import validateNewFenceDevice, \
- validateFenceDevice, validate_fenceinstance, FD_VAL_SUCCESS
+ validateFenceDevice, FD_VAL_SUCCESS
from ricci_communicator import RicciCommunicator, RicciError, \
batch_status, extract_module_status
@@ -274,23 +264,6 @@
request.SESSION.set('create_cluster', add_cluster)
return (False, { 'errors': errors, 'messages': messages })
- node_list = add_cluster['nodes'].keys()
- batchNode = rq.createClusterBatch(add_cluster['cluster_os'],
- clustername,
- clustername,
- node_list,
- True,
- True,
- add_cluster['shared_storage'],
- False,
- add_cluster['download_pkgs'],
- lockservers)
-
- if not batchNode:
- request.SESSION.set('create_cluster', add_cluster)
- errors.append('Unable to generate cluster creation ricci command')
- return (False, { 'errors': errors, 'messages': messages })
-
error = manageCluster(self, clustername,
add_cluster['nodes'], add_cluster['cluster_os'])
if error:
@@ -298,37 +271,30 @@
request.SESSION.set('create_cluster', add_cluster)
return (False, { 'errors': errors, 'messages': messages })
+ node_list = add_cluster['nodes'].keys()
+
+ ret = send_batch_to_hosts(node_list, 10, rq.create_cluster,
+ add_cluster['cluster_os'], clustername, clustername,
+ node_list, True, True, add_cluster['shared_storage'], False,
+ add_cluster['download_pkgs'], lockservers)
+
batch_id_map = {}
- for i in node_list:
- try:
- rc = RicciCommunicator(i)
- if not rc:
- raise Exception, 'rc is None'
- except Exception, e:
- msg = 'Unable to connect to the ricci agent on %s: %s' % (i, str(e))
+ for i in ret.iterkeys():
+ if ret[i].has_key('error'):
+ msg = 'Unable to connect to the ricci agent on %s: %s' \
+ % (i, ret[i]['err_msg'])
errors.append(msg)
if LUCI_DEBUG_MODE is True:
luci_log.debug_verbose(msg)
-
- if len(batch_id_map) == 0:
- request.SESSION.set('create_cluster', add_cluster)
- return (False, { 'errors': errors, 'messages': messages })
continue
+ batch_id_map[i] = ret[i]['batch_result']
- try:
- resultNode = rc.process_batch(batchNode, async=True)
- batch_id_map[i] = resultNode.getAttribute('batch_id')
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('validateCreateCluster0: %s: %r %s' \
- % (i, e, str(e)))
- errors.append('An error occurred while attempting to add cluster node "%s"' % i)
- if len(batch_id_map) == 0:
- request.SESSION.set('create_cluster', add_cluster)
- return (False, { 'errors': errors, 'messages': messages })
- continue
+ if len(batch_id_map) == 0:
+ request.SESSION.set('create_cluster', add_cluster)
+ return (False, { 'errors': errors, 'messages': messages })
buildClusterCreateFlags(self, batch_id_map, clustername)
+
response = request.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
% (request['URL'], CLUSTER_CONFIG, clustername))
@@ -712,18 +678,16 @@
% (request['URL'], CLUSTER_CONFIG, clustername))
def validateServiceAdd(self, request):
- errors = list()
- fvar = GetReqVars(request, [ 'form_xml', 'clustername', 'domain', 'recovery', 'svc_name', 'action', 'URL' ])
+ from LuciValidation import validate_clusvc_add
+ fvar = GetReqVars(request, [ 'clustername', 'URL' ])
baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- clustername = fvar['clustername']
- form_xml = fvar['form_xml']
- if form_xml is None:
- form_xml = ''
+ clustername = fvar['clustername']
+ if clustername is None:
if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA0: no form_xml')
-
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
model = LuciExtractCluModel(self, request, clustername)
if model is None:
@@ -731,1060 +695,222 @@
luci_log.debug_verbose('vSA1: no model')
return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
- forms = []
- if form_xml.strip():
- try:
- doc = minidom.parseString(form_xml)
- forms = doc.getElementsByTagName('form')
- if len(forms) < 1:
- raise Exception, 'invalid XML'
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA1: error: %r %s: %r' % (e, str(e), form_xml))
- return (False, { 'errors': [ 'The resource data submitted for this service is not properly formed' ]})
-
- form_hash = {}
- form_hash['toplevel'] = { 'form': None, 'kids': [] }
- for i in forms:
- form_id = i.getAttribute('id')
- form_parent = i.getAttribute('parent')
- if not form_id or not form_parent:
- continue
- ielems = i.getElementsByTagName('input')
- if not ielems or len(ielems) < 1:
- continue
- if not form_id in form_hash:
- form_hash[form_id] = {'form': i, 'kids': []}
- elif not form_hash[form_id]['form']:
- form_hash[form_id]['form'] = i
- if not form_parent in form_hash:
- form_hash[form_parent] = {'form': None, 'kids': []}
- form_hash[form_parent]['kids'].append(form_id)
- dummy_form = {}
-
- for i in ielems:
- try:
- input_type = str(i.getAttribute('type'))
- except:
- continue
- if not input_type or input_type == 'button':
- continue
- try:
- dummy_form[str(i.getAttribute('name'))] = str(i.getAttribute('value'))
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA2: parsing XML: %r %s' \
- % (e, str(e)))
-
- try:
- res_type = dummy_form['type'].strip()
- if not res_type:
- raise Exception, 'no resource type'
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA3: %r %s' % (e, str(e)))
- return (False, { 'errors': [ 'No resource type was specified' ]})
-
- try:
- if res_type == 'ip':
- dummy_form['resourceName'] = dummy_form['ip_address']
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA3a: type is ip but no addr: %r %s' \
- % (e, str(e)))
- return (False, { 'errors': [ 'No IP address was given' ]})
-
- try:
- if dummy_form.has_key('immutable'):
- newRes = model.getResourceByName(dummy_form['resourceName'])
- resObj = RefObject(newRes)
- resObj.setRef(newRes.getName())
- else:
- resObj = create_resource(res_type, dummy_form, model)
- except Exception, e:
- resObj = None
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA4: type %s: %r %s' \
- % (res_type, e, str(e)))
-
- if resObj is None:
- return (False, { 'errors': [ 'An error occurred while adding %s' % res_type ]})
-
- if dummy_form.has_key('__independent_subtree'):
- resObj.addAttribute('__independent_subtree', '1')
- else:
- resObj.removeAttribute('__independent_subtree')
- form_hash[form_id]['obj'] = resObj
+ ret = validate_clusvc_add(model, request)
+ if ret[0] is not True:
+ return ret
- if len(errors) > 0:
- return (False, {'errors': errors})
+ action_type = ret[1]['action_type']
+ action_msg = ret[1]['action_msg']
+ ret = propagateClusterConfAsync(self, model, rc=None,
+ action=action_type, pmsg=action_msg)
+ if ret[0] is not True:
+ return ret
- fdom = fvar['domain']
+ response = request.RESPONSE
+ response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, SERVICES, clustername))
- recovery = fvar['recovery']
- if recovery is not None and recovery != 'restart' and recovery != 'relocate' and recovery != 'disable':
- errors.append('You entered an invalid recovery option: "%s" Valid options are "restart" "relocate" and "disable."')
+def validateResourceAdd(self, request):
+ from LuciValidation import validate_clures_add
- service_name = fvar['svc_name']
- if service_name is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA5: no service name')
- errors.append('No service name was given')
+ fvar = GetReqVars(request, [ 'clustername', 'URL' ])
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- autostart = '1'
- try:
- if not request.form.has_key('autostart') or request.form['autostart'] == '0':
- autostart = '0'
- except Exception, e:
- autostart = None
+ clustername = fvar['clustername']
+ if clustername is None:
if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA5a: error getting autostart: %r %s' \
- % (e, str(e)))
-
- exclusive = '0'
- try:
- if not request.form.has_key('exclusive') or request.form['exclusive'] != '1':
- exclusive = '0'
- else:
- exclusive = '1'
- except Exception, e:
- exclusive = '0'
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
- try:
- cur_service = model.retrieveServiceByName(service_name)
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA5c: no service named %s found: %r %s' \
- % (service_name, e, str(e)))
- cur_service = None
-
- action = fvar['action']
- if action is None:
- return (False, {'errors': [ 'No action was given for service %s' % service_name ] })
-
- if 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 action == 'add':
- if cur_service is not None:
- return (False, {'errors': [ 'A service with the name %s already exists' % service_name ]})
- else:
+ model = LuciExtractCluModel(self, request, clustername)
+ if model is None:
if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vSA4a: unknown action %s' \
- % request.form['action'])
- return (False, {'errors': [ 'An unknown action was specified' ]})
+ luci_log.debug_verbose('vRA1: no model')
+ return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
- 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:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('bST0: %r %s' % (e, 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 fdom:
- new_service.addAttribute('domain', fdom)
- if recovery:
- new_service.addAttribute('recovery', recovery)
- new_service.addAttribute('exclusive', str(exclusive))
- if autostart is not None:
- new_service.attr_hash['autostart'] = autostart
-
- buildSvcTree(new_service, form_hash['toplevel']['kids'])
- model.resourcemanager_ptr.addChild(new_service)
- model.setModified(True)
-
- if action == 'edit':
- action_type = SERVICE_CONFIG
- action_msg = 'Configuring service "%s"'
- else:
- action_type = SERVICE_ADD
- action_msg = 'Creating service "%s"'
+ ret = validate_clures_add(model, request)
+ if ret[0] is not True:
+ return ret
+ resname = ret[1]['res_name']
ret = propagateClusterConfAsync(self, model, rc=None,
- action=action_type, pmsg=action_msg % service_name)
+ action=RESOURCES, pmsg='Configuring cluster resource %s' % resname)
if ret[0] is not True:
return ret
response = request.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, SERVICES, model.getClusterName()))
+ % (baseurl, RESOURCES, clustername))
-def validateResourceAdd(self, request):
- try:
- res_type = request.form['type'].strip()
- if not res_type:
- raise KeyError, 'type is blank'
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VRA0: type is blank')
- return (False, {'errors': ['No resource type was given']})
+ return (True, { 'messages': [ 'Resource "%s" configured successfully' % resname]})
- model = LuciExtractCluModel(self, request)
- if model is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VRA1: no model')
- return (False, { 'errors': [ 'Unable to retrieve the cluster configuration. The configuration XML may contain errors' ]})
+def validateConfigCluster(self, request):
+ from LuciValidation import validate_config_mcast, validate_config_qdisk, \
+ validate_config_fence, validate_config_gulm, validate_config_general
+
+ configFormValidators = {
+ 'general': validate_config_general,
+ 'mcast': validate_config_mcast,
+ 'fence': validate_config_fence,
+ 'qdisk': validate_config_qdisk,
+ 'gulm': validate_config_gulm
+ }
errors = list()
- try:
- res = create_resource(res_type, request.form, model)
- except Exception, e:
- errors.extend(e)
+ messages = list()
+ fvar = GetReqVars(request, [ 'configtype', 'clustername', 'URL' ])
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- if len(errors) < 1:
- try:
- resourceAdd(self, request, model, res)
- except Exception, e:
- errors.append('An error occurred while adding resource "%s"' \
- % res.getName())
- if len(errors) > 0:
- errors.append('An error occurred while adding this resource')
+ clustername = fvar['clustername']
+ if clustername is None:
if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('resource error: %r %s' % (e, str(e)))
- return (False, { 'errors': errors})
-
- return (True, { 'messages': [ 'Resource added successfully' ]})
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
-## Cluster properties form validation routines
+ model = LuciExtractCluModel(self, request, clustername)
+ if model is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VCC0: no model')
+ return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
-# rhel5 cluster version
-def validateMCastConfig(model, form):
- try:
- gulm_ptr = model.getGULMPtr()
- if gulm_ptr:
- return (False, {'errors': ['Multicast cannot be used with GULM locking']})
- except:
- pass
+ if clustername is None:
+ clustername = model.getClusterName()
- errors = list()
- try:
- mcast_val = form['mcast'].strip().lower()
- if mcast_val != 'true' and mcast_val != 'false':
- raise KeyError, mcast_val
- if mcast_val == 'true':
- mcast_manual = True
- else:
- mcast_manual = False
- except KeyError, e:
- errors.append('An invalid multicast selection was made')
- return (False, {'errors': errors})
+ config_type = fvar['configtype']
+ if config_type is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VCC1: no config type')
+ return (False, {'errors': [ 'No configuration type was given' ]})
- mcast_interface = None
- if form.has_key('mcast_interface'):
- mcast_interface = form['mcast_interface'].strip()
+ if not configFormValidators.has_key(config_type):
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VCC2: invalid config type: %s' \
+ % config_type)
+ return (False, { 'errors': [ 'An invalid configuration type "%s" was submitted' % config_type ]})
- if mcast_manual is True and form.has_key('cluster_version') and form['cluster_version'].strip() == 'rhel4' and not mcast_interface:
- errors.append('No multicast interface was specified')
- return (False, {'errors': errors})
+ config_validator = configFormValidators[config_type]
+ ret = config_validator(model, request.form)
- if mcast_manual is True:
- import socket
- try:
- addr_str = form['mcast_address'].strip()
- socket.inet_pton(socket.AF_INET, addr_str)
- except KeyError, e:
- addr_str = None
- errors.append('No multicast address was given')
- except socket.error, e:
- try:
- socket.inet_pton(socket.AF_INET6, addr_str)
- except socket.error, e:
- addr_str = None
- errors.append('An invalid multicast address was given: %s')
- else:
- addr_str = None
+ retcode = ret[0]
+ if ret[1].has_key('errors'):
+ errors.extend(ret[1]['errors'])
+ if ret[1].has_key('messages'):
+ messages.extend(ret[1]['messages'])
- try:
- if not addr_str:
- if mcast_interface:
- errors.append('A multicast interface was specified, but no multicast address was given')
- return (False, {'errors': errors})
- model.del_cluster_multicast()
- else:
- model.set_cluster_multicast(addr_str, mcast_if=mcast_interface)
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug('Error updating mcast properties: %r %s' \
- % (e, str(e)))
- errors.append('Unable to update cluster multicast properties')
+ if retcode is not True or len(errors) > 0:
+ return (False, {'errors': errors, 'messages': messages})
- if len(errors) > 0:
- return (False, {'errors': errors})
+ ret = propagateClusterConfAsync(self, model, None,
+ CLUSTER_CONFIG, 'Updating cluster configuration')
+ if ret[0] is not True:
+ if ret[1].has_key('errors'):
+ errors.extend(ret[1]['errors'])
+ return (retcode, {'errors': errors, 'messages': messages})
- return (True, {})
+ request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, CLUSTER_CONFIG, clustername))
-def validateQDiskConfig(model, form):
+def validateFenceAdd(self, request):
errors = list()
+ fvar = GetReqVars(request, [ 'clustername', 'URL' ])
- try:
- qdisk_val = form['quorumd'].strip().lower()
- if qdisk_val != 'true' and qdisk_val != 'false':
- raise KeyError(qdisk_val)
- if qdisk_val == 'true':
- qdisk_val = 1
- else:
- qdisk_val = 0
- except KeyError, e:
- return (False, {'errors': ['An invalid quorum partition selection was made']})
-
- cp = model.getClusterPtr()
- qdp = model.getQuorumdPtr()
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- if not qdisk_val:
- if qdp:
- try:
- cp.removeChild(qdp)
- except Exception, e:
- return (False, {'errors': [ 'Error disabling quorum partition: %s' % str(e) ] })
- return (True, {})
+ clustername = fvar['clustername']
+ if clustername is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
- try:
- interval = int(form['interval'])
- if interval < 0:
- raise ValueError, 'Interval must be 0 or greater'
- except KeyError, e:
- errors.append('No Interval value was given')
- except ValueError, e:
- errors.append('An invalid Interval value was given: %s' % str(e))
-
- try:
- votes = int(form['votes'])
- if votes < 1:
- raise ValueError, 'Votes must be greater than 0'
- except KeyError, e:
- errors.append('No Votes value was given')
- except ValueError, e:
- errors.append('An invalid Votes value was given: %s' % str(e))
-
- try:
- tko = int(form['tko'])
- if tko < 0:
- raise ValueError, 'TKO must be 0 or greater'
- except KeyError, e:
- errors.append('No TKO value was given')
- except ValueError, e:
- errors.append('An invalid TKO value was given: %s' % str(e))
-
- try:
- min_score = int(form['min_score'])
- if min_score < 1:
- raise ValueError('Minimum Score must be greater than 0')
- except KeyError, e:
- errors.append('No Minimum Score value was given')
- except ValueError, e:
- errors.append('An invalid Minimum Score value was given: %s' % str(e))
+ model = LuciExtractCluModel(self, request, clustername)
+ if model is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VFA0: no model')
+ return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ] })
- #Either device or label must be present
- device = None
- try:
- device = form['device'].strip()
- except:
- device = None
+ ret_code, ret_obj = validateNewFenceDevice(request.form, model)
+ if ret_code != FD_VAL_SUCCESS:
+ errors.extend(ret_obj)
+ return (False, { 'errors': errors })
- label = None
- try:
- label = form['label'].strip()
- except:
- label = None
+ ret = propagateClusterConfAsync(self, model, None,
+ CLUSTER_CONFIG, 'Creating fence device "%s"' % ret_obj)
+ if ret[0] is not True:
+ return ret
- if not device and not label:
- errors.append('No Device or Label value was given')
+ request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&fencename=%s&busyfirst=true' % (baseurl, FENCEDEV, clustername, ret_obj))
- num_heuristics = 0
- try:
- num_heuristics = int(form['num_heuristics']) + 1
- if num_heuristics < 1:
- raise ValueError, form['num_heuristics']
- except KeyError, e:
- errors.append('No number of heuristics was given')
- except ValueError, e:
- errors.append('An invalid number of heuristics was given: %s' % str(e))
+def validateFenceEdit(self, request):
+ errors = list()
- heuristics = list()
- for i in xrange(num_heuristics):
- try:
- h = form['heuristic%d' % i]
- if not h or len(h) != 3 or not (h[0].strip() and h[1].strip() and h[2].strip()):
- continue
- except:
- continue
+ fvar = GetReqVars(request, [ 'clustername', 'URL' ])
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- try:
- hprog = h[0]
- if not hprog:
- raise Exception, 'no hprog'
- except Exception, e:
- errors.append('No program was given for heuristic %d' % (i + 1))
- try:
- hint = int(h[1])
- if hint < 1:
- raise ValueError, 'Heuristic interval values must be greater than 0'
- except KeyError, e:
- errors.append('No interval was given for heuristic %d' % (i + 1))
- except ValueError, e:
- errors.append('An invalid interval was given for heuristic %d: %s' \
- % ((i + 1), str(e)))
+ clustername = fvar['clustername']
+ if clustername is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
- try:
- hscore = int(h[2])
- if hscore < 1:
- raise ValueError, 'Heuristic scores must be greater than 0'
- except KeyError, e:
- errors.append('No score was given for heuristic %d' % (i + 1))
- except ValueError, e:
- errors.append('An invalid score was given for heuristic %d: %s' \
- % ((i + 1), str(e)))
+ model = LuciExtractCluModel(self, request, clustername)
+ if model is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VFE1: no model')
+ return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ] })
- heuristics.append([ hprog, hint, hscore ])
+ # This is a fence edit situation, so the model should already have an
+ # entry for this fence device.
+ #
+ # pass form and model to validation method, then save changes if it passes.
+ error_code, retobj = validateFenceDevice(request.form, model)
+ if error_code != FD_VAL_SUCCESS:
+ errors.extend(retobj)
+ return (False, { 'errors': errors })
- if len(errors) > 0:
- return (False, {'errors': errors })
+ ret = propagateClusterConfAsync(self, model, None,
+ CLUSTER_CONFIG, 'Updating fence device "%s"' % retobj)
+ if ret[0] is not True:
+ return ret
- qd = QuorumD()
- qd.addAttribute('interval', str(interval))
- qd.addAttribute('votes', str(votes))
- qd.addAttribute('tko', str(tko))
- qd.addAttribute('min_score', str(min_score))
+ request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&fencename=%s&busyfirst=true' % (baseurl, FENCEDEV, clustername, retobj))
- if device:
- qd.addAttribute('device', str(device))
- else:
- qd.addAttribute('label', str(label))
+def validateNodeFenceConfig(self, request):
+ from LuciValidation import validate_node_fence_config
- if qdp:
- try:
- cp.removeChild(qdp)
- except:
- pass
- cp.addChild(qd)
+ fvar = GetReqVars(request, [ 'nodename', 'clustername', 'URL' ])
+ baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
+ nodename = fvar['nodename']
- for h in heuristics:
- new_h = Heuristic()
- new_h.addAttribute('program', str(h[0]))
- new_h.addAttribute('interval', str(h[1]))
- new_h.addAttribute('score', str(h[2]))
- qd.addChild(new_h)
-
- if len(errors) > 0:
- return (False, {'errors': errors })
-
- return (True, {})
-
-def validateGeneralConfig(model, form):
- errors = list()
-
- try:
- cp = model.getClusterPtr()
- old_name = model.getClusterAlias()
- old_ver = int(cp.getConfigVersion())
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('getConfigVersion: %s' % str(e))
- errors.append('unable to determine the current configuration version')
- return (False, {'errors': errors})
-
- try:
- cluster_name = form['cluname'].strip()
- if not cluster_name:
- raise KeyError('cluname')
- except KeyError, e:
- errors.append('No cluster name was given')
-
- if len(cluster_name) > 15:
- errors.append('A cluster\'s name must be less than 16 characters long')
-
- try:
- version_num = int(form['cfgver'])
- if version_num < old_ver:
- raise ValueError, 'configuration version number must be %d or greater' % old_ver
- except KeyError, e:
- errors.append('No cluster configuration version was given')
- except ValueError, e:
- errors.append('An invalid configuration version was given: %s' % str(e))
-
- if len(errors) < 1:
- try:
- if cluster_name != old_name:
- cp.addAttribute('alias', cluster_name)
- cp.setConfigVersion(str(version_num))
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('unable to update general properties: %r %s' % (e, str(e)))
- errors.append('Unable to update the cluster configuration')
-
- try:
- cluster_version = form['cluster_version'].strip()
- if cluster_version != 'rhel5':
- raise Exception, 'not rhel5'
- except:
- if len(errors) > 0:
- return (False, {'errors': errors})
- return (True, {})
-
- totem = model.getTotemPtr()
- if totem is None:
- totem = model.addTotemPtr()
-
- try:
- token = form['token'].strip()
- if not token:
- raise KeyError, 'token'
- token = int(token)
- if token < 1:
- raise ValueError, '%d is an invalid value for token timeout' % token
- totem.addAttribute('token', str(token))
- except KeyError, e:
- try:
- totem.removeAttribute('token')
- except:
- pass
- except Exception, e:
- errors.append(str(e))
-
- try:
- trblc = form['token_retransmits_before_loss_const'].strip()
- if not trblc:
- raise KeyError, 'token_retransmits_before_loss_const'
- trblc = int(trblc)
- if trblc < 1:
- raise ValueError, '%d is an invalid value for number of token retransmits before loss' % trblc
- totem.addAttribute('token_retransmits_before_loss_const', str(trblc))
- except KeyError, e:
- try:
- totem.removeAttribute('token_retransmits_before_loss_const')
- except:
- pass
- except Exception, e:
- errors.append(str(e))
-
- try:
- join = form['join'].strip()
- if not join:
- raise KeyError, 'join'
- join = int(join)
- if join < 1:
- raise ValueError, '%d is an invalid value for join timeout' % join
- totem.addAttribute('join', str(join))
- except KeyError, e:
- try:
- totem.removeAttribute('join')
- except:
- pass
- except Exception, e:
- errors.append(str(e))
-
- try:
- consensus = form['consensus'].strip()
- if not consensus:
- raise KeyError, 'consensus'
- consensus = int(consensus)
- if consensus < 1:
- raise ValueError, '%d is an invalid value for consensus timeout' % consensus
- totem.addAttribute('consensus', str(consensus))
- except KeyError, e:
- try:
- totem.removeAttribute('consensus')
- except:
- pass
- except Exception, e:
- errors.append(str(e))
-
- if len(errors) > 0:
- return (False, {'errors': errors})
- return (True, {})
-
-def validateFenceConfig(model, form):
- errors = list()
-
- if model.getGULMPtr() is not None:
- return (False, {'errors': [ 'GULM clusters do not support fenced' ]})
-
- try:
- post_fail_delay = int(form['post_fail_delay'])
- if post_fail_delay < 0:
- raise ValueError('post fail delay values must be 0 or greater')
- except KeyError, e:
- errors.append('No post fail delay was given')
- except ValueError, e:
- errors.append('Invalid post fail delay: %s' % str(e))
-
- try:
- post_join_delay = int(form['post_join_delay'])
- if post_join_delay < 0:
- raise ValueError('post join delay values must be 0 or greater')
- except KeyError, e:
- errors.append('No post join delay was given')
- except ValueError, e:
- errors.append('Invalid post join delay: %s' % str(e))
-
- run_xvmd = False
- try:
- run_xvmd = form.has_key('run_xvmd')
- except:
- pass
-
- if run_xvmd is True and not model.hasFenceXVM():
- fenceXVMd = FenceXVMd()
- model.addFenceXVM(fenceXVMd)
- elif not run_xvmd:
- model.delFenceXVM()
-
- try:
- fd = model.getFenceDaemonPtr()
- old_pj_delay = fd.getPostJoinDelay()
- old_pf_delay = fd.getPostFailDelay()
-
- if post_join_delay == old_pj_delay and post_fail_delay == old_pf_delay:
- errors.append('No fence daemon properties were changed')
- else:
- fd.setPostJoinDelay(str(post_join_delay))
- fd.setPostFailDelay(str(post_fail_delay))
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('Unable to update fence daemon properties: %r %s' % (e, str(e)))
- errors.append('An error occurred while attempting to update fence daemon properties')
-
- if len(errors) > 0:
- return (False, {'errors': errors })
-
- return (True, {})
-
-def validateGULMConfig(model, form):
- gulm_ptr = model.getGULMPtr()
- if not gulm_ptr:
- return (False, {'errors': [ 'This cluster appears not to be using GULM locking' ]})
-
- node_list = map(lambda x: x.getName(), gulm_ptr.getChildren())
- for i in model.getNodeNames():
- if not i in node_list:
- node_list.append(i)
-
- gulm_lockservers = list()
- for node in node_list:
- if form.has_key(node) and form[node] == 'on':
- ls = Lockserver()
- ls.addAttribute('name', node)
- gulm_lockservers.append(ls)
-
- try:
- xlockservers = filter(lambda x: x.strip(), form['__GULM__'])
- except:
- xlockservers = list()
-
- for i in xlockservers:
- if not i in node_list:
- ls = Lockserver()
- ls.addAttribute('name', i)
- gulm_lockservers.append(ls)
-
- num_ls = len(gulm_lockservers)
- if not num_ls in (1, 3, 5):
- return (False, {'errors': [ 'You must have exactly 1, 3, or 5 GULM lock servers. You submitted %d lock servers' % num_ls ]})
-
- model.GULM_ptr.children = gulm_lockservers
- return (True, {})
-
-configFormValidators = {
- 'general': validateGeneralConfig,
- 'mcast': validateMCastConfig,
- 'fence': validateFenceConfig,
- 'qdisk': validateQDiskConfig,
- 'gulm': validateGULMConfig
-}
-
-def validateConfigCluster(self, request):
- errors = list()
- messages = list()
- fvar = GetReqVars(request, [ 'configtype', 'clustername', 'URL' ])
-
- baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- clustername = fvar['clustername']
+ clustername = fvar['clustername']
+ if clustername is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
model = LuciExtractCluModel(self, request, clustername)
if model is None:
if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VCC0: no model')
- return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
-
- if clustername is None:
- clustername = model.getClusterName()
-
- config_type = fvar['configtype']
- if config_type is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VCC1: no config type')
- return (False, {'errors': [ 'No configuration type was given' ]})
-
- if not configFormValidators.has_key(config_type):
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VCC2: invalid config type: %s' \
- % config_type)
- return (False, { 'errors': [ 'An invalid configuration type "%s" was submitted' % config_type ]})
-
- config_validator = configFormValidators[config_type]
- ret = config_validator(model, request.form)
-
- retcode = ret[0]
- if ret[1].has_key('errors'):
- errors.extend(ret[1]['errors'])
- if ret[1].has_key('messages'):
- messages.extend(ret[1]['messages'])
-
- if retcode is not True or len(errors) > 0:
- return (False, {'errors': errors, 'messages': messages})
-
- ret = propagateClusterConfAsync(self, model, None,
- CLUSTER_CONFIG, 'Updating cluster configuration')
- if ret[0] is not True:
- if ret[1].has_key('errors'):
- errors.extend(ret[1]['errors'])
- return (retcode, {'errors': errors, 'messages': messages})
-
- request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, CLUSTER_CONFIG, clustername))
-
-def validateFenceAdd(self, request):
- errors = list()
- fvar = GetReqVars(request, [ 'clustername', 'URL' ])
-
- baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- clustername = fvar['clustername']
-
- model = LuciExtractCluModel(self, request, clustername)
- if model is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VFA0: no model')
- return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ] })
-
- ret_code, ret_obj = validateNewFenceDevice(request.form, model)
- if ret_code != FD_VAL_SUCCESS:
- errors.extend(ret_obj)
- return (False, { 'errors': errors })
-
- ret = propagateClusterConfAsync(self, model, None,
- CLUSTER_CONFIG, 'Creating fence device "%s"' % ret_obj)
- if ret[0] is not True:
- return ret
-
- request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&fencename=%s&busyfirst=true' % (baseurl, FENCEDEV, clustername, ret_obj))
-
-def validateFenceEdit(self, request):
- errors = list()
-
- fvar = GetReqVars(request, [ 'clustername', 'URL' ])
- baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
-
- clustername = fvar['clustername']
- if clustername is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VFE0: No cluster name')
- return (False, {'errors': ['No cluster name was given']})
-
- model = LuciExtractCluModel(self, request, clustername)
- if model is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VFE1: no model')
+ luci_log.debug_verbose('vNFC6: no model for %s' % clustername)
return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ] })
- # This is a fence edit situation, so the model should already have an
- # entry for this fence device.
- #
- # pass form and model to validation method, then save changes if it passes.
- error_code, retobj = validateFenceDevice(request.form, model)
- if error_code != FD_VAL_SUCCESS:
- errors.extend(retobj)
- return (False, { 'errors': errors })
-
- ret = propagateClusterConfAsync(self, model, None,
- CLUSTER_CONFIG, 'Updating fence device "%s"' % retobj)
+ ret = validate_node_fence_config(model, request)
if ret[0] is not True:
return ret
- request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&fencename=%s&busyfirst=true' % (baseurl, FENCEDEV, clustername, retobj))
-
-def validateNodeFenceConfig(self, request):
- errors = list()
- fvar = GetReqVars(request,
- [ 'fence_xml', 'fence_level', 'nodename', 'clustername', 'URL' ])
-
- baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
-
- if fvar['fence_xml'] is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC0: no fence_xml for node %s' \
- % fvar['nodename'])
- return (False, {'errors': ['No fence data was supplied']})
-
- if fvar['fence_level'] is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC1: no fence level for %s' \
- % fvar['nodename'])
- return (False, {'errors': ['No fence level was supplied']})
-
- try:
- fence_level = int(fvar['fence_level'])
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC2: invalid fence level: %s: %r %s' \
- % (fvar['fence_level'], e, str(e)))
- return (False, {'errors': ['"%s" is an invalid fence level' % fvar['fence_level'] ]})
-
- nodename = fvar['nodename']
- if nodename is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC3: no nodename: %r %s' % (e, str(e)))
- return (False, {'errors': ['No node name was given']})
-
- clustername = fvar['clustername']
- if clustername is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC4: no clustername: %r %s' % (e, str(e)))
- return (False, {'errors': ['No cluster name was given']})
-
- model = LuciExtractCluModel(self, request, clustername)
- if model is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC6: no model for %s' % clustername)
- return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ] })
-
- try:
- doc = minidom.parseString(fvar['fence_xml'])
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC7: error: %r %s' % (e, str(e)))
- return (False, {'errors': ['The fence data submitted is not properly formed']})
-
- try:
- node = model.retrieveNodeByName(nodename)
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC8: unable to find node name %s in current node list: %r %s' % (nodename, e, str(e)))
- return (False, {'errors': ['Unable to find the cluster node %s in the node list' % nodename ]})
-
- levels = node.getFenceLevels()
- try:
- method_id = levels[fence_level - 1].getAttribute('name')
- if not method_id:
- raise Exception, 'No method ID'
- fence_method = Method()
- fence_method.addAttribute('name', str(method_id))
- levels[fence_level - 1] = fence_method
- except Exception, e:
- method_id = fence_level
- fence_method = Method()
- fence_method.addAttribute('name', str(method_id))
-
- forms = doc.getElementsByTagName('form')
- if len(forms) < 1:
- delete_target = None
- for l in levels:
- # delete the fence level
- if l.getAttribute('name') == method_id:
- delete_target = l
- break
- if delete_target is not None:
- try:
- node.getChildren()[0].removeChild(delete_target)
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC9: %s: %r %s' \
- % (method_id, e, str(e)))
- return (False, {'errors': ['An error occurred while deleting fence method %s' % method_id ]})
- else:
- return (True, {'messages': ['No changes were made'] })
-
- form_hash = {}
- for i in forms:
- form_id = i.getAttribute('id')
- if not form_id:
- continue
- ielems = i.getElementsByTagName('input')
- if not ielems or len(ielems) < 1:
- continue
-
- dummy_form = {}
-
- for i in ielems:
- try:
- input_type = str(i.getAttribute('type'))
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC10: input type: %r %s' \
- % (e, str(e)))
- continue
-
- if not input_type or input_type == 'button':
- continue
-
- try:
- dummy_form[str(i.getAttribute('name'))] = str(i.getAttribute('value'))
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC11: parsing XML: %r %s' \
- % (e, str(e)))
-
- if len(dummy_form) < 1:
- continue
-
- if dummy_form.has_key('fence_instance'):
- try:
- parent = dummy_form['parent_fencedev']
- except:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC12: no parent for instance')
- return (False, {'errors': [ 'Unable to determine what device the current instance uses' ]})
-
- try:
- form_hash[parent][1].append(dummy_form)
- del dummy_form['fence_instance']
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC13: no parent for instance')
- return (False, {'errors': [ 'Unable to determine what device the current instance uses' ]})
- else:
- form_hash[form_id] = (dummy_form, list())
-
- fh_keys = form_hash.keys()
- fh_keys.sort()
- for i in fh_keys:
- fencedev_name = None
- fencedev_unknown = False
-
- try:
- fence_form, instance_list = form_hash[i]
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC14: %r %s' % (e, str(e)))
- continue
-
- try:
- fence_type = fence_form['fence_type']
- if not fence_type:
- raise Exception, 'fence type is blank'
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('vNFC15: %s: %r %s' % (i, e, str(e)))
- fence_type = None
-
- if fence_form.has_key('existing_device'):
- try:
- fencedev_name = fence_form['name']
- if not fencedev_name.strip():
- raise Exception, 'no fence name'
- except Exception, e:
- errors.append('You must provide a unique name for all fence devices')
- continue
-
- if fence_type is None:
- # An unknown fence device agent. Pull the data out of
- # the model and persist it and all instances.
- # All we care about is its name.
- fencedev_unknown = True
- else:
- if not fence_form.has_key('sharable'):
- # If it's a shared fence device that already exists, the
- # user could not have edited it (without playing dirty
- # games), so it's safe to pull the existing entry from
- # the model. All we need is the device name, and nothing
- # else needs to be done here.
- #
- # For an existing non-shared device update the device
- # in the model, since the user could have edited it.
- retcode, retmsg = validateFenceDevice(fence_form, model)
- if retcode != FD_VAL_SUCCESS:
- errors.extend(retmsg)
- continue
- else:
- fencedev_name = retmsg
-
- # Add back the tags under the method block
- # for the fence instance
- if type == 'fence_manual':
- instance_list.append({'name': fencedev_name, 'nodename': nodename })
- else:
- instance_list.append({'name': fencedev_name })
- else:
- # The user created a new fence device.
- retcode, retmsg = validateNewFenceDevice(fence_form, model)
- if retcode != FD_VAL_SUCCESS:
- errors.extend(retmsg)
- continue
- else:
- fencedev_name = retmsg
-
- # If it's not shared, we need to create an instance form
- # so the appropriate XML goes into the <method> block inside
- # <node><fence>. All we need for that is the device name.
- if not fence_form.has_key('sharable'):
- if type == 'fence_manual':
- instance_list.append({'name': fencedev_name, 'nodename': nodename })
- else:
- instance_list.append({'name': fencedev_name })
-
- if fencedev_unknown is True:
- # Save any instances for this fence device.
- # XXX FIX ME - instances must be saved.
- pass
-
- for inst in instance_list:
- retcode, retobj = validate_fenceinstance(inst, fencedev_name, fence_type)
- if retcode != FD_VAL_SUCCESS:
- errors.extend(retobj)
- continue
- fence_method.addChild(retobj)
-
- if len(node.getChildren()) > 0:
- # There's already a <fence> block
- found_target = False
- for idx in xrange(len(levels)):
- if levels[idx].getAttribute('name') == method_id:
- found_target = True
- break
-
- if found_target is False:
- # There's a fence block, but no relevant method
- # block
- node.getChildren()[0].addChild(fence_method)
- else:
- # There is no <fence> tag under the node yet.
- fence_node = Fence()
- fence_node.addChild(fence_method)
- node.addChild(fence_node)
-
- if len(errors) > 0:
- return (False, {'errors': errors })
-
ret = propagateClusterConfAsync(self, model, None, FENCEDEV_NODE_CONFIG,
- 'Updating fence configuration for node "%s"' % fvar['nodename'])
+ 'Updating fence configuration for node "%s"' % nodename)
if ret[0] is not True:
return ret
request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&nodename=%s&busyfirst=true' % (baseurl, NODE, clustername, nodename))
def deleteFenceDevice(self, request):
+ from LuciValidation import validate_fence_del
errors = list()
- fvar = GetReqVars(request,
- [ 'orig_name', 'nodename', 'clustername', 'URL' ])
-
+ fvar = GetReqVars(request, [ 'clustername', 'URL' ])
baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
- nodename = fvar['nodename']
- if nodename is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('DFD0: no node name')
- return (False, {'errors': ['No node name was given']})
-
clustername = fvar['clustername']
if clustername is None:
if LUCI_DEBUG_MODE is True:
@@ -1797,28 +923,12 @@
luci_log.debug_verbose('DFD2: no model')
return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ] })
- fencedev_name = fvar['orig_name']
- if fencedev_name is None:
- return (False, {'errors': ['No fence device name in form submission']})
-
- try:
- fdev = model.getFenceDeviceByName(fencedev_name)
- if fdev:
- if model.deleteFenceDevice(fdev) is not True:
- raise Exception, 'failed to remove %s' % fdev.getName()
- model.removeFenceInstancesForFenceDevice(fencedev_name)
- else:
- raise Exception, 'no fence device named "%s" was found' \
- % fencedev_name
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('DFD3: %s: %r %s' \
- % (fencedev_name, e, str(e)))
- return (False, { 'errors': [ 'Error removing fence device %s: %s' \
- % (fencedev_name, str(e)) ]})
+ ret = validate_fence_del(model, request)
+ if ret[0] is not True:
+ return ret
ret = propagateClusterConfAsync(self, model, None, CLUSTER_CONFIG,
- 'Removing fence device "%s"' % fencedev_name)
+ 'Removing fence device "%s"' % ret[1].get('name'))
if ret[0] is not True:
return ret
@@ -1826,47 +936,22 @@
% (baseurl, FENCEDEVS, clustername))
def validateDaemonProperties(self, request):
- errors = list()
+ from LuciValidation import validate_cluster_daemon_form
fvar = GetReqVars(request,
- [ 'orig_name', 'nodename', 'clustername', 'URL' ])
-
+ [ 'nodename', 'clustername', 'URL' ])
baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
-
clustername = fvar['clustername']
- if clustername is None:
- errors.append('Unable to determine the current cluster name')
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VDP2: no clustername')
-
nodename = fvar['nodename']
- if nodename is None:
- errors.append('Unable to determine the current node name')
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VDP1: no nodename for %s' % clustername)
- disable_list = list()
- enable_list = list()
- for i in request.form.items():
- try:
- if i[0][:11] == '__daemon__:':
- daemon_prop = i[1]
- if len(daemon_prop) == 2:
- if daemon_prop[1] == '1':
- disable_list.append(daemon_prop[0])
- else:
- if daemon_prop[1] == '0' and daemon_prop[2] == 'on':
- enable_list.append(daemon_prop[0])
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VDP3: error: %s: %r %s' \
- % (str(i), e, str(e)))
+ ret = validate_cluster_daemon_form(self, request)
+ if ret[0] is not True:
+ return ret
- if len(enable_list) < 1 and len(disable_list) < 1:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('VDP4: no changes made')
- request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&nodename=%s' \
- % (baseurl, NODE, clustername, nodename))
+ enable_list = ret[1]['enable_list']
+ disable_list = ret[1]['disable_list']
+
+ errors = list()
nodename_resolved = resolve_nodename(self, clustername, nodename)
try:
@@ -1878,14 +963,14 @@
luci_log.debug_verbose('VDP5: RC %s: %r %s' \
% (nodename_resolved, e, str(e)))
errors.append('Unable to connect to the ricci agent on %s to update cluster daemon properties' % nodename_resolved)
- return (False, {'errors': errors})
+ return (False, { 'errors': errors})
batch_id, result = rq.updateServices(rc, enable_list, disable_list)
if batch_id is None or result is None:
if LUCI_DEBUG_MODE is True:
luci_log.debug_verbose('VDP6: setCluserConf: batchid or result is None')
errors.append('Unable to update the cluster daemon properties on node %s' % nodename_resolved)
- return (False, {'errors': errors})
+ return (False, { 'errors': errors})
try:
if len(enable_list) > 0:
@@ -1906,13 +991,17 @@
request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&nodename=%s&busyfirst=true' % (baseurl, NODE, clustername, nodename))
def validateFdom(self, request):
- errors = list()
+ from LuciValidation import validate_fdom
+
fvar = GetReqVars(request, [ 'clustername', 'name', 'oldname', 'URL' ])
baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
+ name = fvar['name']
clustername = fvar['clustername']
if clustername is None:
- errors.append('Unable to determine this cluster\'s name')
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VFE0: No cluster name')
+ return (False, {'errors': ['No cluster name was given']})
model = LuciExtractCluModel(self, request, clustername)
if model is None:
@@ -1920,111 +1009,21 @@
luci_log.debug_verbose('validateFdom0: no model')
return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
- name = fvar['name']
- if name is None:
- errors.append('No name was given for this failover domain')
-
- prioritized = False
- try:
- prioritized = request.form.has_key('prioritized')
- except:
- prioritized = False
-
- restricted = False
- try:
- restricted = request.form.has_key('restricted')
- except:
- restricted = False
-
- nofailback = False
- try:
- nofailback = request.form.has_key('nofailback')
- except:
- nofailback = False
-
- oldname = fvar['oldname']
-
- if oldname is None or oldname != name:
- if model.getFailoverDomainByName(name) is not None:
- errors.append('A failover domain named "%s" already exists' % name)
-
- fdom = None
- if oldname is not None:
- fdom = model.getFailoverDomainByName(oldname)
- if fdom is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('validateFdom1: No fdom named %s exists' % oldname)
- errors.append('No failover domain named "%s" exists' % oldname)
- else:
- fdom.addAttribute('name', name)
- fdom.children = list()
- else:
- fdom = FailoverDomain()
- fdom.addAttribute('name', name)
-
- if fdom is None or len(errors) > 0:
- return (False, {'errors': errors })
-
- if prioritized:
- fdom.addAttribute('ordered', '1')
- else:
- fdom.addAttribute('ordered', '0')
-
- if restricted:
- fdom.addAttribute('restricted', '1')
- else:
- fdom.addAttribute('restricted', '0')
-
- if nofailback:
- fdom.addAttribute('nofailback', '1')
- else:
- fdom.addAttribute('nofailback', '0')
-
- for i in model.getNodeNames():
- if request.form.has_key(i):
- fdn = FailoverDomainNode()
- fdn.addAttribute('name', i)
- if prioritized:
- priority = 1
- try:
- priority = int(request.form['__PRIORITY__%s' % i].strip())
- if priority < 1:
- priority = 1
- except Exception, e:
- priority = 1
- fdn.addAttribute('priority', str(priority))
- fdom.addChild(fdn)
-
- try:
- fdom_ptr = model.getFailoverDomainPtr()
- if not oldname:
- fdom_ptr.addChild(fdom)
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('validateFdom2: %r %s' % (e, str(e)))
- errors.append('Unable to update the cluster configuration')
-
- if len(errors) > 0:
- return (False, {'errors': errors })
-
- if oldname:
- action = FDOM
- status_msg = 'Updating failover domain "%s"' % oldname
- else:
- action = FDOM_ADD
- status_msg = 'Creating failover domain "%s"' % name
+ ret = validate_fdom(self, request)
+ if ret[0] is not True:
+ return ret
- ret = propagateClusterConfAsync(self, model, None, action, status_msg)
+ ret = propagateClusterConfAsync(self, model, None,
+ ret[1]['action'], ret[1]['msg'])
if ret[0] is not True:
return ret
request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&fdomname=%s&busyfirst=true' % (baseurl, FDOM, clustername, name))
def validateVM(self, request):
- errors = list()
-
- fvar = GetReqVars(request, [ 'clustername', 'vmname', 'oldname', 'vmpath', 'recovery', 'domain', 'URL' ])
+ from LuciValidation import validate_vmsvc_form
+ fvar = GetReqVars(request, [ 'clustername', 'URL' ])
baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
clustername = fvar['clustername']
@@ -2039,101 +1038,14 @@
luci_log.debug_verbose('validateVM1: no model')
return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
- vm_name = fvar['vmname']
- if vm_name is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('validateVM2: no vm name')
- errors.append('No virtual machine name was given')
-
- vm_path = fvar['vmpath']
- if vm_path is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('validateVM3: no vm path')
- errors.append('No path to the virtual machine configuration directory was given')
-
- autostart = 1
- if request.form.has_key('autostart'):
- autostart = 1
- else:
- autostart = 0
-
- exclusive = 0
- if request.form.has_key('exclusive'):
- exclusive = 1
- else:
- exclusive = 0
-
- recovery = fvar['recovery']
- if recovery is not None and recovery != 'restart' and recovery != 'relocate' and recovery != 'disable':
- errors.append('You entered an invalid recovery option: "%s" Valid options are "restart" "relocate" and "disable"')
-
- fdom = fvar['domain']
-
- if len(errors) > 0:
- return (False, {'errors': errors })
-
- isNew = False
- old_name = fvar['oldname']
- if old_name is None:
- isNew = True
-
- delete_vm = False
- if request.form.has_key('delete'):
- try:
- xvm = model.retrieveVMsByName(old_name)
- if not xvm:
- raise Exception, 'not found'
- rmptr = model.getResourceManagerPtr()
- rmptr.removeChild(xvm)
- delete_vm = True
- except:
- return (False, {'errors': ['No virtual machine service named "%s" exists' % old_name ]})
- else:
- if isNew is True:
- xvm = Vm()
- xvm.addAttribute('name', vm_name)
- xvm.addAttribute('path', vm_path)
- rmptr = model.getResourceManagerPtr()
- rmptr.addChild(xvm)
- else:
- try:
- xvm = model.retrieveVMsByName(old_name)
- if not xvm:
- raise Exception, 'not found'
- except:
- return (False, {'errors': ['No virtual machine service named "%s" exists' % old_name ]})
- xvm.addAttribute('name', vm_name)
- xvm.addAttribute('path', vm_path)
-
- xvm.addAttribute('autostart', str(autostart))
- xvm.addAttribute('exclusive', str(exclusive))
- if fdom:
- xvm.addAttribute('domain', fdom)
- else:
- try:
- xvm.removeAttribute('domain')
- except:
- pass
-
- if recovery:
- xvm.addAttribute('recovery', recovery)
- else:
- try:
- xvm.removeAttribute('recovery')
- except:
- pass
+ ret = validate_vmsvc_form(model, request)
+ if ret[0] is not True:
+ return ret
- if delete_vm is True:
- action = VM_CONFIG
- status_msg = 'Deleting virtual machine service "%s"' % vm_name
- elif isNew is True:
- action = VM_ADD
- status_msg = 'Creating virtual machine service "%s"' % vm_name
- else:
- action = VM_CONFIG
- status_msg = 'Configuring virtual machine service "%s"' % vm_name
+ action_type = ret[1]['action_type']
+ action_msg = ret[1]['action_msg']
- ret = propagateClusterConfAsync(self, model, None, action, status_msg)
+ ret = propagateClusterConfAsync(self, model, None, action_type, action_msg)
if ret[0] is not True:
return ret
@@ -2204,7 +1116,7 @@
cc = None
if req.has_key('new_cluster_conf'):
cc = req['new_cluster_conf']
- msg_list.append('Checking if valid XML - ')
+ msg_list.append('Checking XML validity - ')
cc_xml = None
try:
cc_xml = minidom.parseString(cc)
@@ -2269,7 +1181,8 @@
57: deleteFenceDevice,
58: validateNodeFenceConfig,
60: validate_xvm_key_dist,
- 80: process_cluster_conf_editor
+ 80: process_cluster_conf_editor,
+ 1001: validate_clusvc_async
}
def validatePost(self, request):
@@ -2278,41 +1191,15 @@
except Exception, e:
if LUCI_DEBUG_MODE is True:
luci_log.debug_verbose('VP0: error: %r %s' % (e, str(e)))
- return None
+ return (False, {})
if not pagetype in formValidators:
if LUCI_DEBUG_MODE is True:
luci_log.debug_verbose('VP1: no handler for page type %d' % pagetype)
- return None
+ return (False, {})
else:
return formValidators[pagetype](self, request)
-def getClusterURL(self, request, model):
- try:
- clustername = request['clustername'].strip()
- if not clustername:
- raise Exception, 'cluster name from request is blank'
- except:
- try:
- clustername = model.getClusterName()
- if not clustername:
- raise Exception, 'cluster name from model is blank'
- except:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('GCURL0: unable to get cluster name')
- return ''
-
- return '/luci/cluster/index_html?pagetype=7&clustername=%s' % clustername
-
-def getRicciAgentForCluster(self, req):
- fvar = GetReqVars(req, [ 'clustername' ])
- clustername = fvar['clustername']
- if clustername is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug('GRAFC0: no cluster name was found')
- return None
- return getRicciAgent(self, clustername)
-
def clusterTaskProcess(self, model, request):
fvar = GetReqVars(request, [ 'task', 'clustername', 'URL' ])
@@ -2366,10 +1253,10 @@
fvar = GetReqVars(request, [ 'task', 'clustername', 'nodename', 'URL' ])
task = fvar['task']
- clustername = fvar['clustername']
nodename = fvar['nodename']
baseurl = fvar['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvar['clustername']
if clustername is None:
if LUCI_DEBUG_MODE is True:
luci_log.debug('NTP0: missing cluster name')
@@ -2435,67 +1322,201 @@
# we'll hit it again, and try again then
pass
- if rc is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug('NTP7: node %s is not authenticated' \
- % nodename_resolved)
- return (False, { 'errors': [ 'Node "%s" is not authenticated' % nodename_resolved ]})
+ if rc is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('NTP7: node %s is not authenticated' \
+ % nodename_resolved)
+ return (False, { 'errors': [ 'Node "%s" is not authenticated' % nodename_resolved ]})
+
+ if task == NODE_LEAVE_CLUSTER:
+ from LuciClusterActions import NodeLeaveCluster
+ if NodeLeaveCluster(self, rc, clustername, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NTP8: nodeLeave failed')
+ return (False, {'errors': [ 'Node "%s" failed to leave cluster "%s"' % (nodename_resolved, clustername) ]})
+
+ response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, NODES, clustername))
+ elif task == NODE_JOIN_CLUSTER:
+ from LuciClusterActions import NodeJoinCluster
+ if NodeJoinCluster(self, rc, clustername, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NTP9: nodeJoin failed')
+ return (False, {'errors': [ 'Node "%s" failed to join cluster "%s"' % (nodename_resolved, clustername) ]})
+
+ response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, NODES, clustername))
+ elif task == NODE_REBOOT:
+ from LuciClusterActions import NodeReboot
+ if NodeReboot(self, rc, clustername, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NTP10: nodeReboot failed')
+ return (False, {'errors': [ 'Node "%s" failed to reboot' \
+ % nodename_resolved ]})
+
+ response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, NODES, clustername))
+ elif task == NODE_FENCE:
+ from LuciClusterActions import NodeFence
+ if NodeFence(self, clustername, nodename, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NTP11: nodeFencefailed')
+ return (False, {'errors': [ 'Fencing of node "%s" failed' \
+ % nodename_resolved]})
+ response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
+ % (baseurl, NODES, clustername))
+ elif task == NODE_DELETE:
+ from LuciClusterActions import NodeDeleteFromCluster
+ if NodeDeleteFromCluster(self, rc, model, clustername, nodename, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NTP12: nodeDelete 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))
+ 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 getResourceInfo(model, request):
+ if not model:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRI0: no model object in session')
+ return {}
+
+ fvars = GetReqVars(request,
+ [ 'resourcename', 'type', 'value', 'clustername', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
+ name = fvars['resourcename']
+ if name is None:
+ if fvars['type'] == 'ip':
+ name = fvars['value']
+
+ if name is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRI1: missing res name')
+ return {}
+
+ from LuciClusterInfo import getResourceInfo as gri
+ return gri(model, name, baseurl, res=None)
+
+def serviceRestart(self, rc, req):
+ from LuciClusterActions import RestartCluSvc
+
+ 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' \
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
+ else:
+ return ret
+
+def serviceStop(self, rc, req):
+ from LuciClusterActions import StopCluSvc
+
+ 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' \
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
+ else:
+ return ret
+
+def serviceStart(self, rc, req):
+ from LuciClusterActions import StartCluSvc
+
+ 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' \
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
+ else:
+ return ret
+
+def serviceDelete(self, rc, req):
+ from LuciClusterActions import DeleteCluSvc
+
+ fvars = GetReqVars(req,
+ [ 'clustername', 'servicename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvars['clustername']
- if task == NODE_LEAVE_CLUSTER:
- from LuciClusterActions import NodeLeaveCluster
- if NodeLeaveCluster(self, rc, clustername, nodename_resolved) is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('NTP8: nodeLeave failed')
- return (False, {'errors': [ 'Node "%s" failed to leave cluster "%s"' % (nodename_resolved, clustername) ]})
+ model = LuciExtractCluModel(self, req, clustername)
+ if model is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('serviceDelete0: no model')
+ return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
+ ret = DeleteCluSvc(self, rc, fvars, model)
+ if ret is None:
+ response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, NODES, clustername))
- elif task == NODE_JOIN_CLUSTER:
- from LuciClusterActions import NodeJoinCluster
- if NodeJoinCluster(self, rc, clustername, nodename_resolved) is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('NTP9: nodeJoin failed')
- return (False, {'errors': [ 'Node "%s" failed to join cluster "%s"' % (nodename_resolved, clustername) ]})
+ % (baseurl, SERVICES, clustername))
+ else:
+ return ret
- response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, NODES, clustername))
- elif task == NODE_REBOOT:
- from LuciClusterActions import NodeReboot
- if NodeReboot(self, rc, clustername, nodename_resolved) is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('NTP10: nodeReboot failed')
- return (False, {'errors': [ 'Node "%s" failed to reboot' \
- % nodename_resolved ]})
+def serviceMigrate(self, rc, req):
+ from LuciClusterActions import MigrateCluSvc
- response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, NODES, clustername))
- elif task == NODE_FENCE:
- from LuciClusterActions import NodeFence
- if NodeFence(self, clustername, nodename, nodename_resolved) is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('NTP11: nodeFencefailed')
- return (False, {'errors': [ 'Fencing of node "%s" failed' \
- % nodename_resolved]})
- response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, NODES, clustername))
- elif task == NODE_DELETE:
- from LuciClusterActions import NodeDeleteFromCluster
- if NodeDeleteFromCluster(self, rc, model, clustername, nodename, nodename_resolved) is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('NTP12: nodeDelete failed')
- return (False, {'errors': [ 'Deletion of node "%s" from cluster "%s" failed' % (nodename_resolved, clustername) ]})
+ 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' \
- % (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) ]})
+ % (baseurl, SERVICE_LIST, fvars['clustername']))
+ else:
+ return ret
+
+def resourceDelete(self, rc, req):
+ from LuciClusterActions import DeleteResource
+
+ fvars = GetReqVars(req,
+ [ 'clustername', 'resourcename', 'nodename', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvars['clustername']
+
+ model = LuciExtractCluModel(self, req, clustername)
+ if model is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('resourceDelete0: no model')
+ return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
+ ret = DeleteResource(self, rc, model, fvars['resourcename'])
+ if ret is None:
+ response = req.RESPONSE
response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, NODES, clustername))
+ % (baseurl, RESOURCES, clustername))
+ else:
+ return ret
+
+def getSystemLogs(self, req):
+ from LuciClusterActions import GetSystemLogs
+
+ fvars = GetReqVars(req, [ 'clustername', 'nodename' ])
+ return GetSystemLogs(self, fvars)
def isClusterBusy(self, req):
items = None
@@ -2832,166 +1853,3 @@
if LUCI_DEBUG_MODE is True:
luci_log.debug_verbose('ICB26: returning busy_map: %s' % str(busy_map))
return busy_map
-
-# These are called from external methods.
-def getResourceInfo(model, request):
- if not model:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('GRI0: no model object in session')
- return {}
-
- fvars = GetReqVars(request,
- [ 'resourcename', 'type', 'value', 'clustername', 'URL' ])
-
- baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
-
- name = fvars['resourcename']
- if name is None:
- if fvars['type'] == 'ip':
- name = fvars['value']
-
- if name is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('GRI1: missing res name')
- return {}
-
- from LuciClusterInfo import getResourceInfo as gri
- return gri(model, name, baseurl, res=None)
-
-def serviceRestart(self, rc, req):
- from LuciClusterActions import RestartCluSvc
-
- 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' \
- % (baseurl, SERVICE_LIST, fvars['clustername']))
- else:
- return ret
-
-def serviceStop(self, rc, req):
- from LuciClusterActions import StopCluSvc
-
- 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' \
- % (baseurl, SERVICE_LIST, fvars['clustername']))
- else:
- return ret
-
-def serviceStart(self, rc, req):
- from LuciClusterActions import StartCluSvc
-
- 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' \
- % (baseurl, SERVICE_LIST, fvars['clustername']))
- else:
- return ret
-
-def serviceDelete(self, rc, req):
- from LuciClusterActions import DeleteCluSvc
-
- fvars = GetReqVars(req,
- [ 'clustername', 'servicename', 'nodename', 'URL' ])
- baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
- clustername = fvars['clustername']
-
- model = LuciExtractCluModel(self, req, clustername)
- if model is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('serviceDelete0: no model')
- return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
-
- ret = DeleteCluSvc(self, rc, fvars, model)
- if ret is None:
- response = req.RESPONSE
- response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, SERVICES, clustername))
- else:
- return ret
-
-def serviceMigrate(self, rc, req):
- from LuciClusterActions import MigrateCluSvc
-
- 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' \
- % (baseurl, SERVICE_LIST, fvars['clustername']))
- else:
- return ret
-
-def resourceDelete(self, rc, req):
- from LuciClusterActions import DeleteResource
-
- fvars = GetReqVars(req,
- [ 'clustername', 'resourcename', 'nodename', 'URL' ])
- baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
- clustername = fvars['clustername']
-
- model = LuciExtractCluModel(self, req, clustername)
- if model is None:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('resourceDelete0: no model')
- return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]})
-
- ret = DeleteResource(self, rc, model, fvars['resourcename'])
- if ret is None:
- response = req.RESPONSE
- response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, RESOURCES, 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()
- rc = getRicciAgent(self, cluname)
- if rc is None:
- raise Exception, 'no rc'
- except Exception, e:
- if LUCI_DEBUG_MODE is True:
- luci_log.debug_verbose('resourceAdd0: no ricci agent: %r %s' \
- % (e, str(e)))
- return (False, { 'errors': [ 'Unable to find a ricci agent for cluster "%s"' % cluname ]})
-
- if req.form.has_key('edit'):
- ret = EditResource(self, rc, model, res)
- else:
- ret = AddResource(self, rc, model, res)
-
- if ret is None:
- response = req.RESPONSE
- response.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
- % (baseurl, RESOURCES, cluname))
- else:
- return ret
-
-def getSystemLogs(self, req):
- from LuciClusterActions import GetSystemLogs
-
- fvars = GetReqVars(req, [ 'clustername', 'nodename' ])
- return GetSystemLogs(self, fvars)
next reply other threads:[~2007-12-12 15:45 UTC|newest]
Thread overview: 185+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-12 15:45 rmccabe [this message]
-- strict thread matches above, loose matches on Subject: below --
2008-07-17 16:36 [Cluster-devel] conga/luci/site/luci/Extensions cluster_adapte rmccabe
2008-04-18 20:37 rmccabe
2007-08-23 19:00 rmccabe
2007-08-22 20:57 rmccabe
2007-05-03 19:51 rmccabe
2007-04-02 16:35 rmccabe
2007-04-02 15:56 rmccabe
2007-03-27 2:03 rmccabe
2007-03-16 3:19 rmccabe
2007-03-16 3:19 rmccabe
2007-03-16 3:19 rmccabe
2007-03-13 3:07 rmccabe
2007-03-13 3:06 rmccabe
2007-03-12 5:47 rmccabe
2007-03-12 5:46 rmccabe
2007-03-12 5:46 rmccabe
2007-03-06 22:48 rmccabe
2007-03-01 20:22 rmccabe
2007-03-01 20:22 rmccabe
2007-03-01 20:22 rmccabe
2007-02-13 19:50 rmccabe
2007-02-13 19:50 rmccabe
2007-02-12 20:25 rmccabe
2007-02-12 20:24 rmccabe
2007-02-07 22:00 rmccabe
2007-02-07 21:30 rmccabe
2007-02-05 19:56 rmccabe
2007-01-31 23:45 rmccabe
2007-01-31 19:28 rmccabe
2007-01-31 18:50 rmccabe
2007-01-30 21:41 jparsons
2007-01-30 21:21 jparsons
2007-01-30 21:05 jparsons
2007-01-29 23:30 rmccabe
2007-01-26 19:35 rmccabe
2007-01-18 2:48 rmccabe
2007-01-17 22:26 rmccabe
2007-01-17 22:14 rmccabe
2007-01-10 23:33 jparsons
2007-01-10 22:45 rmccabe
2007-01-10 20:06 rmccabe
2006-12-20 20:40 jparsons
2006-12-14 21:37 rmccabe
2006-12-14 17:03 rmccabe
2006-12-08 23:02 rmccabe
2006-11-30 20:12 jparsons
2006-11-27 21:06 rmccabe
2006-11-27 21:05 rmccabe
2006-11-27 18:15 rmccabe
2006-11-20 23:32 rmccabe
2006-11-20 15:05 jparsons
2006-11-17 5:50 rmccabe
2006-11-17 5:48 rmccabe
2006-11-10 18:18 rmccabe
2006-11-10 17:59 rmccabe
2006-11-09 22:30 rmccabe
2006-11-09 14:17 rmccabe
2006-11-08 21:42 rmccabe
2006-11-08 15:52 jparsons
2006-11-07 20:14 jparsons
2006-11-07 20:13 jparsons
2006-11-07 2:36 jparsons
2006-11-07 1:32 jparsons
2006-11-06 23:55 rmccabe
2006-11-05 0:59 rmccabe
2006-11-03 21:13 jparsons
2006-11-03 1:24 rmccabe
2006-11-03 1:08 rmccabe
2006-11-02 20:58 rmccabe
2006-11-02 20:45 rmccabe
2006-11-02 20:41 rmccabe
2006-11-02 3:17 rmccabe
2006-10-31 17:18 rmccabe
2006-10-31 0:16 rmccabe
2006-10-30 22:52 rmccabe
2006-10-30 20:43 jparsons
2006-10-27 1:11 rmccabe
2006-10-25 0:43 rmccabe
2006-10-24 14:08 rmccabe
2006-10-23 20:47 jparsons
2006-10-20 22:09 rmccabe
2006-10-20 21:59 rmccabe
2006-10-19 14:57 rmccabe
2006-10-18 23:12 rmccabe
2006-10-18 19:16 rmccabe
2006-10-16 21:01 rmccabe
2006-10-16 20:51 jparsons
2006-10-16 19:17 jparsons
2006-10-16 5:28 rmccabe
2006-10-16 4:54 rmccabe
2006-10-16 4:51 rmccabe
2006-10-13 22:56 rmccabe
2006-10-12 22:11 jparsons
2006-10-12 21:00 kupcevic
2006-10-12 20:54 jparsons
2006-10-12 20:48 jparsons
2006-10-12 19:40 rmccabe
2006-10-12 17:27 jparsons
2006-10-12 17:08 jparsons
2006-10-12 15:50 jparsons
2006-10-12 15:45 jparsons
2006-10-12 0:04 jparsons
2006-10-11 23:56 jparsons
2006-10-11 23:11 jparsons
2006-10-11 23:08 rmccabe
2006-10-11 22:37 jparsons
2006-10-11 20:58 jparsons
2006-10-11 17:43 jparsons
2006-10-11 17:29 rmccabe
2006-10-11 16:35 jparsons
2006-10-11 16:25 jparsons
2006-10-11 16:18 rmccabe
2006-10-10 21:33 kupcevic
2006-10-09 20:21 rmccabe
2006-10-04 16:20 rmccabe
2006-10-04 16:05 jparsons
2006-10-04 15:11 jparsons
2006-10-02 22:30 rmccabe
2006-10-02 21:42 rmccabe
2006-10-02 21:09 rmccabe
2006-10-02 20:53 rmccabe
2006-09-28 22:04 rmccabe
2006-09-28 20:10 rmccabe
2006-09-27 18:46 rmccabe
2006-09-27 16:18 jparsons
2006-09-27 15:51 jparsons
2006-09-27 15:35 jparsons
2006-09-25 22:59 rmccabe
2006-09-22 18:24 rmccabe
2006-08-30 22:59 rmccabe
2006-08-22 17:46 jparsons
2006-08-22 17:41 jparsons
2006-08-16 23:40 jparsons
2006-08-16 21:56 jparsons
2006-08-16 21:54 jparsons
2006-08-16 21:51 jparsons
2006-08-16 19:14 rmccabe
2006-08-16 16:10 jparsons
2006-08-14 15:12 jparsons
2006-08-13 19:38 jparsons
2006-08-13 19:37 jparsons
2006-08-13 18:36 jparsons
2006-08-13 16:32 jparsons
2006-08-13 16:15 jparsons
2006-08-13 15:02 jparsons
2006-08-13 14:57 jparsons
2006-08-13 13:48 jparsons
2006-08-12 21:13 jparsons
2006-08-12 20:31 jparsons
2006-08-12 18:22 jparsons
2006-08-12 17:53 jparsons
2006-08-11 0:29 jparsons
2006-08-10 23:06 shuennek
2006-08-10 16:50 jparsons
2006-08-10 14:16 jparsons
2006-08-09 22:05 jparsons
2006-08-09 21:48 jparsons
2006-08-03 13:37 jparsons
2006-08-02 18:59 rmccabe
2006-08-02 17:25 rmccabe
2006-08-01 15:29 jparsons
2006-08-01 15:25 jparsons
2006-08-01 15:20 jparsons
2006-08-01 15:13 jparsons
2006-08-01 15:04 jparsons
2006-07-31 18:21 rmccabe
2006-07-28 19:03 jparsons
2006-07-28 18:57 jparsons
2006-07-28 18:40 jparsons
2006-07-28 14:16 jparsons
2006-07-28 14:02 jparsons
2006-07-28 11:46 jparsons
2006-07-27 16:34 jparsons
2006-07-27 15:53 rmccabe
2006-07-25 20:16 jparsons
2006-07-25 20:01 jparsons
2006-07-25 0:56 jparsons
2006-07-24 21:51 jparsons
2006-07-24 21:13 jparsons
2006-07-24 19:50 jparsons
2006-07-19 22:28 rmccabe
2006-07-19 21:38 rmccabe
2006-07-19 20:57 rmccabe
2006-07-19 20:19 rmccabe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071212154527.2580.qmail@sourceware.org \
--to=rmccabe@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.