Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/ephemeris/shed_tools.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:18:57 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d30785e31577 |
|---|---|
| 1 """ | |
| 2 A tool to automate installation of tool repositories from a Galaxy Tool Shed | |
| 3 into an instance of Galaxy. | |
| 4 | |
| 5 Shed-tools has three commands: update, test and install. | |
| 6 | |
| 7 Update simply updates all the tools in a Galaxy given connection details on the command line. | |
| 8 | |
| 9 Test tests the specified tools in the Galaxy Instance. | |
| 10 | |
| 11 Install allows installation of tools in multiple ways. | |
| 12 Galaxy instance details and the installed tools can be provided in one of three | |
| 13 ways: | |
| 14 | |
| 15 1. In the YAML format via dedicated files (a sample can be found | |
| 16 `here <https://github.com/galaxyproject/ansible-galaxy-tools/blob/master/files/tool_list.yaml.sample>`_). | |
| 17 2. On the command line as dedicated script options (see the usage help). | |
| 18 3. As a single composite parameter to the script. The parameter must be a | |
| 19 single, YAML-formatted string with the keys corresponding to the keys | |
| 20 available for use in the YAML formatted file (for example: | |
| 21 `--yaml_tool "{'owner': 'kellrott', 'tool_shed_url': | |
| 22 'https://testtoolshed.g2.bx.psu.edu', 'tool_panel_section_id': | |
| 23 'peak_calling', 'name': 'synapse_interface'}"`). | |
| 24 | |
| 25 Only one of the methods can be used with each invocation of the script but if | |
| 26 more than one are provided are provided, precedence will correspond to order | |
| 27 of the items in the list above. | |
| 28 When installing tools, Galaxy expects any `tool_panel_section_id` provided when | |
| 29 installing a tool to already exist in the configuration. If the section | |
| 30 does not exist, the tool will be installed outside any section. See | |
| 31 `shed_tool_conf.xml.sample` in this directory for a sample of such file. Before | |
| 32 running this script to install the tools, make sure to place such file into | |
| 33 Galaxy's configuration directory and set Galaxy configuration option | |
| 34 `tool_config_file` to include it. | |
| 35 """ | |
| 36 import datetime as dt | |
| 37 import json | |
| 38 import os | |
| 39 import re | |
| 40 import time | |
| 41 from collections import namedtuple | |
| 42 from concurrent.futures import thread, ThreadPoolExecutor | |
| 43 | |
| 44 import requests | |
| 45 import yaml | |
| 46 from bioblend.galaxy.client import ConnectionError | |
| 47 from bioblend.galaxy.toolshed import ToolShedClient | |
| 48 from galaxy.tool_util.verify.interactor import ( | |
| 49 GalaxyInteractorApi, | |
| 50 verify_tool, | |
| 51 ) | |
| 52 from galaxy.util import unicodify | |
| 53 | |
| 54 from . import get_galaxy_connection, load_yaml_file | |
| 55 from .ephemeris_log import disable_external_library_logging, setup_global_logger | |
| 56 from .get_tool_list_from_galaxy import GiToToolYaml, the_same_repository, tools_for_repository | |
| 57 from .shed_tools_args import parser | |
| 58 from .shed_tools_methods import complete_repo_information, flatten_repo_info, VALID_KEYS | |
| 59 | |
| 60 NON_TERMINAL_REPOSITORY_STATES = { | |
| 61 'New', | |
| 62 'Cloning', | |
| 63 'Setting tool versions', | |
| 64 'Installing repository dependencies', | |
| 65 'Installing tool dependencies', | |
| 66 'Loading proprietary datatypes' | |
| 67 } | |
| 68 | |
| 69 | |
| 70 class InstallRepositoryManager(object): | |
| 71 """Manages the installation of new repositories on a galaxy instance""" | |
| 72 | |
| 73 def __init__(self, | |
| 74 galaxy_instance): | |
| 75 """Initialize a new tool manager""" | |
| 76 self.gi = galaxy_instance | |
| 77 self.tool_shed_client = ToolShedClient(self.gi) | |
| 78 | |
| 79 def installed_repositories(self): | |
| 80 """Get currently installed tools""" | |
| 81 return GiToToolYaml( | |
| 82 gi=self.gi, | |
| 83 skip_tool_panel_section_name=False, | |
| 84 get_data_managers=True, | |
| 85 get_all_tools=True | |
| 86 ).tool_list.get("tools") | |
| 87 | |
| 88 def filter_installed_repos(self, repos, check_revision=True): | |
| 89 # TODO: Find a speedier algorithm. | |
| 90 """This filters a list of repositories""" | |
| 91 not_installed_repos = [] | |
| 92 already_installed_repos = [] | |
| 93 if check_revision: | |
| 94 # If we want to check if revisions are equal, flatten the list, | |
| 95 # so each repository - revision combination has its own entry | |
| 96 installed_repos = flatten_repo_info(self.installed_repositories()) | |
| 97 else: | |
| 98 # If we do not care about revision equality, do not do the flatten | |
| 99 # action to limit the number of comparisons. | |
| 100 installed_repos = self.installed_repositories() | |
| 101 | |
| 102 for repo in repos: | |
| 103 for installed_repo in installed_repos: | |
| 104 if the_same_repository(installed_repo, repo, check_revision): | |
| 105 already_installed_repos.append(repo) | |
| 106 break | |
| 107 else: # This executes when the for loop completes and no match has been found. | |
| 108 not_installed_repos.append(repo) | |
| 109 FilterResults = namedtuple("FilterResults", ["not_installed_repos", "already_installed_repos"]) | |
| 110 return FilterResults(already_installed_repos=already_installed_repos, not_installed_repos=not_installed_repos) | |
| 111 | |
| 112 def install_repositories(self, | |
| 113 repositories, | |
| 114 log=None, | |
| 115 force_latest_revision=False, | |
| 116 default_toolshed='https://toolshed.g2.bx.psu.edu/', | |
| 117 default_install_tool_dependencies=False, | |
| 118 default_install_resolver_dependencies=True, | |
| 119 default_install_repository_dependencies=True): | |
| 120 """Install a list of tools on the current galaxy""" | |
| 121 if not repositories: | |
| 122 raise ValueError("Empty list of tools was given") | |
| 123 installation_start = dt.datetime.now() | |
| 124 installed_repositories = [] | |
| 125 skipped_repositories = [] | |
| 126 errored_repositories = [] | |
| 127 counter = 0 | |
| 128 | |
| 129 # Check repos for invalid keys | |
| 130 for repo in repositories: | |
| 131 for key in repo.keys(): | |
| 132 if key not in VALID_KEYS and key != 'revisions': | |
| 133 if log: | |
| 134 log.warning("'{0}' not a valid key. Will be skipped during parsing".format(key)) | |
| 135 | |
| 136 # Start by flattening the repo list per revision | |
| 137 flattened_repos = flatten_repo_info(repositories) | |
| 138 total_num_repositories = len(flattened_repos) | |
| 139 | |
| 140 # Complete the repo information, and make sure each repository has a revision | |
| 141 repository_list = [] | |
| 142 for repository in flattened_repos: | |
| 143 start = dt.datetime.now() | |
| 144 try: | |
| 145 complete_repo = complete_repo_information( | |
| 146 repository, | |
| 147 default_toolshed_url=default_toolshed, | |
| 148 require_tool_panel_info=True, | |
| 149 default_install_tool_dependencies=default_install_tool_dependencies, | |
| 150 default_install_resolver_dependencies=default_install_resolver_dependencies, | |
| 151 default_install_repository_dependencies=default_install_repository_dependencies, | |
| 152 force_latest_revision=force_latest_revision) | |
| 153 repository_list.append(complete_repo) | |
| 154 except Exception as e: | |
| 155 # We'll run through the loop come whatever may, we log the errored repositories at the end anyway. | |
| 156 if log: | |
| 157 log_repository_install_error(repository, start, unicodify(e), log) | |
| 158 errored_repositories.append(repository) | |
| 159 | |
| 160 # Filter out already installed repos | |
| 161 filtered_repos = self.filter_installed_repos(repository_list) | |
| 162 | |
| 163 for skipped_repo in filtered_repos.already_installed_repos: | |
| 164 counter += 1 | |
| 165 if log: | |
| 166 log_repository_install_skip(skipped_repo, counter, total_num_repositories, log) | |
| 167 skipped_repositories.append(skipped_repo) | |
| 168 | |
| 169 # Install repos | |
| 170 for repository in filtered_repos.not_installed_repos: | |
| 171 counter += 1 | |
| 172 if log: | |
| 173 log_repository_install_start(repository, counter=counter, installation_start=installation_start, log=log, | |
| 174 total_num_repositories=total_num_repositories) | |
| 175 result = self.install_repository_revision(repository, log) | |
| 176 if result == "error": | |
| 177 errored_repositories.append(repository) | |
| 178 elif result == "skipped": | |
| 179 skipped_repositories.append(repository) | |
| 180 elif result == "installed": | |
| 181 installed_repositories.append(repository) | |
| 182 | |
| 183 # Log results | |
| 184 if log: | |
| 185 log.info("Installed repositories ({0}): {1}".format( | |
| 186 len(installed_repositories), | |
| 187 [( | |
| 188 t['name'], | |
| 189 t.get('changeset_revision') | |
| 190 ) for t in installed_repositories]) | |
| 191 ) | |
| 192 log.info("Skipped repositories ({0}): {1}".format( | |
| 193 len(skipped_repositories), | |
| 194 [( | |
| 195 t['name'], | |
| 196 t.get('changeset_revision') | |
| 197 ) for t in skipped_repositories]) | |
| 198 ) | |
| 199 log.info("Errored repositories ({0}): {1}".format( | |
| 200 len(errored_repositories), | |
| 201 [( | |
| 202 t['name'], | |
| 203 t.get('changeset_revision', "") | |
| 204 ) for t in errored_repositories]) | |
| 205 ) | |
| 206 log.info("All repositories have been installed.") | |
| 207 log.info("Total run time: {0}".format(dt.datetime.now() - installation_start)) | |
| 208 InstallResults = namedtuple("InstallResults", | |
| 209 ["installed_repositories", "errored_repositories", "skipped_repositories"]) | |
| 210 return InstallResults(installed_repositories=installed_repositories, | |
| 211 skipped_repositories=skipped_repositories, | |
| 212 errored_repositories=errored_repositories) | |
| 213 | |
| 214 def update_repositories(self, repositories=None, log=None, **kwargs): | |
| 215 if not repositories: # Repositories None or empty list | |
| 216 repositories = self.installed_repositories() | |
| 217 else: | |
| 218 filtered_repos = self.filter_installed_repos(repositories, check_revision=False) | |
| 219 if filtered_repos.not_installed_repos: | |
| 220 if log: | |
| 221 log.warning("The following tools are not installed and will not be upgraded: {0}".format( | |
| 222 filtered_repos.not_installed_repos)) | |
| 223 repositories = filtered_repos.already_installed_repos | |
| 224 return self.install_repositories(repositories, force_latest_revision=True, log=log, **kwargs) | |
| 225 | |
| 226 def test_tools(self, | |
| 227 test_json, | |
| 228 repositories=None, | |
| 229 log=None, | |
| 230 test_user_api_key=None, | |
| 231 test_user="ephemeris@galaxyproject.org", | |
| 232 parallel_tests=1, | |
| 233 ): | |
| 234 """Run tool tests for all tools in each repository in supplied tool list or ``self.installed_repositories()``. | |
| 235 """ | |
| 236 tool_test_start = dt.datetime.now() | |
| 237 tests_passed = [] | |
| 238 test_exceptions = [] | |
| 239 | |
| 240 if not repositories: # If repositories is None or empty list | |
| 241 # Consider a variant of this that doesn't even consume a tool list YAML? target | |
| 242 # something like installed_repository_revisions(self.gi) | |
| 243 repositories = self.installed_repositories() | |
| 244 | |
| 245 target_repositories = flatten_repo_info(repositories) | |
| 246 | |
| 247 installed_tools = [] | |
| 248 for target_repository in target_repositories: | |
| 249 repo_tools = tools_for_repository(self.gi, target_repository) | |
| 250 installed_tools.extend(repo_tools) | |
| 251 | |
| 252 all_test_results = [] | |
| 253 galaxy_interactor = self._get_interactor(test_user, test_user_api_key) | |
| 254 test_history = galaxy_interactor.new_history() | |
| 255 | |
| 256 with ThreadPoolExecutor(max_workers=parallel_tests) as executor: | |
| 257 try: | |
| 258 for tool in installed_tools: | |
| 259 self._test_tool(executor=executor, | |
| 260 tool=tool, | |
| 261 galaxy_interactor=galaxy_interactor, | |
| 262 test_history=test_history, | |
| 263 log=log, | |
| 264 tool_test_results=all_test_results, | |
| 265 tests_passed=tests_passed, | |
| 266 test_exceptions=test_exceptions, | |
| 267 ) | |
| 268 finally: | |
| 269 # Always write report, even if test was cancelled. | |
| 270 try: | |
| 271 executor.shutdown(wait=True) | |
| 272 except KeyboardInterrupt: | |
| 273 executor._threads.clear() | |
| 274 thread._threads_queues.clear() | |
| 275 n_passed = len(tests_passed) | |
| 276 n_failed = len(test_exceptions) | |
| 277 report_obj = { | |
| 278 'version': '0.1', | |
| 279 'suitename': 'Ephemeris tool tests targeting %s' % self.gi.base_url, | |
| 280 'results': { | |
| 281 'total': n_passed + n_failed, | |
| 282 'errors': n_failed, | |
| 283 'failures': 0, | |
| 284 'skips': 0, | |
| 285 }, | |
| 286 'tests': sorted(all_test_results, key=lambda el: el['id']), | |
| 287 } | |
| 288 with open(test_json, "w") as f: | |
| 289 json.dump(report_obj, f) | |
| 290 if log: | |
| 291 log.info("Report written to '%s'", os.path.abspath(test_json)) | |
| 292 log.info("Passed tool tests ({0}): {1}".format( | |
| 293 n_passed, | |
| 294 [t for t in tests_passed]) | |
| 295 ) | |
| 296 log.info("Failed tool tests ({0}): {1}".format( | |
| 297 n_failed, | |
| 298 [t[0] for t in test_exceptions]) | |
| 299 ) | |
| 300 log.info("Total tool test time: {0}".format(dt.datetime.now() - tool_test_start)) | |
| 301 | |
| 302 def _get_interactor(self, test_user, test_user_api_key): | |
| 303 if test_user_api_key is None: | |
| 304 whoami = self.gi.make_get_request(self.gi.url + "/whoami").json() | |
| 305 if whoami is not None: | |
| 306 test_user_api_key = self.gi.key | |
| 307 galaxy_interactor_kwds = { | |
| 308 "galaxy_url": re.sub('/api', '', self.gi.url), | |
| 309 "master_api_key": self.gi.key, | |
| 310 "api_key": test_user_api_key, # TODO | |
| 311 "keep_outputs_dir": '', | |
| 312 } | |
| 313 if test_user_api_key is None: | |
| 314 galaxy_interactor_kwds["test_user"] = test_user | |
| 315 galaxy_interactor = GalaxyInteractorApi(**galaxy_interactor_kwds) | |
| 316 return galaxy_interactor | |
| 317 | |
| 318 @staticmethod | |
| 319 def _test_tool(executor, | |
| 320 tool, | |
| 321 galaxy_interactor, | |
| 322 tool_test_results, | |
| 323 tests_passed, | |
| 324 test_exceptions, | |
| 325 log, | |
| 326 test_history=None, | |
| 327 ): | |
| 328 if test_history is None: | |
| 329 test_history = galaxy_interactor.new_history() | |
| 330 tool_id = tool["id"] | |
| 331 tool_version = tool["version"] | |
| 332 try: | |
| 333 tool_test_dicts = galaxy_interactor.get_tool_tests(tool_id, tool_version=tool_version) | |
| 334 except Exception as e: | |
| 335 if log: | |
| 336 log.warning("Fetching test definition for tool '%s' failed", tool_id, exc_info=True) | |
| 337 test_exceptions.append((tool_id, e)) | |
| 338 Results = namedtuple("Results", ["tool_test_results", "tests_passed", "test_exceptions"]) | |
| 339 return Results(tool_test_results=tool_test_results, | |
| 340 tests_passed=tests_passed, | |
| 341 test_exceptions=test_exceptions) | |
| 342 test_indices = list(range(len(tool_test_dicts))) | |
| 343 | |
| 344 for test_index in test_indices: | |
| 345 test_id = tool_id + "-" + str(test_index) | |
| 346 | |
| 347 def run_test(index, test_id): | |
| 348 | |
| 349 def register(job_data): | |
| 350 tool_test_results.append({ | |
| 351 'id': test_id, | |
| 352 'has_data': True, | |
| 353 'data': job_data, | |
| 354 }) | |
| 355 | |
| 356 try: | |
| 357 if log: | |
| 358 log.info("Executing test '%s'", test_id) | |
| 359 verify_tool( | |
| 360 tool_id, galaxy_interactor, test_index=index, tool_version=tool_version, | |
| 361 register_job_data=register, quiet=True, test_history=test_history, | |
| 362 ) | |
| 363 tests_passed.append(test_id) | |
| 364 if log: | |
| 365 log.info("Test '%s' passed", test_id) | |
| 366 except Exception as e: | |
| 367 if log: | |
| 368 log.warning("Test '%s' failed", test_id, exc_info=True) | |
| 369 test_exceptions.append((test_id, e)) | |
| 370 | |
| 371 executor.submit(run_test, test_index, test_id) | |
| 372 | |
| 373 def install_repository_revision(self, repository, log): | |
| 374 default_err_msg = ('All repositories that you are attempting to install ' | |
| 375 'have been previously installed.') | |
| 376 start = dt.datetime.now() | |
| 377 try: | |
| 378 repository['new_tool_panel_section_label'] = repository.pop('tool_panel_section_label') | |
| 379 response = self.tool_shed_client.install_repository_revision(**repository) | |
| 380 if isinstance(response, dict) and response.get('status', None) == 'ok': | |
| 381 # This rare case happens if a repository is already installed but | |
| 382 # was not recognised as such in the above check. In such a | |
| 383 # case the return value looks like this: | |
| 384 # {u'status': u'ok', u'message': u'No repositories were | |
| 385 # installed, possibly because the selected repository has | |
| 386 # already been installed.'} | |
| 387 if log: | |
| 388 log.debug("\tRepository {0} is already installed.".format(repository['name'])) | |
| 389 if log: | |
| 390 log_repository_install_success( | |
| 391 repository=repository, | |
| 392 start=start, | |
| 393 log=log) | |
| 394 return "installed" | |
| 395 except (ConnectionError, requests.exceptions.ConnectionError) as e: | |
| 396 if default_err_msg in unicodify(e): | |
| 397 # THIS SHOULD NOT HAPPEN DUE TO THE CHECKS EARLIER | |
| 398 if log: | |
| 399 log.debug("\tRepository %s already installed (at revision %s)" % | |
| 400 (repository['name'], repository['changeset_revision'])) | |
| 401 return "skipped" | |
| 402 elif "504" in unicodify(e) or 'Connection aborted' in unicodify(e): | |
| 403 if log: | |
| 404 log.debug("Timeout during install of %s, extending wait to 1h", repository['name']) | |
| 405 success = self.wait_for_install(repository=repository, log=log, timeout=3600) | |
| 406 if success: | |
| 407 if log: | |
| 408 log_repository_install_success( | |
| 409 repository=repository, | |
| 410 start=start, | |
| 411 log=log) | |
| 412 return "installed" | |
| 413 else: | |
| 414 if log: | |
| 415 log_repository_install_error( | |
| 416 repository=repository, | |
| 417 start=start, msg=e.body, | |
| 418 log=log) | |
| 419 return "error" | |
| 420 else: | |
| 421 if log: | |
| 422 log_repository_install_error( | |
| 423 repository=repository, | |
| 424 start=start, msg=e.body, | |
| 425 log=log) | |
| 426 return "error" | |
| 427 | |
| 428 def wait_for_install(self, repository, log=None, timeout=3600): | |
| 429 """ | |
| 430 If nginx times out, we look into the list of installed repositories | |
| 431 and try to determine if a repository of the same namer/owner is still installing. | |
| 432 Returns True if install finished successfully, | |
| 433 returns False when timeout is exceeded or installation has failed. | |
| 434 """ | |
| 435 # We request a repository revision, but Galaxy may decide to install the next downloable revision. | |
| 436 # This ensures we have a revision to track, and if not, finds the revision that is actually being installed | |
| 437 name = repository['name'] | |
| 438 owner = repository['owner'] | |
| 439 changeset_revision = repository['changeset_revision'] | |
| 440 installed_repos = self.tool_shed_client.get_repositories() | |
| 441 non_terminal = [r for r in installed_repos if r['name'] == name and r['owner'] == owner and r['status'] in NON_TERMINAL_REPOSITORY_STATES] | |
| 442 assert len(non_terminal) > 0, "Repository '%s' from owner '%s' not in currently installling Repositories" % (name, owner) | |
| 443 installing_repo_id = None | |
| 444 if len(non_terminal) == 1: | |
| 445 # Unambiguous, we wait for this repo | |
| 446 installing_repo_id = non_terminal[0]['id'] | |
| 447 if len(non_terminal) > 1: | |
| 448 # More than one repo with the requested name and owner in installing status. | |
| 449 # If any repo is of the requested changeset revision we wait for this repo. | |
| 450 for installing_repo in non_terminal: | |
| 451 if installing_repo['changeset_revision'] == changeset_revision: | |
| 452 installing_repo_id = installing_repo['id'] | |
| 453 break | |
| 454 if not installing_repo_id: | |
| 455 # We may have a repo that is permanently in a non-terminal state (e.g because of restart during installation). | |
| 456 # Raise an exception and continue with the remaining repos. | |
| 457 msg = "Multiple repositories for name '%s', owner '%s' found in non-terminal states. Please uninstall all non-terminal repositories." | |
| 458 raise AssertionError(msg % (name, owner)) | |
| 459 start = dt.datetime.now() | |
| 460 while (dt.datetime.now() - start) < dt.timedelta(seconds=timeout): | |
| 461 try: | |
| 462 installed_repo = self.tool_shed_client.show_repository(installing_repo_id) | |
| 463 status = installed_repo['status'] | |
| 464 if status == 'Installed': | |
| 465 return True | |
| 466 elif status == 'Error': | |
| 467 return False | |
| 468 elif status in NON_TERMINAL_REPOSITORY_STATES: | |
| 469 time.sleep(10) | |
| 470 else: | |
| 471 raise AssertionError("Repository name '%s', owner '%s' in unknown status '%s'" % (name, owner, status)) | |
| 472 except ConnectionError as e: | |
| 473 if log: | |
| 474 log.warning('Failed to get repositories list: %s', unicodify(e)) | |
| 475 time.sleep(10) | |
| 476 return False | |
| 477 | |
| 478 | |
| 479 def log_repository_install_error(repository, start, msg, log): | |
| 480 """ | |
| 481 Log failed repository installations. Return a dictionary with information | |
| 482 """ | |
| 483 end = dt.datetime.now() | |
| 484 log.error( | |
| 485 "\t* Error installing a repository (after %s seconds)! Name: %s," "owner: %s, ""revision: %s, error: %s", | |
| 486 str(end - start), | |
| 487 repository.get('name', ""), | |
| 488 repository.get('owner', ""), | |
| 489 repository.get('changeset_revision', ""), | |
| 490 msg) | |
| 491 | |
| 492 | |
| 493 def log_repository_install_success(repository, start, log): | |
| 494 """ | |
| 495 Log successful repository installation. | |
| 496 Repositories that finish in error still count as successful installs currently. | |
| 497 """ | |
| 498 end = dt.datetime.now() | |
| 499 log.debug( | |
| 500 "\trepository %s installed successfully (in %s) at revision %s" % ( | |
| 501 repository['name'], | |
| 502 str(end - start), | |
| 503 repository['changeset_revision'] | |
| 504 ) | |
| 505 ) | |
| 506 | |
| 507 | |
| 508 def log_repository_install_skip(repository, counter, total_num_repositories, log): | |
| 509 log.debug( | |
| 510 "({0}/{1}) repository {2} already installed at revision {3}. Skipping." | |
| 511 .format( | |
| 512 counter, | |
| 513 total_num_repositories, | |
| 514 repository['name'], | |
| 515 repository['changeset_revision'] | |
| 516 ) | |
| 517 ) | |
| 518 | |
| 519 | |
| 520 def log_repository_install_start(repository, counter, total_num_repositories, installation_start, log): | |
| 521 log.debug( | |
| 522 '(%s/%s) Installing repository %s from %s to section "%s" at revision %s (TRT: %s)' % ( | |
| 523 counter, total_num_repositories, | |
| 524 repository['name'], | |
| 525 repository['owner'], | |
| 526 repository['tool_panel_section_id'] or repository['tool_panel_section_label'], | |
| 527 repository['changeset_revision'], | |
| 528 dt.datetime.now() - installation_start | |
| 529 ) | |
| 530 ) | |
| 531 | |
| 532 | |
| 533 def args_to_repos(args): | |
| 534 if args.tool_list_file: | |
| 535 tool_list = load_yaml_file(args.tool_list_file) | |
| 536 repos = tool_list['tools'] | |
| 537 elif args.tool_yaml: | |
| 538 repos = [yaml.safe_load(args.tool_yaml)] | |
| 539 elif args.name and args.owner: | |
| 540 repo = dict( | |
| 541 owner=args.owner, | |
| 542 name=args.name, | |
| 543 tool_panel_section_id=args.tool_panel_section_id, | |
| 544 tool_panel_section_label=args.tool_panel_section_label, | |
| 545 revisions=args.revisions | |
| 546 ) | |
| 547 if args.tool_shed_url: | |
| 548 repo["tool_shed_url"] = args.tool_shed_url | |
| 549 repos = [repo] | |
| 550 else: | |
| 551 repos = [] | |
| 552 return repos | |
| 553 | |
| 554 | |
| 555 def main(): | |
| 556 disable_external_library_logging() | |
| 557 args = parser().parse_args() | |
| 558 log = setup_global_logger(name=__name__, log_file=args.log_file) | |
| 559 gi = get_galaxy_connection(args, file=args.tool_list_file, log=log, login_required=True) | |
| 560 install_repository_manager = InstallRepositoryManager(gi) | |
| 561 | |
| 562 repos = args_to_repos(args) | |
| 563 | |
| 564 if args.tool_list_file: | |
| 565 tool_list = load_yaml_file(args.tool_list_file) | |
| 566 else: | |
| 567 tool_list = dict() | |
| 568 | |
| 569 # Get some of the other installation arguments | |
| 570 kwargs = dict( | |
| 571 default_install_tool_dependencies=tool_list.get("install_tool_dependencies") or getattr(args, | |
| 572 "install_tool_dependencies", | |
| 573 False), | |
| 574 default_install_repository_dependencies=tool_list.get("install_repository_dependencies") or getattr(args, | |
| 575 "install_repository_dependencies", | |
| 576 False), | |
| 577 default_install_resolver_dependencies=tool_list.get("install_resolver_dependencies") or getattr(args, | |
| 578 "install_resolver_dependencies", | |
| 579 False)) | |
| 580 | |
| 581 # Start installing/updating and store the results in install_results. | |
| 582 # Or do testing if the action is `test` | |
| 583 install_results = None | |
| 584 if args.action == "update": | |
| 585 install_results = install_repository_manager.update_repositories( | |
| 586 repositories=repos, | |
| 587 log=log, | |
| 588 **kwargs) | |
| 589 elif args.action == "install": | |
| 590 install_results = install_repository_manager.install_repositories( | |
| 591 repos, | |
| 592 log=log, | |
| 593 force_latest_revision=args.force_latest_revision, | |
| 594 **kwargs) | |
| 595 elif args.action == "test": | |
| 596 install_repository_manager.test_tools( | |
| 597 test_json=args.test_json, | |
| 598 repositories=repos, | |
| 599 log=log, | |
| 600 test_user_api_key=args.test_user_api_key, | |
| 601 test_user=args.test_user, | |
| 602 parallel_tests=args.parallel_tests, | |
| 603 ) | |
| 604 else: | |
| 605 raise NotImplementedError("This point in the code should not be reached. Please contact the developers.") | |
| 606 | |
| 607 # Run tests on the install results if required. | |
| 608 if install_results and args.test or args.test_existing: | |
| 609 to_be_tested_repositories = install_results.installed_repositories | |
| 610 if args.test_existing: | |
| 611 to_be_tested_repositories.extend(install_results.skipped_repositories) | |
| 612 if to_be_tested_repositories: | |
| 613 install_repository_manager.test_tools( | |
| 614 test_json=args.test_json, | |
| 615 repositories=to_be_tested_repositories, | |
| 616 log=log, | |
| 617 test_user_api_key=args.test_user_api_key, | |
| 618 test_user=args.test_user, | |
| 619 parallel_tests=args.parallel_tests, | |
| 620 ) | |
| 621 | |
| 622 | |
| 623 if __name__ == "__main__": | |
| 624 main() |
