Esempio n. 1
0
 def get_repair_dict(self, repository):
     """
     Inspect the installed repository dependency hierarchy for a specified repository
     and attempt to make sure they are all properly installed as well as each repository's
     tool dependencies.  This method is called only from Galaxy when attempting to correct
     issues with an installed repository that has installation problems somewhere in its
     dependency hierarchy. Problems with dependencies that have never been installed
     cannot be resolved with a repair.
     """
     rdim = repository_dependency_manager.RepositoryDependencyInstallManager(
         self.app)
     tsr_ids = []
     repo_info_dicts = []
     tool_panel_section_keys = []
     repair_dict = {}
     irm = install_manager.InstallRepositoryManager(self.app)
     # Get a dictionary of all repositories upon which the contents of the current repository_metadata
     # record depend.
     repository_dependencies_dict = rdim.get_repository_dependencies_for_installed_tool_shed_repository(
         self.app, repository)
     if repository_dependencies_dict:
         # Generate the list of installed repositories from the information contained in the
         # repository_dependencies dictionary.
         installed_repositories = self.get_installed_repositories_from_repository_dependencies(
             repository_dependencies_dict)
         # Some repositories may have repository dependencies that are required to be installed before
         # the dependent repository, so we'll order the list of tsr_ids to ensure all repositories are
         # repaired in the required order.
         installed_repositories.append(repository)
         for installed_repository in installed_repositories:
             tsr_ids.append(
                 self.app.security.encode_id(installed_repository.id))
             repo_info_dict, tool_panel_section_key = self.get_repo_info_dict_for_repair(
                 rdim, installed_repository)
             tool_panel_section_keys.append(tool_panel_section_key)
             repo_info_dicts.append(repo_info_dict)
     else:
         # The received repository has no repository dependencies.
         tsr_ids.append(self.app.security.encode_id(repository.id))
         repo_info_dict, tool_panel_section_key = self.get_repo_info_dict_for_repair(
             rdim, repository)
         tool_panel_section_keys.append(tool_panel_section_key)
         repo_info_dicts.append(repo_info_dict)
     ordered_tsr_ids, ordered_repo_info_dicts, ordered_tool_panel_section_keys = \
         irm.order_components_for_installation( tsr_ids,
                                                repo_info_dicts,
                                                tool_panel_section_keys=tool_panel_section_keys )
     repair_dict['ordered_tsr_ids'] = ordered_tsr_ids
     repair_dict['ordered_repo_info_dicts'] = ordered_repo_info_dicts
     repair_dict[
         'ordered_tool_panel_section_keys'] = ordered_tool_panel_section_keys
     return repair_dict
class RepairRepositoryManager():
    def __init__(self, app):
        self.app = app

    def get_installed_repositories_from_repository_dependencies(
            self, repository_dependencies_dict):
        installed_repositories = []
        if repository_dependencies_dict and isinstance(
                repository_dependencies_dict, dict):
            for rd_key, rd_vals in repository_dependencies_dict.items():
                if rd_key in ['root_key', 'description']:
                    continue
                # rd_key is something like: 'http://localhost:9009__ESEP__package_rdkit_2012_12__ESEP__test__ESEP__d635ffb9c665__ESEP__True'
                # rd_val is something like: [['http://localhost:9009', 'package_numpy_1_7', 'test', 'cddd64ecd985', 'True']]
                repository_components_tuple = container_util.get_components_from_key(
                    rd_key)
                components_list = suc.extract_components_from_tuple(
                    repository_components_tuple)
                tool_shed, name, owner, changeset_revision = components_list[
                    0:4]
                installed_repository = suc.get_installed_repository(
                    self.app,
                    tool_shed=tool_shed,
                    name=name,
                    owner=owner,
                    changeset_revision=changeset_revision)
                if (installed_repository) and (installed_repository
                                               not in installed_repositories):
                    installed_repositories.append(installed_repository)
                for rd_val in rd_vals:
                    tool_shed, name, owner, changeset_revision = rd_val[0:4]
                    installed_repository = suc.get_installed_repository(
                        self.app,
                        tool_shed=tool_shed,
                        name=name,
                        owner=owner,
                        changeset_revision=changeset_revision)
                    if (installed_repository) and (
                            installed_repository
                            not in installed_repositories):
                        installed_repositories.append(installed_repository)
        return installed_repositories

    def get_repair_dict(self, repository):
        """
        Inspect the installed repository dependency hierarchy for a specified repository
        and attempt to make sure they are all properly installed as well as each repository's
        tool dependencies.  This method is called only from Galaxy when attempting to correct
        issues with an installed repository that has installation problems somewhere in its
        dependency hierarchy.
        """
        rdim = repository_dependency_manager.RepositoryDependencyInstallManager(
            self.app)
        tsr_ids = []
        repo_info_dicts = []
        tool_panel_section_keys = []
        repair_dict = {}
        irm = install_manager.InstallRepositoryManager(self.app)
        # Get a dictionary of all repositories upon which the contents of the current repository_metadata
        # record depend.
        repository_dependencies_dict = rdim.get_repository_dependencies_for_installed_tool_shed_repository(
            self.app, repository)
        if repository_dependencies_dict:
            # Generate the list of installed repositories from the information contained in the
            # repository_dependencies dictionary.
            installed_repositories = self.get_installed_repositories_from_repository_dependencies(
                repository_dependencies_dict)
            # Some repositories may have repository dependencies that are required to be installed before
            # the dependent repository, so we'll order the list of tsr_ids to ensure all repositories are
            # repaired in the required order.
            installed_repositories.append(repository)
            for installed_repository in installed_repositories:
                tsr_ids.append(
                    self.app.security.encode_id(installed_repository.id))
                repo_info_dict, tool_panel_section_key = self.get_repo_info_dict_for_repair(
                    rdim, installed_repository)
                tool_panel_section_keys.append(tool_panel_section_key)
                repo_info_dicts.append(repo_info_dict)
        else:
            # The received repository has no repository dependencies.
            tsr_ids.append(self.app.security.encode_id(repository.id))
            repo_info_dict, tool_panel_section_key = self.get_repo_info_dict_for_repair(
                rdim, repository)
            tool_panel_section_keys.append(tool_panel_section_key)
            repo_info_dicts.append(repo_info_dict)
        ordered_tsr_ids, ordered_repo_info_dicts, ordered_tool_panel_section_keys = \
            irm.order_components_for_installation( tsr_ids,
                                                   repo_info_dicts,
                                                   tool_panel_section_keys=tool_panel_section_keys )
        repair_dict['ordered_tsr_ids'] = ordered_tsr_ids
        repair_dict['ordered_repo_info_dicts'] = ordered_repo_info_dicts
        repair_dict[
            'ordered_tool_panel_section_keys'] = ordered_tool_panel_section_keys
        return repair_dict

    def get_repo_info_dict_for_repair(self, rdim, repository):
        tool_panel_section_key = None
        repository_clone_url = common_util.generate_clone_url_for_installed_repository(
            self.app, repository)
        repository_dependencies = rdim.get_repository_dependencies_for_installed_tool_shed_repository(
            self.app, repository)
        metadata = repository.metadata
        if metadata:
            tool_dependencies = metadata.get('tool_dependencies', None)
            tool_panel_section_dict = metadata.get('tool_panel_section', None)
            if tool_panel_section_dict:
                # The repository must be in the uninstalled state.  The structure of tool_panel_section_dict is:
                # {<tool guid> :
                # [{ 'id':<section id>, 'name':<section name>, 'version':<section version>, 'tool_config':<tool config file name> }]}
                # Here is an example:
                # {"localhost:9009/repos/test/filter/Filter1/1.1.0":
                # [{"id": "filter_and_sort", "name": "Filter and Sort", "tool_config": "filtering.xml", "version": ""}]}
                # Currently all tools contained within an installed tool shed repository must be loaded into the same
                # section in the tool panel, so we can get the section id of the first guid in the tool_panel_section_dict.
                # In the future, we'll have to handle different sections per guid.
                guid = tool_panel_section_dict.keys()[0]
                section_dicts = tool_panel_section_dict[guid]
                section_dict = section_dicts[0]
                tool_panel_section_id = section_dict['id']
                tool_panel_section_name = section_dict['name']
                if tool_panel_section_id:
                    tpm = tool_panel_manager.ToolPanelManager(self.app)
                    tool_panel_section_key, _ = \
                        tpm.get_or_create_tool_section( self.app.toolbox,
                                                        tool_panel_section_id=tool_panel_section_id,
                                                        new_tool_panel_section_label=tool_panel_section_name )
        else:
            tool_dependencies = None
        repo_info_dict = repository_util.create_repo_info_dict(
            app=self.app,
            repository_clone_url=repository_clone_url,
            changeset_revision=repository.changeset_revision,
            ctx_rev=repository.ctx_rev,
            repository_owner=repository.owner,
            repository_name=repository.name,
            repository=None,
            repository_metadata=None,
            tool_dependencies=tool_dependencies,
            repository_dependencies=repository_dependencies)
        return repo_info_dict, tool_panel_section_key

    def repair_tool_shed_repository(self, repository, repo_info_dict):
        def add_repair_dict_entry(repository_name, error_message):
            if repository_name in repair_dict:
                repair_dict[repository_name].append(error_message)
            else:
                repair_dict[repository_name] = [error_message]
            return repair_dict

        metadata = repository.metadata
        repair_dict = {}
        tpm = tool_panel_manager.ToolPanelManager(self.app)
        if repository.status in [
                self.app.install_model.ToolShedRepository.installation_status.
                DEACTIVATED
        ]:
            try:
                self.app.installed_repository_manager.activate_repository(
                    repository)
            except Exception, e:
                error_message = "Error activating repository %s: %s" % (
                    repository.name, str(e))
                log.debug(error_message)
                repair_dict[repository.name] = error_message
        elif repository.status not in [
                self.app.install_model.ToolShedRepository.installation_status.
                INSTALLED
        ]:
            shed_tool_conf, tool_path, relative_install_dir = \
                suc.get_tool_panel_config_tool_path_install_dir( self.app, repository )
            # Reset the repository attributes to the New state for installation.
            if metadata:
                _, tool_panel_section_key = \
                    tpm.handle_tool_panel_selection( self.app.toolbox,
                                                     metadata,
                                                     no_changes_checked=True,
                                                     tool_panel_section_id=None,
                                                     new_tool_panel_section_label=None )
            else:
                # The tools will be loaded outside of any sections in the tool panel.
                tool_panel_section_key = None
            suc.set_repository_attributes(
                self.app,
                repository,
                status=self.app.install_model.ToolShedRepository.
                installation_status.NEW,
                error_message=None,
                deleted=False,
                uninstalled=False,
                remove_from_disk=True)
            irm = install_manager.InstallRepositoryManager(self.app, tpm)
            irm.install_tool_shed_repository(repository,
                                             repo_info_dict,
                                             tool_panel_section_key,
                                             shed_tool_conf,
                                             tool_path,
                                             install_tool_dependencies=True,
                                             reinstalling=True)
            if repository.status in [
                    self.app.install_model.ToolShedRepository.
                    installation_status.ERROR
            ]:
                repair_dict = add_repair_dict_entry(repository.name,
                                                    repository.error_message)
     irm = install_manager.InstallRepositoryManager(self.app, tpm)
     irm.install_tool_shed_repository(repository,
                                      repo_info_dict,
                                      tool_panel_section_key,
                                      shed_tool_conf,
                                      tool_path,
                                      install_tool_dependencies=True,
                                      reinstalling=True)
     if repository.status in [
             self.app.install_model.ToolShedRepository.
             installation_status.ERROR
     ]:
         repair_dict = add_repair_dict_entry(repository.name,
                                             repository.error_message)
 else:
     irm = install_manager.InstallRepositoryManager(self.app, tpm)
     # We have an installed tool shed repository, so handle tool dependencies if necessary.
     if repository.missing_tool_dependencies and metadata and 'tool_dependencies' in metadata:
         work_dir = tempfile.mkdtemp(prefix="tmp-toolshed-itdep")
         # Reset missing tool dependencies.
         for tool_dependency in repository.missing_tool_dependencies:
             if tool_dependency.status in [
                     self.app.install_model.ToolDependency.
                     installation_status.ERROR, self.app.install_model.
                     ToolDependency.installation_status.INSTALLING
             ]:
                 tool_dependency = \
                     tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                          tool_dependency=tool_dependency,
                                                                          status=self.app.install_model.ToolDependency.installation_status.UNINSTALLED )
         # Install tool dependencies.
Esempio n. 4
0
 def install_repository(self,
                        repository_elem,
                        tool_shed_repository,
                        install_dependencies,
                        is_repository_dependency=False):
     """Install a single repository, loading contained tools into the tool panel."""
     # Install path is of the form: <tool path>/<tool shed>/repos/<repository owner>/<repository name>/<installed changeset revision>
     relative_clone_dir = os.path.join(
         tool_shed_repository.tool_shed, 'repos',
         tool_shed_repository.owner, tool_shed_repository.name,
         tool_shed_repository.installed_changeset_revision)
     clone_dir = os.path.join(self.tool_path, relative_clone_dir)
     cloned_ok = self.__iscloned(clone_dir)
     is_installed = False
     # Any of the following states should count as installed in this context.
     if tool_shed_repository.status in [
             self.app.install_model.ToolShedRepository.installation_status.
             INSTALLED, self.app.install_model.ToolShedRepository.
             installation_status.ERROR, self.app.install_model.
             ToolShedRepository.installation_status.UNINSTALLED,
             self.app.install_model.ToolShedRepository.installation_status.
             DEACTIVATED
     ]:
         is_installed = True
     if cloned_ok and is_installed:
         log.info(
             "Skipping automatic install of repository '%s' because it has already been installed in location %s",
             tool_shed_repository.name, clone_dir)
     else:
         irm = install_manager.InstallRepositoryManager(self.app, self.tpm)
         repository_clone_url = os.path.join(self.tool_shed_url, 'repos',
                                             tool_shed_repository.owner,
                                             tool_shed_repository.name)
         relative_install_dir = os.path.join(relative_clone_dir,
                                             tool_shed_repository.name)
         install_dir = os.path.join(clone_dir, tool_shed_repository.name)
         ctx_rev = suc.get_ctx_rev(
             self.app, self.tool_shed_url, tool_shed_repository.name,
             tool_shed_repository.owner,
             tool_shed_repository.installed_changeset_revision)
         if not cloned_ok:
             irm.update_tool_shed_repository_status(
                 tool_shed_repository, self.app.install_model.
                 ToolShedRepository.installation_status.CLONING)
             cloned_ok, error_message = hg_util.clone_repository(
                 repository_clone_url, os.path.abspath(install_dir),
                 ctx_rev)
         if cloned_ok and not is_installed:
             self.handle_repository_contents(
                 tool_shed_repository=tool_shed_repository,
                 repository_clone_url=repository_clone_url,
                 relative_install_dir=relative_install_dir,
                 repository_elem=repository_elem,
                 install_dependencies=install_dependencies,
                 is_repository_dependency=is_repository_dependency)
             self.app.install_model.context.refresh(tool_shed_repository)
             irm.update_tool_shed_repository_status(
                 tool_shed_repository, self.app.install_model.
                 ToolShedRepository.installation_status.INSTALLED)
         else:
             log.error('Error attempting to clone repository %s: %s',
                       str(tool_shed_repository.name), str(error_message))
             irm.update_tool_shed_repository_status(
                 tool_shed_repository,
                 self.app.install_model.ToolShedRepository.
                 installation_status.ERROR,
                 error_message=error_message)
Esempio n. 5
0
 def handle_repository_contents(self,
                                tool_shed_repository,
                                repository_clone_url,
                                relative_install_dir,
                                repository_elem,
                                install_dependencies,
                                is_repository_dependency=False):
     """
     Generate the metadata for the installed tool shed repository, among other things.  If the installed tool_shed_repository
     contains tools that are loaded into the Galaxy tool panel, this method will automatically eliminate all entries for each
     of the tools defined in the received repository_elem from all non-shed-related tool panel configuration files since the
     entries are automatically added to the reserved migrated_tools_conf.xml file as part of the migration process.
     """
     tool_configs_to_filter = []
     tool_panel_dict_for_display = odict()
     if self.tool_path:
         repo_install_dir = os.path.join(self.tool_path,
                                         relative_install_dir)
     else:
         repo_install_dir = relative_install_dir
     if not is_repository_dependency:
         for tool_elem in repository_elem:
             # The tool_elem looks something like this:
             # <tool id="EMBOSS: antigenic1" version="5.0.0" file="emboss_antigenic.xml" />
             tool_config = tool_elem.get('file')
             guid = self.get_guid(repository_clone_url,
                                  relative_install_dir, tool_config)
             # See if tool_config is defined inside of a section in self.proprietary_tool_panel_elems.
             is_displayed, tool_sections = self.get_containing_tool_sections(
                 tool_config)
             if is_displayed:
                 tool_panel_dict_for_tool_config = \
                     self.tpm.generate_tool_panel_dict_for_tool_config(guid,
                                                                       tool_config,
                                                                       tool_sections=tool_sections)
                 # The tool-panel_dict has the following structure.
                 # {<Tool guid> : [{ tool_config : <tool_config_file>,
                 #                   id: <ToolSection id>,
                 #                   version : <ToolSection version>,
                 #                   name : <TooSection name>}]}
                 for k, v in tool_panel_dict_for_tool_config.items():
                     tool_panel_dict_for_display[k] = v
                     for tool_panel_dict in v:
                         # Keep track of tool config file names associated with entries that have been made to the
                         # migrated_tools_conf.xml file so they can be eliminated from all non-shed-related tool panel configs.
                         if tool_config not in tool_configs_to_filter:
                             tool_configs_to_filter.append(tool_config)
             else:
                 log.error(
                     'The tool "%s" (%s) has not been enabled because it is not defined in a proprietary tool config (%s).'
                     % (guid, tool_config, ", ".join(
                         self.proprietary_tool_confs or [])))
         if tool_configs_to_filter:
             lock = threading.Lock()
             lock.acquire(True)
             try:
                 self.filter_and_persist_proprietary_tool_panel_configs(
                     tool_configs_to_filter)
             except Exception:
                 log.exception(
                     "Exception attempting to filter and persist non-shed-related tool panel configs"
                 )
             finally:
                 lock.release()
     irmm = InstalledRepositoryMetadataManager(
         app=self.app,
         tpm=self.tpm,
         repository=tool_shed_repository,
         changeset_revision=tool_shed_repository.changeset_revision,
         repository_clone_url=repository_clone_url,
         shed_config_dict=self.shed_config_dict,
         relative_install_dir=relative_install_dir,
         repository_files_dir=None,
         resetting_all_metadata_on_repository=False,
         updating_installed_repository=False,
         persist=True)
     irmm.generate_metadata_for_changeset_revision()
     irmm_metadata_dict = irmm.get_metadata_dict()
     tool_shed_repository.metadata = irmm_metadata_dict
     self.app.install_model.context.add(tool_shed_repository)
     self.app.install_model.context.flush()
     has_tool_dependencies = self.__has_tool_dependencies(
         irmm_metadata_dict)
     if has_tool_dependencies:
         # All tool_dependency objects must be created before the tools are processed even if no
         # tool dependencies will be installed.
         tool_dependencies = tool_dependency_util.create_tool_dependency_objects(
             self.app,
             tool_shed_repository,
             relative_install_dir,
             set_status=True)
     else:
         tool_dependencies = None
     if 'tools' in irmm_metadata_dict:
         tdtm = data_table_manager.ToolDataTableManager(self.app)
         sample_files = irmm_metadata_dict.get('sample_files', [])
         sample_files = [str(s) for s in sample_files]
         tool_index_sample_files = tdtm.get_tool_index_sample_files(
             sample_files)
         tool_util.copy_sample_files(self.app,
                                     tool_index_sample_files,
                                     tool_path=self.tool_path)
         sample_files_copied = [s for s in tool_index_sample_files]
         repository_tools_tups = irmm.get_repository_tools_tups()
         if repository_tools_tups:
             # Handle missing data table entries for tool parameters that are dynamically
             # generated select lists.
             repository_tools_tups = tdtm.handle_missing_data_table_entry(
                 relative_install_dir, self.tool_path,
                 repository_tools_tups)
             # Handle missing index files for tool parameters that are dynamically generated select lists.
             repository_tools_tups, sample_files_copied = tool_util.handle_missing_index_file(
                 self.app, self.tool_path, sample_files,
                 repository_tools_tups, sample_files_copied)
             # Copy remaining sample files included in the repository to the ~/tool-data
             # directory of the local Galaxy instance.
             tool_util.copy_sample_files(
                 self.app,
                 sample_files,
                 tool_path=self.tool_path,
                 sample_files_copied=sample_files_copied)
             if not is_repository_dependency:
                 self.tpm.add_to_tool_panel(
                     tool_shed_repository.name,
                     repository_clone_url,
                     tool_shed_repository.installed_changeset_revision,
                     repository_tools_tups,
                     self.repository_owner,
                     self.migrated_tools_config,
                     tool_panel_dict=tool_panel_dict_for_display,
                     new_install=True)
     if install_dependencies and tool_dependencies and has_tool_dependencies:
         # Install tool dependencies.
         irm = install_manager.InstallRepositoryManager(self.app, self.tpm)
         itdm = install_manager.InstallToolDependencyManager(self.app)
         irm.update_tool_shed_repository_status(
             tool_shed_repository,
             self.app.install_model.ToolShedRepository.installation_status.
             INSTALLING_TOOL_DEPENDENCIES)
         # Get the tool_dependencies.xml file from disk.
         tool_dependencies_config = hg_util.get_config_from_disk(
             'tool_dependencies.xml', repo_install_dir)
         installed_tool_dependencies = itdm.install_specified_tool_dependencies(
             tool_shed_repository=tool_shed_repository,
             tool_dependencies_config=tool_dependencies_config,
             tool_dependencies=tool_dependencies,
             from_tool_migration_manager=True)
         for installed_tool_dependency in installed_tool_dependencies:
             if installed_tool_dependency.status == self.app.install_model.ToolDependency.installation_status.ERROR:
                 log.error(
                     'The ToolMigrationManager returned the following error while installing tool dependency %s: %s',
                     installed_tool_dependency.name,
                     installed_tool_dependency.error_message)
     if 'datatypes' in irmm_metadata_dict:
         cdl = custom_datatype_manager.CustomDatatypeLoader(self.app)
         tool_shed_repository.status = self.app.install_model.ToolShedRepository.installation_status.LOADING_PROPRIETARY_DATATYPES
         if not tool_shed_repository.includes_datatypes:
             tool_shed_repository.includes_datatypes = True
         self.app.install_model.context.add(tool_shed_repository)
         self.app.install_model.context.flush()
         work_dir = tempfile.mkdtemp(prefix="tmp-toolshed-hrc")
         datatypes_config = hg_util.get_config_from_disk(
             suc.DATATYPES_CONFIG_FILENAME, repo_install_dir)
         # Load proprietary data types required by tools.  The value of override is not
         # important here since the Galaxy server will be started after this installation
         # completes.
         converter_path, display_path = \
             cdl.alter_config_and_load_prorietary_datatypes(datatypes_config,
                                                            repo_install_dir,
                                                            override=False)
         if converter_path or display_path:
             # Create a dictionary of tool shed repository related information.
             repository_dict = \
                 cdl.create_repository_dict_for_proprietary_datatypes(tool_shed=self.tool_shed_url,
                                                                      name=tool_shed_repository.name,
                                                                      owner=self.repository_owner,
                                                                      installed_changeset_revision=tool_shed_repository.installed_changeset_revision,
                                                                      tool_dicts=irmm_metadata_dict.get('tools', []),
                                                                      converter_path=converter_path,
                                                                      display_path=display_path)
         if converter_path:
             # Load proprietary datatype converters
             self.app.datatypes_registry.load_datatype_converters(
                 self.toolbox, installed_repository_dict=repository_dict)
         if display_path:
             # Load proprietary datatype display applications
             self.app.datatypes_registry.load_display_applications(
                 self.app, installed_repository_dict=repository_dict)
         basic_util.remove_dir(work_dir)
Esempio n. 6
0
    def repair_tool_shed_repository(self, repository, repo_info_dict):
        def add_repair_dict_entry(repository_name, error_message):
            if repository_name in repair_dict:
                repair_dict[repository_name].append(error_message)
            else:
                repair_dict[repository_name] = [error_message]
            return repair_dict

        tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry(
            self.app, repository.tool_shed)
        metadata = repository.metadata
        # The repository.metadata contains dependency information that corresponds to the current changeset revision,
        # which may be different from what is stored in the database
        # If any of these repository-repository dependency associations is obsolete, clean_dependency_relationships removes them.
        suc.clean_dependency_relationships(self.app, metadata, repository,
                                           tool_shed_url)
        repair_dict = {}
        tpm = tool_panel_manager.ToolPanelManager(self.app)
        if repository.status in [
                self.app.install_model.ToolShedRepository.installation_status.
                DEACTIVATED
        ]:
            try:
                self.app.installed_repository_manager.activate_repository(
                    repository)
            except Exception as e:
                error_message = "Error activating repository %s: %s" % (
                    repository.name, str(e))
                log.debug(error_message)
                repair_dict[repository.name] = error_message
        elif repository.status not in [
                self.app.install_model.ToolShedRepository.installation_status.
                INSTALLED
        ]:
            shed_tool_conf, tool_path, relative_install_dir = \
                suc.get_tool_panel_config_tool_path_install_dir( self.app, repository )
            # Reset the repository attributes to the New state for installation.
            if metadata:
                _, tool_panel_section_key = \
                    tpm.handle_tool_panel_selection( self.app.toolbox,
                                                     metadata,
                                                     no_changes_checked=True,
                                                     tool_panel_section_id=None,
                                                     new_tool_panel_section_label=None )
            else:
                # The tools will be loaded outside of any sections in the tool panel.
                tool_panel_section_key = None
            repository_util.set_repository_attributes(
                self.app,
                repository,
                status=self.app.install_model.ToolShedRepository.
                installation_status.NEW,
                error_message=None,
                deleted=False,
                uninstalled=False,
                remove_from_disk=True)
            irm = install_manager.InstallRepositoryManager(self.app, tpm)
            irm.install_tool_shed_repository(
                repository,
                repo_info_dict,
                tool_panel_section_key,
                shed_tool_conf,
                tool_path,
                install_tool_dependencies=True,
                install_resolver_dependencies=
                False,  # Assuming repairs are only necessary toolshed packages
                reinstalling=True)
            if repository.status in [
                    self.app.install_model.ToolShedRepository.
                    installation_status.ERROR
            ]:
                repair_dict = add_repair_dict_entry(repository.name,
                                                    repository.error_message)
        else:
            irm = install_manager.InstallRepositoryManager(self.app, tpm)
            # We have an installed tool shed repository, so handle tool dependencies if necessary.
            if repository.missing_tool_dependencies and metadata and 'tool_dependencies' in metadata:
                work_dir = tempfile.mkdtemp(prefix="tmp-toolshed-itdep")
                # Reset missing tool dependencies.
                for tool_dependency in repository.missing_tool_dependencies:
                    if tool_dependency.status in [
                            self.app.install_model.ToolDependency.
                            installation_status.ERROR, self.app.install_model.
                            ToolDependency.installation_status.INSTALLING
                    ]:
                        tool_dependency = \
                            tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                                 tool_dependency=tool_dependency,
                                                                                 status=self.app.install_model.ToolDependency.installation_status.UNINSTALLED )
                # Install tool dependencies.
                irm.update_tool_shed_repository_status(
                    repository, self.app.install_model.ToolShedRepository.
                    installation_status.INSTALLING_TOOL_DEPENDENCIES)
                # Get the tool_dependencies.xml file from the repository.
                tool_dependencies_config = hg_util.get_config_from_disk(
                    'tool_dependencies.xml', repository.repo_path(self.app))
                itdm = install_manager.InstallToolDependencyManager(self.app)
                installed_tool_dependencies = itdm.install_specified_tool_dependencies(
                    tool_shed_repository=repository,
                    tool_dependencies_config=tool_dependencies_config,
                    tool_dependencies=repository.tool_dependencies,
                    from_tool_migration_manager=False)
                for installed_tool_dependency in installed_tool_dependencies:
                    if installed_tool_dependency.status in [
                            self.app.install_model.ToolDependency.
                            installation_status.ERROR
                    ]:
                        repair_dict = add_repair_dict_entry(
                            repository.name,
                            installed_tool_dependency.error_message)
                basic_util.remove_dir(work_dir)
            irm.update_tool_shed_repository_status(
                repository, self.app.install_model.ToolShedRepository.
                installation_status.INSTALLED)
        return repair_dict
 def install_repository(self,
                        repository_elem,
                        tool_shed_repository,
                        install_dependencies,
                        is_repository_dependency=False):
     """Install a single repository, loading contained tools into the tool panel."""
     # Install path is of the form: <tool path>/<tool shed>/repos/<repository owner>/<repository name>/<installed changeset revision>
     relative_clone_dir = os.path.join(
         tool_shed_repository.tool_shed, 'repos',
         tool_shed_repository.owner, tool_shed_repository.name,
         tool_shed_repository.installed_changeset_revision)
     clone_dir = os.path.join(self.tool_path, relative_clone_dir)
     cloned_ok = self.__iscloned(clone_dir)
     is_installed = False
     # Any of the following states should count as installed in this context.
     if tool_shed_repository.status in [
             self.app.install_model.ToolShedRepository.installation_status.
             INSTALLED, self.app.install_model.ToolShedRepository.
             installation_status.ERROR, self.app.install_model.
             ToolShedRepository.installation_status.UNINSTALLED,
             self.app.install_model.ToolShedRepository.installation_status.
             DEACTIVATED
     ]:
         is_installed = True
     if cloned_ok and is_installed:
         log.info(
             "Skipping automatic install of repository '%s' because it has already been installed in location %s",
             tool_shed_repository.name, clone_dir)
     else:
         irm = install_manager.InstallRepositoryManager(self.app, self.tpm)
         repository_clone_url = os.path.join(self.tool_shed_url, 'repos',
                                             tool_shed_repository.owner,
                                             tool_shed_repository.name)
         relative_install_dir = os.path.join(relative_clone_dir,
                                             tool_shed_repository.name)
         install_dir = os.path.join(clone_dir, tool_shed_repository.name)
         ctx_rev = suc.get_ctx_rev(
             self.app, self.tool_shed_url, tool_shed_repository.name,
             tool_shed_repository.owner,
             tool_shed_repository.installed_changeset_revision)
         if not cloned_ok:
             irm.update_tool_shed_repository_status(
                 tool_shed_repository, self.app.install_model.
                 ToolShedRepository.installation_status.CLONING)
             cloned_ok, error_message = hg_util.clone_repository(
                 repository_clone_url, os.path.abspath(install_dir),
                 ctx_rev)
         if cloned_ok and not is_installed:
             self.handle_repository_contents(
                 tool_shed_repository=tool_shed_repository,
                 repository_clone_url=repository_clone_url,
                 relative_install_dir=relative_install_dir,
                 repository_elem=repository_elem,
                 install_dependencies=install_dependencies,
                 is_repository_dependency=is_repository_dependency)
             self.app.install_model.context.refresh(tool_shed_repository)
             metadata_dict = tool_shed_repository.metadata
             if 'tools' in metadata_dict:
                 # Initialize the ToolVersionManager.
                 tvm = tool_version_manager.ToolVersionManager(self.app)
                 irm.update_tool_shed_repository_status(
                     tool_shed_repository,
                     self.app.install_model.ToolShedRepository.
                     installation_status.SETTING_TOOL_VERSIONS)
                 # Get the tool_versions from the tool shed for each tool in the installed change set.
                 params = dict(name=tool_shed_repository.name,
                               owner=self.repository_owner,
                               changeset_revision=tool_shed_repository.
                               installed_changeset_revision)
                 pathspec = ['repository', 'get_tool_versions']
                 text = util.url_get(
                     self.tool_shed_url,
                     password_mgr=self.app.tool_shed_registry.url_auth(
                         self.tool_shed_url),
                     pathspec=pathspec,
                     params=params)
                 if text:
                     tool_version_dicts = json.loads(text)
                     tvm.handle_tool_versions(tool_version_dicts,
                                              tool_shed_repository)
                 else:
                     # Set the tool versions since they seem to be missing
                     # for this repository in the tool shed. CRITICAL NOTE:
                     # These default settings may not properly handle all
                     # parent/child associations.
                     for tool_dict in metadata_dict['tools']:
                         tool_id = tool_dict['guid']
                         old_tool_id = tool_dict['id']
                         tool_version_using_old_id = tvm.get_tool_version(
                             old_tool_id)
                         tool_version_using_guid = tvm.get_tool_version(
                             tool_id)
                         if not tool_version_using_old_id:
                             tool_version_using_old_id = self.app.install_model.ToolVersion(
                                 tool_id=old_tool_id,
                                 tool_shed_repository=tool_shed_repository)
                             self.app.install_model.context.add(
                                 tool_version_using_old_id)
                             self.app.install_model.context.flush()
                         if not tool_version_using_guid:
                             tool_version_using_guid = self.app.install_model.ToolVersion(
                                 tool_id=tool_id,
                                 tool_shed_repository=tool_shed_repository)
                             self.app.install_model.context.add(
                                 tool_version_using_guid)
                             self.app.install_model.context.flush()
                         # Associate the two versions as parent / child.
                         tool_version_association = tvm.get_tool_version_association(
                             tool_version_using_old_id,
                             tool_version_using_guid)
                         if not tool_version_association:
                             tool_version_association = \
                                 self.app.install_model.ToolVersionAssociation( tool_id=tool_version_using_guid.id,
                                                                                parent_id=tool_version_using_old_id.id )
                             self.app.install_model.context.add(
                                 tool_version_association)
                             self.app.install_model.context.flush()
             irm.update_tool_shed_repository_status(
                 tool_shed_repository, self.app.install_model.
                 ToolShedRepository.installation_status.INSTALLED)
         else:
             log.error('Error attempting to clone repository %s: %s',
                       str(tool_shed_repository.name), str(error_message))
             irm.update_tool_shed_repository_status(
                 tool_shed_repository,
                 self.app.install_model.ToolShedRepository.
                 installation_status.ERROR,
                 error_message=error_message)