From ea5305a135b44a864dd070050cec72de9f144223 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 27 Feb 2009 20:46:23 -0500 Subject: [PATCH 01/16] Start tracking the membership of the adminacl setting in the admins table. svn path=/trunk/packages/invirt-web/; revision=2223 --- code/cache_acls.py | 10 ++++++++++ 1 file changed, 10 insertions(+) mode change 100644 => 100755 code/cache_acls.py diff --git a/code/cache_acls.py b/code/cache_acls.py old mode 100644 new mode 100755 index fe69815..e18b3d0 --- a/code/cache_acls.py +++ b/code/cache_acls.py @@ -70,6 +70,16 @@ def refreshCache(): refreshMachine(m) session.flush() + # Update the admin ACL as well + admin_acl = set(expandName(config.adminacl)) + old_admin_acl = set(a.user for a in Admin.query()) + for removed in old_admin_acl - admin_acl: + Admin.query.filter_by(user=removed).delete() + for added in admin_acl - old_admin_acl: + a = Admin(user=added) + session.save_or_update(a) + session.flush() + # Atomically execute our changes session.commit() except: -- 1.7.9.5 From 7c46b15066612e0c33c1a96cec20e9aca6c2b6f5 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 27 Feb 2009 21:01:05 -0500 Subject: [PATCH 02/16] Don't use a SA 0.5ism svn path=/trunk/packages/invirt-web/; revision=2226 --- code/cache_acls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/cache_acls.py b/code/cache_acls.py index e18b3d0..f92ad91 100755 --- a/code/cache_acls.py +++ b/code/cache_acls.py @@ -74,7 +74,8 @@ def refreshCache(): admin_acl = set(expandName(config.adminacl)) old_admin_acl = set(a.user for a in Admin.query()) for removed in old_admin_acl - admin_acl: - Admin.query.filter_by(user=removed).delete() + old = Admin.query.filter_by(user=removed).first() + session.delete(old) for added in admin_acl - old_admin_acl: a = Admin(user=added) session.save_or_update(a) -- 1.7.9.5 From 3e14c57b6d958e317a5e93eb236b85073f815c8c Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 27 Feb 2009 21:07:15 -0500 Subject: [PATCH 03/16] Add a changelog entry for the cache_acls change. svn path=/trunk/packages/invirt-web/; revision=2227 --- debian/changelog | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 26fd5c8..7dc3811 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,13 @@ invirt-web (0.0.21) unstable; urgency=low + [ Quentin Smith ] * Don't reuse IP addresses that are special in some way. - -- Quentin Smith Fri, 27 Feb 2009 11:55:51 -0500 + [ Evan Broder ] + * Cache the membership of the adminacl in addition to the ACLs for + machines. + + -- Evan Broder Fri, 27 Feb 2009 21:06:55 -0500 invirt-web (0.0.20) unstable; urgency=low -- 1.7.9.5 From fda1a1290d1c87bf8c50c99cfdf2ec8602003f81 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 27 Feb 2009 21:13:11 -0500 Subject: [PATCH 04/16] Don't bork of there is no main.fcgi. svn path=/trunk/packages/invirt-web/; revision=2231 --- code/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Makefile b/code/Makefile index ee8bbd9..b114e86 100644 --- a/code/Makefile +++ b/code/Makefile @@ -7,7 +7,7 @@ chmod: chmod -R g+w . 2>/dev/null || true kill: - pkill main.fcgi + -pkill main.fcgi compile: for dir in $(DIRS); do \ -- 1.7.9.5 From 4ed55b4ba8476ccdc46f0c7610870e39988f5e55 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Thu, 5 Mar 2009 17:13:42 -0500 Subject: [PATCH 05/16] Power off VMs after a Javascript popup. svn path=/trunk/packages/invirt-web/; revision=2238 --- code/templates/list.tmpl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/templates/list.tmpl b/code/templates/list.tmpl index 7c8e5d1..8a0231e 100644 --- a/code/templates/list.tmpl +++ b/code/templates/list.tmpl @@ -124,7 +124,11 @@ $helppopup('Windows')#slurp #if $machine.uptime then 'on' else 'off' " name="action" value="#slurp #if $machine.uptime then 'Power off' else 'Power on' -"/> +"#slurp +#if $machine.uptime + onclick="return confirm('Are you sure you want to power off this VM?');" +#end if +/> $machine.name -- 1.7.9.5 From 91a84d3f26706dca91ff915354667bf4f667fcc5 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Mon, 6 Apr 2009 22:13:53 -0400 Subject: [PATCH 06/16] Fix a potential quota hole from cross-realm Hesiod entries. svn path=/trunk/packages/invirt-web/; revision=2293 --- code/validation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/validation.py b/code/validation.py index 480d007..0285044 100644 --- a/code/validation.py +++ b/code/validation.py @@ -241,6 +241,8 @@ def testOwner(user, owner, machine=None): return machine.owner if owner is None: raise InvalidInput('owner', owner, "Owner must be specified") + if '@' in owner: + raise InvalidInput('owner', owner, "No cross-realm Hesiod lockers allowed") try: if user not in cache_acls.expandLocker(owner): raise InvalidInput('owner', owner, 'You do not have access to the ' -- 1.7.9.5 From b064cfab48993c4a009858a86000f69777ce9636 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 17 Apr 2009 12:51:42 -0400 Subject: [PATCH 07/16] When creating a new VM, create the disks in the try/except block so that everything gets rolled back if that fails. svn path=/trunk/packages/invirt-web/; revision=2295 --- code/controls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controls.py b/code/controls.py index 911c41a..e32b1c2 100644 --- a/code/controls.py +++ b/code/controls.py @@ -105,11 +105,11 @@ def createVm(username, state, owner, contact, name, description, memory, disksiz session.save_or_update(nic) session.save_or_update(disk) cache_acls.refreshMachine(machine) + makeDisks(machine) session.commit() except: session.rollback() raise - makeDisks(machine) try: if autoinstall: lvinstall(machine, autoinstall) -- 1.7.9.5 From 0478dcd4e3b9cac8a8dac99392be35d74c29582f Mon Sep 17 00:00:00 2001 From: Greg Price Date: Sat, 2 May 2009 18:53:48 -0400 Subject: [PATCH 08/16] xen-ips: silently ignore already-present IPs Also from the first hours of April. You all can imagine how happy I was to be running this code. =) svn path=/trunk/packages/invirt-web/; revision=2322 --- code/xen-ips | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/xen-ips b/code/xen-ips index 58f3078..b0b8fed 100755 --- a/code/xen-ips +++ b/code/xen-ips @@ -1,6 +1,7 @@ #!/usr/bin/python import random from invirt import database +import sqlalchemy.exceptions import sys # stolen directly from xend/server/netif.py @@ -37,9 +38,12 @@ def usage(): print >> sys.stderr, "USAGE: " + sys.argv[0] + " " def addip(ip): - n = database.NIC(machine=None, mac_addr=randomMAC(), ip=ip, hostname=None) - database.session.save(n) - database.session.flush() + try: + n = database.NIC(machine=None, mac_addr=randomMAC(), ip=ip, hostname=None) + database.session.save(n) + database.session.flush() + except sqlalchemy.exceptions.IntegrityError: + pass if __name__ == '__main__': -- 1.7.9.5 From 2e60cdc0ff93ce9858eed6fdbdf9fff2037d07f1 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Mon, 28 Sep 2009 21:26:38 -0400 Subject: [PATCH 09/16] Punt the "moocow" VNC password - it's dumb, and we already have our own authentication mechanism (that uses real authentication). svn path=/trunk/packages/invirt-web/; revision=2487 --- code/templates/vnc.tmpl | 1 - debian/changelog | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/templates/vnc.tmpl b/code/templates/vnc.tmpl index c61b4f6..78a0bbc 100644 --- a/code/templates/vnc.tmpl +++ b/code/templates/vnc.tmpl @@ -15,7 +15,6 @@ Console to $machine.name

See tips about framebuffer and other issues.

- diff --git a/debian/changelog b/debian/changelog index 7dc3811..1beb4b6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +invirt-web (0.0.22) unstable; urgency=low + + * Don't supply a password to the VNC server, since one is no longer + required. + + -- Evan Broder Mon, 28 Sep 2009 21:24:06 -0400 + invirt-web (0.0.21) unstable; urgency=low [ Quentin Smith ] -- 1.7.9.5 From e3ef118dac44137bda1374d8e124b095d7f6ad06 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Mon, 28 Sep 2009 23:28:28 -0400 Subject: [PATCH 10/16] Revert punting the "moocow" password in invirt-web and invirt-vnc-client, since we can't change the VNC passwod of running VMs. This reverts parts of commit r2487 svn path=/trunk/packages/invirt-web/; revision=2492 --- code/templates/vnc.tmpl | 1 + debian/changelog | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/code/templates/vnc.tmpl b/code/templates/vnc.tmpl index 78a0bbc..c61b4f6 100644 --- a/code/templates/vnc.tmpl +++ b/code/templates/vnc.tmpl @@ -15,6 +15,7 @@ Console to $machine.name

See tips about framebuffer and other issues.

+ diff --git a/debian/changelog b/debian/changelog index 1beb4b6..0a1e9a9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +invirt-web (0.0.23) unstable; urgency=low + + * Revert 0.0.22, since running VMs still have a password set. + + -- Evan Broder Mon, 28 Sep 2009 23:24:00 -0400 + invirt-web (0.0.22) unstable; urgency=low * Don't supply a password to the VNC server, since one is no longer -- 1.7.9.5 From 846195518ab335ada11115dfee10d0de5219cddc Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Sun, 22 Nov 2009 20:54:11 -0500 Subject: [PATCH 11/16] Re-arrange the authz configuration. In particular, even if we allow for mixing of multiple authz mechanisms at some point, you won't have multiple instances of the locker authz type, so the "type" shouldn't be a property of each of the cells we specify how to authenticate against. svn path=/trunk/packages/invirt-web/; revision=2557 --- code/cache_acls.py | 2 +- code/getafsgroups.py | 4 ++-- code/validation.py | 2 +- invirt-cache-acls | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/code/cache_acls.py b/code/cache_acls.py index f92ad91..75f4720 100755 --- a/code/cache_acls.py +++ b/code/cache_acls.py @@ -39,7 +39,7 @@ def expandName(name): return [name] return [] try: - return getafsgroups.getAfsGroupMembers(name, config.authz[0].cell) + return getafsgroups.getAfsGroupMembers(name, config.authz.cells[0].cell) except getafsgroups.AfsProcessError: return [] diff --git a/code/getafsgroups.py b/code/getafsgroups.py index 7067e53..21de4d7 100755 --- a/code/getafsgroups.py +++ b/code/getafsgroups.py @@ -30,8 +30,8 @@ class AfsProcessError(Exception): def getAfsGroupMembers(group, cell): encrypt = True - for c in config.authz: - if c.type == 'afs' and c.cell == cell and hasattr(c, 'auth'): + for c in config.authz.cells: + if c.cell == cell and hasattr(c, 'auth'): encrypt = c.auth subprocess.check_call(['aklog', cell], stdout=subprocess.PIPE, stderr=subprocess.PIPE) p = subprocess.Popen(["pts", "membership", "-encrypt" if encrypt else '-noauth', group, '-c', cell], diff --git a/code/validation.py b/code/validation.py index 0285044..4cbc7c0 100644 --- a/code/validation.py +++ b/code/validation.py @@ -222,7 +222,7 @@ def testAdmin(user, admin, machine): return admin admin = 'system:' + admin try: - if user in getafsgroups.getAfsGroupMembers(admin, config.authz[0].cell): + if user in getafsgroups.getAfsGroupMembers(admin, config.authz.cells[0].cell): return admin except getafsgroups.AfsProcessError, e: errmsg = str(e) diff --git a/invirt-cache-acls b/invirt-cache-acls index b099eca..922d9ba 100755 --- a/invirt-cache-acls +++ b/invirt-cache-acls @@ -1,9 +1,7 @@ #!/bin/sh cells () { - for i in $(invirt-getconf -l authz); do - if [ afs = "$(invirt-getconf authz.$i.type)" ]; then - invirt-getconf authz.$i.cell - fi + for i in $(invirt-getconf -l authz.cells); do + invirt-getconf authz.cells.$i.cell done } kinit -k -t /etc/invirt/keytab daemon/$(hostname -f) -- 1.7.9.5 From 703e83c521982e9c6ebb337694074e0abaf3c7ff Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Mon, 7 Dec 2009 21:33:43 -0500 Subject: [PATCH 12/16] Store AFS cell configuration at authz.afs.cells instead of just authz.cells, to be more clear about purpose. svn path=/trunk/packages/invirt-web/; revision=2590 --- code/cache_acls.py | 2 +- code/getafsgroups.py | 2 +- code/validation.py | 2 +- invirt-cache-acls | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/cache_acls.py b/code/cache_acls.py index 75f4720..7ae4ac8 100755 --- a/code/cache_acls.py +++ b/code/cache_acls.py @@ -39,7 +39,7 @@ def expandName(name): return [name] return [] try: - return getafsgroups.getAfsGroupMembers(name, config.authz.cells[0].cell) + return getafsgroups.getAfsGroupMembers(name, config.authz.afs.cells[0].cell) except getafsgroups.AfsProcessError: return [] diff --git a/code/getafsgroups.py b/code/getafsgroups.py index 21de4d7..fed3a6b 100755 --- a/code/getafsgroups.py +++ b/code/getafsgroups.py @@ -30,7 +30,7 @@ class AfsProcessError(Exception): def getAfsGroupMembers(group, cell): encrypt = True - for c in config.authz.cells: + for c in config.authz.afs.cells: if c.cell == cell and hasattr(c, 'auth'): encrypt = c.auth subprocess.check_call(['aklog', cell], stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/code/validation.py b/code/validation.py index 4cbc7c0..875115c 100644 --- a/code/validation.py +++ b/code/validation.py @@ -222,7 +222,7 @@ def testAdmin(user, admin, machine): return admin admin = 'system:' + admin try: - if user in getafsgroups.getAfsGroupMembers(admin, config.authz.cells[0].cell): + if user in getafsgroups.getAfsGroupMembers(admin, config.authz.afs.cells[0].cell): return admin except getafsgroups.AfsProcessError, e: errmsg = str(e) diff --git a/invirt-cache-acls b/invirt-cache-acls index 922d9ba..79a7650 100755 --- a/invirt-cache-acls +++ b/invirt-cache-acls @@ -1,7 +1,7 @@ #!/bin/sh cells () { - for i in $(invirt-getconf -l authz.cells); do - invirt-getconf authz.cells.$i.cell + for i in $(invirt-getconf -l authz.afs.cells); do + invirt-getconf authz.afs.cells.$i.cell done } kinit -k -t /etc/invirt/keytab daemon/$(hostname -f) -- 1.7.9.5 From b3969219ebe0ca5d9ba6e3015d9c6b750a435631 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Wed, 16 Dec 2009 13:01:46 -0500 Subject: [PATCH 13/16] Bump the version on the invirt-web package since we changed invirt-cache-acls. svn path=/trunk/packages/invirt-web/; revision=2611 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 0a1e9a9..5479ee5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +invirt-web (0.0.24) unstable; urgency=low + + * Update authorization code for new config structure. + + -- Evan Broder Wed, 16 Dec 2009 11:47:13 -0600 + invirt-web (0.0.23) unstable; urgency=low * Revert 0.0.22, since running VMs still have a password set. -- 1.7.9.5 From 134a1150f85e70fa5e7fb8c3780c5b69fb1fe257 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sun, 9 Aug 2009 18:45:18 -0400 Subject: [PATCH 14/16] Depend on python-cherrypy3 and python-mako in preparation of migrating the web site svn path=/package_branches/invirt-web/cherrypy-rebased/; revision=2658 --- debian/changelog | 7 +++++++ debian/control | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 5479ee5..9ac19a3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +invirt-web (0.0.25) unstable; urgency=low + + * Depend on python-cherrypy3 and python-mako in preparation of migrating the + web site. + + -- Quentin Smith Sat, 02 May 2009 22:32:53 -0400 + invirt-web (0.0.24) unstable; urgency=low * Update authorization code for new config structure. diff --git a/debian/control b/debian/control index 386b107..3ae872c 100644 --- a/debian/control +++ b/debian/control @@ -17,7 +17,8 @@ Depends: ${misc:Depends}, debathena-ssl-certificates, # python libraries python-flup, python-cheetah, python-simplejson, - python-dns, python-dnspython, + python-dns, python-dnspython, python-cherrypy3, + python-mako, # misc kstart, debathena-afs-config, openafs-modules-xen, -- 1.7.9.5 From 701fd288f46b5ed9d60c3c5c1f71f22be3bec76d Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sun, 9 Aug 2009 18:45:18 -0400 Subject: [PATCH 15/16] Mako and SimpleJSON CherryPy hooks svn path=/package_branches/invirt-web/cherrypy-rebased/; revision=2659 --- code/view.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 code/view.py diff --git a/code/view.py b/code/view.py new file mode 100644 index 0000000..a375a9e --- /dev/null +++ b/code/view.py @@ -0,0 +1,71 @@ +import os + +import cherrypy +from mako.template import Template +from mako.lookup import TemplateLookup +import simplejson +import datetime, decimal + +class MakoHandler(cherrypy.dispatch.LateParamPageHandler): + """Callable which sets response.body.""" + + def __init__(self, template, next_handler, content_type='text/html; charset=utf-8'): + self.template = template + self.next_handler = next_handler + self.content_type = content_type + + def __call__(self): + env = globals().copy() + env.update(self.next_handler()) + cherrypy.response.headers['Content-Type'] = self.content_type + return self.template.render(**env) + + +class MakoLoader(object): + + def __init__(self): + self.lookups = {} + + def __call__(self, filename, directories, module_directory=None, + collection_size=-1, content_type='text/html; charset=utf-8'): + # Find the appropriate template lookup. + key = (tuple(directories), module_directory) + try: + lookup = self.lookups[key] + except KeyError: + lookup = TemplateLookup(directories=directories, + module_directory=module_directory, + collection_size=collection_size, + default_filters=['decode.utf8'], + input_encoding='utf-8', + output_encoding='utf-8', + ) + self.lookups[key] = lookup + cherrypy.request.lookup = lookup + + # Replace the current handler. + cherrypy.request.template = t = lookup.get_template(filename) + cherrypy.request.handler = MakoHandler(t, cherrypy.request.handler, content_type) + +main = MakoLoader() +cherrypy.tools.mako = cherrypy.Tool('on_start_resource', main) + +class JSONEncoder(simplejson.JSONEncoder): + def default(self, obj): + if isinstance(obj, datetime.datetime): + return str(obj) + elif isinstance(obj, decimal.Decimal): + return float(obj) + else: + return simplejson.JSONEncoder.default(self, obj) + +def jsonify_tool_callback(*args, **kwargs): + if not cherrypy.request.cached: + response = cherrypy.response + response.headers['Content-Type'] = 'text/javascript' + response.body = JSONEncoder().iterencode(response.body) + +cherrypy.tools.jsonify = cherrypy.Tool('before_finalize', jsonify_tool_callback, priority=30) + +class View(object): + _cp_config = {'tools.mako.directories': [os.path.join(os.path.dirname(__file__),'templates')]} -- 1.7.9.5 From 8f7f618a72a975abf592788212301fc315c21d55 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sun, 9 Aug 2009 18:45:19 -0400 Subject: [PATCH 16/16] Basic CherryPy FastCGI handler svn path=/package_branches/invirt-web/cherrypy-rebased/; revision=2660 --- code/main.fcgi | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/code/main.fcgi b/code/main.fcgi index b2c7031..ac34a64 100755 --- a/code/main.fcgi +++ b/code/main.fcgi @@ -1,3 +1,30 @@ #!/usr/bin/python -import main -main.main() +"""Main FastCGI entry point for web interface""" + +import cherrypy +import os +import sys +from main import InvirtWeb + +dev = False +base_dir = os.path.dirname(__file__) + +if __name__=="__main__": + if len(sys.argv) > 1: + conf_file = sys.argv[1] + dev = True + else: + conf_file = os.path.join(base_dir, 'main.conf') + app = cherrypy.tree.mount(InvirtWeb(), '/' if dev else '/main.fcgi') + app.merge(conf_file) + cherrypy.config.update(conf_file) + + if dev: + cherrypy.server.quickstart() + cherrypy.engine.start() + cherrypy.engine.block() + else: + cherrypy.engine.start(blocking=False) + from flup.server.fcgi import WSGIServer + server = WSGIServer(app) + server.run() -- 1.7.9.5