[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