From ae67d8076ff4ed9024109b4486903ecd9b32c2ab Mon Sep 17 00:00:00 2001
From: John Chilton <jmchilton@gmail.com>
Date: Mon, 17 Jun 2019 15:22:21 -0400
Subject: [PATCH] Allow Kubernetes to be used with DependencyResolution.

---
 docker/coexecutor/Dockerfile  |  6 ++++--
 docker/coexecutor/Makefile    |  8 +++++---
 pulsar/client/client.py       | 27 +++++++++++++--------------
 pulsar/core.py                | 19 ++++++++++++-------
 pulsar/scripts/_conda_init.py | 28 ++++++++++++++++++++++++++++
 setup.py                      |  1 +
 6 files changed, 63 insertions(+), 26 deletions(-)
 create mode 100644 pulsar/scripts/_conda_init.py

diff --git a/docker/coexecutor/Dockerfile b/docker/coexecutor/Dockerfile
index a97ce20e..8ffc70dd 100644
--- a/docker/coexecutor/Dockerfile
+++ b/docker/coexecutor/Dockerfile
@@ -4,13 +4,14 @@ ENV PYTHONUNBUFFERED 1
 ENV DEBIAN_FRONTEND noninteractive
 ENV PULSAR_CONFIG_CONDA_PREFIX /usr/local
 
+# wget, gcc, pip - to build and install Pulsar.
+# bzip2 for Miniconda.
 # TODO: pycurl stuff...
-
 RUN apt-get update \
-    # Install CVMFS client
     && apt-get install -y --no-install-recommends lsb-release wget \
         gcc python-setuptools \
         python-dev python-pip \
+        bzip2 \
     && apt-get -y autoremove \
     && apt-get autoclean \
     && rm -rf /var/lib/apt/lists/* /var/log/dpkg.log
@@ -20,3 +21,4 @@ RUN pip install -U pip && pip install wheel kombu pykube poster
 ADD pulsar_app-*.dev0-py2.py3-none-any.whl /pulsar_app-*.dev0-py2.py3-none-any.whl
 
 RUN pip install /pulsar_app-*.dev0-py2.py3-none-any.whl[galaxy_extended_metadata]
+RUN _pulsar-conda-init --conda_prefix=/pulsar_dependencies/conda
diff --git a/docker/coexecutor/Makefile b/docker/coexecutor/Makefile
index ec1ab0af..26ede1af 100644
--- a/docker/coexecutor/Makefile
+++ b/docker/coexecutor/Makefile
@@ -1,7 +1,9 @@
 
 
-docker-image:
+dist:
 	cd ../..; make dist; cp dist/pulsar*whl docker/coexecutor
 
-all: docker-image
-	docker build -t 'galaxy/pulsar-pod-staging:0.12.0' .
+docker-image:
+	docker build -t 'galaxy/pulsar-pod-staging:0.13.0' .
+
+all: dist docker-image
diff --git a/pulsar/client/client.py b/pulsar/client/client.py
index 81b4cc13..298c0458 100644
--- a/pulsar/client/client.py
+++ b/pulsar/client/client.py
@@ -397,9 +397,6 @@ class MessageCoexecutionPodJobClient(BaseMessageJobClient):
         volume_mounts = [
             {"mountPath": "/pulsar_staging", "name": "staging-directory"},
         ]
-        tool_container_image = container  # TODO: this isn't right at all...
-        if not container:
-            raise Exception("Must declare a container for kubernetes job execution.")
         pulsar_container_dict = {
             "name": "pulsar-container",
             "image": pulsar_container_image,
@@ -408,17 +405,19 @@ class MessageCoexecutionPodJobClient(BaseMessageJobClient):
             "workingDir": "/",
             "volumeMounts": volume_mounts,
         }
-        command = TOOL_EXECUTION_CONTAINER_COMMAND_TEMPLATE % job_directory.job_directory
-        tool_container_spec = {
-            "name": "tool-container",
-            "image": tool_container_image,
-            "command": ["sh"],
-            "args": ["-c", command],
-            "workingDir": "/",
-            "volumeMounts": volume_mounts,
-        }
-
-        container_dicts = [pulsar_container_dict, tool_container_spec]
+        tool_container_image = container
+        container_dicts = [pulsar_container_dict]
+        if container:
+            command = TOOL_EXECUTION_CONTAINER_COMMAND_TEMPLATE % job_directory.job_directory
+            tool_container_spec = {
+                "name": "tool-container",
+                "image": tool_container_image,
+                "command": ["sh"],
+                "args": ["-c", command],
+                "workingDir": "/",
+                "volumeMounts": volume_mounts,
+            }
+            container_dicts.append(tool_container_spec)
         for container_dict in container_dicts:
             if self._default_pull_policy:
                 container_dict["imagePullPolicy"] = self._default_pull_policy
diff --git a/pulsar/core.py b/pulsar/core.py
index 2f392d49..f3e497aa 100644
--- a/pulsar/core.py
+++ b/pulsar/core.py
@@ -10,11 +10,13 @@ from pulsar.tools.authorization import get_authorizer
 from pulsar import messaging
 from galaxy.objectstore import build_object_store_from_config
 try:
-    # If galaxy-lib or Galaxy <19.05 present.
-    from galaxy.tools.deps import DependencyManager
-except ImportError:
     # If galaxy-tool-util or Galaxy >=19.09 present.
+    from galaxy.tools.deps import build_dependency_manager
+    DependencyManager = None
+except ImportError:
+    # If galaxy-lib or Galaxy <19.05 present.
     from galaxy.tool_util.deps import DependencyManager
+    build_dependency_manager = None
 try:
     # If galaxy-lib or Galaxy <19.05 present.
     from galaxy.jobs.metrics import JobMetrics
@@ -140,10 +142,13 @@ class PulsarApp(object):
         self.object_store = build_object_store_from_config(object_store_config, config_dict=config_dict)
 
     def __setup_dependency_manager(self, conf):
-        dependencies_dir = conf.get("tool_dependency_dir", "dependencies")
-        resolvers_config_file = conf.get("dependency_resolvers_config_file", "dependency_resolvers_conf.xml")
-        conda_config = {k: v for k, v in conf.items() if k.startswith("conda_")}
-        self.dependency_manager = DependencyManager(dependencies_dir, resolvers_config_file, app_config=conda_config)
+        if build_dependency_manager is not None:
+            self.dependency_manager = build_dependency_manager(app_config_dict=conf)
+        else:
+            dependencies_dir = conf.get("tool_dependency_dir", "dependencies")
+            resolvers_config_file = conf.get("dependency_resolvers_config_file", "dependency_resolvers_conf.xml")
+            conda_config = {k: v for k, v in conf.items() if k.startswith("conda_")}
+            self.dependency_manager = DependencyManager(dependencies_dir, resolvers_config_file, app_config=conda_config)
 
     def __setup_job_metrics(self, conf):
         job_metrics = conf.get("job_metrics", None)
diff --git a/pulsar/scripts/_conda_init.py b/pulsar/scripts/_conda_init.py
new file mode 100644
index 00000000..dad2b8b7
--- /dev/null
+++ b/pulsar/scripts/_conda_init.py
@@ -0,0 +1,28 @@
+"""Small utility for bootstrapping a Conda environment for Pulsar.
+
+This should probably be moved into galaxy-tool-util.
+"""
+
+import os.path
+import sys
+from argparse import ArgumentParser
+
+from galaxy.tool_util.deps.conda_util import CondaContext, install_conda
+from galaxy.util import safe_makedirs
+
+
+def main(argv=None):
+    mod_docstring = sys.modules[__name__].__doc__
+    arg_parser = ArgumentParser(description=mod_docstring)
+    arg_parser.add_argument("--conda_prefix", required=True)
+    args = arg_parser.parse_args(argv)
+    conda_prefix = args.conda_prefix
+    safe_makedirs(os.path.dirname(conda_prefix))
+    conda_context = CondaContext(
+        conda_prefix=conda_prefix,
+    )
+    install_conda(conda_context)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/setup.py b/setup.py
index 8e9c406e..2064548f 100644
--- a/setup.py
+++ b/setup.py
@@ -100,6 +100,7 @@ setup(
         pulsar-chown-working-directory=pulsar.scripts.chown_working_directory:main
         pulsar-submit=pulsar.scripts.submit:main
         pulsar-run=pulsar.scripts.run:main
+        _pulsar-conda-init=pulsar.scripts._conda_init:main
     ''',
     scripts=scripts,
     package_data={'pulsar': [
-- 
GitLab