Index: luci/cluster/fdom-macros =================================================================== RCS file: /cvs/cluster/conga/luci/cluster/fdom-macros,v retrieving revision 1.2.2.1 diff -u -r1.2.2.1 fdom-macros --- a/luci/cluster/fdom-macros 23 Jan 2008 04:44:30 -0000 1.2.2.1 +++ b/luci/cluster/fdom-macros 6 Aug 2010 21:55:11 -0000 @@ -105,6 +105,7 @@ src="/luci/cluster/validate_fdom.js"> </script> +<div class="hbSubmit"> <form method="post" action=""> <input type="hidden" name="clustername" tal:attributes="value request/clustername | nothing" /> @@ -155,10 +156,8 @@ <tfoot class="systemsTable"> <tr class="systemsTable"><td> - <div class="hbSubmit"> - <input type="button" name="add" value="Submit" - onclick="validate_add_fdom(this.form)" /> - </div> + <input type="button" name="add" value="Submit" + onclick="validate_add_fdom(this.form)" /> </td></tr> </tfoot> @@ -191,8 +190,24 @@ </tal:block> </tbody> </table> -</form> + </form> + <table class="systemsTable" width="100%"> + <tr class="systemsTable"> + <td tal:condition="exists: fdom/name"> + <form method="post"> + <input type="hidden" name="clustername" + tal:attributes="value request/clustername | nothing" /> + <input type="hidden" name="pagetype" value="46"/> + <input type="hidden" name="name" + tal:attributes="value fdom/name | nothing" /> + <input type="button" value="Delete this failover domain" + onclick="if (confirm('Delete this failover domain?')) this.form.submit()" /> + </form> + </td> + </tr> + </table> +</div> </tal:block> <div metal:define-macro="fdomadd-form"> @@ -213,6 +228,9 @@ </div> <div metal:define-macro="fdom-form"> + <script type="text/javascript"> + set_page_title('Luci — cluster — failover domains — Configure a failover domain'); + </script> <h2>Failover Domain Form</h2> <tal:block tal:define="fdom python:here.getFdomInfo(modelb, request)"> <tal:block metal:use-macro="here/fdom-macros/macros/fdom-macro" /> Index: luci/site/luci/Extensions/LuciValidation.py =================================================================== RCS file: /cvs/cluster/conga/luci/site/luci/Extensions/LuciValidation.py,v retrieving revision 1.6.2.14 diff -u -r1.6.2.14 LuciValidation.py --- a/luci/site/luci/Extensions/LuciValidation.py 5 Aug 2010 19:32:58 -0000 1.6.2.14 +++ b/luci/site/luci/Extensions/LuciValidation.py 6 Aug 2010 21:55:11 -0000 @@ -16,7 +16,7 @@ from ClusterModel.Lockserver import Lockserver from ClusterModel.Vm import Vm -from conga_constants import LUCI_DEBUG_MODE, FDOM, FDOM_ADD, SERVICE_CONFIG, SERVICE_ADD, VM_CONFIG, VM_ADD +from conga_constants import LUCI_DEBUG_MODE, FDOM, FDOM_ADD, FDOM_DELETE, SERVICE_CONFIG, SERVICE_ADD, VM_CONFIG, VM_ADD from FenceHandler import validateFenceDevice, validateNewFenceDevice, validate_fenceinstance, FD_VAL_SUCCESS from LuciSyslog import get_logger @@ -524,6 +524,38 @@ return (False, { 'errors': [ 'Error configuring resource %s %s: ' % (resname, str(e)) ] }) return (True, { 'res_name': resname }) +def validate_fdom_delete(model, name): + errors = list() + + fdom = model.getFailoverDomainByName(name) + if fdom is None: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('validateFdomdel1: No fdom named %s exists' % name) + errors.append('No failover domain named "%s" exists' % name) + + svc_list = model.getServicesForFdom(name) + if svc_list and len(svc_list) != 0: + errors.append('Unable to delete failover domain "%s" because it is in use by %s %s' % (name, len(svc_list) == 1 and 'service' or 'services', ', '.join(map(lambda x: x.getName(), svc_list)))) + + if len(errors) > 0: + return (False, { 'errors': errors }) + + try: + fdom_ptr = model.getFailoverDomainPtr() + fdom_ptr.removeChild(fdom) + except: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('validateFdomdel2: unable to fdom remove %s' % name) + errors.append('Unable to remove failover domain "%s"' % name) + + if len(errors) > 0: + return (False, { 'errors': errors }) + + action = FDOM_DELETE + status_msg = 'Deleting failover domain "%s"' % name + + return (True, { 'msg': status_msg, 'action': action }) + def validate_fdom(model, request): errors = list() fvar = GetReqVars(request, [ 'clustername', 'name', 'oldname' ]) Index: luci/site/luci/Extensions/cluster_adapters.py =================================================================== RCS file: /cvs/cluster/conga/luci/site/luci/Extensions/cluster_adapters.py,v retrieving revision 1.120.2.49 diff -u -r1.120.2.49 cluster_adapters.py --- a/luci/site/luci/Extensions/cluster_adapters.py 6 Aug 2010 20:17:21 -0000 1.120.2.49 +++ b/luci/site/luci/Extensions/cluster_adapters.py 6 Aug 2010 21:55:11 -0000 @@ -30,7 +30,7 @@ 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, \ + RICCI_CONNECT_FAILURE_MSG, SEND_CONF, FDOMS, \ SERVICE_LIST, SERVICES, START_NODE, TASKTYPE, \ REDIRECT_SEC, LUCI_CLUSTER_BASE_URL, FENCE_XVM_KEY_CREATE @@ -967,6 +967,36 @@ request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&nodename=%s&busyfirst=true' % (baseurl, NODE, clustername, nodename)) +def deleteFdom(self, request): + from LuciValidation import validate_fdom_delete + + 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: + 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('validateFdomdel0: no model') + return (False, { 'errors': [ 'Unable to retrieve the cluster configuration for %s. The configuration XML may contain errors' % clustername ]}) + + ret = validate_fdom_delete(model, name) + if ret[0] is not True: + return ret + + 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&busyfirst=true' % (baseurl, FDOMS, clustername)) + def validateFdom(self, request): from LuciValidation import validate_fdom @@ -1175,6 +1205,7 @@ 33: validateResourceAdd, 41: validateFdom, 44: validateFdom, + 46: deleteFdom, 51: validateFenceAdd, 54: validateFenceEdit, 55: validateDaemonProperties, Index: luci/site/luci/Extensions/conga_constants.py =================================================================== RCS file: /cvs/cluster/conga/luci/site/luci/Extensions/conga_constants.py,v retrieving revision 1.19.2.17 diff -u -r1.19.2.17 conga_constants.py --- a/luci/site/luci/Extensions/conga_constants.py 12 Mar 2008 15:13:13 -0000 1.19.2.17 +++ b/luci/site/luci/Extensions/conga_constants.py 6 Aug 2010 21:55:11 -0000 @@ -44,6 +44,7 @@ FDOM_LIST = '42' FDOM_CONFIG = '43' FDOM = '44' +FDOM_DELETE = '46' FENCEDEVS = '50' FENCEDEV_ADD = '51' FENCEDEV_LIST = '52' Index: luci/site/luci/Extensions/ClusterModel/ModelBuilder.py =================================================================== RCS file: /cvs/cluster/conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py,v retrieving revision 1.1.4.13 diff -u -r1.1.4.13 ModelBuilder.py --- a/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py 7 Jan 2010 18:08:35 -0000 1.1.4.13 +++ b/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py 6 Aug 2010 21:55:11 -0000 @@ -600,6 +600,9 @@ raise KeyError, 'Couldn\'t find service name %s in current list' % name + def getServicesForFdom(self, name): + return filter(lambda x: x.getAttribute('domain') == name, self.getServices()) + def retrieveVMsByName(self, name): vms = self.getVMs() for v in vms: