[Ovirt-devel] [PATCH server] fixes to the multiple vm/nets component
Mohammed Morsi
mmorsi at redhat.com
Thu Jul 30 20:05:27 UTC 2009
- changes to the form/style cleaning it up greatly
- changes to the controller fixing allowing nics/
networks to actually be saved (credit to Michel
Loiseleur for helping with this)
- very small test and indentation fixes
---
src/app/controllers/vm_controller.rb | 41 +++-
src/app/views/vm/_form.rhtml | 365 ++++++++++++++---------------
src/public/stylesheets/components.css | 32 ++-
src/test/functional/vm_controller_test.rb | 1 -
4 files changed, 231 insertions(+), 208 deletions(-)
diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb
index 54c39cf..eda5798 100644
--- a/src/app/controllers/vm_controller.rb
+++ b/src/app/controllers/vm_controller.rb
@@ -177,9 +177,10 @@ class VmController < ApplicationController
nnic = Nic.new(:mac => nic.mac,
:vm_id => @vm.id,
:network => nic.network)
- if(nic.network.boot_type.proto == 'static')
- nnic.ip_addresses << IpAddress.new(:address => nic.ip_address)
- end
+
+ if(nic.network.boot_type.proto == 'static')
+ nnic.ip_addresses << IpAddress.new(:address => nic.ip_address)
+ end
@nics.push nnic
net_conditions += (net_conditions == "" ? "" : " AND ") +
@@ -191,9 +192,9 @@ class VmController < ApplicationController
networks.each{ |net|
nnic = Nic.new(:mac => Nic::gen_mac, :network => net)
- if(net.boot_type.proto == 'static')
- nnic.ip_addresses << IpAddress.new(:address => '127.0.0.1') # FIXME
- end
+ if(net.boot_type.proto == 'static')
+ nnic.ip_addresses << IpAddress.new(:address => '127.0.0.1') # FIXME
+ end
@nics.push nnic
}
@@ -201,14 +202,32 @@ class VmController < ApplicationController
# merges vm / network parameters as submitted on the vm form
def _parse_network_params(params)
+ # 'params' subarrays 'networks', 'macs', and 'ip_addresses' all
+ # correspond to each other such that networks[i] corresponds
+ # to macs[i] and networks.static_networks_subset[j] corresponds
+ # to ip_addresses[j]
+ ip_counter = 0
params[:nics] = []
+
unless params[:networks].nil?
- params[:networks].each { |network, id|
- params[:nics].push({ :mac => params[("nic_"+network.to_s).intern],
- :network_id => network,
- :bandwidth => 0})
+ (0...params[:networks].length).each { |i|
+
+ network_id = params[:networks][i]
+ unless network_id.nil? || network_id == ""
+ nic = { :mac => params[:macs][i],
+ :network_id => network_id, :bandwidth => 0 }
+
+ if(Network.find(network_id).boot_type.proto == 'static')
+ # FIXME make this able to be v4 or v6 address
+ nic[:ip_addresses] = [IpV4Address.new({ :address => params[:ip_addresses][ip_counter] })]
+ ip_counter += 1
+ end
+
+ params[:nics].push(nic)
+ end
+
}
- end
+ end
end
end
diff --git a/src/app/views/vm/_form.rhtml b/src/app/views/vm/_form.rhtml
index 2373678..5f519fc 100644
--- a/src/app/views/vm/_form.rhtml
+++ b/src/app/views/vm/_form.rhtml
@@ -50,28 +50,60 @@
<div class="form_heading clickable closed">Network</div>
<div class="vm_form_section" style="display:none;">
<div class="clear_row"></div>
+
<% if @nics.size > 0 %>
<div id="vm_network_config_header">
- <div id="vm_network_config_header_network">
- Network:
- </div>
- <div id="vm_network_config_header_mac">
- MAC Address:
- </div>
- <div id="vm_network_config_header_ip">
- <%# this column is only populated if a static ip network is selected: %>
- IP Address:
- </div>
+ <div id="vm_network_config_header_network">Network:</div>
+ <div id="vm_network_config_header_mac">MAC Address:</div>
+
+ <%# this column is only populated if a static ip network is selected: %>
+ <div id="vm_network_config_header_ip" style="display: none;">IP Address:</div>
<div class="clear_row"></div><div style="clear:both;"></div>
</div>
- <%# populated with jquery below: %>
- <div id="vm_network_config_networks"></div>
- <div id="vm_network_config_add">
- Add Another Network
- </div>
+
+ <div id="vm_network_config_networks">
+ <%# add number of rows equal to nics.size, initially only show first %>
+ <% (0... at nics.size).each { |i| %>
+ <div id="vm_network_config_row_<%= i %>" class="vm_network_config_row"
+ <% if i != 0 %>style="display: none;"<%end%> >
+
+ <div class="vm_network_config_net">
+ <select name="networks[]" id="vm_network_config_select_<%= i %>" class="vm_network_config_select">
+ <option value="">None</option>
+ <% @nics.each { |nic| %>
+ <option value="<%= nic.network_id %>"><%= nic.network.name %></option>
+ <% } %>
+ </select>
+ </div>
+
+ <div class="vm_network_config_mac">
+ <input name="macs[]" id="vm_network_config_mac_<%= i %>" ></input>
+ </div>
+
+ <div class="vm_network_config_ip">
+
+ </div>
+
+ <% if i != 0 %>
+ <div id="vm_network_config_remove_<%= i %>" class="vm_network_config_remove">
+ Remove
+ </div>
+ <% end %>
+
+ <div class="clear_row"></div><div class="clear_row"></div>
+ <div style="clear:both;"></div>
+ </div>
+ <% } %>
+ </div>
+
+ <div id="vm_network_config_add">
+ Add Another Network
+ </div>
+
<% else %>
<b>No networks available</b>
<% end %>
+
<div style="clear:both;"></div>
<div class="clear_row"></div>
@@ -134,189 +166,152 @@ ${htmlList(pools, id)}
$(this).toggleClass('open').toggleClass('closed').next().slideToggle('slow');
}
});
- });
/////////////////////////////////////////////////// vm networks config
- // number of rows which we are currently displaying in net config
- var vm_network_config_rows = 0;
-
- // last row currently being displayed
- var vm_network_config_last_row = 0;
-
- // value of current selectbox
- var current_selectbox_value = 0;
-
- // create list of nics
- var nics = new Array();
- <% @nics.each { |rnic| %>
- jnic = new Object;
- jnic.network_id = "<%= rnic.network_id.to_s %>";
- jnic.name = "<%= rnic.network.name %>";
- jnic.mac = "<%= rnic.mac %>";
- jnic.ip = "<%= rnic.ip_address %>";
- jnic.static_ip = <%= rnic.network.boot_type.proto == 'static' %>;
- jnic.selected = false;
- nics.push(jnic);
- <% } %>
-
- // adds unselected network back to selectboxes indicated by selector
- function add_unselected_network(selector, network_id){
- for(j = 0; j < nics.length; ++j){
- if(nics[j].network_id == network_id){
- nics[j].selected = false;
- $(selector).append('<option value="' + nics[j].network_id + '">' + nics[j].name + '</option>');
- break;
+ // create list of nics
+ var nics = new Array();
+ <% @nics.each { |rnic| %>
+ jnic = new Object;
+ jnic.network_id = "<%= rnic.network_id.to_s %>";
+ jnic.name = "<%= rnic.network.name %>";
+ jnic.mac = "<%= rnic.mac %>";
+ jnic.ip = "<%= rnic.ip_address %>";
+ jnic.static_ip = <%= rnic.network.boot_type.proto == 'static' %>;
+ jnic.selected = false;
+ jnic.row = null;
+ nics.push(jnic);
+ <% } %>
+
+ // find nic in nics array matching network id
+ function find_nic_by_id(network_id){
+ for(j = 0; j < nics.length; ++j){
+ if(nics[j].network_id == network_id){
+ return nics[j];
+ }
}
- }
- }
-
- // show / hide ip address column
- function toggle_ip_address_column(){
- for(i = 0; i < nics.length; ++i){
- if(nics[i].selected && nics[i].static_ip){
- $('#vm_network_config_header_ip').show();
- return;
- }
- }
- $('#vm_network_config_header_ip').hide();
- }
-
- // show a new network config row
- function add_network_config_row(no_remove_link){
-
- // if the number of rows is equal to the number of
- // networks, don't show any more rows
- if(vm_network_config_rows == nics.length)
- return;
-
- vm_network_config_rows += 1;
- vm_network_config_last_row = vm_network_config_rows;
-
- // create the content for another row to be added to the vm_network_config_networks div above.
- // currently a row has a network select box, a mac text field, and an ip address field if a static network is selected
- var content = '<div id="vm_network_config_row_'+vm_network_config_rows+'" class="vm_network_config_row">';
- content += ' <div class="vm_network_config_net">';
- content += ' <select id="vm_network_config_network_select_'+vm_network_config_rows+'" class="vm_network_config_network_select">';
- content += ' <option value="">None</option>';
- for(i = 0; i < nics.length; ++i){
- if(!nics[i].selected)
- content += ' <option value="' + nics[i].network_id + '">' + nics[i].name + '</option>';
- }
- content += ' </select>';
- content += ' </div>';
- content += ' <div id="vm_network_config_mac_'+vm_network_config_rows+'" class="vm_network_config_mac">';
- content += ' <input style="width: 130px;"></input>';
- content += ' </div>';
- content += ' <div id="vm_network_config_ip_'+vm_network_config_rows+'" class="vm_network_config_ip">';
- content += ' ';
- content += ' </div>';
-
- if(!no_remove_link){
- content += ' <div id="vm_network_config_remove_'+vm_network_config_rows+'" class="vm_network_config_remove">';
- content += ' Remove';
- content += ' </div>';
- }
- content += ' <div class="clear_row"></div><div class="clear_row"></div><div style="clear:both;"></div>';
- content += '</div>';
-
- $('#vm_network_config_networks').append(content);
-
- $('#vm_network_config_networks').ready(function(){
- // when vm_network_config_remove link is click remove target row
- $('#vm_network_config_remove_'+vm_network_config_rows).bind('click', function(e){
- remove_network_config_row(e.target.id.substr(25)); // remove vm_network_config_remove_ bit to get row num
- });
-
- // when select box clicked, store current value for use on change
- $('#vm_network_config_network_select_'+vm_network_config_rows).bind('click', function(e){
- current_selectbox_value = e.target.value;
- });
-
- // when value of network select box is switched
- $('#vm_network_config_network_select_'+vm_network_config_rows).bind('change', function(e){
- row = e.target.id.substr(33)
-
- // find nic w/ selected network id
+ return null;
+ }
+
+ // parses a row out of a div id
+ function get_row_from_div_id(id){
+ return parseInt(id.substr(id.lastIndexOf('_') + 1));
+ }
+
+ // show / hide ip address column header
+ // depending if any static networks
+ // are selected
+ function toggle_ip_address_column(){
for(i = 0; i < nics.length; ++i){
- if(nics[i].network_id == e.target.value){
- nics[i].selected = true;
+ if(nics[i].selected && nics[i].static_ip){
+ $('#vm_network_config_header_ip').show();
- // fill in mac / ip address textfields as necessary
- $('#vm_network_config_mac_'+row).html('<input id="vm_network_config_mac_field_'+nics[i].network_id+'" style="width: 130px" value="'+nics[i].mac+'"/>');
- if(nics[i].static_ip != ""){
- $('#vm_network_config_ip_'+row).html('<input id="vm_network_config_ip_field_'+nics[i].ip+'" style="width: 130px" value="'+nics[i].ip+'"/>');
- }else{
- $('#vm_network_config_ip_'+row).html(' ');
- }
+ // set the min width, for the columns that don't have static_ips
+ $('.vm_network_config_ip').css('min-width', '140px')
- // for the other select boxes, removed selected network
- $('.vm_network_config_network_select:not(#vm_network_config_network_select_'+row+') option[@value='+nics[i].network_id+']').remove();
-
- break;
+ return;
}
}
+ $('#vm_network_config_header_ip').hide();
+ $('.vm_network_config_ip').css('min-width', '')
+ }
- // if we are clearing the row, do so
- if(e.target.value == ""){
- $('#vm_network_config_mac_'+row).html('<input id="vm_network_config_mac_field_'+row+'" style="width: 130px" value=""/>');
- $('#vm_network_config_ip_'+row).html(' ');
- }
- // add unselected network back to other selectboxes.
- add_unselected_network('.vm_network_config_network_select:not(#vm_network_config_network_select_'+row+')', current_selectbox_value);
-
- // show / hide ip address column
- toggle_ip_address_column();
-
- // only add a new blank row if last row's select box was changed
- if(e.target.value != "" && row == vm_network_config_last_row){
- // add row
- add_network_config_row();
- }
- });
+ // register the value of current selectbox,
+ // so we can easily add it back to the others
+ var current_network_selectbox_value = 0;
+ $('.vm_network_config_net select').bind('click', function(e){
+ current_network_selectbox_value = e.target.value;
});
- // show / hide ip address column
- toggle_ip_address_column();
- }
-
-
-
- // remove a network config row
- function remove_network_config_row(row_num){
- // if trying to remove the first row or a nonexistant one, fail to do so
- if(row_num < 2 || row_num > vm_network_config_last_row)
- return;
-
- // get selected network, add it to other selectboxes
- network_id = $('#vm_network_config_network_select_' + row_num).val();
- add_unselected_network('.vm_network_config_network_select:not(#vm_network_config_network_select_'+row_num+')', network_id);
-
- // remove the row
- $('#vm_network_config_row_' + row_num).remove();
-
- // when removed, set global params
- $('#vm_network_config_networks').ready(function(){
- vm_network_config_rows -= 1;
- rows = $('#vm_network_config_networks').children();
- vm_network_config_last_row = rows[rows.length - 1].id.substr(22);
-
- // show / hide ip address column
- toggle_ip_address_column();
- });
- }
-
- // intially show only one vm network config row
- $(document).ready(function(){
- add_network_config_row(true);
- });
+ // event handler for network select box changes
+ $('.vm_network_config_net select').bind('change', function(e){
+ row = get_row_from_div_id(e.target.id);
+
+ // if we've selected a network
+ if(e.target.value != ""){
+
+ // update nic attributes
+ nic = find_nic_by_id(e.target.value);
+ nic.selected = true;
+ nic.row = row;
+
+ // update old nic attributes if neccessary
+ if(current_network_selectbox_value != ""){
+ old_nic = find_nic_by_id(current_network_selectbox_value);
+ old_nic.selected = false;
+ old_nic.row = null;
+ }
+
+ // remove the value from all other selectboxes
+ $('.vm_network_config_select:not(#vm_network_config_select_'+row+') option[@value='+nic.network_id+']').hide();
+
+ // fill in mac
+ $('#vm_network_config_mac_'+row).attr('value', nic.mac);
+
+ // show / hide ip address textbox
+ ip_div = $('#vm_network_config_mac_'+row).parent().next();
+ if(nic.static_ip){
+ ip_div.html('<input name="ip_addresses[]" id="#vm_network_config_ip_'+row+'" value="'+nic.ip+'" />');
+ }else{
+ ip_div.html(' ');
+ }
+
+ // show new row only if last row's select box was
+ // previously empty, and if all are not shown
+ displayed_rows = $('.vm_network_config_row:visible').size();
+ if(current_network_selectbox_value == "" && displayed_rows != nics.length){
+ $('#vm_network_config_row_' + (row+1)).show();
+ }
+
+ // if we've unselected a network
+ }else{
+ // update old nic attributes if neccessary
+ if(current_network_selectbox_value != ""){
+ old_nic = find_nic_by_id(current_network_selectbox_value);
+ old_nic.selected = false;
+ old_nic.row = null;
+
+ // add network back to others
+ $('.vm_network_config_select:not(#vm_network_config_select_'+row+') option[@value='+old_nic.network_id+']').show();
+ }
+
+ // clear row mac and ip addresses
+ $('#vm_network_config_mac_'+row).attr('value', '');
+ $('#vm_network_config_mac_'+row).parent().next().html(' ');
+
+ // hide row if not the first
+ if(row != 0){
+ $('#vm_network_config_row_' + row).hide();
+ }
+ }
- // when vm_network_config_add link is clicked show new row
- $('#vm_network_config_add').bind('click', function(){
- // TODO check if there exists an empty row
- // TODO check to see if we've already added as many rows as there are nets
- add_network_config_row();
- });
+ toggle_ip_address_column();
+ });
+ // wire up add link
+ $('#vm_network_config_add').bind('click', function(){
+ // show new row if we're not currently display the max
+ displayed_rows = $('.vm_network_config_row:visible').size();
+ if(displayed_rows != nics.length){
+ row = get_row_from_div_id($('.vm_network_config_row:hidden').get(0).id);
+ $('#vm_network_config_row_' + (row)).show();
+ }
+ });
+
+ // wire up remove links
+ $('.vm_network_config_remove').bind('click', function(e){
+ // unselect network if selected
+ row = get_row_from_div_id(e.target.id);
+ current_network_selectbox_value = $('#vm_network_config_select_' + row).val();
+ $('#vm_network_config_select_' + row).val("").trigger('change');
+ });
+
+ // finally if the vm has nics, preselect them
+ <% unless @vm.nil?
+ (0... at vm.nics.size).each { |i| %>
+ $('#vm_network_config_select_<%= i %>').val("<%= @vm.nics[i].network_id %>").trigger('change');
+ <% }
+ end %>
+ });
</script>
diff --git a/src/public/stylesheets/components.css b/src/public/stylesheets/components.css
index fe4cda9..2cda65d 100644
--- a/src/public/stylesheets/components.css
+++ b/src/public/stylesheets/components.css
@@ -345,29 +345,39 @@
float: left;
}
-#vm_network_config_header_network {
- float: left;
- width: 20%;
+.vm_network_config_row {
+ min-width: 500px;
}
-#vm_network_config_header_mac, #vm_network_config_header_ip{
+
+#vm_network_config_header_network,
+#vm_network_config_header_mac,
+#vm_network_config_header_ip{
float: left;
- width: 33%;
+ width: 150px;
}
-.vm_network_config_net {
+.vm_network_config_net,
+.vm_network_config_mac{
float: left;
- width: 20%;
+ width: 150px;
}
-.vm_network_config_mac, .vm_network_config_ip{
+
+.vm_network_config_ip{
float: left;
- width: 33%;
- min-width: 100px;
+ max-width: 150px;
+}
+
+.vm_network_config_net select,
+.vm_network_config_mac input,
+.vm_network_config_ip input {
+ width: 130px;
}
.vm_network_config_remove {
float: left;
- padding-top: 5px;
color: #0033CC;
+ padding-top: 5px;
+ padding-left: 5px;
}
.vm_network_config_remove:hover {
cursor: pointer;
diff --git a/src/test/functional/vm_controller_test.rb b/src/test/functional/vm_controller_test.rb
index 1271851..206ab8f 100644
--- a/src/test/functional/vm_controller_test.rb
+++ b/src/test/functional/vm_controller_test.rb
@@ -61,7 +61,6 @@ class VmControllerTest < ActionController::TestCase
:description => 'descript',
:num_vcpus_allocated => 4,
:memory_allocated => 262144,
- :vnic_mac_addr => 'AA:BB:CC:DD:EE:FF',
:boot_device => 'network' }
assert_response :success
--
1.6.0.6
More information about the ovirt-devel
mailing list