From d5c709a5a9d53bbff6fae1e3eab6e0a4acf294bf Mon Sep 17 00:00:00 2001 From: Quentin Smith <quentin@mit.edu> Date: Sun, 9 Aug 2009 18:45:35 -0400 Subject: [PATCH] Upgrade info page to Mako, and use REST-style URLs. svn path=/package_branches/invirt-web/cherrypy-rebased/; revision=2678 --- code/main.py | 33 +++++++--- code/templates/info.mako | 102 ++++++++++++++++++++++++++++++ code/templates/info.tmpl | 142 ------------------------------------------ code/templates/list.mako | 6 +- code/templates/skeleton.mako | 5 +- 5 files changed, 134 insertions(+), 154 deletions(-) create mode 100644 code/templates/info.mako delete mode 100644 code/templates/info.tmpl diff --git a/code/main.py b/code/main.py index 47f9b01..656c209 100755 --- a/code/main.py +++ b/code/main.py @@ -150,6 +150,31 @@ console will suffer artifacts. return {'request': cherrypy.request, 'kwargs': kwargs} helloworld._cp_config['tools.require_login.on'] = False + class MachineView(View): + # This is hairy. Fix when CherryPy 3.2 is out. (rename to + # _cp_dispatch, and parse the argument as a list instead of + # string + + def __getattr__(self, name): + try: + machine_id = int(name) + cherrypy.request.params['machine_id'] = machine_id + return self + except ValueError: + return None + + @cherrypy.expose + @cherrypy.tools.mako(filename="/info.mako") + def info(self, machine_id): + """Handler for info on a single VM.""" + machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine + d = infoDict(cherrypy.request.login, cherrypy.request.state, machine) + checkpoint.checkpoint('Got infodict') + return d + index = info + + machine = MachineView() + def pathSplit(path): if path.startswith('/'): path = path[1:] @@ -605,13 +630,6 @@ def infoDict(username, state, machine): fields = fields) return d -def info(username, state, path, fields): - """Handler for info on a single VM.""" - machine = validation.Validate(username, state, machine_id=fields.getfirst('machine_id')).machine - d = infoDict(username, state, machine) - checkpoint.checkpoint('Got infodict') - return templates.info(searchList=[d]) - def unauthFront(_, _2, _3, fields): """Information for unauth'd users.""" return templates.unauth(searchList=[{'simple' : True, @@ -636,7 +654,6 @@ def throwError(_, __, ___, ____): mapping = dict(vnc=vnc, command=command, modify=modify, - info=info, create=create, unauth=unauthFront, admin=admin, diff --git a/code/templates/info.mako b/code/templates/info.mako new file mode 100644 index 0000000..5af29bb --- /dev/null +++ b/code/templates/info.mako @@ -0,0 +1,102 @@ +<%page expression_filter="h"/> +<%inherit file="skeleton.mako" /> + +<%def name="title()"> +Info on ${machine.name} +</%def> + +<%def name="infoTable()"> +<h2>Info</h2> +<table> + % for key, value in fields: + <tr><td>${key}:</td><td>${value}</td></tr> + % endfor +</table> +</%def> + +<%def name="commands()"> +% if on: + % if not machine.type.hvm: + Console access: type + <tt>ssh ${machine.name}@${config.console.hostname}</tt> + on Athena. <a href="https://xvm.scripts.mit.edu/wiki/SerialConsole">(more info)</a> + % elif has_vnc: + <strong><a href="machine/${machine.machine_id}/vnc">Get Console</a></strong> + % else: + VNC console not enabled; still booting? + % endif +% endif +<form action="command" method="POST"> + <input type="hidden" name="back" value="info"/> + <input type="hidden" name="machine_id" value="${machine.machine_id}"/> + <div> + % if on: + <button type="submit" class="button" name="action" value="Power off">Power off (hard)</button> + <button type="submit" class="button" name="action" value="Shutdown">Shut down</button> + <input type="submit" class="button" name="action" value="Reboot"/> + % else: + <input type="submit" class="button" name="action" value="Power on"/> + % endif + </div> + <div> + Boot CD: +${self.fn.cdromList()} + </div> + <div> + <input type="submit" class="button" name="action" value="Delete VM" onclick="return confirm('Are you sure that you want to delete this VM?');"/> + </div> +</form> +</%def> + +<%def name="modifyForm()"> +% if err: +<p class="error">We had a problem with your request:</p> +% elif new_machine: +<p>Successfully modified.</p> +% endif +% if on: +(To edit ram, disk size, or machine name, turn off the machine first.) +% endif +<form action="modify" method="POST"> + <input type="hidden" name="machine_id" value="${defaults.machine_id}"/> + <table> + <tr><td>Description:</td><td colspan="2"><textarea name="description" rows="4" cols="60">${defaults.description}</textarea></td></tr> + <tr><td>Owner${self.fn.helppopup("Owner")}:</td><td><input type="text" name="owner", value="${defaults.owner}"/></td></tr> +${self.fn.errorRow('owner', err)} + <tr><td>Administrator${self.fn.helppopup("Administrator")}:</td><td><input type="text" name="admin", value="${defaults.administrator}"/></td></tr> +${self.fn.errorRow('administrator', err)} + <tr><td>Contact email:</td><td><input type="text" name="contact" value="${defaults.contact}"/></td></tr> +${self.fn.errorRow('contact', err)} +% if not on: + <tr><td>Machine Name:</td><td><input type="text" name="name" value="${defaults.name}"/>.${config.dns.domains[0]}</td></tr> +${self.fn.errorRow('name', err)} + <tr> + <td>HVM/ParaVM${self.fn.helppopup('HVM/ParaVM')}</td> + <td>${self.fn.vmTypeList(defaults.type)}</td> + </tr> + <tr><td>Ram:</td><td><input type="text" size=3 name="memory" value="${defaults.memory}"/>MiB (max ${max_mem})</td></tr> +${self.fn.errorRow('memory', err)} + <tr><td>Disk:</td><td><input type="text" size=3 name="disksize" value="${defaults.disk}"/>GiB (max ${max_disk})</td><td>WARNING: Modifying disk size may corrupt your data.</td></tr> +${self.fn.errorRow('disk', err)} +% else: +${self.fn.errorRow('name', err)} +${self.fn.errorRow('memory', err)} +${self.fn.errorRow('disk', err)} +% endif + <tr><td><input type="submit" class="button" name="action" value="Change"/></td></tr> + </table> +</form> +</%def> + +<div id="info"> + ${infoTable()} +</div> + +<h2>Commands</h2> +<div id="commands"> + ${commands()} +</div> +<h2>Settings</h2> +<div id="modify"> + ${modifyForm()} +</div> diff --git a/code/templates/info.tmpl b/code/templates/info.tmpl deleted file mode 100644 index d872fce..0000000 --- a/code/templates/info.tmpl +++ /dev/null @@ -1,142 +0,0 @@ -#from skeleton import skeleton -#extends skeleton - -#def title -Info on $machine.name -#end def - -#def infoTable() -<h2>Info</h2> -<table> - #for $key, $value in $fields - <tr><td>$key:</td><td>$value</td></tr> - #end for -</table> -#end def - -#def commands() -#if $on - #if not $machine.type.hvm - Console access: type - <tt>ssh $machine.name@$config.console.hostname</tt> - on Athena. <a href="https://xvm.scripts.mit.edu/wiki/SerialConsole">(more info)</a> - #elif $has_vnc - <strong><a href="vnc?machine_id=$machine.machine_id">Get Console</a></strong> - #else - VNC console not enabled; still booting? - #end if -#end if -<form action="command" method="POST"> - <input type="hidden" name="back" value="info"/> - <input type="hidden" name="machine_id" value="$machine.machine_id"/> - <div> - #if $on - <button type="submit" class="button" name="action" value="Power off">Power off (hard)</button> - <button type="submit" class="button" name="action" value="Shutdown">Shut down</button> - <input type="submit" class="button" name="action" value="Reboot"/> - #else - <input type="submit" class="button" name="action" value="Power on"/> - #end if - </div> - <div> - Boot CD: -#filter None -$cdromList()#slurp -#end filter - </div> - <div> - <input type="submit" class="button" name="action" value="Delete VM" onclick="return confirm('Are you sure that you want to delete this VM?');"/> - </div> -</form> -#end def - -#def modifyForm() -#if $err -<p class="error">We had a problem with your request:</p> -#else if $varExists('new_machine') -<p>Successfully modified.</p> -#end if -#if $on -(To edit ram, disk size, or machine name, turn off the machine first.) -#end if -<form action="modify" method="POST"> - <input type="hidden" name="machine_id" value="$defaults.machine_id"/> - <table> - <tr><td>Description:</td><td colspan="2"><textarea name="description" rows="4" cols="60">$defaults.description</textarea></td></tr> - <tr><td>Owner#slurp -#filter None -$helppopup("Owner")#slurp -#end filter -:</td><td><input type="text" name="owner", value="$defaults.owner"/></td></tr> -#filter None -$errorRow('owner', $err) -#end filter - <tr><td>Administrator#slurp -#filter None -$helppopup("Administrator")#slurp -#end filter -:</td><td><input type="text" name="admin", value="$defaults.administrator"/></td></tr> -#filter None -$errorRow('administrator', $err) -#end filter - <tr><td>Contact email:</td><td><input type="text" name="contact" value="$defaults.contact"/></td></tr> -#filter None -$errorRow('contact', $err) -#end filter -#if not $on - <tr><td>Machine Name:</td><td><input type="text" name="name" value="$defaults.name"/>.${config.dns.domains[0]}</td></tr> -#filter None -$errorRow('name', $err) -#end filter - <tr> - <td>HVM/ParaVM#slurp -#filter None -$helppopup('HVM/ParaVM')#slurp -#end filter -</td> - <td>#slurp -#filter None -$vmTypeList($defaults.type)#slurp -#end filter -</td> - </tr> - <tr><td>Ram:</td><td><input type="text" size=3 name="memory" value="$defaults.memory"/>MiB (max $max_mem)</td></tr> -#filter None -$errorRow('memory', $err) -#end filter - <tr><td>Disk:</td><td><input type="text" size=3 name="disksize" value="$defaults.disk"/>GiB (max $max_disk)</td><td>WARNING: Modifying disk size may corrupt your data.</td></tr> -#filter None -$errorRow('disk', $err) -#end filter -#else -#filter None -$errorRow('name', $err) -$errorRow('memory', $err) -$errorRow('disk', $err) -#end filter -#end if - <tr><td><input type="submit" class="button" name="action" value="Change"/></td></tr> - </table> -</form> -#end def - -#def body -<div id="info"> -#filter None - $infoTable() -#end filter -</div> - -<h2>Commands</h2> -<div id="commands"> -#filter None - $commands() -#end filter -</div> -<h2>Settings</h2> -<div id="modify"> -#filter None - $modifyForm() -#end filter -</div> -#end def diff --git a/code/templates/list.mako b/code/templates/list.mako index b03a04f..e500896 100644 --- a/code/templates/list.mako +++ b/code/templates/list.mako @@ -95,7 +95,7 @@ ${self.fn.cdromList(defaults.cdrom, "$('cd_or_auto_cd').checked = true;$('autoin /> </form> </td> - <td><a href="info?machine_id=${machine.machine_id}">${machine.name}</a></td> + <td><a href="machine/${machine.machine_id}">${machine.name}</a></td> <td>${machine.memory}M</td> <td>${machine.owner}</td> <td>${machine.administrator}</td> @@ -111,7 +111,9 @@ ${datetime.timedelta(seconds=int(machine.uptime))}\ </td> <td>\ % if has_vnc[machine] == True: -<a href="vnc?machine_id=${machine.machine_id}">Console</a>\ +<a href="machine/${machine.machine_id}/vnc">Console</a>\ +% elif has_vnc[machine] == 'ParaVM': +ParaVM${self.fn.helppopup("ParaVM Console")} % elif has_vnc[machine] != 'Off': ${has_vnc[machine]} % endif diff --git a/code/templates/skeleton.mako b/code/templates/skeleton.mako index a619a67..9c60c56 100644 --- a/code/templates/skeleton.mako +++ b/code/templates/skeleton.mako @@ -5,6 +5,7 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head><title>${self.title()} — XVM</title> + <base href="${cherrypy.request.base}" /> <link href="static/favicon.ico" type="image/x-icon" rel="shortcut icon"> <link rel="stylesheet" href="static/style.css" type="text/css" /> <link rel="stylesheet" href="static/layout.css" type="text/css" media="screen" /> @@ -53,8 +54,8 @@ function helppopup(name){ <ul class="navigation"> <li><a href="list">List</a></li> % if machine: -<li><a href="info?machine_id=${machine.machine_id}">Info</a></li> -<li><a href="vnc?machine_id=${machine.machine_id}">Console</a></li> +<li><a href="machine/${machine.machine_id}">Info</a></li> +<li><a href="machine/${machine.machine_id}/vnc">Console</a></li> % endif <li><a href="help">Help</a></li> </ul> -- 1.7.9.5