commit f341922c3e86cc3da041a298dad57c98fdd27bc0
Author: root <root(a)chipotle.numb.lan>
Date: Fri Sep 25 13:54:18 2009 -0400
- Add file missing from the last commit
- Clean up the database objects a bit
luci/lib/cluster_status.py | 40 ++++
luci/lib/db_helpers.py | 51 +++++-
luci/model/objects.py | 56 +++---
luci/templates/cluster.html | 2 +-
.../validate_create_cluster_form.py | 41 +++--
old_db.py | 191 --------------------
6 files changed, 138 insertions(+), 243 deletions(-)
---
diff --git a/luci/lib/cluster_status.py b/luci/lib/cluster_status.py
new file mode 100644
index 0000000..1a66a3d
--- /dev/null
+++ b/luci/lib/cluster_status.py
@@ -0,0 +1,40 @@
+from luci.model import metadata, DBSession
+from luci.model.objects import Node,Cluster,Task
+from sqlalchemy.orm.exc import NoResultFound
+
+from luci.lib.ricci_communicator import RicciCommunicator
+import luci.lib.ricci_queries as rq
+
+class NodeStatus:
+ def __init__(self, node_xml):
+ self.name = node_xml.getAttribute('name')
+ self.clustered = node_xml.getAttribute('clustered')
+ self.online = node_xml.getAttribute('online')
+ self.uptime = node_xml.getAttribute('uptime')
+ self.votes = node_xml.getAttribute('votes')
+
+class ServiceStatus:
+ def __init__(self, svc_xml):
+ self.type = 'service'
+ self.name = svc_xml.getAttribute('name')
+ self.nodename = svc_xml.getAttribute('nodename')
+ self.running = svc_xml.getAttribute('running')
+ self.failed = svc_xml.getAttribute('failed')
+ self.autostart = svc_xml.getAttribute('autostart')
+ self.is_vm = svc_xml.getAttribute('vm').lower() == 'true'
+
+class ClusterStatus:
+ def __init__(self, status_xml):
+ self.alias = status_xml.firstChild.getAttribute('alias')
+ self.name = status_xml.firstChild.getAttribute('name')
+ self.quorate = status_xml.firstChild.getAttribute('quorate')
+ self.votes = status_xml.firstChild.getAttribute('votes')
+ self.minQuorum = status_xml.firstChild.getAttribute('minQuorum')
+ self.nodes = []
+ self.services = []
+
+ for node in status_xml.firstChild.childNodes:
+ if node.nodeName == 'node':
+ self.nodes.append(NodeStatus(node))
+ elif node.nodeName == 'service':
+ self.services.append(ServiceStatus(node))
diff --git a/luci/lib/db_helpers.py b/luci/lib/db_helpers.py
index 8db6069..9f1174c 100644
--- a/luci/lib/db_helpers.py
+++ b/luci/lib/db_helpers.py
@@ -1,10 +1,11 @@
"""Database Helpers used in luci."""
-from luci.model import metadata, DBSession, NoResultFound
+from luci.model import metadata, DBSession
from luci.model.objects import Node,Cluster,Task
+from sqlalchemy.orm.exc import NoResultFound
from luci.lib.ricci_communicator import RicciCommunicator
-from luci.lib.ricci_queries import getClusterConf
+import luci.lib.ricci_queries as rq
def get_cluster_db_obj(cluster_name):
db_obj = None
@@ -17,7 +18,7 @@ def get_cluster_db_obj(cluster_name):
pass
return db_obj
-def get_conf_for_cluster(cluster_name):
+def get_agent_for_cluster(cluster_name):
db_obj = get_cluster_db_obj(cluster_name)
if db_obj is None:
return None
@@ -30,15 +31,40 @@ def get_conf_for_cluster(cluster_name):
port = node_obj.port
try:
rc = RicciCommunicator(host, port=port)
- conf = getClusterConf(rc)
- if conf is not None:
- return conf
+ if rc is not None:
+ return rc
except Exception, e:
- continue
+ # log this
+ pass
+ return None
+
+def get_model_for_cluster(cluster_name, rc=None):
+ if rc is None:
+ rc = get_agent_for_cluster(cluster_name)
+ if rc is None:
+ return None
+
+ try:
+ from luci.lib.ClusterConf.ModelBuilder import ModelBuilder
+ conf = rq.getClusterConf(rc)
+ if conf is not None:
+ model = ModelBuilder(None, conf, rc.os())
+ return model
+ except Exception, e:
+ # log this
+ pass
# Couldn't get the conf from any nodes
return None
+def get_cluster_status(rc):
+ try:
+ doc = rq.getClusterStatusBatch(rc)
+ except Exception, e:
+ # log this
+ return None
+ return doc
+
def get_cluster_list():
db_obj = None
try:
@@ -50,3 +76,14 @@ def get_cluster_list():
return None
return db_obj
+
+def get_cluster_task_status(cluster_name):
+ db_obj = get_cluster_db_obj(cluster_name)
+ if db_obj is None:
+ return None
+ tasks = db_obj.tasks
+ if len(tasks) > 0:
+ pass
+ # get status
+
+ return False
diff --git a/luci/model/objects.py b/luci/model/objects.py
index 5bfb57c..ec520fe 100644
--- a/luci/model/objects.py
+++ b/luci/model/objects.py
@@ -16,6 +16,30 @@ cluster_tasks_table = Table('cluster_tasks', metadata,
Column('cluster_id', Integer, ForeignKey('clusters.cluster_id'),
primary_key=True),
Column('task_id', Integer, ForeignKey('tasks.task_id'),
primary_key=True))
+node_tasks_table = Table('node_tasks', metadata,
+ Column('node_id', Integer, ForeignKey('nodes.node_id'),
primary_key=True),
+ Column('task_id', Integer, ForeignKey('tasks.task_id'),
primary_key=True))
+
+class Task(DeclarativeBase):
+ __tablename__ = 'tasks'
+
+ task_id = Column(Integer, autoincrement=True, primary_key=True)
+ batch_id = Column(Integer)
+ batch_status = Column(Integer)
+ started = Column(DateTime, default=datetime.now)
+ last_status = Column(DateTime, default=datetime.now)
+ finished = Column(DateTime)
+ description = Column(Unicode(255))
+ status_msg = Column(Unicode(255))
+ redirect_url = Column(Unicode(512))
+
+ def __repr__(self):
+ return '<Task: id=%d batchid=%d>' % (self.task_id, self.batch_id)
+
+ def __unicode__(self):
+ return self.task_id
+
+
class Node(DeclarativeBase):
__tablename__ = 'nodes'
@@ -29,6 +53,7 @@ class Node(DeclarativeBase):
port = Column(Integer)
#{ Relations
+ tasks = relation(Task, secondary=node_tasks_table, backref="node")
#{ Special methods
@@ -40,49 +65,26 @@ class Node(DeclarativeBase):
#}
-class Task(DeclarativeBase):
- __tablename__ = 'tasks'
-
- task_id = Column(Integer, autoincrement=True, primary_key=True)
- batch_id = Column(Integer)
- batch_status = Column(Integer)
- started = Column(DateTime, default=datetime.now)
- last_status = Column(DateTime, default=datetime.now)
- finished = Column(DateTime)
- description = Column(Unicode(255))
- status_msg = Column(Unicode(255))
- system = Column(Integer)
- cluster = Column(Integer)
-
- def __repr__(self):
- return '<Task: id=%d batchid=%d>' % (self.task_id, self.batch_id)
-
- def __unicode__(self):
- return self.task_id
-
class Cluster(DeclarativeBase):
__tablename__ = 'clusters'
#{ Columns
cluster_id = Column(Integer, autoincrement=True, primary_key=True)
-
name = Column(Unicode(16), unique=True, nullable=False)
-
display_name = Column(Unicode(255))
-
created = Column(DateTime, default=datetime.now)
#{ Relations
- nodes = relation(Node, secondary=cluster_nodes_table, backref="clusters")
- tasks = relation(Task, secondary=cluster_tasks_table, backref="clusters")
+ nodes = relation(Node, secondary=cluster_nodes_table, backref="cluster")
+ tasks = relation(Task, secondary=cluster_tasks_table, backref="cluster")
#{ Special methods
def __repr__(self):
- return '<Cluster: display name="%s">' % (
- self.display_name)
+ return '<Cluster: id="%d" name="%s"
display_name="%s">' % (
+ self.cluster_id, self.name, self.display_name)
def __unicode__(self):
return self.display_name or self.name
diff --git a/luci/templates/cluster.html b/luci/templates/cluster.html
index 3236ac3..5c75249 100644
--- a/luci/templates/cluster.html
+++ b/luci/templates/cluster.html
@@ -16,7 +16,7 @@
<tr>
<td valign="top">
<div class="sidebar">
- <a href="${tg.url('/cluster/clusterlist')}">Cluster
List</a><br/>
+ <a href="${tg.url('/clusters/')}">Cluster
List</a><br/>
<a href="${tg.url('/cluster/createcluster')}">Create a New
Cluster</a><br/>
<a
href="${tg.url('/cluster/configure')}">Configure</a><br/>
</div>
diff --git a/luci/widget_validators/validate_create_cluster_form.py
b/luci/widget_validators/validate_create_cluster_form.py
index 496c95c..7142861 100644
--- a/luci/widget_validators/validate_create_cluster_form.py
+++ b/luci/widget_validators/validate_create_cluster_form.py
@@ -76,12 +76,13 @@ def validate_create_cluster_form(self, **kw):
cluster_db_obj = Cluster(name=cluster_name,
display_name=cluster_name)
+
node_list = []
- node_db_obj = []
- task_db_obj = []
+ node_db_obj = {}
+ task_db_obj = {}
for node in nodes:
try:
- rc = RicciCommunicator(node[0], enforce_trust=False)
+ rc = RicciCommunicator(node[0], port=int(node[2]), enforce_trust=False)
rc.trust()
rc.auth(node[1])
if not rc.authed():
@@ -97,16 +98,18 @@ def validate_create_cluster_form(self, **kw):
break
node_list.append(node[0])
- node_db_obj.append(Node(node_name=node[0],
- display_name=node[0],
- hostname=node[0],
- ipaddr=node[0],
- port=node[2]))
+ node_db_obj[node[0]] = Node(node_name=node[0],
+ display_name=node[0],
+ hostname=node[0],
+ ipaddr=node[0],
+ port=node[2])
+ DBSession.add(node_db_obj[node[0]])
except Exception, e:
errors.append(str(e))
if len(errors) > 0:
flash(_('The following errors occurred: %s') % str(errors),
'error')
+ DBSession.rollback()
return
ret = send_batch_to_hosts(node_list, 10, rq.create_cluster,
@@ -118,19 +121,23 @@ def validate_create_cluster_form(self, **kw):
if ret[i].has_key('error'):
errors.append(_('Unable to connect to the ricci agent on node %s: %s')
% (i, ret[i]['err_msg']))
task_id = ret[i]['batch_result'][0]
- task_db_obj.append(
- Task(batch_id=task_id,
- batch_status=0,
- status_msg=_('Creating node "%s" for cluster
"%s"') % (i, cluster_name)))
+ task_obj = Task(batch_id=task_id,
+ batch_status=0,
+ redirect_url='/clusters/%s/' % cluster_name,
+ status_msg=_('Creating node "%s" for cluster
"%s"') % (i, cluster_name))
+ DBSession.add(task_obj)
+ task_db_obj[i] = task_obj
try:
- for i in node_db_obj:
- DBSession.add(i)
- cluster_db_obj.nodes = node_db_obj
- cluster_db_obj.tasks = task_db_obj
+ cluster_db_obj.nodes = node_db_obj.values()
+ cluster_db_obj.tasks = task_db_obj.values()
+ for i in node_db_obj.iterkeys():
+ node_db_obj[i].tasks = [ task_db_obj[i] ]
DBSession.add(cluster_db_obj)
except Exception, e:
- flash(_('An error occurred while updating the luci database'))
+ DBSession.rollback()
+ flash(_('An error occurred while updating the luci database: %s') %
str(e), 'error')
return
+ flash(_('Creating the cluster "%s"... Please wait...') %
cluster_name, 'info')
redirect("/clusters/%s/" % cluster_name)