def toolshed_to_dict(options): ts = ToolShedInstance(url=options.url_toolshed) ts.verify = False repositories = ts.repositories.get_repositories() listrepos = [] for repo in repositories: revisions = ts.repositories.get_ordered_installable_revisions(repo['name'], repo['owner']) if len(revisions) > 0: revision = revisions[-1:] listrepos.append({'name': repo['name'], 'owner': repo['owner'], 'tool_panel_section_id': '', 'tool_shed_url': options.url_toolshed, 'tool_panel_section_label': '', 'revisions': revision, 'verify_ssl': False}) listrepos = set_section_id(ts, listrepos, options.url_galaxy_ref) dict_repos = {'api_key': options.adminkey_galaxy_target, 'galaxy_instance': options.url_galaxy_target, 'tools': listrepos} write_yaml(dict_repos, options.output_yaml)
def _tools_to_install(owners=['devteam', 'iuc'], return_formatted=False): """ This is mostly a convenience method to jumpstart the tools list. Get a list of tools that should be installed. This list is composed by including all the non-package tools that are owned by `owners` from the Main Tool Shed. If `return_formatted` is set, return a list of dicts that have been formatted according to the required input file for installing tools (see other methods). *Note*: there is no way to programatically get a category a tool belongs in a Tool Shed so the returned list cannot simply be used as the input file but (manual!?!) adjustment is necessesary to provide tool category for each tool. """ tsi = ToolShedInstance('https://toolshed.g2.bx.psu.edu') repos = tsi.repositories.get_repositories() tti = [] # tools to install for repo in repos: if repo['owner'] in owners and 'package' not in repo['name']: if return_formatted: repo = { 'name': repo['name'], 'owner': repo['owner'], 'tool_shed_url': 'https://toolshed.g2.bx.psu.edu', 'tool_panel_section_id': '' } tti.append(repo) return tti
def get_new_revision(tool, repos, trusted_owners): matching_owners = [o for o in trusted_owners if tool['owner'] == o['owner']] if not matching_owners: return [owner] = matching_owners blacklist = owner.get('blacklist', []) if isinstance(owner, dict) else [] blacklisted_revisions = [b.get('revision', 'all') for b in blacklist if b.get('name') == tool['name']] if 'all' in blacklisted_revisions: return toolshed = ToolShedInstance(url='https://' + tool['tool_shed_url']) repo_client = ToolShedRepositoryClient(toolshed) matching_repos = [r for r in repos if r['name'] == tool['name'] and r['owner'] == tool['owner']] if not matching_repos: return try: latest_revision = repo_client.get_ordered_installable_revisions(tool['name'], tool['owner'])[-1] except Exception as e: print('Skipping %s. Error querying tool revisions: %s' % (tool['name'], str(e))) return blacklisted = latest_revision in blacklisted_revisions installed = latest_revision in [r['changeset_revision'] for r in matching_repos] if blacklisted or installed: return def get_version(revision): try: data = repo_client.get_repository_revision_install_info(tool['name'], tool['owner'], revision) repository, metadata, install_info = data version = metadata['valid_tools'][0]['version'] return version except Exception as e: print('Skipping %s. Error querying tool revisions: %s' % (tool['name'], str(e))) latest_revision_version = get_version(latest_revision) installed_versions = [get_version(r['changeset_revision']) for r in matching_repos] if latest_revision_version is None or None in installed_versions: # skip on errors from get_version return skip_tests = latest_revision_version in installed_versions if skip_tests: print('Latest revision %s of %s has version %s already installed on GA. Skipping tests for this tool ' % ( latest_revision, tool['name'], latest_revision_version )) return {'revisions': [latest_revision], 'skip_tests': skip_tests}
def check_installable(tools): # Go through all tool_shed_url values in request files and run get_ordered_installable_revisions # to ascertain whether the specified revision is installable errors = [] tools_by_shed = {} for tool in tools: if 'tool_shed_url' not in tool.keys(): tool.update({'tool_shed_url': default_tool_shed}) if tool['tool_shed_url'] in tools_by_shed.keys(): tools_by_shed[tool['tool_shed_url']].append(tool) else: tools_by_shed[tool['tool_shed_url']] = [tool] for shed in tools_by_shed.keys(): url = 'https://%s' % shed toolshed = ToolShedInstance(url=url) repo_client = ToolShedRepositoryClient(toolshed) for counter, tool in enumerate(tools_by_shed[shed]): try: installable_revisions = repo_client.get_ordered_installable_revisions( tool['name'], tool['owner']) if counter == 0: sys.stderr.write('Connected to toolshed %s\n' % url) installable_revisions = [ str(r) for r in installable_revisions ][::-1] # un-unicode and list most recent first if not installable_revisions: errors.append( 'Tool with name: %s, owner: %s and tool_shed_url: %s has no installable revisions' % (tool['name'], tool['owner'], shed)) continue except Exception as e: raise Exception(e) if 'revisions' in tool.keys( ): # Check that requested revisions are installable for revision in tool['revisions']: if revision not in installable_revisions: errors.append('%s revision %s is not installable' % (tool['name'], revision)) else: tool.update({'revisions': [installable_revisions[0]]}) return errors
def get_changeset_revisions(repository, force_latest_revision=False): """ Select the correct changeset revision for a repository, and make sure the repository exists (i.e a request to the tool shed with name and owner returns a list of revisions). Return repository or None, if the repository could not be found on the specified tool shed. """ # Do not connect to the internet when not necessary if repository.get('changeset_revision') is None or force_latest_revision: ts = ToolShedInstance(url=repository['tool_shed_url']) # Get the set revision or set it to the latest installable revision installable_revisions = ts.repositories.get_ordered_installable_revisions( repository['name'], repository['owner']) if not installable_revisions: # raise LookupError( "Repo does not exist in tool shed: {0}".format(repository)) repository['changeset_revision'] = installable_revisions[-1] return repository
def get_changeset_revision(self, repository): """ Select the correct changeset revision for a repository, and make sure the repository exists (i.e a request to the tool shed with name and owner returns a list of revisions). Return repository or None, if the repository could not be found on the specified tool shed. """ ts = ToolShedInstance(url=repository['tool_shed_url']) # Get the set revision or set it to the latest installable revision installable_revisions = ts.repositories.get_ordered_installable_revisions( repository['name'], repository['owner']) if not installable_revisions: # Repo does not exist in tool shed now = dt.datetime.now() log_repository_install_error( repository, start=now, msg="Repository does not exist in tool shed", errored_repositories=self.errored_repositories) return None if not repository['changeset_revision'] or self.force_latest_revision: repository['changeset_revision'] = installable_revisions[-1] return repository
def get_toolshed_instance(url): if not url.startswith('https://'): url = 'https://' + url return ToolShedInstance(url=url)
def main(): try: tool_list_file = 'tool_shed_tool_list.yaml' # Load tool list with open(tool_list_file, 'r') as f: tl = yaml.load(f) r_info = tl['tools'] responses = [] counter = 1 total_num_tools = len(r_info) default_err_msg = 'All repositories that you are attempting to install have been previously installed.' gInstance = GalaxyInstance(url=GALAXY_URL, key=API_KEY) tsc = ToolShedClient(gInstance) tool_set = tsc.get_repositories() tool_name_list = [x['name'] for x in tool_set] for r in r_info: #if r['name'] in tool_name_list: # print '%s already installed. skipping...' % r['name'] # continue if 'install_tool_dependencies' not in r: r['install_tool_dependencies'] = True if 'install_repository_dependencies' not in r: r['install_repository_dependencies'] = True if 'tool_shed_url' not in r: r['tool_shed_url'] = 'http://toolshed.g2.bx.psu.edu' ts = ToolShedInstance(url=r['tool_shed_url']) if 'revision' not in r: r['revision'] = ts.repositories.get_ordered_installable_revisions( r['name'], r['owner'])[-1] start = dt.datetime.now() print '\n(%s/%s) Installing tool %s from %s to section %s (revision:%s depend-install:%s depend_repo_install:%s) ' % ( counter, total_num_tools, r['name'], r['owner'], r['tool_panel_section_id'], r['revision'], r['install_tool_dependencies'], r['install_repository_dependencies']) try: response = tsc.install_repository_revision( r['tool_shed_url'], r['name'], r['owner'], r['revision'], r['install_tool_dependencies'], r['install_repository_dependencies'], r['tool_panel_section_id']) # new_tool_panel_section_label='API tests') except: print 'failed installing %s tool.' % r['name'] info = sys.exc_info() err_msg = '>>>>>> This tool already installed in Galaxy.' if '"err_code": 400008' in str( info[1]) else str(info[1]) print err_msg else: print 'successful %s installation.' % r['name'] end = dt.datetime.now() counter += 1 # print responses print "\r\nAll tools listed in %s have been installed." % tool_list_file except: info = sys.exc_info() tbinfo = traceback.format_tb(info[2]) print 'Error Info...'.ljust(80, '=') for tbi in tbinfo: print tbi print ' %s' % str(info[1]) print '\n'.rjust(85, '=') sys.exit(1)
def get_new_revision(tool, repos, trusted_owners): matching_owners = [ o for o in trusted_owners if tool['owner'] == o['owner'] ] if not matching_owners: return [owner] = matching_owners skipped_tools = owner.get('skip_tools', []) if isinstance(owner, dict) else [] skipped_revisions = [ st.get('revision', 'all') for st in skipped_tools if st.get('name') == tool['name'] ] if 'all' in skipped_revisions: return matching_repos = [ r for r in repos if r['name'] == tool['name'] and r['owner'] == tool['owner'] ] if not matching_repos: return toolshed = ToolShedInstance(url='https://' + tool['tool_shed_url']) try: latest_revision = toolshed.repositories.get_ordered_installable_revisions( tool['name'], tool['owner'])[-1] except Exception as e: print('Skipping %s. Error querying tool revisions: %s' % (tool['name'], str(e))) return skip_this_tool = latest_revision in skipped_revisions installed = latest_revision in [ r['changeset_revision'] for r in matching_repos ] if skip_this_tool or installed: return # Check whether the new revision updates tool versions on Galaxy. If it does not, it will be installed # in place of the current latest revision on Galaxy and needs to be flagged as a version update so that # it will not be autoremoved in the instance of failing tests def get_installable_revision_for_revision(revision): # make a call to the toolshed to get a large blob of information about the repository # that includes the hash of the corresponding installable revision. try: data = toolshed.repositories.get_repository_revision_install_info( tool['name'], tool['owner'], revision) repository, metadata, install_info = data desc, clone_url, installable_revision, ctx_rev, owner, repo_deps, tool_deps = install_info[ tool['name']] except Exception as e: # KeyError, ValueError, bioblend.ConnectionError, return None print( 'Unexpected result querying install info for %s, %s, %s, returning None' % (tool['name'], tool['owner'], revision)) return None return installable_revision latest_installed_revision = sorted(matching_repos, key=lambda x: int(x['ctx_rev']), reverse=True)[0]['changeset_revision'] latest_installed_revision_installable_revision = get_installable_revision_for_revision( latest_installed_revision) if latest_installed_revision_installable_revision is None: return # skip on errors from revision query version_update = latest_installed_revision_installable_revision == latest_revision if version_update: print( 'Latest revision %s of %s is a version update of installed revision %s. Skipping tests for this tool ' % (latest_revision, tool['name'], latest_installed_revision)) return {'revisions': [latest_revision], 'version_update': version_update}
def install_tools(options): """ Parse the default input file and proceed to install listed tools. :type options: OptionParser object :param options: command line arguments parsed by OptionParser """ istart = dt.datetime.now() tool_list_file = options.tool_list_file tl = load_input_file(tool_list_file) # Input file contents tools_info = tl['tools'] # The list of tools to install galaxy_url = options.galaxy_url or tl['galaxy_instance'] api_key = options.api_key or tl['api_key'] gi = galaxy_instance(galaxy_url, api_key) tsc = tool_shed_client(gi) itl = installed_revisions(tsc) # installed tools list responses = [] errored_tools = [] skipped_tools = [] counter = 0 tools_info = _flatten_tools_info(tools_info) total_num_tools = len(tools_info) default_err_msg = ('All repositories that you are attempting to install ' 'have been previously installed.') # Process each tool/revision: check if it's already installed or install it for tool_info in tools_info: counter += 1 already_installed = False # Reset the flag tool = {} # Payload for the tool we are installing # Copy required `tool_info` keys into the `tool` dict tool['name'] = tool_info.get('name', None) tool['owner'] = tool_info.get('owner', None) tool['tool_panel_section_id'] = tool_info.get('tool_panel_section_id', None) # Check if all required tool sections have been provided; if not, skip # the installation of this tool. Note that data managers are an exception # but they must contain string `data_manager` within the tool name. if not tool['name'] or not tool['owner'] or ( not tool['tool_panel_section_id'] and 'data_manager' not in tool.get('name', '')): log.error( "Missing required tool info field; skipping [name: '{0}'; " "owner: '{1}'; tool_panel_section_id: '{2}']".format( tool['name'], tool['owner'], tool['tool_panel_section_id'])) continue # Populate fields that can optionally be provided (if not provided, set # defaults). tool['install_tool_dependencies'] = \ tool_info.get('install_tool_dependencies', True) tool['install_repository_dependencies'] = \ tool_info.get('install_repository_dependencies', True) tool['tool_shed_url'] = \ tool_info.get('tool_shed_url', 'https://toolshed.g2.bx.psu.edu/') ts = ToolShedInstance(url=tool['tool_shed_url']) # Get the set revision or set it to the latest installable revision tool['revision'] = tool_info.get( 'revision', ts.repositories.get_ordered_installable_revisions( tool['name'], tool['owner'])[-1]) # Check if the tool@revision is already installed for installed in itl: if the_same_tool( installed, tool) and installed['revision'] == tool['revision']: log.debug( "({0}/{1}) Tool {2} already installed at revision {3} " "(Is latest? {4}). Skipping...".format( counter, total_num_tools, tool['name'], tool['revision'], installed['latest'])) skipped_tools.append({ 'name': tool['name'], 'owner': tool['owner'], 'revision': tool['revision'] }) already_installed = True break if not already_installed: # Initate tool installation start = dt.datetime.now() log.debug('(%s/%s) Installing tool %s from %s to section %s at ' 'revision %s (TRT: %s)' % (counter, total_num_tools, tool['name'], tool['owner'], tool['tool_panel_section_id'], tool['revision'], dt.datetime.now() - istart)) try: response = tsc.install_repository_revision( tool['tool_shed_url'], tool['name'], tool['owner'], tool['revision'], tool['install_tool_dependencies'], tool['install_repository_dependencies'], tool['tool_panel_section_id']) tool_id = None tool_status = None if len(response) > 0: tool_id = response[0].get('id', None) tool_status = response[0].get('status', None) if tool_id and tool_status: # Possibly an infinite loop here. Introduce a kick-out counter? log.debug("\tTool installing", extra={'same_line': True}) while tool_status not in ['Installed', 'Error']: log.debug("", extra={'same_line': True}) time.sleep(10) tool_status = update_tool_status(tsc, tool_id) end = dt.datetime.now() log.debug( "\tTool %s installed successfully (in %s) at revision %s" % (tool['name'], str(end - start), tool['revision'])) else: end = dt.datetime.now() log.error( "\tCould not retrieve tool status for {0}".format( tool['name'])) except ConnectionError, e: response = None end = dt.datetime.now() if default_err_msg in e.body: log.debug("\tTool %s already installed (at revision %s)" % (tool['name'], tool['revision'])) else: log.error( "\t* Error installing a tool (after %s)! Name: %s," "owner: %s, revision: %s, error: %s" % (tool['name'], str(end - start), tool['owner'], tool['revision'], e.body)) errored_tools.append({ 'name': tool['name'], 'owner': tool['owner'], 'revision': tool['revision'], 'error': e.body }) outcome = { 'tool': tool, 'response': response, 'duration': str(end - start) } responses.append(outcome)
def install_tools(options): """ Parse the default input file and proceed to install listed tools. :type options: OptionParser object :param options: command line arguments parsed by OptionParser """ istart = dt.datetime.now() tool_list_file = options.tool_list_file if tool_list_file: tl = load_input_file(tool_list_file) # Input file contents tools_info = tl['tools'] # The list of tools to install elif options.tool_yaml: tools_info = [yaml.load(options.tool_yaml)] else: # An individual tool was specified on the command line tools_info = [{"owner": options.owner, "name": options.name, "tool_panel_section_id": options.tool_panel_section_id, "tool_shed_url": options.tool_shed_url or MTS}] galaxy_url = options.galaxy_url or tl.get('galaxy_instance') api_key = options.api_key or tl.get('api_key') gi = galaxy_instance(galaxy_url, api_key) tsc = tool_shed_client(gi) itl = installed_tool_revisions(gi) # installed tools list responses = [] errored_tools = [] skipped_tools = [] installed_tools = [] counter = 0 tools_info = _flatten_tools_info(tools_info) total_num_tools = len(tools_info) default_err_msg = ('All repositories that you are attempting to install ' 'have been previously installed.') # Process each tool/revision: check if it's already installed or install it for tool_info in tools_info: counter += 1 already_installed = False # Reset the flag tool = {} # Payload for the tool we are installing # Copy required `tool_info` keys into the `tool` dict tool['name'] = tool_info.get('name', None) tool['owner'] = tool_info.get('owner', None) tool['tool_panel_section_id'] = tool_info.get('tool_panel_section_id', None) tool['tool_panel_section_label'] = tool_info.get('tool_panel_section_label', None) # Check if all required tool sections have been provided; if not, skip # the installation of this tool. Note that data managers are an exception # but they must contain string `data_manager` within the tool name. if not tool['name'] or not tool['owner'] or (not (tool['tool_panel_section_id'] or tool['tool_panel_section_label']) and 'data_manager' not in tool.get('name', '')): log.error("Missing required tool info field; skipping [name: '{0}'; " "owner: '{1}'; tool_panel_section_id: '{2}']; tool_panel_section_label: '{3}'" .format(tool['name'], tool['owner'], tool['tool_panel_section_id'], tool['tool_panel_section_label'])) continue # Populate fields that can optionally be provided (if not provided, set # defaults). tool['install_tool_dependencies'] = \ tool_info.get('install_tool_dependencies', True) tool['install_repository_dependencies'] = \ tool_info.get('install_repository_dependencies', True) tool['tool_shed_url'] = \ tool_info.get('tool_shed_url', MTS) ts = ToolShedInstance(url=tool['tool_shed_url']) # Get the set revision or set it to the latest installable revision tool['revision'] = tool_info.get('revision', ts.repositories. get_ordered_installable_revisions (tool['name'], tool['owner'])[-1]) # Check if the tool@revision is already installed for installed in itl: if the_same_tool(installed, tool) and tool['revision'] in installed['revisions']: log.debug("({0}/{1}) Tool {2} already installed at revision {3}. Skipping." .format(counter, total_num_tools, tool['name'], tool['revision'])) skipped_tools.append({'name': tool['name'], 'owner': tool['owner'], 'revision': tool['revision']}) already_installed = True break if not already_installed: # Initate tool installation start = dt.datetime.now() log.debug('(%s/%s) Installing tool %s from %s to section "%s" at ' 'revision %s (TRT: %s)' % (counter, total_num_tools, tool['name'], tool['owner'], tool['tool_panel_section_id'] or tool['tool_panel_section_label'], tool['revision'], dt.datetime.now() - istart)) try: response = install_repository_revision(tool, tsc) end = dt.datetime.now() log_tool_install_success(tool=tool, start=start, end=end, installed_tools=installed_tools) except ConnectionError, e: response = None end = dt.datetime.now() if default_err_msg in e.body: log.debug("\tTool %s already installed (at revision %s)" % (tool['name'], tool['revision'])) else: if e.message == "Unexpected response from galaxy: 504": log.debug("Timeout during install of %s, extending wait to 1h" % ((tool['name']))) success = wait_for_install(tool=tool, tsc=tsc, timeout=3600) if success: log_tool_install_success(tool=tool, start=start, end=end, installed_tools=installed_tools) response = e.body # TODO: find a better response message else: log_tool_install_error(tool=tool, start=start, end=end, e=e, errored_tools=errored_tools) else: log_tool_install_error(tool=tool, start=start, end=end, e=e, errored_tools=errored_tools) outcome = {'tool': tool, 'response': response, 'duration': str(end - start)} responses.append(outcome)
def install_tools(options): """ Parse the default input file and proceed to install listed tools. :type options: OptionParser object :param options: command line arguments parsed by OptionParser """ istart = dt.datetime.now() tool_list_file = options.tool_list_file tl = load_input_file(tool_list_file) # Input file contents tools_info = tl['tools'] # The list of tools to install galaxy_url = options.galaxy_url or tl['galaxy_instance'] api_key = options.api_key or tl['api_key'] gi = galaxy_instance(galaxy_url, api_key) tsc = tool_shed_client(gi) itl = installed_tools(tsc) # installed tools list responses = [] errored_tools = [] skipped_tools = [] counter = 1 total_num_tools = len(tools_info) default_err_msg = 'All repositories that you are attempting to install have been previously installed.' for r in tools_info: already_installed = False if 'install_tool_dependencies' not in r: r['install_tool_dependencies'] = True if 'install_repository_dependencies' not in r: r['install_repository_dependencies'] = True if 'tool_shed_url' not in r: r['tool_shed_url'] = 'https://toolshed.g2.bx.psu.edu' # Check if the tool is already installed for it in itl: if r['name'] == it['name'] and r['owner'] == it['owner'] and \ it['tool_shed'] in r['tool_shed_url'] and it['latest']: log.debug( "({0}/{1}) Tool {2} already installed. Skipping...".format( counter, total_num_tools, r['name'])) skipped_tools.append({'name': r['name'], 'owner': r['owner']}) already_installed = True break if not already_installed: # Set the payload ts = ToolShedInstance(url=r['tool_shed_url']) if 'revision' not in r: r['revision'] = ts.repositories.get_ordered_installable_revisions( r['name'], r['owner'])[-1] # Initate tool installation start = dt.datetime.now() log.debug('(%s/%s) Installing tool %s from %s to section %s' % (counter, total_num_tools, r['name'], r['owner'], r.get('tool_panel_section_id', 'N/A'))) try: response = tsc.install_repository_revision( r['tool_shed_url'], r['name'], r['owner'], r['revision'], r['install_tool_dependencies'], r['install_repository_dependencies'], r.get('tool_panel_section_id', '')) tool_id = None tool_status = None if len(response) > 0: tool_id = response[0].get('id', None) tool_status = response[0].get('status', None) if tool_id and tool_status: # Possibly an infinite loop here. Introduce a kick-out counter? log.debug("\tTool installing", extra={'same_line': True}) while tool_status not in ['Installed', 'Error']: log.debug("", extra={'same_line': True}) time.sleep(10) tool_status = update_tool_status(tsc, tool_id) end = dt.datetime.now() log.debug( "\tTool %s installed successfully (in %s) at revision %s" % (r['name'], str(end - start), r['revision'])) else: end = dt.datetime.now() log.error( "\tCould not retrieve tool status for {0}".format( r['name'])) except ConnectionError, e: response = None end = dt.datetime.now() if default_err_msg in e.body: log.debug("\tTool %s already installed (at revision %s)" % (r['name'], r['revision'])) else: log.error( "\t* Error installing a tool (after %s)! Name: %s," "owner: %s, revision: %s, error: %s" % (r['name'], str(end - start), r['owner'], r['revision'], e.body)) errored_tools.append({ 'name': r['name'], 'owner': r['owner'], 'revision': r['revision'], 'error': e.body }) outcome = { 'tool': r, 'response': response, 'duration': str(end - start) } responses.append(outcome) counter += 1
gi = GalaxyInstance(tl['galaxy_instance'], tl['api_key']) r_info = tl['tools'] responses = [] counter = 1 total_num_tools = len(r_info) default_err_msg = 'All repositories that you are attempting to install have been previously installed.' for r in r_info: if 'install_tool_dependencies' not in r: r['install_tool_dependencies'] = True if 'install_repository_dependencies' not in r: r['install_repository_dependencies'] = True if 'tool_shed_url' not in r: r['tool_shed_url'] = 'http://toolshed.g2.bx.psu.edu' ts = ToolShedInstance(url=r['tool_shed_url']) if 'revision' not in r: r['revision'] = ts.repositories.get_ordered_installable_revisions( r['name'], r['owner'])[-1] tsc = ToolShedClient(gi) start = dt.datetime.now() print '\n(%s/%s) Installing tool %s from %s to section %s' % (counter, total_num_tools, r['name'], r['owner'], r['tool_panel_section_id']) response = tsc.install_repository_revision(r['tool_shed_url'], r['name'], r['owner'], r['revision'], r['install_tool_dependencies'], r['install_repository_dependencies'], r['tool_panel_section_id']) # new_tool_panel_section_label='API tests') end = dt.datetime.now() if 'error' in response: if response['error'] == default_err_msg: