X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/a1c4ece152e1e992c18f0cb368528cd2ac843b07..adc0f36eeab40f4b8e0603247392b3c804d7272a:/sdk/cwl/arvados_cwl/pathmapper.py diff --git a/sdk/cwl/arvados_cwl/pathmapper.py b/sdk/cwl/arvados_cwl/pathmapper.py index 4cd204f7df..a5dd5ccf39 100644 --- a/sdk/cwl/arvados_cwl/pathmapper.py +++ b/sdk/cwl/arvados_cwl/pathmapper.py @@ -21,7 +21,9 @@ import arvados.collection from schema_salad.sourceline import SourceLine from arvados.errors import ApiError -from cwltool.pathmapper import PathMapper, MapperEnt, abspath, adjustFileObjs, adjustDirObjs +from cwltool.pathmapper import PathMapper, MapperEnt +from cwltool.utils import adjustFileObjs, adjustDirObjs +from cwltool.stdfsaccess import abspath from cwltool.workflow import WorkflowException from .http import http_to_keep @@ -50,7 +52,8 @@ class ArvPathMapper(PathMapper): """Convert container-local paths to and from Keep collection ids.""" def __init__(self, arvrunner, referenced_files, input_basedir, - collection_pattern, file_pattern, name=None, single_collection=False): + collection_pattern, file_pattern, name=None, single_collection=False, + optional_deps=None): self.arvrunner = arvrunner self.input_basedir = input_basedir self.collection_pattern = collection_pattern @@ -59,6 +62,7 @@ class ArvPathMapper(PathMapper): self.referenced_files = [r["location"] for r in referenced_files] self.single_collection = single_collection self.pdh_to_uuid = {} + self.optional_deps = optional_deps or [] super(ArvPathMapper, self).__init__(referenced_files, input_basedir, None) def visit(self, srcobj, uploadfiles): @@ -71,6 +75,7 @@ class ArvPathMapper(PathMapper): if isinstance(src, basestring) and src.startswith("keep:"): if collection_pdh_pattern.match(src): self._pathmap[src] = MapperEnt(src, self.collection_pattern % urllib.parse.unquote(src[5:]), srcobj["class"], True) + if arvados_cwl.util.collectionUUID in srcobj: self.pdh_to_uuid[src.split("/", 1)[0][5:]] = srcobj[arvados_cwl.util.collectionUUID] elif not collection_uuid_pattern.match(src): @@ -99,9 +104,12 @@ class ArvPathMapper(PathMapper): if srcobj["class"] == "Directory" and "listing" not in srcobj: raise WorkflowException("Directory literal '%s' is missing `listing`" % src) elif src.startswith("http:") or src.startswith("https:"): - keepref = http_to_keep(self.arvrunner.api, self.arvrunner.project_uuid, src) - logger.info("%s is %s", src, keepref) - self._pathmap[src] = MapperEnt(keepref, keepref, srcobj["class"], True) + try: + keepref = http_to_keep(self.arvrunner.api, self.arvrunner.project_uuid, src) + logger.info("%s is %s", src, keepref) + self._pathmap[src] = MapperEnt(keepref, keepref, srcobj["class"], True) + except Exception as e: + logger.warning(str(e)) else: self._pathmap[src] = MapperEnt(src, src, srcobj["class"], True) @@ -130,6 +138,9 @@ class ArvPathMapper(PathMapper): f.write(obj["contents"]) remap.append((obj["location"], path + "/" + obj["basename"])) else: + for opt in self.optional_deps: + if obj["location"] == opt["location"]: + return raise SourceLine(obj, "location", WorkflowException).makeError("Don't know what to do with '%s'" % obj["location"]) def needs_new_collection(self, srcobj, prefix=""): @@ -144,15 +155,19 @@ class ArvPathMapper(PathMapper): loc = srcobj["location"] if loc.startswith("_:"): return True - if prefix: - if loc != prefix+srcobj["basename"]: - return True - else: + + if not prefix: i = loc.rfind("/") if i > -1: prefix = loc[:i+1] + suffix = urllib.parse.quote(urllib.parse.unquote(loc[i+1:]), "/+@") else: prefix = loc+"/" + suffix = "" + + if prefix+suffix != prefix+urllib.parse.quote(srcobj["basename"], "/+@"): + return True + if srcobj["class"] == "File" and loc not in self._pathmap: return True for s in srcobj.get("secondaryFiles", []): @@ -189,7 +204,7 @@ class ArvPathMapper(PathMapper): packed=False) for src, ab, st in uploadfiles: - self._pathmap[src] = MapperEnt(urllib.parse.quote(st.fn, "/:+@"), self.collection_pattern % st.fn[5:], + self._pathmap[src] = MapperEnt(urllib.parse.quote(st.fn, "/:+@"), urllib.parse.quote(self.collection_pattern % st.fn[5:], "/:+@"), "Directory" if os.path.isdir(ab) else "File", True) for srcobj in referenced_files: @@ -212,19 +227,10 @@ class ArvPathMapper(PathMapper): ab = self.collection_pattern % c.portable_data_hash() self._pathmap[srcobj["location"]] = MapperEnt("keep:"+c.portable_data_hash(), ab, "Directory", True) - elif srcobj["class"] == "File" and (srcobj.get("secondaryFiles") or - (srcobj["location"].startswith("_:") and "contents" in srcobj)): - - # If all secondary files/directories are located in - # the same collection as the primary file and the - # paths and names that are consistent with staging, - # don't create a new collection. - if not self.needs_new_collection(srcobj): - continue - + elif srcobj["class"] == "File" and self.needs_new_collection(srcobj): c = arvados.collection.Collection(api_client=self.arvrunner.api, keep_client=self.arvrunner.keep_client, - num_retries=self.arvrunner.num_retries ) + num_retries=self.arvrunner.num_retries) self.addentry(srcobj, c, ".", remap) container = arvados_cwl.util.get_current_container(self.arvrunner.api, self.arvrunner.num_retries, logger) @@ -285,6 +291,7 @@ class StagingPathMapper(PathMapper): def visit(self, obj, stagedir, basedir, copy=False, staged=False): # type: (Dict[unicode, Any], unicode, unicode, bool) -> None loc = obj["location"] + stagedir = obj.get("dirname") or stagedir tgt = os.path.join(stagedir, obj["basename"]) basetgt, baseext = os.path.splitext(tgt)