Add a very basic framework to the Tool Shed for creating a Galaxy flavor Docker Image that uses Bjoern Gruning's Galaxy Docker project. This is a proof-of-concept that should be enhanced if kept.

This commit is contained in:
Greg Von Kuster
2014-07-01 21:44:49 -04:00
parent 606dff1089
commit 595d737fa8
7 changed files with 183 additions and 0 deletions
+2
View File
@@ -65,6 +65,8 @@ class Configuration( object ):
self.tool_dependency_dir = None
self.use_tool_dependencies = False
self.update_integrated_tool_panel = False
# Galaxy flavor Docker Image
self.enable_galaxy_flavor_docker_image = string_as_bool( kwargs.get( "enable_galaxy_flavor_docker_image", "False" ) )
self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) )
self.user_activation_on = kwargs.get( 'user_activation_on', None )
self.activation_grace_period = kwargs.get( 'activation_grace_period', None )
@@ -55,6 +55,7 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ):
datatypes_grid = repository_grids.DatatypesGrid()
deprecated_repositories_i_own_grid = repository_grids.DeprecatedRepositoriesIOwnGrid()
email_alerts_repository_grid = repository_grids.EmailAlertsRepositoryGrid()
docker_image_grid = repository_grids.DockerImageGrid()
install_matched_repository_grid = repository_grids.InstallMatchedRepositoryGrid()
matched_repository_grid = repository_grids.MatchedRepositoryGrid()
my_writable_repositories_grid = repository_grids.MyWritableRepositoriesGrid()
@@ -985,6 +986,62 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ):
# Do all we can to eliminate spam.
return trans.show_error_message( "You must be logged in to contact the owner of a repository." )
@web.expose
def create_galaxy_docker_image( self, trans, **kwd ):
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository_ids = util.listify( kwd.get( 'id', '' ) )
if 'operation' in kwd:
if repository_ids:
operation = kwd[ 'operation' ].lower()
if operation == "include in docker image":
repository_tups = []
for repository_id in repository_ids:
repository = suc.get_repository_by_id( trans.app, repository_id )
repository_tups.append( ( str( repository.name ),
str( repository.user.username ),
str( repository.type ) ) )
return trans.fill_template( "/webapps/tool_shed/repository/docker_image_repositories.mako",
id=','.join( repository_ids ),
repository_tups=repository_tups,
message=message,
status=status )
else:
# This can only occur when there is a multi-select grid with check boxes and an operation,
# and the user clicked the operation button without checking any of the check boxes.
kwd[ 'message' ] = "No items were selected."
kwd[ 'status' ] = 'error'
elif kwd.get( 'create_docker_image_button', False ):
tmp_image_dir = tempfile.mkdtemp( prefix="tmp-toolshed-cdidir" )
docker_file_name = 'Dockerfile'
docker_file_path = os.path.join( tmp_image_dir, docker_file_name )
tool_shed_url = tool_shed_url = web.url_for( '/', qualified=True )
repository_string = ''
for repository_id in repository_ids:
repository = suc.get_repository_by_id( trans.app, repository_id )
template = basic_util.SELECTED_REPOSITORIES_TEMPLATE
repository_template = \
string.Template( template ).safe_substitute( tool_shed_url=tool_shed_url,
repository_owner=str( repository.user.username ) ,
repository_name=str( repository.name ) )
repository_string = '%s\n%s' % ( repository_string, repository_template )
template = basic_util.DOCKER_IMAGE_TEMPLATE
docker_image_template = \
string.Template( template ).safe_substitute( selected_repositories=repository_string )
docker_image_string = docker_image_template
trans.response.set_content_type( 'application/text/plain' )
trans.response.headers[ "Content-Disposition" ] = 'attachment; filename="%s"' % docker_file_name
opened_file = open( docker_file_path, "w" )
opened_file.write( docker_image_string )
opened_file.close()
opened_file = open( docker_file_path, "r" )
# Make sure the file is removed from disk after the contents have been downloaded.
os.unlink( docker_file_path )
docker_file_path, docker_file_name = os.path.split( docker_file_path )
basic_util.remove_dir( docker_file_path )
return opened_file
return self.docker_image_grid( trans, **kwd )
@web.expose
def create_repository( self, trans, **kwd ):
message = kwd.get( 'message', '' )
+20
View File
@@ -329,6 +329,26 @@ class RepositoryGrid( grids.Grid ):
.outerjoin( model.Category.table )
class DockerImageGrid( RepositoryGrid ):
columns = [
RepositoryGrid.NameColumn( "Name",
key="name",
link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
attach_popup=False ),
RepositoryGrid.DescriptionColumn( "Synopsis",
key="description",
attach_popup=False ),
RepositoryGrid.UserColumn( "Owner",
model_class=model.User,
link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
attach_popup=False,
key="User.username" ),
RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
]
operations = [ grids.GridOperation( "Include in Docker image", allow_multiple=True ) ]
show_item_checkboxes = True
class EmailAlertsRepositoryGrid( RepositoryGrid ):
columns = [
RepositoryGrid.NameColumn( "Name",
+27
View File
@@ -20,6 +20,33 @@ NO_OUTPUT_TIMEOUT = 1200.0
MAXDIFFSIZE = 8000
MAX_DISPLAY_SIZE = 32768
DOCKER_IMAGE_TEMPLATE = '''
# Galaxy Docker image
FROM bgruening/galaxy-stable
MAINTAINER Bjoern A. Gruning, bjoern.gruening@gmail.com
RUN sed -i 's|brand.*|brand = deepTools|g' ~/galaxy-central/universe_wsgi.ini
WORKDIR /galaxy-central
${selected_repositories}
# Mark one folder as imported from the host.
VOLUME ["/export/"]
# Expose port 80 to the host
EXPOSE :80
# Autostart script that is invoked during container start
CMD ["/usr/bin/startup"]
'''
SELECTED_REPOSITORIES_TEMPLATE = '''
RUN service postgresql start && service apache2 start && ./run.sh --daemon && sleep 120 && python ./scripts/api/install_tool_shed_repositories.py --api admin -l http://localhost:8080 --url ${tool_shed_url} -o ${repository_owner} --name ${repository_name} --tool-deps --repository-deps --panel-section-name 'Docker'
'''
def evaluate_template( text, install_environment ):
"""
Substitute variables defined in XML blocks from dependencies file. The value of the received
+10
View File
@@ -155,6 +155,11 @@
<div class="toolTitle">
<a target="galaxy_main" href="${h.url_for( controller='repository', action='upload_capsule' )}">Import repository capsule</a>
</div>
%if trans.app.config.enable_galaxy_flavor_docker_image:
<div class="toolTitle">
<a target="galaxy_main" href="${h.url_for( controller='repository', action='create_galaxy_docker_image' )}">Create Galaxy Docker Image</a>
</div>
%endif
%if can_review_repositories:
<div class="toolSectionPad"></div>
<div class="toolSectionTitle">
@@ -216,6 +221,11 @@
<div class="toolTitle">
<a target="galaxy_main" href="${h.url_for( controller='/user', action='login' )}">Login to create a repository</a>
</div>
%if trans.app.config.enable_galaxy_flavor_docker_image:
<div class="toolTitle">
<a target="galaxy_main" href="${h.url_for( controller='repository', action='create_galaxy_docker_image' )}">Create Galaxy Docker Image</a>
</div>
%endif
%endif
%endif
</div>
@@ -0,0 +1,64 @@
<%namespace file="/message.mako" import="render_msg" />
<%!
def inherit(context):
if context.get('use_panels'):
return '/webapps/tool_shed/base_panels.mako'
else:
return '/base.mako'
%>
<%inherit file="${inherit(context)}"/>
<%def name="stylesheets()">
${parent.stylesheets()}
</%def>
<%def name="javascripts()">
${parent.javascripts()}
</%def>
%if message:
${render_msg( message, status )}
%endif
<div class="toolForm">
<div class="toolFormBody">
<div class="form-row">
<div class="warningmessage">
Click the <b>Create Docker Image</b> button below to create a Docker Image that will install the following repositories.
</div>
<div style="clear: both"></div>
</div>
</div>
</div>
<div class="toolForm">
<div class="toolFormTitle">Repositories for inclusion in Docker Image</div>
<form id="docker_image_form" name="docker_image_form" action="${h.url_for( controller='repository', action='create_galaxy_docker_image' )}" enctype="multipart/form-data" method="post">
<div class="form-row">
<input type="hidden" name="id" value="${id}" />
</div>
<div class="form-row">
<table class="grid">
<tr>
<th bgcolor="#D8D8D8">Name</th>
<th bgcolor="#D8D8D8">Owner</th>
<th bgcolor="#D8D8D8">Type</th>
</tr>
%for repository_tup in repository_tups:
<% name, owner, type = repository_tup %>
<tr>
<td>${ name | h }</td>
<td>${ owner | h }</td>
<td>${ type | h }</td>
</tr>
%endfor
</table>
</div>
<div style="clear: both"></div>
<div class="form-row">
<input type="submit" class="primary-button" name="create_docker_image_button" value="Create Docker Image">
</div>
</form>
</div>
</div>
+3
View File
@@ -90,6 +90,9 @@ sendmail_path = /usr/sbin/sendmail
# Profiling middleware (cProfile based)
## use_profile = True
# Enable creation of Galaxy flavor Docker Image
#enable_galaxy_flavor_docker_image = False
# Use the new iframe / javascript based layout
use_new_layout = true