1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/59a35ec1e2e7/ changeset: 59a35ec1e2e7 user: dannon date: 2012-11-01 20:39:38 summary: 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. affected #: 2 files diff -r c42882c539811eac231c5989f89d0dc5f5e3c18e -r 59a35ec1e2e7ce608d2ae566c7c1e201760c53a1 lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py --- a/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py +++ b/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py @@ -59,14 +59,34 @@ 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 @@ 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 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 @@ 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: diff -r c42882c539811eac231c5989f89d0dc5f5e3c18e -r 59a35ec1e2e7ce608d2ae566c7c1e201760c53a1 templates/cloud/index.mako --- a/templates/cloud/index.mako +++ b/templates/cloud/index.mako @@ -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 @@ <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 @@ </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> Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.