details: http://www.bx.psu.edu/hg/galaxy/rev/6632a5d39f41 changeset: 3073:6632a5d39f41 user: Enis Afgan <afgane@gmail.com> date: Mon Oct 26 17:04:47 2009 -0400 description: Added UCI usage record and some automated page refreshes to cope with proper status reporting/visible links. diffstat: lib/galaxy/web/controllers/cloud.py | 11 +++- templates/cloud/configure_cloud.mako | 39 +++++++++++- templates/cloud/view.mako | 35 +++++++---- templates/cloud/view_usage.mako | 88 ++++++++++++++++++++++++++--- 4 files changed, 144 insertions(+), 29 deletions(-) diffs (285 lines): diff -r 676fae1a35f9 -r 6632a5d39f41 lib/galaxy/web/controllers/cloud.py --- a/lib/galaxy/web/controllers/cloud.py Fri Oct 23 17:41:35 2009 -0400 +++ b/lib/galaxy/web/controllers/cloud.py Mon Oct 26 17:04:47 2009 -0400 @@ -165,6 +165,10 @@ ( uci.state != uci_states.PENDING ) and \ ( uci.state != uci_states.DELETING ) and \ ( uci.state != uci_states.DELETING_UCI ) and \ + ( uci.state != uci_states.DELETED ) and \ + ( uci.state != uci_states.RUNNING ) and \ + ( uci.state != uci_states.NEW_UCI ) and \ + ( uci.state != uci_states.NEW ) and \ ( uci.state != uci_states.ERROR ): instance = model.CloudInstance() instance.user = user @@ -247,13 +251,16 @@ @web.expose @web.require_login( "use Galaxy cloud" ) - def usageReport( self, trans ): + def usageReport( self, trans, id ): user = trans.get_user() + id = trans.security.decode_id( id ) prevInstances = trans.sa_session.query( model.CloudInstance ) \ - .filter_by( user=user, state=instance_states.TERMINATED ) \ + .filter_by( user=user, state=instance_states.TERMINATED, uci_id=id ) \ .order_by( desc( model.CloudInstance.c.update_time ) ) \ .all() + + log.debug( "id: %s" % id ) return trans.fill_template( "cloud/view_usage.mako", prevInstances = prevInstances ) diff -r 676fae1a35f9 -r 6632a5d39f41 templates/cloud/configure_cloud.mako --- a/templates/cloud/configure_cloud.mako Fri Oct 23 17:41:35 2009 -0400 +++ b/templates/cloud/configure_cloud.mako Mon Oct 26 17:04:47 2009 -0400 @@ -24,16 +24,46 @@ $.getJSON( "${h.url_for( action='json_update' )}", {}, function ( data ) { for (var i in data) { var elem = '#' + data[i].id; + // Because of different list managing 'live' vs. 'available' instances, refresh entire + // page on necessary state change. + old_state = $(elem + "-state").text(); + new_state = data[i].state; + console.log( "old_state[%d] = %s", i, old_state ); + console.log( "new_state[%d] = %s", i, new_state ); + if ( old_state=='pending' && new_state=='running' ) { + location.reload(true); + } + else if ( old_state=='shutting-down' && new_state=='available' ) { + location.reload(true); + } + else if ( new_state=='shutting-down' || new_state=='shutting-downUCI' ) { + $(elem + "-link").text( "" ); + } + xmlhttp = new XMLHttpRequest(); + xmlhttp.open( "HEAD", "http://127.0.0.1:8080/admin", false ); + xmlhttp.send( null ); + //alert(xmlhttp.getAllResponseHeaders()) + console.log( "xmlhttp.readyState: %s", xmlhttp.readyState ); + console.log( "xmlhttp.status: %s", xmlhttp.status ); + if ( new_state=='running' && xmlhttp.readyState==1 ) { + console.log ("in ready statsus = 1"); + //if (xmlhttp.status==200) { + // console.log( "in status = 200" ); + // location.reload(true); + //} + } + + // Update 'state' and 'time alive' fields $(elem + "-state").text( data[i].state ); if (data[i].launch_time) { - $(elem + "-launch_time").text( data[i].launch_time.substring(0, 16 ) + " (" + data[i].time_ago + ")" ); + $(elem + "-launch_time").text( data[i].launch_time.substring(0, 16 ) + " UTC (" + data[i].time_ago + ")" ); } else { $(elem + "-launch_time").text( "N/A" ); } } }); - setTimeout("update_state()", 10000); + setTimeout("update_state()", 15000); } $(function() { @@ -141,7 +171,7 @@ context.write( ')' ) %> </td> - <td><div align="right"> + <td id="${ liveInstance.id }-link"><div align="right"> %for j, instance in enumerate( liveInstance.instance ): ## TODO: Once more instances will be running under the same liveInstance, additional logic will need to be added to account for that %if instance.state == "running": @@ -165,6 +195,7 @@ <a class="action-button" confirm="Are you sure you want to stop instance '${liveInstance.name}'? Please note that this may take up to 1 minute during which time the page will not refresh." href="${h.url_for( action='stop', id=trans.security.encode_id(liveInstance.id) )}">Stop</a> <a class="action-button" href="${h.url_for( action='renameInstance', id=trans.security.encode_id(liveInstance.id) )}">Rename</a> <a class="action-button" href="${h.url_for( action='viewInstance', id=trans.security.encode_id(liveInstance.id) )}">View details</a> + <a class="action-button" href="${h.url_for( action='usageReport', id=trans.security.encode_id(liveInstance.id) )}">Usage report</a> </div> </td> </tr> @@ -230,7 +261,7 @@ <a class="action-button" href="${h.url_for( action='start', id=trans.security.encode_id(prevInstance.id), type='c1.medium' )}"> Start c1.medium</a> <a class="action-button" href="${h.url_for( action='renameInstance', id=trans.security.encode_id(prevInstance.id) )}">Rename</a> <a class="action-button" href="${h.url_for( action='addStorage', id=trans.security.encode_id(prevInstance.id) )}" target="_parent">Add storage</a> - <a class="action-button" href="${h.url_for( action='usageReport' )}">Usage report</a> + <a class="action-button" href="${h.url_for( action='usageReport', id=trans.security.encode_id(prevInstance.id) )}">Usage report</a> <a class="action-button" confirm="Are you sure you want to delete instance '${prevInstance.name}'? This will delete all of your data assocaiated with this instance!" href="${h.url_for( action='deleteInstance', id=trans.security.encode_id(prevInstance.id) )}">Delete</a> </div> </td> diff -r 676fae1a35f9 -r 6632a5d39f41 templates/cloud/view.mako --- a/templates/cloud/view.mako Fri Oct 23 17:41:35 2009 -0400 +++ b/templates/cloud/view.mako Mon Oct 26 17:04:47 2009 -0400 @@ -1,20 +1,29 @@ <%inherit file="/base.mako"/> -<%def name="title()">Cloud home</%def> +<%def name="title()">Cloud credentials</%def> <h2>Credentials details</h2> +<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> + %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> + ${view_cred( credDetails )} +%else: + There are no credentials under that name. +%endif - <table class="mange-table colored" border="0" cellspacing="0" cellpadding="0" width="100%"> + + + +<%def name="view_cred( credDetails )"> + <table class="mange-table colored" border="0" cellspacing="0" cellpadding="0" width="100%"> <tr> <td> Credentials name: </td> <td> @@ -71,7 +80,7 @@ </div> </td> </tr> - <tr><td><b>Additional cloud provider information (if available):</b></td></tr> + <tr><td id="addl"><b>Additional cloud provider information (if available):</b></td></tr> %if credDetails.provider.region_connection != None: <tr> <td> Region connection: </td> @@ -145,6 +154,4 @@ </tr> %endif </table> -%else: - There are no credentials under that name. -%endif +</%def> diff -r 676fae1a35f9 -r 6632a5d39f41 templates/cloud/view_usage.mako --- a/templates/cloud/view_usage.mako Fri Oct 23 17:41:35 2009 -0400 +++ b/templates/cloud/view_usage.mako Mon Oct 26 17:04:47 2009 -0400 @@ -18,30 +18,100 @@ </div> %endif -<h2>Instance usage report</h2> +%if prevInstances: + <h2>Usage report for instance ${prevInstances[0].uci.name}</h2> +%else: + <h2>Selected instance has no record of being used.</h2> +%endif + +<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> %if prevInstances: <table class="mange-table colored" border="0" cellspacing="0" cellpadding="0" width="100%"> <colgroup width="2%"></colgroup> - <colgroup width="20%"></colgroup> - <colgroup width="20%"></colgroup> + <colgroup width="16%"></colgroup> + <colgroup width="16%"></colgroup> + <colgroup width="10%"></colgroup> <colgroup width="5%"></colgroup> <tr class="header"> <th>#</th> <th>Launch time</th> <th>Termination time</th> + <th>Time alive</th> <th>Type</th> <th></th> </tr> + <% + total_hours = 0 + %> %for i, prevInstance in enumerate( prevInstances ): <tr> <td>${i+1}</td> - <td>${str(prevInstance.launch_time)[:16]} UCT</td> - <td>${str(prevInstance.stop_time)[:16]} UCT</td> + <td> + %if prevInstance.launch_time: + ${str(prevInstance.launch_time)[:16]} UCT + %else: + N/A + %endif + </td> + <td> + %if prevInstance.stop_time: + ${str(prevInstance.stop_time)[:16]} UCT + %else: + N/A + %endif + </td> + <td> + <% + # This is where current time and since duration is calculated + if prevInstance.launch_time is None or prevInstance.stop_time is None: + context.write( 'N/A' ) + else: + context.write( str(h.date.distance_of_time_in_words (prevInstance.launch_time, prevInstance.stop_time ) ) ) + time_delta = prevInstance.stop_time - prevInstance.launch_time + total_hours += time_delta.seconds / 3600 + if time_delta.seconds != 0: + total_hours += 1 + + %> + </td> <td>${prevInstance.type}</td> - </tr> + </tr> %endfor </table> -%else: - Selected instance has no record of being used. -%endif \ No newline at end of file + <br/>Total number of hours instance was alive: ${total_hours} <br /> + Note that these are just best effort estimates - true usage should be obtained from respective cloud provider. <br /> + <%namespace name="view_cred" file="view.mako" /> + + <div id="hide_cred_details"> + This instance uses credentials: + <a onclick="document.getElementById('show_cred_details').style.display = 'block'; + document.getElementById('hide_cred_details').style.display = 'none'; return 0" + href="javascript:void(0)"> + ${prevInstances[0].uci.credentials.name} + </a> + </div> + <div id="show_cred_details" style="DISPLAY: none"> + This instance uses credentials: + <a onclick="document.getElementById('hide_cred_details').style.display = 'block'; + document.getElementById('show_cred_details').style.display = 'none'; return 0;" + href="javascript:void(0)"> + ${prevInstances[0].uci.credentials.name} + </a> + ${view_cred.view_cred( prevInstances[0].uci.credentials ) } + </div> + + +%endif + + + + +