diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 25d64e8d891..f31454e66c2 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -33,7 +33,7 @@ public interface Volume extends ControlledEntity, BasedOn, StateObject avoids, long size, HypervisorType hyperType) throws NoTransitionException; + + String getSupportedImageFormatForCluster(Long clusterId); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 7be946b2849..87012fbb8d5 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -3802,4 +3802,21 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag return _volumeDao.search(sc, searchFilter); } + @Override + public String getSupportedImageFormatForCluster(Long clusterId) { + ClusterVO cluster = ApiDBUtils.findClusterById(clusterId); + + if (cluster.getHypervisorType() == HypervisorType.XenServer) { + return "vhd"; + } else if (cluster.getHypervisorType() == HypervisorType.KVM) { + return "qcow2"; + } else if (cluster.getHypervisorType() == HypervisorType.VMware) { + return "ova"; + } else if (cluster.getHypervisorType() == HypervisorType.Ovm) { + return "raw"; + } else { + return null; + } + } + } diff --git a/server/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java b/server/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java index 9f3020aebae..ef4da57c878 100755 --- a/server/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java +++ b/server/src/com/cloud/upgrade/PremiumDatabaseUpgradeChecker.java @@ -109,7 +109,7 @@ public class PremiumDatabaseUpgradeChecker extends DatabaseUpgradeChecker { _upgradeMap.put("2.2.10", new DbUpgrade[] { new Upgrade2210to2211(), new Upgrade2211to2212Premium(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), - new Upgrade302to303() }); + new Upgrade301to302(), new Upgrade302to303() }); _upgradeMap.put("2.2.11", new DbUpgrade[] { new Upgrade2211to2212Premium(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c4f528e18d7..81f0700a666 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -590,6 +590,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager volume = _storageMgr.createVolume(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList(), volume.getSize(), rootDiskHyperType); }else { try { + // Format of data disk should be the same as root disk + if(_storageMgr.getSupportedImageFormatForCluster(rootDiskPool.getClusterId()) != volHostVO.getFormat().getFileExtension()){ + throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " +volHostVO.getFormat().getFileExtension()+ + " is not compatible with the vm hypervisor type" ); + } volume = _storageMgr.copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList(), volume.getSize(), rootDiskHyperType); } catch (NoTransitionException e) { e.printStackTrace(); diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 9bfcfc19f7e..816fe437a65 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -1,5 +1,4 @@ /*[fmt]1C20-1C0D-E*/ -/*dmin*/ /*+clearfix {*/ div.toolbar:after, .multi-wizard .progress ul li:after, @@ -5454,6 +5453,10 @@ label.error { overflow: hidden; } +.multi-wizard.zone-wizard .setup-guest-traffic.basic .select-container { + background: #FFFFFF; +} + .multi-wizard.zone-wizard .main-desc { width: 516px; float: left; diff --git a/ui/index.jsp b/ui/index.jsp index 06654a4c91f..1074a80c8a2 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -2952,6 +2952,7 @@ dictionary = { 'message.validate.instance.name': '', 'label.action.register.template': '', 'label.action.register.iso': '', -'label.isolation.method': '' +'label.isolation.method': '', +'label.checksum': '' }; diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 3d52633d600..58fdf9882f2 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -51,10 +51,7 @@ // For localization return str; }, - label: 'label.state', - converter: function(str) { - return 'state.' + str; - }, + label: 'label.state', indicator: { 'enabled': 'on', 'Destroyed': 'off', diff --git a/ui/scripts/cloud.core.callbacks.js b/ui/scripts/cloud.core.callbacks.js index bcaa0fe128e..505b739115d 100644 --- a/ui/scripts/cloud.core.callbacks.js +++ b/ui/scripts/cloud.core.callbacks.js @@ -23,10 +23,14 @@ the session ID has been changed (i.e. another user logging into the UI via a dif or it's the first time the user has come to this page. */ function onLogoutCallback() { - // Returning true means the LOGIN page will be show. If you wish to redirect the user - // to different login page, this is where you would do that. - g_loginResponse = null; - return true; + g_loginResponse = null; //clear single signon variable g_loginResponse + + + return true; // return true means the login page will show + /* + window.location.replace("http://www.google.com"); //redirect to a different location + return false; //return false means it will stay in the location window.location.replace() sets it to (i.e. "http://www.google.com") + */ } var g_loginResponse = null; diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index b7101d79c68..1b6637dfd0b 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -317,15 +317,14 @@ $.cookie('timezone', null); $.cookie('supportELB', null); - if(onLogoutCallback()) { //set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen. - document.location.reload(); + if(onLogoutCallback()) { //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen. + document.location.reload(); //when onLogoutCallback() returns true, reload the current document. } }, error: function() { - if(onLogoutCallback()) { //set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen. - document.location.reload(); - } - document.location.reload(); + if(onLogoutCallback()) { //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen. + document.location.reload(); //when onLogoutCallback() returns true, reload the current document. + } }, beforeSend : function(XMLHttpResponse) { return true; diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 6d1b9ddb9eb..cd690e64e78 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -47,11 +47,7 @@ instancename: { label: 'label.internal.name' }, zonename: { label: 'label.zone.name' }, state: { - label: 'label.state', - converter: function(str) { - // For localization - return 'state.' + str; - }, + label: 'label.state', indicator: { 'Running': 'on', 'Stopped': 'off', diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 0abba2efe24..bd111001b88 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -899,11 +899,7 @@ title: 'label.menu.ipaddresses', listView: { id: 'ipAddresses', - label: 'IPs', - filters: { - allocated: { label: 'label.allocated' }, - mine: { label: 'label.my.network' } - }, + label: 'IPs', fields: { ipaddress: { label: 'IP', diff --git a/ui/scripts/projects.js b/ui/scripts/projects.js index 233fecb1ec4..6132e793f84 100644 --- a/ui/scripts/projects.js +++ b/ui/scripts/projects.js @@ -576,16 +576,13 @@ displaytext: { label: 'label.display.name' }, domain: { label: 'label.domain' }, account: { label: 'label.owner.account' }, - state: { - converter: function(str) { - // For localization - return 'state.' + str; - }, - label: 'label.status', indicator: { - converter: function(str) { - return 'state.' + str; - }, - 'Active': 'on', 'Destroyed': 'off', 'Disabled': 'off', 'Left Project': 'off' + state: { + label: 'label.status', + indicator: { + 'Active': 'on', + 'Destroyed': 'off', + 'Disabled': 'off', + 'Left Project': 'off' } } }, @@ -870,11 +867,7 @@ project: { label: 'label.project' }, domain: { label: 'label.domain' }, state: { - label: 'label.status', - converter: function(str) { - // For localization - return 'state.' + str; - }, + label: 'label.status', indicator: { 'Accepted': 'on', 'Completed': 'on', 'Pending': 'off', 'Declined': 'off' diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 512cf678993..c490f7b9cc3 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -35,14 +35,12 @@ type: { label: 'label.type' }, storagetype: { label: 'label.storage.type' }, vmdisplayname: { label: 'label.vm.display.name' }, - state: { - converter: function(str) { - // For localization - return 'state.' + str; - }, - label: 'State', - indicator: { 'Ready': 'on' } - } + state: { + label: 'State', + indicator: { + 'Ready': 'on' + } + } }, // List view actions @@ -172,8 +170,7 @@ poll: pollAsyncJobResult } }, - - //??? + uploadVolume: { isHeader: true, label: 'label.upload.volume', @@ -216,7 +213,10 @@ url: { label: 'label.url', validation: { required: true } - } + }, + checksum : { + label: 'label.checksum' + } } }, @@ -226,26 +226,16 @@ array1.push("&zoneId=" + args.data.availabilityZone); array1.push("&format=" + args.data.format); array1.push("&url=" + todb(args.data.url)); + if(args.data.checksum != null && args.data.checksum.length > 0) + array1.push("&checksum=" + todb(args.data.checksum)); $.ajax({ url: createURL("uploadVolume" + array1.join("")), dataType: "json", async: true, - success: function(json) { - debugger; - var jid = json.uploadvolumeresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.volume; - }, - getActionFilter: function() { - return volumeActionfilter; - } - } - } - ); + success: function(json) { + var items = json.uploadvolumeresponse.volume; + args.response.success({data:items[0]}); }, error: function(json) { args.response.error(parseXMLHttpResponse(json)); @@ -254,11 +244,12 @@ }, notification: { - poll: pollAsyncJobResult + poll: function(args) { + args.complete(); + } } } - //??? - + }, dataProvider: function(args) { @@ -1000,16 +991,11 @@ volumename: { label: 'label.volume' }, intervaltype: { label: 'label.interval.type' }, created: { label: 'label.created', converter: cloudStack.converters.toLocalDate }, - state: { - converter: function(str) { - // For localization - return 'state.'+str; - }, - label: 'label.state', indicator: { - converter: function(str) { - return 'state.' + str; - }, - 'BackedUp': 'on', 'Destroyed': 'off' + state: { + label: 'label.state', + indicator: { + 'BackedUp': 'on', + 'Destroyed': 'off' } } }, diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 7f638d880da..8217bd923b9 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1258,7 +1258,7 @@ var selectedNetworkOfferingId = $(this).val(); $(networkOfferingObjs).each(function(){ if(this.id == selectedNetworkOfferingId) { - if(this.guestiptype == "Isolated") { + if(this.guestiptype == "Isolated") { //*** Isolated *** if(this.specifyipranges == false) { $form.find('.form-item[rel=guestStartIp]').hide(); $form.find('.form-item[rel=guestEndIp]').hide(); @@ -1266,26 +1266,40 @@ else { $form.find('.form-item[rel=guestStartIp]').css('display', 'inline-block'); $form.find('.form-item[rel=guestEndIp]').css('display', 'inline-block'); + } + + var includingSourceNat = false; + var serviceObjArray = this.service; + for(var k = 0; k < serviceObjArray.length; k++) { + if(serviceObjArray[k].name == "SourceNat") { + includingSourceNat = true; + break; + } + } + if(includingSourceNat == true) { //Isolated with SourceNat + cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=guestGateway]')); //make guestGateway optional + cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=guestNetmask]')); //make guestNetmask optional } - - //cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=guestGateway]')); //make guestGateway optional - //cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=guestNetmask]')); //make guestNetmask optional + else { //Isolated with no SourceNat + cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=guestGateway]')); //make guestGateway required + cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=guestNetmask]')); //make guestNetmask required + } } - else { //this.guestiptype == "Shared" + else { //*** Shared *** $form.find('.form-item[rel=guestStartIp]').css('display', 'inline-block'); $form.find('.form-item[rel=guestEndIp]').css('display', 'inline-block'); - //cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=guestGateway]')); //make guestGateway required - //cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=guestNetmask]')); //make guestNetmask required + cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=guestGateway]')); //make guestGateway required + cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=guestNetmask]')); //make guestNetmask required } if(this.specifyvlan == false) { $form.find('.form-item[rel=vlanId]').hide(); - //cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=vlanId]')); //make vlanId optional + cloudStack.dialog.createFormField.validation.required.remove($form.find('.form-item[rel=vlanId]')); //make vlanId optional } else { $form.find('.form-item[rel=vlanId]').css('display', 'inline-block'); - //cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=vlanId]')); //make vlanId required + cloudStack.dialog.createFormField.validation.required.add($form.find('.form-item[rel=vlanId]')); //make vlanId required } return false; //break each loop } @@ -7815,10 +7829,7 @@ 'Enabled': 'on', 'Disabled': 'off', 'Destroyed': 'off' - }, - converter: function(str) { - return 'state.' + str; - } + } } }, diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js index 709fabfefc7..9b659b26863 100644 --- a/ui/scripts/ui/dialog.js +++ b/ui/scripts/ui/dialog.js @@ -53,6 +53,7 @@ var fields = $.map(args.form.fields, function(value, key) { return key; }) + $(fields).each(function() { var key = this; var field = args.form.fields[key]; @@ -86,15 +87,21 @@ closeOnEscape: false }); */ // Label field + + //if( field.label == 'label.network.offering' || field.label == 'label.guest.gateway') + // debugger; + var $name = $('
').addClass('name') .appendTo($formItem) .append( $('