commit 01c335417a1bafb35a30093f9016b5ace3f7dc0d
Author: Ryan McCabe <rmccabe(a)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')