diff options
35 files changed, 407 insertions, 34 deletions
diff --git a/devel/management/commands/pgp_import.py b/devel/management/commands/pgp_import.py index faa9ff5e..3f557fe9 100644 --- a/devel/management/commands/pgp_import.py +++ b/devel/management/commands/pgp_import.py @@ -134,7 +134,7 @@ def import_keys(keyring): logger.info("creating or finding %d keys", len(keydata)) created_ct = updated_ct = 0 - with transaction.commit_on_success(): + with transaction.atomic(): finder = UserFinder() # we are dependent on parents coming before children; parse_keydata # uses an OrderedDict to ensure this is the case. @@ -232,7 +232,7 @@ def import_signatures(keyring): logger.info("creating or finding up to %d signatures", len(pruned_edges)) created_ct = updated_ct = 0 - with transaction.commit_on_success(): + with transaction.atomic(): for edge in pruned_edges: sig, created = PGPSignature.objects.get_or_create( signer=edge.signer, signee=edge.signee, diff --git a/devel/management/commands/rematch_developers.py b/devel/management/commands/rematch_developers.py index 2b379588..7a06e084 100644 --- a/devel/management/commands/rematch_developers.py +++ b/devel/management/commands/rematch_developers.py @@ -44,7 +44,7 @@ class Command(NoArgsCommand): match_packager(finder) match_flagrequest(finder) -@transaction.commit_on_success +@transaction.atomic def match_packager(finder): logger.info("getting all unmatched packager strings") package_count = matched_count = 0 @@ -70,7 +70,7 @@ def match_packager(finder): package_count, matched_count) -@transaction.commit_on_success +@transaction.atomic def match_flagrequest(finder): logger.info("getting all flag request email addresses from unknown users") req_count = matched_count = 0 diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py index ff7a8427..2b565cfc 100644 --- a/devel/management/commands/reporead.py +++ b/devel/management/commands/reporead.py @@ -13,6 +13,7 @@ Example: ./manage.py reporead i686 /tmp/core.db.tar.gz """ +from base64 import b64decode from collections import defaultdict from copy import copy import io @@ -217,7 +218,7 @@ def populate_pkg(dbpkg, repopkg, force=False, timestamp=None): dbpkg.packager_str = repopkg.packager # attempt to find the corresponding django user for this string dbpkg.packager = finder.find(repopkg.packager) - dbpkg.pgp_signature = repopkg.pgpsig + dbpkg.signature_bytes = b64decode(repopkg.pgpsig.encode('utf-8')) if timestamp: dbpkg.last_update = timestamp @@ -302,7 +303,7 @@ def update_common(archname, reponame, pkgs, sanity_check=True): # If isolation level is repeatable-read, we need to ensure each package # update starts a new transaction and re-queries the database as # necessary to guard against simultaneous updates. - with transaction.commit_on_success(): + with transaction.atomic(): # force the transaction dirty, even though we will only do reads transaction.set_dirty() @@ -365,7 +366,7 @@ def db_update(archname, reponame, pkgs, force=False): dbpkg = Package(pkgname=pkg.name, arch=architecture, repo=repository, created=timestamp) try: - with transaction.commit_on_success(): + with transaction.atomic(): populate_pkg(dbpkg, pkg, timestamp=timestamp) Update.objects.log_update(None, dbpkg) except IntegrityError: @@ -380,7 +381,7 @@ def db_update(archname, reponame, pkgs, force=False): for pkgname in (dbset - syncset): logger.info("Removing package %s", pkgname) dbpkg = dbdict[pkgname] - with transaction.commit_on_success(): + with transaction.atomic(): Update.objects.log_update(dbpkg, None) # no race condition here as long as simultaneous threads both # issue deletes; second delete will be a no-op @@ -403,7 +404,7 @@ def db_update(archname, reponame, pkgs, force=False): # The odd select_for_update song and dance here are to ensure # simultaneous updates don't happen on a package, causing # files/depends/all related items to be double-imported. - with transaction.commit_on_success(): + with transaction.atomic(): dbpkg = Package.objects.select_for_update().get(id=dbpkg.id) if not force and pkg_same_version(pkg, dbpkg): logger.debug("Package %s was already updated", pkg.name) @@ -431,7 +432,7 @@ def filesonly_update(archname, reponame, pkgs, force=False): # The odd select_for_update song and dance here are to ensure # simultaneous updates don't happen on a package, causing # files to be double-imported. - with transaction.commit_on_success(): + with transaction.atomic(): if not dbpkg.files_last_update or not dbpkg.last_update: pass elif not force and dbpkg.files_last_update >= dbpkg.last_update: diff --git a/devel/management/commands/reporead_inotify.py b/devel/management/commands/reporead_inotify.py index 6aa4e0e0..e3c720bc 100644 --- a/devel/management/commands/reporead_inotify.py +++ b/devel/management/commands/reporead_inotify.py @@ -66,7 +66,7 @@ class Command(BaseCommand): if hasattr(thread, 'cancel'): thread.cancel() - @transaction.commit_on_success + @transaction.atomic def setup_notifier(self): '''Set up and configure the inotify machinery and logic. This takes the provided or default path_template and builds a list of diff --git a/devel/views.py b/devel/views.py index b6e85822..29954b51 100644 --- a/devel/views.py +++ b/devel/views.py @@ -167,7 +167,7 @@ def change_profile(request): request.user.email = form.cleaned_data['email'] if form.cleaned_data['passwd1']: request.user.set_password(form.cleaned_data['passwd1']) - with transaction.commit_on_success(): + with transaction.atomic(): request.user.save() profile_form.save() return HttpResponseRedirect('/devel/') @@ -275,7 +275,7 @@ def report(request, report_name, username=None): cutoff = timedelta(hours=24) filtered = [] packages = packages.select_related( - 'arch', 'repo', 'packager').filter(pgp_signature__isnull=False) + 'arch', 'repo', 'packager').filter(signature_bytes__isnull=False) known_keys = DeveloperKey.objects.select_related( 'owner').filter(owner__isnull=False) known_keys = {dk.key: dk for dk in known_keys} @@ -335,7 +335,7 @@ def new_user_form(request): if request.POST: form = NewUserForm(request.POST) if form.is_valid(): - with transaction.commit_on_success(): + with transaction.atomic(): form.save() log_addition(request, form.instance.user) return HttpResponseRedirect('/admin/auth/user/%d/' % \ diff --git a/main/migrations/0065_auto__add_field_package_signature_bytes.py b/main/migrations/0065_auto__add_field_package_signature_bytes.py new file mode 100644 index 00000000..a954166e --- /dev/null +++ b/main/migrations/0065_auto__add_field_package_signature_bytes.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.add_column('packages', 'signature_bytes', + self.gf('django.db.models.fields.BinaryField')(null=True), + keep_default=True) + + def backwards(self, orm): + db.delete_column('packages', 'signature_bytes') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'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'}), + u'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'}) + }, + u'main.arch': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'required_signoffs': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2'}) + }, + u'main.donor': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Donor', 'db_table': "'donors'"}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'unique_together': "(('pkgname', 'repo', 'arch'),)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': u"orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pgp_signature': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': u"orm['main.Repo']"}), + 'signature_bytes': ('django.db.models.fields.BinaryField', [], {'null': 'True'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + u'main.packagefile': { + 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"}, + 'directory': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_directory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['main.Package']"}) + }, + u'main.repo': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + } + } + + complete_apps = ['main'] diff --git a/main/migrations/0066_move_signature_data.py b/main/migrations/0066_move_signature_data.py new file mode 100644 index 00000000..75fcfa92 --- /dev/null +++ b/main/migrations/0066_move_signature_data.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import DataMigration +from django.db import models +from base64 import b64decode, b64encode + +class Migration(DataMigration): + + def forwards(self, orm): + pkgs = orm.Package.objects.only( + 'id', 'pgp_signature', 'signature_bytes').all() + for pkg in pkgs: + if not pkg.pgp_signature: + continue + pkg.signature_bytes = b64decode(pkg.pgp_signature.encode('utf-8')) + pkg.save() + + def backwards(self, orm): + pkgs = orm.Package.objects.only( + 'id', 'pgp_signature', 'signature_bytes').all() + for pkg in pkgs: + if not pkg.signature_bytes: + continue + pkg.pgp_signature = b64encode(pkg.signature_bytes).decode('utf-8') + pkg.save() + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'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'}), + u'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'}) + }, + u'main.arch': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'required_signoffs': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2'}) + }, + u'main.donor': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Donor', 'db_table': "'donors'"}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'unique_together': "(('pkgname', 'repo', 'arch'),)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': u"orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pgp_signature': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': u"orm['main.Repo']"}), + 'signature_bytes': ('django.db.models.fields.BinaryField', [], {'null': 'True'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + u'main.packagefile': { + 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"}, + 'directory': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_directory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['main.Package']"}) + }, + u'main.repo': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + } + } + + complete_apps = ['main'] + symmetrical = True diff --git a/main/migrations/0067_auto__del_field_package_pgp_signature.py b/main/migrations/0067_auto__del_field_package_pgp_signature.py new file mode 100644 index 00000000..8c1d9b7a --- /dev/null +++ b/main/migrations/0067_auto__del_field_package_pgp_signature.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.delete_column('packages', 'pgp_signature') + + def backwards(self, orm): + db.add_column('packages', 'pgp_signature', + self.gf('django.db.models.fields.TextField')(null=True, blank=True), + keep_default=True) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'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'}), + u'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'}) + }, + u'main.arch': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Arch', 'db_table': "'arches'"}, + 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'required_signoffs': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2'}) + }, + u'main.donor': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Donor', 'db_table': "'donors'"}, + 'created': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'main.package': { + 'Meta': {'ordering': "('pkgname',)", 'unique_together': "(('pkgname', 'repo', 'arch'),)", 'object_name': 'Package', 'db_table': "'packages'"}, + 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': u"orm['main.Arch']"}), + 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'compressed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {}), + 'epoch': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'installed_size': ('main.fields.PositiveBigIntegerField', [], {}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'pkgdesc': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'on_delete': 'models.PROTECT', 'to': u"orm['main.Repo']"}), + 'signature_bytes': ('django.db.models.fields.BinaryField', [], {'null': 'True'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}) + }, + u'main.packagefile': { + 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"}, + 'directory': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_directory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['main.Package']"}) + }, + u'main.repo': { + 'Meta': {'ordering': "('name',)", 'object_name': 'Repo', 'db_table': "'repos'"}, + 'bugs_category': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}), + 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'staging': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + } + } + + complete_apps = ['main'] diff --git a/main/models.py b/main/models.py index 2ace0109..3f964082 100644 --- a/main/models.py +++ b/main/models.py @@ -1,4 +1,3 @@ -from base64 import b64decode from datetime import datetime from itertools import groupby from pgpdump import BinaryData @@ -97,7 +96,7 @@ class Package(models.Model): pkgver = models.CharField(max_length=255) pkgrel = models.CharField(max_length=255) epoch = models.PositiveIntegerField(default=0) - pkgdesc = models.TextField(null=True) + pkgdesc = models.TextField('description', null=True) url = models.CharField(max_length=255, null=True) filename = models.CharField(max_length=255) compressed_size = PositiveBigIntegerField() @@ -106,10 +105,10 @@ class Package(models.Model): last_update = models.DateTimeField(db_index=True) files_last_update = models.DateTimeField(null=True, blank=True) created = models.DateTimeField() - packager_str = models.CharField(max_length=255) + packager_str = models.CharField('packager string', max_length=255) packager = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL) - pgp_signature = models.TextField(null=True, blank=True) + signature_bytes = models.BinaryField('PGP signature', null=True) flag_date = models.DateTimeField(null=True, blank=True) objects = PackageManager() @@ -140,13 +139,9 @@ class Package(models.Model): @property def signature(self): - try: - data = b64decode(self.pgp_signature.encode('utf-8')) - except TypeError: - return None - if not data: + if not self.signature_bytes: return None - data = BinaryData(data) + data = BinaryData(self.signature_bytes) packets = list(data.packets()) return packets[0] diff --git a/mirrors/admin.py b/mirrors/admin.py index d0f2f475..e35d9ce7 100644 --- a/mirrors/admin.py +++ b/mirrors/admin.py @@ -10,6 +10,7 @@ from .models import (Mirror, MirrorProtocol, MirrorUrl, MirrorRsync, class MirrorUrlForm(forms.ModelForm): class Meta: model = MirrorUrl + fields = ('url', 'country', 'active') def clean_url(self): # is this a valid-looking URL? @@ -39,6 +40,7 @@ class MirrorUrlInlineAdmin(admin.TabularInline): class MirrorRsyncForm(forms.ModelForm): class Meta: model = MirrorRsync + fields = ('ip',) class MirrorRsyncInlineAdmin(admin.TabularInline): @@ -50,6 +52,10 @@ class MirrorRsyncInlineAdmin(admin.TabularInline): class MirrorAdminForm(forms.ModelForm): class Meta: model = Mirror + fields = ('name', 'tier', 'upstream', 'admin_email', 'alternate_email', + 'public', 'active', 'isos', 'rsync_user', 'rsync_password', + 'notes') + upstream = forms.ModelChoiceField( queryset=Mirror.objects.filter(tier__gte=0, tier__lte=1), required=False) diff --git a/mirrors/management/commands/mirrorcheck.py b/mirrors/management/commands/mirrorcheck.py index 3f026c36..e48aa42e 100644 --- a/mirrors/management/commands/mirrorcheck.py +++ b/mirrors/management/commands/mirrorcheck.py @@ -241,7 +241,7 @@ class MirrorCheckPool(object): thread.daemon = True self.threads.append(thread) - @transaction.commit_on_success + @transaction.atomic def run(self): logger.debug("starting threads") for thread in self.threads: diff --git a/packages/admin.py b/packages/admin.py index 820bbb29..4680c755 100644 --- a/packages/admin.py +++ b/packages/admin.py @@ -20,7 +20,7 @@ class FlagRequestAdmin(admin.ModelAdmin): ordering = ('-created',) date_hierarchy = 'created' - def queryset(self, request): + def get_queryset(self, request): qs = super(FlagRequestAdmin, self).queryset(request) return qs.select_related('repo', 'user') @@ -42,7 +42,7 @@ class SignoffSpecificationAdmin(admin.ModelAdmin): ordering = ('-created',) date_hierarchy = 'created' - def queryset(self, request): + def get_queryset(self, request): qs = super(SignoffSpecificationAdmin, self).queryset(request) return qs.select_related('arch', 'repo', 'user') diff --git a/packages/views/flag.py b/packages/views/flag.py index 39cdcef8..9fe60e2c 100644 --- a/packages/views/flag.py +++ b/packages/views/flag.py @@ -84,7 +84,7 @@ def flag(request, name, repo, arch): else: email = form.cleaned_data['email'] - @transaction.commit_on_success + @transaction.atomic def perform_updates(): current_time = now() pkgs.update(flag_date=current_time) diff --git a/packages/views/signoff.py b/packages/views/signoff.py index c37aa0fc..fcc6de45 100644 --- a/packages/views/signoff.py +++ b/packages/views/signoff.py @@ -81,7 +81,7 @@ class SignoffOptionsForm(forms.ModelForm): def _signoff_options_all(request, name, repo): seen_ids = set() - with transaction.commit_on_success(): + with transaction.atomic(): # find or create a specification for all architectures, then # graft the form data onto them packages = Package.objects.filter(pkgbase=name, diff --git a/requirements.txt b/requirements.txt index 479c2134..08d89107 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -e git+git://github.com/fredj/cssmin.git@master#egg=cssmin -Django==1.5.5 +Django==1.6 IPy==0.81 Markdown==2.3.1 South==0.8.2 @@ -7,4 +7,4 @@ bencode==1.0 django-countries==1.5 jsmin==2.0.6 pgpdump==1.4 -pytz>=2013.7 +pytz>=2013.8 diff --git a/requirements_prod.txt b/requirements_prod.txt index 2c38903e..565c3c6c 100644 --- a/requirements_prod.txt +++ b/requirements_prod.txt @@ -1,5 +1,5 @@ -e git+git://github.com/fredj/cssmin.git@master#egg=cssmin -Django==1.5.5 +Django==1.6 IPy==0.81 Markdown==2.3.1 South==0.8.2 @@ -10,4 +10,4 @@ pgpdump==1.4 psycopg2==2.5.1 pyinotify==0.9.4 python-memcached==1.53 -pytz>=2013.7 +pytz>=2013.8 diff --git a/templates/devel/clock.html b/templates/devel/clock.html index 2c5bfacf..9d672f12 100644 --- a/templates/devel/clock.html +++ b/templates/devel/clock.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load flags %} {% load tz %} diff --git a/templates/devel/index.html b/templates/devel/index.html index 03e5d73a..c0c437a6 100644 --- a/templates/devel/index.html +++ b/templates/devel/index.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load cache %} {% load package_extras %} diff --git a/templates/devel/packages.html b/templates/devel/packages.html index d6aab497..74aebf20 100644 --- a/templates/devel/packages.html +++ b/templates/devel/packages.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load attributes %} {% load package_extras %} diff --git a/templates/devel/stats.html b/templates/devel/stats.html index 2dbe4755..9b3b1d28 100644 --- a/templates/devel/stats.html +++ b/templates/devel/stats.html @@ -1,3 +1,4 @@ +{% load cycle from future %} {% load cache %} {% cache 60 dev-dash-by-arch %} diff --git a/templates/mirrors/error_table.html b/templates/mirrors/error_table.html index 6054814f..cd7265af 100644 --- a/templates/mirrors/error_table.html +++ b/templates/mirrors/error_table.html @@ -1,3 +1,4 @@ +{% load cycle from future %} {% load flags mirror_status %} <table id="errorlog_mirrors" class="results"> <thead> diff --git a/templates/mirrors/mirror_details.html b/templates/mirrors/mirror_details.html index 1c7f5633..f2ffce20 100644 --- a/templates/mirrors/mirror_details.html +++ b/templates/mirrors/mirror_details.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load mirror_status %} {% load flags %} diff --git a/templates/mirrors/mirrors.html b/templates/mirrors/mirrors.html index 458b693f..4276b30a 100644 --- a/templates/mirrors/mirrors.html +++ b/templates/mirrors/mirrors.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% block title %}Arch Linux - Mirror Overview{% endblock %} diff --git a/templates/mirrors/status_table.html b/templates/mirrors/status_table.html index 28175420..6fc07a31 100644 --- a/templates/mirrors/status_table.html +++ b/templates/mirrors/status_table.html @@ -1,3 +1,4 @@ +{% load cycle from future %} {% load flags mirror_status %} <table id="{{ table_id }}" class="results"> <thead> diff --git a/templates/news/list.html b/templates/news/list.html index e85ceced..4acbc7e9 100644 --- a/templates/news/list.html +++ b/templates/news/list.html @@ -1,4 +1,6 @@ {% extends "base.html" %} +{% load cycle from future %} + {% block title %}Arch Linux - News{% endblock %} {% block head %} diff --git a/templates/packages/differences.html b/templates/packages/differences.html index b0b9b419..f137126d 100644 --- a/templates/packages/differences.html +++ b/templates/packages/differences.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% block title %}Arch Linux - Package Differences Reports{% endblock %} diff --git a/templates/packages/groups.html b/templates/packages/groups.html index c135791f..ee4f0312 100644 --- a/templates/packages/groups.html +++ b/templates/packages/groups.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% block title %}Arch Linux - Package Groups{% if arch %} - {{ arch }}{% endif %}{% endblock %} diff --git a/templates/packages/packages_list.html b/templates/packages/packages_list.html index 3dcc03dc..0a1627f8 100644 --- a/templates/packages/packages_list.html +++ b/templates/packages/packages_list.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load package_extras %} diff --git a/templates/packages/search.html b/templates/packages/search.html index f50bc8be..d312c374 100644 --- a/templates/packages/search.html +++ b/templates/packages/search.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load package_extras %} {% block title %}Arch Linux - Package Database{% endblock %} diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html index 807b613b..83f81d39 100644 --- a/templates/packages/signoffs.html +++ b/templates/packages/signoffs.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load package_extras %} diff --git a/templates/packages/stale_relations.html b/templates/packages/stale_relations.html index 14fac397..76f32052 100644 --- a/templates/packages/stale_relations.html +++ b/templates/packages/stale_relations.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% block title %}Arch Linux - Stale Package Relations{% endblock %} diff --git a/templates/releng/release_list.html b/templates/releng/release_list.html index 7197cc8d..f7e90377 100644 --- a/templates/releng/release_list.html +++ b/templates/releng/release_list.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% block title %}Arch Linux - Releases{% endblock %} diff --git a/templates/todolists/list.html b/templates/todolists/list.html index 56f9874d..7f0368de 100644 --- a/templates/todolists/list.html +++ b/templates/todolists/list.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% block title %}Arch Linux - Todo Lists{% endblock %} diff --git a/templates/todolists/view.html b/templates/todolists/view.html index b26cd91c..a3ee5479 100644 --- a/templates/todolists/view.html +++ b/templates/todolists/view.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load cycle from future %} {% load static from staticfiles %} {% load package_extras %} {% load todolists %} diff --git a/todolists/views.py b/todolists/views.py index ff75686d..c37c13f5 100644 --- a/todolists/views.py +++ b/todolists/views.py @@ -147,7 +147,7 @@ class DeleteTodolist(DeleteView): success_url = '/todo/' -@transaction.commit_on_success +@transaction.atomic def create_todolist_packages(form, creator=None): package_names = form.package_names() packages = form.packages() |