From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Campbell Subject: [PATCH 9/9] tools: drop 'sv' Date: Wed, 31 Jul 2013 16:15:57 +0100 Message-ID: <1375283757-19465-9-git-send-email-ian.campbell@citrix.com> References: <1375283736.7382.100.camel@kazak.uk.xensource.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1375283736.7382.100.camel@kazak.uk.xensource.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: keir@xen.org, ian.jackson@eu.citrix.com, Ian Campbell List-Id: xen-devel@lists.xenproject.org I'm not even sure what this thing is. Looks like some sort of Twisted Python based frontend to xend. Whatever it is I am perfectly sure no one can be using it. Apart from drive by build fixes caused by updates elsewhere it has seen no real development since 2005. I suspect it was never even finished/usable. Signed-off-by: Ian Campbell --- tools/python/setup.py | 1 - tools/python/xen/sv/CreateDomain.py | 205 -------------------------- tools/python/xen/sv/DomInfo.py | 268 ---------------------------------- tools/python/xen/sv/GenTabbed.py | 147 ------------------- tools/python/xen/sv/HTMLBase.py | 53 ------- tools/python/xen/sv/Main.py | 82 ----------- tools/python/xen/sv/NodeInfo.py | 73 --------- tools/python/xen/sv/RestoreDomain.py | 50 ------- tools/python/xen/sv/Wizard.py | 245 ------------------------------- tools/python/xen/sv/__init__.py | 1 - tools/python/xen/sv/util.py | 126 ---------------- tools/sv/Makefile | 3 - tools/sv/images/destroy.png | Bin 2408 -> 0 bytes tools/sv/images/finish.png | Bin 1189 -> 0 bytes tools/sv/images/next.png | Bin 1270 -> 0 bytes tools/sv/images/pause.png | Bin 1662 -> 0 bytes tools/sv/images/previous.png | Bin 1285 -> 0 bytes tools/sv/images/reboot.png | Bin 3132 -> 0 bytes tools/sv/images/shutdown.png | Bin 2901 -> 0 bytes tools/sv/images/small-destroy.png | Bin 483 -> 0 bytes tools/sv/images/small-pause.png | Bin 434 -> 0 bytes tools/sv/images/small-unpause.png | Bin 500 -> 0 bytes tools/sv/images/unpause.png | Bin 1890 -> 0 bytes tools/sv/images/xen.png | Bin 10575 -> 0 bytes tools/sv/inc/script.js | 31 ---- tools/sv/inc/style.css | 95 ------------ tools/sv/index.psp | 34 ----- 27 files changed, 0 insertions(+), 1414 deletions(-) delete mode 100755 tools/python/xen/sv/CreateDomain.py delete mode 100755 tools/python/xen/sv/DomInfo.py delete mode 100755 tools/python/xen/sv/GenTabbed.py delete mode 100755 tools/python/xen/sv/HTMLBase.py delete mode 100755 tools/python/xen/sv/Main.py delete mode 100755 tools/python/xen/sv/NodeInfo.py delete mode 100755 tools/python/xen/sv/RestoreDomain.py delete mode 100755 tools/python/xen/sv/Wizard.py delete mode 100755 tools/python/xen/sv/__init__.py delete mode 100755 tools/python/xen/sv/util.py delete mode 100644 tools/sv/Makefile delete mode 100755 tools/sv/images/destroy.png delete mode 100755 tools/sv/images/finish.png delete mode 100755 tools/sv/images/next.png delete mode 100755 tools/sv/images/pause.png delete mode 100755 tools/sv/images/previous.png delete mode 100755 tools/sv/images/reboot.png delete mode 100755 tools/sv/images/shutdown.png delete mode 100755 tools/sv/images/small-destroy.png delete mode 100755 tools/sv/images/small-pause.png delete mode 100755 tools/sv/images/small-unpause.png delete mode 100755 tools/sv/images/unpause.png delete mode 100755 tools/sv/images/xen.png delete mode 100755 tools/sv/inc/script.js delete mode 100755 tools/sv/inc/style.css delete mode 100755 tools/sv/index.psp diff --git a/tools/python/setup.py b/tools/python/setup.py index 8e584e6..8127b21 100644 --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -132,7 +132,6 @@ setup(name = 'xen', description = 'Xen', packages = ['xen', 'xen.lowlevel', - 'xen.sv', ] + xend_packages, ext_package = "xen.lowlevel", ext_modules = modules diff --git a/tools/python/xen/sv/CreateDomain.py b/tools/python/xen/sv/CreateDomain.py deleted file mode 100755 index 748d99b..0000000 --- a/tools/python/xen/sv/CreateDomain.py +++ /dev/null @@ -1,205 +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 CreateDomain( Wizard ): - def __init__( self, urlWriter ): - - sheets = [ CreatePage0, - CreatePage1, - CreatePage2, - CreatePage3, - CreatePage4, - 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 ) - 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 ): - if not self.passback: self.parseForm( request ) - - previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference - - num_vbds = previous_values.get( 'num_vbds' ) - - for i in range( int( num_vbds ) ): - self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i ) ) - self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) ) - self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) ) - - self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) ) - - Sheet.write_BODY( self, request ) - -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:' ) ) - self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) ) - self.addControl( InputControl( 'ip_addr', '192.168.1.1', 'VM IP Address:' ) ) - self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) ) - self.addControl( InputControl( 'ip_gateway', '192.168.1.1', 'VM Gateway:' ) ) - self.addControl( InputControl( 'ip_nfs', '192.168.1.1', 'NFS Server:' ) ) - -class CreateFinish( Sheet ): - - title = "Finish" - - def __init__( self, urlWriter ): - Sheet.__init__( self, urlWriter, "All Done", 5 ) - - 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: - 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 ) - - def translate_sxp( self, fin_sxp ): - fin_hash = ssxp2hash( fin_sxp ) - - def get( key ): - ret = fin_hash.get( key ) - if ret: - return ret - else: - return "" - - vals = OptVals() - - vals.name = get( 'name' ) - vals.memory = get( 'memory' ) - vals.maxmem = get( 'maxmem' ) - vals.cpu = get( 'cpu' ) - vals.cpu_weight = get( 'cpu_weight' ) - vals.vcpus = get( 'vcpus' ) - - vals.builder = get( 'builder' ) - vals.kernel = get( 'kernel' ) - vals.root = get( 'root' ) - vals.extra = get( 'extra' ) - - #setup vbds - - vbds = [] - - for i in range( int( get( 'num_vbds' ) ) ): - vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ), None ) ) - - vals.disk = vbds - - #misc - - vals.pci = [] - - vals.blkif = None - vals.netif = None - vals.restart = None - vals.console = None - vals.ramdisk = None - vals.ssidref = -1 - vals.bootloader = None - vals.usb = [] - vals.acpi = [] - - #setup vifs - - vals.vif = [] - vals.nics = 1 - - ip = get( 'ip_addr' ) - nfs = get( 'ip_nfs' ) - gate = get( 'ip_gateway' ) - mask = get( 'ip_subnet' ) - host = get( 'hostname' ) - dhcp = get( 'dhcp' ) - - vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp) - - opts = None - - try: - 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/DomInfo.py b/tools/python/xen/sv/DomInfo.py deleted file mode 100755 index 89feca0..0000000 --- a/tools/python/xen/sv/DomInfo.py +++ /dev/null @@ -1,268 +0,0 @@ -from xen.xend.XendClient import server -from xen.xend import PrettyPrint - -from xen.sv.HTMLBase import HTMLBase -from xen.sv.util import * -from xen.sv.GenTabbed import * -from xen.sv.Wizard import * - -DEBUG=1 - -class DomInfo( GenTabbed ): - - def __init__( self, urlWriter ): - - self.dom = 0; - - GenTabbed.__init__( self, "Domain Info", urlWriter, [ 'General', 'SXP', 'Devices', 'Migrate', 'Save' ], [ DomGeneralTab, DomSXPTab, DomDeviceTab, DomMigrateTab, DomSaveTab ] ) - - def write_BODY( self, request ): - try: - dom = int( getVar( 'dom', request ) ) - except: - request.write( "

Please Select a Domain

" ) - return None - - GenTabbed.write_BODY( self, request ) - - def write_MENU( self, request ): - 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, urlWriter ): - CompositeTab.__init__( self, [ DomGenTab, DomActionTab ], urlWriter ) - -class DomGenTab( GeneralTab ): - - def __init__( self, _ ): - - titles = {} - - titles[ 'ID' ] = 'dom' - titles[ 'Name' ] = 'name' - titles[ 'CPU' ] = 'cpu' - titles[ 'Memory' ] = ( 'mem', memoryFormatter ) - titles[ 'State' ] = ( 'state', stateFormatter ) - titles[ 'Total CPU' ] = ( 'cpu_time', smallTimeFormatter ) - titles[ 'Up Time' ] = ( 'up_time', bigTimeFormatter ) - - GeneralTab.__init__( self, {}, titles ) - - def write_BODY( self, request ): - - self.dom = getVar('dom', request) - - if self.dom is None: - request.write( "

Please Select a Domain

" ) - return None - - self.dict = getDomInfo( self.dom ) - - GeneralTab.write_BODY( self, request ) - -class DomSXPTab( PreTab ): - - def __init__( self, _ ): - self.dom = 0 - PreTab.__init__( self, "" ) - - - def write_BODY( self, request ): - self.dom = getVar('dom', request) - - if self.dom is None: - request.write( "

Please Select a Domain

" ) - return None - - try: - domInfo = server.xend_domain( self.dom ) - except: - domInfo = [["Error getting domain details."]] - - self.source = sxp2prettystring( domInfo ) - - PreTab.write_BODY( self, request ) - -class DomActionTab( ActionTab ): - - def __init__( self, _ ): - actions = { "shutdown" : "Shutdown", - "reboot" : "Reboot", - "pause" : "Pause", - "unpause" : "Unpause", - "destroy" : "Destroy" } - ActionTab.__init__( self, actions ) - - def op_shutdown( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != '0': - if DEBUG: print ">DomShutDown %s" % dom - try: - server.xend_domain_shutdown( int( dom ), "poweroff" ) - except: - pass - - def op_reboot( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != '0': - if DEBUG: print ">DomReboot %s" % dom - try: - server.xend_domain_shutdown( int( dom ), "reboot" ) - except: - pass - - def op_pause( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != '0': - if DEBUG: print ">DomPause %s" % dom - try: - server.xend_domain_pause( int( dom ) ) - except: - pass - - def op_unpause( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != '0': - if DEBUG: print ">DomUnpause %s" % dom - try: - server.xend_domain_unpause( int( dom ) ) - except: - pass - - def op_destroy( self, request ): - dom = getVar( 'dom', request ) - if not dom is None and dom != '0': - if DEBUG: print ">DomDestroy %s" % dom - try: - server.xend_domain_destroy(int( dom )) - 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, _ ): - pass - -class DomDeviceOptionsTab( NullTab ): - - title = "Device Options" - - def __init__( self, _ ): - pass - -class DomDeviceActionTab( ActionTab ): - - def __init__( self, _ ): - 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, _ ): - 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, _ ): - 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/GenTabbed.py b/tools/python/xen/sv/GenTabbed.py deleted file mode 100755 index 6631663..0000000 --- a/tools/python/xen/sv/GenTabbed.py +++ /dev/null @@ -1,147 +0,0 @@ -import types - -from xen.sv.HTMLBase import HTMLBase -from xen.sv.util import getVar - -class GenTabbed( HTMLBase ): - - def __init__( self, title, urlWriter, tabStrings, tabObjects ): - HTMLBase.__init__(self) - self.tabStrings = tabStrings - self.tabObjects = tabObjects - self.urlWriter = urlWriter - self.title = title - - def write_BODY( self, request ): - if not self.__dict__.has_key( "tab" ): - try: - self.tab = int( getVar( 'tab', request, 0 ) ) - except: - self.tab = 0 - - request.write( "\n
%s
" % self.title ) - - TabView( self.tab, self.tabStrings, self.urlWriter ).write_BODY( request ) - - try: - 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: - 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: - pass - -class PreTab( HTMLBase ): - - def __init__( self, source ): - HTMLBase.__init__( self ) - self.source = source - - def write_BODY( self, request ): - request.write( "\n
" )
-        request.write( self.source )
-        request.write( "\n
" ) - -class GeneralTab( HTMLBase ): - - def __init__( self, dict, titles ): - HTMLBase.__init__( self ) - self.dict = dict - self.titles = titles - - def write_BODY( self, request ): - - request.write( "\n" ) - - def writeAttr( niceName, attr, formatter=None ): - if type( attr ) is types.TupleType: - ( attr, formatter ) = attr - - if attr in self.dict: - if formatter: - temp = formatter( self.dict[ attr ] ) - else: - temp = str( self.dict[ attr ] ) - request.write( "\n" % ( niceName, temp ) ) - - for niceName, attr in self.titles.items(): - writeAttr( niceName, attr ) - - request.write( "

%s:

%s

" ) - -class NullTab( HTMLBase ): - - def __init__( self, title="Null Tab" ): - HTMLBase.__init__( self ) - self.title = title - - def write_BODY( self, request ): - request.write( "\n

%s

" % self.title ) - -class ActionTab( HTMLBase ): - - def __init__( self, actions ): - self.actions = actions - HTMLBase.__init__( self ) - - def write_BODY( self, request ): - 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, urlWriter ): - HTMLBase.__init__( self ) - self.tabs = tabs - self.urlWriter = urlWriter - - def write_BODY( self, request ): - for tab in self.tabs: - tab( self.urlWriter ).write_BODY( request ) - - def perform( self, request ): - for tab in self.tabs: - 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 deleted file mode 100755 index d0fca13..0000000 --- a/tools/python/xen/sv/HTMLBase.py +++ /dev/null @@ -1,53 +0,0 @@ -from xen.sv.util import * - -class HTMLBase: - - isLeaf = True - - def __init__( self ): - pass - - def render_POST( self, request ): - self.perform( request ) - return self.render_GET( request ) - - def render_GET( self, request ): - pass - - def write_BODY( self, request ): - pass - - def write_TOP( self, request ): - pass - - def write_BOTTOM( self, request ): - pass - - def get_op_method(self, op): - """Get the method for an operation. - For operation 'foo' looks for 'op_foo'. - - op operation name - returns method or None - """ - op_method_name = 'op_' + op - return getattr(self, op_method_name, None) - - def perform(self, req): - """General operation handler for posted operations. - For operation 'foo' looks for a method op_foo and calls - it with op_foo(req). Replies with code 500 if op_foo - is not found. - - The method must return a list when req.use_sxp is true - and an HTML string otherwise (or list). - Methods may also return a Deferred (for incomplete processing). - - req request - """ - op = req.args.get('op') - if not op is None and len(op) == 1: - op = op[0] - op_method = self.get_op_method(op) - if op_method: - op_method( req ) diff --git a/tools/python/xen/sv/Main.py b/tools/python/xen/sv/Main.py deleted file mode 100755 index ea62af1..0000000 --- a/tools/python/xen/sv/Main.py +++ /dev/null @@ -1,82 +0,0 @@ - -from xen.sv.NodeInfo import NodeInfo -from xen.sv.DomInfo import DomInfo -from xen.sv.CreateDomain import CreateDomain -from xen.sv.RestoreDomain import RestoreDomain - -from xen.sv.util import getVar - -# adapter to make this all work with mod_python -# as opposed to Twisted -# (c) Tom Wilkie 2005 - -class Args: - def __init__( self, req ): - from mod_python.util import FieldStorage - self.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 - -# This is the Main class -# It pieces 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 _, 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[ moduleName ] - module.write_BODY( request ) - - def do_POST( self, request ): - if not self.init_done: - self.init_modules( request ) - self.init_done = True - - 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/NodeInfo.py b/tools/python/xen/sv/NodeInfo.py deleted file mode 100755 index f8b47b1..0000000 --- a/tools/python/xen/sv/NodeInfo.py +++ /dev/null @@ -1,73 +0,0 @@ -from xen.xend.XendClient import server - -from xen.sv.util import * -from xen.sv.GenTabbed import * - -class NodeInfo( GenTabbed ): - - def __init__( self, urlWriter ): - GenTabbed.__init__( self, "Node Details", urlWriter, [ 'General', 'Dmesg', 'SXP' ], [ NodeGeneralTab, NodeDmesgTab, NodeSXPTab ] ) - - def write_MENU( self, request ): - request.write( "

Node details

" % self.urlWriter( '' ) ) - -class NodeGeneralTab( CompositeTab ): - def __init__( self, urlWriter ): - CompositeTab.__init__( self, [ NodeInfoTab, NodeActionTab ], urlWriter ) - -class NodeInfoTab( GeneralTab ): - - def __init__( self, urlWriter ): - - nodeInfo = {} - try: - nodeInfo = sxp2hash( server.xend_node() ) - except: - nodeInfo[ 'system' ] = 'Error getting node info' - - dictTitles = {} - dictTitles[ 'System' ] = 'system' - dictTitles[ 'Hostname' ] = 'host' - dictTitles[ 'Release' ] = 'release' - dictTitles[ 'Version' ] ='version' - dictTitles[ 'Machine' ] = 'machine' - dictTitles[ 'Cores' ] = 'cores' - dictTitles[ 'Hyperthreading' ] = ( 'hyperthreads_per_core', hyperthreadFormatter ) - dictTitles[ 'CPU Speed' ] = ( 'cpu_mhz', cpuFormatter ) - dictTitles[ 'Memory' ] = ( 'memory', memoryFormatter ) - dictTitles[ 'Free Memory' ] = ( 'free_memory', memoryFormatter ) - - GeneralTab.__init__( self, dict=nodeInfo, titles=dictTitles ) - -class NodeDmesgTab( PreTab ): - - def __init__( self, urlWriter ): - try: - dmesg = server.xend_node_get_dmesg() - except: - dmesg = "Error getting node information: XenD not running?" - PreTab.__init__( self, dmesg ) - -class NodeActionTab( ActionTab ): - - def __init__( self, urlWriter ): - ActionTab.__init__( self, { "shutdown" : "shutdown", - "reboot" : "reboot" } ) - - def op_shutdown( self, request ): - if debug: print ">NodeShutDown" - server.xend_node_shutdown() - - def op_reboot( self, request ): - if debug: print ">NodeReboot" - server.xend_node_reboot() - -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 deleted file mode 100755 index b836a43..0000000 --- a/tools/python/xen/sv/RestoreDomain.py +++ /dev/null @@ -1,50 +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 RestoreDomain( Wizard ): - def __init__( self, urlWriter ): - - sheets = [ ChooseRestoreDomain, - DoRestore ] - - Wizard.__init__( self, urlWriter, "Restore Domain", sheets ) - - -class ChooseRestoreDomain( Sheet ): - title = "Configure Restore" - - def __init__( self, urlWriter ): - Sheet.__init__( self, urlWriter, "Configure Restore", 0) - - self.addControl( InputControl( 'file', '', - 'Suspend file name:', - ".*") ) - -class DoRestore( Sheet ): - title = "Restore Done" - - def __init__(self, urlWriter ): - Sheet.__init__(self, urlWriter, "Restore Done", 1) - - def write_BODY( self, request, err ): - - if not self.passback: self.parseForm( request ) - config = ssxp2hash ( string2sxp( self.passback ) ) - - try: - dom_sxp = server.xend_domain_restore( config['file'] ) - success = "Your domain was successfully restored.\n" - except Exception, e: - success = "There was an error restoring your domain\n" - dom_sxp = str(e) - - pt = PreTab( success + sxp2prettystring( dom_sxp ) ) - pt.write_BODY( request ) - - request.write( "

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

" % self.location ) diff --git a/tools/python/xen/sv/Wizard.py b/tools/python/xen/sv/Wizard.py deleted file mode 100755 index c4ac53b..0000000 --- a/tools/python/xen/sv/Wizard.py +++ /dev/null @@ -1,245 +0,0 @@ -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( GenTabbed ): - - def __init__( self, urlWriter, title, sheets ): - 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 ): - 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 ) - - 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 - -class Sheet( HTMLBase ): - - def __init__( self, urlWriter, title, location ): - HTMLBase.__init__( self ) - self.urlWriter = urlWriter - self.fields = [] - self.title = title - self.location = location - self.passback = None - - def parseForm( self, request ): - do_not_parse = [ 'mod', 'op', 'passback' ] - - passed_back = request.args - - temp_passback = passed_back.get( "passback" ) - - if temp_passback is not None and len( temp_passback ) > 0: - temp_passback = temp_passback[ len( temp_passback )-1 ] - else: - temp_passback = "( )" - - last_passback = ssxp2hash( string2sxp( temp_passback ) ) #use special function - will work with no head on sxp - - if DEBUG: print last_passback - - for (key, value) in passed_back.items(): - if key not in do_not_parse: - last_passback[ key ] = value[ len( value ) - 1 ] - - self.passback = sxp2string( hash2sxp( last_passback ) ) #store the sxp - - if DEBUG: print self.passback - - def write_BODY( self, request ): - - if not self.passback: self.parseForm( request ) - - request.write( "

%s

" % self.title ) - - previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference - - request.write( "" ) - - for (field, control) in self.fields: - control.write_Control( request, previous_values.get( field ) ) - if previous_values.get( field ) is not None and not control.validate( previous_values.get( field ) ): - control.write_Help( request ) - - request.write( "
" ) - - request.write( "

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

" % self.location ) - - def addControl( self, control ): - self.fields.append( [ control.getName(), control ] ) - - def validate( self, request ): - - if not self.passback: self.parseForm( request ) - - check = True - - previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the map for quick reference - if DEBUG: print previous_values - - for (field, control) in self.fields: - if not control.validate( previous_values.get( field ) ): - check = False - if DEBUG: print "> %s = %s" % (field, previous_values.get( field )) - - return check - -class SheetControl( HTMLBase ): - - def __init__( self, reg_exp = ".*" ): - HTMLBase.__init__( self ) - self.name = "" - self.reg_exp = reg_exp - - def write_Control( self, request, persistedValue ): - request.write( "%s" % persistedValue ) - - def write_Help( self, request ): - request.write( "

Text must match pattern:" ) - request.write( " %s

" % self.reg_exp ) - - def validate( self, persistedValue ): - if persistedValue is None: - persistedValue = "" - - return not re.compile( self.reg_exp ).match( persistedValue ) is None - - def getName( self ): - return self.name - - def setName( self, name ): - self.name = name - -class InputControl( SheetControl ): - - def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this field." ): - SheetControl.__init__( self, reg_exp ) - self.setName( name ) - - self.defaultValue = defaultValue - self.humanText = humanText - self.help_text = help_text - - def write_Control( self, request, persistedValue ): - if persistedValue is None: - persistedValue = self.defaultValue - - request.write( "

%s

" % (self.humanText, self.getName(), persistedValue) ) - - def write_Help( self, request ): - request.write( "

" ) - request.write( " %s

" % self.help_text ) - -class TextControl( SheetControl ): - - def __init__( self, text ): - SheetControl.__init__( self ) - self.text = text - - def write_Control( self, request, persistedValue ): - request.write( "

%s

" % self.text ) - -class SmallTextControl( SheetControl ): - - def __init__( self, text ): - SheetControl.__init__( self ) - self.text = text - - def write_Control( self, request, persistedValue ): - request.write( "

%s

" % self.text ) - -class ListControl( SheetControl ): - - def __init__( self, name, options, humanText ): - SheetControl.__init__( self ) - self.setName( name ) - self.options = options - self.humanText = humanText - - def write_Control( self, request, persistedValue ): - request.write( "

%s

" % self.humanText ) - request.write( "" ) - - def validate( self, persistedValue ): - for (value, text) in self.options: - if value == persistedValue: - return True - - return False - -class FileControl( InputControl ): - - def __init__( self, name, defaultValue, humanText, reg_exp = ".*", help_text = "You must enter the appropriate details in this field." ): - InputControl.__init__( self, name, defaultValue, humanText ) - - def validate( self, persistedValue ): - if persistedValue is None: return False - try: - open( persistedValue ) - return True - except IOError, TypeError: - return False - - def write_Help( self, request ): - request.write( "

File does not exist: you must enter a valid, absolute file path.

" ) - -class TickControl( SheetControl ): - - def __init__( self, name, defaultValue, humanText ): - SheetControl.__init__( self ) - self.setName( name ) - self.defaultValue = defaultValue - self.humanText = humanText - - def write_Control( self, request, persistedValue ): - request.write( "

%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( "" ) - - diff --git a/tools/python/xen/sv/__init__.py b/tools/python/xen/sv/__init__.py deleted file mode 100755 index 8d1c8b6..0000000 --- a/tools/python/xen/sv/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tools/python/xen/sv/util.py b/tools/python/xen/sv/util.py deleted file mode 100755 index cfed397..0000000 --- a/tools/python/xen/sv/util.py +++ /dev/null @@ -1,126 +0,0 @@ -from xen.xend.XendClient import server -from xen.xend import sxp -from xen.xend import PrettyPrint - -import types - -def getDomInfo( domain ): - domInfoHash = {} - try: - domInfoHash = sxp2hash( server.xend_domain( domain ) ) - domInfoHash['dom'] = domain - except: - domInfoHash['name'] = "Error getting domain details" - return domInfoHash - -def sxp2hash( s ): - sxphash = {} - - for child in sxp.children( s ): - if isinstance( child, types.ListType ) and len( child ) > 1: - if isinstance( child[1], types.ListType ) and len( child ) > 1: - sxphash[ child[0] ] = sxp2hash( child[1] ) - else: - sxphash[ child[0] ] = child[1] - - return sxphash - -def ssxp2hash( s ): - sxphash = {} - - for i in s: - if isinstance( i, types.ListType ) and len( i ) > 1: - sxphash[ i[0] ] = i[1] - - return sxphash - -def hash2sxp( h ): - hashsxp = [] - - for (key, item) in h.items(): - hashsxp.append( [key, item] ) - - return hashsxp - -def string2sxp( string ): - pin = sxp.Parser() - pin.input( string ) - return pin.get_val() - -def sxp2string( sexp ): - return sxp.to_string( sexp ) - -def sxp2prettystring( sxp ): - class tmp: - def __init__( self ): - self.str = "" - def write( self, str ): - self.str = self.str + str - temp = tmp() - PrettyPrint.prettyprint( sxp, out=temp ) - return temp.str - -def getVar( var, request, default=None ): - - arg = request.args.get( var ) - - if arg is None: - return default - else: - return arg[ len( arg )-1 ] - -def bigTimeFormatter( time ): - time = float( time ) - weeks = time // 604800 - remainder = time % 604800 - days = remainder // 86400 - - remainder = remainder % 86400 - - hms = smallTimeFormatter( remainder ) - - return "%d weeks, %d days, %s" % ( weeks, days, hms ) - -def smallTimeFormatter( time ): - time = float( time ) - hours = time // 3600 - remainder = time % 3600 - mins = remainder // 60 - secs = time % 60 - return "%02d:%02d:%04.1f (hh:mm:ss.s)" % ( hours, mins, secs ) - -def stateFormatter( state ): - states = [ 'Running', 'Blocked', 'Paused', 'Shutdown', 'Crashed' ] - - stateStr = "" - - for i in range( len( state ) ): - if state[i] != "-": - stateStr += "%s, " % states[ i ] - - return stateStr + " (%s)" % state - -def memoryFormatter( mem ): - mem = int( mem ) - if mem >= 1024: - mem = float( mem ) / 1024 - return "%3.2fGb" % mem - else: - return "%7dMb" % mem - -def cpuFormatter( mhz ): - mhz = int( mhz ) - if mhz > 1000: - ghz = float( mhz ) / 1000.0 - return "%4.2fGHz" % ghz - else: - return "%4dMHz" % mhz - -def hyperthreadFormatter( threads ): - try: - if int( threads ) > 1: - return "Yes" - else: - return "No" - except: - return "No" diff --git a/tools/sv/Makefile b/tools/sv/Makefile deleted file mode 100644 index c9ae1de..0000000 --- a/tools/sv/Makefile +++ /dev/null @@ -1,3 +0,0 @@ - -.PHONY: all -all: diff --git a/tools/sv/images/destroy.png b/tools/sv/images/destroy.png deleted file mode 100755 index 9545fc4837b958ef6e146c2c5f21e30258e8d8ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2408 zcmW+&3pCW(AHTnOV`e-WljqE+)}xY3b*OkTHvM@GUZ7BG^0G0CcHdaRb*QYvXuMV7%Xv1Mx>gW5WS^{}Dkr!|QNp zM7VEw=>DXb*6=L=5WaYMvi%dg1z(qz+|YH3o_j~IaDl$wL__kNw`TF%f@R3V5R|k>+#RL+i|09Q3e`Zp)$g0J4vpJ08|#= zNv@8_$;%Ve$BmMkUf&FPEMR>7cPfO~(A(P^aU5yl`G2tMG!QCNEBh*@^&{oEN4hUc zzC8lGH^v1A2S-Q6#KhPGA2yE9hGI8v{KTR)<6zo`H$)6$!_ay<1CCCfY|f^K4<||~ zil%wP27>`U<AG+%(7q+lK=$sL=B34*( zb@A(b)AY=U4~`%DL{?MNCabE_`c#mWMMN`~;4mWPntcBm(jO<6`ZU9>`Q@r%fFi8S zZb;H7u}04(9-drk^OWn=(oX1I8{z8zyd}F_O<_&_Xq7;usxeg2t4px_y zrTZEp5G+d`(W$;F9JApO;hAOf_^^)Gukp=#Ez4x?Xv#6xf^kjABeJ(6zx~~5dm~kC zSo1nz6GTQxpk?dPOmj=Qc;K9!b)6Gj^sckQV z>ykJP54Pr8VZwB%!HNoV?>r2FVOe&(Jo@wWpjl9owtu5|hAhw3`DA3>#Ui^M{l~27 z%C>ApE%v#?fC`<2^N)s^wIl*R>oo}52`TXeMtw7EVd#17F1^JM0gkV0vwC%^=H*|% zZ7^=Tbo1Aoge?XN$!j} zdj`>4T0UKV4b45sFi|~)j^*^y@XWs@P`*>8>7PK4wWH(Cly;Ww;h;pRL?U7D*pbB! z2%t{#c^1&*dwARecTf}?3RG5ExK02)!Pt^YB7Z`quKvZ@*%?Qp(W2QgQ++PdJX8Io z!>CLg5<7oAW#fr2@r)ZYRO`DeTOFPO+R#8|kR4E(>NFY%CtLz7Pz!ABQRlY~y~;G_ zc~Je+o4ONa$%J8hUX)mhi22g8y~q8ADg1MWI6c-{7Jh8EK-+ps7#S&!%-I$VW# zVhqRb;1upH2s2ro6<%i#@ElsYyG?rkX5iqU4~Uiqx|E$)wi%bYp73_ah9=y(h;@kK z<0nz)d6&zCuR1%Sx^_jvvMS(je@G~V_gcubivwEq8E_z6y29q9SfE82FF>taxiZ=Z zqneX(YL}3w3gL`c{cAy7ZuaWZREQ@z93IX&otF!J-zi_Q*h!R~dyZK`252MJr$}Vps!1#R1^eCaCU9mAdv3fH2p6 zic<9Q_X$ZX+LZt)DAp`Tf}|~EarGj8q;s)&JpSz#+<1bwoyZ51 z$t|C=kARF|*hB>R_3QH46coY?sZ>gb6I#so%@g}EP#sj+z7;!-RTaxS=#9h$Q{f|A@Pr zhQ=+DoSlD9V7juvW0wO0!3?nOOt&pb+j=PS=S&zig;)or2%1!AFDxv$!5@(%hffA? z-Fm=Y7-inTfF!G0;_jgK+ziHM2j}YaH5|L=&1OU8Q)nbuVM8}}e0;n{@rTIN#Va-A zN>vV?354D1&mZ3v`0L*k-?(}jF-mJJ1~IiAU!6B^o`OVvmQen1$n5Z~xY1qJlvXA% zx!wQp#OA&tA9tWqB$kwx_GPRi>#+hOer#%NtN=ZkZ`DP{1?^ooLv(5MG76m6cRyjm zy4p&NRc1_1MqT&N04P0<9OUPB`*cakH=QrQs#4uwAG5Nl+~-0IEgjnFeLc9L__7Lr zKg>!lZFJ5>fJ(gJG1+sEJA@RIcDB9bFq7inQCL(Y#)oH)txBD-uADtKH*UzO{Wh-| ztz&UV(lauK_K_hy7G}8|XwD71eQ>lN(loj8Crl3!(<~d=%XDA7c)@RPRNAr1*9fZ# z!}=Y)%gYU2T5hn8MuGEvUi$j_iKhyXYNGyOn?pp~MVrBuID}g|(aP|`lUEsK8&9lzch?; zcc&`XlU>g2@K`RUeIZP~ZML$sbY(P~!QgV@*jo9zAv~2_qu6wl8fX=R>WQkBHDd0z zoGvVce(F%T54y_j5+HRED$`KkW_*RmVu diff --git a/tools/sv/images/finish.png b/tools/sv/images/finish.png deleted file mode 100755 index 6c5d18a9b7f6091f3a92723f27029b7629ee45e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1189 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 IM6N<$f|-xg+W-In diff --git a/tools/sv/images/previous.png b/tools/sv/images/previous.png deleted file mode 100755 index 22292d6e9c8d7aa0c3ee21d9dfa96988178837c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1285 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 feXAVM7;V6O*9ZG8z{!&*89*9A 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 diff --git a/tools/sv/images/xen.png b/tools/sv/images/xen.png deleted file mode 100755 index 344c361b3cc1182bf22ab1da590936157f8e851d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10575 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" ) - -from xen.sv.Main import Main, TwistedAdapter - -main = Main() -request = TwistedAdapter( req ) -main.do_POST( request ) -%> - - - XenSV - - - - -
- -
- <% main.render_main( request ) %> -
- - -
- - -- 1.7.2.5