X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/1ef981e08fb9905fbe4fdd294197368a3a9e5bbb..e41dc06c9115d0ce30207560b83d6c8dec6fd18a:/sdk/python/arvados/commands/keepdocker.py diff --git a/sdk/python/arvados/commands/keepdocker.py b/sdk/python/arvados/commands/keepdocker.py index 72c5e8d359..3a0b64c38f 100644 --- a/sdk/python/arvados/commands/keepdocker.py +++ b/sdk/python/arvados/commands/keepdocker.py @@ -21,6 +21,8 @@ import arvados.commands._util as arv_cmd import arvados.commands.put as arv_put import ciso8601 +from arvados._version import __version__ + EARLIEST_DATETIME = datetime.datetime(datetime.MINYEAR, 1, 1, 0, 0, 0) STAT_CACHE_ERRORS = (IOError, OSError, ValueError) @@ -28,6 +30,9 @@ DockerImage = collections.namedtuple( 'DockerImage', ['repo', 'tag', 'hash', 'created', 'vsize']) keepdocker_parser = argparse.ArgumentParser(add_help=False) +keepdocker_parser.add_argument( + '--version', action='version', version="%s %s" % (sys.argv[0], __version__), + help='Print version and exit.') keepdocker_parser.add_argument( '-f', '--force', action='store_true', default=False, help="Re-upload the image even if it already exists on the server") @@ -283,6 +288,9 @@ def list_images_in_arv(api_client, num_retries, image_name=None, image_tag=None) return [(image['collection'], image) for image in images if image['collection'] in existing_coll_uuids] +def items_owned_by(owner_uuid, arv_items): + return (item for item in arv_items if item['owner_uuid'] == owner_uuid) + def main(arguments=None, stdout=sys.stdout): args = arg_parser.parse_args(arguments) api = arvados.api('v1') @@ -326,10 +334,10 @@ def main(arguments=None, stdout=sys.stdout): num_retries=args.retries)['uuid'] # Find image hash tags - existing_links = api.links().list( + existing_links = _get_docker_links( + api, args.retries, filters=[['link_class', '=', 'docker_image_hash'], - ['name', '=', image_hash]] - ).execute(num_retries=args.retries)['items'] + ['name', '=', image_hash]]) if existing_links: # get readable collections collections = api.collections().list( @@ -339,21 +347,18 @@ def main(arguments=None, stdout=sys.stdout): if collections: # check for repo+tag links on these collections - existing_repo_tag = (api.links().list( - filters=[['link_class', '=', 'docker_image_repo+tag'], - ['name', '=', image_repo_tag], - ['head_uuid', 'in', collections]] - ).execute(num_retries=args.retries)['items']) if image_repo_tag else [] - - # Filter on elements owned by the parent project - owned_col = [c for c in collections if c['owner_uuid'] == parent_project_uuid] - owned_img = [c for c in existing_links if c['owner_uuid'] == parent_project_uuid] - owned_rep = [c for c in existing_repo_tag if c['owner_uuid'] == parent_project_uuid] - - if owned_col: - # already have a collection owned by this project - coll_uuid = owned_col[0]['uuid'] + if image_repo_tag: + existing_repo_tag = _get_docker_links( + api, args.retries, + filters=[['link_class', '=', 'docker_image_repo+tag'], + ['name', '=', image_repo_tag], + ['head_uuid', 'in', collections]]) else: + existing_repo_tag = [] + + try: + coll_uuid = next(items_owned_by(parent_project_uuid, collections))['uuid'] + except StopIteration: # create new collection owned by the project coll_uuid = api.collections().create( body={"manifest_text": collections[0]['manifest_text'], @@ -363,14 +368,15 @@ def main(arguments=None, stdout=sys.stdout): ).execute(num_retries=args.retries)['uuid'] link_base = {'owner_uuid': parent_project_uuid, - 'head_uuid': coll_uuid } + 'head_uuid': coll_uuid, + 'properties': existing_links[0]['properties']} - if not owned_img: + if not any(items_owned_by(parent_project_uuid, existing_links)): # create image link owned by the project make_link(api, args.retries, 'docker_image_hash', image_hash, **link_base) - if not owned_rep and image_repo_tag: + if image_repo_tag and not any(items_owned_by(parent_project_uuid, existing_repo_tag)): # create repo+tag link owned by the project make_link(api, args.retries, 'docker_image_repo+tag', image_repo_tag, **link_base) @@ -398,7 +404,12 @@ def main(arguments=None, stdout=sys.stdout): # Read the image metadata and make Arvados links from it. image_file.seek(0) image_tar = tarfile.open(fileobj=image_file) - json_file = image_tar.extractfile(image_tar.getmember(image_hash + '/json')) + image_hash_type, _, raw_image_hash = image_hash.rpartition(':') + if image_hash_type: + json_filename = raw_image_hash + '.json' + else: + json_filename = raw_image_hash + '/json' + json_file = image_tar.extractfile(image_tar.getmember(json_filename)) image_metadata = json.load(json_file) json_file.close() image_tar.close()