Commit 471144fc authored by Georgios Ouzounis's avatar Georgios Ouzounis
Browse files

Dynamically change the VM-parameters drop down lists on create lambda instance form

parent 06c28956
import Ember from "ember";
export default Ember.Controller.extend({
selectedProject: null,
selectedProjectName: null,
selectedProjectVMs: null,
selectedProjectCPUs: null,
selectedProjectRAM: [],
selectedProjectDisk: [],
selectedNumberOfSlaves: null,
selectedMasterNodeCPUs: null,
selectedSlaveNodeCPUs: null,
......@@ -21,31 +26,43 @@ export default Ember.Controller.extend({
minQuotasPerProject: {
'vms': 2,
'cpus': 4,
'ram': {"bytes": 4294967296, "megaBytes": 4096},
'disk': {"bytes": 21474836480, "gigaBytes": 20},
'ram': {'bytes': 4294967296, 'megaBytes': 4096},
'disk': {'bytes': 21474836480, 'gigaBytes': 20},
'floatingIPs': 1,
'privateNetworks': 1
},
enoughQuotas: false,
submitButtonDisabled: false,
masterCPUsSelectDisabled: false,
masterRAMSelectDisabled: false,
masterDiskSelectDisabled: false,
slaveCPUsSelectDisabled: false,
slaveRAMSelectDisabled: false,
slaveDiskSelectDisabled: false,
myValue: 1,
actions: {
saveLambdaInstance: function(newLambdaInstance){
newLambdaInstance.set('instanceName', this.get('instanceName'));
newLambdaInstance.set('masterName', this.get('masterName'));
newLambdaInstance.set('slaves', this.$("input[name='slaves']")[0].value);
newLambdaInstance.set('slaves', $("input[name='slaves']")[0].value);
newLambdaInstance.set('projectName', this.$("select[name='okeanos_project']")[0].value);
newLambdaInstance.set('VCPUsMaster', this.$("select[name='vcpus_master']")[0].value);
newLambdaInstance.set('VCPUsSlave', this.$("select[name='vcpus_slave']")[0].value);
newLambdaInstance.set('RamMaster', this.$("select[name='ram_master']")[0].value);
newLambdaInstance.set('RamSlave', this.$("select[name='ram_slave']")[0].value);
newLambdaInstance.set('DiskMaster', this.$("select[name='disk_master']")[0].value);
newLambdaInstance.set('DiskSlave', this.$("select[name='disk_slave']")[0].value);
newLambdaInstance.set('projectName', $("select[name='okeanos_project']")[0].value);
newLambdaInstance.set('VCPUsMaster', $("select[name='vcpus_master']")[0].value);
newLambdaInstance.set('VCPUsSlave', $("select[name='vcpus_slave']")[0].value);
newLambdaInstance.set('RamMaster', $("select[name='ram_master']")[0].value);
newLambdaInstance.set('RamSlave', $("select[name='ram_slave']")[0].value);
newLambdaInstance.set('DiskMaster', $("select[name='disk_master']")[0].value);
newLambdaInstance.set('DiskSlave', $("select[name='disk_slave']")[0].value);
var requestedPublicKeys = [];
var options = this.$("select[name='public_key_name']")[0].options;
var options = $("select[name='public_key_name']")[0].options;
for(var i = 0;i < options.length;i++){
if(options[i].selected){
requestedPublicKeys.push(options[i].value);
......@@ -102,14 +119,103 @@ export default Ember.Controller.extend({
},
selectFromDropDownList: function(variable, event){
var value = event.target.value;
this.set(variable, value);
this.set(variable, event.target.value);
this.calculateDropDownListValues();
var self = this;
Ember.run.schedule('render', function task(){
self.calculateDropDownListValues();
});
}
},
calculateDropDownListValues: function(){
var model = this.get('model');
// Get the quotas of the selected project. Each project inside the model has the minimum
// quotas needed for the creation of a Lambda Instance since those that didn't, were removed
// from the router.
var selectedProjectName = this.get('selectedProjectName');
for(var i = 0, n = model.userOkeanosProjects.get('length');i < n;i++){
var currentProject = model.userOkeanosProjects.objectAt(i);
if(currentProject.get('name').localeCompare(selectedProjectName) == 0){
this.set('selectedProjectVMs', currentProject.get('vm'));
this.set('selectedProjectCPUs', currentProject.get('cpu'));
this.set('selectedProjectRAM', {'megaBytes': currentProject.get('ram') / 1048576});
this.set('selectedProjectDisk', {'gigaBytes': currentProject.get('disk') / 1073741824});
break;
}
}
// Set the selected number of slaves to a proper value.
if(this.get('selectedNumberOfSlaves') <= 0){
this.set('selectedNumberOfSlaves', 1);
}
else if(this.get('selectedNumberOfSlaves') >= this.get('selectedProjectVMs')){
this.set('selectedNumberOfSlaves', this.get('selectedProjectVMs') - 1);
}
var selectedNumberOfSlaves = this.get('selectedNumberOfSlaves');
var masterNodeCPUValues = this.get('masterNodeCPUValues');
var slaveNodeCPUValues = this.get('slaveNodeCPUValues');
var masterNodeRAMValues = this.get('masterNodeRAMValues');
var slaveNodeRAMValues = this.get('slaveNodeRAMValues');
var masterNodeDiskValues= this.get('masterNodeDiskValues');
var slaveNodeDiskValues = this.get('slaveNodeDiskValues');
var availableCPUs = this.get('selectedProjectCPUs');
var availableRAM = this.get('selectedProjectRAM')['megaBytes'];
var availableDisk = this.get('selectedProjectDisk')['gigaBytes'];
var leastCPUsForSlaves = selectedNumberOfSlaves * slaveNodeCPUValues.objectAt(0).get('value');
var leastRAMForSlaves = selectedNumberOfSlaves * slaveNodeRAMValues.objectAt(0).get('value');
var leastDiskForSlaves = selectedNumberOfSlaves * slaveNodeDiskValues.objectAt(0).get('value');
var maxCPUsForMaster = availableCPUs - leastCPUsForSlaves;
var maxRAMForMaster = availableRAM - leastRAMForSlaves;
var maxDiskForMaster = availableDisk - leastDiskForSlaves;
masterNodeCPUValues.forEach(function(item){
item.set('enabled', !(item.get('value') > maxCPUsForMaster));
});
this.set('masterCPUsSelectDisabled', masterNodeCPUValues.isEvery('enabled', false));
masterNodeRAMValues.forEach(function(item){
item.set('enabled', !(item.get('value') > maxRAMForMaster));
});
this.set('masterRAMSelectDisabled', masterNodeRAMValues.isEvery('enabled', false));
masterNodeDiskValues.forEach(function(item){
item.set('enabled', !(item.get('value') > maxDiskForMaster));
});
this.set('masterDiskSelectDisabled', masterNodeDiskValues.isEvery('enabled', false));
var maxCPUsForSlave = (availableCPUs - this.get('selectedMasterNodeCPUs')) / selectedNumberOfSlaves;
var maxRAMForSlave = (availableRAM - this.get('selectedMasterNodeRAM')) / selectedNumberOfSlaves;
var maxDiskForSlave = (availableDisk - this.get('selectedMasterNodeDisk')) / selectedNumberOfSlaves;
slaveNodeCPUValues.forEach(function(item){
item.set('enabled', !(item.get('value') > maxCPUsForSlave));
});
this.set('slaveCPUsSelectDisabled', slaveNodeCPUValues.isEvery('enabled', false));
slaveNodeRAMValues.forEach(function(item){
item.set('enabled', !(item.get('value') > maxRAMForSlave));
});
this.set('slaveRAMSelectDisabled', slaveNodeRAMValues.isEvery('enabled', false));
slaveNodeDiskValues.forEach(function(item){
item.set('enabled', !(item.get('value') > maxDiskForSlave));
});
this.set('slaveDiskSelectDisabled', slaveNodeDiskValues.isEvery('enabled', false));
this.set('submitButtonDisabled', (
this.get('masterCPUsSelectDisabled') || this.get('masterRAMSelectDisabled') ||
this.get('masterDiskSelectDisabled') || this.get('slaveCPUsSelectDisabled') ||
this.get('slaveRAMSelectDisabled') || this.get('slaveDiskSelectDisabled')
)
);
}
});
......@@ -17,6 +17,10 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
// Instance.
var controller = this.controllerFor('create-lambda-instance');
var minQuotasPerProject = controller.get('minQuotasPerProject');
// Keep the index of the first project that satisfies the restrictions since deleted
// records are not immediately removed from the model.
var selectedProjectIndex = -1;
for (var i = 0;i < model.userOkeanosProjects.get('length');i++){
if (model.userOkeanosProjects.objectAt(i).get('vm') >= minQuotasPerProject['vms'] &&
model.userOkeanosProjects.objectAt(i).get('cpu') >= minQuotasPerProject['cpus'] &&
......@@ -27,6 +31,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
if(!controller.get('enoughQuotas')){
controller.set('enoughQuotas', true);
selectedProjectIndex = i;
}
}
else{
......@@ -35,24 +40,76 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
}
// If at least one project has enough quotas, set the default values for the drop down lists.
if(model.userOkeanosProjects.get('length') > 0){
controller.set('selectedProject', model.userOkeanosProjects.objectAt(0).get('name'));
// If there is no project with enough quotas, then 'enoughQuotas' will be set to false and
// the form will never be presented to the user.
if(selectedProjectIndex > - 1){
var selectedProject = model.userOkeanosProjects.objectAt(selectedProjectIndex);
controller.set('selectedProjectName', selectedProject.get('name'));
controller.set('selectedProjectVMs', selectedProject.get('vm'));
controller.set('selectedProjectCPUs', selectedProject.get('cpu'));
controller.set('selectedProjectRAM', {'megaBytes': selectedProject.get('ram') / 1048576});
controller.set('selectedProjectDisk', {'gigaBytes': selectedProject.get('disk') / 1073741824});
controller.set('selectedNumberOfSlaves', minQuotasPerProject['vms'] - 1);
var minQuotasPerVM = controller.get('minQuotasPerVM');
controller.set('selectedMasterNodeCPUs', minQuotasPerVM['cpus']);
controller.set('selectedSlaveNodeCPUs', minQuotasPerVM['cpus']);
controller.set('selectedMasterNodeRAM', minQuotasPerVM['ram']);
controller.set('selectedSlaveNodeRAM', minQuotasPerVM['ram']);
controller.set('selectedMasterNodeDisk', minQuotasPerVM['disk']);
controller.set('selectedSlaveNodeDisk', minQuotasPerVM['disk']);
controller.set('masterNodeCPUValues', model.VMParameterValues.objectAt(0).get('vcpus'));
controller.set('slaveNodeCPUValues', model.VMParameterValues.objectAt(0).get('vcpus'));
controller.set('masterNodeRAMValues', model.VMParameterValues.objectAt(0).get('ram'));
controller.set('slaveNodeRAMValues', model.VMParameterValues.objectAt(0).get('ram'));
controller.set('masterNodeDiskValues', model.VMParameterValues.objectAt(0).get('disk'));
controller.set('slaveNodeDiskValues', model.VMParameterValues.objectAt(0).get('disk'));
var masterNodeCPUValues = controller.get('masterNodeCPUValues');
var slaveNodeCPUValues = controller.get('slaveNodeCPUValues');
var masterNodeRAMValues = controller.get('masterNodeRAMValues');
var slaveNodeRAMValues = controller.get('slaveNodeRAMValues');
var masterNodeDiskValues = controller.get('masterNodeDiskValues');
var slaveNodeDiskValues = controller.get('slaveNodeDiskValues');
for(var i = 0, n = model.VMParameterValues.get('length');i < n;i++){
var cpus = model.VMParameterValues.objectAt(i).get('vcpus');
for(var j = 0, m = cpus.get('length');j < m;j++){
if(cpus[j] >= minQuotasPerVM['cpus']){
masterNodeCPUValues.pushObject(Ember.Object.create({'value': cpus[j], 'enabled': true}));
slaveNodeCPUValues.pushObject(Ember.Object.create({'value': cpus[j], 'enabled': true}));
}
}
var ram = model.VMParameterValues.objectAt(i).get('ram');
for(var j = 0, m = ram.get('length');j < m;j++){
if(ram[j] >= minQuotasPerVM['ram']){
masterNodeRAMValues.pushObject(Ember.Object.create({'value': ram[j], 'enabled': true}));
slaveNodeRAMValues.pushObject(Ember.Object.create({'value': ram[j], 'enabled': true}));
}
}
var disk = model.VMParameterValues.objectAt(i).get('disk');
for(var j = 0, m = disk.get('length');j < m;j++){
if(disk[j] >= minQuotasPerVM['disk']){
masterNodeDiskValues.pushObject(Ember.Object.create({'value': disk[j], 'enabled': true}));
slaveNodeDiskValues.pushObject(Ember.Object.create({'value': disk[j], 'enabled': true}));
}
}
}
var compareFunction = function(a, b){
return a['value'] > b['value'];
};
masterNodeCPUValues.sort(compareFunction);
slaveNodeCPUValues.sort(compareFunction);
masterNodeRAMValues.sort(compareFunction);
slaveNodeRAMValues.sort(compareFunction);
masterNodeDiskValues.sort(compareFunction);
slaveNodeDiskValues.sort(compareFunction);
controller.set('selectedMasterNodeCPUs', masterNodeCPUValues[0]['value']);
controller.set('selectedSlaveNodeCPUs', slaveNodeCPUValues[0]['value']);
controller.set('selectedMasterNodeRAM', masterNodeRAMValues[0]['value']);
controller.set('selectedSlaveNodeRAM', slaveNodeRAMValues[0]['value']);
controller.set('selectedMasterNodeDisk', masterNodeDiskValues[0]['value']);
controller.set('selectedSlaveNodeDisk', slaveNodeDiskValues[0]['value']);
}
}
});
......@@ -81,7 +81,7 @@
<div class="row">
<div class="form-group col-sm-8">
<label for="okeanos_project" class="col-sm-6">~okeanos Project (*):</label>
<select name="okeanos_project" class="form-control" onchange={{action "selectFromDropDownList" "selectedProject"}}>
<select name="okeanos_project" class="form-control" onchange={{action "selectFromDropDownList" "selectedProjectName"}}>
{{#each model.userOkeanosProjects as |project|}}
<option value={{project.name}}>{{project.name}} (VMs: {{project.vm}}, CPUs: {{project.cpu}}, RAM: {{normalize-bytes project.ram}}, Disk: {{normalize-bytes project.disk}}, Floating IPs: {{project.floating_ip}}, Private Networks: {{project.private_network}})</option>
{{/each}}
......@@ -90,7 +90,7 @@
</div> <!--class="col-sm-6"-->
<div class="form-group col-sm-3">
<label for="slaves">Number of slaves:</label>
<input type="number" min="1" value={{selectedNumberOfSlaves}} name="slaves" class="form-control" oninput={{action "selectFromDropDownList" "selectedNumberOfSlaves"}}>
{{input type="number" value=selectedNumberOfSlaves min=1 max=(math-op selectedProjectVMs '-' 1) name="slaves" class="form-control" change=(action "selectFromDropDownList" "selectedNumberOfSlaves")}}
<span id="helpBlock" class="help-block">Select the number of slaves</span>
</div> <!--class="form-group col-sm-3"-->
</div>
......@@ -147,13 +147,15 @@
<div class="row">
<div class="form-group col-sm-4">
<label for="vcpus_master">Number of CPUs on Master Node:</label>
<select name="vcpus_master" class="form-control" onchange={{action "selectFromDropDownList" "selectedMasterNodeCPUs"}}>
<select name="vcpus_master" class="form-control" onchange={{action "selectFromDropDownList" "selectedMasterNodeCPUs"}} disabled={{masterCPUsSelectDisabled}}>
{{#each masterNodeCPUValues as |vcpusValue|}}
{{#if (compare vcpusValue ">=" minQuotasPerVM.cpus)}}
{{#if (compare vcpusValue "!==" selectedMasterNodeCPUs)}}
<option value={{vcpusValue}}>{{vcpusValue}}</option>
{{#if (compare vcpusValue.value "==" selectedMasterNodeCPUs)}}
<option value={{vcpusValue.value}} selected>{{vcpusValue.value}}</option>
{{else}}
{{#if vcpusValue.enabled}}
<option value={{vcpusValue.value}}>{{vcpusValue.value}}</option>
{{else}}
<option value={{vcpusValue}} selected>{{vcpusValue}}</option>
<option value={{vcpusValue.value}} disabled>{{vcpusValue.value}}</option>
{{/if}}
{{/if}}
{{/each}}
......@@ -162,13 +164,15 @@
</div> <!--class="col-sm-4"-->
<div class="form-group col-sm-4">
<label for="ram_master" >Amount or RAM memory on Master Node: </label>
<select name="ram_master" class="form-control" onchange={{action "selectFromDropDownList" "selectedMasterNodeRAM"}}>
<select name="ram_master" class="form-control" onchange={{action "selectFromDropDownList" "selectedMasterNodeRAM"}} disabled={{masterRAMSelectDisabled}}>
{{#each masterNodeRAMValues as |ramValue|}}
{{#if (compare ramValue ">=" minQuotasPerVM.ram)}}
{{#if (compare ramValue "!==" selectedMasterNodeRAM)}}
<option value={{ramValue}}>{{ramValue}}</option>
{{#if (compare ramValue.value "==" selectedMasterNodeRAM)}}
<option value={{ramValue.value}} selected>{{ramValue.value}}</option>
{{else}}
{{#if ramValue.enabled}}
<option value={{ramValue.value}}>{{ramValue.value}}</option>
{{else}}
<option value={{ramValue}} selected>{{ramValue}}</option>
<option value={{ramValue.value}} disabled>{{ramValue.value}}</option>
{{/if}}
{{/if}}
{{/each}}
......@@ -177,13 +181,15 @@
</div><!--class="form-group col-sm-6"-->
<div class="form-group col-sm-4">
<label for="disk_master"> Size of hard disk on Master Node: </label>
<select name="disk_master" class="form-control" onchange={{action "selectFromDropDownList" "selectedMasterNodeDisk"}}>
<select name="disk_master" class="form-control" onchange={{action "selectFromDropDownList" "selectedMasterNodeDisk"}} disabled={{masterDiskSelectDisabled}}>
{{#each masterNodeDiskValues as |diskValue|}}
{{#if (compare diskValue ">=" minQuotasPerVM.disk)}}
{{#if (compare diskValue "!==" selectedMasterNodeDisk)}}
<option value={{diskValue}}>{{diskValue}}</option>
{{#if (compare diskValue.value "==" selectedMasterNodeDisk)}}
<option value={{diskValue.value}} selected>{{diskValue.value}}</option>
{{else}}
{{#if diskValue.enabled}}
<option value={{diskValue.value}}>{{diskValue.value}}</option>
{{else}}
<option value={{diskValue}} selected>{{diskValue}}</option>
<option value={{diskValue.value}} disabled>{{diskValue.value}}</option>
{{/if}}
{{/if}}
{{/each}}
......@@ -206,13 +212,15 @@
<div class="row">
<div class="form-group col-sm-4">
<label for="vcpus_slave">Number of CPUs on each Slave Node:</label>
<select name="vcpus_slave" class="form-control" onchange={{action "selectFromDropDownList" "selectedSlaveNodeCPUs"}}>
<select name="vcpus_slave" class="form-control" onchange={{action "selectFromDropDownList" "selectedSlaveNodeCPUs"}} disabled={{slaveCPUsSelectDisabled}}>
{{#each slaveNodeCPUValues as |vcpusValue|}}
{{#if (compare vcpusValue ">=" minQuotasPerVM.cpus)}}
{{#if (compare vcpusValue "!==" selectedSlaveNodeCPUs)}}
<option value={{vcpusValue}}>{{vcpusValue}}</option>
{{#if (compare vcpusValue.value "==" selectedSlaveNodeCPUs)}}
<option value={{vcpusValue.value}} selected>{{vcpusValue.value}}</option>
{{else}}
{{#if vcpusValue.enabled}}
<option value={{vcpusValue.value}}>{{vcpusValue.value}}</option>
{{else}}
<option value={{vcpusValue}} selected>{{vcpusValue}}</option>
<option value={{vcpusValue.value}} disabled>{{vcpusValue.value}}</option>
{{/if}}
{{/if}}
{{/each}}
......@@ -221,13 +229,15 @@
</div> <!--class="col-sm-4"-->
<div class="form-group col-sm-4">
<label for="ram_slave" >Amount or RAM memory on each Slave Node:</label>
<select name="ram_slave" class="form-control" onchange={{action "selectFromDropDownList" "selectedSlaveNodeRAM"}}>
<select name="ram_slave" class="form-control" onchange={{action "selectFromDropDownList" "selectedSlaveNodeRAM"}} disabled={{slaveRAMSelectDisabled}}>
{{#each slaveNodeRAMValues as |ramValue|}}
{{#if (compare ramValue ">=" minQuotasPerVM.ram)}}
{{#if (compare ramValue "!==" selectedSlaveNodeRAM)}}
<option value={{ramValue}}>{{ramValue}}</option>
{{#if (compare ramValue.value "==" selectedSlaveNodeRAM)}}
<option value={{ramValue.value}} selected>{{ramValue.value}}</option>
{{else}}
{{#if ramValue.enabled}}
<option value={{ramValue.value}}>{{ramValue.value}}</option>
{{else}}
<option value={{ramValue}} selected>{{ramValue}}</option>
<option value={{ramValue.value}} disabled>{{ramValue.value}}</option>
{{/if}}
{{/if}}
{{/each}}
......@@ -237,13 +247,15 @@
<div class="form-group col-sm-4">
<label for="disk_slave"> Size of hard disk on each Slave Node:</label>
<select name="disk_slave" class="form-control" onchange={{action "selectFromDropDownList" "selectedSlaveNodeDisk"}}>
<select name="disk_slave" class="form-control" onchange={{action "selectFromDropDownList" "selectedSlaveNodeDisk"}} disabled={{slaveDiskSelectDisabled}}>
{{#each slaveNodeDiskValues as |diskValue|}}
{{#if (compare diskValue ">=" minQuotasPerVM.disk)}}
{{#if (compare diskValue "!==" selectedSlaveNodeDisk)}}
<option value={{diskValue}}>{{diskValue}}</option>
{{#if (compare diskValue.value "==" selectedSlaveNodeDisk)}}
<option value={{diskValue.value}} selected>{{diskValue.value}}</option>
{{else}}
{{#if diskValue.enabled}}
<option value={{diskValue.value}}>{{diskValue.value}}</option>
{{else}}
<option value={{diskValue}} selected>{{diskValue}}</option>
<option value={{diskValue.value}} disabled>{{diskValue.value}}</option>
{{/if}}
{{/if}}
{{/each}}
......@@ -256,7 +268,7 @@
</div><!--col-->
</div><!--row-->
<button type="submit" class="btn btn-primary">Submit</button>
<button type="submit" class="btn btn-primary" disabled={{submitButtonDisabled}}>Submit</button>
<div class="row">
<div class="col-xs-12">
&nbsp;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment