Repository: common-workflow-language/cwltool

Issue:
we broke udocker ; doesn't suport --mount syntax, only --volume syntax
```
$ cwltool --enable-ext --default-container=debian --user-space-docker-cmd=udocker tests/wf/timelimit.cwl --sleep_time 10
INFO /home/michael/cwltool/env3.7/bin/cwltool 3.0.20200521133004
INFO Resolved 'tests/wf/timelimit.cwl' to 'file:///home/michael/cwltool/tests/wf/timelimit.cwl'
INFO ['udocker', 'pull', 'debian']
Downloading layer: sha256:376057ac6fa17f65688c56977118e2e764b27c348b3f70637fa829cd2a12b200
Downloading layer: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
INFO [job timelimit.cwl] /tmp/yjljpdqe$ udocker \
    --quiet \
    run \
    --mount=type=bind,source=/tmp/yjljpdqe,target=/eLjWfd \
    --mount=type=bind,source=/tmp/5ze79_5y,target=/tmp \
    --workdir=/eLjWfd \
    --rm \
    --env=TMPDIR=/tmp \
    --env=HOME=/eLjWfd \
    debian \
    sleep \
    10
Error: syntax error at: --mount=type=bind,source=/tmp/yjljpdqe,target=/eLjWfd --mount=type=bind,source=/tmp/5ze79_5y,target=/tmp
```

Probably introduced in https://github.com/common-workflow-language/cwltool/pull/1251

We missed this due to the `udocker` tests being skipped due to another issue which has since been fixed


Discussion:

Resolving patch:
diff --git a/cwltool/argparser.py b/cwltool/argparser.py
--- a/cwltool/argparser.py
+++ b/cwltool/argparser.py
@@ -395,10 +395,17 @@ def arg_parser() -> argparse.ArgumentParser:
     dockergroup.add_argument(
         "--user-space-docker-cmd",
         metavar="CMD",
-        help="(Linux/OS X only) Specify a user space docker "
-        "command (like udocker or dx-docker) that will be "
-        "used to call 'pull' and 'run'",
+        help="(Linux/OS X only) Specify the path to udocker. Implies --udocker",
     )
+    dockergroup.add_argument(
+        "--udocker",
+        help="(Linux/OS X only) Use the udocker runtime for running containers "
+        "(equivalent to --user-space-docker-cmd=udocker).",
+        action="store_const",
+        const="udocker",
+        dest="user_space_docker_cmd",
+    )
+
     dockergroup.add_argument(
         "--singularity",
         action="store_true",
diff --git a/cwltool/command_line_tool.py b/cwltool/command_line_tool.py
--- a/cwltool/command_line_tool.py
+++ b/cwltool/command_line_tool.py
@@ -63,6 +63,7 @@
 )
 from .singularity import SingularityCommandLineJob
 from .stdfsaccess import StdFsAccess
+from .udocker import UDockerCommandLineJob
 from .utils import (
     aslist,
     convert_pathsep_to_unix,
@@ -357,6 +358,8 @@ def make_job_runner(self, runtimeContext: RuntimeContext) -> Type[JobBase]:
         if dockerReq is not None and runtimeContext.use_container:
             if runtimeContext.singularity:
                 return SingularityCommandLineJob
+            elif runtimeContext.user_space_docker_cmd:
+                return UDockerCommandLineJob
             return DockerCommandLineJob
         for t in reversed(self.requirements):
             if t["class"] == "DockerRequirement":
diff --git a/cwltool/udocker.py b/cwltool/udocker.py
new file mode 100644
--- /dev/null
+++ b/cwltool/udocker.py
@@ -0,0 +1,18 @@
+"""Enables Docker software containers via the udocker runtime."""
+
+from typing import List
+
+from .docker import DockerCommandLineJob
+
+
+class UDockerCommandLineJob(DockerCommandLineJob):
+    """Runs a CommandLineJob in a sofware container using the udocker engine."""
+
+    @staticmethod
+    def append_volume(
+        runtime: List[str], source: str, target: str, writable: bool = False
+    ) -> None:
+        """Add binding arguments to the runtime list."""
+        runtime.append(
+            "--volume={}:{}:{}".format(source, target, "rw" if writable else "ro")
+        )


Test patch:
diff --git a/tests/test_examples.py b/tests/test_examples.py
--- a/tests/test_examples.py
+++ b/tests/test_examples.py
@@ -1057,6 +1057,7 @@ def test_no_compute_chcksum(tmpdir, factor):
     assert "checksum" not in stdout
 
 
+@pytest.mark.skipif(onWindows(), reason="udocker is Linux/macOS only")
 @pytest.mark.parametrize("factor", test_factors)
 def test_bad_userspace_runtime(factor):
     test_file = "tests/wf/wc-tool.cwl"
diff --git a/tests/test_udocker.py b/tests/test_udocker.py
--- a/tests/test_udocker.py
+++ b/tests/test_udocker.py
@@ -12,10 +12,7 @@
 LINUX = sys.platform in ("linux", "linux2")
 
 
-# @pytest.mark.skipif(not LINUX, reason="LINUX only")
-@pytest.mark.skip(
-    "Udocker install is broken, see https://github.com/indigo-dc/udocker/issues/221"
-)
+@pytest.mark.skipif(not LINUX, reason="LINUX only")
 class TestUdocker:
     udocker_path = None