Audit the number of SQL queries we make in writing manifests, and significantly reduce in the common case
Instead of 41 queries now for the simple manifest, we are down to 14. The biggest changes: - Only synthesize the V1 image rows if we haven't already found them in the database - Thread the repository object through to the other model method calls, and use it instead of loading again and again
This commit is contained in:
parent
4f47808e99
commit
9e16a989f5
8 changed files with 145 additions and 66 deletions
|
@ -75,15 +75,12 @@ class PreOCIModel(DockerRegistryV2DataInterface):
|
|||
except DataModelException:
|
||||
return None
|
||||
|
||||
def get_docker_v1_metadata_by_image_id(self, namespace_name, repo_name, docker_image_ids):
|
||||
repo = model.repository.get_repository(namespace_name, repo_name)
|
||||
if repo is None:
|
||||
return {}
|
||||
|
||||
images_query = model.image.lookup_repository_images(repo, docker_image_ids)
|
||||
def get_docker_v1_metadata_by_image_id(self, repository, docker_image_ids):
|
||||
images_query = model.image.lookup_repository_images(repository.id, docker_image_ids)
|
||||
return {
|
||||
image.docker_image_id: _docker_v1_metadata(namespace_name, repo_name, image)
|
||||
for image in images_query}
|
||||
image.docker_image_id: _docker_v1_metadata(repository.namespace_name, repository.name, image)
|
||||
for image in images_query
|
||||
}
|
||||
|
||||
def get_parents_docker_v1_metadata(self, namespace_name, repo_name, docker_image_id):
|
||||
repo_image = model.image.get_repo_image(namespace_name, repo_name, docker_image_id)
|
||||
|
@ -104,29 +101,21 @@ class PreOCIModel(DockerRegistryV2DataInterface):
|
|||
|
||||
def synthesize_v1_image(self, repository, storage, image_id, created, comment, command,
|
||||
compat_json, parent_image_id):
|
||||
repo = model.repository.get_repository(repository.namespace_name, repository.name)
|
||||
if repo is None:
|
||||
raise DataModelException('Unknown repository: %s/%s' % (repository.namespace_name,
|
||||
repository.name))
|
||||
|
||||
parent_image = None
|
||||
if parent_image_id is not None:
|
||||
parent_image = model.image.get_image(repo, parent_image_id)
|
||||
parent_image = model.image.get_image(repository.id, parent_image_id)
|
||||
if parent_image is None:
|
||||
raise DataModelException('Unknown parent image: %s' % parent_image_id)
|
||||
|
||||
storage_obj = model.storage.get_storage_by_uuid(storage.uuid)
|
||||
if storage_obj is None:
|
||||
raise DataModelException('Unknown storage: %s' % storage.uuid)
|
||||
repo_image = model.image.synthesize_v1_image(repository.id, storage.id, storage.size,
|
||||
image_id, created, comment, command, compat_json,
|
||||
parent_image)
|
||||
return _docker_v1_metadata(repository.namespace_name, repository.name, repo_image)
|
||||
|
||||
repo_image = model.image.synthesize_v1_image(repo, storage_obj, image_id, created, comment,
|
||||
command, compat_json, parent_image)
|
||||
return _docker_v1_metadata(repo.namespace_user.username, repo.name, repo_image)
|
||||
|
||||
def save_manifest(self, namespace_name, repo_name, tag_name, leaf_layer_docker_id,
|
||||
manifest_digest, manifest_bytes):
|
||||
(_, newly_created) = model.tag.store_tag_manifest(
|
||||
namespace_name, repo_name, tag_name, leaf_layer_docker_id, manifest_digest, manifest_bytes)
|
||||
def save_manifest(self, repository, tag_name, leaf_layer_docker_id, manifest_digest,
|
||||
manifest_bytes):
|
||||
(_, newly_created) = model.tag.store_tag_manifest_for_repo(
|
||||
repository.id, tag_name, leaf_layer_docker_id, manifest_digest, manifest_bytes)
|
||||
return newly_created
|
||||
|
||||
def repository_tags(self, namespace_name, repo_name, limit, offset):
|
||||
|
@ -208,15 +197,18 @@ class PreOCIModel(DockerRegistryV2DataInterface):
|
|||
namespace_name, repo_name, blob_digest, location_obj.id, blob_upload.byte_count,
|
||||
expiration_sec, blob_upload.uncompressed_byte_count)
|
||||
return Blob(
|
||||
id=blob_record.id,
|
||||
uuid=blob_record.uuid,
|
||||
digest=blob_digest,
|
||||
size=blob_upload.byte_count,
|
||||
locations=[blob_upload.location_name],
|
||||
cas_path=blob_record.cas_path)
|
||||
cas_path=blob_record.cas_path
|
||||
)
|
||||
|
||||
def lookup_blobs_by_digest(self, namespace_name, repo_name, digests):
|
||||
def lookup_blobs_by_digest(self, repository, digests):
|
||||
def _blob_view(blob_record):
|
||||
return Blob(
|
||||
id=blob_record.id,
|
||||
uuid=blob_record.uuid,
|
||||
digest=blob_record.content_checksum,
|
||||
size=blob_record.image_size,
|
||||
|
@ -224,21 +216,20 @@ class PreOCIModel(DockerRegistryV2DataInterface):
|
|||
locations=None, # Note: Locations is None in this case.
|
||||
)
|
||||
|
||||
repo = model.repository.get_repository(namespace_name, repo_name)
|
||||
if repo is None:
|
||||
return {}
|
||||
query = model.storage.lookup_repo_storages_by_content_checksum(repo, digests)
|
||||
query = model.storage.lookup_repo_storages_by_content_checksum(repository.id, digests)
|
||||
return {storage.content_checksum: _blob_view(storage) for storage in query}
|
||||
|
||||
def get_blob_by_digest(self, namespace_name, repo_name, digest):
|
||||
try:
|
||||
blob_record = model.blob.get_repo_blob_by_digest(namespace_name, repo_name, digest)
|
||||
return Blob(
|
||||
id=blob_record.id,
|
||||
uuid=blob_record.uuid,
|
||||
digest=digest,
|
||||
size=blob_record.image_size,
|
||||
locations=blob_record.locations,
|
||||
cas_path=blob_record.cas_path)
|
||||
cas_path=blob_record.cas_path
|
||||
)
|
||||
except model.BlobDoesNotExist:
|
||||
return None
|
||||
|
||||
|
@ -286,7 +277,8 @@ def _docker_v1_metadata(namespace_name, repo_name, repo_image):
|
|||
comment=repo_image.comment,
|
||||
command=repo_image.command,
|
||||
# TODO: make sure this isn't needed anywhere, as it is expensive to lookup
|
||||
parent_image_id=None,)
|
||||
parent_image_id=None,
|
||||
)
|
||||
|
||||
|
||||
def _repository_for_repo(repo):
|
||||
|
|
Reference in a new issue