1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/6390e1f3a723/ changeset: 6390e1f3a723 user: greg date: 2012-09-19 22:35:49 summary: Fix and enhance the features for resetting a repository that encounted errors during the cloning process so the Galaxy admin can make another attempt to install it. affected #: 11 files diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 lib/galaxy/tool_shed/install_manager.py --- a/lib/galaxy/tool_shed/install_manager.py +++ b/lib/galaxy/tool_shed/install_manager.py @@ -244,57 +244,58 @@ owner=self.repository_owner, dist_to_shed=True ) update_tool_shed_repository_status( self.app, tool_shed_repository, self.app.model.ToolShedRepository.installation_status.CLONING ) - clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) - 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 ) - self.app.sa_session.refresh( tool_shed_repository ) - metadata_dict = tool_shed_repository.metadata - if 'tools' in metadata_dict: - update_tool_shed_repository_status( self.app, - tool_shed_repository, - self.app.model.ToolShedRepository.installation_status.SETTING_TOOL_VERSIONS ) - # Get the tool_versions from the tool shed for each tool in the installed change set. - url = '%s/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ - ( tool_shed_url, tool_shed_repository.name, self.repository_owner, installed_changeset_revision ) - response = urllib2.urlopen( url ) - text = response.read() - response.close() - if text: - tool_version_dicts = from_json_string( text ) - handle_tool_versions( self.app, 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' ]: - flush_needed = False - tool_id = tool_dict[ 'guid' ] - old_tool_id = tool_dict[ 'id' ] - tool_version = tool_dict[ 'version' ] - tool_version_using_old_id = get_tool_version( self.app, old_tool_id ) - tool_version_using_guid = get_tool_version( self.app, tool_id ) - if not tool_version_using_old_id: - tool_version_using_old_id = self.app.model.ToolVersion( tool_id=old_tool_id, - tool_shed_repository=tool_shed_repository ) - self.app.sa_session.add( tool_version_using_old_id ) - self.app.sa_session.flush() - if not tool_version_using_guid: - tool_version_using_guid = self.app.model.ToolVersion( tool_id=tool_id, - tool_shed_repository=tool_shed_repository ) - self.app.sa_session.add( tool_version_using_guid ) - self.app.sa_session.flush() - # Associate the two versions as parent / child. - tool_version_association = get_tool_version_association( self.app, - tool_version_using_old_id, - tool_version_using_guid ) - if not tool_version_association: - tool_version_association = self.app.model.ToolVersionAssociation( tool_id=tool_version_using_guid.id, - parent_id=tool_version_using_old_id.id ) - self.app.sa_session.add( tool_version_association ) - self.app.sa_session.flush() - update_tool_shed_repository_status( self.app, tool_shed_repository, self.app.model.ToolShedRepository.installation_status.INSTALLED ) + cloned_ok, error_message = clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) + if cloned_ok: + 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 ) + self.app.sa_session.refresh( tool_shed_repository ) + metadata_dict = tool_shed_repository.metadata + if 'tools' in metadata_dict: + update_tool_shed_repository_status( self.app, + tool_shed_repository, + self.app.model.ToolShedRepository.installation_status.SETTING_TOOL_VERSIONS ) + # Get the tool_versions from the tool shed for each tool in the installed change set. + url = '%s/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ + ( tool_shed_url, tool_shed_repository.name, self.repository_owner, installed_changeset_revision ) + response = urllib2.urlopen( url ) + text = response.read() + response.close() + if text: + tool_version_dicts = from_json_string( text ) + handle_tool_versions( self.app, 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' ]: + flush_needed = False + tool_id = tool_dict[ 'guid' ] + old_tool_id = tool_dict[ 'id' ] + tool_version = tool_dict[ 'version' ] + tool_version_using_old_id = get_tool_version( self.app, old_tool_id ) + tool_version_using_guid = get_tool_version( self.app, tool_id ) + if not tool_version_using_old_id: + tool_version_using_old_id = self.app.model.ToolVersion( tool_id=old_tool_id, + tool_shed_repository=tool_shed_repository ) + self.app.sa_session.add( tool_version_using_old_id ) + self.app.sa_session.flush() + if not tool_version_using_guid: + tool_version_using_guid = self.app.model.ToolVersion( tool_id=tool_id, + tool_shed_repository=tool_shed_repository ) + self.app.sa_session.add( tool_version_using_guid ) + self.app.sa_session.flush() + # Associate the two versions as parent / child. + tool_version_association = get_tool_version_association( self.app, + tool_version_using_old_id, + tool_version_using_guid ) + if not tool_version_association: + tool_version_association = self.app.model.ToolVersionAssociation( tool_id=tool_version_using_guid.id, + parent_id=tool_version_using_old_id.id ) + self.app.sa_session.add( tool_version_association ) + self.app.sa_session.flush() + update_tool_shed_repository_status( self.app, tool_shed_repository, self.app.model.ToolShedRepository.installation_status.INSTALLED ) @property def non_shed_tool_panel_configs( self ): # Get the non-shed related tool panel config file names from the Galaxy config - the default is tool_conf.xml. diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 lib/galaxy/util/shed_util.py --- a/lib/galaxy/util/shed_util.py +++ b/lib/galaxy/util/shed_util.py @@ -380,10 +380,11 @@ pull=True, noupdate=False, rev=util.listify( str( ctx_rev ) ) ) - return True + return True, None except Exception, e: - log.debug( 'Encountered an exception while cloning the repository: %s' % e ) - return False + error_message = 'Error cloning repository: %s' % str( e ) + log.debug( error_message ) + return False, error_message def copy_sample_file( app, filename, dest_path=None ): """Copy xxx.sample to dest_path/xxx.sample and dest_path/xxx. The default value for dest_path is ~/tool-data.""" if dest_path is None: diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 lib/galaxy/web/controllers/admin_toolshed.py --- a/lib/galaxy/web/controllers/admin_toolshed.py +++ b/lib/galaxy/web/controllers/admin_toolshed.py @@ -63,8 +63,9 @@ columns = [ NameColumn( "Name", key="name", - link=( lambda item: iff( item.status == model.ToolShedRepository.installation_status.ERROR, \ - None, dict( operation="manage_repository", id=item.id, webapp="galaxy" ) ) ), + link=( lambda item: iff( item.status in [ model.ToolShedRepository.installation_status.CLONING ], + None, + dict( operation="manage_repository", id=item.id, webapp="galaxy" ) ) ), attach_popup=True ), DescriptionColumn( "Description" ), OwnerColumn( "Owner" ), @@ -90,25 +91,25 @@ [ model.ToolShedRepository.installation_status.ERROR, model.ToolShedRepository.installation_status.NEW ] ), async_compatible=False, url_args=dict( controller='admin_toolshed', action='browse_repositories', operation='get updates' ) ), + grids.GridOperation( "Install", + allow_multiple=False, + condition=( lambda item: not item.deleted and item.status == model.ToolShedRepository.installation_status.NEW ), + async_compatible=False, + url_args=dict( controller='admin_toolshed', action='manage_repository', operation='install' ) ), grids.GridOperation( "Deactivate or uninstall", allow_multiple=False, condition=( lambda item: not item.deleted and item.status not in \ [ model.ToolShedRepository.installation_status.ERROR, model.ToolShedRepository.installation_status.NEW ] ), async_compatible=False, url_args=dict( controller='admin_toolshed', action='browse_repositories', operation='deactivate or uninstall' ) ), - grids.GridOperation( "Uninstall", - allow_multiple=False, - condition=( lambda item: ( item.status == model.ToolShedRepository.installation_status.ERROR ) ), - async_compatible=False, - url_args=dict( controller='admin_toolshed', action='browse_repositories', operation='uninstall' ) ), grids.GridOperation( "Reset to install", allow_multiple=False, condition=( lambda item: ( item.status == model.ToolShedRepository.installation_status.ERROR ) ), async_compatible=False, - url_args=dict( controller='admin_toolshed', action='browse_repositories', operation='reset status to new' ) ), + url_args=dict( controller='admin_toolshed', action='browse_repositories', operation='reset to install' ) ), grids.GridOperation( "Activate or reinstall", allow_multiple=False, - condition=( lambda item: ( item.deleted or item.uninstalled ) ), + condition=( lambda item: item.deleted ), async_compatible=False, url_args=dict( controller='admin_toolshed', action='browse_repositories', operation='activate or reinstall' ) ) ] standard_filters = [] @@ -354,16 +355,9 @@ return self.manage_repository( trans, **kwd ) if operation == "get updates": return self.check_for_updates( trans, **kwd ) - if operation == "uninstall": - kwd[ 'deactivate_or_uninstall_repository_button' ] = 'Deactivate or Uninstall' - kwd[ 'remove_from_disk' ] = [u'true', u'true'] - return self.deactivate_or_uninstall_repository( trans, **kwd ) - if operation == "reset status to new": - repository = get_repository( trans, kwd[ 'id' ] ) - repository.status = model.ToolShedRepository.installation_status.NEW - repository.deleted = False - repository.uninstalled = True - trans.app.model.context.current.flush() + if operation == "reset to install": + kwd[ 'reset_repository' ] = True + return self.reset_to_install( trans, **kwd ) if operation == "activate or reinstall": repository = get_repository( trans, kwd[ 'id' ] ) if repository.uninstalled: @@ -386,9 +380,19 @@ message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) tool_dependency = get_tool_dependency( trans, kwd[ 'id' ] ) + in_error_state = tool_dependency.status == trans.model.ToolDependency.installation_status.ERROR + can_uninstall = tool_dependency.status in [ trans.model.ToolDependency.installation_status.ERROR, + trans.model.ToolDependency.installation_status.INSTALLED ] + if in_error_state: + message = "This tool dependency is not installed correctly (see the <b>Tool dependency installation error</b> below). " + message += "Choose <b>Uninstall this tool dependency</b> from the <b>Repository Actions</b> menu, correct problems " + message += "if necessary, and try installing the dependency again." + status = "error" return trans.fill_template( '/admin/tool_shed_repository/browse_tool_dependency.mako', repository=tool_dependency.tool_shed_repository, tool_dependency=tool_dependency, + in_error_state=in_error_state, + can_uninstall=can_uninstall, message=message, status=status ) @web.expose @@ -428,7 +432,10 @@ remove_from_disk_checked = CheckboxField.is_checked( remove_from_disk ) tool_shed_repository = get_repository( trans, kwd[ 'id' ] ) shed_tool_conf, tool_path, relative_install_dir = get_tool_panel_config_tool_path_install_dir( trans.app, tool_shed_repository ) - repository_install_dir = os.path.abspath ( relative_install_dir ) if relative_install_dir is not None else None + if relative_install_dir: + repository_install_dir = os.path.abspath( relative_install_dir ) + else: + repository_install_dir = None errors = '' if params.get( 'deactivate_or_uninstall_repository_button', False ): if tool_shed_repository.includes_tools: @@ -448,12 +455,8 @@ log.debug( "Removed repository installation directory: %s" % str( repository_install_dir ) ) removed = True except Exception, e: - if repository_install_dir is not None: - removed = False - log.debug( "Error removing repository installation directory %s: %s" % ( str( repository_install_dir ), str( e ) ) ) - else: - log.debug( "Repository installation directory does not exist." ) - removed = True + log.debug( "Error removing repository installation directory %s: %s" % ( str( repository_install_dir ), str( e ) ) ) + removed = False if removed: tool_shed_repository.uninstalled = True # Remove all installed tool dependencies. @@ -636,67 +639,72 @@ description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, tool_dependencies = repo_info_tuple clone_dir = os.path.join( tool_path, self.generate_tool_path( repository_clone_url, tool_shed_repository.installed_changeset_revision ) ) relative_install_dir = os.path.join( clone_dir, tool_shed_repository.name ) - result = clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) - if not result: - update_tool_shed_repository_status( trans.app, tool_shed_repository, trans.model.ToolShedRepository.installation_status.ERROR ) - return trans.response.send_redirect( web.url_for( controller='admin_toolshed', - action='monitor_repository_installation', - tool_shed_repository_ids=[ trans.security.encode_id( tool_shed_repository.id ) ] ) ) - if reinstalling: - # Since we're reinstalling the repository we need to find the latest changeset revision to which is can be updated. - current_changeset_revision, current_ctx_rev = get_update_to_changeset_revision_and_ctx_rev( trans, tool_shed_repository ) - if current_ctx_rev != ctx_rev: - repo = hg.repository( get_configured_ui(), path=os.path.abspath( relative_install_dir ) ) - pull_repository( repo, repository_clone_url, current_changeset_revision ) - update_repository( repo, ctx_rev=current_ctx_rev ) - self.handle_repository_contents( trans, - tool_shed_repository=tool_shed_repository, - tool_path=tool_path, - repository_clone_url=repository_clone_url, - relative_install_dir=relative_install_dir, - tool_shed=tool_shed_repository.tool_shed, - tool_section=tool_section, - shed_tool_conf=kwd.get( 'shed_tool_conf', '' ), - reinstalling=reinstalling ) - trans.sa_session.refresh( tool_shed_repository ) - metadata = tool_shed_repository.metadata - if 'tools' in metadata: - # Get the tool_versions from the tool shed for each tool in the installed change set. - update_tool_shed_repository_status( trans.app, - tool_shed_repository, - trans.model.ToolShedRepository.installation_status.SETTING_TOOL_VERSIONS ) - tool_shed_url = get_url_from_repository_tool_shed( trans.app, tool_shed_repository ) - url = url_join( tool_shed_url, - '/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ - ( tool_shed_repository.name, tool_shed_repository.owner, tool_shed_repository.changeset_revision ) ) - response = urllib2.urlopen( url ) - text = response.read() - response.close() - if text: - tool_version_dicts = from_json_string( text ) - handle_tool_versions( trans.app, tool_version_dicts, tool_shed_repository ) - else: - message += "Version information for the tools included in the <b>%s</b> repository is missing. " % name - message += "Reset all of this repository's metadata in the tool shed, then set the installed tool versions " - message += "from the installed repository's <b>Repository Actions</b> menu. " - status = 'error' - if install_tool_dependencies and tool_shed_repository.tool_dependencies and 'tool_dependencies' in metadata: - work_dir = tempfile.mkdtemp() - # Install tool dependencies. - update_tool_shed_repository_status( trans.app, - tool_shed_repository, - trans.model.ToolShedRepository.installation_status.INSTALLING_TOOL_DEPENDENCIES ) - # Get the tool_dependencies.xml file from the repository. - tool_dependencies_config = get_config_from_disk( 'tool_dependencies.xml', relative_install_dir ) - installed_tool_dependencies = handle_tool_dependencies( app=trans.app, - tool_shed_repository=tool_shed_repository, - tool_dependencies_config=tool_dependencies_config, - tool_dependencies=tool_shed_repository.tool_dependencies ) - try: - shutil.rmtree( work_dir ) - except: - pass - update_tool_shed_repository_status( trans.app, tool_shed_repository, trans.model.ToolShedRepository.installation_status.INSTALLED ) + cloned_ok, error_message = clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) + if cloned_ok: + if reinstalling: + # Since we're reinstalling the repository we need to find the latest changeset revision to which is can be updated. + current_changeset_revision, current_ctx_rev = get_update_to_changeset_revision_and_ctx_rev( trans, tool_shed_repository ) + if current_ctx_rev != ctx_rev: + repo = hg.repository( get_configured_ui(), path=os.path.abspath( relative_install_dir ) ) + pull_repository( repo, repository_clone_url, current_changeset_revision ) + update_repository( repo, ctx_rev=current_ctx_rev ) + self.handle_repository_contents( trans, + tool_shed_repository=tool_shed_repository, + tool_path=tool_path, + repository_clone_url=repository_clone_url, + relative_install_dir=relative_install_dir, + tool_shed=tool_shed_repository.tool_shed, + tool_section=tool_section, + shed_tool_conf=kwd.get( 'shed_tool_conf', '' ), + reinstalling=reinstalling ) + trans.sa_session.refresh( tool_shed_repository ) + metadata = tool_shed_repository.metadata + if 'tools' in metadata: + # Get the tool_versions from the tool shed for each tool in the installed change set. + update_tool_shed_repository_status( trans.app, + tool_shed_repository, + trans.model.ToolShedRepository.installation_status.SETTING_TOOL_VERSIONS ) + tool_shed_url = get_url_from_repository_tool_shed( trans.app, tool_shed_repository ) + url = url_join( tool_shed_url, + '/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ + ( tool_shed_repository.name, tool_shed_repository.owner, tool_shed_repository.changeset_revision ) ) + response = urllib2.urlopen( url ) + text = response.read() + response.close() + if text: + tool_version_dicts = from_json_string( text ) + handle_tool_versions( trans.app, tool_version_dicts, tool_shed_repository ) + else: + message += "Version information for the tools included in the <b>%s</b> repository is missing. " % name + message += "Reset all of this repository's metadata in the tool shed, then set the installed tool versions " + message += "from the installed repository's <b>Repository Actions</b> menu. " + status = 'error' + if install_tool_dependencies and tool_shed_repository.tool_dependencies and 'tool_dependencies' in metadata: + work_dir = tempfile.mkdtemp() + # Install tool dependencies. + update_tool_shed_repository_status( trans.app, + tool_shed_repository, + trans.model.ToolShedRepository.installation_status.INSTALLING_TOOL_DEPENDENCIES ) + # Get the tool_dependencies.xml file from the repository. + tool_dependencies_config = get_config_from_disk( 'tool_dependencies.xml', relative_install_dir ) + installed_tool_dependencies = handle_tool_dependencies( app=trans.app, + tool_shed_repository=tool_shed_repository, + tool_dependencies_config=tool_dependencies_config, + tool_dependencies=tool_shed_repository.tool_dependencies ) + try: + shutil.rmtree( work_dir ) + except: + pass + update_tool_shed_repository_status( trans.app, tool_shed_repository, trans.model.ToolShedRepository.installation_status.INSTALLED ) + else: + # An error occurred while cloning the repository, so reset everything necessary to enable another attempt. + self.set_repository_attributes( trans, + tool_shed_repository, + status=trans.model.ToolShedRepository.installation_status.ERROR, + error_message=error_message, + deleted=False, + uninstalled=False, + remove_from_disk=True ) tsr_ids_for_monitoring = [ trans.security.encode_id( tsr.id ) for tsr in tool_shed_repositories ] return trans.response.send_redirect( web.url_for( controller='admin_toolshed', action='monitor_repository_installation', @@ -776,17 +784,39 @@ message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) repository_id = kwd[ 'id' ] + operation = kwd.get( 'operation', None ) repository = get_repository( trans, repository_id ) - if repository.status in [ trans.model.ToolShedRepository.installation_status.NEW, - trans.model.ToolShedRepository.installation_status.CLONING, - trans.model.ToolShedRepository.installation_status.ERROR ]: + in_error_state = repository.status == trans.model.ToolShedRepository.installation_status.ERROR + can_install = repository.status == trans.model.ToolShedRepository.installation_status.NEW + if repository.status in [ trans.model.ToolShedRepository.installation_status.CLONING ]: return trans.response.send_redirect( web.url_for( controller='admin_toolshed', action='monitor_repository_installation', **kwd ) ) + if can_install and operation == 'install': + # Send a request to the tool shed to install the repository. + tool_shed_url = get_url_from_repository_tool_shed( trans.app, repository ) + url = url_join( tool_shed_url, + 'repository/install_repositories_by_revision?name=%s&owner=%s&changeset_revisions=%s&galaxy_url=%s&webapp=galaxy' % \ + ( repository.name, + repository.owner, + repository.installed_changeset_revision, + ( url_for( '/', qualified=True ) ) ) ) + return trans.response.send_redirect( url ) description = util.restore_text( params.get( 'description', repository.description ) ) shed_tool_conf, tool_path, relative_install_dir = get_tool_panel_config_tool_path_install_dir( trans.app, repository ) - repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, repository.name ) ) - if params.get( 'edit_repository_button', False ): + if relative_install_dir: + repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, repository.name ) ) + else: + repo_files_dir = None + if in_error_state: + message = "This repository is not installed correctly (see the <b>Repository installation error</b> below). Choose " + message += "<b>Reset to install</b> from the <b>Repository Actions</b> menu, correct problems if necessary, and try " + message += "installing the repository again." + status = "error" + elif can_install: + message = "This repository is not installed. You can install it by choosing <b>Install</b> from the <b>Repository Actions</b> menu." + status = "error" + elif params.get( 'edit_repository_button', False ): if description != repository.description: repository.description = description trans.sa_session.add( repository ) @@ -809,6 +839,8 @@ message = "Repository metadata has been reset." return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako', repository=repository, + in_error_state=in_error_state, + can_install=can_install, description=description, repo_files_dir=repo_files_dir, message=message, @@ -890,7 +922,7 @@ url_args=dict( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( tool_shed_repository.id ) ) ), - grids.GridAction( label='Get updates', + grids.GridAction( label='Get repository updates', url_args=dict( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( tool_shed_repository.id ) ) ), @@ -1390,6 +1422,41 @@ status=status ) @web.expose @web.require_admin + def reset_to_install( self, trans, **kwd ): + # An error occurred while cloning the repository, so reset everything necessary to enable another attempt. + repository = get_repository( trans, kwd[ 'id' ] ) + if kwd.get( 'reset_repository', False ): + self.set_repository_attributes( trans, + repository, + status=trans.model.ToolShedRepository.installation_status.NEW, + error_message=None, + deleted=False, + uninstalled=False, + remove_from_disk=True ) + new_kwd = {} + new_kwd[ 'message' ] = "You can now attempt to install the repository named <b>%s</b> again." % repository.name + new_kwd[ 'status' ] = "done" + return trans.response.send_redirect( web.url_for( controller='admin_toolshed', + action='browse_repositories', + **new_kwd ) ) + return trans.response.send_redirect( web.url_for( controller='admin_toolshed', + action='manage_repository', + **kwd ) ) + def set_repository_attributes( self, trans, repository, status, error_message, deleted, uninstalled, remove_from_disk=False ): + if remove_from_disk: + relative_install_dir = repository.repo_path( trans.app ) + if relative_install_dir: + clone_dir = os.path.abspath( relative_install_dir ) + shutil.rmtree( clone_dir ) + log.debug( "Removed repository installation directory: %s" % str( clone_dir ) ) + repository.error_message = error_message + repository.status = status + repository.deleted = deleted + repository.uninstalled = uninstalled + trans.sa_session.add( repository ) + trans.sa_session.flush() + @web.expose + @web.require_admin def set_tool_versions( self, trans, **kwd ): # Get the tool_versions from the tool shed for each tool in the installed change set. repository = get_repository( trans, kwd[ 'id' ] ) diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -875,59 +875,60 @@ current_changeset_revision = str( repo.changectx( changeset ) ) ctx = repo.changectx( changeset ) log.debug( "Cloning repository revision: %s", str( ctx.rev() ) ) - clone_repository( repository_clone_url, work_dir, str( ctx.rev() ) ) - log.debug( "Generating metadata for changset revision: %s", str( ctx.rev() ) ) - current_metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app, - repository_clone_url=repository_clone_url, - relative_install_dir=repo_dir, - repository_files_dir=work_dir, - resetting_all_metadata_on_repository=True, - webapp='community' ) - if current_metadata_dict: - if not metadata_changeset_revision and not metadata_dict: - # We're at the first change set in the change log. - metadata_changeset_revision = current_changeset_revision - metadata_dict = current_metadata_dict - if ancestor_changeset_revision: - # Compare metadata from ancestor and current. The value of comparison will be one of: - # 'no metadata' - no metadata for either ancestor or current, so continue from current - # 'equal' - ancestor metadata is equivalent to current metadata, so continue from current - # 'subset' - ancestor metadata is a subset of current metadata, so continue from current - # 'not equal and not subset' - ancestor metadata is neither equal to nor a subset of current metadata, so persist ancestor metadata. - comparison = compare_changeset_revisions( ancestor_changeset_revision, - ancestor_metadata_dict, - current_changeset_revision, - current_metadata_dict ) - if comparison in [ 'no metadata', 'equal', 'subset' ]: + cloned_ok, error_message = clone_repository( repository_clone_url, work_dir, str( ctx.rev() ) ) + if cloned_ok: + log.debug( "Generating metadata for changset revision: %s", str( ctx.rev() ) ) + current_metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app, + repository_clone_url=repository_clone_url, + relative_install_dir=repo_dir, + repository_files_dir=work_dir, + resetting_all_metadata_on_repository=True, + webapp='community' ) + if current_metadata_dict: + if not metadata_changeset_revision and not metadata_dict: + # We're at the first change set in the change log. + metadata_changeset_revision = current_changeset_revision + metadata_dict = current_metadata_dict + if ancestor_changeset_revision: + # Compare metadata from ancestor and current. The value of comparison will be one of: + # 'no metadata' - no metadata for either ancestor or current, so continue from current + # 'equal' - ancestor metadata is equivalent to current metadata, so continue from current + # 'subset' - ancestor metadata is a subset of current metadata, so continue from current + # 'not equal and not subset' - ancestor metadata is neither equal to nor a subset of current metadata, so persist ancestor metadata. + comparison = compare_changeset_revisions( ancestor_changeset_revision, + ancestor_metadata_dict, + current_changeset_revision, + current_metadata_dict ) + if comparison in [ 'no metadata', 'equal', 'subset' ]: + ancestor_changeset_revision = current_changeset_revision + ancestor_metadata_dict = current_metadata_dict + elif comparison == 'not equal and not subset': + metadata_changeset_revision = ancestor_changeset_revision + metadata_dict = ancestor_metadata_dict + repository_metadata = create_or_update_repository_metadata( trans, id, repository, metadata_changeset_revision, metadata_dict ) + changeset_revisions.append( metadata_changeset_revision ) + ancestor_changeset_revision = current_changeset_revision + ancestor_metadata_dict = current_metadata_dict + else: + # We're at the beginning of the change log. ancestor_changeset_revision = current_changeset_revision ancestor_metadata_dict = current_metadata_dict - elif comparison == 'not equal and not subset': - metadata_changeset_revision = ancestor_changeset_revision - metadata_dict = ancestor_metadata_dict + if not ctx.children(): + metadata_changeset_revision = current_changeset_revision + metadata_dict = current_metadata_dict + # We're at the end of the change log. repository_metadata = create_or_update_repository_metadata( trans, id, repository, metadata_changeset_revision, metadata_dict ) changeset_revisions.append( metadata_changeset_revision ) - ancestor_changeset_revision = current_changeset_revision - ancestor_metadata_dict = current_metadata_dict - else: - # We're at the beginning of the change log. - ancestor_changeset_revision = current_changeset_revision - ancestor_metadata_dict = current_metadata_dict - if not ctx.children(): - metadata_changeset_revision = current_changeset_revision - metadata_dict = current_metadata_dict - # We're at the end of the change log. - repository_metadata = create_or_update_repository_metadata( trans, id, repository, metadata_changeset_revision, metadata_dict ) - changeset_revisions.append( metadata_changeset_revision ) - ancestor_changeset_revision = None - ancestor_metadata_dict = None - elif ancestor_metadata_dict: - # We reach here only if current_metadata_dict is empty and ancestor_metadata_dict is not. - if not ctx.children(): - # We're at the end of the change log. - repository_metadata = create_or_update_repository_metadata( trans, id, repository, metadata_changeset_revision, metadata_dict ) - changeset_revisions.append( metadata_changeset_revision ) - ancestor_changeset_revision = None - ancestor_metadata_dict = None + ancestor_changeset_revision = None + ancestor_metadata_dict = None + elif ancestor_metadata_dict: + # We reach here only if current_metadata_dict is empty and ancestor_metadata_dict is not. + if not ctx.children(): + # We're at the end of the change log. + repository_metadata = create_or_update_repository_metadata( trans, id, repository, metadata_changeset_revision, metadata_dict ) + changeset_revisions.append( metadata_changeset_revision ) + ancestor_changeset_revision = None + ancestor_metadata_dict = None if os.path.exists( work_dir ): try: shutil.rmtree( work_dir ) diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -1020,10 +1020,11 @@ repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id ) encoded_repository_ids.append( trans.security.encode_id( repository_metadata.repository.id ) ) changeset_revisions.append( repository_metadata.changeset_revision ) + new_kwd[ 'repository_ids' ] = encoded_repository_ids + new_kwd[ 'changeset_revisions' ] = changeset_revisions return trans.response.send_redirect( web.url_for( controller='repository', action='install_repositories_by_revision', - repository_ids=encoded_repository_ids, - changeset_revisions=changeset_revisions ) ) + **new_kwd ) ) else: # This can only occur when there is a multi-select grid with check boxes and an operation, # and the user clicked the operation button without checking any of the check boxes. @@ -1106,10 +1107,12 @@ repository_metadata = get_repository_metadata_by_id( trans, item_id ) encoded_repository_ids.append( trans.security.encode_id( repository_metadata.repository.id ) ) changeset_revisions.append( repository_metadata.changeset_revision ) + new_kwd = {} + new_kwd[ 'repository_ids' ] = encoded_repository_ids + new_kwd[ 'changeset_revisions' ] = changeset_revisions return trans.response.send_redirect( web.url_for( controller='repository', action='install_repositories_by_revision', - repository_ids=encoded_repository_ids, - changeset_revisions=changeset_revisions ) ) + **new_kwd ) ) else: # This can only occur when there is a multi-select grid with check boxes and an operation, # and the user clicked the operation button without checking any of the check boxes. @@ -1188,7 +1191,7 @@ repo_info_dicts = [] for tup in zip( util.listify( repository_ids ), util.listify( changeset_revisions ) ): repository_id, changeset_revision = tup - repository_clone_url = generate_clone_url( trans, repository_id ) + repository_clone_url = generate_clone_url( trans, repository_id ) repository = get_repository( trans, repository_id ) repository_metadata = get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ) metadata = repository_metadata.metadata @@ -1414,9 +1417,22 @@ message=message, status=status ) @web.expose - def install_repositories_by_revision( self, trans, repository_ids, changeset_revisions, **kwd ): - """Send the list of repository_ids and changeset_revisions to Galaxy so it can begin the installation process.""" - galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) + def install_repositories_by_revision( self, trans, **kwd ): + """ + Send the list of repository_ids and changeset_revisions to Galaxy so it can begin the installation process. If the value of + repository_ids is not received, then the name and owner of a single repository must be received to install a single repository. + """ + repository_ids = kwd.get( 'repository_ids', None ) + changeset_revisions = kwd.get( 'changeset_revisions', None ) + name = kwd.get( 'name', None ) + owner = kwd.get( 'owner', None ) + galaxy_url = kwd.get( 'galaxy_url', None ) + if not repository_ids: + repository = get_repository_by_name_and_owner( trans, name, owner ) + repository_ids = trans.security.encode_id( repository.id ) + if not galaxy_url: + # If galaxy_url is not in the request, it had to have been stored in a cookie by the tool shed. + galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) # Redirect back to local Galaxy to perform install. url = url_join( galaxy_url, 'admin_toolshed/prepare_for_install?tool_shed_url=%s&repository_ids=%s&changeset_revisions=%s' % \ diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 templates/admin/tool_shed_repository/browse_repository.mako --- a/templates/admin/tool_shed_repository/browse_repository.mako +++ b/templates/admin/tool_shed_repository/browse_repository.mako @@ -18,7 +18,7 @@ <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get repository updates</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or uninstall repository</a> %if repository.tool_dependencies: <% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %> diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 templates/admin/tool_shed_repository/browse_tool_dependency.mako --- a/templates/admin/tool_shed_repository/browse_tool_dependency.mako +++ b/templates/admin/tool_shed_repository/browse_tool_dependency.mako @@ -21,9 +21,12 @@ <div popupmenu="tool_dependency-${tool_dependency.id}-popup"><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get repository updates</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or uninstall repository</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', tool_dependency_ids=tool_dependency_ids )}">Manage tool dependencies</a> + %if can_uninstall: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='uninstall_tool_dependencies', tool_dependency_ids=trans.security.encode_id( tool_dependency.id ) )}">Uninstall this tool dependency</a> + %endif </div></ul> @@ -45,6 +48,18 @@ <div style="clear: both"></div></div><div class="form-row" > + <label>Tool dependency status:</label> + ${tool_dependency.status} + <div style="clear: both"></div> + </div> + %if in_error_state: + <div class="form-row" > + <label>Tool dependency installation error:</label> + ${tool_dependency.error_message} + <div style="clear: both"></div> + </div> + %endif + <div class="form-row" ><label>Tool dependency installation directory:</label> ${tool_dependency.installation_directory( trans.app )} <div style="clear: both"></div> diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 templates/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako --- a/templates/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako +++ b/templates/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako @@ -8,7 +8,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get repository updates</a> %if repository.tool_dependencies: <% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', tool_dependency_ids=tool_dependency_ids )}">Manage tool dependencies</a> diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 templates/admin/tool_shed_repository/manage_repository.mako --- a/templates/admin/tool_shed_repository/manage_repository.mako +++ b/templates/admin/tool_shed_repository/manage_repository.mako @@ -6,16 +6,22 @@ <ul class="manage-table-actions"><li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> - %if repository.includes_tools: - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='set_tool_versions', id=trans.security.encode_id( repository.id ) )}">Set tool versions</a> + %if in_error_state: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='reset_to_install', id=trans.security.encode_id( repository.id ), reset_repository=True )}">Reset to install</a> + %elif can_install: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ), operation='install' )}">Install</a> + %else: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get repository updates</a> + %if repository.includes_tools: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='set_tool_versions', id=trans.security.encode_id( repository.id ) )}">Set tool versions</a> + %endif + %if repository.tool_dependencies: + <% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', tool_dependency_ids=tool_dependency_ids )}">Manage tool dependencies</a> + %endif + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or uninstall repository</a> %endif - %if repository.tool_dependencies: - <% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', tool_dependency_ids=tool_dependency_ids )}">Manage tool dependencies</a> - %endif - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or uninstall repository</a></div></ul> @@ -39,7 +45,11 @@ </div><div class="form-row"><label>Description:</label> - <input name="description" type="textfield" value="${description}" size="80"/> + %if in_error_state: + ${description} + %else: + <input name="description" type="textfield" value="${description}" size="80"/> + %endif <div style="clear: both"></div></div><div class="form-row"> @@ -50,17 +60,26 @@ <label>Owner:</label> ${repository.owner} </div> - <div class="form-row"> - <label>Location:</label> - ${repo_files_dir} - </div> + %if in_error_state: + <div class="form-row"> + <label>Repository installation error:</label> + ${repository.error_message} + </div> + %else: + <div class="form-row"> + <label>Location:</label> + ${repo_files_dir} + </div> + %endif <div class="form-row"><label>Deleted:</label> ${repository.deleted} </div> - <div class="form-row"> - <input type="submit" name="edit_repository_button" value="Save"/> - </div> + %if not in_error_state: + <div class="form-row"> + <input type="submit" name="edit_repository_button" value="Save"/> + </div> + %endif </form></div></div> diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 templates/admin/tool_shed_repository/manage_tool_dependencies.mako --- a/templates/admin/tool_shed_repository/manage_tool_dependencies.mako +++ b/templates/admin/tool_shed_repository/manage_tool_dependencies.mako @@ -9,7 +9,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get repository updates</a> %if repository.includes_tools: <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='set_tool_versions', id=trans.security.encode_id( repository.id ) )}">Set tool versions</a> %endif diff -r da9d740fce314d67b51ff4f9d80b34bd37d3fd84 -r 6390e1f3a72300974c113f927b80eec98b32fe94 templates/admin/tool_shed_repository/view_tool_metadata.mako --- a/templates/admin/tool_shed_repository/view_tool_metadata.mako +++ b/templates/admin/tool_shed_repository/view_tool_metadata.mako @@ -7,7 +7,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get repository updates</a> %if repository.tool_dependencies: <% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', tool_dependency_ids=tool_dependency_ids )}">Manage tool dependencies</a> Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.