launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06735
[Merge] lp:~rvb/maas/maas-south into lp:maas
Raphaël Badin has proposed merging lp:~rvb/maas/maas-south into lp:maas.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~rvb/maas/maas-south/+merge/97840
This branch uses South to manage database migrations in MAAS. The files in src/*/migrations/ (except from the header) are autogenerated by South (they simply correspond to a copy - in the South format - of the current db structure), they were generated by running "./bin/maas schemamigration maasserver --initial && ./bin/maas schemamigration metadataserver --initial".
I'm planning to wait for a consensus on whether or not our db structure is ok for 12.04 before landing this. If we have to make changes to the db we will have to modifiy this branch:
- remove the file in src/*/migrations/
- run "./bin/maas schemamigration maasserver --initial && ./bin/maas schemamigration metadataserver --initial"
- add back the header in src/*/migrations/
--
https://code.launchpad.net/~rvb/maas/maas-south/+merge/97840
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rvb/maas/maas-south into lp:maas.
=== modified file 'HACKING.txt'
--- HACKING.txt 2012-03-15 22:43:55 +0000
+++ HACKING.txt 2012-03-16 10:57:27 +0000
@@ -39,7 +39,7 @@
python-django-south python-twisted python-txamqp python-amqplib \
python-formencode python-oauth python-oops python-oops-datedir-repo \
python-twisted python-oops-wsgi python-oops-twisted \
- python-psycopg2 python-yaml python-convoy
+ python-psycopg2 python-yaml python-convoy python-django-south
Additionally, you need to install the following python libraries
for development convenience::
=== modified file 'Makefile'
--- Makefile 2012-03-15 22:43:55 +0000
+++ Makefile 2012-03-16 10:57:27 +0000
@@ -108,7 +108,7 @@
bin/maas shell --settings=maas.demo
syncdb: bin/maas dev-db
- bin/maas syncdb --noinput
+ bin/maas syncdb --noinput --migrate
checkbox: config=checkbox/plugins/jobs_info/directories=$(PWD)/qa/checkbox
checkbox:
=== modified file 'src/maas/settings.py'
--- src/maas/settings.py 2012-03-15 17:30:53 +0000
+++ src/maas/settings.py 2012-03-16 10:57:27 +0000
@@ -236,6 +236,7 @@
'maasserver',
'metadataserver',
'piston',
+ 'south',
)
if DEBUG:
=== modified file 'src/maasserver/fields.py'
--- src/maasserver/fields.py 2012-02-29 19:00:41 +0000
+++ src/maasserver/fields.py 2012-03-16 10:57:27 +0000
@@ -28,6 +28,7 @@
)
from django.forms import RegexField
import psycopg2.extensions
+from south.modelsinspector import add_introspection_rules
mac_re = re.compile(r'^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$')
@@ -39,6 +40,17 @@
validate_mac = RegexValidator(regex=mac_re, message=mac_error_msg)
+# The MACAddressField and the JSONObjectField don't introduce any new
+# parameter compared to their parent's constructors so South will handle
+# them just fine.
+# See http://south.aeracode.org/docs/customfields.html#extending-introspection
+# for details.
+add_introspection_rules(
+ [],
+ ["^maasserver\.fields\.MACAddressField",
+ "^maasserver\.fields\.JSONObjectField"])
+
+
class MACAddressFormField(RegexField):
def __init__(self, *args, **kwargs):
=== added directory 'src/maasserver/migrations'
=== added file 'src/maasserver/migrations/0001_initial.py'
--- src/maasserver/migrations/0001_initial.py 1970-01-01 00:00:00 +0000
+++ src/maasserver/migrations/0001_initial.py 2012-03-16 10:57:27 +0000
@@ -0,0 +1,190 @@
+# Copyright 2012 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Initial maasserver migration."""
+
+from __future__ import (
+ print_function,
+ # This breaks South.
+ #unicode_literals,
+ )
+
+__metaclass__ = type
+__all__ = []
+
+# flake8: noqa
+# SKIP this file when reformatting.
+# The rest of this file was generated by South.
+
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'Node'
+ db.create_table('maasserver_node', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('created', self.gf('django.db.models.fields.DateField')()),
+ ('updated', self.gf('django.db.models.fields.DateTimeField')()),
+ ('system_id', self.gf('django.db.models.fields.CharField')(default=u'node-abe5fcd0-6f3a-11e1-b5bf-00219bd0a2de', unique=True, max_length=41)),
+ ('hostname', self.gf('django.db.models.fields.CharField')(default=u'', max_length=255, blank=True)),
+ ('status', self.gf('django.db.models.fields.IntegerField')(default=0, max_length=10)),
+ ('owner', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['auth.User'], null=True, blank=True)),
+ ('after_commissioning_action', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('architecture', self.gf('django.db.models.fields.CharField')(default=u'i386', max_length=10)),
+ ('power_type', self.gf('django.db.models.fields.CharField')(default=u'', max_length=10, blank=True)),
+ ))
+ db.send_create_signal('maasserver', ['Node'])
+
+ # Adding model 'MACAddress'
+ db.create_table('maasserver_macaddress', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('created', self.gf('django.db.models.fields.DateField')()),
+ ('updated', self.gf('django.db.models.fields.DateTimeField')()),
+ ('mac_address', self.gf('maasserver.fields.MACAddressField')()),
+ ('node', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['maasserver.Node'])),
+ ))
+ db.send_create_signal('maasserver', ['MACAddress'])
+
+ # Adding model 'UserProfile'
+ db.create_table('maasserver_userprofile', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)),
+ ))
+ db.send_create_signal('maasserver', ['UserProfile'])
+
+ # Adding model 'SSHKeys'
+ db.create_table('maasserver_sshkeys', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['maasserver.UserProfile'])),
+ ('key', self.gf('django.db.models.fields.TextField')()),
+ ))
+ db.send_create_signal('maasserver', ['SSHKeys'])
+
+ # Adding model 'FileStorage'
+ db.create_table('maasserver_filestorage', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('filename', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)),
+ ('data', self.gf('django.db.models.fields.files.FileField')(max_length=255)),
+ ))
+ db.send_create_signal('maasserver', ['FileStorage'])
+
+ # Adding model 'Config'
+ db.create_table('maasserver_config', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('value', self.gf('maasserver.fields.JSONObjectField')(null=True)),
+ ))
+ db.send_create_signal('maasserver', ['Config'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'Node'
+ db.delete_table('maasserver_node')
+
+ # Deleting model 'MACAddress'
+ db.delete_table('maasserver_macaddress')
+
+ # Deleting model 'UserProfile'
+ db.delete_table('maasserver_userprofile')
+
+ # Deleting model 'SSHKeys'
+ db.delete_table('maasserver_sshkeys')
+
+ # Deleting model 'FileStorage'
+ db.delete_table('maasserver_filestorage')
+
+ # Deleting model 'Config'
+ db.delete_table('maasserver_config')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'maasserver.config': {
+ 'Meta': {'object_name': 'Config'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'value': ('maasserver.fields.JSONObjectField', [], {'null': 'True'})
+ },
+ 'maasserver.filestorage': {
+ 'Meta': {'object_name': 'FileStorage'},
+ 'data': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+ 'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ 'maasserver.macaddress': {
+ 'Meta': {'object_name': 'MACAddress'},
+ 'created': ('django.db.models.fields.DateField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mac_address': ('maasserver.fields.MACAddressField', [], {}),
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['maasserver.Node']"}),
+ 'updated': ('django.db.models.fields.DateTimeField', [], {})
+ },
+ 'maasserver.node': {
+ 'Meta': {'object_name': 'Node'},
+ 'after_commissioning_action': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'architecture': ('django.db.models.fields.CharField', [], {'default': "u'i386'", 'max_length': '10'}),
+ 'created': ('django.db.models.fields.DateField', [], {}),
+ 'hostname': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'power_type': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '10', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '10'}),
+ 'system_id': ('django.db.models.fields.CharField', [], {'default': "u'node-abe7a9cc-6f3a-11e1-b5bf-00219bd0a2de'", 'unique': 'True', 'max_length': '41'}),
+ 'updated': ('django.db.models.fields.DateTimeField', [], {})
+ },
+ 'maasserver.sshkeys': {
+ 'Meta': {'object_name': 'SSHKeys'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.TextField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['maasserver.UserProfile']"})
+ },
+ 'maasserver.userprofile': {
+ 'Meta': {'object_name': 'UserProfile'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
+ }
+ }
+
+ complete_apps = ['maasserver']
=== added file 'src/maasserver/migrations/__init__.py'
=== modified file 'src/maastesting/testcase.py'
--- src/maastesting/testcase.py 2012-03-13 05:34:38 +0000
+++ src/maastesting/testcase.py 2012-03-16 10:57:27 +0000
@@ -17,7 +17,7 @@
import unittest
from django.conf import settings
-from django.core.management import call_command
+from django.core.management.commands.syncdb import Command
from django.db.models import loading
import django.test
import testresources
@@ -81,7 +81,8 @@
assert self.app is not None, "TestCase.app must be defined!"
settings.INSTALLED_APPS.append(self.app)
loading.cache.loaded = False
- call_command('syncdb', interactive=False, verbosity=0)
+ # Use Django's 'syncdb' rather than South's.
+ Command().handle_noargs(verbosity=0, interactive=False)
super(TestModelTestCase, self)._pre_setup()
def _post_teardown(self):
=== modified file 'src/metadataserver/fields.py'
--- src/metadataserver/fields.py 2012-02-29 17:31:38 +0000
+++ src/metadataserver/fields.py 2012-03-16 10:57:27 +0000
@@ -22,6 +22,7 @@
Field,
SubfieldBase,
)
+from south.modelsinspector import add_introspection_rules
class Bin(bytes):
@@ -52,6 +53,13 @@
super(Bin, self).__init__(initializer)
+# The BinaryField does not introduce any new parameter compared to its
+# parent's constructor so South will handle it just fine.
+# See http://south.aeracode.org/docs/customfields.html#extending-introspection
+# for details.
+add_introspection_rules([], ["^metadataserver\.fields\.BinaryField"])
+
+
class BinaryField(Field):
"""A field that stores binary data.
=== added directory 'src/metadataserver/migrations'
=== added file 'src/metadataserver/migrations/0001_initial.py'
--- src/metadataserver/migrations/0001_initial.py 1970-01-01 00:00:00 +0000
+++ src/metadataserver/migrations/0001_initial.py 2012-03-16 10:57:27 +0000
@@ -0,0 +1,145 @@
+# Copyright 2012 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Initial metadataserver migration."""
+
+from __future__ import (
+ print_function,
+ # This breaks South.
+ #unicode_literals,
+ )
+
+__metaclass__ = type
+__all__ = []
+
+# flake8: noqa
+# SKIP this file when reformatting.
+# The rest of this file was generated by South.
+
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'NodeKey'
+ db.create_table('metadataserver_nodekey', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('node', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['maasserver.Node'], unique=True)),
+ ('token', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['piston.Token'], unique=True)),
+ ('key', self.gf('django.db.models.fields.CharField')(unique=True, max_length=18)),
+ ))
+ db.send_create_signal('metadataserver', ['NodeKey'])
+
+ # Adding model 'NodeUserData'
+ db.create_table('metadataserver_nodeuserdata', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('node', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['maasserver.Node'], unique=True)),
+ ('data', self.gf('metadataserver.fields.BinaryField')()),
+ ))
+ db.send_create_signal('metadataserver', ['NodeUserData'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'NodeKey'
+ db.delete_table('metadataserver_nodekey')
+
+ # Deleting model 'NodeUserData'
+ db.delete_table('metadataserver_nodeuserdata')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'maasserver.node': {
+ 'Meta': {'object_name': 'Node'},
+ 'after_commissioning_action': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'architecture': ('django.db.models.fields.CharField', [], {'default': "u'i386'", 'max_length': '10'}),
+ 'created': ('django.db.models.fields.DateField', [], {}),
+ 'hostname': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'power_type': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '10', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '10'}),
+ 'system_id': ('django.db.models.fields.CharField', [], {'default': "u'node-b5811680-6f3a-11e1-baa5-00219bd0a2de'", 'unique': 'True', 'max_length': '41'}),
+ 'updated': ('django.db.models.fields.DateTimeField', [], {})
+ },
+ 'metadataserver.nodekey': {
+ 'Meta': {'object_name': 'NodeKey'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '18'}),
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['maasserver.Node']", 'unique': 'True'}),
+ 'token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['piston.Token']", 'unique': 'True'})
+ },
+ 'metadataserver.nodeuserdata': {
+ 'Meta': {'object_name': 'NodeUserData'},
+ 'data': ('metadataserver.fields.BinaryField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['maasserver.Node']", 'unique': 'True'})
+ },
+ 'piston.consumer': {
+ 'Meta': {'object_name': 'Consumer'},
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '18'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'secret': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '16'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'consumers'", 'null': 'True', 'to': "orm['auth.User']"})
+ },
+ 'piston.token': {
+ 'Meta': {'object_name': 'Token'},
+ 'callback': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'callback_confirmed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'consumer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['piston.Consumer']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '18'}),
+ 'secret': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+ 'timestamp': ('django.db.models.fields.IntegerField', [], {'default': '1331883374L'}),
+ 'token_type': ('django.db.models.fields.IntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tokens'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'verifier': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+ }
+ }
+
+ complete_apps = ['metadataserver']
=== added file 'src/metadataserver/migrations/__init__.py'
Follow ups