[hg] galaxy 3092: Cleaned up code in main cloud controller.
details: http://www.bx.psu.edu/hg/galaxy/rev/118dc385752b changeset: 3092:118dc385752b user: Enis Afgan <afgane@gmail.com> date: Thu Nov 12 14:24:43 2009 -0500 description: Cleaned up code in main cloud controller. diffstat: lib/galaxy/cloud/providers/ec2.py | 16 +- lib/galaxy/cloud/providers/eucalyptus.py | 12 +- lib/galaxy/web/controllers/cloud.py | 632 +++++++++++++++++----------------- templates/admin/index.mako | 4 +- templates/cloud/add_credentials.mako | 2 +- templates/cloud/add_image.mako | 2 +- templates/cloud/configure_cloud.mako | 30 +- templates/cloud/configure_uci.mako | 2 +- templates/cloud/edit_credentials.mako | 2 +- templates/cloud/edit_image.mako | 2 +- templates/cloud/list_images.mako | 6 +- templates/cloud/view.mako | 157 -------- templates/cloud/viewInstance.mako | 140 ------- templates/cloud/view_credentials.mako | 157 ++++++++ templates/cloud/view_instance.mako | 140 +++++++ templates/cloud/view_usage.mako | 2 +- 16 files changed, 660 insertions(+), 646 deletions(-) diffs (1644 lines): diff -r e21f605d2766 -r 118dc385752b lib/galaxy/cloud/providers/ec2.py --- a/lib/galaxy/cloud/providers/ec2.py Thu Nov 12 12:42:17 2009 -0500 +++ b/lib/galaxy/cloud/providers/ec2.py Thu Nov 12 14:24:43 2009 -0500 @@ -48,7 +48,7 @@ ERROR = "error" ) -store_states = Bunch( +store_status = Bunch( IN_USE = "in-use", CREATING = "creating", DELETED = 'deleted', @@ -105,14 +105,14 @@ elif uci_state==uci_states.SNAPSHOT: self.snapshotUCI( uci_wrapper ) except: - log.exception( "Uncaught exception executing request." ) + log.exception( "Uncaught exception executing cloud request." ) cnt += 1 def get_connection( self, uci_wrapper ): """ Establishes EC2 cloud connection using user's credentials associated with given UCI """ - log.debug( 'Establishing %s cloud connection' % self.type ) + log.debug( 'Establishing %s cloud connection.' % self.type ) provider = uci_wrapper.get_provider() try: region = RegionInfo( None, provider.region_name, provider.region_endpoint ) @@ -127,8 +127,8 @@ is_secure=provider.is_secure, region=region, path=provider.path ) - except Exception, ex: - err = "Establishing connection with cloud failed: " + str( ex ) + except boto.exception.EC2ResponseError, e: + err = "Establishing connection with cloud failed: " + str( e ) log.error( err ) uci_wrapper.set_error( err, True ) return None @@ -545,8 +545,8 @@ self.updateInstance( inst ) # Update storage volume(s) - stores = model.CloudStore.filter( or_( model.CloudStore.c.status==store_states.IN_USE, - model.CloudStore.c.status==store_states.CREATING, + stores = model.CloudStore.filter( or_( model.CloudStore.c.status==store_status.IN_USE, + model.CloudStore.c.status==store_status.CREATING, model.CloudStore.c.status==None ) ).all() for store in stores: if self.type == store.uci.credentials.provider.type: # and store.volume_id != None: @@ -558,7 +558,7 @@ # store.uci.error = "There exists an entry in local database for a storage volume without an ID. Storage volume might have been created " \ # "with cloud provider though. Manual check is recommended. After understanding what happened, local database entry for given " \ # "storage volume should be updated." -# store.status = store_states.ERROR +# store.status = store_status.ERROR # store.uci.state = uci_states.ERROR # store.uci.flush() # store.flush() diff -r e21f605d2766 -r 118dc385752b lib/galaxy/cloud/providers/eucalyptus.py --- a/lib/galaxy/cloud/providers/eucalyptus.py Thu Nov 12 12:42:17 2009 -0500 +++ b/lib/galaxy/cloud/providers/eucalyptus.py Thu Nov 12 14:24:43 2009 -0500 @@ -114,9 +114,9 @@ log.debug( 'Establishing %s cloud connection.' % self.type ) provider = uci_wrapper.get_provider() try: - euca_region = RegionInfo( None, provider.region_name, provider.region_endpoint ) - except Exception, e: - err = "Selecting region with cloud provider failed: " + str( e ) + region = RegionInfo( None, provider.region_name, provider.region_endpoint ) + except Exception, ex: + err = "Selecting region with cloud provider failed: " + str( ex ) log.error( err ) uci_wrapper.set_error( err, True ) return None @@ -125,7 +125,7 @@ aws_secret_access_key=uci_wrapper.get_secret_key(), is_secure=provider.is_secure, port=provider.port, - region=euca_region, + region=region, path=provider.path ) except boto.exception.EC2ResponseError, e: err = "Establishing connection with cloud failed: " + str( e ) @@ -853,12 +853,12 @@ s_key = uci.credentials.secret_key # Get connection try: - euca_region = RegionInfo( None, uci.credentials.provider.region_name, uci.credentials.provider.region_endpoint ) + region = RegionInfo( None, uci.credentials.provider.region_name, uci.credentials.provider.region_endpoint ) conn = EC2Connection( aws_access_key_id=a_key, aws_secret_access_key=s_key, is_secure=uci.credentials.provider.is_secure, port=uci.credentials.provider.port, - region=euca_region, + region=region, path=uci.credentials.provider.path ) except boto.exception.EC2ResponseError, e: err = "Establishing connection with cloud failed: " + str( e ) diff -r e21f605d2766 -r 118dc385752b lib/galaxy/web/controllers/cloud.py --- a/lib/galaxy/web/controllers/cloud.py Thu Nov 12 12:42:17 2009 -0500 +++ b/lib/galaxy/web/controllers/cloud.py Thu Nov 12 14:24:43 2009 -0500 @@ -59,7 +59,7 @@ ERROR = "error" ) -store_states = Bunch( +store_status = Bunch( IN_USE = "in-use", CREATING = "creating", DELETED = 'deleted', @@ -135,9 +135,9 @@ model.UCI.c.state==uci_states.SUBMITTED_UCI ) ) \ .all() if pendingInstances: - trans.set_message( "Galaxy instance started. Note that it will take several minutes for the instance to start " - "(typically, 3-5 minutes). Once the instance is running and Galaxy is available, " - "a button to connect to the instance will then appear alongside instance description." ) + trans.set_message( "Galaxy instance started. NOTE: Please wait about 5 minutes for the instance to " + "start up. A button to connect to the instance will appear alongside " + "instance description once cloud instance of Galaxy is ready." ) # log.debug( "provider.is_secure: '%s'" % trans.sa_session.query( model.CloudProvider).filter_by(id=1).first().is_secure ) # trans.sa_session.query( model.CloudProvider).filter_by(id=1).first().is_secure=False @@ -152,200 +152,11 @@ prevInstances = prevInstances, cloudProviders = cloudProviders ) - @web.expose - @web.require_login( "start Galaxy cloud instance" ) - def start( self, trans, id, type='m1.small' ): - """ - Start a new cloud resource instance - """ - user = trans.get_user() - uci = get_uci( trans, id ) - stores = get_stores( trans, uci ) - # Ensure instance is available and then store relevant data - # into DB to initiate instance startup by cloud manager - if ( len(stores) is not 0 ) and ( uci.state == uci_states.AVAILABLE ): - instance = model.CloudInstance() - instance.user = user - instance.uci = uci - instance.state = instance_states.SUBMITTED - instance.availability_zone = stores[0].availability_zone # Bc. all EBS volumes need to be in the same avail. zone, just check 1st - instance.type = type - uci.state = uci_states.SUBMITTED_UCI - # Persist - session = trans.sa_session - session.save_or_update( instance ) - session.save_or_update( uci ) - session.flush() - # Log - trans.log_event ("User initiated starting of UCI '%s'." % uci.name ) - trans.set_message( "Galaxy instance started. NOTE: Please wait about 5 minutes for the instance to " - "start up. A button to connect to the instance will appear alongside " - "instance description once cloud instance of Galaxy is ready." ) - return self.list( trans ) - - if len(stores) == 0: - error( "This instance does not have any storage volumes associated it and thus cannot be started." ) - else: - error( "Cannot start instance that is in state '%s'." % uci.state ) - return self.list( trans ) - - @web.expose - @web.require_login( "stop Galaxy cloud instance" ) - def stop( self, trans, id ): - """ - Stop a cloud UCI instance. - """ - uci = get_uci( trans, id ) - if ( uci.state != uci_states.DELETING ) and \ - ( uci.state != uci_states.DELETING_UCI ) and \ - ( uci.state != uci_states.ERROR ) and \ - ( uci.state != uci_states.SHUTTING_DOWN_UCI ) and \ - ( uci.state != uci_states.SHUTTING_DOWN ) and \ - ( uci.state != uci_states.AVAILABLE ): - uci.state = uci_states.SHUTTING_DOWN_UCI - session = trans.sa_session - session.save_or_update( uci ) - session.flush() - trans.log_event( "User stopped cloud instance '%s' (id: %s)" % ( uci.name, uci.id ) ) - trans.set_message( "Stopping of Galaxy instance '%s' initiated." % uci.name ) - - return self.list( trans ) - - trans.show_error_message( "Cannot stop instance that is in state '%s'." % uci.state ) - return self.list( trans ) - - @web.expose - @web.require_login( "delete user configured Galaxy cloud instance" ) - def deleteInstance( self, trans, id ): - """ - Deletes User Configured Instance (UCI) from the cloud and local database. NOTE that this implies deletion of - any and all storage associated with this UCI! - """ - uci = get_uci( trans, id ) - - if ( uci.state != uci_states.DELETING_UCI ) and ( uci.state != uci_states.DELETING ) and ( uci.state != uci_states.ERROR ): - name = uci.name - uci.state = uci_states.DELETING_UCI - session = trans.sa_session - session.save_or_update( uci ) - session.flush() - trans.log_event( "User marked cloud instance '%s' for deletion." % name ) - trans.set_message( "Galaxy instance '%s' marked for deletion." % name ) - return self.list( trans ) - - if uci.state != uci_states.ERROR: - trans.set_message( "Cannot delete instance in state ERROR." ) - else: - trans.set_message( "Instance '%s' is already marked for deletion." % uci.name ) - return self.list( trans ) + # ----- UCI methods ----- @web.expose @web.require_login( "use Galaxy cloud" ) - def create_snapshot( self, trans, id ): - user = trans.get_user() - id = trans.security.decode_id( id ) - uci = get_uci( trans, id ) - - stores = trans.sa_session.query( model.CloudStore ) \ - .filter_by( user=user, deleted=False, uci_id=id ) \ - .all() - - if ( len( stores ) > 0 ) and ( uci.state == uci_states.AVAILABLE ): - for store in stores: - snapshot = model.CloudSnapshot() - snapshot.user = user - snapshot.uci = uci - snapshot.store = store - snapshot.status = snapshot_status.SUBMITTED - uci.state = uci_states.SNAPSHOT_UCI - # Persist - session = trans.sa_session - session.save_or_update( snapshot ) - session.save_or_update( uci ) - session.flush() - elif len( stores ) == 0: - error( "No storage volumes found that are associated with this instance." ) - else: - error( "Snapshot can be created only for an instance that is in 'available' state." ) - - # Log and display the management page - trans.log_event( "User initiated creation of new snapshot." ) - trans.set_message( "Creation of new snapshot initiated. " ) - return self.list( trans ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - def view_snapshots( self, trans, id=None ): - """ - View details about any snapshots associated with given UCI - """ - user = trans.get_user() - id = trans.security.decode_id( id ) - - snaps = trans.sa_session.query( model.CloudSnapshot ) \ - .filter_by( user=user, uci_id=id, deleted=False ) \ - .order_by( desc( model.CloudSnapshot.c.update_time ) ) \ - .all() - - return trans.fill_template( "cloud/view_snapshots.mako", - snaps = snaps ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - def delete_snapshot( self, trans, uci_id=None, snap_id=None ): - """ - Initiates deletion of a snapshot - """ - user = trans.get_user() - snap_id = trans.security.decode_id( snap_id ) - # Set snapshot as 'ready for deletion' to be picked up by general updater - snap = trans.sa_session.query( model.CloudSnapshot ).get( snap_id ) - - if snap.status == snapshot_status.COMPLETED: - snap.status = snapshot_status.DELETE - snap.flush() - trans.set_message( "Snapshot '%s' is marked for deletion. Once the deletion is complete, it will no longer be visible in this list. " - "Please note that this process may take up to a minute." % snap.snapshot_id ) - else: - error( "Only snapshots in state 'completed' can be deleted. See the cloud provider directly " - "if you believe the snapshot is available and can be deleted." ) - - # Display new list of snapshots - uci_id = trans.security.decode_id( uci_id ) - snaps = trans.sa_session.query( model.CloudSnapshot ) \ - .filter_by( user=user, uci_id=uci_id, deleted=False ) \ - .order_by( desc( model.CloudSnapshot.c.update_time ) ) \ - .all() - - return trans.fill_template( "cloud/view_snapshots.mako", - snaps = snaps ) - - @web.expose - @web.require_login( "add instance storage" ) - def addStorage( self, trans, id ): - instance = get_uci( trans, id ) - - - error( "Adding storage to instance '%s' is not supported yet." % instance.name ) - - return self.list( trans ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - 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, uci_id=id ) \ - .order_by( desc( model.CloudInstance.c.update_time ) ) \ - .all() - - return trans.fill_template( "cloud/view_usage.mako", prevInstances = prevInstances ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - def configureNew( self, trans, instanceName='', credName='', volSize='', zone='' ): + def configure_new_uci( self, trans, instanceName='', credName='', volSize='', zone='' ): """ Configure and add new cloud instance to user's instance pool """ @@ -447,8 +258,255 @@ providersToZones = providersToZones ) @web.expose + @web.require_login( "start Galaxy cloud instance" ) + def start( self, trans, id, type='m1.small' ): + """ + Start a new cloud resource instance + """ + user = trans.get_user() + uci = get_uci( trans, id ) + stores = get_stores( trans, uci ) + # Ensure instance is available and then store relevant data + # into DB to initiate instance startup by cloud manager + if ( len(stores) is not 0 ) and ( uci.state == uci_states.AVAILABLE ): + instance = model.CloudInstance() + instance.user = user + instance.uci = uci + instance.state = instance_states.SUBMITTED + instance.availability_zone = stores[0].availability_zone # Bc. all EBS volumes need to be in the same avail. zone, just check 1st + instance.type = type + uci.state = uci_states.SUBMITTED_UCI + # Persist + session = trans.sa_session + session.save_or_update( instance ) + session.save_or_update( uci ) + session.flush() + # Log + trans.log_event ("User initiated starting of UCI '%s'." % uci.name ) + trans.set_message( "Galaxy instance started. NOTE: Please wait about 5 minutes for the instance to " + "start up. A button to connect to the instance will appear alongside " + "instance description once cloud instance of Galaxy is ready." ) + return self.list( trans ) + + if len(stores) == 0: + error( "This instance does not have any storage volumes associated it and thus cannot be started." ) + else: + error( "Cannot start instance that is in state '%s'." % uci.state ) + return self.list( trans ) + + @web.expose + @web.require_login( "stop Galaxy cloud instance" ) + def stop( self, trans, id ): + """ + Stop a cloud UCI instance. + """ + uci = get_uci( trans, id ) + if ( uci.state != uci_states.DELETING ) and \ + ( uci.state != uci_states.DELETING_UCI ) and \ + ( uci.state != uci_states.ERROR ) and \ + ( uci.state != uci_states.SHUTTING_DOWN_UCI ) and \ + ( uci.state != uci_states.SHUTTING_DOWN ) and \ + ( uci.state != uci_states.AVAILABLE ): + uci.state = uci_states.SHUTTING_DOWN_UCI + session = trans.sa_session + session.save_or_update( uci ) + session.flush() + trans.log_event( "User stopped cloud instance '%s' (id: %s)" % ( uci.name, uci.id ) ) + trans.set_message( "Stopping of Galaxy instance '%s' initiated." % uci.name ) + + return self.list( trans ) + + trans.show_error_message( "Cannot stop instance that is in state '%s'." % uci.state ) + return self.list( trans ) + + @web.expose + @web.require_login( "use Galaxy cloud" ) + def set_uci_state( self, trans, id, state='available', clear_error=True ): + """ + Sets state of UCI to given state, optionally resets error field, and resets UCI's launch time field to 'None'. + """ + uci = get_uci( trans, id ) + uci.state = state + if clear_error: + uci.error = None + uci.launch_time = None + trans.sa_session.flush() + trans.set_message( "Instance '%s' state reset." % uci.name ) + return self.list( trans ) + + @web.expose + @web.require_login( "view instance details" ) + def view_uci_details( self, trans, id=None ): + """ + View details about running instance + """ + uci = get_uci( trans, id ) + instances = get_instances( trans, uci ) # TODO: Handle list (will probably need to be done in mako template) + + return trans.fill_template( "cloud/view_instance.mako", + liveInstance = instances ) + + @web.expose + @web.require_login( "use Galaxy cloud" ) + def rename_uci( self, trans, id, new_name=None ): + instance = get_uci( trans, id ) + if new_name is not None: + if len(new_name) > 255: + error( "Instance name must be less than 255 characters long." ) + user = trans.get_user() + name_exists = trans.sa_session.query( model.UCI ) \ + .filter_by( user=user, name=new_name ) \ + .first() + if name_exists: + error( "Specified name ('%s') is already used by an existing instance. Please choose an alternative name." % new_name ) + + # Update name in local DB + instance.name = new_name + trans.sa_session.flush() + trans.set_message( "Instance renamed to '%s'." % new_name ) + return self.list( trans ) + else: + return trans.show_form( + web.FormBuilder( url_for( id=trans.security.encode_id(instance.id) ), "Rename instance", submit_text="Rename" ) + .add_text( "new_name", "Instance name", value=instance.name ) ) + + @web.expose + @web.require_login( "use Galaxy cloud" ) + def uci_usage_report( 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, uci_id=id ) \ + .order_by( desc( model.CloudInstance.c.update_time ) ) \ + .all() + + return trans.fill_template( "cloud/view_usage.mako", prevInstances = prevInstances ) + + @web.expose + @web.require_login( "delete user configured Galaxy cloud instance" ) + def delete_uci( self, trans, id ): + """ + Deletes User Configured Instance (UCI) from the cloud and local database. NOTE that this implies deletion of + any and all storage associated with this UCI! + """ + uci = get_uci( trans, id ) + + if ( uci.state != uci_states.DELETING_UCI ) and ( uci.state != uci_states.DELETING ) and ( uci.state != uci_states.ERROR ): + name = uci.name + uci.state = uci_states.DELETING_UCI + session = trans.sa_session + session.save_or_update( uci ) + session.flush() + trans.log_event( "User marked cloud instance '%s' for deletion." % name ) + trans.set_message( "Galaxy instance '%s' marked for deletion." % name ) + return self.list( trans ) + + if uci.state != uci_states.ERROR: + trans.set_message( "Cannot delete instance in state ERROR." ) + else: + trans.set_message( "Instance '%s' is already marked for deletion." % uci.name ) + return self.list( trans ) + + # ----- Snapshot methods ----- + + @web.expose + @web.require_login( "use Galaxy cloud" ) + def create_snapshot( self, trans, id ): + user = trans.get_user() + id = trans.security.decode_id( id ) + uci = get_uci( trans, id ) + + stores = trans.sa_session.query( model.CloudStore ) \ + .filter_by( user=user, deleted=False, uci_id=id ) \ + .all() + + if ( len( stores ) > 0 ) and ( uci.state == uci_states.AVAILABLE ): + for store in stores: + snapshot = model.CloudSnapshot() + snapshot.user = user + snapshot.uci = uci + snapshot.store = store + snapshot.status = snapshot_status.SUBMITTED + uci.state = uci_states.SNAPSHOT_UCI + # Persist + session = trans.sa_session + session.save_or_update( snapshot ) + session.save_or_update( uci ) + session.flush() + elif len( stores ) == 0: + error( "No storage volumes found that are associated with this instance." ) + else: + error( "Snapshot can be created only for an instance that is in 'available' state." ) + + # Log and display the management page + trans.log_event( "User initiated creation of new snapshot." ) + trans.set_message( "Creation of new snapshot initiated. " ) + return self.list( trans ) + + @web.expose + @web.require_login( "use Galaxy cloud" ) + def view_snapshots( self, trans, id=None ): + """ + View details about any snapshots associated with given UCI + """ + user = trans.get_user() + id = trans.security.decode_id( id ) + + snaps = trans.sa_session.query( model.CloudSnapshot ) \ + .filter_by( user=user, uci_id=id, deleted=False ) \ + .order_by( desc( model.CloudSnapshot.c.update_time ) ) \ + .all() + + return trans.fill_template( "cloud/view_snapshots.mako", + snaps = snaps ) + + @web.expose + @web.require_login( "use Galaxy cloud" ) + def delete_snapshot( self, trans, uci_id=None, snap_id=None ): + """ + Initiates deletion of a snapshot + """ + user = trans.get_user() + snap_id = trans.security.decode_id( snap_id ) + # Set snapshot as 'ready for deletion' to be picked up by general updater + snap = trans.sa_session.query( model.CloudSnapshot ).get( snap_id ) + + if snap.status == snapshot_status.COMPLETED: + snap.status = snapshot_status.DELETE + snap.flush() + trans.set_message( "Snapshot '%s' is marked for deletion. Once the deletion is complete, it will no longer be visible in this list. " + "Please note that this process may take up to a minute." % snap.snapshot_id ) + else: + error( "Only snapshots in state 'completed' can be deleted. See the cloud provider directly " + "if you believe the snapshot is available and can be deleted." ) + + # Display new list of snapshots + uci_id = trans.security.decode_id( uci_id ) + snaps = trans.sa_session.query( model.CloudSnapshot ) \ + .filter_by( user=user, uci_id=uci_id, deleted=False ) \ + .order_by( desc( model.CloudSnapshot.c.update_time ) ) \ + .all() + + return trans.fill_template( "cloud/view_snapshots.mako", + snaps = snaps ) + + # ----- Storage methods ----- + + @web.expose + @web.require_login( "add instance storage" ) + def add_storage( self, trans, id ): + instance = get_uci( trans, id ) + + + error( "Adding storage to instance '%s' is not supported yet." % instance.name ) + + return self.list( trans ) + + # ----- Image methods ----- + @web.expose @web.require_admin - def addNewImage( self, trans, provider_type='', image_id='', manifest='', architecture='', state=None ): + def add_new_image( self, trans, provider_type='', image_id='', manifest='', architecture='', state=None ): #id_error = arch_error = provider_error = manifest_error = None error = {} if provider_type or image_id or manifest or architecture: @@ -498,24 +556,24 @@ @web.expose @web.require_login( "use Galaxy cloud" ) - def listMachineImages( self, trans ): + def list_machine_images( self, trans ): images = trans.sa_session.query( model.CloudImage ).filter( trans.app.model.CloudImage.table.c.deleted != True ).all() return trans.fill_template( '/cloud/list_images.mako', images=images ) @web.expose @web.require_admin - def deleteImage( self, trans, id=None ): + def delete_image( self, trans, id=None ): if not isinstance( id, int ): id = trans.security.decode_id( id ) image = trans.sa_session.query( model.CloudImage ).get( id ) image.deleted = True image.flush() - return self.listMachineImages( trans ) + return self.list_machine_images( trans ) @web.expose @web.require_admin - def editImage( self, trans, provider_type='', image_id='', manifest='', architecture='', id='', edited=False ): + def edit_image( self, trans, provider_type='', image_id='', manifest='', architecture='', id='', edited=False ): error = {} if not isinstance( id, int ): id = trans.security.decode_id( id ) @@ -552,93 +610,13 @@ session.flush() # Log and display the management page trans.set_message( "Machine image '%s' edited." % image.image_id ) - return self.listMachineImages( trans ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - def edit( self, trans, id, credName=None, accessKey=None, secretKey=None, edited=False ): - error = {} - if not edited: - credentials = get_stored_credentials( trans, id ) - return trans.fill_template( "cloud/edit_credentials.mako", - credential = credentials, - error = error - ) - else: - user = trans.get_user() - credentials = get_stored_credentials( trans, id ) - if credName=='' or len( credName ) > 255: - error['cred_error'] = "Credentials name must be between 1 and 255 characters in length." - elif trans.app.model.CloudUserCredentials \ - .filter_by( user=user ) \ - .filter( and_( trans.app.model.CloudUserCredentials.table.c.id != credentials.id, trans.app.model.CloudUserCredentials.table.c.name==credName ) ) \ - .first(): - error['cred_error'] = "Credentials with name '" + credName + "' already exist. Please choose an alternative name." - elif accessKey=='' or len( accessKey ) > 255: - error['access_key_error'] = "Access key must be between 1 and 255 characters long." - elif secretKey=='' or len( secretKey ) > 255: - error['secret_key_error'] = "Secret key must be between 1 and 255 characters long." + return self.list_machine_images( trans ) - if error: - return trans.fill_template( "cloud/edit_credentials.mako", - credential = credentials, - error = error - ) - else: - # Edit user stored credentials - credentials.name = credName - 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.set_message( "Credential '%s' edited." % credentials.name ) - return self.list( trans ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - def renameInstance( self, trans, id, new_name=None ): - instance = get_uci( trans, id ) - if new_name is not None: - if len(new_name) > 255: - error( "Instance name must be less than 255 characters long." ) - user = trans.get_user() - name_exists = trans.sa_session.query( model.UCI ) \ - .filter_by( user=user, name=new_name ) \ - .first() - if name_exists: - error( "Specified name ('%s') is already used by an existing instance. Please choose an alternative name." % new_name ) - - # Update name in local DB - instance.name = new_name - trans.sa_session.flush() - trans.set_message( "Instance renamed to '%s'." % new_name ) - return self.list( trans ) - else: - return trans.show_form( - web.FormBuilder( url_for( id=trans.security.encode_id(instance.id) ), "Rename instance", submit_text="Rename" ) - .add_text( "new_name", "Instance name", value=instance.name ) ) - - @web.expose - @web.require_login( "use Galaxy cloud" ) - def set_uci_state( self, trans, id, state='available', clear_error=True ): - """ - Sets state of UCI to given state, optionally resets error field, and resets UCI's launch time field to 'None'. - """ - uci = get_uci( trans, id ) - uci.state = state - if clear_error: - uci.error = None - uci.launch_time = None - trans.sa_session.flush() - trans.set_message( "Instance '%s' state reset." % uci.name ) - return self.list( trans ) - + # ----- Credentials methods ----- + @web.expose @web.require_login( "add credentials" ) - def add( self, trans, credName='', accessKey='', secretKey='', providerName='' ): + def add_credentials( self, trans, credName='', accessKey='', secretKey='', providerName='' ): """ Add user's cloud credentials stored under name `credName`. """ @@ -688,15 +666,58 @@ ) @web.expose + @web.require_login( "use Galaxy cloud" ) + def edit_credentials( self, trans, id, credName=None, accessKey=None, secretKey=None, edited=False ): + error = {} + if not edited: + credentials = get_stored_credentials( trans, id ) + return trans.fill_template( "cloud/edit_credentials.mako", + credential = credentials, + error = error + ) + else: + user = trans.get_user() + credentials = get_stored_credentials( trans, id ) + if credName=='' or len( credName ) > 255: + error['cred_error'] = "Credentials name must be between 1 and 255 characters in length." + elif trans.app.model.CloudUserCredentials \ + .filter_by( user=user ) \ + .filter( and_( trans.app.model.CloudUserCredentials.table.c.id != credentials.id, trans.app.model.CloudUserCredentials.table.c.name==credName ) ) \ + .first(): + error['cred_error'] = "Credentials with name '" + credName + "' already exist. Please choose an alternative name." + elif accessKey=='' or len( accessKey ) > 255: + error['access_key_error'] = "Access key must be between 1 and 255 characters long." + elif secretKey=='' or len( secretKey ) > 255: + error['secret_key_error'] = "Secret key must be between 1 and 255 characters long." + + if error: + return trans.fill_template( "cloud/edit_credentials.mako", + credential = credentials, + error = error + ) + else: + # Edit user stored credentials + credentials.name = credName + 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.set_message( "Credential '%s' edited." % credentials.name ) + return self.list( trans ) + + @web.expose @web.require_login( "view credentials" ) - def view( self, trans, id=None ): + def view_credentials( 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", + return trans.fill_template( "cloud/view_credentials.mako", credDetails = stored ) @web.expose @@ -707,42 +728,33 @@ """ @web.expose - @web.require_login( "view instance details" ) - def viewInstance( self, trans, id=None ): - """ - View details about running instance - """ - uci = get_uci( trans, id ) - instances = get_instances( trans, uci ) # TODO: Handle list (will probably need to be done in mako template) - - return trans.fill_template( "cloud/viewInstance.mako", - liveInstance = instances ) - - @web.expose @web.require_login( "delete credentials" ) - def delete( self, trans, id=None ): + def delete_credentials( self, trans, id=None ): """ Delete user's cloud credentials checking that no registered instances are tied to given credentials. """ # Load credentials from database user = trans.get_user() stored = get_stored_credentials( trans, id ) - UCIs = trans.sa_session.query( model.UCI ) \ - .filter_by( user=user, credentials_id=stored.id ) \ - .filter( model.UCI.c.deleted != True ) \ - .all() + # Check if there are any UCIs that depend on these credentials + UCI = None + UCI = trans.sa_session.query( model.UCI ) \ + .filter_by( user=user, credentials_id=stored.id, deleted=False ) \ + .first() - if len(UCIs) == 0: + if UCI == None: # Delete and save stored.deleted = True stored.flush() # Display the management page trans.set_message( "Credentials '%s' deleted." % stored.name ) return self.list( trans ) - - error( "Existing instance(s) depend on credentials '%s'. You must delete those instances before being able \ - to delete these credentials." % stored.name ) - return self.list( trans ) + else: + error( "Existing instance(s) depend on credentials '%s'. You must delete those instances before being able \ + to delete these credentials." % stored.name ) + return self.list( trans ) + + # ----- Provider methods ----- @web.expose @web.require_login( "add provider" ) @@ -1007,6 +1019,8 @@ to delete this cloud provider." % provider.name ) return self.list( trans ) + # ----- AJAX methods ----- + @web.json def json_update( self, trans ): user = trans.get_user() @@ -1132,7 +1146,7 @@ user = trans.get_user() stores = trans.sa_session.query( model.CloudStore ) \ .filter_by( user=user, uci_id=uci.id ) \ - .filter( model.CloudStore.c.status != store_states.ERROR ) \ + .filter( model.CloudStore.c.status != store_status.ERROR ) \ .all() return stores diff -r e21f605d2766 -r 118dc385752b templates/admin/index.mako --- a/templates/admin/index.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/admin/index.mako Thu Nov 12 14:24:43 2009 -0500 @@ -127,8 +127,8 @@ </div> <div class="toolSectionBody"> <div class="toolSectionBg"> - <div class="toolTitle"><a href="${h.url_for( controller='cloud', action='listMachineImages' )}" target="galaxy_main">List machine images</a></div> - <div class="toolTitle"><a href="${h.url_for( controller='cloud', action='addNewImage' )}" target="galaxy_main">Add machine image</a></div> + <div class="toolTitle"><a href="${h.url_for( controller='cloud', action='list_machine_images' )}" target="galaxy_main">List machine images</a></div> + <div class="toolTitle"><a href="${h.url_for( controller='cloud', action='add_new_image' )}" target="galaxy_main">Add machine image</a></div> </div> </div> </div> diff -r e21f605d2766 -r 118dc385752b templates/cloud/add_credentials.mako --- a/templates/cloud/add_credentials.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/add_credentials.mako Thu Nov 12 14:24:43 2009 -0500 @@ -20,7 +20,7 @@ <div class="form"> <div class="form-title">Add credentials</div> <div class="form-body"> - <form name="Add credentials" action="${h.url_for( action='add' )}" method="post" > + <form name="add_credentials" action="${h.url_for( action='add_credentials' )}" method="post" > <% cls = "form-row" diff -r e21f605d2766 -r 118dc385752b templates/cloud/add_image.mako --- a/templates/cloud/add_image.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/add_image.mako Thu Nov 12 14:24:43 2009 -0500 @@ -18,7 +18,7 @@ <div class="form"> <div class="form-title">Add machine image</div> <div class="form-body"> - <form name="add_image" action="${h.url_for( action='addNewImage' )}" method="post" > + <form name="add_image" action="${h.url_for( action='add_new_image' )}" method="post" > <% cls = "form-row" if error.has_key('provider_error'): diff -r e21f605d2766 -r 118dc385752b templates/cloud/configure_cloud.mako --- a/templates/cloud/configure_cloud.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/configure_cloud.mako Thu Nov 12 14:24:43 2009 -0500 @@ -156,7 +156,7 @@ %if cloudCredentials: <ul class="manage-table-actions"> <li> - <a class="action-button" href="${h.url_for( action='add' )}"> + <a class="action-button" href="${h.url_for( action='add_credentials' )}"> <img src="${h.url_for('/static/images/silk/add.png')}" /> <span>Add credentials</span> </a> @@ -181,9 +181,9 @@ </td> <td> <div popupmenu="cr-${i}-popup"> - <a class="action-button" href="${h.url_for( action='view', id=trans.security.encode_id(cloudCredential.id) )}">View</a> - <a class="action-button" href="${h.url_for( action='edit', id=trans.security.encode_id(cloudCredential.id) )}">Edit</a> - <a class="action-button" confirm="Are you sure you want to delete credentials '${cloudCredential.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(cloudCredential.id) )}">Delete</a> + <a class="action-button" href="${h.url_for( action='view_credentials', id=trans.security.encode_id(cloudCredential.id) )}">View</a> + <a class="action-button" href="${h.url_for( action='edit_credentials', id=trans.security.encode_id(cloudCredential.id) )}">Edit</a> + <a class="action-button" confirm="Are you sure you want to delete credentials '${cloudCredential.name}'?" href="${h.url_for( action='delete_credentials', id=trans.security.encode_id(cloudCredential.id) )}">Delete</a> </div> </td> </tr> @@ -196,7 +196,7 @@ <h3>Manage your cloud instances</h3> <ul class="manage-table-actions"> <li> - <a class="action-button" href="${h.url_for( action='configureNew' )}"> + <a class="action-button" href="${h.url_for( action='configure_new_uci' )}"> <img src="${h.url_for('/static/images/silk/add.png')}" /> <span>Configure new instance</span> </a> @@ -253,10 +253,10 @@ <td id="${ liveInstance.id }-link"></td> <td> <div popupmenu="li-${i}-popup"> - <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> + <a class="action-button" confirm="Are you sure you want to stop instance '${liveInstance.name}'?" href="${h.url_for( action='stop', id=trans.security.encode_id(liveInstance.id) )}">Stop</a> + <a class="action-button" href="${h.url_for( action='rename_uci', id=trans.security.encode_id(liveInstance.id) )}">Rename</a> + <a class="action-button" href="${h.url_for( action='view_uci_details', id=trans.security.encode_id(liveInstance.id) )}">View details</a> + <a class="action-button" href="${h.url_for( action='uci_usage_report', id=trans.security.encode_id(liveInstance.id) )}">Usage report</a> </div> </td> </tr> @@ -322,12 +322,12 @@ <div popupmenu="pi-${i}-popup"> <a class="action-button" href="${h.url_for( action='start', id=trans.security.encode_id(prevInstance.id), type='m1.small' )}"> Start m1.small</a> <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='create_snapshot', id=trans.security.encode_id(prevInstance.id) )}">Create snapshot</a> + <a class="action-button" href="${h.url_for( action='rename_uci', id=trans.security.encode_id(prevInstance.id) )}">Rename</a> + <a class="action-button" href="${h.url_for( action='uci_usage_report', id=trans.security.encode_id(prevInstance.id) )}">Usage report</a> + <a class="action-button" href="${h.url_for( action='create_snapshot', id=trans.security.encode_id(prevInstance.id) )}">Create snapshot</a> <a class="action-button" href="${h.url_for( action='view_snapshots', id=trans.security.encode_id(prevInstance.id) )}">View snapshots</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', 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> + <a class="action-button" href="${h.url_for( action='add_storage', id=trans.security.encode_id(prevInstance.id) )}" target="_parent">Add storage</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='delete_uci', id=trans.security.encode_id(prevInstance.id) )}">Delete</a> </div> </td> </tr> @@ -341,7 +341,7 @@ %else: You have no credentials associated with your Galaxy account: - <a class="action-button" href="${h.url_for( action='add' )}"> + <a class="action-button" href="${h.url_for( action='add_credentials' )}"> <img src="${h.url_for('/static/images/silk/add.png')}" /> <span>add credentials</span> </a> diff -r e21f605d2766 -r 118dc385752b templates/cloud/configure_uci.mako --- a/templates/cloud/configure_uci.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/configure_uci.mako Thu Nov 12 14:24:43 2009 -0500 @@ -35,7 +35,7 @@ <div class="form"> <div class="form-title">Configure new Galaxy instance</div> <div class="form-body"> - <form name="Configure new UCI" action="${h.url_for( action='configureNew' )}" method="post" > + <form name="Configure new UCI" action="${h.url_for( action='configure_new_uci' )}" method="post" > <% cls = "form-row" diff -r e21f605d2766 -r 118dc385752b templates/cloud/edit_credentials.mako --- a/templates/cloud/edit_credentials.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/edit_credentials.mako Thu Nov 12 14:24:43 2009 -0500 @@ -20,7 +20,7 @@ <div class="form"> <div class="form-title">Edit credentials</div> <div class="form-body"> - <form name="edit_credentials" action="${h.url_for( action='edit', id=trans.security.encode_id(credential.id), edited="true" )}" method="post" > + <form name="edit_credentials" action="${h.url_for( action='edit_credentials', id=trans.security.encode_id(credential.id), edited="true" )}" method="post" > <% cls = "form-row" diff -r e21f605d2766 -r 118dc385752b templates/cloud/edit_image.mako --- a/templates/cloud/edit_image.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/edit_image.mako Thu Nov 12 14:24:43 2009 -0500 @@ -20,7 +20,7 @@ <div class="form"> <div class="form-title">Edit image</div> <div class="form-body"> - <form name="edit_image" action="${h.url_for( action='editImage', id=trans.security.encode_id(image.id), edited="true" )}" method="post" > + <form name="edit_image" action="${h.url_for( action='edit_image', id=trans.security.encode_id(image.id), edited="true" )}" method="post" > <% cls = "form-row" if error.has_key('provider_error'): diff -r e21f605d2766 -r 118dc385752b templates/cloud/list_images.mako --- a/templates/cloud/list_images.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/list_images.mako Thu Nov 12 14:24:43 2009 -0500 @@ -69,18 +69,18 @@ %endif </td> <td> - <a href="${h.url_for( controller='cloud', action='editImage', image_id=image.image_id, manifest=image.manifest, id=trans.security.encode_id(image.id) )}">e</a> + <a href="${h.url_for( controller='cloud', action='edit_image', image_id=image.image_id, manifest=image.manifest, id=trans.security.encode_id(image.id) )}">e</a> </td> <td> <a confirm="Are you sure you want to delete machine image '${image.image_id}'? Note that this may result in users' UCI's not to work any more!" - href="${h.url_for( controller='cloud', action='deleteImage', id=trans.security.encode_id(image.id) )}">x</a> + href="${h.url_for( controller='cloud', action='delete_image', id=trans.security.encode_id(image.id) )}">x</a> </td> </tr> %endfor </table> %else: <h3>There are no registered machine images.</h3><br /> - <a href="${h.url_for( controller='cloud', action='addNewImage' )}" target="galaxy_main">Add machine image now?</a> + <a href="${h.url_for( controller='cloud', action='add_new_image' )}" target="galaxy_main">Add machine image now?</a> %endif diff -r e21f605d2766 -r 118dc385752b templates/cloud/view.mako --- a/templates/cloud/view.mako Thu Nov 12 12:42:17 2009 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -<%inherit file="/base.mako"/> - -<%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: - ${view_cred( credDetails )} -%else: - There are no credentials under that name. -%endif - - - - -<%def name="view_cred( credDetails )"> - <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 credentials '${credDetails.name}'?" href="${h.url_for( action='delete', id=trans.security.encode_id(credDetails.id) )}">Delete</a> - </div> - </td> - </tr> - <tr> - <td> Last updated: </td> - <td> ${str(credDetails.update_time)[:16]} - <% - context.write( ' UTC (' ) - context.write( str(h.date.distance_of_time_in_words (credDetails.update_time, h.date.datetime.utcnow() ) ) ) - %> ago) - </td> - </tr> - <tr> - <td> Cloud provider type: </td> - <td> ${str(credDetails.provider.type)}</td> - </tr> - <tr> - <td> Cloud provider name: </td> - <td> ${str(credDetails.provider.name)}</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"> - <a onclick="document.getElementById('shortComment2').style.display = 'block'; - document.getElementById('fullComment2').style.display = 'none'; return 0;" - href="javascript:void(0)"> - - Hide - </a><br /> - <nobr>${credDetails.secret_key}</nobr><br/> - </div> - </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> - <td> ${credDetails.provider.region_connection} </td> - </tr> - %endif - %if credDetails.provider.region_name != None: - <tr> - <td> Region name: </td> - <td> ${credDetails.provider.region_name} </td> - </tr> - %endif - %if credDetails.provider.region_endpoint != None: - <tr> - <td> Region endpoint: </td> - <td> ${credDetails.provider.region_endpoint} </td> - </tr> - %endif - %if credDetails.provider.is_secure != None: - <tr> - <td> Is secure: </td> - <td> ${credDetails.provider.is_secure} </td> - </tr> - %endif - %if credDetails.provider.host != None: - <tr> - <td> Host: </td> - <td> ${credDetails.provider.host} </td> - </tr> - %endif - %if credDetails.provider.port != None: - <tr> - <td> Port: </td> - <td> ${credDetails.provider.port} </td> - </tr> - %endif - %if credDetails.provider.proxy != None: - <tr> - <td> Proxy: </td> - <td> ${credDetails.provider.proxy} </td> - </tr> - %endif - %if credDetails.provider.proxy_port != None: - <tr> - <td> Proxy port: </td> - <td> ${credDetails.provider.proxy_port} </td> - </tr> - %endif - %if credDetails.provider.proxy_pass != None: - <tr> - <td> Proxy pass: </td> - <td> ${credDetails.provider.proxy_pass} </td> - </tr> - %endif - %if credDetails.provider.debug != None: - <tr> - <td> Debug: </td> - <td> ${credDetails.provider.debug} </td> - </tr> - %endif - %if credDetails.provider.https_connection_factory != None: - <tr> - <td> HTTPS connection factory: </td> - <td> ${credDetails.provider.https_connection_factory} </td> - </tr> - %endif - %if credDetails.provider.path != None: - <tr> - <td> Path: </td> - <td> ${credDetails.provider.path} </td> - </tr> - %endif - </table> -</%def> diff -r e21f605d2766 -r 118dc385752b templates/cloud/viewInstance.mako --- a/templates/cloud/viewInstance.mako Thu Nov 12 12:42:17 2009 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -<%inherit file="/base.mako"/> -<%def name="title()">Live instance details</%def> - -<% - # Because of the one-to-many relationship between liveInstance (i.e., UCI) and actual instances, need to know - # which one is currently active. Because only one instance of UCI can be alive at any point in time, simply - # select the most recent one. - # TODO: Once individual UCI's will be able to start more than one instance, this will need to be fixed - #i_id = len(liveInstance.instance) - 1 -%> - -<h2>Live instance details</h2> - -%if liveInstance: - <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> Instance name: </td> - <td> - ${liveInstance.uci.name} - <a id="li-popup" class="popup-arrow" style="display: none;">▼</a> - </td> - <td> - <div popupmenu="li-popup"> - <a class="action-button" href="${h.url_for( action='renameInstance', id=trans.security.encode_id(liveInstance.uci.id) )}">Rename</a> - <a class="action-button" confirm="Are you sure you want to stop instance '${liveInstance.uci.name}'?" href="${h.url_for( action='stop', id=trans.security.encode_id(liveInstance.uci.id) )}">Stop</a> - </div> - </td> - </tr> - <tr> - <td> Date created: </td> - <td> ${str(liveInstance.uci.create_time)[:16]} - <% - context.write( ' UTC (' ) - context.write( str(h.date.distance_of_time_in_words (liveInstance.uci.create_time, h.date.datetime.utcnow() ) ) ) - %> ago) - </td> - </tr> - <tr> - <td> Alive since: </td> - <td> ${str(liveInstance.launch_time)[:16]} - <% - context.write( ' UTC (' ) - context.write( str(h.date.distance_of_time_in_words (liveInstance.launch_time, h.date.datetime.utcnow() ) ) ) - %> ago) - </td> - </tr> - %if liveInstance.instance_id != None: - <tr> - <td> Instance ID: </td> - <td> ${liveInstance.instance_id} </td> - </tr> - %endif - %if liveInstance.reservation_id != None: - <tr> - <td> Reservation ID: </td> - <td> ${liveInstance.reservation_id} </td> - </tr> - %endif - <tr> - <td> AMI: </td> - <td> ${liveInstance.mi_id} </td> - </tr> - <tr> - <td> State:</td> - <td> ${liveInstance.state} </td> - </tr> - <tr> - <td> Type:</td> - <td> ${liveInstance.type} </td> - </tr> - <tr> - <td> Storage size:</td> - <td> ${liveInstance.uci.total_size} </td> - </tr> - <tr> - <td> Public DNS:</td> - <% - lnk="http://"+str(liveInstance.public_dns) - %> - <td> <a href="${lnk}" target="_blank">${liveInstance.public_dns}</a></td> - </tr> - %if liveInstance.private_dns != None: - <tr> - <td> Private DNS:</td> - <td> ${liveInstance.private_dns}</td> - </tr> - %endif - %if liveInstance.security_group != None: - <tr> - <td> Security group zone:</td> - <td> ${liveInstance.security_group} </td> - </tr> - %endif - %if liveInstance.availability_zone != None: - <tr> - <td> Availabilty zone:</td> - <td> ${liveInstance.availability_zone} </td> - </tr> - %endif - %if liveInstance.uci.key_pair_name != None: - <tr> - <td> Keypair file name:</td> - <td> ${liveInstance.uci.key_pair_name} </td> - </tr> - %endif - %if liveInstance.uci.key_pair_material != None: - <tr> - <td> Keypair material:</td> - <td> - <div id="short"> - <a onclick="document.getElementById('full').style.display = 'block'; - document.getElementById('short').style.display = 'none'; return 0" - href="javascript:void(0)"> - + Show - </a> - </div> - <div id="full" style="DISPLAY: none"> - <a onclick="document.getElementById('short').style.display = 'block'; - document.getElementById('full').style.display = 'none'; return 0;" - href="javascript:void(0)"> - - Hide</a> - ${liveInstance.uci.key_pair_material}<br/> - </div> - </td> - </tr> - %endif - - </table> -%else: - There is no live instance under that name. -%endif diff -r e21f605d2766 -r 118dc385752b templates/cloud/view_credentials.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/cloud/view_credentials.mako Thu Nov 12 14:24:43 2009 -0500 @@ -0,0 +1,157 @@ +<%inherit file="/base.mako"/> + +<%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: + ${view_cred( credDetails )} +%else: + There are no credentials under that name. +%endif + + + + +<%def name="view_cred( credDetails )"> + <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='edit_credentials', id=trans.security.encode_id(credDetails.id) )}">Edit</a> + <a class="action-button" confirm="Are you sure you want to delete credentials '${credDetails.name}'?" href="${h.url_for( action='delete_credentials', id=trans.security.encode_id(credDetails.id) )}">Delete</a> + </div> + </td> + </tr> + <tr> + <td> Last updated: </td> + <td> ${str(credDetails.update_time)[:16]} + <% + context.write( ' UTC (' ) + context.write( str(h.date.distance_of_time_in_words (credDetails.update_time, h.date.datetime.utcnow() ) ) ) + %> ago) + </td> + </tr> + <tr> + <td> Cloud provider type: </td> + <td> ${str(credDetails.provider.type)}</td> + </tr> + <tr> + <td> Cloud provider name: </td> + <td> ${str(credDetails.provider.name)}</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"> + <a onclick="document.getElementById('shortComment2').style.display = 'block'; + document.getElementById('fullComment2').style.display = 'none'; return 0;" + href="javascript:void(0)"> + - Hide + </a><br /> + <nobr>${credDetails.secret_key}</nobr><br/> + </div> + </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> + <td> ${credDetails.provider.region_connection} </td> + </tr> + %endif + %if credDetails.provider.region_name != None: + <tr> + <td> Region name: </td> + <td> ${credDetails.provider.region_name} </td> + </tr> + %endif + %if credDetails.provider.region_endpoint != None: + <tr> + <td> Region endpoint: </td> + <td> ${credDetails.provider.region_endpoint} </td> + </tr> + %endif + %if credDetails.provider.is_secure != None: + <tr> + <td> Is secure: </td> + <td> ${credDetails.provider.is_secure} </td> + </tr> + %endif + %if credDetails.provider.host != None: + <tr> + <td> Host: </td> + <td> ${credDetails.provider.host} </td> + </tr> + %endif + %if credDetails.provider.port != None: + <tr> + <td> Port: </td> + <td> ${credDetails.provider.port} </td> + </tr> + %endif + %if credDetails.provider.proxy != None: + <tr> + <td> Proxy: </td> + <td> ${credDetails.provider.proxy} </td> + </tr> + %endif + %if credDetails.provider.proxy_port != None: + <tr> + <td> Proxy port: </td> + <td> ${credDetails.provider.proxy_port} </td> + </tr> + %endif + %if credDetails.provider.proxy_pass != None: + <tr> + <td> Proxy pass: </td> + <td> ${credDetails.provider.proxy_pass} </td> + </tr> + %endif + %if credDetails.provider.debug != None: + <tr> + <td> Debug: </td> + <td> ${credDetails.provider.debug} </td> + </tr> + %endif + %if credDetails.provider.https_connection_factory != None: + <tr> + <td> HTTPS connection factory: </td> + <td> ${credDetails.provider.https_connection_factory} </td> + </tr> + %endif + %if credDetails.provider.path != None: + <tr> + <td> Path: </td> + <td> ${credDetails.provider.path} </td> + </tr> + %endif + </table> +</%def> diff -r e21f605d2766 -r 118dc385752b templates/cloud/view_instance.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/cloud/view_instance.mako Thu Nov 12 14:24:43 2009 -0500 @@ -0,0 +1,140 @@ +<%inherit file="/base.mako"/> +<%def name="title()">Live instance details</%def> + +<% + # Because of the one-to-many relationship between liveInstance (i.e., UCI) and actual instances, need to know + # which one is currently active. Because only one instance of UCI can be alive at any point in time, simply + # select the most recent one. + # TODO: Once individual UCI's will be able to start more than one instance, this will need to be fixed + #i_id = len(liveInstance.instance) - 1 +%> + +<h2>Live instance details</h2> + +%if liveInstance: + <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> Instance name: </td> + <td> + ${liveInstance.uci.name} + <a id="li-popup" class="popup-arrow" style="display: none;">▼</a> + </td> + <td> + <div popupmenu="li-popup"> + <a class="action-button" href="${h.url_for( action='rename_uci', id=trans.security.encode_id(liveInstance.uci.id) )}">Rename</a> + <a class="action-button" confirm="Are you sure you want to stop instance '${liveInstance.uci.name}'?" href="${h.url_for( action='stop', id=trans.security.encode_id(liveInstance.uci.id) )}">Stop</a> + </div> + </td> + </tr> + <tr> + <td> Date created: </td> + <td> ${str(liveInstance.uci.create_time)[:16]} + <% + context.write( ' UTC (' ) + context.write( str(h.date.distance_of_time_in_words (liveInstance.uci.create_time, h.date.datetime.utcnow() ) ) ) + %> ago) + </td> + </tr> + <tr> + <td> Alive since: </td> + <td> ${str(liveInstance.launch_time)[:16]} + <% + context.write( ' UTC (' ) + context.write( str(h.date.distance_of_time_in_words (liveInstance.launch_time, h.date.datetime.utcnow() ) ) ) + %> ago) + </td> + </tr> + %if liveInstance.instance_id != None: + <tr> + <td> Instance ID: </td> + <td> ${liveInstance.instance_id} </td> + </tr> + %endif + %if liveInstance.reservation_id != None: + <tr> + <td> Reservation ID: </td> + <td> ${liveInstance.reservation_id} </td> + </tr> + %endif + <tr> + <td> AMI: </td> + <td> ${liveInstance.mi_id} </td> + </tr> + <tr> + <td> State:</td> + <td> ${liveInstance.state} </td> + </tr> + <tr> + <td> Type:</td> + <td> ${liveInstance.type} </td> + </tr> + <tr> + <td> Storage size:</td> + <td> ${liveInstance.uci.total_size} </td> + </tr> + <tr> + <td> Public DNS:</td> + <% + lnk="http://"+str(liveInstance.public_dns) + %> + <td> <a href="${lnk}" target="_blank">${liveInstance.public_dns}</a></td> + </tr> + %if liveInstance.private_dns != None: + <tr> + <td> Private DNS:</td> + <td> ${liveInstance.private_dns}</td> + </tr> + %endif + %if liveInstance.security_group != None: + <tr> + <td> Security group zone:</td> + <td> ${liveInstance.security_group} </td> + </tr> + %endif + %if liveInstance.availability_zone != None: + <tr> + <td> Availabilty zone:</td> + <td> ${liveInstance.availability_zone} </td> + </tr> + %endif + %if liveInstance.uci.key_pair_name != None: + <tr> + <td> Keypair file name:</td> + <td> ${liveInstance.uci.key_pair_name} </td> + </tr> + %endif + %if liveInstance.uci.key_pair_material != None: + <tr> + <td> Keypair material:</td> + <td> + <div id="short"> + <a onclick="document.getElementById('full').style.display = 'block'; + document.getElementById('short').style.display = 'none'; return 0" + href="javascript:void(0)"> + + Show + </a> + </div> + <div id="full" style="DISPLAY: none"> + <a onclick="document.getElementById('short').style.display = 'block'; + document.getElementById('full').style.display = 'none'; return 0;" + href="javascript:void(0)"> + - Hide</a> + ${liveInstance.uci.key_pair_material}<br/> + </div> + </td> + </tr> + %endif + + </table> +%else: + There is no live instance under that name. +%endif diff -r e21f605d2766 -r 118dc385752b templates/cloud/view_usage.mako --- a/templates/cloud/view_usage.mako Thu Nov 12 12:42:17 2009 -0500 +++ b/templates/cloud/view_usage.mako Thu Nov 12 14:24:43 2009 -0500 @@ -88,7 +88,7 @@ </table> <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" /> + <%namespace name="view_cred" file="view_credentials.mako" /> <div id="hide_cred_details"> This instance uses credentials:
participants (1)
-
Greg Von Kuster