Merge pull request #3148 from quay/joseph.schorr/QUAY-950/appr-step-3

Phase 3 of Appr migration
This commit is contained in:
Joseph Schorr 2018-07-21 15:46:54 -04:00 committed by GitHub
commit 0346cb651e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 219 additions and 168 deletions

View file

@ -1,7 +1,5 @@
from collections import namedtuple from collections import namedtuple
from data.database import (Tag, TagKind, BlobPlacementLocation, ManifestList, ManifestBlob, Blob,
ManifestListManifest, Manifest, BlobPlacement, Channel)
from data.database import (ApprTag, ApprTagKind, ApprBlobPlacementLocation, ApprManifestList, from data.database import (ApprTag, ApprTagKind, ApprBlobPlacementLocation, ApprManifestList,
ApprManifestBlob, ApprBlob, ApprManifestListManifest, ApprManifest, ApprManifestBlob, ApprBlob, ApprManifestListManifest, ApprManifest,
ApprBlobPlacement, ApprChannel) ApprBlobPlacement, ApprChannel)
@ -11,10 +9,6 @@ ModelsRef = namedtuple('ModelsRef', ['Tag', 'TagKind', 'BlobPlacementLocation',
'BlobPlacement', 'Channel', 'manifestlistmanifest_set_name', 'BlobPlacement', 'Channel', 'manifestlistmanifest_set_name',
'tag_set_prefetch_name']) 'tag_set_prefetch_name'])
OLD_MODELS = ModelsRef(Tag, TagKind, BlobPlacementLocation, ManifestList, ManifestBlob, Blob,
ManifestListManifest, Manifest, BlobPlacement, Channel,
'manifestlistmanifest_set', 'tag_set_prefetch')
NEW_MODELS = ModelsRef(ApprTag, ApprTagKind, ApprBlobPlacementLocation, ApprManifestList, NEW_MODELS = ModelsRef(ApprTag, ApprTagKind, ApprBlobPlacementLocation, ApprManifestList,
ApprManifestBlob, ApprBlob, ApprManifestListManifest, ApprManifest, ApprManifestBlob, ApprBlob, ApprManifestListManifest, ApprManifest,
ApprBlobPlacement, ApprChannel, 'apprmanifestlistmanifest_set', ApprBlobPlacement, ApprChannel, 'apprmanifestlistmanifest_set',

View file

@ -471,7 +471,7 @@ class User(BaseModel):
TagManifest, AccessToken, OAuthAccessToken, BlobUpload, TagManifest, AccessToken, OAuthAccessToken, BlobUpload,
RepositoryNotification, OAuthAuthorizationCode, RepositoryNotification, OAuthAuthorizationCode,
RepositoryActionCount, TagManifestLabel, RepositoryActionCount, TagManifestLabel,
TeamSync, RepositorySearchScore, DeletedNamespace} | cnr_classes | appr_classes TeamSync, RepositorySearchScore, DeletedNamespace} | appr_classes
delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes) delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes)
@ -619,7 +619,7 @@ class Repository(BaseModel):
# are cleaned up directly # are cleaned up directly
skip_transitive_deletes = {RepositoryTag, RepositoryBuild, RepositoryBuildTrigger, BlobUpload, skip_transitive_deletes = {RepositoryTag, RepositoryBuild, RepositoryBuildTrigger, BlobUpload,
Image, TagManifest, TagManifestLabel, Label, DerivedStorageForImage, Image, TagManifest, TagManifestLabel, Label, DerivedStorageForImage,
RepositorySearchScore} | cnr_classes | appr_classes RepositorySearchScore} | appr_classes
delete_instance_filtered(self, Repository, delete_nullable, skip_transitive_deletes) delete_instance_filtered(self, Repository, delete_nullable, skip_transitive_deletes)
@ -1231,17 +1231,6 @@ class TagManifestLabel(BaseModel):
) )
class Blob(BaseModel):
""" Blob represents a content-addressable object stored outside of the database.
This is deprecated in favor of ApprBlob.
"""
digest = CharField(index=True, unique=True)
media_type = EnumField(MediaType)
size = BigIntegerField()
uncompressed_size = BigIntegerField(null=True)
class ApprBlob(BaseModel): class ApprBlob(BaseModel):
""" ApprBlob represents a content-addressable object stored outside of the database. """ ApprBlob represents a content-addressable object stored outside of the database.
""" """
@ -1251,34 +1240,12 @@ class ApprBlob(BaseModel):
uncompressed_size = BigIntegerField(null=True) uncompressed_size = BigIntegerField(null=True)
class BlobPlacementLocation(BaseModel):
""" BlobPlacementLocation is an enumeration of the possible storage locations for Blobs.
This is deprecated in favor of ApprBlobPlacementLocation.
"""
name = CharField(index=True, unique=True)
class ApprBlobPlacementLocation(BaseModel): class ApprBlobPlacementLocation(BaseModel):
""" ApprBlobPlacementLocation is an enumeration of the possible storage locations for ApprBlobs. """ ApprBlobPlacementLocation is an enumeration of the possible storage locations for ApprBlobs.
""" """
name = CharField(index=True, unique=True) name = CharField(index=True, unique=True)
class BlobPlacement(BaseModel):
""" BlobPlacement represents the location of a Blob.
This is deprecated in favor of ApprBlobPlacement.
"""
blob = ForeignKeyField(Blob)
location = EnumField(BlobPlacementLocation)
class Meta:
database = db
read_slaves = (read_slave,)
indexes = (
(('blob', 'location'), True),
)
class ApprBlobPlacement(BaseModel): class ApprBlobPlacement(BaseModel):
""" ApprBlobPlacement represents the location of a Blob. """ ApprBlobPlacement represents the location of a Blob.
""" """
@ -1293,15 +1260,6 @@ class ApprBlobPlacement(BaseModel):
) )
class Manifest(BaseModel):
""" Manifest represents the metadata and collection of blobs that comprise a container image.
This is deprecated in favor of ApprManifest.
"""
digest = CharField(index=True, unique=True)
media_type = EnumField(MediaType)
manifest_json = JSONField()
class ApprManifest(BaseModel): class ApprManifest(BaseModel):
""" ApprManifest represents the metadata and collection of blobs that comprise an Appr image. """ ApprManifest represents the metadata and collection of blobs that comprise an Appr image.
""" """
@ -1310,21 +1268,6 @@ class ApprManifest(BaseModel):
manifest_json = JSONField() manifest_json = JSONField()
class ManifestBlob(BaseModel):
""" ManifestBlob is a many-to-many relation table linking Manifests and Blobs.
This is deprecated in favor of ApprManifestBlob.
"""
manifest = ForeignKeyField(Manifest, index=True)
blob = ForeignKeyField(Blob, index=True)
class Meta:
database = db
read_slaves = (read_slave,)
indexes = (
(('manifest', 'blob'), True),
)
class ApprManifestBlob(BaseModel): class ApprManifestBlob(BaseModel):
""" ApprManifestBlob is a many-to-many relation table linking ApprManifests and ApprBlobs. """ ApprManifestBlob is a many-to-many relation table linking ApprManifests and ApprBlobs.
""" """
@ -1339,16 +1282,6 @@ class ApprManifestBlob(BaseModel):
) )
class ManifestList(BaseModel):
""" ManifestList represents all of the various manifests that compose a Tag.
This is deprecated in favor of ApprManifestList.
"""
digest = CharField(index=True, unique=True)
manifest_list_json = JSONField()
schema_version = CharField()
media_type = EnumField(MediaType)
class ApprManifestList(BaseModel): class ApprManifestList(BaseModel):
""" ApprManifestList represents all of the various Appr manifests that compose an ApprTag. """ ApprManifestList represents all of the various Appr manifests that compose an ApprTag.
""" """
@ -1358,45 +1291,12 @@ class ApprManifestList(BaseModel):
media_type = EnumField(MediaType) media_type = EnumField(MediaType)
class TagKind(BaseModel):
""" TagKind is a enumtable to reference tag kinds.
This model is deprecated in favor of ApprTagKind.
"""
name = CharField(index=True, unique=True)
class ApprTagKind(BaseModel): class ApprTagKind(BaseModel):
""" ApprTagKind is a enumtable to reference tag kinds. """ ApprTagKind is a enumtable to reference tag kinds.
""" """
name = CharField(index=True, unique=True) name = CharField(index=True, unique=True)
class Tag(BaseModel):
""" Tag represents a user-facing alias for referencing a ManifestList.
This model is deprecated in favor of ApprTag.
"""
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 = (
(('repository', 'name'), False),
(('repository', 'name', 'hidden'), False),
# This unique index prevents deadlocks when concurrently moving and deleting tags
(('repository', 'name', 'lifetime_end'), True),
)
class ApprTag(BaseModel): class ApprTag(BaseModel):
""" ApprTag represents a user-facing alias for referencing an ApprManifestList. """ ApprTag represents a user-facing alias for referencing an ApprManifestList.
""" """
@ -1421,30 +1321,9 @@ class ApprTag(BaseModel):
(('repository', 'name', 'lifetime_end'), True), (('repository', 'name', 'lifetime_end'), True),
) )
Channel = Tag.alias()
ApprChannel = ApprTag.alias() ApprChannel = ApprTag.alias()
class ManifestListManifest(BaseModel):
""" ManifestListManifest is a many-to-many relation table linking ManifestLists and Manifests.
This model is deprecated in favor of ApprManifestListManifest.
"""
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),
)
class ApprManifestListManifest(BaseModel): class ApprManifestListManifest(BaseModel):
""" ApprManifestListManifest is a many-to-many relation table linking ApprManifestLists and """ ApprManifestListManifest is a many-to-many relation table linking ApprManifestLists and
ApprManifests. ApprManifests.
@ -1484,8 +1363,6 @@ class AppSpecificAuthToken(BaseModel):
) )
cnr_classes = set([Tag, TagKind, BlobPlacementLocation, ManifestList, ManifestBlob, Blob,
ManifestListManifest, Manifest, BlobPlacement])
appr_classes = set([ApprTag, ApprTagKind, ApprBlobPlacementLocation, ApprManifestList, appr_classes = set([ApprTag, ApprTagKind, ApprBlobPlacementLocation, ApprManifestList,
ApprManifestBlob, ApprBlob, ApprManifestListManifest, ApprManifest, ApprManifestBlob, ApprBlob, ApprManifestListManifest, ApprManifest,
ApprBlobPlacement]) ApprBlobPlacement])

View file

@ -13,6 +13,7 @@ down_revision = 'e2894a3a3c19'
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.dialects import mysql from sqlalchemy.dialects import mysql
from sqlalchemy.sql import table, column
from util.migrate import UTF8LongText, UTF8CharField from util.migrate import UTF8LongText, UTF8CharField
@ -274,8 +275,13 @@ def upgrade(tables, tester):
) )
op.create_index('manifestlayerscan_layer_id', 'manifestlayerscan', ['layer_id'], unique=True) op.create_index('manifestlayerscan_layer_id', 'manifestlayerscan', ['layer_id'], unique=True)
blobplacementlocation_table = table('blobplacementlocation',
column('id', sa.Integer()),
column('name', sa.String()),
)
op.bulk_insert( op.bulk_insert(
tables.blobplacementlocation, blobplacementlocation_table,
[ [
{'name': 'local_eu'}, {'name': 'local_eu'},
{'name': 'local_us'}, {'name': 'local_us'},
@ -297,8 +303,13 @@ def upgrade(tables, tester):
], ],
) )
tagkind_table = table('tagkind',
column('id', sa.Integer()),
column('name', sa.String()),
)
op.bulk_insert( op.bulk_insert(
tables.tagkind, tagkind_table,
[ [
{'id': 1, 'name': 'tag'}, {'id': 1, 'name': 'tag'},
{'id': 2, 'name': 'release'}, {'id': 2, 'name': 'release'},
@ -306,7 +317,6 @@ def upgrade(tables, tester):
] ]
) )
def downgrade(tables, tester): def downgrade(tables, tester):
op.drop_table('manifestlayerscan') op.drop_table('manifestlayerscan')
op.drop_table('manifestlayerdockerv1') op.drop_table('manifestlayerdockerv1')

View file

@ -0,0 +1,189 @@
"""Delete old Appr tables
Revision ID: d17c695859ea
Revises: 5d463ea1e8a8
Create Date: 2018-07-16 15:21:11.593040
"""
# revision identifiers, used by Alembic.
revision = 'd17c695859ea'
down_revision = '5d463ea1e8a8'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql import table, column
from util.migrate import UTF8LongText, UTF8CharField
def upgrade(tables, tester):
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('tag')
op.drop_table('manifestlistmanifest')
op.drop_table('manifestlist')
op.drop_table('manifestblob')
op.drop_table('manifest')
op.drop_table('blobplacement')
op.drop_table('blob')
op.drop_table('blobplacementlocation')
op.drop_table('tagkind')
# ### end Alembic commands ###
def downgrade(tables, tester):
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
'tagkind',
sa.Column('id', sa.Integer(), 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)
op.create_table(
'blobplacementlocation',
sa.Column('id', sa.Integer(), 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)
op.create_table(
'blob',
sa.Column('id', sa.Integer(), 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),
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(
'manifest',
sa.Column('id', sa.Integer(), 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')),
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', 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),
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(
'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(
'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(
'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=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),
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', ['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)
# ### end Alembic commands ###
blobplacementlocation_table = table('blobplacementlocation',
column('id', sa.Integer()),
column('name', sa.String()),
)
op.bulk_insert(
blobplacementlocation_table,
[
{'name': 'local_eu'},
{'name': 'local_us'},
],
)
tagkind_table = table('tagkind',
column('id', sa.Integer()),
column('name', sa.String()),
)
op.bulk_insert(
tagkind_table,
[
{'id': 1, 'name': 'tag'},
{'id': 2, 'name': 'release'},
{'id': 3, 'name': 'channel'},
]
)

View file

@ -9,11 +9,11 @@ from cachetools import ttl_cache
from data.model import ( from data.model import (
config, DataModelException, tag, db_transaction, storage, permission, _basequery) config, DataModelException, tag, db_transaction, storage, permission, _basequery)
from data.database import ( from data.database import (
Repository, Namespace, RepositoryTag, Star, Image, ImageStorage, User, Visibility, Tag, ApprTag, Repository, Namespace, RepositoryTag, Star, Image, ImageStorage, User, Visibility,
RepositoryPermission, RepositoryActionCount, Role, RepositoryAuthorizedEmail, TagManifest, RepositoryPermission, RepositoryActionCount, Role, RepositoryAuthorizedEmail, TagManifest,
DerivedStorageForImage, Label, TagManifestLabel, db_for_update, get_epoch_timestamp, DerivedStorageForImage, Label, TagManifestLabel, db_for_update, get_epoch_timestamp,
db_random_func, db_concat_func, RepositorySearchScore, RepositoryKind) db_random_func, db_concat_func, RepositorySearchScore, RepositoryKind, ApprTag)
from data.text import prefix_search from data.text import prefix_search
from util.itertoolrecipes import take from util.itertoolrecipes import take
@ -90,8 +90,6 @@ def purge_repository(namespace_name, repository_name):
# Delete the repository of all Appr-referenced entries. # Delete the repository of all Appr-referenced entries.
# Note that new-model Tag's must be deleted in *two* passes, as they can reference parent tags, # Note that new-model Tag's must be deleted in *two* passes, as they can reference parent tags,
# and MySQL is... particular... about such relationships when deleting. # and MySQL is... particular... about such relationships when deleting.
Tag.delete().where(Tag.repository == repo, ~(Tag.linked_tag >> None)).execute()
Tag.delete().where(Tag.repository == repo).execute()
ApprTag.delete().where(ApprTag.repository == repo, ~(ApprTag.linked_tag >> None)).execute() ApprTag.delete().where(ApprTag.repository == repo, ~(ApprTag.linked_tag >> None)).execute()
ApprTag.delete().where(ApprTag.repository == repo).execute() ApprTag.delete().where(ApprTag.repository == repo).execute()

View file

@ -8,8 +8,8 @@ from data.model import (config, db_transaction, InvalidImageException, TorrentIn
DataModelException, _basequery) DataModelException, _basequery)
from data.database import (ImageStorage, Image, ImageStoragePlacement, ImageStorageLocation, from data.database import (ImageStorage, Image, ImageStoragePlacement, ImageStorageLocation,
ImageStorageTransformation, ImageStorageSignature, ImageStorageTransformation, ImageStorageSignature,
ImageStorageSignatureKind, Repository, Namespace, TorrentInfo, Blob, ImageStorageSignatureKind, Repository, Namespace, TorrentInfo, ApprBlob,
ApprBlob, ensure_under_transaction) ensure_under_transaction)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -105,21 +105,15 @@ def garbage_collect_storage(storage_id_whitelist):
logger.warning('GC attempted to remove CAS checksums %s, which are still IS referenced', logger.warning('GC attempted to remove CAS checksums %s, which are still IS referenced',
is_referenced_checksums) is_referenced_checksums)
# Check the ApprBlob tables as well. # Check the ApprBlob table as well.
query = Blob.select(Blob.digest).where(Blob.digest << list(content_checksums))
blob_referenced_checksums = set([blob.digest for blob in query])
if blob_referenced_checksums:
logger.warning('GC attempted to remove CAS checksums %s, which are still Blob referenced',
blob_referenced_checksums)
query = ApprBlob.select(ApprBlob.digest).where(ApprBlob.digest << list(content_checksums)) query = ApprBlob.select(ApprBlob.digest).where(ApprBlob.digest << list(content_checksums))
appr_blob_referenced_checksums = set([blob.digest for blob in query]) appr_blob_referenced_checksums = set([blob.digest for blob in query])
if appr_blob_referenced_checksums: if appr_blob_referenced_checksums:
logger.warning('GC attempted to remove CAS checksums %s, which are ApprBlob referenced', logger.warning('GC attempted to remove CAS checksums %s, which are ApprBlob referenced',
appr_blob_referenced_checksums) appr_blob_referenced_checksums)
unreferenced_checksums = (content_checksums - blob_referenced_checksums - unreferenced_checksums = (content_checksums - appr_blob_referenced_checksums -
appr_blob_referenced_checksums - is_referenced_checksums) is_referenced_checksums)
# Return all placements for all image storages found not at a CAS path or with a content # Return all placements for all image storages found not at a CAS path or with a content
# checksum that is referenced. # checksum that is referenced.

View file

@ -10,7 +10,7 @@ from playhouse.test_utils import assert_query_count
from data import model, database from data import model, database
from data.database import (Image, ImageStorage, DerivedStorageForImage, Label, TagManifestLabel, from data.database import (Image, ImageStorage, DerivedStorageForImage, Label, TagManifestLabel,
Blob, ApprBlob) ApprBlob)
from test.fixtures import * from test.fixtures import *
@ -187,9 +187,6 @@ def assert_gc_integrity(expect_storage_removed=True):
if storage_row.cas_path: if storage_row.cas_path:
storage.get_content({preferred}, storage.blob_path(storage_row.content_checksum)) storage.get_content({preferred}, storage.blob_path(storage_row.content_checksum))
for blob_row in Blob.select():
storage.get_content({preferred}, storage.blob_path(blob_row.digest))
for blob_row in ApprBlob.select(): for blob_row in ApprBlob.select():
storage.get_content({preferred}, storage.blob_path(blob_row.digest)) storage.get_content({preferred}, storage.blob_path(blob_row.digest))
@ -592,7 +589,6 @@ def test_images_shared_cas_with_new_blob_table(default_tag_policy, initialized_d
media_type = database.MediaType.get(name='text/plain') media_type = database.MediaType.get(name='text/plain')
is1 = database.ImageStorage.create(content_checksum=digest, uploading=False) is1 = database.ImageStorage.create(content_checksum=digest, uploading=False)
database.Blob.create(digest=digest, size=0, media_type=media_type)
database.ApprBlob.create(digest=digest, size=0, media_type=media_type) database.ApprBlob.create(digest=digest, size=0, media_type=media_type)
location = database.ImageStorageLocation.get(name=preferred) location = database.ImageStorageLocation.get(name=preferred)

View file

@ -10,7 +10,7 @@ import data.model
from app import storage, authentication from app import storage, authentication
from data import appr_model from data import appr_model
from data.database import Repository, MediaType, db_transaction from data.database import Repository, MediaType, db_transaction
from data.appr_model.models import OLD_MODELS, NEW_MODELS from data.appr_model.models import NEW_MODELS
from endpoints.appr.models_interface import ( from endpoints.appr.models_interface import (
ApplicationManifest, ApplicationRelease, ApplicationSummaryView, AppRegistryDataInterface, ApplicationManifest, ApplicationRelease, ApplicationSummaryView, AppRegistryDataInterface,
BlobDescriptor, ChannelView, ChannelReleasesView) BlobDescriptor, ChannelView, ChannelReleasesView)
@ -310,5 +310,5 @@ class CNRAppModel(AppRegistryDataInterface):
return appr_model.blob.get_blob_locations(digest, self.models_ref) return appr_model.blob.get_blob_locations(digest, self.models_ref)
# Phase 2: Read and write from new tables. # Phase 3: Read and write from new tables.
model = CNRAppModel(NEW_MODELS, features.READONLY_APP_REGISTRY) model = CNRAppModel(NEW_MODELS, features.READONLY_APP_REGISTRY)

View file

@ -14,14 +14,14 @@ from uuid import UUID, uuid4
from threading import Event from threading import Event
from email.utils import formatdate from email.utils import formatdate
from data.database import (db, all_models, cnr_classes, Role, TeamRole, Visibility, LoginService, from data.database import (db, all_models, Role, TeamRole, Visibility, LoginService,
BuildTriggerService, AccessTokenKind, LogEntryKind, ImageStorageLocation, BuildTriggerService, AccessTokenKind, LogEntryKind, ImageStorageLocation,
ImageStorageTransformation, ImageStorageSignatureKind, ImageStorageTransformation, ImageStorageSignatureKind,
ExternalNotificationEvent, ExternalNotificationMethod, NotificationKind, ExternalNotificationEvent, ExternalNotificationMethod, NotificationKind,
QuayRegion, QuayService, UserRegion, OAuthAuthorizationCode, QuayRegion, QuayService, UserRegion, OAuthAuthorizationCode,
ServiceKeyApprovalType, MediaType, LabelSourceType, UserPromptKind, ServiceKeyApprovalType, MediaType, LabelSourceType, UserPromptKind,
RepositoryKind, TagKind, BlobPlacementLocation, User, DisableReason, RepositoryKind, User, DisableReason, DeletedNamespace, appr_classes,
DeletedNamespace, appr_classes, ApprTagKind, ApprBlobPlacementLocation) ApprTagKind, ApprBlobPlacementLocation)
from data import model from data import model
from data.queue import WorkQueue from data.queue import WorkQueue
from app import app, storage as store, tf from app import app, storage as store, tf
@ -361,9 +361,6 @@ def initialize_database():
ImageStorageLocation.create(name='local_eu') ImageStorageLocation.create(name='local_eu')
ImageStorageLocation.create(name='local_us') ImageStorageLocation.create(name='local_us')
BlobPlacementLocation.create(name='local_eu')
BlobPlacementLocation.create(name='local_us')
ApprBlobPlacementLocation.create(name='local_eu') ApprBlobPlacementLocation.create(name='local_eu')
ApprBlobPlacementLocation.create(name='local_us') ApprBlobPlacementLocation.create(name='local_us')
@ -434,10 +431,6 @@ def initialize_database():
RepositoryKind.create(name='image') RepositoryKind.create(name='image')
RepositoryKind.create(name='application') RepositoryKind.create(name='application')
TagKind.create(name='tag')
TagKind.create(name='release')
TagKind.create(name='channel')
ApprTagKind.create(name='tag') ApprTagKind.create(name='tag')
ApprTagKind.create(name='release') ApprTagKind.create(name='release')
ApprTagKind.create(name='channel') ApprTagKind.create(name='channel')
@ -913,7 +906,7 @@ def find_models_missing_data():
# whitelisted. # whitelisted.
models_missing_data = set() models_missing_data = set()
for one_model in all_models: for one_model in all_models:
if one_model in cnr_classes or one_model in appr_classes: if one_model in appr_classes:
continue continue
try: try: