from app import app, storage as store from data import model from data.model import db_transaction from util.morecollections import AttrDict def placement_locations_docker_v1(namespace_name, repo_name, image_id): """ Returns all the placements for the image with the given V1 Docker ID, found under the given repository or None if no image was found. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return None return repo_image.storage.locations def placement_locations_and_path_docker_v1(namespace_name, repo_name, image_id): """ Returns a tuple of the placements and storage path location for the image with the given V1 Docker ID, found under the given repository or None if no image was found. """ repo_image = model.image.get_repo_image_extended(namespace_name, repo_name, image_id) if not repo_image or repo_image.storage is None: return None, None return repo_image.storage.locations, model.storage.get_layer_path(repo_image.storage) def docker_v1_metadata(namespace_name, repo_name, image_id): """ Returns various pieces of metadata associated with an image with the given V1 Docker ID, including the checksum and its V1 JSON metadata. """ repo_image = model.image.get_repo_image(namespace_name, repo_name, image_id) if repo_image is None: return None return AttrDict({ 'namespace_name': namespace_name, 'repo_name': repo_name, 'image_id': image_id, 'checksum': repo_image.v1_checksum, 'compat_json': repo_image.v1_json_metadata, }) def update_docker_v1_metadata(namespace_name, repo_name, image_id, created_date_str, comment, command, compat_json, parent_image_id=None): """ Updates various pieces of V1 metadata associated with a particular image. """ parent_image = None if parent_image_id is not None: parent_image = model.image.get_repo_image(namespace_name, repo_name, parent_image_id) model.image.set_image_metadata(image_id, namespace_name, repo_name, created_date_str, comment, command, compat_json, parent=parent_image) def storage_exists(namespace_name, repo_name, image_id): """ Returns whether storage already exists for the image with the V1 Docker ID under the given repository. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return False if repo_image.storage.uploading: return False layer_path = model.storage.get_layer_path(repo_image.storage) return store.exists(repo_image.storage.locations, layer_path) def store_docker_v1_checksums(namespace_name, repo_name, image_id, checksum, content_checksum): """ Stores the various V1 checksums for the image with the V1 Docker ID. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return with db_transaction(): repo_image.storage.content_checksum = content_checksum repo_image.v1_checksum = checksum repo_image.storage.save() repo_image.save() def is_image_uploading(namespace_name, repo_name, image_id): """ Returns whether the image with the V1 Docker ID is currently marked as uploading. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return False return repo_image.storage.uploading def update_image_uploading(namespace_name, repo_name, image_id, is_uploading): """ Marks the image with the V1 Docker ID with the given uploading status. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return repo_image.storage.uploading = is_uploading repo_image.storage.save() return repo_image.storage def update_image_sizes(namespace_name, repo_name, image_id, size, uncompressed_size): """ Updates the sizing information for the image with the given V1 Docker ID. """ model.storage.set_image_storage_metadata(image_id, namespace_name, repo_name, size, uncompressed_size) def get_image_size(namespace_name, repo_name, image_id): """ Returns the wire size of the image with the given Docker V1 ID. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return None return repo_image.storage.image_size def create_bittorrent_pieces(namespace_name, repo_name, image_id, pieces_bytes): """ Saves the bittorrent piece hashes for the image with the given Docker V1 ID. """ repo_image = model.image.get_repo_image_and_storage(namespace_name, repo_name, image_id) if repo_image is None or repo_image.storage is None: return model.storage.save_torrent_info(repo_image.storage, app.config['BITTORRENT_PIECE_SIZE'], pieces_bytes) def image_ancestry(namespace_name, repo_name, image_id): """ Returns a list containing the full ancestry of Docker V1 IDs, in order, for the image with the givne Docker V1 ID. """ try: image = model.image.get_image_by_id(namespace_name, repo_name, image_id) except model.InvalidImageException: return None parents = model.image.get_parent_images(namespace_name, repo_name, image) ancestry_docker_ids = [image.docker_image_id] ancestry_docker_ids.extend([parent.docker_image_id for parent in parents]) return ancestry_docker_ids def repository_exists(namespace_name, repo_name): """ Returns whether the repository with the given name and namespace exists. """ repo = model.repository.get_repository(namespace_name, repo_name) return repo is not None def create_or_link_image(username, namespace_name, repo_name, image_id, storage_location): """ Adds the given image to the given repository, by either linking to an existing image visible to the user with the given username, or creating a new one if no existing image matches. """ repo = model.repository.get_repository(namespace_name, repo_name) model.image.find_create_or_link_image(image_id, repo, username, {}, storage_location) def create_temp_hidden_tag(namespace_name, repo_name, image_id, expiration): """ Creates a hidden tag under the matching namespace pointing to the image with the given V1 Docker ID. """ repo_image = model.image.get_repo_image(namespace_name, repo_name, image_id) if repo_image is None: return repo = repo_image.repository model.tag.create_temporary_hidden_tag(repo, repo_image, expiration) def list_tags(namespace_name, repo_name): """ Returns all the tags defined in the repository with the given namespace and name. """ return model.tag.list_repository_tags(namespace_name, repo_name) def create_or_update_tag(namespace_name, repo_name, image_id, tag_name): """ Creates or updates a tag under the matching repository to point to the image with the given Docker V1 ID. """ model.tag.create_or_update_tag(namespace_name, repo_name, tag_name, image_id) def find_image_id_by_tag(namespace_name, repo_name, tag_name): """ Returns the Docker V1 image ID for the HEAD image for the tag with the given name under the matching repository, or None if none. """ try: tag_image = model.tag.get_tag_image(namespace_name, repo_name, tag_name) except model.DataModelException: return None return tag_image.docker_image_id def delete_tag(namespace_name, repo_name, tag_name): """ Deletes the given tag from the given repository. """ model.tag.delete_tag(namespace_name, repo_name, tag_name)