Fixes for getting updates to installed tool shed repositories.

This commit is contained in:
Greg Von Kuster
2012-06-06 13:26:15 -04:00
parent dfd49c1999
commit 44fa0ff880
2 changed files with 74 additions and 94 deletions
+46 -34
View File
@@ -174,6 +174,40 @@ class AdminToolshed( AdminGalaxy ):
return trans.response.send_redirect( url )
@web.expose
@web.require_admin
def check_installed_tool_dependencies( self, trans, repository_id, relative_install_dir ):
"""See if any tool dependencies need to be installed."""
tool_dependencies_missing = False
repository = get_repository( trans, repository_id )
if repository.includes_tool_dependencies:
# Get the tool_dependencies.xml file from the repository.
work_dir = make_tmp_directory()
tool_dependencies_config = get_config_from_repository( trans.app,
'tool_dependencies.xml',
repository,
repository.changeset_revision,
work_dir,
install_dir=relative_install_dir )
# Parse the tool_dependencies.xml config.
tree = ElementTree.parse( tool_dependencies_config )
root = tree.getroot()
ElementInclude.include( root )
fabric_version_checked = False
for elem in root:
if elem.tag == 'package':
package_name = elem.get( 'name', None )
package_version = elem.get( 'version', None )
if package_name and package_version:
install_dir = get_install_dir( trans.app, repository, repository.installed_changeset_revision, package_name, package_version )
if not_installed( install_dir ):
tool_dependencies_missing = True
break
try:
shutil.rmtree( work_dir )
except:
pass
return tool_dependencies_missing
@web.expose
@web.require_admin
def deactivate_or_uninstall_repository( self, trans, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
@@ -540,7 +574,8 @@ class AdminToolshed( AdminGalaxy ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
repository = get_repository( trans, kwd[ 'id' ] )
repository_id = kwd[ 'id' ]
repository = get_repository( trans, repository_id )
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 ) )
@@ -558,34 +593,7 @@ class AdminToolshed( AdminGalaxy ):
trans.sa_session.add( repository )
trans.sa_session.flush()
message = "Repository metadata has been reset."
tool_dependencies_missing = False
if repository.includes_tool_dependencies:
# See if any tool dependencies need to be installed, get the tool_dependencies.xml file from the repository.
work_dir = make_tmp_directory()
tool_dependencies_config = get_config_from_repository( trans.app,
'tool_dependencies.xml',
repository,
repository.changeset_revision,
work_dir,
install_dir=relative_install_dir )
# Parse the tool_dependencies.xml config.
tree = ElementTree.parse( tool_dependencies_config )
root = tree.getroot()
ElementInclude.include( root )
fabric_version_checked = False
for elem in root:
if elem.tag == 'package':
package_name = elem.get( 'name', None )
package_version = elem.get( 'version', None )
if package_name and package_version:
install_dir = get_install_dir( trans.app, repository, repository.installed_changeset_revision, package_name, package_version )
if not_installed( install_dir ):
tool_dependencies_missing = True
break
try:
shutil.rmtree( work_dir )
except:
pass
tool_dependencies_missing = self.check_installed_tool_dependencies( trans, repository_id, relative_install_dir )
return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako',
repository=repository,
description=description,
@@ -782,7 +790,7 @@ class AdminToolshed( AdminGalaxy ):
repository = get_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed_url, name, owner, changeset_revision )
if changeset_revision and latest_changeset_revision and latest_ctx_rev:
if changeset_revision == latest_changeset_revision:
message = "The cloned tool shed repository named '%s' is current (there are no updates available)." % name
message = "The installed repository named '%s' is current, there are no updates available. " % name
else:
shed_tool_conf, tool_path, relative_install_dir = get_tool_panel_config_tool_path_install_dir( trans.app, repository )
if relative_install_dir:
@@ -801,13 +809,17 @@ class AdminToolshed( AdminGalaxy ):
repository.update_available = False
trans.sa_session.add( repository )
trans.sa_session.flush()
message = "The cloned repository named '%s' has been updated to change set revision '%s'." % \
( name, latest_changeset_revision )
message = "The installed repository named '%s' has been updated to change set revision '%s'. " % ( name, latest_changeset_revision )
# See if any tool dependencies can be installed.
shed_tool_conf, tool_path, relative_install_dir = get_tool_panel_config_tool_path_install_dir( trans.app, repository )
tool_dependencies_missing = self.check_installed_tool_dependencies( trans, trans.security.encode_id( repository.id ), relative_install_dir )
if tool_dependencies_missing:
message += "Select <b>Install tool dependencies</b> from the repository's pop-up menu to install tool dependencies."
else:
message = "The directory containing the cloned repository named '%s' cannot be found." % name
message = "The directory containing the installed repository named '%s' cannot be found. " % name
status = 'error'
else:
message = "The latest changeset revision could not be retrieved for the repository named '%s'." % name
message = "The latest changeset revision could not be retrieved for the installed repository named '%s'. " % name
status = 'error'
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_repository',
@@ -599,6 +599,9 @@ class RepositoryController( BaseUIController, ItemRatings ):
repository = get_repository_by_name_and_owner( trans, name, owner )
repo_dir = repository.repo_path
repo = hg.repository( get_configured_ui(), repo_dir )
# Default to the current changeset revision.
update_to_ctx = get_changectx_for_changeset( repo, changeset_revision )
latest_changeset_revision = changeset_revision
from_update_manager = webapp == 'update_manager'
if from_update_manager:
update = 'true'
@@ -608,80 +611,45 @@ class RepositoryController( BaseUIController, ItemRatings ):
url = '%sadmin_toolshed/update_to_changeset_revision?tool_shed_url=%s' % ( galaxy_url, url_for( '/', qualified=True ) )
url += '&name=%s&owner=%s&changeset_revision=%s&latest_changeset_revision=' % ( repository.name, repository.user.username, changeset_revision )
if changeset_revision == repository.tip:
# If changeset_revision is the repository tip, we know there are no additional updates for the tools.
# If changeset_revision is the repository tip, there are no additional updates.
if from_update_manager:
return no_update
# Return the same value for changeset_revision and latest_changeset_revision.
url += repository.tip
url += latest_changeset_revision
else:
repository_metadata = get_repository_metadata_by_changeset_revision( trans,
trans.security.encode_id( repository.id ),
changeset_revision )
if repository_metadata:
# If changeset_revision is in the repository_metadata table for this repository, then we know there are no additional updates
# for the tools.
# If changeset_revision is in the repository_metadata table for this repository, there are no additional updates.
if from_update_manager:
return no_update
else:
# Return the same value for changeset_revision and latest_changeset_revision.
url += changeset_revision
url += latest_changeset_revision
else:
# TODO: Re-engineer this to define the change set for update to be the one just before the next change set in the repository_metadata
# table for this repository.
# The changeset_revision column in the repository_metadata table has been updated with a new changeset_revision value since the
# repository was cloned. Load each tool in the repository's changeset_revision to generate a list of tool guids, since guids
# differentiate tools by id and version.
ctx = get_changectx_for_changeset( repo, changeset_revision )
if ctx is not None:
work_dir = make_tmp_directory()
tool_guids = []
for filename in ctx:
# Find all tool configs in this repository changeset_revision.
if filename not in NOT_TOOL_CONFIGS and filename.endswith( '.xml' ):
is_tool_config, valid, tool, error_message = load_tool_from_tmp_directory( trans,
repo,
repo_dir,
ctx,
filename,
work_dir )
if valid and tool is not None:
tool_guids.append( generate_tool_guid( trans, repository, tool ) )
tool_guids.sort()
if tool_guids:
# Compare our list of tool guids against those in each repository_metadata record for the repository to find the
# repository_metadata record with the changeset_revision value we want to pass back to the caller.
found = False
for repository_metadata in get_repository_metadata_by_repository_id( trans, trans.security.encode_id( repository.id ) ):
metadata = repository_metadata.metadata
metadata_tool_guids = []
for tool_dict in metadata[ 'tools' ]:
metadata_tool_guids.append( tool_dict[ 'guid' ] )
metadata_tool_guids.sort()
if tool_guids == metadata_tool_guids:
# We've found the repository_metadata record whose changeset_revision value has been updated.
if from_update_manager:
return update
url += repository_metadata.changeset_revision
# Get the ctx_rev for the discovered changeset_revision.
latest_ctx = get_changectx_for_changeset( repo, repository_metadata.changeset_revision )
found = True
break
if not found:
# There must be a problem in the data, so we'll just send back the received changeset_revision.
log.debug( "Possible data corruption - updated repository_metadata cannot be found for repository id %d." % repository.id )
if from_update_manager:
return no_update
url += changeset_revision
else:
# There are no tools in the changeset_revision, so no tool updates are possible.
if from_update_manager:
return no_update
url += changeset_revision
try:
shutil.rmtree( work_dir )
except:
pass
url += '&latest_ctx_rev=%s' % str( latest_ctx.rev() )
# repository was installed. We need to find the changeset_revision to which we need to update.
update_to_changeset_hash = None
for changeset in repo.changelog:
changeset_hash = str( repo.changectx( changeset ) )
ctx = get_changectx_for_changeset( repo, changeset_hash )
if update_to_changeset_hash:
if get_repository_metadata_by_changeset_revision( trans, trans.security.encode_id( repository.id ), changeset_hash ):
# We found a RepositoryMetadata record.
if changeset_hash == repository.tip:
# The current ctx is the repository tip, so use it.
update_to_ctx = get_changectx_for_changeset( repo, changeset_hash )
latest_changeset_revision = changeset_hash
else:
update_to_ctx = get_changectx_for_changeset( repo, update_to_changeset_hash )
latest_changeset_revision = update_to_changeset_hash
break
elif not update_to_changeset_hash and changeset_hash == changeset_revision:
# We've found the changeset in the changelog for which we need to get the next update.
update_to_changeset_hash = changeset_hash
url += str( latest_changeset_revision )
url += '&latest_ctx_rev=%s' % str( update_to_ctx.rev() )
return trans.response.send_redirect( url )
@web.expose
def contact_owner( self, trans, id, **kwd ):