ia64/xen-unstable

changeset 5893:2333f6616d18

merge?
author cl349@firebug.cl.cam.ac.uk
date Tue Jul 26 18:41:39 2005 +0000 (2005-07-26)
parents 69beaae8a1fa 22984cc20ff9
children 4c52791a0444
files linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/asm-xen/xenbus.h tools/Makefile tools/python/setup.py tools/python/xen/lowlevel/xs/xs.c 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/python/xen/xend/image.py tools/python/xen/xm/main.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 tools/xenstore/Makefile tools/xenstore/TODO tools/xenstore/testsuite/02directory.sh tools/xenstore/testsuite/07watch.sh tools/xenstore/testsuite/08transaction.sh tools/xenstore/testsuite/09domain.sh tools/xenstore/testsuite/10domain-homedir.sh tools/xenstore/testsuite/11domain-watch.sh tools/xenstore/testsuite/12readonly.sh tools/xenstore/testsuite/test.sh tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_domain.c tools/xenstore/xenstored_domain.h tools/xenstore/xenstored_transaction.c tools/xenstore/xenstored_transaction.h tools/xenstore/xenstored_watch.c tools/xenstore/xenstored_watch.h tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_random.c tools/xenstore/xs_test.c
line diff
     7.1 --- a/tools/python/setup.py	Tue Jul 26 17:38:33 2005 +0000
     7.2 +++ b/tools/python/setup.py	Tue Jul 26 18:41:39 2005 +0000
     7.3 @@ -51,6 +51,7 @@ setup(name            = 'xen',
     7.4                           'xen.xend.xenstore',
     7.5                           'xen.xm',
     7.6                           'xen.web',
     7.7 +						 'xen.sv'
     7.8                           ],
     7.9        ext_package = "xen.lowlevel",
    7.10        ext_modules = [ xc, xu, xs ]
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/python/xen/sv/CreateDomain.py	Tue Jul 26 18:41:39 2005 +0000
     9.3 @@ -0,0 +1,163 @@
     9.4 +from xen.sv.Wizard import *
     9.5 +from xen.sv.util import *
     9.6 +from xen.sv.GenTabbed import PreTab
     9.7 +
     9.8 +from xen.xm.create import make_config, OptVals
     9.9 +
    9.10 +from xen.xend.XendClient import server
    9.11 +
    9.12 +class CreateDomain( Wizard ):
    9.13 +    def __init__( self, urlWriter ):
    9.14 +    	
    9.15 +    	sheets = [ CreatePage0,
    9.16 +          	   CreatePage1,
    9.17 +          	   CreatePage2,
    9.18 +                   CreatePage3,
    9.19 +                   CreatePage4,
    9.20 +                   CreateFinish ]
    9.21 +    
    9.22 +    	Wizard.__init__( self, urlWriter, "Create Domain", sheets )
    9.23 +       
    9.24 +class CreatePage0( Sheet ):
    9.25 +
    9.26 +    def __init__( self, urlWriter ):
    9.27 +        Sheet.__init__( self, urlWriter, "General", 0 )
    9.28 +        self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) )
    9.29 +        self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) )
    9.30 +        self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) )
    9.31 +        self.addControl( InputControl( 'cpu_weight', '1', 'CPU Weight:', "[\\d]+", "You must enter a number in this feild" ) )
    9.32 +                        
    9.33 +class CreatePage1( Sheet ):
    9.34 +
    9.35 +    def __init__( self, urlWriter ):
    9.36 +        Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 )
    9.37 +# For now we don't need to select a builder...
    9.38 +#        self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) )
    9.39 +        self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.6.9-xenU', 'Kernel Image:' ) )
    9.40 +        self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) )
    9.41 +
    9.42 +class CreatePage2( Sheet ):
    9.43 +
    9.44 +    def __init__( self, urlWriter ):
    9.45 +    	Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 )
    9.46 +        self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) )
    9.47 +
    9.48 +class CreatePage3( Sheet ):
    9.49 +
    9.50 +    def __init__( self, urlWriter ):
    9.51 +        Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 )
    9.52 +        
    9.53 +    def write_BODY( self, request, err ):
    9.54 +        if not self.passback: self.parseForm( request )
    9.55 +    
    9.56 +    	previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
    9.57 +        
    9.58 +        num_vbds = previous_values.get( 'num_vbds' )
    9.59 +        
    9.60 +        for i in range( int( num_vbds ) ):
    9.61 +            self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i  ) )
    9.62 +            self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) )
    9.63 +            self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) )
    9.64 +            
    9.65 +        self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) )
    9.66 +        
    9.67 +        Sheet.write_BODY( self, request, err )
    9.68 +                
    9.69 +class CreatePage4( Sheet ):
    9.70 +
    9.71 +    def __init__( self, urlWriter ):        
    9.72 +        Sheet.__init__( self, urlWriter, "Network settings", 4 )
    9.73 +        self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) )
    9.74 +        self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) )
    9.75 +        self.addControl( InputControl( 'ip_addr', '1.2.3.4', 'VM IP Address:' ) )
    9.76 +        self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) ) 
    9.77 +        self.addControl( InputControl( 'ip_gateway', '1.2.3.4', 'VM Gateway:' ) )           
    9.78 +        self.addControl( InputControl( 'ip_nfs', '1.2.3.4', 'NFS Server:' ) )  
    9.79 +                 
    9.80 +class CreateFinish( Sheet ):
    9.81 +
    9.82 +    def __init__( self, urlWriter ):
    9.83 +        Sheet.__init__( self, urlWriter, "All Done", 5 )
    9.84 +        
    9.85 +    def write_BODY( self, request, err ):
    9.86 +    
    9.87 +        if not self.passback: self.parseForm( request )
    9.88 +        
    9.89 +        xend_sxp = self.translate_sxp( string2sxp( self.passback ) )
    9.90 +        
    9.91 +        try:
    9.92 +            dom_sxp = server.xend_domain_create( xend_sxp )
    9.93 +            success = "Your domain was successfully created.\n"
    9.94 +        except:
    9.95 +            success = "There was an error creating your domain.\nThe configuration used is as follows:\n"
    9.96 +            dom_sxp = xend_sxp
    9.97 +            
    9.98 +            
    9.99 +        
   9.100 +        pt = PreTab( success + sxp2prettystring( dom_sxp ) )
   9.101 +        pt.write_BODY( request )
   9.102 +
   9.103 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   9.104 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
   9.105 +    
   9.106 +    def translate_sxp( self, fin_sxp ):
   9.107 +   	fin_hash = ssxp2hash( fin_sxp )
   9.108 +    
   9.109 +        def get( key ):
   9.110 +            ret = fin_hash.get( key )
   9.111 +            if ret:
   9.112 +                return ret
   9.113 +            else:
   9.114 +                return ""
   9.115 +        
   9.116 +    	vals = OptVals()
   9.117 +        
   9.118 +        vals.name = 	get( 'name' )
   9.119 +        vals.memory = 	get( 'memory' )
   9.120 +        vals.maxmem =   get( 'maxmem' )
   9.121 +        vals.cpu =  	get( 'cpu' )
   9.122 +        vals.cpu_weight = get( 'cpu_weight' )
   9.123 +        
   9.124 +        vals.builder =  get( 'builder' )       
   9.125 +        vals.kernel =   get( 'kernel' )
   9.126 +	vals.root = 	get( 'root' )
   9.127 +        vals.extra = 	get( 'extra' )
   9.128 +        
   9.129 +        #setup vbds
   9.130 +        
   9.131 +        vbds = []
   9.132 +        
   9.133 +        for i in range( int( get( 'num_vbds' ) ) ):
   9.134 +            vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) )
   9.135 +        
   9.136 +        vals.disk = vbds    
   9.137 +            
   9.138 +        #misc
   9.139 +        
   9.140 +        vals.pci = []
   9.141 +        
   9.142 +        vals.blkif = None
   9.143 +        vals.netif = None
   9.144 +        vals.restart = None
   9.145 +        vals.console = None
   9.146 +        vals.ramdisk = None
   9.147 +        
   9.148 +        #setup vifs
   9.149 +        
   9.150 +        vals.vif = []
   9.151 +        vals.nics = 1
   9.152 +                
   9.153 +        ip =   get( 'ip_addr' )
   9.154 +        nfs =  get( 'ip_nfs' )
   9.155 +        gate = get( 'ip_gateway' )
   9.156 +        mask = get( 'ip_subnet' )
   9.157 +        host = get( 'hostname' )
   9.158 +        dhcp = get( 'dhcp' )
   9.159 +        
   9.160 +        vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp)
   9.161 +        
   9.162 +        try:
   9.163 +            return make_config( vals )
   9.164 +        except:
   9.165 +            return [["Error creating domain config."]]    
   9.166 +        
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/python/xen/sv/Daemon.py	Tue Jul 26 18:41:39 2005 +0000
    10.3 @@ -0,0 +1,110 @@
    10.4 +###########################################################
    10.5 +## XenSV Web Control Interface Daemon
    10.6 +## Copyright (C) 2004, K A Fraser (University of Cambridge)
    10.7 +## Copyright (C) 2004, Mike Wray <mike.wray@hp.com>
    10.8 +## Copyright (C) 2004, Tom Wilkie <tw275@cam.ac.uk>
    10.9 +###########################################################
   10.10 +
   10.11 +import os
   10.12 +import os.path
   10.13 +import sys
   10.14 +import re
   10.15 +
   10.16 +from xen.sv.params import *
   10.17 +
   10.18 +from twisted.internet import reactor
   10.19 +from twisted.web import static, server, script
   10.20 +
   10.21 +from xen.util.ip import _readline, _readlines
   10.22 +
   10.23 +class Daemon:
   10.24 +    """The xend daemon.
   10.25 +    """
   10.26 +    def __init__(self):
   10.27 +        self.shutdown = 0
   10.28 +        self.traceon = 0
   10.29 +
   10.30 +    def daemon_pids(self):
   10.31 +        pids = []
   10.32 +        pidex = '(?P<pid>\d+)'
   10.33 +        pythonex = '(?P<python>\S*python\S*)'
   10.34 +        cmdex = '(?P<cmd>.*)'
   10.35 +        procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$')
   10.36 +        xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$')
   10.37 +        procs = os.popen('ps -e -o pid,args 2>/dev/null')
   10.38 +        for proc in procs:
   10.39 +            pm = procre.match(proc)
   10.40 +            if not pm: continue
   10.41 +            xm = xendre.match(pm.group('cmd'))
   10.42 +            if not xm: continue
   10.43 +            #print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd')
   10.44 +            pids.append(int(pm.group('pid')))
   10.45 +        return pids
   10.46 +
   10.47 +    def new_cleanup(self, kill=0):
   10.48 +        err = 0
   10.49 +        pids = self.daemon_pids()
   10.50 +        if kill:
   10.51 +            for pid in pids:
   10.52 +                print "Killing daemon pid=%d" % pid
   10.53 +                os.kill(pid, signal.SIGHUP)
   10.54 +        elif pids:
   10.55 +            err = 1
   10.56 +            print "Daemon already running: ", pids
   10.57 +        return err
   10.58 +            
   10.59 +    def cleanup(self, kill=False):
   10.60 +        # No cleanup to do if PID_FILE is empty.
   10.61 +        if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE):
   10.62 +            return 0
   10.63 +        # Read the pid of the previous invocation and search active process list.
   10.64 +        pid = open(PID_FILE, 'r').read()
   10.65 +        lines = _readlines(os.popen('ps ' + pid + ' 2>/dev/null'))
   10.66 +        for line in lines:
   10.67 +            if re.search('^ *' + pid + '.+xensv', line):
   10.68 +                if not kill:
   10.69 +                    print "Daemon is already running (pid %d)" % int(pid)
   10.70 +                    return 1
   10.71 +                # Old daemon is still active: terminate it.
   10.72 +                os.kill(int(pid), 1)
   10.73 +        # Delete the stale PID_FILE.
   10.74 +        os.remove(PID_FILE)
   10.75 +        return 0
   10.76 +
   10.77 +    def start(self, trace=0):
   10.78 +        if self.cleanup(kill=False):
   10.79 +            return 1
   10.80 +   
   10.81 +        # Fork -- parent writes PID_FILE and exits.
   10.82 +        pid = os.fork()
   10.83 +        if pid:
   10.84 +            # Parent
   10.85 +            pidfile = open(PID_FILE, 'w')
   10.86 +            pidfile.write(str(pid))
   10.87 +            pidfile.close()
   10.88 +            return 0
   10.89 +        # Child
   10.90 +        self.run()
   10.91 +        return 0
   10.92 +
   10.93 +    def stop(self):
   10.94 +        return self.cleanup(kill=True)
   10.95 +
   10.96 +    def run(self):
   10.97 +	root = static.File( SV_ROOT )
   10.98 +        root.indexNames = [ 'Main.rpy' ]
   10.99 +        root.processors = { '.rpy': script.ResourceScript }
  10.100 +        reactor.listenTCP( SV_PORT, server.Site( root ) )
  10.101 +        reactor.run()
  10.102 +
  10.103 +    def exit(self):
  10.104 +        reactor.disconnectAll()
  10.105 +        sys.exit(0)
  10.106 +
  10.107 +def instance():
  10.108 +    global inst
  10.109 +    try:
  10.110 +        inst
  10.111 +    except:
  10.112 +        inst = Daemon()
  10.113 +    return inst
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/python/xen/sv/DomInfo.py	Tue Jul 26 18:41:39 2005 +0000
    11.3 @@ -0,0 +1,148 @@
    11.4 +from xen.xend.XendClient import server
    11.5 +from xen.xend import PrettyPrint
    11.6 +
    11.7 +from xen.sv.HTMLBase import HTMLBase
    11.8 +from xen.sv.util import *
    11.9 +from xen.sv.GenTabbed import *
   11.10 +
   11.11 +DEBUG=1
   11.12 +
   11.13 +class DomInfo( GenTabbed ):
   11.14 +
   11.15 +    def __init__( self, urlWriter ):
   11.16 +        
   11.17 +        self.dom = 0;
   11.18 +    
   11.19 +        def tabUrlWriter( tab ):
   11.20 +            return urlWriter( "&dom=%s%s" % ( self.dom, tab ) )
   11.21 +        
   11.22 +        GenTabbed.__init__( self, "Domain Info", tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGeneralTab, DomSXPTab, NullTab ]  )
   11.23 +
   11.24 +    def write_BODY( self, request ):
   11.25 +        dom = request.args.get('dom')
   11.26 +        
   11.27 +        if dom is None or len(dom) != 1:
   11.28 +            request.write( "<p>Please Select a Domain</p>" )
   11.29 +            return None
   11.30 +        else:
   11.31 +            self.dom = dom[0]
   11.32 +        
   11.33 +        GenTabbed.write_BODY( self, request )
   11.34 +        
   11.35 +    def write_MENU( self, request ):
   11.36 +        pass
   11.37 +
   11.38 +class DomGeneralTab( CompositeTab ):
   11.39 +    def __init__( self ):
   11.40 +       CompositeTab.__init__( self, [ DomGenTab, DomActionTab ] )        
   11.41 +        
   11.42 +class DomGenTab( GeneralTab ):
   11.43 +
   11.44 +    def __init__( self ):
   11.45 +    
   11.46 +        titles = {}
   11.47 +    
   11.48 +        titles[ 'ID' ] = 'dom'      
   11.49 +        titles[ 'Name' ] = 'name'
   11.50 +        titles[ 'CPU' ] = 'cpu'
   11.51 +        titles[ 'Memory' ] = ( 'mem', memoryFormatter )
   11.52 +        titles[ 'State' ] = ( 'state', stateFormatter )
   11.53 +        titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter )
   11.54 +        titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter )
   11.55 +    
   11.56 +        GeneralTab.__init__( self, {}, titles )
   11.57 +        
   11.58 +    def write_BODY( self, request ):
   11.59 +    
   11.60 +        self.dom = getVar('dom', request)
   11.61 +        
   11.62 +        if self.dom is None:
   11.63 +            request.write( "<p>Please Select a Domain</p>" )
   11.64 +            return None
   11.65 +            
   11.66 +        self.dict = getDomInfoHash( self.dom )
   11.67 +        
   11.68 +        GeneralTab.write_BODY( self, request )
   11.69 +            
   11.70 +class DomSXPTab( PreTab ):
   11.71 +
   11.72 +    def __init__( self ):
   11.73 +        self.dom = 0
   11.74 +        PreTab.__init__( self, "" )
   11.75 +
   11.76 +
   11.77 +    def write_BODY( self, request ):
   11.78 +        self.dom = getVar('dom', request)
   11.79 +        
   11.80 +        if self.dom is None:
   11.81 +            request.write( "<p>Please Select a Domain</p>" )
   11.82 +            return None
   11.83 +
   11.84 +        try:
   11.85 +            domInfo = server.xend_domain( self.dom )
   11.86 +        except:
   11.87 +            domInfo = [["Error getting domain details."]]
   11.88 +            
   11.89 +        self.source = sxp2prettystring( domInfo )
   11.90 +        
   11.91 +        PreTab.write_BODY( self, request )
   11.92 +        
   11.93 +class DomActionTab( ActionTab ):
   11.94 +
   11.95 +    def __init__( self ):
   11.96 +    	actions = { "shutdown" : "shutdown",
   11.97 +        	    "reboot" : "reboot",
   11.98 +                    "pause" : "pause",
   11.99 +                    "unpause" : "unpause",
  11.100 +                    "destroy" : "destroy" }
  11.101 +        ActionTab.__init__( self, actions )    
  11.102 +        
  11.103 +    def op_shutdown( self, request ):
  11.104 +   	dom = getVar( 'dom', request )
  11.105 +        if not dom is None and dom != '0':
  11.106 +    	   if DEBUG: print ">DomShutDown %s" % dom
  11.107 +           try:
  11.108 +    	   	server.xend_domain_shutdown( int( dom ), "halt" )
  11.109 +           except:
  11.110 +           	pass
  11.111 +    
  11.112 +    def op_reboot( self, request ):
  11.113 +       	dom = getVar( 'dom', request )
  11.114 +        if not dom is None and dom != '0':
  11.115 +    	    if DEBUG: print ">DomReboot %s" % dom
  11.116 +            try:
  11.117 +            	server.xend_domain_shutdown( int( dom ), "reboot" )
  11.118 +            except:
  11.119 +            	pass
  11.120 +                
  11.121 +    def op_pause( self, request ):
  11.122 +       	dom = getVar( 'dom', request )
  11.123 +        if not dom is None and dom != '0':
  11.124 +    	    if DEBUG: print ">DomPause %s" % dom
  11.125 +            try:
  11.126 +                server.xend_domain_pause( int( dom ) )
  11.127 +            except:
  11.128 +            	pass
  11.129 +               
  11.130 +    def op_unpause( self, request ):
  11.131 +       	dom = getVar( 'dom', request )
  11.132 +        if not dom is None and dom != '0':
  11.133 +    	   if DEBUG: print ">DomUnpause %s" % dom
  11.134 +           try:
  11.135 +               server.xend_domain_unpause( int( dom ) )
  11.136 +    	   except:
  11.137 +               pass
  11.138 +               
  11.139 +    def op_destroy( self, request ):
  11.140 +    	dom = getVar( 'dom', request )
  11.141 +        if not dom is None and dom != '0':
  11.142 +    	   if DEBUG: print ">DomDestroy %s" % dom
  11.143 +           try:
  11.144 +           	server.xend_domain_destroy( int( dom ), "halt" )
  11.145 +           except:
  11.146 +           	pass
  11.147 +        
  11.148 +    
  11.149 +    
  11.150 +        
  11.151 +
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/python/xen/sv/DomList.py	Tue Jul 26 18:41:39 2005 +0000
    12.3 @@ -0,0 +1,81 @@
    12.4 +from xen.xend.XendClient import server
    12.5 +from xen.xend import sxp
    12.6 +
    12.7 +from xen.sv.HTMLBase import HTMLBase
    12.8 +from xen.sv.util import *
    12.9 +
   12.10 +class DomList( HTMLBase ):
   12.11 +    
   12.12 +    isLeaf = True
   12.13 +
   12.14 +    def __init__( self, urlWriter ):
   12.15 +        HTMLBase.__init__(self)
   12.16 +        self.urlWriter = urlWriter
   12.17 +        
   12.18 +    def write_MENU( self, request ):
   12.19 +    	return self.write_BODY( request, head=True, long=False ) 
   12.20 +
   12.21 +    def write_BODY( self, request, head=True, long=True ):
   12.22 +        
   12.23 +    	domains = []
   12.24 +    
   12.25 +        try:
   12.26 +            domains = server.xend_domains()
   12.27 +            domains.sort()
   12.28 +  	except:
   12.29 +            pass
   12.30 +                
   12.31 +        request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" )
   12.32 +        
   12.33 +        if head:
   12.34 +            request.write( "<tr class='domainInfoHead'>" )
   12.35 +            self.write_DOMAIN_HEAD( request, long )
   12.36 +            request.write( "</tr>" )
   12.37 +        
   12.38 +        odd = True
   12.39 +        
   12.40 +        if not domains is None:
   12.41 +            for domain in domains:
   12.42 +                if odd:
   12.43 +                    request.write( "<tr class='domainInfoOdd'>\n" )
   12.44 +                    odd = False
   12.45 +                else:
   12.46 +                    request.write( "<tr class='domainInfoEven'>\n" )
   12.47 +                    odd = True
   12.48 +                self.write_DOMAIN( request, getDomInfoHash( domain ), long )
   12.49 +                request.write( "</tr>\n" )
   12.50 +        else:
   12.51 +        	request.write( "<tr colspan='10'><p class='small'>Error getting domain list<br/>Perhaps XenD not running?</p></tr>")
   12.52 +                
   12.53 +        request.write( "</table>\n" )
   12.54 +            
   12.55 +    def write_DOMAIN( self, request, domInfoHash, long=True ):   
   12.56 +        request.write( "<td class='domainInfo' align='center'>%(id)s</td>\n" % domInfoHash )
   12.57 +
   12.58 +        url = self.urlWriter( "&mod=info&dom=%(id)s" % domInfoHash )
   12.59 +
   12.60 +        request.write( "<td class='domainInfo' align='center'><a href='%s'>%s</a></td>\n" % ( url, domInfoHash['name'] ) )
   12.61 +        if long: 
   12.62 +            request.write( "<td class='domainInfo' align='center'>%(memory)5s</td>\n" % domInfoHash )
   12.63 +            request.write( "<td class='domainInfo' align='center'>%(cpu)2s</td>\n" % domInfoHash )
   12.64 +        request.write( "<td class='domainInfo' align='center'>%(state)5s</td>\n" % domInfoHash )
   12.65 +        if domInfoHash[ 'id' ] != "0":
   12.66 +            request.write( "<td class='domainInfo' align='center'>" )
   12.67 +            
   12.68 +            if domInfoHash[ 'state' ][ 2 ] == "-":
   12.69 +                request.write( "<img src='images/small-pause.png' onclick='doOp2( \"pause\", \"%(dom)-4s\" )'>" % domInfoHash )
   12.70 +            else:
   12.71 +                request.write( "<img src='images/small-unpause.png' onclick='doOp2( \"unpause\", \"%(dom)-4s\" )'>" % domInfoHash )              
   12.72 +            
   12.73 +            request.write( "<img src='images/small-destroy.png' onclick='doOp2( \"destroy\", \"%(dom)-4s\" )'></td>" % domInfoHash)
   12.74 +        else:
   12.75 +            request.write( "<td>&nbsp;</td>" )
   12.76 +
   12.77 +    def write_DOMAIN_HEAD( self, request, long=True ):
   12.78 +        request.write( "<td class='domainInfoHead' align='center'>Domain</td>\n" )      
   12.79 +        request.write( "<td class='domainInfoHead' align='center'>Name</td>\n" )      
   12.80 +        if long:
   12.81 +            request.write( "<td class='domainInfoHead' align='center'>Memory / Mb</td>\n" )      
   12.82 +            request.write( "<td class='domainInfoHead' align='center'>CPU</td>\n" )      
   12.83 +        request.write( "<td class='domainInfoHead' align='center'>State</td>\n" )      
   12.84 +        request.write( "<td class='domainInfoHead' align='center'></td>\n" )
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/python/xen/sv/GenTabbed.py	Tue Jul 26 18:41:39 2005 +0000
    13.3 @@ -0,0 +1,135 @@
    13.4 +import types
    13.5 +
    13.6 +from xen.sv.HTMLBase import HTMLBase
    13.7 +from xen.sv.TabView import TabView
    13.8 +from xen.sv.util import getVar
    13.9 +
   13.10 +class GenTabbed( HTMLBase ):
   13.11 +
   13.12 +    def __init__( self, title, urlWriter, tabStrings, tabObjects ):
   13.13 +        HTMLBase.__init__(self)
   13.14 +        self.tabStrings = tabStrings
   13.15 +        self.tabObjects = tabObjects
   13.16 +        self.urlWriter = urlWriter
   13.17 +        self.title = title
   13.18 +
   13.19 +    def write_BODY( self, request, urlWriter = None ):
   13.20 +        try:
   13.21 +            tab = int( getVar( 'tab', request, 0 ) )
   13.22 +        except:
   13.23 +            tab = 0
   13.24 +            
   13.25 +        request.write( "<table style='' width='100%' border='0' cellspacing='0' cellpadding='0'>" )
   13.26 +        request.write( "<tr><td>" )
   13.27 +        request.write( "<p align='center'><u>%s</u></p>" % self.title )
   13.28 +        
   13.29 +        TabView( tab, self.tabStrings, self.urlWriter ).write_BODY( request )
   13.30 +        
   13.31 +        request.write( "</td></tr><tr><td>" )
   13.32 +
   13.33 +        try:
   13.34 +            render_tab = self.tabObjects[ tab ]
   13.35 +            render_tab().write_BODY( request )
   13.36 +        except:
   13.37 +            request.write( "<p>Error Rendering Tab</p>" )
   13.38 +       
   13.39 +        request.write( "</td></tr></table>" )
   13.40 +       
   13.41 +    def perform( self, request ):
   13.42 +        try:
   13.43 +            tab = int( getVar( 'tab', request, 0 ) )
   13.44 +        except:
   13.45 +            tab = 0;
   13.46 +            
   13.47 +        op_tab = self.tabObjects[ tab ]
   13.48 +        
   13.49 +        if op_tab:
   13.50 +            op_tab().perform( request )
   13.51 +        
   13.52 +class PreTab( HTMLBase ):
   13.53 +
   13.54 +    def __init__( self, source ):
   13.55 +        HTMLBase.__init__( self )
   13.56 +        self.source = source
   13.57 +    
   13.58 +    def write_BODY( self, request ):
   13.59 +        
   13.60 +        request.write( "<div style='display: block; overflow: auto; border: 0px solid black; width: 540px; padding: 5px; z-index:0; align: center'><pre>" )
   13.61 +        
   13.62 +        request.write( self.source )
   13.63 +        
   13.64 +        request.write( "</pre></div>" )
   13.65 +
   13.66 +class GeneralTab( HTMLBase ):
   13.67 +                        
   13.68 +    def __init__( self, dict, titles ):
   13.69 +        HTMLBase.__init__( self )
   13.70 +        self.dict = dict
   13.71 +        self.titles = titles
   13.72 +                        
   13.73 +    def write_BODY( self, request ): 
   13.74 +        
   13.75 +        request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" )
   13.76 +        
   13.77 +        def writeAttr( niceName, attr, formatter=None ):
   13.78 +            if type( attr ) is types.TupleType:
   13.79 +                ( attr, formatter ) = attr
   13.80 +            
   13.81 +            if attr in self.dict:
   13.82 +                if formatter:
   13.83 +                    temp = formatter( self.dict[ attr ] )
   13.84 +                else:
   13.85 +                    temp = str( self.dict[ attr ] )
   13.86 +                request.write( "<tr><td width='50%%'><p>%s:</p></td><td width='50%%'><p>%s</p></td></tr>" % ( niceName, temp ) )
   13.87 +        
   13.88 +        for niceName, attr in self.titles.items():
   13.89 +            writeAttr( niceName, attr )
   13.90 +                            
   13.91 +        request.write( "</table>" )
   13.92 +
   13.93 +class NullTab( HTMLBase ):
   13.94 +    
   13.95 +    def __init__( self ):
   13.96 +        HTMLBase.__init__( self )
   13.97 +        self.title = "Null Tab"
   13.98 +
   13.99 +    def __init__( self, title ):
  13.100 +        HTMLBase.__init__( self )
  13.101 +        self.title = title
  13.102 +        
  13.103 +    def write_BODY( self, request ):
  13.104 +        request.write( "<p>%s</p>" % self.title )
  13.105 +
  13.106 +class ActionTab( HTMLBase ):
  13.107 +
  13.108 +    def __init__( self, actions ):
  13.109 +        self.actions = actions
  13.110 +        HTMLBase.__init__( self )
  13.111 +        
  13.112 +    def write_BODY( self, request ):
  13.113 +        request.write( "<p align='center'><table cellspacing='3' cellpadding='2' border='0'><tr>" )
  13.114 +    
  13.115 +        for ( command, text ) in self.actions.items():
  13.116 +            request.write( "<td style='border: 1px solid black; background-color: grey' onmouseover='buttonMouseOver( this )' onmouseout='buttonMouseOut( this )'>" )
  13.117 +            request.write( "<p><a href='javascript: doOp( \"%s\" );'>%s</a></p></td>" % (command, text) )
  13.118 + 
  13.119 +        request.write("</table></p>")        
  13.120 +        
  13.121 +class CompositeTab( HTMLBase ):
  13.122 +
  13.123 +    def __init__( self, tabs ):
  13.124 +    	HTMLBase.__init__( self )
  13.125 +        self.tabs = tabs
  13.126 +        
  13.127 +    def write_BODY( self, request ):
  13.128 +    	for tab in self.tabs:
  13.129 +            request.write( "<br/>" )
  13.130 +            tab().write_BODY( request )
  13.131 +            
  13.132 +    def perform( self, request ):
  13.133 +    	for tab in self.tabs:
  13.134 +            tab().perform( request )
  13.135 +    
  13.136 +    
  13.137 +       
  13.138 +        
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/python/xen/sv/HTMLBase.py	Tue Jul 26 18:41:39 2005 +0000
    14.3 @@ -0,0 +1,62 @@
    14.4 +from xen.sv.util import *
    14.5 +
    14.6 +class HTMLBase:
    14.7 +
    14.8 +    isLeaf = True
    14.9 + 
   14.10 +    def __init__( self ):
   14.11 +        pass
   14.12 +
   14.13 +    def render_POST( self, request ):
   14.14 +        self.perform( request )
   14.15 +        return self.render_GET( request )
   14.16 +        
   14.17 +    def render_GET( self, request ):
   14.18 +        self.write_TOP( request )
   14.19 +        self.write_BODY( request )
   14.20 +        self.write_BOTTOM( request )
   14.21 +        return ''
   14.22 +                
   14.23 +    def write_BODY( self, request ):
   14.24 +        request.write( "BODY" )
   14.25 +        
   14.26 +    def write_TOP( self, request ):
   14.27 +        request.write( '<html><head><title>Xen</title><link rel="stylesheet" type="text/css" href="inc/style.css" />' )
   14.28 +        request.write( '<script src="inc/script.js"></script>' )
   14.29 +        request.write( '</head><body>' )
   14.30 +        request.write('<form method="post" action="%s">' % request.uri)
   14.31 +
   14.32 +    def write_BOTTOM( self, request ):
   14.33 +        request.write('<input type="hidden" name="op" value="">')
   14.34 +        request.write('<input type="hidden" name="args" value="">')
   14.35 +        request.write('</form>')
   14.36 +        request.write( "</body></html>" )
   14.37 +
   14.38 +    def get_op_method(self, op):
   14.39 +        """Get the method for an operation.
   14.40 +        For operation 'foo' looks for 'op_foo'.
   14.41 +
   14.42 +        op	operation name
   14.43 +        returns method or None
   14.44 +        """
   14.45 +        op_method_name = 'op_' + op
   14.46 +        return getattr(self, op_method_name, None)
   14.47 +        
   14.48 +    def perform(self, req):
   14.49 +        """General operation handler for posted operations.
   14.50 +        For operation 'foo' looks for a method op_foo and calls
   14.51 +        it with op_foo(req). Replies with code 500 if op_foo
   14.52 +        is not found.
   14.53 +
   14.54 +        The method must return a list when req.use_sxp is true
   14.55 +        and an HTML string otherwise (or list).
   14.56 +        Methods may also return a Deferred (for incomplete processing).
   14.57 +
   14.58 +        req	request
   14.59 +        """
   14.60 +        op = req.args.get('op')
   14.61 +        if not op is None and len(op) == 1:
   14.62 +            op = op[0]
   14.63 +            op_method = self.get_op_method(op)
   14.64 +            if op_method:
   14.65 +                op_method( req )   
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/python/xen/sv/Main.py	Tue Jul 26 18:41:39 2005 +0000
    15.3 @@ -0,0 +1,113 @@
    15.4 +from xen.sv.HTMLBase import HTMLBase
    15.5 +from xen.sv.DomList  import DomList
    15.6 +from xen.sv.NodeInfo import NodeInfo
    15.7 +from xen.sv.DomInfo  import DomInfo
    15.8 +from xen.sv.CreateDomain import CreateDomain
    15.9 +from xen.sv.MigrateDomain import MigrateDomain
   15.10 +from xen.sv.SaveDomain import SaveDomain
   15.11 +from xen.sv.RestoreDomain import RestoreDomain
   15.12 +
   15.13 +from xen.xend.XendClient import server
   15.14 +
   15.15 +from xen.sv.util import getVar
   15.16 +
   15.17 +class Main( HTMLBase ):
   15.18 +    
   15.19 +    isLeaf = True
   15.20 +
   15.21 +    def __init__( self, urlWriter = None ):
   15.22 +        self.modules = { "node": NodeInfo, 
   15.23 +                         "list": DomList, 
   15.24 +                         "info": DomInfo,
   15.25 +                         "create": CreateDomain,
   15.26 +                         "migrate" : MigrateDomain,
   15.27 +                         "save" : SaveDomain,
   15.28 +                         "restore" : RestoreDomain }
   15.29 +
   15.30 +        # ordered list of module menus to display
   15.31 +        self.module_menus = [ "node", "create", "migrate", "save",
   15.32 +                              "restore", "list" ]
   15.33 +        HTMLBase.__init__(self)
   15.34 +        
   15.35 +    def render_POST( self, request ):
   15.36 +    
   15.37 +    	#decide what module post'd the action
   15.38 +                
   15.39 +    	args = getVar( 'args', request )
   15.40 +
   15.41 +        mod = getVar( 'mod', request )
   15.42 +                
   15.43 +        if not mod is None and args is None:
   15.44 +            module = self.modules[ mod ]
   15.45 +            #check module exists
   15.46 +            if module:
   15.47 +               module( self.mainUrlWriter ).perform( request )
   15.48 +        else:
   15.49 +            self.perform( request )     
   15.50 +    
   15.51 +        return self.render_GET( request )
   15.52 +
   15.53 +    def mainUrlWriter( self, module ):
   15.54 +    	def fun( f ):
   15.55 +            return "Main.rpy?mod=%s%s" % ( module, f )
   15.56 +        return fun    
   15.57 +        
   15.58 +    def write_BODY( self, request ):
   15.59 +    
   15.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" )
   15.61 +        request.write( "<tr>\n" )
   15.62 +        request.write( " <td width='15px'>&nbsp;</td>" )
   15.63 +        request.write( " <td width='175px' align='center' valign'center'>" )
   15.64 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
   15.65 +        request.write( "   <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" )
   15.66 +        request.write( "   <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" )
   15.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>")
   15.68 +        request.write( "   <tr><td align='center' valign='top'>" )
   15.69 +
   15.70 +        for modName in self.module_menus:
   15.71 +            self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request )
   15.72 +        
   15.73 +        request.write( "   </td></tr>" )
   15.74 +        request.write( "  </table>" )
   15.75 +        request.write( " &nbsp;" )
   15.76 +        request.write( " </td>\n" )
   15.77 +        request.write( " <td width='15px'>&nbsp;</td>" )
   15.78 +        request.write( " <td width='558px' align='left' valign='top'>" )
   15.79 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
   15.80 +        request.write( "   <tr><td height='20px'></td></tr>" )
   15.81 +        request.write( "   <tr><td align='center' valign='top'>" )
   15.82 +        
   15.83 +        modName = getVar('mod', request)
   15.84 +        
   15.85 +        if modName is None:
   15.86 +            request.write( '<p>Please select a module</p>' )
   15.87 +        else:
   15.88 +            module = self.modules[ modName ]
   15.89 +            if module:
   15.90 +               module( self.mainUrlWriter( modName ) ).write_BODY( request )  
   15.91 +            else:
   15.92 +               request.write( '<p>Invalid module. Please select another</p>' )
   15.93 +    
   15.94 +        request.write( "   </td></tr>" )
   15.95 +        request.write( "  </table>" )
   15.96 +        request.write( " </td>\n" )
   15.97 +        request.write( " <td width='17px'>&nbsp;</td>" )
   15.98 +        request.write( "</tr>\n" )
   15.99 +        
  15.100 +        request.write( "</table>\n" )
  15.101 +        
  15.102 +                
  15.103 +    def op_destroy( self, request ):
  15.104 +    	dom = getVar( 'dom', request )
  15.105 +        if not dom is None and dom != "0":
  15.106 +            server.xend_domain_destroy( int( dom ), "halt" ) 
  15.107 +                 
  15.108 +    def op_pause( self, request ):
  15.109 +    	dom = getVar( 'dom', request )
  15.110 +        if not dom is None and dom != "0":
  15.111 +            server.xend_domain_pause( int( dom ) )      
  15.112 +    
  15.113 +    def op_unpause( self, request ):
  15.114 +    	dom = getVar( 'dom', request )
  15.115 +        if not dom is None and dom != "0":
  15.116 +            server.xend_domain_unpause( int( dom ) )      
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/python/xen/sv/MigrateDomain.py	Tue Jul 26 18:41:39 2005 +0000
    16.3 @@ -0,0 +1,74 @@
    16.4 +from xen.sv.Wizard import *
    16.5 +from xen.sv.util import *
    16.6 +from xen.sv.GenTabbed import PreTab
    16.7 +
    16.8 +from xen.xm.create import make_config, OptVals
    16.9 +
   16.10 +from xen.xend.XendClient import server
   16.11 +
   16.12 +class MigrateDomain( Wizard ):
   16.13 +    def __init__( self, urlWriter ):
   16.14 +
   16.15 +        sheets = [ ChooseMigrateDomain,
   16.16 +                   DoMigrate ]
   16.17 +
   16.18 +        Wizard.__init__( self, urlWriter, "Migrate Domain", sheets )
   16.19 +
   16.20 +
   16.21 +class ChooseMigrateDomain( Sheet ):
   16.22 +    def __init__( self, urlWriter ):
   16.23 +        Sheet.__init__( self, urlWriter, "Configure Migration", 0)
   16.24 +	domains = []
   16.25 +	domnames = []
   16.26 +
   16.27 +        try:
   16.28 +            domains = server.xend_domains()
   16.29 +            domains.sort()
   16.30 +        except:
   16.31 +            pass
   16.32 +
   16.33 +        for i in domains:
   16.34 +            if i != 'Domain-0': domnames.append((i,i))
   16.35 +        
   16.36 +        self.addControl( ListControl('domid',
   16.37 +                                     domnames,
   16.38 +                                     'Domain ID:') )
   16.39 +        self.addControl( TickControl('live',
   16.40 +                                     'True',
   16.41 +                                     'Live migrate:') )
   16.42 +        self.addControl( InputControl('rate',
   16.43 +                                      '0',
   16.44 +                                      'Rate limit:') )
   16.45 +        self.addControl( InputControl( 'dest', 'myhost.mydomain',
   16.46 +                                       'Name or IP address:',
   16.47 +                                       ".*") )
   16.48 +
   16.49 +class DoMigrate( Sheet ):
   16.50 +    def __init__(self, urlWriter ):
   16.51 +        Sheet.__init__(self, urlWriter, "Migration Done", 1)
   16.52 +
   16.53 +    def write_BODY( self, request, err ):
   16.54 +
   16.55 +        if not self.passback: self.parseForm( request )
   16.56 +
   16.57 +#        print string2sxp(self.passback)
   16.58 +        
   16.59 +        config = ssxp2hash ( string2sxp( self.passback ) )
   16.60 +      
   16.61 +        try:
   16.62 +            print config
   16.63 +            print config['domid'], config['dest']
   16.64 +            dom_sxp = server.xend_domain_migrate( config['domid'],
   16.65 +                                                  config['dest'],
   16.66 +                                                  config.get('live') == 'True',
   16.67 +                                                  config['rate'] )
   16.68 +            success = "Your domain was successfully Migrated.\n"
   16.69 +        except Exception, e:
   16.70 +            success = "There was an error migrating your domain\n"
   16.71 +            dom_sxp = str(e)
   16.72 +        
   16.73 +        pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) )
   16.74 +        pt.write_BODY( request )
   16.75 +
   16.76 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   16.77 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/python/xen/sv/NodeInfo.py	Tue Jul 26 18:41:39 2005 +0000
    17.3 @@ -0,0 +1,63 @@
    17.4 +from xen.xend.XendClient import server
    17.5 +
    17.6 +from xen.sv.util import *
    17.7 +from xen.sv.GenTabbed import *
    17.8 +
    17.9 +class NodeInfo( GenTabbed ):
   17.10 +
   17.11 +    def __init__( self, urlWriter ):  
   17.12 +        GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', ], [ NodeGeneralTab, NodeDmesgTab ] )
   17.13 +    
   17.14 +    def write_MENU( self, request ):
   17.15 +        request.write( "<p class='small'><a href='%s'>Node details</a></p>" % self.urlWriter( '' ) )
   17.16 +
   17.17 +class NodeGeneralTab( CompositeTab ):
   17.18 +    def __init__( self ):
   17.19 +    	CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ] )        
   17.20 +        
   17.21 +class NodeInfoTab( GeneralTab ):
   17.22 +                        
   17.23 +    def __init__( self ):
   17.24 +         
   17.25 +    	nodeInfo = {}
   17.26 +        try:
   17.27 +            nodeInfo = sxp2hash( server.xend_node() )
   17.28 +   	except:
   17.29 +            nodeInfo[ 'system' ] = 'Error getting node info'
   17.30 +             
   17.31 +        dictTitles = {}
   17.32 +        dictTitles[ 'System' ] = 'system'
   17.33 +        dictTitles[ 'Hostname' ] = 'host' 
   17.34 +        dictTitles[ 'Release' ] = 'release' 
   17.35 +        dictTitles[ 'Version' ] ='version' 
   17.36 +        dictTitles[ 'Machine' ] = 'machine' 
   17.37 +        dictTitles[ 'Cores' ] = 'cores' 
   17.38 +        dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter )
   17.39 +        dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter )
   17.40 +        dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter )
   17.41 +        dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter )
   17.42 +        
   17.43 +        GeneralTab.__init__( self, dict=nodeInfo, titles=dictTitles )
   17.44 +
   17.45 +class NodeDmesgTab( PreTab ):
   17.46 +
   17.47 +    def __init__( self ):
   17.48 +    	try:
   17.49 +            dmesg = server.xend_node_get_dmesg()
   17.50 +        except:
   17.51 +            dmesg = "Error getting node information: XenD not running?"
   17.52 +        PreTab.__init__( self, dmesg )
   17.53 +  
   17.54 +class NodeActionTab( ActionTab ):
   17.55 +
   17.56 +    def __init__( self ):
   17.57 +        ActionTab.__init__( self, { "shutdown" : "shutdown",
   17.58 +        	"reboot" : "reboot" } )    
   17.59 +        
   17.60 +    def op_shutdown( self, request ):
   17.61 +        if debug: print ">NodeShutDown"
   17.62 +    	server.xend_node_shutdown()
   17.63 +    
   17.64 +    def op_reboot( self, request ):
   17.65 +        if debug: print ">NodeReboot"
   17.66 +        server.xend_node_reboot()
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/python/xen/sv/RestoreDomain.py	Tue Jul 26 18:41:39 2005 +0000
    18.3 @@ -0,0 +1,46 @@
    18.4 +from xen.sv.Wizard import *
    18.5 +from xen.sv.util import *
    18.6 +from xen.sv.GenTabbed import PreTab
    18.7 +
    18.8 +from xen.xm.create import make_config, OptVals
    18.9 +
   18.10 +from xen.xend.XendClient import server
   18.11 +
   18.12 +class RestoreDomain( Wizard ):
   18.13 +    def __init__( self, urlWriter ):
   18.14 +
   18.15 +        sheets = [ ChooseRestoreDomain,
   18.16 +                   DoRestore ]
   18.17 +
   18.18 +        Wizard.__init__( self, urlWriter, "Restore Domain", sheets )
   18.19 +
   18.20 +
   18.21 +class ChooseRestoreDomain( Sheet ):
   18.22 +    def __init__( self, urlWriter ):
   18.23 +        Sheet.__init__( self, urlWriter, "Configure Restore", 0)
   18.24 +        
   18.25 +        self.addControl( InputControl( 'file', '',
   18.26 +                                       'Suspend file name:',
   18.27 +                                       ".*") )
   18.28 +
   18.29 +class DoRestore( Sheet ):
   18.30 +    def __init__(self, urlWriter ):
   18.31 +        Sheet.__init__(self, urlWriter, "Restore Done", 1)
   18.32 +
   18.33 +    def write_BODY( self, request, err ):
   18.34 +
   18.35 +        if not self.passback: self.parseForm( request )
   18.36 +        config = ssxp2hash ( string2sxp( self.passback ) )
   18.37 +      
   18.38 +        try:
   18.39 +            dom_sxp = server.xend_domain_restore( config['file'] )
   18.40 +            success = "Your domain was successfully restored.\n"
   18.41 +        except Exception, e:
   18.42 +            success = "There was an error restoring your domain\n"
   18.43 +            dom_sxp = str(e)
   18.44 +        
   18.45 +        pt = PreTab( success + sxp2prettystring( dom_sxp ) )
   18.46 +        pt.write_BODY( request )
   18.47 +
   18.48 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   18.49 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/python/xen/sv/SaveDomain.py	Tue Jul 26 18:41:39 2005 +0000
    19.3 @@ -0,0 +1,62 @@
    19.4 +from xen.sv.Wizard import *
    19.5 +from xen.sv.util import *
    19.6 +from xen.sv.GenTabbed import PreTab
    19.7 +
    19.8 +from xen.xm.create import make_config, OptVals
    19.9 +
   19.10 +from xen.xend.XendClient import server
   19.11 +
   19.12 +class SaveDomain( Wizard ):
   19.13 +    def __init__( self, urlWriter ):
   19.14 +
   19.15 +        sheets = [ ChooseSaveDomain,
   19.16 +                   DoSave ]
   19.17 +
   19.18 +        Wizard.__init__( self, urlWriter, "Save Domain", sheets )
   19.19 +
   19.20 +
   19.21 +class ChooseSaveDomain( Sheet ):
   19.22 +    def __init__( self, urlWriter ):
   19.23 +        Sheet.__init__( self, urlWriter, "Configure Save", 0)
   19.24 +        
   19.25 +	domains = []
   19.26 +	domnames = []
   19.27 +
   19.28 +	try:
   19.29 +            domains = server.xend_domains()
   19.30 +            domains.sort()
   19.31 +        except:
   19.32 +            pass
   19.33 +
   19.34 +        for i in domains:
   19.35 +            if i != 'Domain-0': domnames.append((i,i))
   19.36 +        
   19.37 +        self.addControl( ListControl('domid',
   19.38 +                                     domnames,
   19.39 +                                     'Domain ID:') )
   19.40 +        self.addControl( InputControl( 'file', '',
   19.41 +                                       'Suspend file name:',
   19.42 +                                       ".*") )
   19.43 +
   19.44 +class DoSave( Sheet ):
   19.45 +    def __init__(self, urlWriter ):
   19.46 +        Sheet.__init__(self, urlWriter, "Save Done", 1)
   19.47 +
   19.48 +    def write_BODY( self, request, err ):
   19.49 +
   19.50 +        if not self.passback: self.parseForm( request )
   19.51 +        config = ssxp2hash ( string2sxp( self.passback ) )
   19.52 +      
   19.53 +        try:
   19.54 +            dom_sxp = server.xend_domain_save( config['domid'],
   19.55 +                                                  config['file'] )
   19.56 +            success = "Your domain was successfully saved.\n"
   19.57 +        except Exception, e:
   19.58 +            success = "There was an error saving your domain\n"
   19.59 +            dom_sxp = str(e)
   19.60 +        
   19.61 +        pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) )
   19.62 +        pt.write_BODY( request )
   19.63 +
   19.64 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
   19.65 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/python/xen/sv/TabView.py	Tue Jul 26 18:41:39 2005 +0000
    20.3 @@ -0,0 +1,26 @@
    20.4 +from xen.sv.HTMLBase import HTMLBase
    20.5 +
    20.6 +class TabView( HTMLBase ):
    20.7 +
    20.8 +    # tab - int, id into tabs of selected tab
    20.9 +    # tabs - list of strings, tab names
   20.10 +    # urlWriter - 
   20.11 +    def __init__( self, tab, tabs, urlWriter ):
   20.12 +        HTMLBase.__init__(self)
   20.13 +        self.tab = tab
   20.14 +        self.tabs = tabs
   20.15 +        self.urlWriter = urlWriter
   20.16 +
   20.17 +    def write_BODY( self, request ):
   20.18 +        request.write( "<table style='' border='0' cellspacing='3' cellpadding='2' align='center'>" )
   20.19 +        request.write( "<tr height='22'>" )                  
   20.20 +    
   20.21 +        for i in range( len( self.tabs ) ):
   20.22 +            if self.tab == i:
   20.23 +                backgroundColor = "white"
   20.24 +            else:
   20.25 +                backgroundColor = "grey"
   20.26 +        
   20.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 ] ) )
   20.28 +  
   20.29 +        request.write( "</tr></table>" )
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/python/xen/sv/Wizard.py	Tue Jul 26 18:41:39 2005 +0000
    21.3 @@ -0,0 +1,269 @@
    21.4 +from xen.sv.util import *
    21.5 +from xen.sv.HTMLBase import HTMLBase
    21.6 +from xen.xend import sxp
    21.7 +
    21.8 +import re
    21.9 +
   21.10 +DEBUG = 0
   21.11 +
   21.12 +class Wizard( HTMLBase ):
   21.13 +
   21.14 +    def __init__( self, urlWriter, title, sheets ):
   21.15 +        HTMLBase.__init__( self )
   21.16 +        self.title = title
   21.17 +        self.sheets = sheets
   21.18 +        self.urlWriter = urlWriter
   21.19 +        
   21.20 +    def write_MENU( self, request ):
   21.21 +    	request.write( "<p class='small'><a href='%s'>%s</a></p>" % (self.urlWriter( '' ), self.title) ) 
   21.22 +    
   21.23 +    def write_BODY( self, request ):
   21.24 +        
   21.25 +   	request.write( "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr><td>" )
   21.26 +        request.write( "<p align='center'><u>%s</u></p></td></tr><tr><td>" % self.title )
   21.27 +        
   21.28 +        currSheet = getVar( 'sheet', request )
   21.29 +    
   21.30 +        if not currSheet is None:
   21.31 +            currSheet = int( currSheet )
   21.32 +        else:
   21.33 +            currSheet = 0
   21.34 +            
   21.35 +        sheet = self.sheets[ currSheet ]( self.urlWriter )
   21.36 +        
   21.37 +        err = not sheet.validate( request )
   21.38 +        
   21.39 +        if not err:    
   21.40 +            op = getVar( 'op', request )
   21.41 +        
   21.42 +            if op == 'next':
   21.43 +               currSheet += 1
   21.44 +            elif op == 'prev':
   21.45 +               currSheet -= 1
   21.46 +             
   21.47 +            sheet = self.sheets[ currSheet ]( self.urlWriter )
   21.48 +        
   21.49 +        if getVar( 'visited-sheet%s' % currSheet, request ):
   21.50 +            sheet.write_BODY( request, err )
   21.51 +        else:
   21.52 +            sheet.write_BODY( request, False )
   21.53 +
   21.54 +        
   21.55 +        request.write( "</td></tr><tr><td><table width='100%' border='0' cellspacing='0' cellpadding='0'><tr>" )
   21.56 +        request.write( "<td width='80%'></td><td width='20%' align='center'><p align='center'>" )
   21.57 +	if currSheet > 0:
   21.58 +       	    request.write( "<img src='images/previous.png' onclick='doOp( \"prev\" )' onmouseover='update( \"wizText\", \"Previous\" )' onmouseout='update( \"wizText\", \"&nbsp;\" )'>&nbsp;" )
   21.59 +        if currSheet < ( len( self.sheets ) - 2 ):        
   21.60 +            request.write( "<img src='images/next.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Next\" )' onmouseout='update( \"wizText\", \"&nbsp;\" )'>" )
   21.61 +        elif currSheet == ( len( self.sheets ) - 2 ):
   21.62 +            request.write( "<img src='images/finish.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Finish\" )' onmouseout='update( \"wizText\", \"&nbsp;\" )'>" )
   21.63 +        request.write( "</p><p align='center'><span id='wizText'></span></p></td></tr></table>" )
   21.64 +        request.write( "</td></tr></table>" )
   21.65 +        
   21.66 +    def op_next( self, request ):
   21.67 +    	pass
   21.68 +        
   21.69 +    def op_prev( self, request ):
   21.70 +    	pass
   21.71 +        
   21.72 +    def op_finish( self, request ):
   21.73 +    	pass  
   21.74 +        
   21.75 +class Sheet( HTMLBase ):
   21.76 +
   21.77 +    def __init__( self, urlWriter, title, location ):
   21.78 +        HTMLBase.__init__( self )
   21.79 +        self.urlWriter = urlWriter
   21.80 +        self.feilds = []
   21.81 +        self.title = title
   21.82 +        self.location = location
   21.83 +        self.passback = None
   21.84 +        
   21.85 +    def parseForm( self, request ):
   21.86 +    	do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ] 
   21.87 +    
   21.88 +    	passed_back = request.args
   21.89 +        
   21.90 +        temp_passback = passed_back.get( "passback" )
   21.91 +        
   21.92 +        if temp_passback is not None and len( temp_passback ) > 0:
   21.93 +            temp_passback = temp_passback[ len( temp_passback )-1 ]
   21.94 +        else:
   21.95 +            temp_passback = "( )"        
   21.96 +        
   21.97 +        last_passback = ssxp2hash( string2sxp( temp_passback ) ) #use special function - will work with no head on sxp
   21.98 +        
   21.99 +        if DEBUG: print last_passback
  21.100 +        
  21.101 +        for (key, value) in passed_back.items():
  21.102 +            if key not in do_not_parse:
  21.103 +                last_passback[ key ] = value[ len( value ) - 1 ]
  21.104 +                
  21.105 +        self.passback = sxp2string( hash2sxp( last_passback ) ) #store the sxp
  21.106 +        
  21.107 +        if DEBUG: print self.passback
  21.108 +        
  21.109 +    def write_BODY( self, request, err ):
  21.110 +    
  21.111 +    	if not self.passback: self.parseForm( request )
  21.112 +        
  21.113 +   	request.write( "<p>%s</p>" % self.title )
  21.114 +    
  21.115 +    	previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
  21.116 +        
  21.117 +        request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" )
  21.118 +        
  21.119 +    	for (feild, control) in self.feilds:
  21.120 +            control.write_Control( request, previous_values.get( feild ) )
  21.121 +            if err and not control.validate( previous_values.get( feild ) ):
  21.122 +            	control.write_Help( request )
  21.123 +            
  21.124 +        request.write( "</table>" )
  21.125 +            
  21.126 +        request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
  21.127 +        request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
  21.128 +        request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location )
  21.129 +                
  21.130 +    def addControl( self, control ):
  21.131 +    	self.feilds.append( [ control.getName(), control ] )
  21.132 +        
  21.133 +    def validate( self, request ):
  21.134 +    
  21.135 +        if not self.passback: self.parseForm( request )
  21.136 +            
  21.137 +    	check = True
  21.138 +        
  21.139 +        previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
  21.140 +    	if DEBUG: print previous_values
  21.141 +      
  21.142 +      	for (feild, control) in self.feilds:
  21.143 +            if not control.validate( previous_values.get( feild ) ):
  21.144 +                check = False
  21.145 +                if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild ))
  21.146 +
  21.147 +        return check
  21.148 +        
  21.149 +class SheetControl( HTMLBase ):
  21.150 +
  21.151 +    def __init__( self, reg_exp = ".*" ):
  21.152 +        HTMLBase.__init__( self )
  21.153 +        self.name = ""
  21.154 +        self.reg_exp = reg_exp 
  21.155 +        
  21.156 +    def write_Control( self, request, persistedValue ):
  21.157 +        request.write( "<tr colspan='2'><td>%s</td></tr>" % persistedValue )
  21.158 +        
  21.159 +    def write_Help( self, request ):
  21.160 +        request.write( "<tr><td align='right' colspan='2'><p class='small'>Text must match pattern:" )
  21.161 +        request.write( " %s</p></td></tr>" % self.reg_exp )
  21.162 +        
  21.163 +    def validate( self, persistedValue ):
  21.164 +    	if persistedValue is None:
  21.165 +            persistedValue = ""
  21.166 +            
  21.167 +        return not re.compile( self.reg_exp ).match( persistedValue ) is None
  21.168 +
  21.169 +    def getName( self ):
  21.170 +    	return self.name
  21.171 +        
  21.172 +    def setName( self, name ):
  21.173 +    	self.name = name
  21.174 +        
  21.175 +class InputControl( SheetControl ):
  21.176 +
  21.177 +    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
  21.178 +        SheetControl.__init__( self, reg_exp )
  21.179 +        self.setName( name )
  21.180 +        
  21.181 +        self.defaultValue = defaultValue
  21.182 +        self.humanText = humanText
  21.183 +        self.help_text = help_text
  21.184 +        
  21.185 +    def write_Control( self, request, persistedValue ):
  21.186 +    	if persistedValue is None:
  21.187 +            persistedValue = self.defaultValue
  21.188 +        
  21.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) )
  21.190 +
  21.191 +    def write_Help( self, request ):
  21.192 +        request.write( "<tr><td align='right' colspan='2'><p class='small'>" )
  21.193 +        request.write( " %s</p></td></tr>" % self.help_text )         
  21.194 +        
  21.195 +class TextControl( SheetControl ):
  21.196 +
  21.197 +    def __init__( self, text ):
  21.198 +    	SheetControl.__init__( self )
  21.199 +        self.text = text
  21.200 +        
  21.201 +    def write_Control( self, request, persistedValue ):
  21.202 +    	request.write( "<tr><td colspan='2'><p>%s</p></td></tr>" % self.text )
  21.203 +
  21.204 +class SmallTextControl( SheetControl ):
  21.205 +
  21.206 +    def __init__( self, text ):
  21.207 +    	SheetControl.__init__( self )
  21.208 +        self.text = text
  21.209 +        
  21.210 +    def write_Control( self, request, persistedValue ):
  21.211 +    	request.write( "<tr><td colspan='2'><p class='small'>%s</p></tr></td>" % self.text )
  21.212 +        
  21.213 +class ListControl( SheetControl ):
  21.214 +
  21.215 +    def __init__( self, name, options, humanText ):
  21.216 +    	SheetControl.__init__( self )
  21.217 +        self.setName( name )
  21.218 +        self.options = options
  21.219 +        self.humanText = humanText
  21.220 +        
  21.221 +    def write_Control( self, request, persistedValue ):
  21.222 +        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
  21.223 +    	request.write( "<select name='%s'>" % self.getName() )
  21.224 +        for (value, text) in self.options:
  21.225 +            if value == persistedValue:
  21.226 +            	request.write( "<option value='%s' selected>%s\n" % (value, text) )
  21.227 +            else:
  21.228 +                request.write( "<option value='%s'>%s\n" % (value, text) )
  21.229 +        request.write( "</select></td></tr>" )
  21.230 +
  21.231 +    def validate( self, persistedValue ):
  21.232 +        for (value, text) in self.options:
  21.233 +            if value == persistedValue:
  21.234 +                return True
  21.235 +                
  21.236 +        return False
  21.237 +        
  21.238 +class FileControl( InputControl ):
  21.239 +
  21.240 +    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
  21.241 +	InputControl.__init__( self, name, defaultValue, humanText )
  21.242 +        
  21.243 +    def validate( self, persistedValue ):
  21.244 +        if persistedValue is None: return False
  21.245 +        try:
  21.246 +            open( persistedValue )
  21.247 +            return True
  21.248 +        except IOError, TypeError:
  21.249 +            return False
  21.250 +    
  21.251 +    def write_Help( self, request ):
  21.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>" )
  21.253 +
  21.254 +class TickControl( SheetControl ):
  21.255 +
  21.256 +    def __init__( self, name, defaultValue, humanText ):
  21.257 +        SheetControl.__init__( self )
  21.258 +        self.setName( name )
  21.259 +        self.defaultValue = defaultValue
  21.260 +        self.humanText = humanText
  21.261 +        
  21.262 +    def write_Control( self, request, persistedValue ):
  21.263 +        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
  21.264 +        
  21.265 +        if persistedValue == 'True':
  21.266 +    	    request.write( "<input type='checkbox' name='%s' value='True' checked>" % self.getName() )
  21.267 +        else:
  21.268 +    	    request.write( "<input type='checkbox' name='%s' value='True'>" % self.getName() )
  21.269 +            
  21.270 +        request.write( "</select></td></tr>" )
  21.271 +
  21.272 +      
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/python/xen/sv/__init__.py	Tue Jul 26 18:41:39 2005 +0000
    22.3 @@ -0,0 +1,1 @@
    22.4 + 
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/python/xen/sv/params.py	Tue Jul 26 18:41:39 2005 +0000
    23.3 @@ -0,0 +1,3 @@
    23.4 +SV_PORT = 8080
    23.5 +SV_ROOT = "/var/lib/xen/sv/"
    23.6 +PID_FILE = "/var/run/xen-sv.pid"
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/python/xen/sv/util.py	Tue Jul 26 18:41:39 2005 +0000
    24.3 @@ -0,0 +1,126 @@
    24.4 +from xen.xend.XendClient import server
    24.5 +from xen.xend import sxp
    24.6 +from xen.xend import PrettyPrint
    24.7 +
    24.8 +import types
    24.9 +
   24.10 +def getDomInfoHash( domain ):
   24.11 +    domInfoHash = {}
   24.12 +    try:
   24.13 +        domInfoHash = sxp2hash( server.xend_domain( domain ) )
   24.14 +        domInfoHash['dom'] = domain
   24.15 +    except:
   24.16 +    	domInfoHash['name'] = "Error getting domain details"
   24.17 +    return domInfoHash
   24.18 +
   24.19 +def sxp2hash( s ):
   24.20 +    sxphash = {}
   24.21 +        
   24.22 +    for child in sxp.children( s ):
   24.23 +    	if isinstance( child, types.ListType ) and len( child ) > 1:
   24.24 +            if isinstance( child[1], types.ListType ) and len( child ) > 1:
   24.25 +                sxphash[ child[0] ] = sxp2hash( child[1] )
   24.26 +            else:
   24.27 +                sxphash[ child[0] ] = child[1]
   24.28 +        
   24.29 +    return sxphash  
   24.30 +    
   24.31 +def ssxp2hash( s ):
   24.32 +    sxphash = {}
   24.33 +    
   24.34 +    for i in s:
   24.35 +       if isinstance( i, types.ListType ) and len( i ) > 1:
   24.36 +          sxphash[ i[0] ] = i[1]
   24.37 +    
   24.38 +    return sxphash 
   24.39 +    
   24.40 +def hash2sxp( h ):
   24.41 +    hashsxp = []
   24.42 +    
   24.43 +    for (key, item) in h.items():
   24.44 +    	hashsxp.append( [key, item] )
   24.45 +        
   24.46 +    return hashsxp    
   24.47 +    
   24.48 +def string2sxp( string ):
   24.49 +    pin = sxp.Parser()
   24.50 +    pin.input( string )
   24.51 +    return pin.get_val()    
   24.52 +
   24.53 +def sxp2string( sexp ):
   24.54 +    return sxp.to_string( sexp )    
   24.55 +    
   24.56 +def sxp2prettystring( sxp ):
   24.57 +    class tmp:
   24.58 +        def __init__( self ):
   24.59 +                self.str = ""
   24.60 +        def write( self, str ):
   24.61 +                self.str = self.str + str
   24.62 +    temp = tmp()
   24.63 +    PrettyPrint.prettyprint( sxp, out=temp )
   24.64 +    return temp.str
   24.65 +
   24.66 +def getVar( var, request, default=None ):
   24.67 +   
   24.68 +    arg = request.args.get( var )
   24.69 +
   24.70 +    if arg is None:
   24.71 +        return default
   24.72 +    else:
   24.73 +        return arg[ len( arg )-1 ]
   24.74 +
   24.75 +def bigTimeFormatter( time ):
   24.76 +    time = float( time )
   24.77 +    weeks = time // 604800
   24.78 +    remainder = time % 604800
   24.79 +    days = remainder // 86400
   24.80 +    
   24.81 +    remainder = remainder % 86400
   24.82 +
   24.83 +    hms = smallTimeFormatter( remainder )
   24.84 +    
   24.85 +    return "%d weeks, %d days, %s" % ( weeks, days, hms )
   24.86 +
   24.87 +def smallTimeFormatter( time ):
   24.88 +    time = float( time )
   24.89 +    hours = time // 3600
   24.90 +    remainder = time % 3600
   24.91 +    mins = remainder // 60
   24.92 +    secs = time % 60
   24.93 +    return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs ) 
   24.94 +
   24.95 +def stateFormatter( state ):
   24.96 +    states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ]
   24.97 +    
   24.98 +    stateStr = ""
   24.99 +    
  24.100 +    for i in range( len( state ) ):
  24.101 +        if state[i] != "-":
  24.102 +            stateStr += "%s, " % states[ i ] 
  24.103 +           
  24.104 +    return stateStr + " (%s)" % state
  24.105 +
  24.106 +def memoryFormatter( mem ):
  24.107 +    mem = int( mem )
  24.108 +    if mem >= 1024:
  24.109 +        mem = float( mem ) / 1024
  24.110 +        return "%3.2fGb" % mem
  24.111 +    else:    
  24.112 +        return "%7dMb" % mem
  24.113 +
  24.114 +def cpuFormatter( mhz ):
  24.115 +    mhz = int( mhz )
  24.116 +    if mhz > 1000:
  24.117 +        ghz = float( mhz ) / 1000.0
  24.118 +        return "%4.2fGHz" % ghz
  24.119 +    else:
  24.120 +        return "%4dMHz" % mhz
  24.121 +        
  24.122 +def hyperthreadFormatter( threads ):
  24.123 +    try:
  24.124 +        if int( threads ) > 1:
  24.125 +            return "Yes"
  24.126 +        else:
  24.127 +            return "No"
  24.128 +    except:
  24.129 +        return "No"
    25.1 --- a/tools/python/xen/xend/image.py	Tue Jul 26 17:38:33 2005 +0000
    25.2 +++ b/tools/python/xen/xend/image.py	Tue Jul 26 18:41:39 2005 +0000
    25.3 @@ -130,7 +130,13 @@ class ImageHandler:
    25.4          # xc.domain_setuuid(dom, uuid)
    25.5          xc.domain_setcpuweight(dom, cpu_weight)
    25.6          xc.domain_setmaxmem(dom, mem_kb)
    25.7 -        xc.domain_memory_increase_reservation(dom, mem_kb)
    25.8 +
    25.9 +        try:
   25.10 +            xc.domain_memory_increase_reservation(dom, mem_kb)
   25.11 +        except:
   25.12 +            xc.domain_destroy(dom)
   25.13 +            raise
   25.14 +
   25.15          if cpu != -1:
   25.16              xc.domain_pincpu(dom, 0, 1<<int(cpu))
   25.17          return dom
    26.1 --- a/tools/python/xen/xm/main.py	Tue Jul 26 17:38:33 2005 +0000
    26.2 +++ b/tools/python/xen/xm/main.py	Tue Jul 26 18:41:39 2005 +0000
    26.3 @@ -11,6 +11,13 @@ warnings.filterwarnings('ignore', catego
    26.4  
    26.5  from xen.xend import PrettyPrint
    26.6  from xen.xend import sxp
    26.7 +# this is a nasty place to stick this in, but required because
    26.8 +# log file access is set up via a 5 deep import chain.  This
    26.9 +# ensures the user sees a useful message instead of a stack trace
   26.10 +if os.getuid() != 0:
   26.11 +    print "xm requires root access to execute, please try again as root"
   26.12 +    sys.exit(1)
   26.13 +
   26.14  from xen.xend.XendClient import XendError, server
   26.15  from xen.xend.XendClient import main as xend_client_main
   26.16  from xen.xm import create, destroy, migrate, shutdown, sysrq
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/sv/Makefile	Tue Jul 26 18:41:39 2005 +0000
    27.3 @@ -0,0 +1,2 @@
    27.4 +
    27.5 +all:
    28.1 Binary file tools/sv/images/destroy.png has changed
    29.1 Binary file tools/sv/images/finish.png has changed
    30.1 Binary file tools/sv/images/internet copy.jpg has changed
    31.1 Binary file tools/sv/images/internet.jpg has changed
    32.1 Binary file tools/sv/images/internet.psd has changed
    33.1 Binary file tools/sv/images/next.png has changed
    34.1 Binary file tools/sv/images/orb_01.jpg has changed
    35.1 Binary file tools/sv/images/orb_02.jpg has changed
    36.1 Binary file tools/sv/images/pause.png has changed
    37.1 Binary file tools/sv/images/previous.png has changed
    38.1 Binary file tools/sv/images/reboot.png has changed
    39.1 Binary file tools/sv/images/seperator-left-highlight.jpg has changed
    40.1 Binary file tools/sv/images/seperator-right-highlight.jpg has changed
    41.1 Binary file tools/sv/images/seperator.jpg has changed
    42.1 Binary file tools/sv/images/shutdown.png has changed
    43.1 Binary file tools/sv/images/small-destroy.png has changed
    44.1 Binary file tools/sv/images/small-pause.png has changed
    45.1 Binary file tools/sv/images/small-unpause.png has changed
    46.1 Binary file tools/sv/images/unpause.png has changed
    47.1 Binary file tools/sv/images/xen.png has changed
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tools/sv/inc/script.js	Tue Jul 26 18:41:39 2005 +0000
    48.3 @@ -0,0 +1,31 @@
    48.4 +function update( objRef, text ) {
    48.5 +    if ( document.all || document.getElementById ) {
    48.6 +        obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef );
    48.7 +        obj.innerHTML= text
    48.8 +    }
    48.9 +}
   48.10 +
   48.11 +function buttonMouseOver( objRef ) {
   48.12 +    if ( document.all || document.getElementById ) {
   48.13 +        obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef );
   48.14 +        objRef.style.background = "white";
   48.15 +    }
   48.16 +}
   48.17 +
   48.18 +function buttonMouseOut( objRef ) {
   48.19 +    if ( document.all || document.getElementById ) {
   48.20 +        obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef );
   48.21 +        objRef.style.background = "grey";
   48.22 +    }
   48.23 +}
   48.24 +
   48.25 +function doOp( op ) {
   48.26 +    document.forms[0].op.value = op
   48.27 +    document.forms[0].submit()
   48.28 +}
   48.29 +
   48.30 +function doOp2( op, args ) {
   48.31 +    document.forms[0].op.value = op
   48.32 +    document.forms[0].args.value = args
   48.33 +    document.forms[0].submit()
   48.34 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/tools/sv/inc/style.css	Tue Jul 26 18:41:39 2005 +0000
    49.3 @@ -0,0 +1,32 @@
    49.4 +
    49.5 +P       {font-family: verdana, arial; font-size: 12px; color: black}
    49.6 +.small  {font-size: 10px}
    49.7 +
    49.8 +TD.domainInfo     {font-family: verdana, arial; font-size: 10px; color: black}
    49.9 +TD.domainInfoHead {font-family: verdana, arial; font-size: 10px; color: white; font-face: bold}
   49.10 +
   49.11 +TD.domainInfoHead {background-color: black}
   49.12 +TR.domainInfoOdd  {background-color: white}
   49.13 +TR.domainInfoEven {background-color: lightgrey}
   49.14 +
   49.15 +body { 
   49.16 +	width: 670px;
   49.17 +	margin: 0px;
   49.18 +	padding: 0px;
   49.19 +	background-color: #fff;
   49.20 +	background-image: url(../images/orb_02.jpg);
   49.21 +	background-repeat: repeat-y;
   49.22 +	background-position: left top;
   49.23 +	font-family: Arial, Helvetica, sans-serif;
   49.24 +	font-weight: bold;
   49.25 +	color: #333333;
   49.26 +	letter-spacing: 0px;
   49.27 +	scrollbar-base-color: #333333;
   49.28 +	scrollbar-track-color: #666666;
   49.29 +	scrollbar-face-color: #fff;
   49.30 +	
   49.31 +	
   49.32 +	}
   49.33 +        
   49.34 +.button (cursor:hand)
   49.35 +	
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/tools/sv/index.psp	Tue Jul 26 18:41:39 2005 +0000
    50.3 @@ -0,0 +1,164 @@
    50.4 +<%
    50.5 +import sys
    50.6 +sys.path.append( "/usr/lib/python" )
    50.7 +
    50.8 +debug = True and False
    50.9 +
   50.10 +for path in sys.path:
   50.11 +    if debug: req.write( path + "<br/>" )
   50.12 +
   50.13 +from xen.sv.HTMLBase import HTMLBase
   50.14 +from xen.sv.DomList  import DomList
   50.15 +from xen.sv.NodeInfo import NodeInfo
   50.16 +from xen.sv.DomInfo  import DomInfo
   50.17 +from xen.sv.CreateDomain import CreateDomain
   50.18 +from xen.sv.MigrateDomain import MigrateDomain
   50.19 +from xen.sv.SaveDomain import SaveDomain
   50.20 +from xen.sv.RestoreDomain import RestoreDomain
   50.21 +
   50.22 +from xen.xend.XendClient import server
   50.23 +
   50.24 +from xen.sv.util import getVar
   50.25 +
   50.26 +# adapter to make this all work with mod_python
   50.27 +# (c) Tom Wilkie 2005
   50.28 +
   50.29 +class TwistedAdapter:
   50.30 +
   50.31 +    def write( self, text ):
   50.32 +        req.write( text )
   50.33 +
   50.34 +    class Args:
   50.35 +
   50.36 +        from mod_python.util import FieldStorage
   50.37 +
   50.38 +        fieldStorage = FieldStorage( req, True )
   50.39 +
   50.40 +        # return a list of values for the given key,
   50.41 +        # or None if key not there
   50.42 +        def get( self, var ):
   50.43 +            retVar = self.fieldStorage.getlist( var )
   50.44 +            if len( retVar ) == 0:
   50.45 +                return None
   50.46 +            else:
   50.47 +                return retVar
   50.48 +
   50.49 +        # return a list of tuples, 
   50.50 +        # (key, value) where value is a list of values
   50.51 +	def items( self ):
   50.52 +            result = [];
   50.53 +            for key in self.fieldStorage.keys():
   50.54 +            	result.append( (key, self.fieldStorage.getlist( key ) ) )
   50.55 +	    return result
   50.56 +
   50.57 +    args = Args()
   50.58 +
   50.59 +    uri = req.unparsed_uri
   50.60 +
   50.61 +
   50.62 +class Main( HTMLBase ):
   50.63 +    
   50.64 +    isLeaf = True
   50.65 +
   50.66 +    def __init__( self, urlWriter = None ):
   50.67 +        self.modules = { "node": NodeInfo, 
   50.68 +                         "list": DomList, 
   50.69 +                         "info": DomInfo,
   50.70 +                         "create": CreateDomain,
   50.71 +                         "migrate" : MigrateDomain,
   50.72 +                         "save" : SaveDomain,
   50.73 +                         "restore" : RestoreDomain }
   50.74 +
   50.75 +        # ordered list of module menus to display
   50.76 +        self.module_menus = [ "node", "create", "migrate", "save",
   50.77 +                              "restore", "list" ]
   50.78 +        HTMLBase.__init__(self)
   50.79 +        
   50.80 +    def render_POST( self, request ):
   50.81 +    
   50.82 +    	#decide what module post'd the action
   50.83 +                
   50.84 +    	args = getVar( 'args', request )
   50.85 +
   50.86 +        mod = getVar( 'mod', request )
   50.87 +                
   50.88 +        if mod in self.modules and args is None:
   50.89 +            module = self.modules[ mod ]
   50.90 +            #check module exists
   50.91 +            if module:
   50.92 +               module( self.mainUrlWriter ).perform( request )
   50.93 +        else:
   50.94 +            self.perform( request )     
   50.95 +    
   50.96 +        return self.render_GET( request )
   50.97 +
   50.98 +    #TODO: need to make this get the request uri automatically
   50.99 +    def mainUrlWriter( self, module ):
  50.100 +    	def fun( f ):
  50.101 +            return "index.psp?mod=%s%s" % ( module, f )
  50.102 +        return fun    
  50.103 +        
  50.104 +    def write_BODY( self, request ):
  50.105 +    
  50.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" )
  50.107 +        request.write( "<tr>\n" )
  50.108 +        request.write( " <td width='15px'>&nbsp;</td>" )
  50.109 +        request.write( " <td width='175px' align='center' valign'center'>" )
  50.110 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
  50.111 +        request.write( "   <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" )
  50.112 +        request.write( "   <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" )
  50.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>")
  50.114 +        request.write( "   <tr><td align='center' valign='top'>" )
  50.115 +
  50.116 +        for modName in self.module_menus:
  50.117 +            self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request )
  50.118 +        
  50.119 +        request.write( "   </td></tr>" )
  50.120 +        request.write( "  </table>" )
  50.121 +        request.write( " &nbsp;" )
  50.122 +        request.write( " </td>\n" )
  50.123 +        request.write( " <td width='15px'>&nbsp;</td>" )
  50.124 +        request.write( " <td width='558px' align='left' valign='top'>" )
  50.125 +        request.write( "  <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" )
  50.126 +        request.write( "   <tr><td height='20px'></td></tr>" )
  50.127 +        request.write( "   <tr><td align='center' valign='top'>" )
  50.128 +        
  50.129 +        modName = getVar('mod', request)
  50.130 +        
  50.131 +        if modName not in self.modules:
  50.132 +            request.write( '<p>Please select a module</p>' )
  50.133 +        else:
  50.134 +            module = self.modules[ modName ]
  50.135 +            if module:
  50.136 +               module( self.mainUrlWriter( modName ) ).write_BODY( request )  
  50.137 +            else:
  50.138 +               request.write( '<p>Invalid module. Please select another</p>' )
  50.139 +    
  50.140 +        request.write( "   </td></tr>" )
  50.141 +        request.write( "  </table>" )
  50.142 +        request.write( " </td>\n" )
  50.143 +        request.write( " <td width='17px'>&nbsp;</td>" )
  50.144 +        request.write( "</tr>\n" )
  50.145 +        
  50.146 +        request.write( "</table>\n" )
  50.147 +        
  50.148 +                
  50.149 +    def op_destroy( self, request ):
  50.150 +    	dom = getVar( 'dom', request )
  50.151 +        if not dom is None and dom != "0":
  50.152 +            server.xend_domain_destroy( int( dom ), "halt" ) 
  50.153 +                 
  50.154 +    def op_pause( self, request ):
  50.155 +    	dom = getVar( 'dom', request )
  50.156 +        if not dom is None and dom != "0":
  50.157 +            server.xend_domain_pause( int( dom ) )      
  50.158 +    
  50.159 +    def op_unpause( self, request ):
  50.160 +    	dom = getVar( 'dom', request )
  50.161 +        if not dom is None and dom != "0":
  50.162 +            server.xend_domain_unpause( int( dom ) )      
  50.163 +
  50.164 +main = Main()
  50.165 +
  50.166 +main.render_POST( TwistedAdapter() )
  50.167 +%>