mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Cleaned up code in main cloud controller.
This commit is contained in:
@@ -48,7 +48,7 @@ instance_states = Bunch(
|
||||
ERROR = "error"
|
||||
)
|
||||
|
||||
store_states = Bunch(
|
||||
store_status = Bunch(
|
||||
IN_USE = "in-use",
|
||||
CREATING = "creating",
|
||||
DELETED = 'deleted',
|
||||
@@ -105,14 +105,14 @@ class EC2CloudProvider( object ):
|
||||
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 @@ class EC2CloudProvider( object ):
|
||||
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 @@ class EC2CloudProvider( object ):
|
||||
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 @@ class EC2CloudProvider( object ):
|
||||
# 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()
|
||||
|
||||
@@ -114,9 +114,9 @@ class EucalyptusCloudProvider( object ):
|
||||
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 @@ class EucalyptusCloudProvider( object ):
|
||||
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 @@ class EucalyptusCloudProvider( object ):
|
||||
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 )
|
||||
|
||||
+323
-309
@@ -59,7 +59,7 @@ instance_states = Bunch(
|
||||
ERROR = "error"
|
||||
)
|
||||
|
||||
store_states = Bunch(
|
||||
store_status = Bunch(
|
||||
IN_USE = "in-use",
|
||||
CREATING = "creating",
|
||||
DELETED = 'deleted',
|
||||
@@ -135,9 +135,9 @@ class CloudController( BaseController ):
|
||||
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 @@ class CloudController( BaseController ):
|
||||
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
|
||||
"""
|
||||
@@ -446,9 +257,256 @@ class CloudController( BaseController ):
|
||||
error = error,
|
||||
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 @@ class CloudController( BaseController ):
|
||||
|
||||
@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 @@ class CloudController( BaseController ):
|
||||
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`.
|
||||
"""
|
||||
@@ -687,16 +665,59 @@ class CloudController( BaseController ):
|
||||
providers = providers
|
||||
)
|
||||
|
||||
@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
|
||||
@@ -706,43 +727,34 @@ class CloudController( BaseController ):
|
||||
Tests credentials provided by user with selected cloud provider
|
||||
"""
|
||||
|
||||
@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 @@ class CloudController( BaseController ):
|
||||
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 @@ def get_stores( trans, uci ):
|
||||
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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -20,7 +20,7 @@ $(function(){
|
||||
<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"
|
||||
|
||||
@@ -18,7 +18,7 @@ $(function(){
|
||||
<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'):
|
||||
|
||||
@@ -156,7 +156,7 @@ function trim19(str){
|
||||
%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 @@ function trim19(str){
|
||||
</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 @@ function trim19(str){
|
||||
<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 @@ function trim19(str){
|
||||
<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 @@ function trim19(str){
|
||||
<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 @@ function trim19(str){
|
||||
|
||||
%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>
|
||||
|
||||
@@ -35,7 +35,7 @@ $(function(){
|
||||
<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"
|
||||
|
||||
@@ -20,7 +20,7 @@ $(function(){
|
||||
<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"
|
||||
|
||||
@@ -20,7 +20,7 @@ $(function(){
|
||||
<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'):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
</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>
|
||||
<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>
|
||||
@@ -30,7 +30,7 @@
|
||||
</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" 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>
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user