ia64/xen-unstable

changeset 5861:df19d43b95d0

Add XenSV back into the repository.
Now uses Python Server Pages, not twisted.
author twilkie@paploo.uk.xensource.com
date Tue Jul 26 13:56:30 2005 +0000 (2005-07-26)
parents ecb17ef5a587
children 6c24d2b4f3ea
files tools/Makefile tools/python/setup.py tools/python/xen/sv/CreateDomain.py tools/python/xen/sv/Daemon.py tools/python/xen/sv/DomInfo.py tools/python/xen/sv/DomList.py tools/python/xen/sv/GenTabbed.py tools/python/xen/sv/HTMLBase.py tools/python/xen/sv/Main.py tools/python/xen/sv/MigrateDomain.py tools/python/xen/sv/NodeInfo.py tools/python/xen/sv/RestoreDomain.py tools/python/xen/sv/SaveDomain.py tools/python/xen/sv/TabView.py tools/python/xen/sv/Wizard.py tools/python/xen/sv/__init__.py tools/python/xen/sv/params.py tools/python/xen/sv/util.py tools/sv/Makefile tools/sv/images/destroy.png tools/sv/images/finish.png tools/sv/images/internet copy.jpg tools/sv/images/internet.jpg tools/sv/images/internet.psd tools/sv/images/next.png tools/sv/images/orb_01.jpg tools/sv/images/orb_02.jpg tools/sv/images/pause.png tools/sv/images/previous.png tools/sv/images/reboot.png tools/sv/images/seperator-left-highlight.jpg tools/sv/images/seperator-right-highlight.jpg tools/sv/images/seperator.jpg tools/sv/images/shutdown.png tools/sv/images/small-destroy.png tools/sv/images/small-pause.png tools/sv/images/small-unpause.png tools/sv/images/unpause.png tools/sv/images/xen.png tools/sv/inc/script.js tools/sv/inc/style.css tools/sv/index.psp
line diff
     1.1 --- a/tools/Makefile	Mon Jul 25 21:19:14 2005 +0000
     1.2 +++ b/tools/Makefile	Tue Jul 26 13:56:30 2005 +0000
     1.3 @@ -13,6 +13,7 @@ SUBDIRS += xcutils
     1.4  SUBDIRS += pygrub
     1.5  SUBDIRS += firmware
     1.6  SUBDIRS += policy
     1.7 +SUBDIRS += sv
     1.8  
     1.9  .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
    1.10  
     2.1 --- a/tools/python/setup.py	Mon Jul 25 21:19:14 2005 +0000
     2.2 +++ b/tools/python/setup.py	Tue Jul 26 13:56:30 2005 +0000
     2.3 @@ -51,6 +51,7 @@ setup(name            = 'xen',
     2.4                           'xen.xend.xenstore',
     2.5                           'xen.xm',
     2.6                           'xen.web',
     2.7 +						 'xen.sv'
     2.8                           ],
     2.9        ext_package = "xen.lowlevel",
    2.10        ext_modules = [ xc, xu, xs ]
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/python/xen/sv/CreateDomain.py	Tue Jul 26 13:56:30 2005 +0000
     3.3 @@ -0,0 +1,163 @@
     3.4 +from xen.sv.Wizard import *
     3.5 +from xen.sv.util import *
     3.6 +from xen.sv.GenTabbed import PreTab
     3.7 +
     3.8 +from xen.xm.create import make_config, OptVals
     3.9 +
    3.10 +from xen.xend.XendClient import server
    3.11 +
    3.12 +class CreateDomain( Wizard ):
    3.13 +    def __init__( self, urlWriter ):
    3.14 +    	
    3.15 +    	sheets = [ CreatePage0,
    3.16 +          	   CreatePage1,
    3.17 +          	   CreatePage2,
    3.18 +                   CreatePage3,
    3.19 +                   CreatePage4,
    3.20 +                   CreateFinish ]
    3.21 +    
    3.22 +    	Wizard.__init__( self, urlWriter, "Create Domain", sheets )
    3.23 +       
    3.24 +class CreatePage0( Sheet ):
    3.25 +
    3.26 +    def __init__( self, urlWriter ):
    3.27 +        Sheet.__init__( self, urlWriter, "General", 0 )
    3.28 +        self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) )
    3.29 +        self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) )
    3.30 +        self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) )
    3.31 +        self.addControl( InputControl( 'cpu_weight', '1', 'CPU Weight:', "[\\d]+", "You must enter a number in this feild" ) )
    3.32 +                        
    3.33 +class CreatePage1( Sheet ):
    3.34 +
    3.35 +    def __init__( self, urlWriter ):
    3.36 +        Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 )
    3.37 +# For now we don't need to select a builder...
    3.38 +#        self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) )
    3.39 +        self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.6.9-xenU', 'Kernel Image:' ) )
    3.40 +        self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) )
    3.41 +
    3.42 +class CreatePage2( Sheet ):
    3.43 +
    3.44 +    def __init__( self, urlWriter ):
    3.45 +    	Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 )
    3.46 +        self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) )
    3.47 +
    3.48 +class CreatePage3( Sheet ):
    3.49 +
    3.50 +    def __init__( self, urlWriter ):
    3.51 +        Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 )
    3.52 +        
    3.53 +    def write_BODY( self, request, err ):
    3.54 +        if not self.passback: self.parseForm( request )
    3.55 +    
    3.56 +    	previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
    3.57 +        
    3.58 +        num_vbds = previous_values.get( 'num_vbds' )
    3.59 +        
    3.60 +        for i in range( int( num_vbds ) ):
    3.61 +            self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i  ) )
    3.62 +            self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) )
    3.63 +            self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) )
    3.64 +            
    3.65 +        self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) )
    3.66 +        
    3.67 +        Sheet.write_BODY( self, request, err )
    3.68 +                
    3.69 +class CreatePage4( Sheet ):
    3.70 +
    3.71 +    def __init__( self, urlWriter ):        
    3.72 +        Sheet.__init__( self, urlWriter, "Network settings", 4 )
    3.73 +        self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) )
    3.74 +        self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) )
    3.75 +        self.addControl( InputControl( 'ip_addr', '1.2.3.4', 'VM IP Address:' ) )
    3.76 +        self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) ) 
    3.77 +        self.addControl( InputControl( 'ip_gateway', '1.2.3.4', 'VM Gateway:' ) )           
    3.78 +        self.addControl( InputControl( 'ip_nfs', '1.2.3.4', 'NFS Server:' ) )  
    3.79 +                 
    3.80 +class CreateFinish( Sheet ):
    3.81 +
    3.82 +    def __init__( self, urlWriter ):
    3.83 +        Sheet.__init__( self, urlWriter, "All Done", 5 )
    3.84 +        
    3.85 +    def write_BODY( self, request, err ):
    3.86 +    
    3.87 +        if not self.passback: self.parseForm( request )
    3.88 +        
    3.89 +        xend_sxp = self.translate_sxp( string2sxp( self.passback ) )
    3.90 +        
    3.91 +        try:
    3.92 +            dom_sxp = server.xend_domain_create( xend_sxp )
    3.93 +            success = "Your domain was successfully created.\n"
    3.94 +        except:
    3.95 +            success = "There was an error creating your domain.\nThe configuration used is as follows:\n"
    3.96 +            dom_sxp = xend_sxp
    3.97 +            
    3.98 +            
    3.99 +        
   3.100 +        pt = PreTab( success + sxp2prettystring( dom_sxp ) )
   3.101 +        pt.write_BODY( request )
   3.102 +
   3.103 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   3.104 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
   3.105 +    
   3.106 +    def translate_sxp( self, fin_sxp ):
   3.107 +   	fin_hash = ssxp2hash( fin_sxp )
   3.108 +    
   3.109 +        def get( key ):
   3.110 +            ret = fin_hash.get( key )
   3.111 +            if ret:
   3.112 +                return ret
   3.113 +            else:
   3.114 +                return ""
   3.115 +        
   3.116 +    	vals = OptVals()
   3.117 +        
   3.118 +        vals.name = 	get( 'name' )
   3.119 +        vals.memory = 	get( 'memory' )
   3.120 +        vals.maxmem =   get( 'maxmem' )
   3.121 +        vals.cpu =  	get( 'cpu' )
   3.122 +        vals.cpu_weight = get( 'cpu_weight' )
   3.123 +        
   3.124 +        vals.builder =  get( 'builder' )       
   3.125 +        vals.kernel =   get( 'kernel' )
   3.126 +	vals.root = 	get( 'root' )
   3.127 +        vals.extra = 	get( 'extra' )
   3.128 +        
   3.129 +        #setup vbds
   3.130 +        
   3.131 +        vbds = []
   3.132 +        
   3.133 +        for i in range( int( get( 'num_vbds' ) ) ):
   3.134 +            vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) )
   3.135 +        
   3.136 +        vals.disk = vbds    
   3.137 +            
   3.138 +        #misc
   3.139 +        
   3.140 +        vals.pci = []
   3.141 +        
   3.142 +        vals.blkif = None
   3.143 +        vals.netif = None
   3.144 +        vals.restart = None
   3.145 +        vals.console = None
   3.146 +        vals.ramdisk = None
   3.147 +        
   3.148 +        #setup vifs
   3.149 +        
   3.150 +        vals.vif = []
   3.151 +        vals.nics = 1
   3.152 +                
   3.153 +        ip =   get( 'ip_addr' )
   3.154 +        nfs =  get( 'ip_nfs' )
   3.155 +        gate = get( 'ip_gateway' )
   3.156 +        mask = get( 'ip_subnet' )
   3.157 +        host = get( 'hostname' )
   3.158 +        dhcp = get( 'dhcp' )
   3.159 +        
   3.160 +        vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp)
   3.161 +        
   3.162 +        try:
   3.163 +            return make_config( vals )
   3.164 +        except:
   3.165 +            return [["Error creating domain config."]]    
   3.166 +        
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/python/xen/sv/Daemon.py	Tue Jul 26 13:56:30 2005 +0000
     4.3 @@ -0,0 +1,110 @@
     4.4 +###########################################################
     4.5 +## XenSV Web Control Interface Daemon
     4.6 +## Copyright (C) 2004, K A Fraser (University of Cambridge)
     4.7 +## Copyright (C) 2004, Mike Wray <mike.wray@hp.com>
     4.8 +## Copyright (C) 2004, Tom Wilkie <tw275@cam.ac.uk>
     4.9 +###########################################################
    4.10 +
    4.11 +import os
    4.12 +import os.path
    4.13 +import sys
    4.14 +import re
    4.15 +
    4.16 +from xen.sv.params import *
    4.17 +
    4.18 +from twisted.internet import reactor
    4.19 +from twisted.web import static, server, script
    4.20 +
    4.21 +from xen.util.ip import _readline, _readlines
    4.22 +
    4.23 +class Daemon:
    4.24 +    """The xend daemon.
    4.25 +    """
    4.26 +    def __init__(self):
    4.27 +        self.shutdown = 0
    4.28 +        self.traceon = 0
    4.29 +
    4.30 +    def daemon_pids(self):
    4.31 +        pids = []
    4.32 +        pidex = '(?P<pid>\d+)'
    4.33 +        pythonex = '(?P<python>\S*python\S*)'
    4.34 +        cmdex = '(?P<cmd>.*)'
    4.35 +        procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$')
    4.36 +        xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$')
    4.37 +        procs = os.popen('ps -e -o pid,args 2>/dev/null')
    4.38 +        for proc in procs:
    4.39 +            pm = procre.match(proc)
    4.40 +            if not pm: continue
    4.41 +            xm = xendre.match(pm.group('cmd'))
    4.42 +            if not xm: continue
    4.43 +            #print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd')
    4.44 +            pids.append(int(pm.group('pid')))
    4.45 +        return pids
    4.46 +
    4.47 +    def new_cleanup(self, kill=0):
    4.48 +        err = 0
    4.49 +        pids = self.daemon_pids()
    4.50 +        if kill:
    4.51 +            for pid in pids:
    4.52 +                print "Killing daemon pid=%d" % pid
    4.53 +                os.kill(pid, signal.SIGHUP)
    4.54 +        elif pids:
    4.55 +            err = 1
    4.56 +            print "Daemon already running: ", pids
    4.57 +        return err
    4.58 +            
    4.59 +    def cleanup(self, kill=False):
    4.60 +        # No cleanup to do if PID_FILE is empty.
    4.61 +        if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE):
    4.62 +            return 0
    4.63 +        # Read the pid of the previous invocation and search active process list.
    4.64 +        pid = open(PID_FILE, 'r').read()
    4.65 +        lines = _readlines(os.popen('ps ' + pid + ' 2>/dev/null'))
    4.66 +        for line in lines:
    4.67 +            if re.search('^ *' + pid + '.+xensv', line):
    4.68 +                if not kill:
    4.69 +                    print "Daemon is already running (pid %d)" % int(pid)
    4.70 +                    return 1
    4.71 +                # Old daemon is still active: terminate it.
    4.72 +                os.kill(int(pid), 1)
    4.73 +        # Delete the stale PID_FILE.
    4.74 +        os.remove(PID_FILE)
    4.75 +        return 0
    4.76 +
    4.77 +    def start(self, trace=0):
    4.78 +        if self.cleanup(kill=False):
    4.79 +            return 1
    4.80 +   
    4.81 +        # Fork -- parent writes PID_FILE and exits.
    4.82 +        pid = os.fork()
    4.83 +        if pid:
    4.84 +            # Parent
    4.85 +            pidfile = open(PID_FILE, 'w')
    4.86 +            pidfile.write(str(pid))
    4.87 +            pidfile.close()
    4.88 +            return 0
    4.89 +        # Child
    4.90 +        self.run()
    4.91 +        return 0
    4.92 +
    4.93 +    def stop(self):
    4.94 +        return self.cleanup(kill=True)
    4.95 +
    4.96 +    def run(self):
    4.97 +	root = static.File( SV_ROOT )
    4.98 +        root.indexNames = [ 'Main.rpy' ]
    4.99 +        root.processors = { '.rpy': script.ResourceScript }
   4.100 +        reactor.listenTCP( SV_PORT, server.Site( root ) )
   4.101 +        reactor.run()
   4.102 +
   4.103 +    def exit(self):
   4.104 +        reactor.disconnectAll()
   4.105 +        sys.exit(0)
   4.106 +
   4.107 +def instance():
   4.108 +    global inst
   4.109 +    try:
   4.110 +        inst
   4.111 +    except:
   4.112 +        inst = Daemon()
   4.113 +    return inst
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/python/xen/sv/DomInfo.py	Tue Jul 26 13:56:30 2005 +0000
     5.3 @@ -0,0 +1,148 @@
     5.4 +from xen.xend.XendClient import server
     5.5 +from xen.xend import PrettyPrint
     5.6 +
     5.7 +from xen.sv.HTMLBase import HTMLBase
     5.8 +from xen.sv.util import *
     5.9 +from xen.sv.GenTabbed import *
    5.10 +
    5.11 +DEBUG=1
    5.12 +
    5.13 +class DomInfo( GenTabbed ):
    5.14 +
    5.15 +    def __init__( self, urlWriter ):
    5.16 +        
    5.17 +        self.dom = 0;
    5.18 +    
    5.19 +        def tabUrlWriter( tab ):
    5.20 +            return urlWriter( "&dom=%s%s" % ( self.dom, tab ) )
    5.21 +        
    5.22 +        GenTabbed.__init__( self, "Domain Info", tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGeneralTab, DomSXPTab, NullTab ]  )
    5.23 +
    5.24 +    def write_BODY( self, request ):
    5.25 +        dom = request.args.get('dom')
    5.26 +        
    5.27 +        if dom is None or len(dom) != 1:
    5.28 +            request.write( "<p>Please Select a Domain</p>" )
    5.29 +            return None
    5.30 +        else:
    5.31 +            self.dom = dom[0]
    5.32 +        
    5.33 +        GenTabbed.write_BODY( self, request )
    5.34 +        
    5.35 +    def write_MENU( self, request ):
    5.36 +        pass
    5.37 +
    5.38 +class DomGeneralTab( CompositeTab ):
    5.39 +    def __init__( self ):
    5.40 +       CompositeTab.__init__( self, [ DomGenTab, DomActionTab ] )        
    5.41 +        
    5.42 +class DomGenTab( GeneralTab ):
    5.43 +
    5.44 +    def __init__( self ):
    5.45 +    
    5.46 +        titles = {}
    5.47 +    
    5.48 +        titles[ 'ID' ] = 'dom'      
    5.49 +        titles[ 'Name' ] = 'name'
    5.50 +        titles[ 'CPU' ] = 'cpu'
    5.51 +        titles[ 'Memory' ] = ( 'mem', memoryFormatter )
    5.52 +        titles[ 'State' ] = ( 'state', stateFormatter )
    5.53 +        titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter )
    5.54 +        titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter )
    5.55 +    
    5.56 +        GeneralTab.__init__( self, {}, titles )
    5.57 +        
    5.58 +    def write_BODY( self, request ):
    5.59 +    
    5.60 +        self.dom = getVar('dom', request)
    5.61 +        
    5.62 +        if self.dom is None:
    5.63 +            request.write( "<p>Please Select a Domain</p>" )
    5.64 +            return None
    5.65 +            
    5.66 +        self.dict = getDomInfoHash( self.dom )
    5.67 +        
    5.68 +        GeneralTab.write_BODY( self, request )
    5.69 +            
    5.70 +class DomSXPTab( PreTab ):
    5.71 +
    5.72 +    def __init__( self ):
    5.73 +        self.dom = 0
    5.74 +        PreTab.__init__( self, "" )
    5.75 +
    5.76 +
    5.77 +    def write_BODY( self, request ):
    5.78 +        self.dom = getVar('dom', request)
    5.79 +        
    5.80 +        if self.dom is None:
    5.81 +            request.write( "<p>Please Select a Domain</p>" )
    5.82 +            return None
    5.83 +
    5.84 +        try:
    5.85 +            domInfo = server.xend_domain( self.dom )
    5.86 +        except:
    5.87 +            domInfo = [["Error getting domain details."]]
    5.88 +            
    5.89 +        self.source = sxp2prettystring( domInfo )
    5.90 +        
    5.91 +        PreTab.write_BODY( self, request )
    5.92 +        
    5.93 +class DomActionTab( ActionTab ):
    5.94 +
    5.95 +    def __init__( self ):
    5.96 +    	actions = { "shutdown" : "shutdown",
    5.97 +        	    "reboot" : "reboot",
    5.98 +                    "pause" : "pause",
    5.99 +                    "unpause" : "unpause",
   5.100 +                    "destroy" : "destroy" }
   5.101 +        ActionTab.__init__( self, actions )    
   5.102 +        
   5.103 +    def op_shutdown( self, request ):
   5.104 +   	dom = getVar( 'dom', request )
   5.105 +        if not dom is None and dom != '0':
   5.106 +    	   if DEBUG: print ">DomShutDown %s" % dom
   5.107 +           try:
   5.108 +    	   	server.xend_domain_shutdown( int( dom ), "halt" )
   5.109 +           except:
   5.110 +           	pass
   5.111 +    
   5.112 +    def op_reboot( self, request ):
   5.113 +       	dom = getVar( 'dom', request )
   5.114 +        if not dom is None and dom != '0':
   5.115 +    	    if DEBUG: print ">DomReboot %s" % dom
   5.116 +            try:
   5.117 +            	server.xend_domain_shutdown( int( dom ), "reboot" )
   5.118 +            except:
   5.119 +            	pass
   5.120 +                
   5.121 +    def op_pause( self, request ):
   5.122 +       	dom = getVar( 'dom', request )
   5.123 +        if not dom is None and dom != '0':
   5.124 +    	    if DEBUG: print ">DomPause %s" % dom
   5.125 +            try:
   5.126 +                server.xend_domain_pause( int( dom ) )
   5.127 +            except:
   5.128 +            	pass
   5.129 +               
   5.130 +    def op_unpause( self, request ):
   5.131 +       	dom = getVar( 'dom', request )
   5.132 +        if not dom is None and dom != '0':
   5.133 +    	   if DEBUG: print ">DomUnpause %s" % dom
   5.134 +           try:
   5.135 +               server.xend_domain_unpause( int( dom ) )
   5.136 +    	   except:
   5.137 +               pass
   5.138 +               
   5.139 +    def op_destroy( self, request ):
   5.140 +    	dom = getVar( 'dom', request )
   5.141 +        if not dom is None and dom != '0':
   5.142 +    	   if DEBUG: print ">DomDestroy %s" % dom
   5.143 +           try:
   5.144 +           	server.xend_domain_destroy( int( dom ), "halt" )
   5.145 +           except:
   5.146 +           	pass
   5.147 +        
   5.148 +    
   5.149 +    
   5.150 +        
   5.151 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/python/xen/sv/DomList.py	Tue Jul 26 13:56:30 2005 +0000
     6.3 @@ -0,0 +1,81 @@
     6.4 +from xen.xend.XendClient import server
     6.5 +from xen.xend import sxp
     6.6 +
     6.7 +from xen.sv.HTMLBase import HTMLBase
     6.8 +from xen.sv.util import *
     6.9 +
    6.10 +class DomList( HTMLBase ):
    6.11 +    
    6.12 +    isLeaf = True
    6.13 +
    6.14 +    def __init__( self, urlWriter ):
    6.15 +        HTMLBase.__init__(self)
    6.16 +        self.urlWriter = urlWriter
    6.17 +        
    6.18 +    def write_MENU( self, request ):
    6.19 +    	return self.write_BODY( request, head=True, long=False ) 
    6.20 +
    6.21 +    def write_BODY( self, request, head=True, long=True ):
    6.22 +        
    6.23 +    	domains = []
    6.24 +    
    6.25 +        try:
    6.26 +            domains = server.xend_domains()
    6.27 +            domains.sort()
    6.28 +  	except:
    6.29 +            pass
    6.30 +                
    6.31 +        request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" )
    6.32 +        
    6.33 +        if head:
    6.34 +            request.write( "<tr class='domainInfoHead'>" )
    6.35 +            self.write_DOMAIN_HEAD( request, long )
    6.36 +            request.write( "</tr>" )
    6.37 +        
    6.38 +        odd = True
    6.39 +        
    6.40 +        if not domains is None:
    6.41 +            for domain in domains:
    6.42 +                if odd:
    6.43 +                    request.write( "<tr class='domainInfoOdd'>\n" )
    6.44 +                    odd = False
    6.45 +                else:
    6.46 +                    request.write( "<tr class='domainInfoEven'>\n" )
    6.47 +                    odd = True
    6.48 +                self.write_DOMAIN( request, getDomInfoHash( domain ), long )
    6.49 +                request.write( "</tr>\n" )
    6.50 +        else:
    6.51 +        	request.write( "<tr colspan='10'><p class='small'>Error getting domain list<br/>Perhaps XenD not running?</p></tr>")
    6.52 +                
    6.53 +        request.write( "</table>\n" )
    6.54 +            
    6.55 +    def write_DOMAIN( self, request, domInfoHash, long=True ):   
    6.56 +        request.write( "<td class='domainInfo' align='center'>%(id)s</td>\n" % domInfoHash )
    6.57 +
    6.58 +        url = self.urlWriter( "&mod=info&dom=%(id)s" % domInfoHash )
    6.59 +
    6.60 +        request.write( "<td class='domainInfo' align='center'><a href='%s'>%s</a></td>\n" % ( url, domInfoHash['name'] ) )
    6.61 +        if long: 
    6.62 +            request.write( "<td class='domainInfo' align='center'>%(memory)5s</td>\n" % domInfoHash )
    6.63 +            request.write( "<td class='domainInfo' align='center'>%(cpu)2s</td>\n" % domInfoHash )
    6.64 +        request.write( "<td class='domainInfo' align='center'>%(state)5s</td>\n" % domInfoHash )
    6.65 +        if domInfoHash[ 'id' ] != "0":
    6.66 +            request.write( "<td class='domainInfo' align='center'>" )
    6.67 +            
    6.68 +            if domInfoHash[ 'state' ][ 2 ] == "-":
    6.69 +                request.write( "<img src='images/small-pause.png' onclick='doOp2( \"pause\", \"%(dom)-4s\" )'>" % domInfoHash )
    6.70 +            else:
    6.71 +                request.write( "<img src='images/small-unpause.png' onclick='doOp2( \"unpause\", \"%(dom)-4s\" )'>" % domInfoHash )              
    6.72 +            
    6.73 +            request.write( "<img src='images/small-destroy.png' onclick='doOp2( \"destroy\", \"%(dom)-4s\" )'></td>" % domInfoHash)
    6.74 +        else:
    6.75 +            request.write( "<td>&nbsp;</td>" )
    6.76 +
    6.77 +    def write_DOMAIN_HEAD( self, request, long=True ):
    6.78 +        request.write( "<td class='domainInfoHead' align='center'>Domain</td>\n" )      
    6.79 +        request.write( "<td class='domainInfoHead' align='center'>Name</td>\n" )      
    6.80 +        if long:
    6.81 +            request.write( "<td class='domainInfoHead' align='center'>Memory / Mb</td>\n" )      
    6.82 +            request.write( "<td class='domainInfoHead' align='center'>CPU</td>\n" )      
    6.83 +        request.write( "<td class='domainInfoHead' align='center'>State</td>\n" )      
    6.84 +        request.write( "<td class='domainInfoHead' align='center'></td>\n" )
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/python/xen/sv/GenTabbed.py	Tue Jul 26 13:56:30 2005 +0000
     7.3 @@ -0,0 +1,135 @@
     7.4 +import types
     7.5 +
     7.6 +from xen.sv.HTMLBase import HTMLBase
     7.7 +from xen.sv.TabView import TabView
     7.8 +from xen.sv.util import getVar
     7.9 +
    7.10 +class GenTabbed( HTMLBase ):
    7.11 +
    7.12 +    def __init__( self, title, urlWriter, tabStrings, tabObjects ):
    7.13 +        HTMLBase.__init__(self)
    7.14 +        self.tabStrings = tabStrings
    7.15 +        self.tabObjects = tabObjects
    7.16 +        self.urlWriter = urlWriter
    7.17 +        self.title = title
    7.18 +
    7.19 +    def write_BODY( self, request, urlWriter = None ):
    7.20 +        try:
    7.21 +            tab = int( getVar( 'tab', request, 0 ) )
    7.22 +        except:
    7.23 +            tab = 0
    7.24 +            
    7.25 +        request.write( "<table style='' width='100%' border='0' cellspacing='0' cellpadding='0'>" )
    7.26 +        request.write( "<tr><td>" )
    7.27 +        request.write( "<p align='center'><u>%s</u></p>" % self.title )
    7.28 +        
    7.29 +        TabView( tab, self.tabStrings, self.urlWriter ).write_BODY( request )
    7.30 +        
    7.31 +        request.write( "</td></tr><tr><td>" )
    7.32 +
    7.33 +        try:
    7.34 +            render_tab = self.tabObjects[ tab ]
    7.35 +            render_tab().write_BODY( request )
    7.36 +        except:
    7.37 +            request.write( "<p>Error Rendering Tab</p>" )
    7.38 +       
    7.39 +        request.write( "</td></tr></table>" )
    7.40 +       
    7.41 +    def perform( self, request ):
    7.42 +        try:
    7.43 +            tab = int( getVar( 'tab', request, 0 ) )
    7.44 +        except:
    7.45 +            tab = 0;
    7.46 +            
    7.47 +        op_tab = self.tabObjects[ tab ]
    7.48 +        
    7.49 +        if op_tab:
    7.50 +            op_tab().perform( request )
    7.51 +        
    7.52 +class PreTab( HTMLBase ):
    7.53 +
    7.54 +    def __init__( self, source ):
    7.55 +        HTMLBase.__init__( self )
    7.56 +        self.source = source
    7.57 +    
    7.58 +    def write_BODY( self, request ):
    7.59 +        
    7.60 +        request.write( "<div style='display: block; overflow: auto; border: 0px solid black; width: 540px; padding: 5px; z-index:0; align: center'><pre>" )
    7.61 +        
    7.62 +        request.write( self.source )
    7.63 +        
    7.64 +        request.write( "</pre></div>" )
    7.65 +
    7.66 +class GeneralTab( HTMLBase ):
    7.67 +                        
    7.68 +    def __init__( self, dict, titles ):
    7.69 +        HTMLBase.__init__( self )
    7.70 +        self.dict = dict
    7.71 +        self.titles = titles
    7.72 +                        
    7.73 +    def write_BODY( self, request ): 
    7.74 +        
    7.75 +        request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" )
    7.76 +        
    7.77 +        def writeAttr( niceName, attr, formatter=None ):
    7.78 +            if type( attr ) is types.TupleType:
    7.79 +                ( attr, formatter ) = attr
    7.80 +            
    7.81 +            if attr in self.dict:
    7.82 +                if formatter:
    7.83 +                    temp = formatter( self.dict[ attr ] )
    7.84 +                else:
    7.85 +                    temp = str( self.dict[ attr ] )
    7.86 +                request.write( "<tr><td width='50%%'><p>%s:</p></td><td width='50%%'><p>%s</p></td></tr>" % ( niceName, temp ) )
    7.87 +        
    7.88 +        for niceName, attr in self.titles.items():
    7.89 +            writeAttr( niceName, attr )
    7.90 +                            
    7.91 +        request.write( "</table>" )
    7.92 +
    7.93 +class NullTab( HTMLBase ):
    7.94 +    
    7.95 +    def __init__( self ):
    7.96 +        HTMLBase.__init__( self )
    7.97 +        self.title = "Null Tab"
    7.98 +
    7.99 +    def __init__( self, title ):
   7.100 +        HTMLBase.__init__( self )
   7.101 +        self.title = title
   7.102 +        
   7.103 +    def write_BODY( self, request ):
   7.104 +        request.write( "<p>%s</p>" % self.title )
   7.105 +
   7.106 +class ActionTab( HTMLBase ):
   7.107 +
   7.108 +    def __init__( self, actions ):
   7.109 +        self.actions = actions
   7.110 +        HTMLBase.__init__( self )
   7.111 +        
   7.112 +    def write_BODY( self, request ):
   7.113 +        request.write( "<p align='center'><table cellspacing='3' cellpadding='2' border='0'><tr>" )
   7.114 +    
   7.115 +        for ( command, text ) in self.actions.items():
   7.116 +            request.write( "<td style='border: 1px solid black; background-color: grey' onmouseover='buttonMouseOver( this )' onmouseout='buttonMouseOut( this )'>" )
   7.117 +            request.write( "<p><a href='javascript: doOp( \"%s\" );'>%s</a></p></td>" % (command, text) )
   7.118 + 
   7.119 +        request.write("</table></p>")        
   7.120 +        
   7.121 +class CompositeTab( HTMLBase ):
   7.122 +
   7.123 +    def __init__( self, tabs ):
   7.124 +    	HTMLBase.__init__( self )
   7.125 +        self.tabs = tabs
   7.126 +        
   7.127 +    def write_BODY( self, request ):
   7.128 +    	for tab in self.tabs:
   7.129 +            request.write( "<br/>" )
   7.130 +            tab().write_BODY( request )
   7.131 +            
   7.132 +    def perform( self, request ):
   7.133 +    	for tab in self.tabs:
   7.134 +            tab().perform( request )
   7.135 +    
   7.136 +    
   7.137 +       
   7.138 +        
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/python/xen/sv/HTMLBase.py	Tue Jul 26 13:56:30 2005 +0000
     8.3 @@ -0,0 +1,62 @@
     8.4 +from xen.sv.util import *
     8.5 +
     8.6 +class HTMLBase:
     8.7 +
     8.8 +    isLeaf = True
     8.9 + 
    8.10 +    def __init__( self ):
    8.11 +        pass
    8.12 +
    8.13 +    def render_POST( self, request ):
    8.14 +        self.perform( request )
    8.15 +        return self.render_GET( request )
    8.16 +        
    8.17 +    def render_GET( self, request ):
    8.18 +        self.write_TOP( request )
    8.19 +        self.write_BODY( request )
    8.20 +        self.write_BOTTOM( request )
    8.21 +        return ''
    8.22 +                
    8.23 +    def write_BODY( self, request ):
    8.24 +        request.write( "BODY" )
    8.25 +        
    8.26 +    def write_TOP( self, request ):
    8.27 +        request.write( '<html><head><title>Xen</title><link rel="stylesheet" type="text/css" href="inc/style.css" />' )
    8.28 +        request.write( '<script src="inc/script.js"></script>' )
    8.29 +        request.write( '</head><body>' )
    8.30 +        request.write('<form method="post" action="%s">' % request.uri)
    8.31 +
    8.32 +    def write_BOTTOM( self, request ):
    8.33 +        request.write('<input type="hidden" name="op" value="">')
    8.34 +        request.write('<input type="hidden" name="args" value="">')
    8.35 +        request.write('</form>')
    8.36 +        request.write( "</body></html>" )
    8.37 +
    8.38 +    def get_op_method(self, op):
    8.39 +        """Get the method for an operation.
    8.40 +        For operation 'foo' looks for 'op_foo'.
    8.41 +
    8.42 +        op	operation name
    8.43 +        returns method or None
    8.44 +        """
    8.45 +        op_method_name = 'op_' + op
    8.46 +        return getattr(self, op_method_name, None)
    8.47 +        
    8.48 +    def perform(self, req):
    8.49 +        """General operation handler for posted operations.
    8.50 +        For operation 'foo' looks for a method op_foo and calls
    8.51 +        it with op_foo(req). Replies with code 500 if op_foo
    8.52 +        is not found.
    8.53 +
    8.54 +        The method must return a list when req.use_sxp is true
    8.55 +        and an HTML string otherwise (or list).
    8.56 +        Methods may also return a Deferred (for incomplete processing).
    8.57 +
    8.58 +        req	request
    8.59 +        """
    8.60 +        op = req.args.get('op')
    8.61 +        if not op is None and len(op) == 1:
    8.62 +            op = op[0]
    8.63 +            op_method = self.get_op_method(op)
    8.64 +            if op_method:
    8.65 +                op_method( req )   
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/python/xen/sv/Main.py	Tue Jul 26 13:56:30 2005 +0000
     9.3 @@ -0,0 +1,113 @@
     9.4 +from xen.sv.HTMLBase import HTMLBase
     9.5 +from xen.sv.DomList  import DomList
     9.6 +from xen.sv.NodeInfo import NodeInfo
     9.7 +from xen.sv.DomInfo  import DomInfo
     9.8 +from xen.sv.CreateDomain import CreateDomain
     9.9 +from xen.sv.MigrateDomain import MigrateDomain
    9.10 +from xen.sv.SaveDomain import SaveDomain
    9.11 +from xen.sv.RestoreDomain import RestoreDomain
    9.12 +
    9.13 +from xen.xend.XendClient import server
    9.14 +
    9.15 +from xen.sv.util import getVar
    9.16 +
    9.17 +class Main( HTMLBase ):
    9.18 +    
    9.19 +    isLeaf = True
    9.20 +
    9.21 +    def __init__( self, urlWriter = None ):
    9.22 +        self.modules = { "node": NodeInfo, 
    9.23 +                         "list": DomList, 
    9.24 +                         "info": DomInfo,
    9.25 +                         "create": CreateDomain,
    9.26 +                         "migrate" : MigrateDomain,
    9.27 +                         "save" : SaveDomain,
    9.28 +                         "restore" : RestoreDomain }
    9.29 +
    9.30 +        # ordered list of module menus to display
    9.31 +        self.module_menus = [ "node", "create", "migrate", "save",
    9.32 +                              "restore", "list" ]
    9.33 +        HTMLBase.__init__(self)
    9.34 +        
    9.35 +    def render_POST( self, request ):
    9.36 +    
    9.37 +    	#decide what module post'd the action
    9.38 +                
    9.39 +    	args = getVar( 'args', request )
    9.40 +
    9.41 +        mod = getVar( 'mod', request )
    9.42 +                
    9.43 +        if not mod is None and args is None:
    9.44 +            module = self.modules[ mod ]
    9.45 +            #check module exists
    9.46 +            if module:
    9.47 +               module( self.mainUrlWriter ).perform( request )
    9.48 +        else:
    9.49 +            self.perform( request )     
    9.50 +    
    9.51 +        return self.render_GET( request )
    9.52 +
    9.53 +    def mainUrlWriter( self, module ):
    9.54 +    	def fun( f ):
    9.55 +            return "Main.rpy?mod=%s%s" % ( module, f )
    9.56 +        return fun    
    9.57 +        
    9.58 +    def write_BODY( self, request ):
    9.59 +    
    9.60 +        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" )
    9.61 +        request.write( "<tr>\n" )
    9.62 +        request.write( " <td width='15px'>&nbsp;</td>" )
    9.63 +        request.write( " <td width='175px' align='center' valign'center'>" )
    9.64 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
    9.65 +        request.write( "   <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" )
    9.66 +        request.write( "   <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" )
    9.67 +        request.write( "   <tr><td height='60px' align='center'><p class='small'>SV Web Interface<br/>(C) <a href='mailto:tw275@cam.ac.uk'>Tom Wilkie</a> 2004</p></td></tr>")
    9.68 +        request.write( "   <tr><td align='center' valign='top'>" )
    9.69 +
    9.70 +        for modName in self.module_menus:
    9.71 +            self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request )
    9.72 +        
    9.73 +        request.write( "   </td></tr>" )
    9.74 +        request.write( "  </table>" )
    9.75 +        request.write( " &nbsp;" )
    9.76 +        request.write( " </td>\n" )
    9.77 +        request.write( " <td width='15px'>&nbsp;</td>" )
    9.78 +        request.write( " <td width='558px' align='left' valign='top'>" )
    9.79 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
    9.80 +        request.write( "   <tr><td height='20px'></td></tr>" )
    9.81 +        request.write( "   <tr><td align='center' valign='top'>" )
    9.82 +        
    9.83 +        modName = getVar('mod', request)
    9.84 +        
    9.85 +        if modName is None:
    9.86 +            request.write( '<p>Please select a module</p>' )
    9.87 +        else:
    9.88 +            module = self.modules[ modName ]
    9.89 +            if module:
    9.90 +               module( self.mainUrlWriter( modName ) ).write_BODY( request )  
    9.91 +            else:
    9.92 +               request.write( '<p>Invalid module. Please select another</p>' )
    9.93 +    
    9.94 +        request.write( "   </td></tr>" )
    9.95 +        request.write( "  </table>" )
    9.96 +        request.write( " </td>\n" )
    9.97 +        request.write( " <td width='17px'>&nbsp;</td>" )
    9.98 +        request.write( "</tr>\n" )
    9.99 +        
   9.100 +        request.write( "</table>\n" )
   9.101 +        
   9.102 +                
   9.103 +    def op_destroy( self, request ):
   9.104 +    	dom = getVar( 'dom', request )
   9.105 +        if not dom is None and dom != "0":
   9.106 +            server.xend_domain_destroy( int( dom ), "halt" ) 
   9.107 +                 
   9.108 +    def op_pause( self, request ):
   9.109 +    	dom = getVar( 'dom', request )
   9.110 +        if not dom is None and dom != "0":
   9.111 +            server.xend_domain_pause( int( dom ) )      
   9.112 +    
   9.113 +    def op_unpause( self, request ):
   9.114 +    	dom = getVar( 'dom', request )
   9.115 +        if not dom is None and dom != "0":
   9.116 +            server.xend_domain_unpause( int( dom ) )      
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/python/xen/sv/MigrateDomain.py	Tue Jul 26 13:56:30 2005 +0000
    10.3 @@ -0,0 +1,74 @@
    10.4 +from xen.sv.Wizard import *
    10.5 +from xen.sv.util import *
    10.6 +from xen.sv.GenTabbed import PreTab
    10.7 +
    10.8 +from xen.xm.create import make_config, OptVals
    10.9 +
   10.10 +from xen.xend.XendClient import server
   10.11 +
   10.12 +class MigrateDomain( Wizard ):
   10.13 +    def __init__( self, urlWriter ):
   10.14 +
   10.15 +        sheets = [ ChooseMigrateDomain,
   10.16 +                   DoMigrate ]
   10.17 +
   10.18 +        Wizard.__init__( self, urlWriter, "Migrate Domain", sheets )
   10.19 +
   10.20 +
   10.21 +class ChooseMigrateDomain( Sheet ):
   10.22 +    def __init__( self, urlWriter ):
   10.23 +        Sheet.__init__( self, urlWriter, "Configure Migration", 0)
   10.24 +	domains = []
   10.25 +	domnames = []
   10.26 +
   10.27 +        try:
   10.28 +            domains = server.xend_domains()
   10.29 +            domains.sort()
   10.30 +        except:
   10.31 +            pass
   10.32 +
   10.33 +        for i in domains:
   10.34 +            if i != 'Domain-0': domnames.append((i,i))
   10.35 +        
   10.36 +        self.addControl( ListControl('domid',
   10.37 +                                     domnames,
   10.38 +                                     'Domain ID:') )
   10.39 +        self.addControl( TickControl('live',
   10.40 +                                     'True',
   10.41 +                                     'Live migrate:') )
   10.42 +        self.addControl( InputControl('rate',
   10.43 +                                      '0',
   10.44 +                                      'Rate limit:') )
   10.45 +        self.addControl( InputControl( 'dest', 'myhost.mydomain',
   10.46 +                                       'Name or IP address:',
   10.47 +                                       ".*") )
   10.48 +
   10.49 +class DoMigrate( Sheet ):
   10.50 +    def __init__(self, urlWriter ):
   10.51 +        Sheet.__init__(self, urlWriter, "Migration Done", 1)
   10.52 +
   10.53 +    def write_BODY( self, request, err ):
   10.54 +
   10.55 +        if not self.passback: self.parseForm( request )
   10.56 +
   10.57 +#        print string2sxp(self.passback)
   10.58 +        
   10.59 +        config = ssxp2hash ( string2sxp( self.passback ) )
   10.60 +      
   10.61 +        try:
   10.62 +            print config
   10.63 +            print config['domid'], config['dest']
   10.64 +            dom_sxp = server.xend_domain_migrate( config['domid'],
   10.65 +                                                  config['dest'],
   10.66 +                                                  config.get('live') == 'True',
   10.67 +                                                  config['rate'] )
   10.68 +            success = "Your domain was successfully Migrated.\n"
   10.69 +        except Exception, e:
   10.70 +            success = "There was an error migrating your domain\n"
   10.71 +            dom_sxp = str(e)
   10.72 +        
   10.73 +        pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) )
   10.74 +        pt.write_BODY( request )
   10.75 +
   10.76 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   10.77 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/python/xen/sv/NodeInfo.py	Tue Jul 26 13:56:30 2005 +0000
    11.3 @@ -0,0 +1,63 @@
    11.4 +from xen.xend.XendClient import server
    11.5 +
    11.6 +from xen.sv.util import *
    11.7 +from xen.sv.GenTabbed import *
    11.8 +
    11.9 +class NodeInfo( GenTabbed ):
   11.10 +
   11.11 +    def __init__( self, urlWriter ):  
   11.12 +        GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', ], [ NodeGeneralTab, NodeDmesgTab ] )
   11.13 +    
   11.14 +    def write_MENU( self, request ):
   11.15 +        request.write( "<p class='small'><a href='%s'>Node details</a></p>" % self.urlWriter( '' ) )
   11.16 +
   11.17 +class NodeGeneralTab( CompositeTab ):
   11.18 +    def __init__( self ):
   11.19 +    	CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ] )        
   11.20 +        
   11.21 +class NodeInfoTab( GeneralTab ):
   11.22 +                        
   11.23 +    def __init__( self ):
   11.24 +         
   11.25 +    	nodeInfo = {}
   11.26 +        try:
   11.27 +            nodeInfo = sxp2hash( server.xend_node() )
   11.28 +   	except:
   11.29 +            nodeInfo[ 'system' ] = 'Error getting node info'
   11.30 +             
   11.31 +        dictTitles = {}
   11.32 +        dictTitles[ 'System' ] = 'system'
   11.33 +        dictTitles[ 'Hostname' ] = 'host' 
   11.34 +        dictTitles[ 'Release' ] = 'release' 
   11.35 +        dictTitles[ 'Version' ] ='version' 
   11.36 +        dictTitles[ 'Machine' ] = 'machine' 
   11.37 +        dictTitles[ 'Cores' ] = 'cores' 
   11.38 +        dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter )
   11.39 +        dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter )
   11.40 +        dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter )
   11.41 +        dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter )
   11.42 +        
   11.43 +        GeneralTab.__init__( self, dict=nodeInfo, titles=dictTitles )
   11.44 +
   11.45 +class NodeDmesgTab( PreTab ):
   11.46 +
   11.47 +    def __init__( self ):
   11.48 +    	try:
   11.49 +            dmesg = server.xend_node_get_dmesg()
   11.50 +        except:
   11.51 +            dmesg = "Error getting node information: XenD not running?"
   11.52 +        PreTab.__init__( self, dmesg )
   11.53 +  
   11.54 +class NodeActionTab( ActionTab ):
   11.55 +
   11.56 +    def __init__( self ):
   11.57 +        ActionTab.__init__( self, { "shutdown" : "shutdown",
   11.58 +        	"reboot" : "reboot" } )    
   11.59 +        
   11.60 +    def op_shutdown( self, request ):
   11.61 +        if debug: print ">NodeShutDown"
   11.62 +    	server.xend_node_shutdown()
   11.63 +    
   11.64 +    def op_reboot( self, request ):
   11.65 +        if debug: print ">NodeReboot"
   11.66 +        server.xend_node_reboot()
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/python/xen/sv/RestoreDomain.py	Tue Jul 26 13:56:30 2005 +0000
    12.3 @@ -0,0 +1,46 @@
    12.4 +from xen.sv.Wizard import *
    12.5 +from xen.sv.util import *
    12.6 +from xen.sv.GenTabbed import PreTab
    12.7 +
    12.8 +from xen.xm.create import make_config, OptVals
    12.9 +
   12.10 +from xen.xend.XendClient import server
   12.11 +
   12.12 +class RestoreDomain( Wizard ):
   12.13 +    def __init__( self, urlWriter ):
   12.14 +
   12.15 +        sheets = [ ChooseRestoreDomain,
   12.16 +                   DoRestore ]
   12.17 +
   12.18 +        Wizard.__init__( self, urlWriter, "Restore Domain", sheets )
   12.19 +
   12.20 +
   12.21 +class ChooseRestoreDomain( Sheet ):
   12.22 +    def __init__( self, urlWriter ):
   12.23 +        Sheet.__init__( self, urlWriter, "Configure Restore", 0)
   12.24 +        
   12.25 +        self.addControl( InputControl( 'file', '',
   12.26 +                                       'Suspend file name:',
   12.27 +                                       ".*") )
   12.28 +
   12.29 +class DoRestore( Sheet ):
   12.30 +    def __init__(self, urlWriter ):
   12.31 +        Sheet.__init__(self, urlWriter, "Restore Done", 1)
   12.32 +
   12.33 +    def write_BODY( self, request, err ):
   12.34 +
   12.35 +        if not self.passback: self.parseForm( request )
   12.36 +        config = ssxp2hash ( string2sxp( self.passback ) )
   12.37 +      
   12.38 +        try:
   12.39 +            dom_sxp = server.xend_domain_restore( config['file'] )
   12.40 +            success = "Your domain was successfully restored.\n"
   12.41 +        except Exception, e:
   12.42 +            success = "There was an error restoring your domain\n"
   12.43 +            dom_sxp = str(e)
   12.44 +        
   12.45 +        pt = PreTab( success + sxp2prettystring( dom_sxp ) )
   12.46 +        pt.write_BODY( request )
   12.47 +
   12.48 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   12.49 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/python/xen/sv/SaveDomain.py	Tue Jul 26 13:56:30 2005 +0000
    13.3 @@ -0,0 +1,62 @@
    13.4 +from xen.sv.Wizard import *
    13.5 +from xen.sv.util import *
    13.6 +from xen.sv.GenTabbed import PreTab
    13.7 +
    13.8 +from xen.xm.create import make_config, OptVals
    13.9 +
   13.10 +from xen.xend.XendClient import server
   13.11 +
   13.12 +class SaveDomain( Wizard ):
   13.13 +    def __init__( self, urlWriter ):
   13.14 +
   13.15 +        sheets = [ ChooseSaveDomain,
   13.16 +                   DoSave ]
   13.17 +
   13.18 +        Wizard.__init__( self, urlWriter, "Save Domain", sheets )
   13.19 +
   13.20 +
   13.21 +class ChooseSaveDomain( Sheet ):
   13.22 +    def __init__( self, urlWriter ):
   13.23 +        Sheet.__init__( self, urlWriter, "Configure Save", 0)
   13.24 +        
   13.25 +	domains = []
   13.26 +	domnames = []
   13.27 +
   13.28 +	try:
   13.29 +            domains = server.xend_domains()
   13.30 +            domains.sort()
   13.31 +        except:
   13.32 +            pass
   13.33 +
   13.34 +        for i in domains:
   13.35 +            if i != 'Domain-0': domnames.append((i,i))
   13.36 +        
   13.37 +        self.addControl( ListControl('domid',
   13.38 +                                     domnames,
   13.39 +                                     'Domain ID:') )
   13.40 +        self.addControl( InputControl( 'file', '',
   13.41 +                                       'Suspend file name:',
   13.42 +                                       ".*") )
   13.43 +
   13.44 +class DoSave( Sheet ):
   13.45 +    def __init__(self, urlWriter ):
   13.46 +        Sheet.__init__(self, urlWriter, "Save Done", 1)
   13.47 +
   13.48 +    def write_BODY( self, request, err ):
   13.49 +
   13.50 +        if not self.passback: self.parseForm( request )
   13.51 +        config = ssxp2hash ( string2sxp( self.passback ) )
   13.52 +      
   13.53 +        try:
   13.54 +            dom_sxp = server.xend_domain_save( config['domid'],
   13.55 +                                                  config['file'] )
   13.56 +            success = "Your domain was successfully saved.\n"
   13.57 +        except Exception, e:
   13.58 +            success = "There was an error saving your domain\n"
   13.59 +            dom_sxp = str(e)
   13.60 +        
   13.61 +        pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) )
   13.62 +        pt.write_BODY( request )
   13.63 +
   13.64 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   13.65 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/python/xen/sv/TabView.py	Tue Jul 26 13:56:30 2005 +0000
    14.3 @@ -0,0 +1,26 @@
    14.4 +from xen.sv.HTMLBase import HTMLBase
    14.5 +
    14.6 +class TabView( HTMLBase ):
    14.7 +
    14.8 +    # tab - int, id into tabs of selected tab
    14.9 +    # tabs - list of strings, tab names
   14.10 +    # urlWriter - 
   14.11 +    def __init__( self, tab, tabs, urlWriter ):
   14.12 +        HTMLBase.__init__(self)
   14.13 +        self.tab = tab
   14.14 +        self.tabs = tabs
   14.15 +        self.urlWriter = urlWriter
   14.16 +
   14.17 +    def write_BODY( self, request ):
   14.18 +        request.write( "<table style='' border='0' cellspacing='3' cellpadding='2' align='center'>" )
   14.19 +        request.write( "<tr height='22'>" )                  
   14.20 +    
   14.21 +        for i in range( len( self.tabs ) ):
   14.22 +            if self.tab == i:
   14.23 +                backgroundColor = "white"
   14.24 +            else:
   14.25 +                backgroundColor = "grey"
   14.26 +        
   14.27 +            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 ] ) )
   14.28 +  
   14.29 +        request.write( "</tr></table>" )
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/python/xen/sv/Wizard.py	Tue Jul 26 13:56:30 2005 +0000
    15.3 @@ -0,0 +1,269 @@
    15.4 +from xen.sv.util import *
    15.5 +from xen.sv.HTMLBase import HTMLBase
    15.6 +from xen.xend import sxp
    15.7 +
    15.8 +import re
    15.9 +
   15.10 +DEBUG = 0
   15.11 +
   15.12 +class Wizard( HTMLBase ):
   15.13 +
   15.14 +    def __init__( self, urlWriter, title, sheets ):
   15.15 +        HTMLBase.__init__( self )
   15.16 +        self.title = title
   15.17 +        self.sheets = sheets
   15.18 +        self.urlWriter = urlWriter
   15.19 +        
   15.20 +    def write_MENU( self, request ):
   15.21 +    	request.write( "<p class='small'><a href='%s'>%s</a></p>" % (self.urlWriter( '' ), self.title) ) 
   15.22 +    
   15.23 +    def write_BODY( self, request ):
   15.24 +        
   15.25 +   	request.write( "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr><td>" )
   15.26 +        request.write( "<p align='center'><u>%s</u></p></td></tr><tr><td>" % self.title )
   15.27 +        
   15.28 +        currSheet = getVar( 'sheet', request )
   15.29 +    
   15.30 +        if not currSheet is None:
   15.31 +            currSheet = int( currSheet )
   15.32 +        else:
   15.33 +            currSheet = 0
   15.34 +            
   15.35 +        sheet = self.sheets[ currSheet ]( self.urlWriter )
   15.36 +        
   15.37 +        err = not sheet.validate( request )
   15.38 +        
   15.39 +        if not err:    
   15.40 +            op = getVar( 'op', request )
   15.41 +        
   15.42 +            if op == 'next':
   15.43 +               currSheet += 1
   15.44 +            elif op == 'prev':
   15.45 +               currSheet -= 1
   15.46 +             
   15.47 +            sheet = self.sheets[ currSheet ]( self.urlWriter )
   15.48 +        
   15.49 +        if getVar( 'visited-sheet%s' % currSheet, request ):
   15.50 +            sheet.write_BODY( request, err )
   15.51 +        else:
   15.52 +            sheet.write_BODY( request, False )
   15.53 +
   15.54 +        
   15.55 +        request.write( "</td></tr><tr><td><table width='100%' border='0' cellspacing='0' cellpadding='0'><tr>" )
   15.56 +        request.write( "<td width='80%'></td><td width='20%' align='center'><p align='center'>" )
   15.57 +	if currSheet > 0:
   15.58 +       	    request.write( "<img src='images/previous.png' onclick='doOp( \"prev\" )' onmouseover='update( \"wizText\", \"Previous\" )' onmouseout='update( \"wizText\", \"&nbsp;\" )'>&nbsp;" )
   15.59 +        if currSheet < ( len( self.sheets ) - 2 ):        
   15.60 +            request.write( "<img src='images/next.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Next\" )' onmouseout='update( \"wizText\", \"&nbsp;\" )'>" )
   15.61 +        elif currSheet == ( len( self.sheets ) - 2 ):
   15.62 +            request.write( "<img src='images/finish.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Finish\" )' onmouseout='update( \"wizText\", \"&nbsp;\" )'>" )
   15.63 +        request.write( "</p><p align='center'><span id='wizText'></span></p></td></tr></table>" )
   15.64 +        request.write( "</td></tr></table>" )
   15.65 +        
   15.66 +    def op_next( self, request ):
   15.67 +    	pass
   15.68 +        
   15.69 +    def op_prev( self, request ):
   15.70 +    	pass
   15.71 +        
   15.72 +    def op_finish( self, request ):
   15.73 +    	pass  
   15.74 +        
   15.75 +class Sheet( HTMLBase ):
   15.76 +
   15.77 +    def __init__( self, urlWriter, title, location ):
   15.78 +        HTMLBase.__init__( self )
   15.79 +        self.urlWriter = urlWriter
   15.80 +        self.feilds = []
   15.81 +        self.title = title
   15.82 +        self.location = location
   15.83 +        self.passback = None
   15.84 +        
   15.85 +    def parseForm( self, request ):
   15.86 +    	do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ] 
   15.87 +    
   15.88 +    	passed_back = request.args
   15.89 +        
   15.90 +        temp_passback = passed_back.get( "passback" )
   15.91 +        
   15.92 +        if temp_passback is not None and len( temp_passback ) > 0:
   15.93 +            temp_passback = temp_passback[ len( temp_passback )-1 ]
   15.94 +        else:
   15.95 +            temp_passback = "( )"        
   15.96 +        
   15.97 +        last_passback = ssxp2hash( string2sxp( temp_passback ) ) #use special function - will work with no head on sxp
   15.98 +        
   15.99 +        if DEBUG: print last_passback
  15.100 +        
  15.101 +        for (key, value) in passed_back.items():
  15.102 +            if key not in do_not_parse:
  15.103 +                last_passback[ key ] = value[ len( value ) - 1 ]
  15.104 +                
  15.105 +        self.passback = sxp2string( hash2sxp( last_passback ) ) #store the sxp
  15.106 +        
  15.107 +        if DEBUG: print self.passback
  15.108 +        
  15.109 +    def write_BODY( self, request, err ):
  15.110 +    
  15.111 +    	if not self.passback: self.parseForm( request )
  15.112 +        
  15.113 +   	request.write( "<p>%s</p>" % self.title )
  15.114 +    
  15.115 +    	previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
  15.116 +        
  15.117 +        request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" )
  15.118 +        
  15.119 +    	for (feild, control) in self.feilds:
  15.120 +            control.write_Control( request, previous_values.get( feild ) )
  15.121 +            if err and not control.validate( previous_values.get( feild ) ):
  15.122 +            	control.write_Help( request )
  15.123 +            
  15.124 +        request.write( "</table>" )
  15.125 +            
  15.126 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
  15.127 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
  15.128 +        request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location )
  15.129 +                
  15.130 +    def addControl( self, control ):
  15.131 +    	self.feilds.append( [ control.getName(), control ] )
  15.132 +        
  15.133 +    def validate( self, request ):
  15.134 +    
  15.135 +        if not self.passback: self.parseForm( request )
  15.136 +            
  15.137 +    	check = True
  15.138 +        
  15.139 +        previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
  15.140 +    	if DEBUG: print previous_values
  15.141 +      
  15.142 +      	for (feild, control) in self.feilds:
  15.143 +            if not control.validate( previous_values.get( feild ) ):
  15.144 +                check = False
  15.145 +                if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild ))
  15.146 +
  15.147 +        return check
  15.148 +        
  15.149 +class SheetControl( HTMLBase ):
  15.150 +
  15.151 +    def __init__( self, reg_exp = ".*" ):
  15.152 +        HTMLBase.__init__( self )
  15.153 +        self.name = ""
  15.154 +        self.reg_exp = reg_exp 
  15.155 +        
  15.156 +    def write_Control( self, request, persistedValue ):
  15.157 +        request.write( "<tr colspan='2'><td>%s</td></tr>" % persistedValue )
  15.158 +        
  15.159 +    def write_Help( self, request ):
  15.160 +        request.write( "<tr><td align='right' colspan='2'><p class='small'>Text must match pattern:" )
  15.161 +        request.write( " %s</p></td></tr>" % self.reg_exp )
  15.162 +        
  15.163 +    def validate( self, persistedValue ):
  15.164 +    	if persistedValue is None:
  15.165 +            persistedValue = ""
  15.166 +            
  15.167 +        return not re.compile( self.reg_exp ).match( persistedValue ) is None
  15.168 +
  15.169 +    def getName( self ):
  15.170 +    	return self.name
  15.171 +        
  15.172 +    def setName( self, name ):
  15.173 +    	self.name = name
  15.174 +        
  15.175 +class InputControl( SheetControl ):
  15.176 +
  15.177 +    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
  15.178 +        SheetControl.__init__( self, reg_exp )
  15.179 +        self.setName( name )
  15.180 +        
  15.181 +        self.defaultValue = defaultValue
  15.182 +        self.humanText = humanText
  15.183 +        self.help_text = help_text
  15.184 +        
  15.185 +    def write_Control( self, request, persistedValue ):
  15.186 +    	if persistedValue is None:
  15.187 +            persistedValue = self.defaultValue
  15.188 +        
  15.189 +        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) )
  15.190 +
  15.191 +    def write_Help( self, request ):
  15.192 +        request.write( "<tr><td align='right' colspan='2'><p class='small'>" )
  15.193 +        request.write( " %s</p></td></tr>" % self.help_text )         
  15.194 +        
  15.195 +class TextControl( SheetControl ):
  15.196 +
  15.197 +    def __init__( self, text ):
  15.198 +    	SheetControl.__init__( self )
  15.199 +        self.text = text
  15.200 +        
  15.201 +    def write_Control( self, request, persistedValue ):
  15.202 +    	request.write( "<tr><td colspan='2'><p>%s</p></td></tr>" % self.text )
  15.203 +
  15.204 +class SmallTextControl( SheetControl ):
  15.205 +
  15.206 +    def __init__( self, text ):
  15.207 +    	SheetControl.__init__( self )
  15.208 +        self.text = text
  15.209 +        
  15.210 +    def write_Control( self, request, persistedValue ):
  15.211 +    	request.write( "<tr><td colspan='2'><p class='small'>%s</p></tr></td>" % self.text )
  15.212 +        
  15.213 +class ListControl( SheetControl ):
  15.214 +
  15.215 +    def __init__( self, name, options, humanText ):
  15.216 +    	SheetControl.__init__( self )
  15.217 +        self.setName( name )
  15.218 +        self.options = options
  15.219 +        self.humanText = humanText
  15.220 +        
  15.221 +    def write_Control( self, request, persistedValue ):
  15.222 +        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
  15.223 +    	request.write( "<select name='%s'>" % self.getName() )
  15.224 +        for (value, text) in self.options:
  15.225 +            if value == persistedValue:
  15.226 +            	request.write( "<option value='%s' selected>%s\n" % (value, text) )
  15.227 +            else:
  15.228 +                request.write( "<option value='%s'>%s\n" % (value, text) )
  15.229 +        request.write( "</select></td></tr>" )
  15.230 +
  15.231 +    def validate( self, persistedValue ):
  15.232 +        for (value, text) in self.options:
  15.233 +            if value == persistedValue:
  15.234 +                return True
  15.235 +                
  15.236 +        return False
  15.237 +        
  15.238 +class FileControl( InputControl ):
  15.239 +
  15.240 +    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
  15.241 +	InputControl.__init__( self, name, defaultValue, humanText )
  15.242 +        
  15.243 +    def validate( self, persistedValue ):
  15.244 +        if persistedValue is None: return False
  15.245 +        try:
  15.246 +            open( persistedValue )
  15.247 +            return True
  15.248 +        except IOError, TypeError:
  15.249 +            return False
  15.250 +    
  15.251 +    def write_Help( self, request ):
  15.252 +        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>" )
  15.253 +
  15.254 +class TickControl( SheetControl ):
  15.255 +
  15.256 +    def __init__( self, name, defaultValue, humanText ):
  15.257 +        SheetControl.__init__( self )
  15.258 +        self.setName( name )
  15.259 +        self.defaultValue = defaultValue
  15.260 +        self.humanText = humanText
  15.261 +        
  15.262 +    def write_Control( self, request, persistedValue ):
  15.263 +        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
  15.264 +        
  15.265 +        if persistedValue == 'True':
  15.266 +    	    request.write( "<input type='checkbox' name='%s' value='True' checked>" % self.getName() )
  15.267 +        else:
  15.268 +    	    request.write( "<input type='checkbox' name='%s' value='True'>" % self.getName() )
  15.269 +            
  15.270 +        request.write( "</select></td></tr>" )
  15.271 +
  15.272 +      
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/python/xen/sv/__init__.py	Tue Jul 26 13:56:30 2005 +0000
    16.3 @@ -0,0 +1,1 @@
    16.4 + 
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/python/xen/sv/params.py	Tue Jul 26 13:56:30 2005 +0000
    17.3 @@ -0,0 +1,3 @@
    17.4 +SV_PORT = 8080
    17.5 +SV_ROOT = "/var/lib/xen/sv/"
    17.6 +PID_FILE = "/var/run/xen-sv.pid"
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/python/xen/sv/util.py	Tue Jul 26 13:56:30 2005 +0000
    18.3 @@ -0,0 +1,126 @@
    18.4 +from xen.xend.XendClient import server
    18.5 +from xen.xend import sxp
    18.6 +from xen.xend import PrettyPrint
    18.7 +
    18.8 +import types
    18.9 +
   18.10 +def getDomInfoHash( domain ):
   18.11 +    domInfoHash = {}
   18.12 +    try:
   18.13 +        domInfoHash = sxp2hash( server.xend_domain( domain ) )
   18.14 +        domInfoHash['dom'] = domain
   18.15 +    except:
   18.16 +    	domInfoHash['name'] = "Error getting domain details"
   18.17 +    return domInfoHash
   18.18 +
   18.19 +def sxp2hash( s ):
   18.20 +    sxphash = {}
   18.21 +        
   18.22 +    for child in sxp.children( s ):
   18.23 +    	if isinstance( child, types.ListType ) and len( child ) > 1:
   18.24 +            if isinstance( child[1], types.ListType ) and len( child ) > 1:
   18.25 +                sxphash[ child[0] ] = sxp2hash( child[1] )
   18.26 +            else:
   18.27 +                sxphash[ child[0] ] = child[1]
   18.28 +        
   18.29 +    return sxphash  
   18.30 +    
   18.31 +def ssxp2hash( s ):
   18.32 +    sxphash = {}
   18.33 +    
   18.34 +    for i in s:
   18.35 +       if isinstance( i, types.ListType ) and len( i ) > 1:
   18.36 +          sxphash[ i[0] ] = i[1]
   18.37 +    
   18.38 +    return sxphash 
   18.39 +    
   18.40 +def hash2sxp( h ):
   18.41 +    hashsxp = []
   18.42 +    
   18.43 +    for (key, item) in h.items():
   18.44 +    	hashsxp.append( [key, item] )
   18.45 +        
   18.46 +    return hashsxp    
   18.47 +    
   18.48 +def string2sxp( string ):
   18.49 +    pin = sxp.Parser()
   18.50 +    pin.input( string )
   18.51 +    return pin.get_val()    
   18.52 +
   18.53 +def sxp2string( sexp ):
   18.54 +    return sxp.to_string( sexp )    
   18.55 +    
   18.56 +def sxp2prettystring( sxp ):
   18.57 +    class tmp:
   18.58 +        def __init__( self ):
   18.59 +                self.str = ""
   18.60 +        def write( self, str ):
   18.61 +                self.str = self.str + str
   18.62 +    temp = tmp()
   18.63 +    PrettyPrint.prettyprint( sxp, out=temp )
   18.64 +    return temp.str
   18.65 +
   18.66 +def getVar( var, request, default=None ):
   18.67 +   
   18.68 +    arg = request.args.get( var )
   18.69 +
   18.70 +    if arg is None:
   18.71 +        return default
   18.72 +    else:
   18.73 +        return arg[ len( arg )-1 ]
   18.74 +
   18.75 +def bigTimeFormatter( time ):
   18.76 +    time = float( time )
   18.77 +    weeks = time // 604800
   18.78 +    remainder = time % 604800
   18.79 +    days = remainder // 86400
   18.80 +    
   18.81 +    remainder = remainder % 86400
   18.82 +
   18.83 +    hms = smallTimeFormatter( remainder )
   18.84 +    
   18.85 +    return "%d weeks, %d days, %s" % ( weeks, days, hms )
   18.86 +
   18.87 +def smallTimeFormatter( time ):
   18.88 +    time = float( time )
   18.89 +    hours = time // 3600
   18.90 +    remainder = time % 3600
   18.91 +    mins = remainder // 60
   18.92 +    secs = time % 60
   18.93 +    return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs ) 
   18.94 +
   18.95 +def stateFormatter( state ):
   18.96 +    states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ]
   18.97 +    
   18.98 +    stateStr = ""
   18.99 +    
  18.100 +    for i in range( len( state ) ):
  18.101 +        if state[i] != "-":
  18.102 +            stateStr += "%s, " % states[ i ] 
  18.103 +           
  18.104 +    return stateStr + " (%s)" % state
  18.105 +
  18.106 +def memoryFormatter( mem ):
  18.107 +    mem = int( mem )
  18.108 +    if mem >= 1024:
  18.109 +        mem = float( mem ) / 1024
  18.110 +        return "%3.2fGb" % mem
  18.111 +    else:    
  18.112 +        return "%7dMb" % mem
  18.113 +
  18.114 +def cpuFormatter( mhz ):
  18.115 +    mhz = int( mhz )
  18.116 +    if mhz > 1000:
  18.117 +        ghz = float( mhz ) / 1000.0
  18.118 +        return "%4.2fGHz" % ghz
  18.119 +    else:
  18.120 +        return "%4dMHz" % mhz
  18.121 +        
  18.122 +def hyperthreadFormatter( threads ):
  18.123 +    try:
  18.124 +        if int( threads ) > 1:
  18.125 +            return "Yes"
  18.126 +        else:
  18.127 +            return "No"
  18.128 +    except:
  18.129 +        return "No"
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/sv/Makefile	Tue Jul 26 13:56:30 2005 +0000
    19.3 @@ -0,0 +1,2 @@
    19.4 +
    19.5 +all:
    20.1 Binary file tools/sv/images/destroy.png has changed
    21.1 Binary file tools/sv/images/finish.png has changed
    22.1 Binary file tools/sv/images/internet copy.jpg has changed
    23.1 Binary file tools/sv/images/internet.jpg has changed
    24.1 Binary file tools/sv/images/internet.psd has changed
    25.1 Binary file tools/sv/images/next.png has changed
    26.1 Binary file tools/sv/images/orb_01.jpg has changed
    27.1 Binary file tools/sv/images/orb_02.jpg has changed
    28.1 Binary file tools/sv/images/pause.png has changed
    29.1 Binary file tools/sv/images/previous.png has changed
    30.1 Binary file tools/sv/images/reboot.png has changed
    31.1 Binary file tools/sv/images/seperator-left-highlight.jpg has changed
    32.1 Binary file tools/sv/images/seperator-right-highlight.jpg has changed
    33.1 Binary file tools/sv/images/seperator.jpg has changed
    34.1 Binary file tools/sv/images/shutdown.png has changed
    35.1 Binary file tools/sv/images/small-destroy.png has changed
    36.1 Binary file tools/sv/images/small-pause.png has changed
    37.1 Binary file tools/sv/images/small-unpause.png has changed
    38.1 Binary file tools/sv/images/unpause.png has changed
    39.1 Binary file tools/sv/images/xen.png has changed
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tools/sv/inc/script.js	Tue Jul 26 13:56:30 2005 +0000
    40.3 @@ -0,0 +1,31 @@
    40.4 +function update( objRef, text ) {
    40.5 +    if ( document.all || document.getElementById ) {
    40.6 +        obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef );
    40.7 +        obj.innerHTML= text
    40.8 +    }
    40.9 +}
   40.10 +
   40.11 +function buttonMouseOver( objRef ) {
   40.12 +    if ( document.all || document.getElementById ) {
   40.13 +        obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef );
   40.14 +        objRef.style.background = "white";
   40.15 +    }
   40.16 +}
   40.17 +
   40.18 +function buttonMouseOut( objRef ) {
   40.19 +    if ( document.all || document.getElementById ) {
   40.20 +        obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef );
   40.21 +        objRef.style.background = "grey";
   40.22 +    }
   40.23 +}
   40.24 +
   40.25 +function doOp( op ) {
   40.26 +    document.forms[0].op.value = op
   40.27 +    document.forms[0].submit()
   40.28 +}
   40.29 +
   40.30 +function doOp2( op, args ) {
   40.31 +    document.forms[0].op.value = op
   40.32 +    document.forms[0].args.value = args
   40.33 +    document.forms[0].submit()
   40.34 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/tools/sv/inc/style.css	Tue Jul 26 13:56:30 2005 +0000
    41.3 @@ -0,0 +1,32 @@
    41.4 +
    41.5 +P       {font-family: verdana, arial; font-size: 12px; color: black}
    41.6 +.small  {font-size: 10px}
    41.7 +
    41.8 +TD.domainInfo     {font-family: verdana, arial; font-size: 10px; color: black}
    41.9 +TD.domainInfoHead {font-family: verdana, arial; font-size: 10px; color: white; font-face: bold}
   41.10 +
   41.11 +TD.domainInfoHead {background-color: black}
   41.12 +TR.domainInfoOdd  {background-color: white}
   41.13 +TR.domainInfoEven {background-color: lightgrey}
   41.14 +
   41.15 +body { 
   41.16 +	width: 670px;
   41.17 +	margin: 0px;
   41.18 +	padding: 0px;
   41.19 +	background-color: #fff;
   41.20 +	background-image: url(../images/orb_02.jpg);
   41.21 +	background-repeat: repeat-y;
   41.22 +	background-position: left top;
   41.23 +	font-family: Arial, Helvetica, sans-serif;
   41.24 +	font-weight: bold;
   41.25 +	color: #333333;
   41.26 +	letter-spacing: 0px;
   41.27 +	scrollbar-base-color: #333333;
   41.28 +	scrollbar-track-color: #666666;
   41.29 +	scrollbar-face-color: #fff;
   41.30 +	
   41.31 +	
   41.32 +	}
   41.33 +        
   41.34 +.button (cursor:hand)
   41.35 +	
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/tools/sv/index.psp	Tue Jul 26 13:56:30 2005 +0000
    42.3 @@ -0,0 +1,164 @@
    42.4 +<%
    42.5 +import sys
    42.6 +sys.path.append( "/usr/lib/python" )
    42.7 +
    42.8 +debug = True and False
    42.9 +
   42.10 +for path in sys.path:
   42.11 +    if debug: req.write( path + "<br/>" )
   42.12 +
   42.13 +from xen.sv.HTMLBase import HTMLBase
   42.14 +from xen.sv.DomList  import DomList
   42.15 +from xen.sv.NodeInfo import NodeInfo
   42.16 +from xen.sv.DomInfo  import DomInfo
   42.17 +from xen.sv.CreateDomain import CreateDomain
   42.18 +from xen.sv.MigrateDomain import MigrateDomain
   42.19 +from xen.sv.SaveDomain import SaveDomain
   42.20 +from xen.sv.RestoreDomain import RestoreDomain
   42.21 +
   42.22 +from xen.xend.XendClient import server
   42.23 +
   42.24 +from xen.sv.util import getVar
   42.25 +
   42.26 +# adapter to make this all work with mod_python
   42.27 +# (c) Tom Wilkie 2005
   42.28 +
   42.29 +class TwistedAdapter:
   42.30 +
   42.31 +    def write( self, text ):
   42.32 +        req.write( text )
   42.33 +
   42.34 +    class Args:
   42.35 +
   42.36 +        from mod_python.util import FieldStorage
   42.37 +
   42.38 +        fieldStorage = FieldStorage( req, True )
   42.39 +
   42.40 +        # return a list of values for the given key,
   42.41 +        # or None if key not there
   42.42 +        def get( self, var ):
   42.43 +            retVar = self.fieldStorage.getlist( var )
   42.44 +            if len( retVar ) == 0:
   42.45 +                return None
   42.46 +            else:
   42.47 +                return retVar
   42.48 +
   42.49 +        # return a list of tuples, 
   42.50 +        # (key, value) where value is a list of values
   42.51 +	def items( self ):
   42.52 +            result = [];
   42.53 +            for key in self.fieldStorage.keys():
   42.54 +            	result.append( (key, self.fieldStorage.getlist( key ) ) )
   42.55 +	    return result
   42.56 +
   42.57 +    args = Args()
   42.58 +
   42.59 +    uri = req.unparsed_uri
   42.60 +
   42.61 +
   42.62 +class Main( HTMLBase ):
   42.63 +    
   42.64 +    isLeaf = True
   42.65 +
   42.66 +    def __init__( self, urlWriter = None ):
   42.67 +        self.modules = { "node": NodeInfo, 
   42.68 +                         "list": DomList, 
   42.69 +                         "info": DomInfo,
   42.70 +                         "create": CreateDomain,
   42.71 +                         "migrate" : MigrateDomain,
   42.72 +                         "save" : SaveDomain,
   42.73 +                         "restore" : RestoreDomain }
   42.74 +
   42.75 +        # ordered list of module menus to display
   42.76 +        self.module_menus = [ "node", "create", "migrate", "save",
   42.77 +                              "restore", "list" ]
   42.78 +        HTMLBase.__init__(self)
   42.79 +        
   42.80 +    def render_POST( self, request ):
   42.81 +    
   42.82 +    	#decide what module post'd the action
   42.83 +                
   42.84 +    	args = getVar( 'args', request )
   42.85 +
   42.86 +        mod = getVar( 'mod', request )
   42.87 +                
   42.88 +        if mod in self.modules and args is None:
   42.89 +            module = self.modules[ mod ]
   42.90 +            #check module exists
   42.91 +            if module:
   42.92 +               module( self.mainUrlWriter ).perform( request )
   42.93 +        else:
   42.94 +            self.perform( request )     
   42.95 +    
   42.96 +        return self.render_GET( request )
   42.97 +
   42.98 +    #TODO: need to make this get the request uri automatically
   42.99 +    def mainUrlWriter( self, module ):
  42.100 +    	def fun( f ):
  42.101 +            return "index.psp?mod=%s%s" % ( module, f )
  42.102 +        return fun    
  42.103 +        
  42.104 +    def write_BODY( self, request ):
  42.105 +    
  42.106 +        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" )
  42.107 +        request.write( "<tr>\n" )
  42.108 +        request.write( " <td width='15px'>&nbsp;</td>" )
  42.109 +        request.write( " <td width='175px' align='center' valign'center'>" )
  42.110 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
  42.111 +        request.write( "   <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" )
  42.112 +        request.write( "   <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" )
  42.113 +        request.write( "   <tr><td height='60px' align='center'><p class='small'>SV Web Interface<br/>(C) <a href='mailto:tw275@cam.ac.uk'>Tom Wilkie</a> 2004</p></td></tr>")
  42.114 +        request.write( "   <tr><td align='center' valign='top'>" )
  42.115 +
  42.116 +        for modName in self.module_menus:
  42.117 +            self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request )
  42.118 +        
  42.119 +        request.write( "   </td></tr>" )
  42.120 +        request.write( "  </table>" )
  42.121 +        request.write( " &nbsp;" )
  42.122 +        request.write( " </td>\n" )
  42.123 +        request.write( " <td width='15px'>&nbsp;</td>" )
  42.124 +        request.write( " <td width='558px' align='left' valign='top'>" )
  42.125 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
  42.126 +        request.write( "   <tr><td height='20px'></td></tr>" )
  42.127 +        request.write( "   <tr><td align='center' valign='top'>" )
  42.128 +        
  42.129 +        modName = getVar('mod', request)
  42.130 +        
  42.131 +        if modName not in self.modules:
  42.132 +            request.write( '<p>Please select a module</p>' )
  42.133 +        else:
  42.134 +            module = self.modules[ modName ]
  42.135 +            if module:
  42.136 +               module( self.mainUrlWriter( modName ) ).write_BODY( request )  
  42.137 +            else:
  42.138 +               request.write( '<p>Invalid module. Please select another</p>' )
  42.139 +    
  42.140 +        request.write( "   </td></tr>" )
  42.141 +        request.write( "  </table>" )
  42.142 +        request.write( " </td>\n" )
  42.143 +        request.write( " <td width='17px'>&nbsp;</td>" )
  42.144 +        request.write( "</tr>\n" )
  42.145 +        
  42.146 +        request.write( "</table>\n" )
  42.147 +        
  42.148 +                
  42.149 +    def op_destroy( self, request ):
  42.150 +    	dom = getVar( 'dom', request )
  42.151 +        if not dom is None and dom != "0":
  42.152 +            server.xend_domain_destroy( int( dom ), "halt" ) 
  42.153 +                 
  42.154 +    def op_pause( self, request ):
  42.155 +    	dom = getVar( 'dom', request )
  42.156 +        if not dom is None and dom != "0":
  42.157 +            server.xend_domain_pause( int( dom ) )      
  42.158 +    
  42.159 +    def op_unpause( self, request ):
  42.160 +    	dom = getVar( 'dom', request )
  42.161 +        if not dom is None and dom != "0":
  42.162 +            server.xend_domain_unpause( int( dom ) )      
  42.163 +
  42.164 +main = Main()
  42.165 +
  42.166 +main.render_POST( TwistedAdapter() )
  42.167 +%>