From: rmccabe@sourceware.org <rmccabe@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] conga/luci/site/luci/Extensions LuciClusterAct ...
Date: 9 Aug 2007 21:35:23 -0000 [thread overview]
Message-ID: <20070809213523.31286.qmail@sourceware.org> (raw)
CVSROOT: /cvs/cluster
Module name: conga
Branch: RHEL4
Changes by: rmccabe at sourceware.org 2007-08-09 21:35:22
Added files:
luci/site/luci/Extensions: LuciClusterActions.py
LuciClusterInfo.py LuciDB.py
LuciZope.py LuciZopeAsync.py
LuciZopeClusterPortal.py
LuciZopeExternal.py LuciZopePerm.py
ResourceHandler.py RicciQueries.py
Log message:
Merge in fixes from the RHEL5 branch, pass 4
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciClusterActions.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.4.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciClusterInfo.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.10.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciDB.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.6.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZope.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.4.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopeAsync.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopeClusterPortal.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopeExternal.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.3.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopePerm.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ResourceHandler.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.2.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/RicciQueries.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.7.2.1
/cvs/cluster/conga/luci/site/luci/Extensions/LuciClusterActions.py,v --> standard output
revision 1.4.2.1
--- conga/luci/site/luci/Extensions/LuciClusterActions.py
+++ - 2007-08-09 21:35:22.549359000 +0000
@@ -0,0 +1,725 @@
+# Copyright (C) 2006-2007 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 LuciSyslog import get_logger
+import RicciQueries as rq
+
+from ricci_communicator import RicciCommunicator
+
+from LuciDB import set_node_flag, getRicciAgent, \
+ getClusterNode, getStorageNode, NodeBusy, \
+ setNodeStatus, resolve_nodename, \
+ delCluster, delClusterSystem, \
+ CLUSTER_NODE_NEED_AUTH
+
+from conga_constants import CLUSTER_CONFIG, LUCI_DEBUG_MODE, \
+ NODE_DELETE, NODE_FORCE_DELETE, CLUSTER_DELETE, CLUSTERLIST, \
+ NODE_FENCE, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, NODE_REBOOT, \
+ RESOURCE_ADD, RESOURCE_CONFIG, RESOURCE_REMOVE, \
+ SERVICE_DELETE, SERVICE_RESTART, SERVICE_START, SERVICE_STOP
+
+luci_log = get_logger()
+
+#
+# Cluster service tasks
+#
+
+def RestartCluSvc(self, rc, fvars):
+ svcname = fvars['servicename']
+ cluname = fvars['clustername']
+
+ if svcname is None or cluname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('RestartCluSvc0: svcname: %s, cluname %s' \
+ % (svcname, cluname))
+ return (False, { 'errors': [ 'Both a cluster service name and the cluster name must be given' ] })
+
+ batch_number, result = rq.restartService(rc, svcname)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('RestartCluSvc0: %s failed' % svcname)
+ return (False, { 'errors': [ 'An error occurred while restarting cluster service "%s"' % svcname ] })
+
+ try:
+ set_node_flag(self, cluname, rc.hostname(),
+ str(batch_number), SERVICE_RESTART,
+ 'Restarting service "%s"' % svcname)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('RestartCluSvc1: error setting flags for service %s for cluster %s' % (svcname, cluname))
+
+def StartCluSvc(self, rc, fvars):
+ svcname = fvars['servicename']
+ cluname = fvars['clustername']
+ nodename = fvars['nodename']
+
+ if svcname is None or cluname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('StartCluSvc0: svcname: %s, cluname %s' \
+ % (svcname, cluname))
+ return (False, { 'errors': [ 'Both a cluster service name and the cluster name must be given' ] })
+
+ batch_number, result = rq.startService(rc, svcname, nodename)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('StartCluSvc0: SS(%s,%s,%s) call failed' \
+ % (svcname, cluname, nodename))
+ return (False, { 'errors': [ 'An error occurred while starting cluster service "%s"' % svcname ] })
+
+ try:
+ if nodename is not None:
+ status_msg = 'Starting cluster service "%s" on node "%s"' \
+ % (svcname, nodename)
+ else:
+ status_msg = 'Starting cluster service "%s"' % svcname
+
+ set_node_flag(self, cluname, rc.hostname(),
+ str(batch_number), SERVICE_START, status_msg)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('StartCluSvc1: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+
+def StopCluSvc(self, rc, fvars):
+ svcname = fvars['servicename']
+ cluname = fvars['clustername']
+
+ if svcname is None or cluname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('StopCluSvc0: svcname: %s, cluname %s' \
+ % (svcname, cluname))
+ return (False, { 'errors': [ 'Both a cluster service name and the cluster name must be given' ] })
+
+ batch_number, result = rq.stopService(rc, svcname)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('StopCluSvc0: stop %s failed' % svcname)
+ return (False, { 'errors': [ 'An error occurred while stopping cluster service "%s"' % svcname ] })
+
+ try:
+ set_node_flag(self, cluname, rc.hostname(),
+ str(batch_number), SERVICE_STOP,
+ 'Stopping cluster service "%s"' % svcname)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('StopCluSvc1: error setting flags for service %s for cluster %s' % (svcname, cluname))
+
+def DeleteCluSvc(self, rc, fvars, model):
+ svcname = fvars['servicename']
+ cluname = fvars['clustername']
+
+ if svcname is None or cluname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('DeleteCluSvc0: svcname: %s, cluname %s' \
+ % (svcname, cluname))
+ return (False, { 'errors': [ 'Both a cluster service name and the cluster name must be given' ] })
+
+ try:
+ model.deleteService(svcname)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('DeleteCluSvc1: Unable to find a service named %s for cluster %s: %r %s' % (svcname, cluname, e, str(e)))
+ return (False, { 'errors': [ 'Error removing cluster service "%s"' % svcname ]})
+
+ ret = propagateClusterConfAsync(self, model, rc,
+ SERVICE_DELETE, 'Removing service "%s"' % svcname)
+ if ret[0] is False:
+ return ret
+
+def MigrateCluSvc(self, rc, fvars):
+ svcname = fvars['servicename']
+ cluname = fvars['clustername']
+ nodename = fvars['nodename']
+
+ if svcname is None or cluname is None or nodename is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MigrateCluSvc0: svc: %s, clu: %s, nn: %s' \
+ % (svcname, cluname, nodename))
+ return (False, { 'errors': [ 'A cluster service name, the cluster name, and the target node name must be given' ] })
+
+ batch_number, result = rq.migrateService(rc, svcname, nodename)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MigrateCluSvc0: SS(%s,%s,%s) call failed' \
+ % (svcname, cluname, nodename))
+ return (False, { 'errors': [ 'Error migrating cluster service "%s" to node "%s"' % (svcname, nodename) ]})
+
+ try:
+ set_node_flag(self, cluname, rc.hostname(),
+ str(batch_number), SERVICE_START,
+ 'Migrating service "%s" to node "%s"' % (svcname, nodename))
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MigrateCluSvc1: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+
+#
+# Cluster resource-related tasks
+#
+
+def DeleteResource(self, rc, model, resname):
+ errstr = 'An error occurred while attempting to delete this cluster resource'
+ if resname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('DeleteResource0: no res name')
+ return (False, { 'errors': [ '%s: no resource name was given' % errstr ]})
+
+ try:
+ model.deleteResource(resname)
+ except KeyError, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('DeleteResource1: no res %s: %r %s' \
+ % (resname, e, str(e)))
+ return (False, { 'errors': [ '%s: no resource named "%s" was found' % (errstr, resname) ]})
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('DeleteResource2: err: %s: %r %s' \
+ % (resname, e, str(e)))
+ return (False, { 'errors': [ '%s: unable to delete resource "%s"' % (errstr, resname) ]})
+
+ ret = propagateClusterConfAsync(self, model, rc,
+ RESOURCE_REMOVE, 'Removing cluster resource "%s"' % resname)
+ if ret[0] is False:
+ return ret
+
+def AddResource(self, rc, model, res):
+ resname = None
+ try:
+ resname = res.getName()
+ model.getResourcesPtr().addChild(res)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('AddResource0: %r %s' % (e, str(e)))
+ if resname is not None:
+ errstr = 'Unable to add new resource "%s"' % resname
+ else:
+ errstr = 'Unable to add this new resource'
+ return (False, { 'errors': [ errstr ] })
+
+ ret = propagateClusterConfAsync(self, model, rc, RESOURCE_ADD,
+ 'Creating new cluster resource "%s"' % resname)
+ if ret[0] is False:
+ return ret
+
+def EditResource(self, rc, model, res):
+ resname = None
+ try:
+ resname = res.getName()
+ model.getResourcesPtr().addChild(res)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('EditResource0: %r %s' % (e, str(e)))
+ if resname is not None:
+ errstr = 'Unable to edit cluster resource "%s"' % resname
+ else:
+ errstr = 'Unable to edit this cluster resource'
+ return (False, { 'errors': [ errstr ] })
+
+ ret = propagateClusterConfAsync(self, model, rc, RESOURCE_CONFIG,
+ 'Configuring cluster resource "%s"' % resname)
+
+ if ret[0] is False:
+ return ret
+
+#
+# Cluster node membership-related tasks
+#
+
+def NodeJoinCluster(self, rc, clustername, nodename_resolved):
+ batch_number, result = rq.nodeJoinCluster(rc)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NJ0: batch_number and/or result is None')
+ return None
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), NODE_JOIN_CLUSTER,
+ 'Node "%s" joining cluster "%s"' % (nodename_resolved, clustername))
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NJ1: failed to set flags: %r %s' \
+ % (e, str(e)))
+ return None
+ return True
+
+def NodeLeaveCluster( self,
+ rc,
+ clustername,
+ nodename_resolved,
+ stop_cluster=False):
+ reported_cluname = None
+ try:
+ cluster_info = rc.cluster_info()
+ reported_cluname = cluster_info[0] or cluster_info[1]
+ if not reported_cluname:
+ raise Exception, 'not a cluster member'
+ if reported_cluname.lower() != clustername.lower():
+ raise Exception, 'cluster mismatch: expected %s, got %s' \
+ % (clustername, reported_cluname)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NCL0: no cluster name: %r %s' % (e, str(e)))
+ return None
+
+ if NodeBusy(self, clustername, nodename_resolved, rc) is not False:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('NLC1: %s is busy, can\'t leave cluster yet.' \
+ % nodename_resolved)
+ return None
+
+ batch_number, result = rq.nodeLeaveCluster(rc, cluster_shutdown=stop_cluster)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NLC2: %s: batch_number or result is None' \
+ % nodename_resolved)
+ return None
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), NODE_LEAVE_CLUSTER,
+ 'Node "%s" leaving cluster "%s"' % (nodename_resolved, clustername))
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NLC3: failed to set flags: %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+ return True
+
+def NodeForceDeleteFromCluster(self, model, clustername, nodename, nodename_resolved):
+ rc = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved, nodename ], exclude_busy=True)
+
+ if rc is None:
+ rc = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved, nodename ])
+
+ if rc is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC0: no agent to delete node %s "%s"' \
+ % (nodename_resolved, clustername))
+ return None
+
+ try:
+ model.deleteNodeByName(nodename.lower())
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC1: deleteNode %s: %r %s' \
+ % (nodename, e, str(e)))
+ return None
+
+ try:
+ model.setModified(True)
+ str_buf = str(model.exportModelAsString())
+ if not str_buf:
+ raise Exception, 'model string is blank'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC2: exportModelAsString: %r %s' \
+ % (e, str(e)))
+ return None
+
+ batch_number, result = rq.setClusterConf(rc, str_buf)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC3: batch number is None')
+ return None
+
+ try:
+ ret = delClusterSystem(self, clustername, nodename_resolved)
+ if ret is not None:
+ raise Exception, ret
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC4: error deleting %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), NODE_FORCE_DELETE,
+ 'Forcing the deletion of node "%s"' % nodename)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NFDFC5: failed to set flags: %r %s' \
+ % (e, str(e)))
+ return True
+
+def NodeDeleteFromCluster( self,
+ rc,
+ model,
+ clustername,
+ nodename,
+ nodename_resolved,
+ delete_cluster=False):
+
+ # We need to get a node name other than the node
+ # to be deleted, then delete the node from the cluster.conf
+ # and propogate it. We will need two ricci agents for this task,
+ # unless we are deleting the cluster itself.
+
+ if delete_cluster is False:
+ # Make sure we can find a second node before we hose anything.
+ rc2 = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved ], exclude_busy=True)
+
+ if rc2 is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND0: unable to find ricci agent to delete %s from %s' % (nodename_resolved, clustername))
+ return None
+
+ # First, delete cluster.conf from node to be deleted.
+ # next, have node leave cluster.
+
+ batch_number, result = rq.nodeLeaveCluster(rc, purge=True)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND5: batch_number and/or result is None')
+ return None
+
+ # Unless we're deleting the whole cluster, it is not worth
+ # flagging this node in DB, as we are going to delete it
+ # anyway. Now, we need to delete node from model and send out
+ # new cluster.conf
+
+ if delete_cluster is True:
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), CLUSTER_DELETE,
+ 'Deleting cluster "%s": Deleting node "%s"' \
+ % (clustername, nodename_resolved))
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND5a: failed to set flags: %r %s' \
+ % (e, str(e)))
+ else:
+ try:
+ model.deleteNodeByName(nodename.lower())
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND6: deleteNode %s: %r %s' \
+ % (nodename, e, str(e)))
+ return None
+
+ try:
+ model.setModified(True)
+ str_buf = str(model.exportModelAsString())
+ if not str_buf:
+ raise Exception, 'model string is blank'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND7: exportModelAsString: %r %s' \
+ % (e, str(e)))
+ return None
+
+ # propagate the new cluster.conf via the second node
+ batch_number, result = rq.setClusterConf(rc2, str_buf)
+ if batch_number is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND8: batch number is None')
+ return None
+
+ try:
+ ret = delClusterSystem(self, clustername, nodename_resolved)
+ if ret is not None:
+ raise Exception, ret
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND9: error deleting %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+
+ if delete_cluster:
+ return True
+
+ try:
+ set_node_flag(self, clustername, rc2.hostname(),
+ str(batch_number), NODE_DELETE,
+ 'Deleting node "%s"' % nodename)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ND10: failed to set flags: %r %s' \
+ % (e, str(e)))
+ return True
+
+#
+# Cluster management-related tasks.
+#
+
+def ClusterStart(self, model):
+ if model is None:
+ return None
+
+ clustername = model.getClusterName()
+ nodes = model.getNodes()
+ if not nodes or len(nodes) < 1:
+ return None
+
+ errors = 0
+ for node in nodes:
+ nodename = node.getName().strip()
+ nodename_resolved = resolve_nodename(self, clustername, nodename)
+
+ try:
+ # XXX - do this in parallel
+ rc = RicciCommunicator(nodename_resolved)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CStart: RC %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+ errors += 1
+ continue
+
+ if NodeJoinCluster(self, rc, clustername, nodename_resolved) is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CStart1: nodeJoin %s' \
+ % nodename_resolved)
+ errors += 1
+
+ return errors
+
+def ClusterStop(self, model, delete=False):
+ if model is None:
+ return None
+
+ clustername = model.getClusterName()
+ nodes = model.getNodes()
+ if not nodes or len(nodes) < 1:
+ return None
+
+ errors = 0
+ for node in nodes:
+ nodename = node.getName().strip()
+ nodename_resolved = resolve_nodename(self, clustername, nodename)
+
+ try:
+ # XXX - do this in parallel
+ rc = RicciCommunicator(nodename_resolved)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CStop0: [%d] RC %s: %r %s' \
+ % (delete is True, str(nodename_resolved), e, str(e)))
+ errors += 1
+ continue
+
+ if delete is True:
+ ret = NodeDeleteFromCluster(self, rc, model, clustername,
+ nodename, nodename_resolved, delete_cluster=True)
+ if ret is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CStop1: [1] nodeDelete failed')
+ errors += 1
+ else:
+ ret = NodeLeaveCluster(self, rc, clustername,
+ nodename_resolved, stop_cluster=True)
+ if ret is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CStop2: [0] nodeLeave %s' \
+ % (nodename_resolved))
+ errors += 1
+ return errors
+
+def ClusterRestart(self, model):
+ snum_err = ClusterStop(self, model)
+ if snum_err:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('cluRestart0: ClusterStop: %d errs' \
+ % snum_err)
+
+ jnum_err = ClusterStart(self, model)
+ if jnum_err:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('cluRestart1: ClusterStart: %d errs' \
+ % jnum_err)
+ return snum_err + jnum_err
+
+def ClusterDelete(self, model):
+ try:
+ clustername = model.getClusterName()
+ if not clustername:
+ raise Exception, 'no cluster name found'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ClusterDelete0: %r %s' % (e, str(e)))
+ return None
+
+ # Try to stop all the cluster nodes before deleting any.
+ num_errors = ClusterStop(self, model, delete=False)
+ if num_errors > 0:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ClusterDelete1: %s: %d errors' \
+ % (clustername, num_errors))
+ return None
+
+ # If the cluster is stopped, delete all of the nodes.
+ num_errors = ClusterStop(self, model, delete=True)
+ if num_errors > 0:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ClusterDelete2: %s: %d errors' \
+ % (clustername, num_errors))
+ return None
+
+ try:
+ ret = delCluster(self, clustername)
+ if ret is not None:
+ raise Exception, ret
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('ClusterDelete3: %s: %r %s' \
+ % (clustername, e, str(e)))
+ return None
+ return CLUSTERLIST
+
+def NodeReboot(self, rc, clustername, nodename_resolved):
+ batch_number, result = rq.nodeReboot(rc)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('FNR0: batch_number and/or result is None')
+ return None
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), NODE_REBOOT,
+ 'Node "%s" is being rebooted' % nodename_resolved)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('FNR1: failed to set flags: %r %s' \
+ % (e, str(e)))
+ return True
+
+def NodeFence(self, clustername, nodename, nodename_resolved):
+ rc = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved, nodename ], exclude_busy=True)
+ if rc is None:
+ rc = getRicciAgent(self, clustername,
+ exclude_names=[ nodename_resolved, nodename ])
+ if rc is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('FNF0: no ricci to fence %s for cluster %s' \
+ % (nodename_resolved, clustername))
+ return None
+
+ batch_number, result = rq.nodeFence(rc, nodename_resolved)
+ if batch_number is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('FNF1: batch_number and/or result is None')
+ return None
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ str(batch_number), NODE_FENCE,
+ 'Node "%s" is being fenced by node "%s"' \
+ % (nodename_resolved, rc.hostname()))
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('FNF2: failed to set flags: %r %s' \
+ % (e, str(e)))
+ return True
+
+def propagateClusterConfAsync( self,
+ model,
+ rc=None,
+ action=CLUSTER_CONFIG,
+ pmsg=None):
+ errors = list()
+ messages = list()
+
+ try:
+ clustername = model.getClusterName()
+ if not clustername:
+ raise Exception, 'cluster name from model.getClusterName() is blank'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('PCC0: getClusterName: %r %s' \
+ % (e, str(e)))
+ errors.append('Unable to determine cluster name')
+ return (False, { 'errors': errors, 'messages': messages })
+
+ if rc is None:
+ rc = getRicciAgent(self, clustername, exclude_busy=True)
+ if rc is None:
+ rc = getRicciAgent(self, clustername)
+
+ if rc is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('PCC1: no ricci agent for the %s cluster' \
+ % clustername)
+ errors.append('Unable to contact a ricci agent for cluster "%s"' \
+ % clustername)
+ return (False, { 'errors': errors, 'messages': messages })
+
+ try:
+ model.setModified(True)
+ conf_str = str(model.exportModelAsString()).strip()
+ if not conf_str:
+ raise Exception, 'The new cluster configuration is blank'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('PCC2: %r %s' % (e, str(e)))
+ errors.append(repr(e))
+ return (False, { 'errors': errors, 'messages': messages })
+
+ batch_id, result = rq.setClusterConf(rc, conf_str)
+ if batch_id is None or result is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('PCC3: batchid or result is None')
+ errors.append('Unable to propagate a new cluster configuration for %s' \
+ % clustername)
+ return (False, { 'errors': errors, 'messages': messages })
+
+ if pmsg is None:
+ pmsg = 'Updating the cluster configuration for "%s"' % clustername
+
+ try:
+ set_node_flag(self, clustername, rc.hostname(),
+ batch_id, action, pmsg)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('PCC4: set_node_flag: %r %s' \
+ % (e, str(e)))
+
+ return (True, { 'errors': errors, 'messages': messages, 'batchid': batch_id })
+
+def GetSystemLogs(self, fvars):
+ nodename = fvars['nodename']
+ if nodename is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GSL0: no node name')
+ return 'No system name was given'
+
+ clustername = fvars['clustername']
+ if clustername is None:
+ nodename_resolved = nodename
+ else:
+ nodename_resolved = resolve_nodename(self, clustername, nodename)
+
+ try:
+ rc = RicciCommunicator(nodename_resolved)
+ if not rc:
+ raise Exception, 'no rc'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GSL1: unexpected exception for %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+ return 'Ricci error while getting logs for %s' % nodename_resolved
+
+ if not rc.authed():
+ try:
+ snode = getStorageNode(self, nodename_resolved)
+ setNodeStatus(snode, CLUSTER_NODE_NEED_AUTH)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GSL2: %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+
+ if clustername is not None:
+ try:
+ cnode = getClusterNode(self, nodename_resolved, clustername)
+ setNodeStatus(cnode, CLUSTER_NODE_NEED_AUTH)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GNL5: %s: %r %s' \
+ % (nodename_resolved, e, str(e)))
+ return 'Luci is not authenticated to %s. Reauthenticate first.' \
+ % nodename
+
+ return rq.getNodeLogs(rc)
/cvs/cluster/conga/luci/site/luci/Extensions/LuciClusterInfo.py,v --> standard output
revision 1.10.2.1
--- conga/luci/site/luci/Extensions/LuciClusterInfo.py
+++ - 2007-08-09 21:35:22.667793000 +0000
@@ -0,0 +1,1620 @@
+# Copyright (C) 2006-2007 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 Products.Archetypes.utils import make_uuid
+from ClusterModel.ModelBuilder import ModelBuilder
+import RicciQueries as rq
+from ricci_communicator import RicciCommunicator
+from FenceHandler import FENCE_OPTS
+from LuciSyslog import get_logger
+from LuciDB import resolve_nodename
+from LuciZope import GetReqVars
+
+from conga_constants import CLUSTER_CONFIG, CLUSTER_DELETE, \
+ CLUSTER_PROCESS, CLUSTER_RESTART, CLUSTER_START, CLUSTER_STOP, \
+ NODE_FORCE_DELETE, FDOM, FENCEDEV, NODE, NODE_ACTIVE, \
+ NODE_ACTIVE_STR, NODE_DELETE, NODE_FENCE, NODE_INACTIVE, \
+ NODE_INACTIVE_STR, NODE_JOIN_CLUSTER, NODE_LEAVE_CLUSTER, \
+ NODE_PROCESS, NODE_REBOOT, NODE_UNKNOWN, NODE_UNKNOWN_STR, \
+ PROP_FENCE_TAB, PROP_GENERAL_TAB, PROP_GULM_TAB, PROP_MCAST_TAB, \
+ PROP_QDISK_TAB, RESOURCE, RESOURCE_CONFIG, RESOURCE_REMOVE, \
+ SERVICE, SERVICE_DELETE, SERVICE_MIGRATE, SERVICE_RESTART, \
+ SERVICE_START, SERVICE_STOP, VM_CONFIG, \
+ LUCI_DEBUG_MODE, LUCI_CLUSTER_BASE_URL
+
+luci_log = get_logger()
+
+def getnodes(self, model):
+ try:
+ return map(lambda x: str(x.getName()), model.getNodes())
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getnodes0: %r %s' % (e, str(e)))
+ return []
+
+def getResourceInfo(model, name, baseurl, res=None):
+ if res is None:
+ try:
+ res = model.getResourceByName(name)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRI0: %s: %r %s' % (name, e, str(e)))
+ return {}
+
+ res_info = {}
+ res_name = res.getName().strip()
+
+ res_info['name'] = res_name
+ res_info['attrs'] = res.attr_hash
+ res_info['type'] = res.resource_type
+ res_info['tag_name'] = res.TAG_NAME
+
+ cluname = model.getClusterName()
+ res_info['cfgurl'] = '%s?clustername=%s&resourcename=%s&pagetype=%s' \
+ % (baseurl, cluname, res_name, RESOURCE_CONFIG)
+ res_info['url'] = '%s?clustername=%s&resourcename=%s&pagetype=%s' \
+ % (baseurl, cluname, res_name, RESOURCE)
+ res_info['delurl'] = '%s?clustername=%s&resourcename=%s&pagetype=%s' \
+ % (baseurl, cluname, res_name, RESOURCE_REMOVE)
+ return res_info
+
+def getResources(model, baseurl):
+ if model is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getResources0: model is none')
+ return []
+ return map(lambda x: getResourceInfo(model, None, baseurl, x), model.getResources())
+
+def getClusterStatusModel(model):
+ results = list()
+ vals = {}
+
+ try:
+ clustername = model.getClusterName()
+ clusteralias = model.getClusterAlias()
+ vals['type'] = 'cluster'
+ vals['alias'] = clusteralias
+ vals['name'] = clustername
+ vals['error'] = True
+ vals['votes'] = '[unknown]'
+ vals['quorate'] = '[unknown]'
+ vals['minQuorum'] = '[unknown]'
+ results.append(vals)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSM0: %r %s' % (e, str(e)))
+ return None
+
+ try:
+ nodelist = model.getNodes()
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSM1: %r %s' % (e, str(e)))
+ return None
+
+ for node in nodelist:
+ node_val = {}
+ node_val['type'] = 'node'
+ try:
+ node_name = node.getName()
+ if not node_name:
+ raise Exception, 'cluster node name is unknown'
+ except:
+ node_name = '[unknown]'
+
+ node_val['name'] = node_name
+ node_val['clustered'] = '[unknown]'
+ node_val['online'] = '[unknown]'
+ node_val['error'] = True
+
+ try:
+ votes = node.getVotes()
+ if not votes:
+ raise Exception, 'unknown unmber of votes'
+ except:
+ votes = '[unknown]'
+
+ node_val['votes'] = votes
+ results.append(node_val)
+ return results
+
+def getClusterStatus(self, request, rc, cluname=None):
+ try:
+ doc = rq.getClusterStatusBatch(rc) or None
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCS0: error: %r: %r %s' \
+ % (cluname, e, str(e)))
+ doc = None
+
+ if doc is None:
+ model = LuciExtractCluModel(self, request, cluname)
+ if model is not None:
+ try:
+ cinfo = getClusterStatusModel(model)
+ if not cinfo or len(cinfo) < 1:
+ raise Exception, 'cinfo is None'
+ return cinfo
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCS1: %r: %r %s' \
+ % (cluname, e, str(e)))
+
+ if doc is None:
+ try:
+ from LuciDB import getClusterStatusDB
+ if cluname:
+ clustername = cluname
+ else:
+ fvars = GetReqVars(request, [ 'clustername' ])
+
+ clustername = fvars['clustername']
+ if clustername is None:
+ raise Exception, 'unable to determine cluster name'
+
+ cinfo = getClusterStatusDB(self, clustername)
+ if not cinfo or len(cinfo) < 1:
+ raise Exception, 'cinfo is None'
+ return cinfo
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCS2: cluster %r info from DB: %r %s' \
+ % (cluname, e, str(e)))
+ return []
+
+ results = list()
+ vals = {}
+ vals['type'] = 'cluster'
+
+ try:
+ vals['alias'] = doc.firstChild.getAttribute('alias')
+ except AttributeError, e:
+ vals['alias'] = doc.firstChild.getAttribute('name')
+
+ vals['votes'] = doc.firstChild.getAttribute('votes')
+ vals['name'] = doc.firstChild.getAttribute('name')
+ vals['minQuorum'] = doc.firstChild.getAttribute('minQuorum')
+ vals['quorate'] = doc.firstChild.getAttribute('quorate')
+ results.append(vals)
+
+ for node in doc.firstChild.childNodes:
+ if node.nodeName == 'node':
+ vals = {}
+ vals['type'] = 'node'
+ vals['clustered'] = node.getAttribute('clustered')
+ vals['name'] = node.getAttribute('name')
+ vals['online'] = node.getAttribute('online')
+ vals['uptime'] = node.getAttribute('uptime')
+ vals['votes'] = node.getAttribute('votes')
+ results.append(vals)
+ elif node.nodeName == 'service':
+ vals = {}
+ vals['type'] = 'service'
+ vals['name'] = node.getAttribute('name')
+ vals['nodename'] = node.getAttribute('nodename')
+ vals['running'] = node.getAttribute('running')
+ try:
+ vals['is_vm'] = node.getAttribute('vm').lower() == 'true'
+ except:
+ vals['is_vm'] = False
+ vals['failed'] = node.getAttribute('failed')
+ vals['autostart'] = node.getAttribute('autostart')
+ results.append(vals)
+ return results
+
+def getServicesInfo(self, status, model, req):
+ svc_map = {}
+ maplist = list()
+ fvars = GetReqVars(req, [ 'clustername', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
+ cluname = fvars['clustername']
+ if cluname is None:
+ cluname = model.getClusterName()
+
+ nodes = model.getNodes()
+ for item in status:
+ if item['type'] == 'service':
+ itemmap = {}
+ itemmap['name'] = item['name']
+
+ cur_node = None
+ if item['running'] == 'true':
+ cur_node = item['nodename']
+ itemmap['running'] = 'true'
+ itemmap['nodename'] = cur_node
+ itemmap['disableurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], SERVICE_STOP)
+ itemmap['restarturl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], SERVICE_RESTART)
+ else:
+ itemmap['enableurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], SERVICE_START)
+
+ itemmap['autostart'] = item['autostart']
+
+ try:
+ svc = model.retrieveServiceByName(item['name'])
+ itemmap['cfgurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], SERVICE)
+ itemmap['delurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], SERVICE_DELETE)
+ except:
+ try:
+ svc = model.retrieveVMsByName(item['name'])
+ itemmap['is_vm'] = True
+ itemmap['cfgurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], VM_CONFIG)
+ itemmap['delurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, item['name'], VM_CONFIG)
+ except:
+ continue
+
+ starturls = list()
+ for node in nodes:
+ cur_nodename = node.getName()
+ if node.getName() != cur_node:
+ starturl = {}
+ starturl['nodename'] = cur_nodename
+ starturl['url'] = '%s?clustername=%s&servicename=%s&pagetype=%s&nodename=%s' % (baseurl, cluname, item['name'], SERVICE_START, cur_nodename)
+ starturls.append(starturl)
+
+ if itemmap.has_key('is_vm') and itemmap['is_vm'] is True:
+ migrate_url = { 'nodename': cur_nodename }
+ migrate_url['migrate'] = True
+ migrate_url['url'] = '%s?clustername=%s&servicename=%s&pagetype=%s&nodename=%s' % (baseurl, cluname, item['name'], SERVICE_MIGRATE, cur_nodename)
+ starturls.append(migrate_url)
+
+ itemmap['links'] = starturls
+
+ dom = svc.getAttribute('domain')
+ if dom is not None:
+ itemmap['faildom'] = dom
+ else:
+ itemmap['faildom'] = 'No Failover Domain'
+ maplist.append(itemmap)
+
+ svc_map['services'] = maplist
+ return svc_map
+
+def recurse_resources(parent_uuid, child, resource_list, indent_ctr, parent=None):
+ #First, add the incoming child as a resource
+ #Next, check for children of it
+ #Call yourself on every children
+ #then return
+
+ rc_map = {}
+ if parent is not None:
+ rc_map['parent'] = parent
+ rc_map['name'] = child.getName()
+
+ #Note: Final version needs all resource attrs
+ if child.isRefObject() is True:
+ rc_map['ref_object'] = True
+ rc_map['tag_name'] = child.getObj().TAG_NAME
+ rc_map['type'] = child.getObj().getResourceType()
+ rc_map['attrs'] = child.getObj().getAttributes()
+ else:
+ rc_map['tag_name'] = child.TAG_NAME
+ rc_map['type'] = child.getResourceType()
+ rc_map['attrs'] = child.getAttributes()
+
+ rc_map['indent_ctr'] = indent_ctr
+
+ rc_map['uuid'] = make_uuid('resource')
+ rc_map['parent_uuid'] = parent_uuid
+
+ resource_list.append(rc_map)
+ kids = child.getChildren()
+ child_depth = 0
+ new_indent_ctr = indent_ctr + 1
+ for kid in kids:
+ cdepth = recurse_resources(rc_map['uuid'], kid, resource_list, new_indent_ctr, child)
+ child_depth = max(cdepth, child_depth)
+
+ rc_map['max_depth'] = child_depth
+ return child_depth + 1
+
+
+def get_fdom_names(model):
+ return map(lambda x: x.getName(), model.getFailoverDomains())
+
+
+def getServiceInfo(self, status, model, req):
+ root_uuid = 'toplevel'
+
+ fvars = GetReqVars(req, [ 'clustername', 'servicename', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ if not model:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getServiceInfo0: no model: %r' % model)
+ return {}
+
+ #set up struct for service config page
+ hmap = {}
+
+ try:
+ cluname = fvars['clustername'] or model.getClusterName()
+ hmap['fdoms'] = get_fdom_names(model)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getServiceInfo1: %r %s' % (e, str(e)))
+ hmap['fdoms'] = list()
+
+ hmap['root_uuid'] = root_uuid
+ # uuids for the service page needed when new resources are created
+ hmap['uuid_list'] = map(lambda x: make_uuid('resource'), xrange(30))
+
+ servicename = fvars['servicename']
+ if servicename is None:
+ return hmap
+
+ if len(status) > 0:
+ nodenames = model.getNodeNames()
+
+ for item in status:
+ innermap = {}
+ if item['type'] == 'service':
+ if item['name'] == servicename:
+ hmap['name'] = servicename
+ hmap['autostart'] = item['autostart']
+
+ starturls = list()
+ if item['running'] == 'true':
+ hmap['running'] = 'true'
+ nodename = item['nodename']
+ innermap['current'] = 'Running on %s' % nodename
+
+ innermap['disableurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, servicename, SERVICE_STOP)
+ innermap['restarturl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, servicename, SERVICE_RESTART)
+ innermap['delurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, servicename, SERVICE_DELETE)
+
+ # In this case, determine where it can run...
+ for node in nodenames:
+ if node != nodename:
+ starturl = {}
+ starturl['nodename'] = node
+ starturl['url'] = '%s?clustername=%s&servicename=%s&pagetype=%s&nodename=%s' % (baseurl, cluname, servicename, SERVICE_START, node)
+ starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': node }
+ migrate_url['url'] = '%s?clustername=%s&servicename=%s&pagetype=%s&nodename=%s' % (baseurl, cluname, servicename, SERVICE_MIGRATE, node)
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
+ innermap['links'] = starturls
+ else:
+ #Do not set ['running'] in this case...ZPT will detect it is missing
+ innermap['current'] = 'Stopped'
+ innermap['enableurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, servicename, SERVICE_START)
+ innermap['delurl'] = '%s?clustername=%s&servicename=%s&pagetype=%s' % (baseurl, cluname, servicename, SERVICE_DELETE)
+
+ starturls = list()
+ for node in nodenames:
+ starturl = {}
+
+ starturl['nodename'] = node
+ starturl['url'] = '%s?clustername=%s&servicename=%s&pagetype=%s&nodename=%s' % (baseurl, cluname, servicename, SERVICE_START, node)
+ starturls.append(starturl)
+
+ if item.has_key('is_vm') and item['is_vm'] is True:
+ migrate_url = { 'nodename': node }
+ migrate_url['url'] = '%s?clustername=%s&servicename=%s&pagetype=%s&nodename=%s' % (baseurl, cluname, servicename, SERVICE_MIGRATE, node)
+ migrate_url['migrate'] = True
+ starturls.append(migrate_url)
+ innermap['links'] = starturls
+ hmap['innermap'] = innermap
+
+ # Now build hashes for resources under service.
+ # first get service by name from model
+
+ svc = model.getService(servicename)
+ try:
+ hmap['domain'] = svc.getAttribute('domain')
+ except:
+ hmap['domain'] = None
+
+ try:
+ hmap['recovery'] = svc.getAttribute('recovery')
+ except:
+ hmap['recovery'] = None
+
+ try:
+ if int(svc.getAttribute('exclusive')):
+ hmap['exclusive'] = 'true'
+ else:
+ hmap['exclusive'] = 'false'
+ except:
+ hmap['exclusive'] = 'false'
+
+ resource_list = list()
+ if svc is not None:
+ indent_ctr = 0
+ children = svc.getChildren()
+ for child in children:
+ recurse_resources(root_uuid, child, resource_list, indent_ctr)
+
+ hmap['resource_list'] = resource_list
+ return hmap
+
+def getFdomInfo(self, model, request):
+ fhash = {}
+ fhash['members'] = {}
+
+ try:
+ fdom = model.getFailoverDomainByName(request['fdomname'])
+ fhash['name'] = fdom.getName()
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getFdomInfo0: %r %s' % (e, str(e)))
+ return fhash
+
+ ordered_attr = fdom.getAttribute('ordered')
+ if ordered_attr is not None and (ordered_attr == 'true' or ordered_attr == '1'):
+ fhash['prioritized'] = '1'
+ else:
+ fhash['prioritized'] = '0'
+
+ restricted_attr = fdom.getAttribute('restricted')
+ if restricted_attr is not None and (restricted_attr == 'true' or restricted_attr == '1'):
+ fhash['restricted'] = '1'
+ else:
+ fhash['restricted'] = '0'
+
+ nodes = fdom.getChildren()
+ for node in nodes:
+ try:
+ priority = node.getAttribute('priority')
+ except:
+ priority = '1'
+ fhash['members'][node.getName()] = { 'priority': priority }
+ return fhash
+
+def getFdomsInfo(self, model, request, clustatus):
+ fvars = GetReqVars(request, [ 'clustername', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvars['clustername']
+ if clustername is None:
+ return {}
+
+ slist = list()
+ nlist = list()
+ for item in clustatus:
+ if item['type'] == 'node':
+ nlist.append(item)
+ elif item['type'] == 'service':
+ slist.append(item)
+
+ fdomlist = list()
+ for fdom in model.getFailoverDomains():
+ fdom_map = {}
+ fdom_name = fdom.getName()
+ fdom_map['name'] = fdom_name
+ fdom_map['cfgurl'] = '%s?pagetype=%s&clustername=%s&fdomname=%s' \
+ % (baseurl, FDOM, clustername, fdom.getName())
+
+ ordered_attr = fdom.getAttribute('ordered')
+ if ordered_attr is not None and (ordered_attr == 'true' or ordered_attr == '1'):
+ fdom_map['ordered'] = True
+ else:
+ fdom_map['ordered'] = False
+
+ restricted_attr = fdom.getAttribute('restricted')
+ if restricted_attr is not None and (restricted_attr == 'true' or restricted_attr == '1'):
+ fdom_map['restricted'] = True
+ else:
+ fdom_map['restricted'] = False
+
+ nodelist = list()
+ for node in fdom.getChildren():
+ nodesmap = {}
+ ndname = node.getName()
+
+ for nitem in nlist:
+ if nitem['name'] == ndname:
+ nodesmap['nodename'] = ndname
+ nodesmap['nodecfgurl'] = '%s?clustername=%s&nodename=%s&pagetype=%s' \
+ % (baseurl, clustername, ndname, NODE)
+ if nitem['clustered'] == 'true':
+ nodesmap['status'] = NODE_ACTIVE
+ elif nitem['online'] == 'false':
+ nodesmap['status'] = NODE_UNKNOWN
+ else:
+ nodesmap['status'] = NODE_INACTIVE
+ priority_attr = node.getAttribute('priority')
+ if priority_attr is not None:
+ nodesmap['priority'] = '0'
+ nodelist.append(nodesmap)
+ fdom_map['nodeslist'] = nodelist
+
+ svclist = list()
+ tmp = model.getServices()
+ tmp.extend(model.getVMs())
+ for svc in tmp:
+ svcname = svc.getName()
+ for sitem in slist:
+ if sitem['name'] == svcname:
+ domain = svc.getAttribute('domain')
+ if domain == fdom_name:
+ svcmap = {}
+ svcmap['name'] = svcname
+ svcmap['status'] = sitem['running']
+ if svc.getTagName() == 'vm':
+ svcmap['svcurl'] = '%s?pagetype=%s&clustername=%s&servicename=%s' % (baseurl, VM_CONFIG, clustername, svcname)
+ else:
+ svcmap['svcurl'] = '%s?pagetype=%s&clustername=%s&servicename=%s' % (baseurl, SERVICE, clustername, svcname)
+ svcmap['location'] = sitem['nodename']
+ svclist.append(svcmap)
+ fdom_map['svclist'] = svclist
+ fdomlist.append(fdom_map)
+
+ return fdomlist
+
+def getClusterInfo(self, model, req):
+ fvars = GetReqVars(req, [ 'clustername', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ cluname = fvars['clustername']
+ if cluname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCI0: unable to determine cluster name')
+ return {}
+
+ clumap = {}
+ if not model:
+ try:
+ model = getModelForCluster(self, cluname)
+ if not model:
+ raise Exception, 'model is none'
+ req.SESSION.set('model', model)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCI1: unable to get model for cluster %s: %r %s' % (cluname, e, str(e)))
+ return {}
+ else:
+ totem = model.getTotemPtr()
+ if totem:
+ clumap['totem'] = totem.getAttributes()
+
+ prop_baseurl = '%s?pagetype=%s&clustername=%s&' \
+ % (baseurl, CLUSTER_CONFIG, cluname)
+ basecluster_url = '%stab=%s' % (prop_baseurl, PROP_GENERAL_TAB)
+ # needed:
+ clumap['basecluster_url'] = basecluster_url
+ # name field
+ clumap['clustername'] = model.getClusterAlias()
+ # config version
+ cp = model.getClusterPtr()
+ clumap['config_version'] = cp.getConfigVersion()
+
+ # xvmd info
+ clumap['fence_xvmd'] = model.hasFenceXVM()
+
+ #-------------
+ #new cluster params - if rhel5
+ #-------------
+ gulm_ptr = model.getGULMPtr()
+ if not gulm_ptr:
+ #Fence Daemon Props
+ fencedaemon_url = '%stab=%s' % (prop_baseurl, PROP_FENCE_TAB)
+ clumap['fencedaemon_url'] = fencedaemon_url
+ fdp = model.getFenceDaemonPtr()
+ pjd = fdp.getAttribute('post_join_delay')
+ if pjd is None:
+ pjd = '6'
+ pfd = fdp.getAttribute('post_fail_delay')
+ if pfd is None:
+ pfd = '0'
+ #post join delay
+ clumap['pjd'] = pjd
+ #post fail delay
+ clumap['pfd'] = pfd
+
+ #-------------
+ #if multicast
+ multicast_url = '%stab=%s' % (prop_baseurl, PROP_MCAST_TAB)
+ clumap['multicast_url'] = multicast_url
+ #mcast addr
+ is_mcast = model.isMulticast()
+ if is_mcast:
+ clumap['mcast_addr'] = model.getMcastAddr()
+ clumap['is_mcast'] = 'True'
+ else:
+ clumap['is_mcast'] = 'False'
+ clumap['mcast_addr'] = '1.2.3.4'
+ clumap['gulm'] = False
+ else:
+ #-------------
+ # GULM params (RHEL4 only)
+ #-------------
+ lockserv_list = list()
+ clunodes = model.getNodes()
+ gulm_lockservs = map(lambda x: x.getName(), gulm_ptr.getChildren())
+ lockserv_list = map(lambda x: (x, True), gulm_lockservs)
+ for node in clunodes:
+ n = node.getName()
+ if not n in gulm_lockservs:
+ lockserv_list.append((n, False))
+ clumap['gulm'] = True
+ clumap['gulm_url'] = '%stab=%s' % (prop_baseurl, PROP_GULM_TAB)
+ clumap['gulm_lockservers'] = lockserv_list
+
+ #-------------
+ # quorum disk params
+ #-------------
+ quorumd_url = '%stab=%s' % (prop_baseurl, PROP_QDISK_TAB)
+ clumap['quorumd_url'] = quorumd_url
+ is_quorumd = model.isQuorumd()
+ clumap['is_quorumd'] = is_quorumd
+ clumap['interval'] = ''
+ clumap['tko'] = ''
+ clumap['votes'] = ''
+ clumap['min_score'] = ''
+ clumap['device'] = ''
+ clumap['label'] = ''
+
+ # list struct for heuristics...
+ hlist = list()
+ if is_quorumd:
+ qdp = model.getQuorumdPtr()
+ interval = qdp.getAttribute('interval')
+ if interval is not None:
+ clumap['interval'] = interval
+
+ tko = qdp.getAttribute('tko')
+ if tko is not None:
+ clumap['tko'] = tko
+
+ votes = qdp.getAttribute('votes')
+ if votes is not None:
+ clumap['votes'] = votes
+
+ min_score = qdp.getAttribute('min_score')
+ if min_score is not None:
+ clumap['min_score'] = min_score
+
+ device = qdp.getAttribute('device')
+ if device is not None:
+ clumap['device'] = device
+
+ label = qdp.getAttribute('label')
+ if label is not None:
+ clumap['label'] = label
+
+ heuristic_kids = qdp.getChildren()
+ for kid in heuristic_kids:
+ hmap = {}
+ hprog = kid.getAttribute('program')
+ if hprog is None:
+ continue
+
+ hscore = kid.getAttribute('score')
+ hmap['hprog'] = hprog
+ if hscore is not None:
+ hmap['hscore'] = hscore
+ else:
+ hmap['hscore'] = ''
+
+ hinterval = kid.getAttribute('interval')
+ if hinterval is not None:
+ hmap['hinterval'] = hinterval
+ else:
+ hmap['hinterval'] = ''
+ hlist.append(hmap)
+ clumap['hlist'] = hlist
+
+ return clumap
+
+def getClustersInfo(self, status, req):
+ clu_map = {}
+
+ fvars = GetReqVars(req, [ 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
+ nodelist = list()
+ svclist = list()
+ clulist = list()
+ for item in status:
+ if item['type'] == 'node':
+ nodelist.append(item)
+ elif item['type'] == 'service':
+ svclist.append(item)
+ elif item['type'] == 'cluster':
+ clulist.append(item)
+ else:
+ continue
+
+ if len(clulist) < 1:
+ return {}
+ clu = clulist[0]
+ if clu.has_key('error'):
+ clu_map['error'] = clu['error']
+ if clu.has_key('errmsg'):
+ clu_map['errmsg'] = clu['errmsg']
+ clustername = clu['name']
+ if not clu['alias']:
+ clu_map['clusteralias'] = clu['alias']
+ else:
+ clu_map['clusteralias'] = clustername
+ clu_map['clustername'] = clustername
+ if clu['quorate'] == 'true':
+ clu_map['status'] = 'Quorate'
+ clu_map['running'] = 'true'
+ else:
+ clu_map['status'] = 'Not Quorate'
+ clu_map['running'] = 'false'
+ clu_map['votes'] = clu['votes']
+ clu_map['minquorum'] = clu['minQuorum']
+
+ clu_map['clucfg'] = '%s?pagetype=%s&clustername=%s' \
+ % (baseurl, CLUSTER_CONFIG, clustername)
+
+ clu_map['restart_url'] = '%s?pagetype=%s&clustername=%s&task=%s' \
+ % (baseurl, CLUSTER_PROCESS, clustername, CLUSTER_RESTART)
+ clu_map['stop_url'] = '%s?pagetype=%s&clustername=%s&task=%s' \
+ % (baseurl, CLUSTER_PROCESS, clustername, CLUSTER_STOP)
+ clu_map['start_url'] = '%s?pagetype=%s&clustername=%s&task=%s' \
+ % (baseurl, CLUSTER_PROCESS, clustername, CLUSTER_START)
+ clu_map['delete_url'] = '%s?pagetype=%s&clustername=%s&task=%s' \
+ % (baseurl, CLUSTER_PROCESS, clustername, CLUSTER_DELETE)
+
+ svc_dict_list = list()
+ for svc in svclist:
+ svc_dict = {}
+ svcname = svc['name']
+ svc_dict['name'] = svcname
+ svc_dict['servicename'] = svcname
+ svc_dict['nodename'] = svc['nodename']
+ svc_dict['srunning'] = svc['running']
+
+ if svc.has_key('is_vm') and svc['is_vm'] is True:
+ target_page = VM_CONFIG
+ else:
+ target_page = SERVICE
+
+ svcurl = '%s?pagetype=%s&clustername=%s&servicename=%s' \
+ % (baseurl, target_page, clustername, svcname)
+ svc_dict['svcurl'] = svcurl
+ svc_dict_list.append(svc_dict)
+
+ clu_map['currentservices'] = svc_dict_list
+ node_dict_list = list()
+
+ for item in nodelist:
+ nmap = {}
+ name = item['name']
+ nmap['nodename'] = name
+ cfgurl = '%s?pagetype=%s&clustername=%s&nodename=%s' \
+ % (baseurl, NODE, clustername, name)
+ nmap['configurl'] = cfgurl
+ if item['clustered'] == 'true':
+ nmap['status'] = NODE_ACTIVE
+ elif item['online'] == 'false':
+ nmap['status'] = NODE_UNKNOWN
+ else:
+ nmap['status'] = NODE_INACTIVE
+ node_dict_list.append(nmap)
+
+ clu_map['currentnodes'] = node_dict_list
+ return clu_map
+
+def getNodeInfo(self, model, status, request):
+ infohash = {}
+ item = None
+ fvars = GetReqVars(request, [ 'URL', 'clustername', 'nodename' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
+ nodestate = NODE_ACTIVE
+ svclist = list()
+ for thing in status:
+ if thing['type'] == 'service':
+ svclist.append(thing)
+
+ clustername = fvars['clustername']
+ nodename = fvars['nodename']
+ if clustername is None or nodename is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getNodeInfo0: %r %r' \
+ % (clustername, nodename))
+ return {}
+
+ # extract correct node line from cluster status
+ found = False
+ for item in status:
+ if (item['type'] == 'node') and (item['name'] == nodename):
+ if item['online'] == 'false':
+ nodestate = NODE_UNKNOWN
+ elif item['clustered'] == 'true':
+ nodestate = NODE_ACTIVE
+ else:
+ nodestate = NODE_INACTIVE
+ found = True
+ break
+
+ if found is False:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getNodeInfo1: Unable to find node "%s" in cluster status' % nodename)
+ nodestate = NODE_UNKNOWN
+
+ infohash['nodestate'] = nodestate
+ infohash['nodename'] = nodename
+
+ # set up drop down links
+ if nodestate == NODE_ACTIVE:
+ infohash['jl_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_LEAVE_CLUSTER, nodename, clustername)
+ infohash['reboot_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_REBOOT, nodename, clustername)
+ infohash['fence_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FENCE, nodename, clustername)
+ infohash['delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_DELETE, nodename, clustername)
+ elif nodestate == NODE_INACTIVE:
+ infohash['jl_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_JOIN_CLUSTER, nodename, clustername)
+ infohash['reboot_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_REBOOT, nodename, clustername)
+ infohash['fence_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FENCE, nodename, clustername)
+ infohash['delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_DELETE, nodename, clustername)
+ else:
+ infohash['fence_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FENCE, nodename, clustername)
+ infohash['force_delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FORCE_DELETE, nodename, clustername)
+
+ # figure out current services running on this node
+ svc_dict_list = list()
+ for svc in svclist:
+ if svc['nodename'] == nodename:
+ svc_dict = {}
+ svcname = svc['name']
+ svcurl = '%s?pagetype=%s&clustername=%s&servicename=%s' \
+ % (baseurl, SERVICE, clustername, svcname)
+ svc_dict['servicename'] = svcname
+ svc_dict['svcurl'] = svcurl
+ svc_dict_list.append(svc_dict)
+
+ infohash['currentservices'] = svc_dict_list
+
+ fdom_dict_list = list()
+ gulm_cluster = False
+ if model:
+ gulm_cluster = model.getGULMPtr() is not None
+ try:
+ infohash['gulm_lockserver'] = model.isNodeLockserver(nodename)
+ except:
+ infohash['gulm_lockserver'] = False
+
+ # next is faildoms
+ fdoms = model.getFailoverDomainsForNode(nodename)
+ for fdom in fdoms:
+ fdom_dict = {}
+ fdom_dict['name'] = fdom.getName()
+ fdomurl = '%s?pagetype=%s&clustername=%s&fdomname=%s' \
+ % (baseurl, FDOM, clustername, fdom.getName())
+ fdom_dict['fdomurl'] = fdomurl
+ fdom_dict_list.append(fdom_dict)
+ else:
+ infohash['gulm_lockserver'] = False
+
+ infohash['fdoms'] = fdom_dict_list
+
+ infohash['d_states'] = None
+ nodename_resolved = resolve_nodename(self, clustername, nodename)
+
+ if nodestate == NODE_ACTIVE or nodestate == NODE_INACTIVE:
+ try:
+ rc = RicciCommunicator(nodename_resolved)
+ if not rc:
+ raise Exception, 'connection failed'
+ except Exception, e:
+ rc = None
+ infohash['ricci_error'] = True
+ luci_log.info('Error connecting to %s: %s' \
+ % (nodename_resolved, str(e)))
+
+ if rc is not None:
+ # call service module on node and find out which daemons are running
+ dlist = list()
+ dlist.append('ccsd')
+ if not gulm_cluster:
+ dlist.append('cman')
+ dlist.append('fenced')
+ else:
+ dlist.append('lock_gulmd')
+ dlist.append('rgmanager')
+ states = rq.getDaemonStates(rc, dlist)
+ infohash['d_states'] = states
+ else:
+ infohash['ricci_error'] = True
+
+ infohash['logurl'] = '/luci/logs/?nodename=%s&clustername=%s' \
+ % (nodename_resolved, clustername)
+ return infohash
+
+def getNodesInfo(self, model, status, req):
+ resultlist = list()
+ nodelist = list()
+ svclist = list()
+
+ fvars = GetReqVars(req, [ 'URL', 'clustername' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvars['clustername']
+
+ #Sort into lists...
+ for item in status:
+ if item['type'] == 'node':
+ nodelist.append(item)
+ elif item['type'] == 'service':
+ svclist.append(item)
+ else:
+ continue
+
+ if clustername is None:
+ try:
+ clustername = model.getClusterName().strip()
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GNI0: no cluster name: %r %s' \
+ % (e, str(e)))
+ return {}
+
+ for item in nodelist:
+ nl_map = {}
+ name = item['name']
+ nl_map['nodename'] = name
+
+ try:
+ nl_map['gulm_lockserver'] = model.isNodeLockserver(name)
+ except:
+ nl_map['gulm_lockserver'] = False
+
+ cfgurl = '%s?pagetype=%s&clustername=%s&nodename=%s' \
+ % (baseurl, NODE, clustername, name)
+ nl_map['configurl'] = cfgurl
+ nl_map['fenceurl'] = '%s#fence' % cfgurl
+ if item['clustered'] == 'true':
+ nl_map['status'] = NODE_ACTIVE
+ nl_map['status_str'] = NODE_ACTIVE_STR
+ elif item['online'] == 'false':
+ nl_map['status'] = NODE_UNKNOWN
+ nl_map['status_str'] = NODE_UNKNOWN_STR
+ else:
+ nl_map['status'] = NODE_INACTIVE
+ nl_map['status_str'] = NODE_INACTIVE_STR
+
+ nodename_resolved = resolve_nodename(self, clustername, name)
+
+ nl_map['logurl'] = '/luci/logs?nodename=%s&clustername=%s' \
+ % (nodename_resolved, clustername)
+
+ # set up URLs for dropdown menu...
+ if nl_map['status'] == NODE_ACTIVE:
+ nl_map['jl_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_LEAVE_CLUSTER, name, clustername)
+ nl_map['reboot_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_REBOOT, name, clustername)
+ nl_map['fence_it_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FENCE, name, clustername)
+ nl_map['delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_DELETE, name, clustername)
+ elif nl_map['status'] == NODE_INACTIVE:
+ nl_map['jl_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_JOIN_CLUSTER, name, clustername)
+ nl_map['reboot_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_REBOOT, name, clustername)
+ nl_map['fence_it_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FENCE, name, clustername)
+ nl_map['delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_DELETE, name, clustername)
+ else:
+ nl_map['fence_it_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FENCE, name, clustername)
+ nl_map['force_delete_url'] = '%s?pagetype=%s&task=%s&nodename=%s&clustername=%s' \
+ % (baseurl, NODE_PROCESS, NODE_FORCE_DELETE, name, clustername)
+
+ # figure out current services running on this node
+ svc_dict_list = list()
+ for svc in svclist:
+ if svc['nodename'] == name:
+ svc_dict = {}
+ svcname = svc['name']
+ svcurl = '%s?pagetype=%s&clustername=%s&servicename=%s' \
+ % (baseurl, SERVICE, clustername, svcname)
+ svc_dict['servicename'] = svcname
+ svc_dict['svcurl'] = svcurl
+ svc_dict_list.append(svc_dict)
+
+ nl_map['currentservices'] = svc_dict_list
+
+ # next is faildoms
+ if model:
+ fdoms = model.getFailoverDomainsForNode(name)
+ else:
+ nl_map['ricci_error'] = True
+ fdoms = list()
+
+ fdom_dict_list = list()
+ for fdom in fdoms:
+ fdom_dict = {}
+ fdom_dict['name'] = fdom.getName()
+ fdomurl = '%s?pagetype=%s&clustername=%s&fdomname=%s' \
+ % (baseurl, FDOM, clustername, fdom.getName())
+ fdom_dict['fdomurl'] = fdomurl
+ fdom_dict_list.append(fdom_dict)
+
+ nl_map['fdoms'] = fdom_dict_list
+ resultlist.append(nl_map)
+
+ return resultlist
+
+def getFence(self, model, request):
+ if not model:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getFence0: model is None')
+ return {}
+
+ fvars = GetReqVars(request, [ 'URL', 'fencename' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ fencename = fvars['fencename']
+
+ fence_map = {}
+ nodes = model.getNodes()
+ fencedevs = model.getFenceDevices()
+ clustername = model.getClusterName()
+
+ for fencedev in fencedevs:
+ if fencedev.getName().strip() == fencename:
+ fence_map = fencedev.getAttributes()
+ try:
+ fence_map['pretty_name'] = FENCE_OPTS[fencedev.getAgentType()]
+ except:
+ fence_map['unknown'] = True
+ fence_map['pretty_name'] = fencedev.getAgentType()
+
+ nodes_used = list()
+ for node in nodes:
+ flevels = node.getFenceLevels()
+ for flevel in flevels:
+ # These are the method blocks...
+ kids = flevel.getChildren()
+ for kid in kids:
+ # These are actual devices in each level
+ if kid.getName().strip() == fencedev.getName().strip():
+ # See if this fd already has an entry for this node
+ found_duplicate = False
+ for item in nodes_used:
+ if item['nodename'] == node.getName().strip():
+ found_duplicate = True
+ if found_duplicate is True:
+ continue
+ node_hash = {}
+ cur_nodename = node.getName().strip()
+ node_hash['nodename'] = cur_nodename
+ node_hash['nodeurl'] = '%s?clustername=%s&nodename=%s&pagetype=%s' \
+ % (baseurl, clustername, cur_nodename, NODE)
+ nodes_used.append(node_hash)
+
+ fence_map['nodesused'] = nodes_used
+ return fence_map
+
+ return fence_map
+
+def getFDForInstance(fds, name):
+ for fd in fds:
+ if fd.getName().strip() == name:
+ return fd
+ raise
+
+def getFenceInfo(self, model, request):
+ if not model:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getFenceInfo0: model is None')
+ return {}
+
+ fvars = GetReqVars(request, [ 'clustername', 'URL', 'nodename' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvars['clustername'] or model.getClusterName()
+
+ nodename = fvars['nodename']
+ if nodename is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getFenceInfo1: no nodename')
+ return {}
+
+ fence_map = {}
+ level1 = list() #First level fence devices
+ level2 = list() #Second level fence devices
+ shared1 = list() #List of available sharable fence devs not used in level1
+ shared2 = list() #List of available sharable fence devs not used in level2
+ fence_map['level1'] = level1
+ fence_map['level2'] = level2
+ fence_map['shared1'] = shared1
+ fence_map['shared2'] = shared2
+
+ major_num = 1
+ minor_num = 100
+
+ # Here we need to get fences for a node - just the first two levels
+ # Each level has its own list of fence devs used in that level
+ # For each fence dev, a list of instance structs is appended
+ # In addition, for each level, a list of available but unused fence devs
+ # is returned.
+ try:
+ node = model.retrieveNodeByName(nodename)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getFenceInfo3: unable to find node name "%s" in current node list: %r %s' % (str(nodename), e, str(e)))
+ return {}
+
+ fds = model.getFenceDevices()
+
+ levels = node.getFenceLevels()
+ len_levels = len(levels)
+
+ if len_levels == 0:
+ return fence_map
+
+ if len_levels >= 1:
+ first_level = levels[0]
+ kids = first_level.getChildren()
+
+ # This is a marker for allowing multi instances
+ # beneath a fencedev
+ last_kid_fd = None
+
+ for kid in kids:
+ instance_name = kid.getName().strip()
+ try:
+ fd = getFDForInstance(fds, instance_name)
+ except:
+ # Set to None in case last time thru loop
+ fd = None
+ continue
+
+ if fd is not None:
+ if fd.isShared() is False:
+ # Not a shared dev... build struct and add
+ fencedev = {}
+
+ try:
+ fencedev['prettyname'] = FENCE_OPTS[fd.getAgentType()]
+ except:
+ fencedev['unknown'] = True
+ fencedev['prettyname'] = fd.getAgentType()
+ fencedev['isShared'] = False
+ fencedev['id'] = str(major_num)
+ major_num = major_num + 1
+ devattrs = fd.getAttributes()
+ kees = devattrs.keys()
+ for kee in kees:
+ fencedev[kee] = devattrs[kee]
+ kidattrs = kid.getAttributes()
+ kees = kidattrs.keys()
+ for kee in kees:
+ if kee == 'name':
+ # Don't duplicate name attr
+ continue
+ fencedev[kee] = kidattrs[kee]
+
+ # This fencedev struct is complete, and needs
+ # to be placed on the level1 Q. Because it is
+ # non-shared, we should set last_kid_fd to none.
+ last_kid_fd = None
+ level1.append(fencedev)
+ else:
+ # This dev is shared
+ if (last_kid_fd is not None) and (fd.getName().strip() == last_kid_fd['name'].strip()):
+ # just append a new instance struct to last_kid_fd
+ instance_struct = {}
+ instance_struct['id'] = str(minor_num)
+ minor_num = minor_num + 1
+ kidattrs = kid.getAttributes()
+ kees = kidattrs.keys()
+
+ for kee in kees:
+ if kee != 'name':
+ instance_struct[kee] = kidattrs[kee]
+
+ # Now just add this struct to last_kid_fd
+ # and reset last_kid_fd
+ ilist = last_kid_fd['instance_list']
+ ilist.append(instance_struct)
+ continue
+ else:
+ # Shared, but not used above...so we need
+ # a new fencedev struct
+ fencedev = {}
+ try:
+ fencedev['prettyname'] = FENCE_OPTS[fd.getAgentType()]
+ except:
+ fencedev['unknown'] = True
+ fencedev['prettyname'] = fd.getAgentType()
+ fencedev['isShared'] = True
+ fencedev['cfgurl'] = '%s?clustername=%s&fencename=%s&pagetype=%s' \
+ % (baseurl, clustername, fd.getName().strip(), FENCEDEV)
+ fencedev['id'] = str(major_num)
+ major_num = major_num + 1
+ inlist = list()
+ fencedev['instance_list'] = inlist
+ devattrs = fd.getAttributes()
+ kees = devattrs.keys()
+ for kee in kees:
+ fencedev[kee] = devattrs[kee]
+ instance_struct = {}
+ kidattrs = kid.getAttributes()
+ kees = kidattrs.keys()
+ for kee in kees:
+ if kee != 'name':
+ instance_struct[kee] = kidattrs[kee]
+
+ inlist.append(instance_struct)
+ level1.append(fencedev)
+ last_kid_fd = fencedev
+ continue
+ fence_map['level1'] = level1
+
+ # level1 list is complete now, but it is still
+ # necessary to build shared1
+ for fd in fds:
+ isUnique = True
+ if fd.isShared() is False:
+ continue
+ for fdev in level1:
+ if fd.getName().strip() == fdev['name']:
+ isUnique = False
+ break
+ if isUnique is True:
+ shared_struct = {}
+ shared_struct['name'] = fd.getName().strip()
+ agentname = fd.getAgentType()
+ shared_struct['agent'] = agentname
+ try:
+ shared_struct['prettyname'] = FENCE_OPTS[agentname]
+ except:
+ shared_struct['unknown'] = True
+ shared_struct['prettyname'] = agentname
+ shared1.append(shared_struct)
+ fence_map['shared1'] = shared1
+
+ # YUK: This next section violates the DRY rule, :-(
+ if len_levels >= 2:
+ second_level = levels[1]
+ kids = second_level.getChildren()
+ last_kid_fd = None #This is a marker for allowing multi instances
+ #beneath a fencedev
+ for kid in kids:
+ instance_name = kid.getName().strip()
+ try:
+ fd = getFDForInstance(fds, instance_name)
+ except:
+ fd = None #Set to None in case last time thru loop
+ continue
+ if fd is not None:
+ if fd.isShared() is False: #Not a shared dev...build struct and add
+ fencedev = {}
+ try:
+ fencedev['prettyname'] = FENCE_OPTS[fd.getAgentType()]
+ except:
+ fencedev['unknown'] = True
+ fencedev['prettyname'] = fd.getAgentType()
+ fencedev['isShared'] = False
+ fencedev['id'] = str(major_num)
+ major_num = major_num + 1
+ devattrs = fd.getAttributes()
+ kees = devattrs.keys()
+ for kee in kees:
+ fencedev[kee] = devattrs[kee]
+ kidattrs = kid.getAttributes()
+ kees = kidattrs.keys()
+ for kee in kees:
+ if kee == 'name':
+ continue #Don't duplicate name attr
+ fencedev[kee] = kidattrs[kee]
+ #This fencedev struct is complete, and needs to be placed on the
+ #level2 Q. Because it is non-shared, we should set last_kid_fd
+ #to none.
+ last_kid_fd = None
+ level2.append(fencedev)
+ else: #This dev is shared
+ if (last_kid_fd is not None) and (fd.getName().strip() == last_kid_fd['name'].strip()): #just append a new instance struct to last_kid_fd
+ instance_struct = {}
+ instance_struct['id'] = str(minor_num)
+ minor_num = minor_num + 1
+ kidattrs = kid.getAttributes()
+ kees = kidattrs.keys()
+ for kee in kees:
+ if kee == 'name':
+ continue
+ instance_struct[kee] = kidattrs[kee]
+ #Now just add this struct to last_kid_fd and reset last_kid_fd
+ ilist = last_kid_fd['instance_list']
+ ilist.append(instance_struct)
+ #last_kid_fd = fd
+ continue
+ else: #Shared, but not used above...so we need a new fencedev struct
+ fencedev = {}
+ try:
+ fencedev['prettyname'] = FENCE_OPTS[fd.getAgentType()]
+ except:
+ fencedev['unknown'] = True
+ fencedev['prettyname'] = fd.getAgentType()
+ fencedev['isShared'] = True
+ fencedev['cfgurl'] = '%s?clustername=%s&fencename=%s&pagetype=%s' \
+ % (baseurl, clustername, fd.getName().strip(), FENCEDEV)
+ fencedev['id'] = str(major_num)
+ major_num = major_num + 1
+ inlist = list()
+ fencedev['instance_list'] = inlist
+ devattrs = fd.getAttributes()
+ kees = devattrs.keys()
+ for kee in kees:
+ fencedev[kee] = devattrs[kee]
+ instance_struct = {}
+ kidattrs = kid.getAttributes()
+ kees = kidattrs.keys()
+ for kee in kees:
+ if kee == 'name':
+ continue
+ instance_struct[kee] = kidattrs[kee]
+ inlist.append(instance_struct)
+ level2.append(fencedev)
+ last_kid_fd = fencedev
+ continue
+ fence_map['level2'] = level2
+
+ #level2 list is complete but like above, we need to build shared2
+ for fd in fds:
+ isUnique = True
+ if fd.isShared() is False:
+ continue
+ for fdev in level2:
+ if fd.getName().strip() == fdev['name']:
+ isUnique = False
+ break
+ if isUnique is True:
+ shared_struct = {}
+ shared_struct['name'] = fd.getName().strip()
+ agentname = fd.getAgentType()
+ shared_struct['agent'] = agentname
+ try:
+ shared_struct['prettyname'] = FENCE_OPTS[agentname]
+ except:
+ shared_struct['unknown'] = True
+ shared_struct['prettyname'] = agentname
+ shared2.append(shared_struct)
+ fence_map['shared2'] = shared2
+
+ return fence_map
+
+def getFencesInfo(self, model, request):
+ fences_map = {}
+ if not model:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getFencesInfo0: model is None')
+ fences_map['fencedevs'] = list()
+ return fences_map
+
+ fvars = GetReqVars(request, [ 'clustername', 'URL' ])
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ clustername = fvars['clustername'] or model.getClusterName()
+
+ fencedevs = list() #This is for the fencedev list page
+
+ #Get list of fence devices
+ fds = model.getFenceDevices()
+ for fd in fds:
+ #This section determines which nodes use the dev
+ #create fencedev hashmap
+ nodes_used = list()
+
+ if fd.isShared() is True:
+ fencedev = {}
+ attr_hash = fd.getAttributes()
+ kees = attr_hash.keys()
+
+ for kee in kees:
+ fencedev[kee] = attr_hash[kee] #copy attrs over
+ try:
+ fencedev['pretty_name'] = FENCE_OPTS[fd.getAgentType()]
+ except:
+ fencedev['unknown'] = True
+ fencedev['pretty_name'] = fd.getAgentType()
+
+ fencedev['agent'] = fd.getAgentType()
+ #Add config url for this fencedev
+ fencedev['cfgurl'] = '%s?clustername=%s&fencename=%s&pagetype=%s' \
+ % (baseurl, clustername, fd.getName().strip(), FENCEDEV)
+
+ nodes = model.getNodes()
+ for node in nodes:
+ flevels = node.getFenceLevels()
+ for flevel in flevels: #These are the method blocks...
+ kids = flevel.getChildren()
+ for kid in kids: #These are actual devices in each level
+ if kid.getName().strip() == fd.getName().strip():
+ #See if this fd already has an entry for this node
+ found_duplicate = False
+ for item in nodes_used:
+ if item['nodename'] == node.getName().strip():
+ found_duplicate = True
+ if found_duplicate is True:
+ continue
+ node_hash = {}
+ cur_nodename = node.getName().strip()
+ node_hash['nodename'] = cur_nodename
+ node_hash['nodeurl'] = '%s?clustername=%s&nodename=%s&pagetype=%s' \
+ % (baseurl, clustername, cur_nodename, NODE)
+ nodes_used.append(node_hash)
+
+ fencedev['nodesused'] = nodes_used
+ fencedevs.append(fencedev)
+
+ fences_map['fencedevs'] = fencedevs
+ return fences_map
+
+def getVMInfo(self, model, request):
+ vm_map = {}
+ fvars = GetReqVars(request, [ 'clustername', 'servicename', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
+ clustername = fvars['clustername']
+ if clustername is None:
+ clustername = model.getName()
+
+ svcname = fvars['servicename']
+ if svcname is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getVMInfo0: no service name')
+ return vm_map
+
+ vm_map['formurl'] = '%s?clustername=%s&pagetype=29&servicename=%s' \
+ % (baseurl, clustername, svcname)
+
+ try:
+ vm = model.retrieveVMsByName(svcname)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('getVMInfo1: %s: %r %s' % (svcname, e, str(e)))
+ return vm_map
+
+ attrs = vm.getAttributes()
+ keys = attrs.keys()
+ for key in keys:
+ vm_map[key] = attrs[key]
+
+ return vm_map
+
+def getResourcesInfo(self, model, request):
+ fvars = GetReqVars(request, [ 'clustername', 'URL' ])
+
+ baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+ if fvars['clustername'] is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getResourcesInfo missing cluster name')
+ return []
+
+ return getResources(model, baseurl)
+
+def getClusterName(self, model):
+ return model.getClusterName()
+
+def getClusterAlias(self, model):
+ if not model:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCA0: no model')
+ return ''
+ alias = model.getClusterAlias()
+ if not alias:
+ return model.getClusterName()
+ return alias
+
+def getModelBuilder(self, rc, isVirtualized):
+ try:
+ cluster_conf_node = rq.getClusterConf(rc)
+ if not cluster_conf_node:
+ raise Exception, 'getClusterConf returned None'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GMB0: unable to get cluster_conf_node in getModelBuilder: %r %s' % (e, str(e)))
+ return None
+
+ try:
+ model = ModelBuilder(0, None, None, cluster_conf_node)
+ if not model:
+ raise Exception, 'ModelBuilder() returned None'
+ model.setIsVirtualized(isVirtualized)
+ except Exception, e:
+ try:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GMB1: An error occurred while trying to get model for conf "%s": %r %s' % (cluster_conf_node.toxml(), e, str(e)))
+ except:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GMB1: ModelBuilder failed')
+ return None
+
+ return model
+
+def getModelForCluster(self, clustername):
+ from LuciDB import getRicciAgent
+
+ rc = getRicciAgent(self, clustername)
+ if not rc:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GMFC0: no ricci agent for %s' % clustername)
+ return None
+
+ try:
+ model = getModelBuilder(None, rc, rc.dom0())
+ if not model:
+ raise Exception, 'model is none'
+ return model
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GMFC1: unable to get model builder for %s: %r %s' % (clustername, e, str(e)))
+ return None
+
+def LuciExtractCluModel(self, request, cluster_name=None):
+ model = None
+ try:
+ model = request.SESSION.get('model')
+ model.getClusterName()
+ return model
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('LECM0: %r: %r %s' \
+ % (cluster_name, e, str(e)))
+ model = None
+
+ if not cluster_name:
+ fvar = GetReqVars(request, [ 'clustername' ])
+ cluster_name = fvar['clustername']
+
+ if cluster_name is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('LECM1: no cluster name')
+ return None
+
+ try:
+ model = getModelForCluster(self, cluster_name)
+ model.getClusterName()
+ return model
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('LECM2: no model for %s: %r %s' \
+ % (cluster_name, e, str(e)))
+ return None
+
+def getClusterOS(self, rc):
+ from HelperFunctions import resolveOSType
+
+ clu_map = {}
+
+ try:
+ os_str = resolveOSType(rc.os())
+ clu_map['os'] = os_str
+ clu_map['isVirtualized'] = rc.dom0()
+ except:
+ # default to rhel5 if something crazy happened.
+ try:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('An error occurred while attempting to get OS/Virt info for %s -- defaulting to rhel5/False' % rc.hostname())
+ except:
+ # this can throw an exception if the original exception
+ # is caused by rc being None or stale.
+ pass
+ clu_map['os'] = 'rhel5'
+ clu_map['isVirtualized'] = False
+ return clu_map
+
+def getClusterConfNodes(conf_dom):
+ try:
+ cluster_nodes = conf_dom.getElementsByTagName('clusternode')
+ return map(lambda x: str(x.getAttribute('name')), cluster_nodes)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCCN0: %r %s' % (e, str(e)))
+ return None
/cvs/cluster/conga/luci/site/luci/Extensions/LuciDB.py,v --> standard output
revision 1.6.2.1
--- conga/luci/site/luci/Extensions/LuciDB.py
+++ - 2007-08-09 21:35:22.772198000 +0000
@@ -0,0 +1,969 @@
+# Copyright (C) 2006-2007 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 AccessControl import getSecurityManager
+from ricci_communicator import RicciCommunicator
+from LuciZopePerm import isAdmin
+from LuciSyslog import get_logger
+
+from conga_constants import CLUSTER_FOLDER_PATH, BATCH_ID, TASKTYPE, \
+ FLAG_DESC, CLUSTER_ADD, LAST_STATUS, \
+ STORAGE_FOLDER_PATH, LUCI_DEBUG_MODE
+
+# Cluster node exception attribute flags
+CLUSTER_NODE_NEED_AUTH = 0x01
+CLUSTER_NODE_NOT_MEMBER = 0x02
+CLUSTER_NODE_ADDED = 0x04
+
+luci_log = get_logger()
+
+def getClusterNode(self, nodename, clustername):
+ try:
+ path = str('%s%s/%s' % (CLUSTER_FOLDER_PATH, clustername, nodename))
+ cluster_node = self.restrictedTraverse(path)
+ if not cluster_node:
+ return None
+ return cluster_node
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getClusterNode0: %s %s: %r %s' \
+ % (nodename, clustername, e, str(e)))
+ return None
+
+def getStorageNode(self, nodename):
+ try:
+ path = str('%s%s' % (STORAGE_FOLDER_PATH, nodename))
+ storage_node = self.restrictedTraverse(path)
+ if not storage_node:
+ raise Exception, 'no storage node found'
+ return storage_node
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('getStorageNode0: %s: %r %s' \
+ % (nodename, e, str(e)))
+ return None
+
+def testNodeStatus(node, flag_mask):
+ try:
+ flags = node.getProperty('flags')
+ if flags is None:
+ return False
+ return flags & flag_mask != 0
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('testNodeStatus0: %r %s' % (e, str(e)))
+ return False
+
+def setNodeStatus(node, flag_mask):
+ try:
+ flags = node.getProperty('flags')
+ if flags is None:
+ flags = 0
+ node.manage_changeProperties({ 'flags': flags | flag_mask })
+ except:
+ try:
+ node.manage_addProperty('flags', flag_mask, 'int')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('setNodeStatus0: %r %s' \
+ % (e, str(e)))
+
+def clearNodeStatus(node, flag_mask):
+ try:
+ flags = node.getProperty('flags')
+ if flags is None:
+ return
+ if flags & flag_mask != 0:
+ node.manage_changeProperties({ 'flags': flags & ~flag_mask })
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('clearNodeStatus0: %r %s' \
+ % (e, str(e)))
+
+def set_node_flag(self, cluname, agent, batchid, task, desc):
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, cluname))
+ batch_id = str(batchid)
+ objname = '%s____flag' % agent
+
+ objpath = ''
+ try:
+ clusterfolder = self.restrictedTraverse(path)
+ clusterfolder.manage_addProduct['ManagedSystem'].addManagedSystem(objname)
+ objpath = str('%s/%s' % (path, objname))
+ flag = self.restrictedTraverse(objpath)
+ flag.manage_addProperty(BATCH_ID, batch_id, 'string')
+ flag.manage_addProperty(TASKTYPE, task, 'string')
+ flag.manage_addProperty(FLAG_DESC, desc, 'string')
+ except Exception, e:
+ errmsg = 'SNF0: error creating flag (%s,%s,%s) at %s: %s' \
+ % (batch_id, task, desc, objpath, str(e))
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('SNF0: %r %s' % (e, errmsg))
+ raise Exception, errmsg
+
+def NodeBusy(self, clustername, nodename, rc=None):
+ try:
+ path = str('%s%s/%s' % (CLUSTER_FOLDER_PATH, clustername, nodename))
+ nodefolder = self.restrictedTraverse(path)
+ if not nodefolder:
+ raise Exception, 'cannot find database object at %s' % path
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('NodeBusy0: (%s,%s) %r %s' \
+ % (clustername, nodename, e, str(e)))
+ return None
+
+ flagname = '%s____flag' % nodename
+
+ try:
+ items = nodefolder.objectItems('ManagedSystem')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('NodeBusy1: error getting flags for %s: %r %s' \
+ % (nodefolder[0], e, str(e)))
+ return None
+
+ for item in items:
+ if item[0] != flagname:
+ continue
+
+ # A flag already exists. Check to see whether we're done.
+ if rc is None:
+ try:
+ rc = RicciCommunicator(nodename)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.info('NodeBusy2: ricci error %s: %r %s' \
+ % (nodename, e, str(e)))
+ # We can't know if we're done or not; err on the
+ # side of caution.
+ return True
+
+ if not rc.authed():
+ try:
+ snode = getStorageNode(self, nodename)
+ setNodeStatus(snode, CLUSTER_NODE_NEED_AUTH)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NodeBusy3: %s: %r %s' \
+ % (nodename, e, str(e)))
+ if LUCI_DEBUG_MODE is True:
+ luci_log.info('%s not authenticated' % item[0])
+ # The comment above applies here, too.
+ return True
+
+ batch_id = item[1].getProperty(BATCH_ID)
+ batch_ret = rc.batch_status(batch_id)
+ finished = batch_ret[0]
+ if finished is True or finished == -1:
+ if finished == -1:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('NodeBusy5: batch error: %s' \
+ % batch_ret[1])
+
+ try:
+ nodefolder.manage_delObjects([item[0]])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.info('NodeBusy6: %s: %r %s' % (item[0], e, str(e)))
+ return False
+
+ # Not finished, so don't remove the flag.
+ return True
+
+ # If this code is ever reached, no flags exist for the node in question.
+ return False
+
+def resolve_nodename(self, clustername, nodename):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ clusterfolder = self.restrictedTraverse(path)
+ objs = clusterfolder.objectItems('Folder')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('RNN0: error for %s/%s: %r %s' \
+ % (nodename, clustername, e, str(e)))
+ return nodename
+
+ for obj in objs:
+ try:
+ if obj[0].find(nodename) != (-1):
+ return obj[0]
+ except:
+ continue
+
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('RNN1: failed for %s/%s: nothing found' \
+ % (nodename, clustername))
+ return nodename
+
+def resolveClusterChanges(self, clustername, model):
+ try:
+ mb_nodes = model.getNodes()
+ if not mb_nodes or not len(mb_nodes):
+ raise Exception, 'node list is empty'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('RCC0: no model builder nodes found for %s: %r %s' % (clustername, e, str(e)))
+ return 'Unable to find cluster nodes for %s' % clustername
+
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ cluster_node = self.restrictedTraverse(path)
+ if not cluster_node:
+ raise Exception, 'cluster node is none'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('RCC1: cant find cluster node for %s: %r %s' \
+ % (clustername, e, str(e)))
+ return 'Unable to find an entry for %s in the Luci database.' % clustername
+
+ try:
+ db_nodes = map(lambda x: x[0], cluster_node.objectItems('Folder'))
+ if not db_nodes or not len(db_nodes):
+ raise Exception, 'no database nodes'
+ except Exception, e:
+ # Should we just create them all? Can this even happen?
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('RCC2: error: %r %s' % (e, str(e)))
+ return 'Unable to find database entries for any nodes in %s' % clustername
+
+ same_host = lambda x, y: x == y or x[:len(y) + 1] == y + '.' or y[:len(x) + 1] == x + '.'
+
+ # this is a really great algorithm.
+ missing_list = list()
+ new_list = list()
+ for i in mb_nodes:
+ for j in db_nodes:
+ f = 0
+ if same_host(i, j):
+ f = 1
+ break
+ if not f:
+ new_list.append(i)
+
+ for i in db_nodes:
+ for j in mb_nodes:
+ f = 0
+ if same_host(i, j):
+ f = 1
+ break
+ if not f:
+ missing_list.append(i)
+
+ messages = list()
+ for i in missing_list:
+ try:
+ # or alternately
+ # new_node = cluster_node.restrictedTraverse(i)
+ # #setNodeStatus(self, new_node, CLUSTER_NODE_NOT_MEMBER)
+ cluster_node.delObjects([i])
+ messages.append('Node "%s" is no longer in a member of cluster "%s." It has been deleted from the management interface for this cluster.' % (i, clustername))
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VCC3: deleted node %s' % i)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VCC4: delObjects: %s: %r %s' \
+ % (i, e, str(e)))
+
+ new_flags = CLUSTER_NODE_NEED_AUTH | CLUSTER_NODE_ADDED
+ for i in new_list:
+ try:
+ cluster_node.manage_addFolder(i)
+ new_node = cluster_node.restrictedTraverse(str(i))
+ setNodeStatus(self, new_node, new_flags)
+ messages.append('A new cluster node, "%s," is now a member of cluster "%s." It has been added to the management interface for this cluster, but you must authenticate to it in order for it to be fully functional.' % (i, clustername))
+ except Exception, e:
+ messages.append('A new cluster node, "%s," is now a member of cluster "%s,". but it has not been added to the management interface for this cluster as a result of an error creating a database entry for it.' % (i, clustername))
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('VCC5: addFolder: %s/%s: %r %s' \
+ % (clustername, i, e, str(e)))
+
+ return messages
+
+def buildClusterCreateFlags(self, batch_map, clustername):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ clusterfolder = self.restrictedTraverse(path)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('buildCCF0: no cluster folder at %s: %r %s' \
+ % (path, e, str(e)))
+ return None
+
+ for key in batch_map.keys():
+ try:
+ key = str(key)
+ batch_id = str(batch_map[key])
+ # This suffix needed to avoid name collision
+ objname = '%s____flag' % key
+
+ clusterfolder.manage_addProduct['ManagedSystem'].addManagedSystem(objname)
+ # now designate this new object properly
+ objpath = str('%s/%s' % (path, objname))
+ flag = self.restrictedTraverse(objpath)
+
+ flag.manage_addProperty(BATCH_ID, batch_id, 'string')
+ flag.manage_addProperty(TASKTYPE, CLUSTER_ADD, 'string')
+ flag.manage_addProperty(FLAG_DESC, 'Creating node "%s" for cluster "%s"' % (key, clustername), 'string')
+ flag.manage_addProperty(LAST_STATUS, 0, 'int')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('buildCCF1: error creating flag for %s: %r %s' % (key, e, str(e)))
+
+def manageCluster(self, clustername, node_list, cluster_os):
+ try:
+ clusters = self.restrictedTraverse(str(CLUSTER_FOLDER_PATH))
+ if not clusters:
+ raise Exception, 'cannot find the cluster entry in the DB'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC0: %s: %r %s' % (clustername, e, str(e)))
+ return 'Unable to create cluster %s: the cluster directory is missing.' % clustername
+
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ newCluster = self.restrictedTraverse(path)
+ if newCluster:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC1: cluster %s: already exists' \
+ % clustername)
+ return 'A cluster named %s is already managed by Luci' % clustername
+ except:
+ pass
+
+ try:
+ clusters.manage_addFolder(clustername)
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ newCluster = self.restrictedTraverse(path)
+ if not newCluster:
+ raise Exception, 'unable to create the cluster DB entry for %s' % clustername
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC2: %s: %r %s' % (clustername, e, str(e)))
+ return 'Unable to create cluster %s: %s' % (clustername, str(e))
+
+ try:
+ newCluster.manage_acquiredPermissions([])
+ newCluster.manage_role('View', ['Access Contents Information', 'View'])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC3: %s: %r %s' % (clustername, e, str(e)))
+ try:
+ clusters.manage_delObjects([clustername])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC4: %s: %r %s' \
+ % (clustername, e, str(e)))
+ return 'Unable to set permissions on new cluster: %s: %s' \
+ % (clustername, str(e))
+
+ try:
+ newCluster.manage_addProperty('cluster_os', cluster_os, 'string')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC5: %s: %s: %r %s' \
+ % (clustername, cluster_os, e, str(e)))
+
+ for i in node_list:
+ host = node_list[i]['host']
+
+ try:
+ newCluster.manage_addFolder(host)
+ path = str('%s%s/%s' % (CLUSTER_FOLDER_PATH, clustername, host))
+ newSystem = self.restrictedTraverse(path)
+ if not newSystem:
+ raise Exception, 'unable to create cluster system DB entry for node %s' % host
+ newSystem.manage_acquiredPermissions([])
+ newSystem.manage_role('View', [ 'Access contents information' , 'View' ])
+ except Exception, e:
+ try:
+ clusters.manage_delObjects([clustername])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC6: %s: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC7: %s: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+ return 'Unable to create cluster node %s for cluster %s: %s' \
+ % (host, clustername, str(e))
+
+ try:
+ ssystem = self.restrictedTraverse(STORAGE_FOLDER_PATH)
+ if not ssystem:
+ raise Exception, 'The storage DB entry is missing'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC8: %s: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+ return 'Error adding storage node %s: %s' % (host, str(e))
+
+ # Only add storage systems if the cluster and cluster node DB
+ # objects were added successfully.
+ for i in node_list:
+ host = node_list[i]['host']
+
+ try:
+ # It's already there, as a storage system, no problem.
+ path = str('%s%s' % (STORAGE_FOLDER_PATH, host))
+ dummy = self.restrictedTraverse(path)
+ continue
+ except:
+ pass
+
+ try:
+ ssystem.manage_addFolder(host)
+ path = str('%s%s' % (STORAGE_FOLDER_PATH, host))
+ newSystem = self.restrictedTraverse(path)
+ newSystem.manage_acquiredPermissions([])
+ newSystem.manage_role('View', [ 'Access contents information' , 'View' ])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('MC9: %s: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+
+def createClusterSystems(self, clustername, node_list):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ clusterObj = self.restrictedTraverse(path)
+ if not clusterObj:
+ raise Exception, 'cluster %s DB entry is missing' % clustername
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CCS0: %s: %r %s' \
+ % (clustername, e, str(e)))
+ return 'No cluster named "%s" is managed by Luci' % clustername
+
+ for x in node_list:
+ i = node_list[x]
+ host = str(i['host'])
+
+ try:
+ clusterObj.manage_addFolder(host)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CCS0a: %s: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+
+ try:
+ path = str('%s%s/%s' % (CLUSTER_FOLDER_PATH, clustername, host))
+ newSystem = self.restrictedTraverse(path)
+ if not newSystem:
+ raise Exception, 'cluster node DB entry for %s disappeared from under us' % host
+ newSystem.manage_acquiredPermissions([])
+ newSystem.manage_role('View', [ 'Access contents information' , 'View' ])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CCS1: %s: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+ return 'Unable to create cluster node %s for cluster %s: %s' \
+ % (host, clustername, str(e))
+
+ try:
+ ssystem = self.restrictedTraverse(STORAGE_FOLDER_PATH)
+ if not ssystem:
+ raise Exception, 'storage DB entry is missing'
+ except Exception, e:
+ # This shouldn't fail, but if it does, it's harmless right now
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CCS2: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+ return None
+
+ # Only add storage systems if the and cluster node DB
+ # objects were added successfully.
+ for x in node_list:
+ i = node_list[x]
+ host = str(i['host'])
+
+ try:
+ # It's already there, as a storage system, no problem.
+ path = str('%s%s' % (STORAGE_FOLDER_PATH, host))
+ dummy = self.restrictedTraverse(path)
+ continue
+ except:
+ pass
+
+ try:
+ ssystem.manage_addFolder(host)
+ path = str('%s%s' % (STORAGE_FOLDER_PATH, host))
+ newSystem = self.restrictedTraverse(path)
+ newSystem.manage_acquiredPermissions([])
+ newSystem.manage_role('View', [ 'Access contents information' , 'View' ])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CCS3: %s: %r %s' \
+ % (clustername, host, e, str(e)))
+
+def delSystem(self, systemName):
+ try:
+ ssystem = self.restrictedTraverse(STORAGE_FOLDER_PATH)
+ if not ssystem:
+ raise Exception, 'storage DB entry is missing'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delSystem0: %s: %r %s' \
+ % (systemName, e, str(e)))
+ return 'Unable to find storage system %s: %s' % (systemName, str(e))
+
+ try:
+ rc = RicciCommunicator(systemName, enforce_trust=False)
+ if rc is None:
+ raise Exception, 'rc is None'
+ except Exception, e:
+ try:
+ ssystem.manage_delObjects([ systemName ])
+ except Exception, e1:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delSystem1: %s: %r %s' \
+ % (systemName, e1, str(e1)))
+ return 'Unable to delete the storage system %s' % systemName
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delSystem2: %s: %r %s' \
+ % (systemName, e, str(e)))
+ return
+
+ # Only unauthenticate if the system isn't a member of
+ # a managed cluster.
+ cluster_info = rc.cluster_info()
+ if not cluster_info:
+ cluster_name = None
+ elif not cluster_info[0]:
+ cluster_name = cluster_info[1]
+ else:
+ cluster_name = cluster_info[0]
+
+ unauth = False
+ if not cluster_name:
+ # If it's a member of no cluster, unauthenticate
+ unauth = True
+ else:
+ try:
+ path = str('%s%s/%s' % (CLUSTER_FOLDER_PATH, cluster_name, systemName))
+ dummy = self.restrictedTraverse(path).objectItems()
+ except Exception, e:
+ # It's not a member of a managed cluster, so unauthenticate.
+ unauth = True
+
+ if unauth is True:
+ try:
+ rc.unauth()
+ except:
+ pass
+
+ try:
+ ssystem.manage_delObjects([ systemName ])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delSystem3: %s: %r %s' \
+ % (systemName, e, str(e)))
+ return 'Unable to delete storage system %s: %s' \
+ % (systemName, str(e))
+
+def delCluster(self, clustername):
+ try:
+ clusters = self.restrictedTraverse(CLUSTER_FOLDER_PATH)
+ if not clusters:
+ raise Exception, 'clusters DB entry is missing'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delCluster0: %r %s' % (e, str(e)))
+ return 'Unable to find cluster %s' % clustername
+
+ err = delClusterSystems(self, clustername)
+ if err:
+ return err
+
+ try:
+ clusters.manage_delObjects([ clustername ])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delCluster1: %s %r %s' \
+ % (clustername, e, str(e)))
+ return 'Unable to delete cluster %s' % clustername
+
+def delClusterSystem(self, cluster, systemName):
+ try:
+ path = str('%s%s' % (STORAGE_FOLDER_PATH, systemName))
+ dummy = self.restrictedTraverse(path).objectItems()
+ except:
+ # It's not a storage system, so unauthenticate.
+ try:
+ rc = RicciCommunicator(systemName, enforce_trust=False)
+ rc.unauth()
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delClusterSystem0: ricci error for %s: %r %s' % (systemName, e, str(e)))
+
+ try:
+ cluster.manage_delObjects([ systemName ])
+ except Exception, e:
+ err_str = 'Error deleting cluster object %s: %s' % (systemName, str(e))
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delClusterSystem1: %r %s' % (e, err_str))
+ return err_str
+
+def delClusterSystems(self, clustername):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ cluster = self.restrictedTraverse(path)
+ if not cluster:
+ raise Exception, 'cluster DB entry is missing'
+
+ try:
+ csystems = getClusterSystems(self, clustername)
+ if not csystems or len(csystems) < 1:
+ return None
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delCluSystems0: %r %s' % (e, str(e)))
+ return None
+ except Exception, er:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delCluSystems1: error for %s: %r %s' \
+ % (clustername, er, str(er)))
+ return str(er)
+
+ error_list = list()
+ for i in csystems:
+ err = delClusterSystem(self, cluster, i[0])
+ if err:
+ error_list.append('Unable to delete the cluster system %s: %s\n' \
+ % (i[0], err))
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('delCluSystems2: %s' % err)
+ return ''.join(error_list)
+
+def getSystems(self):
+ storage = getStorage(self)
+ clusters = getClusters(self)
+ storageList = list()
+ ret = [{}, [], {}]
+
+ need_auth_hash = {}
+ for i in storage:
+ storageList.append(i[0])
+ if testNodeStatus(i[1], CLUSTER_NODE_NEED_AUTH) is not False:
+ need_auth_hash[i[0]] = i[1]
+
+ chash = {}
+ for i in clusters:
+ csystems = getClusterSystems(self, i[0])
+ cslist = list()
+ for c in csystems:
+ if testNodeStatus(c[1], CLUSTER_NODE_NEED_AUTH) is not False:
+ need_auth_hash[c[0]] = c[1]
+ cslist.append(c[0])
+ chash[i[0]] = cslist
+
+ ret[0] = chash
+ ret[1] = storageList
+ ret[2] = need_auth_hash
+ return ret
+
+def getCluster(self, clustername):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ cluster_obj = self.restrictedTraverse(path)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCobj0: %s: %r %s' \
+ % (clustername, e, str(e)))
+ return None
+
+ if cluster_permission_check(self, cluster_obj):
+ return cluster_obj
+ return None
+
+def getClusterSystems(self, clustername):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ cluster_nodes = self.restrictedTraverse(path).objectItems('Folder')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSy0: %s: %r %s' \
+ % (clustername, e, str(e)))
+ return None
+
+ if isAdmin(self):
+ return cluster_nodes
+ cluster_obj = getCluster(self, clustername)
+ if cluster_permission_check(self, cluster_obj):
+ return cluster_nodes
+ return None
+
+def getClusters(self):
+ try:
+ clusters = self.restrictedTraverse(CLUSTER_FOLDER_PATH).objectItems('Folder')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GC0: %r %s' % (e, str(e)))
+ return None
+
+ if isAdmin(self):
+ return clusters
+ return check_clusters(self, clusters)
+
+def getStorage(self):
+ try:
+ storage = self.restrictedTraverse(STORAGE_FOLDER_PATH).objectItems('Folder')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GS0: %r %s' % (e, str(e)))
+ return None
+
+ if isAdmin(self):
+ return storage
+ return allowed_systems(storage)
+
+def check_clusters(self, clusters):
+ ret = []
+ try:
+ user = getSecurityManager().getUser()
+ ret = filter(lambda x: user.has_permission('View', x[1]), clusters)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CC0: %r %s' % (e, str(e)))
+ return ret
+
+def cluster_permission_check(self, cluster):
+ if isAdmin(self):
+ return True
+
+ try:
+ user = getSecurityManager().getUser()
+ if user.has_permission('View', cluster[1]):
+ return True
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('CPC0: %s: %r %s' % (cluster, e, str(e)))
+ return False
+
+def allowed_systems(self, systems):
+ user = getSecurityManager().getUser()
+ return filter(lambda x: user.has_permission('View', x[1]), systems)
+
+def access_to_host_allowed(self, hostname, allowed_systems_list):
+ allowed = dict(map(lambda x: [ x[0], None ], allowed_systems_list))
+ return allowed.has_key(hostname)
+
+def getRicciAgent(self, clustername, exclude_names=None, exclude_busy=False):
+ try:
+ perm = cluster_permission_check(self, clustername)
+ if not perm:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA0: no permission for %s' \
+ % clustername)
+ return None
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA0: %r %s' % (e, str(e)))
+ return None
+
+ clusterfolder = None
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ clusterfolder = self.restrictedTraverse(path)
+ if not clusterfolder:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('GRA1: cluster folder %s for %s is missing' \
+ % (path, clustername))
+ return None
+
+ nodes = clusterfolder.objectItems('Folder')
+ if len(nodes) < 1:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('GRA2: no cluster nodes for %s found' \
+ % clustername)
+ raise Exception, 'No cluster nodes were found@%s' % path
+ except Exception, e:
+ try:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('GRA3: cluster folder %s for %s is missing: %r %s' % (path, clustername, e, str(e)))
+
+ if clusterfolder is not None and len(clusterfolder.objectItems()) < 1:
+ clusters = self.restrictedTraverse(CLUSTER_FOLDER_PATH)
+ clusters.manage_delObjects([clustername])
+ except Exception, ein:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA4: %r %s' % (ein, str(ein)))
+ return None
+
+ cluname = clustername.lower()
+ for node in nodes:
+ hostname = node[0]
+
+ if exclude_names is not None and hostname in exclude_names:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA5: %s is in the excluded names list, excluding it' % hostname)
+ continue
+
+ try:
+ rc = RicciCommunicator(hostname)
+ if not rc:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA6: rc is None')
+ continue
+
+ ricci_hostname = rc.hostname()
+ if not ricci_hostname:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA7: ricci_hostname is blank')
+ continue
+
+ clu_info = rc.cluster_info()
+
+ cur_name = str(clu_info[0]).strip().lower()
+ if not cur_name:
+ cur_name = None
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA8: cluster name is none for %s' \
+ % ricci_hostname)
+ raise Exception, '%s not in a cluster' % ricci_hostname
+
+ cur_alias = str(clu_info[1]).strip().lower()
+ if not cur_alias:
+ cur_alias = None
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA9: no cluster alias for %s' \
+ % ricci_hostname)
+
+ if (cur_name is not None and cluname != cur_name) and (cur_alias is not None and cluname != cur_alias):
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('GRA10: node %s reports it\'s in cluster [%s:%s] we expect %s' % (ricci_hostname, clu_info[0], clu_info[1], cluname))
+ setNodeStatus(self, node, CLUSTER_NODE_NOT_MEMBER)
+ continue
+
+ if not rc.authed():
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA11: %s is not authenticated' \
+ % ricci_hostname)
+ setNodeStatus(node[1], CLUSTER_NODE_NEED_AUTH)
+ continue
+ except Exception, eout:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA12: %r %s' % (eout, str(eout)))
+ continue
+
+ if exclude_busy is True:
+ if NodeBusy(self, cluname, ricci_hostname, rc) is not False:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRA13: %s is busy, excluding' \
+ % ricci_hostname)
+ continue
+ return rc
+
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug('GRA14: no ricci agent could be found for cluster %s' \
+ % cluname)
+ return None
+
+def getClusterDBObj(self, clustername):
+ try:
+ cluster_path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ nodelist = self.restrictedTraverse(cluster_path)
+ if not nodelist:
+ raise Exception, 'no nodelist'
+ return nodelist
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCDB0: %s -> %s: %r %s' \
+ % (clustername, cluster_path, e, str(e)))
+ return None
+
+def getClusterDBNodes(self, clustername):
+ try:
+ cluster_path = str('%s%s' % (CLUSTER_FOLDER_PATH, clustername))
+ nodelist = self.restrictedTraverse(cluster_path).objectItems('Folder')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCDBN0: %s -> %s: %r %s' \
+ % (clustername, cluster_path, e, str(e)))
+ return []
+ return nodelist
+
+def getClusterDBVersion(cluster_folder):
+ try:
+ cluster_os = str(cluster_folder.getProperty('cluster_os'))
+ if not cluster_os:
+ raise Exception, 'cluster os is blank'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCDBV0: %s: %r %s' \
+ % (cluster_folder.getId(), e, str(e)))
+ cluster_os = None
+ return cluster_os
+
+def setClusterDBVersion(cluster_folder, version_str):
+ if cluster_folder.getProperty('cluster_os') is None:
+ try:
+ cluster_folder.manage_addProperty('cluster_os',
+ version_str, 'string')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('SCDBV0: %s: %r %s' \
+ % (cluster_folder.getId(), e, str(e)))
+ return None
+ else:
+ try:
+ cluster_folder.manage_changeProperties({'cluster_os': version_str })
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('SCDBV1: %s: %r %s' \
+ % (cluster_folder.getId(), e, str(e)))
+ return None
+ return True
+
+def getClusterFlags(self, cluname):
+ try:
+ path = str('%s%s' % (CLUSTER_FOLDER_PATH, cluname))
+ clusterfolder = self.restrictedTraverse(path)
+ if not clusterfolder:
+ raise Exception, 'clusterfolder is None'
+ return clusterfolder.objectItems('ManagedSystem')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCF0: cluster %s [%s] folder missing: %r %s -- returning empty map' % (cluname, path, e, str(e)))
+ return None
+
+def getClusterStatusDB(self, clustername):
+ results = list()
+ vals = {}
+
+ vals['type'] = 'cluster'
+ vals['alias'] = clustername
+ vals['name'] = clustername
+ vals['error'] = True
+ vals['quorate'] = '[unknown]'
+ vals['votes'] = '[unknown]'
+ vals['minQuorum'] = '[unknown]'
+ results.append(vals)
+
+ nodelist = getClusterDBNodes(self, clustername)
+ if len(nodelist) < 1:
+ luci_log.info('Removing cluster %s because it has no nodes' \
+ % clustername)
+ try:
+ clusters_dir = self.restrictedTraverse(CLUSTER_FOLDER_PATH)
+ clusters_dir.manage_delObjects([clustername])
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSDB0b: %s: %r %s' \
+ % (clustername, e, str(e)))
+ return results
+
+ for node in nodelist:
+ node_val = {}
+ node_val['type'] = 'node'
+ node_val['name'] = node[0]
+ node_val['clustered'] = '[unknown]'
+ node_val['online'] = '[unknown]'
+ node_val['error'] = True
+ results.append(node_val)
+ return results
/cvs/cluster/conga/luci/site/luci/Extensions/LuciZope.py,v --> standard output
revision 1.4.2.1
--- conga/luci/site/luci/Extensions/LuciZope.py
+++ - 2007-08-09 21:35:22.887659000 +0000
@@ -0,0 +1,147 @@
+# Copyright (C) 2006-2007 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 LuciZopePerm import userAuthenticated
+from LuciDB import allowed_systems
+from LuciSyslog import get_logger
+from conga_constants import LUCI_DEBUG_MODE
+
+luci_log = get_logger()
+
+def siteIsSetup(self):
+ import os
+ from ricci_communicator import CERTS_DIR_PATH
+
+ try:
+ return os.path.isfile('%sprivkey.pem' % CERTS_DIR_PATH) and os.path.isfile('%scacert.pem' % CERTS_DIR_PATH)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('SIS0: %r %s' % (e, str(e)))
+ return False
+
+def strFilter(regex, replaceChar, arg):
+ import re
+ return re.sub(regex, replaceChar, arg)
+
+# removes systems that user is not authorized access to
+def get_systems_statuses(self, systems, from_cache=False):
+ from HelperFunctions import get_system_info
+
+ CACHED_INDEX = '_get_systems_statuses()_cached_result_'
+ session = self.REQUEST.SESSION
+ if session.has_key(CACHED_INDEX):
+ res = session[CACHED_INDEX]
+ if res is not None:
+ session.set(CACHED_INDEX, None)
+ if from_cache:
+ return res
+
+ allowed_sys_list = allowed_systems(self, systems)
+ ss_list = get_system_info(self, allowed_sys_list)
+ session.set(CACHED_INDEX, ss_list)
+ return ss_list
+
+def set_persistent_var(self, var_name, default_value):
+ request = self.REQUEST
+ response = request.RESPONSE
+ session = request.SESSION
+
+ # TODO: add username into cookie_prefix, so users don't overwrite each other
+ cookie_prefix = '__luci_storage_cookie_'
+
+ value = default_value
+ if request.has_key(var_name):
+ value = request[var_name]
+ elif session.has_key(var_name):
+ value = session[var_name]
+ elif request.cookies.has_key(cookie_prefix + var_name):
+ value = request.cookies[cookie_prefix + var_name]
+
+ session.set(var_name, value)
+ response.setCookie(cookie_prefix + var_name, value,
+ expires='Tue, 30 Jun 2060 12:00:00 GMT')
+ return value
+
+# returns (str(float), units) that fits best,
+# takes prefered units into account
+
+def bytes_to_value_prefunits(self, bytes):
+ from HelperFunctions import bytes_to_value_units, convert_bytes, get_units_multiplier
+
+ p_units = self.REQUEST.SESSION.get('preferred_size_units')
+ dummy, units = bytes_to_value_units(bytes)
+ if get_units_multiplier(units) > get_units_multiplier(p_units):
+ units = p_units
+ return (convert_bytes(bytes, units), units)
+
+def getTabs(self, req):
+ if not userAuthenticated(self):
+ return []
+
+ htab = {
+ 'Title': 'homebase',
+ 'Description': 'Home base for this luci server',
+ 'Taburl': '/luci/homebase',
+ 'isSelected': False
+ }
+ ctab = {
+ 'Title': 'cluster',
+ 'Description': 'Cluster configuration area',
+ 'Taburl': '/luci/cluster/index_html?pagetype=3',
+ 'isSelected': False
+ }
+ stab = {
+ 'Title': 'storage',
+ 'Description': 'Storage configuration page',
+ 'Taburl': '/luci/storage',
+ 'isSelected': False
+ }
+
+ try:
+ baseurl = req['URL']
+ if baseurl.find('cluster') > (-1):
+ ctab['isSelected'] = True
+ elif baseurl.find('storage') > (-1):
+ stab['isSelected'] = True
+ else:
+ htab['isSelected'] = True
+ except KeyError, e:
+ pass
+ except Exception, e:
+ htab['isSelected'] = True
+
+ return [ htab, ctab, stab ]
+
+def appendModel(request, model):
+ try:
+ request.SESSION.set('model', model)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('Appending model to request failed: %r %s' \
+ % (e, str(e)))
+
+def GetReqVars(req, varlist):
+ ret = {}
+ from types import ListType;
+
+ for i in varlist:
+ pval = None
+ if req and req.has_key(i):
+ pval = req[i]
+ if type(req[i]) is not ListType:
+ pval = req[i].strip()
+ if not pval:
+ pval = None
+ if req and pval is None:
+ if req.form and req.form.has_key(i):
+ pval = req.form[i]
+ if type(req.form[i]) is not ListType:
+ pval.strip()
+ if not pval:
+ pval = None
+ ret[i] = pval
+ return ret
/cvs/cluster/conga/luci/site/luci/Extensions/LuciZopeAsync.py,v --> standard output
revision 1.1.4.1
--- conga/luci/site/luci/Extensions/LuciZopeAsync.py
+++ - 2007-08-09 21:35:23.007073000 +0000
@@ -0,0 +1,182 @@
+# Copyright (C) 2007 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 xml.dom import minidom
+
+from LuciSyslog import get_logger
+from LuciZope import GetReqVars
+from ricci_communicator import RicciCommunicator
+from conga_constants import LUCI_DEBUG_MODE
+
+luci_log = get_logger()
+
+def write_xml_resp(request, xml_obj):
+ request.RESPONSE.setHeader('Content-Type', 'text/xml; charset=UTF-8')
+ request.RESPONSE.setHeader('Cache-Control', 'no-cache, no-store, private')
+ request.RESPONSE.write(str(xml_obj.toprettyxml()))
+
+def result_to_xml(result):
+ import types
+
+ numeric_types = [
+ types.IntType, types.BooleanType, types.LongType, types.FloatType
+ ]
+
+ root = minidom.Document()
+
+ def pyobj_to_xml(element_name, element, parent_node):
+ if type(element) is types.DictType:
+ if len(element) > 0:
+ xml_elem = root.createElement('dict')
+ xml_elem.setAttribute('name', str(element_name))
+
+ for i in element.iterkeys():
+ pyobj_to_xml(i, element[i], xml_elem)
+ else:
+ xml_elem = None
+ elif type(element) in [ types.ListType, types.TupleType ]:
+ if len(element) > 0:
+ xml_elem = root.createElement('list')
+ xml_elem.setAttribute('name', str(element_name))
+ for i in element:
+ pyobj_to_xml(element_name, i, xml_elem)
+ else:
+ xml_elem = None
+ else:
+ cur_tagname = None
+ try:
+ if parent_node.tagName == 'list':
+ cur_tagname = parent_node.getAttribute('name')
+ except:
+ cur_tagname = None
+
+ if not cur_tagname:
+ xml_elem = root.createElement('var')
+ else:
+ xml_elem = root.createElement(cur_tagname)
+
+ if type(element) in types.StringTypes:
+ cur_type = 'str'
+ elif type(element) in numeric_types:
+ cur_type = 'num'
+ else:
+ cur_type = None
+
+ if cur_type:
+ try:
+ if parent_node.tagName == 'dict':
+ xml_elem.setAttribute('name', str(element_name))
+ except:
+ pass
+
+ xml_elem.setAttribute('type', cur_type)
+ xml_elem.setAttribute('value', str(element))
+ else:
+ xml_elem = None
+
+ if xml_elem is not None:
+ parent_node.appendChild(xml_elem)
+
+ pyobj_to_xml('result', result[1], root)
+ res_elem = root.createElement('result')
+ res_elem.setAttribute('name', 'success')
+ res_elem.setAttribute('value', str(result[0]).lower())
+ root.firstChild.appendChild(res_elem)
+ return root
+
+def write_err_async(request, err_msg):
+ xml_obj = result_to_xml((False, { 'errors': err_msg }))
+ write_xml_resp(request, xml_obj)
+
+def get_cluster_nodes_async(self, request):
+ from LuciClusterInfo import getClusterConfNodes
+ from RicciQueries import getClusterConf
+
+ fvars = GetReqVars(request, [ 'QUERY_STRING' ])
+ if fvars['QUERY_STRING'] is None:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCNA: No query string was given')
+ write_err_async(request, 'No node names were given')
+ return None
+
+ try:
+ nodes = fvars['QUERY_STRING'].split('&')
+ node_list = map(lambda x: x[1], filter(lambda x: x[0][:4] == 'node', map(lambda x: x.split('='), nodes)))
+ if not node_list or len(node_list) < 1:
+ raise Exception, 'No node list'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCNA: %r %s' % (e, str(e)))
+ write_err_async(request, 'No node names were given')
+ return None
+
+ errors = list()
+ ret = {}
+ for node_host in node_list:
+ try:
+ rc = RicciCommunicator(node_host)
+ cluster_name = rc.cluster_info()[0]
+ if not cluster_name:
+ errors.append('%s is not a member of a cluster' \
+ % cluster_name)
+ continue
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCNA0: ricci: %s: %r %s' \
+ % (node_host, e, str(e)))
+ errors.append('Unable to communicate with the ricci agent on %s' \
+ % node_host)
+ continue
+
+ try:
+ conf = getClusterConf(rc)
+ node_names = getClusterConfNodes(conf)
+ if not node_names or len(node_names) < 1:
+ raise Exception, 'no nodes'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCNA1: ricci: %s: %r %s' \
+ % (node_host, e, str(e)))
+ errors.append('Unable to retrieve a list of cluster nodes from %s' \
+ % node_host)
+ continue
+ ret[cluster_name] = {
+ 'cluster': cluster_name,
+ 'num_nodes': len(node_names),
+ 'clusternode': node_names
+ }
+
+ ret['errors'] = errors
+ xml_obj = result_to_xml((len(errors) < len(node_list), ret))
+ write_xml_resp(request, xml_obj)
+
+def get_sysinfo_async(self, request):
+ from HelperFunctions import get_system_info
+
+ fvars = GetReqVars(request, [ 'QUERY_STRING' ])
+ try:
+ nodes = fvars['QUERY_STRING'].split('&')
+ node_list = map(lambda x: x[1], filter(lambda x: x[0][:4] == 'node', map(lambda x: x.split('='), nodes)))
+ if not node_list or len(node_list) < 1:
+ raise Exception, 'No node list'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GSIA: %r %s' % (e, str(e)))
+ write_err_async(request, 'No node names were given')
+ return None
+
+ ret = {}
+ try:
+ ret = get_system_info(self, node_list)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GNFPA %r: %r %s' \
+ % (request['nodenames'], e, str(e)))
+ write_err_async(request, 'Error retrieving information')
+ return None
+ xml_obj = result_to_xml(True, { 'result': ret })
+ write_xml_resp(request, xml_obj)
/cvs/cluster/conga/luci/site/luci/Extensions/LuciZopeClusterPortal.py,v --> standard output
revision 1.2.2.1
--- conga/luci/site/luci/Extensions/LuciZopeClusterPortal.py
+++ - 2007-08-09 21:35:23.144029000 +0000
@@ -0,0 +1,551 @@
+# Copyright (C) 2006-2007 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 LuciZopePerm import havePermCreateCluster
+from conga_constants import CLUNAME, CLUSTER, \
+ CLUSTER_ADD, CLUSTER_CONFIG, CLUSTERLIST, CLUSTERS, \
+ FDOM, FDOM_ADD, FDOM_CONFIG, FDOMS, \
+ FENCEDEV, FENCEDEV_ADD, FENCEDEV_CONFIG, FENCEDEVS, \
+ NODE, NODE_ADD, NODE_CONFIG, NODE_GRID, NODE_LIST, NODES, PAGETYPE, \
+ RESOURCE, RESOURCE_ADD, RESOURCE_CONFIG, RESOURCES, \
+ SERVICE, SERVICE_ADD, SERVICE_CONFIG, SERVICE_LIST, SERVICES, \
+ VM_ADD, VM_CONFIG
+
+# Policy for showing the cluster chooser menu:
+# 1) If there are no clusters in the ManagedClusterSystems
+# folder, then only the admin user may see this menu, and
+# the configure option should not be displayed.
+# 2)If there are clusters in the ManagedClusterSystems,
+# then only display chooser if the current user has
+# permissions on at least one. If the user is admin, show ALL clusters
+
+def createCluChooser(self, request, systems):
+ from cluster_adapters import validatePost
+ dummynode = {}
+
+ if request.REQUEST_METHOD == 'POST':
+ ret = validatePost(self, request)
+ try:
+ request.SESSION.set('checkRet', ret[1])
+ except:
+ request.SESSION.set('checkRet', {})
+ else:
+ try:
+ request.SESSION.set('checkRet', {})
+ except:
+ pass
+
+ # First, see if a cluster is chosen, then
+ # check that the current user can access that system
+ cname = None
+ try:
+ cname = request[CLUNAME]
+ except:
+ cname = ''
+
+ try:
+ url = request['URL']
+ except:
+ url = '/luci/cluster/index_html'
+
+ try:
+ pagetype = request[PAGETYPE]
+ except:
+ pagetype = '3'
+
+ cldata = {}
+ cldata['Title'] = 'Cluster List'
+ cldata['cfg_type'] = 'clusters'
+ cldata['absolute_url'] = '%s?pagetype=%s' % (url, CLUSTERLIST)
+ cldata['Description'] = 'Clusters available for configuration'
+ if pagetype == CLUSTERLIST:
+ cldata['currentItem'] = True
+ else:
+ cldata['currentItem'] = False
+
+ UserHasPerms = havePermCreateCluster(self)
+ if UserHasPerms:
+ cladd = {}
+ cladd['Title'] = 'Create a New Cluster'
+ cladd['cfg_type'] = 'clusteradd'
+ cladd['absolute_url'] = '%s?pagetype=%s' % (url, CLUSTER_ADD)
+ cladd['Description'] = 'Create a Cluster'
+ if pagetype == CLUSTER_ADD:
+ cladd['currentItem'] = True
+ else:
+ cladd['currentItem'] = False
+
+ clcfg = {}
+ clcfg['Title'] = 'Configure'
+ clcfg['cfg_type'] = 'clustercfg'
+ clcfg['absolute_url'] = '%s?pagetype=%s' % (url, CLUSTERS)
+ clcfg['Description'] = 'Configure a cluster'
+ if pagetype == CLUSTERS:
+ clcfg['currentItem'] = True
+ else:
+ clcfg['currentItem'] = False
+
+ #test...
+ #clcfg['show_children'] = True
+ #Add all cluster type pages here:
+ if pagetype == CLUSTER or pagetype == CLUSTER_CONFIG:
+ clcfg['show_children'] = True
+ else:
+ clcfg['show_children'] = False
+
+ #loop through all clusters
+ syslist = list()
+ for system in systems:
+ clsys = {}
+ clsys['Title'] = system[0]
+ clsys['cfg_type'] = 'cluster'
+ clsys['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, CLUSTER, system[0])
+ clsys['Description'] = 'Configure this cluster'
+
+ if pagetype == CLUSTER or pagetype == CLUSTER_CONFIG:
+ if cname == system[0]:
+ clsys['currentItem'] = True
+ else:
+ clsys['currentItem'] = False
+ else:
+ clsys['currentItem'] = False
+ syslist.append(clsys)
+
+ clcfg['children'] = syslist
+
+ mylist = list()
+ mylist.append(cldata)
+ if UserHasPerms:
+ mylist.append(cladd)
+ mylist.append(clcfg)
+ dummynode['children'] = mylist
+
+ return dummynode
+
+def createCluConfigTree(self, request, model):
+ dummynode = {}
+
+ if not model:
+ return {}
+
+ # There should be a positive page type
+ try:
+ pagetype = request[PAGETYPE]
+ except:
+ pagetype = '3'
+
+ try:
+ url = request['URL']
+ except:
+ url = '/luci/cluster/index_html'
+
+ # The only way this method can run is if there exists
+ # a clustername query var
+ cluname = request['clustername']
+
+ nd = {}
+ nd['Title'] = 'Nodes'
+ nd['cfg_type'] = 'nodes'
+ nd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, NODES, cluname)
+ nd['Description'] = 'Node configuration for this cluster'
+ if pagetype == NODES or pagetype == NODE_GRID or pagetype == NODE_LIST or pagetype == NODE_CONFIG or pagetype == NODE_ADD or pagetype == NODE:
+ nd['show_children'] = True
+ else:
+ nd['show_children'] = False
+ if pagetype == '0':
+ nd['show_children'] = False
+
+ if pagetype == NODES:
+ nd['currentItem'] = True
+ else:
+ nd['currentItem'] = False
+
+
+ ndadd = {}
+ ndadd['Title'] = 'Add a Node'
+ ndadd['cfg_type'] = 'nodeadd'
+ ndadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, NODE_ADD, cluname)
+ ndadd['Description'] = 'Add a node to this cluster'
+ if pagetype == NODE_ADD:
+ ndadd['currentItem'] = True
+ else:
+ ndadd['currentItem'] = False
+
+ ndcfg = {}
+ ndcfg['Title'] = 'Configure'
+ ndcfg['cfg_type'] = 'nodecfg'
+ ndcfg['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, NODE_CONFIG, cluname)
+ ndcfg['Description'] = 'Configure cluster nodes'
+ if pagetype == NODE_CONFIG or pagetype == NODE or pagetype == NODES or pagetype == NODE_LIST or pagetype == NODE_GRID or pagetype == NODE_ADD:
+ ndcfg['show_children'] = True
+ else:
+ ndcfg['show_children'] = False
+ if pagetype == NODE_CONFIG:
+ ndcfg['currentItem'] = True
+ else:
+ ndcfg['currentItem'] = False
+
+ nodes = model.getNodes()
+ nodenames = list()
+ for node in nodes:
+ nodenames.append(node.getName())
+
+ cfgablenodes = list()
+ for nodename in nodenames:
+ cfg = {}
+ cfg['Title'] = nodename
+ cfg['cfg_type'] = 'node'
+ cfg['absolute_url'] = '%s?pagetype=%s&nodename=%s&clustername=%s' % (url, NODE, nodename, cluname)
+ cfg['Description'] = 'Configure this cluster node'
+ if pagetype == NODE:
+ try:
+ nname = request['nodename']
+ except KeyError, e:
+ nname = ''
+ if nodename == nname:
+ cfg['currentItem'] = True
+ else:
+ cfg['currentItem'] = False
+ else:
+ cfg['currentItem'] = False
+
+ cfgablenodes.append(cfg)
+
+ #Now add nodename structs as children of the config element
+ ndcfg['children'] = cfgablenodes
+
+ ndkids = list()
+ ndkids.append(ndadd)
+ ndkids.append(ndcfg)
+
+ nd['children'] = ndkids
+
+ ##################################################################
+ sv = {}
+ sv['Title'] = 'Services'
+ sv['cfg_type'] = 'services'
+ sv['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, SERVICES, cluname)
+ sv['Description'] = 'Service configuration for this cluster'
+ if pagetype == SERVICES or pagetype == SERVICE_CONFIG or pagetype == SERVICE_ADD or pagetype == SERVICE or pagetype == SERVICE_LIST or pagetype == VM_ADD or pagetype == VM_CONFIG:
+ sv['show_children'] = True
+ else:
+ sv['show_children'] = False
+ if pagetype == SERVICES or pagetype == SERVICE_LIST:
+ sv['currentItem'] = True
+ else:
+ sv['currentItem'] = False
+
+ svadd = {}
+ svadd['Title'] = 'Add a Service'
+ svadd['cfg_type'] = 'serviceadd'
+ svadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, SERVICE_ADD, cluname)
+ svadd['Description'] = 'Add a Service to this cluster'
+ if pagetype == SERVICE_ADD:
+ svadd['currentItem'] = True
+ else:
+ svadd['currentItem'] = False
+
+ if model.getIsVirtualized() is True:
+ vmadd = {}
+ vmadd['Title'] = 'Add a Virtual Service'
+ vmadd['cfg_type'] = 'vmadd'
+ vmadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, VM_ADD, cluname)
+ vmadd['Description'] = 'Add a Virtual Service to this cluster'
+ if pagetype == VM_ADD:
+ vmadd['currentItem'] = True
+ else:
+ vmadd['currentItem'] = False
+
+ svcfg = {}
+ svcfg['Title'] = 'Configure a Service'
+ svcfg['cfg_type'] = 'servicecfg'
+ svcfg['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, SERVICE_CONFIG, cluname)
+ svcfg['Description'] = 'Configure a Service for this cluster'
+ if pagetype == SERVICE_CONFIG or pagetype == SERVICE or pagetype == VM_CONFIG:
+ svcfg['show_children'] = True
+ else:
+ svcfg['show_children'] = False
+ if pagetype == SERVICE_CONFIG or pagetype == VM_CONFIG:
+ svcfg['currentItem'] = True
+ else:
+ svcfg['currentItem'] = False
+
+ services = model.getServices()
+ serviceable = list()
+
+ for service in services:
+ servicename = service.getName()
+ svc = {}
+ svc['Title'] = servicename
+ svc['cfg_type'] = 'service'
+ svc['absolute_url'] = '%s?pagetype=%s&servicename=%s&clustername=%s' % (url, SERVICE, servicename, cluname)
+ svc['Description'] = 'Configure this service'
+ if pagetype == SERVICE:
+ try:
+ sname = request['servicename']
+ except KeyError, e:
+ sname = ''
+ if servicename == sname:
+ svc['currentItem'] = True
+ else:
+ svc['currentItem'] = False
+ else:
+ svc['currentItem'] = False
+
+ serviceable.append(svc)
+
+ vms = model.getVMs()
+ for vm in vms:
+ name = vm.getName()
+ svc = {}
+ svc['Title'] = name
+ svc['cfg_type'] = 'vm'
+ svc['absolute_url'] = '%s?pagetype=%s&servicename=%s&clustername=%s' % (url, VM_CONFIG, name, cluname)
+ svc['Description'] = 'Configure this Virtual Service'
+ if pagetype == VM_CONFIG:
+ try:
+ xname = request['servicename']
+ except KeyError, e:
+ xname = ''
+ if name == xname:
+ svc['currentItem'] = True
+ else:
+ svc['currentItem'] = False
+ else:
+ svc['currentItem'] = False
+
+ serviceable.append(svc)
+
+ svcfg['children'] = serviceable
+
+
+
+ kids = list()
+ kids.append(svadd)
+ if model.getIsVirtualized() is True:
+ kids.append(vmadd)
+ kids.append(svcfg)
+ sv['children'] = kids
+#############################################################
+ rv = {}
+ rv['Title'] = 'Resources'
+ rv['cfg_type'] = 'resources'
+ rv['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, RESOURCES, cluname)
+ rv['Description'] = 'Resource configuration for this cluster'
+ if pagetype == RESOURCES or pagetype == RESOURCE_CONFIG or pagetype == RESOURCE_ADD or pagetype == RESOURCE:
+ rv['show_children'] = True
+ else:
+ rv['show_children'] = False
+ if pagetype == RESOURCES:
+ rv['currentItem'] = True
+ else:
+ rv['currentItem'] = False
+
+ rvadd = {}
+ rvadd['Title'] = 'Add a Resource'
+ rvadd['cfg_type'] = 'resourceadd'
+ rvadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, RESOURCE_ADD, cluname)
+ rvadd['Description'] = 'Add a Resource to this cluster'
+ if pagetype == RESOURCE_ADD:
+ rvadd['currentItem'] = True
+ else:
+ rvadd['currentItem'] = False
+
+ rvcfg = {}
+ rvcfg['Title'] = 'Configure a Resource'
+ rvcfg['cfg_type'] = 'resourcecfg'
+ rvcfg['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, RESOURCE_CONFIG, cluname)
+ rvcfg['Description'] = 'Configure a Resource for this cluster'
+ if pagetype == RESOURCE_CONFIG or pagetype == RESOURCE:
+ rvcfg['show_children'] = True
+ else:
+ rvcfg['show_children'] = False
+ if pagetype == RESOURCE_CONFIG:
+ rvcfg['currentItem'] = True
+ else:
+ rvcfg['currentItem'] = False
+
+ resources = model.getResources()
+ resourceable = list()
+ for resource in resources:
+ resourcename = resource.getName()
+ rvc = {}
+ rvc['Title'] = resourcename
+ rvc['cfg_type'] = 'resource'
+ rvc['absolute_url'] = '%s?pagetype=%s&resourcename=%s&clustername=%s' % (url, RESOURCES, resourcename, cluname)
+ rvc['Description'] = 'Configure this resource'
+ if pagetype == RESOURCE:
+ try:
+ rname = request['resourcename']
+ except KeyError, e:
+ rname = ''
+ if resourcename == rname:
+ rvc['currentItem'] = True
+ else:
+ rvc['currentItem'] = False
+ else:
+ rvc['currentItem'] = False
+
+ resourceable.append(rvc)
+ rvcfg['children'] = resourceable
+
+
+
+ kids = list()
+ kids.append(rvadd)
+ kids.append(rvcfg)
+ rv['children'] = kids
+ ################################################################
+ fd = {}
+ fd['Title'] = 'Failover Domains'
+ fd['cfg_type'] = 'failoverdomains'
+ fd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, FDOMS, cluname)
+ fd['Description'] = 'Failover domain configuration for this cluster'
+ if pagetype == FDOMS or pagetype == FDOM_CONFIG or pagetype == FDOM_ADD or pagetype == FDOM:
+ fd['show_children'] = True
+ else:
+ fd['show_children'] = False
+ if pagetype == FDOMS:
+ fd['currentItem'] = True
+ else:
+ fd['currentItem'] = False
+
+ fdadd = {}
+ fdadd['Title'] = 'Add a Failover Domain'
+ fdadd['cfg_type'] = 'failoverdomainadd'
+ fdadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, FDOM_ADD, cluname)
+ fdadd['Description'] = 'Add a Failover Domain to this cluster'
+ if pagetype == FDOM_ADD:
+ fdadd['currentItem'] = True
+ else:
+ fdadd['currentItem'] = False
+
+ fdcfg = {}
+ fdcfg['Title'] = 'Configure a Failover Domain'
+ fdcfg['cfg_type'] = 'failoverdomaincfg'
+ fdcfg['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, FDOM_CONFIG, cluname)
+ fdcfg['Description'] = 'Configure a Failover Domain for this cluster'
+ if pagetype == FDOM_CONFIG or pagetype == FDOM:
+ fdcfg['show_children'] = True
+ else:
+ fdcfg['show_children'] = False
+ if pagetype == FDOM_CONFIG:
+ fdcfg['currentItem'] = True
+ else:
+ fdcfg['currentItem'] = False
+
+ fdoms = model.getFailoverDomains()
+ fdomable = list()
+ for fdom in fdoms:
+ fdomname = fdom.getName()
+ fdc = {}
+ fdc['Title'] = fdomname
+ fdc['cfg_type'] = 'fdom'
+ fdc['absolute_url'] = '%s?pagetype=%s&fdomname=%s&clustername=%s' % (url, FDOM, fdomname, cluname)
+ fdc['Description'] = 'Configure this Failover Domain'
+ if pagetype == FDOM:
+ try:
+ fname = request['fdomname']
+ except KeyError, e:
+ fname = ''
+ if fdomname == fname:
+ fdc['currentItem'] = True
+ else:
+ fdc['currentItem'] = False
+ else:
+ fdc['currentItem'] = False
+
+ fdomable.append(fdc)
+ fdcfg['children'] = fdomable
+
+
+
+ kids = list()
+ kids.append(fdadd)
+ kids.append(fdcfg)
+ fd['children'] = kids
+#############################################################
+ fen = {}
+ fen['Title'] = 'Shared Fence Devices'
+ fen['cfg_type'] = 'fencedevicess'
+ fen['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, FENCEDEVS, cluname)
+ fen['Description'] = 'Fence Device configuration for this cluster'
+ if pagetype == FENCEDEVS or pagetype == FENCEDEV_CONFIG or pagetype == FENCEDEV_ADD or pagetype == FENCEDEV:
+ fen['show_children'] = True
+ else:
+ fen['show_children'] = False
+ if pagetype == FENCEDEVS:
+ fen['currentItem'] = True
+ else:
+ fen['currentItem'] = False
+
+ fenadd = {}
+ fenadd['Title'] = 'Add a Fence Device'
+ fenadd['cfg_type'] = 'fencedeviceadd'
+ fenadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, FENCEDEV_ADD, cluname)
+ fenadd['Description'] = 'Add a Fence Device to this cluster'
+ if pagetype == FENCEDEV_ADD:
+ fenadd['currentItem'] = True
+ else:
+ fenadd['currentItem'] = False
+
+ fencfg = {}
+ fencfg['Title'] = 'Configure a Fence Device'
+ fencfg['cfg_type'] = 'fencedevicecfg'
+ fencfg['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, FENCEDEV_CONFIG, cluname)
+ fencfg['Description'] = 'Configure a Fence Device for this cluster'
+ if pagetype == FENCEDEV_CONFIG or pagetype == FENCEDEV:
+ fencfg['show_children'] = True
+ else:
+ fencfg['show_children'] = False
+ if pagetype == FENCEDEV_CONFIG:
+ fencfg['currentItem'] = True
+ else:
+ fencfg['currentItem'] = False
+
+ fences = model.getFenceDevices()
+ fenceable = list()
+ for fence in fences:
+ fencename = fence.getName()
+ fenc = {}
+ fenc['Title'] = fencename
+ fenc['cfg_type'] = 'fencedevice'
+ fenc['absolute_url'] = '%s?pagetype=%s&fencename=%s&clustername=%s' % (url, FENCEDEV, fencename, cluname)
+ fenc['Description'] = 'Configure this Fence Device'
+ if pagetype == FENCEDEV:
+ try:
+ fenname = request['fencename']
+ except KeyError, e:
+ fenname = ''
+ if fencename == fenname:
+ fenc['currentItem'] = True
+ else:
+ fenc['currentItem'] = False
+ else:
+ fenc['currentItem'] = False
+
+ fenceable.append(fenc)
+ fencfg['children'] = fenceable
+
+
+
+ kids = list()
+ kids.append(fenadd)
+ kids.append(fencfg)
+ fen['children'] = kids
+#############################################################
+
+ mylist = list()
+ mylist.append(nd)
+ mylist.append(sv)
+ mylist.append(rv)
+ mylist.append(fd)
+ mylist.append(fen)
+
+ dummynode['children'] = mylist
+
+ return dummynode
/cvs/cluster/conga/luci/site/luci/Extensions/LuciZopeExternal.py,v --> standard output
revision 1.3.2.1
--- conga/luci/site/luci/Extensions/LuciZopeExternal.py
+++ - 2007-08-09 21:35:23.301305000 +0000
@@ -0,0 +1,53 @@
+# Copyright (C) 2007 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.
+
+#
+# The only purpose of this file is to aggregate all the functions
+# called by Zope External Methods.
+#
+
+from homebase_adapters import getUserPerms, homebaseControl, \
+ getDefaultUser
+
+from cluster_adapters import clusterTaskProcess, \
+ resourceAdd, resourceDelete, serviceDelete, \
+ getClusterURL, getSystemLogs, getRicciAgentForCluster, \
+ isClusterBusy, nodeTaskProcess, process_cluster_conf_editor, \
+ serviceMigrate, serviceRestart, serviceStart, serviceStop, \
+ getResourceInfo
+
+from HelperFunctions import add_commas, bytes_to_value_units, convert_bytes
+
+from LuciClusterInfo import getClusterAlias, getClusterInfo, getClusterName, \
+ getClustersInfo, getClusterStatus, getFdomInfo, get_fdom_names, \
+ getFdomsInfo, getFence, getFenceInfo, getFencesInfo, getModelBuilder, \
+ getNodeInfo, getnodes, getNodesInfo, getResourcesInfo, \
+ getServiceInfo, getServicesInfo, getVMInfo, getClusterOS
+
+from LuciDB import access_to_host_allowed, allowed_systems, \
+ check_clusters, getRicciAgent, getSystems, getClusters, \
+ getStorage
+
+from LuciZope import appendModel, bytes_to_value_prefunits, \
+ set_persistent_var, strFilter, getTabs, siteIsSetup
+
+from LuciZopeClusterPortal import createCluChooser, createCluConfigTree
+
+from LuciZopePerm import isAdmin, userAuthenticated
+
+from ricci_communicator import get_ricci_communicator
+
+from storage_adapters import createStorageChooser, \
+ createStorageConfigTree, getStorageURL
+
+from StorageReport import apply_storage_changes, cache_storage_report, \
+ get_bd_data, get_mapper_data, get_mappers_data, get_mapper_template_data, \
+ get_mappings_info, get_storage_batch_result, get_storage_report, \
+ group_systems_by_cluster, is_storage_report_cached, validate, \
+ get_content_data
+
+from LuciZopeAsync import get_cluster_nodes_async, get_sysinfo_async
/cvs/cluster/conga/luci/site/luci/Extensions/LuciZopePerm.py,v --> standard output
revision 1.2.2.1
--- conga/luci/site/luci/Extensions/LuciZopePerm.py
+++ - 2007-08-09 21:35:23.488645000 +0000
@@ -0,0 +1,50 @@
+# Copyright (C) 2006-2007 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 AccessControl import getSecurityManager
+from conga_constants import PLONE_ROOT
+
+def userAuthenticated(self):
+ try:
+ if (isAdmin(self) or getSecurityManager().getUser().has_role('Authenticated', self.restrictedTraverse(PLONE_ROOT))):
+ return True
+ except Exception, e:
+ pass
+ return False
+
+def isAdmin(self):
+ try:
+ return getSecurityManager().getUser().has_role('Owner', self.restrictedTraverse(PLONE_ROOT))
+ except Exception, e:
+ pass
+ return False
+
+# In case we want to give access to non-admin users in the future
+
+def havePermCreateCluster(self):
+ return isAdmin(self)
+
+def havePermAddStorage(self):
+ return isAdmin(self)
+
+def havePermAddCluster(self):
+ return isAdmin(self)
+
+def havePermAddUser(self):
+ return isAdmin(self)
+
+def havePermDelUser(self):
+ return isAdmin(self)
+
+def havePermRemStorage(self):
+ return isAdmin(self)
+
+def havePermRemCluster(self):
+ return isAdmin(self)
+
+def havePermEditPerms(self):
+ return isAdmin(self)
/cvs/cluster/conga/luci/site/luci/Extensions/ResourceHandler.py,v --> standard output
revision 1.2.2.1
--- conga/luci/site/luci/Extensions/ResourceHandler.py
+++ - 2007-08-09 21:35:23.613137000 +0000
@@ -0,0 +1,793 @@
+# Copyright (C) 2006-2007 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 ClusterModel.Ip import Ip
+from ClusterModel.Fs import Fs
+from ClusterModel.Clusterfs import Clusterfs
+from ClusterModel.Netfs import Netfs
+from ClusterModel.NFSExport import NFSExport
+from ClusterModel.NFSClient import NFSClient
+from ClusterModel.Script import Script
+from ClusterModel.Samba import Samba
+from ClusterModel.Tomcat5 import Tomcat5
+from ClusterModel.Postgres8 import Postgres8
+from ClusterModel.Apache import Apache
+from ClusterModel.OpenLDAP import OpenLDAP
+from ClusterModel.LVM import LVM
+from ClusterModel.MySQL import MySQL
+from ClusterModel.SAPDatabase import SAPDatabase
+from ClusterModel.SAPInstance import SAPInstance
+from LuciSyslog import get_logger
+from conga_constants import LUCI_DEBUG_MODE
+
+luci_log = get_logger()
+
+def get_fsid_list(model):
+ obj_list = model.searchObjectTree('fs')
+ obj_list.extend(model.searchObjectTree('clusterfs'))
+ return map(lambda x: x.getAttribute('fsid') and int(x.getAttribute('fsid')) or 0, obj_list)
+
+def fsid_is_unique(model, fsid):
+ fsid_list = get_fsid_list(model)
+ return fsid not in fsid_list
+
+def generate_fsid(model, name):
+ import binascii
+ from random import random
+ fsid_list = get_fsid_list(model)
+
+ fsid = binascii.crc32(name) & 0xffff
+ dupe = fsid in fsid_list
+ while dupe is True:
+ fsid = (fsid + random.randrange(1, 0xfffe)) & 0xffff
+ dupe = fsid in fsid_list
+ return fsid
+
+def getResourceForEdit(model, name):
+ resPtr = model.getResourcesPtr()
+ resources = resPtr.getChildren()
+
+ for res in resources:
+ if res.getName() == name:
+ resPtr.removeChild(res)
+ return res
+
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GRFE0: unable to find resource "%s"' % name)
+ raise KeyError, name
+
+def addIp(res, rname, form, model):
+ errors = list()
+
+ try:
+ addr = form['ip_address'].strip()
+ if not addr:
+ raise KeyError, 'No IP address was given'
+ res.addAttribute('address', addr)
+ except KeyError, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addIp4: %s' % err)
+
+ if form.has_key('monitorLink'):
+ res.addAttribute('monitor_link', '1')
+ else:
+ res.addAttribute('monitor_link', '0')
+
+ return errors
+
+def addFs(res, rname, form, model):
+ errors = list()
+
+ try:
+ mountpoint = form['mountpoint'].strip()
+ if not mountpoint:
+ raise Exception, 'No mount point was given for "%s"' % rname
+ res.addAttribute('mountpoint', mountpoint)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addFs6: %s' % err)
+
+ try:
+ device = form['device'].strip()
+ if not device:
+ raise Exception, 'No device was given for "%s"' % rname
+ res.addAttribute('device', device)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addFs7: %s' % err)
+
+ try:
+ options = form['options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addFs8: %s' % err)
+
+ try:
+ fstype = form['fstype'].strip()
+ if not fstype:
+ raise Exception, 'No filesystem type was given for "%s"' % rname
+ res.addAttribute('fstype', fstype)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addFs9: %s' % err)
+
+ try:
+ fsid = form['fsid'].strip()
+ if not fsid:
+ raise Exception, 'no fsid'
+ fsid_int = int(fsid)
+ if not fsid_is_unique(model, fsid_int):
+ raise Exception, 'fsid not uniq'
+ except Exception, e:
+ fsid = str(generate_fsid(model, rname))
+ res.addAttribute('fsid', fsid)
+
+ if form.has_key('forceunmount'):
+ res.addAttribute('force_unmount', '1')
+ else:
+ res.addAttribute('force_unmount', '0')
+
+ if form.has_key('selffence'):
+ res.addAttribute('self_fence', '1')
+ else:
+ res.addAttribute('self_fence', '0')
+
+ if form.has_key('checkfs'):
+ res.addAttribute('force_fsck', '1')
+ else:
+ res.addAttribute('force_fsck', '0')
+
+ return errors
+
+def addClusterfs(res, rname, form, model):
+ errors = list()
+
+ try:
+ mountpoint = form['mountpoint'].strip()
+ if not mountpoint:
+ raise Exception, 'No mount point was given for "%s"' % rname
+ res.addAttribute('mountpoint', mountpoint)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addGfs5: %s' % err)
+
+ try:
+ device = form['device'].strip()
+ if not device:
+ raise Exception, 'No device was given for "%s"' % rname
+ res.addAttribute('device', device)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addGfs6: %s' % err)
+
+ try:
+ options = form['options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addGfs7: %s' % err)
+
+ try:
+ fsid = form['fsid'].strip()
+ if not fsid:
+ raise Exception, 'no fsid'
+ fsid_int = int(fsid)
+ if not fsid_is_unique(model, fsid_int):
+ raise Exception, 'not uniq'
+ except Exception, e:
+ fsid = str(generate_fsid(model, rname))
+ res.addAttribute('fsid', fsid)
+
+ if form.has_key('forceunmount'):
+ res.addAttribute('force_unmount', '1')
+ else:
+ res.addAttribute('force_unmount', '0')
+
+ return errors
+
+def addNetfs(res, rname, form, model):
+ errors = list()
+
+ try:
+ mountpoint = form['mountpoint'].strip()
+ if not mountpoint:
+ raise Exception, 'No mount point was given for "%s"' % rname
+ res.addAttribute('mountpoint', mountpoint)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsm5: %s' % err)
+
+ try:
+ host = form['host'].strip()
+ if not host:
+ raise Exception, 'No host server was given for "%s"' % rname
+ res.addAttribute('host', host)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsm6 error: %s' % err)
+
+ try:
+ options = form['options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsm7: %s' % err)
+
+ try:
+ exportpath = form['exportpath'].strip()
+ if not exportpath:
+ raise Exception, 'No export path was given for "%s"' % rname
+ res.addAttribute('exportpath', exportpath)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsm8: %s' % err)
+
+ try:
+ nfstype = form['nfstype'].strip().lower()
+ if nfstype != 'nfs' and nfstype != 'nfs4':
+ raise Exception, 'An invalid NFS version "%s" was given for "%s"' \
+ % (nfstype, rname)
+ res.addAttribute('nfstype', nfstype)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsm9: %s' % err)
+
+ if form.has_key('forceunmount'):
+ res.addAttribute('force_unmount', '1')
+ else:
+ res.addAttribute('force_unmount', '0')
+
+ return errors
+
+def addNFSClient(res, rname, form, model):
+ errors = list()
+
+ try:
+ target = form['target'].strip()
+ if not target:
+ raise Exception, 'No target was given for "%s"' % rname
+ res.addAttribute('target', target)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsc5: %s' % err)
+
+ try:
+ options = form['options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addNfsc6: %s' % err)
+
+ if form.has_key('allow_recover'):
+ res.addAttribute('allow_recover', '1')
+ else:
+ res.addAttribute('allow_recover', '0')
+
+ return errors
+
+def addNFSExport(res, rname, form, model):
+ errors = list()
+ return errors
+
+def addScript(res, rname, form, model):
+ errors = list()
+
+ try:
+ path = form['file'].strip()
+ if not path:
+ raise Exception, 'No path to a script file was given for this "%s"' % rname
+ res.addAttribute('file', path)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addScr5: %s' % err)
+
+ return errors
+
+def addSamba(res, rname, form, model):
+ errors = list()
+
+ try:
+ workgroup = form['workgroup'].strip()
+ if not workgroup:
+ raise Exception, 'No workgroup was given for "%s"' % rname
+ res.addAttribute('workgroup', workgroup)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addSmb5: %s' % err)
+
+ return errors
+
+def addApache(res, rname, form, model):
+ errors = list()
+
+ try:
+ server_root = form['server_root'].strip()
+ if not server_root:
+ raise KeyError, 'No server root was given for "%s"' % rname
+ res.addAttribute('server_root', server_root)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addApache5: %s' % err)
+
+ try:
+ config_file = form['config_file'].strip()
+ if not server_root:
+ raise KeyError, 'No path to the Apache configuration file was given for "%s"' % rname
+ res.addAttribute('config_file', config_file)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addApache6: %s' % err)
+
+ try:
+ options = form['httpd_options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('httpd_options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('httpd_options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addApache7: %s' % err)
+
+ try:
+ shutdown_wait = int(form['shutdown_wait'].strip())
+ res.addAttribute('shutdown_wait', str(shutdown_wait))
+ except KeyError, e:
+ res.addAttribute('shutdown_wait', '0')
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addApache7: %s' % err)
+
+ return errors
+
+def addMySQL(res, rname, form, model):
+ errors = list()
+
+ try:
+ config_file = form['config_file'].strip()
+ if not config_file:
+ raise KeyError, 'No path to the MySQL configuration file was given for "%s"' % rname
+ res.addAttribute('config_file', config_file)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addMySQL5: %s' % err)
+
+ try:
+ listen_addr = form['listen_address'].strip()
+ if not listen_addr:
+ raise KeyError, 'No address was given for "%s"' % rname
+ res.addAttribute('listen_address', listen_addr)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addMySQL6: %s' % err)
+
+ try:
+ options = form['mysql_options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('mysql_options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('mysql_options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addMySQL7: %s' % err)
+
+ try:
+ shutdown_wait = int(form['shutdown_wait'].strip())
+ res.addAttribute('shutdown_wait', str(shutdown_wait))
+ except KeyError, e:
+ res.addAttribute('shutdown_wait', '0')
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addMySQL7: %s' % err)
+
+ return errors
+
+def addOpenLDAP(res, rname, form, model):
+ errors = list()
+
+ try:
+ url_list = form['url_list'].strip()
+ if not url_list:
+ raise KeyError, 'No URL list was given for "%s"' % rname
+ res.addAttribute('url_list', url_list)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addOpenLDAP5: %s' % err)
+
+ try:
+ config_file = form['config_file'].strip()
+ if not config_file:
+ raise KeyError, 'No path to the OpenLDAP configuration file was given for "%s"' % rname
+ res.addAttribute('config_file', config_file)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addOpenLDAP6: %s' % err)
+
+ try:
+ options = form['slapd_options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('slapd_options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('slapd_options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addOpenLDAP7: %s' % err)
+
+ try:
+ shutdown_wait = int(form['shutdown_wait'].strip())
+ res.addAttribute('shutdown_wait', str(shutdown_wait))
+ except KeyError, e:
+ res.addAttribute('shutdown_wait', '0')
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addOpenLDAP7: %s' % err)
+
+ return errors
+
+def addPostgres8(res, rname, form, model):
+ errors = list()
+ try:
+ user = form['postmaster_user'].strip()
+ if not user:
+ raise KeyError, 'No postmaster user was given for "%s"' % rname
+ res.addAttribute('postmaster_user', user)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addPostgreSQL85: %s' % err)
+
+ try:
+ config_file = form['config_file'].strip()
+ if not config_file:
+ raise KeyError, 'No path to the PostgreSQL 8 configuration file was given for "%s"' % rname
+ res.addAttribute('config_file', config_file)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addPostgreSQL86: %s' % err)
+
+ try:
+ options = form['postmaster_options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('postmaster_options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('postmaster_options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addPostgreSQL87: %s' % err)
+
+ try:
+ shutdown_wait = int(form['shutdown_wait'].strip())
+ res.addAttribute('shutdown_wait', str(shutdown_wait))
+ except KeyError, e:
+ res.addAttribute('shutdown_wait', '0')
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addPostgreSQL87: %s' % err)
+
+ return errors
+
+def addTomcat5(res, rname, form, model):
+ errors = list()
+
+ try:
+ user = form['tomcat_user'].strip()
+ if not user:
+ raise KeyError, 'No Tomcat user was given for "%s"' % rname
+ res.addAttribute('tomcat_user', user)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addTomcat55: %s' % err)
+
+ try:
+ config_file = form['config_file'].strip()
+ if not config_file:
+ raise KeyError, 'No path to the Tomcat 5 configuration file was given for "%s"' % rname
+ res.addAttribute('config_file', config_file)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addTomcat56: %s' % err)
+
+ try:
+ options = form['catalina_options'].strip()
+ if not options:
+ raise KeyError, 'no options'
+ res.addAttribute('catalina_options', options)
+ except KeyError, e:
+ try:
+ res.removeAttribute('catalina_options')
+ except:
+ pass
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addTomcat57: %s' % err)
+
+ try:
+ catalina_base = form['catalina_base'].strip()
+ if not catalina_base:
+ raise KeyError, 'No cataliny base directory was given for "%s"' % rname
+ res.addAttribute('catalina_base', catalina_base)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addTomcat58: %s' % err)
+
+ try:
+ shutdown_wait = int(form['shutdown_wait'].strip())
+ res.addAttribute('shutdown_wait', str(shutdown_wait))
+ except KeyError, e:
+ res.addAttribute('shutdown_wait', '0')
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addTomcat59: %s' % err)
+
+ return errors
+
+def addLVM(res, rname, form, model):
+ errors = list()
+
+ try:
+ vg_name = form['vg_name'].strip()
+ if not vg_name:
+ raise KeyError, 'No volume group name was given for "%s"' % rname
+ res.addAttribute('vg_name', vg_name)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addLVM5: %s' % err)
+
+ try:
+ lv_name = form['lv_name'].strip()
+ if not lv_name:
+ raise KeyError, 'No logical volume name was given for "%s"' % rname
+ res.addAttribute('lv_name', lv_name)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addLVM6: %s' % err)
+
+ return errors
+
+def addSAPDatabase(res, rname, form, model):
+ errors = list()
+
+ res.removeAttribute('name')
+ res.addAttribute('SID', rname)
+
+ try:
+ dbtype = form['DBTYPE'].strip()
+ if not dbtype in [ 'ORA', 'DB6', 'ADA' ]:
+ raise Exception, 'You gave an invalid database type: %s' % dbtype
+ res.addAttribute('DBTYPE', dbtype)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addSAPD1: %s' % err)
+
+ if form.has_key('DBJ2EE_ONLY'):
+ res.addAttribute('DBJ2EE_ONLY', 'TRUE')
+ else:
+ res.removeAttribute('DBJ2EE_ONLY')
+
+ # Optional string parameters
+ for param in [ 'DIR_EXECUTABLE', 'NETSERVICENAME', 'DIR_BOOTSTRAP', 'DIR_SECSTORE' ]:
+ try:
+ pval = form[param].strip()
+ if not pval:
+ raise KeyError, 'blank'
+ res.addAttribute(param, pval)
+ except KeyError, e:
+ res.removeAttribute(param)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addSAPD2: %s %s' % (param, err))
+ return errors
+
+def addSAPInstance(res, rname, form, model):
+ errors = list()
+
+ res.removeAttribute('name')
+ res.addAttribute('InstanceName', rname)
+
+ # Optional string parameters
+ for param in [ 'DIR_EXECUTABLE', 'DIR_PROFILE', 'START_PROFILE' ]:
+ try:
+ pval = form[param].strip()
+ if not pval:
+ raise KeyError, 'blank'
+ res.addAttribute(param, pval)
+ except KeyError, e:
+ res.removeAttribute(param)
+ except Exception, e:
+ err = str(e)
+ errors.append(err)
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('addSAPI1: %s %s' % (param, err))
+ return errors
+
+resource_table = {
+ 'ip': [ addIp, Ip ],
+ 'fs': [ addFs, Fs ],
+ 'gfs': [ addClusterfs, Clusterfs ],
+ 'nfsm': [ addNetfs, Netfs ],
+ 'nfsx': [ addNFSExport, NFSExport ],
+ 'nfsc': [ addNFSClient, NFSClient ],
+ 'scr': [ addScript, Script ],
+ 'smb': [ addSamba, Samba ],
+ 'tomcat-5': [ addTomcat5, Tomcat5 ],
+ 'postgres-8': [ addPostgres8, Postgres8 ],
+ 'apache': [ addApache, Apache ],
+ 'openldap': [ addOpenLDAP, OpenLDAP ],
+ 'lvm': [ addLVM, LVM ],
+ 'mysql': [ addMySQL, MySQL ],
+ 'SAPDatabase': [ addSAPDatabase, SAPDatabase ],
+ 'SAPInstance': [ addSAPInstance, SAPInstance ]
+}
+
+def create_resource(res_type, form, model):
+ if not resource_table.has_key(res_type):
+ raise Exception, [ 'Unknown resource type: "%s"' % res_type ]
+
+ res = None
+ if form.has_key('edit'):
+ if not form.has_key('oldname'):
+ raise Exception, [ 'Cannot find this resource\'s original name.' ]
+
+ oldname = form['oldname'].strip()
+ if not oldname:
+ raise Exception, [ 'Cannot find this resource\'s original name.' ]
+
+ try:
+ res = getResourceForEdit(model, oldname)
+ if not res:
+ raise Exception, 'not found'
+ except Exception, e:
+ raise Exception, [ 'No Resource named "%s" exists.' % oldname ]
+ else:
+ res = resource_table[res_type][1]()
+
+ if res_type != 'ip':
+ if not form.has_key('resourceName') or not form['resourceName'].strip():
+ raise Exception, [ 'All resources must have a unique name.' ]
+ rname = form['resourceName'].strip()
+ res.addAttribute('name', rname)
+ else:
+ rname = form['ip_address'].strip()
+
+ errors = resource_table[res_type][0](res, rname, form, model)
+ try:
+ dummy = getResourceForEdit(model, rname)
+ if dummy:
+ errors.append('A resource named "%s" already exists.' % rname)
+ except:
+ pass
+
+ if len(errors) > 0:
+ raise Exception, errors
+ return res
/cvs/cluster/conga/luci/site/luci/Extensions/RicciQueries.py,v --> standard output
revision 1.7.2.1
--- conga/luci/site/luci/Extensions/RicciQueries.py
+++ - 2007-08-09 21:35:23.742263000 +0000
@@ -0,0 +1,728 @@
+# Copyright (C) 2006-2007 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 xml.dom import minidom
+from ricci_communicator import RicciCommunicator
+from LuciSyslog import get_logger
+from conga_constants import LUCI_DEBUG_MODE
+
+luci_log = get_logger()
+
+def addClusterNodeBatch(cluster_name,
+ install_base,
+ install_services,
+ install_shared_storage,
+ install_LVS,
+ upgrade_rpms,
+ gulm):
+ batch = list()
+
+ batch.append('<?xml version="1.0" ?>')
+ batch.append('<batch>')
+ batch.append('<module name="rpm">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="install">')
+ if upgrade_rpms:
+ batch.append('<var name="upgrade" type="boolean" value="true"/>')
+ else:
+ batch.append('<var name="upgrade" type="boolean" value="false"/>')
+ batch.append('<var name="sets" type="list_xml">')
+ if install_base or install_services or install_shared_storage:
+ if gulm:
+ batch.append('<set name="Cluster Base - Gulm"/>')
+ else:
+ batch.append('<set name="Cluster Base"/>')
+ if install_services:
+ batch.append('<set name="Cluster Service Manager"/>')
+ if install_shared_storage:
+ batch.append('<set name="Clustered Storage"/>')
+ if install_LVS:
+ batch.append('<set name="Linux Virtual Server"/>')
+ batch.append('</var>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ batch.append('<module name="service">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="disable">')
+ batch.append('<var mutable="false" name="services" type="list_xml">')
+ if install_base or install_services or install_shared_storage:
+ if gulm:
+ batch.append('<set name="Cluster Base - Gulm"/>')
+ else:
+ batch.append('<set name="Cluster Base"/>')
+ if install_services:
+ batch.append('<set name="Cluster Service Manager"/>')
+ if install_shared_storage:
+ batch.append('<set name="Clustered Storage"/>')
+ if install_LVS:
+ batch.append('<set name="Linux Virtual Server"/>')
+ batch.append('</var>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ need_reboot = install_base or install_services or install_shared_storage or install_LVS
+ if need_reboot:
+ batch.append('<module name="reboot">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="reboot_now"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+ else:
+ batch.append('<module name="rpm">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="install"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ batch.append('<module name="cluster">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="set_cluster.conf">')
+ batch.append('<var mutable="false" name="propagate" type="boolean" value="false"/>')
+ batch.append('<var mutable="false" name="cluster.conf" type="xml">')
+ batch.append('<cluster config_version="1" name="%s">' % cluster_name)
+ batch.append('<fence_daemon post_fail_delay="0" post_join_delay="3"/>')
+ batch.append('<clusternodes/>')
+ batch.append('<cman/>')
+ batch.append('<fencedevices/>')
+ batch.append('<rm/>')
+ batch.append('</cluster>')
+ batch.append('</var>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ if install_shared_storage:
+ batch.append('<module name="storage">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="enable_clustered_lvm"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+ else:
+ batch.append('<module name="rpm">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="install"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ batch.append('<module name="cluster">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="start_node"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+ batch.append('</batch>')
+
+ return minidom.parseString(''.join(batch)).firstChild
+
+def createClusterBatch( os_str,
+ cluster_name,
+ cluster_alias,
+ nodeList,
+ install_base,
+ install_services,
+ install_shared_storage,
+ install_LVS,
+ upgrade_rpms,
+ gulm_lockservers):
+
+ batch = list()
+ batch.append('<?xml version="1.0" ?>')
+ batch.append('<batch>')
+
+ batch.append('<module name="rpm">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="install">')
+ if upgrade_rpms:
+ batch.append('<var name="upgrade" type="boolean" value="true"/>')
+ else:
+ batch.append('<var name="upgrade" type="boolean" value="false"/>')
+
+ batch.append('<var name="sets" type="list_xml">')
+ if install_base or install_services or install_shared_storage:
+ if gulm_lockservers:
+ batch.append('<set name="Cluster Base - Gulm"/>')
+ else:
+ batch.append('<set name="Cluster Base"/>')
+
+ if install_services:
+ batch.append('<set name="Cluster Service Manager"/>')
+
+ if install_shared_storage:
+ batch.append('<set name="Clustered Storage"/>')
+ if install_LVS:
+ batch.append('<set name="Linux Virtual Server"/>')
+ batch.append('</var>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ batch.append('<module name="service">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="disable">')
+ batch.append('<var mutable="false" name="services" type="list_xml">')
+ if install_base or install_services or install_shared_storage:
+ if gulm_lockservers:
+ batch.append('<set name="Cluster Base - Gulm"/>')
+ else:
+ batch.append('<set name="Cluster Base"/>')
+ if install_services:
+ batch.append('<set name="Cluster Service Manager"/>')
+ if install_shared_storage:
+ batch.append('<set name="Clustered Storage"/>')
+ if install_LVS:
+ batch.append('<set name="Linux Virtual Server"/>')
+ batch.append('</var>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ need_reboot = install_base or install_services or install_shared_storage or install_LVS
+ if need_reboot:
+ batch.append('<module name="reboot">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="reboot_now"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+ else:
+ batch.append('<module name="rpm">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="install"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ batch.append('<module name="cluster">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="set_cluster.conf">')
+ batch.append('<var mutable="false" name="propagate" type="boolean" value="false"/>')
+ batch.append('<var mutable="false" name="cluster.conf" type="xml">')
+ batch.append('<cluster config_version="1" name="%s" alias="%s">' % (cluster_name, cluster_alias))
+ batch.append('<fence_daemon post_fail_delay="0" post_join_delay="3"/>')
+ batch.append('<clusternodes>')
+ x = 1
+ for i in nodeList:
+ if os_str == 'rhel4':
+ batch.append('<clusternode name="%s" votes="1"/>' % i)
+ else:
+ batch.append('<clusternode name="%s" votes="1" nodeid="%d"/>' % (i, x))
+ x += 1
+ batch.append('</clusternodes>')
+
+ if not gulm_lockservers:
+ if len(nodeList) == 2:
+ batch.append('<cman expected_votes="1" two_node="1"/>')
+ else:
+ batch.append('<cman/>')
+ batch.append('<fencedevices/>')
+ batch.append('<rm/>')
+ if gulm_lockservers:
+ batch.append('<gulm>')
+ for i in gulm_lockservers:
+ batch.append('<lockserver name="%s" />' % i)
+ batch.append('</gulm>')
+ batch.append('</cluster>')
+ batch.append('</var>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ if install_shared_storage:
+ batch.append('<module name="storage">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="enable_clustered_lvm"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+ else:
+ batch.append('<module name="rpm">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="install"/>')
+ batch.append('</request>')
+ batch.append('</module>')
+
+ batch.append('<module name="cluster">')
+ batch.append('<request API_version="1.0">')
+ batch.append('<function_call name="start_node">')
+ batch.append('<var mutable="false" name="cluster_startup" type="boolean" value="true"/>')
+ batch.append('</function_call>')
+ batch.append('</request>')
+ batch.append('</module>')
+ batch.append('</batch>')
+
+ return minidom.parseString(''.join(batch)).firstChild
+
+def batchAttemptResult(doc):
+ if not doc:
+ return (None, None)
+
+ try:
+ batch = doc.getElementsByTagName('batch')
+ if not batch or len(batch) < 1:
+ raise Exception, 'no batch tag was found'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('BAR0: %r %s' % (e, str(e)))
+ return (None, None)
+
+ for i in batch:
+ try:
+ batch_number = str(i.getAttribute('batch_id'))
+ result = str(i.getAttribute('status'))
+ return (batch_number, result)
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('BAR1: %s' % e)
+
+ if LUCI_DEBUG_MODE is True:
+ try:
+ luci_log.debug_verbose('BAR2: batchid, status not in \"%s\"' \
+ % doc.toxml())
+ except:
+ pass
+ return (None, None)
+
+def getClusterStatusBatch(rc):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="status"/></request></module>'
+ ricci_xml = rc.batch_run(batch_str, async=False)
+
+ if not ricci_xml:
+ return None
+
+ try:
+ cluster_tags = ricci_xml.getElementsByTagName('cluster')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSB0: %r %s' % (e, str(e)))
+ return None
+
+ if len(cluster_tags) < 1:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSB1: %d entries - expecting 1' \
+ % len(cluster_tags))
+ return None
+ elif len(cluster_tags) > 1:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSB2: %d entries, expecting 1 use first' \
+ % len(cluster_tags))
+
+ try:
+ cluster_node = cluster_tags[0]
+ if not cluster_node:
+ raise Exception, 'element 0 is None'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSB3: %r %s' % (e, str(e)))
+ return None
+
+ try:
+ doc = minidom.Document()
+ doc.appendChild(cluster_node)
+ return doc
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCSB4: %r %s' % (e, str(e)))
+
+ return None
+
+def setClusterConf(rc, clusterconf, propagate=True):
+ if propagate is True:
+ propg = 'true'
+ else:
+ propg = 'false'
+
+ conf = str(clusterconf).replace('<?xml version="1.0"?>', '')
+ conf = conf.replace('<?xml version="1.0" ?>', '')
+ conf = conf.replace('<? xml version="1.0"?>', '')
+ conf = conf.replace('<? xml version="1.0" ?>', '')
+
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="set_cluster.conf"><var type="boolean" name="propagate" mutable="false" value="%s"/><var type="xml" mutable="false" name="cluster.conf">%s</var></function_call></request></module>' % (propg, conf)
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def getNodeLogs(rc):
+ from time import time, ctime
+
+ errstr = 'log not accessible'
+
+ batch_str = '<module name="log"><request API_version="1.0"><function_call name="get"><var mutable="false" name="age" type="int" value="18000"/><var mutable="false" name="tags" type="list_str"></var></function_call></request></module>'
+
+ ricci_xml = rc.batch_run(batch_str, async=False)
+ if not ricci_xml:
+ return errstr
+ try:
+ log_entries = ricci_xml.getElementsByTagName('logentry')
+ if not log_entries or len(log_entries) < 1:
+ raise Exception, 'no log data is available.'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GNL0: retrieving log data from %s: %r %s' \
+ % (rc.hostname(), e, str(e)))
+ return None
+
+ time_now = time()
+ entry_list = list()
+
+ try:
+ # Show older entries first.
+ log_entries.sort(lambda x, y: int(y.getAttribute('age')) - int(x.getAttribute('age')))
+ except:
+ pass
+
+ for i in log_entries:
+ try:
+ log_msg = i.getAttribute('msg')
+ except:
+ log_msg = ''
+
+ if not log_msg:
+ continue
+
+ try:
+ log_age = int(i.getAttribute('age'))
+ except:
+ log_age = 0
+
+ try:
+ log_domain = i.getAttribute('domain')
+ except:
+ log_domain = ''
+
+ try:
+ log_pid = i.getAttribute('pid')
+ except:
+ log_pid = ''
+
+ if log_age:
+ entry_list.append('%s ' % ctime(time_now - log_age))
+ if log_domain:
+ entry_list.append(log_domain)
+ if log_pid:
+ entry_list.append('[%s]' % log_pid)
+ entry_list.append(': %s<br/>' % log_msg)
+ return ''.join(entry_list)
+
+def nodeReboot(rc):
+ batch_str = '<module name="reboot"><request API_version="1.0"><function_call name="reboot_now"/></request></module>'
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def nodeLeaveCluster(rc, cluster_shutdown=False, purge=False):
+ cshutdown = 'false'
+ if cluster_shutdown is True:
+ cshutdown = 'true'
+
+ purge_conf = 'true'
+ if purge is False:
+ purge_conf = 'false'
+
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="stop_node"><var mutable="false" name="cluster_shutdown" type="boolean" value="%s"/><var mutable="false" name="purge_conf" type="boolean" value="%s"/></function_call></request></module>' % (cshutdown, purge_conf)
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def nodeFence(rc, nodename):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="fence_node"><var mutable="false" name="nodename" type="string" value="%s"/></function_call></request></module>' % nodename
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def nodeJoinCluster(rc, cluster_startup=False):
+ cstartup = 'false'
+ if cluster_startup is True:
+ cstartup = 'true'
+
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="start_node"><var mutable="false" name="cluster_startup" type="boolean" value="%s"/></function_call></request></module>' % cstartup
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def startService(rc, servicename, preferrednode=None):
+ if preferrednode is not None:
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="start_service"><var mutable="false" name="servicename" type="string" value="%s"/><var mutable="false" name="nodename" type="string" value="%s"/></function_call></request></module>' % (servicename, preferrednode)
+ else:
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="start_service"><var mutable="false" name="servicename" type="string" value="%s"/></function_call></request></module>' % servicename
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def migrateService(rc, servicename, preferrednode):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="migrate_service"><var mutable="false" name="servicename" type="string" value="%s"/><var mutable="false" name="nodename" type="string" value="%s" /></function_call></request></module>' % (servicename, preferrednode)
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def updateServices(rc, enable_list, disable_list):
+ batch_list = list()
+
+ if enable_list and len(enable_list) > 0:
+ batch_list.append('<module name="service"><request API_version="1.0"><function_call name="enable"><var mutable="false" name="services" type="list_xml">')
+ for i in enable_list:
+ batch_list.append('<service name="%s"/>' % str(i))
+ batch_list.append('</var></function_call></request></module>')
+
+ if disable_list and len(disable_list) > 0:
+ batch_list.append('<module name="service"><request API_version="1.0"><function_call name="disable"><var mutable="false" name="services" type="list_xml">')
+ for i in disable_list:
+ batch_list.append('<service name="%s"/>' % str(i))
+ batch_list.append('</var></function_call></request></module>')
+
+ if len(batch_list) < 1:
+ return None, None
+ ricci_xml = rc.batch_run(''.join(batch_list))
+ return batchAttemptResult(ricci_xml)
+
+def restartService(rc, servicename):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="restart_service"><var mutable="false" name="servicename" type="string" value=\"%s\"/></function_call></request></module>' % servicename
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def stopService(rc, servicename):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="stop_service"><var mutable="false" name="servicename" type="string" value=\"%s\"/></function_call></request></module>' % servicename
+
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
+
+def svc_manage(rc, hostname, servicename, op):
+ svc_func = None
+
+ doc = minidom.Document()
+ elem = doc.createElement('result')
+ elem.setAttribute('success', '0')
+
+ if not servicename:
+ elem.setAttribute('service', 'No service name was specified.')
+ elem.setAttribute('message', 'No service name was specified.')
+
+ if not op:
+ elem.setAttribute('operation', 'No operation was specified.')
+ elem.setAttribute('message', 'No operation was specified.')
+
+ if not servicename or not op:
+ doc.appendChild(elem)
+ return doc
+
+ elem.setAttribute('service', servicename)
+ elem.setAttribute('operation', op)
+ elem.setAttribute('hostname', hostname)
+
+ try:
+ op = op.strip().lower()
+ if op == 'restart' or op == 'start' or op == 'stop':
+ svc_func = op
+ else:
+ raise Exception, op
+ except Exception, e:
+ elem.setAttribute('message', 'Unknown operation: %s' % str(e))
+ doc.appendChild(elem)
+ return doc
+
+ batch_str = '<module name="service"><request API_version="1.0"><function_call name="%s"><var mutable="false" name="services" type="list_xml"><service name="%s"/></var></function_call></request></module>' % (svc_func, servicename)
+
+ ricci_xml = rc.batch_run(batch_str, async=False)
+ if not ricci_xml or not ricci_xml.firstChild:
+ elem.setAttribute('message', 'operation failed')
+ doc.appendChild(elem)
+ return doc
+
+ try:
+ mod_elem = ricci_xml.getElementsByTagName('module')
+ status_code = int(mod_elem[0].getAttribute('status'))
+ if status_code == 0:
+ var_elem = mod_elem[0].getElementsByTagName('var')
+ for i in var_elem:
+ name = i.getAttribute('name').lower()
+ if name == 'success':
+ success = i.getAttribute('value').lower()
+ if success == 'true':
+ elem.setAttribute('success', '1')
+ elem.setAttribute('message', 'success')
+ else:
+ elem.setAttribute('message', 'operation failed')
+ break
+ else:
+ err_msg = mod_elem[0].childNodes[1].getAttribute('description')
+ elem.setAttribute('message', err_msg)
+ except Exception, e:
+ elem.setAttribute('message', 'operation failed')
+
+ doc.appendChild(elem)
+ return doc
+
+def list_services(rc):
+ batch_str = '<module name="service"><request API_version="1.0"><function_call name="list"><var mutable="false" name="description" type="boolean" value="true"/></function_call></request></module>'
+ ricci_xml = rc.batch_run(batch_str, async=False)
+ if not ricci_xml or not ricci_xml.firstChild:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('LS0: None returned')
+ return None
+ try:
+ service_tags = ricci_xml.getElementsByTagName('service')
+ return service_tags
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('LS1: %r %s' % (e, str(e)))
+ return None
+
+def nodeIsVirtual(rc):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="virt_guest"/></request></module>'
+
+ ricci_xml = rc.batch_run(batch_str, async=False)
+ if not ricci_xml or not ricci_xml.firstChild:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('nodeIsVirtual0: None returned')
+ return None
+
+ var_tags = ricci_xml.getElementsByTagName('var')
+ if not var_tags or len(var_tags) < 2:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('nodeIsVirtual1: unexpected response %s' \
+ % ricci_xml.toxml())
+ return None
+
+ success = False
+ virtual = False
+ for i in var_tags:
+ try:
+ name = i.getAttribute('name')
+ if not name:
+ raise Exception, 'name is blank'
+ if name == 'success':
+ result = i.getAttribute('value')
+ if result == 'true':
+ success = True
+ elif name == 'virt_guest':
+ result = i.getAttribute('value')
+ if result == 'true':
+ virtual = True
+ else:
+ raise Exception, 'unexpected attribute name: %s' % name
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('nodeIsVirtual2: error: %r %s' \
+ % (e, str(e)))
+
+ if not success:
+ return None
+ return virtual
+
+def getDaemonStates(rc, dlist):
+ batch_list = list()
+ batch_list.append('<module name="service"><request API_version="1.0"><function_call name="query"><var mutable="false" name="search" type="list_xml">')
+
+ for item in dlist:
+ batch_list.append('<service name=\"%s\"/>' % item)
+ batch_list.append('</var></function_call></request></module>')
+
+ ricci_xml = rc.batch_run(''.join(batch_list), async=False)
+ if not ricci_xml or not ricci_xml.firstChild:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GDS0: no ricci_xml')
+ return None
+ result = extractDaemonInfo(ricci_xml.firstChild)
+ return result
+
+def extractDaemonInfo(bt_node):
+ if not bt_node:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('EDI0: no bt_node')
+ return None
+
+ resultlist = list()
+ svc_nodes = bt_node.getElementsByTagName('service')
+ for node in svc_nodes:
+ svchash = {}
+ try:
+ name = node.getAttribute('name')
+ if not name:
+ raise Exception, 'No name'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('EDI1: no service name: %r %s' \
+ % (e, str(e)))
+ name = '[unknown]'
+ svchash['name'] = name
+
+ try:
+ svc_enabled = node.getAttribute('enabled')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('EDI2: no enabled: %r %s' \
+ % (e, str(e)))
+ svc_enabled = '[unknown]'
+ svchash['enabled'] = svc_enabled
+
+ try:
+ running = node.getAttribute('running')
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('EDI3: no running: %r %s' \
+ % (e, str(e)))
+ running = '[unknown]'
+ svchash['running'] = running
+ resultlist.append(svchash)
+
+ return resultlist
+
+def getClusterConf(rc):
+ import xml.dom
+
+ if rc is None:
+ return None
+
+ doc = minidom.Document()
+ batch = doc.createElement('batch')
+ module = doc.createElement('module')
+ module.setAttribute('name', 'cluster')
+ request = doc.createElement('request')
+ request.setAttribute('API_version', '1.0')
+ call = doc.createElement('function_call')
+ call.setAttribute('name', 'get_cluster.conf')
+ request.appendChild(call)
+ module.appendChild(request)
+ batch.appendChild(module)
+
+ # temporary workaround for ricci bug
+ system_info = rc.hostname()
+ try:
+ rc = RicciCommunicator(system_info)
+ if rc is None:
+ raise Exception, 'unknown error'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCC0: connecting to %s: %r %s' \
+ % (system_info, e, str(e)))
+ return None
+ # end workaround
+
+ try:
+ ret = rc.process_batch(batch)
+ if not ret:
+ raise Exception, 'no XML response'
+ except Exception, e:
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCC1: process_batch error for %s: %r %s' \
+ % (system_info, e, str(e)))
+ return None
+
+ var_nodes = ret.getElementsByTagName('var')
+ for i in var_nodes:
+ if i.getAttribute('name') == 'cluster.conf':
+ for j in i.childNodes:
+ if j.nodeType == xml.dom.Node.ELEMENT_NODE:
+ return j
+
+ if LUCI_DEBUG_MODE is True:
+ luci_log.debug_verbose('GCC2: no conf node found')
+ return None
+
+def set_xvm_key(rc, key_base64):
+ batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="set_xvm_key"><var mutable="false" name="key_base64" type="string" value="%s"/></function_call></request></module>' % key_base64
+ ricci_xml = rc.batch_run(batch_str)
+ return batchAttemptResult(ricci_xml)
next reply other threads:[~2007-08-09 21:35 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-09 21:35 rmccabe [this message]
-- strict thread matches above, loose matches on Subject: below --
2010-08-05 18:16 [Cluster-devel] conga/luci/site/luci/Extensions LuciClusterAct rmccabe
2007-10-22 19:24 rmccabe
2007-09-28 5:36 rmccabe
2007-07-26 4:21 rmccabe
2007-05-23 21:21 rmccabe
2007-05-22 21:52 rmccabe
2007-05-18 5:23 rmccabe
2007-05-14 18:00 rmccabe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070809213523.31286.qmail@sourceware.org \
--to=rmccabe@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).