Fix get_blob_path to not make any database calls and add a test

This will be supported by caching, hopefully removing the need to hit the database when the blob object is cached
This commit is contained in:
Joseph Schorr 2017-12-13 16:27:46 -05:00
parent e06a83faf9
commit 51e67ab7f5
4 changed files with 44 additions and 10 deletions

View file

@ -248,12 +248,19 @@ def get_storage_by_uuid(storage_uuid):
def get_layer_path(storage_record): def get_layer_path(storage_record):
""" Returns the path in the storage engine to the layer data referenced by the storage row. """ """ Returns the path in the storage engine to the layer data referenced by the storage row. """
store = config.store return get_layer_path_for_storage(storage_record.uuid, storage_record.cas_path,
if not storage_record.cas_path: storage_record.content_checksum)
logger.debug('Serving layer from legacy v1 path')
return store.v1_image_layer_path(storage_record.uuid)
return store.blob_path(storage_record.content_checksum)
def get_layer_path_for_storage(storage_uuid, cas_path, content_checksum):
""" Returns the path in the storage engine to the layer data referenced by the storage
information. """
store = config.store
if not cas_path:
logger.debug('Serving layer from legacy v1 path for storage %s', storage_uuid)
return store.v1_image_layer_path(storage_uuid)
return store.blob_path(content_checksum)
def lookup_repo_storages_by_content_checksum(repo, checksums): def lookup_repo_storages_by_content_checksum(repo, checksums):

View file

@ -41,7 +41,7 @@ class BlobUpload(
""" """
class Blob(namedtuple('Blob', ['uuid', 'digest', 'size', 'locations'])): class Blob(namedtuple('Blob', ['uuid', 'digest', 'size', 'locations', 'cas_path'])):
""" """
Blob represents an opaque binary blob saved to the storage system. Blob represents an opaque binary blob saved to the storage system.
""" """

View file

@ -211,7 +211,8 @@ class PreOCIModel(DockerRegistryV2DataInterface):
uuid=blob_record.uuid, uuid=blob_record.uuid,
digest=blob_digest, digest=blob_digest,
size=blob_upload.byte_count, size=blob_upload.byte_count,
locations=[blob_upload.location_name],) locations=[blob_upload.location_name],
cas_path=blob_record.cas_path)
def lookup_blobs_by_digest(self, namespace_name, repo_name, digests): def lookup_blobs_by_digest(self, namespace_name, repo_name, digests):
def _blob_view(blob_record): def _blob_view(blob_record):
@ -219,6 +220,7 @@ class PreOCIModel(DockerRegistryV2DataInterface):
uuid=blob_record.uuid, uuid=blob_record.uuid,
digest=blob_record.content_checksum, digest=blob_record.content_checksum,
size=blob_record.image_size, size=blob_record.image_size,
cas_path=blob_record.cas_path,
locations=None, # Note: Locations is None in this case. locations=None, # Note: Locations is None in this case.
) )
@ -235,7 +237,8 @@ class PreOCIModel(DockerRegistryV2DataInterface):
uuid=blob_record.uuid, uuid=blob_record.uuid,
digest=digest, digest=digest,
size=blob_record.image_size, size=blob_record.image_size,
locations=blob_record.locations,) locations=blob_record.locations,
cas_path=blob_record.cas_path)
except model.BlobDoesNotExist: except model.BlobDoesNotExist:
return None return None
@ -254,8 +257,7 @@ class PreOCIModel(DockerRegistryV2DataInterface):
label.media_type) label.media_type)
def get_blob_path(self, blob): def get_blob_path(self, blob):
blob_record = model.storage.get_storage_by_uuid(blob.uuid) return model.storage.get_layer_path_for_storage(blob.uuid, blob.cas_path, blob.digest)
return model.storage.get_layer_path(blob_record)
def set_manifest_expires_after(self, namespace_name, repo_name, digest, expires_after_sec): def set_manifest_expires_after(self, namespace_name, repo_name, digest, expires_after_sec):
try: try:

View file

@ -0,0 +1,25 @@
import hashlib
from playhouse.test_utils import assert_query_count
from data import model
from data.database import ImageStorageLocation
from endpoints.v2.models_pre_oci import data_model
from test.fixtures import *
def test_get_blob_path(initialized_db):
# Add a blob.
digest = 'sha256:' + hashlib.sha256("a").hexdigest()
location = ImageStorageLocation.get(name='local_us')
db_blob = model.blob.store_blob_record_and_temp_link('devtable', 'simple', digest, location, 1,
10000000)
with assert_query_count(1):
blob = data_model.get_blob_by_digest('devtable', 'simple', digest)
assert blob.uuid == db_blob.uuid
# The blob tuple should have everything get_blob_path needs, so there should be no queries.
with assert_query_count(0):
assert data_model.get_blob_path(blob)
assert data_model.get_blob_path(blob) == model.storage.get_layer_path(db_blob)