From 11ce744c449409ba7371944bd55a4a80a0d0f300 Mon Sep 17 00:00:00 2001
From: John Chilton <jmchilton@gmail.com>
Date: Mon, 12 Dec 2016 14:50:31 -0500
Subject: [PATCH] Finish hooking the pieces together for Conda resolution.

With a test case.
---
 Makefile                             |  2 +-
 install_test/common_functions.bash   | 12 ++++++++++++
 install_test/test_install_conda.bash | 24 ++++++++++++++++++++++++
 pulsar/core.py                       |  6 +++++-
 pulsar/managers/base/__init__.py     |  5 +++--
 pulsar/managers/base/directory.py    |  2 +-
 pulsar/managers/queued_cli.py        |  2 +-
 pulsar/managers/unqueued.py          |  2 +-
 pulsar/scripts/config.py             | 13 +++++++++++++
 9 files changed, 61 insertions(+), 7 deletions(-)
 create mode 100755 install_test/test_install_conda.bash

diff --git a/Makefile b/Makefile
index 316a4e4b..26bc3790 100644
--- a/Makefile
+++ b/Makefile
@@ -83,7 +83,7 @@ test-install-pypi:
 	bash install_test/test_install.bash
 
 test-install-wheel: dist
-	PULSAR_INSTALL_TARGET=$(shell pwd)/dist/pulsar_app*.whl bash install_test/test_install.bash
+	PULSAR_INSTALL_TARGET=$(shell pwd)/dist/pulsar_app*.whl bash install_test/test_install_conda.bash
 
 coverage:
 	coverage run --source $(SOURCE_DIR) setup.py $(TEST_DIR)
diff --git a/install_test/common_functions.bash b/install_test/common_functions.bash
index f19745a4..2d0e8a4c 100644
--- a/install_test/common_functions.bash
+++ b/install_test/common_functions.bash
@@ -2,6 +2,7 @@ set -e
 
 shopt -s nullglob
 
+PULSAR_TARGET_POORT="${PULSAR_TARGET_POORT:-8913}"
 PULSAR_INSTALL_TARGET="${PULSAR_INSTALL_TARGET:-pulsar-app}"
 PLANEMO_INSTALL_TARGET="${PLANEMO_INSTALL_TARGET:-planemo==0.36.1}"
 
@@ -38,9 +39,20 @@ stop_pulsar() {
 check_pulsar() {
     cd pulsar
 
+    if curl -s "http://localhost:$PULSAR_TARGET_POORT"
+    then
+        echo "Port $PULSAR_TARGET_POORT already bound, Pulsar will fail to start."
+        exit 1;
+    fi
+
     echo "Starting Pulsar in daemon mode."
     pulsar --daemon
     echo "Waiting for Pulsar to start."
+    while ! curl -s "http://localhost:$PULSAR_TARGET_POORT";
+    do
+        printf "."
+        sleep 1;
+    done
     sleep 2
     echo "Running a standalone Pulsar job."
     pulsar-check # runs a test job
diff --git a/install_test/test_install_conda.bash b/install_test/test_install_conda.bash
new file mode 100755
index 00000000..959e277f
--- /dev/null
+++ b/install_test/test_install_conda.bash
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+SCRIPT_DIR="$( cd "$(dirname "$0")" ; pwd )"
+. "$SCRIPT_DIR/common_functions.bash"
+
+init_temp_dir
+
+init_pulsar
+
+cd pulsar
+echo "Running pulsar-config with --auto_conda"
+pulsar-config --auto_conda
+
+cd ..
+
+check_pulsar
+
+init_planemo "conda_testing"
+
+run_planemo --job_config_file "$SCRIPT_DIR/galaxy_job_conf.xml" test_tools/bwa.xml
+
+stop_pulsar
diff --git a/pulsar/core.py b/pulsar/core.py
index e4547d27..346dcc38 100644
--- a/pulsar/core.py
+++ b/pulsar/core.py
@@ -124,7 +124,11 @@ class PulsarApp(object):
     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")
-        self.dependency_manager = DependencyManager(dependencies_dir, resolvers_config_file)
+        conda_config = {}
+        for key, value in conf.items():
+            if key.startswith("conda_"):
+                conda_config[key] = value
+        self.dependency_manager = DependencyManager(dependencies_dir, resolvers_config_file, **conda_config)
 
     def __setup_job_metrics(self, conf):
         job_metrics = conf.get("job_metrics", None)
diff --git a/pulsar/managers/base/__init__.py b/pulsar/managers/base/__init__.py
index 513e9f6a..91d27570 100644
--- a/pulsar/managers/base/__init__.py
+++ b/pulsar/managers/base/__init__.py
@@ -176,7 +176,7 @@ class BaseManager(ManagerInterface):
         else:
             return listdir(directory_or_none)
 
-    def _expand_command_line(self, command_line, dependencies_description):
+    def _expand_command_line(self, command_line, dependencies_description, job_directory=None):
         if dependencies_description is None:
             return command_line
 
@@ -184,7 +184,8 @@ class BaseManager(ManagerInterface):
         installed_tool_dependencies = dependencies_description.installed_tool_dependencies
         dependency_commands = self.dependency_manager.dependency_shell_commands(
             requirements=requirements,
-            installed_tool_dependencies=installed_tool_dependencies
+            installed_tool_dependencies=installed_tool_dependencies,
+            job_directory=job_directory,
         )
         if dependency_commands:
             command_line = "%s; %s" % ("; ".join(dependency_commands), command_line)
diff --git a/pulsar/managers/base/directory.py b/pulsar/managers/base/directory.py
index 90308bef..0463b84c 100644
--- a/pulsar/managers/base/directory.py
+++ b/pulsar/managers/base/directory.py
@@ -105,7 +105,7 @@ class DirectoryBaseManager(BaseManager):
 
     # Helpers methods related to setting up job script files.
     def _setup_job_file(self, job_id, command_line, dependencies_description=None, env=[]):
-        command_line = self._expand_command_line(command_line, dependencies_description)
+        command_line = self._expand_command_line(command_line, dependencies_description, job_directory=self.job_directory(job_id).job_directory)
         script_env = self._job_template_env(job_id, command_line=command_line, env=env)
         script = job_script(**script_env)
         return self._write_job_script(job_id, script)
diff --git a/pulsar/managers/queued_cli.py b/pulsar/managers/queued_cli.py
index 65fc442c..016cd6c6 100644
--- a/pulsar/managers/queued_cli.py
+++ b/pulsar/managers/queued_cli.py
@@ -26,7 +26,7 @@ class CliQueueManager(ExternalBaseManager):
         stdout_path = self._stdout_path(job_id)
         stderr_path = self._stderr_path(job_id)
         job_name = self._job_name(job_id)
-        command_line = self._expand_command_line(command_line, dependencies_description)
+        command_line = self._expand_command_line(command_line, dependencies_description, job_directory=self.job_directory(job_id).job_directory)
         job_script_kwargs = self._job_template_env(job_id, command_line=command_line, env=env)
         extra_kwargs = job_interface.job_script_kwargs(stdout_path, stderr_path, job_name)
         job_script_kwargs.update(extra_kwargs)
diff --git a/pulsar/managers/unqueued.py b/pulsar/managers/unqueued.py
index 705b72e1..525215a5 100644
--- a/pulsar/managers/unqueued.py
+++ b/pulsar/managers/unqueued.py
@@ -152,7 +152,7 @@ class Manager(DirectoryBaseManager):
         if platform.system().lower() == "windows":
             # TODO: Don't ignore requirements and env without warning. Ideally
             # process them or at least warn about them being ignored.
-            command_line = self._expand_command_line(command_line, dependencies_description)
+            command_line = self._expand_command_line(command_line, dependencies_description, job_directory=self.job_directory(job_id).job_directory)
         else:
             command_line = self._setup_job_file(job_id, command_line, dependencies_description=dependencies_description, env=env)
         return command_line
diff --git a/pulsar/scripts/config.py b/pulsar/scripts/config.py
index efb7a738..abde0d74 100644
--- a/pulsar/scripts/config.py
+++ b/pulsar/scripts/config.py
@@ -29,6 +29,8 @@ DESCRIPTION = "Initialize a directory with a minimal pulsar config."
 HELP_DIRECTORY = "Directory containing the configuration files for Pulsar."
 HELP_MQ = ("Write configuration files for message queue server deployment "
            "instead of more traditional RESTful web based pulsar.")
+HELP_AUTO_CONDA = ("Auto initialize Conda for tool resolution and auto install "
+                   "dependencies on demand.")
 HELP_NO_LOGGING = ("Do not write Pulsar's default logging configuration to server.ini "
                    "and if uwsgi is configured do not configure its logging either.")
 HELP_SUPERVISOR = ("Write a supervisord configuration file for "
@@ -145,6 +147,10 @@ def main(argv=None):
     arg_parser.add_argument("--directory",
                             default=".",
                             help=HELP_DIRECTORY)
+    arg_parser.add_argument("--auto_conda",
+                            action="store_true",
+                            default=False,
+                            help=HELP_AUTO_CONDA)
     arg_parser.add_argument("--mq",
                             action="store_true",
                             default=False,
@@ -198,6 +204,10 @@ def main(argv=None):
     if not os.path.exists(directory):
         os.makedirs(directory)
 
+    default_dependencies_dir = os.path.join(directory, "dependencies")
+    if not os.path.exists(default_dependencies_dir):
+        os.makedirs(default_dependencies_dir)
+
     print("Bootstrapping pulsar configuration into directory %s" % relative_directory)
     _handle_app_yaml(args, directory)
     _handle_server_ini(args, directory)
@@ -298,6 +308,9 @@ def _handle_app_yaml(args, directory):
         contents += 'private_token: %s\n' % args.private_token
     if args.mq:
         contents += 'message_queue_url: "amqp://guest:guest@localhost:5672//"\n'
+    if args.auto_conda:
+        contents += 'conda_auto_init: true\n'
+        contents += 'conda_auto_install: true\n'
     else:
         if not IS_WINDOWS and args.libdrmaa_path:
             contents += 'manager:\n  type: queued_drmaa\n'
-- 
GitLab