galaxy-dev
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- 10008 discussions

23 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/6b3f453078c4
changeset: 3052:6b3f453078c4
user: Enis Afgan <afgane(a)gmail.com>
date: Mon Aug 24 17:46:22 2009 -0400
description:
Added ability to select default credentials.
diffstat:
eggs.ini | 2 +
lib/galaxy/model/mapping.py | 3 +-
lib/galaxy/model/migrate/versions/0014_credentials_table.py | 3 +-
lib/galaxy/web/controllers/cloud.py | 75 +++++++++++-------
templates/cloud/configure_cloud.mako | 20 ++++-
5 files changed, 68 insertions(+), 35 deletions(-)
diffs (236 lines):
diff -r a83d7220136f -r 6b3f453078c4 eggs.ini
--- a/eggs.ini Mon Aug 24 12:19:57 2009 -0400
+++ b/eggs.ini Mon Aug 24 17:46:22 2009 -0400
@@ -51,6 +51,7 @@
wsgiref = 0.1.2
Babel = 0.9.4
wchartype = 0.1
+boto = 1.8d
; extra version information
[tags]
@@ -100,3 +101,4 @@
wsgiref = http://pypi.python.org/packages/source/w/wsgiref/wsgiref-0.1.2.zip
Babel = http://ftp.edgewall.com/pub/babel/Babel-0.9.4.zip
wchartype = http://ginstrom.com/code/wchartype-0.1.zip
+boto = http://boto.googlecode.com/files/boto-1.8d.tar.gz
\ No newline at end of file
diff -r a83d7220136f -r 6b3f453078c4 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Mon Aug 24 12:19:57 2009 -0400
+++ b/lib/galaxy/model/mapping.py Mon Aug 24 17:46:22 2009 -0400
@@ -386,7 +386,8 @@
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True, nullable=False ),
Column( "name", TEXT),
Column( "access_key", TEXT),
- Column( "secret_key", TEXT)
+ Column( "secret_key", TEXT),
+ Column( "defaultCred", Boolean, default=False)
)
StoredWorkflow.table = Table( "stored_workflow", metadata,
diff -r a83d7220136f -r 6b3f453078c4 lib/galaxy/model/migrate/versions/0014_credentials_table.py
--- a/lib/galaxy/model/migrate/versions/0014_credentials_table.py Mon Aug 24 12:19:57 2009 -0400
+++ b/lib/galaxy/model/migrate/versions/0014_credentials_table.py Mon Aug 24 17:46:22 2009 -0400
@@ -19,7 +19,8 @@
Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True, nullable=False ),
Column( "name", TEXT),
Column( "access_key", TEXT),
- Column( "secret_key", TEXT) )
+ Column( "secret_key", TEXT),
+ Column( "defaultCred", Boolean, default=False ) )
def upgrade():
metadata.reflect()
diff -r a83d7220136f -r 6b3f453078c4 lib/galaxy/web/controllers/cloud.py
--- a/lib/galaxy/web/controllers/cloud.py Mon Aug 24 12:19:57 2009 -0400
+++ b/lib/galaxy/web/controllers/cloud.py Mon Aug 24 17:46:22 2009 -0400
@@ -15,7 +15,11 @@
from galaxy.model.mapping import desc
from galaxy.model.orm import *
+# Required for Cloud tab
+import galaxy.eggs
+galaxy.eggs.require("boto")
from boto.ec2.connection import EC2Connection
+
import logging
log = logging.getLogger( __name__ )
@@ -32,34 +36,32 @@
Render cloud main page (management of cloud resources)
"""
user = trans.get_user()
- #awsCredentials = 0
awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ) \
.order_by( desc( model.StoredUserCredentials.c.update_time ) ) \
.all()
- log.debug( "in list" )
- log.debug( awsCredentials )
-
- workflows = trans.sa_session.query( model.StoredWorkflow ) \
- .filter_by( user=user, deleted=False ) \
- .order_by( desc( model.StoredWorkflow.c.update_time ) ) \
- .all()
- return trans.fill_template( "cloud/configure_cloud.mako",
- awsCredentials = awsCredentials,
- workflows = workflows )
-
- @web.expose
- @web.require_login( "use Galaxy cloud" )
- def makeDefault( self, trans ):
- """
- Set current credentials as default to be used for submitting jobs
- TODO: Implement, this is only a dummy method.
- """
- awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
return trans.fill_template( "cloud/configure_cloud.mako",
awsCredentials = awsCredentials )
@web.expose
+ @web.require_login( "use Galaxy cloud" )
+ def makeDefault( self, trans, id=None ):
+ """
+ Set current credentials as default to be used for acquiring cloud resources.
+ """
+ currentDefault = get_defalt_credentials (trans)
+ if currentDefault:
+ currentDefault.defaultCred = False
+
+ newDefault = get_stored_credentials( trans, id )
+ newDefault.defaultCred = True
+ trans.sa_session.flush()
+ trans.set_message( "Credentials '%s' set as default." % newDefault.name )
+
+ return self.list( trans ) #trans.fill_template( "cloud/configure_cloud.mako",
+ #awsCredentials = awsCredentials )
+
+ @web.expose
@web.require_login( "use Galaxy workflows" )
def list_for_run( self, trans ):
"""
@@ -176,10 +178,9 @@
@web.expose
@web.require_login( "add credentials" )
- def add( self, trans, credName='', accessKey='', secretKey='', default=False ):
+ def add( self, trans, credName='', accessKey='', secretKey='', defaultCred=False ):
"""
Add user's AWS credentials stored under name `credName`.
- TODO: Make use of 'default' credential selection
"""
user = trans.get_user()
cred_error = accessKey_error = secretKey_error = None
@@ -203,18 +204,15 @@
# Log and display the management page
trans.log_event( "User added new credentials" )
trans.set_message( "Credential '%s' created" % credentials.name )
- if default:
- mail = os.popen("%s -t" % trans.app.config.sendmail_path, 'w')
- mail.write("To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % (trans.app.config.mailing_join_addr,email) )
- if mail.close():
- return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.", refresh_frames=refresh_frames )
+ if defaultCred:
+ self.makeDefault( trans, credentials.id)
return self.list( trans )
return trans.show_form(
web.FormBuilder( web.url_for(), "Add credentials", submit_text="Add" )
.add_text( "credName", "Credentials name", value="Unnamed credentials", error=cred_error )
.add_text( "accessKey", "Access key", value='', error=accessKey_error )
.add_password( "secretKey", "Secret key", value='', error=secretKey_error )
- .add_input( "checkbox","Make default credentials","default", value='default' ) )
+ .add_input( "checkbox","Make default credentials","defaultCred", value='defaultCred' ) )
@web.expose
@web.require_login( "view credentials" )
@@ -232,7 +230,7 @@
@web.require_login( "delete credentials" )
def delete( self, trans, id=None ):
"""
- Delete credentials
+ Delete user's cloud credentials
"""
# Load credentials from database
stored = get_stored_credentials( trans, id )
@@ -690,8 +688,11 @@
"""
Get a StoredUserCredntials from the database by id, verifying ownership.
"""
- # Load credentials from database
- id = trans.security.decode_id( id )
+ # Check if 'id' is in int (i.e., it was called from this program) or
+ # it was passed from the web (in which case decode it)
+ if not isinstance( id, int ):
+ id = trans.security.decode_id( id )
+
stored = trans.sa_session.query( model.StoredUserCredentials ).get( id )
if not stored:
error( "Credentials not found" )
@@ -704,6 +705,18 @@
# Looks good
return stored
+def get_defalt_credentials( trans, check_ownership=True ):
+ """
+ Get a StoredUserCredntials from the database by 'default' setting, verifying ownership.
+ """
+ user = trans.get_user()
+ # Load credentials from database
+ stored = trans.sa_session.query( model.StoredUserCredentials ) \
+ .filter_by (user=user, defaultCred=True) \
+ .first()
+
+ return stored
+
def attach_ordered_steps( workflow, steps ):
ordered_steps = order_workflow_steps( steps )
if ordered_steps:
diff -r a83d7220136f -r 6b3f453078c4 templates/cloud/configure_cloud.mako
--- a/templates/cloud/configure_cloud.mako Mon Aug 24 12:19:57 2009 -0400
+++ b/templates/cloud/configure_cloud.mako Mon Aug 24 17:46:22 2009 -0400
@@ -9,6 +9,9 @@
except:
messagetype = "done"
%>
+
+
+
<p />
<div class="${messagetype}message">
${message}
@@ -31,7 +34,6 @@
<tr class="header">
<th>Credentials Name</th>
<th>Default</th>
- ## <th>Last Updated</th>
<th></th>
</tr>
%for i, awsCredential in enumerate( awsCredentials ):
@@ -41,8 +43,17 @@
<a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a>
</td>
## Comment <td>${len(workflow.latest_workflow.steps)}</td>
- ##<td>${str(awsCredentials.update_time)[:19]}</td>
+ ##<td>${str(awsCredential.update_time)[:19]}</td>
<td>
+ ${str(awsCredential.defaultCred)}
+ <%
+ c=str(awsCredential.defaultCred)
+ %>
+
+ ##${dflt(cred=c)}
+ </td>
+
+ <td>
<div popupmenu="wf-${i}-popup">
<a class="action-button" href="${h.url_for( action='view', id=trans.security.encode_id(awsCredential.id) )}">View</a>
<a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(awsCredential.id) )}">Rename</a>
@@ -65,3 +76,8 @@
%endif
+<%def name="dflt(cred)">
+ %if cred:
+ default
+ %endif
+</%def>
1
0

23 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/a83d7220136f
changeset: 3051:a83d7220136f
user: Enis Afgan <afgane(a)gmail.com>
date: Mon Aug 24 12:19:57 2009 -0400
description:
Enabled editing/viewing of user credentials.
diffstat:
lib/galaxy/web/controllers/cloud.py | 169 +++++++++++----------------------
static/images/silk/resultset_previous.png |
templates/cloud/configure_cloud.mako | 3 +-
templates/cloud/view.mako | 60 ++++++++++++
4 files changed, 120 insertions(+), 112 deletions(-)
diffs (276 lines):
diff -r 6f32d42dab74 -r a83d7220136f lib/galaxy/web/controllers/cloud.py
--- a/lib/galaxy/web/controllers/cloud.py Fri Aug 21 17:36:40 2009 -0400
+++ b/lib/galaxy/web/controllers/cloud.py Mon Aug 24 12:19:57 2009 -0400
@@ -33,7 +33,9 @@
"""
user = trans.get_user()
#awsCredentials = 0
- awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
+ awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ) \
+ .order_by( desc( model.StoredUserCredentials.c.update_time ) ) \
+ .all()
log.debug( "in list" )
log.debug( awsCredentials )
@@ -50,6 +52,7 @@
def makeDefault( self, trans ):
"""
Set current credentials as default to be used for submitting jobs
+ TODO: Implement, this is only a dummy method.
"""
awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
@@ -170,119 +173,63 @@
else:
return form( url_for( id=trans.security.encode_id(stored.id) ), "Rename credentials", submit_text="Rename" ) \
.add_text( "new_name", "Credentials Name", value=stored.name )
+
+ @web.expose
+ @web.require_login( "add credentials" )
+ def add( self, trans, credName='', accessKey='', secretKey='', default=False ):
+ """
+ Add user's AWS credentials stored under name `credName`.
+ TODO: Make use of 'default' credential selection
+ """
+ user = trans.get_user()
+ cred_error = accessKey_error = secretKey_error = None
+ if credName:
+ if len( credName ) > 255:
+ cred_error = "Credentials name exceeds maximum allowable length."
+ elif trans.app.model.StoredUserCredentials.filter(
+ trans.app.model.StoredUserCredentials.table.c.name==credName ).first():
+ cred_error = "Credentials with that name already exist."
+ else:
+ # Create new user stored credentials
+ credentials = model.StoredUserCredentials()
+ credentials.name = credName
+ credentials.user = user
+ credentials.access_key = accessKey
+ credentials.secret_key = secretKey
+ # Persist
+ session = trans.sa_session
+ session.save_or_update( credentials )
+ session.flush()
+ # Log and display the management page
+ trans.log_event( "User added new credentials" )
+ trans.set_message( "Credential '%s' created" % credentials.name )
+ if default:
+ mail = os.popen("%s -t" % trans.app.config.sendmail_path, 'w')
+ mail.write("To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % (trans.app.config.mailing_join_addr,email) )
+ if mail.close():
+ return trans.show_warn_message( "Now logged in as " + user.email+". However, subscribing to the mailing list has failed.", refresh_frames=refresh_frames )
+ return self.list( trans )
+ return trans.show_form(
+ web.FormBuilder( web.url_for(), "Add credentials", submit_text="Add" )
+ .add_text( "credName", "Credentials name", value="Unnamed credentials", error=cred_error )
+ .add_text( "accessKey", "Access key", value='', error=accessKey_error )
+ .add_password( "secretKey", "Secret key", value='', error=secretKey_error )
+ .add_input( "checkbox","Make default credentials","default", value='default' ) )
@web.expose
- @web.require_login( "use Galaxy workflows" )
- def clone( self, trans, id ):
- stored = get_stored_workflow( trans, id, check_ownership=False )
- user = trans.get_user()
- if stored.user == user:
- owner = True
- else:
- if trans.sa_session.query( model.StoredWorkflowUserShareAssociation ) \
- .filter_by( user=user, stored_workflow=stored ).count() == 0:
- error( "Workflow is not owned by or shared with current user" )
- owner = False
- new_stored = model.StoredWorkflow()
- new_stored.name = "Clone of '%s'" % stored.name
- new_stored.latest_workflow = stored.latest_workflow
- if not owner:
- new_stored.name += " shared by '%s'" % stored.user.email
- new_stored.user = user
- # Persist
- session = trans.sa_session
- session.save_or_update( new_stored )
- session.flush()
- # Display the management page
- trans.set_message( 'Clone created with name "%s"' % new_stored.name )
- return self.list( trans )
-
+ @web.require_login( "view credentials" )
+ def view( self, trans, id=None ):
+ """
+ View details for user credentials
+ """
+ # Load credentials from database
+ stored = get_stored_credentials( trans, id )
+
+ return trans.fill_template( "cloud/view.mako",
+ credDetails = stored)
+
@web.expose
- @web.require_login( "create workflows" )
- def create( self, trans, workflow_name=None ):
- """
- Create a new stored workflow with name `workflow_name`.
- """
- user = trans.get_user()
- if workflow_name is not None:
- # Create the new stored workflow
- stored_workflow = model.StoredWorkflow()
- stored_workflow.name = workflow_name
- stored_workflow.user = user
- # And the first (empty) workflow revision
- workflow = model.Workflow()
- workflow.name = workflow_name
- workflow.stored_workflow = stored_workflow
- stored_workflow.latest_workflow = workflow
- # Persist
- session = trans.sa_session
- session.save_or_update( stored_workflow )
- session.flush()
- # Display the management page
- trans.set_message( "Workflow '%s' created" % stored_workflow.name )
- return self.list( trans )
- else:
- return form( url_for(), "Create new workflow", submit_text="Create" ) \
- .add_text( "workflow_name", "Workflow Name", value="Unnamed cloud" )
-
- @web.expose
- @web.require_login( "add AWS credentials" )
- def add( self, trans, account_name=None ):
- """
- Add user's AWS credentials stored under name `account_name`.
- """
- user = trans.get_user()
-
- """
- awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
- log.debug( "in add" )
- log.debug( user )
- log.debug( credentials.name )
- log.debug( awsCredentials )
- """
-
- if account_name is not None:
- # Create new user stored credentials
- credentials = model.StoredUserCredentials()
- credentials.name = account_name
- credentials.user = user
- credentials.access_key = "access key"
- credentials.secret_key = "secret key"
- # Persist
- session = trans.sa_session
- session.save_or_update( credentials )
- session.flush()
- # Display the management page
- trans.set_message( "Credential '%s' created" % credentials.name )
- return self.list( trans )
-
- """
- # Create the new stored workflow
- stored_workflow = model.StoredWorkflow()
- stored_workflow.name = workflow_name
- stored_workflow.user = user
- # And the first (empty) workflow revision
- workflow = model.Workflow()
- workflow.name = workflow_name
- workflow.stored_workflow = stored_workflow
- stored_workflow.latest_workflow = workflow
- # Persist
- session = trans.sa_session
- session.save_or_update( stored_workflow )
- session.flush()
- # Display the management page
- trans.set_message( "Workflow '%s' created" % stored_workflow.name )
- return self.list( trans )
- """
- else:
- return trans.fill_template("cloud/credentials.mako")
- """
- form( url_for(), "Add AWS credentials", submit_text="Add" ) \
- .add_text( "account_name", "Account Name", value="Unnamed credentials" )
- .add_text( "access_key", "Access Key", value="" )
- .add_text( "secret_key", "Secret Key", value="" )
- """
- @web.expose
+ @web.require_login( "delete credentials" )
def delete( self, trans, id=None ):
"""
Delete credentials
diff -r 6f32d42dab74 -r a83d7220136f static/images/silk/resultset_previous.png
Binary file static/images/silk/resultset_previous.png has changed
diff -r 6f32d42dab74 -r a83d7220136f templates/cloud/configure_cloud.mako
--- a/templates/cloud/configure_cloud.mako Fri Aug 21 17:36:40 2009 -0400
+++ b/templates/cloud/configure_cloud.mako Mon Aug 24 12:19:57 2009 -0400
@@ -44,8 +44,9 @@
##<td>${str(awsCredentials.update_time)[:19]}</td>
<td>
<div popupmenu="wf-${i}-popup">
- <a class="action-button" href="${h.url_for( action='makeDefault', id=trans.security.encode_id(awsCredential.id) )}" target="_parent">Made default</a>
+ <a class="action-button" href="${h.url_for( action='view', id=trans.security.encode_id(awsCredential.id) )}">View</a>
<a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(awsCredential.id) )}">Rename</a>
+ <a class="action-button" href="${h.url_for( action='makeDefault', id=trans.security.encode_id(awsCredential.id) )}" target="_parent">Make default</a>
<a class="action-button" confirm="Are you sure you want to delete workflow '${awsCredential.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(awsCredential.id) )}">Delete</a>
</div>
</td>
diff -r 6f32d42dab74 -r a83d7220136f templates/cloud/view.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/cloud/view.mako Mon Aug 24 12:19:57 2009 -0400
@@ -0,0 +1,60 @@
+<%inherit file="/base.mako"/>
+<%def name="title()">Cloud home</%def>
+
+
+<h2>Credentials details</h2>
+
+%if credDetails:
+ <ul class="manage-table-actions">
+ <li>
+ <a class="action-button" href="${h.url_for( action='list' )}">
+ <img src="${h.url_for('/static/images/silk/resultset_previous.png')}" />
+ <span>Return to cloud management console</span>
+ </a>
+ </li>
+ </ul>
+
+ <table class="mange-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
+ <tr>
+ <td> Credentials name: </td>
+ <td>
+ ${credDetails.name}
+ <a id="wf-popup" class="popup-arrow" style="display: none;">▼</a>
+ </td>
+ <td>
+ <div popupmenu="wf-popup">
+ <a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(credDetails.id) )}">Rename</a>
+ <a class="action-button" confirm="Are you sure you want to delete workflow '${credDetails.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(credDetails.id) )}">Delete</a>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td> Access key: </td>
+ <td>
+ ${credDetails.access_key}
+ </td>
+ </tr>
+ <tr>
+ <td> Secret key: </td>
+ <td>
+ <div id="shortComment2">
+ <a onclick="document.getElementById('fullComment2').style.display = 'block';
+ document.getElementById('shortComment2').style.display = 'none'; return 0"
+ href="javascript:void(0)">
+ + Show
+ </a>
+ </div>
+ <div id="fullComment2" style="DISPLAY: none">
+ <nobr><b>${credDetails.secret_key}</b></nobr><br/>
+ <a onclick="document.getElementById('shortComment2').style.display = 'block';
+ document.getElementById('fullComment2').style.display = 'none'; return 0;"
+ href="javascript:void(0)">
+ - Hide
+ </a>
+ </div>
+ </td>
+ </tr>
+ </table>
+%else:
+ There are no credentials under that name.
+%endif
1
0

23 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/6f32d42dab74
changeset: 3050:6f32d42dab74
user: Enis Afgan <afgane(a)gmail.com>
date: Fri Aug 21 17:36:40 2009 -0400
description:
Cloud credentials can now be deleted/renamed
diffstat:
lib/galaxy/model/__init__.py | 9 ----
lib/galaxy/web/controllers/cloud.py | 76 +++++++++++++++++++++++---------------
templates/cloud/configure_cloud.mako | 26 ++++++++-----
3 files changed, 62 insertions(+), 49 deletions(-)
diffs (217 lines):
diff -r 4b4259e46607 -r 6f32d42dab74 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Fri Aug 21 15:15:30 2009 -0400
+++ b/lib/galaxy/model/__init__.py Fri Aug 21 17:36:40 2009 -0400
@@ -166,15 +166,6 @@
self.user = user
self.group = group
-class Credential( object ):
- """
- Crediential stores user credential data for accessing cloud resources
- """
- def __init__(self, name=None, accessKey=None, secretKey=None):
- self.name = name or "Unnamed account"
- self.accessKey = accesKey
- self.secretKey = secretKey
-
class History( object ):
def __init__( self, id=None, name=None, user=None ):
self.id = id
diff -r 4b4259e46607 -r 6f32d42dab74 lib/galaxy/web/controllers/cloud.py
--- a/lib/galaxy/web/controllers/cloud.py Fri Aug 21 15:15:30 2009 -0400
+++ b/lib/galaxy/web/controllers/cloud.py Fri Aug 21 17:36:40 2009 -0400
@@ -46,6 +46,17 @@
workflows = workflows )
@web.expose
+ @web.require_login( "use Galaxy cloud" )
+ def makeDefault( self, trans ):
+ """
+ Set current credentials as default to be used for submitting jobs
+ """
+ awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
+
+ return trans.fill_template( "cloud/configure_cloud.mako",
+ awsCredentials = awsCredentials )
+
+ @web.expose
@web.require_login( "use Galaxy workflows" )
def list_for_run( self, trans ):
"""
@@ -146,20 +157,20 @@
session.flush()
# Redirect to load galaxy frames.
return trans.response.send_redirect( url_for( controller='workflow' ) )
-
+
@web.expose
- @web.require_login( "use Galaxy workflows" )
+ @web.require_login( "use Galaxy cloud" )
def rename( self, trans, id, new_name=None ):
- stored = get_stored_workflow( trans, id )
+ stored = get_stored_credentials( trans, id )
if new_name is not None:
stored.name = new_name
trans.sa_session.flush()
- trans.set_message( "Workflow renamed to '%s'." % new_name )
+ trans.set_message( "Credentials renamed to '%s'." % new_name )
return self.list( trans )
else:
- return form( url_for( id=trans.security.encode_id(stored.id) ), "Rename workflow", submit_text="Rename" ) \
- .add_text( "new_name", "Workflow Name", value=stored.name )
-
+ return form( url_for( id=trans.security.encode_id(stored.id) ), "Rename credentials", submit_text="Rename" ) \
+ .add_text( "new_name", "Credentials Name", value=stored.name )
+
@web.expose
@web.require_login( "use Galaxy workflows" )
def clone( self, trans, id ):
@@ -226,23 +237,23 @@
awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
log.debug( "in add" )
log.debug( user )
- log.debug( stored_credentials.name )
+ log.debug( credentials.name )
log.debug( awsCredentials )
"""
if account_name is not None:
# Create new user stored credentials
- stored_credentials = model.StoredUserCredentials()
- stored_credentials.name = account_name
- stored_credentials.user = user
- stored_credentials.access_key = "access key"
- stored_credentials.secret_key = "secret key"
+ credentials = model.StoredUserCredentials()
+ credentials.name = account_name
+ credentials.user = user
+ credentials.access_key = "access key"
+ credentials.secret_key = "secret key"
# Persist
session = trans.sa_session
- session.save_or_update( stored_credentials )
+ session.save_or_update( credentials )
session.flush()
# Display the management page
- trans.set_message( "Credential '%s' created" % stored_credentials.name )
+ trans.set_message( "Credential '%s' created" % credentials.name )
return self.list( trans )
"""
@@ -264,21 +275,26 @@
return self.list( trans )
"""
else:
- return form( url_for(), "Add AWS credentials", submit_text="Add" ) \
+ return trans.fill_template("cloud/credentials.mako")
+ """
+ form( url_for(), "Add AWS credentials", submit_text="Add" ) \
.add_text( "account_name", "Account Name", value="Unnamed credentials" )
-
+ .add_text( "access_key", "Access Key", value="" )
+ .add_text( "secret_key", "Secret Key", value="" )
+ """
@web.expose
def delete( self, trans, id=None ):
"""
- Mark a workflow as deleted
+ Delete credentials
"""
- # Load workflow from database
- stored = get_stored_workflow( trans, id )
- # Marke as deleted and save
- stored.deleted = True
+ # Load credentials from database
+ stored = get_stored_credentials( trans, id )
+ # Delete and save
+ sess = trans.sa_session
+ sess.delete( stored )
stored.flush()
# Display the management page
- trans.set_message( "Workflow '%s' deleted" % stored.name )
+ trans.set_message( "Credentials '%s' deleted." % stored.name )
return self.list( trans )
@web.expose
@@ -723,21 +739,21 @@
## ---- Utility methods -------------------------------------------------------
-def get_stored_workflow( trans, id, check_ownership=True ):
+def get_stored_credentials( trans, id, check_ownership=True ):
"""
- Get a StoredWorkflow from the database by id, verifying ownership.
+ Get a StoredUserCredntials from the database by id, verifying ownership.
"""
- # Load workflow from database
+ # Load credentials from database
id = trans.security.decode_id( id )
- stored = trans.sa_session.query( model.StoredWorkflow ).get( id )
+ stored = trans.sa_session.query( model.StoredUserCredentials ).get( id )
if not stored:
- error( "Workflow not found" )
+ error( "Credentials not found" )
# Verify ownership
user = trans.get_user()
if not user:
- error( "Must be logged in to use workflows" )
+ error( "Must be logged in to use the cloud." )
if check_ownership and not( stored.user == user ):
- error( "Workflow is not owned by current user" )
+ error( "Credentials are not owned by current user." )
# Looks good
return stored
diff -r 4b4259e46607 -r 6f32d42dab74 templates/cloud/configure_cloud.mako
--- a/templates/cloud/configure_cloud.mako Fri Aug 21 15:15:30 2009 -0400
+++ b/templates/cloud/configure_cloud.mako Fri Aug 21 17:36:40 2009 -0400
@@ -1,6 +1,6 @@
<%inherit file="/base.mako"/>
-<%def name="title()">Workflow home</%def>
+<%def name="title()">Cloud home</%def>
%if message:
<%
@@ -18,10 +18,19 @@
<h2>Galaxy in the clouds</h2>
%if awsCredentials:
+ <ul class="manage-table-actions">
+ <li>
+ <a class="action-button" href="${h.url_for( action='add' )}">
+ <img src="${h.url_for('/static/images/silk/add.png')}" />
+ <span>Add AWS credentials</span>
+ </a>
+ </li>
+ </ul>
+
<table class="mange-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr class="header">
- <th>Name</th>
- <th># of Steps</th>
+ <th>Credentials Name</th>
+ <th>Default</th>
## <th>Last Updated</th>
<th></th>
</tr>
@@ -32,15 +41,12 @@
<a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a>
</td>
## Comment <td>${len(workflow.latest_workflow.steps)}</td>
- ## Comment <td>${str(workflow.update_time)[:19]}</td>
+ ##<td>${str(awsCredentials.update_time)[:19]}</td>
<td>
<div popupmenu="wf-${i}-popup">
- ##<a class="action-button" href="${h.url_for( action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">Edit</a>
- ##<a class="action-button" href="${h.url_for( controller='root', action='index', workflow_id=trans.security.encode_id(workflow.id) )}" target="_parent">Run</a>
- ##<a class="action-button" href="${h.url_for( action='clone', id=trans.security.encode_id(workflow.id) )}">Clone</a>
- ##<a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(workflow.id) )}">Rename</a>
- ##<a class="action-button" href="${h.url_for( action='sharing', id=trans.security.encode_id(workflow.id) )}">Sharing</a>
- ##<a class="action-button" confirm="Are you sure you want to delete workflow '${workflow.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(workflow.id) )}">Delete</a>
+ <a class="action-button" href="${h.url_for( action='makeDefault', id=trans.security.encode_id(awsCredential.id) )}" target="_parent">Made default</a>
+ <a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(awsCredential.id) )}">Rename</a>
+ <a class="action-button" confirm="Are you sure you want to delete workflow '${awsCredential.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(awsCredential.id) )}">Delete</a>
</div>
</td>
</tr>
1
0

23 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/4b4259e46607
changeset: 3049:4b4259e46607
user: Enis Afgan <afgane(a)gmail.com>
date: Fri Aug 21 15:15:30 2009 -0400
description:
Added credentials table to DB and did intital integration with Cloud tab.
diffstat:
lib/galaxy/model/__init__.py | 21 ++++++-
lib/galaxy/model/mapping.py | 14 ++++
lib/galaxy/model/migrate/versions/0014_credentials_table.py | 30 ++++++++++
lib/galaxy/web/controllers/cloud.py | 43 +++++++++++---
templates/cloud/configure_cloud.mako | 23 +++----
5 files changed, 109 insertions(+), 22 deletions(-)
diffs (228 lines):
diff -r 7d19363e6e0d -r 4b4259e46607 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py Thu Aug 20 11:27:30 2009 -0400
+++ b/lib/galaxy/model/__init__.py Fri Aug 21 15:15:30 2009 -0400
@@ -35,6 +35,7 @@
self.purged = False
# Relationships
self.histories = []
+ self.credentials = []
def set_password_cleartext( self, cleartext ):
"""Set 'self.password' to the digest of 'cleartext'."""
@@ -165,6 +166,15 @@
self.user = user
self.group = group
+class Credential( object ):
+ """
+ Crediential stores user credential data for accessing cloud resources
+ """
+ def __init__(self, name=None, accessKey=None, secretKey=None):
+ self.name = name or "Unnamed account"
+ self.accessKey = accesKey
+ self.secretKey = secretKey
+
class History( object ):
def __init__( self, id=None, name=None, user=None ):
self.id = id
@@ -930,7 +940,16 @@
def __init__( self, galaxy_session, history ):
self.galaxy_session = galaxy_session
self.history = history
-
+
+class StoredUserCredentials( object ):
+ def __init__( self ):
+ self.id = None
+ self.user = None
+ self.name = None
+ self.accessKey = None
+ self.secretKey = None
+ self.credentials = []
+
class StoredWorkflow( object ):
def __init__( self ):
self.id = None
diff -r 7d19363e6e0d -r 4b4259e46607 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py Thu Aug 20 11:27:30 2009 -0400
+++ b/lib/galaxy/model/mapping.py Fri Aug 21 15:15:30 2009 -0400
@@ -379,6 +379,16 @@
Column( "session_id", Integer, ForeignKey( "galaxy_session.id" ), index=True ),
Column( "history_id", Integer, ForeignKey( "history.id" ), index=True ) )
+StoredUserCredentials.table = Table( "stored_user_credentials", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True, nullable=False ),
+ Column( "name", TEXT),
+ Column( "access_key", TEXT),
+ Column( "secret_key", TEXT)
+ )
+
StoredWorkflow.table = Table( "stored_workflow", metadata,
Column( "id", Integer, primary_key=True ),
Column( "create_time", DateTime, default=now ),
@@ -884,6 +894,10 @@
output_step=relation( WorkflowStep, backref="output_connections", cascade="all",
primaryjoin=( WorkflowStepConnection.table.c.output_step_id == WorkflowStep.table.c.id ) ) ) )
+assign_mapper( context, StoredUserCredentials, StoredUserCredentials.table,
+ properties=dict( user=relation( User) )
+ )
+
assign_mapper( context, StoredWorkflow, StoredWorkflow.table,
properties=dict( user=relation( User ),
workflows=relation( Workflow, backref='stored_workflow',
diff -r 7d19363e6e0d -r 4b4259e46607 lib/galaxy/model/migrate/versions/0014_credentials_table.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/model/migrate/versions/0014_credentials_table.py Fri Aug 21 15:15:30 2009 -0400
@@ -0,0 +1,30 @@
+from sqlalchemy import *
+from migrate 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 logging
+log = logging.getLogger( __name__ )
+
+metadata = MetaData( migrate_engine )
+
+Credentials_table = Table( "stored_user_credentials", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True, nullable=False ),
+ Column( "name", TEXT),
+ Column( "access_key", TEXT),
+ Column( "secret_key", TEXT) )
+
+def upgrade():
+ metadata.reflect()
+ Credentials_table.create()
+
+def downgrade():
+ metadata.reflect()
+ Credentials_table.drop()
diff -r 7d19363e6e0d -r 4b4259e46607 lib/galaxy/web/controllers/cloud.py
--- a/lib/galaxy/web/controllers/cloud.py Thu Aug 20 11:27:30 2009 -0400
+++ b/lib/galaxy/web/controllers/cloud.py Fri Aug 21 15:15:30 2009 -0400
@@ -15,6 +15,10 @@
from galaxy.model.mapping import desc
from galaxy.model.orm import *
+from boto.ec2.connection import EC2Connection
+import logging
+log = logging.getLogger( __name__ )
+
class CloudController( BaseController ):
@web.expose
@@ -28,20 +32,18 @@
Render cloud main page (management of cloud resources)
"""
user = trans.get_user()
+ #awsCredentials = 0
+ awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
+ log.debug( "in list" )
+ log.debug( awsCredentials )
+
workflows = trans.sa_session.query( model.StoredWorkflow ) \
.filter_by( user=user, deleted=False ) \
.order_by( desc( model.StoredWorkflow.c.update_time ) ) \
.all()
- shared_by_others = trans.sa_session \
- .query( model.StoredWorkflowUserShareAssociation ) \
- .filter_by( user=user ) \
- .join( 'stored_workflow' ) \
- .filter( model.StoredWorkflow.deleted == False ) \
- .order_by( desc( model.StoredWorkflow.update_time ) ) \
- .all()
return trans.fill_template( "cloud/configure_cloud.mako",
- workflows = workflows,
- shared_by_others = shared_by_others )
+ awsCredentials = awsCredentials,
+ workflows = workflows )
@web.expose
@web.require_login( "use Galaxy workflows" )
@@ -219,7 +221,30 @@
Add user's AWS credentials stored under name `account_name`.
"""
user = trans.get_user()
+
+ """
+ awsCredentials = trans.sa_session.query ( model.StoredUserCredentials ).all()
+ log.debug( "in add" )
+ log.debug( user )
+ log.debug( stored_credentials.name )
+ log.debug( awsCredentials )
+ """
+
if account_name is not None:
+ # Create new user stored credentials
+ stored_credentials = model.StoredUserCredentials()
+ stored_credentials.name = account_name
+ stored_credentials.user = user
+ stored_credentials.access_key = "access key"
+ stored_credentials.secret_key = "secret key"
+ # Persist
+ session = trans.sa_session
+ session.save_or_update( stored_credentials )
+ session.flush()
+ # Display the management page
+ trans.set_message( "Credential '%s' created" % stored_credentials.name )
+ return self.list( trans )
+
"""
# Create the new stored workflow
stored_workflow = model.StoredWorkflow()
diff -r 7d19363e6e0d -r 4b4259e46607 templates/cloud/configure_cloud.mako
--- a/templates/cloud/configure_cloud.mako Thu Aug 20 11:27:30 2009 -0400
+++ b/templates/cloud/configure_cloud.mako Fri Aug 21 15:15:30 2009 -0400
@@ -25,30 +25,29 @@
## <th>Last Updated</th>
<th></th>
</tr>
- %for i, workflow in enumerate( workflows ):
+ %for i, awsCredential in enumerate( awsCredentials ):
<tr>
<td>
- ${workflow.name}
+ ${awsCredential.name}
<a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a>
</td>
- <td>${len(workflow.latest_workflow.steps)}</td>
- ## <td>${str(workflow.update_time)[:19]}</td>
+ ## Comment <td>${len(workflow.latest_workflow.steps)}</td>
+ ## Comment <td>${str(workflow.update_time)[:19]}</td>
<td>
<div popupmenu="wf-${i}-popup">
- <a class="action-button" href="${h.url_for( action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">Edit</a>
- <a class="action-button" href="${h.url_for( controller='root', action='index', workflow_id=trans.security.encode_id(workflow.id) )}" target="_parent">Run</a>
- <a class="action-button" href="${h.url_for( action='clone', id=trans.security.encode_id(workflow.id) )}">Clone</a>
- <a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(workflow.id) )}">Rename</a>
- <a class="action-button" href="${h.url_for( action='sharing', id=trans.security.encode_id(workflow.id) )}">Sharing</a>
- <a class="action-button" confirm="Are you sure you want to delete workflow '${workflow.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(workflow.id) )}">Delete</a>
+ ##<a class="action-button" href="${h.url_for( action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">Edit</a>
+ ##<a class="action-button" href="${h.url_for( controller='root', action='index', workflow_id=trans.security.encode_id(workflow.id) )}" target="_parent">Run</a>
+ ##<a class="action-button" href="${h.url_for( action='clone', id=trans.security.encode_id(workflow.id) )}">Clone</a>
+ ##<a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(workflow.id) )}">Rename</a>
+ ##<a class="action-button" href="${h.url_for( action='sharing', id=trans.security.encode_id(workflow.id) )}">Sharing</a>
+ ##<a class="action-button" confirm="Are you sure you want to delete workflow '${workflow.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(workflow.id) )}">Delete</a>
</div>
</td>
</tr>
%endfor
</table>
%else:
-
- You have no AWS credentials associated with your Galaxy account:
+ You have no AWS credentials associated with your Galaxy account:
<a class="action-button" href="${h.url_for( action='add' )}">
<img src="${h.url_for('/static/images/silk/add.png')}" />
<span>Add AWS credentials</span>
1
0

23 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/7d19363e6e0d
changeset: 3048:7d19363e6e0d
user: "Enis Afgan <afgane(a)gmail.com>"
date: Thu Aug 20 11:27:30 2009 -0400
description:
Added files associated with previous commit.
diffstat:
lib/galaxy/web/controllers/cloud.py | 844 ++++++++++++++++++++++++++++++++++++++++
templates/cloud/configure_cloud.mako | 61 ++
templates/cloud/index.mako | 16 +
3 files changed, 921 insertions(+), 0 deletions(-)
diffs (934 lines):
diff -r b46effa7b459 -r 7d19363e6e0d lib/galaxy/web/controllers/cloud.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/web/controllers/cloud.py Thu Aug 20 11:27:30 2009 -0400
@@ -0,0 +1,844 @@
+from galaxy.web.base.controller import *
+
+import pkg_resources
+pkg_resources.require( "simplejson" )
+import simplejson
+
+from galaxy.tools.parameters import *
+from galaxy.tools import DefaultToolState
+from galaxy.tools.parameters.grouping import Repeat, Conditional
+from galaxy.datatypes.data import Data
+from galaxy.util.odict import odict
+from galaxy.util.bunch import Bunch
+from galaxy.util.topsort import topsort, topsort_levels, CycleError
+from galaxy.workflow.modules import *
+from galaxy.model.mapping import desc
+from galaxy.model.orm import *
+
+class CloudController( BaseController ):
+
+ @web.expose
+ def index( self, trans ):
+ return trans.fill_template( "cloud/index.mako" )
+
+ @web.expose
+ @web.require_login( "use Galaxy cloud" )
+ def list( self, trans ):
+ """
+ Render cloud main page (management of cloud resources)
+ """
+ user = trans.get_user()
+ workflows = trans.sa_session.query( model.StoredWorkflow ) \
+ .filter_by( user=user, deleted=False ) \
+ .order_by( desc( model.StoredWorkflow.c.update_time ) ) \
+ .all()
+ shared_by_others = trans.sa_session \
+ .query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=user ) \
+ .join( 'stored_workflow' ) \
+ .filter( model.StoredWorkflow.deleted == False ) \
+ .order_by( desc( model.StoredWorkflow.update_time ) ) \
+ .all()
+ return trans.fill_template( "cloud/configure_cloud.mako",
+ workflows = workflows,
+ shared_by_others = shared_by_others )
+
+ @web.expose
+ @web.require_login( "use Galaxy workflows" )
+ def list_for_run( self, trans ):
+ """
+ Render workflow list for analysis view (just allows running workflow
+ or switching to management view)
+ """
+ user = trans.get_user()
+ workflows = trans.sa_session.query( model.StoredWorkflow ) \
+ .filter_by( user=user, deleted=False ) \
+ .order_by( desc( model.StoredWorkflow.c.update_time ) ) \
+ .all()
+ shared_by_others = trans.sa_session \
+ .query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=user ) \
+ .filter( model.StoredWorkflow.c.deleted == False ) \
+ .order_by( desc( model.StoredWorkflow.c.update_time ) ) \
+ .all()
+ return trans.fill_template( "workflow/list_for_run.mako",
+ workflows = workflows,
+ shared_by_others = shared_by_others )
+
+ @web.expose
+ @web.require_login( "use Galaxy workflows" )
+ def share( self, trans, id, email="" ):
+ msg = mtype = None
+ # Load workflow from database
+ stored = get_stored_workflow( trans, id )
+ if email:
+ other = model.User.filter( and_( model.User.table.c.email==email,
+ model.User.table.c.deleted==False ) ).first()
+ if not other:
+ mtype = "error"
+ msg = ( "User '%s' does not exist" % email )
+ elif other == trans.get_user():
+ mtype = "error"
+ msg = ( "You cannot share a workflow with yourself" )
+ elif trans.sa_session.query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=other, stored_workflow=stored ).count() > 0:
+ mtype = "error"
+ msg = ( "Workflow already shared with '%s'" % email )
+ else:
+ share = model.StoredWorkflowUserShareAssociation()
+ share.stored_workflow = stored
+ share.user = other
+ session = trans.sa_session
+ session.save_or_update( share )
+ session.flush()
+ trans.set_message( "Workflow '%s' shared with user '%s'" % ( stored.name, other.email ) )
+ return trans.response.send_redirect( url_for( controller='workflow', action='sharing', id=id ) )
+ return trans.fill_template( "workflow/share.mako",
+ message = msg,
+ messagetype = mtype,
+ stored=stored,
+ email=email )
+
+ @web.expose
+ @web.require_login( "use Galaxy workflows" )
+ def sharing( self, trans, id, **kwargs ):
+ session = trans.sa_session
+ stored = get_stored_workflow( trans, id )
+ if 'enable_import_via_link' in kwargs:
+ stored.importable = True
+ stored.flush()
+ elif 'disable_import_via_link' in kwargs:
+ stored.importable = False
+ stored.flush()
+ elif 'unshare_user' in kwargs:
+ user = session.query( model.User ).get( trans.security.decode_id( kwargs['unshare_user' ] ) )
+ if not user:
+ error( "User not found for provided id" )
+ association = session.query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=user, stored_workflow=stored ).one()
+ session.delete( association )
+ session.flush()
+ return trans.fill_template( "workflow/sharing.mako",
+ stored=stored )
+
+ @web.expose
+ @web.require_login( "use Galaxy workflows" )
+ def imp( self, trans, id, **kwargs ):
+ session = trans.sa_session
+ stored = get_stored_workflow( trans, id, check_ownership=False )
+ if stored.importable == False:
+ error( "The owner of this workflow has disabled imports via this link" )
+ elif stored.user == trans.user:
+ error( "You are already the owner of this workflow, can't import" )
+ elif stored.deleted:
+ error( "This workflow has been deleted, can't import" )
+ elif session.query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=trans.user, stored_workflow=stored ).count() > 0:
+ error( "This workflow is already shared with you" )
+ else:
+ share = model.StoredWorkflowUserShareAssociation()
+ share.stored_workflow = stored
+ share.user = trans.user
+ session = trans.sa_session
+ session.save_or_update( share )
+ session.flush()
+ # Redirect to load galaxy frames.
+ return trans.response.send_redirect( url_for( controller='workflow' ) )
+
+ @web.expose
+ @web.require_login( "use Galaxy workflows" )
+ def rename( self, trans, id, new_name=None ):
+ stored = get_stored_workflow( trans, id )
+ if new_name is not None:
+ stored.name = new_name
+ trans.sa_session.flush()
+ trans.set_message( "Workflow renamed to '%s'." % new_name )
+ return self.list( trans )
+ else:
+ return form( url_for( id=trans.security.encode_id(stored.id) ), "Rename workflow", submit_text="Rename" ) \
+ .add_text( "new_name", "Workflow Name", value=stored.name )
+
+ @web.expose
+ @web.require_login( "use Galaxy workflows" )
+ def clone( self, trans, id ):
+ stored = get_stored_workflow( trans, id, check_ownership=False )
+ user = trans.get_user()
+ if stored.user == user:
+ owner = True
+ else:
+ if trans.sa_session.query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=user, stored_workflow=stored ).count() == 0:
+ error( "Workflow is not owned by or shared with current user" )
+ owner = False
+ new_stored = model.StoredWorkflow()
+ new_stored.name = "Clone of '%s'" % stored.name
+ new_stored.latest_workflow = stored.latest_workflow
+ if not owner:
+ new_stored.name += " shared by '%s'" % stored.user.email
+ new_stored.user = user
+ # Persist
+ session = trans.sa_session
+ session.save_or_update( new_stored )
+ session.flush()
+ # Display the management page
+ trans.set_message( 'Clone created with name "%s"' % new_stored.name )
+ return self.list( trans )
+
+ @web.expose
+ @web.require_login( "create workflows" )
+ def create( self, trans, workflow_name=None ):
+ """
+ Create a new stored workflow with name `workflow_name`.
+ """
+ user = trans.get_user()
+ if workflow_name is not None:
+ # Create the new stored workflow
+ stored_workflow = model.StoredWorkflow()
+ stored_workflow.name = workflow_name
+ stored_workflow.user = user
+ # And the first (empty) workflow revision
+ workflow = model.Workflow()
+ workflow.name = workflow_name
+ workflow.stored_workflow = stored_workflow
+ stored_workflow.latest_workflow = workflow
+ # Persist
+ session = trans.sa_session
+ session.save_or_update( stored_workflow )
+ session.flush()
+ # Display the management page
+ trans.set_message( "Workflow '%s' created" % stored_workflow.name )
+ return self.list( trans )
+ else:
+ return form( url_for(), "Create new workflow", submit_text="Create" ) \
+ .add_text( "workflow_name", "Workflow Name", value="Unnamed cloud" )
+
+ @web.expose
+ @web.require_login( "add AWS credentials" )
+ def add( self, trans, account_name=None ):
+ """
+ Add user's AWS credentials stored under name `account_name`.
+ """
+ user = trans.get_user()
+ if account_name is not None:
+ """
+ # Create the new stored workflow
+ stored_workflow = model.StoredWorkflow()
+ stored_workflow.name = workflow_name
+ stored_workflow.user = user
+ # And the first (empty) workflow revision
+ workflow = model.Workflow()
+ workflow.name = workflow_name
+ workflow.stored_workflow = stored_workflow
+ stored_workflow.latest_workflow = workflow
+ # Persist
+ session = trans.sa_session
+ session.save_or_update( stored_workflow )
+ session.flush()
+ # Display the management page
+ trans.set_message( "Workflow '%s' created" % stored_workflow.name )
+ return self.list( trans )
+ """
+ else:
+ return form( url_for(), "Add AWS credentials", submit_text="Add" ) \
+ .add_text( "account_name", "Account Name", value="Unnamed credentials" )
+
+ @web.expose
+ def delete( self, trans, id=None ):
+ """
+ Mark a workflow as deleted
+ """
+ # Load workflow from database
+ stored = get_stored_workflow( trans, id )
+ # Marke as deleted and save
+ stored.deleted = True
+ stored.flush()
+ # Display the management page
+ trans.set_message( "Workflow '%s' deleted" % stored.name )
+ return self.list( trans )
+
+ @web.expose
+ @web.require_login( "edit workflows" )
+ def editor( self, trans, id=None ):
+ """
+ Render the main workflow editor interface. The canvas is embedded as
+ an iframe (neccesary for scrolling to work properly), which is
+ rendered by `editor_canvas`.
+ """
+ if not id:
+ error( "Invalid workflow id" )
+ id = trans.security.decode_id( id )
+ return trans.fill_template( "workflow/editor.mako", workflow_id=id )
+
+ @web.json
+ def editor_form_post( self, trans, type='tool', tool_id=None, **incoming ):
+ """
+ Accepts a tool state and incoming values, and generates a new tool
+ form and some additional information, packed into a json dictionary.
+ This is used for the form shown in the right pane when a node
+ is selected.
+ """
+ trans.workflow_building_mode = True
+ module = module_factory.from_dict( trans, {
+ 'type': type,
+ 'tool_id': tool_id,
+ 'tool_state': incoming.pop("tool_state")
+ } )
+ module.update_state( incoming )
+ return {
+ 'tool_state': module.get_state(),
+ 'data_inputs': module.get_data_inputs(),
+ 'data_outputs': module.get_data_outputs(),
+ 'tool_errors': module.get_errors(),
+ 'form_html': module.get_config_form()
+ }
+
+ @web.json
+ def get_new_module_info( self, trans, type, **kwargs ):
+ """
+ Get the info for a new instance of a module initialized with default
+ paramters (any keyword arguments will be passed along to the module).
+ Result includes data inputs and outputs, html representation
+ of the initial form, and the initial tool state (with default values).
+ This is called asynchronously whenever a new node is added.
+ """
+ trans.workflow_building_mode = True
+ module = module_factory.new( trans, type, **kwargs )
+ return {
+ 'type': module.type,
+ 'name': module.get_name(),
+ 'tool_id': module.get_tool_id(),
+ 'tool_state': module.get_state(),
+ 'data_inputs': module.get_data_inputs(),
+ 'data_outputs': module.get_data_outputs(),
+ 'form_html': module.get_config_form()
+ }
+
+ @web.json
+ def load_workflow( self, trans, id ):
+ """
+ Get the latest Workflow for the StoredWorkflow identified by `id` and
+ encode it as a json string that can be read by the workflow editor
+ web interface.
+ """
+ user = trans.get_user()
+ id = trans.security.decode_id( id )
+ trans.workflow_building_mode = True
+ # Load encoded workflow from database
+ stored = trans.sa_session.query( model.StoredWorkflow ).get( id )
+ assert stored.user == user
+ workflow = stored.latest_workflow
+ # Pack workflow data into a dictionary and return
+ data = {}
+ data['name'] = workflow.name
+ data['steps'] = {}
+ data['upgrade_messages'] = {}
+ # For each step, rebuild the form and encode the state
+ for step in workflow.steps:
+ # Load from database representation
+ module = module_factory.from_workflow_step( trans, step )
+ # Fix any missing parameters
+ upgrade_message = module.check_and_update_state()
+ if upgrade_message:
+ data['upgrade_messages'][step.order_index] = upgrade_message
+ # Pack atrributes into plain dictionary
+ step_dict = {
+ 'id': step.order_index,
+ 'type': module.type,
+ 'tool_id': module.get_tool_id(),
+ 'name': module.get_name(),
+ 'tool_state': module.get_state(),
+ 'tool_errors': module.get_errors(),
+ 'data_inputs': module.get_data_inputs(),
+ 'data_outputs': module.get_data_outputs(),
+ 'form_html': module.get_config_form(),
+ }
+ # Connections
+ input_conn_dict = {}
+ for conn in step.input_connections:
+ input_conn_dict[ conn.input_name ] = \
+ dict( id=conn.output_step.order_index, output_name=conn.output_name )
+ step_dict['input_connections'] = input_conn_dict
+ # Position
+ step_dict['position'] = step.position
+ # Add to return value
+ data['steps'][step.order_index] = step_dict
+ print data['upgrade_messages']
+ return data
+
+ @web.json
+ def save_workflow( self, trans, id, workflow_data ):
+ """
+ Save the workflow described by `workflow_data` with id `id`.
+ """
+ # Get the stored workflow
+ stored = get_stored_workflow( trans, id )
+ # Put parameters in workflow mode
+ trans.workflow_building_mode = True
+ # Convert incoming workflow data from json
+ data = simplejson.loads( workflow_data )
+ # Create new workflow from incoming data
+ workflow = model.Workflow()
+ # Just keep the last name (user can rename later)
+ workflow.name = stored.name
+ # Assume no errors until we find a step that has some
+ workflow.has_errors = False
+ # Create each step
+ steps = []
+ # The editor will provide ids for each step that we don't need to save,
+ # but do need to use to make connections
+ steps_by_external_id = {}
+ # First pass to build step objects and populate basic values
+ for key, step_dict in data['steps'].iteritems():
+ # Create the model class for the step
+ step = model.WorkflowStep()
+ steps.append( step )
+ steps_by_external_id[ step_dict['id' ] ] = step
+ # FIXME: Position should be handled inside module
+ step.position = step_dict['position']
+ module = module_factory.from_dict( trans, step_dict )
+ module.save_to_step( step )
+ if step.tool_errors:
+ workflow.has_errors = True
+ # Stick this in the step temporarily
+ step.temp_input_connections = step_dict['input_connections']
+ # Second pass to deal with connections between steps
+ for step in steps:
+ # Input connections
+ for input_name, conn_dict in step.temp_input_connections.iteritems():
+ if conn_dict:
+ conn = model.WorkflowStepConnection()
+ conn.input_step = step
+ conn.input_name = input_name
+ conn.output_name = conn_dict['output_name']
+ conn.output_step = steps_by_external_id[ conn_dict['id'] ]
+ del step.temp_input_connections
+ # Order the steps if possible
+ attach_ordered_steps( workflow, steps )
+ # Connect up
+ workflow.stored_workflow = stored
+ stored.latest_workflow = workflow
+ # Persist
+ trans.sa_session.flush()
+ # Return something informative
+ errors = []
+ if workflow.has_errors:
+ errors.append( "Some steps in this workflow have validation errors" )
+ if workflow.has_cycles:
+ errors.append( "This workflow contains cycles" )
+ if errors:
+ rval = dict( message="Workflow saved, but will not be runnable due to the following errors",
+ errors=errors )
+ else:
+ rval = dict( message="Workflow saved" )
+ rval['name'] = workflow.name
+ return rval
+
+ @web.json
+ def get_datatypes( self, trans ):
+ ext_to_class_name = dict()
+ classes = []
+ for k, v in trans.app.datatypes_registry.datatypes_by_extension.iteritems():
+ c = v.__class__
+ ext_to_class_name[k] = c.__module__ + "." + c.__name__
+ classes.append( c )
+ class_to_classes = dict()
+ def visit_bases( types, cls ):
+ for base in cls.__bases__:
+ if issubclass( base, Data ):
+ types.add( base.__module__ + "." + base.__name__ )
+ visit_bases( types, base )
+ for c in classes:
+ n = c.__module__ + "." + c.__name__
+ types = set( [ n ] )
+ visit_bases( types, c )
+ class_to_classes[ n ] = dict( ( t, True ) for t in types )
+ return dict( ext_to_class_name=ext_to_class_name, class_to_classes=class_to_classes )
+
+ @web.expose
+ def build_from_current_history( self, trans, job_ids=None, dataset_ids=None, workflow_name=None ):
+ user = trans.get_user()
+ history = trans.get_history()
+ if not user:
+ return trans.show_error_message( "Must be logged in to create workflows" )
+ if ( job_ids is None and dataset_ids is None ) or workflow_name is None:
+ jobs, warnings = get_job_dict( trans )
+ # Render
+ return trans.fill_template(
+ "workflow/build_from_current_history.mako",
+ jobs=jobs,
+ warnings=warnings,
+ history=history )
+ else:
+ # Ensure job_ids and dataset_ids are lists (possibly empty)
+ if job_ids is None:
+ job_ids = []
+ elif type( job_ids ) is not list:
+ job_ids = [ job_ids ]
+ if dataset_ids is None:
+ dataset_ids = []
+ elif type( dataset_ids ) is not list:
+ dataset_ids = [ dataset_ids ]
+ # Convert both sets of ids to integers
+ job_ids = [ int( id ) for id in job_ids ]
+ dataset_ids = [ int( id ) for id in dataset_ids ]
+ # Find each job, for security we (implicately) check that they are
+ # associated witha job in the current history.
+ jobs, warnings = get_job_dict( trans )
+ jobs_by_id = dict( ( job.id, job ) for job in jobs.keys() )
+ steps = []
+ steps_by_job_id = {}
+ hid_to_output_pair = {}
+ # Input dataset steps
+ for hid in dataset_ids:
+ step = model.WorkflowStep()
+ step.type = 'data_input'
+ hid_to_output_pair[ hid ] = ( step, 'output' )
+ steps.append( step )
+ # Tool steps
+ for job_id in job_ids:
+ assert job_id in jobs_by_id, "Attempt to create workflow with job not connected to current history"
+ job = jobs_by_id[ job_id ]
+ tool = trans.app.toolbox.tools_by_id[ job.tool_id ]
+ param_values = job.get_param_values( trans.app )
+ associations = cleanup_param_values( tool.inputs, param_values )
+ step = model.WorkflowStep()
+ step.type = 'tool'
+ step.tool_id = job.tool_id
+ step.tool_inputs = tool.params_to_strings( param_values, trans.app )
+ # NOTE: We shouldn't need to do two passes here since only
+ # an earlier job can be used as an input to a later
+ # job.
+ for other_hid, input_name in associations:
+ if other_hid in hid_to_output_pair:
+ other_step, other_name = hid_to_output_pair[ other_hid ]
+ conn = model.WorkflowStepConnection()
+ conn.input_step = step
+ conn.input_name = input_name
+ # Should always be connected to an earlier step
+ conn.output_step = other_step
+ conn.output_name = other_name
+ steps.append( step )
+ steps_by_job_id[ job_id ] = step
+ # Store created dataset hids
+ for assoc in job.output_datasets:
+ hid_to_output_pair[ assoc.dataset.hid ] = ( step, assoc.name )
+ # Workflow to populate
+ workflow = model.Workflow()
+ workflow.name = workflow_name
+ # Order the steps if possible
+ attach_ordered_steps( workflow, steps )
+ # And let's try to set up some reasonable locations on the canvas
+ # (these are pretty arbitrary values)
+ levorder = order_workflow_steps_with_levels( steps )
+ base_pos = 10
+ for i, steps_at_level in enumerate( levorder ):
+ for j, index in enumerate( steps_at_level ):
+ step = steps[ index ]
+ step.position = dict( top = ( base_pos + 120 * j ),
+ left = ( base_pos + 220 * i ) )
+ # Store it
+ stored = model.StoredWorkflow()
+ stored.user = user
+ stored.name = workflow_name
+ workflow.stored_workflow = stored
+ stored.latest_workflow = workflow
+ trans.sa_session.save_or_update( stored )
+ trans.sa_session.flush()
+ # Index page with message
+ return trans.show_message( "Workflow '%s' created from current history." % workflow_name )
+ ## return trans.show_ok_message( "<p>Workflow '%s' created.</p><p><a target='_top' href='%s'>Click to load in workflow editor</a></p>"
+ ## % ( workflow_name, web.url_for( action='editor', id=trans.security.encode_id(stored.id) ) ) )
+
+ @web.expose
+ def run( self, trans, id, check_user=True, **kwargs ):
+ stored = get_stored_workflow( trans, id, check_ownership=False )
+ if check_user:
+ user = trans.get_user()
+ if stored.user != user:
+ if trans.sa_session.query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=user, stored_workflow=stored ).count() == 0:
+ error( "Workflow is not owned by or shared with current user" )
+ # Get the latest revision
+ workflow = stored.latest_workflow
+ # It is possible for a workflow to have 0 steps
+ if len( workflow.steps ) == 0:
+ error( "Workflow cannot be run because it does not have any steps" )
+ #workflow = Workflow.from_simple( simplejson.loads( stored.encoded_value ), trans.app )
+ if workflow.has_cycles:
+ error( "Workflow cannot be run because it contains cycles" )
+ if workflow.has_errors:
+ error( "Workflow cannot be run because of validation errors in some steps" )
+ # Build the state for each step
+ errors = {}
+ if kwargs:
+ # If kwargs were provided, the states for each step should have
+ # been POSTed
+ for step in workflow.steps:
+ # Connections by input name
+ step.input_connections_by_name = \
+ dict( ( conn.input_name, conn ) for conn in step.input_connections )
+ # Extract just the arguments for this step by prefix
+ p = "%s|" % step.id
+ l = len(p)
+ step_args = dict( ( k[l:], v ) for ( k, v ) in kwargs.iteritems() if k.startswith( p ) )
+ step_errors = None
+ if step.type == 'tool' or step.type is None:
+ module = module_factory.from_workflow_step( trans, step )
+ # Any connected input needs to have value DummyDataset (these
+ # are not persisted so we need to do it every time)
+ module.add_dummy_datasets( connections=step.input_connections )
+ # Get the tool
+ tool = module.tool
+ # Get the state
+ step.state = state = module.state
+ # Get old errors
+ old_errors = state.inputs.pop( "__errors__", {} )
+ # Update the state
+ step_errors = tool.update_state( trans, tool.inputs, step.state.inputs, step_args,
+ update_only=True, old_errors=old_errors )
+ else:
+ module = step.module = module_factory.from_workflow_step( trans, step )
+ state = step.state = module.decode_runtime_state( trans, step_args.pop( "tool_state" ) )
+ step_errors = module.update_runtime_state( trans, state, step_args )
+ if step_errors:
+ errors[step.id] = state.inputs["__errors__"] = step_errors
+ if 'run_workflow' in kwargs and not errors:
+ # Run each step, connecting outputs to inputs
+ outputs = odict()
+ for i, step in enumerate( workflow.steps ):
+ if step.type == 'tool' or step.type is None:
+ tool = trans.app.toolbox.tools_by_id[ step.tool_id ]
+ input_values = step.state.inputs
+ # Connect up
+ def callback( input, value, prefixed_name, prefixed_label ):
+ if isinstance( input, DataToolParameter ):
+ if prefixed_name in step.input_connections_by_name:
+ conn = step.input_connections_by_name[ prefixed_name ]
+ return outputs[ conn.output_step.id ][ conn.output_name ]
+ visit_input_values( tool.inputs, step.state.inputs, callback )
+ # Execute it
+ outputs[ step.id ] = tool.execute( trans, step.state.inputs )
+ else:
+ outputs[ step.id ] = step.module.execute( trans, step.state )
+
+ return trans.fill_template( "workflow/run_complete.mako",
+ workflow=stored,
+ outputs=outputs )
+ else:
+ for step in workflow.steps:
+ if step.type == 'tool' or step.type is None:
+ # Restore the tool state for the step
+ module = module_factory.from_workflow_step( trans, step )
+ # Any connected input needs to have value DummyDataset (these
+ # are not persisted so we need to do it every time)
+ module.add_dummy_datasets( connections=step.input_connections )
+ # Store state with the step
+ step.module = module
+ step.state = module.state
+ # Error dict
+ if step.tool_errors:
+ errors[step.id] = step.tool_errors
+ else:
+ ## Non-tool specific stuff?
+ step.module = module_factory.from_workflow_step( trans, step )
+ step.state = step.module.get_runtime_state()
+ # Connections by input name
+ step.input_connections_by_name = dict( ( conn.input_name, conn ) for conn in step.input_connections )
+ # Render the form
+ return trans.fill_template(
+ "workflow/run.mako",
+ steps=workflow.steps,
+ workflow=stored,
+ errors=errors,
+ incoming=kwargs )
+
+ @web.expose
+ def configure_menu( self, trans, workflow_ids=None ):
+ user = trans.get_user()
+ if trans.request.method == "POST":
+ if workflow_ids is None:
+ workflow_ids = []
+ elif type( workflow_ids ) != list:
+ workflow_ids = [ workflow_ids ]
+ sess = trans.sa_session
+ # This explicit remove seems like a hack, need to figure out
+ # how to make the association do it automatically.
+ for m in user.stored_workflow_menu_entries:
+ sess.delete( m )
+ user.stored_workflow_menu_entries = []
+ q = sess.query( model.StoredWorkflow )
+ # To ensure id list is unique
+ seen_workflow_ids = set()
+ for id in workflow_ids:
+ if id in seen_workflow_ids:
+ continue
+ else:
+ seen_workflow_ids.add( id )
+ m = model.StoredWorkflowMenuEntry()
+ m.stored_workflow = q.get( id )
+ user.stored_workflow_menu_entries.append( m )
+ sess.flush()
+ return trans.show_message( "Menu updated", refresh_frames=['tools'] )
+ else:
+ user = trans.get_user()
+ ids_in_menu = set( [ x.stored_workflow_id for x in user.stored_workflow_menu_entries ] )
+ workflows = trans.sa_session.query( model.StoredWorkflow ) \
+ .filter_by( user=user, deleted=False ) \
+ .order_by( desc( model.StoredWorkflow.c.update_time ) ) \
+ .all()
+ shared_by_others = trans.sa_session \
+ .query( model.StoredWorkflowUserShareAssociation ) \
+ .filter_by( user=user ) \
+ .filter( model.StoredWorkflow.c.deleted == False ) \
+ .all()
+ return trans.fill_template( "workflow/configure_menu.mako",
+ workflows=workflows,
+ shared_by_others=shared_by_others,
+ ids_in_menu=ids_in_menu )
+
+## ---- Utility methods -------------------------------------------------------
+
+def get_stored_workflow( trans, id, check_ownership=True ):
+ """
+ Get a StoredWorkflow from the database by id, verifying ownership.
+ """
+ # Load workflow from database
+ id = trans.security.decode_id( id )
+ stored = trans.sa_session.query( model.StoredWorkflow ).get( id )
+ if not stored:
+ error( "Workflow not found" )
+ # Verify ownership
+ user = trans.get_user()
+ if not user:
+ error( "Must be logged in to use workflows" )
+ if check_ownership and not( stored.user == user ):
+ error( "Workflow is not owned by current user" )
+ # Looks good
+ return stored
+
+def attach_ordered_steps( workflow, steps ):
+ ordered_steps = order_workflow_steps( steps )
+ if ordered_steps:
+ workflow.has_cycles = False
+ for i, step in enumerate( ordered_steps ):
+ step.order_index = i
+ workflow.steps.append( step )
+ else:
+ workflow.has_cycles = True
+ workflow.steps = steps
+
+def edgelist_for_workflow_steps( steps ):
+ """
+ Create a list of tuples representing edges between `WorkflowSteps` based
+ on associated `WorkflowStepConnection`s
+ """
+ edges = []
+ steps_to_index = dict( ( step, i ) for i, step in enumerate( steps ) )
+ for step in steps:
+ edges.append( ( steps_to_index[step], steps_to_index[step] ) )
+ for conn in step.input_connections:
+ edges.append( ( steps_to_index[conn.output_step], steps_to_index[conn.input_step] ) )
+ return edges
+
+def order_workflow_steps( steps ):
+ """
+ Perform topological sort of the steps, return ordered or None
+ """
+ try:
+ edges = edgelist_for_workflow_steps( steps )
+ node_order = topsort( edges )
+ return [ steps[i] for i in node_order ]
+ except CycleError:
+ return None
+
+def order_workflow_steps_with_levels( steps ):
+ try:
+ return topsort_levels( edgelist_for_workflow_steps( steps ) )
+ except CycleError:
+ return None
+
+class FakeJob( object ):
+ """
+ Fake job object for datasets that have no creating_job_associations,
+ they will be treated as "input" datasets.
+ """
+ def __init__( self, dataset ):
+ self.is_fake = True
+ self.id = "fake_%s" % dataset.id
+
+def get_job_dict( trans ):
+ """
+ Return a dictionary of Job -> [ Dataset ] mappings, for all finished
+ active Datasets in the current history and the jobs that created them.
+ """
+ history = trans.get_history()
+ # Get the jobs that created the datasets
+ warnings = set()
+ jobs = odict()
+ for dataset in history.active_datasets:
+ # FIXME: Create "Dataset.is_finished"
+ if dataset.state in ( 'new', 'running', 'queued' ):
+ warnings.add( "Some datasets still queued or running were ignored" )
+ continue
+
+ #if this hda was copied from another, we need to find the job that created the origial hda
+ job_hda = dataset
+ while job_hda.copied_from_history_dataset_association:
+ job_hda = job_hda.copied_from_history_dataset_association
+
+ if not job_hda.creating_job_associations:
+ jobs[ FakeJob( dataset ) ] = [ ( None, dataset ) ]
+
+ for assoc in job_hda.creating_job_associations:
+ job = assoc.job
+ if job in jobs:
+ jobs[ job ].append( ( assoc.name, dataset ) )
+ else:
+ jobs[ job ] = [ ( assoc.name, dataset ) ]
+ return jobs, warnings
+
+def cleanup_param_values( inputs, values ):
+ """
+ Remove 'Data' values from `param_values`, along with metadata cruft,
+ but track the associations.
+ """
+ associations = []
+ names_to_clean = []
+ # dbkey is pushed in by the framework
+ if 'dbkey' in values:
+ del values['dbkey']
+ root_values = values
+ # Recursively clean data inputs and dynamic selects
+ def cleanup( prefix, inputs, values ):
+ for key, input in inputs.items():
+ if isinstance( input, ( SelectToolParameter, DrillDownSelectToolParameter ) ):
+ if input.is_dynamic:
+ values[key] = UnvalidatedValue( values[key] )
+ if isinstance( input, DataToolParameter ):
+ tmp = values[key]
+ values[key] = None
+ # HACK: Nested associations are not yet working, but we
+ # still need to clean them up so we can serialize
+ # if not( prefix ):
+ if tmp: #this is false for a non-set optional dataset
+ associations.append( ( tmp.hid, prefix + key ) )
+ # Cleanup the other deprecated crap associated with datasets
+ # as well. Worse, for nested datasets all the metadata is
+ # being pushed into the root. FIXME: MUST REMOVE SOON
+ key = prefix + key + "_"
+ for k in root_values.keys():
+ if k.startswith( key ):
+ del root_values[k]
+ elif isinstance( input, Repeat ):
+ group_values = values[key]
+ for i, rep_values in enumerate( group_values ):
+ rep_index = rep_values['__index__']
+ prefix = "%s_%d|" % ( key, rep_index )
+ cleanup( prefix, input.inputs, group_values[i] )
+ elif isinstance( input, Conditional ):
+ group_values = values[input.name]
+ current_case = group_values['__current_case__']
+ prefix = "%s|" % ( key )
+ cleanup( prefix, input.cases[current_case].inputs, group_values )
+ cleanup( "", inputs, values )
+ return associations
diff -r b46effa7b459 -r 7d19363e6e0d templates/cloud/configure_cloud.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/cloud/configure_cloud.mako Thu Aug 20 11:27:30 2009 -0400
@@ -0,0 +1,61 @@
+<%inherit file="/base.mako"/>
+
+<%def name="title()">Workflow home</%def>
+
+%if message:
+<%
+ try:
+ messagetype
+ except:
+ messagetype = "done"
+%>
+<p />
+<div class="${messagetype}message">
+ ${message}
+</div>
+%endif
+
+<h2>Galaxy in the clouds</h2>
+
+%if awsCredentials:
+ <table class="mange-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
+ <tr class="header">
+ <th>Name</th>
+ <th># of Steps</th>
+ ## <th>Last Updated</th>
+ <th></th>
+ </tr>
+ %for i, workflow in enumerate( workflows ):
+ <tr>
+ <td>
+ ${workflow.name}
+ <a id="wf-${i}-popup" class="popup-arrow" style="display: none;">▼</a>
+ </td>
+ <td>${len(workflow.latest_workflow.steps)}</td>
+ ## <td>${str(workflow.update_time)[:19]}</td>
+ <td>
+ <div popupmenu="wf-${i}-popup">
+ <a class="action-button" href="${h.url_for( action='editor', id=trans.security.encode_id(workflow.id) )}" target="_parent">Edit</a>
+ <a class="action-button" href="${h.url_for( controller='root', action='index', workflow_id=trans.security.encode_id(workflow.id) )}" target="_parent">Run</a>
+ <a class="action-button" href="${h.url_for( action='clone', id=trans.security.encode_id(workflow.id) )}">Clone</a>
+ <a class="action-button" href="${h.url_for( action='rename', id=trans.security.encode_id(workflow.id) )}">Rename</a>
+ <a class="action-button" href="${h.url_for( action='sharing', id=trans.security.encode_id(workflow.id) )}">Sharing</a>
+ <a class="action-button" confirm="Are you sure you want to delete workflow '${workflow.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(workflow.id) )}">Delete</a>
+ </div>
+ </td>
+ </tr>
+ %endfor
+ </table>
+%else:
+
+ You have no AWS credentials associated with your Galaxy account:
+ <a class="action-button" href="${h.url_for( action='add' )}">
+ <img src="${h.url_for('/static/images/silk/add.png')}" />
+ <span>Add AWS credentials</span>
+ </a>
+ or
+ <a href="http://aws.amazon.com/" target="_blank">
+ open AWS account with Amazon</a>.
+
+%endif
+
diff -r b46effa7b459 -r 7d19363e6e0d templates/cloud/index.mako
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/cloud/index.mako Thu Aug 20 11:27:30 2009 -0400
@@ -0,0 +1,16 @@
+<%inherit file="/base_panels.mako"/>
+
+<%def name="init()">
+<%
+ self.has_left_panel=False
+ self.has_right_panel=False
+ self.active_view="cloud"
+ self.message_box_visible=False
+%>
+</%def>
+
+<%def name="center_panel()">
+
+ <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${h.url_for( controller="cloud", action="list" )}"> </iframe>
+
+</%def>
\ No newline at end of file
1
0

23 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/b46effa7b459
changeset: 3047:b46effa7b459
user: afgane(a)dhcp243061.rollins.emory.edu
date: Thu Aug 20 11:01:57 2009 -0400
description:
Added Cloud tab to main page with associated pages.
diffstat:
templates/base_panels.mako | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diffs (12 lines):
diff -r 5fa8803716fd -r b46effa7b459 templates/base_panels.mako
--- a/templates/base_panels.mako Wed Aug 19 18:07:55 2009 -0400
+++ b/templates/base_panels.mako Thu Aug 20 11:01:57 2009 -0400
@@ -141,6 +141,8 @@
${tab( "libraries", "Data Libraries", h.url_for( controller='library', action='index' ))}
+ ${tab( "cloud", "Cloud", h.url_for( controller='cloud', action='index' ))}
+
%if trans.request_types():
<td class="tab">
<a>Lab</a>
1
0
Hi,
Our group has recently installed a local copy of GALAXY. Prior to that, I had been working from the online version and have a number of histories that I would like to be able to use in our local copy. Is there any way to transfer these histories?
Regards,
Beth Marosy
Beth Marosy, M.S.
Research Specialist
Center for Inherited Disease Research
Johns Hopkins University
410-550-2795
bmarosy1(a)jhmi.edu
2
1
Dear Galaxy team,
I am Sondos Seif, an undergrad student, in Cairo University,
Biomedical Engineering Department. I want to replace the SQLite
database with XML, I was just wondering if there is a way to do that
without having to edit in the engine or detaching SQLAlchemy?
Regards,
--
Sondos Seif El-Din
2
1
Hello Greg Von Kuster,
Thanks very much for your reply.
I have installed a local Galaxy and wrote a new tool config file for our GMap. It's really easy to build a local instance and it works very well now. :)
Becaues our GMap project is still under development, we will email you the inclusion file when we have a stable version which will come soon.
Thanks again for your help.
Best,
Kathleen
20091118
发件人: Greg Von Kuster
发送时间: 2009-11-18 02:10:17
收件人: wangjun
抄送: galaxy-dev
主题: Re: [galaxy-dev] Questions about Galaxy!
Kathleen,
Please install a local instance of Galaxy and develop a data source tool that works between your Galaxy instance and GMap. You can download Galaxy from http://bitbucket.org/galaxy/galaxy-central/wiki/GetGalaxy. When you have your tool working, please submit it to us for possible inclusion in the public Galaxy instance. Thanks very much for your interest in doing this.
Greg Von Kuster
1
0

18 Nov '09
details: http://www.bx.psu.edu/hg/galaxy/rev/4c3cddd02b09
changeset: 3043:4c3cddd02b09
user: Nate Coraor <nate(a)bx.psu.edu>
date: Mon Nov 16 18:38:32 2009 -0500
description:
Job recovery fix for jobs queued but with no runner where track_jobs_in_database=True
diffstat:
lib/galaxy/jobs/__init__.py | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diffs (20 lines):
diff -r df9814119044 -r 4c3cddd02b09 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py Mon Nov 16 16:27:48 2009 -0500
+++ b/lib/galaxy/jobs/__init__.py Mon Nov 16 18:38:32 2009 -0500
@@ -139,10 +139,15 @@
JobWrapper( job, None, self ).fail( 'This tool was disabled before the job completed. Please contact your Galaxy administrator, or' )
elif job.job_runner_name is None:
log.debug( "no runner: %s is still in queued state, adding to the jobs queue" %job.id )
- self.queue.put( ( job.id, job.tool_id ) )
+ if self.track_jobs_in_database:
+ job.state = model.Job.states.NEW
+ else:
+ self.queue.put( ( job.id, job.tool_id ) )
else:
job_wrapper = JobWrapper( job, self.app.toolbox.tools_by_id[ job.tool_id ], self )
self.dispatcher.recover( job, job_wrapper )
+ if self.sa_session.dirty:
+ self.sa_session.flush()
def __monitor( self ):
"""
1
0