import sys
import time
import urllib
+import socket
+import cherrypy
from StringIO import StringIO
-
def revertStandardError():
"""Move stderr to stdout, and return the contents of the old stderr."""
errio = sys.stderr
from invirt.config import structs as config
from invirt.common import InvalidInput, CodeError
+from view import View
+
+class InvirtWeb(View):
+ def __init__(self):
+ super(self.__class__,self).__init__()
+ connect()
+ self._cp_config['tools.require_login.on'] = True
+ self._cp_config['tools.mako.imports'] = ['from invirt.config import structs as config',
+ 'from invirt import database']
+
+
+ @cherrypy.expose
+ @cherrypy.tools.mako(filename="/list.mako")
+ def list(self):
+ """Handler for list requests."""
+ checkpoint.checkpoint('Getting list dict')
+ d = getListDict(cherrypy.request.login, cherrypy.request.state)
+ checkpoint.checkpoint('Got list dict')
+ return d
+ index=list
+
+ @cherrypy.expose
+ @cherrypy.tools.mako(filename="/help.mako")
+ def help(self, subject=None, simple=False):
+ """Handler for help messages."""
+
+ help_mapping = {
+ 'Autoinstalls': """
+The autoinstaller builds a minimal Debian or Ubuntu system to run as a
+ParaVM. You can access the resulting system by logging into the <a
+href="help?simple=true&subject=ParaVM+Console">serial console server</a>
+with your Kerberos tickets; there is no root password so sshd will
+refuse login.</p>
+
+<p>Under the covers, the autoinstaller uses our own patched version of
+xen-create-image, which is a tool based on debootstrap. If you log
+into the serial console while the install is running, you can watch
+it.
+""",
+ 'ParaVM Console': """
+ParaVM machines do not support local console access over VNC. To
+access the serial console of these machines, you can SSH with Kerberos
+to %s, using the name of the machine as your
+username.""" % config.console.hostname,
+ 'HVM/ParaVM': """
+HVM machines use the virtualization features of the processor, while
+ParaVM machines rely on a modified kernel to communicate directly with
+the hypervisor. HVMs support boot CDs of any operating system, and
+the VNC console applet. The three-minute autoinstaller produces
+ParaVMs. ParaVMs typically are more efficient, and always support the
+<a href="help?subject=ParaVM+Console">console server</a>.</p>
+
+<p>More details are <a
+href="https://xvm.scripts.mit.edu/wiki/Paravirtualization">on the
+wiki</a>, including steps to prepare an HVM guest to boot as a ParaVM
+(which you can skip by using the autoinstaller to begin with.)</p>
+
+<p>We recommend using a ParaVM when possible and an HVM when necessary.
+""",
+ 'CPU Weight': """
+Don't ask us! We're as mystified as you are.""",
+ 'Owner': """
+The owner field is used to determine <a
+href="help?subject=Quotas">quotas</a>. It must be the name of a
+locker that you are an AFS administrator of. In particular, you or an
+AFS group you are a member of must have AFS rlidwka bits on the
+locker. You can check who administers the LOCKER locker using the
+commands 'attach LOCKER; fs la /mit/LOCKER' on Athena.) See also <a
+href="help?subject=Administrator">administrator</a>.""",
+ 'Administrator': """
+The administrator field determines who can access the console and
+power on and off the machine. This can be either a user or a moira
+group.""",
+ 'Quotas': """
+Quotas are determined on a per-locker basis. Each locker may have a
+maximum of 512 mebibytes of active ram, 50 gibibytes of disk, and 4
+active machines.""",
+ 'Console': """
+<strong>Framebuffer:</strong> At a Linux boot prompt in your VM, try
+setting <tt>fb=false</tt> to disable the framebuffer. If you don't,
+your machine will run just fine, but the applet's display of the
+console will suffer artifacts.
+""",
+ 'Windows': """
+<strong>Windows Vista:</strong> The Vista image is licensed for all MIT students and will automatically activate off the network; see <a href="/static/msca-email.txt">the licensing confirmation e-mail</a> for details. The installer requires 512 MiB RAM and at least 7.5 GiB disk space (15 GiB or more recommended).<br>
+<strong>Windows XP:</strong> This is the volume license CD image. You will need your own volume license key to complete the install. We do not have these available for the general MIT community; ask your department if they have one.
+"""
+ }
+
+ if not subject:
+ subject = sorted(help_mapping.keys())
+ if not isinstance(subject, list):
+ subject = [subject]
+
+ return dict(simple=simple,
+ subjects=subject,
+ mapping=help_mapping)
+ help._cp_config['tools.require_login.on'] = False
+
+ @cherrypy.expose
+ @cherrypy.tools.mako(filename="/helloworld.mako")
+ def helloworld(self, **kwargs):
+ return {'request': cherrypy.request, 'kwargs': kwargs}
+ helloworld._cp_config['tools.require_login.on'] = False
+
def pathSplit(path):
if path.startswith('/'):
path = path[1:]
checkpoint = Checkpoint()
-def jquote(string):
- return "'" + string.replace('\\', '\\\\').replace("'", "\\'").replace('\n', '\\n') + "'"
-
-def helppopup(subj):
- """Return HTML code for a (?) link to a specified help topic"""
- return ('<span class="helplink"><a href="help?' +
- cgi.escape(urllib.urlencode(dict(subject=subj, simple='true')))
- +'" target="_blank" ' +
- 'onclick="return helppopup(' + cgi.escape(jquote(subj)) + ')">(?)</a></span>')
-
def makeErrorPre(old, addition):
if addition is None:
return
Template.database = database
Template.config = config
-Template.helppopup = staticmethod(helppopup)
Template.err = None
class JsonDict:
kws = dict([(kw, fields.getfirst(kw)) for kw in 'name description owner memory disksize vmtype cdrom autoinstall'.split()])
validate = validation.Validate(username, state, strict=True, **kws)
return dict(contact=username, name=validate.name, description=validate.description, memory=validate.memory,
- disksize=validate.disksize, owner=validate.owner, machine_type=validate.vmtype,
+ disksize=validate.disksize, owner=validate.owner, machine_type=getattr(validate, 'vmtype', Defaults.type),
cdrom=getattr(validate, 'cdrom', None),
autoinstall=getattr(validate, 'autoinstall', None))
can_clone=can_clone)
return d
-def listVms(username, state, path, fields):
- """Handler for list requests."""
- checkpoint.checkpoint('Getting list dict')
- d = getListDict(username, state)
- checkpoint.checkpoint('Got list dict')
- return templates.list(searchList=[d])
-
def vnc(username, state, path, fields):
"""VNC applet page.
info_dict['result'] = result
return templates.info(searchList=[info_dict])
-
-def helpHandler(username, state, path, fields):
- """Handler for help messages."""
- simple = fields.getfirst('simple')
- subjects = fields.getlist('subject')
-
- help_mapping = {
- 'Autoinstalls': """
-The autoinstaller builds a minimal Debian or Ubuntu system to run as a
-ParaVM. You can access the resulting system by logging into the <a
-href="help?simple=true&subject=ParaVM+Console">serial console server</a>
-with your Kerberos tickets; there is no root password so sshd will
-refuse login.</p>
-
-<p>Under the covers, the autoinstaller uses our own patched version of
-xen-create-image, which is a tool based on debootstrap. If you log
-into the serial console while the install is running, you can watch
-it.
-""",
- 'ParaVM Console': """
-ParaVM machines do not support local console access over VNC. To
-access the serial console of these machines, you can SSH with Kerberos
-to %s, using the name of the machine as your
-username.""" % config.console.hostname,
- 'HVM/ParaVM': """
-HVM machines use the virtualization features of the processor, while
-ParaVM machines rely on a modified kernel to communicate directly with
-the hypervisor. HVMs support boot CDs of any operating system, and
-the VNC console applet. The three-minute autoinstaller produces
-ParaVMs. ParaVMs typically are more efficient, and always support the
-<a href="help?subject=ParaVM+Console">console server</a>.</p>
-
-<p>More details are <a
-href="https://xvm.scripts.mit.edu/wiki/Paravirtualization">on the
-wiki</a>, including steps to prepare an HVM guest to boot as a ParaVM
-(which you can skip by using the autoinstaller to begin with.)</p>
-
-<p>We recommend using a ParaVM when possible and an HVM when necessary.
-""",
- 'CPU Weight': """
-Don't ask us! We're as mystified as you are.""",
- 'Owner': """
-The owner field is used to determine <a
-href="help?subject=Quotas">quotas</a>. It must be the name of a
-locker that you are an AFS administrator of. In particular, you or an
-AFS group you are a member of must have AFS rlidwka bits on the
-locker. You can check who administers the LOCKER locker using the
-commands 'attach LOCKER; fs la /mit/LOCKER' on Athena.) See also <a
-href="help?subject=Administrator">administrator</a>.""",
- 'Administrator': """
-The administrator field determines who can access the console and
-power on and off the machine. This can be either a user or a moira
-group.""",
- 'Quotas': """
-Quotas are determined on a per-locker basis. Each locker may have a
-maximum of 512 megabytes of active ram, 50 gigabytes of disk, and 4
-active machines.""",
- 'Console': """
-<strong>Framebuffer:</strong> At a Linux boot prompt in your VM, try
-setting <tt>fb=false</tt> to disable the framebuffer. If you don't,
-your machine will run just fine, but the applet's display of the
-console will suffer artifacts.
-""",
- 'Windows': """
-<strong>Windows Vista:</strong> The Vista image is licensed for all MIT students and will automatically activate off the network; see <a href="/static/msca-email.txt">the licensing confirmation e-mail</a> for details. The installer req uires 512 MB RAM and at least 7.5 GB disk space (15 GB or more recommended).<br>
-<strong>Windows XP:</strong> This is the volume license CD image. You will need your own volume license key to complete the install. We do not have these available for the general MIT community; ask your department if they have one.
-"""
- }
-
- if not subjects:
- subjects = sorted(help_mapping.keys())
-
- d = dict(user=username,
- simple=simple,
- subjects=subjects,
- mapping=help_mapping)
-
- return templates.help(searchList=[d])
-
-
def badOperation(u, s, p, e):
"""Function called when accessing an unknown URI."""
return ({'Status': '404 Not Found'}, 'Invalid operation.')
def unauthFront(_, _2, _3, fields):
"""Information for unauth'd users."""
- return templates.unauth(searchList=[{'simple' : True}])
+ return templates.unauth(searchList=[{'simple' : True,
+ 'hostname' : socket.getfqdn()}])
def admin(username, state, path, fields):
if path == '':
return ({'Status': '303 See Other',
'Location': 'admin/'},
"You shouldn't see this message.")
- if not username in getAfsGroupMembers(config.web.adminacl, 'athena.mit.edu'):
+ if not username in getAfsGroupMembers(config.adminacl, 'athena.mit.edu'):
raise InvalidInput('username', username,
- 'Not in admin group %s.' % config.web.adminacl)
+ 'Not in admin group %s.' % config.adminacl)
newstate = State(username, isadmin=True)
newstate.environ = state.environ
return handler(username, newstate, path, fields)
"""Throw an error, to test the error-tracing mechanisms."""
raise RuntimeError("test of the emergency broadcast system")
-mapping = dict(list=listVms,
- vnc=vnc,
+mapping = dict(vnc=vnc,
command=command,
modify=modify,
info=info,
create=create,
- help=helpHandler,
unauth=unauthFront,
admin=admin,
overlord=admin,
d['details'] = details
return templates.error(searchList=[d])
-def getUser(environ):
- """Return the current user based on the SSL environment variables"""
- user = environ.get('REMOTE_USER')
- if user is None:
- return
-
- if environ.get('AUTH_TYPE') == 'Negotiate':
- # Convert the krb5 principal into a krb4 username
- if not user.endswith('@%s' % config.kerberos.realm):
- return
- else:
- return user.split('@')[0].replace('/', '.')
- else:
- return user
-
def handler(username, state, path, fields):
operation, path = pathSplit(path)
if not operation: