Skip to content

Commit 0cfd6c5

Browse files
author
Anton Khodak
committed
Merge remote-tracking branch 'origin/parallel-exec' into parallel-exec
2 parents 563315b + c9d0f25 commit 0cfd6c5

File tree

11 files changed

+83
-54
lines changed

11 files changed

+83
-54
lines changed

README.rst

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Running tests locally
6565
To run the basis tests after installing `cwltool` execute the following:
6666

6767
.. code:: bash
68-
68+
6969
pip install pytest mock
7070
py.test --ignore cwltool/schemas/ --pyarg cwltool
7171
@@ -113,20 +113,31 @@ and ``--tmp-outdir-prefix`` to somewhere under ``/Users``::
113113
.. |Build Status| image:: https://ci.commonwl.org/buildStatus/icon?job=cwltool-conformance
114114
:target: https://ci.commonwl.org/job/cwltool-conformance/
115115

116-
Running user-space implementations of Docker
117-
--------------------------------------------
116+
Using user-space replacements for Docker
117+
----------------------------------------
118118

119-
Some compute environments disallow user-space installation of Docker due to incompatiblities in libraries or to meet security requirements. The CWL reference supports using a user space implementation with the `--user-space-docker-cmd` option.
119+
Some shared computing environments don't support Docker software containers for technical or policy reasons.
120+
As a work around, the CWL reference runner supports using a alternative ``docker`` implementations on Linux
121+
with the ``--user-space-docker-cmd`` option.
120122

121-
Example using `dx-docker` (https://wiki.dnanexus.com/Developer-Tutorials/Using-Docker-Images):
123+
One such "user space" friendly docker replacement is ``udocker`` https://github.com/indigo-dc/udocker and another
124+
is ``dx-docker`` https://wiki.dnanexus.com/Developer-Tutorials/Using-Docker-Images
122125

123-
For use on Linux, install the DNAnexus toolkit (see https://wiki.dnanexus.com/Downloads for instructions).
126+
udocker installation: https://github.com/indigo-dc/udocker/blob/master/doc/installation_manual.md#22-install-from-indigo-datacloud-repositories
127+
128+
dx-docker installation: start with the DNAnexus toolkit (see https://wiki.dnanexus.com/Downloads for instructions).
124129

125130
Run `cwltool` just as you normally would, but with the new option, e.g. from the conformance tests:
126131

127132
.. code:: bash
128133
129-
cwltool --user-space-docker-cmd=dx-docker --outdir=/tmp/tmpidytmp v1.0/test-cwl-out2.cwl v1.0/empty.json
134+
cwltool --user-space-docker-cmd=udocker https://raw.githubusercontent.com/common-workflow-language/common-workflow-language/master/v1.0/v1.0/test-cwl-out2.cwl https://github.com/common-workflow-language/common-workflow-language/blob/master/v1.0/v1.0/empty.json
135+
136+
or
137+
138+
.. code:: bash
139+
140+
cwltool --user-space-docker-cmd=dx-docker https://raw.githubusercontent.com/common-workflow-language/common-workflow-language/master/v1.0/v1.0/test-cwl-out2.cwl https://github.com/common-workflow-language/common-workflow-language/blob/master/v1.0/v1.0/empty.json
130141
131142
Tool or workflow loading from remote or local locations
132143
-------------------------------------------------------
@@ -224,7 +235,7 @@ the correct module environment before executing the above tool would simply be:
224235

225236
.. code:: yaml
226237
227-
- type: module
238+
- type: modules
228239
229240
The outer list indicates that one plugin is being enabled, the plugin parameters are
230241
defined as a dictionary for this one list item. There is only one required parameter
@@ -399,17 +410,16 @@ environment or with a particular dataset. To avoid the need to modify the
399410
underlying workflow, cwltool supports requirement "overrides".
400411

401412
The format of the "overrides" object is a mapping of item identifier (workflow,
402-
workflow step, or command line tool) followed by a list of ProcessRequirements
403-
that should be applied.
413+
workflow step, or command line tool) to the process requirements that should be applied.
404414

405415
.. code:: yaml
406416
407417
cwltool:overrides:
408418
echo.cwl:
409-
- class: EnvVarRequirement
410-
envDef:
411-
MESSAGE: override_value
412-
419+
requirements:
420+
EnvVarRequirement:
421+
envDef:
422+
MESSAGE: override_value
413423
414424
Overrides can be specified either on the command line, or as part of the job
415425
input document. Workflow steps are identified using the name of the workflow
@@ -426,9 +436,10 @@ Override identifiers are relative to the toplevel workflow document.
426436
input_parameter2: value2
427437
cwltool:overrides:
428438
workflow.cwl#step1:
429-
- class: EnvVarRequirement
430-
envDef:
431-
MESSAGE: override_value
439+
requirements:
440+
EnvVarRequirement:
441+
envDef:
442+
MESSAGE: override_value
432443
433444
.. code:: bash
434445

cwltool/job.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from __future__ import absolute_import
2+
import codecs
23
import functools
34
import io
45
import json
@@ -553,14 +554,14 @@ def _job_popen(
553554
stdin_path=stdin_path,
554555
)
555556
with open(os.path.join(job_dir, "job.json"), "wb") as f:
556-
json.dump(job_description, f)
557+
json.dump(job_description, codecs.getwriter('utf-8')(f), ensure_ascii=False) # type: ignore
557558
try:
558559
job_script = os.path.join(job_dir, "run_job.bash")
559560
with open(job_script, "wb") as f:
560561
f.write(job_script_contents.encode('utf-8'))
561562
job_run = os.path.join(job_dir, "run_job.py")
562563
with open(job_run, "wb") as f:
563-
f.write(PYTHON_RUN_SCRIPT)
564+
f.write(PYTHON_RUN_SCRIPT.encode('utf-8'))
564565
sp = subprocess.Popen(
565566
["bash", job_script.encode("utf-8")],
566567
shell=False,

cwltool/load_tool.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@
4545
u"overrides": {
4646
"@id": "cwltool:overrides",
4747
"mapSubject": "overrideTarget",
48-
"mapPredicate": "override"
4948
},
50-
u"override": {
51-
"@id": "cwltool:override",
49+
"requirements": {
50+
"@id": "https://w3id.org/cwl/cwl#requirements",
5251
"mapSubject": "class"
5352
}
5453
} # type: ContextType

cwltool/pack.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ def import_embed(d, seen):
9595
import_embed(d[k], seen)
9696

9797

98-
def pack(document_loader, processobj, uri, metadata):
99-
# type: (Loader, Union[Dict[Text, Any], List[Dict[Text, Any]]], Text, Dict[Text, Text]) -> Dict[Text, Any]
98+
def pack(document_loader, processobj, uri, metadata, rewrite_out=None):
99+
# type: (Loader, Union[Dict[Text, Any], List[Dict[Text, Any]]], Text, Dict[Text, Text], Dict[Text, Text]) -> Dict[Text, Any]
100100

101101
document_loader = SubLoader(document_loader)
102102
document_loader.idx = {}
@@ -114,15 +114,20 @@ def loadref(b, u):
114114
# type: (Text, Text) -> Union[Dict, List, Text]
115115
return document_loader.resolve_ref(u, base_url=b)[0]
116116

117+
ids = set() # type: Set[Text]
118+
find_ids(processobj, ids)
119+
117120
runs = {uri}
118121
find_run(processobj, loadref, runs)
119122

120-
ids = set() # type: Set[Text]
121123
for f in runs:
122124
find_ids(document_loader.resolve_ref(f)[0], ids)
123125

124126
names = set() # type: Set[Text]
125-
rewrite = {} # type: Dict[Text, Text]
127+
if rewrite_out is None:
128+
rewrite = {} # type: Dict[Text, Text]
129+
else:
130+
rewrite = rewrite_out
126131

127132
mainpath, _ = urllib.parse.urldefrag(uri)
128133

@@ -131,8 +136,10 @@ def rewrite_id(r, mainuri):
131136
if r == mainuri:
132137
rewrite[r] = "#main"
133138
elif r.startswith(mainuri) and r[len(mainuri)] in ("#", "/"):
134-
path, frag = urllib.parse.urldefrag(r)
135-
rewrite[r] = "#"+frag
139+
if r[len(mainuri):].startswith("#main/"):
140+
rewrite[r] = "#" + uniquename(r[len(mainuri)+1:], names)
141+
else:
142+
rewrite[r] = "#" + uniquename("main/"+r[len(mainuri)+1:], names)
136143
else:
137144
path, frag = urllib.parse.urldefrag(r)
138145
if path == mainpath:
@@ -144,8 +151,7 @@ def rewrite_id(r, mainuri):
144151
sortedids = sorted(ids)
145152

146153
for r in sortedids:
147-
if r in document_loader.idx:
148-
rewrite_id(r, uri)
154+
rewrite_id(r, uri)
149155

150156
packed = {"$graph": [], "cwlVersion": metadata["cwlVersion"]
151157
} # type: Dict[Text, Any]

cwltool/process.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,13 @@ def avroize_type(field_type, name_prefix=""):
422422
avroize_type(field_type["items"], name_prefix)
423423
return field_type
424424

425-
def get_overrides(overrides, toolid): # type: (List[Dict[Text, Any]], Text) -> List[Dict[Text, Any]]
426-
req = [] # type: List[Dict[Text, Any]]
425+
def get_overrides(overrides, toolid): # type: (List[Dict[Text, Any]], Text) -> Dict[Text, Any]
426+
req = {} # type: Dict[Text, Any]
427427
if not isinstance(overrides, list):
428428
raise validate.ValidationException("Expected overrides to be a list, but was %s" % type(overrides))
429429
for ov in overrides:
430430
if ov["overrideTarget"] == toolid:
431-
req.extend(ov["override"])
431+
req.update(ov)
432432
return req
433433

434434
class Process(six.with_metaclass(abc.ABCMeta, object)):
@@ -467,7 +467,7 @@ def __init__(self, toolpath_object, **kwargs):
467467
self.tool = toolpath_object
468468
self.requirements = (kwargs.get("requirements", []) +
469469
self.tool.get("requirements", []) +
470-
get_overrides(kwargs.get("overrides", []), self.tool["id"]))
470+
get_overrides(kwargs.get("overrides", []), self.tool["id"]).get("requirements", []))
471471
self.hints = kwargs.get("hints", []) + self.tool.get("hints", [])
472472
self.formatgraph = None # type: Graph
473473
if "loader" in kwargs:

cwltool/workflow.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,13 @@ def object_from_state(state, parms, frag_only, supportsMultipleInput, sourceFiel
210210
if frag_only:
211211
iid = shortname(iid)
212212
if sourceField in inp:
213-
if (isinstance(inp[sourceField], list) and not
214-
supportsMultipleInput):
213+
connections = aslist(inp[sourceField])
214+
if (len(connections) > 1 and
215+
not supportsMultipleInput):
215216
raise WorkflowException(
216217
"Workflow contains multiple inbound links to a single "
217218
"parameter but MultipleInputFeatureRequirement is not "
218219
"declared.")
219-
connections = aslist(inp[sourceField])
220220
for src in connections:
221221
if src in state and state[src] is not None and (state[src].success == "success" or incomplete):
222222
if not match_types(
@@ -673,7 +673,7 @@ def __init__(self, toolpath_object, pos, **kwargs):
673673

674674
kwargs["requirements"] = (kwargs.get("requirements", []) +
675675
toolpath_object.get("requirements", []) +
676-
get_overrides(kwargs.get("overrides", []), self.id))
676+
get_overrides(kwargs.get("overrides", []), self.id).get("requirements", []))
677677
kwargs["hints"] = kwargs.get("hints", []) + toolpath_object.get("hints", [])
678678

679679
try:
@@ -710,7 +710,14 @@ def __init__(self, toolpath_object, pos, **kwargs):
710710
for tool_entry in self.embedded_tool.tool[toolfield]:
711711
frag = shortname(tool_entry["id"])
712712
if frag == shortinputid:
713+
#if the case that the step has a default for a parameter,
714+
#we do not want the default of the tool to override it
715+
step_default = None
716+
if "default" in param and "default" in tool_entry:
717+
step_default = param["default"]
713718
param.update(tool_entry)
719+
if step_default is not None:
720+
param["default"] = step_default
714721
found = True
715722
bound.add(frag)
716723
break

tests/override/echo-job-ov.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
m1: zing
22
cwltool:overrides:
33
echo.cwl:
4-
- class: EnvVarRequirement
5-
envDef:
6-
MESSAGE: hello3
4+
requirements:
5+
EnvVarRequirement:
6+
envDef:
7+
MESSAGE: hello3

tests/override/echo-job-ov2.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
m1: zing
22
cwltool:overrides:
33
echo.cwl:
4-
- class: EnvVarRequirement
5-
envDef:
6-
MESSAGE: hello4
4+
requirements:
5+
EnvVarRequirement:
6+
envDef:
7+
MESSAGE: hello4
78
cwl:tool: echo.cwl

tests/override/ov.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cwltool:overrides:
22
echo.cwl:
3-
- class: EnvVarRequirement
4-
envDef:
5-
MESSAGE: hello2
3+
requirements:
4+
EnvVarRequirement:
5+
envDef:
6+
MESSAGE: hello2

tests/override/ov2.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cwltool:overrides:
22
"echo-wf.cwl#step1":
3-
- class: EnvVarRequirement
4-
envDef:
5-
MESSAGE: hello5
3+
requirements:
4+
EnvVarRequirement:
5+
envDef:
6+
MESSAGE: hello5

0 commit comments

Comments
 (0)