Refinements for installing and managing tool dependencies for tools contained in installed tool shed repositories.

This commit is contained in:
Greg Von Kuster
2012-06-22 10:21:09 -04:00
parent ddd70c8e04
commit ba91ecef9f
26 changed files with 951 additions and 528 deletions
+39 -21
View File
@@ -2647,6 +2647,12 @@ class APIKeys( object ):
pass
class ToolShedRepository( object ):
installation_status = Bunch( CLONED='cloned',
SETTING_TOOL_VERSIONS='setting tool versions',
INSTALLING_TOOL_DEPENDENCIES='installing tool dependencies',
INSTALLED='installed',
ERROR='error',
UNINSTALLED='uninstalled' )
def __init__( self, id=None, create_time=None, tool_shed=None, name=None, description=None, owner=None, installed_changeset_revision=None,
changeset_revision=None, ctx_rev=None, metadata=None, includes_datatypes=False, update_available=False, deleted=False,
uninstalled=False, dist_to_shed=False ):
@@ -2696,47 +2702,59 @@ class ToolShedRepository( object ):
"""Return the repository's tool dependencies that are currently installed."""
installed_dependencies = []
for tool_dependency in self.tool_dependencies:
if not tool_dependency.uninstalled:
if tool_dependency.status == ToolDependency.installation_status.INSTALLED:
installed_dependencies.append( tool_dependency )
return installed_dependencies
@property
def missing_tool_dependencies( self ):
"""Return the repository's tool dependencies that are not currently installed, and may not ever have been installed."""
missing_dependencies = []
# Get the dependency information from the metadata for comparison against the installed tool dependencies.
tool_dependencies = self.metadata.get( 'tool_dependencies', None )
if tool_dependencies:
for dependency_key, requirements_dict in tool_dependencies.items():
name = requirements_dict[ 'name' ]
version = requirements_dict[ 'version' ]
type = requirements_dict[ 'type' ]
if self.tool_dependencies:
found = False
for tool_dependency in self.tool_dependencies:
if tool_dependency.name==name and tool_dependency.version==version and tool_dependency.type==type:
found = True
if tool_dependency.uninstalled:
missing_dependencies.append( ( tool_dependency.name, tool_dependency.version, tool_dependency.type ) )
break
if not found:
missing_dependencies.append( ( name, version, type ) )
for tool_dependency in self.tool_dependencies:
if tool_dependency.status in [ ToolDependency.installation_status.NEVER_INSTALLED,
ToolDependency.installation_status.ERROR,
ToolDependency.installation_status.UNINSTALLED ]:
missing_dependencies.append( tool_dependency )
return missing_dependencies
@property
def tool_dependencies_being_installed( self ):
dependencies_being_installed = []
for tool_dependency in self.tool_dependencies:
if tool_dependency.status == ToolDependency.installation_status.INSTALLING:
dependencies_being_installed.append( tool_dependency )
return dependencies_being_installed
@property
def tool_dependencies_with_installation_errors( self ):
dependencies_with_installation_errors = []
for tool_dependency in self.tool_dependencies:
if tool_dependency.status == ToolDependency.installation_status.ERROR:
dependencies_with_installation_errors.append( tool_dependency )
return dependencies_with_installation_errors
@property
def uninstalled_tool_dependencies( self ):
"""Return the repository's tool dependencies that have been uninstalled."""
uninstalled_tool_dependencies = []
for tool_dependency in self.tool_dependencies:
if tool_dependency.uninstalled:
if tool_dependency.status == ToolDependency.installation_status.UNINSTALLED:
uninstalled_tool_dependencies.append( tool_dependency )
return uninstalled_tool_dependencies
class ToolDependency( object ):
def __init__( self, tool_shed_repository_id=None, name=None, version=None, type=None, uninstalled=False ):
installation_status = Bunch( NEVER_INSTALLED='Never installed',
INSTALLING='Installing',
INSTALLED='Installed',
ERROR='Error',
UNINSTALLED='Uninstalled' )
states = Bunch( INSTALLING = 'running',
OK = 'ok',
ERROR = 'error',
UNINSTALLED = 'deleted_new' )
def __init__( self, tool_shed_repository_id=None, name=None, version=None, type=None, status=None, error_message=None ):
self.tool_shed_repository_id = tool_shed_repository_id
self.name = name
self.version = version
self.type = type
self.uninstalled = uninstalled
self.status = status
self.error_message = error_message
def installation_directory( self, app ):
return os.path.join( app.config.tool_dependency_dir,
self.name,
+2 -1
View File
@@ -398,7 +398,8 @@ ToolDependency.table = Table( "tool_dependency", metadata,
Column( "name", TrimmedString( 255 ) ),
Column( "version", Text ),
Column( "type", TrimmedString( 40 ) ),
Column( "uninstalled", Boolean, default=False ) )
Column( "status", TrimmedString( 255 ), nullable=False ),
Column( "error_message", TEXT ) )
ToolVersion.table = Table( "tool_version", metadata,
Column( "id", Integer, primary_key=True ),
@@ -0,0 +1,63 @@
"""
Migration script to add status and error_message columns to the tool_dependency table and drop the uninstalled column from the tool_dependency table.
"""
from sqlalchemy import *
from sqlalchemy.orm import *
from migrate import *
from migrate.changeset import *
import datetime
now = datetime.datetime.utcnow
# Need our custom types, but don't import anything else from model
from galaxy.model.custom_types import *
import sys, logging
log = logging.getLogger( __name__ )
log.setLevel(logging.DEBUG)
handler = logging.StreamHandler( sys.stdout )
format = "%(name)s %(levelname)s %(asctime)s %(message)s"
formatter = logging.Formatter( format )
handler.setFormatter( formatter )
log.addHandler( handler )
metadata = MetaData( migrate_engine )
db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) )
def upgrade():
print __doc__
metadata.reflect()
ToolDependency_table = Table( "tool_dependency", metadata, autoload=True )
col = Column( "status", TrimmedString( 255 ), nullable=False )
try:
col.create( ToolDependency_table )
assert col is ToolDependency_table.c.status
except Exception, e:
print "Adding status column to the tool_dependency table failed: %s" % str( e )
col = Column( "error_message", TEXT )
try:
col.create( ToolDependency_table )
assert col is ToolDependency_table.c.error_message
except Exception, e:
print "Adding error_message column to the tool_dependency table failed: %s" % str( e )
try:
ToolDependency_table.c.uninstalled.drop()
except Exception, e:
print "Dropping uninstalled column from the tool_dependency table failed: %s" % str( e )
def downgrade():
metadata.reflect()
ToolDependency_table = Table( "tool_dependency", metadata, autoload=True )
try:
ToolDependency_table.c.status.drop()
except Exception, e:
print "Dropping column status from the tool_dependency table failed: %s" % str( e )
try:
ToolDependency_table.c.error_message.drop()
except Exception, e:
print "Dropping column error_message from the tool_dependency table failed: %s" % str( e )
col = Column( "uninstalled", Boolean, default=False )
try:
col.create( ToolDependency_table )
assert col is ToolDependency_table.c.uninstalled
except Exception, e:
print "Adding uninstalled column to the tool_dependency table failed: %s" % str( e )
+1 -2
View File
@@ -7,7 +7,6 @@ from galaxy.tools import ToolSection
from galaxy.util.json import from_json_string, to_json_string
from galaxy.util.shed_util import *
from galaxy.util.odict import odict
from galaxy.tool_shed.migrate.common import *
REPOSITORY_OWNER = 'devteam'
@@ -177,7 +176,7 @@ class InstallManager( object ):
status, message = handle_tool_dependencies( app=self.app,
tool_shed_repository=tool_shed_repository,
tool_dependencies_config=tool_dependencies_config )
if status != 'ok' and message:
if status != 'done' and message:
print 'The following error occurred from the InstallManager while installing tool dependencies:'
print message
add_to_tool_panel( self.app,
@@ -1,10 +1,6 @@
import os, shutil, tarfile, urllib2
from galaxy.datatypes.checkers import *
MISCELLANEOUS_ACTIONS = [ 'change_directory' ]
MOVE_ACTIONS = [ 'move_directory_files', 'move_file' ]
ALL_ACTIONS = MISCELLANEOUS_ACTIONS + MOVE_ACTIONS
def extract_tar( file_name, file_path ):
if isgzip( file_name ) or isbz2( file_name ):
# Open for reading with transparent compression.
@@ -13,6 +13,8 @@ pkg_resources.require( 'Fabric' )
from fabric.api import env, lcd, local, settings
INSTALLATION_LOG = 'INSTALLATION.log'
def check_fabric_version():
version = env.version
if int( version.split( "." )[ 0 ] ) < 1:
@@ -32,16 +34,19 @@ def make_tmp_dir():
yield work_dir
if os.path.exists( work_dir ):
local( 'rm -rf %s' % work_dir )
def handle_post_build_processing( tool_dependency_dir, install_dir, env_dependency_path, package_name=None ):
def handle_post_build_processing( app, tool_dependency, install_dir, env_dependency_path, package_name=None ):
sa_session = app.model.context.current
cmd = "echo 'PATH=%s:$PATH; export PATH' > %s/env.sh;chmod +x %s/env.sh" % ( env_dependency_path, install_dir, install_dir )
message = ''
output = local( cmd, capture=True )
log_results( cmd, output, os.path.join( install_dir, 'env_sh.log' ) )
log_results( cmd, output, os.path.join( install_dir, INSTALLATION_LOG ) )
if output.return_code:
message = '%s %s' % ( message, str( output.stderr ) )
return message
def install_and_build_package( params_dict ):
tool_dependency.status = app.model.ToolDependency.installation_status.ERROR
tool_dependency.error_message = str( output.stderr )
sa_session.add( tool_dependency )
sa_session.flush()
def install_and_build_package( app, tool_dependency, params_dict ):
"""Install a Galaxy tool dependency package either via a url or a mercurial or git clone command."""
sa_session = app.model.context.current
install_dir = params_dict[ 'install_dir' ]
download_url = params_dict.get( 'download_url', None )
clone_cmd = params_dict.get( 'clone_cmd', None )
@@ -59,43 +64,38 @@ def install_and_build_package( params_dict ):
dir = work_dir
elif clone_cmd:
output = local( clone_cmd, capture=True )
log_results( clone_cmd, output, os.path.join( install_dir, 'clone_repository.log' ) )
log_results( clone_cmd, output, os.path.join( install_dir, INSTALLATION_LOG ) )
if output.return_code:
return '%s. ' % str( output.stderr )
tool_dependency.status = app.model.ToolDependency.installation_status.ERROR
tool_dependency.error_message = str( output.stderr )
sa_session.add( tool_dependency )
sa_session.flush()
return
dir = package_name
if actions:
with lcd( dir ):
current_dir = os.path.abspath( os.path.join( work_dir, dir ) )
for action_tup in actions:
action_key, action_dict = action_tup
if action_key.find( 'v^v^v' ) >= 0:
action_items = action_key.split( 'v^v^v' )
action_name = action_items[ 0 ]
action = action_items[ 1 ]
elif action_key in common_util.ALL_ACTIONS:
action_name = action_key
else:
action_name = None
if action_name:
if action_name == 'change_directory':
current_dir = os.path.join( current_dir, action )
lcd( current_dir )
elif action_name == 'move_directory_files':
common_util.move_directory_files( current_dir=current_dir,
source_dir=os.path.join( action_dict[ 'source_directory' ] ),
destination_dir=os.path.join( action_dict[ 'destination_directory' ] ) )
elif action_name == 'move_file':
common_util.move_file( current_dir=current_dir,
source=os.path.join( action_dict[ 'source' ] ),
destination_dir=os.path.join( action_dict[ 'destination' ] ) )
if action_key == 'move_directory_files':
common_util.move_directory_files( current_dir=current_dir,
source_dir=os.path.join( action_dict[ 'source_directory' ] ),
destination_dir=os.path.join( action_dict[ 'destination_directory' ] ) )
elif action_key == 'move_file':
common_util.move_file( current_dir=current_dir,
source=os.path.join( action_dict[ 'source' ] ),
destination_dir=os.path.join( action_dict[ 'destination' ] ) )
else:
action = action_key
with settings( warn_only=True ):
output = local( action, capture=True )
log_results( action, output, os.path.join( install_dir, 'actions.log' ) )
log_results( action, output, os.path.join( install_dir, INSTALLATION_LOG ) )
if output.return_code:
return '%s. ' % str( output.stderr )
return ''
tool_dependency.status = app.model.ToolDependency.installation_status.ERROR
tool_dependency.error_message = str( output.stderr )
sa_session.add( tool_dependency )
sa_session.flush()
return
def log_results( command, fabric_AttributeString, file_path ):
"""
Write attributes of fabric.operations._AttributeString (which is the output of executing command using fabric's local() method)
@@ -105,12 +105,12 @@ def log_results( command, fabric_AttributeString, file_path ):
logfile = open( file_path, 'ab' )
else:
logfile = open( file_path, 'wb' )
logfile.write( "\n#############################################" )
logfile.write( '\n%s\nSTDOUT\n' % command )
logfile.write( "\n#############################################\n" )
logfile.write( '%s\nSTDOUT\n' % command )
logfile.write( str( fabric_AttributeString.stdout ) )
logfile.write( "#############################################\n" )
logfile.write( "\n#############################################" )
logfile.write( '\n%s\nSTDERR\n' % command )
logfile.write( "\n#############################################\n" )
logfile.write( "\n#############################################\n" )
logfile.write( '%s\nSTDERR\n' % command )
logfile.write( str( fabric_AttributeString.stderr ) )
logfile.write( "#############################################\n" )
logfile.write( "\n#############################################\n" )
logfile.close()
@@ -11,19 +11,16 @@ pkg_resources.require( 'elementtree' )
from elementtree import ElementTree, ElementInclude
from elementtree.ElementTree import Element, SubElement
def create_or_update_tool_dependency( app, tool_shed_repository, name, version, type ):
def create_or_update_tool_dependency( app, tool_shed_repository, name, version, type, status ):
# Called from Galaxy (never the tool shed) when a new repository is being installed or when an uninstalled repository is being reinstalled.
# First see if an appropriate tool_dependency record exists for the received tool_shed_repository.
sa_session = app.model.context.current
# First see if an appropriate tool_dependency record exists for the received tool_shed_repository.
tool_dependency = get_tool_dependency_by_name_version_type_repository( app, tool_shed_repository, name, version, type )
if tool_dependency:
tool_dependency.uninstalled = False
tool_dependency.status = status
else:
# Create a new tool_dependency record for the tool_shed_repository.
tool_dependency = app.model.ToolDependency( tool_shed_repository_id=tool_shed_repository.id,
name=name,
version=version,
type=type )
tool_dependency = app.model.ToolDependency( tool_shed_repository.id, name, version, type, status )
sa_session.add( tool_dependency )
sa_session.flush()
return tool_dependency
@@ -42,14 +39,15 @@ def get_tool_dependency_install_dir( app, repository, package_name, package_vers
repository.owner,
repository.name,
repository.installed_changeset_revision ) )
def install_package( app, elem, tool_shed_repository, name=None, version=None ):
# If name and version are not None, then a specific tool dependency is being installed.
message = ''
def install_package( app, elem, tool_shed_repository, tool_dependencies=None ):
# The value of tool_dependencies is a partial or full list of ToolDependency records associated with the tool_shed_repository.
sa_session = app.model.context.current
tool_dependency = None
# The value of package_name should match the value of the "package" type in the tool config's <requirements> tag set, but it's not required.
package_name = elem.get( 'name', None )
package_version = elem.get( 'version', None )
if package_name and package_version:
if ( not name and not version ) or ( name and version and name==package_name and version==package_version ):
if tool_dependencies:
install_dir = get_tool_dependency_install_dir( app, tool_shed_repository, package_name, package_version )
if not os.path.exists( install_dir ):
for package_elem in elem:
@@ -66,26 +64,22 @@ def install_package( app, elem, tool_shed_repository, name=None, version=None ):
# Handle tool dependency installation using a fabric method included in the Galaxy framework.
fabfile_path = None
for method_elem in package_elem:
error_message = run_fabric_method( app,
method_elem,
fabfile_path,
app.config.tool_dependency_dir,
install_dir,
package_name=package_name )
if error_message:
message += '%s' % error_message
else:
tool_dependency = create_or_update_tool_dependency( app,
tool_shed_repository,
name=package_name,
version=package_version,
type='package' )
tool_dependency = create_or_update_tool_dependency( app,
tool_shed_repository,
name=package_name,
version=package_version,
type='package',
status=app.model.ToolDependency.installation_status.INSTALLING )
run_fabric_method( app, tool_dependency, method_elem, fabfile_path, install_dir, package_name=package_name )
sa_session.refresh( tool_dependency )
if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR:
print package_name, 'version', package_version, 'installed in', install_dir
else:
print '\nSkipping installation of tool dependency', package_name, 'version', package_version, 'since it is installed in', install_dir, '\n'
return message
def run_fabric_method( app, elem, fabfile_path, tool_dependency_dir, install_dir, package_name=None, **kwd ):
return tool_dependency
def run_fabric_method( app, tool_dependency, elem, fabfile_path, install_dir, package_name=None, **kwd ):
"""Parse a tool_dependency.xml file's fabfile <method> tag set to build the method parameters and execute the method."""
sa_session = app.model.context.current
if not os.path.exists( install_dir ):
os.makedirs( install_dir )
# Default value for env_dependency_path.
@@ -109,7 +103,7 @@ def run_fabric_method( app, elem, fabfile_path, tool_dependency_dir, install_dir
action_key = action_elem.text.replace( '$INSTALL_DIR', install_dir )
if not action_key:
continue
elif action_type in MOVE_ACTIONS:
elif action_type in [ 'move_directory_files', 'move_file' ]:
# Examples:
# <action type="move_file">
# <source>misc/some_file</source>
@@ -124,9 +118,6 @@ def run_fabric_method( app, elem, fabfile_path, tool_dependency_dir, install_dir
move_elem_text = move_elem.text.replace( '$INSTALL_DIR', install_dir )
if move_elem_text:
action_dict[ move_elem.tag ] = move_elem_text
elif action_elem.text:
# Example: <action type="change_directory">bin</action>
action_key = '%sv^v^v%s' % ( action_type, action_elem.text )
else:
continue
actions.append( ( action_key, action_dict ) )
@@ -141,24 +132,36 @@ def run_fabric_method( app, elem, fabfile_path, tool_dependency_dir, install_dir
params_dict[ 'package_name' ] = package_name
if fabfile_path:
# TODO: Handle this using the fabric api.
# run_proprietary_fabric_method( app, elem, fabfile_path, tool_dependency_dir, install_dir, package_name=package_name )
# run_proprietary_fabric_method( app, elem, fabfile_path, install_dir, package_name=package_name )
return 'Tool dependency installation using proprietary fabric scripts is not yet supported. '
else:
# There is currently only 1 fabric method, install_and_build_package().
try:
message = install_and_build_package( params_dict )
if message:
return message
install_and_build_package( app, tool_dependency, params_dict )
except Exception, e:
return '%s. ' % str( e )
try:
message = handle_post_build_processing( tool_dependency_dir, install_dir, env_dependency_path, package_name=package_name )
if message:
return message
except:
return '%s. ' % str( e )
return ''
def run_proprietary_fabric_method( app, elem, fabfile_path, tool_dependency_dir, install_dir, package_name=None, **kwd ):
tool_dependency.status = app.model.ToolDependency.installation_status.ERROR
tool_dependency.error_message = str( e )
sa_session.add( tool_dependency )
sa_session.flush()
sa_session.refresh( tool_dependency )
if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR:
try:
handle_post_build_processing( app,
tool_dependency,
install_dir,
env_dependency_path,
package_name=package_name )
except Exception, e:
tool_dependency.status = app.model.ToolDependency.installation_status.ERROR
tool_dependency.error_message = str( e )
sa_session.add( tool_dependency )
sa_session.flush()
sa_session.refresh( tool_dependency )
if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR:
tool_dependency.status = app.model.ToolDependency.installation_status.INSTALLED
sa_session.add( tool_dependency )
sa_session.flush()
def run_proprietary_fabric_method( app, elem, fabfile_path, install_dir, package_name=None, **kwd ):
"""
TODO: Handle this using the fabric api.
Parse a tool_dependency.xml file's fabfile <method> tag set to build the method parameters and execute the method.
@@ -193,7 +196,7 @@ def run_proprietary_fabric_method( app, elem, fabfile_path, tool_dependency_dir,
return "Exception executing fabric script %s: %s. " % ( str( fabfile_path ), str( e ) )
if returncode:
return message
message = handle_post_build_processing( tool_dependency_dir, install_dir, env_dependency_path, package_name=package_name )
message = handle_post_build_processing( app, tool_dependency, install_dir, env_dependency_path, package_name=package_name )
if message:
return message
else:
+59 -30
View File
@@ -6,7 +6,7 @@ from galaxy import util
from galaxy.datatypes.checkers import *
from galaxy.util.json import *
from galaxy.tools.search import ToolBoxSearch
from galaxy.tool_shed.tool_dependencies.install_util import install_package
from galaxy.tool_shed.tool_dependencies.install_util import create_or_update_tool_dependency, install_package
from galaxy.tool_shed.encoding_util import *
from galaxy.model.orm import *
@@ -318,8 +318,8 @@ def create_or_update_tool_shed_repository( app, name, description, installed_cha
# to be in the Galaxy distribution, but have been moved to the main Galaxy tool shed.
if current_changeset_revision is None:
# The current_changeset_revision is not passed if a repository is being installed for the first time. If a previously installed repository
# was later uninstalled, this value should be received as the value of that change set to which the repository had been updated just prior to
# it being uninstalled.
# was later uninstalled, this value should be received as the value of that change set to which the repository had been updated just prior
# to it being uninstalled.
current_changeset_revision = installed_changeset_revision
sa_session = app.model.context.current
tool_shed = get_tool_shed_from_clone_url( repository_clone_url )
@@ -353,6 +353,37 @@ def create_or_update_tool_shed_repository( app, name, description, installed_cha
sa_session.add( tool_shed_repository )
sa_session.flush()
return tool_shed_repository
def create_tool_dependency_objects( app, tool_shed_repository, current_changeset_revision ):
# Create or update a ToolDependency for each entry in tool_dependencies_config. This method is called when installing a new tool_shed_repository.
tool_dependency_objects = []
work_dir = make_tmp_directory()
# Get the tool_dependencies.xml file from the repository.
tool_dependencies_config = get_config_from_repository( app,
'tool_dependencies.xml',
tool_shed_repository,
current_changeset_revision,
work_dir )
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:
tool_dependency = create_or_update_tool_dependency( app,
tool_shed_repository,
name=package_name,
version=package_version,
type='package',
status=app.model.ToolDependency.installation_status.NEVER_INSTALLED )
tool_dependency_objects.append( tool_dependency )
try:
shutil.rmtree( work_dir )
except:
pass
return tool_dependency_objects
def generate_clone_url( trans, repository ):
"""Generate the URL for cloning a repository."""
tool_shed_url = get_url_from_repository_tool_shed( trans.app, repository )
@@ -1163,7 +1194,7 @@ def handle_sample_tool_data_table_conf_file( app, filename, persist=False ):
message = str( e )
error = True
return error, message
def handle_tool_dependencies( app, tool_shed_repository, tool_dependencies_config, name=None, version=None, type='package' ):
def handle_tool_dependencies( app, tool_shed_repository, tool_dependencies_config, tool_dependencies=None ):
"""
Install and build tool dependencies defined in the tool_dependencies_config. This config's tag sets can currently refer to installation
methods in Galaxy's tool_dependencies module. In the future, proprietary fabric scripts contained in the repository will be supported.
@@ -1171,7 +1202,7 @@ def handle_tool_dependencies( app, tool_shed_repository, tool_dependencies_confi
will be installed in:
~/<app.config.tool_dependency_dir>/<package_name>/<package_version>/<repo_owner>/<repo_name>/<repo_installed_changeset_revision>
"""
status = 'ok'
status = 'done'
message = ''
# Parse the tool_dependencies.xml config.
tree = ElementTree.parse( tool_dependencies_config )
@@ -1179,12 +1210,24 @@ def handle_tool_dependencies( app, tool_shed_repository, tool_dependencies_confi
ElementInclude.include( root )
fabric_version_checked = False
for elem in root:
if elem.tag == type:
error_message = install_package( app, elem, tool_shed_repository, name=name, version=version )
if error_message:
message += ' %s' % error_message
if message:
status = 'error'
if elem.tag == 'package':
package_name = elem.get( 'name', None )
package_version = elem.get( 'version', None )
if package_name and package_version:
can_install = True
if tool_dependencies:
# Only install the package if it is not already installed.
can_install = False
for tool_dependency in tool_dependencies:
if tool_dependency.name==package_name and tool_dependency.version==package_version:
can_install = tool_dependency.status in [ app.model.ToolDependency.installation_status.NEVER_INSTALLED,
app.model.ToolDependency.installation_status.UNINSTALLED ]
break
if can_install:
tool_dependency = install_package( app, elem, tool_shed_repository, tool_dependencies=tool_dependencies )
if tool_dependency and tool_dependency.status == app.model.ToolDependency.installation_status.ERROR:
message = tool_dependency.error_message
status = 'error'
return status, message
def handle_tool_versions( app, tool_version_dicts, tool_shed_repository ):
"""
@@ -1247,13 +1290,11 @@ def load_installed_display_applications( installed_repository_dict, deactivate=F
# Load or deactivate proprietary datatype display applications
app.datatypes_registry.load_display_applications( installed_repository_dict=installed_repository_dict, deactivate=deactivate )
def load_repository_contents( trans, repository_name, description, owner, installed_changeset_revision, current_changeset_revision, ctx_rev,
tool_path, repository_clone_url, relative_install_dir, tool_shed=None, tool_section=None, shed_tool_conf=None,
install_tool_dependencies=False ):
tool_path, repository_clone_url, relative_install_dir, tool_shed=None, tool_section=None, shed_tool_conf=None ):
"""
Generate the metadata for the installed tool shed repository, among other things. This method is called from Galaxy (never the tool shed)
when an admin is installing a new repository or reinstalling an uninstalled repository.
"""
message = ''
metadata_dict = generate_metadata_using_disk_files( trans.app.toolbox, relative_install_dir, repository_clone_url )
# Add a new record to the tool_shed_repository table if one doesn't already exist. If one exists but is marked deleted, undelete it. This
# must happen before the call to add_to_tool_panel() below because tools will not be properly loaded if the repository is marked deleted.
@@ -1285,20 +1326,6 @@ def load_repository_contents( trans, repository_name, description, owner, instal
repository_tools_tups, sample_files_copied = handle_missing_index_file( trans.app, tool_path, sample_files, repository_tools_tups )
# Copy remaining sample files included in the repository to the ~/tool-data directory of the local Galaxy instance.
copy_sample_files( trans.app, sample_files, sample_files_copied=sample_files_copied )
if install_tool_dependencies and 'tool_dependencies' in metadata_dict:
# Get the tool_dependencies.xml file from the repository.
tool_dependencies_config = get_config_from_repository( trans.app,
'tool_dependencies.xml',
tool_shed_repository,
current_changeset_revision,
work_dir )
# Install dependencies for repository tools.
status, message = handle_tool_dependencies( app=trans.app,
tool_shed_repository=tool_shed_repository,
tool_dependencies_config=tool_dependencies_config )
if status != 'ok' and message:
print 'The following error occurred from load_repository_contents while installing tool dependencies:'
print message
add_to_tool_panel( app=trans.app,
repository_name=repository_name,
repository_clone_url=repository_clone_url,
@@ -1340,7 +1367,9 @@ def load_repository_contents( trans, repository_name, description, owner, instal
shutil.rmtree( work_dir )
except:
pass
return tool_shed_repository, metadata_dict, message
if 'tool_dependencies' in metadata_dict:
tool_dependencies = create_tool_dependency_objects( trans.app, tool_shed_repository, current_changeset_revision )
return tool_shed_repository, metadata_dict
def make_tmp_directory():
tmp_dir = os.getenv( 'TMPDIR', '' )
if tmp_dir:
@@ -1505,7 +1534,7 @@ def remove_tool_dependency( trans, tool_dependency ):
error_message = "Error removing tool dependency installation directory %s: %s" % ( str( dependency_install_dir ), str( e ) )
log.debug( error_message )
if removed:
tool_dependency.uninstalled = True
tool_dependency.status = trans.model.ToolDependency.installation_status.UNINSTALLED
trans.sa_session.add( tool_dependency )
trans.sa_session.flush()
return removed, error_message
+346 -189
View File
@@ -77,9 +77,71 @@ class RepositoryListGrid( grids.Grid ):
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( self.model_class )
class ToolDependencyGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, tool_dependency ):
return tool_dependency.name
class VersionColumn( grids.TextColumn ):
def get_value( self, trans, grid, tool_dependency ):
return tool_dependency.version
class TypeColumn( grids.TextColumn ):
def get_value( self, trans, grid, tool_dependency ):
return tool_dependency.type
class StatusColumn( grids.TextColumn ):
def get_value( self, trans, grid, tool_dependency ):
if tool_dependency.status in [ trans.model.ToolDependency.installation_status.INSTALLING ]:
return tool_dependency.status
else:
if tool_dependency.status in [ trans.model.ToolDependency.installation_status.NEVER_INSTALLED,
trans.model.ToolDependency.installation_status.UNINSTALLED ]:
bgcolor = trans.model.ToolDependency.states.UNINSTALLED
elif tool_dependency.status in [ trans.model.ToolDependency.installation_status.ERROR ]:
bgcolor = trans.model.ToolDependency.states.ERROR
elif tool_dependency.status in [ trans.model.ToolDependency.installation_status.INSTALLED ]:
bgcolor = trans.model.ToolDependency.states.OK
rval = '<div class="count-box state-color-%s" id="ToolDependencyStatus-%s">' % ( bgcolor, trans.security.encode_id( tool_dependency.id ) )
rval += '%s</div>' % tool_dependency.status
return rval
webapp = "galaxy"
title = "Tool Dependencies"
template = "admin/tool_shed_repository/tool_dependencies_grid.mako"
model_class = model.ToolDependency
default_sort_key = "-create_time"
num_rows_per_page = 50
preserve_state = True
use_paging = False
columns = [
NameColumn( "Name",
filterable="advanced" ),
VersionColumn( "Version",
filterable="advanced" ),
TypeColumn( "Type",
filterable="advanced" ),
StatusColumn( "Installation Status",
filterable="advanced" ),
]
operations = [
grids.GridOperation( "Install",
allow_multiple=True,
condition=( lambda item: item.status in [ model.ToolDependency.installation_status.NEVER_INSTALLED,
model.ToolDependency.installation_status.UNINSTALLED ] ) ),
grids.GridOperation( "Uninstall",
allow_multiple=True,
allow_popup=False,
condition=( lambda item: item.status in [ model.ToolDependency.installation_status.INSTALLED,
model.ToolDependency.installation_status.ERROR ] ) )
]
def apply_query_filter( self, trans, query, **kwd ):
tool_dependency_id = kwd.get( 'tool_dependency_id', None )
if not tool_dependency_id:
return query
return query.filter_by( tool_dependency_id=trans.security.decode_id( tool_dependency_id ) )
class AdminToolshed( AdminGalaxy ):
repository_list_grid = RepositoryListGrid()
tool_dependency_grid = ToolDependencyGrid()
@web.expose
@web.require_admin
@@ -153,9 +215,8 @@ class AdminToolshed( AdminGalaxy ):
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
tool_dependency = get_tool_dependency( trans, kwd[ 'id' ] )
repository = get_repository( trans, kwd[ 'repository_id' ] )
return trans.fill_template( '/admin/tool_shed_repository/browse_tool_dependency.mako',
repository=repository,
repository=tool_dependency.tool_shed_repository,
tool_dependency=tool_dependency,
message=message,
status=status )
@@ -187,6 +248,35 @@ class AdminToolshed( AdminGalaxy ):
return trans.response.send_redirect( url )
@web.expose
@web.require_admin
def confirm_tool_dependency_install( self, trans, **kwd ):
"""Display a page enabling the Galaxy administrator to choose to install tool dependencies for a tool shed repository they are installing."""
# This method is called from the tool shed (never Galaxy) when a tool shed repository that includes a file named tool_dependencies.xml
# is being installed into a local Galaxy instance.
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
tool_shed_url = kwd[ 'tool_shed_url' ]
repo_info_dict = kwd[ 'repo_info_dict' ]
includes_tools = util.string_as_bool( kwd.get( 'includes_tools', False ) )
# Decode the encoded repo_info_dict param value.
dict_with_tool_dependencies = tool_shed_decode( repo_info_dict )
# The repo_info_dict includes tool dependencies which we need to display so the user knows what will be installed.
new_repo_info_dict = {}
for name, repo_info_tuple in dict_with_tool_dependencies.items():
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, tool_dependencies = repo_info_tuple
# Create a new repo_info_dict by eliminating tool-dependencies from the repo_info_tuple.
new_repo_info_dict[ name ] = ( description, repository_clone_url, changeset_revision, ctx_rev )
repo_info_dict = tool_shed_encode( new_repo_info_dict )
install_tool_dependencies_check_box = CheckboxField( 'install_tool_dependencies', checked=True )
return trans.fill_template( '/admin/tool_shed_repository/confirm_tool_dependency_install.mako',
tool_shed_url=tool_shed_url,
repo_info_dict=repo_info_dict,
dict_with_tool_dependencies=dict_with_tool_dependencies,
includes_tools=includes_tools,
install_tool_dependencies_check_box=install_tool_dependencies_check_box,
message=message,
status=status )
@web.expose
@web.require_admin
def deactivate_or_uninstall_repository( self, trans, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
@@ -270,71 +360,33 @@ class AdminToolshed( AdminGalaxy ):
return get_repository_file_contents( file_path )
@web.expose
@web.require_admin
def install_missing_tool_dependencies( self, trans, **kwd ):
"""
Install dependencies for tools included in the repository that were not installed when the repository was installed or that are
being reinstalled after the repository was uninstalled.
"""
reinstalling = util.string_as_bool( kwd.get( 'reinstalling', False ) )
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository = get_repository( trans, kwd[ 'id' ] )
install_tool_dependencies = CheckboxField.is_checked( kwd.get( 'install_tool_dependencies', '' ) )
if not reinstalling and install_tool_dependencies and kwd.get( 'install_missing_tool_dependencies_button', False ):
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 ) )
# 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 )
status, message = handle_tool_dependencies( app=trans.app,
tool_shed_repository=repository,
tool_dependencies_config=tool_dependencies_config )
try:
shutil.rmtree( work_dir )
except:
pass
return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako',
repository=repository,
description=repository.description,
repo_files_dir=repo_files_dir,
message=message,
status=status )
if reinstalling and kwd.get( 'install_missing_tool_dependencies_button', False ):
# The user has been presented the option to install tool dependencies, so redirect to reinstall the repository, sending
# along the user's choice.
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='reinstall_repository',
**kwd ) )
tool_dependencies = repository.metadata[ 'tool_dependencies' ]
install_tool_dependencies_check_box = CheckboxField( 'install_tool_dependencies', checked=True )
if not reinstalling:
# Filter the tool_dependencies dictionary to eliminate successfully installed dependencies.
filtered_tool_dependencies = {}
for missing_dependency_tup in repository.missing_tool_dependencies:
name, version, type = missing_dependency_tup
dependency_key = '%s/%s' % ( name, version )
install_dir = get_tool_dependency_install_dir( trans.app, repository, name, version )
filtered_tool_dependencies[ dependency_key ] = dict( name=name, type=type, version=version )
tool_dependencies = filtered_tool_dependencies
no_changes = kwd.get( 'no_changes', '' )
no_changes_checked = CheckboxField.is_checked( no_changes )
new_tool_panel_section = kwd.get( 'new_tool_panel_section', '' )
tool_panel_section = kwd.get( 'tool_panel_section', '' )
return trans.fill_template( '/admin/tool_shed_repository/install_missing_tool_dependencies.mako',
repository=repository,
reinstalling=reinstalling,
tool_dependencies=tool_dependencies,
no_changes_checked=no_changes_checked,
new_tool_panel_section=new_tool_panel_section,
tool_panel_section=tool_panel_section,
install_tool_dependencies_check_box=install_tool_dependencies_check_box,
message=message,
status=status )
def initiate_tool_dependency_installation( self, trans, tool_dependencies ):
"""Install specified dependencies for repository tools."""
# Get the tool_shed_repository from one of the tool_dependencies.
tool_shed_repository = tool_dependencies[ 0 ].tool_shed_repository
work_dir = make_tmp_directory()
# Get the tool_dependencies.xml file from the repository.
tool_dependencies_config = get_config_from_repository( trans.app,
'tool_dependencies.xml',
tool_shed_repository,
tool_shed_repository.changeset_revision,
work_dir )
status, message = handle_tool_dependencies( app=trans.app,
tool_shed_repository=tool_shed_repository,
tool_dependencies_config=tool_dependencies_config,
tool_dependencies=tool_dependencies )
try:
shutil.rmtree( work_dir )
except:
pass
tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in tool_dependencies ]
if not message:
message = "Installed tool dependencies: %s" % ','.join( td.name for td in tool_dependencies )
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_tool_dependencies',
tool_dependency_ids=tool_dependency_ids,
message=message,
status=status ) )
@web.expose
@web.require_admin
def install_repository( self, trans, **kwd ):
@@ -413,23 +465,19 @@ class AdminToolshed( AdminGalaxy ):
clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev )
owner = get_repository_owner( clean_repository_clone_url( repository_clone_url ) )
tool_shed = clean_tool_shed_url( tool_shed_url )
tool_shed_repository, metadata_dict, error_message = load_repository_contents( trans,
repository_name=name,
description=description,
owner=owner,
installed_changeset_revision=changeset_revision,
current_changeset_revision=changeset_revision,
ctx_rev=ctx_rev,
tool_path=tool_path,
repository_clone_url=repository_clone_url,
relative_install_dir=relative_install_dir,
tool_shed=tool_shed,
tool_section=tool_section,
shed_tool_conf=shed_tool_conf,
install_tool_dependencies=install_tool_dependencies )
if error_message:
message += error_message
status = 'error'
tool_shed_repository, metadata_dict, = load_repository_contents( trans,
repository_name=name,
description=description,
owner=owner,
installed_changeset_revision=changeset_revision,
current_changeset_revision=changeset_revision,
ctx_rev=ctx_rev,
tool_path=tool_path,
repository_clone_url=repository_clone_url,
relative_install_dir=relative_install_dir,
tool_shed=tool_shed,
tool_section=tool_section,
shed_tool_conf=shed_tool_conf )
if 'tools' in metadata_dict:
# Get the tool_versions from the tool shed for each tool in the installed change set.
url = '%srepository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy&no_reset=true' % \
@@ -449,26 +497,28 @@ class AdminToolshed( AdminGalaxy ):
if installed_repository_names:
installed_repository_names.sort()
num_repositories_installed = len( installed_repository_names )
if install_tool_dependencies:
dependency_str = ' along with tool dependencies '
else:
dependency_str = ''
if tool_section:
message += 'Installed %d %s%sand all tools were loaded into tool panel section <b>%s</b>:<br/>Installed repositories: ' % \
message += 'Installed %d %s and all tools were loaded into tool panel section <b>%s</b>:<br/>Installed repositories: ' % \
( num_repositories_installed,
inflector.cond_plural( num_repositories_installed, 'repository' ),
dependency_str,
tool_section.name )
else:
message += 'Installed %d %s%s and all tools were loaded into the tool panel outside of any sections.<br/>Installed repositories: ' % \
message += 'Installed %d %s and all tools were loaded into the tool panel outside of any sections.<br/>Installed repositories: ' % \
( num_repositories_installed,
inflector.cond_plural( num_repositories_installed, 'repository' ),
dependency_str )
inflector.cond_plural( num_repositories_installed, 'repository' ) )
for i, repo_name in enumerate( installed_repository_names ):
if i == len( installed_repository_names ) -1:
message += '%s.<br/>' % repo_name
else:
message += '%s, ' % repo_name
if install_tool_dependencies:
tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in tool_shed_repository.missing_tool_dependencies ]
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_tool_dependencies',
operation='install',
tool_dependency_ids=tool_dependency_ids,
status=status,
message=message ) )
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='browse_repositories',
message=message,
@@ -520,61 +570,42 @@ class AdminToolshed( AdminGalaxy ):
@web.expose
@web.require_admin
def install_tool_dependencies( self, trans, **kwd ):
"""Install dependencies for tools included in the repository when the repository is being installed."""
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
tool_shed_url = kwd[ 'tool_shed_url' ]
repo_info_dict = kwd[ 'repo_info_dict' ]
includes_tools = util.string_as_bool( kwd.get( 'includes_tools', False ) )
# Decode the encoded repo_info_dict param value.
dict_with_tool_dependencies = tool_shed_decode( repo_info_dict )
# The repo_info_dict includes tool dependencies which we need to display so the user knows what will be installed.
new_repo_info_dict = {}
for name, repo_info_tuple in dict_with_tool_dependencies.items():
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, tool_dependencies = repo_info_tuple
# Create a new repo_info_dict by eliminating tool-dependencies from the repo_info_tuple.
new_repo_info_dict[ name ] = ( description, repository_clone_url, changeset_revision, ctx_rev )
repo_info_dict = tool_shed_encode( new_repo_info_dict )
install_tool_dependencies_check_box = CheckboxField( 'install_tool_dependencies', checked=True )
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
tool_dependency_ids = util.listify( params.get( 'tool_dependency_ids', None ) )
if not tool_dependency_ids:
tool_dependency_ids = util.listify( params.get( 'id', None ) )
tool_dependencies = []
for tool_dependency_id in tool_dependency_ids:
tool_dependency = get_tool_dependency( trans, tool_dependency_id )
tool_dependencies.append( tool_dependency )
if kwd.get( 'install_tool_dependencies_button', False ):
# Filter tool dependencies to only those that are installed.
tool_dependencies_for_installation = []
for tool_dependency in tool_dependencies:
if tool_dependency.status in [ trans.model.ToolDependency.installation_status.UNINSTALLED,
trans.model.ToolDependency.installation_status.ERROR ]:
tool_dependencies_for_installation.append( tool_dependency )
if tool_dependencies_for_installation:
# Redirect back to the ToolDependencyGrid before initiating installation.
tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in tool_dependencies_for_installation ]
new_kwd = dict( action='manage_tool_dependencies',
operation='initiate_tool_dependency_installation',
tool_dependency_ids=tool_dependency_ids,
message=message,
status=status )
return self.tool_dependency_grid( trans, **new_kwd )
else:
message = 'All of the selected tool dependencies are already installed.'
status = 'error'
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_tool_dependencies',
tool_dependency_ids=tool_dependency_ids,
status=status,
message=message ) )
return trans.fill_template( '/admin/tool_shed_repository/install_tool_dependencies.mako',
tool_shed_url=tool_shed_url,
repo_info_dict=repo_info_dict,
dict_with_tool_dependencies=dict_with_tool_dependencies,
includes_tools=includes_tools,
install_tool_dependencies_check_box=install_tool_dependencies_check_box,
message=message,
status=status )
@web.expose
@web.require_admin
def install_tool_dependency( self, trans, name, version, type, repository_id, **kwd ):
"""Install dependencies for tools included in the repository when the repository is being installed."""
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository = get_repository( trans, repository_id )
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 ) )
# 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 )
status, message = handle_tool_dependencies( app=trans.app,
tool_shed_repository=repository,
tool_dependencies_config=tool_dependencies_config,
name=name,
version=version,
type=type )
try:
shutil.rmtree( work_dir )
except:
pass
return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako',
repository=repository,
description=repository.description,
repo_files_dir=repo_files_dir,
tool_dependencies=tool_dependencies,
message=message,
status=status )
@web.expose
@@ -614,12 +645,79 @@ class AdminToolshed( AdminGalaxy ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
repository_id = kwd[ 'id' ]
repository = get_repository( trans, repository_id )
return trans.fill_template( '/admin/tool_shed_repository/manage_tool_dependencies.mako',
repository=repository,
message=message,
status=status )
tool_dependency_id = params.get( 'tool_dependency_id', None )
tool_dependency_ids = util.listify( params.get( 'tool_dependency_ids', None ) )
if not tool_dependency_ids:
tool_dependency_ids = util.listify( params.get( 'id', None ) )
if tool_dependency_id and tool_dependency_id not in tool_dependency_ids:
tool_dependency_ids.append( tool_dependency_id )
tool_dependencies = []
# We need a tool_shed_repository, so get it from one of the tool_dependencies.
tool_dependency = get_tool_dependency( trans, tool_dependency_ids[ 0 ] )
tool_shed_repository = tool_dependency.tool_shed_repository
self.tool_dependency_grid.title = "Tool shed repository '%s' tool dependencies" % tool_shed_repository.name
self.tool_dependency_grid.global_actions = \
[ grids.GridAction( label='Browse repository',
url_args=dict( controller='admin_toolshed',
action='browse_repository',
id=trans.security.encode_id( tool_shed_repository.id ) ) ),
grids.GridAction( label='Manage repository',
url_args=dict( controller='admin_toolshed',
action='manage_repository',
id=trans.security.encode_id( tool_shed_repository.id ) ) ),
grids.GridAction( label='Get updates',
url_args=dict( controller='admin_toolshed',
action='check_for_updates',
id=trans.security.encode_id( tool_shed_repository.id ) ) ),
grids.GridAction( label='Set tool versions',
url_args=dict( controller='admin_toolshed',
action='set_tool_versions',
id=trans.security.encode_id( tool_shed_repository.id ) ) ),
grids.GridAction( label='Deactivate or uninstall repository',
url_args=dict( controller='admin_toolshed',
action='deactivate_or_uninstall_repository',
id=trans.security.encode_id( tool_shed_repository.id ) ) ) ]
if 'operation' in kwd:
operation = kwd[ 'operation' ].lower()
if not tool_dependency_ids:
message = 'Select at least 1 tool dependency to %s.' % operation
kwd[ 'message' ] = message
kwd[ 'status' ] = 'error'
del kwd[ 'operation' ]
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_tool_dependencies',
**kwd ) )
if operation == 'browse':
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='browse_tool_dependency',
**kwd ) )
elif operation == 'uninstall':
tool_dependencies_for_uninstallation = []
for tool_dependency_id in tool_dependency_ids:
tool_dependency = get_tool_dependency( trans, tool_dependency_id )
if tool_dependency.status in [ trans.model.ToolDependency.installation_status.INSTALLED,
trans.model.ToolDependency.installation_status.ERROR ]:
tool_dependencies_for_uninstallation.append( tool_dependency )
if tool_dependencies_for_uninstallation:
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='uninstall_tool_dependencies',
**kwd ) )
else:
kwd[ 'message' ] = 'All selected tool dependencies are already uninstalled.'
kwd[ 'status' ] = 'error'
elif operation == "install":
tool_dependencies_for_installation = []
for tool_dependency_id in tool_dependency_ids:
tool_dependency = get_tool_dependency( trans, tool_dependency_id )
if tool_dependency.status in [ trans.model.ToolDependency.installation_status.NEVER_INSTALLED,
trans.model.ToolDependency.installation_status.UNINSTALLED ]:
tool_dependencies_for_installation.append( tool_dependency )
if tool_dependencies_for_installation:
self.initiate_tool_dependency_installation( trans, tool_dependencies_for_installation )
else:
kwd[ 'message' ] = 'All selected tool dependencies are already installed.'
kwd[ 'status' ] = 'error'
return self.tool_dependency_grid( trans, **kwd )
@web.json
@web.require_admin
def open_folder( self, trans, folder_path ):
@@ -710,39 +808,52 @@ class AdminToolshed( AdminGalaxy ):
tool_section = trans.app.toolbox.tool_panel[ section_key ]
else:
tool_section = None
tool_shed_repository, metadata_dict, error_message = load_repository_contents( trans,
repository_name=repository.name,
description=repository.description,
owner=repository.owner,
installed_changeset_revision=repository.installed_changeset_revision,
current_changeset_revision=current_changeset_revision,
ctx_rev=ctx_rev,
tool_path=tool_path,
repository_clone_url=repository_clone_url,
relative_install_dir=relative_install_dir,
tool_shed=repository.tool_shed,
tool_section=tool_section,
shed_tool_conf=shed_tool_conf,
install_tool_dependencies=install_tool_dependencies )
if error_message:
# We'll only have an error_message if there was a problem installing tool dependencies.
message += error_message
status = 'error'
tool_shed_repository, metadata_dict, load_repository_contents( trans,
repository_name=repository.name,
description=repository.description,
owner=repository.owner,
installed_changeset_revision=repository.installed_changeset_revision,
current_changeset_revision=current_changeset_revision,
ctx_rev=ctx_rev,
tool_path=tool_path,
repository_clone_url=repository_clone_url,
relative_install_dir=relative_install_dir,
tool_shed=repository.tool_shed,
tool_section=tool_section,
shed_tool_conf=shed_tool_conf )
repository.uninstalled = False
repository.deleted = False
trans.sa_session.add( repository )
trans.sa_session.flush()
message += 'The <b>%s</b> repository has been reinstalled. ' % repository.name
if install_tool_dependencies:
dependency_str = ' along with tool dependencies'
if error_message:
dependency_str += ', but with some errors installing the dependencies'
else:
dependency_str = ' without tool dependencies'
message += 'The <b>%s</b> repository has been reinstalled%s. ' % ( repository.name, dependency_str )
message += 'The following tool dependencies are now being installed, please wait...'
tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in tool_shed_repository.missing_tool_dependencies ]
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_tool_dependencies',
operation='install',
tool_dependency_ids=tool_dependency_ids,
status=status,
message=message ) )
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='browse_repositories',
message=message,
status=status ) )
@web.json
def repository_installation_status_updates( self, trans, id=None, status=None ):
# Avoid caching
trans.response.headers[ 'Pragma' ] = 'no-cache'
trans.response.headers[ 'Expires' ] = '0'
# Create new HTML for any that have changed
rval = {}
if id is not None and status is not None:
repository = trans.sa_session.query( trans.model.ToolShedRepository ).get( trans.security.decode_id( id ) )
if repository.status != status:
repository.status = status
rval[ id ] = { "status": repository.status,
"html_status": unicode( trans.fill_template( "admin/tool_shed_repository/repository_installation_status.mako",
repository=repository ),
'utf-8' ) }
@web.expose
@web.require_admin
def reselect_tool_panel_section( self, trans, **kwd ):
@@ -811,22 +922,62 @@ class AdminToolshed( AdminGalaxy ):
repo_files_dir=repo_files_dir,
message=message,
status=status )
@web.json
def tool_dependency_status_updates( self, trans, ids=None, status_list=None ):
# Avoid caching
trans.response.headers[ 'Pragma' ] = 'no-cache'
trans.response.headers[ 'Expires' ] = '0'
# Create new HTML for any that have changed
rval = {}
if ids is not None and status_list is not None:
ids = ids.split( "," )
status_list = status_list.split( "," )
for id, status in zip( ids, status_list ):
tool_dependency = trans.sa_session.query( trans.model.ToolDependency ).get( trans.security.decode_id( id ) )
if tool_dependency.status != status:
rval[ id ] = { "status": tool_dependency.status,
"html_status": unicode( trans.fill_template( "admin/tool_shed_repository/tool_dependency_installation_status.mako",
tool_dependency=tool_dependency ),
'utf-8' ) }
return rval
@web.expose
@web.require_admin
def uninstall_tool_dependency( self, trans, **kwd ):
def uninstall_tool_dependencies( self, trans, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
repository = get_repository( trans, kwd[ 'repository_id' ] )
tool_dependency = get_tool_dependency( trans, kwd[ 'id' ] )
uninstalled, error_message = remove_tool_dependency( trans, tool_dependency )
if uninstalled:
message = "The '%s' tool dependency has been uninstalled." % tool_dependency.name
else:
message = "Error attempting to uninstall the '%s' tool dependency: %s" % ( tool_dependency.name, error_message )
status = 'error'
return trans.fill_template( '/admin/tool_shed_repository/manage_tool_dependencies.mako',
repository=repository,
tool_dependency_ids = util.listify( params.get( 'tool_dependency_ids', None ) )
if not tool_dependency_ids:
tool_dependency_ids = util.listify( params.get( 'id', None ) )
tool_dependencies = []
for tool_dependency_id in tool_dependency_ids:
tool_dependency = get_tool_dependency( trans, tool_dependency_id )
tool_dependencies.append( tool_dependency )
if kwd.get( 'uninstall_tool_dependencies_button', False ):
errors = False
# Filter tool dependencies to only those that are installed.
tool_dependencies_for_uninstallation = []
for tool_dependency in tool_dependencies:
if tool_dependency.status in [ trans.model.ToolDependency.installation_status.INSTALLED,
trans.model.ToolDependency.installation_status.ERROR ]:
tool_dependencies_for_uninstallation.append( tool_dependency )
for tool_dependency in tool_dependencies_for_uninstallation:
uninstalled, error_message = remove_tool_dependency( trans, tool_dependency )
if error_message:
errors = True
message = '%s %s' % ( message, error_message )
if errors:
message = "Error attempting to uninstall tool dependencies: %s" % message
status = 'error'
else:
message = "These tool dependencies have been uninstalled: %s" % ','.join( td.name for td in tool_dependencies_for_uninstallation )
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
action='manage_tool_dependencies',
tool_dependency_ids=tool_dependency_ids,
status=status,
message=message ) )
return trans.fill_template( '/admin/tool_shed_repository/uninstall_tool_dependencies.mako',
tool_dependencies=tool_dependencies,
message=message,
status=status )
@web.expose
@@ -864,11 +1015,14 @@ class AdminToolshed( AdminGalaxy ):
repository.update_available = False
trans.sa_session.add( repository )
trans.sa_session.flush()
# Create tool_dependency records if necessary.
if 'tool_dependencies' in metadata_dict:
tool_dependencies = create_tool_dependency_objects( trans.app, repository, repository.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 )
if repository.missing_tool_dependencies:
message += "Select <b>Install tool dependencies</b> from the repository's pop-up menu to install tool dependencies."
message += "Click the name of one of the missing tool dependencies listed below to install tool dependencies."
else:
message = "The directory containing the installed repository named '%s' cannot be found. " % name
status = 'error'
@@ -951,3 +1105,6 @@ def build_tool_panel_section_select_field( trans ):
def get_repository( trans, id ):
"""Get a tool_shed_repository from the database via id"""
return trans.sa_session.query( trans.model.ToolShedRepository ).get( trans.security.decode_id( id ) )
def get_tool_dependency( trans, id ):
"""Get a tool_dependency from the database via id"""
return trans.sa_session.query( trans.model.ToolDependency ).get( trans.security.decode_id( id ) )
+2 -3
View File
@@ -128,18 +128,17 @@ class ToolRunner( BaseUIController ):
else:
tool_id_select_field = None
tool = tools[ 0 ]
if tool.id == job.tool_id and tool.version == job.tool_version:
if ( tool.id == job.tool_id or tool.old_id == job.tool_id ) and tool.version == job.tool_version:
tool_id_version_message = ''
elif tool.id == job.tool_id:
if job.tool_version == None:
# For some reason jobs don't always keep track of the tool version.
tool_id_version_message = ''
else:
tool_id_version_message = 'This job was initially run with tool version "%s", which is not currently available. ' % job.tool_version
if len( tools ) > 1:
tool_id_version_message = 'This job was initially run with tool version "%s", which is not currently available. ' % job.tool_version
tool_id_version_message += 'You can rerun the job with the selected tool or choose another derivation of the tool.'
else:
tool_id_version_message = 'This job was initially run with tool version "%s", which is not currently available. ' % job.tool_version
tool_id_version_message += 'You can rerun the job with this tool version, which is a derivation of the original tool.'
else:
if len( tools ) > 1:
@@ -1229,7 +1229,7 @@ class RepositoryController( BaseUIController, ItemRatings ):
encoded_repo_info_dict = encode( repo_info_dict )
if includes_tool_dependencies:
# Redirect back to local Galaxy to present the option to install tool dependencies.
url = '%sadmin_toolshed/install_tool_dependencies?tool_shed_url=%s&repo_info_dict=%s&includes_tools=%s' % \
url = '%sadmin_toolshed/confirm_tool_dependency_install?tool_shed_url=%s&repo_info_dict=%s&includes_tools=%s' % \
( galaxy_url, url_for( '/', qualified=True ), encoded_repo_info_dict, str( includes_tools ) )
else:
# Redirect back to local Galaxy to perform install.
@@ -10,7 +10,7 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "ui.core", "jquery.dynatree" )}
${common_javascripts(repository.name, repository.repo_files_directory(trans.app))}
${browse_files(repository.name, repository.repo_files_directory(trans.app))}
</%def>
<br/><br/>
@@ -21,10 +21,8 @@
<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='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or uninstall repository</a>
%if repository.tool_dependencies:
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a>
%endif
%if repository.missing_tool_dependencies:
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Install missing tool dependencies</a>
<% 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
</div>
</ul>
@@ -10,9 +10,11 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "ui.core", "jquery.dynatree" )}
${common_javascripts(tool_dependency.name, tool_dependency.installation_directory( trans.app ))}
${browse_files(tool_dependency.name, tool_dependency.installation_directory( trans.app ))}
</%def>
<% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %>
<br/><br/>
<ul class="manage-table-actions">
<li><a class="action-button" id="tool_dependency-${tool_dependency.id}-popup" class="menubutton">Repository Actions</a></li>
@@ -21,8 +23,7 @@
<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='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', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a>
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='uninstall_tool_dependency', id=trans.security.encode_id( tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">Uninstall this tool dependency</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>
</div>
</ul>
@@ -1,4 +1,4 @@
<%def name="common_javascripts(title_text, directory_path)">
<%def name="browse_files(title_text, directory_path)">
<script type="text/javascript">
$(function(){
$("#tree").ajaxComplete(function(event, XMLHttpRequest, ajaxOptions) {
@@ -66,3 +66,131 @@
});
</script>
</%def>
<%def name="dependency_status_updater()">
<script type="text/javascript">
// Tool dependency status updater - used to update the installation status on the Tool Dependencies grid.
// Looks for changes in tool dependency installation status using an async request. Keeps calling itself
// (via setTimeout) until dependency installation status is neither 'Installing' nor 'Building'.
var tool_dependency_status_updater = function ( dependency_status_list ) {
// See if there are any items left to track
var empty = true;
for ( i in dependency_status_list ) {
empty = false;
break;
}
if ( ! empty ) {
setTimeout( function() { tool_dependency_status_updater_callback( dependency_status_list ) }, 3000 );
}
};
var tool_dependency_status_updater_callback = function ( dependency_status_list ) {
var ids = []
var status_list = []
$.each( dependency_status_list, function ( id, dependency_status ) {
ids.push( id );
status_list.push( dependency_status );
});
// Make ajax call
$.ajax( {
type: "POST",
url: "${h.url_for( controller='admin_toolshed', action='tool_dependency_status_updates' )}",
dataType: "json",
data: { ids: ids.join( "," ), status_list: status_list.join( "," ) },
success : function ( data ) {
$.each( data, function( id, val ) {
// Replace HTML
var cell1 = $("#ToolDependencyStatus-" + id);
cell1.html( val.html_status );
dependency_status_list[ id ] = val.status;
});
tool_dependency_status_updater( dependency_status_list );
},
error: function() {
tool_dependency_status_updater( dependency_status_list );
}
});
};
</script>
</%def>
<%def name="tool_dependency_installation_updater()">
<%
can_update = False
if query.count():
# Get the first tool dependency to get to the tool shed repository.
tool_dependency = query[0]
tool_shed_repository = tool_dependency.tool_shed_repository
can_update = tool_shed_repository.tool_dependencies_being_installed or tool_shed_repository.missing_tool_dependencies
%>
%if can_update:
<script type="text/javascript">
// Tool dependency installation status updater
tool_dependency_status_updater( {${ ",".join( [ '"%s" : "%s"' % ( trans.security.encode_id( td.id ), td.status ) for td in query ] ) }});
</script>
%endif
</%def>
<%def name="repository_installation_status_updater()">
<script type="text/javascript">
// Tool shed repository status updater - used to update the installation status on the repository_installation.mako template.
// Looks for changes in repository installation status using an async request. Keeps calling itself (via setTimeout) until
// repository installation status is neither 'cloning', 'cloned' nor 'installing tool dependencies'.
var tool_shed_repository_status_updater = function ( repository_status_list ) {
// See if there are any items left to track
var empty = true;
for ( i in repository_status_list ) {
empty = false;
break;
}
if ( ! empty ) {
setTimeout( function() { tool_shed_repository_status_updater_callback( repository_status_list ) }, 3000 );
}
};
var tool_shed_repository_status_updater_callback = function ( repository_status_list ) {
var ids = []
var status_list = []
$.each( repository_status_list, function ( id, repository_status ) {
ids.push( id );
status_list.push( repository_status );
});
// Make ajax call
$.ajax( {
type: "POST",
url: "${h.url_for( controller='admin_toolshed', action='repository_installation_status_updates' )}",
dataType: "json",
data: { id: ids[0], status_list: status_list.join( "," ) },
success : function ( data ) {
$.each( data, function( id, val ) {
// Replace HTML
var cell1 = $("#RepositoryStatus-" + id);
cell1.html( val.html_status );
repository_status_list[ id ] = val.status;
});
tool_shed_repository_status_updater( repository_status_list );
},
error: function() {
tool_shed_repository_status_updater( repository_status_list );
}
});
};
</script>
</%def>
<%def name="repository_installation_updater()">
<%
can_update = True
if tool_shed_repository:
can_update = tool_shed_repository.status not in [ trans.model.ToolShedRepository.installation_status.INSTALLED,
trans.model.ToolShedRepository.installation_status.ERROR,
trans.model.ToolShedRepository.installation_status.UNINSTALLED ]
%>
%if can_update:
<script type="text/javascript">
// Tool shed repository installation status updater
repository_installation_status_updater( {${ ",".join( [ '"%s" : "%s"' % ( trans.security.encode_id( repository.id ), repository.status ) for repository in query ] ) }});
</script>
%endif
</%def>
@@ -0,0 +1,86 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
<% import os %>
%if message:
${render_msg( message, status )}
%endif
<div class="warningmessage">
<p>
The tool dependencies listed below can be automatically installed with the repository. Installing them provides significant
benefits and Galaxy includes various features to manage them.
</p>
<p>
Each of these dependencies may require their own build requirements (e.g., CMake, g++, etc). Galaxy will not attempt to install
these build requirements, so if any are missing from your environment tool dependency installation may partially fail. The
repository and all of it's contents will be installed in any case.
</p>
<p>
If tool dependency installation fails in any way, you can install the missing build requirements and have Galaxy attempt to install
the tool dependencies again using the <b>Install tool dependencies</b> pop-up menu option on the <b>Manage repository</b> page.
</p>
</div>
<div class="toolForm">
<div class="toolFormBody">
<form name="confirm_tool_dependency_install" id="confirm_tool_dependency_install" action="${h.url_for( controller='admin_toolshed', action='install_repository', tool_shed_url=tool_shed_url, repo_info_dict=repo_info_dict, includes_tools=includes_tools )}" method="post" >
<div style="clear: both"></div>
<div class="form-row">
<label>Install tool dependencies?</label>
${install_tool_dependencies_check_box.get_html()}
<div class="toolParamHelp" style="clear: both;">
Un-check to skip automatic installation of these tool dependencies.
</div>
</div>
<div style="clear: both"></div>
<div class="form-row">
<table class="grid">
<tr><td colspan="4" bgcolor="#D8D8D8"><b>Tool dependencies</b></td></tr>
<tr>
<th>Name</th>
<th>Version</th>
<th>Type</th>
<th>Install directory</th>
</tr>
%for repository_name, repo_info_tuple in dict_with_tool_dependencies.items():
<%
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, tool_dependencies = repo_info_tuple
%>
%for dependency_key, requirements_dict in tool_dependencies.items():
<%
name = requirements_dict[ 'name' ]
version = requirements_dict[ 'version' ]
type = requirements_dict[ 'type' ]
install_dir = os.path.join( trans.app.config.tool_dependency_dir,
name,
version,
repository_owner,
repository_name,
changeset_revision )
readme_text = requirements_dict.get( 'readme', None )
%>
%if not os.path.exists( install_dir ):
<tr>
<td>${name}</td>
<td>${version}</td>
<td>${type}</td>
<td>${install_dir}</td>
</tr>
%if readme_text:
<tr><td colspan="4" bgcolor="#FFFFCC">${name} ${version} requirements and installation information</td></tr>
<tr><td colspan="4"><pre>${readme_text}</pre></td></tr>
%endif
%endif
%endfor
%endfor
</table>
<div style="clear: both"></div>
</div>
<div class="form-row">
<input type="submit" name="confirm_tool_dependency_install_button" value="Continue"/>
</div>
</form>
</div>
</div>
@@ -86,7 +86,7 @@
* The repository's installed tool dependencies will be removed from disk.
</div>
<div class="toolParamHelp" style="clear: both;">
* Each associated tool dependency record's uninstalled column in the tool_dependency database table will be set to True.
* Each associated tool dependency record's status column in the tool_dependency database table will be set to 'Uninstalled'.
</div>
%endif
%if repository.includes_datatypes:
@@ -1,109 +0,0 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
<% import os %>
<br/><br/>
<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='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>
%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:
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">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>
%if message:
${render_msg( message, status )}
%endif
<div class="warningmessage">
<p>
Galaxy will attempt to install the missing tool dependencies listed below. Each of these dependencies may require their own build
requirements (e.g., CMake, g++, etc). Galaxy will not attempt to install these build requirements, so if any are missing from your
environment tool dependency installation may partially fail. If this happens, you can install the missing build requirements and
have Galaxy attempt to install the tool dependencies again.
</p>
</div>
<br/>
<div class="warningmessage">
<p>
Installation may take a while. <b>Always wait until a message is displayed in your browser after clicking the <b>Go</b> button below.</b>
If you get bored, watching your Galaxy server's paster log will help pass the time.
</p>
<p>
Information about the tool dependency installation process will be saved in various files named with a ".log" extension in the directory:
${trans.app.config.tool_dependency_dir}/<i>package name</i>/<i>package version</i>/${repository.owner}/${repository.name}/${repository.changeset_revision}
</p>
</div>
<br/>
<div class="toolForm">
<div class="toolFormBody">
<form name="install_missing_tool_dependencies" id="install_missing_tool_dependencies" action="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ), tool_panel_section=tool_panel_section, new_tool_panel_section=new_tool_panel_section, reinstalling=reinstalling )}" method="post" >
<div style="clear: both"></div>
<div class="form-row">
<label>Install missing tool dependencies?</label>
${install_tool_dependencies_check_box.get_html()}
<div class="toolParamHelp" style="clear: both;">
Un-check to skip installation of these missing tool dependencies.
</div>
## Fake the no_changes_check_box value.
%if no_changes_checked:
<input type="hidden" id="no_changes" name="no_changes" value="true" checked="checked"><input type="hidden" name="no_changes" value="true">
%else:
<input type="hidden" name="no_changes" value="true">
%endif
</div>
<div style="clear: both"></div>
<div class="form-row">
<table class="grid">
<tr><td colspan="4" bgcolor="#D8D8D8"><b>Missing tool dependencies</b></td></tr>
<tr>
<th>Name</th>
<th>Version</th>
<th>Type</th>
<th>Install directory</th>
</tr>
%for dependency_key, requirements_dict in tool_dependencies.items():
<%
name = requirements_dict[ 'name' ]
version = requirements_dict[ 'version' ]
type = requirements_dict[ 'type' ]
install_dir = os.path.join( trans.app.config.tool_dependency_dir,
name,
version,
repository.owner,
repository.name,
repository.changeset_revision )
readme_text = requirements_dict.get( 'readme', None )
%>
%if not os.path.exists( install_dir ):
<tr>
<td>${name}</td>
<td>${version}</td>
<td>${type}</td>
<td>${install_dir}</td>
</tr>
%if readme_text:
<tr><td colspan="4" bgcolor="#FFFFCC">${name} ${version} requirements and installation information</td></tr>
<tr><td colspan="4"><pre>${readme_text}</pre></td></tr>
%endif
%endif
%endfor
</table>
<div style="clear: both"></div>
</div>
<div class="form-row">
<input type="submit" name="install_missing_tool_dependencies_button" value="Go"/>
</div>
</form>
</div>
</div>
@@ -25,16 +25,7 @@
<div class="toolForm">
<div class="toolFormBody">
<form name="install_tool_dependenceies" id="install_tool_dependenceies" action="${h.url_for( controller='admin_toolshed', action='install_repository', tool_shed_url=tool_shed_url, repo_info_dict=repo_info_dict, includes_tools=includes_tools )}" method="post" >
<div style="clear: both"></div>
<div class="form-row">
<label>Install tool dependencies?</label>
${install_tool_dependencies_check_box.get_html()}
<div class="toolParamHelp" style="clear: both;">
Un-check to skip automatic installation of these tool dependencies.
</div>
</div>
<div style="clear: both"></div>
<form name="install_tool_dependenceies" id="install_tool_dependenceies" action="${h.url_for( controller='admin_toolshed', action='install_tool_dependencies' )}" method="post" >
<div class="form-row">
<table class="grid">
<tr><td colspan="4" bgcolor="#D8D8D8"><b>Tool dependencies</b></td></tr>
@@ -44,42 +35,46 @@
<th>Type</th>
<th>Install directory</th>
</tr>
%for repository_name, repo_info_tuple in dict_with_tool_dependencies.items():
<% tool_shed_repository = None %>
%for tool_dependency in tool_dependencies:
<input type="hidden" name="tool_dependency_ids" value="${trans.security.encode_id( tool_dependency.id )}"/>
<%
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, tool_dependencies = repo_info_tuple
readme_text = None
if tool_shed_repository is None:
tool_shed_repository = tool_dependency.tool_shed_repository
metadata = tool_shed_repository.metadata
tool_dependencies_dict = metadata[ 'tool_dependencies' ]
for key, requirements_dict in tool_dependencies_dict.items():
key_items = key.split( '/' )
key_name = key_items[ 0 ]
key_version = key_items[ 1 ]
if key_name == tool_dependency.name and key_version == tool_dependency.version:
readme_text = requirements_dict.get( 'readme', None )
install_dir = os.path.join( trans.app.config.tool_dependency_dir,
tool_dependency.name,
tool_dependency.version,
tool_shed_repository.owner,
tool_shed_repository.name,
tool_shed_repository.installed_changeset_revision )
%>
%for dependency_key, requirements_dict in tool_dependencies.items():
<%
name = requirements_dict[ 'name' ]
version = requirements_dict[ 'version' ]
type = requirements_dict[ 'type' ]
install_dir = os.path.join( trans.app.config.tool_dependency_dir,
name,
version,
repository_owner,
repository_name,
changeset_revision )
readme_text = requirements_dict.get( 'readme', None )
%>
%if not os.path.exists( install_dir ):
<tr>
<td>${name}</td>
<td>${version}</td>
<td>${type}</td>
<td>${install_dir}</td>
</tr>
%if readme_text:
<tr><td colspan="4" bgcolor="#FFFFCC">${name} ${version} requirements and installation information</td></tr>
<tr><td colspan="4"><pre>${readme_text}</pre></td></tr>
%endif
%if not os.path.exists( install_dir ):
<tr>
<td>${tool_dependency.name}</td>
<td>${tool_dependency.version}</td>
<td>${tool_dependency.type}</td>
<td>${install_dir}</td>
</tr>
%if readme_text:
<tr><td colspan="4" bgcolor="#FFFFCC">${tool_dependency.name} ${tool_dependency.version} requirements and installation information</td></tr>
<tr><td colspan="4"><pre>${readme_text}</pre></td></tr>
%endif
%endfor
%endif
%endfor
</table>
<div style="clear: both"></div>
</div>
<div class="form-row">
<input type="submit" name="install_tool_dependenceies_button" value="Continue"/>
<input type="submit" name="install_tool_dependencies_button" value="Install"/>
</div>
</form>
</div>
@@ -12,10 +12,8 @@
<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:
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a>
%endif
%if repository.missing_tool_dependencies:
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Install missing tool dependencies</a>
<% 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>
@@ -91,21 +89,15 @@
<td><b>version</b></td>
<td><b>type</b></td>
</tr>
%for index, missing_dependency_tup in enumerate( missing_tool_dependencies ):
<% name, version, type = missing_dependency_tup %>
%for tool_dependency in missing_tool_dependencies:
<tr>
<td>
<div style="float: left; margin-left: 1px;" class="menubutton split popup" id="missing_dependency-${index}-popup">
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='install_tool_dependency', name=name, version=version, type=type, repository_id=trans.security.encode_id( repository.id ) )}">
${name}
</a>
</div>
<div popupmenu="missing_dependency-${index}-popup">
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_tool_dependency', name=name, version=version, type=type, repository_id=trans.security.encode_id( repository.id ) )}">Install this dependency</a>
</div>
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( tool_dependency.id ) )}">
${tool_dependency.name}
</a>
</td>
<td>${version}</td>
<td>${type}</td>
<td>${tool_dependency.version}</td>
<td>${tool_dependency.type}</td>
</tr>
%endfor
</table>
@@ -131,14 +123,9 @@
%for installed_tool_dependency in installed_tool_dependencies:
<tr>
<td>
<div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dependency-${installed_tool_dependency.id}-popup">
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='browse_tool_dependency', id=trans.security.encode_id( installed_tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">
${installed_tool_dependency.name}
</a>
</div>
<div popupmenu="dependency-${installed_tool_dependency.id}-popup">
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='uninstall_tool_dependency', id=trans.security.encode_id( installed_tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">Uninstall this dependency</a>
</div>
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='browse_tool_dependency', id=trans.security.encode_id( installed_tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">
${installed_tool_dependency.name}
</a>
</td>
<td>${installed_tool_dependency.version}</td>
<td>${installed_tool_dependency.type}</td>
@@ -13,9 +13,6 @@
%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.missing_tool_dependencies:
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Install missing 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>
@@ -34,25 +31,25 @@
name = tool_dependency.name
version = tool_dependency.version
type = tool_dependency.type
uninstalled = tool_dependency.uninstalled
installed = tool_dependency.status == 'trans.model.ToolDependency.installation_status.INSTALLED
install_dir = tool_dependency.installation_directory( trans.app )
%>
<tr>
<td bgcolor="#D8D8D8">
<div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dependency-${tool_dependency.id}-popup">
%if uninstalled:
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='install_tool_dependency', name=name, version=version, type=type, repository_id=trans.security.encode_id( repository.id ) )}">
%if not installed:
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', operation='browse', tool_dependency_id=trans.security.encode_id( tool_dependency.id ) )}">
<b>Name</b>
</a>
<div popupmenu="dependency-${tool_dependency.id}-popup">
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_tool_dependency', name=name, version=version, type=type, repository_id=trans.security.encode_id( repository.id ) )}">Install this dependency</a>
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', operation='install', tool_dependency_id=trans.security.encode_id( tool_dependency.id ) )}">Install this tool dependency</a>
</div>
%else:
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='browse_tool_dependency', id=trans.security.encode_id( tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', operation='browse', tool_dependency_id=trans.security.encode_id( tool_dependency.id ) )}">
<b>Name</b>
</a>
<div popupmenu="dependency-${tool_dependency.id}-popup">
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='uninstall_tool_dependency', id=trans.security.encode_id( tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">Uninstall this dependency</a>
<a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', operation='uninstall', tool_dependency_id=trans.security.encode_id( tool_dependency.id ) )}">Uninstall this tool dependency</a>
</div>
%endif
</div>
@@ -64,7 +61,7 @@
<tr>
<th>Install directory</th>
<td>
%if uninstalled:
%if not installed:
This dependency is not currently installed
%else:
<a class="view-info" href="${h.url_for( controller='admin_toolshed', action='browse_tool_dependency', id=trans.security.encode_id( tool_dependency.id ), repository_id=trans.security.encode_id( repository.id ) )}">
@@ -73,7 +70,7 @@
%endif
</td>
</tr>
<tr><th>Uninstalled</th><td>${uninstalled}</td></tr>
<tr><th>Installed</th><td>${not installed}</td></tr>
%endfor
</table>
<div style="clear: both"></div>
@@ -8,8 +8,9 @@
<div class="toolForm">
<div class="toolFormTitle">Choose the tool panel section to contain the installed tools (optional)</div>
<div class="toolFormBody">
%if repository.includes_tool_dependencies:
<form name="reselect_tool_panel_section" id="reselect_tool_panel_section" action="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ), reinstalling=True )}" method="post" >
%if repository.tool_dependencies:
<% tool_dependency_ids = [ trans.security.encode_id( td.id ) for td in repository.tool_dependencies ] %>
<form name="reselect_tool_panel_section" id="reselect_tool_panel_section" action="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', operation='install', tool_dependency_ids=tool_dependency_ids )}" method="post" >
%else:
<form name="reselect_tool_panel_section" id="reselect_tool_panel_section" action="${h.url_for( controller='admin_toolshed', action='reinstall_repository', id=trans.security.encode_id( repository.id ) )}" method="post" >
%endif
@@ -78,6 +78,7 @@
<div class="toolForm">
<div class="toolFormTitle">Repository README file (may contain important installation or license information)</div>
<div class="toolFormBody">
<input type="hidden" name="readme_text" value="${readme_text}"/>
<div class="form-row">
<pre>${readme_text}</pre>
</div>
@@ -0,0 +1,8 @@
<%inherit file="/grid_base.mako"/>
<%namespace file="/admin/tool_shed_repository/common.mako" import="*" />
<%def name="javascripts()">
${parent.javascripts()}
${dependency_status_updater()}
${tool_dependency_installation_updater()}
</%def>
@@ -0,0 +1,13 @@
<%def name="render_tool_dependency_status( tool_dependency )">
<%
if tool_dependency.status == trans.model.ToolDependency.installation_status.INSTALLING:
bgcolor = trans.model.ToolDependency.states.INSTALLING
rval = '<div class="count-box state-color-%s" id="ToolDependencyStatus-%s">' % ( bgcolor, trans.security.encode_id( tool_dependency.id ) )
rval += '%s</div>' % tool_dependency.status
else:
rval = tool_dependency.status
%>
${rval}
</%def>
${render_tool_dependency_status( tool_dependency )}
@@ -0,0 +1,52 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
<% import os %>
%if message:
${render_msg( message, status )}
%endif
<div class="toolForm">
<div class="toolFormTitle">Uninstall tool dependencies</div>
<div class="toolFormBody">
<form name="uninstall_tool_dependenceies" id="uninstall_tool_dependenceies" action="${h.url_for( controller='admin_toolshed', action='uninstall_tool_dependencies' )}" method="post" >
<div class="form-row">
<table class="grid">
<tr>
<th>Name</th>
<th>Version</th>
<th>Type</th>
<th>Install directory</th>
</tr>
%for tool_dependency in tool_dependencies:
<input type="hidden" name="tool_dependency_ids" value="${trans.security.encode_id( tool_dependency.id )}"/>
<%
install_dir = os.path.join( trans.app.config.tool_dependency_dir,
tool_dependency.name,
tool_dependency.version,
tool_dependency.tool_shed_repository.owner,
tool_dependency.tool_shed_repository.name,
tool_dependency.tool_shed_repository.installed_changeset_revision )
%>
%if os.path.exists( install_dir ):
<tr>
<td>${tool_dependency.name}</td>
<td>${tool_dependency.version}</td>
<td>${tool_dependency.type}</td>
<td>${install_dir}</td>
</tr>
%endif
%endfor
</table>
<div style="clear: both"></div>
</div>
<div class="form-row">
<input type="submit" name="uninstall_tool_dependencies_button" value="Uninstall"/>
<div class="toolParamHelp" style="clear: both;">
Click to uninstall the tool dependencies listed above.
</div>
</div>
</form>
</div>
</div>
+1 -1
View File
@@ -283,7 +283,7 @@
%>
%if tool_id_version_message:
${render_msg( tool_id_version_message, 'error' )}
${render_msg( tool_id_version_message, 'warning' )}
%endif
<div class="toolForm" id="${tool.id}">