X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-web.git/blobdiff_plain/a5aac31f655f0372f64bc459bf979813a41b0295..1e922a353a14f5f231040595a93af3054ea41664:/code/main.py diff --git a/code/main.py b/code/main.py index a2ab887..3655352 100755 --- a/code/main.py +++ b/code/main.py @@ -86,7 +86,7 @@ class InvirtWeb(View): def __getattr__(self, name): if name in ("admin", "overlord"): - if not cherrypy.request.login in getAfsGroupMembers(config.adminacl, config.authz[0].cell): + if not cherrypy.request.login in getAfsGroupMembers(config.adminacl, config.authz.afs.cells[0].cell): raise InvalidInput('username', cherrypy.request.login, 'Not in admin group %s.' % config.adminacl) cherrypy.request.state = State(cherrypy.request.login, isadmin=True) @@ -97,14 +97,12 @@ class InvirtWeb(View): def handle_error(self): err = sys.exc_info()[1] if isinstance(err, InvalidInput): - e = revertStandardError() cherrypy.request.params['err'] = err - cherrypy.request.params['emsg'] = e + cherrypy.request.params['emsg'] = revertStandardError() raise cherrypy.InternalRedirect('/invalidInput') if not cherrypy.request.prev or 'err' not in cherrypy.request.prev.params: - e = revertStandardError() cherrypy.request.params['err'] = err - cherrypy.request.params['emsg'] = e + cherrypy.request.params['emsg'] = revertStandardError() cherrypy.request.params['traceback'] = _cperror.format_exc() raise cherrypy.InternalRedirect('/error') # fall back to cherrypy default error page @@ -201,10 +199,16 @@ console will suffer artifacts. help._cp_config['tools.require_login.on'] = False def parseCreate(self, fields): - kws = dict([(kw, fields.get(kw)) for kw in 'name description owner memory disksize vmtype cdrom autoinstall'.split() if fields.get(kw)]) - validate = validation.Validate(cherrypy.request.login, cherrypy.request.state, strict=True, **kws) - return dict(contact=cherrypy.request.login, name=validate.name, description=validate.description, memory=validate.memory, - disksize=validate.disksize, owner=validate.owner, machine_type=getattr(validate, 'vmtype', Defaults.type), + kws = dict([(kw, fields[kw]) for kw in + 'name description owner memory disksize vmtype cdrom autoinstall'.split() + if fields[kw]]) + validate = validation.Validate(cherrypy.request.login, + cherrypy.request.state, + strict=True, **kws) + return dict(contact=cherrypy.request.login, name=validate.name, + description=validate.description, memory=validate.memory, + disksize=validate.disksize, owner=validate.owner, + machine_type=getattr(validate, 'vmtype', Defaults.type), cdrom=getattr(validate, 'cdrom', None), autoinstall=getattr(validate, 'autoinstall', None)) @@ -215,7 +219,8 @@ console will suffer artifacts. """Handler for create requests.""" try: parsed_fields = self.parseCreate(fields) - machine = controls.createVm(cherrypy.request.login, cherrypy.request.state, **parsed_fields) + machine = controls.createVm(cherrypy.request.login, + cherrypy.request.state, **parsed_fields) except InvalidInput, err: pass else: @@ -224,8 +229,8 @@ console will suffer artifacts. d = getListDict(cherrypy.request.login, cherrypy.request.state) d['err'] = err if err: - for field in fields.keys(): - setattr(d['defaults'], field, fields.get(field)) + for field, value in fields.items(): + setattr(d['defaults'], field, value) else: d['new_machine'] = parsed_fields['name'] return d @@ -243,14 +248,19 @@ console will suffer artifacts. raise RuntimeError("test of the emergency broadcast system") 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): + """Synthesize attributes to allow RESTful URLs like + /machine/13/info. This is hairy. CherryPy 3.2 adds a + method called _cp_dispatch that allows you to explicitly + handle URLs that can't be mapped, and it allows you to + rewrite the path components and continue processing. + + This function gets the next path component being resolved + as a string. _cp_dispatch will get an array of strings + representing any subsequent path components as well.""" + try: - machine_id = int(name) - cherrypy.request.params['machine_id'] = machine_id + cherrypy.request.params['machine_id'] = int(name) return self except ValueError: return None @@ -259,7 +269,9 @@ console will suffer artifacts. @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 + 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 @@ -271,19 +283,24 @@ console will suffer artifacts. def modify(self, machine_id, **fields): """Handler for modifying attributes of a machine.""" try: - modify_dict = modifyDict(cherrypy.request.login, cherrypy.request.state, machine_id, fields) + modify_dict = modifyDict(cherrypy.request.login, + cherrypy.request.state, + machine_id, fields) except InvalidInput, err: result = None - machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine + machine = validation.Validate(cherrypy.request.login, + cherrypy.request.state, + machine_id=machine_id).machine else: machine = modify_dict['machine'] result = 'Success!' err = None - info_dict = infoDict(cherrypy.request.login, cherrypy.request.state, machine) + info_dict = infoDict(cherrypy.request.login, + cherrypy.request.state, machine) info_dict['err'] = err if err: - for field in fields.keys(): - setattr(info_dict['defaults'], field, fields.get(field)) + for field, value in fields.items(): + setattr(info_dict['defaults'], field, value) info_dict['result'] = result return info_dict @@ -309,8 +326,9 @@ console will suffer artifacts. Remember to enable iptables! echo 1 > /proc/sys/net/ipv4/ip_forward """ - machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine - + machine = validation.Validate(cherrypy.request.login, + cherrypy.request.state, + machine_id=machine_id).machine token = controls.vnctoken(machine) host = controls.listHost(machine) if host: @@ -328,14 +346,17 @@ console will suffer artifacts. port=port, authtoken=token) return d + @cherrypy.expose @cherrypy.tools.mako(filename="/command.mako") @cherrypy.tools.require_POST() def command(self, command_name, machine_id, **kwargs): """Handler for running commands like boot and delete on a VM.""" - back = kwargs.get('back', None) + back = kwargs.get('back') try: - d = controls.commandResult(cherrypy.request.login, cherrypy.request.state, command_name, machine_id, kwargs) + d = controls.commandResult(cherrypy.request.login, + cherrypy.request.state, + command_name, machine_id, kwargs) if d['command'] == 'Delete VM': back = 'list' except InvalidInput, err: @@ -349,9 +370,12 @@ console will suffer artifacts. return d if back == 'list': cherrypy.request.state.clear() #Changed global state - raise cherrypy.InternalRedirect('/list?result=%s' % urllib.quote(result)) + raise cherrypy.InternalRedirect('/list?result=%s' + % urllib.quote(result)) elif back == 'info': - raise cherrypy.HTTPRedirect(cherrypy.request.base + '/machine/%d/' % machine_id, status=303) + raise cherrypy.HTTPRedirect(cherrypy.request.base + + '/machine/%d/' % machine_id, + status=303) else: raise InvalidInput('back', back, 'Not a known back page.') @@ -509,7 +533,9 @@ def modifyDict(username, state, machine_id, fields): olddisk = {} session.begin() try: - kws = dict([(kw, fields.get(kw)) for kw in 'owner admin contact name description memory vmtype disksize'.split() if fields.get(kw)]) + kws = dict([(kw, fields[kw]) for kw in + 'owner admin contact name description memory vmtype disksize'.split() + if fields[kw]]) kws['machine_id'] = machine_id validate = validation.Validate(username, state, **kws) machine = validate.machine @@ -663,4 +689,4 @@ Subject: %s p.stdin.close() p.wait() -random.seed() +random.seed() #sigh