[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Manual merge.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 6c24d2b4f3eaf85e64879b03f159a2edce4e3719 # Parent d63b100b327ab8354bc9a71c38dbca436c64c0a5 # Parent df19d43b95d03054fa4534fe8449e0c05aaec1fc Manual merge. diff -r d63b100b327a -r 6c24d2b4f3ea tools/Makefile --- a/tools/Makefile Tue Jul 26 10:09:06 2005 +++ b/tools/Makefile Tue Jul 26 15:16:12 2005 @@ -13,6 +13,7 @@ SUBDIRS += pygrub SUBDIRS += firmware SUBDIRS += policy +SUBDIRS += sv .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/setup.py --- a/tools/python/setup.py Tue Jul 26 10:09:06 2005 +++ b/tools/python/setup.py Tue Jul 26 15:16:12 2005 @@ -51,6 +51,7 @@ 'xen.xend.xenstore', 'xen.xm', 'xen.web', + 'xen.sv' ], ext_package = "xen.lowlevel", ext_modules = [ xc, xu, xs ] diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/CreateDomain.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/CreateDomain.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,163 @@ +from xen.sv.Wizard import * +from xen.sv.util import * +from xen.sv.GenTabbed import PreTab + +from xen.xm.create import make_config, OptVals + +from xen.xend.XendClient import server + +class CreateDomain( Wizard ): + def __init__( self, urlWriter ): + + sheets = [ CreatePage0, + CreatePage1, + CreatePage2, + CreatePage3, + CreatePage4, + CreateFinish ] + + Wizard.__init__( self, urlWriter, "Create Domain", sheets ) + +class CreatePage0( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "General", 0 ) + self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) ) + self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) ) + self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) ) + self.addControl( InputControl( 'cpu_weight', '1', 'CPU Weight:', "[\\d]+", "You must enter a number in this feild" ) ) + +class CreatePage1( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 ) +# For now we don't need to select a builder... +# self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) ) + self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.6.9-xenU', 'Kernel Image:' ) ) + self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) ) + +class CreatePage2( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 ) + self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) ) + +class CreatePage3( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 ) + + def write_BODY( self, request, err ): + if not self.passback: self.parseForm( request ) + + previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference + + num_vbds = previous_values.get( 'num_vbds' ) + + for i in range( int( num_vbds ) ): + self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i ) ) + self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) ) + self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) ) + + self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) ) + + Sheet.write_BODY( self, request, err ) + +class CreatePage4( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Network settings", 4 ) + self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) ) + self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) ) + self.addControl( InputControl( 'ip_addr', '1.2.3.4', 'VM IP Address:' ) ) + self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) ) + self.addControl( InputControl( 'ip_gateway', '1.2.3.4', 'VM Gateway:' ) ) + self.addControl( InputControl( 'ip_nfs', '1.2.3.4', 'NFS Server:' ) ) + +class CreateFinish( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "All Done", 5 ) + + def write_BODY( self, request, err ): + + if not self.passback: self.parseForm( request ) + + xend_sxp = self.translate_sxp( string2sxp( self.passback ) ) + + try: + dom_sxp = server.xend_domain_create( xend_sxp ) + success = "Your domain was successfully created.\n" + except: + success = "There was an error creating your domain.\nThe configuration used is as follows:\n" + dom_sxp = xend_sxp + + + + pt = PreTab( success + sxp2prettystring( dom_sxp ) ) + pt.write_BODY( request ) + + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) + + def translate_sxp( self, fin_sxp ): + fin_hash = ssxp2hash( fin_sxp ) + + def get( key ): + ret = fin_hash.get( key ) + if ret: + return ret + else: + return "" + + vals = OptVals() + + vals.name = get( 'name' ) + vals.memory = get( 'memory' ) + vals.maxmem = get( 'maxmem' ) + vals.cpu = get( 'cpu' ) + vals.cpu_weight = get( 'cpu_weight' ) + + vals.builder = get( 'builder' ) + vals.kernel = get( 'kernel' ) + vals.root = get( 'root' ) + vals.extra = get( 'extra' ) + + #setup vbds + + vbds = [] + + for i in range( int( get( 'num_vbds' ) ) ): + vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) ) + + vals.disk = vbds + + #misc + + vals.pci = [] + + vals.blkif = None + vals.netif = None + vals.restart = None + vals.console = None + vals.ramdisk = None + + #setup vifs + + vals.vif = [] + vals.nics = 1 + + ip = get( 'ip_addr' ) + nfs = get( 'ip_nfs' ) + gate = get( 'ip_gateway' ) + mask = get( 'ip_subnet' ) + host = get( 'hostname' ) + dhcp = get( 'dhcp' ) + + vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp) + + try: + return make_config( vals ) + except: + return [["Error creating domain config."]] + diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/Daemon.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/Daemon.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,110 @@ +########################################################### +## XenSV Web Control Interface Daemon +## Copyright (C) 2004, K A Fraser (University of Cambridge) +## Copyright (C) 2004, Mike Wray <mike.wray@xxxxxx> +## Copyright (C) 2004, Tom Wilkie <tw275@xxxxxxxxx> +########################################################### + +import os +import os.path +import sys +import re + +from xen.sv.params import * + +from twisted.internet import reactor +from twisted.web import static, server, script + +from xen.util.ip import _readline, _readlines + +class Daemon: + """The xend daemon. + """ + def __init__(self): + self.shutdown = 0 + self.traceon = 0 + + def daemon_pids(self): + pids = [] + pidex = '(?P<pid>\d+)' + pythonex = '(?P<python>\S*python\S*)' + cmdex = '(?P<cmd>.*)' + procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$') + xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$') + procs = os.popen('ps -e -o pid,args 2>/dev/null') + for proc in procs: + pm = procre.match(proc) + if not pm: continue + xm = xendre.match(pm.group('cmd')) + if not xm: continue + #print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd') + pids.append(int(pm.group('pid'))) + return pids + + def new_cleanup(self, kill=0): + err = 0 + pids = self.daemon_pids() + if kill: + for pid in pids: + print "Killing daemon pid=%d" % pid + os.kill(pid, signal.SIGHUP) + elif pids: + err = 1 + print "Daemon already running: ", pids + return err + + def cleanup(self, kill=False): + # No cleanup to do if PID_FILE is empty. + if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE): + return 0 + # Read the pid of the previous invocation and search active process list. + pid = open(PID_FILE, 'r').read() + lines = _readlines(os.popen('ps ' + pid + ' 2>/dev/null')) + for line in lines: + if re.search('^ *' + pid + '.+xensv', line): + if not kill: + print "Daemon is already running (pid %d)" % int(pid) + return 1 + # Old daemon is still active: terminate it. + os.kill(int(pid), 1) + # Delete the stale PID_FILE. + os.remove(PID_FILE) + return 0 + + def start(self, trace=0): + if self.cleanup(kill=False): + return 1 + + # Fork -- parent writes PID_FILE and exits. + pid = os.fork() + if pid: + # Parent + pidfile = open(PID_FILE, 'w') + pidfile.write(str(pid)) + pidfile.close() + return 0 + # Child + self.run() + return 0 + + def stop(self): + return self.cleanup(kill=True) + + def run(self): + root = static.File( SV_ROOT ) + root.indexNames = [ 'Main.rpy' ] + root.processors = { '.rpy': script.ResourceScript } + reactor.listenTCP( SV_PORT, server.Site( root ) ) + reactor.run() + + def exit(self): + reactor.disconnectAll() + sys.exit(0) + +def instance(): + global inst + try: + inst + except: + inst = Daemon() + return inst diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/DomInfo.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/DomInfo.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,148 @@ +from xen.xend.XendClient import server +from xen.xend import PrettyPrint + +from xen.sv.HTMLBase import HTMLBase +from xen.sv.util import * +from xen.sv.GenTabbed import * + +DEBUG=1 + +class DomInfo( GenTabbed ): + + def __init__( self, urlWriter ): + + self.dom = 0; + + def tabUrlWriter( tab ): + return urlWriter( "&dom=%s%s" % ( self.dom, tab ) ) + + GenTabbed.__init__( self, "Domain Info", tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGeneralTab, DomSXPTab, NullTab ] ) + + def write_BODY( self, request ): + dom = request.args.get('dom') + + if dom is None or len(dom) != 1: + request.write( "<p>Please Select a Domain</p>" ) + return None + else: + self.dom = dom[0] + + GenTabbed.write_BODY( self, request ) + + def write_MENU( self, request ): + pass + +class DomGeneralTab( CompositeTab ): + def __init__( self ): + CompositeTab.__init__( self, [ DomGenTab, DomActionTab ] ) + +class DomGenTab( GeneralTab ): + + def __init__( self ): + + titles = {} + + titles[ 'ID' ] = 'dom' + titles[ 'Name' ] = 'name' + titles[ 'CPU' ] = 'cpu' + titles[ 'Memory' ] = ( 'mem', memoryFormatter ) + titles[ 'State' ] = ( 'state', stateFormatter ) + titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter ) + titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter ) + + GeneralTab.__init__( self, {}, titles ) + + def write_BODY( self, request ): + + self.dom = getVar('dom', request) + + if self.dom is None: + request.write( "<p>Please Select a Domain</p>" ) + return None + + self.dict = getDomInfoHash( self.dom ) + + GeneralTab.write_BODY( self, request ) + +class DomSXPTab( PreTab ): + + def __init__( self ): + self.dom = 0 + PreTab.__init__( self, "" ) + + + def write_BODY( self, request ): + self.dom = getVar('dom', request) + + if self.dom is None: + request.write( "<p>Please Select a Domain</p>" ) + return None + + try: + domInfo = server.xend_domain( self.dom ) + except: + domInfo = [["Error getting domain details."]] + + self.source = sxp2prettystring( domInfo ) + + PreTab.write_BODY( self, request ) + +class DomActionTab( ActionTab ): + + def __init__( self ): + actions = { "shutdown" : "shutdown", + "reboot" : "reboot", + "pause" : "pause", + "unpause" : "unpause", + "destroy" : "destroy" } + ActionTab.__init__( self, actions ) + + def op_shutdown( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != '0': + if DEBUG: print ">DomShutDown %s" % dom + try: + server.xend_domain_shutdown( int( dom ), "halt" ) + except: + pass + + def op_reboot( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != '0': + if DEBUG: print ">DomReboot %s" % dom + try: + server.xend_domain_shutdown( int( dom ), "reboot" ) + except: + pass + + def op_pause( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != '0': + if DEBUG: print ">DomPause %s" % dom + try: + server.xend_domain_pause( int( dom ) ) + except: + pass + + def op_unpause( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != '0': + if DEBUG: print ">DomUnpause %s" % dom + try: + server.xend_domain_unpause( int( dom ) ) + except: + pass + + def op_destroy( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != '0': + if DEBUG: print ">DomDestroy %s" % dom + try: + server.xend_domain_destroy( int( dom ), "halt" ) + except: + pass + + + + + diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/DomList.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/DomList.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,81 @@ +from xen.xend.XendClient import server +from xen.xend import sxp + +from xen.sv.HTMLBase import HTMLBase +from xen.sv.util import * + +class DomList( HTMLBase ): + + isLeaf = True + + def __init__( self, urlWriter ): + HTMLBase.__init__(self) + self.urlWriter = urlWriter + + def write_MENU( self, request ): + return self.write_BODY( request, head=True, long=False ) + + def write_BODY( self, request, head=True, long=True ): + + domains = [] + + try: + domains = server.xend_domains() + domains.sort() + except: + pass + + request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" ) + + if head: + request.write( "<tr class='domainInfoHead'>" ) + self.write_DOMAIN_HEAD( request, long ) + request.write( "</tr>" ) + + odd = True + + if not domains is None: + for domain in domains: + if odd: + request.write( "<tr class='domainInfoOdd'>\n" ) + odd = False + else: + request.write( "<tr class='domainInfoEven'>\n" ) + odd = True + self.write_DOMAIN( request, getDomInfoHash( domain ), long ) + request.write( "</tr>\n" ) + else: + request.write( "<tr colspan='10'><p class='small'>Error getting domain list<br/>Perhaps XenD not running?</p></tr>") + + request.write( "</table>\n" ) + + def write_DOMAIN( self, request, domInfoHash, long=True ): + request.write( "<td class='domainInfo' align='center'>%(id)s</td>\n" % domInfoHash ) + + url = self.urlWriter( "&mod=info&dom=%(id)s" % domInfoHash ) + + request.write( "<td class='domainInfo' align='center'><a href='%s'>%s</a></td>\n" % ( url, domInfoHash['name'] ) ) + if long: + request.write( "<td class='domainInfo' align='center'>%(memory)5s</td>\n" % domInfoHash ) + request.write( "<td class='domainInfo' align='center'>%(cpu)2s</td>\n" % domInfoHash ) + request.write( "<td class='domainInfo' align='center'>%(state)5s</td>\n" % domInfoHash ) + if domInfoHash[ 'id' ] != "0": + request.write( "<td class='domainInfo' align='center'>" ) + + if domInfoHash[ 'state' ][ 2 ] == "-": + request.write( "<img src='images/small-pause.png' onclick='doOp2( \"pause\", \"%(dom)-4s\" )'>" % domInfoHash ) + else: + request.write( "<img src='images/small-unpause.png' onclick='doOp2( \"unpause\", \"%(dom)-4s\" )'>" % domInfoHash ) + + request.write( "<img src='images/small-destroy.png' onclick='doOp2( \"destroy\", \"%(dom)-4s\" )'></td>" % domInfoHash) + else: + request.write( "<td> </td>" ) + + def write_DOMAIN_HEAD( self, request, long=True ): + request.write( "<td class='domainInfoHead' align='center'>Domain</td>\n" ) + request.write( "<td class='domainInfoHead' align='center'>Name</td>\n" ) + if long: + request.write( "<td class='domainInfoHead' align='center'>Memory / Mb</td>\n" ) + request.write( "<td class='domainInfoHead' align='center'>CPU</td>\n" ) + request.write( "<td class='domainInfoHead' align='center'>State</td>\n" ) + request.write( "<td class='domainInfoHead' align='center'></td>\n" ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/GenTabbed.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/GenTabbed.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,135 @@ +import types + +from xen.sv.HTMLBase import HTMLBase +from xen.sv.TabView import TabView +from xen.sv.util import getVar + +class GenTabbed( HTMLBase ): + + def __init__( self, title, urlWriter, tabStrings, tabObjects ): + HTMLBase.__init__(self) + self.tabStrings = tabStrings + self.tabObjects = tabObjects + self.urlWriter = urlWriter + self.title = title + + def write_BODY( self, request, urlWriter = None ): + try: + tab = int( getVar( 'tab', request, 0 ) ) + except: + tab = 0 + + 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( tab, self.tabStrings, self.urlWriter ).write_BODY( request ) + + request.write( "</td></tr><tr><td>" ) + + try: + render_tab = self.tabObjects[ tab ] + render_tab().write_BODY( request ) + except: + request.write( "<p>Error Rendering Tab</p>" ) + + request.write( "</td></tr></table>" ) + + def perform( self, request ): + try: + tab = int( getVar( 'tab', request, 0 ) ) + except: + tab = 0; + + op_tab = self.tabObjects[ tab ] + + if op_tab: + op_tab().perform( request ) + +class PreTab( HTMLBase ): + + def __init__( self, source ): + HTMLBase.__init__( self ) + self.source = source + + def write_BODY( self, request ): + + 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 ) + + request.write( "</pre></div>" ) + +class GeneralTab( HTMLBase ): + + def __init__( self, dict, titles ): + HTMLBase.__init__( self ) + self.dict = dict + self.titles = titles + + def write_BODY( self, request ): + + request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" ) + + def writeAttr( niceName, attr, formatter=None ): + if type( attr ) is types.TupleType: + ( attr, formatter ) = attr + + if attr in self.dict: + if formatter: + temp = formatter( self.dict[ attr ] ) + else: + temp = str( self.dict[ attr ] ) + request.write( "<tr><td width='50%%'><p>%s:</p></td><td width='50%%'><p>%s</p></td></tr>" % ( niceName, temp ) ) + + for niceName, attr in self.titles.items(): + writeAttr( niceName, attr ) + + request.write( "</table>" ) + +class NullTab( HTMLBase ): + + def __init__( self ): + HTMLBase.__init__( self ) + self.title = "Null Tab" + + def __init__( self, title ): + HTMLBase.__init__( self ) + self.title = title + + 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'><table cellspacing='3' cellpadding='2' border='0'><tr>" ) + + for ( command, text ) in self.actions.items(): + request.write( "<td style='border: 1px solid black; background-color: grey' onmouseover='buttonMouseOver( this )' onmouseout='buttonMouseOut( this )'>" ) + request.write( "<p><a href='javascript: doOp( \"%s\" );'>%s</a></p></td>" % (command, text) ) + + request.write("</table></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 ) + + + + diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/HTMLBase.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/HTMLBase.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,62 @@ +from xen.sv.util import * + +class HTMLBase: + + isLeaf = True + + def __init__( self ): + pass + + def render_POST( self, request ): + self.perform( request ) + return self.render_GET( request ) + + def render_GET( self, request ): + self.write_TOP( request ) + self.write_BODY( request ) + self.write_BOTTOM( request ) + return '' + + def write_BODY( self, request ): + request.write( "BODY" ) + + 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>' ) + request.write('<form method="post" action="%s">' % request.uri) + + def write_BOTTOM( self, request ): + request.write('<input type="hidden" name="op" value="">') + request.write('<input type="hidden" name="args" 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 ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/Main.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/Main.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,113 @@ +from xen.sv.HTMLBase import HTMLBase +from xen.sv.DomList import DomList +from xen.sv.NodeInfo import NodeInfo +from xen.sv.DomInfo import DomInfo +from xen.sv.CreateDomain import CreateDomain +from xen.sv.MigrateDomain import MigrateDomain +from xen.sv.SaveDomain import SaveDomain +from xen.sv.RestoreDomain import RestoreDomain + +from xen.xend.XendClient import server + +from xen.sv.util import getVar + +class Main( HTMLBase ): + + isLeaf = True + + def __init__( self, urlWriter = None ): + self.modules = { "node": NodeInfo, + "list": DomList, + "info": DomInfo, + "create": CreateDomain, + "migrate" : MigrateDomain, + "save" : SaveDomain, + "restore" : RestoreDomain } + + # ordered list of module menus to display + self.module_menus = [ "node", "create", "migrate", "save", + "restore", "list" ] + HTMLBase.__init__(self) + + def render_POST( self, request ): + + #decide what module post'd the action + + args = getVar( 'args', request ) + + mod = getVar( 'mod', request ) + + if not mod is None and args is None: + module = self.modules[ mod ] + #check module exists + if module: + module( self.mainUrlWriter ).perform( request ) + else: + self.perform( request ) + + return self.render_GET( request ) + + def mainUrlWriter( self, module ): + def fun( f ): + return "Main.rpy?mod=%s%s" % ( module, f ) + return fun + + def write_BODY( self, request ): + + request.write( "\n<table style='border:0px solid black; background: url(images/orb_01.jpg) no-repeat' cellspacing='0' cellpadding='0' border='0' width='780px' height='536px'>\n" ) + request.write( "<tr>\n" ) + request.write( " <td width='15px'> </td>" ) + request.write( " <td width='175px' align='center' valign'center'>" ) + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) + request.write( " <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" ) + request.write( " <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" ) + request.write( " <tr><td height='60px' align='center'><p class='small'>SV Web Interface<br/>(C) <a href='mailto:tw275@xxxxxxxxx'>Tom Wilkie</a> 2004</p></td></tr>") + request.write( " <tr><td align='center' valign='top'>" ) + + for modName in self.module_menus: + self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request ) + + request.write( " </td></tr>" ) + request.write( " </table>" ) + request.write( " " ) + request.write( " </td>\n" ) + request.write( " <td width='15px'> </td>" ) + request.write( " <td width='558px' align='left' valign='top'>" ) + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) + request.write( " <tr><td height='20px'></td></tr>" ) + request.write( " <tr><td align='center' valign='top'>" ) + + modName = getVar('mod', request) + + if modName is None: + request.write( '<p>Please select a module</p>' ) + else: + module = self.modules[ modName ] + if module: + module( self.mainUrlWriter( modName ) ).write_BODY( request ) + else: + request.write( '<p>Invalid module. Please select another</p>' ) + + request.write( " </td></tr>" ) + request.write( " </table>" ) + request.write( " </td>\n" ) + request.write( " <td width='17px'> </td>" ) + request.write( "</tr>\n" ) + + request.write( "</table>\n" ) + + + def op_destroy( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != "0": + server.xend_domain_destroy( int( dom ), "halt" ) + + def op_pause( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != "0": + server.xend_domain_pause( int( dom ) ) + + def op_unpause( self, request ): + dom = getVar( 'dom', request ) + if not dom is None and dom != "0": + server.xend_domain_unpause( int( dom ) ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/MigrateDomain.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/MigrateDomain.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,74 @@ +from xen.sv.Wizard import * +from xen.sv.util import * +from xen.sv.GenTabbed import PreTab + +from xen.xm.create import make_config, OptVals + +from xen.xend.XendClient import server + +class MigrateDomain( Wizard ): + def __init__( self, urlWriter ): + + sheets = [ ChooseMigrateDomain, + DoMigrate ] + + Wizard.__init__( self, urlWriter, "Migrate Domain", sheets ) + + +class ChooseMigrateDomain( Sheet ): + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Configure Migration", 0) + domains = [] + domnames = [] + + try: + domains = server.xend_domains() + domains.sort() + except: + pass + + for i in domains: + if i != 'Domain-0': domnames.append((i,i)) + + self.addControl( ListControl('domid', + domnames, + 'Domain ID:') ) + self.addControl( TickControl('live', + 'True', + 'Live migrate:') ) + self.addControl( InputControl('rate', + '0', + 'Rate limit:') ) + self.addControl( InputControl( 'dest', 'myhost.mydomain', + 'Name or IP address:', + ".*") ) + +class DoMigrate( Sheet ): + def __init__(self, urlWriter ): + Sheet.__init__(self, urlWriter, "Migration Done", 1) + + def write_BODY( self, request, err ): + + if not self.passback: self.parseForm( request ) + +# print string2sxp(self.passback) + + config = ssxp2hash ( string2sxp( self.passback ) ) + + try: + print config + print config['domid'], config['dest'] + dom_sxp = server.xend_domain_migrate( config['domid'], + config['dest'], + config.get('live') == 'True', + config['rate'] ) + success = "Your domain was successfully Migrated.\n" + except Exception, e: + success = "There was an error migrating your domain\n" + dom_sxp = str(e) + + pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) ) + pt.write_BODY( request ) + + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/NodeInfo.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/NodeInfo.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,63 @@ +from xen.xend.XendClient import server + +from xen.sv.util import * +from xen.sv.GenTabbed import * + +class NodeInfo( GenTabbed ): + + def __init__( self, urlWriter ): + GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', ], [ NodeGeneralTab, NodeDmesgTab ] ) + + def write_MENU( self, request ): + request.write( "<p class='small'><a href='%s'>Node details</a></p>" % self.urlWriter( '' ) ) + +class NodeGeneralTab( CompositeTab ): + def __init__( self ): + CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ] ) + +class NodeInfoTab( GeneralTab ): + + def __init__( self ): + + nodeInfo = {} + try: + nodeInfo = sxp2hash( server.xend_node() ) + except: + nodeInfo[ 'system' ] = 'Error getting node info' + + dictTitles = {} + dictTitles[ 'System' ] = 'system' + dictTitles[ 'Hostname' ] = 'host' + dictTitles[ 'Release' ] = 'release' + dictTitles[ 'Version' ] ='version' + dictTitles[ 'Machine' ] = 'machine' + dictTitles[ 'Cores' ] = 'cores' + dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter ) + dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter ) + dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter ) + dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter ) + + GeneralTab.__init__( self, dict=nodeInfo, titles=dictTitles ) + +class NodeDmesgTab( PreTab ): + + def __init__( self ): + try: + dmesg = server.xend_node_get_dmesg() + except: + dmesg = "Error getting node information: XenD not running?" + PreTab.__init__( self, dmesg ) + +class NodeActionTab( ActionTab ): + + def __init__( self ): + ActionTab.__init__( self, { "shutdown" : "shutdown", + "reboot" : "reboot" } ) + + def op_shutdown( self, request ): + if debug: print ">NodeShutDown" + server.xend_node_shutdown() + + def op_reboot( self, request ): + if debug: print ">NodeReboot" + server.xend_node_reboot() diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/RestoreDomain.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/RestoreDomain.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,46 @@ +from xen.sv.Wizard import * +from xen.sv.util import * +from xen.sv.GenTabbed import PreTab + +from xen.xm.create import make_config, OptVals + +from xen.xend.XendClient import server + +class RestoreDomain( Wizard ): + def __init__( self, urlWriter ): + + sheets = [ ChooseRestoreDomain, + DoRestore ] + + Wizard.__init__( self, urlWriter, "Restore Domain", sheets ) + + +class ChooseRestoreDomain( Sheet ): + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Configure Restore", 0) + + self.addControl( InputControl( 'file', '', + 'Suspend file name:', + ".*") ) + +class DoRestore( Sheet ): + def __init__(self, urlWriter ): + Sheet.__init__(self, urlWriter, "Restore Done", 1) + + def write_BODY( self, request, err ): + + if not self.passback: self.parseForm( request ) + config = ssxp2hash ( string2sxp( self.passback ) ) + + try: + dom_sxp = server.xend_domain_restore( config['file'] ) + success = "Your domain was successfully restored.\n" + except Exception, e: + success = "There was an error restoring your domain\n" + dom_sxp = str(e) + + pt = PreTab( success + sxp2prettystring( dom_sxp ) ) + pt.write_BODY( request ) + + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/SaveDomain.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/SaveDomain.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,62 @@ +from xen.sv.Wizard import * +from xen.sv.util import * +from xen.sv.GenTabbed import PreTab + +from xen.xm.create import make_config, OptVals + +from xen.xend.XendClient import server + +class SaveDomain( Wizard ): + def __init__( self, urlWriter ): + + sheets = [ ChooseSaveDomain, + DoSave ] + + Wizard.__init__( self, urlWriter, "Save Domain", sheets ) + + +class ChooseSaveDomain( Sheet ): + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Configure Save", 0) + + domains = [] + domnames = [] + + try: + domains = server.xend_domains() + domains.sort() + except: + pass + + for i in domains: + if i != 'Domain-0': domnames.append((i,i)) + + self.addControl( ListControl('domid', + domnames, + 'Domain ID:') ) + self.addControl( InputControl( 'file', '', + 'Suspend file name:', + ".*") ) + +class DoSave( Sheet ): + def __init__(self, urlWriter ): + Sheet.__init__(self, urlWriter, "Save Done", 1) + + def write_BODY( self, request, err ): + + if not self.passback: self.parseForm( request ) + config = ssxp2hash ( string2sxp( self.passback ) ) + + try: + dom_sxp = server.xend_domain_save( config['domid'], + config['file'] ) + success = "Your domain was successfully saved.\n" + except Exception, e: + success = "There was an error saving your domain\n" + dom_sxp = str(e) + + pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) ) + pt.write_BODY( request ) + + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/TabView.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/TabView.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,26 @@ +from xen.sv.HTMLBase import HTMLBase + +class TabView( HTMLBase ): + + # tab - int, id into tabs of selected tab + # tabs - list of strings, tab names + # urlWriter - + def __init__( self, tab, tabs, urlWriter ): + HTMLBase.__init__(self) + self.tab = tab + self.tabs = tabs + self.urlWriter = urlWriter + + def write_BODY( self, request ): + request.write( "<table style='' border='0' cellspacing='3' cellpadding='2' align='center'>" ) + request.write( "<tr height='22'>" ) + + for i in range( len( self.tabs ) ): + if self.tab == i: + backgroundColor = "white" + else: + backgroundColor = "grey" + + request.write( "<td style='border:1px solid black; background-color: %s'><p align='center'><a href='%s'>%s</a></p></td>" % ( backgroundColor, self.urlWriter( "&tab=%s" % i ), self.tabs[ i ] ) ) + + request.write( "</tr></table>" ) diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/Wizard.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/Wizard.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,269 @@ +from xen.sv.util import * +from xen.sv.HTMLBase import HTMLBase +from xen.xend import sxp + +import re + +DEBUG = 0 + +class Wizard( HTMLBase ): + + def __init__( self, urlWriter, title, sheets ): + HTMLBase.__init__( self ) + self.title = title + self.sheets = sheets + self.urlWriter = urlWriter + + def write_MENU( self, request ): + request.write( "<p class='small'><a href='%s'>%s</a></p>" % (self.urlWriter( '' ), self.title) ) + + def write_BODY( self, request ): + + request.write( "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr><td>" ) + request.write( "<p align='center'><u>%s</u></p></td></tr><tr><td>" % self.title ) + + currSheet = getVar( 'sheet', request ) + + if not currSheet is None: + currSheet = int( currSheet ) + else: + currSheet = 0 + + sheet = self.sheets[ currSheet ]( self.urlWriter ) + + err = not sheet.validate( request ) + + if not err: + op = getVar( 'op', request ) + + if op == 'next': + currSheet += 1 + elif op == 'prev': + currSheet -= 1 + + sheet = self.sheets[ currSheet ]( self.urlWriter ) + + if getVar( 'visited-sheet%s' % currSheet, request ): + sheet.write_BODY( request, err ) + else: + sheet.write_BODY( request, False ) + + + request.write( "</td></tr><tr><td><table width='100%' border='0' cellspacing='0' cellpadding='0'><tr>" ) + request.write( "<td width='80%'></td><td width='20%' align='center'><p align='center'>" ) + if currSheet > 0: + request.write( "<img src='images/previous.png' onclick='doOp( \"prev\" )' onmouseover='update( \"wizText\", \"Previous\" )' onmouseout='update( \"wizText\", \" \" )'> " ) + if currSheet < ( len( self.sheets ) - 2 ): + request.write( "<img src='images/next.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Next\" )' onmouseout='update( \"wizText\", \" \" )'>" ) + elif currSheet == ( len( self.sheets ) - 2 ): + request.write( "<img src='images/finish.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Finish\" )' onmouseout='update( \"wizText\", \" \" )'>" ) + request.write( "</p><p align='center'><span id='wizText'></span></p></td></tr></table>" ) + request.write( "</td></tr></table>" ) + + def op_next( self, request ): + pass + + def op_prev( self, request ): + pass + + def op_finish( self, request ): + pass + +class Sheet( HTMLBase ): + + def __init__( self, urlWriter, title, location ): + HTMLBase.__init__( self ) + self.urlWriter = urlWriter + self.feilds = [] + self.title = title + self.location = location + self.passback = None + + def parseForm( self, request ): + do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ] + + passed_back = request.args + + temp_passback = passed_back.get( "passback" ) + + if temp_passback is not None and len( temp_passback ) > 0: + temp_passback = temp_passback[ len( temp_passback )-1 ] + else: + temp_passback = "( )" + + last_passback = ssxp2hash( string2sxp( temp_passback ) ) #use special function - will work with no head on sxp + + if DEBUG: print last_passback + + for (key, value) in passed_back.items(): + if key not in do_not_parse: + last_passback[ key ] = value[ len( value ) - 1 ] + + self.passback = sxp2string( hash2sxp( last_passback ) ) #store the sxp + + if DEBUG: print self.passback + + def write_BODY( self, request, err ): + + if not self.passback: self.parseForm( request ) + + request.write( "<p>%s</p>" % self.title ) + + previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference + + request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" ) + + for (feild, control) in self.feilds: + control.write_Control( request, previous_values.get( feild ) ) + if err and not control.validate( previous_values.get( feild ) ): + control.write_Help( request ) + + request.write( "</table>" ) + + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) + request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location ) + + def addControl( self, control ): + self.feilds.append( [ control.getName(), control ] ) + + def validate( self, request ): + + if not self.passback: self.parseForm( request ) + + check = True + + previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference + if DEBUG: print previous_values + + for (feild, control) in self.feilds: + if not control.validate( previous_values.get( feild ) ): + check = False + if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild )) + + return check + +class SheetControl( HTMLBase ): + + def __init__( self, reg_exp = ".*" ): + HTMLBase.__init__( self ) + self.name = "" + self.reg_exp = reg_exp + + def write_Control( self, request, persistedValue ): + request.write( "<tr colspan='2'><td>%s</td></tr>" % persistedValue ) + + def write_Help( self, request ): + request.write( "<tr><td align='right' colspan='2'><p class='small'>Text must match pattern:" ) + request.write( " %s</p></td></tr>" % self.reg_exp ) + + def validate( self, persistedValue ): + if persistedValue is None: + persistedValue = "" + + return not re.compile( self.reg_exp ).match( persistedValue ) is None + + def getName( self ): + return self.name + + def setName( self, name ): + self.name = name + +class InputControl( SheetControl ): + + def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ): + SheetControl.__init__( self, reg_exp ) + self.setName( name ) + + self.defaultValue = defaultValue + self.humanText = humanText + self.help_text = help_text + + def write_Control( self, request, persistedValue ): + if persistedValue is None: + persistedValue = self.defaultValue + + request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'><input size='40'type='text' name='%s' value=\"%s\"></td></tr>" % (self.humanText, self.getName(), persistedValue) ) + + def write_Help( self, request ): + request.write( "<tr><td align='right' colspan='2'><p class='small'>" ) + request.write( " %s</p></td></tr>" % self.help_text ) + +class TextControl( SheetControl ): + + def __init__( self, text ): + SheetControl.__init__( self ) + self.text = text + + def write_Control( self, request, persistedValue ): + request.write( "<tr><td colspan='2'><p>%s</p></td></tr>" % self.text ) + +class SmallTextControl( SheetControl ): + + def __init__( self, text ): + SheetControl.__init__( self ) + self.text = text + + def write_Control( self, request, persistedValue ): + request.write( "<tr><td colspan='2'><p class='small'>%s</p></tr></td>" % self.text ) + +class ListControl( SheetControl ): + + def __init__( self, name, options, humanText ): + SheetControl.__init__( self ) + self.setName( name ) + self.options = options + self.humanText = humanText + + def write_Control( self, request, persistedValue ): + request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText ) + request.write( "<select name='%s'>" % self.getName() ) + for (value, text) in self.options: + if value == persistedValue: + request.write( "<option value='%s' selected>%s\n" % (value, text) ) + else: + request.write( "<option value='%s'>%s\n" % (value, text) ) + request.write( "</select></td></tr>" ) + + def validate( self, persistedValue ): + for (value, text) in self.options: + if value == persistedValue: + return True + + return False + +class FileControl( InputControl ): + + def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ): + InputControl.__init__( self, name, defaultValue, humanText ) + + def validate( self, persistedValue ): + if persistedValue is None: return False + try: + open( persistedValue ) + return True + except IOError, TypeError: + return False + + def write_Help( self, request ): + request.write( "<tr><td colspan='2' align='right'><p class='small'>File does not exist: you must enter a valid, absolute file path.</p></td></tr>" ) + +class TickControl( SheetControl ): + + def __init__( self, name, defaultValue, humanText ): + SheetControl.__init__( self ) + self.setName( name ) + self.defaultValue = defaultValue + self.humanText = humanText + + def write_Control( self, request, persistedValue ): + request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText ) + + if persistedValue == 'True': + request.write( "<input type='checkbox' name='%s' value='True' checked>" % self.getName() ) + else: + request.write( "<input type='checkbox' name='%s' value='True'>" % self.getName() ) + + request.write( "</select></td></tr>" ) + + diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/__init__.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/__init__.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,1 @@ + diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/params.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/params.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,3 @@ +SV_PORT = 8080 +SV_ROOT = "/var/lib/xen/sv/" +PID_FILE = "/var/run/xen-sv.pid" diff -r d63b100b327a -r 6c24d2b4f3ea tools/python/xen/sv/util.py --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/python/xen/sv/util.py Tue Jul 26 15:16:12 2005 @@ -0,0 +1,126 @@ +from xen.xend.XendClient import server +from xen.xend import sxp +from xen.xend import PrettyPrint + +import types + +def getDomInfoHash( domain ): + domInfoHash = {} + try: + domInfoHash = sxp2hash( server.xend_domain( domain ) ) + domInfoHash['dom'] = domain + except: + domInfoHash['name'] = "Error getting domain details" + return domInfoHash + +def sxp2hash( s ): + sxphash = {} + + for child in sxp.children( s ): + if isinstance( child, types.ListType ) and len( child ) > 1: + if isinstance( child[1], types.ListType ) and len( child ) > 1: + sxphash[ child[0] ] = sxp2hash( child[1] ) + else: + sxphash[ child[0] ] = child[1] + + return sxphash + +def ssxp2hash( s ): + sxphash = {} + + for i in s: + if isinstance( i, types.ListType ) and len( i ) > 1: + sxphash[ i[0] ] = i[1] + + return sxphash + +def hash2sxp( h ): + hashsxp = [] + + for (key, item) in h.items(): + hashsxp.append( [key, item] ) + + return hashsxp + +def string2sxp( string ): + pin = sxp.Parser() + pin.input( string ) + return pin.get_val() + +def sxp2string( sexp ): + return sxp.to_string( sexp ) + +def sxp2prettystring( sxp ): + class tmp: + def __init__( self ): + self.str = "" + def write( self, str ): + self.str = self.str + str + temp = tmp() + PrettyPrint.prettyprint( sxp, out=temp ) + return temp.str + +def getVar( var, request, default=None ): + + arg = request.args.get( var ) + + if arg is None: + return default + else: + return arg[ len( arg )-1 ] + +def bigTimeFormatter( time ): + time = float( time ) + weeks = time // 604800 + remainder = time % 604800 + days = remainder // 86400 + + remainder = remainder % 86400 + + hms = smallTimeFormatter( remainder ) + + return "%d weeks, %d days, %s" % ( weeks, days, hms ) + +def smallTimeFormatter( time ): + time = float( time ) + hours = time // 3600 + remainder = time % 3600 + mins = remainder // 60 + secs = time % 60 + return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs ) + +def stateFormatter( state ): + states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ] + + stateStr = "" + + for i in range( len( state ) ): + if state[i] != "-": + stateStr += "%s, " % states[ i ] + + return stateStr + " (%s)" % state + +def memoryFormatter( mem ): + mem = int( mem ) + if mem >= 1024: + mem = float( mem ) / 1024 + return "%3.2fGb" % mem + else: + return "%7dMb" % mem + +def cpuFormatter( mhz ): + mhz = int( mhz ) + if mhz > 1000: + ghz = float( mhz ) / 1000.0 + return "%4.2fGHz" % ghz + else: + return "%4dMHz" % mhz + +def hyperthreadFormatter( threads ): + try: + if int( threads ) > 1: + return "Yes" + else: + return "No" + except: + return "No" diff -r d63b100b327a -r 6c24d2b4f3ea tools/sv/Makefile --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/sv/Makefile Tue Jul 26 15:16:12 2005 @@ -0,0 +1,2 @@ + +all: diff -r d63b100b327a -r 6c24d2b4f3ea tools/sv/images/destroy.png --- /dev/null Tue Jul 26 10:09:06 2005 +++ b/tools/sv/images/destroy.png Tue Jul 26 15:16:12 2005 @@ -0,0 +1,23 @@ +?PNG + + \ No newline at end of file +IHDR 6 6 ?EjÝ |