commit 01c335417a1bafb35a30093f9016b5ace3f7dc0d Author: Ryan McCabe rmccabe@redhat.com Date: Sun Oct 24 01:26:54 2010 -0400
Big cleanup of the cluster model class - Add support for retaining <!-- comments --> - Make sure the order of resources in services stays the same after resolving refs - Don't set the defaults for the totem, dlm, gfs_controld, and fence_daemon tags explicitly (unless a user specifies them)
luci/lib/ClusterConf/Action.py | 42 +++ luci/lib/ClusterConf/ClusterNode.py | 5 +- luci/lib/ClusterConf/Cman.py | 1 - luci/lib/ClusterConf/DLM.py | 1 - luci/lib/ClusterConf/Device.py | 10 +- luci/lib/ClusterConf/Event.py | 48 +++ luci/lib/ClusterConf/Events.py | 15 + luci/lib/ClusterConf/FenceDaemon.py | 1 - luci/lib/ClusterConf/FenceDevice.py | 13 +- luci/lib/ClusterConf/GFSControld.py | 1 - luci/lib/ClusterConf/LoggingDaemon.py | 9 + luci/lib/ClusterConf/ModelBuilder.py | 587 ++++++++++++++++----------------- luci/lib/ClusterConf/TagObject.py | 18 +- luci/lib/ClusterConf/Totem.py | 1 - 14 files changed, 434 insertions(+), 318 deletions(-) --- diff --git a/luci/lib/ClusterConf/Action.py b/luci/lib/ClusterConf/Action.py new file mode 100644 index 0000000..a27d69c --- /dev/null +++ b/luci/lib/ClusterConf/Action.py @@ -0,0 +1,42 @@ +# Copyright (C) 2010 Red Hat, Inc. +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of version 2 of the +# GNU General Public License as published by the +# Free Software Foundation. + +from TagObject import TagObject + +TAG_NAME = "action" + +class Action(TagObject): + def __init__(self): + TagObject.__init__(self) + self.TAG_NAME = TAG_NAME + + def getDepth(self): + return self.getAttribute('depth') + + def setDepth(self, val): + return self.addAttribute('depth', val) + + def delDepth(self): + return self.removeAttribute('depth') + + def getInterval(self): + return self.getAttribute('interval') + + def setInterval(self, val): + return self.addIntegerAttribute('interval', val, (0, None)) + + def delInterval(self): + return self.removeAttribute('interval') + + def getTimeout(self): + return self.getAttribute('timeout') + + def setTimeout(self, val): + return self.addIntegerAttribute('timeout', val, (0, None)) + + def delTimeout(self): + return self.removeAttribute('timeout') diff --git a/luci/lib/ClusterConf/ClusterNode.py b/luci/lib/ClusterConf/ClusterNode.py index 7949373..2929ddc 100644 --- a/luci/lib/ClusterConf/ClusterNode.py +++ b/luci/lib/ClusterConf/ClusterNode.py @@ -26,9 +26,8 @@ class ClusterNode(TagObject): self.addChild(ret) return ret
- def getFenceLevels(self): - # This method returns the set of 'method' objs. 'method' blocks represent - # fence levels + def getFenceMethods(self): + # This method returns the set of 'method' objs. return self.getFenceNode().getChildren()
def getVotes(self): diff --git a/luci/lib/ClusterConf/Cman.py b/luci/lib/ClusterConf/Cman.py index 00e9740..2f66a19 100644 --- a/luci/lib/ClusterConf/Cman.py +++ b/luci/lib/ClusterConf/Cman.py @@ -13,7 +13,6 @@ class Cman(TagObject): def __init__(self): TagObject.__init__(self) self.TAG_NAME = TAG_NAME - self.DEFAULTS = {}
def setBroadcast(self, val): return self.addBinaryAttribute('broadcast', val, (None, 'yes')) diff --git a/luci/lib/ClusterConf/DLM.py b/luci/lib/ClusterConf/DLM.py index b4d64d3..ab875af 100644 --- a/luci/lib/ClusterConf/DLM.py +++ b/luci/lib/ClusterConf/DLM.py @@ -29,7 +29,6 @@ class DLM(TagObject): def __init__(self): TagObject.__init__(self) self.TAG_NAME = TAG_NAME - self.attr_hash.update(DLM.DEFAULTS)
def getLogDebug(self): return self.getBinaryAttribute('log_debug') diff --git a/luci/lib/ClusterConf/Device.py b/luci/lib/ClusterConf/Device.py index 9f92f62..a991318 100644 --- a/luci/lib/ClusterConf/Device.py +++ b/luci/lib/ClusterConf/Device.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2009 Red Hat, Inc. +# Copyright (C) 2006-2010 Red Hat, Inc. # # This program is free software; you can redistribute # it and/or modify it under the terms of version 2 of the @@ -17,7 +17,6 @@ class Device(TagObject): self.TAG_NAME = TAG_NAME self.agent_type = "" self.has_native_option_set = False - self.pretty_fence_names = FenceDeviceAttr.FENCE_OPTS
def getAgentType(self): return self.agent_type @@ -34,12 +33,11 @@ class Device(TagObject): def addAttribute(self, name, value): if name == OPTION: self.has_native_option_set = True - self.attr_hash[name] = value + return super(Device, self).addAttribute(name, value)
def clone(self): """Creates a shallow copy of itself.""" - ret = TagObject.clone(self) - ret.agent_type = self.agent_type + ret = super(Device, self).clone() + ret.setAgentType(self.getAgentType()) ret.has_native_option_set = self.has_native_option_set - ret.pretty_fence_names = self.pretty_fence_names return ret diff --git a/luci/lib/ClusterConf/Event.py b/luci/lib/ClusterConf/Event.py new file mode 100644 index 0000000..82c52b0 --- /dev/null +++ b/luci/lib/ClusterConf/Event.py @@ -0,0 +1,48 @@ +# Copyright (C) 2010 Red Hat, Inc. +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of version 2 of the +# GNU General Public License as published by the +# Free Software Foundation. + +from TagObject import TagObject + +TAG_NAME = "event" + +class Event(TagObject): + def __init__(self): + TagObject.__init__(self) + self.TAG_NAME = TAG_NAME + + def getFile(self): + return self.getAttribute('file') + + def getPriority(self): + return self.getAttribute('priority') + + def getClass(self): + return self.getAttribute('class') + + def getService(self): + return self.getAttribute('service') + + def getServiceState(self): + return self.getAttribute('service_state') + + def getServiceOwner(self): + return self.getAttribute('service_owner') + + def getNode(self): + return self.getAttribute('node') + + def getNodeID(self): + return self.getAttribute('node_id') + + def getNodeState(self): + return self.getBinaryAttribute('node_state') + + def getNodeClean(self): + return self.getBinaryAttribute('node_clean') + + def getNodeLocal(self): + return self.getBinaryAttribute('node_local') diff --git a/luci/lib/ClusterConf/Events.py b/luci/lib/ClusterConf/Events.py new file mode 100644 index 0000000..2f78bdc --- /dev/null +++ b/luci/lib/ClusterConf/Events.py @@ -0,0 +1,15 @@ +# Copyright (C) 2010 Red Hat, Inc. +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of version 2 of the +# GNU General Public License as published by the +# Free Software Foundation. + +from TagObject import TagObject + +TAG_NAME = "events" + +class Events(TagObject): + def __init__(self): + TagObject.__init__(self) + self.TAG_NAME = TAG_NAME diff --git a/luci/lib/ClusterConf/FenceDaemon.py b/luci/lib/ClusterConf/FenceDaemon.py index 4a8d7af..bd665a1 100644 --- a/luci/lib/ClusterConf/FenceDaemon.py +++ b/luci/lib/ClusterConf/FenceDaemon.py @@ -19,7 +19,6 @@ class FenceDaemon(TagObject): def __init__(self): TagObject.__init__(self) self.TAG_NAME = TAG_NAME - self.attr_hash.update(FenceDaemon.DEFAULTS)
def getPostJoinDelay(self): return self.getAttribute('post_join_delay') diff --git a/luci/lib/ClusterConf/FenceDevice.py b/luci/lib/ClusterConf/FenceDevice.py index 2c01672..3a90403 100644 --- a/luci/lib/ClusterConf/FenceDevice.py +++ b/luci/lib/ClusterConf/FenceDevice.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2009 Red Hat, Inc. +# Copyright (C) 2006-2010 Red Hat, Inc. # # This program is free software; you can redistribute # it and/or modify it under the terms of version 2 of the @@ -10,16 +10,13 @@ from TagObject import TagObject
TAG_NAME = "fencedevice"
- class FenceDevice(TagObject): def __init__(self): TagObject.__init__(self) self.TAG_NAME = TAG_NAME - self.pretty_fence_names = FenceDeviceAttr.FENCE_OPTS - self.shared_fences = FenceDeviceAttr.FENCE_SHARED
def getAgentType(self): - agent = self.attr_hash["agent"] + agent = self.attr_hash.get('agent') try: return agent[agent.rfind('/') + 1:] except: @@ -28,9 +25,9 @@ class FenceDevice(TagObject):
def getPrettyName(self): agent_type = self.getAgentType() - pname = self.pretty_fence_names.get(agent_type) + pname = FenceDeviceAttr.FENCE_OPTS.get(agent_type) if pname is None: - pname = agent_type + return agent_type return pname
def isShared(self): @@ -41,4 +38,4 @@ class FenceDevice(TagObject): return False else: return True - return self.shared_fences.has_key(agent) + return FenceDeviceAttr.FENCE_SHARED.has_key(agent) diff --git a/luci/lib/ClusterConf/GFSControld.py b/luci/lib/ClusterConf/GFSControld.py index 297a7e6..0429e6d 100644 --- a/luci/lib/ClusterConf/GFSControld.py +++ b/luci/lib/ClusterConf/GFSControld.py @@ -24,7 +24,6 @@ class GFSControld(TagObject): def __init__(self): TagObject.__init__(self) self.TAG_NAME = TAG_NAME - self.attr_hash.update(GFSControld.DEFAULTS)
def getEnableWithdraw(self): return self.getBinaryAttribute('enable_withdraw') diff --git a/luci/lib/ClusterConf/LoggingDaemon.py b/luci/lib/ClusterConf/LoggingDaemon.py index d886bc6..86bac98 100644 --- a/luci/lib/ClusterConf/LoggingDaemon.py +++ b/luci/lib/ClusterConf/LoggingDaemon.py @@ -13,3 +13,12 @@ class LoggingDaemon(Logging): def __init__(self): Logging.__init__(self) self.TAG_NAME = TAG_NAME + + def getSubsys(self): + return self.getAttribute('subsys') + + def setSubsys(self, val): + return self.addAttribute('subsys', val) + + def delSubsys(self): + return self.removeAttribute('subsys') diff --git a/luci/lib/ClusterConf/ModelBuilder.py b/luci/lib/ClusterConf/ModelBuilder.py index 463010b..ffa6497 100644 --- a/luci/lib/ClusterConf/ModelBuilder.py +++ b/luci/lib/ClusterConf/ModelBuilder.py @@ -7,163 +7,159 @@
from xml.dom import minidom, Node from TagObject import TagObject -from Cluster import Cluster -from ClusterNode import ClusterNode -from ClusterNodes import ClusterNodes -from Fence import Fence -from Unfence import Unfence -from FenceDevice import FenceDevice -from FenceDevices import FenceDevices -from Method import Method -from Device import Device -from Cman import Cman -from Totem import Totem -from DLM import DLM -from Lockspace import Lockspace -from GFSControld import GFSControld -from Interface import Interface -from Clvmd import Clvmd -from Group import Group -from Master import Master -from Ip import Ip -from Script import Script -from Logging import Logging -from LoggingDaemon import LoggingDaemon -from NFSClient import NFSClient -from NFSExport import NFSExport -from NFSServer import NFSServer -from Fs import Fs -from Samba import Samba -from Apache import Apache -from Named import Named -from DRBD import DRBD -from LVM import LVM -from MySQL import MySQL -from OpenLDAP import OpenLDAP -from Postgres8 import Postgres8 -from Tomcat5 import Tomcat5 -from Tomcat6 import Tomcat6 -from SAPDatabase import SAPDatabase -from SAPInstance import SAPInstance -from SybaseASE import SybaseASE -from OracleDB import OracleDB -from Multicast import Multicast -from FenceDaemon import FenceDaemon -from FenceXVMd import FenceXVMd -from Netfs import Netfs -from Clusterfs import Clusterfs -from Resources import Resources -from Service import Service -from QuorumD import QuorumD -from Heuristic import Heuristic -from Vm import Vm from RefObject import RefObject -from FailoverDomain import FailoverDomain -from FailoverDomains import FailoverDomains -from FailoverDomainNode import FailoverDomainNode -from Rm import Rm -from Altname import Altname + +import Cluster + +# Children of <cluster> +import Cman, Totem, QuorumD, FenceDaemon, FenceXVMd, DLM, GFSControld, \ + Group, Logging, ClusterNodes, FenceDevices, Rm, Clvmd + +# Children of <cman> +import Multicast + +# Children of <totem> +import Interface + +# Children of <quorumd> +import Heuristic + +# Children of <dlm> +import Lockspace + +# Children of <lockspace> +import Master + +# Children of <logging> +import LoggingDaemon + +# Children of <clusternodes> +import ClusterNode + +# Children of <clusternode> +import Altname, Fence, Unfence + +# Children of <fence> +import Method + +# Children of <method> +import Device + +# Children of <fencedevices> +import FenceDevice + +# Children of <rm> +import FailoverDomains, Events, Resources, Service, Vm + +# Children of <failoverdomains> +import FailoverDomain + +# Children of <failoverdomain> +import FailoverDomainNode + +# Children of <events> +import Event + +# Children of <resources> and <service> +import Ip, Script, NFSClient, NFSExport, NFSServer, Fs, Samba, Apache, Named, \ + DRBD, LVM, MySQL, OpenLDAP, Postgres8, Tomcat5, Tomcat6, \ + SAPDatabase, SAPInstance, SybaseASE, OracleDB, Netfs, Clusterfs + +# Children of resource types +import Action
TAGNAMES = { - 'cluster': Cluster, - 'clusternodes': ClusterNodes, - 'clusternode': ClusterNode, - 'altname': Altname, - 'fence': Fence, - 'device': Device, - 'unfence': Unfence, - 'logging': Logging, - 'logging_daemon': LoggingDaemon, - 'fencedevice': FenceDevice, - 'fencedevices': FenceDevices, - 'method': Method, - 'cman': Cman, - 'totem': Totem, - 'interface': Interface, - 'group': Group, - 'clvmd': Clvmd, - 'gfs_controld': GFSControld, - 'dlm': DLM, - 'lockspace': Lockspace, - 'master': Master, - 'rm': Rm, - 'service': Service, - 'vm': Vm, - 'fence_xvmd': FenceXVMd, - 'resources': Resources, - 'failoverdomain': FailoverDomain, - 'failoverdomains': FailoverDomains, - 'failoverdomainnode': FailoverDomainNode, - 'quorumd': QuorumD, - 'heuristic': Heuristic, - 'ip': Ip, - 'fs': Fs, - 'smb': Samba, - 'apache': Apache, - 'named': Named, - 'drbd': DRBD, - 'lvm': LVM, - 'mysql': MySQL, - 'openldap': OpenLDAP, - 'postgres-8': Postgres8, - 'tomcat-5': Tomcat5, - 'tomcat-6': Tomcat6, - 'fence_daemon': FenceDaemon, - 'multicast': Multicast, - 'clusterfs': Clusterfs, - 'netfs': Netfs, - 'script': Script, - 'nfsexport': NFSExport, - 'nfsclient': NFSClient, - 'nfsserver': NFSServer, - 'SAPDatabase': SAPDatabase, - 'SAPInstance': SAPInstance, - 'ASEHAagent': SybaseASE, - 'oracledb': OracleDB, + Cluster.TAG_NAME: Cluster.Cluster, + Totem.TAG_NAME: Totem.Totem, + Interface.TAG_NAME: Interface.Interface, + Cman.TAG_NAME: Cman.Cman, + Multicast.TAG_NAME: Multicast.Multicast, + Group.TAG_NAME: Group.Group, + Clvmd.TAG_NAME: Clvmd.Clvmd, + GFSControld.TAG_NAME: GFSControld.GFSControld, + DLM.TAG_NAME: DLM.DLM, + Lockspace.TAG_NAME: Lockspace.Lockspace, + Master.TAG_NAME: Master.Master, + ClusterNodes.TAG_NAME: ClusterNodes.ClusterNodes, + ClusterNode.TAG_NAME: ClusterNode.ClusterNode, + Altname.TAG_NAME: Altname.Altname, + Method.TAG_NAME: Method.Method, + Fence.TAG_NAME: Fence.Fence, + Device.TAG_NAME: Device.Device, + Unfence.TAG_NAME: Unfence.Unfence, + FenceDaemon.TAG_NAME: FenceDaemon.FenceDaemon, + Logging.TAG_NAME: Logging.Logging, + LoggingDaemon.TAG_NAME: LoggingDaemon.LoggingDaemon, + FenceDevice.TAG_NAME: FenceDevice.FenceDevice, + FenceDevices.TAG_NAME: FenceDevices.FenceDevices, + FenceXVMd.TAG_NAME: FenceXVMd.FenceXVMd, + FailoverDomains.TAG_NAME: FailoverDomains.FailoverDomains, + FailoverDomain.TAG_NAME: FailoverDomain.FailoverDomain, + FailoverDomainNode.TAG_NAME: FailoverDomainNode.FailoverDomainNode, + Events.TAG_NAME: Events.Events, + Event.TAG_NAME: Event.Event, + QuorumD.TAG_NAME: QuorumD.QuorumD, + Heuristic.TAG_NAME: Heuristic.Heuristic, + Rm.TAG_NAME: Rm.Rm, + Service.TAG_NAME: Service.Service, + Vm.TAG_NAME: Vm.Vm, + Resources.TAG_NAME: Resources.Resources, + Ip.TAG_NAME: Ip.Ip, + Fs.TAG_NAME: Fs.Fs, + Samba.TAG_NAME: Samba.Samba, + Apache.TAG_NAME: Apache.Apache, + Named.TAG_NAME: Named.Named, + DRBD.TAG_NAME: DRBD.DRBD, + LVM.TAG_NAME: LVM.LVM, + MySQL.TAG_NAME: MySQL.MySQL, + OpenLDAP.TAG_NAME: OpenLDAP.OpenLDAP, + Postgres8.TAG_NAME: Postgres8.Postgres8, + Tomcat5.TAG_NAME: Tomcat5.Tomcat5, + Tomcat6.TAG_NAME: Tomcat6.Tomcat6, + Clusterfs.TAG_NAME: Clusterfs.Clusterfs, + Netfs.TAG_NAME: Netfs.Netfs, + Script.TAG_NAME: Script.Script, + NFSExport.TAG_NAME: NFSExport.NFSExport, + NFSClient.TAG_NAME: NFSClient.NFSClient, + NFSServer.TAG_NAME: NFSServer.NFSServer, + SAPDatabase.TAG_NAME: SAPDatabase.SAPDatabase, + SAPInstance.TAG_NAME: SAPInstance.SAPInstance, + SybaseASE.TAG_NAME: SybaseASE.SybaseASE, + OracleDB.TAG_NAME: OracleDB.OracleDB, + Action.TAG_NAME: Action.Action, }
-###---Don't translate strings below--- -CLUSTER_PTR_STR = "cluster" -CLUSTERNODES_PTR_STR = "clusternodes" -FAILDOMS_PTR_STR = "failoverdomains" -FENCEDEVICES_PTR_STR = "fencedevices" -RESOURCEMANAGER_PTR_STR = "rm" -RESOURCES_PTR_STR = "resources" -FENCEDAEMON_PTR_STR = "fence_daemon" -SERVICE = "service" -VM = "vm" -FENCE_XVMD_STR = "fence_xvmd" -MCAST_STR = "multicast" -CMAN_PTR_STR = "cman" -TOTEM_PTR_STR = "totem" -QUORUMD_PTR_STR = "quorumd" -###----------------------------------- - class ModelBuilder: - def __init__(self, domm=None, cluster_version=(3, 'Fedora')): - if domm is None: + def __init__(self, conf_xml_obj, cluster_version=(3, 'Fedora')): + if conf_xml_obj is None: raise Exception, 'No cluster configuration' - self.errors = False self.errmsg = None - self.mcast_ptr = None + self.isModified = False + self.cluster_ptr = None - self.CMAN_ptr = None - self.TOTEM_ptr = None + self.cman_ptr = None + self.totem_ptr = None self.logging_ptr = None + self.group_ptr = None + self.clvmd_ptr = None self.clusternodes_ptr = None self.failoverdomains_ptr = None self.fencedevices_ptr = None self.resourcemanager_ptr = None - self.resources_ptr = None self.fence_daemon_ptr = None - self.isModified = False self.quorumd_ptr = None self.fence_xvmd_ptr = None - self.unusual_items = list() + self.dlm_ptr = None + self.gfscontrold_ptr = None + self.events_ptr = None + self.resources_ptr = None + self.mcast_ptr = None + self.lockspace_ptr = None + self.unknown_elements = list() (self.cluster_version, self.cluster_os) = cluster_version
- self.parent = domm + self.parent = conf_xml_obj self.object_tree = self.buildModel(None) self.check_empty_ptrs() self.check_fence_daemon() @@ -188,70 +184,96 @@ class ModelBuilder: if parent_node is None: parent_node = self.parent
+ comment_nodes = [] new_object = None + if parent_node.nodeType == Node.DOCUMENT_NODE: - parent_node = parent_node.firstChild + for n in parent_node.childNodes: + if n.nodeType == Node.ELEMENT_NODE: + parent_node = n + elif n.nodeType == Node.COMMENT_NODE: + comment_nodes.append(n)
if parent_node.nodeType == Node.ELEMENT_NODE: - #Create proper type + unknown_element = False try: + # Create proper type new_object = TAGNAMES[parent_node.nodeName]() - attrs = parent_node.attributes - for attrName in attrs.keys(): - attrNode = attrs.get(attrName) - attrValue = attrNode.nodeValue - new_object.addAttribute(attrName, attrValue) - except KeyError, e: ##This allows for custom tags + except KeyError, e: + # This allows for custom tags new_object = TagObject(parent_node.nodeName) - attrs = parent_node.attributes - for attrName in attrs.keys(): - attrNode = attrs.get(attrName) - attrValue = attrNode.nodeValue - new_object.addAttribute(attrName, attrValue) - self.unusual_items.append((parent_object, new_object)) + unknown_element = True + + new_object.comments = [c.data for c in comment_nodes] + + for k, v in parent_node.attributes.items(): + new_object.addAttribute(k, v) + + if unknown_element is True: + self.unknown_elements.append((parent_object, new_object)) for item in parent_node.childNodes: result_object = self.buildModel(item, new_object) if result_object is not None: new_object.addChild(result_object) return None
- ######End of unusual item exception - - if parent_node.nodeName == CLUSTER_PTR_STR: + if parent_node.nodeName == Cluster.TAG_NAME: self.cluster_ptr = new_object - if parent_node.nodeName == CLUSTERNODES_PTR_STR: + elif parent_node.nodeName == Cman.TAG_NAME: + self.cman_ptr = new_object + elif parent_node.nodeName == Totem.TAG_NAME: + self.totem_ptr = new_object + elif parent_node.nodeName == QuorumD.TAG_NAME: + self.quorumd_ptr = new_object + elif parent_node.nodeName == FenceDaemon.TAG_NAME: + self.fence_daemon_ptr = new_object + elif parent_node.nodeName == FenceXVMd.TAG_NAME: + self.fence_xvmd_ptr = new_object + elif parent_node.nodeName == DLM.TAG_NAME: + self.dlm_ptr = new_object + elif parent_node.nodeName == GFSControld.TAG_NAME: + self.gfscontrold_ptr = new_object + elif parent_node.nodeName == Group.TAG_NAME: + self.group_ptr = new_object + elif parent_node.nodeName == Logging.TAG_NAME: + self.logging_ptr = new_object + elif parent_node.nodeName == ClusterNodes.TAG_NAME: self.clusternodes_ptr = new_object - elif parent_node.nodeName == FENCEDEVICES_PTR_STR: + elif parent_node.nodeName == Rm.TAG_NAME: + self.resourcemanager_ptr = new_object + elif parent_node.nodeName == Clvmd.TAG_NAME: + self.clvmd_ptr = new_object + elif parent_node.nodeName == FenceDevices.TAG_NAME: self.fencedevices_ptr = new_object - elif parent_node.nodeName == FAILDOMS_PTR_STR: + elif parent_node.nodeName == FailoverDomains.TAG_NAME: self.failoverdomains_ptr = new_object - elif parent_node.nodeName == RESOURCEMANAGER_PTR_STR: - self.resourcemanager_ptr = new_object - elif parent_node.nodeName == RESOURCES_PTR_STR: + elif parent_node.nodeName == Resources.TAG_NAME: self.resources_ptr = new_object - elif parent_node.nodeName == FENCEDAEMON_PTR_STR: - self.fence_daemon_ptr = new_object - elif parent_node.nodeName == QUORUMD_PTR_STR: - self.quorumd_ptr = new_object - elif parent_node.nodeName == CMAN_PTR_STR: - self.CMAN_ptr = new_object - elif parent_node.nodeName == TOTEM_PTR_STR: - self.TOTEM_ptr = new_object - elif parent_node.nodeName == MCAST_STR: + elif parent_node.nodeName == Multicast.TAG_NAME: self.mcast_ptr = new_object - elif parent_node.nodeName == FENCE_XVMD_STR: - self.fence_xvmd_ptr = new_object - + elif parent_node.nodeName == Lockspace.TAG_NAME: + self.lockspace_ptr = new_object + elif parent_node.nodeName == Events.TAG_NAME: + self.events_ptr = new_object else: + if parent_node.nodeType == Node.COMMENT_NODE: + return parent_node return None
- + pending_comments = [] for item in parent_node.childNodes: result_object = self.buildModel(item, new_object) if result_object is not None: - new_object.addChild(result_object) + if not issubclass(type(result_object), TagObject): + pending_comments.append(result_object.data) + else: + result_object.comments = pending_comments + new_object.addChild(result_object) + pending_comments = []
- return (new_object) + if len(pending_comments) > 0: + new_object.trailing_comments = pending_comments + return new_object
def getFenceDeviceByName(self, name): device = filter(lambda x: x.getName() == name, self.getFenceDevices()) @@ -280,8 +302,8 @@ class ModelBuilder: self.errors = True
for node in self.getNodes(): - for level in node.getFenceLevels(): - for child in level.getChildren(): + for method in node.getFenceMethods(): + for child in method.getChildren(): try: child.setAgentType(agent_hash[child.getName()]) except KeyError, e: @@ -298,25 +320,21 @@ class ModelBuilder: reset_list_sentinel = False resource_children = self.resourcemanager_ptr.getChildren() for r_child in resource_children: - if r_child.getTagName() == SERVICE: + if r_child.getTagName() == Service.TAG_NAME: reset_list_sentinel = self.find_references(r_child) if reset_list_sentinel is True: break
def find_references(self, entity, parent=None): - result = False - if (entity.getAttribute("ref") is not None) and (entity.isRefObject() is False): - result = self.transform_reference(entity, parent) - return result + if entity.getAttribute("ref") is not None and entity.isRefObject() is False: + result = self.transform_reference(entity, parent) + return result
- children = entity.getChildren() - if len(children) > 0: - for child in children: + for child in entity.getChildren(): result = self.find_references(child, entity) if result is True: return result - - return result + return False
def transform_reference(self, entity, parent): result = False @@ -355,12 +373,10 @@ class ModelBuilder: pass
if parent is None: #Must be a service - self.resourcemanager_ptr.addChild(rf) - self.resourcemanager_ptr.removeChild(entity) + self.resourcemanager_ptr.replaceChild(entity, rf) return True else: - parent.addChild(rf) - parent.removeChild(entity) + parent.replaceChild(entity, rf) return True
def exportModelAsString(self): @@ -369,7 +385,7 @@ class ModelBuilder:
#check for dual power fences self.dual_power_fence_check() - self.restore_unusual_items() + self.restore_unknown_elements()
try: doc = minidom.Document() @@ -387,36 +403,25 @@ class ModelBuilder: self.resolve_fence_instance_types() self.purgePCDuplicates() self.resolve_references() - - finally: - pass - #dual_power_fence_check() adds extra - #fence instance entries for dual power controllers - #These must be removed from the tree before the UI - #can be used - #self.purgePCDuplicates() + except Exception, e: + strbuf = ""
return strbuf
- def restore_unusual_items(self): - for item in self.unusual_items: + def restore_unknown_elements(self): + for item in self.unknown_elements: duplicate = False - kids = item[0].getChildren() - for kid in kids: + for kid in item[0].getChildren(): if kid == item[1]: duplicate = True break - if duplicate is True: - continue - else: + if duplicate is not True: item[0].addChild(item[1])
def check_for_nodeids(self): - nodes = self.getNodes() - for node in nodes: - if node.getAttribute('nodeid') is None: - new_id = self.getUniqueNodeID() - node.addAttribute('nodeid', new_id) + for node in self.getNodes(): + if node.getNodeID() is None: + node.setNodeID(self.getUniqueNodeID())
def getUniqueNodeID(self): nodes = self.getNodes() @@ -450,15 +455,17 @@ class ModelBuilder:
def getNodeNameById(self, node_id): try: - return filter(lambda x: x.getAttribute('nodeid') == node_id, self.clusternodes_ptr.getChildren())[0].getName() + return filter(lambda x: x.getNodeID() == node_id, self.clusternodes_ptr.getChildren())[0].getName() except: - return None + pass + return None
def getNodeByName(self, node_name): try: - return filter(lambda x: x.getAttribute('name') == node_name, self.clusternodes_ptr.getChildren())[0] + return filter(lambda x: x.getName() == node_name, self.clusternodes_ptr.getChildren())[0] except: - return None + pass + return None
def addNode(self, clusternode): self.clusternodes_ptr.addChild(clusternode) @@ -471,8 +478,8 @@ class ModelBuilder:
name = clusternode.getName()
- for level in clusternode.getFenceLevels(): - for fence in level.getChildren(): + for method in clusternode.getFenceMethods(): + for fence in method.getChildren(): fdev = self.getFenceDeviceByName(fence.getName()) if fdev and not fdev.isShared(): self.deleteFenceDevice(fdev) @@ -511,7 +518,7 @@ class ModelBuilder: return None
def getServicesForFdom(self, name): - svc_list = filter(lambda x: x.getAttribute('domain') == name, self.getServices()) + svc_list = filter(lambda x: x.getFailoverDomain() == name, self.getServices()) return svc_list
def retrieveVMsByName(self, name): @@ -522,16 +529,16 @@ class ModelBuilder: return None
def del_totem(self): - if self.TOTEM_ptr is not None: - self.cluster_ptr.removeChild(self.TOTEM_ptr) - self.TOTEM_ptr = None + if self.totem_ptr is not None: + self.cluster_ptr.removeChild(self.totem_ptr) + self.totem_ptr = None
def addTotem(self): self.del_totem() - if self.TOTEM_ptr is None: - self.TOTEM_ptr = Totem() - self.cluster_ptr.addChild(self.TOTEM_ptr) - return self.TOTEM_ptr + if self.totem_ptr is None: + self.totem_ptr = Totem.Totem() + self.cluster_ptr.addChild(self.totem_ptr) + return self.totem_ptr
def hasFenceXVM(self): return self.fence_xvmd_ptr is not None @@ -570,8 +577,8 @@ class ModelBuilder: nodes = self.getNodes() for i in nodes: added_node = False - levels = i.getFenceLevels() - for l in levels: + methods = i.getFenceMethods() + for l in methods: lc = l.getChildren() for dev in lc: if dev.getName() == fence_name: @@ -621,18 +628,12 @@ class ModelBuilder: for fdom in fdoms: if fdom.getName().encode('ascii', 'ignore') == fd: kids = fdom.getChildren() - newnode = FailoverDomainNode() + newnode = FailoverDomainNode.FailoverDomainNode() if len(kids) != 0: #Use an existing node as a baseline... - attrs = kids[0].getAttributes() - kees = attrs.keys() - for k in kees: - newnode.addAttribute(k, attrs[k]) - newnode.addAttribute("name", node) - else: - newnode.addAttribute("name", node) + newnode.attr_hash.update(kids[0].getAttributes()) + newnode.setName(node) fdom.addChild(newnode) return - return
def removeNodeFromFailoverDomain(self, node, fd): @@ -683,27 +684,27 @@ class ModelBuilder:
def check_empty_ptrs(self): if self.resourcemanager_ptr is None: - rm = Rm() + rm = Rm.Rm() self.cluster_ptr.addChild(rm) self.resourcemanager_ptr = rm
if self.failoverdomains_ptr is None: - fdoms = FailoverDomains() + fdoms = FailoverDomains.FailoverDomains() self.resourcemanager_ptr.addChild(fdoms) self.failoverdomains_ptr = fdoms
if self.fencedevices_ptr is None: - fds = FenceDevices() + fds = FenceDevices.FenceDevices() self.cluster_ptr.addChild(fds) self.fencedevices_ptr = fds
if self.resources_ptr is None: - rcs = Resources() + rcs = Resources.Resources() self.resourcemanager_ptr.addChild(rcs) self.resources_ptr = rcs
if self.fence_daemon_ptr is None: - fdp = FenceDaemon() + fdp = FenceDaemon.FenceDaemon() self.cluster_ptr.addChild(fdp) self.fence_daemon_ptr = fdp
@@ -712,7 +713,7 @@ class ModelBuilder: if self.resourcemanager_ptr is not None: kids = self.resourcemanager_ptr.getChildren() for kid in kids: - if kid.getTagName() in (SERVICE, VM): + if kid.getTagName() in (Service.TAG_NAME, Vm.TAG_NAME): rg_list.append(kid)
return rg_list @@ -730,7 +731,7 @@ class ModelBuilder: if self.resourcemanager_ptr is not None: kids = self.resourcemanager_ptr.getChildren() for kid in kids: - if kid.getTagName() == VM: + if kid.getTagName() == Vm.TAG_NAME: rg_list.append(kid)
return rg_list @@ -794,10 +795,10 @@ class ModelBuilder: return self.getClusterPtr().setConfigVersion(version)
def getCMANPtr(self): - return self.CMAN_ptr + return self.cman_ptr
def getTotemPtr(self): - return self.TOTEM_ptr + return self.totem_ptr
def getLoggingPtr(self): return self.logging_ptr @@ -805,40 +806,40 @@ class ModelBuilder: def set_cluster_broadcast(self): if self.del_cluster_multicast() is False: return False - return self.CMAN_ptr.setBroadcast(True) + return self.cman_ptr.setBroadcast(True)
def del_cluster_broadcast(self): - if self.CMAN_ptr is None: + if self.cman_ptr is None: return False - self.CMAN_ptr.removeAttribute('broadcast') + self.cman_ptr.delBroadcast() self.isModified = True
def get_cluster_broadcast(self): - if self.CMAN_ptr is None: + if self.cman_ptr is None: return False - return self.CMAN_ptr.getBroadcast() + return self.cman_ptr.getBroadcast()
def set_cluster_multicast(self, mcast_addr=None): self.del_cluster_broadcast() if mcast_addr is not None: if self.mcast_ptr is None: - self.mcast_ptr = Multicast() - self.CMAN_ptr.addChild(self.mcast_ptr) + self.mcast_ptr = Multicast.Multicast() + self.cman_ptr.addChild(self.mcast_ptr) self.mcast_ptr.setAddr(mcast_addr)
def del_cluster_multicast(self): - if self.CMAN_ptr is None: + if self.cman_ptr is None: return True
if self.mcast_ptr is not None: - self.CMAN_ptr.removeChild(self.mcast_ptr) + self.cman_ptr.removeChild(self.mcast_ptr) self.mcast_ptr = None self.isModified = True return True
def check_fence_daemon(self): if self.fence_daemon_ptr is None: - self.fence_daemon_ptr = FenceDaemon() + self.fence_daemon_ptr = FenceDaemon.FenceDaemon() self.cluster_ptr.addChild(self.fence_daemon_ptr)
def getFenceDaemonPtr(self): @@ -859,43 +860,43 @@ class ModelBuilder: children = fdom.getChildren() #These are failoverdomainnodes... for child in children: if child.getName().strip() == oldname: - child.addAttribute("name", newname) + child.setName(newname)
###This method runs through ALL fences (Device objs) and changes name attr ###to new name def rectifyNewFencedevicenameWithFences(self, oldname, newname): nodes = self.getNodes() for node in nodes: - levels = node.getFenceLevels() - for level in levels: - fences = level.getChildren() + methods = node.getFenceMethods() + for method in methods: + fences = method.getChildren() for fence in fences: if fence.getName() == oldname: - fence.addAttribute("name", newname) + fence.setName(newname)
###Method for removing fence instances if a fence device ###has been deleted from the configuration def removeFenceInstancesForFenceDevice(self, name): nodes = self.getNodes() for node in nodes: - levels = node.getFenceLevels() - for level in levels: - fences = level.getChildren() + methods = node.getFenceMethods() + for method in methods: + fences = method.getChildren() kill_list = list() for fence in fences: if fence.getName() == name: kill_list.append(fence) for victim in kill_list: - node.removeFenceInstance(level, victim) + node.removeFenceInstance(method, victim)
def removeReferences(self, tagobj): self.__removeReferences(tagobj, self.cluster_ptr)
- def __removeReferences(self, tagobj, level): - for t in level.getChildren()[:]: + def __removeReferences(self, tagobj, method): + for t in method.getChildren()[:]: if t.isRefObject(): if t.getObj() == tagobj: - level.removeChild(t) + method.removeChild(t) continue self.__removeReferences(tagobj, t)
@@ -924,8 +925,8 @@ class ModelBuilder: def updateReferences(self): self.__updateReferences(self.cluster_ptr)
- def __updateReferences(self, level): - for t in level.getChildren(): + def __updateReferences(self, method): + for t in method.getChildren(): if t.isRefObject(): t.setRef(t.getObj().getName()) self.__updateReferences(t) @@ -938,52 +939,50 @@ class ModelBuilder: clusternodes_count = len(self.getNodes()) # Make certain that there is a cman tag in the file # If missing, it will not hurt to add it here - if self.CMAN_ptr is None: - cman = Cman() + if self.cman_ptr is None: + cman = Cman.Cman() self.cluster_ptr.addChild(cman) - self.CMAN_ptr = cman + self.cman_ptr = cman
if self.isQuorumd(): - self.CMAN_ptr.removeAttribute('two_node') - self.CMAN_ptr.addAttribute('expected_votes', str(self.get_expected_votes())) + self.cman_ptr.delTwoNode() + self.cman_ptr.setExpectedVotes(self.get_expected_votes()) else: if clusternodes_count == 2: - self.CMAN_ptr.addAttribute('two_node', '1') - self.CMAN_ptr.addAttribute('expected_votes', '1') + self.cman_ptr.setTwoNode(True) + self.cman_ptr.setExpectedVotes(1) else: - self.CMAN_ptr.removeAttribute('two_node') - self.CMAN_ptr.removeAttribute('expected_votes') + self.cman_ptr.delTwoNode() + self.cman_ptr.delExpectedVotes()
def dual_power_fence_check(self): - # if 2 or more power controllers reside in the same fence level, + # if 2 or more power controllers reside in the same fence method, # duplicate entries must be made for every controller with an # attribute for option set first for off, then for on.
# for every node: - # for every fence level: + # for every fence method: # examine every fence - # If fence is of power type, add to 'found' list for that level + # If fence is of power type, add to 'found' list for that method # If 'found' list is longer than 1, write out extra objs for node in self.getNodes(): - for level in node.getFenceLevels(): + for method in node.getFenceMethods(): pc_list = list() - for kid in level.getChildren(): + for kid in method.getChildren(): if kid.hasNativeOptionSet() is True: continue if kid.isPowerController() is True: pc_list.append(kid)
if len(pc_list) > 1: - # Means we found multiple PCs in the same level + # Means we found multiple PCs in the same method for fence in pc_list: fence.addAttribute("option", "off") - d = Device() + d = Device.Device() + d.attr_hash.update(fence.getAttributes()) d.setAgentType(fence.getAgentType()) - attrs = fence.getAttributes() - for (k, v) in attrs.iteritems(): - d.addAttribute(k, v) d.addAttribute("option", "on") - level.addChild(d) + method.addChild(d)
def purgePCDuplicates(self): found_one = True @@ -991,9 +990,9 @@ class ModelBuilder: found_one = False nodes = self.getNodes() for node in nodes: - levels = node.getFenceLevels() - for level in levels: - kids = level.getChildren() + methods = node.getFenceMethods() + for method in methods: + kids = method.getChildren() for kid in kids: #kids are actual fence instance objects #Need to pass over this device if: ##1) It is not a power controller, or @@ -1007,7 +1006,7 @@ class ModelBuilder: if res == "off": kid.removeAttribute("option") else: - level.removeChild(kid) + method.removeChild(kid) found_one = True break if found_one is True: diff --git a/luci/lib/ClusterConf/TagObject.py b/luci/lib/ClusterConf/TagObject.py index 3dbbe9d..7d4c093 100644 --- a/luci/lib/ClusterConf/TagObject.py +++ b/luci/lib/ClusterConf/TagObject.py @@ -12,6 +12,8 @@ class TagObject(object): self.attr_hash = {} self.children = list() self.TAG_NAME = tagname + self.comments = list() + self.trailing_comments = list()
def addChild(self, child): self.children.append(child) @@ -44,7 +46,7 @@ class TagObject(object): if len(bounds) > 1 and bounds[1] is not None: if int_val > bounds[1]: raise ValueError, '%d not <= %d' % (int_val, bounds[1]) - return self.addAttribute(name, val) + return self.addAttribute(name, str(val))
def addBinaryAttribute(self, name, value, mapping): if value is None: @@ -96,15 +98,23 @@ class TagObject(object): tag.setAttribute(k, v)
def generateXML(self, doc, parent=None): - tag = doc.createElement(self.TAG_NAME) if parent is None: parent = doc + + for c in self.comments: + parent.appendChild(doc.createComment(c)) + + tag = doc.createElement(self.TAG_NAME) parent.appendChild(tag) self.exportAttributes(tag) + for child in self.children: if child is not None: child.generateXML(doc, tag)
+ for c in self.trailing_comments: + tag.appendChild(doc.createComment(c)) + def getAttributes(self): return self.attr_hash
@@ -118,6 +128,10 @@ class TagObject(object): def getName(self): return self.attr_hash.get('name', '')
+ def setName(self, val): + self.attr_hash['name'] = val + return val + def getTagName(self): return self.TAG_NAME
diff --git a/luci/lib/ClusterConf/Totem.py b/luci/lib/ClusterConf/Totem.py index bf270a2..86c87de 100644 --- a/luci/lib/ClusterConf/Totem.py +++ b/luci/lib/ClusterConf/Totem.py @@ -20,7 +20,6 @@ class Totem(TagObject): def __init__(self): TagObject.__init__(self) self.TAG_NAME = TAG_NAME - self.attr_hash.update(Totem.DEFAULTS)
def getJoinTimeout(self): return self.getAttribute('join')
luci-commits@lists.fedorahosted.org