[Ovirt-devel] [PATCH server] new host networking wui

Mohammed Morsi mmorsi at redhat.com
Tue Oct 6 22:31:30 UTC 2009


Frontend and backend changes needed to implement
   http://ovirt.org/page/Networking_UX#Option_3
---
 src/app/controllers/host_controller.rb |   38 ++-
 src/app/services/host_service.rb       |   35 ++
 src/app/views/host/edit_network.rhtml  |  593 ++++++++++++++++++++++++++++----
 src/public/stylesheets/components.css  |   76 ++++
 4 files changed, 676 insertions(+), 66 deletions(-)

diff --git a/src/app/controllers/host_controller.rb b/src/app/controllers/host_controller.rb
index 20e9fca..5cb89a9 100644
--- a/src/app/controllers/host_controller.rb
+++ b/src/app/controllers/host_controller.rb
@@ -104,10 +104,46 @@ class HostController < ApplicationController
     render :layout => 'popup'
   end
 
+  def update_network
+    # adjust parameters as necessary
+    params[:nics]     = {} if params[:nics].nil?
+    params[:bondings] = {} if params[:bondings].nil?
+    params[:nics].each { |id,n|
+      unless n[:ip_address].nil?
+        # FIXME make this able to be v4 or v6 address
+        n[:ip_addresses] = [IpV4Address.new({ :address => n[:ip_address] })]
+        n.delete(:ip_address)
+      end
+    }
+    params[:bondings].each { |id,b|
+      unless b[:ip_address].nil?
+        # FIXME make this able to be v4 or v6 address
+        b[:ip_addresses] = [IpV4Address.new({ :address => b[:ip_address] })]
+        b.delete(:ip_address)
+      end
+
+      if b[:nic_ids].nil? || b[:nic_ids].size == 0
+         b[:nics] = []
+      else
+         b[:nics] = b[:nic_ids].collect { |n| Nic.find(n) }
+         b.delete(:nic_ids)
+      end
+
+      b[:interface_name] = b[:name] if b[:interface_name].nil? && !b[:name].nil?
+   }
+   params[:bondings].delete('NBID') # delete new bonding row
+
+   svc_update_network(params[:id], params[:nics], params[:bondings])
+   render :json => {
+     :object => "host",
+     :success => true,
+     :alert => "Host network entities successfully updated."
+   }
+  end
+
   def bondings_json
     svc_show(params[:id])
     bondings = @host.bondings
     render :json => bondings.collect{ |x| {:id => x.id, :name => x.name} }
   end
-
 end
diff --git a/src/app/services/host_service.rb b/src/app/services/host_service.rb
index 4ace9fb..3b59f0e 100644
--- a/src/app/services/host_service.rb
+++ b/src/app/services/host_service.rb
@@ -72,6 +72,41 @@ module HostService
   # [<tt>Privilege::MODIFY</tt>] on host's HardwarePool
   def svc_modify(id)
     lookup(id, Privilege::MODIFY)
+    @networks = Network.find(:all)
+    @bonding_types = BondingType.find(:all)
+  end
+
+  # Update the network entities associated with the Host with +id+
+  # === Instance variables
+  # [<tt>@host</tt>] stores the Host with +id+
+  # === Required permissions
+  # [<tt>Privilege::MODIFY</tt>] on host's HardwarePool
+  def svc_update_network(id, nics, bondings)
+    lookup(id, Privilege::MODIFY)
+
+    nics.each { |nic_id, nic|
+      dnic = @host.nics.all.find { |n| n.id == nic_id.to_i }
+      unless dnic.nil?
+        dnic.update_attributes!(nic)
+      end
+    }
+
+    # delete any bondings associated w/ host but not in bondings array
+    @host.bondings.each { |b|
+      b.destroy unless bondings.include?(b.id.to_s)
+    }
+
+    bondings.each { |bond_id, bond|
+      dbond = @host.bondings.all.find { |b| b.id == bond_id.to_i }
+      unless dbond.nil?
+        # update original bonding
+        dbond.update_attributes!(bond)
+      else
+        bond[:host_id] = id
+        # create new bonding
+        Bonding.create!(bond)
+      end
+    }
   end
 
   # Set the disabled state of the Host with +id+ to <tt>:enabled</tt>
diff --git a/src/app/views/host/edit_network.rhtml b/src/app/views/host/edit_network.rhtml
index 760f508..1154595 100644
--- a/src/app/views/host/edit_network.rhtml
+++ b/src/app/views/host/edit_network.rhtml
@@ -6,80 +6,543 @@
   Select and edit nics and bonded interfaces on <%= @host.hostname %>
 <%- end -%>
 
-<div id="select-host-nic" class="popup-content-selection">
-<%= select_with_label "NICs", "nic", "id",
-        @host.nics.
-          collect{ |nic| [nic.interface_name.to_s + " " + nic.mac, nic.id] }.
-          insert(0, "") %>
-</div>
 
-<div id="select-host-bonding" class="popup-content-selection">
-<%= select_with_label "Bonded Interfaces", "bonding", "id", [] %>
-</div>
+<form id="host_network_form" method="POST"
+      action="<%= url_for :action => 'update_network' %>" >
+
+<%= hidden_field_tag 'id', @host.id %>
+<div id="host_network_table">
+  <div class="host_network_table_row">
+     
+    <div class="host_network_table_device_column">
+      <b>Device</b>
+    </div>
+    <div class="host_network_table_network_column">
+      <b>Network</b>
+    </div>
+
+    <div style="clear:both;"></div>
+  </div>
+
+  <% @host.nics.each { |nic| %>
+   <div class="host_network_table_row" id="host_network_table_nic_<%= nic.id %>">
+     
+    <div class="host_network_table_device_column host_network_table_aligned_column">
+      <%= nic.interface_name + " " + nic.mac %>
+    </div>
+
+    <div class="host_network_table_network_column">
+      <select name="nics[<%= nic.id %>][network_id]"
+              id="host_network_table_select_net_nic_<%= nic.id %>"
+              class="host_network_table_select_net">
+
+       <option value="">Select a network...</option>
+       <% @networks.find_all { |net| net.type.to_s == 'PhysicalNetwork' }.each { |net| %>
+           <option value="<%= net.id %>"
+                   <% if net.id == nic.network_id %>selected<% end %> >
+              <%= net.name %>
+           </option>
+       <% } %>
+      </select>
+
+      <div class="host_network_table_subcolumn">
+           Ip Address:
+         <input type="text" name="nics[<%= nic.id %>][ip_address]"
+                value="<%= nic.ip_address if nic.ip_address %>">
+
+         </input>
+      </div>
+    </div>
+
+    <div class="host_network_table_buttons_column
+                host_network_table_aligned_column">
+      <div class="host_network_table_edit_column">
+        <%= image_tag("icon_edit_11px.png") %>
+      </div>
+    </div>
+
+    <div style="clear:both;"></div>
+   </div>
+  <% } %>
+
+  <% @host.bondings.each { |bonding| %>
+   <div class="host_network_table_row"
+        id="host_network_table_bonding_<%= bonding.id %>" >
+     
+    <div class="host_network_table_device_column host_network_table_aligned_column">
+     <div class="host_network_table_show_label">
+      <%= bonding.interface_name + " - " + bonding.bonding_type.label %>
+     </div>
+     <div class="host_network_table_edit_label" style="display: none;">
+       Name: <input type="text" name="bondings[<%= bonding.id %>][name]"
+                    value="<%= bonding.interface_name %>"/>
+     </div>
+
+      <div class="host_network_table_subcolumn">
+        <% bonding.nics.each { |nic| %>
+          <div class="host_network_table_subcolumn_row">
+               <%= nic.interface_name + " " + nic.mac %>
+          </div>
+        <% } %>
+
+        <% if bonding.nics.size == 0 %>
+             <i>No NICs associated</i>
+        <% end %>
+      </div>
+
+      <div class="host_network_table_subcolumn" style="display: none;">
+         NICs:
+         <select multiple name="bondings[<%= bonding.id %>][nic_ids][]"
+              id="host_network_table_select_nics_bonding_<%= bonding.id %>"
+              class="host_network_table_select_nics" >
+
+          <% @host.nics.each { |nic| %>
+             <option value="<%= nic.id %>"
+               <% if bonding.nics.all.find{ |n| n.id == nic.id } %>selected<%end%> >
+               <%= nic.interface_name %>
+             </option>
+          <% } %>
+         </select>
+      </div>
+
+    </div>
+
+    <div class="host_network_table_network_column">
+      <select name="bondings[<%= bonding.id %>[vlan_id]"
+              id="host_network_table_select_net_bonding_<%= bonding.id %>"
+              class="host_network_table_select_net" >
+
+          <option value="">Select a network...</option>
+          <% @networks.find_all { |net| net.type.to_s == 'Vlan' }.each { |net| %>
+              <option value="<%= net.id %>"
+                      <% if net.id == bonding.vlan_id %>selected<% end %> >
+                 <%= net.name %>
+              </option>
+          <% } %>
+      </select>
+
+      <div class="host_network_table_subcolumn">
+           Ip Address:
+         <input type="text"
+                name="bondings[<%= bonding.id %>][ip_address]"
+                value="<%= bonding.ip_address if bonding.ip_address %>" />
+      </div>
+
+      <div class="host_network_table_subcolumn" style="display: none;">
+           Bonding Type:
+         <select name="bondings[<%= bonding.id %>][bonding_type_id]">
+           <% @bonding_types.each { |bt| %>
+               <option value="<%= bt.id %>"
+                       <% if bt.id == bonding.bonding_type_id %>selected<% end %> >
+                  <%= bt.label %>
+               </option>
+           <% } %>
+         </select>
+      </div>
+    </div>
+
+    <div class="host_network_table_buttons_column host_network_table_aligned_column">
+      <div class="host_network_table_edit_column">
+        <%= image_tag("icon_edit_11px.png") %>
+      </div>
+      <div class="host_network_table_delete_column">
+        <%= image_tag("icon_delete_11px.png") %>
+      </div>
+    </div>
+
+    <div style="clear:both;"></div>
+   </div>
 
-<div style="clear: both;"></div>
 
-<div id="selected_nic_bonding" class="selected_popup_content"></div>
+  <% } %>
+
+  <%# create hidden row for new bondings, NBID will be replaced w/ New Bonding ID %>
+  <div class="host_network_table_row"
+       id="host_network_table_new_bondings"
+       style="display:none;">
+
+    <div class="host_network_table_device_column host_network_table_aligned_column">
+     <div class="host_network_table_edit_label">
+       Name: <input type="text" name="bondings[NBID][name]" value=""/>
+     </div>
+
+     <div class="host_network_table_subcolumn">
+        NICs:
+        <select multiple name="bondings[NBID][nic_ids][]"
+                         id="host_network_table_select_nics_bonding_NBID"
+                         class="host_network_table_select_nics">
+         <% @host.nics.each { |nic| %>
+             <option value="<%= nic.id %>"><%= nic.interface_name %></option>
+         <% } %>
+        </select>
+     </div>
+    </div>
+
+    <div class="host_network_table_network_column">
+      <select name="bondings[NBID][vlan_id]"
+              id="host_network_table_select_net_bonding_NBID"
+              class="host_network_table_select_net">
+          <option value="">Select a network...</option>
+          <% @networks.find_all { |net| net.type.to_s == "Vlan" }.each { |net| %>
+              <option value="<%= net.id %>" >
+                 <%= net.name %>
+              </option>
+          <% } %>
+      </select>
+
+      <div class="host_network_table_subcolumn" style="display: none;">
+           Ip Address:
+         <input type="text" name="bondings[NBID][ip_address]"/>
+      </div>
+
+      <div class="host_network_table_subcolumn">
+           Bonding Type:
+         <select name="bondings[NBID][bonding_type_id]">
+           <% @bonding_types.each { |bt| %>
+               <option value="<%= bt.id %>"><%= bt.label %></option>
+           <% } %>
+         </select>
+      </div>
+    </div>
+
+    <div class="host_network_table_buttons_column host_network_table_aligned_column">
+      <div class="host_network_table_edit_column">
+           
+      </div>
+      <div class="host_network_table_delete_column">
+        <%= image_tag("icon_delete_11px.png") %>
+      </div>
+    </div>
+
+    <div style="clear:both;"></div>
+  </div>
+
+  <div class="host_network_table_row" style="border-bottom: none; padding-top: 18px;" >
+     
+    <div class="host_network_table_buttons_column" id="host_network_table_add_bonding" >
+      <%= image_tag("icon_add_11px.png") %> New Bonded Interface
+    </div>
+    <div style="clear:both;"></div>
+  </div>
+
+</div>
 
 <div id="host_network_footer" class="popup-content-footer">
-  <%= ok_footer %>
+  <%= popup_footer("$('#host_network_form').submit()", "OK") %>
 </div>
+</form>
 
 <script type="text/javascript">
-function reset_nics_bonding_detail(){
-   var data='Select NIC or Bonded Interface<br/>';
-
-   $("#selected_nic_bonding").html(data);
-   $("#host_network_footer").show();
-};
-
-reset_nics_bonding_detail(); // run it once for inital content
-
-function reset_nics_select(){
-  $("#nic_id option:first").attr("selected", true);
-};
-
-function reset_bonding_select(){
-  // incase of new additions / deletions, repopulate select box
-  $.getJSON(
-     "<%= url_for :action => 'bondings_json', :id => @host.id %>",
-      {},
-      function(j){
-        var options = "<option value=''></option>" +
-                      "<option value='New'>New</option>";
-        for(var i = 0; i < j.length; i++){
-          options += '<option value="' + j[i].id + '">' + j[i].name +
-                     '</option>';
+  // create list of networks
+  var networks = new Array();
+  <% @networks.each { |rnet|  %>
+    jnet = new Object;
+    jnet.id = <%= rnet.id.to_s %>;
+    jnet.static_ip  = <%= rnet.boot_type.proto == 'static' %>;
+    jnet.boot_type  = "<%= rnet.boot_type.proto %>";
+    jnet.selected = false;
+    networks.push(jnet);
+  <% } %>
+
+  // the last network selected upon clicking a network select box
+  var last_network_selected = null;
+
+  // create list of devices...
+  var devices = new Array();
+
+  // ...add nics to it
+  <% @host.nics.each { |rnic| %>
+    jnic = new Object;
+    jnic.type = 'nic';
+    jnic.id   = <%= rnic.id.to_s %>;
+    jnic.ip_address = "<%= rnic.ip_address ? rnic.ip_address : "" %>";
+    jnic.network_id = "<%= rnic.network_id %>";
+    devices.push(jnic);
+  <% } %>
+
+  // ...add bondings to it
+  <% @host.bondings.each { |rbond| %>
+    jbond = new Object;
+    jbond.type = 'bonding';
+    jbond.id   = <%= rbond.id.to_s %>;
+    jbond.ip_address = "<%= rbond.ip_address ? rbond.ip_address : "" %>";
+    jbond.network_id = "<%= rbond.vlan_id %>";
+    jbond.nics = [];
+    devices.push(jbond);
+  <% } %>
+
+  // generate an id greater than any the host currently has,
+  var current_device_id = 1;
+  for(j = 0; j < devices.length; ++j){
+     if(devices[j].id >= current_device_id){
+      current_device_id = devices[j].id + 1;
+    }
+  }
+
+  // find network in networks array matching id
+  function find_network_by_id(network_id){
+      for(j = 0; j < networks.length; ++j){
+        if(networks[j].id == network_id){
+           return networks[j];
         }
-        $("#bonding_id").html(options);
-      });
-
-  $("#bonding_id option:first").attr("selected", true);
-};
-
-reset_bonding_select(); // run it once for initial content
-
-$("#nic_id").change(function () {
-  reset_bonding_select();
-  if($('#nic_id').val() != ""){
-    $("#selected_nic_bonding").load("<%= url_for :controller => 'network',
-        :action => 'edit_nic'%>/" + $('#nic_id').val());
-    $("#host_network_footer").hide();
-  }else{
-     reset_nics_bonding_detail();
+      }
+      return null;
+  }
+
+  // parses device type out of a div id
+  function device_type_from_div_id(div_id){
+    div_id = div_id.replace("host_network_table_", "");
+    delim  = div_id.search("_");
+    result = div_id.substr(0, delim);
+    return result;
+  }
+
+  // parses device id out of a div id
+  function device_id_from_div_id(div_id){
+    div_id = div_id.replace("host_network_table_", "");
+    delim  = div_id.search("_");
+    result = div_id.substr(delim+1);
+    return result;
   }
-});
-
-$("#bonding_id").change(function () {
-  reset_nics_select();
-  if($('#bonding_id').val() == "New"){
-      $("#selected_nic_bonding").load("<%= url_for :controller => 'network', :action => 'new_bonding', :host_id => @host.id %>");
-    $("#host_network_footer").hide();
-  }else if($('#bonding_id').val() != ""){
-      $("#selected_nic_bonding").load("<%= url_for :controller => 'network', :action => 'edit_bonding'%>/" + $('#bonding_id').val());
-    $("#host_network_footer").hide();
-  }else{
-     reset_nics_bonding_detail();
+
+  // find a device from a div id, searches devices array
+  // for device type/id pulled from the div id
+  function find_device(div_id){
+    device_type = device_type_from_div_id(div_id);
+    device_id   = device_id_from_div_id(div_id);
+
+     for(j = 0; j < devices.length; ++j){
+       if(devices[j].type == device_type &&
+          devices[j].id == device_id){
+            return devices[j];
+       }
+     }
+     return null;
+  }
+
+  // delete device specified by the given div id
+  function delete_device(div_id){
+    device_type = device_type_from_div_id(div_id);
+    device_id   = device_id_from_div_id(div_id);
+
+    index_to_delete = -1;
+    for(j = 0; j < devices.length; ++j){
+      if(devices[j].type == device_type &&
+         devices[j].id == device_id){
+           index_to_delete = j;
+           break;
+      }
+    }
+
+    if(index_to_delete != -1){
+       devices.splice(index_to_delete, 1);
+       return true;
+    }
+
+     return false;
+  }
+
+  // store currently selected network on select box clicked
+  // parameter should be the select box changed event
+  function on_network_select_box_clicked(e){
+    last_network_selected = find_network_by_id(e.target.value);
   }
-});
+
+  // modify table upon network select box changing
+  // parameter should be the select box changed event
+  function on_network_select_box_changed(e){
+    // find network selected
+    network = find_network_by_id(e.target.value)
+
+    // parse device out of row and set corresponding network id
+    device = find_device($(e.target).parent().parent()[0].id);
+    if(device != null){
+       device.network_id = e.target.value;
+    }
+
+    // mark network as selected, last net as unselected, and add/remove
+    // from other select boxes if appropriate
+    if(network != null){
+       network.selected = true;
+       $('.host_network_table_select_net:not(#host_network_table_select_net_'+
+           device.type+'_'+device.id+') option[@value='+network.id+']').hide();
+    }
+    if(last_network_selected != null){
+       last_network_selected.selected = false;
+       $('.host_network_table_select_net ' +
+         ' option[@value='+last_network_selected.id+']').show();
+    }
+
+    // for static ip networks show editable ip address textbox
+    if(network != null && network.static_ip){
+      div = $(e.target).next('.host_network_table_subcolumn');
+      div.show();
+      div.children("input").removeAttr("disabled");
+
+      // grab value of address field from device
+      address = device ? device.ip_address : "";
+      div.children("input").val(address);
+
+    // for non-static networks disable/hide ip address textbox
+    }else{
+      div = $(e.target).next('.host_network_table_subcolumn');
+      div.hide();
+      div.children("input").attr("disabled", true);
+      div.children("input").val(network ? network.boot_type : "Select network");
+    }
+  }
+
+  // modify table upon nics select box changing
+  // parameter should be the select box changed event
+  function on_nics_select_box_changed(e){
+     // parse device out of row
+     device = find_device($(e.target).parent().parent().parent()[0].id);
+     if(device != null){
+       device.nics = [];
+     }
+
+     // hide selected attributes in all other selectboxes
+     $(e.target).children('option:selected').each(function(i){
+         $('.host_network_table_select_nics:not(#host_network_table_select_nics_'+
+             device.type+'_'+device.id+') option[@value='+this.value+']').hide();
+         device.nics.push(this.value);
+     });
+
+     $(e.target).children('option:not(:selected):not(:hidden)').each(function(e){
+         $('.host_network_table_select_nics '+
+           ' option[@value='+this.value+']').show();
+     });
+  }
+
+  // modify a row upon clicking the edit button
+  // toggles the visibility of various columns
+  // parameter should be the button img clicked event
+  function on_edit_button_clicked(e){
+     // network column input fields
+     div = $(e.target).parent().parent().
+            prev().children('.host_network_table_subcolumn');
+
+     // bring ip address column in line w/
+     // other columns if applicable (bit of a hack
+     // to fix problem if ip address field is shown
+     // when edit button is clicked to edit)
+     if(div.size() == 2){
+       if($(div[1]).is(":visible")){
+          $(div[0]).show();
+       }else{
+          $(div[0]).hide();
+       }
+     }
+
+     // toggle network column inputs visibility
+     div.toggle();
+
+     // toggle show/edit label divs
+     div = $(e.target).parent().parent().
+            prev().prev();
+     div.children('.host_network_table_edit_label').toggle();
+     div.children('.host_network_table_show_label').toggle();
+
+     // toggle show/edit nics divs
+     div = $(e.target).parent().parent().
+            prev().prev().children('.host_network_table_subcolumn');
+     div.toggle();
+  }
+
+  // delete when upon clicking the delete button
+  // parameters should be the button img clicked event
+  function on_delete_button_clicked(e){
+     // mark network/nics as available
+     device = find_device($(e.target).parent().parent().parent()[0].id);
+     $('.host_network_table_select_net ' +
+       ' option[@value='+device.network_id+']').show();
+     for(j = 0; j < device.nics.length; ++j){
+       $('.host_network_table_select_nics '+
+         ' option[@value='+device.nics[j]+']').show();
+     }
+
+     // delete device given by row id
+     delete_device($(e.target).parent().parent().parent()[0].id);
+
+     // delete row which button is on
+     $(e.target).parent().parent().parent().remove();
+  }
+
+  // add new row to table using template when add new bonding button is clicked
+  // parameters should be the button div clicked event
+  function on_add_bonding_button_clicked(e){
+     // create new bonding device
+     jbond = new Object;
+     jbond.type = 'bonding';
+     jbond.id   = current_device_id++;
+     jbond.ip_address = "";
+     jbond.network_id = "";
+     jbond.nics = [];
+     devices.push(jbond);
+
+     // find and copy the new bonding template, append it as a new row
+     div = $("#host_network_table_new_bondings")
+     content = '<div class="host_network_table_row"'+
+                     'id="host_network_table_bonding_'+jbond.id+'">'+
+                         div.html().replace(/NBID/g, jbond.id)+
+               '</div>';
+     div.before(content);
+     // set div id ?
+  }
+
+  // wire up host_network_form when document is ready
+  function on_document_ready(){
+    var opts = {
+      target: '<%= url_for :action => 'update_network' %>',   // target element to update
+      dataType:      'json',
+      success:  function(response, status) {
+        ajax_validation(response, status)
+          if (response.success) {
+           jQuery(document).trigger('close.facebox');
+           $("#hosts_grid").flexReload()
+           refresh_summary('hosts_selection',
+                           '<%= url_for :controller => "host",
+                                        :action => "show" %>',
+                           <%= @host.id %>)
+        }
+      }
+    };
+
+    // bind form using 'ajaxForm'
+    $('#host_network_form').ajaxForm(opts);
+  }
+
+  // handle network select box clicked event
+  $(".host_network_table_select_net").
+     livequery('click', on_network_select_box_clicked).
+     bind('click', on_network_select_box_clicked);
+
+  // handle network select box changed event
+  $(".host_network_table_select_net").
+     livequery('change', on_network_select_box_changed).
+     bind('change', on_network_select_box_changed).
+     trigger('change');
+
+  // handle nics select box changed event
+  $(".host_network_table_select_nics").
+     livequery('change', on_nics_select_box_changed).
+     bind('change', on_nics_select_box_changed).
+     trigger('change');
+
+  // when edit button is clicked
+  $(".host_network_table_edit_column img").
+     bind('click', on_edit_button_clicked);
+
+  // when delete button is clicked
+  $(".host_network_table_delete_column img").
+     livequery("click", on_delete_button_clicked).
+     bind('click', on_delete_button_clicked);
+
+  // when add bonding button is click
+  $("#host_network_table_add_bonding").
+     bind("click", on_add_bonding_button_clicked);
+
+  // when the document is ready
+  $(on_document_ready);
+
 </script>
diff --git a/src/public/stylesheets/components.css b/src/public/stylesheets/components.css
index 2cda65d..b973b3b 100644
--- a/src/public/stylesheets/components.css
+++ b/src/public/stylesheets/components.css
@@ -389,3 +389,79 @@
 #vm_network_config_add:hover {
   cursor: pointer;
 }
+
+
+/* Host > Edit Network Configuration */
+
+#host_network_table {
+  padding-top:  20px;
+  padding-left: 20px;
+  padding-bottom: 20px;
+  width: 93%;
+}
+
+.host_network_table_row {
+  padding-top:    5px;
+  padding-bottom: 5px;
+  border-bottom: 1px solid gray;
+}
+
+.host_network_table_device_column {
+  float: left;
+  width: 37%;
+}
+
+.host_network_table_network_column {
+  float: left;
+  width: 49%;
+}
+
+.host_network_table_subcolumn {
+  margin-top: 4px;
+}
+
+.host_network_table_subcolumn input {
+  margin-top: 4px;
+  text-align: right;
+  width: 140px;
+}
+
+.host_network_table_buttons_column {
+  float: left;
+  width: 8%;
+}
+
+.host_network_table_buttons_column img {
+  cursor: pointer;
+}
+
+.host_network_table_select_net {
+  min-width: 230px;
+}
+
+.host_network_table_select_nics {
+  min-width: 160px;
+}
+
+.host_network_table_edit_column,
+.host_network_table_delete_column {
+  padding-top: 7px;
+  padding-left: 5px;
+  float: left;
+}
+
+.host_network_table_show_label {
+  padding-top: 7px;
+}
+
+.host_network_table_edit_label input {
+  width: 110px;
+}
+
+#host_network_table_add_bonding {
+  border: 1px solid black;
+  padding: 5px;
+  width: 150px;
+  cursor: pointer;
+}
+/* ***** */
-- 
1.6.0.6




More information about the ovirt-devel mailing list