Example #1
0
def test_env_file_builder():
    install_dir = "/opt/galaxy/dependencies/foo/"
    env_file_builder = EnvFileBuilder( install_dir )
    added_lines = []
    mock_return = dict(value=0)

    def mock_file_append( text, file_path, **kwds ):
        added_lines.append( text )
        return mock_return[ "value" ]

    with __mock_env_file_builder_method( env_file_builder, "file_append", mock_file_append ):
        env_file_builder.append_line( name="PATH", action="prepend_to", value="/usr/bin/local/R" )
        assert added_lines == [ "PATH=/usr/bin/local/R:$PATH; export PATH" ]
        assert env_file_builder.return_code == 0

        # Reset mock lines
        del added_lines[:]
        # Next time file_append will fail
        mock_return["value"] = 1

        env_file_builder.append_line( action="source", value="/usr/bin/local/R/env.sh" )
        assert added_lines == [ "if [ -f /usr/bin/local/R/env.sh ] ; then . /usr/bin/local/R/env.sh ; fi" ]
        # Check failure
        assert env_file_builder.return_code == 1

        mock_return["value"] = 0
        env_file_builder.append_line( name="LD_LIBRARY_PATH", action="append_to", value="/usr/bin/local/R/lib" )
        # Verify even though last append succeeded, previous failure still recorded.
        assert env_file_builder.return_code == 1
def test_env_file_builder():
    install_dir = "/opt/galaxy/dependencies/foo/"
    env_file_builder = EnvFileBuilder( install_dir )
    added_lines = []
    mock_return = dict(value=0)

    def mock_file_append( text, file_path, **kwds ):
        added_lines.append( text )
        return mock_return[ "value" ]

    with __mock_env_file_builder_method( env_file_builder, "file_append", mock_file_append ):
        env_file_builder.append_line( name="PATH", action="prepend_to", value="/usr/bin/local/R" )
        assert added_lines == [ "PATH=/usr/bin/local/R:$PATH; export PATH" ]
        assert env_file_builder.return_code == 0

        # Reset mock lines
        del added_lines[:]
        # Next time file_append will fail
        mock_return["value"] = 1

        env_file_builder.append_line( action="source", value="/usr/bin/local/R/env.sh" )
        assert added_lines == [ "if [ -f /usr/bin/local/R/env.sh ] ; then . /usr/bin/local/R/env.sh ; fi" ]
        # Check failure
        assert env_file_builder.return_code == 1

        mock_return["value"] = 0
        env_file_builder.append_line( name="LD_LIBRARY_PATH", action="append_to", value="/usr/bin/local/R/lib" )
        # Verify even though last append succeeded, previous failure still recorded.
        assert env_file_builder.return_code == 1
    def set_environment( self, elem, tool_shed_repository, attr_tups_of_dependencies_for_install ):
        """
        Create a ToolDependency to set an environment variable.  This is different from the process used to
        set an environment variable that is associated with a package.  An example entry in a tool_dependencies.xml
        file is::

            <set_environment version="1.0">
                <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
            </set_environment>

        This method must also handle the sub-element tag::
            <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
        """
        # TODO: Add support for a repository dependency definition within this tool dependency type's tag set.  This should look something like
        # the following.  See the implementation of support for this in the tool dependency package type's method above.
        # This function is only called for set environment actions as defined below, not within an <install version="1.0"> tool
        # dependency type. Here is an example of the tag set this function does handle:
        # <action type="set_environment">
        #     <environment_variable name="PATH" action="prepend_to">$INSTALL_DIR</environment_variable>
        # </action>
        # Here is an example of the tag set this function does not handle:
        # <set_environment version="1.0">
        #    <repository toolshed="<tool shed>" name="<repository name>" owner="<repository owner>" changeset_revision="<changeset revision>" />
        # </set_environment>
        env_manager = EnvManager( self.app )
        tool_dependencies = []
        env_var_version = elem.get( 'version', '1.0' )
        tool_shed_repository_install_dir = os.path.abspath( tool_shed_repository.repo_files_directory( self.app ) )
        if elem.tag == 'environment_variable':
            # <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
            elems = [ elem ]
        else:
            # <set_environment version="1.0">
            #    <environment_variable name="R_SCRIPT_PATH" action="set_to">$REPOSITORY_INSTALL_DIR</environment_variable>
            # </set_environment>
            elems = [ env_var_elem for env_var_elem in elem ]
        for env_var_elem in elems:
            env_var_name = env_var_elem.get( 'name', None )
            # The value of env_var_name must match the text value of at least 1 <requirement> tag in the
            # tool config's <requirements> tag set whose "type" attribute is "set_environment" (e.g.,
            # <requirement type="set_environment">R_SCRIPT_PATH</requirement>).
            env_var_action = env_var_elem.get( 'action', None )
            if env_var_name and env_var_action:
                # Tool dependencies of type "set_environment" always have the version attribute set to None.
                attr_tup = ( env_var_name, None, 'set_environment' )
                if attr_tup in attr_tups_of_dependencies_for_install:
                    install_dir = \
                        tool_dependency_util.get_tool_dependency_install_dir( app=self.app,
                                                                              repository_name=tool_shed_repository.name,
                                                                              repository_owner=tool_shed_repository.owner,
                                                                              repository_changeset_revision=tool_shed_repository.installed_changeset_revision,
                                                                              tool_dependency_type='set_environment',
                                                                              tool_dependency_name=env_var_name,
                                                                              tool_dependency_version=None )
                    install_environment = InstallEnvironment( app=self.app,
                                                              tool_shed_repository_install_dir=tool_shed_repository_install_dir,
                                                              install_dir=install_dir )
                    env_var_dict = env_manager.create_env_var_dict( elem=env_var_elem,
                                                                    install_environment=install_environment )
                    if env_var_dict:
                        if not os.path.exists( install_dir ):
                            os.makedirs( install_dir )
                        status = self.app.install_model.ToolDependency.installation_status.INSTALLING
                        tool_dependency = \
                            tool_dependency_util.create_or_update_tool_dependency( app=self.app,
                                                                                   tool_shed_repository=tool_shed_repository,
                                                                                   name=env_var_name,
                                                                                   version=None,
                                                                                   type='set_environment',
                                                                                   status=status,
                                                                                   set_status=True )
                        if env_var_version == '1.0':
                            # Create this tool dependency's env.sh file.
                            env_file_builder = EnvFileBuilder( install_dir )
                            return_code = env_file_builder.append_line( make_executable=True, **env_var_dict )
                            if return_code:
                                error_message = 'Error creating env.sh file for tool dependency %s, return_code: %s' % \
                                    ( str( tool_dependency.name ), str( return_code ) )
                                log.debug( error_message )
                                status = self.app.install_model.ToolDependency.installation_status.ERROR
                                tool_dependency = \
                                    tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                                         tool_dependency=tool_dependency,
                                                                                         status=status,
                                                                                         error_message=error_message )
                            else:
                                if tool_dependency.status not in [ self.app.install_model.ToolDependency.installation_status.ERROR,
                                                                   self.app.install_model.ToolDependency.installation_status.INSTALLED ]:
                                    status = self.app.install_model.ToolDependency.installation_status.INSTALLED
                                    tool_dependency = \
                                        tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                                             tool_dependency=tool_dependency,
                                                                                             status=status )
                                    log.debug( 'Environment variable %s set in %s for tool dependency %s.' %
                                        ( str( env_var_name ), str( install_dir ), str( tool_dependency.name ) ) )
                        else:
                            error_message = 'Only set_environment version 1.0 is currently supported (i.e., change your tag to be <set_environment version="1.0">).'
                            status = self.app.install_model.ToolDependency.installation_status.ERROR
                            tool_dependency = \
                                tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                                     tool_dependency=tool_dependency,
                                                                                     status=status,
                                                                                     error_message=error_message )
            tool_dependencies.append( tool_dependency )
        return tool_dependencies
 def create_tool_dependency_with_initialized_env_sh_file( self, dependent_install_dir, tool_shed_repository,
                                                          required_repository, package_name, package_version,
                                                          tool_dependencies_config ):
     """
     Create or get a tool_dependency record that is defined by the received package_name and package_version.
     An env.sh file will be created for the tool_dependency in the received dependent_install_dir.
     """
     # The received required_repository refers to a tool_shed_repository record that is defined as a complex
     # repository dependency for this tool_dependency.  The required_repository may or may not be currently
     # installed (it doesn't matter).  If it is installed, it is associated with a tool_dependency that has
     # an env.sh file that this new tool_dependency must be able to locate and "source".  If it is not installed,
     # we can still determine where that env.sh file will be, so we'll initialize this new tool_dependency's env.sh
     # file in either case.  If the required repository ends up with an installation error, this new tool
     # dependency will still be fine because its containing repository will be defined as missing dependencies.
     tool_dependencies = []
     if not os.path.exists( dependent_install_dir ):
         os.makedirs( dependent_install_dir )
     required_tool_dependency_env_file_path = None
     if tool_dependencies_config:
         required_td_tree, error_message = xml_util.parse_xml( tool_dependencies_config )
         if required_td_tree:
             required_td_root = required_td_tree.getroot()
             for required_td_elem in required_td_root:
                 # Find the appropriate package name and version.
                 if required_td_elem.tag == 'package':
                     # <package name="bwa" version="0.5.9">
                     required_td_package_name = required_td_elem.get( 'name', None )
                     required_td_package_version = required_td_elem.get( 'version', None )
                     # Check the database to see if we have a record for the required tool dependency (we may not which is ok).  If we
                     # find a record, we need to see if it is in an error state and if so handle it appropriately.
                     required_tool_dependency = \
                         tool_dependency_util.get_tool_dependency_by_name_version_type_repository( self.app,
                                                                                                   required_repository,
                                                                                                   required_td_package_name,
                                                                                                   required_td_package_version,
                                                                                                   'package' )
                     if required_td_package_name == package_name and required_td_package_version == package_version:
                         # Get or create a database tool_dependency record with which the installed package on disk will be associated.
                         tool_dependency = \
                             tool_dependency_util.create_or_update_tool_dependency( app=self.app,
                                                                                    tool_shed_repository=tool_shed_repository,
                                                                                    name=package_name,
                                                                                    version=package_version,
                                                                                    type='package',
                                                                                    status=self.app.install_model.ToolDependency.installation_status.NEVER_INSTALLED,
                                                                                    set_status=True )
                         # Create an env.sh file for the tool_dependency whose first line will source the env.sh file located in
                         # the path defined by required_tool_dependency_env_file_path.  It doesn't matter if the required env.sh
                         # file currently exists..
                         required_tool_dependency_env_file_path = \
                             self.get_required_repository_package_env_sh_path( package_name,
                                                                               package_version,
                                                                               required_repository )
                         env_file_builder = EnvFileBuilder( tool_dependency.installation_directory( self.app ) )
                         env_file_builder.append_line( action="source", value=required_tool_dependency_env_file_path )
                         return_code = env_file_builder.return_code
                         if return_code:
                             error_message = 'Error defining env.sh file for package %s, return_code: %s' % \
                                 ( str( package_name ), str( return_code ) )
                             tool_dependency = \
                                 tool_dependency_util.set_tool_dependency_attributes(self.app,
                                                                                     tool_dependency=tool_dependency,
                                                                                     status=self.app.install_model.ToolDependency.installation_status.ERROR,
                                                                                     error_message=error_message)
                         elif required_tool_dependency is not None and required_tool_dependency.in_error_state:
                             error_message = "This tool dependency's required tool dependency %s version %s has status %s." % \
                                 ( str( required_tool_dependency.name ), str( required_tool_dependency.version ), str( required_tool_dependency.status ) )
                             tool_dependency = \
                                 tool_dependency_util.set_tool_dependency_attributes(self.app,
                                                                                     tool_dependency=tool_dependency,
                                                                                     status=self.app.install_model.ToolDependency.installation_status.ERROR,
                                                                                     error_message=error_message)
                         else:
                             tool_dependency = \
                                 tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                                      tool_dependency=tool_dependency,
                                                                                      status=self.app.install_model.ToolDependency.installation_status.INSTALLED )
                         tool_dependencies.append( tool_dependency )
     return tool_dependencies