diff --git a/tools/python/xen/sv/CreateDomain.py b/tools/python/xen/sv/CreateDomain.py index 4378897e5c..77a3483a44 100755 --- a/tools/python/xen/sv/CreateDomain.py +++ b/tools/python/xen/sv/CreateDomain.py @@ -17,37 +17,69 @@ class CreateDomain( Wizard ): CreateFinish ] Wizard.__init__( self, urlWriter, "Create Domain", sheets ) - + + def op_finish( self, request ): + pass + class CreatePage0( Sheet ): + title = "General" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "General", 0 ) self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) ) self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) ) self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) ) self.addControl( InputControl( 'cpu_weight', '1', 'CPU Weight:', "[\\d]+", "You must enter a number in this feild" ) ) + self.addControl( InputControl( 'vcpus', '1', 'Virtual CPUs:', '[\\d]+', "You must enter a number in this feild") ) class CreatePage1( Sheet ): + title = "Setup Kernel Image" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 ) -# For now we don't need to select a builder... -# self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) ) - self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.6.9-xenU', 'Kernel Image:' ) ) + self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Domain Builder:' ) ) + self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.6.12-xenU', 'Kernel Image:' ) ) self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) ) + self.addControl( ListControl( 'use-initrd', [('yes', 'Yes'), ('no', 'No')], 'Use an Initial Ram Disk?:' ) ) + self.addControl( FileControl( 'initrd', '/boot/initrd-2.6.12-xenU.img', 'Initial Ram Disk:' ) ) + + def validate( self, request ): + if not self.passback: self.parseForm( request ) + check = True + request.write( previous_values.get( '>>>>>use-initrd' ) ) + previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the map for quick reference + if DEBUG: print previous_values + for (feild, control) in self.feilds: + if feild == 'initrd' and previous_values.get( 'use-initrd' ) != 'no': + request.write( previous_values.get( '>>>>>use-initrd' ) ) + if control.validate( previous_values.get( feild ) ): + check = False + elif not control.validate( previous_values.get( feild ) ): + check = False + + if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild )) + + return check + class CreatePage2( Sheet ): + title = "Choose number of VBDS" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 ) self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) ) class CreatePage3( Sheet ): + title = "Setup VBDS" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 ) - def write_BODY( self, request, err ): + def write_BODY( self, request ): if not self.passback: self.parseForm( request ) previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference @@ -61,10 +93,12 @@ class CreatePage3( Sheet ): self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) ) - Sheet.write_BODY( self, request, err ) + Sheet.write_BODY( self, request ) class CreatePage4( Sheet ): + title = "Network Setting" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "Network settings", 4 ) self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) ) @@ -76,26 +110,27 @@ class CreatePage4( Sheet ): class CreateFinish( Sheet ): + title = "Finish" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "All Done", 5 ) - def write_BODY( self, request, err ): + def write_BODY( self, request ): if not self.passback: self.parseForm( request ) xend_sxp = self.translate_sxp( string2sxp( self.passback ) ) + + request.write( "
%s
" % sxp2prettystring( xend_sxp ) ) try: - dom_sxp = server.xend_domain_create( xend_sxp ) - success = "Your domain was successfully created.\n" - except: - success = "There was an error creating your domain.\nThe configuration used is as follows:\n" - dom_sxp = xend_sxp - - - - pt = PreTab( success + sxp2prettystring( dom_sxp ) ) - pt.write_BODY( request ) + server.xend_domain_create( xend_sxp ) + request.write( "

You domain had been successfully created.

" ) + except Exception, e: + request.write( "

There was an error creating your domain.
The configuration used is as follows:\n

" ) + request.write( "
%s
" % sxp2prettystring( xend_sxp ) ) + request.write( "

The error was:

" ) + request.write( "
%s
" % str( e ) ) request.write( "

" % self.passback ) request.write( "

" % self.location ) @@ -117,6 +152,7 @@ class CreateFinish( Sheet ): vals.maxmem = get( 'maxmem' ) vals.cpu = get( 'cpu' ) vals.cpu_weight = get( 'cpu_weight' ) + vals.vcpus = get( 'vcpus' ) vals.builder = get( 'builder' ) vals.kernel = get( 'kernel' ) @@ -128,7 +164,7 @@ class CreateFinish( Sheet ): vbds = [] for i in range( int( get( 'num_vbds' ) ) ): - vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) ) + vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ), None ) ) vals.disk = vbds @@ -141,6 +177,9 @@ class CreateFinish( Sheet ): vals.restart = None vals.console = None vals.ramdisk = None + vals.ssidref = -1 + vals.bootloader = None + vals.usb = [] #setup vifs @@ -155,9 +194,11 @@ class CreateFinish( Sheet ): dhcp = get( 'dhcp' ) vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp) + + opts = None try: - return make_config( vals ) - except: - return [["Error creating domain config."]] + return make_config( opts, vals ) + except Exception, e: + return [["There was an error creating the domain config SXP. This is typically due to an interface change in xm/create.py:make_config", e]] diff --git a/tools/python/xen/sv/Daemon.py b/tools/python/xen/sv/Daemon.py deleted file mode 100755 index 5a8d18e5e4..0000000000 --- a/tools/python/xen/sv/Daemon.py +++ /dev/null @@ -1,110 +0,0 @@ -########################################################### -## XenSV Web Control Interface Daemon -## Copyright (C) 2004, K A Fraser (University of Cambridge) -## Copyright (C) 2004, Mike Wray -## Copyright (C) 2004, Tom Wilkie -########################################################### - -import os -import os.path -import sys -import re - -from xen.sv.params import * - -from twisted.internet import reactor -from twisted.web import static, server, script - -from xen.util.ip import _readline, _readlines - -class Daemon: - """The xend daemon. - """ - def __init__(self): - self.shutdown = 0 - self.traceon = 0 - - def daemon_pids(self): - pids = [] - pidex = '(?P\d+)' - pythonex = '(?P\S*python\S*)' - cmdex = '(?P.*)' - procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$') - xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$') - procs = os.popen('ps -e -o pid,args 2>/dev/null') - for proc in procs: - pm = procre.match(proc) - if not pm: continue - xm = xendre.match(pm.group('cmd')) - if not xm: continue - #print 'pid=', pm.group('pid'), 'cmd=', pm.group('cmd') - pids.append(int(pm.group('pid'))) - return pids - - def new_cleanup(self, kill=0): - err = 0 - pids = self.daemon_pids() - if kill: - for pid in pids: - print "Killing daemon pid=%d" % pid - os.kill(pid, signal.SIGHUP) - elif pids: - err = 1 - print "Daemon already running: ", pids - return err - - def cleanup(self, kill=False): - # No cleanup to do if PID_FILE is empty. - if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE): - return 0 - # Read the pid of the previous invocation and search active process list. - pid = open(PID_FILE, 'r').read() - lines = _readlines(os.popen('ps ' + pid + ' 2>/dev/null')) - for line in lines: - if re.search('^ *' + pid + '.+xensv', line): - if not kill: - print "Daemon is already running (pid %d)" % int(pid) - return 1 - # Old daemon is still active: terminate it. - os.kill(int(pid), 1) - # Delete the stale PID_FILE. - os.remove(PID_FILE) - return 0 - - def start(self, trace=0): - if self.cleanup(kill=False): - return 1 - - # Fork -- parent writes PID_FILE and exits. - pid = os.fork() - if pid: - # Parent - pidfile = open(PID_FILE, 'w') - pidfile.write(str(pid)) - pidfile.close() - return 0 - # Child - self.run() - return 0 - - def stop(self): - return self.cleanup(kill=True) - - def run(self): - root = static.File( SV_ROOT ) - root.indexNames = [ 'Main.rpy' ] - root.processors = { '.rpy': script.ResourceScript } - reactor.listenTCP( SV_PORT, server.Site( root ) ) - reactor.run() - - def exit(self): - reactor.disconnectAll() - sys.exit(0) - -def instance(): - global inst - try: - inst - except: - inst = Daemon() - return inst diff --git a/tools/python/xen/sv/DomInfo.py b/tools/python/xen/sv/DomInfo.py index e0cabbd209..0f7a8ab486 100755 --- a/tools/python/xen/sv/DomInfo.py +++ b/tools/python/xen/sv/DomInfo.py @@ -4,6 +4,7 @@ from xen.xend import PrettyPrint from xen.sv.HTMLBase import HTMLBase from xen.sv.util import * from xen.sv.GenTabbed import * +from xen.sv.Wizard import * DEBUG=1 @@ -12,33 +13,69 @@ class DomInfo( GenTabbed ): def __init__( self, urlWriter ): self.dom = 0; - - def tabUrlWriter( tab ): - return urlWriter( "&dom=%s%s" % ( self.dom, tab ) ) - - GenTabbed.__init__( self, "Domain Info", tabUrlWriter, [ 'General', 'SXP', 'Devices' ], [ DomGeneralTab, DomSXPTab, NullTab ] ) + + GenTabbed.__init__( self, "Domain Info", urlWriter, [ 'General', 'SXP', 'Devices', 'Migrate', 'Save' ], [ DomGeneralTab, DomSXPTab, DomDeviceTab, DomMigrateTab, DomSaveTab ] ) def write_BODY( self, request ): - dom = request.args.get('dom') - - if dom is None or len(dom) != 1: + try: + dom = int( getVar( 'dom', request ) ) + except: request.write( "

Please Select a Domain

" ) return None - else: - self.dom = dom[0] - + GenTabbed.write_BODY( self, request ) def write_MENU( self, request ): - pass + domains = [] + try: + domains = server.xend_domains() + domains.sort() + except: + pass + + request.write( "\n\n" ) + request.write( "" ) + request.write( "\n" ) + request.write( "\n" ) + request.write( "\n" ) + request.write( "\n" ) + request.write( "" ) + + odd = True + if not domains is None: + for domain in domains: + odd = not odd; + if odd: + request.write( "\n" ) + else: + request.write( "\n" ) + domInfo = getDomInfo( domain ) + request.write( "\n" % domInfo ) + url = self.urlWriter( "&dom=%(id)s" % domInfo ) + request.write( "\n" % ( url, domInfo['name'] ) ) + request.write( "\n" % domInfo ) + if domInfo[ 'id' ] != "0": + request.write( "" % domInfo ) + else: + request.write( "" ) + request.write( "\n" ) + else: + request.write( "

Error getting domain list
Perhaps XenD not running?

") + request.write( "
DomainNameState
%(id)s%s%(state)5s" ) + if domInfo[ 'state' ][ 2 ] == "-": + request.write( "" % domInfo ) + else: + request.write( "" % domInfo ) + request.write( " 
" ) + class DomGeneralTab( CompositeTab ): - def __init__( self ): - CompositeTab.__init__( self, [ DomGenTab, DomActionTab ] ) - + def __init__( self, urlWriter ): + CompositeTab.__init__( self, [ DomGenTab, DomActionTab ], urlWriter ) + class DomGenTab( GeneralTab ): - def __init__( self ): + def __init__( self, urlWriter ): titles = {} @@ -60,13 +97,13 @@ class DomGenTab( GeneralTab ): request.write( "

Please Select a Domain

" ) return None - self.dict = getDomInfoHash( self.dom ) + self.dict = getDomInfo( self.dom ) GeneralTab.write_BODY( self, request ) class DomSXPTab( PreTab ): - def __init__( self ): + def __init__( self, urlWriter ): self.dom = 0 PreTab.__init__( self, "" ) @@ -86,15 +123,15 @@ class DomSXPTab( PreTab ): self.source = sxp2prettystring( domInfo ) PreTab.write_BODY( self, request ) - + class DomActionTab( ActionTab ): - def __init__( self ): - actions = { "shutdown" : "shutdown", - "reboot" : "reboot", - "pause" : "pause", - "unpause" : "unpause", - "destroy" : "destroy" } + def __init__( self, urlWriter ): + actions = { "shutdown" : "Shutdown", + "reboot" : "Reboot", + "pause" : "Pause", + "unpause" : "Unpause", + "destroy" : "Destroy" } ActionTab.__init__( self, actions ) def op_shutdown( self, request ): @@ -141,8 +178,91 @@ class DomActionTab( ActionTab ): server.xend_domain_destroy( int( dom ), "halt" ) except: pass - - - - +class DomDeviceTab( CompositeTab ): + + def __init__( self, urlWriter ): + CompositeTab.__init__( self, [ DomDeviceListTab, DomDeviceOptionsTab, DomDeviceActionTab ], urlWriter ) + +class DomDeviceListTab( NullTab ): + + title = "Device List" + + def __init__( self, urlWriter ): + pass + +class DomDeviceOptionsTab( NullTab ): + + title = "Device Options" + + def __init__( self, urlWriter ): + pass + +class DomDeviceActionTab( ActionTab ): + + def __init__( self, urlWriter ): + ActionTab.__init__( self, { "addvcpu" : "Add VCPU", "addvbd" : "Add VBD", "addvif" : "Add VIF" } ) + +class DomMigrateTab( CompositeTab ): + + def __init__( self, urlWriter ): + CompositeTab.__init__( self, [ DomMigrateExtraTab, DomMigrateActionTab ], urlWriter ) + +class DomMigrateExtraTab( Sheet ): + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Configure Migration", 0) + self.addControl( TickControl('live', 'True', 'Live migrate:') ) + self.addControl( InputControl('rate', '0', 'Rate limit:') ) + self.addControl( InputControl( 'dest', 'host.domain', 'Name or IP address:', ".*") ) + +class DomMigrateActionTab( ActionTab ): + + def __init__( self, urlWriter ): + actions = { "migrate" : "Migrate" } + ActionTab.__init__( self, actions ) + + def op_migrate( self, request ): + try: + domid = int( getVar( 'dom', request ) ) + live = getVar( 'live', request ) + rate = getVar( 'rate', request ) + dest = getVar( 'dest', request ) + dom_sxp = server.xend_domain_migrate( domid, dest, live == 'True', rate ) + success = "Your domain was successfully Migrated.\n" + except Exception, e: + success = "There was an error migrating your domain\n" + dom_sxp = str(e) + +class DomSaveTab( CompositeTab ): + + def __init__( self, urlWriter ): + CompositeTab.__init__( self, [ DomSaveExtraTab, DomSaveActionTab ], urlWriter ) + +class DomSaveExtraTab( Sheet ): + + title = "Save location" + + def __init__( self, urlWriter ): + Sheet.__init__( self, urlWriter, "Save Domain to file", 0 ) + self.addControl( InputControl( 'file', '', 'Suspend file name:', ".*") ) + +class DomSaveActionTab( ActionTab ): + + def __init__( self, urlWriter ): + actions = { "save" : "Save" } + ActionTab.__init__( self, actions ) + + def op_save( self, request ): + + try: + dom_sxp = server.xend_domain_save( config['domid'], config['file'] ) + success = "Your domain was successfully saved.\n" + except Exception, e: + success = "There was an error saving your domain\n" + dom_sxp = str(e) + + try: + dom = int( getVar( 'dom', request ) ) + except: + pass diff --git a/tools/python/xen/sv/DomList.py b/tools/python/xen/sv/DomList.py deleted file mode 100755 index c3951122d8..0000000000 --- a/tools/python/xen/sv/DomList.py +++ /dev/null @@ -1,81 +0,0 @@ -from xen.xend.XendClient import server -from xen.xend import sxp - -from xen.sv.HTMLBase import HTMLBase -from xen.sv.util import * - -class DomList( HTMLBase ): - - isLeaf = True - - def __init__( self, urlWriter ): - HTMLBase.__init__(self) - self.urlWriter = urlWriter - - def write_MENU( self, request ): - return self.write_BODY( request, head=True, long=False ) - - def write_BODY( self, request, head=True, long=True ): - - domains = [] - - try: - domains = server.xend_domains() - domains.sort() - except: - pass - - request.write( "\n\n" ) - - if head: - request.write( "" ) - self.write_DOMAIN_HEAD( request, long ) - request.write( "" ) - - odd = True - - if not domains is None: - for domain in domains: - if odd: - request.write( "\n" ) - odd = False - else: - request.write( "\n" ) - odd = True - self.write_DOMAIN( request, getDomInfoHash( domain ), long ) - request.write( "\n" ) - else: - request.write( "

Error getting domain list
Perhaps XenD not running?

") - - request.write( "
\n" ) - - def write_DOMAIN( self, request, domInfoHash, long=True ): - request.write( "%(id)s\n" % domInfoHash ) - - url = self.urlWriter( "&mod=info&dom=%(id)s" % domInfoHash ) - - request.write( "%s\n" % ( url, domInfoHash['name'] ) ) - if long: - request.write( "%(memory)5s\n" % domInfoHash ) - request.write( "%(cpu)2s\n" % domInfoHash ) - request.write( "%(state)5s\n" % domInfoHash ) - if domInfoHash[ 'id' ] != "0": - request.write( "" ) - - if domInfoHash[ 'state' ][ 2 ] == "-": - request.write( "" % domInfoHash ) - else: - request.write( "" % domInfoHash ) - - request.write( "" % domInfoHash) - else: - request.write( " " ) - - def write_DOMAIN_HEAD( self, request, long=True ): - request.write( "Domain\n" ) - request.write( "Name\n" ) - if long: - request.write( "Memory / Mb\n" ) - request.write( "CPU\n" ) - request.write( "State\n" ) - request.write( "\n" ) diff --git a/tools/python/xen/sv/GenTabbed.py b/tools/python/xen/sv/GenTabbed.py index ce8711ce55..6631663f15 100755 --- a/tools/python/xen/sv/GenTabbed.py +++ b/tools/python/xen/sv/GenTabbed.py @@ -1,7 +1,6 @@ import types from xen.sv.HTMLBase import HTMLBase -from xen.sv.TabView import TabView from xen.sv.util import getVar class GenTabbed( HTMLBase ): @@ -12,39 +11,44 @@ class GenTabbed( HTMLBase ): self.tabObjects = tabObjects self.urlWriter = urlWriter self.title = title - - def write_BODY( self, request, urlWriter = None ): - try: - tab = int( getVar( 'tab', request, 0 ) ) - except: - tab = 0 + + def write_BODY( self, request ): + if not self.__dict__.has_key( "tab" ): + try: + self.tab = int( getVar( 'tab', request, 0 ) ) + except: + self.tab = 0 - request.write( "" ) - request.write( "
" ) - request.write( "

%s

" % self.title ) + request.write( "\n
%s
" % self.title ) - TabView( tab, self.tabStrings, self.urlWriter ).write_BODY( request ) + TabView( self.tab, self.tabStrings, self.urlWriter ).write_BODY( request ) - request.write( "
" ) - try: - render_tab = self.tabObjects[ tab ] - render_tab().write_BODY( request ) - except: - request.write( "

Error Rendering Tab

" ) - - request.write( "
" ) - + request.write( "\n
" ) + render_tab = self.tabObjects[ self.tab ] + render_tab( self.urlWriter ).write_BODY( request ) + request.write( "\n
" ) + except Exception, e: + request.write( "\n

Error Rendering Tab

" ) + request.write( "\n

%s

" % str( e ) ) + + request.write( "\n" % self.tab ) + def perform( self, request ): + request.write( "Tab> perform" ) + request.write( "
op: " + str( getVar( 'op', request ) ) ) + request.write( "
args: " + str( getVar( 'args', request ) ) ) + request.write( "
tab: " + str( getVar( 'tab', request ) ) ) + try: - tab = int( getVar( 'tab', request, 0 ) ) + action = getVar( 'op', request, 0 ) + if action == "tab": + self.tab = int( getVar( 'args', request ) ) + else: + this.tab = int( getVar( 'tab', request, 0 ) ) + self.tabObjects[ self.tab ]( self.urlWriter ).perform( request ) except: - tab = 0; - - op_tab = self.tabObjects[ tab ] - - if op_tab: - op_tab().perform( request ) + pass class PreTab( HTMLBase ): @@ -53,12 +57,9 @@ class PreTab( HTMLBase ): self.source = source def write_BODY( self, request ): - - request.write( "
" )
-        
+        request.write( "\n
" )
         request.write( self.source )
-        
-        request.write( "
" ) + request.write( "\n" ) class GeneralTab( HTMLBase ): @@ -69,7 +70,7 @@ class GeneralTab( HTMLBase ): def write_BODY( self, request ): - request.write( "" ) + request.write( "\n
" ) def writeAttr( niceName, attr, formatter=None ): if type( attr ) is types.TupleType: @@ -80,7 +81,7 @@ class GeneralTab( HTMLBase ): temp = formatter( self.dict[ attr ] ) else: temp = str( self.dict[ attr ] ) - request.write( "" % ( niceName, temp ) ) + request.write( "\n" % ( niceName, temp ) ) for niceName, attr in self.titles.items(): writeAttr( niceName, attr ) @@ -89,16 +90,12 @@ class GeneralTab( HTMLBase ): class NullTab( HTMLBase ): - def __init__( self ): - HTMLBase.__init__( self ) - self.title = "Null Tab" - - def __init__( self, title ): + def __init__( self, title="Null Tab" ): HTMLBase.__init__( self ) self.title = title - + def write_BODY( self, request ): - request.write( "

%s

" % self.title ) + request.write( "\n

%s

" % self.title ) class ActionTab( HTMLBase ): @@ -107,29 +104,44 @@ class ActionTab( HTMLBase ): HTMLBase.__init__( self ) def write_BODY( self, request ): - request.write( "

%s:

%s

%s:

%s

" ) - - for ( command, text ) in self.actions.items(): - request.write( "" % (command, text) ) - - request.write("
" ) - request.write( "

%s

") - + for item in self.actions.items(): + try: + ((op, attr), title) = item + except: + (op, title) = item + attr = "" + request.write( "\n
%s
" % (op, attr, title) ) + class CompositeTab( HTMLBase ): - def __init__( self, tabs ): + def __init__( self, tabs, urlWriter ): HTMLBase.__init__( self ) self.tabs = tabs + self.urlWriter = urlWriter def write_BODY( self, request ): for tab in self.tabs: - request.write( "
" ) - tab().write_BODY( request ) + tab( self.urlWriter ).write_BODY( request ) def perform( self, request ): for tab in self.tabs: - tab().perform( request ) - - - - + tab( self.urlWriter ).perform( request ) + +class TabView( HTMLBase ): + + # tab - int, id into tabs of selected tab + # tabs - list of strings, tab names + # urlWriter - + def __init__( self, tab, tabs, urlWriter ): + HTMLBase.__init__(self) + self.tab = tab + self.tabs = tabs + self.urlWriter = urlWriter + + def write_BODY( self, request ): + for i in range( len( self.tabs ) ): + if self.tab == i: + at = " id='activeTab'" + else: + at = "" + request.write( "\n%s" % ( at, i, self.tabs[ i ] ) ) diff --git a/tools/python/xen/sv/HTMLBase.py b/tools/python/xen/sv/HTMLBase.py index 121463e845..d0fca13a98 100755 --- a/tools/python/xen/sv/HTMLBase.py +++ b/tools/python/xen/sv/HTMLBase.py @@ -12,26 +12,17 @@ class HTMLBase: return self.render_GET( request ) def render_GET( self, request ): - self.write_TOP( request ) - self.write_BODY( request ) - self.write_BOTTOM( request ) - return '' - + pass + def write_BODY( self, request ): - request.write( "BODY" ) + pass def write_TOP( self, request ): - request.write( 'Xen' ) - request.write( '' ) - request.write( '' ) - request.write('
' % request.uri) - + pass + def write_BOTTOM( self, request ): - request.write('') - request.write('') - request.write('
') - request.write( "" ) - + pass + def get_op_method(self, op): """Get the method for an operation. For operation 'foo' looks for 'op_foo'. diff --git a/tools/python/xen/sv/Main.py b/tools/python/xen/sv/Main.py index 196e1c1450..b6772c2509 100755 --- a/tools/python/xen/sv/Main.py +++ b/tools/python/xen/sv/Main.py @@ -1,113 +1,90 @@ + from xen.sv.HTMLBase import HTMLBase -from xen.sv.DomList import DomList from xen.sv.NodeInfo import NodeInfo from xen.sv.DomInfo import DomInfo from xen.sv.CreateDomain import CreateDomain -from xen.sv.MigrateDomain import MigrateDomain -from xen.sv.SaveDomain import SaveDomain from xen.sv.RestoreDomain import RestoreDomain -from xen.xend.XendClient import server - from xen.sv.util import getVar -class Main( HTMLBase ): - - isLeaf = True +# adapter to make this all work with mod_python +# as opposed to Twisted +# (c) Tom Wilkie 2005 - def __init__( self, urlWriter = None ): - self.modules = { "node": NodeInfo, - "list": DomList, - "info": DomInfo, - "create": CreateDomain, - "migrate" : MigrateDomain, - "save" : SaveDomain, - "restore" : RestoreDomain } +class Args: + def __init__( self, req ): + from mod_python.util import FieldStorage + self.fieldStorage = FieldStorage( req, True ) - # ordered list of module menus to display - self.module_menus = [ "node", "create", "migrate", "save", - "restore", "list" ] - HTMLBase.__init__(self) - - def render_POST( self, request ): - - #decide what module post'd the action - - args = getVar( 'args', request ) - - mod = getVar( 'mod', request ) - - if not mod is None and args is None: - module = self.modules[ mod ] - #check module exists - if module: - module( self.mainUrlWriter ).perform( request ) + # return a list of values for the given key, + # or None if key not there + def get( self, var ): + retVar = self.fieldStorage.getlist( var ) + if len( retVar ) == 0: + return None else: - self.perform( request ) - - return self.render_GET( request ) + return retVar - def mainUrlWriter( self, module ): - def fun( f ): - return "Main.rpy?mod=%s%s" % ( module, f ) - return fun - - def write_BODY( self, request ): - - request.write( "\n\n" ) - request.write( "\n" ) - request.write( " " ) - request.write( " \n" ) - request.write( " " ) - request.write( " \n" ) - request.write( " " ) - request.write( "\n" ) + module = self.modules[ moduleName ] + module.write_BODY( request ) + + def do_POST( self, request ): + if not self.init_done: + self.init_modules( request ) + self.init_done = True - request.write( "
 " ) - request.write( " " ) - request.write( " " ) - request.write( " ") - request.write( " " ) - request.write( "
" ) - request.write( "

SV Web Interface
(C) Tom Wilkie 2004

" ) + # return a list of tuples, + # (key, value) where value is a list of values + def items( self ): + result = []; + for key in self.fieldStorage.keys(): + result.append( (key, self.fieldStorage.getlist( key ) ) ) + return result + +class TwistedAdapter: + def __init__( self, req ): + self.args = Args( req ) + self.uri = req.unparsed_uri + self.url = req.uri + self.write = req.write - for modName in self.module_menus: - self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request ) - - request.write( "
" ) - request.write( "  " ) - request.write( "
 " ) - request.write( " " ) - request.write( " " ) - request.write( " " ) - request.write( "
" ) - - modName = getVar('mod', request) - - if modName is None: +# This is the Main class +# It peices together all the modules + +class Main: + def __init__( self ): + self.modules = { "node": NodeInfo, + "create": CreateDomain, + "restore" : RestoreDomain, + "info": DomInfo } + + self.init_done = False + + def init_modules( self, request ): + for moduleName, module in self.modules.iteritems(): + self.modules[ moduleName ] = module( self.urlWriter( moduleName, request.url ) ) + + def render_menu( self, request ): + if not self.init_done: + self.init_modules( request ) + self.init_done = True + + for moduleName, module in self.modules.iteritems(): + module.write_MENU( request ) + request.write( "\n" ) + + def render_main( self, request ): + if not self.init_done: + self.init_modules( request ) + self.init_done = True + + moduleName = getVar('mod', request) + if moduleName not in self.modules: request.write( '

Please select a module

' ) else: - module = self.modules[ modName ] - if module: - module( self.mainUrlWriter( modName ) ).write_BODY( request ) - else: - request.write( '

Invalid module. Please select another

' ) - - request.write( "
" ) - request.write( "
 
\n" ) - - - def op_destroy( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != "0": - server.xend_domain_destroy( int( dom ), "halt" ) - - def op_pause( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != "0": - server.xend_domain_pause( int( dom ) ) - - def op_unpause( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != "0": - server.xend_domain_unpause( int( dom ) ) + moduleName = getVar( 'mod', request ) + if moduleName in self.modules: + self.modules[ moduleName ].perform( request ) + + def urlWriter( self, module, url ): + return lambda x: "%s?mod=%s%s" % ( url, module, x ) diff --git a/tools/python/xen/sv/MigrateDomain.py b/tools/python/xen/sv/MigrateDomain.py deleted file mode 100755 index eb7dacbdfc..0000000000 --- a/tools/python/xen/sv/MigrateDomain.py +++ /dev/null @@ -1,74 +0,0 @@ -from xen.sv.Wizard import * -from xen.sv.util import * -from xen.sv.GenTabbed import PreTab - -from xen.xm.create import make_config, OptVals - -from xen.xend.XendClient import server - -class MigrateDomain( Wizard ): - def __init__( self, urlWriter ): - - sheets = [ ChooseMigrateDomain, - DoMigrate ] - - Wizard.__init__( self, urlWriter, "Migrate Domain", sheets ) - - -class ChooseMigrateDomain( Sheet ): - def __init__( self, urlWriter ): - Sheet.__init__( self, urlWriter, "Configure Migration", 0) - domains = [] - domnames = [] - - try: - domains = server.xend_domains() - domains.sort() - except: - pass - - for i in domains: - if i != 'Domain-0': domnames.append((i,i)) - - self.addControl( ListControl('domid', - domnames, - 'Domain ID:') ) - self.addControl( TickControl('live', - 'True', - 'Live migrate:') ) - self.addControl( InputControl('rate', - '0', - 'Rate limit:') ) - self.addControl( InputControl( 'dest', 'myhost.mydomain', - 'Name or IP address:', - ".*") ) - -class DoMigrate( Sheet ): - def __init__(self, urlWriter ): - Sheet.__init__(self, urlWriter, "Migration Done", 1) - - def write_BODY( self, request, err ): - - if not self.passback: self.parseForm( request ) - -# print string2sxp(self.passback) - - config = ssxp2hash ( string2sxp( self.passback ) ) - - try: - print config - print config['domid'], config['dest'] - dom_sxp = server.xend_domain_migrate( config['domid'], - config['dest'], - config.get('live') == 'True', - config['rate'] ) - success = "Your domain was successfully Migrated.\n" - except Exception, e: - success = "There was an error migrating your domain\n" - dom_sxp = str(e) - - pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) ) - pt.write_BODY( request ) - - request.write( "

" % self.passback ) - request.write( "

" % self.location ) diff --git a/tools/python/xen/sv/NodeInfo.py b/tools/python/xen/sv/NodeInfo.py index a19ca7383c..f8b47b1d4f 100755 --- a/tools/python/xen/sv/NodeInfo.py +++ b/tools/python/xen/sv/NodeInfo.py @@ -6,18 +6,18 @@ from xen.sv.GenTabbed import * class NodeInfo( GenTabbed ): def __init__( self, urlWriter ): - GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', ], [ NodeGeneralTab, NodeDmesgTab ] ) + GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', 'SXP' ], [ NodeGeneralTab, NodeDmesgTab, NodeSXPTab ] ) def write_MENU( self, request ): request.write( "

Node details

" % self.urlWriter( '' ) ) class NodeGeneralTab( CompositeTab ): - def __init__( self ): - CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ] ) + def __init__( self, urlWriter ): + CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ], urlWriter ) class NodeInfoTab( GeneralTab ): - def __init__( self ): + def __init__( self, urlWriter ): nodeInfo = {} try: @@ -41,7 +41,7 @@ class NodeInfoTab( GeneralTab ): class NodeDmesgTab( PreTab ): - def __init__( self ): + def __init__( self, urlWriter ): try: dmesg = server.xend_node_get_dmesg() except: @@ -50,7 +50,7 @@ class NodeDmesgTab( PreTab ): class NodeActionTab( ActionTab ): - def __init__( self ): + def __init__( self, urlWriter ): ActionTab.__init__( self, { "shutdown" : "shutdown", "reboot" : "reboot" } ) @@ -61,3 +61,13 @@ class NodeActionTab( ActionTab ): def op_reboot( self, request ): if debug: print ">NodeReboot" server.xend_node_reboot() + +class NodeSXPTab( PreTab ): + + def __init__( self, urlWriter ): + try: + nodeSXP = sxp2string( server.xend_node() ) + except: + nodeSXP = 'Error getting node sxp' + + PreTab.__init__( self, nodeSXP ) diff --git a/tools/python/xen/sv/RestoreDomain.py b/tools/python/xen/sv/RestoreDomain.py index be8b4f558a..b836a43579 100755 --- a/tools/python/xen/sv/RestoreDomain.py +++ b/tools/python/xen/sv/RestoreDomain.py @@ -16,6 +16,8 @@ class RestoreDomain( Wizard ): class ChooseRestoreDomain( Sheet ): + title = "Configure Restore" + def __init__( self, urlWriter ): Sheet.__init__( self, urlWriter, "Configure Restore", 0) @@ -24,6 +26,8 @@ class ChooseRestoreDomain( Sheet ): ".*") ) class DoRestore( Sheet ): + title = "Restore Done" + def __init__(self, urlWriter ): Sheet.__init__(self, urlWriter, "Restore Done", 1) diff --git a/tools/python/xen/sv/SaveDomain.py b/tools/python/xen/sv/SaveDomain.py deleted file mode 100755 index 18c9b0150b..0000000000 --- a/tools/python/xen/sv/SaveDomain.py +++ /dev/null @@ -1,62 +0,0 @@ -from xen.sv.Wizard import * -from xen.sv.util import * -from xen.sv.GenTabbed import PreTab - -from xen.xm.create import make_config, OptVals - -from xen.xend.XendClient import server - -class SaveDomain( Wizard ): - def __init__( self, urlWriter ): - - sheets = [ ChooseSaveDomain, - DoSave ] - - Wizard.__init__( self, urlWriter, "Save Domain", sheets ) - - -class ChooseSaveDomain( Sheet ): - def __init__( self, urlWriter ): - Sheet.__init__( self, urlWriter, "Configure Save", 0) - - domains = [] - domnames = [] - - try: - domains = server.xend_domains() - domains.sort() - except: - pass - - for i in domains: - if i != 'Domain-0': domnames.append((i,i)) - - self.addControl( ListControl('domid', - domnames, - 'Domain ID:') ) - self.addControl( InputControl( 'file', '', - 'Suspend file name:', - ".*") ) - -class DoSave( Sheet ): - def __init__(self, urlWriter ): - Sheet.__init__(self, urlWriter, "Save Done", 1) - - def write_BODY( self, request, err ): - - if not self.passback: self.parseForm( request ) - config = ssxp2hash ( string2sxp( self.passback ) ) - - try: - dom_sxp = server.xend_domain_save( config['domid'], - config['file'] ) - success = "Your domain was successfully saved.\n" - except Exception, e: - success = "There was an error saving your domain\n" - dom_sxp = str(e) - - pt = PreTab( success + dom_sxp ) # sxp2prettystring( dom_sxp ) ) - pt.write_BODY( request ) - - request.write( "

" % self.passback ) - request.write( "

" % self.location ) diff --git a/tools/python/xen/sv/TabView.py b/tools/python/xen/sv/TabView.py deleted file mode 100755 index 41944715c2..0000000000 --- a/tools/python/xen/sv/TabView.py +++ /dev/null @@ -1,26 +0,0 @@ -from xen.sv.HTMLBase import HTMLBase - -class TabView( HTMLBase ): - - # tab - int, id into tabs of selected tab - # tabs - list of strings, tab names - # urlWriter - - def __init__( self, tab, tabs, urlWriter ): - HTMLBase.__init__(self) - self.tab = tab - self.tabs = tabs - self.urlWriter = urlWriter - - def write_BODY( self, request ): - request.write( "" ) - request.write( "" ) - - for i in range( len( self.tabs ) ): - if self.tab == i: - backgroundColor = "white" - else: - backgroundColor = "grey" - - request.write( "" % ( backgroundColor, self.urlWriter( "&tab=%s" % i ), self.tabs[ i ] ) ) - - request.write( "

%s

" ) diff --git a/tools/python/xen/sv/Wizard.py b/tools/python/xen/sv/Wizard.py index 089d3f2e67..51770e5f6e 100755 --- a/tools/python/xen/sv/Wizard.py +++ b/tools/python/xen/sv/Wizard.py @@ -1,71 +1,44 @@ from xen.sv.util import * from xen.sv.HTMLBase import HTMLBase +from xen.sv.GenTabbed import GenTabbed, ActionTab from xen.xend import sxp import re DEBUG = 0 -class Wizard( HTMLBase ): +class Wizard( GenTabbed ): def __init__( self, urlWriter, title, sheets ): - HTMLBase.__init__( self ) self.title = title self.sheets = sheets self.urlWriter = urlWriter + self.offset = 0 + GenTabbed.__init__( self, title, urlWriter, map( lambda x: x.title, sheets ), sheets ) def write_MENU( self, request ): request.write( "

%s

" % (self.urlWriter( '' ), self.title) ) def write_BODY( self, request ): - - request.write( "
" ) - request.write( "

%s

" % self.title ) - - currSheet = getVar( 'sheet', request ) - - if not currSheet is None: - currSheet = int( currSheet ) - else: - currSheet = 0 - - sheet = self.sheets[ currSheet ]( self.urlWriter ) - - err = not sheet.validate( request ) - - if not err: - op = getVar( 'op', request ) - - if op == 'next': - currSheet += 1 - elif op == 'prev': - currSheet -= 1 - - sheet = self.sheets[ currSheet ]( self.urlWriter ) - - if getVar( 'visited-sheet%s' % currSheet, request ): - sheet.write_BODY( request, err ) - else: - sheet.write_BODY( request, False ) + GenTabbed.write_BODY( self, request ) + actionTab = ActionTab( { ("tab", str(self.tab-1)) : "< Prev", ("tab", str(self.tab+1)) : "Next >", "finish" : "Finish" } ) + actionTab.write_BODY( request ) - - request.write( "
" ) - request.write( "

" ) - if currSheet > 0: - request.write( " " ) - if currSheet < ( len( self.sheets ) - 2 ): - request.write( "" ) - elif currSheet == ( len( self.sheets ) - 2 ): - request.write( "" ) - request.write( "

" ) - request.write( "
" ) - - def op_next( self, request ): - pass - - def op_prev( self, request ): - pass - + def perform( self, request ): + try: + action = getVar( 'op', request, 0 ) + if action == "tab": + self.tab = int( getVar( 'args', request ) ) + oldtab = int( getVar( 'tab', request ) ) + if not self.tabObjects[ oldtab ]( self.urlWriter ).validate( request ): + self.tab = oldtab + else: + self.tab = int( getVar( 'tab', request, 0 ) ) + self.tabObjects[ self.tab ]( self.urlWriter ).perform( request ) + getattr( self, "op_" + getVar( "op", request ), None )( request ) + except: + pass + def op_finish( self, request ): pass @@ -80,7 +53,7 @@ class Sheet( HTMLBase ): self.passback = None def parseForm( self, request ): - do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ] + do_not_parse = [ 'mod', 'op', 'passback' ] passed_back = request.args @@ -103,7 +76,7 @@ class Sheet( HTMLBase ): if DEBUG: print self.passback - def write_BODY( self, request, err ): + def write_BODY( self, request ): if not self.passback: self.parseForm( request ) @@ -115,14 +88,13 @@ class Sheet( HTMLBase ): for (feild, control) in self.feilds: control.write_Control( request, previous_values.get( feild ) ) - if err and not control.validate( previous_values.get( feild ) ): + if previous_values.get( feild ) is not None and not control.validate( previous_values.get( feild ) ): control.write_Help( request ) request.write( "" ) request.write( "

" % self.passback ) - request.write( "

" % self.location ) - request.write( "

" % self.location ) + #request.write( "

" % self.location ) def addControl( self, control ): self.feilds.append( [ control.getName(), control ] ) @@ -133,7 +105,7 @@ class Sheet( HTMLBase ): check = True - previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference + previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the map for quick reference if DEBUG: print previous_values for (feild, control) in self.feilds: @@ -258,12 +230,16 @@ class TickControl( SheetControl ): def write_Control( self, request, persistedValue ): request.write( "

%s

" % self.humanText ) + + #request.write( str( persistedValue ) ) + + #TODO: Theres a problem with this: it doesn't persist an untick, because the browsers don't pass it back. Need a fix... if persistedValue == 'True': request.write( "" % self.getName() ) else: request.write( "" % self.getName() ) - request.write( "" ) + request.write( "" ) diff --git a/tools/python/xen/sv/params.py b/tools/python/xen/sv/params.py deleted file mode 100755 index beed647a4f..0000000000 --- a/tools/python/xen/sv/params.py +++ /dev/null @@ -1,3 +0,0 @@ -SV_PORT = 8080 -SV_ROOT = "/var/lib/xen/sv/" -PID_FILE = "/var/run/xen-sv.pid" diff --git a/tools/python/xen/sv/util.py b/tools/python/xen/sv/util.py index 7c9ebeda80..cfed3976df 100755 --- a/tools/python/xen/sv/util.py +++ b/tools/python/xen/sv/util.py @@ -4,7 +4,7 @@ from xen.xend import PrettyPrint import types -def getDomInfoHash( domain ): +def getDomInfo( domain ): domInfoHash = {} try: domInfoHash = sxp2hash( server.xend_domain( domain ) ) diff --git a/tools/sv/images/internet.jpg b/tools/sv/images/internet.jpg deleted file mode 100755 index 74a03c3a78..0000000000 Binary files a/tools/sv/images/internet.jpg and /dev/null differ diff --git a/tools/sv/images/internet.psd b/tools/sv/images/internet.psd deleted file mode 100755 index a2e9d1754f..0000000000 Binary files a/tools/sv/images/internet.psd and /dev/null differ diff --git a/tools/sv/images/orb_01.jpg b/tools/sv/images/orb_01.jpg deleted file mode 100755 index e30efc4985..0000000000 Binary files a/tools/sv/images/orb_01.jpg and /dev/null differ diff --git a/tools/sv/images/orb_02.jpg b/tools/sv/images/orb_02.jpg deleted file mode 100755 index e5ebc8e4b1..0000000000 Binary files a/tools/sv/images/orb_02.jpg and /dev/null differ diff --git a/tools/sv/images/seperator-left-highlight.jpg b/tools/sv/images/seperator-left-highlight.jpg deleted file mode 100755 index c90f4ffd12..0000000000 Binary files a/tools/sv/images/seperator-left-highlight.jpg and /dev/null differ diff --git a/tools/sv/images/seperator-right-highlight.jpg b/tools/sv/images/seperator-right-highlight.jpg deleted file mode 100755 index f37e6cd546..0000000000 Binary files a/tools/sv/images/seperator-right-highlight.jpg and /dev/null differ diff --git a/tools/sv/images/seperator.jpg b/tools/sv/images/seperator.jpg deleted file mode 100755 index c77e2c5500..0000000000 Binary files a/tools/sv/images/seperator.jpg and /dev/null differ diff --git a/tools/sv/inc/style.css b/tools/sv/inc/style.css index 263ab59b23..1606b21bc5 100755 --- a/tools/sv/inc/style.css +++ b/tools/sv/inc/style.css @@ -1,32 +1,95 @@ +.small { + font-size: 10px +} -P {font-family: verdana, arial; font-size: 12px; color: black} -.small {font-size: 10px} +TD.domainInfo { + font-size: 10px; + color: black +} -TD.domainInfo {font-family: verdana, arial; font-size: 10px; color: black} -TD.domainInfoHead {font-family: verdana, arial; font-size: 10px; color: white; font-face: bold} +TD.domainInfoHead { + font-size: 10px; + color: white; + font-face: bold +} TD.domainInfoHead {background-color: black} TR.domainInfoOdd {background-color: white} TR.domainInfoEven {background-color: lightgrey} body { - width: 670px; - margin: 0px; - padding: 0px; - background-color: #fff; - background-image: url(../images/orb_02.jpg); - background-repeat: repeat-y; - background-position: left top; - font-family: Arial, Helvetica, sans-serif; - font-weight: bold; - color: #333333; - letter-spacing: 0px; - scrollbar-base-color: #333333; - scrollbar-track-color: #666666; - scrollbar-face-color: #fff; - - - } - -.button (cursor:hand) - + margin: 0px; + padding: 0px; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #000000; +} + +div#menu { + position: absolute; + left: 10px; + top: 10px; + width: 160px; + padding: 10px; + border: 0px solid black; + text-align: center; +} + +div#main { + position: absolute; + left: 200px; + top: 10px; + right: 10px; + padding: 10px; + border: 0px solid black; +} + +div.button { + float: right; + margin: 10px 0px 0px 10px; + padding: 5px; + text-align: center; + border: 1px solid black; + background: gray; + cursor: hand; +} + +div.tabButton { + position: relative; + top: 0px; + float: left; + margin: 0px 10px -1px 0px; + padding: 5px; + text-align: center; + border: 1px solid black; + background: gray; + cursor: hand; +} + +div.tabButton#activeTab { + top: 0px; + background: white; + border-color: black black white black; +} + +div.button:hover, div.tabButton:hover { + background: white; +} + +div.button a, div.tabButton a { + font-size: 12px; + font-weight: bold; +} + +div.title { + float: right; + font-size: 14px; + font-weight: bold; +} + +div.tab { + overflow: auto; + clear: both; + border: 1px solid black; + padding: 10px; +} diff --git a/tools/sv/index.psp b/tools/sv/index.psp index 601d39a5bc..192aff84fa 100755 --- a/tools/sv/index.psp +++ b/tools/sv/index.psp @@ -7,158 +7,29 @@ debug = True and False for path in sys.path: if debug: req.write( path + "
" ) -from xen.sv.HTMLBase import HTMLBase -from xen.sv.DomList import DomList -from xen.sv.NodeInfo import NodeInfo -from xen.sv.DomInfo import DomInfo -from xen.sv.CreateDomain import CreateDomain -from xen.sv.MigrateDomain import MigrateDomain -from xen.sv.SaveDomain import SaveDomain -from xen.sv.RestoreDomain import RestoreDomain - -from xen.xend.XendClient import server - -from xen.sv.util import getVar - -# adapter to make this all work with mod_python -# (c) Tom Wilkie 2005 - -class TwistedAdapter: - - def write( self, text ): - req.write( text ) - - class Args: - - from mod_python.util import FieldStorage - - fieldStorage = FieldStorage( req, True ) - - # return a list of values for the given key, - # or None if key not there - def get( self, var ): - retVar = self.fieldStorage.getlist( var ) - if len( retVar ) == 0: - return None - else: - return retVar - - # return a list of tuples, - # (key, value) where value is a list of values - def items( self ): - result = []; - for key in self.fieldStorage.keys(): - result.append( (key, self.fieldStorage.getlist( key ) ) ) - return result - - args = Args() - - uri = req.unparsed_uri - - -class Main( HTMLBase ): - - isLeaf = True - - def __init__( self, urlWriter = None ): - self.modules = { "node": NodeInfo, - "list": DomList, - "info": DomInfo, - "create": CreateDomain, - "migrate" : MigrateDomain, - "save" : SaveDomain, - "restore" : RestoreDomain } - - # ordered list of module menus to display - self.module_menus = [ "node", "create", "migrate", "save", - "restore", "list" ] - HTMLBase.__init__(self) - - def render_POST( self, request ): - - #decide what module post'd the action - - args = getVar( 'args', request ) - - mod = getVar( 'mod', request ) - - if mod in self.modules and args is None: - module = self.modules[ mod ] - #check module exists - if module: - module( self.mainUrlWriter ).perform( request ) - else: - self.perform( request ) - - return self.render_GET( request ) - - #TODO: need to make this get the request uri automatically - def mainUrlWriter( self, module ): - def fun( f ): - return "index.psp?mod=%s%s" % ( module, f ) - return fun - - def write_BODY( self, request ): - - request.write( "\n\n" ) - request.write( "\n" ) - request.write( " " ) - request.write( " \n" ) - request.write( " " ) - request.write( " \n" ) - request.write( " " ) - request.write( "\n" ) - - request.write( "
 " ) - request.write( " " ) - request.write( " " ) - request.write( " ") - request.write( " " ) - request.write( "
" ) - request.write( "

SV Web Interface
(C) Tom Wilkie 2004

" ) - - for modName in self.module_menus: - self.modules[modName]( self.mainUrlWriter( modName ) ).write_MENU( request ) - - request.write( "
" ) - request.write( "  " ) - request.write( "
 " ) - request.write( " " ) - request.write( " " ) - request.write( " " ) - request.write( "
" ) - - modName = getVar('mod', request) - - if modName not in self.modules: - request.write( '

Please select a module

' ) - else: - module = self.modules[ modName ] - if module: - module( self.mainUrlWriter( modName ) ).write_BODY( request ) - else: - request.write( '

Invalid module. Please select another

' ) - - request.write( "
" ) - request.write( "
 
\n" ) - - - def op_destroy( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != "0": - server.xend_domain_destroy( int( dom ), "halt" ) - - def op_pause( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != "0": - server.xend_domain_pause( int( dom ) ) - - def op_unpause( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != "0": - server.xend_domain_unpause( int( dom ) ) +from xen.sv.Main import Main, TwistedAdapter main = Main() - -main.render_POST( TwistedAdapter() ) +request = TwistedAdapter( req ) +main.do_POST( request ) %> + + + XenSV + + + + +
+ +
+ <% main.render_main( request ) %> +
+ + +
+ +