From c61024586d2ab5466d4e0ef6c29a2e4dbb935aa6 Mon Sep 17 00:00:00 2001 From: Antoine Legrand Date: Wed, 26 Oct 2016 23:19:28 +0200 Subject: [PATCH 1/8] data.database: add CNR/OCI models --- data/database.py | 176 +++++++++++++++++++++++++++++++---------------- 1 file changed, 118 insertions(+), 58 deletions(-) diff --git a/data/database.py b/data/database.py index d51f052bf..296408080 100644 --- a/data/database.py +++ b/data/database.py @@ -21,6 +21,7 @@ from playhouse.shortcuts import RetryOperationalError from sqlalchemy.engine.url import make_url import resumablehashlib +from cachetools import lru_cache from data.fields import (ResumableSHA256Field, ResumableSHA1Field, JSONField, Base64BinaryField, FullIndexedTextField, FullIndexedCharField) @@ -150,6 +151,7 @@ SCHEME_SPECIALIZED_FOR_UPDATE = { 'sqlite': null_for_update, } + class CallableProxy(Proxy): def __call__(self, *args, **kwargs): if self.obj is None: @@ -336,10 +338,54 @@ class QuayUserField(ForeignKeyField): self.robot_null_delete = robot_null_delete if 'rel_model' not in kwargs: kwargs['rel_model'] = User - super(QuayUserField, self).__init__(*args, **kwargs) +# @TODO: Generates client-side enum +class EnumField(ForeignKeyField): + """ Create a cached python Enum from an EnumTable """ + def __init__(self, rel_model, enum_key_field='name', *args, **kwargs): + """ + rel_model is the EnumTable model-class (see ForeignKeyField) + enum_key_field is the field from the EnumTable to use as the enum name + """ + self.enum_key_field = enum_key_field + super(EnumField, self).__init__(rel_model, *args, **kwargs) + + @property + @lru_cache(maxsize=1) + def enum(self): + """ Returns a python enun.Enum generated from the associated EnumTable """ + values = [] + for row in self.rel_model.select(): + key = getattr(row, self.enum_key_field) + value = getattr(row, 'id') + values.append((key, value)) + return Enum(self.rel_model.__name__, values) + + def get_id(self, name): + """ Returns the ForeignKeyId from the name field + Example: + >>> Repository.repo_kind.get_id("application") + 2 + """ + try: + return self.enum[name].value + except KeyError: + raise self.rel_model.DoesNotExist + + def get_name(self, value): + """ Returns the name value from the ForeignKeyId + Example: + >>> Repository.repo_kind.get_name(2) + "application" + """ + try: + return self.enum(value).name + except ValueError: + raise self.rel_model.DoesNotExist + + class BaseModel(ReadSlaveModel): class Meta: database = db @@ -405,7 +451,8 @@ class User(BaseModel): RepositoryTag, PermissionPrototype, DerivedStorageForImage, TagManifest, AccessToken, OAuthAccessToken, BlobUpload, RepositoryNotification, OAuthAuthorizationCode, - RepositoryActionCount, TagManifestLabel} + RepositoryActionCount, TagManifestLabel, Tag, + ManifestLabel, BlobUploading} delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes) @@ -502,12 +549,17 @@ class Visibility(BaseModel): name = CharField(index=True, unique=True) +class RepositoryKind(BaseModel): + name = CharField(index=True, unique=True) + + class Repository(BaseModel): namespace_user = QuayUserField(null=True) name = FullIndexedCharField(match_function=db_match_func) visibility = ForeignKeyField(Visibility) description = FullIndexedTextField(match_function=db_match_func, null=True) badge_token = CharField(default=uuid_generator) + repo_kind = EnumField(RepositoryKind) class Meta: database = db @@ -1069,7 +1121,7 @@ class Label(BaseModel): uuid = CharField(default=uuid_generator, index=True, unique=True) key = CharField(index=True) value = TextField() - media_type = ForeignKeyField(MediaType) + media_type = EnumField(MediaType) source_type = ForeignKeyField(LabelSourceType) @@ -1087,25 +1139,10 @@ class TagManifestLabel(BaseModel): ) -''' - -class ManifestLabel(BaseModel): - repository = ForeignKeyField(Repository, index=True) - annotated = ForeignKeyField(Manifest, index=True) - label = ForeignKeyField(Label) - - class Meta: - database = db - read_slaves = (read_slave,) - indexes = ( - (('repository', 'annotated', 'label'), True), - ) - - class Blob(BaseModel): """ Blob represents a content-addressable object stored outside of the database. """ digest = CharField(index=True, unique=True) - media_type = ForeignKeyField(MediaType) + media_type = EnumField(MediaType) size = BigIntegerField() uncompressed_size = BigIntegerField(null=True) @@ -1118,13 +1155,13 @@ class BlobPlacementLocation(BaseModel): class BlobPlacementLocationPreference(BaseModel): """ BlobPlacementLocationPreference is a location to which a user's data will be replicated. """ user = QuayUserField(index=True, allows_robots=False) - location = ForeignKeyField(BlobPlacementLocation) + location = EnumField(BlobPlacementLocation) class BlobPlacement(BaseModel): """ BlobPlacement represents the location of a Blob. """ blob = ForeignKeyField(Blob) - location = ForeignKeyField(BlobPlacementLocation) + location = EnumField(BlobPlacementLocation) class Meta: database = db @@ -1159,10 +1196,23 @@ class BlobUploading(BaseModel): class Manifest(BaseModel): """ Manifest represents the metadata and collection of blobs that comprise a container image. """ digest = CharField(index=True, unique=True) - media_type = ForeignKeyField(MediaType) + media_type = EnumField(MediaType) manifest_json = JSONField() +class ManifestLabel(BaseModel): + repository = ForeignKeyField(Repository, index=True) + annotated = ForeignKeyField(Manifest, index=True) + label = ForeignKeyField(Label) + + class Meta: + database = db + read_slaves = (read_slave,) + indexes = ( + (('repository', 'annotated', 'label'), True), + ) + + class ManifestBlob(BaseModel): """ ManifestBlob is a many-to-many relation table linking Manifests and Blobs. """ manifest = ForeignKeyField(Manifest, index=True) @@ -1181,22 +1231,56 @@ class ManifestList(BaseModel): digest = CharField(index=True, unique=True) manifest_list_json = JSONField() schema_version = CharField() - media_type = ForeignKeyField(MediaType) + media_type = EnumField(MediaType) -class ManifestListManifest(BaseModel): - """ ManifestListManifest is a many-to-many relation table linking ManifestLists and Manifests. """ - manifest_list = ForeignKeyField(ManifestList, index=True) - manifest = ForeignKeyField(Manifest, index=True) - operating_system = CharField() - architecture = CharField() - platform_json = JSONField() +class TagKind(BaseModel): + """ TagKind is a enumtable of to reference tag kinds """ + name = CharField(index=True, unique=True) + + +class Tag(BaseModel): + """ Tag represents a user-facing alias for referencing a ManifestList. """ + name = CharField() + repository = ForeignKeyField(Repository) + manifest_list = ForeignKeyField(ManifestList, null=True) + lifetime_start = BigIntegerField(default=get_epoch_timestamp_ms) + lifetime_end = BigIntegerField(null=True, index=True) + hidden = BooleanField(default=False) + reverted = BooleanField(default=False) + protected = BooleanField(default=False) + tag_kind = EnumField(TagKind) + linked_tag = ForeignKeyField('self', null=True, related_name='tag_parents') class Meta: database = db read_slaves = (read_slave,) indexes = ( - (('manifest_list', 'operating_system', 'architecture'), False), + (('repository', 'name', 'tag_kind'), False), + (('repository', 'name', 'hidden', 'tag_kind'), False), + # This unique index prevents deadlocks when concurrently moving and deleting tags + (('repository', 'name', 'lifetime_end', 'tag_kind'), True), + ) + + + +Channel = Tag.alias() + +class ManifestListManifest(BaseModel): + """ ManifestListManifest is a many-to-many relation table linking ManifestLists and Manifests. """ + manifest_list = ForeignKeyField(ManifestList, index=True) + manifest = ForeignKeyField(Manifest, index=True) + operating_system = CharField(null=True) + architecture = CharField(null=True) + platform_json = JSONField(null=True) + media_type = EnumField(MediaType) + + class Meta: + database = db + read_slaves = (read_slave,) + indexes = ( + (('manifest_list', 'operating_system', 'architecture', 'media_type'), False), + (('manifest_list', 'media_type'), False), ) @@ -1235,7 +1319,7 @@ class DerivedImage(BaseModel): uuid = CharField(default=uuid_generator, unique=True) source_manifest = ForeignKeyField(Manifest) derived_manifest_json = JSONField() - media_type = ForeignKeyField(MediaType) + media_type = EnumField(MediaType) blob = ForeignKeyField(Blob, related_name='blob') uniqueness_hash = CharField(index=True, unique=True) signature_blob = ForeignKeyField(Blob, null=True, related_name='signature_blob') @@ -1249,28 +1333,6 @@ class DerivedImage(BaseModel): ) -class Tag(BaseModel): - """ Tag represents a user-facing alias for referencing a ManifestList. """ - name = CharField() - repository = ForeignKeyField(Repository) - manifest_list = ForeignKeyField(ManifestList) - lifetime_start = BigIntegerField(default=get_epoch_timestamp_ms) - lifetime_end = BigIntegerField(null=True, index=True) - hidden = BooleanField(default=False) - reverted = BooleanField(default=False) - - class Meta: - database = db - read_slaves = (read_slave,) - indexes = ( - (('repository', 'name'), False), - (('repository', 'name', 'hidden') False), - - # This unique index prevents deadlocks when concurrently moving and deleting tags - (('repository', 'name', 'lifetime_end'), True), - ) - - class BitTorrentPieces(BaseModel): """ BitTorrentPieces represents the BitTorrent piece metadata calculated from a Blob. """ blob = ForeignKeyField(Blob) @@ -1285,11 +1347,9 @@ class BitTorrentPieces(BaseModel): ) -beta_classes = set([ManifestLayerScan, Tag, BlobPlacementLocation, ManifestLayer, ManifestList, +beta_classes = set([ManifestLayerScan, Tag, TagKind, BlobPlacementLocation, ManifestLayer, ManifestList, BitTorrentPieces, MediaType, Label, ManifestBlob, BlobUploading, Blob, ManifestLayerDockerV1, BlobPlacementLocationPreference, ManifestListManifest, - Manifest, DerivedImage, BlobPlacement]) -''' - + Manifest, DerivedImage, BlobPlacement, ManifestLabel]) is_model = lambda x: inspect.isclass(x) and issubclass(x, BaseModel) and x is not BaseModel all_models = [model[1] for model in inspect.getmembers(sys.modules[__name__], is_model)] From 8f323154ce071115737b634c2e45b38671928ffe Mon Sep 17 00:00:00 2001 From: Antoine Legrand Date: Thu, 16 Mar 2017 13:35:36 -0400 Subject: [PATCH 2/8] data.migrations: add OCI/CNR models --- .../7a525c68eb13_add_oci_app_models.py | 322 ++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 data/migrations/versions/7a525c68eb13_add_oci_app_models.py diff --git a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py new file mode 100644 index 000000000..caf5e9c73 --- /dev/null +++ b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py @@ -0,0 +1,322 @@ +"""Add OCI/App models + +Revision ID: 7a525c68eb13 +Revises: e2894a3a3c19 +Create Date: 2017-01-24 16:25:52.170277 + +""" + +# revision identifiers, used by Alembic. +revision = '7a525c68eb13' +down_revision = 'e2894a3a3c19' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql +from util.migrate import UTF8LongText, UTF8CharField + + +def upgrade(tables): + ### commands auto generated by Alembic - please adjust! ### + op.create_table('repositorykind', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_repositorykind')) + ) + + # this is used for the default value of repository.repo_kind + op.bulk_insert(tables.repositorykind, + [ + {'name': 'image', 'id': 1}, + {'name': 'application', 'id': 2}, + ]) + + op.create_table('tagkind', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_tagkind')) + ) + op.create_table('blobplacementlocation', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacementlocation')) + ) + op.create_index('blobplacementlocation_name', 'blobplacementlocation', ['name'], unique=True) + op.create_index('repositorykind_name', 'repositorykind', ['name'], unique=True) + + op.create_index('tagkind_name', 'tagkind', ['name'], unique=True) + op.create_table('blob', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('digest', UTF8CharField(length=255), nullable=False), + sa.Column('media_type_id', sa.Integer(), nullable=False), + sa.Column('size', sa.BigInteger(), nullable=False), + sa.Column('uncompressed_size', sa.BigInteger(), nullable=True), + sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_blob_media_type_id_mediatype')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_blob')) + ) + op.create_index('blob_digest', 'blob', ['digest'], unique=True) + op.create_index('blob_media_type_id', 'blob', ['media_type_id'], unique=False) + op.create_table('blobplacementlocationpreference', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('location_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['location_id'], ['blobplacementlocation.id'], name=op.f('fk_blobplacementlocpref_locid_blobplacementlocation')), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], name=op.f('fk_blobplacementlocationpreference_user_id_user')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacementlocationpreference')) + ) + op.create_index('blobplacementlocationpreference_location_id', 'blobplacementlocationpreference', ['location_id'], unique=False) + op.create_index('blobplacementlocationpreference_user_id', 'blobplacementlocationpreference', ['user_id'], unique=False) + op.create_table('manifest', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('digest', UTF8CharField(length=255), nullable=False), + sa.Column('media_type_id', sa.Integer(), nullable=False), + sa.Column('manifest_json', UTF8LongText, nullable=False), + sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifest_media_type_id_mediatype')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifest')) + ) + op.create_index('manifest_digest', 'manifest', ['digest'], unique=True) + op.create_index('manifest_media_type_id', 'manifest', ['media_type_id'], unique=False) + op.create_table('manifestlist', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('digest', UTF8CharField(length=255), nullable=False), + sa.Column('manifest_list_json', UTF8LongText, nullable=False), + sa.Column('schema_version', UTF8CharField(length=255), nullable=False), + sa.Column('media_type_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifestlist_media_type_id_mediatype')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlist')) + ) + op.create_index('manifestlist_digest', 'manifestlist', ['digest'], unique=True) + op.create_index('manifestlist_media_type_id', 'manifestlist', ['media_type_id'], unique=False) + op.create_table('bittorrentpieces', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('blob_id', sa.Integer(), nullable=False), + sa.Column('pieces', UTF8LongText, nullable=False), + sa.Column('piece_length', sa.BigInteger(), nullable=False), + sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_bittorrentpieces_blob_id_blob')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_bittorrentpieces')) + ) + op.create_index('bittorrentpieces_blob_id', 'bittorrentpieces', ['blob_id'], unique=False) + op.create_index('bittorrentpieces_blob_id_piece_length', 'bittorrentpieces', ['blob_id', 'piece_length'], unique=True) + op.create_table('blobplacement', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('blob_id', sa.Integer(), nullable=False), + sa.Column('location_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_blobplacement_blob_id_blob')), + sa.ForeignKeyConstraint(['location_id'], ['blobplacementlocation.id'], name=op.f('fk_blobplacement_location_id_blobplacementlocation')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacement')) + ) + op.create_index('blobplacement_blob_id', 'blobplacement', ['blob_id'], unique=False) + op.create_index('blobplacement_blob_id_location_id', 'blobplacement', ['blob_id', 'location_id'], unique=True) + op.create_index('blobplacement_location_id', 'blobplacement', ['location_id'], unique=False) + op.create_table('blobuploading', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('uuid', UTF8CharField(length=255), nullable=False), + sa.Column('created', sa.DateTime(), nullable=False), + sa.Column('repository_id', sa.Integer(), nullable=False), + sa.Column('location_id', sa.Integer(), nullable=False), + sa.Column('byte_count', sa.BigInteger(), nullable=False), + sa.Column('uncompressed_byte_count', sa.BigInteger(), nullable=True), + sa.Column('chunk_count', sa.BigInteger(), nullable=False), + sa.Column('storage_metadata', UTF8LongText, nullable=True), + sa.Column('sha_state', UTF8LongText, nullable=True), + sa.Column('piece_sha_state', UTF8LongText, nullable=True), + sa.Column('piece_hashes', UTF8LongText, nullable=True), + sa.ForeignKeyConstraint(['location_id'], ['blobplacementlocation.id'], name=op.f('fk_blobuploading_location_id_blobplacementlocation')), + sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_blobuploading_repository_id_repository')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_blobuploading')) + ) + op.create_index('blobuploading_created', 'blobuploading', ['created'], unique=False) + op.create_index('blobuploading_location_id', 'blobuploading', ['location_id'], unique=False) + op.create_index('blobuploading_repository_id', 'blobuploading', ['repository_id'], unique=False) + op.create_index('blobuploading_repository_id_uuid', 'blobuploading', ['repository_id', 'uuid'], unique=True) + op.create_index('blobuploading_uuid', 'blobuploading', ['uuid'], unique=True) + op.create_table('derivedimage', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('uuid', UTF8CharField(length=255), nullable=False), + sa.Column('source_manifest_id', sa.Integer(), nullable=False), + sa.Column('derived_manifest_json', UTF8LongText, nullable=False), + sa.Column('media_type_id', sa.Integer(), nullable=False), + sa.Column('blob_id', sa.Integer(), nullable=False), + sa.Column('uniqueness_hash', UTF8CharField(length=255), nullable=False), + sa.Column('signature_blob_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_derivedimage_blob_id_blob')), + sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_derivedimage_media_type_id_mediatype')), + sa.ForeignKeyConstraint(['signature_blob_id'], ['blob.id'], name=op.f('fk_derivedimage_signature_blob_id_blob')), + sa.ForeignKeyConstraint(['source_manifest_id'], ['manifest.id'], name=op.f('fk_derivedimage_source_manifest_id_manifest')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_derivedimage')) + ) + op.create_index('derivedimage_blob_id', 'derivedimage', ['blob_id'], unique=False) + op.create_index('derivedimage_media_type_id', 'derivedimage', ['media_type_id'], unique=False) + op.create_index('derivedimage_signature_blob_id', 'derivedimage', ['signature_blob_id'], unique=False) + op.create_index('derivedimage_source_manifest_id', 'derivedimage', ['source_manifest_id'], unique=False) + op.create_index('derivedimage_source_manifest_id_blob_id', 'derivedimage', ['source_manifest_id', 'blob_id'], unique=True) + op.create_index('derivedimage_source_manifest_id_media_type_id_uniqueness_hash', 'derivedimage', ['source_manifest_id', 'media_type_id', 'uniqueness_hash'], unique=True) + op.create_index('derivedimage_uniqueness_hash', 'derivedimage', ['uniqueness_hash'], unique=True) + op.create_index('derivedimage_uuid', 'derivedimage', ['uuid'], unique=True) + op.create_table('manifestblob', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('manifest_id', sa.Integer(), nullable=False), + sa.Column('blob_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_manifestblob_blob_id_blob')), + sa.ForeignKeyConstraint(['manifest_id'], ['manifest.id'], name=op.f('fk_manifestblob_manifest_id_manifest')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestblob')) + ) + op.create_index('manifestblob_blob_id', 'manifestblob', ['blob_id'], unique=False) + op.create_index('manifestblob_manifest_id', 'manifestblob', ['manifest_id'], unique=False) + op.create_index('manifestblob_manifest_id_blob_id', 'manifestblob', ['manifest_id', 'blob_id'], unique=True) + op.create_table('manifestlabel', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('repository_id', sa.Integer(), nullable=False), + sa.Column('annotated_id', sa.Integer(), nullable=False), + sa.Column('label_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['annotated_id'], ['manifest.id'], name=op.f('fk_manifestlabel_annotated_id_manifest')), + sa.ForeignKeyConstraint(['label_id'], ['label.id'], name=op.f('fk_manifestlabel_label_id_label')), + sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_manifestlabel_repository_id_repository')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlabel')) + ) + op.create_index('manifestlabel_annotated_id', 'manifestlabel', ['annotated_id'], unique=False) + op.create_index('manifestlabel_label_id', 'manifestlabel', ['label_id'], unique=False) + op.create_index('manifestlabel_repository_id', 'manifestlabel', ['repository_id'], unique=False) + op.create_index('manifestlabel_repository_id_annotated_id_label_id', 'manifestlabel', ['repository_id', 'annotated_id', 'label_id'], unique=True) + op.create_table('manifestlayer', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('blob_id', sa.Integer(), nullable=False), + sa.Column('manifest_id', sa.Integer(), nullable=False), + sa.Column('manifest_index', sa.BigInteger(), nullable=False), + sa.Column('metadata_json', UTF8LongText, nullable=False), + sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_manifestlayer_blob_id_blob')), + sa.ForeignKeyConstraint(['manifest_id'], ['manifest.id'], name=op.f('fk_manifestlayer_manifest_id_manifest')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlayer')) + ) + op.create_index('manifestlayer_blob_id', 'manifestlayer', ['blob_id'], unique=False) + op.create_index('manifestlayer_manifest_id', 'manifestlayer', ['manifest_id'], unique=False) + op.create_index('manifestlayer_manifest_id_manifest_index', 'manifestlayer', ['manifest_id', 'manifest_index'], unique=True) + op.create_index('manifestlayer_manifest_index', 'manifestlayer', ['manifest_index'], unique=False) + op.create_table('manifestlistmanifest', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('manifest_list_id', sa.Integer(), nullable=False), + sa.Column('manifest_id', sa.Integer(), nullable=False), + sa.Column('operating_system', UTF8CharField(length=255), nullable=True), + sa.Column('architecture', UTF8CharField(length=255), nullable=True), + sa.Column('platform_json', UTF8LongText, nullable=True), + sa.Column('media_type_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['manifest_id'], ['manifest.id'], name=op.f('fk_manifestlistmanifest_manifest_id_manifest')), + sa.ForeignKeyConstraint(['manifest_list_id'], ['manifestlist.id'], name=op.f('fk_manifestlistmanifest_manifest_list_id_manifestlist')), + sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifestlistmanifest_media_type_id_mediatype')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlistmanifest')) + ) + op.create_index('manifestlistmanifest_manifest_id', 'manifestlistmanifest', ['manifest_id'], unique=False) + op.create_index('manifestlistmanifest_manifest_list_id', 'manifestlistmanifest', ['manifest_list_id'], unique=False) + op.create_index('manifestlistmanifest_manifest_listid_os_arch_mtid', 'manifestlistmanifest', ['manifest_list_id', 'operating_system', 'architecture', 'media_type_id'], unique=False) + op.create_index('manifestlistmanifest_manifest_listid_mtid', 'manifestlistmanifest', ['manifest_list_id', 'media_type_id'], unique=False) + op.create_index('manifestlistmanifest_media_type_id', 'manifestlistmanifest', ['media_type_id'], unique=False) + op.create_table('tag', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.Column('repository_id', sa.Integer(), nullable=False), + sa.Column('manifest_list_id', sa.Integer(), nullable=True), + sa.Column('lifetime_start', sa.BigInteger(), nullable=False), + sa.Column('lifetime_end', sa.BigInteger(), nullable=True), + sa.Column('hidden', sa.Boolean(), nullable=False), + sa.Column('reverted', sa.Boolean(), nullable=False), + sa.Column('protected', sa.Boolean(), nullable=False), + sa.Column('tag_kind_id', sa.Integer(), nullable=False), + sa.Column('linked_tag_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['linked_tag_id'], ['tag.id'], name=op.f('fk_tag_linked_tag_id_tag')), + sa.ForeignKeyConstraint(['manifest_list_id'], ['manifestlist.id'], name=op.f('fk_tag_manifest_list_id_manifestlist')), + sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_tag_repository_id_repository')), + sa.ForeignKeyConstraint(['tag_kind_id'], ['tagkind.id'], name=op.f('fk_tag_tag_kind_id_tagkind')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_tag')) + ) + op.create_index('tag_lifetime_end', 'tag', ['lifetime_end'], unique=False) + op.create_index('tag_linked_tag_id', 'tag', ['linked_tag_id'], unique=False) + op.create_index('tag_manifest_list_id', 'tag', ['manifest_list_id'], unique=False) + op.create_index('tag_repository_id', 'tag', ['repository_id'], unique=False) + op.create_index('tag_repository_id_name_hidden_tag_kind_id', 'tag', ['repository_id', 'name', 'hidden', 'tag_kind_id'], unique=False) + op.create_index('tag_repository_id_name_lifetime_end_tag_kind_id', 'tag', ['repository_id', 'name', 'lifetime_end', 'tag_kind_id'], unique=True) + op.create_index('tag_repository_id_name_tag_kind_id', 'tag', ['repository_id', 'name', 'tag_kind_id'], unique=False) + op.create_index('tag_tag_kind_id', 'tag', ['tag_kind_id'], unique=False) + op.create_table('manifestlayerdockerv1', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('manifest_layer_id', sa.Integer(), nullable=False), + sa.Column('image_id', UTF8CharField(length=255), nullable=False), + sa.Column('checksum', UTF8CharField(length=255), nullable=False), + sa.Column('compat_json', UTF8LongText, nullable=False), + sa.ForeignKeyConstraint(['manifest_layer_id'], ['manifestlayer.id'], name=op.f('fk_manifestlayerdockerv1_manifest_layer_id_manifestlayer')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlayerdockerv1')) + ) + op.create_index('manifestlayerdockerv1_image_id', 'manifestlayerdockerv1', ['image_id'], unique=False) + op.create_index('manifestlayerdockerv1_manifest_layer_id', 'manifestlayerdockerv1', ['manifest_layer_id'], unique=False) + op.create_table('manifestlayerscan', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('layer_id', sa.Integer(), nullable=False), + sa.Column('scannable', sa.Boolean(), nullable=False), + sa.Column('scanned_by', UTF8CharField(length=255), nullable=False), + sa.ForeignKeyConstraint(['layer_id'], ['manifestlayer.id'], name=op.f('fk_manifestlayerscan_layer_id_manifestlayer')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlayerscan')) + ) + op.create_index('manifestlayerscan_layer_id', 'manifestlayerscan', ['layer_id'], unique=True) + op.create_index('derivedstorageforimage_source_imageid_trid_uniq_hash', 'derivedstorageforimage', ['source_image_id', 'transformation_id', 'uniqueness_hash'], unique=True) + op.drop_index('uniqueness_index', table_name='derivedstorageforimage') + op.drop_column(u'imagestorage', 'checksum') + op.add_column(u'repository', sa.Column('repo_kind_id', sa.Integer(), nullable=False, server_default="1")) + op.create_index('repository_repo_kind_id', 'repository', ['repo_kind_id'], unique=False) + + op.create_foreign_key(op.f('fk_repository_repo_kind_id_repositorykind'), 'repository', 'repositorykind', ['repo_kind_id'], ['id']) + + + op.bulk_insert(tables.blobplacementlocation, + [ + {'name': 'local_eu'}, + {'name': 'local_us'}, + ]) + + op.bulk_insert(tables.mediatype, + [ + {'name': 'application/vnd.cnr.blob.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.package-manifest.helm.v1.json'}, + {'name': 'application/vnd.cnr.package-manifest.kpm.v1.json'}, + {'name': 'application/vnd.cnr.package-manifest.docker-compose.v1.json'}, + {'name': 'application/vnd.cnr.package.kpm.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.package.helm.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.package.docker-compose.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.manifests.v1.json'}, + {'name': 'application/vnd.cnr.manifest.list.v1.json'}, + ]) + + op.bulk_insert(tables.tagkind, + [ + {'name': 'tag', 'id': 1}, + {'name': 'release', 'id': 2}, + {'name': 'channel', 'id': 3}, + ]) + + ### end Alembic commands ### + + +def downgrade(tables): + ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(op.f('fk_repository_repo_kind_id_repositorykind'), 'repository', type_='foreignkey') + op.drop_column(u'repository', 'repo_kind_id') + op.add_column(u'imagestorage', sa.Column('checksum', mysql.VARCHAR(length=255), nullable=True)) + op.create_index('uniqueness_index', 'derivedstorageforimage', ['source_image_id', 'transformation_id', 'uniqueness_hash'], unique=True) + op.drop_index('derivedstorageforimage_source_imageid_trid_uniq_hash', table_name='derivedstorageforimage') + op.drop_table('manifestlayerscan') + op.drop_table('manifestlayerdockerv1') + op.drop_table('tag') + op.drop_table('manifestlistmanifest') + op.drop_table('manifestlayer') + op.drop_table('manifestlabel') + op.drop_table('manifestblob') + op.drop_table('derivedimage') + op.drop_table('blobuploading') + op.drop_table('blobplacement') + op.drop_table('bittorrentpieces') + op.drop_table('manifestlist') + op.drop_table('manifest') + op.drop_table('blobplacementlocationpreference') + op.drop_table('blob') + op.drop_table('tagkind') + op.drop_table('repositorykind') + op.drop_table('blobplacementlocation') + ### end Alembic commands ### From 1e9ce85af6d79811d02e6e2f5e947d008cf6e4b0 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 16 Mar 2017 15:11:35 -0400 Subject: [PATCH 3/8] data.database/migrations: remove repo_id from db This also manually organizes and removes broken parts of the migration. --- data/database.py | 5 - .../7a525c68eb13_add_oci_app_models.py | 329 +++++++++--------- 2 files changed, 167 insertions(+), 167 deletions(-) diff --git a/data/database.py b/data/database.py index 296408080..58d4e03ce 100644 --- a/data/database.py +++ b/data/database.py @@ -549,17 +549,12 @@ class Visibility(BaseModel): name = CharField(index=True, unique=True) -class RepositoryKind(BaseModel): - name = CharField(index=True, unique=True) - - class Repository(BaseModel): namespace_user = QuayUserField(null=True) name = FullIndexedCharField(match_function=db_match_func) visibility = ForeignKeyField(Visibility) description = FullIndexedTextField(match_function=db_match_func, null=True) badge_token = CharField(default=uuid_generator) - repo_kind = EnumField(RepositoryKind) class Meta: database = db diff --git a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py index caf5e9c73..363f14078 100644 --- a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py +++ b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py @@ -17,35 +17,24 @@ from util.migrate import UTF8LongText, UTF8CharField def upgrade(tables): - ### commands auto generated by Alembic - please adjust! ### - op.create_table('repositorykind', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', UTF8CharField(length=255), nullable=False), - sa.PrimaryKeyConstraint('id', name=op.f('pk_repositorykind')) - ) - - # this is used for the default value of repository.repo_kind - op.bulk_insert(tables.repositorykind, - [ - {'name': 'image', 'id': 1}, - {'name': 'application', 'id': 2}, - ]) - - op.create_table('tagkind', + op.create_table( + 'tagkind', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', UTF8CharField(length=255), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_tagkind')) - ) - op.create_table('blobplacementlocation', + ) + op.create_index('tagkind_name', 'tagkind', ['name'], unique=True) + + op.create_table( + 'blobplacementlocation', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', UTF8CharField(length=255), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacementlocation')) - ) - op.create_index('blobplacementlocation_name', 'blobplacementlocation', ['name'], unique=True) - op.create_index('repositorykind_name', 'repositorykind', ['name'], unique=True) + ) + op.create_index('blobplacementlocation_name', 'blobplacementlocation', ['name'], unique=True) - op.create_index('tagkind_name', 'tagkind', ['name'], unique=True) - op.create_table('blob', + op.create_table( + 'blob', sa.Column('id', sa.Integer(), nullable=False), sa.Column('digest', UTF8CharField(length=255), nullable=False), sa.Column('media_type_id', sa.Integer(), nullable=False), @@ -53,30 +42,36 @@ def upgrade(tables): sa.Column('uncompressed_size', sa.BigInteger(), nullable=True), sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_blob_media_type_id_mediatype')), sa.PrimaryKeyConstraint('id', name=op.f('pk_blob')) - ) - op.create_index('blob_digest', 'blob', ['digest'], unique=True) - op.create_index('blob_media_type_id', 'blob', ['media_type_id'], unique=False) - op.create_table('blobplacementlocationpreference', + ) + op.create_index('blob_digest', 'blob', ['digest'], unique=True) + op.create_index('blob_media_type_id', 'blob', ['media_type_id'], unique=False) + + op.create_table( + 'blobplacementlocationpreference', sa.Column('id', sa.Integer(), nullable=False), sa.Column('user_id', sa.Integer(), nullable=False), sa.Column('location_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['location_id'], ['blobplacementlocation.id'], name=op.f('fk_blobplacementlocpref_locid_blobplacementlocation')), sa.ForeignKeyConstraint(['user_id'], ['user.id'], name=op.f('fk_blobplacementlocationpreference_user_id_user')), sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacementlocationpreference')) - ) - op.create_index('blobplacementlocationpreference_location_id', 'blobplacementlocationpreference', ['location_id'], unique=False) - op.create_index('blobplacementlocationpreference_user_id', 'blobplacementlocationpreference', ['user_id'], unique=False) - op.create_table('manifest', + ) + op.create_index('blobplacementlocationpreference_location_id', 'blobplacementlocationpreference', ['location_id'], unique=False) + op.create_index('blobplacementlocationpreference_user_id', 'blobplacementlocationpreference', ['user_id'], unique=False) + + op.create_table( + 'manifest', sa.Column('id', sa.Integer(), nullable=False), sa.Column('digest', UTF8CharField(length=255), nullable=False), sa.Column('media_type_id', sa.Integer(), nullable=False), sa.Column('manifest_json', UTF8LongText, nullable=False), sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifest_media_type_id_mediatype')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifest')) - ) - op.create_index('manifest_digest', 'manifest', ['digest'], unique=True) - op.create_index('manifest_media_type_id', 'manifest', ['media_type_id'], unique=False) - op.create_table('manifestlist', + ) + op.create_index('manifest_digest', 'manifest', ['digest'], unique=True) + op.create_index('manifest_media_type_id', 'manifest', ['media_type_id'], unique=False) + + op.create_table( + 'manifestlist', sa.Column('id', sa.Integer(), nullable=False), sa.Column('digest', UTF8CharField(length=255), nullable=False), sa.Column('manifest_list_json', UTF8LongText, nullable=False), @@ -84,31 +79,37 @@ def upgrade(tables): sa.Column('media_type_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifestlist_media_type_id_mediatype')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlist')) - ) - op.create_index('manifestlist_digest', 'manifestlist', ['digest'], unique=True) - op.create_index('manifestlist_media_type_id', 'manifestlist', ['media_type_id'], unique=False) - op.create_table('bittorrentpieces', + ) + op.create_index('manifestlist_digest', 'manifestlist', ['digest'], unique=True) + op.create_index('manifestlist_media_type_id', 'manifestlist', ['media_type_id'], unique=False) + + op.create_table( + 'bittorrentpieces', sa.Column('id', sa.Integer(), nullable=False), sa.Column('blob_id', sa.Integer(), nullable=False), sa.Column('pieces', UTF8LongText, nullable=False), sa.Column('piece_length', sa.BigInteger(), nullable=False), sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_bittorrentpieces_blob_id_blob')), sa.PrimaryKeyConstraint('id', name=op.f('pk_bittorrentpieces')) - ) - op.create_index('bittorrentpieces_blob_id', 'bittorrentpieces', ['blob_id'], unique=False) - op.create_index('bittorrentpieces_blob_id_piece_length', 'bittorrentpieces', ['blob_id', 'piece_length'], unique=True) - op.create_table('blobplacement', + ) + op.create_index('bittorrentpieces_blob_id', 'bittorrentpieces', ['blob_id'], unique=False) + op.create_index('bittorrentpieces_blob_id_piece_length', 'bittorrentpieces', ['blob_id', 'piece_length'], unique=True) + + op.create_table( + 'blobplacement', sa.Column('id', sa.Integer(), nullable=False), sa.Column('blob_id', sa.Integer(), nullable=False), sa.Column('location_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_blobplacement_blob_id_blob')), sa.ForeignKeyConstraint(['location_id'], ['blobplacementlocation.id'], name=op.f('fk_blobplacement_location_id_blobplacementlocation')), sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacement')) - ) - op.create_index('blobplacement_blob_id', 'blobplacement', ['blob_id'], unique=False) - op.create_index('blobplacement_blob_id_location_id', 'blobplacement', ['blob_id', 'location_id'], unique=True) - op.create_index('blobplacement_location_id', 'blobplacement', ['location_id'], unique=False) - op.create_table('blobuploading', + ) + op.create_index('blobplacement_blob_id', 'blobplacement', ['blob_id'], unique=False) + op.create_index('blobplacement_blob_id_location_id', 'blobplacement', ['blob_id', 'location_id'], unique=True) + op.create_index('blobplacement_location_id', 'blobplacement', ['location_id'], unique=False) + + op.create_table( + 'blobuploading', sa.Column('id', sa.Integer(), nullable=False), sa.Column('uuid', UTF8CharField(length=255), nullable=False), sa.Column('created', sa.DateTime(), nullable=False), @@ -124,13 +125,15 @@ def upgrade(tables): sa.ForeignKeyConstraint(['location_id'], ['blobplacementlocation.id'], name=op.f('fk_blobuploading_location_id_blobplacementlocation')), sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_blobuploading_repository_id_repository')), sa.PrimaryKeyConstraint('id', name=op.f('pk_blobuploading')) - ) - op.create_index('blobuploading_created', 'blobuploading', ['created'], unique=False) - op.create_index('blobuploading_location_id', 'blobuploading', ['location_id'], unique=False) - op.create_index('blobuploading_repository_id', 'blobuploading', ['repository_id'], unique=False) - op.create_index('blobuploading_repository_id_uuid', 'blobuploading', ['repository_id', 'uuid'], unique=True) - op.create_index('blobuploading_uuid', 'blobuploading', ['uuid'], unique=True) - op.create_table('derivedimage', + ) + op.create_index('blobuploading_created', 'blobuploading', ['created'], unique=False) + op.create_index('blobuploading_location_id', 'blobuploading', ['location_id'], unique=False) + op.create_index('blobuploading_repository_id', 'blobuploading', ['repository_id'], unique=False) + op.create_index('blobuploading_repository_id_uuid', 'blobuploading', ['repository_id', 'uuid'], unique=True) + op.create_index('blobuploading_uuid', 'blobuploading', ['uuid'], unique=True) + + op.create_table( + 'derivedimage', sa.Column('id', sa.Integer(), nullable=False), sa.Column('uuid', UTF8CharField(length=255), nullable=False), sa.Column('source_manifest_id', sa.Integer(), nullable=False), @@ -144,27 +147,31 @@ def upgrade(tables): sa.ForeignKeyConstraint(['signature_blob_id'], ['blob.id'], name=op.f('fk_derivedimage_signature_blob_id_blob')), sa.ForeignKeyConstraint(['source_manifest_id'], ['manifest.id'], name=op.f('fk_derivedimage_source_manifest_id_manifest')), sa.PrimaryKeyConstraint('id', name=op.f('pk_derivedimage')) - ) - op.create_index('derivedimage_blob_id', 'derivedimage', ['blob_id'], unique=False) - op.create_index('derivedimage_media_type_id', 'derivedimage', ['media_type_id'], unique=False) - op.create_index('derivedimage_signature_blob_id', 'derivedimage', ['signature_blob_id'], unique=False) - op.create_index('derivedimage_source_manifest_id', 'derivedimage', ['source_manifest_id'], unique=False) - op.create_index('derivedimage_source_manifest_id_blob_id', 'derivedimage', ['source_manifest_id', 'blob_id'], unique=True) - op.create_index('derivedimage_source_manifest_id_media_type_id_uniqueness_hash', 'derivedimage', ['source_manifest_id', 'media_type_id', 'uniqueness_hash'], unique=True) - op.create_index('derivedimage_uniqueness_hash', 'derivedimage', ['uniqueness_hash'], unique=True) - op.create_index('derivedimage_uuid', 'derivedimage', ['uuid'], unique=True) - op.create_table('manifestblob', + ) + op.create_index('derivedimage_blob_id', 'derivedimage', ['blob_id'], unique=False) + op.create_index('derivedimage_media_type_id', 'derivedimage', ['media_type_id'], unique=False) + op.create_index('derivedimage_signature_blob_id', 'derivedimage', ['signature_blob_id'], unique=False) + op.create_index('derivedimage_source_manifest_id', 'derivedimage', ['source_manifest_id'], unique=False) + op.create_index('derivedimage_source_manifest_id_blob_id', 'derivedimage', ['source_manifest_id', 'blob_id'], unique=True) + op.create_index('derivedimage_source_manifest_id_media_type_id_uniqueness_hash', 'derivedimage', ['source_manifest_id', 'media_type_id', 'uniqueness_hash'], unique=True) + op.create_index('derivedimage_uniqueness_hash', 'derivedimage', ['uniqueness_hash'], unique=True) + op.create_index('derivedimage_uuid', 'derivedimage', ['uuid'], unique=True) + + op.create_table( + 'manifestblob', sa.Column('id', sa.Integer(), nullable=False), sa.Column('manifest_id', sa.Integer(), nullable=False), sa.Column('blob_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_manifestblob_blob_id_blob')), sa.ForeignKeyConstraint(['manifest_id'], ['manifest.id'], name=op.f('fk_manifestblob_manifest_id_manifest')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestblob')) - ) - op.create_index('manifestblob_blob_id', 'manifestblob', ['blob_id'], unique=False) - op.create_index('manifestblob_manifest_id', 'manifestblob', ['manifest_id'], unique=False) - op.create_index('manifestblob_manifest_id_blob_id', 'manifestblob', ['manifest_id', 'blob_id'], unique=True) - op.create_table('manifestlabel', + ) + op.create_index('manifestblob_blob_id', 'manifestblob', ['blob_id'], unique=False) + op.create_index('manifestblob_manifest_id', 'manifestblob', ['manifest_id'], unique=False) + op.create_index('manifestblob_manifest_id_blob_id', 'manifestblob', ['manifest_id', 'blob_id'], unique=True) + + op.create_table( + 'manifestlabel', sa.Column('id', sa.Integer(), nullable=False), sa.Column('repository_id', sa.Integer(), nullable=False), sa.Column('annotated_id', sa.Integer(), nullable=False), @@ -173,12 +180,14 @@ def upgrade(tables): sa.ForeignKeyConstraint(['label_id'], ['label.id'], name=op.f('fk_manifestlabel_label_id_label')), sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_manifestlabel_repository_id_repository')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlabel')) - ) - op.create_index('manifestlabel_annotated_id', 'manifestlabel', ['annotated_id'], unique=False) - op.create_index('manifestlabel_label_id', 'manifestlabel', ['label_id'], unique=False) - op.create_index('manifestlabel_repository_id', 'manifestlabel', ['repository_id'], unique=False) - op.create_index('manifestlabel_repository_id_annotated_id_label_id', 'manifestlabel', ['repository_id', 'annotated_id', 'label_id'], unique=True) - op.create_table('manifestlayer', + ) + op.create_index('manifestlabel_annotated_id', 'manifestlabel', ['annotated_id'], unique=False) + op.create_index('manifestlabel_label_id', 'manifestlabel', ['label_id'], unique=False) + op.create_index('manifestlabel_repository_id', 'manifestlabel', ['repository_id'], unique=False) + op.create_index('manifestlabel_repository_id_annotated_id_label_id', 'manifestlabel', ['repository_id', 'annotated_id', 'label_id'], unique=True) + + op.create_table( + 'manifestlayer', sa.Column('id', sa.Integer(), nullable=False), sa.Column('blob_id', sa.Integer(), nullable=False), sa.Column('manifest_id', sa.Integer(), nullable=False), @@ -187,12 +196,14 @@ def upgrade(tables): sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_manifestlayer_blob_id_blob')), sa.ForeignKeyConstraint(['manifest_id'], ['manifest.id'], name=op.f('fk_manifestlayer_manifest_id_manifest')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlayer')) - ) - op.create_index('manifestlayer_blob_id', 'manifestlayer', ['blob_id'], unique=False) - op.create_index('manifestlayer_manifest_id', 'manifestlayer', ['manifest_id'], unique=False) - op.create_index('manifestlayer_manifest_id_manifest_index', 'manifestlayer', ['manifest_id', 'manifest_index'], unique=True) - op.create_index('manifestlayer_manifest_index', 'manifestlayer', ['manifest_index'], unique=False) - op.create_table('manifestlistmanifest', + ) + op.create_index('manifestlayer_blob_id', 'manifestlayer', ['blob_id'], unique=False) + op.create_index('manifestlayer_manifest_id', 'manifestlayer', ['manifest_id'], unique=False) + op.create_index('manifestlayer_manifest_id_manifest_index', 'manifestlayer', ['manifest_id', 'manifest_index'], unique=True) + op.create_index('manifestlayer_manifest_index', 'manifestlayer', ['manifest_index'], unique=False) + + op.create_table( + 'manifestlistmanifest', sa.Column('id', sa.Integer(), nullable=False), sa.Column('manifest_list_id', sa.Integer(), nullable=False), sa.Column('manifest_id', sa.Integer(), nullable=False), @@ -204,13 +215,15 @@ def upgrade(tables): sa.ForeignKeyConstraint(['manifest_list_id'], ['manifestlist.id'], name=op.f('fk_manifestlistmanifest_manifest_list_id_manifestlist')), sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifestlistmanifest_media_type_id_mediatype')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlistmanifest')) - ) - op.create_index('manifestlistmanifest_manifest_id', 'manifestlistmanifest', ['manifest_id'], unique=False) - op.create_index('manifestlistmanifest_manifest_list_id', 'manifestlistmanifest', ['manifest_list_id'], unique=False) - op.create_index('manifestlistmanifest_manifest_listid_os_arch_mtid', 'manifestlistmanifest', ['manifest_list_id', 'operating_system', 'architecture', 'media_type_id'], unique=False) - op.create_index('manifestlistmanifest_manifest_listid_mtid', 'manifestlistmanifest', ['manifest_list_id', 'media_type_id'], unique=False) - op.create_index('manifestlistmanifest_media_type_id', 'manifestlistmanifest', ['media_type_id'], unique=False) - op.create_table('tag', + ) + op.create_index('manifestlistmanifest_manifest_id', 'manifestlistmanifest', ['manifest_id'], unique=False) + op.create_index('manifestlistmanifest_manifest_list_id', 'manifestlistmanifest', ['manifest_list_id'], unique=False) + op.create_index('manifestlistmanifest_manifest_listid_os_arch_mtid', 'manifestlistmanifest', ['manifest_list_id', 'operating_system', 'architecture', 'media_type_id'], unique=False) + op.create_index('manifestlistmanifest_manifest_listid_mtid', 'manifestlistmanifest', ['manifest_list_id', 'media_type_id'], unique=False) + op.create_index('manifestlistmanifest_media_type_id', 'manifestlistmanifest', ['media_type_id'], unique=False) + + op.create_table( + 'tag', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', UTF8CharField(length=255), nullable=False), sa.Column('repository_id', sa.Integer(), nullable=False), @@ -227,16 +240,18 @@ def upgrade(tables): sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_tag_repository_id_repository')), sa.ForeignKeyConstraint(['tag_kind_id'], ['tagkind.id'], name=op.f('fk_tag_tag_kind_id_tagkind')), sa.PrimaryKeyConstraint('id', name=op.f('pk_tag')) - ) - op.create_index('tag_lifetime_end', 'tag', ['lifetime_end'], unique=False) - op.create_index('tag_linked_tag_id', 'tag', ['linked_tag_id'], unique=False) - op.create_index('tag_manifest_list_id', 'tag', ['manifest_list_id'], unique=False) - op.create_index('tag_repository_id', 'tag', ['repository_id'], unique=False) - op.create_index('tag_repository_id_name_hidden_tag_kind_id', 'tag', ['repository_id', 'name', 'hidden', 'tag_kind_id'], unique=False) - op.create_index('tag_repository_id_name_lifetime_end_tag_kind_id', 'tag', ['repository_id', 'name', 'lifetime_end', 'tag_kind_id'], unique=True) - op.create_index('tag_repository_id_name_tag_kind_id', 'tag', ['repository_id', 'name', 'tag_kind_id'], unique=False) - op.create_index('tag_tag_kind_id', 'tag', ['tag_kind_id'], unique=False) - op.create_table('manifestlayerdockerv1', + ) + op.create_index('tag_lifetime_end', 'tag', ['lifetime_end'], unique=False) + op.create_index('tag_linked_tag_id', 'tag', ['linked_tag_id'], unique=False) + op.create_index('tag_manifest_list_id', 'tag', ['manifest_list_id'], unique=False) + op.create_index('tag_repository_id', 'tag', ['repository_id'], unique=False) + op.create_index('tag_repository_id_name_hidden_tag_kind_id', 'tag', ['repository_id', 'name', 'hidden', 'tag_kind_id'], unique=False) + op.create_index('tag_repository_id_name_lifetime_end_tag_kind_id', 'tag', ['repository_id', 'name', 'lifetime_end', 'tag_kind_id'], unique=True) + op.create_index('tag_repository_id_name_tag_kind_id', 'tag', ['repository_id', 'name', 'tag_kind_id'], unique=False) + op.create_index('tag_tag_kind_id', 'tag', ['tag_kind_id'], unique=False) + + op.create_table( + 'manifestlayerdockerv1', sa.Column('id', sa.Integer(), nullable=False), sa.Column('manifest_layer_id', sa.Integer(), nullable=False), sa.Column('image_id', UTF8CharField(length=255), nullable=False), @@ -244,79 +259,69 @@ def upgrade(tables): sa.Column('compat_json', UTF8LongText, nullable=False), sa.ForeignKeyConstraint(['manifest_layer_id'], ['manifestlayer.id'], name=op.f('fk_manifestlayerdockerv1_manifest_layer_id_manifestlayer')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlayerdockerv1')) - ) - op.create_index('manifestlayerdockerv1_image_id', 'manifestlayerdockerv1', ['image_id'], unique=False) - op.create_index('manifestlayerdockerv1_manifest_layer_id', 'manifestlayerdockerv1', ['manifest_layer_id'], unique=False) - op.create_table('manifestlayerscan', + ) + op.create_index('manifestlayerdockerv1_image_id', 'manifestlayerdockerv1', ['image_id'], unique=False) + op.create_index('manifestlayerdockerv1_manifest_layer_id', 'manifestlayerdockerv1', ['manifest_layer_id'], unique=False) + + op.create_table( + 'manifestlayerscan', sa.Column('id', sa.Integer(), nullable=False), sa.Column('layer_id', sa.Integer(), nullable=False), sa.Column('scannable', sa.Boolean(), nullable=False), sa.Column('scanned_by', UTF8CharField(length=255), nullable=False), sa.ForeignKeyConstraint(['layer_id'], ['manifestlayer.id'], name=op.f('fk_manifestlayerscan_layer_id_manifestlayer')), sa.PrimaryKeyConstraint('id', name=op.f('pk_manifestlayerscan')) - ) - op.create_index('manifestlayerscan_layer_id', 'manifestlayerscan', ['layer_id'], unique=True) - op.create_index('derivedstorageforimage_source_imageid_trid_uniq_hash', 'derivedstorageforimage', ['source_image_id', 'transformation_id', 'uniqueness_hash'], unique=True) - op.drop_index('uniqueness_index', table_name='derivedstorageforimage') - op.drop_column(u'imagestorage', 'checksum') - op.add_column(u'repository', sa.Column('repo_kind_id', sa.Integer(), nullable=False, server_default="1")) - op.create_index('repository_repo_kind_id', 'repository', ['repo_kind_id'], unique=False) + ) + op.create_index('manifestlayerscan_layer_id', 'manifestlayerscan', ['layer_id'], unique=True) - op.create_foreign_key(op.f('fk_repository_repo_kind_id_repositorykind'), 'repository', 'repositorykind', ['repo_kind_id'], ['id']) + op.bulk_insert( + tables.blobplacementlocation, + [ + {'name': 'local_eu'}, + {'name': 'local_us'}, + ], + ) + op.bulk_insert( + tables.mediatype, + [ + {'name': 'application/vnd.cnr.blob.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.package-manifest.helm.v1.json'}, + {'name': 'application/vnd.cnr.package-manifest.kpm.v1.json'}, + {'name': 'application/vnd.cnr.package-manifest.docker-compose.v1.json'}, + {'name': 'application/vnd.cnr.package.kpm.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.package.helm.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.package.docker-compose.v1.tar+gzip'}, + {'name': 'application/vnd.cnr.manifests.v1.json'}, + {'name': 'application/vnd.cnr.manifest.list.v1.json'}, + ], + ) - op.bulk_insert(tables.blobplacementlocation, - [ - {'name': 'local_eu'}, - {'name': 'local_us'}, - ]) - - op.bulk_insert(tables.mediatype, - [ - {'name': 'application/vnd.cnr.blob.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.package-manifest.helm.v1.json'}, - {'name': 'application/vnd.cnr.package-manifest.kpm.v1.json'}, - {'name': 'application/vnd.cnr.package-manifest.docker-compose.v1.json'}, - {'name': 'application/vnd.cnr.package.kpm.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.package.helm.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.package.docker-compose.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.manifests.v1.json'}, - {'name': 'application/vnd.cnr.manifest.list.v1.json'}, - ]) - - op.bulk_insert(tables.tagkind, - [ - {'name': 'tag', 'id': 1}, - {'name': 'release', 'id': 2}, - {'name': 'channel', 'id': 3}, - ]) - - ### end Alembic commands ### + op.bulk_insert( + tables.tagkind, + [ + {'name': 'tag', 'id': 1}, + {'name': 'release', 'id': 2}, + {'name': 'channel', 'id': 3}, + ] + ) def downgrade(tables): - ### commands auto generated by Alembic - please adjust! ### - op.drop_constraint(op.f('fk_repository_repo_kind_id_repositorykind'), 'repository', type_='foreignkey') - op.drop_column(u'repository', 'repo_kind_id') - op.add_column(u'imagestorage', sa.Column('checksum', mysql.VARCHAR(length=255), nullable=True)) - op.create_index('uniqueness_index', 'derivedstorageforimage', ['source_image_id', 'transformation_id', 'uniqueness_hash'], unique=True) - op.drop_index('derivedstorageforimage_source_imageid_trid_uniq_hash', table_name='derivedstorageforimage') - op.drop_table('manifestlayerscan') - op.drop_table('manifestlayerdockerv1') - op.drop_table('tag') - op.drop_table('manifestlistmanifest') - op.drop_table('manifestlayer') - op.drop_table('manifestlabel') - op.drop_table('manifestblob') - op.drop_table('derivedimage') - op.drop_table('blobuploading') - op.drop_table('blobplacement') - op.drop_table('bittorrentpieces') - op.drop_table('manifestlist') - op.drop_table('manifest') - op.drop_table('blobplacementlocationpreference') - op.drop_table('blob') - op.drop_table('tagkind') - op.drop_table('repositorykind') - op.drop_table('blobplacementlocation') - ### end Alembic commands ### + op.drop_table('manifestlayerscan') + op.drop_table('manifestlayerdockerv1') + op.drop_table('tag') + op.drop_table('manifestlistmanifest') + op.drop_table('manifestlayer') + op.drop_table('manifestlabel') + op.drop_table('manifestblob') + op.drop_table('derivedimage') + op.drop_table('blobuploading') + op.drop_table('blobplacement') + op.drop_table('bittorrentpieces') + op.drop_table('manifestlist') + op.drop_table('manifest') + op.drop_table('blobplacementlocationpreference') + op.drop_table('blob') + op.drop_table('tagkind') + op.drop_table('blobplacementlocation') From 2a117f2d2442648ea081e00b527aca6724dc2780 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 16 Mar 2017 15:18:22 -0400 Subject: [PATCH 4/8] data.migrations: change CNR mimetypes to v0 Our initial CNR support is of a pre-v1 implementation of the specification. --- .../7a525c68eb13_add_oci_app_models.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py index 363f14078..c1cbd2655 100644 --- a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py +++ b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py @@ -285,15 +285,15 @@ def upgrade(tables): op.bulk_insert( tables.mediatype, [ - {'name': 'application/vnd.cnr.blob.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.package-manifest.helm.v1.json'}, - {'name': 'application/vnd.cnr.package-manifest.kpm.v1.json'}, - {'name': 'application/vnd.cnr.package-manifest.docker-compose.v1.json'}, - {'name': 'application/vnd.cnr.package.kpm.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.package.helm.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.package.docker-compose.v1.tar+gzip'}, - {'name': 'application/vnd.cnr.manifests.v1.json'}, - {'name': 'application/vnd.cnr.manifest.list.v1.json'}, + {'name': 'application/vnd.cnr.blob.v0.tar+gzip'}, + {'name': 'application/vnd.cnr.package-manifest.helm.v0.json'}, + {'name': 'application/vnd.cnr.package-manifest.kpm.v0.json'}, + {'name': 'application/vnd.cnr.package-manifest.docker-compose.v0.json'}, + {'name': 'application/vnd.cnr.package.kpm.v0.tar+gzip'}, + {'name': 'application/vnd.cnr.package.helm.v0.tar+gzip'}, + {'name': 'application/vnd.cnr.package.docker-compose.v0.tar+gzip'}, + {'name': 'application/vnd.cnr.manifests.v0.json'}, + {'name': 'application/vnd.cnr.manifest.list.v0.json'}, ], ) From f94d5c7684a4eeafb658fc76e3db0802eb8cc297 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 16 Mar 2017 16:37:16 -0400 Subject: [PATCH 5/8] initdb: skip data checks for beta classes & regen --- initdb.py | 5 ++++- test/data/test.db | Bin 1323008 -> 1622016 bytes 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/initdb.py b/initdb.py index c473f073e..55f55314b 100644 --- a/initdb.py +++ b/initdb.py @@ -14,7 +14,7 @@ from uuid import UUID, uuid4 from threading import Event from email.utils import formatdate -from data.database import (db, all_models, Role, TeamRole, Visibility, LoginService, +from data.database import (db, all_models, beta_classes, Role, TeamRole, Visibility, LoginService, BuildTriggerService, AccessTokenKind, LogEntryKind, ImageStorageLocation, ImageStorageTransformation, ImageStorageSignatureKind, ExternalNotificationEvent, ExternalNotificationMethod, NotificationKind, @@ -824,6 +824,9 @@ def find_models_missing_data(): # As a sanity check we are going to make sure that all db tables have some data models_missing_data = set() for one_model in all_models: + if one_model in beta_classes: + continue + try: one_model.select().get() except one_model.DoesNotExist: diff --git a/test/data/test.db b/test/data/test.db index c583ad3a65f0c25774707134c40a5fe5705d0dfb..b62a29fd2cd35c18b5856d9429c0ccf82b302138 100644 GIT binary patch delta 126997 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 delta 111916 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 L`QqO<#<%|im?@cy From 0e32e77e9973b1f38115e4ef4db610f461984508 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 16 Mar 2017 16:53:39 -0400 Subject: [PATCH 6/8] data.database: document all CNR/OCI models --- data/database.py | 85 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 21 deletions(-) diff --git a/data/database.py b/data/database.py index 58d4e03ce..04c90b011 100644 --- a/data/database.py +++ b/data/database.py @@ -1093,7 +1093,9 @@ class ServiceKey(BaseModel): class MediaType(BaseModel): - """ MediaType is an enumeration of the possible formats of various objects in the data model. """ + """ MediaType is an enumeration of the possible formats of various objects in the data model. + This model is a part of the new OCI/CNR model set. + """ name = CharField(index=True, unique=True) @@ -1105,14 +1107,18 @@ class Messages(BaseModel): class LabelSourceType(BaseModel): - """ LabelSourceType is an enumeration of the possible sources for a label. """ + """ LabelSourceType is an enumeration of the possible sources for a label. + This model is a part of the new OCI/CNR model set. + """ name = CharField(index=True, unique=True) mutable = BooleanField(default=False) class Label(BaseModel): - """ Label represents user-facing metadata associated with another entry in the - database (e.g. a Manifest). """ + """ Label represents user-facing metadata associated with another entry in the database (e.g. a + Manifest). + This model is a part of the new OCI/CNR model set. + """ uuid = CharField(default=uuid_generator, index=True, unique=True) key = CharField(index=True) value = TextField() @@ -1121,7 +1127,9 @@ class Label(BaseModel): class TagManifestLabel(BaseModel): - """ Mapping from a tag manifest to a label. """ + """ Mapping from a tag manifest to a label. + This model is a part of the new OCI/CNR model set. + """ repository = ForeignKeyField(Repository, index=True) annotated = ForeignKeyField(TagManifest, index=True) label = ForeignKeyField(Label) @@ -1135,7 +1143,9 @@ class TagManifestLabel(BaseModel): class Blob(BaseModel): - """ Blob represents a content-addressable object stored outside of the database. """ + """ Blob represents a content-addressable object stored outside of the database. + This model is a part of the new OCI/CNR model set. + """ digest = CharField(index=True, unique=True) media_type = EnumField(MediaType) size = BigIntegerField() @@ -1143,18 +1153,24 @@ class Blob(BaseModel): class BlobPlacementLocation(BaseModel): - """ BlobPlacementLocation is an enumeration of the possible storage locations for Blobs. """ + """ BlobPlacementLocation is an enumeration of the possible storage locations for Blobs. + This model is a part of the new OCI/CNR model set. + """ name = CharField(index=True, unique=True) class BlobPlacementLocationPreference(BaseModel): - """ BlobPlacementLocationPreference is a location to which a user's data will be replicated. """ + """ BlobPlacementLocationPreference is a location to which a user's data will be replicated. + This model is a part of the new OCI/CNR model set. + """ user = QuayUserField(index=True, allows_robots=False) location = EnumField(BlobPlacementLocation) class BlobPlacement(BaseModel): - """ BlobPlacement represents the location of a Blob. """ + """ BlobPlacement represents the location of a Blob. + This model is a part of the new OCI/CNR model set. + """ blob = ForeignKeyField(Blob) location = EnumField(BlobPlacementLocation) @@ -1167,7 +1183,9 @@ class BlobPlacement(BaseModel): class BlobUploading(BaseModel): - """ BlobUploading represents the state of a Blob currently being uploaded. """ + """ BlobUploading represents the state of a Blob currently being uploaded. + This model is a part of the new OCI/CNR model set. + """ uuid = CharField(index=True, unique=True) created = DateTimeField(default=datetime.now, index=True) repository = ForeignKeyField(Repository, index=True) @@ -1189,13 +1207,18 @@ class BlobUploading(BaseModel): class Manifest(BaseModel): - """ Manifest represents the metadata and collection of blobs that comprise a container image. """ + """ Manifest represents the metadata and collection of blobs that comprise a container image. + This model is a part of the new OCI/CNR model set. + """ digest = CharField(index=True, unique=True) media_type = EnumField(MediaType) manifest_json = JSONField() class ManifestLabel(BaseModel): + """ ManifestLabel represents label metadata annotating a Manifest. + This model is a part of the new OCI/CNR model set. + """ repository = ForeignKeyField(Repository, index=True) annotated = ForeignKeyField(Manifest, index=True) label = ForeignKeyField(Label) @@ -1209,7 +1232,9 @@ class ManifestLabel(BaseModel): class ManifestBlob(BaseModel): - """ ManifestBlob is a many-to-many relation table linking Manifests and Blobs. """ + """ ManifestBlob is a many-to-many relation table linking Manifests and Blobs. + This model is a part of the new OCI/CNR model set. + """ manifest = ForeignKeyField(Manifest, index=True) blob = ForeignKeyField(Blob, index=True) @@ -1222,7 +1247,9 @@ class ManifestBlob(BaseModel): class ManifestList(BaseModel): - """ ManifestList represents all of the various manifests that compose a Tag. """ + """ ManifestList represents all of the various manifests that compose a Tag. + This model is a part of the new OCI/CNR model set. + """ digest = CharField(index=True, unique=True) manifest_list_json = JSONField() schema_version = CharField() @@ -1230,12 +1257,16 @@ class ManifestList(BaseModel): class TagKind(BaseModel): - """ TagKind is a enumtable of to reference tag kinds """ + """ TagKind is a enumtable to reference tag kinds. + This model is a part of the new OCI/CNR model set. + """ name = CharField(index=True, unique=True) class Tag(BaseModel): - """ Tag represents a user-facing alias for referencing a ManifestList. """ + """ Tag represents a user-facing alias for referencing a ManifestList. + This model is a part of the new OCI/CNR model set. + """ name = CharField() repository = ForeignKeyField(Repository) manifest_list = ForeignKeyField(ManifestList, null=True) @@ -1262,7 +1293,9 @@ class Tag(BaseModel): Channel = Tag.alias() class ManifestListManifest(BaseModel): - """ ManifestListManifest is a many-to-many relation table linking ManifestLists and Manifests. """ + """ ManifestListManifest is a many-to-many relation table linking ManifestLists and Manifests. + This model is a part of the new OCI/CNR model set. + """ manifest_list = ForeignKeyField(ManifestList, index=True) manifest = ForeignKeyField(Manifest, index=True) operating_system = CharField(null=True) @@ -1280,7 +1313,9 @@ class ManifestListManifest(BaseModel): class ManifestLayer(BaseModel): - """ ManifestLayer represents one of the layers that compose a Manifest. """ + """ ManifestLayer represents one of the layers that compose a Manifest. + This model is a part of the new OCI/CNR model set. + """ blob = ForeignKeyField(Blob, index=True) manifest = ForeignKeyField(Manifest) manifest_index = IntegerField(index=True) # index 0 is the last command in a Dockerfile @@ -1295,7 +1330,9 @@ class ManifestLayer(BaseModel): class ManifestLayerDockerV1(BaseModel): - """ ManifestLayerDockerV1 is the Docker v1 registry protocol metadata for a ManifestLayer. """ + """ ManifestLayerDockerV1 is the Docker v1 registry protocol metadata for a ManifestLayer. + This model is a part of the new OCI/CNR model set. + """ manifest_layer = ForeignKeyField(ManifestLayer) image_id = CharField(index=True) checksum = CharField() @@ -1303,14 +1340,18 @@ class ManifestLayerDockerV1(BaseModel): class ManifestLayerScan(BaseModel): - """ ManifestLayerScan represents the state of security scanning for a ManifestLayer. """ + """ ManifestLayerScan represents the state of security scanning for a ManifestLayer. + This model is a part of the new OCI/CNR model set. + """ layer = ForeignKeyField(ManifestLayer, unique=True) scannable = BooleanField() scanned_by = CharField() class DerivedImage(BaseModel): - """ DerivedImage represents a Manifest transcoded into an alternative format. """ + """ DerivedImage represents a Manifest transcoded into an alternative format. + This model is a part of the new OCI/CNR model set. + """ uuid = CharField(default=uuid_generator, unique=True) source_manifest = ForeignKeyField(Manifest) derived_manifest_json = JSONField() @@ -1329,7 +1370,9 @@ class DerivedImage(BaseModel): class BitTorrentPieces(BaseModel): - """ BitTorrentPieces represents the BitTorrent piece metadata calculated from a Blob. """ + """ BitTorrentPieces represents the BitTorrent piece metadata calculated from a Blob. + This model is a part of the new OCI/CNR model set. + """ blob = ForeignKeyField(Blob) pieces = Base64BinaryField() piece_length = IntegerField() From c915a4053177863da77b3b9cf8c97ed648d7388b Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 16 Mar 2017 17:20:54 -0400 Subject: [PATCH 7/8] data.database: rm tag_kind from Tag indexes These shouldn't be necessary. --- data/database.py | 6 +++--- data/migrations/versions/7a525c68eb13_add_oci_app_models.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/database.py b/data/database.py index 04c90b011..1ae5b14d0 100644 --- a/data/database.py +++ b/data/database.py @@ -1282,10 +1282,10 @@ class Tag(BaseModel): database = db read_slaves = (read_slave,) indexes = ( - (('repository', 'name', 'tag_kind'), False), - (('repository', 'name', 'hidden', 'tag_kind'), False), + (('repository', 'name'), False), + (('repository', 'name', 'hidden'), False), # This unique index prevents deadlocks when concurrently moving and deleting tags - (('repository', 'name', 'lifetime_end', 'tag_kind'), True), + (('repository', 'name', 'lifetime_end'), True), ) diff --git a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py index c1cbd2655..1188a312d 100644 --- a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py +++ b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py @@ -245,9 +245,9 @@ def upgrade(tables): op.create_index('tag_linked_tag_id', 'tag', ['linked_tag_id'], unique=False) op.create_index('tag_manifest_list_id', 'tag', ['manifest_list_id'], unique=False) op.create_index('tag_repository_id', 'tag', ['repository_id'], unique=False) - op.create_index('tag_repository_id_name_hidden_tag_kind_id', 'tag', ['repository_id', 'name', 'hidden', 'tag_kind_id'], unique=False) - op.create_index('tag_repository_id_name_lifetime_end_tag_kind_id', 'tag', ['repository_id', 'name', 'lifetime_end', 'tag_kind_id'], unique=True) - op.create_index('tag_repository_id_name_tag_kind_id', 'tag', ['repository_id', 'name', 'tag_kind_id'], unique=False) + op.create_index('tag_repository_id_name_hidden', 'tag', ['repository_id', 'name', 'hidden'], unique=False) + op.create_index('tag_repository_id_name_lifetime_end', 'tag', ['repository_id', 'name', 'lifetime_end'], unique=True) + op.create_index('tag_repository_id_name', 'tag', ['repository_id', 'name'], unique=False) op.create_index('tag_tag_kind_id', 'tag', ['tag_kind_id'], unique=False) op.create_table( From ad029fb3311855baee4cead3fca4d4d47f3328cf Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Fri, 17 Mar 2017 13:56:20 -0400 Subject: [PATCH 8/8] data.migrations: don't use UTF-8 for unique fields Unique indexes must have less than 767 bytes and UTF-8 encoding with 255 chars is beyond this maximum. Since this is an internal identifier, we can be confident that we will not require UTF-8 for it in the future. --- .../7a525c68eb13_add_oci_app_models.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py index 1188a312d..8abe4648c 100644 --- a/data/migrations/versions/7a525c68eb13_add_oci_app_models.py +++ b/data/migrations/versions/7a525c68eb13_add_oci_app_models.py @@ -20,7 +20,7 @@ def upgrade(tables): op.create_table( 'tagkind', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_tagkind')) ) op.create_index('tagkind_name', 'tagkind', ['name'], unique=True) @@ -28,7 +28,7 @@ def upgrade(tables): op.create_table( 'blobplacementlocation', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), sa.PrimaryKeyConstraint('id', name=op.f('pk_blobplacementlocation')) ) op.create_index('blobplacementlocation_name', 'blobplacementlocation', ['name'], unique=True) @@ -36,7 +36,7 @@ def upgrade(tables): op.create_table( 'blob', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('digest', UTF8CharField(length=255), nullable=False), + sa.Column('digest', sa.String(length=255), nullable=False), sa.Column('media_type_id', sa.Integer(), nullable=False), sa.Column('size', sa.BigInteger(), nullable=False), sa.Column('uncompressed_size', sa.BigInteger(), nullable=True), @@ -61,7 +61,7 @@ def upgrade(tables): op.create_table( 'manifest', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('digest', UTF8CharField(length=255), nullable=False), + sa.Column('digest', sa.String(length=255), nullable=False), sa.Column('media_type_id', sa.Integer(), nullable=False), sa.Column('manifest_json', UTF8LongText, nullable=False), sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_manifest_media_type_id_mediatype')), @@ -73,7 +73,7 @@ def upgrade(tables): op.create_table( 'manifestlist', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('digest', UTF8CharField(length=255), nullable=False), + sa.Column('digest', sa.String(length=255), nullable=False), sa.Column('manifest_list_json', UTF8LongText, nullable=False), sa.Column('schema_version', UTF8CharField(length=255), nullable=False), sa.Column('media_type_id', sa.Integer(), nullable=False), @@ -111,7 +111,7 @@ def upgrade(tables): op.create_table( 'blobuploading', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('uuid', UTF8CharField(length=255), nullable=False), + sa.Column('uuid', sa.String(length=255), nullable=False), sa.Column('created', sa.DateTime(), nullable=False), sa.Column('repository_id', sa.Integer(), nullable=False), sa.Column('location_id', sa.Integer(), nullable=False), @@ -135,12 +135,12 @@ def upgrade(tables): op.create_table( 'derivedimage', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('uuid', UTF8CharField(length=255), nullable=False), + sa.Column('uuid', sa.String(length=255), nullable=False), sa.Column('source_manifest_id', sa.Integer(), nullable=False), sa.Column('derived_manifest_json', UTF8LongText, nullable=False), sa.Column('media_type_id', sa.Integer(), nullable=False), sa.Column('blob_id', sa.Integer(), nullable=False), - sa.Column('uniqueness_hash', UTF8CharField(length=255), nullable=False), + sa.Column('uniqueness_hash', sa.String(length=255), nullable=False), sa.Column('signature_blob_id', sa.Integer(), nullable=True), sa.ForeignKeyConstraint(['blob_id'], ['blob.id'], name=op.f('fk_derivedimage_blob_id_blob')), sa.ForeignKeyConstraint(['media_type_id'], ['mediatype.id'], name=op.f('fk_derivedimage_media_type_id_mediatype')), @@ -225,7 +225,7 @@ def upgrade(tables): op.create_table( 'tag', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', UTF8CharField(length=255), nullable=False), + sa.Column('name', UTF8CharField(length=190), nullable=False), sa.Column('repository_id', sa.Integer(), nullable=False), sa.Column('manifest_list_id', sa.Integer(), nullable=True), sa.Column('lifetime_start', sa.BigInteger(), nullable=False),