X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/d6d7788c4e6b1d3da88833329b326fd7a3891503..41a6554ca2281983645cf606ba6291cc2332dced:/sdk/python/arvados/commands/put.py diff --git a/sdk/python/arvados/commands/put.py b/sdk/python/arvados/commands/put.py index 55bf7fcc0f..7b6b048b1d 100644 --- a/sdk/python/arvados/commands/put.py +++ b/sdk/python/arvados/commands/put.py @@ -22,6 +22,7 @@ import tempfile import arvados.commands._util as arv_cmd CAUGHT_SIGNALS = [signal.SIGINT, signal.SIGQUIT, signal.SIGTERM] +api_client = None upload_opts = argparse.ArgumentParser(add_help=False) @@ -40,11 +41,13 @@ stream per filesystem directory that contains files. """) upload_opts.add_argument('--project-uuid', metavar='UUID', help=""" -When a Collection is made, make a Link to save it under the specified project. +Store the collection in the specified project, instead of your Home +project. """) upload_opts.add_argument('--name', help=""" -When a Collection is linked to a project, use the specified name. +Save the collection with the specified name, rather than the default +generic name "Saved at {time} by {username}@{host}". """) _group = upload_opts.add_mutually_exclusive_group() @@ -236,13 +239,14 @@ class ArvPutCollectionWriter(arvados.ResumableCollectionWriter): STATE_PROPS = (arvados.ResumableCollectionWriter.STATE_PROPS + ['bytes_written', '_seen_inputs']) - def __init__(self, cache=None, reporter=None, bytes_expected=None): + def __init__(self, cache=None, reporter=None, bytes_expected=None, + api_client=None): self.bytes_written = 0 self._seen_inputs = [] self.cache = cache self.reporter = reporter self.bytes_expected = bytes_expected - super(ArvPutCollectionWriter, self).__init__() + super(ArvPutCollectionWriter, self).__init__(api_client) @classmethod def from_cache(cls, cache, reporter=None, bytes_expected=None): @@ -340,7 +344,7 @@ def exit_signal_handler(sigcode, frame): def check_project_exists(project_uuid): try: - arvados.api('v1').groups().get(uuid=project_uuid).execute() + api_client.groups().get(uuid=project_uuid).execute() except (apiclient.errors.Error, arvados.errors.NotFoundError) as error: raise ValueError("Project {} not found ({})".format(project_uuid, error)) @@ -352,34 +356,35 @@ def prep_project_link(args, stderr, project_exists=check_project_exists): # to create the desired project link for this Collection, or None. # Raises ValueError if the arguments request something impossible. making_collection = not (args.raw or args.stream) - any_link_spec = args.project_uuid or args.name if not making_collection: - if any_link_spec: + if args.name or args.project_uuid: raise ValueError("Requested a Link without creating a Collection") return None - elif not any_link_spec: - stderr.write( - "arv-put: No --project-uuid or --name specified. This data will be cached\n" - "in Keep. You will need to find this upload by its locator(s) later.\n") - return None - elif not args.project_uuid: - raise ValueError("--name requires --project-uuid") - elif not project_exists(args.project_uuid): + link = {'tail_uuid': args.project_uuid, + 'link_class': 'name', + 'name': args.name} + if not link['tail_uuid']: + link['tail_uuid'] = api_client.users().current().execute()['uuid'] + elif not project_exists(link['tail_uuid']): raise ValueError("Project {} not found".format(args.project_uuid)) - link = {'tail_uuid': args.project_uuid, 'link_class': 'name'} - if args.name: - link['name'] = args.name + if not link['name']: + link['name'] = "Saved at {} by {}@{}".format( + datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC"), + pwd.getpwuid(os.getuid()).pw_name, + socket.gethostname()) + stderr.write( + "arv-put: No --name specified. Saving as \"%s\"\n" % link['name']) + link['owner_uuid'] = link['tail_uuid'] return link def create_project_link(locator, link): link['head_uuid'] = locator - link.setdefault('name', "Collection saved by {}@{} at {}".format( - pwd.getpwuid(os.getuid()).pw_name, - socket.gethostname(), - datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC"))) - return arvados.api('v1').links().create(body=link).execute() + return api_client.links().create(body=link).execute() def main(arguments=None, stdout=sys.stdout, stderr=sys.stderr): + global api_client + if api_client is None: + api_client = arvados.api('v1') status = 0 args = parse_arguments(arguments) @@ -412,7 +417,6 @@ def main(arguments=None, stdout=sys.stdout, stderr=sys.stderr): if resume_cache is None: writer = ArvPutCollectionWriter(resume_cache, reporter, bytes_expected) else: - resume_cache.restart() writer = ArvPutCollectionWriter.from_cache( resume_cache, reporter, bytes_expected) @@ -446,24 +450,33 @@ def main(arguments=None, stdout=sys.stdout, stderr=sys.stderr): output = ','.join(writer.data_locators()) else: # Register the resulting collection in Arvados. - collection = arvados.api().collections().create( + collection = api_client.collections().create( body={ - 'uuid': writer.finish(), 'manifest_text': writer.manifest_text(), + 'owner_uuid': project_link['tail_uuid'] }, ).execute() - # Print the locator (uuid) of the new collection. - output = collection['uuid'] + if 'portable_data_hash' in collection and collection['portable_data_hash']: + output = collection['portable_data_hash'] + else: + output = collection['uuid'] + if project_link is not None: + # Update collection name try: - create_project_link(output, project_link) + if 'name' in collection: + arvados.api().collections().update(uuid=collection['uuid'], + body={"name": project_link["name"]}).execute() + else: + create_project_link(output, project_link) except apiclient.errors.Error as error: print >>stderr, ( "arv-put: Error adding Collection to project: {}.".format( error)) status = 1 + # Print the locator (uuid) of the new collection. stdout.write(output) if not output.endswith('\n'): stdout.write('\n')