ia64/xen-unstable
changeset 5862:6c24d2b4f3ea
Manual merge.
line diff
2.1 --- a/tools/Makefile Tue Jul 26 10:09:06 2005 +0000 2.2 +++ b/tools/Makefile Tue Jul 26 15:16:12 2005 +0000 2.3 @@ -13,6 +13,7 @@ SUBDIRS += xcutils 2.4 SUBDIRS += pygrub 2.5 SUBDIRS += firmware 2.6 SUBDIRS += policy 2.7 +SUBDIRS += sv 2.8 2.9 .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean 2.10
3.1 --- a/tools/python/setup.py Tue Jul 26 10:09:06 2005 +0000 3.2 +++ b/tools/python/setup.py Tue Jul 26 15:16:12 2005 +0000 3.3 @@ -51,6 +51,7 @@ setup(name = 'xen', 3.4 'xen.xend.xenstore', 3.5 'xen.xm', 3.6 'xen.web', 3.7 + 'xen.sv' 3.8 ], 3.9 ext_package = "xen.lowlevel", 3.10 ext_modules = [ xc, xu, xs ]
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/tools/python/xen/sv/CreateDomain.py Tue Jul 26 15:16:12 2005 +0000 4.3 @@ -0,0 +1,163 @@ 4.4 +from xen.sv.Wizard import * 4.5 +from xen.sv.util import * 4.6 +from xen.sv.GenTabbed import PreTab 4.7 + 4.8 +from xen.xm.create import make_config, OptVals 4.9 + 4.10 +from xen.xend.XendClient import server 4.11 + 4.12 +class CreateDomain( Wizard ): 4.13 + def __init__( self, urlWriter ): 4.14 + 4.15 + sheets = [ CreatePage0, 4.16 + CreatePage1, 4.17 + CreatePage2, 4.18 + CreatePage3, 4.19 + CreatePage4, 4.20 + CreateFinish ] 4.21 + 4.22 + Wizard.__init__( self, urlWriter, "Create Domain", sheets ) 4.23 + 4.24 +class CreatePage0( Sheet ): 4.25 + 4.26 + def __init__( self, urlWriter ): 4.27 + Sheet.__init__( self, urlWriter, "General", 0 ) 4.28 + self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) ) 4.29 + self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) ) 4.30 + self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) ) 4.31 + self.addControl( InputControl( 'cpu_weight', '1', 'CPU Weight:', "[\\d]+", "You must enter a number in this feild" ) ) 4.32 + 4.33 +class CreatePage1( Sheet ): 4.34 + 4.35 + def __init__( self, urlWriter ): 4.36 + Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 ) 4.37 +# For now we don't need to select a builder... 4.38 +# self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) ) 4.39 + self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.6.9-xenU', 'Kernel Image:' ) ) 4.40 + self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) ) 4.41 + 4.42 +class CreatePage2( Sheet ): 4.43 + 4.44 + def __init__( self, urlWriter ): 4.45 + Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 ) 4.46 + self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) ) 4.47 + 4.48 +class CreatePage3( Sheet ): 4.49 + 4.50 + def __init__( self, urlWriter ): 4.51 + Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 ) 4.52 + 4.53 + def write_BODY( self, request, err ): 4.54 + if not self.passback: self.parseForm( request ) 4.55 + 4.56 + previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference 4.57 + 4.58 + num_vbds = previous_values.get( 'num_vbds' ) 4.59 + 4.60 + for i in range( int( num_vbds ) ): 4.61 + self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i ) ) 4.62 + self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) ) 4.63 + self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) ) 4.64 + 4.65 + self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) ) 4.66 + 4.67 + Sheet.write_BODY( self, request, err ) 4.68 + 4.69 +class CreatePage4( Sheet ): 4.70 + 4.71 + def __init__( self, urlWriter ): 4.72 + Sheet.__init__( self, urlWriter, "Network settings", 4 ) 4.73 + self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) ) 4.74 + self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) ) 4.75 + self.addControl( InputControl( 'ip_addr', '1.2.3.4', 'VM IP Address:' ) ) 4.76 + self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) ) 4.77 + self.addControl( InputControl( 'ip_gateway', '1.2.3.4', 'VM Gateway:' ) ) 4.78 + self.addControl( InputControl( 'ip_nfs', '1.2.3.4', 'NFS Server:' ) ) 4.79 + 4.80 +class CreateFinish( Sheet ): 4.81 + 4.82 + def __init__( self, urlWriter ): 4.83 + Sheet.__init__( self, urlWriter, "All Done", 5 ) 4.84 + 4.85 + def write_BODY( self, request, err ): 4.86 + 4.87 + if not self.passback: self.parseForm( request ) 4.88 + 4.89 + xend_sxp = self.translate_sxp( string2sxp( self.passback ) ) 4.90 + 4.91 + try: 4.92 + dom_sxp = server.xend_domain_create( xend_sxp ) 4.93 + success = "Your domain was successfully created.\n" 4.94 + except: 4.95 + success = "There was an error creating your domain.\nThe configuration used is as follows:\n" 4.96 + dom_sxp = xend_sxp 4.97 + 4.98 + 4.99 + 4.100 + pt = PreTab( success + sxp2prettystring( dom_sxp ) ) 4.101 + pt.write_BODY( request ) 4.102 + 4.103 + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) 4.104 + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) 4.105 + 4.106 + def translate_sxp( self, fin_sxp ): 4.107 + fin_hash = ssxp2hash( fin_sxp ) 4.108 + 4.109 + def get( key ): 4.110 + ret = fin_hash.get( key ) 4.111 + if ret: 4.112 + return ret 4.113 + else: 4.114 + return "" 4.115 + 4.116 + vals = OptVals() 4.117 + 4.118 + vals.name = get( 'name' ) 4.119 + vals.memory = get( 'memory' ) 4.120 + vals.maxmem = get( 'maxmem' ) 4.121 + vals.cpu = get( 'cpu' ) 4.122 + vals.cpu_weight = get( 'cpu_weight' ) 4.123 + 4.124 + vals.builder = get( 'builder' ) 4.125 + vals.kernel = get( 'kernel' ) 4.126 + vals.root = get( 'root' ) 4.127 + vals.extra = get( 'extra' ) 4.128 + 4.129 + #setup vbds 4.130 + 4.131 + vbds = [] 4.132 + 4.133 + for i in range( int( get( 'num_vbds' ) ) ): 4.134 + vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) ) 4.135 + 4.136 + vals.disk = vbds 4.137 + 4.138 + #misc 4.139 + 4.140 + vals.pci = [] 4.141 + 4.142 + vals.blkif = None 4.143 + vals.netif = None 4.144 + vals.restart = None 4.145 + vals.console = None 4.146 + vals.ramdisk = None 4.147 + 4.148 + #setup vifs 4.149 + 4.150 + vals.vif = [] 4.151 + vals.nics = 1 4.152 + 4.153 + ip = get( 'ip_addr' ) 4.154 + nfs = get( 'ip_nfs' ) 4.155 + gate = get( 'ip_gateway' ) 4.156 + mask = get( 'ip_subnet' ) 4.157 + host = get( 'hostname' ) 4.158 + dhcp = get( 'dhcp' ) 4.159 + 4.160 + vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp) 4.161 + 4.162 + try: 4.163 + return make_config( vals ) 4.164 + except: 4.165 + return [["Error creating domain config."]] 4.166 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/tools/python/xen/sv/Daemon.py Tue Jul 26 15:16:12 2005 +0000 5.3 @@ -0,0 +1,110 @@ 5.4 +########################################################### 5.5 +## XenSV Web Control Interface Daemon 5.6 +## Copyright (C) 2004, K A Fraser (University of Cambridge) 5.7 +## Copyright (C) 2004, Mike Wray <mike.wray@hp.com> 5.8 +## Copyright (C) 2004, Tom Wilkie <tw275@cam.ac.uk> 5.9 +########################################################### 5.10 + 5.11 +import os 5.12 +import os.path 5.13 +import sys 5.14 +import re 5.15 + 5.16 +from xen.sv.params import * 5.17 + 5.18 +from twisted.internet import reactor 5.19 +from twisted.web import static, server, script 5.20 + 5.21 +from xen.util.ip import _readline, _readlines 5.22 + 5.23 +class Daemon: 5.24 + """The xend daemon. 5.25 + """ 5.26 + def __init__(self): 5.27 + self.shutdown = 0 5.28 + self.traceon = 0 5.29 + 5.30 + def daemon_pids(self): 5.31 + pids = [] 5.32 + pidex = '(?P<pid>\d+)' 5.33 + pythonex = '(?P<python>\S*python\S*)' 5.34 + cmdex = '(?P<cmd>.*)' 5.35 + procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$') 5.36 + xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$') 5.37 + procs = os.popen('ps -e -o pid,args 2>/dev/null') 5.38 + for proc in procs: 5.39 + pm = procre.match(proc) 5.40 + if not pm: continue 5.41 + xm = xendre.match(pm.group('cmd')) 5.42 + if not xm: continue 5.43 + #print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd') 5.44 + pids.append(int(pm.group('pid'))) 5.45 + return pids 5.46 + 5.47 + def new_cleanup(self, kill=0): 5.48 + err = 0 5.49 + pids = self.daemon_pids() 5.50 + if kill: 5.51 + for pid in pids: 5.52 + print "Killing daemon pid=%d" % pid 5.53 + os.kill(pid, signal.SIGHUP) 5.54 + elif pids: 5.55 + err = 1 5.56 + print "Daemon already running: ", pids 5.57 + return err 5.58 + 5.59 + def cleanup(self, kill=False): 5.60 + # No cleanup to do if PID_FILE is empty. 5.61 + if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE): 5.62 + return 0 5.63 + # Read the pid of the previous invocation and search active process list. 5.64 + pid = open(PID_FILE, 'r').read() 5.65 + lines = _readlines(os.popen('ps ' + pid + ' 2>/dev/null')) 5.66 + for line in lines: 5.67 + if re.search('^ *' + pid + '.+xensv', line): 5.68 + if not kill: 5.69 + print "Daemon is already running (pid %d)" % int(pid) 5.70 + return 1 5.71 + # Old daemon is still active: terminate it. 5.72 + os.kill(int(pid), 1) 5.73 + # Delete the stale PID_FILE. 5.74 + os.remove(PID_FILE) 5.75 + return 0 5.76 + 5.77 + def start(self, trace=0): 5.78 + if self.cleanup(kill=False): 5.79 + return 1 5.80 + 5.81 + # Fork -- parent writes PID_FILE and exits. 5.82 + pid = os.fork() 5.83 + if pid: 5.84 + # Parent 5.85 + pidfile = open(PID_FILE, 'w') 5.86 + pidfile.write(str(pid)) 5.87 + pidfile.close() 5.88 + return 0 5.89 + # Child 5.90 + self.run() 5.91 + return 0 5.92 + 5.93 + def stop(self): 5.94 + return self.cleanup(kill=True) 5.95 + 5.96 + def run(self): 5.97 + root = static.File( SV_ROOT ) 5.98 + root.indexNames = [ 'Main.rpy' ] 5.99 + root.processors = { '.rpy': script.ResourceScript } 5.100 + reactor.listenTCP( SV_PORT, server.Site( root ) ) 5.101 + reactor.run() 5.102 + 5.103 + def exit(self): 5.104 + reactor.disconnectAll() 5.105 + sys.exit(0) 5.106 + 5.107 +def instance(): 5.108 + global inst 5.109 + try: 5.110 + inst 5.111 + except: 5.112 + inst = Daemon() 5.113 + return inst
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/tools/python/xen/sv/DomInfo.py Tue Jul 26 15:16:12 2005 +0000 6.3 @@ -0,0 +1,148 @@ 6.4 +from xen.xend.XendClient import server 6.5 +from xen.xend import PrettyPrint 6.6 + 6.7 +from xen.sv.HTMLBase import HTMLBase 6.8 +from xen.sv.util import * 6.9 +from xen.sv.GenTabbed import * 6.10 + 6.11 +DEBUG=1 6.12 + 6.13 +class DomInfo( GenTabbed ): 6.14 + 6.15 + def __init__( self, urlWriter ): 6.16 + 6.17 + self.dom = 0; 6.18 + 6.19 + def tabUrlWriter( tab ): 6.20 + return urlWriter( "&dom=%s%s" % ( self.dom, tab ) ) 6.21 + 6.22 + GenTabbed.__init__( self, "Domain Info", tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGeneralTab, DomSXPTab, NullTab ] ) 6.23 + 6.24 + def write_BODY( self, request ): 6.25 + dom = request.args.get('dom') 6.26 + 6.27 + if dom is None or len(dom) != 1: 6.28 + request.write( "<p>Please Select a Domain</p>" ) 6.29 + return None 6.30 + else: 6.31 + self.dom = dom[0] 6.32 + 6.33 + GenTabbed.write_BODY( self, request ) 6.34 + 6.35 + def write_MENU( self, request ): 6.36 + pass 6.37 + 6.38 +class DomGeneralTab( CompositeTab ): 6.39 + def __init__( self ): 6.40 + CompositeTab.__init__( self, [ DomGenTab, DomActionTab ] ) 6.41 + 6.42 +class DomGenTab( GeneralTab ): 6.43 + 6.44 + def __init__( self ): 6.45 + 6.46 + titles = {} 6.47 + 6.48 + titles[ 'ID' ] = 'dom' 6.49 + titles[ 'Name' ] = 'name' 6.50 + titles[ 'CPU' ] = 'cpu' 6.51 + titles[ 'Memory' ] = ( 'mem', memoryFormatter ) 6.52 + titles[ 'State' ] = ( 'state', stateFormatter ) 6.53 + titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter ) 6.54 + titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter ) 6.55 + 6.56 + GeneralTab.__init__( self, {}, titles ) 6.57 + 6.58 + def write_BODY( self, request ): 6.59 + 6.60 + self.dom = getVar('dom', request) 6.61 + 6.62 + if self.dom is None: 6.63 + request.write( "<p>Please Select a Domain</p>" ) 6.64 + return None 6.65 + 6.66 + self.dict = getDomInfoHash( self.dom ) 6.67 + 6.68 + GeneralTab.write_BODY( self, request ) 6.69 + 6.70 +class DomSXPTab( PreTab ): 6.71 + 6.72 + def __init__( self ): 6.73 + self.dom = 0 6.74 + PreTab.__init__( self, "" ) 6.75 + 6.76 + 6.77 + def write_BODY( self, request ): 6.78 + self.dom = getVar('dom', request) 6.79 + 6.80 + if self.dom is None: 6.81 + request.write( "<p>Please Select a Domain</p>" ) 6.82 + return None 6.83 + 6.84 + try: 6.85 + domInfo = server.xend_domain( self.dom ) 6.86 + except: 6.87 + domInfo = [["Error getting domain details."]] 6.88 + 6.89 + self.source = sxp2prettystring( domInfo ) 6.90 + 6.91 + PreTab.write_BODY( self, request ) 6.92 + 6.93 +class DomActionTab( ActionTab ): 6.94 + 6.95 + def __init__( self ): 6.96 + actions = { "shutdown" : "shutdown", 6.97 + "reboot" : "reboot", 6.98 + "pause" : "pause", 6.99 + "unpause" : "unpause", 6.100 + "destroy" : "destroy" } 6.101 + ActionTab.__init__( self, actions ) 6.102 + 6.103 + def op_shutdown( self, request ): 6.104 + dom = getVar( 'dom', request ) 6.105 + if not dom is None and dom != '0': 6.106 + if DEBUG: print ">DomShutDown %s" % dom 6.107 + try: 6.108 + server.xend_domain_shutdown( int( dom ), "halt" ) 6.109 + except: 6.110 + pass 6.111 + 6.112 + def op_reboot( self, request ): 6.113 + dom = getVar( 'dom', request ) 6.114 + if not dom is None and dom != '0': 6.115 + if DEBUG: print ">DomReboot %s" % dom 6.116 + try: 6.117 + server.xend_domain_shutdown( int( dom ), "reboot" ) 6.118 + except: 6.119 + pass 6.120 + 6.121 + def op_pause( self, request ): 6.122 + dom = getVar( 'dom', request ) 6.123 + if not dom is None and dom != '0': 6.124 + if DEBUG: print ">DomPause %s" % dom 6.125 + try: 6.126 + server.xend_domain_pause( int( dom ) ) 6.127 + except: 6.128 + pass 6.129 + 6.130 + def op_unpause( self, request ): 6.131 + dom = getVar( 'dom', request ) 6.132 + if not dom is None and dom != '0': 6.133 + if DEBUG: print ">DomUnpause %s" % dom 6.134 + try: 6.135 + server.xend_domain_unpause( int( dom ) ) 6.136 + except: 6.137 + pass 6.138 + 6.139 + def op_destroy( self, request ): 6.140 + dom = getVar( 'dom', request ) 6.141 + if not dom is None and dom != '0': 6.142 + if DEBUG: print ">DomDestroy %s" % dom 6.143 + try: 6.144 + server.xend_domain_destroy( int( dom ), "halt" ) 6.145 + except: 6.146 + pass 6.147 + 6.148 + 6.149 + 6.150 + 6.151 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/tools/python/xen/sv/DomList.py Tue Jul 26 15:16:12 2005 +0000 7.3 @@ -0,0 +1,81 @@ 7.4 +from xen.xend.XendClient import server 7.5 +from xen.xend import sxp 7.6 + 7.7 +from xen.sv.HTMLBase import HTMLBase 7.8 +from xen.sv.util import * 7.9 + 7.10 +class DomList( HTMLBase ): 7.11 + 7.12 + isLeaf = True 7.13 + 7.14 + def __init__( self, urlWriter ): 7.15 + HTMLBase.__init__(self) 7.16 + self.urlWriter = urlWriter 7.17 + 7.18 + def write_MENU( self, request ): 7.19 + return self.write_BODY( request, head=True, long=False ) 7.20 + 7.21 + def write_BODY( self, request, head=True, long=True ): 7.22 + 7.23 + domains = [] 7.24 + 7.25 + try: 7.26 + domains = server.xend_domains() 7.27 + domains.sort() 7.28 + except: 7.29 + pass 7.30 + 7.31 + request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" ) 7.32 + 7.33 + if head: 7.34 + request.write( "<tr class='domainInfoHead'>" ) 7.35 + self.write_DOMAIN_HEAD( request, long ) 7.36 + request.write( "</tr>" ) 7.37 + 7.38 + odd = True 7.39 + 7.40 + if not domains is None: 7.41 + for domain in domains: 7.42 + if odd: 7.43 + request.write( "<tr class='domainInfoOdd'>\n" ) 7.44 + odd = False 7.45 + else: 7.46 + request.write( "<tr class='domainInfoEven'>\n" ) 7.47 + odd = True 7.48 + self.write_DOMAIN( request, getDomInfoHash( domain ), long ) 7.49 + request.write( "</tr>\n" ) 7.50 + else: 7.51 + request.write( "<tr colspan='10'><p class='small'>Error getting domain list<br/>Perhaps XenD not running?</p></tr>") 7.52 + 7.53 + request.write( "</table>\n" ) 7.54 + 7.55 + def write_DOMAIN( self, request, domInfoHash, long=True ): 7.56 + request.write( "<td class='domainInfo' align='center'>%(id)s</td>\n" % domInfoHash ) 7.57 + 7.58 + url = self.urlWriter( "&mod=info&dom=%(id)s" % domInfoHash ) 7.59 + 7.60 + request.write( "<td class='domainInfo' align='center'><a href='%s'>%s</a></td>\n" % ( url, domInfoHash['name'] ) ) 7.61 + if long: 7.62 + request.write( "<td class='domainInfo' align='center'>%(memory)5s</td>\n" % domInfoHash ) 7.63 + request.write( "<td class='domainInfo' align='center'>%(cpu)2s</td>\n" % domInfoHash ) 7.64 + request.write( "<td class='domainInfo' align='center'>%(state)5s</td>\n" % domInfoHash ) 7.65 + if domInfoHash[ 'id' ] != "0": 7.66 + request.write( "<td class='domainInfo' align='center'>" ) 7.67 + 7.68 + if domInfoHash[ 'state' ][ 2 ] == "-": 7.69 + request.write( "<img src='images/small-pause.png' onclick='doOp2( \"pause\", \"%(dom)-4s\" )'>" % domInfoHash ) 7.70 + else: 7.71 + request.write( "<img src='images/small-unpause.png' onclick='doOp2( \"unpause\", \"%(dom)-4s\" )'>" % domInfoHash ) 7.72 + 7.73 + request.write( "<img src='images/small-destroy.png' onclick='doOp2( \"destroy\", \"%(dom)-4s\" )'></td>" % domInfoHash) 7.74 + else: 7.75 + request.write( "<td> </td>" ) 7.76 + 7.77 + def write_DOMAIN_HEAD( self, request, long=True ): 7.78 + request.write( "<td class='domainInfoHead' align='center'>Domain</td>\n" ) 7.79 + request.write( "<td class='domainInfoHead' align='center'>Name</td>\n" ) 7.80 + if long: 7.81 + request.write( "<td class='domainInfoHead' align='center'>Memory / Mb</td>\n" ) 7.82 + request.write( "<td class='domainInfoHead' align='center'>CPU</td>\n" ) 7.83 + request.write( "<td class='domainInfoHead' align='center'>State</td>\n" ) 7.84 + request.write( "<td class='domainInfoHead' align='center'></td>\n" )
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/tools/python/xen/sv/GenTabbed.py Tue Jul 26 15:16:12 2005 +0000 8.3 @@ -0,0 +1,135 @@ 8.4 +import types 8.5 + 8.6 +from xen.sv.HTMLBase import HTMLBase 8.7 +from xen.sv.TabView import TabView 8.8 +from xen.sv.util import getVar 8.9 + 8.10 +class GenTabbed( HTMLBase ): 8.11 + 8.12 + def __init__( self, title, urlWriter, tabStrings, tabObjects ): 8.13 + HTMLBase.__init__(self) 8.14 + self.tabStrings = tabStrings 8.15 + self.tabObjects = tabObjects 8.16 + self.urlWriter = urlWriter 8.17 + self.title = title 8.18 + 8.19 + def write_BODY( self, request, urlWriter = None ): 8.20 + try: 8.21 + tab = int( getVar( 'tab', request, 0 ) ) 8.22 + except: 8.23 + tab = 0 8.24 + 8.25 + request.write( "<table style='' width='100%' border='0' cellspacing='0' cellpadding='0'>" ) 8.26 + request.write( "<tr><td>" ) 8.27 + request.write( "<p align='center'><u>%s</u></p>" % self.title ) 8.28 + 8.29 + TabView( tab, self.tabStrings, self.urlWriter ).write_BODY( request ) 8.30 + 8.31 + request.write( "</td></tr><tr><td>" ) 8.32 + 8.33 + try: 8.34 + render_tab = self.tabObjects[ tab ] 8.35 + render_tab().write_BODY( request ) 8.36 + except: 8.37 + request.write( "<p>Error Rendering Tab</p>" ) 8.38 + 8.39 + request.write( "</td></tr></table>" ) 8.40 + 8.41 + def perform( self, request ): 8.42 + try: 8.43 + tab = int( getVar( 'tab', request, 0 ) ) 8.44 + except: 8.45 + tab = 0; 8.46 + 8.47 + op_tab = self.tabObjects[ tab ] 8.48 + 8.49 + if op_tab: 8.50 + op_tab().perform( request ) 8.51 + 8.52 +class PreTab( HTMLBase ): 8.53 + 8.54 + def __init__( self, source ): 8.55 + HTMLBase.__init__( self ) 8.56 + self.source = source 8.57 + 8.58 + def write_BODY( self, request ): 8.59 + 8.60 + request.write( "<div style='display: block; overflow: auto; border: 0px solid black; width: 540px; padding: 5px; z-index:0; align: center'><pre>" ) 8.61 + 8.62 + request.write( self.source ) 8.63 + 8.64 + request.write( "</pre></div>" ) 8.65 + 8.66 +class GeneralTab( HTMLBase ): 8.67 + 8.68 + def __init__( self, dict, titles ): 8.69 + HTMLBase.__init__( self ) 8.70 + self.dict = dict 8.71 + self.titles = titles 8.72 + 8.73 + def write_BODY( self, request ): 8.74 + 8.75 + request.write( "<table width='100%' cellspacing='0' cellpadding='0' border='0'>" ) 8.76 + 8.77 + def writeAttr( niceName, attr, formatter=None ): 8.78 + if type( attr ) is types.TupleType: 8.79 + ( attr, formatter ) = attr 8.80 + 8.81 + if attr in self.dict: 8.82 + if formatter: 8.83 + temp = formatter( self.dict[ attr ] ) 8.84 + else: 8.85 + temp = str( self.dict[ attr ] ) 8.86 + request.write( "<tr><td width='50%%'><p>%s:</p></td><td width='50%%'><p>%s</p></td></tr>" % ( niceName, temp ) ) 8.87 + 8.88 + for niceName, attr in self.titles.items(): 8.89 + writeAttr( niceName, attr ) 8.90 + 8.91 + request.write( "</table>" ) 8.92 + 8.93 +class NullTab( HTMLBase ): 8.94 + 8.95 + def __init__( self ): 8.96 + HTMLBase.__init__( self ) 8.97 + self.title = "Null Tab" 8.98 + 8.99 + def __init__( self, title ): 8.100 + HTMLBase.__init__( self ) 8.101 + self.title = title 8.102 + 8.103 + def write_BODY( self, request ): 8.104 + request.write( "<p>%s</p>" % self.title ) 8.105 + 8.106 +class ActionTab( HTMLBase ): 8.107 + 8.108 + def __init__( self, actions ): 8.109 + self.actions = actions 8.110 + HTMLBase.__init__( self ) 8.111 + 8.112 + def write_BODY( self, request ): 8.113 + request.write( "<p align='center'><table cellspacing='3' cellpadding='2' border='0'><tr>" ) 8.114 + 8.115 + for ( command, text ) in self.actions.items(): 8.116 + request.write( "<td style='border: 1px solid black; background-color: grey' onmouseover='buttonMouseOver( this )' onmouseout='buttonMouseOut( this )'>" ) 8.117 + request.write( "<p><a href='javascript: doOp( \"%s\" );'>%s</a></p></td>" % (command, text) ) 8.118 + 8.119 + request.write("</table></p>") 8.120 + 8.121 +class CompositeTab( HTMLBase ): 8.122 + 8.123 + def __init__( self, tabs ): 8.124 + HTMLBase.__init__( self ) 8.125 + self.tabs = tabs 8.126 + 8.127 + def write_BODY( self, request ): 8.128 + for tab in self.tabs: 8.129 + request.write( "<br/>" ) 8.130 + tab().write_BODY( request ) 8.131 + 8.132 + def perform( self, request ): 8.133 + for tab in self.tabs: 8.134 + tab().perform( request ) 8.135 + 8.136 + 8.137 + 8.138 +
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tools/python/xen/sv/HTMLBase.py Tue Jul 26 15:16:12 2005 +0000 9.3 @@ -0,0 +1,62 @@ 9.4 +from xen.sv.util import * 9.5 + 9.6 +class HTMLBase: 9.7 + 9.8 + isLeaf = True 9.9 + 9.10 + def __init__( self ): 9.11 + pass 9.12 + 9.13 + def render_POST( self, request ): 9.14 + self.perform( request ) 9.15 + return self.render_GET( request ) 9.16 + 9.17 + def render_GET( self, request ): 9.18 + self.write_TOP( request ) 9.19 + self.write_BODY( request ) 9.20 + self.write_BOTTOM( request ) 9.21 + return '' 9.22 + 9.23 + def write_BODY( self, request ): 9.24 + request.write( "BODY" ) 9.25 + 9.26 + def write_TOP( self, request ): 9.27 + request.write( '<html><head><title>Xen</title><link rel="stylesheet" type="text/css" href="inc/style.css" />' ) 9.28 + request.write( '<script src="inc/script.js"></script>' ) 9.29 + request.write( '</head><body>' ) 9.30 + request.write('<form method="post" action="%s">' % request.uri) 9.31 + 9.32 + def write_BOTTOM( self, request ): 9.33 + request.write('<input type="hidden" name="op" value="">') 9.34 + request.write('<input type="hidden" name="args" value="">') 9.35 + request.write('</form>') 9.36 + request.write( "</body></html>" ) 9.37 + 9.38 + def get_op_method(self, op): 9.39 + """Get the method for an operation. 9.40 + For operation 'foo' looks for 'op_foo'. 9.41 + 9.42 + op operation name 9.43 + returns method or None 9.44 + """ 9.45 + op_method_name = 'op_' + op 9.46 + return getattr(self, op_method_name, None) 9.47 + 9.48 + def perform(self, req): 9.49 + """General operation handler for posted operations. 9.50 + For operation 'foo' looks for a method op_foo and calls 9.51 + it with op_foo(req). Replies with code 500 if op_foo 9.52 + is not found. 9.53 + 9.54 + The method must return a list when req.use_sxp is true 9.55 + and an HTML string otherwise (or list). 9.56 + Methods may also return a Deferred (for incomplete processing). 9.57 + 9.58 + req request 9.59 + """ 9.60 + op = req.args.get('op') 9.61 + if not op is None and len(op) == 1: 9.62 + op = op[0] 9.63 + op_method = self.get_op_method(op) 9.64 + if op_method: 9.65 + op_method( req )
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/python/xen/sv/Main.py Tue Jul 26 15:16:12 2005 +0000 10.3 @@ -0,0 +1,113 @@ 10.4 +from xen.sv.HTMLBase import HTMLBase 10.5 +from xen.sv.DomList import DomList 10.6 +from xen.sv.NodeInfo import NodeInfo 10.7 +from xen.sv.DomInfo import DomInfo 10.8 +from xen.sv.CreateDomain import CreateDomain 10.9 +from xen.sv.MigrateDomain import MigrateDomain 10.10 +from xen.sv.SaveDomain import SaveDomain 10.11 +from xen.sv.RestoreDomain import RestoreDomain 10.12 + 10.13 +from xen.xend.XendClient import server 10.14 + 10.15 +from xen.sv.util import getVar 10.16 + 10.17 +class Main( HTMLBase ): 10.18 + 10.19 + isLeaf = True 10.20 + 10.21 + def __init__( self, urlWriter = None ): 10.22 + self.modules = { "node": NodeInfo, 10.23 + "list": DomList, 10.24 + "info": DomInfo, 10.25 + "create": CreateDomain, 10.26 + "migrate" : MigrateDomain, 10.27 + "save" : SaveDomain, 10.28 + "restore" : RestoreDomain } 10.29 + 10.30 + # ordered list of module menus to display 10.31 + self.module_menus = [ "node", "create", "migrate", "save", 10.32 + "restore", "list" ] 10.33 + HTMLBase.__init__(self) 10.34 + 10.35 + def render_POST( self, request ): 10.36 + 10.37 + #decide what module post'd the action 10.38 + 10.39 + args = getVar( 'args', request ) 10.40 + 10.41 + mod = getVar( 'mod', request ) 10.42 + 10.43 + if not mod is None and args is None: 10.44 + module = self.modules[ mod ] 10.45 + #check module exists 10.46 + if module: 10.47 + module( self.mainUrlWriter ).perform( request ) 10.48 + else: 10.49 + self.perform( request ) 10.50 + 10.51 + return self.render_GET( request ) 10.52 + 10.53 + def mainUrlWriter( self, module ): 10.54 + def fun( f ): 10.55 + return "Main.rpy?mod=%s%s" % ( module, f ) 10.56 + return fun 10.57 + 10.58 + def write_BODY( self, request ): 10.59 + 10.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" ) 10.61 + request.write( "<tr>\n" ) 10.62 + request.write( " <td width='15px'> </td>" ) 10.63 + request.write( " <td width='175px' align='center' valign'center'>" ) 10.64 + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) 10.65 + request.write( " <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" ) 10.66 + request.write( " <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" ) 10.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>") 10.68 + request.write( " <tr><td align='center' valign='top'>" ) 10.69 + 10.70 + for modName in self.module_menus: 10.71 + self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request ) 10.72 + 10.73 + request.write( " </td></tr>" ) 10.74 + request.write( " </table>" ) 10.75 + request.write( " " ) 10.76 + request.write( " </td>\n" ) 10.77 + request.write( " <td width='15px'> </td>" ) 10.78 + request.write( " <td width='558px' align='left' valign='top'>" ) 10.79 + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) 10.80 + request.write( " <tr><td height='20px'></td></tr>" ) 10.81 + request.write( " <tr><td align='center' valign='top'>" ) 10.82 + 10.83 + modName = getVar('mod', request) 10.84 + 10.85 + if modName is None: 10.86 + request.write( '<p>Please select a module</p>' ) 10.87 + else: 10.88 + module = self.modules[ modName ] 10.89 + if module: 10.90 + module( self.mainUrlWriter( modName ) ).write_BODY( request ) 10.91 + else: 10.92 + request.write( '<p>Invalid module. Please select another</p>' ) 10.93 + 10.94 + request.write( " </td></tr>" ) 10.95 + request.write( " </table>" ) 10.96 + request.write( " </td>\n" ) 10.97 + request.write( " <td width='17px'> </td>" ) 10.98 + request.write( "</tr>\n" ) 10.99 + 10.100 + request.write( "</table>\n" ) 10.101 + 10.102 + 10.103 + def op_destroy( self, request ): 10.104 + dom = getVar( 'dom', request ) 10.105 + if not dom is None and dom != "0": 10.106 + server.xend_domain_destroy( int( dom ), "halt" ) 10.107 + 10.108 + def op_pause( self, request ): 10.109 + dom = getVar( 'dom', request ) 10.110 + if not dom is None and dom != "0": 10.111 + server.xend_domain_pause( int( dom ) ) 10.112 + 10.113 + def op_unpause( self, request ): 10.114 + dom = getVar( 'dom', request ) 10.115 + if not dom is None and dom != "0": 10.116 + server.xend_domain_unpause( int( dom ) )
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/tools/python/xen/sv/MigrateDomain.py Tue Jul 26 15:16:12 2005 +0000 11.3 @@ -0,0 +1,74 @@ 11.4 +from xen.sv.Wizard import * 11.5 +from xen.sv.util import * 11.6 +from xen.sv.GenTabbed import PreTab 11.7 + 11.8 +from xen.xm.create import make_config, OptVals 11.9 + 11.10 +from xen.xend.XendClient import server 11.11 + 11.12 +class MigrateDomain( Wizard ): 11.13 + def __init__( self, urlWriter ): 11.14 + 11.15 + sheets = [ ChooseMigrateDomain, 11.16 + DoMigrate ] 11.17 + 11.18 + Wizard.__init__( self, urlWriter, "Migrate Domain", sheets ) 11.19 + 11.20 + 11.21 +class ChooseMigrateDomain( Sheet ): 11.22 + def __init__( self, urlWriter ): 11.23 + Sheet.__init__( self, urlWriter, "Configure Migration", 0) 11.24 + domains = [] 11.25 + domnames = [] 11.26 + 11.27 + try: 11.28 + domains = server.xend_domains() 11.29 + domains.sort() 11.30 + except: 11.31 + pass 11.32 + 11.33 + for i in domains: 11.34 + if i != 'Domain-0': domnames.append((i,i)) 11.35 + 11.36 + self.addControl( ListControl('domid', 11.37 + domnames, 11.38 + 'Domain ID:') ) 11.39 + self.addControl( TickControl('live', 11.40 + 'True', 11.41 + 'Live migrate:') ) 11.42 + self.addControl( InputControl('rate', 11.43 + '0', 11.44 + 'Rate limit:') ) 11.45 + self.addControl( InputControl( 'dest', 'myhost.mydomain', 11.46 + 'Name or IP address:', 11.47 + ".*") ) 11.48 + 11.49 +class DoMigrate( Sheet ): 11.50 + def __init__(self, urlWriter ): 11.51 + Sheet.__init__(self, urlWriter, "Migration Done", 1) 11.52 + 11.53 + def write_BODY( self, request, err ): 11.54 + 11.55 + if not self.passback: self.parseForm( request ) 11.56 + 11.57 +# print string2sxp(self.passback) 11.58 + 11.59 + config = ssxp2hash ( string2sxp( self.passback ) ) 11.60 + 11.61 + try: 11.62 + print config 11.63 + print config['domid'], config['dest'] 11.64 + dom_sxp = server.xend_domain_migrate( config['domid'], 11.65 + config['dest'], 11.66 + config.get('live') == 'True', 11.67 + config['rate'] ) 11.68 + success = "Your domain was successfully Migrated.\n" 11.69 + except Exception, e: 11.70 + success = "There was an error migrating your domain\n" 11.71 + dom_sxp = str(e) 11.72 + 11.73 + pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) ) 11.74 + pt.write_BODY( request ) 11.75 + 11.76 + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) 11.77 + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/tools/python/xen/sv/NodeInfo.py Tue Jul 26 15:16:12 2005 +0000 12.3 @@ -0,0 +1,63 @@ 12.4 +from xen.xend.XendClient import server 12.5 + 12.6 +from xen.sv.util import * 12.7 +from xen.sv.GenTabbed import * 12.8 + 12.9 +class NodeInfo( GenTabbed ): 12.10 + 12.11 + def __init__( self, urlWriter ): 12.12 + GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', ], [ NodeGeneralTab, NodeDmesgTab ] ) 12.13 + 12.14 + def write_MENU( self, request ): 12.15 + request.write( "<p class='small'><a href='%s'>Node details</a></p>" % self.urlWriter( '' ) ) 12.16 + 12.17 +class NodeGeneralTab( CompositeTab ): 12.18 + def __init__( self ): 12.19 + CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ] ) 12.20 + 12.21 +class NodeInfoTab( GeneralTab ): 12.22 + 12.23 + def __init__( self ): 12.24 + 12.25 + nodeInfo = {} 12.26 + try: 12.27 + nodeInfo = sxp2hash( server.xend_node() ) 12.28 + except: 12.29 + nodeInfo[ 'system' ] = 'Error getting node info' 12.30 + 12.31 + dictTitles = {} 12.32 + dictTitles[ 'System' ] = 'system' 12.33 + dictTitles[ 'Hostname' ] = 'host' 12.34 + dictTitles[ 'Release' ] = 'release' 12.35 + dictTitles[ 'Version' ] ='version' 12.36 + dictTitles[ 'Machine' ] = 'machine' 12.37 + dictTitles[ 'Cores' ] = 'cores' 12.38 + dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter ) 12.39 + dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter ) 12.40 + dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter ) 12.41 + dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter ) 12.42 + 12.43 + GeneralTab.__init__( self, dict=nodeInfo, titles=dictTitles ) 12.44 + 12.45 +class NodeDmesgTab( PreTab ): 12.46 + 12.47 + def __init__( self ): 12.48 + try: 12.49 + dmesg = server.xend_node_get_dmesg() 12.50 + except: 12.51 + dmesg = "Error getting node information: XenD not running?" 12.52 + PreTab.__init__( self, dmesg ) 12.53 + 12.54 +class NodeActionTab( ActionTab ): 12.55 + 12.56 + def __init__( self ): 12.57 + ActionTab.__init__( self, { "shutdown" : "shutdown", 12.58 + "reboot" : "reboot" } ) 12.59 + 12.60 + def op_shutdown( self, request ): 12.61 + if debug: print ">NodeShutDown" 12.62 + server.xend_node_shutdown() 12.63 + 12.64 + def op_reboot( self, request ): 12.65 + if debug: print ">NodeReboot" 12.66 + server.xend_node_reboot()
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/tools/python/xen/sv/RestoreDomain.py Tue Jul 26 15:16:12 2005 +0000 13.3 @@ -0,0 +1,46 @@ 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 RestoreDomain( Wizard ): 13.13 + def __init__( self, urlWriter ): 13.14 + 13.15 + sheets = [ ChooseRestoreDomain, 13.16 + DoRestore ] 13.17 + 13.18 + Wizard.__init__( self, urlWriter, "Restore Domain", sheets ) 13.19 + 13.20 + 13.21 +class ChooseRestoreDomain( Sheet ): 13.22 + def __init__( self, urlWriter ): 13.23 + Sheet.__init__( self, urlWriter, "Configure Restore", 0) 13.24 + 13.25 + self.addControl( InputControl( 'file', '', 13.26 + 'Suspend file name:', 13.27 + ".*") ) 13.28 + 13.29 +class DoRestore( Sheet ): 13.30 + def __init__(self, urlWriter ): 13.31 + Sheet.__init__(self, urlWriter, "Restore Done", 1) 13.32 + 13.33 + def write_BODY( self, request, err ): 13.34 + 13.35 + if not self.passback: self.parseForm( request ) 13.36 + config = ssxp2hash ( string2sxp( self.passback ) ) 13.37 + 13.38 + try: 13.39 + dom_sxp = server.xend_domain_restore( config['file'] ) 13.40 + success = "Your domain was successfully restored.\n" 13.41 + except Exception, e: 13.42 + success = "There was an error restoring your domain\n" 13.43 + dom_sxp = str(e) 13.44 + 13.45 + pt = PreTab( success + sxp2prettystring( dom_sxp ) ) 13.46 + pt.write_BODY( request ) 13.47 + 13.48 + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) 13.49 + 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/SaveDomain.py Tue Jul 26 15:16:12 2005 +0000 14.3 @@ -0,0 +1,62 @@ 14.4 +from xen.sv.Wizard import * 14.5 +from xen.sv.util import * 14.6 +from xen.sv.GenTabbed import PreTab 14.7 + 14.8 +from xen.xm.create import make_config, OptVals 14.9 + 14.10 +from xen.xend.XendClient import server 14.11 + 14.12 +class SaveDomain( Wizard ): 14.13 + def __init__( self, urlWriter ): 14.14 + 14.15 + sheets = [ ChooseSaveDomain, 14.16 + DoSave ] 14.17 + 14.18 + Wizard.__init__( self, urlWriter, "Save Domain", sheets ) 14.19 + 14.20 + 14.21 +class ChooseSaveDomain( Sheet ): 14.22 + def __init__( self, urlWriter ): 14.23 + Sheet.__init__( self, urlWriter, "Configure Save", 0) 14.24 + 14.25 + domains = [] 14.26 + domnames = [] 14.27 + 14.28 + try: 14.29 + domains = server.xend_domains() 14.30 + domains.sort() 14.31 + except: 14.32 + pass 14.33 + 14.34 + for i in domains: 14.35 + if i != 'Domain-0': domnames.append((i,i)) 14.36 + 14.37 + self.addControl( ListControl('domid', 14.38 + domnames, 14.39 + 'Domain ID:') ) 14.40 + self.addControl( InputControl( 'file', '', 14.41 + 'Suspend file name:', 14.42 + ".*") ) 14.43 + 14.44 +class DoSave( Sheet ): 14.45 + def __init__(self, urlWriter ): 14.46 + Sheet.__init__(self, urlWriter, "Save Done", 1) 14.47 + 14.48 + def write_BODY( self, request, err ): 14.49 + 14.50 + if not self.passback: self.parseForm( request ) 14.51 + config = ssxp2hash ( string2sxp( self.passback ) ) 14.52 + 14.53 + try: 14.54 + dom_sxp = server.xend_domain_save( config['domid'], 14.55 + config['file'] ) 14.56 + success = "Your domain was successfully saved.\n" 14.57 + except Exception, e: 14.58 + success = "There was an error saving your domain\n" 14.59 + dom_sxp = str(e) 14.60 + 14.61 + pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) ) 14.62 + pt.write_BODY( request ) 14.63 + 14.64 + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) 14.65 + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/tools/python/xen/sv/TabView.py Tue Jul 26 15:16:12 2005 +0000 15.3 @@ -0,0 +1,26 @@ 15.4 +from xen.sv.HTMLBase import HTMLBase 15.5 + 15.6 +class TabView( HTMLBase ): 15.7 + 15.8 + # tab - int, id into tabs of selected tab 15.9 + # tabs - list of strings, tab names 15.10 + # urlWriter - 15.11 + def __init__( self, tab, tabs, urlWriter ): 15.12 + HTMLBase.__init__(self) 15.13 + self.tab = tab 15.14 + self.tabs = tabs 15.15 + self.urlWriter = urlWriter 15.16 + 15.17 + def write_BODY( self, request ): 15.18 + request.write( "<table style='' border='0' cellspacing='3' cellpadding='2' align='center'>" ) 15.19 + request.write( "<tr height='22'>" ) 15.20 + 15.21 + for i in range( len( self.tabs ) ): 15.22 + if self.tab == i: 15.23 + backgroundColor = "white" 15.24 + else: 15.25 + backgroundColor = "grey" 15.26 + 15.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 ] ) ) 15.28 + 15.29 + request.write( "</tr></table>" )
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/tools/python/xen/sv/Wizard.py Tue Jul 26 15:16:12 2005 +0000 16.3 @@ -0,0 +1,269 @@ 16.4 +from xen.sv.util import * 16.5 +from xen.sv.HTMLBase import HTMLBase 16.6 +from xen.xend import sxp 16.7 + 16.8 +import re 16.9 + 16.10 +DEBUG = 0 16.11 + 16.12 +class Wizard( HTMLBase ): 16.13 + 16.14 + def __init__( self, urlWriter, title, sheets ): 16.15 + HTMLBase.__init__( self ) 16.16 + self.title = title 16.17 + self.sheets = sheets 16.18 + self.urlWriter = urlWriter 16.19 + 16.20 + def write_MENU( self, request ): 16.21 + request.write( "<p class='small'><a href='%s'>%s</a></p>" % (self.urlWriter( '' ), self.title) ) 16.22 + 16.23 + def write_BODY( self, request ): 16.24 + 16.25 + request.write( "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr><td>" ) 16.26 + request.write( "<p align='center'><u>%s</u></p></td></tr><tr><td>" % self.title ) 16.27 + 16.28 + currSheet = getVar( 'sheet', request ) 16.29 + 16.30 + if not currSheet is None: 16.31 + currSheet = int( currSheet ) 16.32 + else: 16.33 + currSheet = 0 16.34 + 16.35 + sheet = self.sheets[ currSheet ]( self.urlWriter ) 16.36 + 16.37 + err = not sheet.validate( request ) 16.38 + 16.39 + if not err: 16.40 + op = getVar( 'op', request ) 16.41 + 16.42 + if op == 'next': 16.43 + currSheet += 1 16.44 + elif op == 'prev': 16.45 + currSheet -= 1 16.46 + 16.47 + sheet = self.sheets[ currSheet ]( self.urlWriter ) 16.48 + 16.49 + if getVar( 'visited-sheet%s' % currSheet, request ): 16.50 + sheet.write_BODY( request, err ) 16.51 + else: 16.52 + sheet.write_BODY( request, False ) 16.53 + 16.54 + 16.55 + request.write( "</td></tr><tr><td><table width='100%' border='0' cellspacing='0' cellpadding='0'><tr>" ) 16.56 + request.write( "<td width='80%'></td><td width='20%' align='center'><p align='center'>" ) 16.57 + if currSheet > 0: 16.58 + request.write( "<img src='images/previous.png' onclick='doOp( \"prev\" )' onmouseover='update( \"wizText\", \"Previous\" )' onmouseout='update( \"wizText\", \" \" )'> " ) 16.59 + if currSheet < ( len( self.sheets ) - 2 ): 16.60 + request.write( "<img src='images/next.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Next\" )' onmouseout='update( \"wizText\", \" \" )'>" ) 16.61 + elif currSheet == ( len( self.sheets ) - 2 ): 16.62 + request.write( "<img src='images/finish.png' onclick='doOp( \"next\" )' onmouseover='update( \"wizText\", \"Finish\" )' onmouseout='update( \"wizText\", \" \" )'>" ) 16.63 + request.write( "</p><p align='center'><span id='wizText'></span></p></td></tr></table>" ) 16.64 + request.write( "</td></tr></table>" ) 16.65 + 16.66 + def op_next( self, request ): 16.67 + pass 16.68 + 16.69 + def op_prev( self, request ): 16.70 + pass 16.71 + 16.72 + def op_finish( self, request ): 16.73 + pass 16.74 + 16.75 +class Sheet( HTMLBase ): 16.76 + 16.77 + def __init__( self, urlWriter, title, location ): 16.78 + HTMLBase.__init__( self ) 16.79 + self.urlWriter = urlWriter 16.80 + self.feilds = [] 16.81 + self.title = title 16.82 + self.location = location 16.83 + self.passback = None 16.84 + 16.85 + def parseForm( self, request ): 16.86 + do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ] 16.87 + 16.88 + passed_back = request.args 16.89 + 16.90 + temp_passback = passed_back.get( "passback" ) 16.91 + 16.92 + if temp_passback is not None and len( temp_passback ) > 0: 16.93 + temp_passback = temp_passback[ len( temp_passback )-1 ] 16.94 + else: 16.95 + temp_passback = "( )" 16.96 + 16.97 + last_passback = ssxp2hash( string2sxp( temp_passback ) ) #use special function - will work with no head on sxp 16.98 + 16.99 + if DEBUG: print last_passback 16.100 + 16.101 + for (key, value) in passed_back.items(): 16.102 + if key not in do_not_parse: 16.103 + last_passback[ key ] = value[ len( value ) - 1 ] 16.104 + 16.105 + self.passback = sxp2string( hash2sxp( last_passback ) ) #store the sxp 16.106 + 16.107 + if DEBUG: print self.passback 16.108 + 16.109 + def write_BODY( self, request, err ): 16.110 + 16.111 + if not self.passback: self.parseForm( request ) 16.112 + 16.113 + request.write( "<p>%s</p>" % self.title ) 16.114 + 16.115 + previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference 16.116 + 16.117 + request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" ) 16.118 + 16.119 + for (feild, control) in self.feilds: 16.120 + control.write_Control( request, previous_values.get( feild ) ) 16.121 + if err and not control.validate( previous_values.get( feild ) ): 16.122 + control.write_Help( request ) 16.123 + 16.124 + request.write( "</table>" ) 16.125 + 16.126 + request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback ) 16.127 + request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location ) 16.128 + request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location ) 16.129 + 16.130 + def addControl( self, control ): 16.131 + self.feilds.append( [ control.getName(), control ] ) 16.132 + 16.133 + def validate( self, request ): 16.134 + 16.135 + if not self.passback: self.parseForm( request ) 16.136 + 16.137 + check = True 16.138 + 16.139 + previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference 16.140 + if DEBUG: print previous_values 16.141 + 16.142 + for (feild, control) in self.feilds: 16.143 + if not control.validate( previous_values.get( feild ) ): 16.144 + check = False 16.145 + if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild )) 16.146 + 16.147 + return check 16.148 + 16.149 +class SheetControl( HTMLBase ): 16.150 + 16.151 + def __init__( self, reg_exp = ".*" ): 16.152 + HTMLBase.__init__( self ) 16.153 + self.name = "" 16.154 + self.reg_exp = reg_exp 16.155 + 16.156 + def write_Control( self, request, persistedValue ): 16.157 + request.write( "<tr colspan='2'><td>%s</td></tr>" % persistedValue ) 16.158 + 16.159 + def write_Help( self, request ): 16.160 + request.write( "<tr><td align='right' colspan='2'><p class='small'>Text must match pattern:" ) 16.161 + request.write( " %s</p></td></tr>" % self.reg_exp ) 16.162 + 16.163 + def validate( self, persistedValue ): 16.164 + if persistedValue is None: 16.165 + persistedValue = "" 16.166 + 16.167 + return not re.compile( self.reg_exp ).match( persistedValue ) is None 16.168 + 16.169 + def getName( self ): 16.170 + return self.name 16.171 + 16.172 + def setName( self, name ): 16.173 + self.name = name 16.174 + 16.175 +class InputControl( SheetControl ): 16.176 + 16.177 + def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ): 16.178 + SheetControl.__init__( self, reg_exp ) 16.179 + self.setName( name ) 16.180 + 16.181 + self.defaultValue = defaultValue 16.182 + self.humanText = humanText 16.183 + self.help_text = help_text 16.184 + 16.185 + def write_Control( self, request, persistedValue ): 16.186 + if persistedValue is None: 16.187 + persistedValue = self.defaultValue 16.188 + 16.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) ) 16.190 + 16.191 + def write_Help( self, request ): 16.192 + request.write( "<tr><td align='right' colspan='2'><p class='small'>" ) 16.193 + request.write( " %s</p></td></tr>" % self.help_text ) 16.194 + 16.195 +class TextControl( SheetControl ): 16.196 + 16.197 + def __init__( self, text ): 16.198 + SheetControl.__init__( self ) 16.199 + self.text = text 16.200 + 16.201 + def write_Control( self, request, persistedValue ): 16.202 + request.write( "<tr><td colspan='2'><p>%s</p></td></tr>" % self.text ) 16.203 + 16.204 +class SmallTextControl( SheetControl ): 16.205 + 16.206 + def __init__( self, text ): 16.207 + SheetControl.__init__( self ) 16.208 + self.text = text 16.209 + 16.210 + def write_Control( self, request, persistedValue ): 16.211 + request.write( "<tr><td colspan='2'><p class='small'>%s</p></tr></td>" % self.text ) 16.212 + 16.213 +class ListControl( SheetControl ): 16.214 + 16.215 + def __init__( self, name, options, humanText ): 16.216 + SheetControl.__init__( self ) 16.217 + self.setName( name ) 16.218 + self.options = options 16.219 + self.humanText = humanText 16.220 + 16.221 + def write_Control( self, request, persistedValue ): 16.222 + request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText ) 16.223 + request.write( "<select name='%s'>" % self.getName() ) 16.224 + for (value, text) in self.options: 16.225 + if value == persistedValue: 16.226 + request.write( "<option value='%s' selected>%s\n" % (value, text) ) 16.227 + else: 16.228 + request.write( "<option value='%s'>%s\n" % (value, text) ) 16.229 + request.write( "</select></td></tr>" ) 16.230 + 16.231 + def validate( self, persistedValue ): 16.232 + for (value, text) in self.options: 16.233 + if value == persistedValue: 16.234 + return True 16.235 + 16.236 + return False 16.237 + 16.238 +class FileControl( InputControl ): 16.239 + 16.240 + def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ): 16.241 + InputControl.__init__( self, name, defaultValue, humanText ) 16.242 + 16.243 + def validate( self, persistedValue ): 16.244 + if persistedValue is None: return False 16.245 + try: 16.246 + open( persistedValue ) 16.247 + return True 16.248 + except IOError, TypeError: 16.249 + return False 16.250 + 16.251 + def write_Help( self, request ): 16.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>" ) 16.253 + 16.254 +class TickControl( SheetControl ): 16.255 + 16.256 + def __init__( self, name, defaultValue, humanText ): 16.257 + SheetControl.__init__( self ) 16.258 + self.setName( name ) 16.259 + self.defaultValue = defaultValue 16.260 + self.humanText = humanText 16.261 + 16.262 + def write_Control( self, request, persistedValue ): 16.263 + request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText ) 16.264 + 16.265 + if persistedValue == 'True': 16.266 + request.write( "<input type='checkbox' name='%s' value='True' checked>" % self.getName() ) 16.267 + else: 16.268 + request.write( "<input type='checkbox' name='%s' value='True'>" % self.getName() ) 16.269 + 16.270 + request.write( "</select></td></tr>" ) 16.271 + 16.272 +
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/tools/python/xen/sv/__init__.py Tue Jul 26 15:16:12 2005 +0000 17.3 @@ -0,0 +1,1 @@ 17.4 +
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/tools/python/xen/sv/params.py Tue Jul 26 15:16:12 2005 +0000 18.3 @@ -0,0 +1,3 @@ 18.4 +SV_PORT = 8080 18.5 +SV_ROOT = "/var/lib/xen/sv/" 18.6 +PID_FILE = "/var/run/xen-sv.pid"
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/tools/python/xen/sv/util.py Tue Jul 26 15:16:12 2005 +0000 19.3 @@ -0,0 +1,126 @@ 19.4 +from xen.xend.XendClient import server 19.5 +from xen.xend import sxp 19.6 +from xen.xend import PrettyPrint 19.7 + 19.8 +import types 19.9 + 19.10 +def getDomInfoHash( domain ): 19.11 + domInfoHash = {} 19.12 + try: 19.13 + domInfoHash = sxp2hash( server.xend_domain( domain ) ) 19.14 + domInfoHash['dom'] = domain 19.15 + except: 19.16 + domInfoHash['name'] = "Error getting domain details" 19.17 + return domInfoHash 19.18 + 19.19 +def sxp2hash( s ): 19.20 + sxphash = {} 19.21 + 19.22 + for child in sxp.children( s ): 19.23 + if isinstance( child, types.ListType ) and len( child ) > 1: 19.24 + if isinstance( child[1], types.ListType ) and len( child ) > 1: 19.25 + sxphash[ child[0] ] = sxp2hash( child[1] ) 19.26 + else: 19.27 + sxphash[ child[0] ] = child[1] 19.28 + 19.29 + return sxphash 19.30 + 19.31 +def ssxp2hash( s ): 19.32 + sxphash = {} 19.33 + 19.34 + for i in s: 19.35 + if isinstance( i, types.ListType ) and len( i ) > 1: 19.36 + sxphash[ i[0] ] = i[1] 19.37 + 19.38 + return sxphash 19.39 + 19.40 +def hash2sxp( h ): 19.41 + hashsxp = [] 19.42 + 19.43 + for (key, item) in h.items(): 19.44 + hashsxp.append( [key, item] ) 19.45 + 19.46 + return hashsxp 19.47 + 19.48 +def string2sxp( string ): 19.49 + pin = sxp.Parser() 19.50 + pin.input( string ) 19.51 + return pin.get_val() 19.52 + 19.53 +def sxp2string( sexp ): 19.54 + return sxp.to_string( sexp ) 19.55 + 19.56 +def sxp2prettystring( sxp ): 19.57 + class tmp: 19.58 + def __init__( self ): 19.59 + self.str = "" 19.60 + def write( self, str ): 19.61 + self.str = self.str + str 19.62 + temp = tmp() 19.63 + PrettyPrint.prettyprint( sxp, out=temp ) 19.64 + return temp.str 19.65 + 19.66 +def getVar( var, request, default=None ): 19.67 + 19.68 + arg = request.args.get( var ) 19.69 + 19.70 + if arg is None: 19.71 + return default 19.72 + else: 19.73 + return arg[ len( arg )-1 ] 19.74 + 19.75 +def bigTimeFormatter( time ): 19.76 + time = float( time ) 19.77 + weeks = time // 604800 19.78 + remainder = time % 604800 19.79 + days = remainder // 86400 19.80 + 19.81 + remainder = remainder % 86400 19.82 + 19.83 + hms = smallTimeFormatter( remainder ) 19.84 + 19.85 + return "%d weeks, %d days, %s" % ( weeks, days, hms ) 19.86 + 19.87 +def smallTimeFormatter( time ): 19.88 + time = float( time ) 19.89 + hours = time // 3600 19.90 + remainder = time % 3600 19.91 + mins = remainder // 60 19.92 + secs = time % 60 19.93 + return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs ) 19.94 + 19.95 +def stateFormatter( state ): 19.96 + states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ] 19.97 + 19.98 + stateStr = "" 19.99 + 19.100 + for i in range( len( state ) ): 19.101 + if state[i] != "-": 19.102 + stateStr += "%s, " % states[ i ] 19.103 + 19.104 + return stateStr + " (%s)" % state 19.105 + 19.106 +def memoryFormatter( mem ): 19.107 + mem = int( mem ) 19.108 + if mem >= 1024: 19.109 + mem = float( mem ) / 1024 19.110 + return "%3.2fGb" % mem 19.111 + else: 19.112 + return "%7dMb" % mem 19.113 + 19.114 +def cpuFormatter( mhz ): 19.115 + mhz = int( mhz ) 19.116 + if mhz > 1000: 19.117 + ghz = float( mhz ) / 1000.0 19.118 + return "%4.2fGHz" % ghz 19.119 + else: 19.120 + return "%4dMHz" % mhz 19.121 + 19.122 +def hyperthreadFormatter( threads ): 19.123 + try: 19.124 + if int( threads ) > 1: 19.125 + return "Yes" 19.126 + else: 19.127 + return "No" 19.128 + except: 19.129 + return "No"
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/tools/sv/Makefile Tue Jul 26 15:16:12 2005 +0000 20.3 @@ -0,0 +1,2 @@ 20.4 + 20.5 +all:
21.1 Binary file tools/sv/images/destroy.png has changed
22.1 Binary file tools/sv/images/finish.png has changed
23.1 Binary file tools/sv/images/internet copy.jpg has changed
24.1 Binary file tools/sv/images/internet.jpg has changed
25.1 Binary file tools/sv/images/internet.psd has changed
26.1 Binary file tools/sv/images/next.png has changed
27.1 Binary file tools/sv/images/orb_01.jpg has changed
28.1 Binary file tools/sv/images/orb_02.jpg has changed
29.1 Binary file tools/sv/images/pause.png has changed
30.1 Binary file tools/sv/images/previous.png has changed
31.1 Binary file tools/sv/images/reboot.png has changed
32.1 Binary file tools/sv/images/seperator-left-highlight.jpg has changed
33.1 Binary file tools/sv/images/seperator-right-highlight.jpg has changed
34.1 Binary file tools/sv/images/seperator.jpg has changed
35.1 Binary file tools/sv/images/shutdown.png has changed
36.1 Binary file tools/sv/images/small-destroy.png has changed
37.1 Binary file tools/sv/images/small-pause.png has changed
38.1 Binary file tools/sv/images/small-unpause.png has changed
39.1 Binary file tools/sv/images/unpause.png has changed
40.1 Binary file tools/sv/images/xen.png has changed
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/tools/sv/inc/script.js Tue Jul 26 15:16:12 2005 +0000 41.3 @@ -0,0 +1,31 @@ 41.4 +function update( objRef, text ) { 41.5 + if ( document.all || document.getElementById ) { 41.6 + obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef ); 41.7 + obj.innerHTML= text 41.8 + } 41.9 +} 41.10 + 41.11 +function buttonMouseOver( objRef ) { 41.12 + if ( document.all || document.getElementById ) { 41.13 + obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef ); 41.14 + objRef.style.background = "white"; 41.15 + } 41.16 +} 41.17 + 41.18 +function buttonMouseOut( objRef ) { 41.19 + if ( document.all || document.getElementById ) { 41.20 + obj = ( document.getElementById )? document.getElementById( objRef ) : document.all( objRef ); 41.21 + objRef.style.background = "grey"; 41.22 + } 41.23 +} 41.24 + 41.25 +function doOp( op ) { 41.26 + document.forms[0].op.value = op 41.27 + document.forms[0].submit() 41.28 +} 41.29 + 41.30 +function doOp2( op, args ) { 41.31 + document.forms[0].op.value = op 41.32 + document.forms[0].args.value = args 41.33 + document.forms[0].submit() 41.34 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/tools/sv/inc/style.css Tue Jul 26 15:16:12 2005 +0000 42.3 @@ -0,0 +1,32 @@ 42.4 + 42.5 +P {font-family: verdana, arial; font-size: 12px; color: black} 42.6 +.small {font-size: 10px} 42.7 + 42.8 +TD.domainInfo {font-family: verdana, arial; font-size: 10px; color: black} 42.9 +TD.domainInfoHead {font-family: verdana, arial; font-size: 10px; color: white; font-face: bold} 42.10 + 42.11 +TD.domainInfoHead {background-color: black} 42.12 +TR.domainInfoOdd {background-color: white} 42.13 +TR.domainInfoEven {background-color: lightgrey} 42.14 + 42.15 +body { 42.16 + width: 670px; 42.17 + margin: 0px; 42.18 + padding: 0px; 42.19 + background-color: #fff; 42.20 + background-image: url(../images/orb_02.jpg); 42.21 + background-repeat: repeat-y; 42.22 + background-position: left top; 42.23 + font-family: Arial, Helvetica, sans-serif; 42.24 + font-weight: bold; 42.25 + color: #333333; 42.26 + letter-spacing: 0px; 42.27 + scrollbar-base-color: #333333; 42.28 + scrollbar-track-color: #666666; 42.29 + scrollbar-face-color: #fff; 42.30 + 42.31 + 42.32 + } 42.33 + 42.34 +.button (cursor:hand) 42.35 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/tools/sv/index.psp Tue Jul 26 15:16:12 2005 +0000 43.3 @@ -0,0 +1,164 @@ 43.4 +<% 43.5 +import sys 43.6 +sys.path.append( "/usr/lib/python" ) 43.7 + 43.8 +debug = True and False 43.9 + 43.10 +for path in sys.path: 43.11 + if debug: req.write( path + "<br/>" ) 43.12 + 43.13 +from xen.sv.HTMLBase import HTMLBase 43.14 +from xen.sv.DomList import DomList 43.15 +from xen.sv.NodeInfo import NodeInfo 43.16 +from xen.sv.DomInfo import DomInfo 43.17 +from xen.sv.CreateDomain import CreateDomain 43.18 +from xen.sv.MigrateDomain import MigrateDomain 43.19 +from xen.sv.SaveDomain import SaveDomain 43.20 +from xen.sv.RestoreDomain import RestoreDomain 43.21 + 43.22 +from xen.xend.XendClient import server 43.23 + 43.24 +from xen.sv.util import getVar 43.25 + 43.26 +# adapter to make this all work with mod_python 43.27 +# (c) Tom Wilkie 2005 43.28 + 43.29 +class TwistedAdapter: 43.30 + 43.31 + def write( self, text ): 43.32 + req.write( text ) 43.33 + 43.34 + class Args: 43.35 + 43.36 + from mod_python.util import FieldStorage 43.37 + 43.38 + fieldStorage = FieldStorage( req, True ) 43.39 + 43.40 + # return a list of values for the given key, 43.41 + # or None if key not there 43.42 + def get( self, var ): 43.43 + retVar = self.fieldStorage.getlist( var ) 43.44 + if len( retVar ) == 0: 43.45 + return None 43.46 + else: 43.47 + return retVar 43.48 + 43.49 + # return a list of tuples, 43.50 + # (key, value) where value is a list of values 43.51 + def items( self ): 43.52 + result = []; 43.53 + for key in self.fieldStorage.keys(): 43.54 + result.append( (key, self.fieldStorage.getlist( key ) ) ) 43.55 + return result 43.56 + 43.57 + args = Args() 43.58 + 43.59 + uri = req.unparsed_uri 43.60 + 43.61 + 43.62 +class Main( HTMLBase ): 43.63 + 43.64 + isLeaf = True 43.65 + 43.66 + def __init__( self, urlWriter = None ): 43.67 + self.modules = { "node": NodeInfo, 43.68 + "list": DomList, 43.69 + "info": DomInfo, 43.70 + "create": CreateDomain, 43.71 + "migrate" : MigrateDomain, 43.72 + "save" : SaveDomain, 43.73 + "restore" : RestoreDomain } 43.74 + 43.75 + # ordered list of module menus to display 43.76 + self.module_menus = [ "node", "create", "migrate", "save", 43.77 + "restore", "list" ] 43.78 + HTMLBase.__init__(self) 43.79 + 43.80 + def render_POST( self, request ): 43.81 + 43.82 + #decide what module post'd the action 43.83 + 43.84 + args = getVar( 'args', request ) 43.85 + 43.86 + mod = getVar( 'mod', request ) 43.87 + 43.88 + if mod in self.modules and args is None: 43.89 + module = self.modules[ mod ] 43.90 + #check module exists 43.91 + if module: 43.92 + module( self.mainUrlWriter ).perform( request ) 43.93 + else: 43.94 + self.perform( request ) 43.95 + 43.96 + return self.render_GET( request ) 43.97 + 43.98 + #TODO: need to make this get the request uri automatically 43.99 + def mainUrlWriter( self, module ): 43.100 + def fun( f ): 43.101 + return "index.psp?mod=%s%s" % ( module, f ) 43.102 + return fun 43.103 + 43.104 + def write_BODY( self, request ): 43.105 + 43.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" ) 43.107 + request.write( "<tr>\n" ) 43.108 + request.write( " <td width='15px'> </td>" ) 43.109 + request.write( " <td width='175px' align='center' valign'center'>" ) 43.110 + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) 43.111 + request.write( " <tr><td height='140px' align='center' valign='bottom'><a href='http://www.cl.cam.ac.uk/Research/SRG/netos/xen/'>" ) 43.112 + request.write( " <img src='images/xen.png' width='150' height='75' border='0'/></a><br/></td></tr>" ) 43.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>") 43.114 + request.write( " <tr><td align='center' valign='top'>" ) 43.115 + 43.116 + for modName in self.module_menus: 43.117 + self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request ) 43.118 + 43.119 + request.write( " </td></tr>" ) 43.120 + request.write( " </table>" ) 43.121 + request.write( " " ) 43.122 + request.write( " </td>\n" ) 43.123 + request.write( " <td width='15px'> </td>" ) 43.124 + request.write( " <td width='558px' align='left' valign='top'>" ) 43.125 + request.write( " <table cellspacing='0' cellpadding='0' border='0' width='100%' height='100%'>" ) 43.126 + request.write( " <tr><td height='20px'></td></tr>" ) 43.127 + request.write( " <tr><td align='center' valign='top'>" ) 43.128 + 43.129 + modName = getVar('mod', request) 43.130 + 43.131 + if modName not in self.modules: 43.132 + request.write( '<p>Please select a module</p>' ) 43.133 + else: 43.134 + module = self.modules[ modName ] 43.135 + if module: 43.136 + module( self.mainUrlWriter( modName ) ).write_BODY( request ) 43.137 + else: 43.138 + request.write( '<p>Invalid module. Please select another</p>' ) 43.139 + 43.140 + request.write( " </td></tr>" ) 43.141 + request.write( " </table>" ) 43.142 + request.write( " </td>\n" ) 43.143 + request.write( " <td width='17px'> </td>" ) 43.144 + request.write( "</tr>\n" ) 43.145 + 43.146 + request.write( "</table>\n" ) 43.147 + 43.148 + 43.149 + def op_destroy( self, request ): 43.150 + dom = getVar( 'dom', request ) 43.151 + if not dom is None and dom != "0": 43.152 + server.xend_domain_destroy( int( dom ), "halt" ) 43.153 + 43.154 + def op_pause( self, request ): 43.155 + dom = getVar( 'dom', request ) 43.156 + if not dom is None and dom != "0": 43.157 + server.xend_domain_pause( int( dom ) ) 43.158 + 43.159 + def op_unpause( self, request ): 43.160 + dom = getVar( 'dom', request ) 43.161 + if not dom is None and dom != "0": 43.162 + server.xend_domain_unpause( int( dom ) ) 43.163 + 43.164 +main = Main() 43.165 + 43.166 +main.render_POST( TwistedAdapter() ) 43.167 +%>