Repository: couler-proj/couler

Issue:
Add `WorkingDir` field when creating containers

Discussion:

Patch:
diff --git a/couler/core/run_templates.py b/couler/core/run_templates.py
index 7596a38..b94d5b6 100644
--- a/couler/core/run_templates.py
+++ b/couler/core/run_templates.py
@@ -98,6 +98,7 @@ def run_container(
     enable_ulogfs=True,
     daemon=False,
     volume_mounts=None,
+    working_dir=None,
 ):
     """
     Generate an Argo container template.  For example, the template whalesay
@@ -174,6 +175,7 @@ def run_container(
             enable_ulogfs=enable_ulogfs,
             daemon=daemon,
             volume_mounts=volume_mounts,
+            working_dir=working_dir,
         )
         states.workflow.add_template(template)
 
diff --git a/couler/core/templates/container.py b/couler/core/templates/container.py
index fc5c158..e3569f0 100644
--- a/couler/core/templates/container.py
+++ b/couler/core/templates/container.py
@@ -41,6 +41,7 @@ class Container(Template):
         enable_ulogfs=True,
         daemon=False,
         volume_mounts=None,
+        working_dir=None,
     ):
         Template.__init__(
             self,
@@ -61,6 +62,7 @@ class Container(Template):
         self.resources = resources
         self.image_pull_policy = image_pull_policy
         self.volume_mounts = volume_mounts
+        self.working_dir = working_dir
 
     def to_dict(self):
         template = Template.to_dict(self)
@@ -159,6 +161,8 @@ class Container(Template):
             container["volumeMounts"] = [
                 vm.to_dict() for vm in self.volume_mounts
             ]
+        if self.working_dir is not None:
+            container["workingDir"] = self.working_dir
         return container
 
     def _convert_args_to_input_parameters(self, args):
diff --git a/couler/core/utils.py b/couler/core/utils.py
index f7857d9..fd4dbb8 100644
--- a/couler/core/utils.py
+++ b/couler/core/utils.py
@@ -58,6 +58,8 @@ def invocation_location():
     else:
         func_name = argo_safe_name(stack[2][3])
         line_number = stack[3][2]
+    if func_name == "<module>":
+        func_name = "module-" + _get_uuid()
     return func_name, line_number
 
 


Test patch:
diff --git a/couler/tests/argo_test.py b/couler/tests/argo_test.py
index 2353cca..8e31ce1 100644
--- a/couler/tests/argo_test.py
+++ b/couler/tests/argo_test.py
@@ -76,6 +76,7 @@ class ArgoTest(unittest.TestCase):
             command=["bash", "-c"],
             step_name="A",
             volume_mounts=[volume_mount],
+            working_dir="/mnt/src",
         )
 
         wf = couler.workflow_yaml()
@@ -84,6 +85,9 @@ class ArgoTest(unittest.TestCase):
             wf["spec"]["templates"][1]["container"]["volumeMounts"][0],
             volume_mount.to_dict(),
         )
+        self.assertEqual(
+            wf["spec"]["templates"][1]["container"]["workingDir"], "/mnt/src"
+        )
         couler._cleanup()
 
     def test_run_container_with_workflow_volume(self):
@@ -157,10 +161,8 @@ class ArgoTest(unittest.TestCase):
         self.assertTrue(
             params["value"]
             in [
-                # Note that the "output-id-92" case is needed for
-                # Python 3.8.
-                '"{{workflow.outputs.parameters.output-id-113}}"',
-                '"{{workflow.outputs.parameters.output-id-114}}"',
+                '"{{workflow.outputs.parameters.output-id-117}}"',
+                '"{{workflow.outputs.parameters.output-id-118}}"',
             ]
         )
         # Check input parameters for step B