[Ovirt-devel] [PATCH server] permit many-to-many vms / networks relationship redux (frontend changes)
Mohammed Morsi
mmorsi at redhat.com
Fri Jul 24 21:01:36 UTC 2009
implements changes to the views, helpers, and css
to permit vms to be associated with multiple networks.
---
src/app/views/host/show.rhtml | 2 +-
src/app/views/network/_select.rhtml | 2 +-
src/app/views/network/edit_nic.rhtml | 4 +-
src/app/views/nic/show.rhtml | 2 +
src/app/views/task/_user_list.rhtml | 2 +-
src/app/views/vm/_form.rhtml | 216 +++++++++++++++++++++++++++++++--
src/app/views/vm/_grid.rhtml | 1 -
src/app/views/vm/_list.rhtml | 2 -
src/app/views/vm/show.rhtml | 6 +-
src/public/stylesheets/components.css | 42 ++++++-
10 files changed, 261 insertions(+), 18 deletions(-)
diff --git a/src/app/views/host/show.rhtml b/src/app/views/host/show.rhtml
index f706761..ddc6481 100644
--- a/src/app/views/host/show.rhtml
+++ b/src/app/views/host/show.rhtml
@@ -64,7 +64,7 @@
<%=h @host.status_str %><br/>
<%= @host.nics.collect{ |n|
n.interface_name.to_s + " " + n.mac +
- (n.physical_network.nil? ? "" : " " + n.physical_network.name)
+ (n.network.nil? ? "" : " " + n.network.name)
}.join("<br/>")
%><br/>
<%= @host.bondings.collect { |n| n.name }.join("<br/>") %><br/>
diff --git a/src/app/views/network/_select.rhtml b/src/app/views/network/_select.rhtml
index 4d056df..47ab319 100644
--- a/src/app/views/network/_select.rhtml
+++ b/src/app/views/network/_select.rhtml
@@ -1,5 +1,5 @@
<% target = 'nic' unless target
- network_id = 'physical_network_id' if target == 'nic'
+ network_id = 'network_id' if target == 'nic'
network_id = 'vlan_id' if target == 'bonding'
%>
diff --git a/src/app/views/network/edit_nic.rhtml b/src/app/views/network/edit_nic.rhtml
index 1b58c20..e458ff2 100644
--- a/src/app/views/network/edit_nic.rhtml
+++ b/src/app/views/network/edit_nic.rhtml
@@ -6,10 +6,12 @@
<%= error_messages_for 'nic' %>
+ <%# TODO doesn't currently break anything due to where this form is displayed
+ but @nic.host assumption should be removed so this template can be included elsewhere %>
<div id="selected_popup_content_expanded" class="dialog_form">
<%= hidden_field_tag 'id', @nic.id %>
<%= hidden_field_tag 'nic_host_id', @nic.host.id %>
- <%= hidden_field_tag 'nic_network_id', @nic.physical_network.id if @nic.physical_network %>
+ <%= hidden_field_tag 'nic_network_id', @nic.network.id if @nic.network %>
<div class="selected_popup_content_left">MAC:</div>
<div class="selected_popup_content_right"><%= @nic.mac %></div>
diff --git a/src/app/views/nic/show.rhtml b/src/app/views/nic/show.rhtml
index 0bd3910..aaee67a 100644
--- a/src/app/views/nic/show.rhtml
+++ b/src/app/views/nic/show.rhtml
@@ -7,6 +7,8 @@
</p>
<% end %>
+<%# TODO doesn't currently break anything due to where this form is displayed
+ but @nic.host assumption should be removed so thiw template can be included elsewhere %>
<p><b>Host:</b> <%= link_to @nic.host.hostname, { :controller => "host", :action => "show", :id => @nic.host }, { :class => "show" } %></p>
</div>
diff --git a/src/app/views/task/_user_list.rhtml b/src/app/views/task/_user_list.rhtml
index e289932..1506359 100644
--- a/src/app/views/task/_user_list.rhtml
+++ b/src/app/views/task/_user_list.rhtml
@@ -7,7 +7,7 @@
<% for task in tasks %>
<li class="task">
<span class="secondary">action: </span><%= link_to task.action, { :controller => "task", :action => 'show', :id => task }, { :class => "action" } -%><br/>
- <span class="secondary">vm: </span><%= link_to task.vm.description, { :controller => "vm", :action => 'show', :id => task }, { :class => "description", :title => "cpus: %s mem: %s vNIC: %s" % [ task.vm.num_vcpus_used, task.vm.memory_used, task.vm.vnic_mac_addr ] } -%><br/>
+ <span class="secondary">vm: </span><%= link_to task.vm.description, { :controller => "vm", :action => 'show', :id => task }, { :class => "description", :title => "cpus: %s mem: %s" % [ task.vm.num_vcpus_used, task.vm.memory_used ] } -%><br/>
<span class="secondary">state: </span><span class="state"><%= task.state -%></span></li>
<% end %>
</ul>
diff --git a/src/app/views/vm/_form.rhtml b/src/app/views/vm/_form.rhtml
index 8373bf4..97b7188 100644
--- a/src/app/views/vm/_form.rhtml
+++ b/src/app/views/vm/_form.rhtml
@@ -50,19 +50,35 @@
<div class="form_heading clickable closed">Network</div>
<div class="vm_form_section" style="display:none;">
<div class="clear_row"></div>
- <div class="clear_row"></div>
- <div style="float:left;">
- <%= text_field_with_label "VNIC:", "vm", "vnic_mac_addr", {:style=>"width:250;"} %>
- </div>
- <div style="float:left;">
- <%= select_with_label "Network:", 'vm', 'network_id', @networks.insert(0, ""), :style=>"width:250px;" %>
- </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 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>
+ <% else %>
+ <b>No networks available</b>
+ <% end %>
+ <div style="clear:both;"></div>
<div class="clear_row"></div>
- <%= check_box_tag_with_label "Forward vm's vnc port locally", "forward_vnc", 1, @vm.forward_vnc %>
</div>
<div class="clear_row"></div>
+ <div class="form_heading"/>
<%= check_box_tag_with_label "Start VM Now? (pending current resource availability)", "start_now", nil if create or @vm.state == Vm::STATE_STOPPED %>
<%= check_box_tag_with_label "Restart VM Now? (pending current resource availability)", "restart_now", nil if @vm.state == Vm::STATE_RUNNING %>
@@ -119,4 +135,188 @@ ${htmlList(pools, id)}
}
});
});
+
+ /////////////////////////////////////////////////// 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;
+ }
+ }
+ }
+
+ // 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
+ for(i = 0; i < nics.length; ++i){
+ if(nics[i].network_id == e.target.value){
+ nics[i].selected = true;
+
+ // 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(' ');
+ }
+
+ // 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;
+ }
+ }
+
+ // 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();
+ }
+ });
+ });
+
+ // 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);
+ });
+
+ // 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();
+ });
+
</script>
diff --git a/src/app/views/vm/_grid.rhtml b/src/app/views/vm/_grid.rhtml
index a110011..e3fa0e0 100644
--- a/src/app/views/vm/_grid.rhtml
+++ b/src/app/views/vm/_grid.rhtml
@@ -34,7 +34,6 @@
<% end %>
{display: 'CPUs', name : 'num_vcpus_allocated', width : 40, sortable : true, align: 'left'},
{display: 'Memory (MB)', name : 'memory_allocated', width : 60, sortable : true, align: 'right'},
- {display: 'vNIC Mac Addr', name : 'vnic_mac_addr', width : 60, sortable : true, align: 'right'},
{display: 'State', name : 'state', width : 50, sortable : true, align: 'right'},
{display: 'Total Run Time', name : 'calc_uptime', width : 50, align: 'right'},
{display: 'Load', name : 'load', width: 180, sortable : false, align: 'left', process: <%= table_id %>_load_widget }
diff --git a/src/app/views/vm/_list.rhtml b/src/app/views/vm/_list.rhtml
index 42300d6..54ae741 100644
--- a/src/app/views/vm/_list.rhtml
+++ b/src/app/views/vm/_list.rhtml
@@ -4,7 +4,6 @@
<th class="empty">Description <span class="amp">&</span> UUID</th>
<th>CPUs</th>
<th>Memory (mb)</th>
- <th>vNIC MAC Addr</th>
<th>State</th>
</thead>
@@ -15,7 +14,6 @@
<td style="text-align:left"><%= link_to vm.description, { :controller => "vm", :action => 'show', :id => vm }, { :class => "show" } %><div class="secondary"><%= vm.uuid %></div></td>
<td><%= vm.num_vcpus_allocated %></td>
<td><%= vm.memory_allocated_in_mb %></td>
- <td><%= vm.vnic_mac_addr %></td>
<td style="text-align:left">
<%= vm.state %>
<%unless vm.needs_restart.nil? or vm.needs_restart == 0 -%>
diff --git a/src/app/views/vm/show.rhtml b/src/app/views/vm/show.rhtml
index ffe5055..1a3f81c 100644
--- a/src/app/views/vm/show.rhtml
+++ b/src/app/views/vm/show.rhtml
@@ -106,7 +106,7 @@
Num vcpus used:<br/>
Memory allocated:<br/>
Memory used:<br/>
- vNIC MAC address:<br/>
+ vNIC MAC addresses:<br/>
Boot device:<br/>
Provisioning source:<br/>
State:<br/>
@@ -122,7 +122,9 @@
<%=h @vm.num_vcpus_used %><br/>
<%=h @vm.memory_allocated_in_mb %> MB<br/>
<%=h @vm.memory_used_in_mb %> MB<br/>
- <%=h @vm.vnic_mac_addr %><br/>
+ <% nic_macs = ""
+ @vm.nics.each { |nic| nic_macs += nic.mac + " " } %>
+ <%=h nic_macs %><br/>
<%=h @vm.boot_device %><br/>
<%=h @vm.provisioning_and_boot_settings %><br/>
<%=h @vm.state %>
diff --git a/src/public/stylesheets/components.css b/src/public/stylesheets/components.css
index 074cc09..3844611 100644
--- a/src/public/stylesheets/components.css
+++ b/src/public/stylesheets/components.css
@@ -339,4 +339,44 @@
height: 11px;
}
-.vm_form_section {padding-left: 2em;}
\ No newline at end of file
+.vm_form_section {padding-left: 2em;}
+
+#vm_network_config .i {
+ float: left;
+}
+
+#vm_network_config_header_network {
+ float: left;
+ width: 20%;
+}
+#vm_network_config_header_mac, #vm_network_config_header_ip{
+ float: left;
+ width: 33%;
+}
+
+.vm_network_config_net {
+ float: left;
+ width: 20%;
+}
+.vm_network_config_mac, .vm_network_config_ip{
+ float: left;
+ width: 33%;
+ min-width: 100px;
+}
+
+.vm_network_config_remove {
+ float: left;
+ padding-top: 5px;
+ color: #0033CC;
+}
+.vm_network_config_remove:hover {
+ cursor: pointer;
+}
+
+#vm_network_config_add {
+ color: #0033CC;
+}
+#vm_network_config_add:hover {
+ cursor: pointer;
+}
+
--
1.6.0.6
More information about the ovirt-devel
mailing list