Index: package_tags/sipb-xen-database/10.15/client/etc/xen/sipb-database
===================================================================
--- package_tags/sipb-xen-database/10.15/client/etc/xen/sipb-database	(revision 833)
+++ package_tags/sipb-xen-database/10.15/client/etc/xen/sipb-database	(revision 833)
@@ -0,0 +1,100 @@
+# -*- mode: python; -*-
+from invirt.database import models, connect
+import re
+import tempfile
+from subprocess import call
+
+connect()
+prefix = "d_"
+
+# 'machine_name', and optionally 'cdrom_image', should get passed in
+# from the xm create call
+
+def check(b):
+    if not b:
+        import sys
+        sys.exit(1)
+
+machine = models.Machine.get_by(name=machine_name)
+check(machine is not None)
+machine_type = models.Type.get_by(type_id=machine.type_id)
+
+memory = machine.memory
+maxmem = memory
+check(re.match('^[A-Za-z0-9][A-Za-z0-9._-]*$', machine.name))
+name = prefix + machine.name
+check(re.match('^[0-9a-f-]+$', machine.uuid))
+uuid = machine.uuid
+
+vcpus = machine.cpus
+
+diskioemu = ""
+viftype = ""
+
+pae = machine_type.pae
+acpi = machine_type.acpi
+apic = machine_type.apic
+
+vif = []
+
+disk = []
+
+if machine_type.hvm:
+    codepath = 'hvm'
+else:
+    codepath = 'paravm'
+
+if 'mirror' in locals(): #Installer
+    disk.append('phy:/dev/xenvg/d_foobar3_hda,hdb,r')
+
+    kernel = '/boot/vmlinuz-2.6.24-19-xen' #From hardy
+    ramdisk = '/boot/initrd.img-2.6.24-19-xen'
+
+    if not machine.nics:
+        raise RuntimeError('You must have a nic to autoinstall')
+    n = machine.nics[0]
+    extra = 'ro noresume'
+    extra += ' ip=%s::18.181.0.1:255.255.0.0:%s:eth0:off' % (n.ip, machine.name)
+    extra += ' mirror=%s dist=%s' % (mirror, dist)
+    extra += ' imagesize=%s' % imagesize
+    if 'noinstall' in locals():
+        extra += ' noinstall'
+    root = '/dev/hdb1'
+    codepath = None
+elif 'cdrom_image' in locals():
+    check(re.match('^[A-Za-z0-9][A-Za-z0-9_.-]*$', cdrom_image))
+    disk.append('file:/srv/images/' + cdrom_image + '.iso,hdc:cdrom,r')
+    boot = 'd'
+    codepath = 'hvm'
+
+if codepath == 'hvm':
+    ioemu = "ioemu:"
+    viftype = "type=ioemu, "
+    kernel = 'hvmloader'
+    builder = 'hvm'
+    vnc = 1
+    vncpasswd = 'moocow'
+    device_model = '/usr/sbin/qemu-dm-sipb'
+    serial = "pty"
+elif codepath == 'paravm':
+    bootloader = '/usr/lib/xen-default/bin/pygrub'
+
+
+for n in machine.nics:
+    check(re.match('^[0-9a-fA-F:]+$', n.mac_addr) and re.match('^[0-9.]*$', n.ip))
+    d = '%smac=%s, ip=%s, bridge=xenbr0, script=vif-sipbroute' % (viftype, n.mac_addr, n.ip)
+    vif.append(d)
+
+for d in machine.disks:
+    check(re.match('^[A-Za-z0-9]+$', d.guest_device_name))
+    device = '/dev/xenvg/' + prefix + machine.name + '_' + d.guest_device_name
+    dspec = 'phy:%s,%s%s,w' % (device, diskioemu, d.guest_device_name)
+    disk.append(dspec)
+
+usbdevice = 'tablet'
+
+on_poweroff = 'destroy'
+on_reboot = 'restart'
+on_crash = 'destroy'
+if machine.autorestart:
+    on_crash = 'restart'
Index: package_tags/sipb-xen-database/10.15/config.todo
===================================================================
--- package_tags/sipb-xen-database/10.15/config.todo	(revision 833)
+++ package_tags/sipb-xen-database/10.15/config.todo	(revision 833)
@@ -0,0 +1,2 @@
+client/etc/xen/sipb-database: gateway, netmask
+sipb-xen-database-tables: db uri
Index: package_tags/sipb-xen-database/10.15/debian/changelog
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/changelog	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/changelog	(revision 833)
@@ -0,0 +1,192 @@
+sipb-xen-database (10.15) unstable; urgency=low
+
+  in /etc/xen/database:
+  * uncommitted changes on black-mesa
+  * sipb_xen_database -> invirt.database
+  * use default db uri
+
+  in invirt.database:
+  * get default db uri from invirt.config
+
+ -- Greg Price <price@mit.edu>  Sun,  3 Aug 2008 00:26:46 -0400
+
+sipb-xen-database (10.14) unstable; urgency=low
+
+  * Rename sipb_xen_database -> invirt.database,
+    keeping old name too for now, for compatibility.
+
+ -- Greg Price <price@mit.edu>  Sat,  2 Aug 2008 23:19:18 -0400
+
+sipb-xen-database (10.13) unstable; urgency=low
+
+  * Modify autoinstalls table to specify distribution/mirror.
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Sat, 21 Jun 2008 21:25:21 -0400
+
+sipb-xen-database (10.12) unstable; urgency=low
+
+  * Add a description field.
+
+ -- Anders Kaseorg <andersk@mit.edu>  Wed, 18 Jun 2008 03:52:49 -0400
+
+sipb-xen-database (10.11) unstable; urgency=low
+
+  * Specify ON DELETE CASCADE
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Fri, 06 Jun 2008 12:25:35 -0400
+
+sipb-xen-database (10.10) unstable; urgency=low
+
+  * Make machine.acl a private relation.
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Fri, 06 Jun 2008 12:03:09 -0400
+
+sipb-xen-database (10.9) unstable; urgency=low
+
+  * Eager loading of relations for better performance.
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Mon, 02 Jun 2008 01:39:11 -0400
+
+sipb-xen-database (10.8) unstable; urgency=low
+
+  * Configure serial console on boot
+
+ -- Quentin Smith <quentin@sipb-xen-dev.mit.edu>  Thu,  1 May 2008 20:21:25 -0400
+
+sipb-xen-database (10.7) unstable; urgency=low
+
+  * Depend on psql client in -client package.
+
+ -- Greg Price <price@mit.edu>  Sat, 26 Apr 2008 21:06:41 -0400
+
+sipb-xen-database (10.6) unstable; urgency=low
+
+  * Support autoinstalls table.
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Mon, 21 Apr 2008 22:34:46 -0400
+
+sipb-xen-database (10.5) unstable; urgency=low
+
+  * Enable USB tablet device in guests.
+
+ -- Anders Kaseorg <andersk@mit.edu>  Mon, 21 Apr 2008 17:39:59 -0400
+
+sipb-xen-database (10.4.1) unstable; urgency=low
+
+  * Actually export the cache clearing function.
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Fri, 28 Mar 2008 21:18:01 -0400
+
+sipb-xen-database (10.4) unstable; urgency=low
+
+  * Ubuntu's dch sucks.
+
+ -- Eric Price <ecprice@sipb-xen-dev.mit.edu>  Fri, 28 Mar 2008 20:43:42 -0400
+
+sipb-xen-database (10.3ubuntu1) gutsy; urgency=low
+
+  * Expose a function for clearing the cache.
+
+ -- Eric Price <ecprice@pseudomyrmex.mit.edu>  Fri, 28 Mar 2008 20:31:06 -0400
+
+sipb-xen-database (10.3) unstable; urgency=low
+
+  * Use 'acl', not 'users', for the reference to the machine_access table.
+
+ -- Eric Price <ecprice@sipb-xen-dev.mit.edu>  Thu, 24 Jan 2008 17:23:33 -0500
+
+sipb-xen-database (10.2) unstable; urgency=low
+
+  * Add MachineAccess to __all__ so it can be imported
+  * Remove unnecessary constructors for database objects
+
+ -- Quentin Smith <quentin@sipb-xen-dev.mit.edu>  Mon, 12 Nov 2007 04:53:47 -0500
+
+sipb-xen-database (10.1) unstable; urgency=low
+
+  * Make sipb-xen-database-tables safer (don't default to drop_all)
+
+ -- Quentin Smith <quentin@sipb-xen-dev.mit.edu>  Mon, 12 Nov 2007 04:39:59 -0500
+
+sipb-xen-database (10) unstable; urgency=low
+
+  * Added a machine_access table for cached ACLs
+
+ -- Quentin Smith <quentin@sipb-xen-dev.mit.edu>  Mon, 12 Nov 2007 04:24:35 -0500
+
+sipb-xen-database (9.0) unstable; urgency=low
+
+  * No changes.
+
+ -- Eric Price <ecprice@sipb-xen-dev.mit.edu>  Wed, 10 Oct 2007 00:17:20 -0400
+
+sipb-xen-database (9) unstable; urgency=low
+
+  * Add administrator column and backrefs to machine.
+
+ -- Eric Price <ecprice@sipb-xen-dev.mit.edu>  Wed, 10 Oct 2007 00:11:47 -0400
+
+sipb-xen-database (8) gutsy; urgency=low
+
+  * Prepend d_ to database VMs.
+
+ -- Eric Price <ecprice@sipb-xen-dev.mit.edu>  Tue,  9 Oct 2007 02:35:51 -0400
+
+sipb-xen-database (7.00002) gutsy; urgency=low
+
+  * Actually import re.
+
+ -- Anders Kaseorg <andersk@mit.edu>  Sun, 07 Oct 2007 04:34:07 -0400
+
+sipb-xen-database (7.00001) gutsy; urgency=low
+
+  * import re.
+
+ -- Anders Kaseorg <andersk@mit.edu>  Sun, 07 Oct 2007 03:40:25 -0400
+
+sipb-xen-database (7) unstable; urgency=low
+
+  * nics primary key should be mac address, not hostname.
+  * Make ip unique, and constructor for nics.
+  * Add a table for boot CDs.
+  * Add cdrom_image parameter.
+  * Regex sanity checking.
+
+ -- Anders Kaseorg <andersk@mit.edu>  Sun, 07 Oct 2007 03:18:30 -0400
+
+sipb-xen-database (6) unstable; urgency=low
+
+  * Adding a script to create lvm volumes
+
+ -- Nelson Elhage <nelhage@mit.edu>  Sat, 22 Sep 2007 13:59:36 -0400
+
+sipb-xen-database (5) unstable; urgency=low
+
+  * Change the host from sipb-vm-1 to sipb-xen-dev
+
+ -- Nelson Elhage <nelhage@mit.edu>  Sat,  8 Sep 2007 16:16:07 -0400
+
+sipb-xen-database (4) unstable; urgency=low
+
+  * Add script=vif-sipbroute to our vif lines
+
+ -- Nelson Elhage <nelhage@mit.edu>  Fri, 24 Aug 2007 22:07:18 -0400
+
+sipb-xen-database (3) unstable; urgency=low
+
+  * Add a connect() line to sipb-database
+  * Fix some other bugs in sipb-database
+
+ -- Nelson Elhage <nelhage@mit.edu>  Sun, 19 Aug 2007 19:40:08 -0400
+
+sipb-xen-database (2) unstable; urgency=low
+
+  * Fix the postinit and prerm scripts to create a sipb-xen user
+
+ -- Nelson Elhage <nelhage@mit.edu>  Thu, 16 Aug 2007 16:27:36 -0400
+
+sipb-xen-database (1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Nelson Elhage <nelhage@mit.edu>  Sun, 15 Jul 2007 16:01:16 -0400
Index: package_tags/sipb-xen-database/10.15/debian/compat
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/compat	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/compat	(revision 833)
@@ -0,0 +1,1 @@
+4
Index: package_tags/sipb-xen-database/10.15/debian/control
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/control	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/control	(revision 833)
@@ -0,0 +1,26 @@
+Source: sipb-xen-database
+Section: net
+Priority: extra
+Maintainer: SIPB Xen Project <sipb-xen@mit.edu>
+Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 4.2.0), python-support (>= 0.5.3)
+Standards-Version: 3.7.2
+
+Package: sipb-xen-database-common
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}, python-sqlalchemy, python-psycopg2
+Provides: ${python:Provides}
+Description: Installs the SIPB Xen database schema files
+ This contains the python modules to access the SIPB Xen database
+
+Package: sipb-xen-database-server
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}, postgresql-8.1, python-sqlalchemy, python-psycopg2, sipb-xen-database-common, adduser
+Description: Installs the SIPB Xen database server
+ This tracks all the user VMs and is accessed from the VM host
+
+Package: sipb-xen-database-client
+Architecture: all
+Depends: ${misc:Depends}, postgresql-client-8.1, python-sqlalchemy, python-psycopg2, sipb-xen-database-common, python
+Description: Installs the SIPB Xen database configuration file
+ This is a python xen configuration script that talks to the database
+ to dynamically load xen domU configuration information
Index: package_tags/sipb-xen-database/10.15/debian/control.in
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/control.in	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/control.in	(revision 833)
@@ -0,0 +1,26 @@
+Source: sipb-xen-database
+Section: net
+Priority: extra
+Maintainer: SIPB Xen Project <sipb-xen@mit.edu>
+Build-Depends: @cdbs@, python-support (>= 0.5.3)
+Standards-Version: 3.7.2
+
+Package: sipb-xen-database-common
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}, python-sqlalchemy, python-psycopg2
+Provides: ${python:Provides}
+Description: Installs the SIPB Xen database schema files
+ This contains the python modules to access the SIPB Xen database
+
+Package: sipb-xen-database-server
+Architecture: all
+Depends: ${misc:Depends}, ${python:Depends}, postgresql-8.1, python-sqlalchemy, python-psycopg2, sipb-xen-database-common, adduser
+Description: Installs the SIPB Xen database server
+ This tracks all the user VMs and is accessed from the VM host
+
+Package: sipb-xen-database-client
+Architecture: all
+Depends: ${misc:Depends}, postgresql-client-8.1, python-sqlalchemy, python-psycopg2, sipb-xen-database-common, python
+Description: Installs the SIPB Xen database configuration file
+ This is a python xen configuration script that talks to the database
+ to dynamically load xen domU configuration information
Index: package_tags/sipb-xen-database/10.15/debian/copyright
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/copyright	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/copyright	(revision 833)
@@ -0,0 +1,3 @@
+This package was created for internal use of the SIPB Xen Project of
+the MIT Student Information Processing Board.  Ask tabbott@mit.edu if
+you have questions about redistribution.
Index: package_tags/sipb-xen-database/10.15/debian/pycompat
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/pycompat	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/pycompat	(revision 833)
@@ -0,0 +1,1 @@
+2
Index: package_tags/sipb-xen-database/10.15/debian/rules
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/rules	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/rules	(revision 833)
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+
+DEB_AUTO_UPDATE_DEBIAN_CONTROL = 1
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+
+binary-install/sipb-xen-database-common::
+	dh_pysupport -psipb-xen-database-common
Index: package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-client.install
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-client.install	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-client.install	(revision 833)
@@ -0,0 +1,1 @@
+client/* .
Index: package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-common.install
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-common.install	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-common.install	(revision 833)
@@ -0,0 +1,3 @@
+common/* .
+python/* usr/share/python-support/sipb-xen-database-common/invirt/
+python/database/* usr/share/python-support/sipb-xen-database-common/sipb_xen_database/
Index: package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.install
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.install	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.install	(revision 833)
@@ -0,0 +1,1 @@
+sipb-xen-database-tables usr/bin
Index: package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.postinst
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.postinst	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.postinst	(revision 833)
@@ -0,0 +1,49 @@
+#!/bin/sh
+# postinst script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    configure)
+        #Don't create users on upgrade
+        if [ -z "$2" ]; then
+            # Don't fail if the user/database already exists
+            su postgres -c 'createuser sipb-xen -S -d -R'    || true
+            su postgres -c 'createdb sipb_xen -O sipb-xen'   || true
+            adduser --system sipb-xen
+        fi
+        su sipb-xen -s /bin/sh -c 'sipb-xen-database-tables create'
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
Index: package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.prerm
===================================================================
--- package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.prerm	(revision 833)
+++ package_tags/sipb-xen-database/10.15/debian/sipb-xen-database-server.prerm	(revision 833)
@@ -0,0 +1,45 @@
+#!/bin/sh
+# prerm script for #PACKAGE#
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    remove|deconfigure)
+
+        # This will destroy data -- do we want to do this?
+        # su postgres -c 'dropdb sipb_xen'
+        # su postgres -c 'dropuser sipb-xen'
+        deluser sipb-xen
+    ;;
+
+    upgrade|failed-upgrade)
+    ;;
+
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
Index: package_tags/sipb-xen-database/10.15/python/database/__init__.py
===================================================================
--- package_tags/sipb-xen-database/10.15/python/database/__init__.py	(revision 833)
+++ package_tags/sipb-xen-database/10.15/python/database/__init__.py	(revision 833)
@@ -0,0 +1,6 @@
+from invirt.config import structs as config
+from models import *
+
+def connect(uri = config.db.uri):
+    """ Connect to a given database URI"""
+    meta.connect(uri)
Index: package_tags/sipb-xen-database/10.15/python/database/models.py
===================================================================
--- package_tags/sipb-xen-database/10.15/python/database/models.py	(revision 833)
+++ package_tags/sipb-xen-database/10.15/python/database/models.py	(revision 833)
@@ -0,0 +1,123 @@
+from sqlalchemy import *
+
+from sqlalchemy.ext.sessioncontext import SessionContext
+from sqlalchemy.ext.assignmapper import assign_mapper
+
+__all__ = ['meta',
+           'ctx',
+           'clear_cache',
+           'machine_table',
+           'machine_access_table',
+           'nic_table',
+           'disk_table',
+           'types_table',
+           'cdroms_table',
+           'autoinstalls_table',
+           'Machine',
+           'MachineAccess',
+           'NIC',
+           'Disk',
+           'Type',
+           'CDROM',
+           'Autoinstall',
+           ]
+
+meta = DynamicMetaData()
+ctx = SessionContext(create_session)
+
+machine_table = Table('machines', meta,
+       Column('machine_id', Integer, primary_key=True, nullable=False),
+       Column('name', String, nullable=False),
+       Column('description', String, nullable=False),
+       Column('memory', Integer, nullable=False),
+       Column('owner', String, nullable=False),
+       Column('contact', String, nullable=False),
+       Column('uuid', String, nullable=False),
+       Column('administrator', String, nullable=False, default=False),
+       Column('type_id', String, ForeignKey('types.type_id'), nullable=False),
+       Column('autorestart', Boolean, nullable=False, default=False),
+       Column('cpus', Integer, nullable=False, default=1))
+
+nic_table = Table('nics', meta,
+       Column('machine_id', Integer, ForeignKey('machines.machine_id'), nullable=True),
+       Column('mac_addr', String, nullable=False, primary_key=True),
+       Column('ip', String, nullable=False, unique=True),
+       Column('hostname', String, nullable=True))
+
+disk_table = Table('disks', meta,
+       Column('machine_id', Integer, ForeignKey('machines.machine_id'), nullable=False),
+       Column('guest_device_name', String, nullable=False),
+       Column('size', Integer, nullable=False),
+       PrimaryKeyConstraint('machine_id', 'guest_device_name'))
+
+types_table = Table('types', meta,
+       Column('type_id', String, primary_key=True, nullable=False),
+       Column('description', String, nullable=False),
+       Column('hvm', Boolean, nullable=False),
+       Column('apic', Boolean, nullable=False),
+       Column('acpi', Boolean, nullable=False),
+       Column('pae', Boolean, nullable=False))
+
+cdroms_table = Table('cdroms', meta,
+       Column('cdrom_id', String, primary_key=True, nullable=False),
+       Column('description', String, nullable=False))
+
+autoinstalls_table = Table('autoinstalls', meta,
+       Column('autoinstall_id', String, primary_key=True, nullable=False),
+       Column('description', String, nullable=False),
+       Column('type_id', String, ForeignKey('types.type_id'), nullable=False),
+       Column('distribution', String, nullable=False),
+       Column('mirror', String, nullable=False))
+
+machine_access_table = Table('machine_access', meta,
+       Column('machine_id', Integer, ForeignKey('machines.machine_id'), nullable=False, index=True),
+       Column('user', String, nullable=False, index=True),
+       PrimaryKeyConstraint('machine_id', 'user', ondelete='CASCADE'))
+
+class Machine(object):
+    def __repr__(self):
+        return "<Machine %s: name='%s' owner='%s'>" % (self.machine_id, self.name, self.owner)
+
+class MachineAccess(object):
+    def __repr__(self):
+        return "<MachineAccess machine='%s' user='%s'>" % (self.machine, self.user)
+
+class NIC(object):
+    def __repr__(self):
+        return "<NIC: mac='%s' machine='%s' ip='%s' hostname='%s'>" % (self.mac_addr, self.machine_id, self.ip, self.hostname)
+
+class Disk(object):
+    def __repr__(self):
+        return "<Disk: machine=%s device=%s size=%s>" % (self.machine_id, self.guest_device_name, self.size)
+
+class Type(object):
+    def __repr__(self):
+        return "<Type %s: %s>" % (self.type_id, self.description)
+
+class CDROM(object):
+    def __repr__(self):
+        return "<CDROM %s: %s>" % (self.cdrom_id, self.description)
+
+class Autoinstall(object):
+    def __repr__(self):
+        return "<Autoinstall %s: %s (%s)>" % (self.autoinstall_id, self.description, self.type.type_id)
+
+assign_mapper(ctx, Machine, machine_table,
+              properties={'nics': relation(NIC, backref="machine", lazy=False),
+                          'disks': relation(Disk, backref="machine", lazy=False),
+                          'type': relation(Type, lazy=False),
+                          'acl': relation(MachineAccess, backref="machine", lazy=False, passive_deletes=True, cascade="all, delete-orphan")});
+assign_mapper(ctx, MachineAccess, machine_access_table)
+assign_mapper(ctx, NIC, nic_table)
+assign_mapper(ctx, Disk, disk_table)
+assign_mapper(ctx, Type, types_table)
+assign_mapper(ctx, CDROM, cdroms_table)
+assign_mapper(ctx, Autoinstall, autoinstalls_table)
+
+def clear_cache():
+    """Clear sqlalchemy's cache.
+
+    This _seems_ to be the way; it works, but the docs don't mention
+    it.  Why is this so obscure?"""
+
+    ctx.registry.clear()
Index: package_tags/sipb-xen-database/10.15/setup.py
===================================================================
--- package_tags/sipb-xen-database/10.15/setup.py	(revision 833)
+++ package_tags/sipb-xen-database/10.15/setup.py	(revision 833)
@@ -0,0 +1,5 @@
+from distutils.core import setup
+setup(name='sipb_xen_database',
+      version='0.1',
+      packages=['sipb_xen_database'],
+      )
Index: package_tags/sipb-xen-database/10.15/sipb-xen-database-tables
===================================================================
--- package_tags/sipb-xen-database/10.15/sipb-xen-database-tables	(revision 833)
+++ package_tags/sipb-xen-database/10.15/sipb-xen-database-tables	(revision 833)
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+from sipb_xen_database import *
+import sys
+
+def usage():
+    print >>sys.stderr, "Usage: %s [create|drop]" %(sys.argv[0],)
+    sys.exit(-1)
+
+if len(sys.argv) == 1:
+    usage()
+
+connect('postgres://sipb-xen@/sipb_xen')
+
+if sys.argv[1] == "create":
+    meta.create_all()
+elif sys.argv[1] == "drop":
+    meta.drop_all()
+else:
+    usage()
