Add interface for batch creation of labels on a manifest

This cannot be a true batch operation right now because of the current mapping table entries needed, but we can create and use the interface now and change the underlying implementation later
This commit is contained in:
Joseph Schorr 2018-09-20 16:00:02 -04:00
parent 8cfb3f4fe8
commit 03789b2210
3 changed files with 51 additions and 0 deletions

View file

@ -57,6 +57,14 @@ class RegistryDataInterface(object):
on the validation errors.
"""
@abstractmethod
def batch_create_manifest_labels(self, manifest):
""" Returns a context manager for batch creation of labels on a manifest.
Can raise InvalidLabelKeyException or InvalidMediaTypeException depending
on the validation errors.
"""
@abstractmethod
def list_manifest_labels(self, manifest, key_prefix=None):
""" Returns all labels found on the manifest. If specified, the key_prefix will filter the

View file

@ -2,6 +2,7 @@
import logging
from collections import defaultdict
from contextlib import contextmanager
from peewee import IntegrityError
@ -138,6 +139,33 @@ class PreOCIModel(RegistryDataInterface):
media_type_name)
return Label.for_label(label)
@contextmanager
def batch_create_manifest_labels(self, manifest):
""" Returns a context manager for batch creation of labels on a manifest.
Can raise InvalidLabelKeyException or InvalidMediaTypeException depending
on the validation errors.
"""
try:
tag_manifest = database.TagManifest.get(id=manifest._db_id)
except database.TagManifest.DoesNotExist:
yield None
return
labels_to_add = []
def add_label(key, value, source_type_name, media_type_name=None):
labels_to_add.append(dict(key=key, value=value, source_type_name=source_type_name,
media_type_name=media_type_name))
yield add_label
if labels_to_add:
pass
# TODO: make this truly batch once we've fully transitioned to V2_2 and no longer need
# the mapping tables.
for label in labels_to_add:
model.label.create_manifest_label(tag_manifest, **label)
def list_manifest_labels(self, manifest, key_prefix=None):
""" Returns all labels found on the manifest. If specified, the key_prefix will filter the
labels returned to those keys that start with the given prefix.

View file

@ -167,6 +167,21 @@ def test_manifest_labels(pre_oci_model):
assert created not in pre_oci_model.list_manifest_labels(found_manifest)
def test_batch_labels(pre_oci_model):
repo = model.repository.get_repository('devtable', 'history')
repository_ref = RepositoryReference.for_repo_obj(repo)
found_tag = pre_oci_model.find_matching_tag(repository_ref, ['latest'])
found_manifest = pre_oci_model.get_manifest_for_tag(found_tag)
with pre_oci_model.batch_create_manifest_labels(found_manifest) as add_label:
add_label('foo', '1', 'api')
add_label('bar', '2', 'api')
add_label('baz', '3', 'api')
# Ensure we can look them up.
assert len(pre_oci_model.list_manifest_labels(found_manifest)) == 3
@pytest.mark.parametrize('repo_namespace, repo_name', [
('devtable', 'simple'),
('devtable', 'complex'),