From 6622f27c93cf8e75ab18291034551e8691f5accd Mon Sep 17 00:00:00 2001 From: Joseph Schorr <joseph.schorr@coreos.com> Date: Wed, 23 May 2018 17:08:00 -0400 Subject: [PATCH] Rename oci_model to appr_model --- data/{oci_model => appr_model}/__init__.py | 2 +- data/{oci_model => appr_model}/blob.py | 0 data/{oci_model => appr_model}/channel.py | 2 +- data/{oci_model => appr_model}/manifest.py | 2 +- .../manifest_list.py | 0 data/{oci_model => appr_model}/package.py | 2 +- data/{oci_model => appr_model}/release.py | 2 +- data/{oci_model => appr_model}/tag.py | 0 data/database.py | 141 ++------------- ..._remove_oci_tables_not_used_by_cnr_the_.py | 167 ++++++++++++++++++ endpoints/api/repository_models_pre_oci.py | 7 +- endpoints/appr/cnr_backend.py | 2 +- .../appr/{models_oci.py => models_cnr.py} | 38 ++-- endpoints/appr/registry.py | 2 +- endpoints/appr/test/test_api.py | 4 +- endpoints/appr/test/test_digest_prefix.py | 2 +- initdb.py | 4 +- test/test_api_usage.py | 12 +- util/config/database.py | 4 +- 19 files changed, 222 insertions(+), 171 deletions(-) rename data/{oci_model => appr_model}/__init__.py (72%) rename data/{oci_model => appr_model}/blob.py (100%) rename data/{oci_model => appr_model}/channel.py (97%) rename data/{oci_model => appr_model}/manifest.py (97%) rename data/{oci_model => appr_model}/manifest_list.py (100%) rename data/{oci_model => appr_model}/package.py (97%) rename data/{oci_model => appr_model}/release.py (98%) rename data/{oci_model => appr_model}/tag.py (100%) create mode 100644 data/migrations/versions/5cbbfc95bac7_remove_oci_tables_not_used_by_cnr_the_.py rename endpoints/appr/{models_oci.py => models_cnr.py} (88%) diff --git a/data/oci_model/__init__.py b/data/appr_model/__init__.py similarity index 72% rename from data/oci_model/__init__.py rename to data/appr_model/__init__.py index 94b4f9bb8..7c9620864 100644 --- a/data/oci_model/__init__.py +++ b/data/appr_model/__init__.py @@ -1,4 +1,4 @@ -from data.oci_model import ( +from data.appr_model import ( blob, channel, manifest, diff --git a/data/oci_model/blob.py b/data/appr_model/blob.py similarity index 100% rename from data/oci_model/blob.py rename to data/appr_model/blob.py diff --git a/data/oci_model/channel.py b/data/appr_model/channel.py similarity index 97% rename from data/oci_model/channel.py rename to data/appr_model/channel.py index d7e340eb0..e9e3c2d90 100644 --- a/data/oci_model/channel.py +++ b/data/appr_model/channel.py @@ -1,5 +1,5 @@ from data.database import Tag, Channel -from data.oci_model import tag as tag_model +from data.appr_model import tag as tag_model def get_channel_releases(repo, channel): diff --git a/data/oci_model/manifest.py b/data/appr_model/manifest.py similarity index 97% rename from data/oci_model/manifest.py rename to data/appr_model/manifest.py index a1af680b5..b6c7341ca 100644 --- a/data/oci_model/manifest.py +++ b/data/appr_model/manifest.py @@ -5,7 +5,7 @@ import json from cnr.models.package_base import get_media_type from data.database import db_transaction, Manifest, ManifestListManifest, MediaType, Blob, Tag -from data.oci_model import tag as tag_model +from data.appr_model import tag as tag_model logger = logging.getLogger(__name__) diff --git a/data/oci_model/manifest_list.py b/data/appr_model/manifest_list.py similarity index 100% rename from data/oci_model/manifest_list.py rename to data/appr_model/manifest_list.py diff --git a/data/oci_model/package.py b/data/appr_model/package.py similarity index 97% rename from data/oci_model/package.py rename to data/appr_model/package.py index 61eae8e20..4e41c6c87 100644 --- a/data/oci_model/package.py +++ b/data/appr_model/package.py @@ -4,7 +4,7 @@ from peewee import prefetch from data import model from data.database import Repository, Namespace, Tag, ManifestListManifest -from data.oci_model import tag as tag_model +from data.appr_model import tag as tag_model def list_packages_query(namespace=None, media_type=None, search_query=None, username=None): diff --git a/data/oci_model/release.py b/data/appr_model/release.py similarity index 98% rename from data/oci_model/release.py rename to data/appr_model/release.py index 890e3e459..82b442f02 100644 --- a/data/oci_model/release.py +++ b/data/appr_model/release.py @@ -5,7 +5,7 @@ from cnr.models.package_base import manifest_media_type from data.database import (db_transaction, get_epoch_timestamp, Manifest, ManifestList, Tag, ManifestListManifest, Blob, ManifestBlob) -from data.oci_model import (blob as blob_model, manifest as manifest_model, +from data.appr_model import (blob as blob_model, manifest as manifest_model, manifest_list as manifest_list_model, tag as tag_model) diff --git a/data/oci_model/tag.py b/data/appr_model/tag.py similarity index 100% rename from data/oci_model/tag.py rename to data/appr_model/tag.py diff --git a/data/database.py b/data/database.py index 82f472378..e3d249f8b 100644 --- a/data/database.py +++ b/data/database.py @@ -471,8 +471,7 @@ class User(BaseModel): TagManifest, AccessToken, OAuthAccessToken, BlobUpload, RepositoryNotification, OAuthAuthorizationCode, RepositoryActionCount, TagManifestLabel, Tag, - ManifestLabel, BlobUploading, TeamSync, - RepositorySearchScore, DeletedNamespace} | beta_classes + TeamSync, RepositorySearchScore, DeletedNamespace} | cnr_classes delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes) @@ -620,7 +619,7 @@ class Repository(BaseModel): # are cleaned up directly skip_transitive_deletes = {RepositoryTag, RepositoryBuild, RepositoryBuildTrigger, BlobUpload, Image, TagManifest, TagManifestLabel, Label, DerivedStorageForImage, - RepositorySearchScore} | beta_classes + RepositorySearchScore} | cnr_classes delete_instance_filtered(self, Repository, delete_nullable, skip_transitive_deletes) @@ -1239,6 +1238,7 @@ class TagManifestLabel(BaseModel): class Blob(BaseModel): """ Blob represents a content-addressable object stored outside of the database. This model is a part of the new OCI/CNR model set. + CNR """ digest = CharField(index=True, unique=True) media_type = EnumField(MediaType) @@ -1249,21 +1249,15 @@ class Blob(BaseModel): class BlobPlacementLocation(BaseModel): """ BlobPlacementLocation is an enumeration of the possible storage locations for Blobs. This model is a part of the new OCI/CNR model set. + CNR """ name = CharField(index=True, unique=True) -class BlobPlacementLocationPreference(BaseModel): - """ 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. This model is a part of the new OCI/CNR model set. + CNR """ blob = ForeignKeyField(Blob) location = EnumField(BlobPlacementLocation) @@ -1276,58 +1270,20 @@ class BlobPlacement(BaseModel): ) -class BlobUploading(BaseModel): - """ 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) - location = ForeignKeyField(BlobPlacementLocation) - byte_count = IntegerField(default=0) - uncompressed_byte_count = IntegerField(null=True) - chunk_count = IntegerField(default=0) - storage_metadata = JSONField(null=True, default={}) - sha_state = ResumableSHA256Field(null=True, default=resumablehashlib.sha256) - piece_sha_state = ResumableSHA1Field(null=True) - piece_hashes = Base64BinaryField(null=True) - - class Meta: - database = db - read_slaves = (read_slave,) - indexes = ( - (('repository', 'uuid'), True), - ) - - class Manifest(BaseModel): """ 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. + CNR """ 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) - - 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. This model is a part of the new OCI/CNR model set. + CNR """ manifest = ForeignKeyField(Manifest, index=True) blob = ForeignKeyField(Blob, index=True) @@ -1343,6 +1299,7 @@ class ManifestBlob(BaseModel): class ManifestList(BaseModel): """ ManifestList represents all of the various manifests that compose a Tag. This model is a part of the new OCI/CNR model set. + CNR """ digest = CharField(index=True, unique=True) manifest_list_json = JSONField() @@ -1353,6 +1310,7 @@ class ManifestList(BaseModel): class TagKind(BaseModel): """ TagKind is a enumtable to reference tag kinds. This model is a part of the new OCI/CNR model set. + CNR """ name = CharField(index=True, unique=True) @@ -1360,6 +1318,7 @@ class TagKind(BaseModel): class Tag(BaseModel): """ Tag represents a user-facing alias for referencing a ManifestList. This model is a part of the new OCI/CNR model set. + CNR """ name = CharField() repository = ForeignKeyField(Repository) @@ -1389,6 +1348,7 @@ Channel = Tag.alias() class ManifestListManifest(BaseModel): """ ManifestListManifest is a many-to-many relation table linking ManifestLists and Manifests. This model is a part of the new OCI/CNR model set. + CNR """ manifest_list = ForeignKeyField(ManifestList, index=True) manifest = ForeignKeyField(Manifest, index=True) @@ -1406,79 +1366,6 @@ class ManifestListManifest(BaseModel): ) -class ManifestLayer(BaseModel): - """ 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 - metadata_json = JSONField() - - class Meta: - database = db - read_slaves = (read_slave,) - indexes = ( - (('manifest', 'manifest_index'), True), - ) - - -class ManifestLayerDockerV1(BaseModel): - """ 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() - compat_json = JSONField() - - -class ManifestLayerScan(BaseModel): - """ 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. - 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() - 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') - - class Meta: - database = db - read_slaves = (read_slave,) - indexes = ( - (('source_manifest', 'blob'), True), - (('source_manifest', 'media_type', 'uniqueness_hash'), True), - ) - - -class BitTorrentPieces(BaseModel): - """ 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() - - class Meta: - database = db - read_slaves = (read_slave,) - indexes = ( - (('blob', 'piece_length'), True), - ) - - class AppSpecificAuthToken(BaseModel): """ AppSpecificAuthToken represents a token generated by a user for use with an external application where putting the user's credentials, even encrypted, is deemed too risky. @@ -1499,9 +1386,7 @@ class AppSpecificAuthToken(BaseModel): ) -beta_classes = set([ManifestLayerScan, Tag, TagKind, BlobPlacementLocation, ManifestLayer, ManifestList, - BitTorrentPieces, MediaType, Label, ManifestBlob, BlobUploading, Blob, - ManifestLayerDockerV1, BlobPlacementLocationPreference, ManifestListManifest, - Manifest, DerivedImage, BlobPlacement, ManifestLabel]) +cnr_classes = set([Tag, TagKind, BlobPlacementLocation, ManifestList, ManifestBlob, Blob, + ManifestListManifest, Manifest, BlobPlacement]) 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)] diff --git a/data/migrations/versions/5cbbfc95bac7_remove_oci_tables_not_used_by_cnr_the_.py b/data/migrations/versions/5cbbfc95bac7_remove_oci_tables_not_used_by_cnr_the_.py new file mode 100644 index 000000000..1deb2ac34 --- /dev/null +++ b/data/migrations/versions/5cbbfc95bac7_remove_oci_tables_not_used_by_cnr_the_.py @@ -0,0 +1,167 @@ +"""Remove 'oci' tables not used by CNR. The rest will be migrated and renamed. + +Revision ID: 5cbbfc95bac7 +Revises: 1783530bee68 +Create Date: 2018-05-23 17:28:40.114433 + +""" + +# revision identifiers, used by Alembic. +revision = '5cbbfc95bac7' +down_revision = '1783530bee68' + +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.drop_table('derivedimage') + op.drop_table('manifestlabel') + op.drop_table('blobplacementlocationpreference') + op.drop_table('blobuploading') + op.drop_table('bittorrentpieces') + op.drop_table('manifestlayerdockerv1') + op.drop_table('manifestlayerscan') + op.drop_table('manifestlayer') + # ### end Alembic commands ### + + +def downgrade(tables): + # ### commands auto generated by Alembic - please adjust! ### + 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_manifest_index', 'manifestlayer', ['manifest_index'], unique=False) + op.create_index('manifestlayer_manifest_id_manifest_index', 'manifestlayer', ['manifest_id', 'manifest_index'], unique=True) + op.create_index('manifestlayer_manifest_id', 'manifestlayer', ['manifest_id'], unique=False) + op.create_index('manifestlayer_blob_id', 'manifestlayer', ['blob_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_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_piece_length', 'bittorrentpieces', ['blob_id', 'piece_length'], unique=True) + op.create_index('bittorrentpieces_blob_id', 'bittorrentpieces', ['blob_id'], unique=False) + + op.create_table( + 'blobuploading', + sa.Column('id', sa.Integer(), 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), + 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_uuid', 'blobuploading', ['uuid'], unique=True) + op.create_index('blobuploading_repository_id_uuid', 'blobuploading', ['repository_id', 'uuid'], unique=True) + op.create_index('blobuploading_repository_id', 'blobuploading', ['repository_id'], unique=False) + op.create_index('blobuploading_location_id', 'blobuploading', ['location_id'], unique=False) + op.create_index('blobuploading_created', 'blobuploading', ['created'], 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_manifest_layer_id', 'manifestlayerdockerv1', ['manifest_layer_id'], unique=False) + op.create_index('manifestlayerdockerv1_image_id', 'manifestlayerdockerv1', ['image_id'], unique=False) + + 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_repository_id_annotated_id_label_id', 'manifestlabel', ['repository_id', 'annotated_id', 'label_id'], unique=True) + op.create_index('manifestlabel_repository_id', 'manifestlabel', ['repository_id'], unique=False) + op.create_index('manifestlabel_label_id', 'manifestlabel', ['label_id'], unique=False) + op.create_index('manifestlabel_annotated_id', 'manifestlabel', ['annotated_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_user_id', 'blobplacementlocationpreference', ['user_id'], unique=False) + op.create_index('blobplacementlocationpreference_location_id', 'blobplacementlocationpreference', ['location_id'], unique=False) + + + op.create_table( + 'derivedimage', + sa.Column('id', sa.Integer(), 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', 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')), + 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_uuid', 'derivedimage', ['uuid'], unique=True) + op.create_index('derivedimage_uniqueness_hash', 'derivedimage', ['uniqueness_hash'], 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_source_manifest_id_blob_id', 'derivedimage', ['source_manifest_id', 'blob_id'], unique=True) + op.create_index('derivedimage_source_manifest_id', 'derivedimage', ['source_manifest_id'], unique=False) + op.create_index('derivedimage_signature_blob_id', 'derivedimage', ['signature_blob_id'], unique=False) + op.create_index('derivedimage_media_type_id', 'derivedimage', ['media_type_id'], unique=False) + op.create_index('derivedimage_blob_id', 'derivedimage', ['blob_id'], unique=False) + # ### end Alembic commands ### diff --git a/endpoints/api/repository_models_pre_oci.py b/endpoints/api/repository_models_pre_oci.py index c42bd7ab7..d394b6d8e 100644 --- a/endpoints/api/repository_models_pre_oci.py +++ b/endpoints/api/repository_models_pre_oci.py @@ -3,7 +3,7 @@ from collections import defaultdict from datetime import datetime, timedelta from auth.permissions import ReadRepositoryPermission -from data import model, oci_model +from data import model, appr_model from endpoints.api.repository_models_interface import RepositoryDataInterface, RepositoryBaseElement, Repository, \ ApplicationRepository, ImageRepositoryRepository, Tag, Channel, Release, Count @@ -142,10 +142,9 @@ class PreOCIModel(RepositoryDataInterface): repo.namespace_user.organization, repo.namespace_user.removed_tag_expiration_s, None, None, False, False, False) - # Note: This is *temporary* code for the new OCI model stuff. if base.kind_name == 'application': - channels = oci_model.channel.get_repo_channels(repo) - releases = oci_model.release.get_release_objs(repo) + channels = appr_model.channel.get_repo_channels(repo) + releases = appr_model.release.get_release_objs(repo) releases_channels_map = defaultdict(list) return ApplicationRepository( base, [_create_channel(channel, releases_channels_map) for channel in channels], [ diff --git a/endpoints/appr/cnr_backend.py b/endpoints/appr/cnr_backend.py index 3ba4820ee..711d1bfe2 100644 --- a/endpoints/appr/cnr_backend.py +++ b/endpoints/appr/cnr_backend.py @@ -8,7 +8,7 @@ from cnr.models.package_base import PackageBase, manifest_media_type from flask import request from app import storage -from endpoints.appr.models_oci import model +from endpoints.appr.models_cnr import model class Blob(BlobBase): diff --git a/endpoints/appr/models_oci.py b/endpoints/appr/models_cnr.py similarity index 88% rename from endpoints/appr/models_oci.py rename to endpoints/appr/models_cnr.py index 3f1c7d19c..d473e911c 100644 --- a/endpoints/appr/models_oci.py +++ b/endpoints/appr/models_cnr.py @@ -7,7 +7,7 @@ from cnr.exception import raise_package_not_found, raise_channel_not_found import data.model from app import storage, authentication -from data import oci_model +from data import appr_model from data.database import Tag, Manifest, MediaType, Blob, Repository, Channel from endpoints.appr.models_interface import ( ApplicationManifest, ApplicationRelease, ApplicationSummaryView, AppRegistryDataInterface, @@ -47,7 +47,7 @@ def _application(package): return repo -class OCIAppModel(AppRegistryDataInterface): +class CNRAppModel(AppRegistryDataInterface): def log_action(self, event_name, namespace_name, repo_name=None, analytics_name=None, analytics_sample=1, metadata=None): metadata = {} if metadata is None else metadata @@ -70,7 +70,7 @@ class OCIAppModel(AppRegistryDataInterface): """ views = [] - for repo in oci_model.package.list_packages_query(namespace, media_type, search, + for repo in appr_model.package.list_packages_query(namespace, media_type, search, username=username): releases = [t.name for t in repo.tag_set_prefetch] if not releases: @@ -81,7 +81,7 @@ class OCIAppModel(AppRegistryDataInterface): if with_channels: channels = [ ChannelView(name=chan.name, current=chan.linked_tag.name) - for chan in oci_model.channel.get_repo_channels(repo)] + for chan in appr_model.channel.get_repo_channels(repo)] app_name = _join_package_name(repo.namespace_user.username, repo.name) manifests = self.list_manifests(app_name, available_releases[0]) @@ -137,7 +137,7 @@ class OCIAppModel(AppRegistryDataInterface): Todo: * Paginate """ - return oci_model.release.get_releases(_application(package_name), media_type) + return appr_model.release.get_releases(_application(package_name), media_type) def list_manifests(self, package_name, release=None): """ Returns the list of all manifests of an Application. @@ -147,7 +147,7 @@ class OCIAppModel(AppRegistryDataInterface): """ try: repo = _application(package_name) - return list(oci_model.manifest.get_manifest_types(repo, release)) + return list(appr_model.manifest.get_manifest_types(repo, release)) except (Repository.DoesNotExist, Tag.DoesNotExist): raise_package_not_found(package_name, release) @@ -157,7 +157,7 @@ class OCIAppModel(AppRegistryDataInterface): """ repo = _application(package_name) try: - tag, manifest, blob = oci_model.release.get_app_release(repo, release, media_type) + tag, manifest, blob = appr_model.release.get_app_release(repo, release, media_type) created_at = _timestamp_to_iso(tag.lifetime_start) blob_descriptor = BlobDescriptor(digest=_strip_sha256_header(blob.digest), @@ -178,7 +178,7 @@ class OCIAppModel(AppRegistryDataInterface): path = cnrblob.upload_url(cnrblob.digest) locations = storage.preferred_locations storage.stream_write(locations, path, fp, 'application/x-gzip') - db_blob = oci_model.blob.get_or_create_blob(cnrblob.digest, cnrblob.size, content_media_type, + db_blob = appr_model.blob.get_or_create_blob(cnrblob.digest, cnrblob.size, content_media_type, locations) return BlobDescriptor(mediaType=content_media_type, digest=_strip_sha256_header(db_blob.digest), size=db_blob.size, urls=[]) @@ -193,7 +193,7 @@ class OCIAppModel(AppRegistryDataInterface): repo = data.model.repository.get_or_create_repository(ns, name, user, visibility=visibility, repo_kind='application') tag_name = package.release - oci_model.release.create_app_release(repo, tag_name, + appr_model.release.create_app_release(repo, tag_name, package.manifest(), manifest['content']['digest'], force) def delete_release(self, package_name, release, media_type): @@ -202,7 +202,7 @@ class OCIAppModel(AppRegistryDataInterface): """ repo = _application(package_name) try: - oci_model.release.delete_app_release(repo, release, media_type) + appr_model.release.delete_app_release(repo, release, media_type) except (Channel.DoesNotExist, Tag.DoesNotExist, MediaType.DoesNotExist): raise_package_not_found(package_name, release, media_type) @@ -213,7 +213,7 @@ class OCIAppModel(AppRegistryDataInterface): def channel_exists(self, package_name, channel_name): """ Returns true if channel exists """ repo = _application(package_name) - return oci_model.tag.tag_exists(repo, channel_name, "channel") + return appr_model.tag.tag_exists(repo, channel_name, "channel") def delete_channel(self, package_name, channel_name): """ Delete an AppChannel @@ -222,14 +222,14 @@ class OCIAppModel(AppRegistryDataInterface): """ repo = _application(package_name) try: - oci_model.channel.delete_channel(repo, channel_name) + appr_model.channel.delete_channel(repo, channel_name) except (Channel.DoesNotExist, Tag.DoesNotExist): raise_channel_not_found(package_name, channel_name) def list_channels(self, package_name): """ Returns all AppChannel for a package """ repo = _application(package_name) - channels = oci_model.channel.get_repo_channels(repo) + channels = appr_model.channel.get_repo_channels(repo) return [ChannelView(name=chan.name, current=chan.linked_tag.name) for chan in channels] def fetch_channel(self, package_name, channel_name, with_releases=True): @@ -237,12 +237,12 @@ class OCIAppModel(AppRegistryDataInterface): repo = _application(package_name) try: - channel = oci_model.channel.get_channel(repo, channel_name) + channel = appr_model.channel.get_channel(repo, channel_name) except (Channel.DoesNotExist, Tag.DoesNotExist): raise_channel_not_found(package_name, channel_name) if with_releases: - releases = oci_model.channel.get_channel_releases(repo, channel) + releases = appr_model.channel.get_channel_releases(repo, channel) chanview = ChannelReleasesView( current=channel.linked_tag.name, name=channel.name, releases=[channel.linked_tag.name] + [c.name for c in releases]) @@ -254,7 +254,7 @@ class OCIAppModel(AppRegistryDataInterface): def list_release_channels(self, package_name, release, active=True): repo = _application(package_name) try: - channels = oci_model.channel.get_tag_channels(repo, release, active=active) + channels = appr_model.channel.get_tag_channels(repo, release, active=active) return [ChannelView(name=c.name, current=c.linked_tag.name) for c in channels] except (Channel.DoesNotExist, Tag.DoesNotExist): raise_package_not_found(package_name, release) @@ -265,11 +265,11 @@ class OCIAppModel(AppRegistryDataInterface): A new AppChannel with the release """ repo = _application(package_name) - channel = oci_model.channel.create_or_update_channel(repo, channel_name, release) + channel = appr_model.channel.create_or_update_channel(repo, channel_name, release) return ChannelView(current=channel.linked_tag.name, name=channel.name) def get_blob_locations(self, digest): - return oci_model.blob.get_blob_locations(digest) + return appr_model.blob.get_blob_locations(digest) -model = OCIAppModel() +model = CNRAppModel() diff --git a/endpoints/appr/registry.py b/endpoints/appr/registry.py index d98996a46..dae4f1799 100644 --- a/endpoints/appr/registry.py +++ b/endpoints/appr/registry.py @@ -17,7 +17,7 @@ from auth.permissions import CreateRepositoryPermission, ModifyRepositoryPermiss from endpoints.appr import appr_bp, require_app_repo_read, require_app_repo_write from endpoints.appr.cnr_backend import Blob, Channel, Package, User from endpoints.appr.decorators import disallow_for_image_repository -from endpoints.appr.models_oci import model +from endpoints.appr.models_cnr import model from endpoints.decorators import anon_allowed, anon_protect from util.names import REPOSITORY_NAME_REGEX, TAG_REGEX diff --git a/endpoints/appr/test/test_api.py b/endpoints/appr/test/test_api.py index b3064e681..ae40ea0aa 100644 --- a/endpoints/appr/test/test_api.py +++ b/endpoints/appr/test/test_api.py @@ -6,13 +6,13 @@ from cnr.tests.conftest import * from cnr.tests.test_apiserver import BaseTestServer from cnr.tests.test_models import CnrTestModels -import data.oci_model.blob as oci_blob +import data.appr_model.blob as oci_blob from data.database import User from data.model import organization, user from endpoints.appr import registry # Needed to register the endpoint from endpoints.appr.cnr_backend import Channel, Package, QuayDB -from endpoints.appr.models_oci import model as oci_app_model +from endpoints.appr.models_cnr import model as oci_app_model from test.fixtures import * diff --git a/endpoints/appr/test/test_digest_prefix.py b/endpoints/appr/test/test_digest_prefix.py index d98d4a248..089becd43 100644 --- a/endpoints/appr/test/test_digest_prefix.py +++ b/endpoints/appr/test/test_digest_prefix.py @@ -1,5 +1,5 @@ import pytest -from endpoints.appr.models_oci import _strip_sha256_header +from endpoints.appr.models_cnr import _strip_sha256_header @pytest.mark.parametrize('digest,expected', [ diff --git a/initdb.py b/initdb.py index c80fc1b60..f368684f8 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, beta_classes, Role, TeamRole, Visibility, LoginService, +from data.database import (db, all_models, cnr_classes, Role, TeamRole, Visibility, LoginService, BuildTriggerService, AccessTokenKind, LogEntryKind, ImageStorageLocation, ImageStorageTransformation, ImageStorageSignatureKind, ExternalNotificationEvent, ExternalNotificationMethod, NotificationKind, @@ -906,7 +906,7 @@ def find_models_missing_data(): # whitelisted. models_missing_data = set() for one_model in all_models: - if one_model in beta_classes: + if one_model in cnr_classes: continue try: diff --git a/test/test_api_usage.py b/test/test_api_usage.py index 8a673175a..6ccd868ac 100644 --- a/test/test_api_usage.py +++ b/test/test_api_usage.py @@ -26,7 +26,7 @@ from endpoints.webhooks import webhooks from app import app, config_provider, all_queues, dockerfile_build_queue, notification_queue from buildtrigger.basehandler import BuildTriggerHandler from initdb import setup_database_for_testing, finished_database_for_testing -from data import database, model, oci_model +from data import database, model, appr_model from data.database import RepositoryActionCount, Repository as RepositoryTable from test.helpers import assert_action_logged from util.secscan.fake import fake_security_scanner @@ -2153,11 +2153,11 @@ class TestDeleteRepository(ApiTestCase): # Add some data for the repository, in addition to is already existing images and tags. repository = model.repository.get_repository(ADMIN_ACCESS_USER, 'complex') - # Add some new-style tags and linked tags. - base_tag = oci_model.tag.create_or_update_tag(repository, 'somebasetag') - base_tag2 = oci_model.tag.create_or_update_tag(repository, 'somebasetag2') - oci_model.tag.create_or_update_tag(repository, 'somelinkedtag', linked_tag=base_tag) - oci_model.tag.create_or_update_tag(repository, 'somelinkedtag2', linked_tag=base_tag2) + # Add some CNR tags and linked tags. + base_tag = appr_model.tag.create_or_update_tag(repository, 'somebasetag') + base_tag2 = appr_model.tag.create_or_update_tag(repository, 'somebasetag2') + appr_model.tag.create_or_update_tag(repository, 'somelinkedtag', linked_tag=base_tag) + appr_model.tag.create_or_update_tag(repository, 'somelinkedtag2', linked_tag=base_tag2) # Create some access tokens. access_token = model.token.create_access_token(repository, 'read') diff --git a/util/config/database.py b/util/config/database.py index 585dfd13d..5180f9401 100644 --- a/util/config/database.py +++ b/util/config/database.py @@ -1,4 +1,4 @@ -from data import model, oci_model +from data import model, appr_model def sync_database_with_config(config): @@ -7,4 +7,4 @@ def sync_database_with_config(config): location_names = config.get('DISTRIBUTED_STORAGE_CONFIG', {}).keys() if location_names: model.image.ensure_image_locations(*location_names) - oci_model.blob.ensure_blob_locations(*location_names) + appr_model.blob.ensure_blob_locations(*location_names)