X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-web.git/blobdiff_plain/d7bc5fe65d556f4174757e657b3c7614289f7186..fe124a0f30e70f1e687bbb3ba2c56e674b20d6b3:/code/main.py diff --git a/code/main.py b/code/main.py index 7c04d25..cf0aca2 100755 --- a/code/main.py +++ b/code/main.py @@ -6,6 +6,7 @@ import cPickle import cgi import datetime import hmac +import os import random import sha import sys @@ -37,11 +38,20 @@ from invirt.common import InvalidInput, CodeError from view import View, revertStandardError + +static_dir = os.path.join(os.path.dirname(__file__), 'static') +InvirtStatic = cherrypy.tools.staticdir.handler( + root=static_dir, + dir=static_dir, + section='/static') + class InvirtUnauthWeb(View): + static = InvirtStatic + @cherrypy.expose @cherrypy.tools.mako(filename="/unauth.mako") def index(self): - return {'simple': True} + return dict(simple=True) class InvirtWeb(View): def __init__(self): @@ -53,6 +63,8 @@ class InvirtWeb(View): 'from invirt import database'] self._cp_config['request.error_response'] = self.handle_error + static = InvirtStatic + @cherrypy.expose @cherrypy.tools.mako(filename="/invalid.mako") def invalidInput(self): @@ -85,6 +97,9 @@ class InvirtWeb(View): return d def __getattr__(self, name): + # At the point __getattr__ is called, tools haven't been run. Make sure the user is logged in. + cherrypy.tools.remote_user_login.callable() + if name in ("admin", "overlord"): if not cherrypy.request.login in getAfsGroupMembers(config.adminacl, config.authz.afs.cells[0].cell): raise InvalidInput('username', cherrypy.request.login, @@ -112,11 +127,9 @@ class InvirtWeb(View): @cherrypy.tools.mako(filename="/list.mako") def list(self, result=None): """Handler for list requests.""" - checkpoint.checkpoint('Getting list dict') d = getListDict(cherrypy.request.login, cherrypy.request.state) if result is not None: d['result'] = result - checkpoint.checkpoint('Got list dict') return d index=list @@ -158,8 +171,6 @@ wiki, including steps to prepare an HVM guest to boot as a ParaVM

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 quotas. It must be the name of a @@ -183,8 +194,9 @@ your machine will run just fine, but the applet's display of the console will suffer artifacts. """, 'Windows': """ +Windows 7: The Windows 7 image is licensed for all MIT students and will automatically activate off the network. The installer requires 512 MiB RAM and at least 15 GiB disk space (20 GiB or more recommended).
Windows Vista: The Vista image is licensed for all MIT students and will automatically activate off the network; see the licensing confirmation e-mail for details. The installer requires 512 MiB RAM and at least 7.5 GiB disk space (15 GiB or more recommended).
-Windows XP: 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, or visit http://msca.mit.edu/ if you are staff/faculty to request one. +Windows XP: 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, or visit http://msca.mit.edu/ if you are staff/faculty to request one. """ } @@ -273,7 +285,6 @@ console will suffer artifacts. 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 @@ -353,12 +364,12 @@ console will suffer artifacts. def command(self, command_name, machine_id, **kwargs): """Handler for running commands like boot and delete on a VM.""" back = kwargs.get('back') + if command_name == 'delete': + back = 'list' try: d = controls.commandResult(cherrypy.request.login, cherrypy.request.state, command_name, machine_id, kwargs) - if d['command'] == 'Delete VM': - back = 'list' except InvalidInput, err: if not back: raise @@ -381,20 +392,6 @@ console will suffer artifacts. machine = MachineView() -class Checkpoint: - def __init__(self): - self.start_time = time.time() - self.checkpoints = [] - - def checkpoint(self, s): - self.checkpoints.append((s, time.time())) - - def __str__(self): - return ('Timing info:\n%s\n' % - '\n'.join(['%s: %s' % (d, t - self.start_time) for - (d, t) in self.checkpoints])) - -checkpoint = Checkpoint() class Defaults: """Class to store default values for fields.""" @@ -428,14 +425,11 @@ def hasVnc(status): def getListDict(username, state): """Gets the list of local variables used by list.tmpl.""" - checkpoint.checkpoint('Starting') machines = state.machines - checkpoint.checkpoint('Got my machines') on = {} has_vnc = {} installing = {} xmlist = state.xmlist - checkpoint.checkpoint('Got uptimes') for m in machines: if m not in xmlist: has_vnc[m] = 'Off' @@ -451,11 +445,9 @@ def getListDict(username, state): has_vnc[m] = "ParaVM" max_memory = validation.maxMemory(username, state) max_disk = validation.maxDisk(username) - checkpoint.checkpoint('Got max mem/disk') defaults = Defaults(max_memory=max_memory, max_disk=max_disk, owner=username) - checkpoint.checkpoint('Got defaults') def sortkey(machine): return (machine.owner != username, machine.owner, machine.name) machines = sorted(machines, key=sortkey) @@ -466,7 +458,8 @@ def getListDict(username, state): defaults=defaults, machines=machines, has_vnc=has_vnc, - installing=installing) + installing=installing, + disable_creation=False) return d def getHostname(nic): @@ -530,9 +523,9 @@ def modifyDict(username, state, machine_id, fields): olddisk = {} session.begin() try: - kws = dict([(kw, fields[kw]) for kw in + kws = dict((kw, fields[kw]) for kw in 'owner admin contact name description memory vmtype disksize'.split() - if fields[kw]]) + if fields.get(kw)) kws['machine_id'] = machine_id validate = validation.Validate(username, state, **kws) machine = validate.machine @@ -544,6 +537,26 @@ def modifyDict(username, state, machine_id, fields): if hasattr(validate, 'vmtype'): machine.type = validate.vmtype + update_acl = False + if hasattr(validate, 'owner') and validate.owner != machine.owner: + machine.owner = validate.owner + update_acl = True + if hasattr(validate, 'description'): + machine.description = validate.description + if hasattr(validate, 'admin') and validate.admin != machine.administrator: + machine.administrator = validate.admin + update_acl = True + if hasattr(validate, 'contact'): + machine.contact = validate.contact + + session.save_or_update(machine) + session.commit() + except: + session.rollback() + raise + + session.begin() + try: if hasattr(validate, 'disksize'): disksize = validate.disksize disk = machine.disks[0] @@ -551,41 +564,37 @@ def modifyDict(username, state, machine_id, fields): olddisk[disk.guest_device_name] = disksize disk.size = disksize session.save_or_update(disk) + for diskname in olddisk: + controls.resizeDisk(oldname, diskname, str(olddisk[diskname])) + session.save_or_update(machine) + session.commit() + except: + session.rollback() + raise - update_acl = False - if hasattr(validate, 'owner') and validate.owner != machine.owner: - machine.owner = validate.owner - update_acl = True + session.begin() + try: if hasattr(validate, 'name'): machine.name = validate.name for n in machine.nics: if n.hostname == oldname: n.hostname = validate.name - if hasattr(validate, 'description'): - machine.description = validate.description - if hasattr(validate, 'admin') and validate.admin != machine.administrator: - machine.administrator = validate.admin - update_acl = True - if hasattr(validate, 'contact'): - machine.contact = validate.contact - + if hasattr(validate, 'name'): + controls.renameMachine(machine, oldname, validate.name) session.save_or_update(machine) - if update_acl: - cache_acls.refreshMachine(machine) session.commit() except: session.rollback() raise - for diskname in olddisk: - controls.resizeDisk(oldname, diskname, str(olddisk[diskname])) - if hasattr(validate, 'name'): - controls.renameMachine(machine, oldname, validate.name) + + if update_acl: + cache_acls.refreshMachine(machine) + return dict(machine=machine) def infoDict(username, state, machine): """Get the variables used by info.tmpl.""" status = controls.statusInfo(machine) - checkpoint.checkpoint('Getting status info') has_vnc = hasVnc(status) if status is None: main_status = dict(name=machine.name, @@ -595,11 +604,14 @@ def infoDict(username, state, machine): else: main_status = dict(status[1:]) main_status['host'] = controls.listHost(machine) - start_time = float(main_status.get('start_time', 0)) - uptime = datetime.timedelta(seconds=int(time.time()-start_time)) + start_time = main_status.get('start_time') + if start_time is None: + uptime = "Still booting?" + else: + start_time = float(start_time) + uptime = datetime.timedelta(seconds=int(time.time()-start_time)) cpu_time_float = float(main_status.get('cpu_time', 0)) cputime = datetime.timedelta(seconds=int(cpu_time_float)) - checkpoint.checkpoint('Status') display_fields = [('name', 'Name'), ('description', 'Description'), ('owner', 'Owner'), @@ -645,11 +657,7 @@ def infoDict(username, state, machine): pass #fields.append((disp, None)) - checkpoint.checkpoint('Got fields') - - max_mem = validation.maxMemory(machine.owner, state, machine, False) - checkpoint.checkpoint('Got mem') max_disk = validation.maxDisk(machine.owner, machine) defaults = Defaults() for name in 'machine_id name description administrator owner memory contact'.split(): @@ -657,7 +665,6 @@ def infoDict(username, state, machine): setattr(defaults, name, getattr(machine, name)) defaults.type = machine.type.type_id defaults.disk = "%0.2f" % (machine.disks[0].size/1024.) - checkpoint.checkpoint('Got defaults') d = dict(user=username, on=status is not None, machine=machine,