From 76342f5aa39f3f4cc5647783ede8710ad030b653 Mon Sep 17 00:00:00 2001 From: Jan Pokorný Date: Mon, 2 Sep 2013 22:08:48 +0200 Subject: More massive update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (sorry, it's an trial-and-error hell) Signed-off-by: Jan Pokorný --- cluster-cman.py | 603 ++++++++++++++++++++++++++++++++++++++++++++------------ lib.py | 59 +++++- 2 files changed, 527 insertions(+), 135 deletions(-) diff --git a/cluster-cman.py b/cluster-cman.py index 69c5fa0..a7f2b56 100755 --- a/cluster-cman.py +++ b/cluster-cman.py @@ -27,136 +27,481 @@ BLACKLIST = [] OUTPUT = splitext(__file__)[0] -graph = lambda: \ -LibDot('Overview of CMAN-based cluster', - overlap='scalexy', - compound='true', - splines='yes', - # , ranksep='1.2', - _subgraphs=[ - # management client - SubgraphStandard('cluster-climgmt', - label='management client', - _nodes=[ - Executable('luci'), - Executable('ccs'), - ] - ), - # other monitoring - SubgraphStandard('cluster-monitor', - label='other monitoring', - _nodes=[ - Executable('snmpwalk'), - Executable('wbemcli'), - ] - ), - # nodes - SubgraphInvisible('cluster-nodes', - _subgraphs=[ - # node c - general - SubgraphImportant('cluster-node_c', - label='NODE C', - _subgraphs=[ - # node c - management - SubgraphStandard('cluster-node_c-conga', - label='management (incomplete)', - _nodes=[ - Daemon('node_c-ricci', - label='ricci'), - Daemon('node_c-modclusterd', - label='modclusterd') - ] - ) - ] - ), - # node b - detailed - SubgraphImportant('cluster-node_b', - label='NODE B', - _subgraphs=[ - # node b - management - SubgraphStandard('cluster-node_b-conga', - label='management', - _nodes=[ - Agent('node_b-libClusterMonitorSnmp.so', label='libClusterMonitorSnmp.so'), - Agent('node_b-libRedHatClusterProvider.so', label='libRedHatClusterProvider.so'), - Artefact('node_b-clumond.sock', label='/var/run/clumond.sock'), - Daemon('node_b-ricci', label='ricci'), - Daemon('node_b-modclusterd', label='modclusterd'), - Executable('node_b-modcluster', label='modcluster'), - ], - _edges=[ - Consume('node_b-libClusterMonitorSnmp.so', 'node_b-clumond.sock'), - Consume('node_b-libRedHatClusterProvider.so', 'node_b-clumond.sock'), - Consume('node_b-modcluster', 'node_b-clumond.sock'), - Produce('node_b-modclusterd', 'node_b-clumond.sock'), - ] - ), - # node b - core - SubgraphStandard('cluster-node_b-core', - label='core', - _nodes=[ - Library('node_b-libccsconfdb', label='libccsconfdb'), - Daemon('node_b-rgmanager', label='rgmanager'), - Executable('node_b-clustat', label='clustat'), - Artefact('node_b-rgmanager.sk', label='/var/run/cluster/rgmanager.sk'), - ], - _edges=[ - Consume('node_b-clustat', 'node_b-rgmanager.sk'), - Consume('node_b-rgmanager', 'node_b-libccsconfdb'), - Produce('node_b-rgmanager', 'node_b-rgmanager.sk'), - ] - ) - ], - _nodes=[ - Artefact('node_b-cluster.conf', label='/etc/cluster/cluster.conf'), - Daemon('node_b-snmpd', label='snmpd'), - Daemon('node_b-cimserver', label='cimserver'), - ], - _edges=[ - Consume('node_b-modcluster', 'node_b-cluster.conf', label='version?'), - Consume('node_b-modclusterd', 'node_b-cluster.conf', label='version?'), - Consume('node_b-libccsconfdb', 'node_b-cluster.conf', label='version?'), - Consume('node_b-ricci', 'node_b-cluster.conf', label='clustername\nclusteralias'), - Consume('node_b-snmpd', 'node_b-libClusterMonitorSnmp.so'), - Consume('node_b-cimserver', 'node_b-libRedHatClusterProvider.so'), - DelegateOddjobExec('node_b-ricci', 'node_b-modcluster'), - ] - ), - # node a - general - SubgraphImportant('cluster-node_a', - label='NODE A', - _subgraphs=[ - # node a - management - SubgraphStandard('cluster-node_a-conga', - label='management (incomplete)', - _nodes=[ - Daemon('node_a-ricci', - label='ricci'), - Daemon('node_a-modclusterd', - label='modclusterd'), - ] - ) - ] - ), - ] - ), - ], - _nodes=[ - Executable('firefox') - ], - _edges=[ - DelegateRICCIRPC('luci', 'node_a-ricci', ltail='cluster-climgmt', constraint='false'), - DelegateRICCIRPC('luci', 'node_b-ricci', ltail='cluster-climgmt'), - DelegateRICCIRPC('luci', 'node_c-ricci', ltail='cluster-climgmt', constraint='false'), - DelegateLuciHTTPS('firefox', 'luci'), +graph = lambda\ +:LibDot('Overview of CMAN-based cluster architecture (~el6)' +,overlap='scalexy' +,compound='true' +,splines='yes' +#,rankdir='LR' +#, ranksep='1.2' +,_subgraphs=\ + [SubgraphInvisible('environment-outer' + # + # outer environment (take the tools as examples) + # + ,label='outer environment' + ,_subgraphs=\ + [SubgraphInvisible('cluster.outer-clients' + ,label='external clients' + ,_nodes=\ + [Executable('firefox') + ,Executable('snmpwalk') + ,Executable('wbemcli') + ]) + ]) + ,SubgraphInvisible('environment-inner' + # + # inner environment (proper cluster parts) + # + ,label='inner environment' + ,_subgraphs=\ + [SubgraphInvisible('management' + # + # cluster management layer + # + ,_label='management' + ,_subgraphs=\ + [SubgraphStandard('cluster.management-cli' + # + # management client + # + ,label='management client' + ,_nodes=\ + [Executable('luci') + ,Executable('ccs') + ,Executable('ccs_sync') + ]) + ]) + ,SubgraphInvisible('cluster.nodes' + # + # cluster nodes layer + # + ,label='nodes' + ,_subgraphs=\ + [SubgraphImportant('cluster.node_c' + # + # node c + # + ,label='NODE C' + ,_subgraphs=\ + [SubgraphStandard('cluster.node_c-conga' + # + # node c - management + # + ,label='management (incomplete)' + ,_nodes=\ + [Daemon('node_c-ricci' + ,label='ricci' + ) + ,Daemon('node_c-modclusterd' + ,label='modclusterd' + )] + )] + ,_nodes=\ + [Program('node_c-kernel' + ,label='kernel' + )] + ) + ,SubgraphImportant('cluster.node_b' + # + # node b (in detail) + # + ,label='NODE B' + ,_subgraphs=\ + [SubgraphStandard('cluster.node_b-conga' + # + # node b - management + # + ,label='management' + ,_nodes=\ + [Agent('node_b-libClusterMonitorSnmp.so' + ,label='lib\nClusterMonitorSnmp\n.so' + ) + ,Agent('node_b-libRedHatClusterProvider.so' + ,label='lib\nRedHatClusterProvider\n.so' + ) + ,Artefact('node_b-clumond.sock' + ,label='/var/run/\nclumond.sock' + ) + ,Daemon('node_b-ricci' + ,label='ricci' + ) + ,Daemon('node_b-modclusterd' + ,label='modclusterd' + ) + ,Executable('node_b-modcluster' + ,label='modcluster' + ) + ,Executable('node_b-ricci-modules' + ,label='ricci-mod{log,\nrpm,service,\nstorage,virt}' + )], + _edges=\ + [Consume\ + ('node_b-libClusterMonitorSnmp.so' + ,'node_b-clumond.sock' + ) + ,Consume\ + ('node_b-libRedHatClusterProvider.so' + ,'node_b-clumond.sock' + ) + ,Consume\ + ('node_b-modcluster' + ,'node_b-clumond.sock' + ) + ,Produce\ + ('node_b-modclusterd' + ,'node_b-clumond.sock' + )] + ) + ,SubgraphStandard('cluster.node_b-core' + # + # node b - core + # + ,label='core' + ,_nodes=\ + [Library('node_b-libccsconfdb' + ,label='libccsconfdb' + ) + ,Daemon('node_b-rgmanager' + ,label='rgmanager' + ) + ,Executable('node_b-clustat' + ,label='clustat' + ) + ,Artefact('node_b-rgmanager.sk' + ,label='/var/run/\ncluster/\nrgmanager.sk' + )] + ,_edges=\ + [Consume\ + ('node_b-clustat' + ,'node_b-rgmanager.sk' + ) + ,Consume\ + ('node_b-rgmanager' + ,'node_b-libccsconfdb' + ) + ,Produce\ + ('node_b-rgmanager' + ,'node_b-rgmanager.sk' + )] + ) + ,SubgraphStandard('cluster.node_b-fence-agents' + # + # node b - fence agents + # + ,label='fence agents' + ,_nodes=\ + [Executable('node_b-fence_virt' + ,label='fence_{virt,xvm}' + ) + ,Executable('node_b-fence_agent' + ,label='fence_*' + )] + ) + ,SubgraphStandard('cluster.node_b-resource-agents' + # + # node b - resource agents + # + ,label='resource agents' + ,_nodes=\ + [Executable('node_b-resource_agent' + ,label='/usr/share/\ncluster/*.sh' + )] + ) + ,SubgraphStandard('cluster.node_b-kernel' + # + # node b - kernel + # + ,label='kernel' + ,_nodes=\ + [Program('node_b-io' + ,label='I/O' + )] + )] + ,_nodes=\ + [Artefact('node_b-cluster.conf' + ,label='/etc/cluster/\ncluster.conf' + ) + ,Daemon('node_b-snmpd' + ,label='snmpd' + ) + ,Daemon('node_b-cimserver' + ,label='cimserver' + )] + ,_edges=\ + [Consume\ + ('node_b-modcluster' + ,'node_b-cluster.conf' + ,label='version?' + ) + ,Consume\ + ('node_b-modclusterd' + ,'node_b-cluster.conf' + ,label='version?' + ) + ,Consume\ + ('node_b-libccsconfdb' + ,'node_b-cluster.conf' + ,label='version?' + ) + ,Consume\ + ('node_b-ricci' + ,'node_b-cluster.conf' + ,label='clustername\nclusteralias' + ) + ,Consume\ + ('node_b-snmpd' + ,'node_b-libClusterMonitorSnmp.so' + ) + ,Consume\ + ('node_b-cimserver' + ,'node_b-libRedHatClusterProvider.so' + ) + ,DelegateOddjobExec\ + ('node_b-ricci' + ,'node_b-modcluster' + ) + ,DelegateOddjobExec\ + ('node_b-ricci' + ,'node_b-ricci-modules' + )] + ) + ,SubgraphImportant('cluster.node_a' + # + # node a + # + ,label='NODE A' + ,_subgraphs=\ + [SubgraphStandard('cluster.node_a-conga' + # + # node a - management + # + ,label='management (incomplete)' + ,_nodes=\ + [Daemon('node_a-ricci' + ,label='ricci' + ) + ,Daemon('node_a-modclusterd' + ,label='modclusterd' + )] + )] + ,_nodes=\ + [Program('node_a-kernel' + ,label='kernel' + )] + )] + ) + ,SubgraphInvisible('services' + # + # cluster services layer + # + ) + ,SubgraphStandard('cluster.shared-storage' + # + # shared storage + # + ,label='shared storage' + ,_nodes=\ + [StorageDevice('nas' + ,label='NAS' + )] + ) + ,SubgraphStandard('cluster.fence' + # + # cluster devices layer + # + ,label='fence devices' + ,_subgraphs=\ + [SubgraphStandard('cluster.power-fence' + # + # power fencing + # + ,label='power fence' + ,_subgraphs=\ + [SubgraphStandard('cluster.hypervisor' + # + # hypervisor (in a role of power fence executor) + # + ,label='hypervisor\n(when cluster is virtualized)' + ,rank='same' + ,_nodes=\ + [Daemon('fence_virtd' + ) + ,Daemon('libvirt' + )] + ,_edges=\ + [Delegate\ + ('fence_virtd' + ,'libvirt' + ,constraint='false' + )] + )] + ,_nodes=\ + [FenceDevice('power-fence' + ,label='Power fence\ndevice(s) (...)' + )] + ) + ,SubgraphStandard('cluster.storage-fence' + # + # storage fence + # + ,label='storage fence' + ,_nodes=\ + [FenceDevice('storage-fence' + ,label='Storage fence\ndevice(s) (...)' + )] + )] + # + ,_edges=\ + ["modclusterd peer-to-peer network"][:0] +\ + [Exchange\ + ('node_a-modclusterd' + ,'node_b-modclusterd' + ,label='port 16851 (either direction)' + ) + ,Exchange\ + ('node_a-modclusterd' + ,'node_c-modclusterd' + ,label='port 16851 (either direction)' + ) + ,Exchange\ + ('node_b-modclusterd' + ,'node_c-modclusterd' + ,label='port 16851 (either direction)' + ) + ,EdgeInvisible\ + ('node_a-modclusterd' + ,'node_b-modclusterd' + ) + ,EdgeInvisible\ + ('node_b-modclusterd' + ,'node_c-modclusterd' + )] + )] + ,_edges=\ + [ + # + # cluster nodes layer - cluster devices layer + # - DelegateSNMP('snmpwalk', 'node_b-snmpd'), - DelegateCIM('wbemcli', 'node_b-cimserver'), - - Exchange('node_a-modclusterd', 'node_b-modclusterd', label='port 16851 (either direction)', constraint='false'), - Exchange('node_a-modclusterd', 'node_c-modclusterd', label='port 16851 (either direction)', constraint='false'), - Exchange('node_b-modclusterd', 'node_c-modclusterd', label='port 16851 (either direction)', constraint='false'), - ] + # fence + ]+\ + [Delegate\ + ('node_b-fence_virt' + ,'fence_virtd' + ,label='multicast/serial port' + ) + ,Delegate\ + ('node_b-fence_agent' + ,'power-fence' + ,ltail='cluster.node_b-fence-agents' + ,lhead='cluster.fence' + ) + #,Delegate\ + #('node_b-fence_agent' + #,'storage-fence' + #,ltail='cluster.node_b-fence-agents' + #,lhead='cluster.storage-fence' + #,constraint='true' + #) + # shared storage + ]+\ + [Databus\ + ('node_a-ricci' + ,'nas' + # this has to be enabled as using kernel instead of ricci + # destroys the intended depiction :-/ + ,ltail='cluster.node_a' + ,lhead='cluster.shared-storage' + ,headport='n' + ) + ,Databus\ + ('node_b-io' + ,'nas' + #,ltail='cluster.node_b' + ,lhead='cluster.shared-storage' + ,headport='se' + ) + ,Databus\ + ('node_c-kernel' + ,'nas' + #,ltail='cluster.node_c' + ,lhead='cluster.shared-storage' + # cluster devices layer - cluster nodes layer (fence execution) + )]+\ + [Kill\ + ('node_a-ricci' + ,'power-fence' + ,ltail='cluster.node_a' + ,lhead='cluster.power-fence' + ) + ,Kill\ + ('node_b-cluster.conf' + ,'libvirt' + ,ltail='cluster.node_b' + ,lhead='cluster.power-fence' + #,constraint='false' + ) + ,Kill\ + ('node_c-ricci' + ,'libvirt' + ,ltail='cluster.node_c' + ,lhead='cluster.power-fence' + ,minlen='2' + ,weight='5' + ) + ,Kill\ + ('nas' + ,'storage-fence' + #,ltail='cluster.node_c' + ,lhead='cluster.storage-fence' + #,minlen='2' + #,weight='5' + )] + )] +,_edges=\ + [ + # + # cluster management layer - cluster nodes layer + # + ]+\ + [DelegateRICCIRPC\ + ('ccs' + ,'node_a-ricci' + ,ltail='cluster.management-cli' + #,constraint='false' + ) + ,DelegateRICCIRPC\ + ('luci' + ,'node_b-ricci' + ,ltail='cluster.management-cli' + ) + ,DelegateRICCIRPC\ + ('ccs_sync' + ,'node_c-ricci' + ,ltail='cluster.management-cli' + #,constraint='false' + ) + # + # outer environment - cluster management layer + # + ]+\ + [DelegateLuciHTTPS\ + ('firefox' + ,'luci' + ) + ,DelegateSNMP\ + ('snmpwalk' + ,'node_b-snmpd' + ) + ,DelegateCIM\ + ('wbemcli' + ,'node_b-cimserver' + #,EdgeInvisible\ + #('snmpwalk' + #,'power-fence' + #,minlen='2' + )] ) diff --git a/lib.py b/lib.py index fac2ba7..1bff402 100644 --- a/lib.py +++ b/lib.py @@ -77,7 +77,7 @@ class LibDot(Dot): def __init__(self, *args, **kwargs): kwargs.setdefault('graph_type', 'digraph') super(LibDot, self).__init__(*args, **kwargs) - self.set_suppress_disconnected(True) + #self.set_suppress_disconnected(True) class LibSubgraph(Subgraph): @@ -116,7 +116,7 @@ class SubgraphStandard(LibSubgraph): class SubgraphInvisible(LibSubgraph): def __init__(self, *args, **kwargs): - kwargs.setdefault('style', 'invisible') + kwargs.setdefault('style', 'invis') super(SubgraphInvisible, self).__init__(*args, **kwargs) @@ -126,6 +126,12 @@ class SubgraphInvisible(LibSubgraph): # +class NodeInvisible(LibNode): + def __init__(self, *args, **kwargs): + kwargs.setdefault('style', 'invis') + super(LibNode, self).__init__(*args, **kwargs) + + class Program(LibNode): def __init__(self, *args, **kwargs): kwargs.setdefault('shape', 'box') @@ -166,10 +172,34 @@ class Artefact(LibNode): super(Artefact, self).__init__(*args, **kwargs) +class Device(LibNode): + def __init__(self, *args, **kwargs): + kwargs.setdefault('shape', 'box3d') + kwargs.setdefault('fillcolor', 'wheat') + kwargs.setdefault('style', 'filled') + super(Device, self).__init__(*args, **kwargs) + + +class StorageDevice(Device): + def __init__(self, *args, **kwargs): + super(StorageDevice, self).__init__(*args, **kwargs) + + +class FenceDevice(Device): + def __init__(self, *args, **kwargs): + super(FenceDevice, self).__init__(*args, **kwargs) + + # # Edge inheritance # +class EdgeInvisible(LibEdge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('style', 'invis') + kwargs.setdefault('arrowhead', 'none') + super(EdgeInvisible, self).__init__(*args, **kwargs) + class DBUS(LibEdge): def __init__(self, *args, **kwargs): @@ -243,19 +273,36 @@ class Delegate(LibEdge): def __init__(self, *args, **kwargs): kwargs.setdefault('color', 'navy') kwargs.setdefault('fontcolor', 'navy') - kwargs.setdefault('dir', 'both') + #kwargs.setdefault('dir', 'both') super(Delegate, self).__init__(*args, **kwargs) -# peer-to-peer +class Kill(LibEdge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('color', 'red') + kwargs.setdefault('dir', 'back') + #kwargs.setdefault('constraint', 'false') + super(Kill, self).__init__(*args, **kwargs) + + +# peer-to-peer (1:1 hence constraint='false') class Exchange(LibEdge): def __init__(self, *args, **kwargs): kwargs.setdefault('color', 'saddlebrown') kwargs.setdefault('fontcolor', 'saddlebrown') kwargs.setdefault('dir', 'both') + kwargs.setdefault('constraint', 'false') super(Exchange, self).__init__(*args, **kwargs) +# data bus +class Databus(Exchange): + def __init__(self, *args, **kwargs): + kwargs.setdefault('color', 'saddlebrown') + kwargs.setdefault('fontcolor', 'saddlebrown') + super(Databus, self).__init__(*args, **kwargs) + + # mixing class DelegateOddjobExec(Delegate, OddjobExec): @@ -391,14 +438,14 @@ def xdot_graph(*args, **kwargs): try: i = globals()[i] if issubclass(i, LibEdge): - if i is LibEdge: + if i in (LibEdge, EdgeInvisible): continue imenuitem = gtk.CheckMenuItem("%s" % i.__name__) imenuitem.set_active(True) imenuitem.connect("activate", self.on_toggle_item) edgemenu.append(imenuitem) elif issubclass(i, LibNode): - if i is LibNode: + if i in (LibNode, NodeInvisible): continue imenuitem = gtk.CheckMenuItem("%s" % i.__name__) imenuitem.set_active(True) -- cgit