Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/client/etc/xen/sipb-database
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/client/etc/xen/sipb-database	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/client/etc/xen/sipb-database	(revision 244)
@@ -0,0 +1,85 @@
+# -*- mode: python; -*-
+import sipb_xen_database.models as models
+from sipb_xen_database import connect
+import re
+import tempfile
+from subprocess import call
+
+connect('postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen')
+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 = ""
+
+if machine_type.hvm:
+    ioemu = "ioemu:"
+    viftype = "type=ioemu, "
+
+    kernel = 'hvmloader'
+    builder = 'hvm'
+    vnc = 1
+    vncpasswd = 'moocow'
+    device_model = '/usr/sbin/qemu-dm-sipb'
+else:
+    kernel  = '/boot/vmlinuz-2.6.18-4-xen-amd64'
+    ramdisk = '/boot/initrd.img-2.6.18-4-xen-amd64'
+    builder = 'linux'
+
+pae = machine_type.pae
+acpi = machine_type.acpi
+apic = machine_type.apic
+
+vif = []
+
+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)
+
+disk = []
+
+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)
+
+if 'installer' in locals():
+    check(re.match('^[A-Za-z0-9][A-Za-z0-9_.-]*$', installer))
+    tmptree = tempfile.mkdtemp('', 'auto-install.', '/tmp')
+    call(['/usr/sbin/sipb-xen-make-iso', installer, tmptree]
+         + installer_options.split(' '))
+    disk.append('file:'+tmptree+'/install.iso,hdc:cdrom,r')
+    boot = 'd'
+    
+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'
+
+on_poweroff = 'destroy'
+on_reboot = 'restart'
+on_crash = 'destroy'
+if machine.autorestart:
+    on_crash = 'restart'
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/client/usr/sbin/sipb-xen-lvcreate
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/client/usr/sbin/sipb-xen-lvcreate	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/client/usr/sbin/sipb-xen-lvcreate	(revision 244)
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+from sipb_xen_database import *
+import sys
+import os.path
+from subprocess import call
+import re
+
+connect('postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen')
+
+def check(b):
+    if not b:
+        exit(1)
+
+vg = "xenvg"
+for d in Disk.select():
+    check(re.match('^[A-Za-z0-9]+$', d.guest_device_name))
+    machine = Machine.get(d.machine_id)
+    check(re.match('^[A-Za-z0-9][A-Za-z0-9._-]*$', machine.name))
+    lvname = machine.name + "_" + d.guest_device_name
+    if not os.path.exists("/dev/%s/%s" % (vg, lvname)):
+        # LV doesn't exist
+        print >>sys.stderr, "Creating LV %s..." % (lvname,)
+        rv = call(["lvcreate", "-L", str(d.size) + "M", "-n", lvname, vg])
+        if rv != 0:
+            print >>sys.stderr, "Error creating LV %s\n" %(lvname,)
+            sys.exit(1)
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/changelog
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/changelog	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/changelog	(revision 244)
@@ -0,0 +1,95 @@
+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.2/sipb-xen-database/debian/compat
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/compat	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/compat	(revision 244)
@@ -0,0 +1,1 @@
+4
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/control
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/control	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/control	(revision 244)
@@ -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), debhelper (>= 5.0.37.2), cdbs (>= 0.4.43), python-dev (>= 2.3.5-11), python-support (>= 0.3.2), 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
+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}, python-sqlalchemy, python-psycopg2, sipb-xen-database-common
+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.2/sipb-xen-database/debian/control.in
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/control.in	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/control.in	(revision 244)
@@ -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
+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}, python-sqlalchemy, python-psycopg2, sipb-xen-database-common
+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.2/sipb-xen-database/debian/copyright
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/copyright	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/copyright	(revision 244)
@@ -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.2/sipb-xen-database/debian/pycompat
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/pycompat	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/pycompat	(revision 244)
@@ -0,0 +1,1 @@
+2
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/rules
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/rules	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/rules	(revision 244)
@@ -0,0 +1,8 @@
+#!/usr/bin/make -f
+
+DEB_AUTO_UPDATE_DEBIAN_CONTROL = 1
+
+DEB_PYTHON_SYSTEM=pysupport
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/python-distutils.mk
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-client.install
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-client.install	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-client.install	(revision 244)
@@ -0,0 +1,1 @@
+client/* .
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-common.install
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-common.install	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-common.install	(revision 244)
@@ -0,0 +1,2 @@
+common/* .
+debian/tmp/usr/lib/python* usr/lib/
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.install
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.install	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.install	(revision 244)
@@ -0,0 +1,1 @@
+sipb-xen-database-tables usr/bin
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.postinst
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.postinst	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.postinst	(revision 244)
@@ -0,0 +1,47 @@
+#!/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 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
+
+        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.2/sipb-xen-database/debian/sipb-xen-database-server.prerm
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.prerm	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/debian/sipb-xen-database-server.prerm	(revision 244)
@@ -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|upgrade|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
+    ;;
+
+    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.2/sipb-xen-database/setup.py
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/setup.py	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/setup.py	(revision 244)
@@ -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.2/sipb-xen-database/sipb-xen-database-tables
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb-xen-database-tables	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb-xen-database-tables	(revision 244)
@@ -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()
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb_xen_database/__init__.py
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb_xen_database/__init__.py	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb_xen_database/__init__.py	(revision 244)
@@ -0,0 +1,5 @@
+from models import *
+
+def connect(uri):
+    """ Connect to a given database URI"""
+    meta.connect(uri)
Index: /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb_xen_database/models.py
===================================================================
--- /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb_xen_database/models.py	(revision 244)
+++ /package_tags/sipb-xen-database/10.2/sipb-xen-database/sipb_xen_database/models.py	(revision 244)
@@ -0,0 +1,98 @@
+from sqlalchemy import *
+
+from sqlalchemy.ext.sessioncontext import SessionContext
+from sqlalchemy.ext.assignmapper import assign_mapper
+
+__all__ = ['meta',
+           'ctx',
+           'machine_table',
+           'machine_access_table',
+           'nic_table',
+           'disk_table',
+           'types_table',
+           'cdroms_table',
+           'Machine',
+           'MachineAccess',
+           'NIC',
+           'Disk',
+           'Type',
+           'CDROM']
+
+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('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))
+
+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'))
+
+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)
+
+assign_mapper(ctx, Machine, machine_table,
+              properties={'nics': relation(NIC, backref="machine"),
+                          'disks': relation(Disk, backref="machine"),
+                          'type': relation(Type),
+                          'users': relation(MachineAccess, backref="machine")});
+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)
