d59bea3569
If a namespace is present in the whitelist, all calls are sent to the OCI model instead of the Pre OCI model Note that this does increase overhead for registry calls (since we need to lookup the namespace for every single call), but it should only be temporary until we've migrated all users over to the OCI data model
82 lines
3.1 KiB
Python
82 lines
3.1 KiB
Python
import inspect
|
|
import logging
|
|
|
|
from data.database import DerivedStorageForImage, TagManifest, Manifest, Image
|
|
from data.registry_model.registry_oci_model import oci_model
|
|
from data.registry_model.registry_pre_oci_model import pre_oci_model
|
|
from data.registry_model.datatypes import LegacyImage, Manifest as ManifestDataType
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SplitModel(object):
|
|
def __init__(self, v22_namespace_whitelist):
|
|
self.v22_namespace_whitelist = set(v22_namespace_whitelist)
|
|
|
|
def supports_schema2(self, namespace_name):
|
|
""" Returns whether the implementation of the data interface supports schema 2 format
|
|
manifests. """
|
|
return namespace_name in self.v22_namespace_whitelist
|
|
|
|
def _namespace_from_kwargs(self, args_dict):
|
|
if 'namespace_name' in args_dict:
|
|
return args_dict['namespace_name']
|
|
|
|
if 'repository_ref' in args_dict:
|
|
return args_dict['repository_ref'].namespace_name
|
|
|
|
if 'tag' in args_dict:
|
|
return args_dict['tag'].repository.namespace_name
|
|
|
|
if 'manifest' in args_dict:
|
|
manifest = args_dict['manifest']
|
|
if manifest._is_tag_manifest:
|
|
return TagManifest.get(id=manifest._db_id).tag.repository.namespace_user.username
|
|
else:
|
|
return Manifest.get(id=manifest._db_id).repository.namespace_user.username
|
|
|
|
if 'manifest_or_legacy_image' in args_dict:
|
|
manifest_or_legacy_image = args_dict['manifest_or_legacy_image']
|
|
if isinstance(manifest_or_legacy_image, LegacyImage):
|
|
return Image.get(id=manifest_or_legacy_image._db_id).repository.namespace_user.username
|
|
else:
|
|
manifest = manifest_or_legacy_image
|
|
if manifest._is_tag_manifest:
|
|
return TagManifest.get(id=manifest._db_id).tag.repository.namespace_user.username
|
|
else:
|
|
return Manifest.get(id=manifest._db_id).repository.namespace_user.username
|
|
|
|
if 'derived_image' in args_dict:
|
|
return (DerivedStorageForImage
|
|
.get(id=args_dict['derived_image']._db_id)
|
|
.source_image
|
|
.repository
|
|
.namespace_user
|
|
.username)
|
|
|
|
if 'blob' in args_dict:
|
|
return '' # Blob functions are shared, so no need to do anything.
|
|
|
|
if 'blob_upload' in args_dict:
|
|
return '' # Blob functions are shared, so no need to do anything.
|
|
|
|
raise Exception('Unknown namespace for dict `%s`' % args_dict)
|
|
|
|
def __getattr__(self, attr):
|
|
def method(*args, **kwargs):
|
|
argnames = inspect.getargspec(getattr(oci_model, attr))[0]
|
|
if not argnames and isinstance(args[0], ManifestDataType):
|
|
args_dict = dict(manifest=args[0])
|
|
else:
|
|
args_dict = {argnames[index + 1]: value for index, value in enumerate(args)}
|
|
|
|
namespace_name = self._namespace_from_kwargs(args_dict)
|
|
if namespace_name in self.v22_namespace_whitelist:
|
|
logger.debug('Calling method `%s` under OCI data model for namespace `%s`',
|
|
attr, namespace_name)
|
|
return getattr(oci_model, attr)(*args, **kwargs)
|
|
else:
|
|
return getattr(pre_oci_model, attr)(*args, **kwargs)
|
|
|
|
return method
|