mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Cloudlaunch: Automatically detect placement AZ of volumes from existing clusters, and launch using those placements. This prevents any "CRITICAL: This instance must be relaunched in zone..." at cloudman start. Also reworked error handling.
This commit is contained in:
@@ -59,14 +59,34 @@ class CloudController(BaseUIController):
|
||||
if pd:
|
||||
# This is a cloudman bucket.
|
||||
# We need to get persistent data, and the cluster name.
|
||||
# DBTODO: Add pyyaml egg, and rewrite this.
|
||||
# This will also allow for much more sophisticated rendering of existing clusters
|
||||
# Currently, this zone detection is a hack.
|
||||
pd_contents = pd.get_contents_as_string()
|
||||
zone = ''
|
||||
try:
|
||||
for line in pd_contents.split('\n'):
|
||||
if 'vol_id' in line:
|
||||
vol_id = line.split(':')[1].strip()
|
||||
v = ec2_conn.get_all_volumes(volume_ids = [vol_id])
|
||||
if v:
|
||||
zone = v[0].zone
|
||||
else:
|
||||
zone = ''
|
||||
except:
|
||||
#If anything goes wrong with zone detection, use the default selection.
|
||||
zone = ''
|
||||
for key in bucket.list():
|
||||
if key.name.endswith('.clusterName'):
|
||||
clusters.append({'name': key.name.split('.clusterName')[0], 'persistent_data': pd.get_contents_as_string()})
|
||||
clusters.append({'name': key.name.split('.clusterName')[0],
|
||||
'persistent_data': pd_contents,
|
||||
'zone':zone})
|
||||
account_info['clusters'] = clusters
|
||||
account_info['zones'] = [z.name for z in ec2_conn.get_all_zones()]
|
||||
return to_json_string(account_info)
|
||||
|
||||
@web.expose
|
||||
def launch_instance(self, trans, cluster_name, password, key_id, secret, instance_type, share_string, keypair, **kwargs):
|
||||
def launch_instance(self, trans, cluster_name, password, key_id, secret, instance_type, share_string, keypair, zone=None, **kwargs):
|
||||
ec2_error = None
|
||||
try:
|
||||
# Create security group & key pair used when starting an instance
|
||||
@@ -90,7 +110,8 @@ class CloudController(BaseUIController):
|
||||
rs = run_instance(ec2_conn=ec2_conn,
|
||||
user_provided_data=user_provided_data,
|
||||
key_name=kp_name,
|
||||
security_groups=[sg_name])
|
||||
security_groups=[sg_name],
|
||||
placement=zone)
|
||||
if rs:
|
||||
instance = rs.instances[0]
|
||||
ct = 0
|
||||
@@ -241,7 +262,7 @@ def create_key_pair(ec2_conn, key_name=DEFAULT_KEYPAIR):
|
||||
|
||||
def run_instance(ec2_conn, user_provided_data, image_id=DEFAULT_AMI,
|
||||
kernel_id=None, ramdisk_id=None, key_name=DEFAULT_KEYPAIR,
|
||||
security_groups=['CloudMan']):
|
||||
placement=None, security_groups=['CloudMan']):
|
||||
""" Start an instance. If instance start was OK, return the ResultSet object
|
||||
else return None.
|
||||
"""
|
||||
@@ -257,7 +278,8 @@ def run_instance(ec2_conn, user_provided_data, image_id=DEFAULT_AMI,
|
||||
security_groups=security_groups,
|
||||
user_data=ud,
|
||||
kernel_id=kernel_id,
|
||||
ramdisk_id=ramdisk_id)
|
||||
ramdisk_id=ramdisk_id,
|
||||
placement=placement)
|
||||
except EC2ResponseError, e:
|
||||
log.error("Problem starting an instance: %s\n%s" % (e, e.body))
|
||||
if rs:
|
||||
|
||||
+35
-28
@@ -60,6 +60,8 @@
|
||||
<script type="text/javascript">
|
||||
var ACCOUNT_URL = "${h.url_for( controller='/cloudlaunch', action='get_account_info')}";
|
||||
var PKEY_DL_URL = "${h.url_for( controller='/cloudlaunch', action='get_pkey')}";
|
||||
var cloudlaunch_clusters = [];
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#id_existing_instance').change(function(){
|
||||
var ei_name = $(this).val();
|
||||
@@ -82,6 +84,7 @@
|
||||
$.getJSON(ACCOUNT_URL,
|
||||
{key_id: key_el.val(),secret:secret_el.val()},
|
||||
function(result){
|
||||
cloudlaunch_clusters = result.clusters;
|
||||
var kplist = $("#id_keypair");
|
||||
var clusterlist = $("#id_existing_instance");
|
||||
kplist.find('option').remove();
|
||||
@@ -112,48 +115,52 @@
|
||||
$('form').ajaxForm({
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSubmit: function(data){
|
||||
beforeSubmit: function(data, form){
|
||||
if ($('#id_password').val() != $('#id_password_confirm').val()){
|
||||
//Passwords don't match.
|
||||
$('#cloudlaunch_form').prepend('<div class="errormessage">Passwords do not match</div>');
|
||||
form.prepend('<div class="errormessage">Passwords do not match</div>');
|
||||
return false;
|
||||
}else{
|
||||
//Clear errors
|
||||
$('.errormessage').remove()
|
||||
//Hide the form, show pending box with spinner.
|
||||
$('#launchFormContainer').hide('fast');
|
||||
$('#responsePanel').show('fast');
|
||||
}
|
||||
//Dig up zone info for selected cluster, set hidden input.
|
||||
//This is not necessary to present to the user though the interface may prove useful.
|
||||
var ei_val = _.find(data, function(f_obj){return f_obj.name === 'existing_instance'});
|
||||
if( ei_val.value !== "New Cluster"){
|
||||
var cluster = _.find(cloudlaunch_clusters, function(cluster){return cluster.name === ei_val.value});
|
||||
var zdata = _.find(data, function(f_obj){return f_obj.name === 'zone'});
|
||||
zdata.value = cluster.zone;
|
||||
}
|
||||
},
|
||||
success: function(data){
|
||||
//Success Message, link to key download if required, link to server itself.
|
||||
$('#launchPending').hide('fast');
|
||||
//Check for success/error.
|
||||
if (data.error){
|
||||
//Apologize profusely.
|
||||
$("launchPending").hide();
|
||||
$("#launchError").show();
|
||||
}else{
|
||||
//Set appropriate fields (dns, key, ami) and then display.
|
||||
if(data.kp_material_tag){
|
||||
var kp_download_link = $('<a/>').attr('href', PKEY_DL_URL + '?kp_material_tag=' + data.kp_material_tag)
|
||||
.attr('target','_blank')
|
||||
.text("Download your key now");
|
||||
$('#keypairInfo').append(kp_download_link);
|
||||
$('#keypairInfo').show();
|
||||
}
|
||||
$('.kp_name').text(data.kp_name);
|
||||
$('#instance_id').text(data.instance_id);
|
||||
$('#image_id').text(data.image_id);
|
||||
$('#instance_link').html($('<a/>')
|
||||
.attr('href', 'http://' + data.public_dns_name + '/cloud')
|
||||
.attr('target','_blank')
|
||||
.text(data.public_dns_name + '/cloud'));
|
||||
$('#instance_dns').text(data.public_dns_name);
|
||||
$('#launchSuccess').show('fast');
|
||||
//Set appropriate fields (dns, key, ami) and then display.
|
||||
if(data.kp_material_tag){
|
||||
var kp_download_link = $('<a/>').attr('href', PKEY_DL_URL + '?kp_material_tag=' + data.kp_material_tag)
|
||||
.attr('target','_blank')
|
||||
.text("Download your key now");
|
||||
$('#keypairInfo').append(kp_download_link);
|
||||
$('#keypairInfo').show();
|
||||
}
|
||||
$('.kp_name').text(data.kp_name);
|
||||
$('#instance_id').text(data.instance_id);
|
||||
$('#image_id').text(data.image_id);
|
||||
$('#instance_link').html($('<a/>')
|
||||
.attr('href', 'http://' + data.public_dns_name + '/cloud')
|
||||
.attr('target','_blank')
|
||||
.text(data.public_dns_name + '/cloud'));
|
||||
$('#instance_dns').text(data.public_dns_name);
|
||||
$('#launchSuccess').show('fast');
|
||||
},
|
||||
error: function(data){
|
||||
$('#cloudlaunch_form').prepend('<div class="errormessage">' + data.responseText + '</div>');
|
||||
error: function(jqXHR, textStatus, errorThrown){
|
||||
$('#launchFormContainer').prepend('<div class="errormessage">' + errorThrown + " : " + jqXHR.responseText + '</div>');
|
||||
$('#responsePanel').hide('fast');
|
||||
$('#launchFormContainer').show('fast');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -196,6 +203,7 @@ Credentials section of the AWS Console</a>. </div>
|
||||
<label for="id_existing_instance">Instances in your account</label>
|
||||
<select name="existing_instance" id="id_existing_instance">
|
||||
</select>
|
||||
<input id='id_zone' type='hidden' name='zone' value=''/>
|
||||
</div>
|
||||
<div id='cluster_name_wrapper' class="form-row">
|
||||
<label for="id_cluster_name">Cluster Name</label>
|
||||
@@ -253,7 +261,6 @@ Credentials section of the AWS Console</a>. </div>
|
||||
</div>
|
||||
<div id="responsePanel" class="toolForm" style="display:none;">
|
||||
<div id="launchPending">Launch Pending, please be patient.</div>
|
||||
<div id="launchError" style="display:none;">ERROR</div>
|
||||
<div id="launchSuccess" style="display:none;">
|
||||
<div id="keypairInfo" style="display:none;margin-bottom:20px;">
|
||||
<h3>Very Important Key Pair Information</h3>
|
||||
|
||||
Reference in New Issue
Block a user