mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1108.13.1 (41013a844lXqlHgR5n6-9AZ5s3WCsQ)
Added general support for actions Slightly generalized and refactored code for modules / tabs
This commit is contained in:
1 parent
60022fa3f3
commit
0ee1e6a7ba
13 files changed
+207
-40
No files matched your search
@@ -14,7 +14,7 @@ class DomInfo( GenTabbed ):
|
||||
def tabUrlWriter( tab ):
|
||||
return urlWriter( "mod=info&dom=%s%s" % ( self.dom, tab ) )
|
||||
|
||||
GenTabbed.__init__( self, tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGenTab, DomSXPTab, NullTab ] )
|
||||
GenTabbed.__init__( self, "Domain Info", tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGeneralTab, DomSXPTab, NullTab ] )
|
||||
|
||||
def write_BODY( self, request ):
|
||||
dom = request.args.get('dom')
|
||||
@@ -27,6 +27,10 @@ class DomInfo( GenTabbed ):
|
||||
|
||||
GenTabbed.write_BODY( self, request )
|
||||
|
||||
class DomGeneralTab( CompositeTab ):
|
||||
def __init__( self ):
|
||||
CompositeTab.__init__( self, [ DomGenTab, DomActionTab ] )
|
||||
|
||||
class DomGenTab( GeneralTab ):
|
||||
|
||||
def __init__( self ):
|
||||
@@ -41,7 +45,7 @@ class DomGenTab( GeneralTab ):
|
||||
titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter )
|
||||
titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter )
|
||||
|
||||
GeneralTab.__init__( self, "General Domain Info", {}, titles )
|
||||
GeneralTab.__init__( self, {}, titles )
|
||||
|
||||
def write_BODY( self, request ):
|
||||
|
||||
@@ -79,4 +83,18 @@ class DomSXPTab( PreTab ):
|
||||
|
||||
PreTab.write_BODY( self, request )
|
||||
|
||||
class DomActionTab( ActionTab ):
|
||||
|
||||
def __init__( self ):
|
||||
ActionTab.__init__( self, { "shutdown" : ( "Shutdown the Domain", "shutdown.png" ),
|
||||
"reboot" : ( "Reboot the Domain", "reboot.png" ) } )
|
||||
|
||||
def op_shutdown( self, request ):
|
||||
print ">DomShutDown"
|
||||
#server.xend_node_shutdown()
|
||||
|
||||
def op_reboot( self, request ):
|
||||
print ">DomReboot"
|
||||
#server.xend_node_reboot()
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@ from xen.sv.TabView import TabView
|
||||
|
||||
class GenTabbed( HTMLBase ):
|
||||
|
||||
def __init__( self, urlWriter, tabStrings, tabObjects ):
|
||||
def __init__( self, title, urlWriter, tabStrings, tabObjects ):
|
||||
HTMLBase.__init__(self)
|
||||
self.tab = 0;
|
||||
self.tabStrings = tabStrings
|
||||
self.tabObjects = tabObjects
|
||||
self.urlWriter = urlWriter
|
||||
self.title = title
|
||||
|
||||
def write_BODY( self, request, urlWriter = None ):
|
||||
tab = request.args.get('tab')
|
||||
@@ -23,19 +24,34 @@ class GenTabbed( HTMLBase ):
|
||||
request.write( "<table style='' width='100%' border='0' cellspacing='0' cellpadding='0'>" )
|
||||
request.write( "<tr><td>" )
|
||||
|
||||
request.write( "<p align='center'><u>%s</u></p>" % self.title )
|
||||
|
||||
TabView( self.tab, self.tabStrings, self.urlWriter ).write_BODY( request )
|
||||
|
||||
request.write( "</td></tr><tr><td>" )
|
||||
|
||||
render_tab = self.tabObjects[ self.tab ]()
|
||||
render_tab = self.tabObjects[ self.tab ]
|
||||
|
||||
if render_tab is None:
|
||||
request.write( "<p>Bad Tab</p>" )
|
||||
self.finish_BODY( request )
|
||||
else:
|
||||
render_tab.write_BODY( request )
|
||||
render_tab().write_BODY( request )
|
||||
|
||||
request.write( "</td></tr></table>" )
|
||||
|
||||
def perform( self, request ):
|
||||
tab = request.args.get('tab')
|
||||
|
||||
if tab is None or len( tab) != 1:
|
||||
self.tab = 0
|
||||
else:
|
||||
self.tab = int( tab[0] )
|
||||
|
||||
op_tab = self.tabObjects[ self.tab ]
|
||||
|
||||
if op_tab:
|
||||
op_tab().perform( request )
|
||||
|
||||
class PreTab( HTMLBase ):
|
||||
|
||||
@@ -45,7 +61,7 @@ class PreTab( HTMLBase ):
|
||||
|
||||
def write_BODY( self, request ):
|
||||
|
||||
request.write( "<div style='display: block; overflow: auto; border: 0px solid black; height: 400px; width: 540px; padding: 5px; z-index:0; align: center'><pre>" )
|
||||
request.write( "<div style='display: block; overflow: auto; border: 0px solid black; width: 540px; padding: 5px; z-index:0; align: center'><pre>" )
|
||||
|
||||
request.write( self.source )
|
||||
|
||||
@@ -53,16 +69,13 @@ class PreTab( HTMLBase ):
|
||||
|
||||
class GeneralTab( HTMLBase ):
|
||||
|
||||
def __init__( self, title, dict, titles ):
|
||||
def __init__( self, dict, titles ):
|
||||
HTMLBase.__init__( self )
|
||||
self.title = title
|
||||
self.dict = dict
|
||||
self.titles = titles
|
||||
|
||||
def write_BODY( self, request ):
|
||||
|
||||
request.write( "<p><u>%s</u></p>" % self.title )
|
||||
|
||||
request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" )
|
||||
|
||||
def writeAttr( niceName, attr, formatter=None ):
|
||||
@@ -90,4 +103,38 @@ class NullTab( HTMLBase ):
|
||||
def write_BODY( self, request ):
|
||||
request.write( "<p>%s</p>" % self.title )
|
||||
|
||||
class ActionTab( HTMLBase ):
|
||||
|
||||
def __init__( self, actions ):
|
||||
self.actions = actions
|
||||
HTMLBase.__init__( self )
|
||||
|
||||
def write_BODY( self, request ):
|
||||
request.write("<p align='center'>")
|
||||
|
||||
for ( command, ( text, image ) ) in self.actions.items():
|
||||
request.write("<img src='images/%s' width='54' height='54' onclick='doOp( \"%s\" )' onmouseover='update( \"button_desc\", \"%s\" )' " % ( image, command, text ) )
|
||||
request.write("onmouseout='update( \"button_desc\", \" \" )' style='button'>")
|
||||
request.write(" ")
|
||||
|
||||
request.write("<p align='center'><span id='button_desc'> </span></p>")
|
||||
request.write("</p>")
|
||||
|
||||
class CompositeTab( HTMLBase ):
|
||||
|
||||
def __init__( self, tabs ):
|
||||
HTMLBase.__init__( self )
|
||||
self.tabs = tabs
|
||||
|
||||
def write_BODY( self, request ):
|
||||
for tab in self.tabs:
|
||||
request.write( "<br/>" )
|
||||
tab().write_BODY( request )
|
||||
|
||||
def perform( self, request ):
|
||||
for tab in self.tabs:
|
||||
tab().perform( request )
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ class HTMLBase( Resource ):
|
||||
def __init__( self ):
|
||||
Resource.__init__(self)
|
||||
|
||||
def render_POST( self, request ):
|
||||
self.perform( request )
|
||||
self.render_GET( request )
|
||||
|
||||
def render_GET( self, request ):
|
||||
self.write_TOP( request )
|
||||
self.write_BODY( request )
|
||||
@@ -19,7 +23,40 @@ class HTMLBase( Resource ):
|
||||
|
||||
def write_TOP( self, request ):
|
||||
request.write( '<html><head><title>Xen</title><link rel="stylesheet" type="text/css" href="inc/style.css" />' )
|
||||
request.write( '<script src="inc/script.js"></script>' )
|
||||
request.write( '</head><body>' )
|
||||
|
||||
def write_BOTTOM( self, request ):
|
||||
request.write('<form method="post" action="%s">' % request.uri)
|
||||
request.write('<input type="hidden" name="op" value="">')
|
||||
request.write('</form>')
|
||||
request.write( "</body></html>" )
|
||||
|
||||
def get_op_method(self, op):
|
||||
"""Get the method for an operation.
|
||||
For operation 'foo' looks for 'op_foo'.
|
||||
|
||||
op operation name
|
||||
returns method or None
|
||||
"""
|
||||
op_method_name = 'op_' + op
|
||||
return getattr(self, op_method_name, None)
|
||||
|
||||
def perform(self, req):
|
||||
"""General operation handler for posted operations.
|
||||
For operation 'foo' looks for a method op_foo and calls
|
||||
it with op_foo(req). Replies with code 500 if op_foo
|
||||
is not found.
|
||||
|
||||
The method must return a list when req.use_sxp is true
|
||||
and an HTML string otherwise (or list).
|
||||
Methods may also return a Deferred (for incomplete processing).
|
||||
|
||||
req request
|
||||
"""
|
||||
op = req.args.get('op')
|
||||
if not op is None and len(op) == 1:
|
||||
op = op[0]
|
||||
op_method = self.get_op_method(op)
|
||||
if op_method:
|
||||
op_method( req )
|
||||
+28
-12
@@ -1,14 +1,31 @@
|
||||
from xen.sv.HTMLBase import HTMLBase
|
||||
from xen.sv import DomList, NodeInfo, DomInfo
|
||||
from xen.sv.DomList import DomList
|
||||
from xen.sv.NodeInfo import NodeInfo
|
||||
from xen.sv.DomInfo import DomInfo
|
||||
|
||||
class Main( HTMLBase ):
|
||||
|
||||
isLeaf = True
|
||||
|
||||
def __init__( self ):
|
||||
def __init__( self, urlWriter = None ):
|
||||
self.modules = { "node": ( "Node details", NodeInfo ),
|
||||
"list": ( "Domain summary", DomList ),
|
||||
"info": ( "Domain info", DomInfo ) }
|
||||
HTMLBase.__init__(self)
|
||||
|
||||
def render_POST( self, request ):
|
||||
|
||||
#decide what module post'd the action
|
||||
|
||||
mod = request.args.get('mod')
|
||||
|
||||
if not mod is None and len(mod) == 1:
|
||||
modTup = self.modules[ mod[0] ]
|
||||
#check module exists
|
||||
if modTup:
|
||||
(modName, module) = modTup
|
||||
module( self.mainUrlWriter ).perform( request )
|
||||
|
||||
return self.render_GET( request )
|
||||
|
||||
def mainUrlWriter( self, s ):
|
||||
@@ -25,10 +42,10 @@ class Main( HTMLBase ):
|
||||
request.write( " <img src='images/xen.png' width='150' height='75' border='0'/></a></td></tr>" )
|
||||
request.write( " <tr><td align='center' valign='top'>" )
|
||||
|
||||
request.write( " <p class='small'><a href='Main.rpy?mod=node'>Node details</a></p>" )
|
||||
request.write( " <p class='small'><a href='Main.rpy?mod=list'>Domains summary</a></p>" )
|
||||
for (modName, (modTitle, module)) in self.modules.items():
|
||||
request.write( " <p class='small'><a href='Main.rpy?mod=%s'>%s</a></p>" % (modName, modTitle))
|
||||
|
||||
DomList.DomList( self.mainUrlWriter ).write_BODY( request, True, False )
|
||||
DomList( self.mainUrlWriter ).write_BODY( request, True, False )
|
||||
|
||||
request.write( " </td></tr>" )
|
||||
request.write( " </table>" )
|
||||
@@ -44,14 +61,13 @@ class Main( HTMLBase ):
|
||||
|
||||
if mod is None or len(mod) != 1:
|
||||
request.write( '<p>Please select a module</p>' )
|
||||
elif mod[0] == 'info':
|
||||
DomInfo.DomInfo( self.mainUrlWriter ).write_BODY( request )
|
||||
elif mod[0] == 'list':
|
||||
DomList.DomList( self.mainUrlWriter ).write_BODY( request )
|
||||
elif mod[0] == 'node':
|
||||
NodeInfo.NodeInfo( self.mainUrlWriter ).write_BODY( request )
|
||||
else:
|
||||
request.write( '<p>Invalid module. Please select another</p>' )
|
||||
modTup = self.modules[ mod[0] ]
|
||||
if modTup:
|
||||
(modName, module) = modTup
|
||||
module( self.mainUrlWriter ).write_BODY( request )
|
||||
else:
|
||||
request.write( '<p>Invalid module. Please select another</p>' )
|
||||
|
||||
request.write( " </td></tr>" )
|
||||
request.write( " </table>" )
|
||||
|
||||
@@ -10,24 +10,18 @@ class NodeInfo( GenTabbed ):
|
||||
def newUrlWriter( url ):
|
||||
return urlWriter( "mod=node%s" % url )
|
||||
|
||||
GenTabbed.__init__( self, newUrlWriter, [ 'General', 'Dmesg' ], [ NodeGenTab, NodeDmesgTab ] )
|
||||
GenTabbed.__init__( self, "Node Details", newUrlWriter, [ 'General', 'Dmesg', ], [ NodeGeneralTab, NodeDmesgTab ] )
|
||||
|
||||
class NodeGenTab( PreTab ):
|
||||
class NodeGeneralTab( CompositeTab ):
|
||||
def __init__( self ):
|
||||
text = sxp2string( server.xend_node() )
|
||||
PreTab.__init__( self, text )
|
||||
|
||||
class NodeGeneralTab( GeneralTab ):
|
||||
CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ] )
|
||||
|
||||
class NodeInfoTab( GeneralTab ):
|
||||
|
||||
def __init__( self ):
|
||||
|
||||
nodeInfo = server.xend_node()
|
||||
|
||||
dictNodeInfo = {}
|
||||
|
||||
for l in nodeInfo:
|
||||
dictNodeInfo[ l[0] ] = l[1]
|
||||
|
||||
nodeInfo = sxp2hash( server.xend_node() )
|
||||
|
||||
dictTitles = {}
|
||||
dictTitles[ 'System' ] = 'system'
|
||||
dictTitles[ 'Hostname' ] = 'host'
|
||||
@@ -40,11 +34,24 @@ class NodeGeneralTab( GeneralTab ):
|
||||
dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter )
|
||||
dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter )
|
||||
|
||||
GeneralTab.__init__( self, title="General Node Info", dict=dictNodeInfo, titles=dictTitles )
|
||||
GeneralTab.__init__( self, dict=nodeInfo, titles=dictTitles )
|
||||
|
||||
class NodeDmesgTab( PreTab ):
|
||||
|
||||
def __init__( self ):
|
||||
dmesg = server.xend_node_dmesg()
|
||||
PreTab.__init__( self, dmesg[ 1 ] )
|
||||
|
||||
class NodeActionTab( ActionTab ):
|
||||
|
||||
def __init__( self ):
|
||||
ActionTab.__init__( self, { "shutdown" : ( "Shutdown the Node", "shutdown.png" ),
|
||||
"reboot" : ( "Reboot the Node", "reboot.png" ) } )
|
||||
|
||||
def op_shutdown( self, request ):
|
||||
print ">NodeShutDown"
|
||||
#server.xend_node_shutdown()
|
||||
|
||||
def op_reboot( self, request ):
|
||||
print ">NodeReboot"
|
||||
#server.xend_node_reboot()
|
||||
@@ -17,8 +17,13 @@ def getDomInfoHash( domain ):
|
||||
d['start_time'] = float( sxp.child_value( domInfo, 'start_time' ) )
|
||||
return d
|
||||
|
||||
def sxp2hash( sxp ):
|
||||
pass
|
||||
def sxp2hash( s ):
|
||||
sxphash = {}
|
||||
|
||||
for child in sxp.children( s ):
|
||||
sxphash[ child[0] ] = child[1]
|
||||
|
||||
return sxphash
|
||||
|
||||
def sxp2string( sxp ):
|
||||
class tmp:
|
||||
@@ -58,7 +63,12 @@ def stateFormatter( state ):
|
||||
return state
|
||||
|
||||
def memoryFormatter( mem ):
|
||||
return "%7dMb" % mem
|
||||
mem = int( mem )
|
||||
if mem >= 1024:
|
||||
mem = float( mem ) / 1024
|
||||
return "%3.2fGb" % mem
|
||||
else:
|
||||
return "%7dMb" % mem
|
||||
|
||||
def cpuFormatter( mhz ):
|
||||
if mhz > 1000:
|
||||
|
||||
@@ -366,6 +366,14 @@ class Xend:
|
||||
def xend_node(self):
|
||||
return self.xendGet(self.nodeurl())
|
||||
|
||||
def xend_node_shutdown(self):
|
||||
return self.xendPost(self.nodeurl(),
|
||||
{'op' : 'shutdown'})
|
||||
|
||||
def xend_node_restart(self):
|
||||
return self.xendPost(self.nodeurl(),
|
||||
{'op' : 'reboot'})
|
||||
|
||||
def xend_node_dmesg(self):
|
||||
return self.xendGet(self.dmesgurl())
|
||||
|
||||
|
||||