Add the basics of geographic data distribution and get the tests to work.
This commit is contained in:
parent
2bf12996f5
commit
bf98575feb
23 changed files with 198 additions and 100 deletions
|
@ -845,20 +845,28 @@ def get_repository(namespace_name, repository_name):
|
|||
|
||||
|
||||
def get_repo_image(namespace_name, repository_name, image_id):
|
||||
query = (Image
|
||||
.select(Image, ImageStorage)
|
||||
location_list = list((ImageStoragePlacement
|
||||
.select(ImageStoragePlacement, Image, ImageStorage, ImageStorageLocation)
|
||||
.join(ImageStorageLocation)
|
||||
.switch(ImageStoragePlacement)
|
||||
.join(ImageStorage)
|
||||
.join(Image)
|
||||
.join(Repository)
|
||||
.switch(Image)
|
||||
.join(ImageStorage, JOIN_LEFT_OUTER)
|
||||
.where(Repository.name == repository_name,
|
||||
Repository.namespace == namespace_name,
|
||||
Image.docker_image_id == image_id))
|
||||
Image.docker_image_id == image_id)))
|
||||
|
||||
try:
|
||||
return query.get()
|
||||
except Image.DoesNotExist:
|
||||
if not location_list:
|
||||
return None
|
||||
|
||||
location_names = {location.location.name for location in location_list}
|
||||
|
||||
image = location_list[0].storage.image
|
||||
image.storage = location_list[0].storage
|
||||
image.storage.locations = location_names
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def repository_is_public(namespace_name, repository_name):
|
||||
joined = Repository.select().join(Visibility)
|
||||
|
@ -940,7 +948,7 @@ def create_repository(namespace, name, creating_user, visibility='private'):
|
|||
return repo
|
||||
|
||||
|
||||
def __translate_ancestry(old_ancestry, translations, repository, username):
|
||||
def __translate_ancestry(old_ancestry, translations, repository, username, preferred_location):
|
||||
if old_ancestry == '/':
|
||||
return '/'
|
||||
|
||||
|
@ -950,9 +958,8 @@ def __translate_ancestry(old_ancestry, translations, repository, username):
|
|||
# Figure out which docker_image_id the old id refers to, then find a
|
||||
# a local one
|
||||
old = Image.select(Image.docker_image_id).where(Image.id == old_id).get()
|
||||
image_in_repo = find_create_or_link_image(old.docker_image_id,
|
||||
repository, username,
|
||||
translations)
|
||||
image_in_repo = find_create_or_link_image(old.docker_image_id, repository, username,
|
||||
translations, preferred_location)
|
||||
translations[old_id] = image_in_repo.id
|
||||
|
||||
return translations[old_id]
|
||||
|
@ -962,8 +969,8 @@ def __translate_ancestry(old_ancestry, translations, repository, username):
|
|||
return '/%s/' % '/'.join(new_ids)
|
||||
|
||||
|
||||
def find_create_or_link_image(docker_image_id, repository, username,
|
||||
translations):
|
||||
def find_create_or_link_image(docker_image_id, repository, username, translations,
|
||||
preferred_location):
|
||||
with config.app_config['DB_TRANSACTION_FACTORY'](db):
|
||||
repo_image = get_repo_image(repository.namespace, repository.name,
|
||||
docker_image_id)
|
||||
|
@ -990,20 +997,29 @@ def find_create_or_link_image(docker_image_id, repository, username,
|
|||
msg = 'Linking image to existing storage with docker id: %s and uuid: %s'
|
||||
logger.debug(msg, docker_image_id, to_copy.storage.uuid)
|
||||
|
||||
new_image_ancestry = __translate_ancestry(to_copy.ancestors,
|
||||
translations, repository,
|
||||
username)
|
||||
new_image_ancestry = __translate_ancestry(to_copy.ancestors, translations, repository,
|
||||
username, preferred_location)
|
||||
|
||||
storage = to_copy.storage
|
||||
storage.locations = {placement.location.name
|
||||
for placement in storage.imagestorageplacement_set}
|
||||
origin_image_id = to_copy.id
|
||||
except Image.DoesNotExist:
|
||||
logger.debug('Creating new storage for docker id: %s', docker_image_id)
|
||||
storage = ImageStorage.create()
|
||||
location = ImageStorageLocation.get(name=preferred_location)
|
||||
ImageStoragePlacement.create(location=location, storage=storage)
|
||||
storage.locations = {preferred_location}
|
||||
|
||||
logger.debug('Storage locations: %s', storage.locations)
|
||||
|
||||
new_image = Image.create(docker_image_id=docker_image_id,
|
||||
repository=repository, storage=storage,
|
||||
ancestors=new_image_ancestry)
|
||||
|
||||
logger.debug('new_image storage locations: %s', new_image.storage.locations)
|
||||
|
||||
|
||||
if origin_image_id:
|
||||
logger.debug('Storing translation %s -> %s', origin_image_id, new_image.id)
|
||||
translations[origin_image_id] = new_image.id
|
||||
|
@ -1130,9 +1146,14 @@ def garbage_collect_repository(namespace_name, repository_name):
|
|||
|
||||
for storage in storage_to_remove:
|
||||
logger.debug('Garbage collecting image storage: %s', storage.uuid)
|
||||
storage.delete_instance()
|
||||
|
||||
image_path = config.store.image_path(storage.uuid)
|
||||
config.store.remove(image_path)
|
||||
for placement in storage.imagestorageplacement_set:
|
||||
location_name = placement.location.name
|
||||
placement.delete_instance()
|
||||
config.store.remove(location_name, image_path)
|
||||
|
||||
storage.delete_instance()
|
||||
|
||||
return len(to_remove)
|
||||
|
||||
|
|
Reference in a new issue