[Ovirt-devel] [PATCH] Enables the generation of a configuration file for a managed node.
Darryl L. Pierce
dpierce at redhat.com
Tue Aug 19 15:26:36 UTC 2008
The configuration is generated from the contents of the nics table. The
managed node then downloads that configuration after completing the
identification and applies those changes.
Signed-off-by: Darryl L. Pierce <dpierce at redhat.com>
---
ovirt-managed-node/src/gather.c | 2 +
ovirt-managed-node/src/ovirt-identify-node.h | 1 +
ovirt-managed-node/src/protocol.c | 3 +-
wui/src/app/controllers/application.rb | 2 +-
wui/src/app/controllers/nic_controller.rb | 13 +-
wui/src/config/environment.rb | 2 +
wui/src/db/migrate/015_add_iface_name_to_nics.rb | 9 +
wui/src/host-browser/host-browser.rb | 582 ++++++++++----------
wui/src/host-browser/test-host-browser-identify.rb | 490 +++++++++--------
wui/src/lib/managed_node_configuration.rb | 49 ++
.../test/unit/managed_node_configuration_test.rb | 87 +++
11 files changed, 706 insertions(+), 534 deletions(-)
create mode 100644 wui/src/db/migrate/015_add_iface_name_to_nics.rb
create mode 100644 wui/src/lib/managed_node_configuration.rb
create mode 100644 wui/src/test/unit/managed_node_configuration_test.rb
diff --git a/ovirt-managed-node/src/gather.c b/ovirt-managed-node/src/gather.c
index 39be6fd..7fa0992 100644
--- a/ovirt-managed-node/src/gather.c
+++ b/ovirt-managed-node/src/gather.c
@@ -205,6 +205,8 @@ get_nic_data(char *nic, nic_info_ptr nic_info)
interface =
libhal_device_get_property_string(hal_ctx, nic, "net.interface",
&dbus_error);
+ snprintf(nic_info->interface_name, BUFFER_LENGTH, "%s", interface);
+
bzero(&ifr, sizeof(struct ifreq));
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
diff --git a/ovirt-managed-node/src/ovirt-identify-node.h b/ovirt-managed-node/src/ovirt-identify-node.h
index c595891..b2814fa 100644
--- a/ovirt-managed-node/src/ovirt-identify-node.h
+++ b/ovirt-managed-node/src/ovirt-identify-node.h
@@ -67,6 +67,7 @@ typedef struct _nic_info {
char mac_address[BUFFER_LENGTH];
char bandwidth[BUFFER_LENGTH];
char ip_address[BUFFER_LENGTH];
+ char interface_name[BUFFER_LENGTH];
struct _nic_info* next;
} t_nic_info;
diff --git a/ovirt-managed-node/src/protocol.c b/ovirt-managed-node/src/protocol.c
index 131bb38..d5c5fac 100644
--- a/ovirt-managed-node/src/protocol.c
+++ b/ovirt-managed-node/src/protocol.c
@@ -181,7 +181,8 @@ send_nic_details(void)
if (!(get_text("NICINFO?")) &&
(!send_value("MAC", current->mac_address)) &&
- (!send_value("BANDWIDTH", current->bandwidth))) {
+ (!send_value("BANDWIDTH", current->bandwidth)) &&
+ (!send_value("IFACE_NAME", current->interface_name))) {
send_text("ENDNIC");
result = get_text("ACK NIC");
}
diff --git a/wui/src/app/controllers/application.rb b/wui/src/app/controllers/application.rb
index d653171..b27ddbe 100644
--- a/wui/src/app/controllers/application.rb
+++ b/wui/src/app/controllers/application.rb
@@ -35,7 +35,7 @@ class ApplicationController < ActionController::Base
before_filter :is_logged_in
def is_logged_in
- redirect_to (:controller => "login", :action => "login") unless get_login_user
+ redirect_to(:controller => "login", :action => "login") unless get_login_user
end
def get_login_user
diff --git a/wui/src/app/controllers/nic_controller.rb b/wui/src/app/controllers/nic_controller.rb
index 85d4315..fef7c5b 100644
--- a/wui/src/app/controllers/nic_controller.rb
+++ b/wui/src/app/controllers/nic_controller.rb
@@ -18,9 +18,10 @@
# also available at http://www.gnu.org/copyleft/gpl.html.
class NicController < ApplicationController
+ after_filter :generate_configuration, :only => [:create, :edit, :update, :destroy]
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
- :redirect_to => { :controller => 'dashboard' }
+ :redirect_to => { :controller => 'dashboard' }
def show
set_perms(@perm_obj)
@@ -44,8 +45,18 @@ class NicController < ApplicationController
def destroy
end
+
+ def generate_configuration
+ host = Host.find_by_id(params[:host_id])
+
+ File.open("#{MANAGED_NODE_CONFIGURATION_DIR}/#{host.hostname}", "w") do |file|
+ # write the nic configuration
+ file.puts ManagedNodeConfiguration.generate(host)
+ end
+ end
private
+
#filter methods
def pre_new
flash[:notice] = 'Network Interfaces may not be edited via the web UI'
diff --git a/wui/src/config/environment.rb b/wui/src/config/environment.rb
index ff6f6e8..57fd461 100644
--- a/wui/src/config/environment.rb
+++ b/wui/src/config/environment.rb
@@ -80,3 +80,5 @@ end
require 'gettext/rails'
gem 'cobbler'
require 'cobbler'
+
+MANAGED_NODE_CONFIGURATION_DIR = '/var/www/html/ovirt-cfgdb'
\ No newline at end of file
diff --git a/wui/src/db/migrate/015_add_iface_name_to_nics.rb b/wui/src/db/migrate/015_add_iface_name_to_nics.rb
new file mode 100644
index 0000000..f1fb28d
--- /dev/null
+++ b/wui/src/db/migrate/015_add_iface_name_to_nics.rb
@@ -0,0 +1,9 @@
+class AddIfaceNameToNics < ActiveRecord::Migration
+ def self.up
+ add_column :nics, :iface_name, :string, :limit => 10
+ end
+
+ def self.down
+ remove_column :nics, :iface_name
+ end
+end
diff --git a/wui/src/host-browser/host-browser.rb b/wui/src/host-browser/host-browser.rb
index 881b2ae..26981fd 100755
--- a/wui/src/host-browser/host-browser.rb
+++ b/wui/src/host-browser/host-browser.rb
@@ -39,361 +39,369 @@ $logfile = '/var/log/ovirt-wui/host-browser.log'
# about the node and then updates the list of active nodes for the WUI.
#
class HostBrowser
- attr_accessor :logfile
- attr_accessor :keytab_dir
- attr_accessor :keytab_filename
-
- def initialize(session)
- @session = session
- @log_prefix = "[#{session.peeraddr[3]}] "
- @keytab_dir = '/usr/share/ipa/html/'
- end
-
- # Ensures the conversation starts properly.
- #
- def begin_conversation
- puts "#{@log_prefix} Begin conversation" unless defined?(TESTING)
- @session.write("HELLO?\n")
-
- response = @session.readline.chomp
- raise Exception.new("received #{response}, expected HELLO!") unless response == "HELLO!"
- end
-
- # Retrieves the mode request from the remote system.
- #
- def get_mode
- puts "#{@log_prefix} Determining the runtime mode." unless defined?(TESTING)
- @session.write("MODE?\n")
- response = @session.readline.chomp
- puts "#{@log_prefix} MODE=#{response}" unless defined?(TESTING)
+ attr_accessor :logfile
+ attr_accessor :keytab_dir
+ attr_accessor :keytab_filename
+
+ def initialize(connection)
+ @connection = connection
+ @log_prefix = "[#{connection.peeraddr[3]}] "
+ @keytab_dir = '/usr/share/ipa/html/'
+ end
+
+ # Ensures the conversation starts properly.
+ #
+ def begin_conversation
+ puts "#{@log_prefix} Begin conversation" unless defined?(TESTING)
+ @connection.write("HELLO?\n")
+
+ response = @connection.readline.chomp
+ raise Exception.new("received #{response}, expected HELLO!") unless response == "HELLO!"
+ end
+
+ # Retrieves the mode request from the remote system.
+ #
+ def get_mode
+ puts "#{@log_prefix} Determining the runtime mode." unless defined?(TESTING)
+ @connection.write("MODE?\n")
+ response = @connection.readline.chomp
+ puts "#{@log_prefix} MODE=#{response}" unless defined?(TESTING)
+
+ response
+ end
+
+ # Requests node information from the remote system.
+ #
+ def get_remote_info
+ puts "#{@log_prefix} Begin remote info collection" unless defined?(TESTING)
+ result = Hash.new
+ result['HOSTNAME'] = @connection.peeraddr[2]
+ result['IPADDR'] = @connection.peeraddr[3]
+
+ @connection.write("INFO?\n")
+
+ loop do
+ info = @connection.readline.chomp
+
+ puts "Received info='#{info}'"
+
+ break if info == "ENDINFO"
+
+ case info
+ when "CPU"
+ cpu = get_cpu_info
+ cpu_info = result['CPUINFO']
+
+ if(cpu_info == nil)
+ cpu_info = Array.new
+ result['CPUINFO'] = cpu_info
+ end
- response
- end
+ cpu_info << cpu
+
+ when "NIC"
+ nic = get_nic_info
+ nic_info = result['NICINFO']
- # Requests node information from the remote system.
- #
- def get_remote_info
- puts "#{@log_prefix} Begin remote info collection" unless defined?(TESTING)
- result = Hash.new
- result['HOSTNAME'] = @session.peeraddr[2]
- result['IPADDR'] = @session.peeraddr[3]
+ if(nic_info == nil)
+ nic_info = Array.new
+ result['NICINFO'] = nic_info
+ end
- @session.write("INFO?\n")
+ nic_info << nic
+
+ else
+ raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/
- loop do
- info = @session.readline.chomp
+ key, value = info.split("=")
- puts "Received info='#{info}'"
+ puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
+ result[key] = value
- break if info == "ENDINFO"
+ @connection.write("ACK #{key}\n")
+ end
+ end
- case info
- when "CPU"
- cpu = get_cpu_info
- cpu_info = result['CPUINFO']
+ return result
+ end
- if(cpu_info == nil)
- cpu_info = Array.new
- result['CPUINFO'] = cpu_info
- end
+ # Extracts CPU details from the managed node.
+ #
+ def get_cpu_info
+ puts "Begin receiving CPU details"
- cpu_info << cpu
- when "NIC"
- nic = get_nic_info
- nic_info = result['NICINFO']
+ result = Hash.new
- if(nic_info == nil)
- nic_info = Array.new
- result['NICINFO'] = nic_info
- end
+ @connection.write("CPUINFO?\n")
- nic_info << nic
- else
+ loop do
+ info = @connection.readline.chomp
- raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/
+ break if info == "ENDCPU"
- key, value = info.split("=")
+ raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/
- puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
- result[key] = value
+ key, value = info.split("=")
- @session.write("ACK #{key}\n")
- end
- end
+ puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
+ result[key] = value
- return result
+ @connection.write("ACK #{key}\n")
end
- # Extracts CPU details from the managed node.
- #
- def get_cpu_info
- puts "Begin receiving CPU details"
+ @connection.write("ACK CPU\n");
- result = Hash.new
+ return result
+ end
- @session.write("CPUINFO?\n")
+ # Extracts NIC details from the managed node.
+ #
+ def get_nic_info
+ puts "Begin receiving NIC details"
- loop do
- info = @session.readline.chomp
+ result = Hash.new
- break if info == "ENDCPU"
+ @connection.write("NICINFO?\n")
- raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/
+ loop do
+ info = @connection.readline.chomp
- key, value = info.split("=")
+ break if info == "ENDNIC"
- puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
- result[key] = value
+ raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/
- @session.write("ACK #{key}\n")
- end
+ key, value = info.split("=")
- @session.write("ACK CPU\n");
+ puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
+ result[key] = value
- return result
+ @connection.write("ACK #{key}\n")
end
- # Extracts NIC details from the managed node.
- #
- def get_nic_info
- puts "Begin receiving NIC details"
-
- result = Hash.new
-
- @session.write("NICINFO?\n")
+ @connection.write("ACK NIC\n");
+
+ return result
+ end
+
+ # Writes the supplied host information to the database.
+ #
+ def write_host_info(host_info)
+ ensure_present(host_info,'HOSTNAME')
+ ensure_present(host_info,'ARCH')
+ ensure_present(host_info,'MEMSIZE')
+ ensure_present(host_info,'CPUINFO')
+ ensure_present(host_info,'NICINFO')
+
+ cpu_info = host_info['CPUINFO']
+ nic_info = host_info['NICINFO']
+
+ cpu_info.each do |cpu|
+ ensure_present(cpu,'CPUNUM')
+ ensure_present(cpu,'CORENUM')
+ ensure_present(cpu,'NUMCORES')
+ ensure_present(cpu,'VENDOR')
+ ensure_present(cpu,'MODEL')
+ ensure_present(cpu,'FAMILY')
+ ensure_present(cpu,'CPUIDLVL')
+ ensure_present(cpu,'SPEED')
+ ensure_present(cpu,'CACHE')
+ ensure_present(cpu,'FLAGS')
+ end
+
+ nic_info.each do |nic|
+ ensure_present(nic, 'MAC')
+ ensure_present(nic, 'BANDWIDTH')
+ ensure_present(nic, 'IFACE_NAME')
+ end
- loop do
- info = @session.readline.chomp
+ puts "Searching for existing host record..." unless defined?(TESTING)
+ host = Host.find(:first, :conditions => ["hostname = ?", host_info['HOSTNAME']])
+
+ if host == nil
+ begin
+ puts "Creating a new record for #{host_info['HOSTNAME']}..." unless defined?(TESTING)
+
+ host = Host.create(
+ "uuid" => host_info['UUID'],
+ "hostname" => host_info['HOSTNAME'],
+ "hypervisor_type" => host_info['HYPERVISOR_TYPE'],
+ "arch" => host_info['ARCH'],
+ "memory" => host_info['MEMSIZE'],
+ "is_disabled" => 0,
+ "hardware_pool" => HardwarePool.get_default_pool,
+ # Let host-status mark it available when it
+ # successfully connects to it via libvirt.
+ "state" => Host::STATE_UNAVAILABLE)
+ rescue Exception => error
+ puts "Error while creating record: #{error.message}" unless defined?(TESTING)
+ end
+ else
+ host.uuid = host_info['UUID']
+ host.hostname = host_info['HOSTNAME']
+ host.arch = host_info['ARCH']
+ host.memory = host_info['MEMSIZE']
+ end
- break if info == "ENDNIC"
+ # delete an existing CPUs and create new ones based on the data
+ puts "Deleting any existing CPUs"
+ Cpu.delete_all(['host_id = ?', host.id])
+
+ puts "Saving new CPU records"
+ cpu_info.collect do |cpu|
+ detail = Cpu.new(
+ "cpu_number" => cpu['CPUNUM'],
+ "core_number" => cpu['CORENUM]'],
+ "number_of_cores" => cpu['NUMCORES'],
+ "vendor" => cpu['VENDOR'],
+ "model" => cpu['MODEL'],
+ "family" => cpu['FAMILY'],
+ "cpuid_level" => cpu['CPUIDLVL'],
+ "speed" => cpu['SPEED'],
+ "cache" => cpu['CACHE'],
+ "flags" => cpu['FLAGS'])
+
+ host.cpus << detail
+ end
- raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/
+ # Update the NIC details for this host:
+ # -if the NIC exists, then update the IP address
+ # -if the NIC does not exist, create it
+ # -any nic not in this list is deleted
- key, value = info.split("=")
+ puts "Updating NIC records for the node"
+ nics = Array.new
- puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
- result[key] = value
+ host.nics.collect do |nic|
+ found = false
- @session.write("ACK #{key}\n")
+ nic_info.collect do |detail|
+ # if we have a match, then update the database and remove
+ # the received data to avoid creating a dupe later
+ if detail['MAC'] == nic.mac
+ nic_info.delete(detail)
end
+ end
- @session.write("ACK NIC\n");
-
- return result
+ # if the record wasn't found, then remove it from the database
+ unless found
+ host.nics.delete(nic)
+ nic.destroy
+ end
end
- # Writes the supplied host information to the database.
- #
- def write_host_info(host_info)
- ensure_present(host_info,'HOSTNAME')
- ensure_present(host_info,'ARCH')
- ensure_present(host_info,'MEMSIZE')
- ensure_present(host_info,'CPUINFO')
- ensure_present(host_info,'NICINFO')
-
- cpu_info = host_info['CPUINFO']
- nic_info = host_info['NICINFO']
-
- cpu_info.each do |cpu|
- ensure_present(cpu,'CPUNUM')
- ensure_present(cpu,'CORENUM')
- ensure_present(cpu,'NUMCORES')
- ensure_present(cpu,'VENDOR')
- ensure_present(cpu,'MODEL')
- ensure_present(cpu,'FAMILY')
- ensure_present(cpu,'CPUIDLVL')
- ensure_present(cpu,'SPEED')
- ensure_present(cpu,'CACHE')
- ensure_present(cpu,'FLAGS')
- end
+ # iterate over any nics left and create new records for them.
- puts "Searching for existing host record..." unless defined?(TESTING)
- host = Host.find(:first, :conditions => ["hostname = ?", host_info['HOSTNAME']])
-
- if host == nil
- begin
- puts "Creating a new record for #{host_info['HOSTNAME']}..." unless defined?(TESTING)
-
- host = Host.create(
- "uuid" => host_info['UUID'],
- "hostname" => host_info['HOSTNAME'],
- "hypervisor_type" => host_info['HYPERVISOR_TYPE'],
- "arch" => host_info['ARCH'],
- "memory" => host_info['MEMSIZE'],
- "is_disabled" => 0,
- "hardware_pool" => HardwarePool.get_default_pool,
- # Let host-status mark it available when it
- # successfully connects to it via libvirt.
- "state" => Host::STATE_UNAVAILABLE)
- rescue Exception => error
- puts "Error while creating record: #{error.message}" unless defined?(TESTING)
- end
- else
- host.uuid = host_info['UUID']
- host.hostname = host_info['HOSTNAME']
- host.arch = host_info['ARCH']
- host.memory = host_info['MEMSIZE']
- end
+ nic_info.collect do |nic|
+ puts "Creating a new nic..."
+ detail = Nic.new(
+ 'mac' => nic['MAC'],
+ 'bandwidth' => nic['BANDWIDTH'],
+ 'iface_name' => nic['IFACE_NAME'],
+ 'usage_type' => 1)
- # delete an existing CPUs and create new ones based on the data
- puts "Deleting any existing CPUs"
- Cpu.delete_all(['host_id = ?', host.id])
-
- puts "Saving new CPU records"
- cpu_info.collect do |cpu|
- detail = Cpu.new(
- "cpu_number" => cpu['CPUNUM'],
- "core_number" => cpu['CORENUM]'],
- "number_of_cores" => cpu['NUMCORES'],
- "vendor" => cpu['VENDOR'],
- "model" => cpu['MODEL'],
- "family" => cpu['FAMILY'],
- "cpuid_level" => cpu['CPUIDLVL'],
- "speed" => cpu['SPEED'],
- "cache" => cpu['CACHE'],
- "flags" => cpu['FLAGS'])
-
- host.cpus << detail
- end
-
- # Update the NIC details for this host:
- # -if the NIC exists, then update the IP address
- # -if the NIC does not exist, create it
- # -any nic not in this list is deleted
-
- puts "Updating NIC records for the node"
- nics = Array.new
-
- host.nics.collect do |nic|
- found = false
-
- nic_info.collect do |detail|
- # if we have a match, then update the database and remove
- # the received data to avoid creating a dupe later
- if detail['MAC'] == nic.mac
- nic_info.delete(detail)
- end
- end
-
- # if the record wasn't found, then remove it from the database
- unless found
- host.nics.delete(nic)
- nic.destroy
- end
- end
-
- # iterate over any nics left and create new records for them.
-
- nic_info.collect do |nic|
- puts "Creating a new nic..."
- detail = Nic.new(
- 'mac' => nic['MAC'],
- 'bandwidth' => nic['BANDWIDTH'],
- 'usage_type' => 1)
+ host.nics << detail
+ end
- host.nics << detail
- end
+ host.save!
- host.save!
+ return host
+ end
- return host
- end
+ # Creates a keytab if one is needed, returning the filename.
+ #
+ def create_keytab(hostname, ipaddress, krb5_arg = nil)
+ krb5 = krb5_arg || Krb5.new
- # Creates a keytab if one is needed, returning the filename.
- #
- def create_keytab(hostname, ipaddress, krb5_arg = nil)
- krb5 = krb5_arg || Krb5.new
+ default_realm = krb5.get_default_realm
+ libvirt_princ = 'libvirt/' + hostname + '@' + default_realm
+ outfile = ipaddress + '-libvirt.tab'
+ @keytab_filename = @keytab_dir + outfile
- default_realm = krb5.get_default_realm
- libvirt_princ = 'libvirt/' + hostname + '@' + default_realm
- outfile = ipaddress + '-libvirt.tab'
- @keytab_filename = @keytab_dir + outfile
+ # TODO need a way to test this portion
+ unless (defined? TESTING) || File.exists?(@keytab_filename)
+ # TODO replace with Kr5Auth when it supports admin actions
+ puts "Writing keytab file: #{@keytab_filename}" unless defined?(TESTING)
+ kadmin_local('addprinc -randkey ' + libvirt_princ)
+ kadmin_local('ktadd -k ' + @keytab_filename + ' ' + libvirt_princ)
- # TODO need a way to test this portion
- unless (defined? TESTING) || File.exists?(@keytab_filename)
- # TODO replace with Kr5Auth when it supports admin actions
- puts "Writing keytab file: #{@keytab_filename}" unless defined?(TESTING)
- kadmin_local('addprinc -randkey ' + libvirt_princ)
- kadmin_local('ktadd -k ' + @keytab_filename + ' ' + libvirt_princ)
+ File.chmod(0644, at keytab_filename)
+ end
- File.chmod(0644, at keytab_filename)
- end
+ hostname = `hostname -f`.chomp
- hostname = `hostname -f`.chomp
+ @connection.write("KTAB http://#{hostname}/ipa/config/#{outfile}\n")
- @session.write("KTAB http://#{hostname}/ipa/config/#{outfile}\n")
+ response = @connection.readline.chomp
- response = @session.readline.chomp
+ raise Exception.new("ERRINFO! No keytab acknowledgement") unless response == "ACK"
+ end
- raise Exception.new("ERRINFO! No keytab acknowledgement") unless response == "ACK"
- end
+ # Ends the conversation, notifying the user of the key version number.
+ #
+ def end_conversation
+ puts "#{@log_prefix} Ending conversation" unless defined?(TESTING)
- # Ends the conversation, notifying the user of the key version number.
- #
- def end_conversation
- puts "#{@log_prefix} Ending conversation" unless defined?(TESTING)
+ @connection.write("BYE\n");
+ end
- @session.write("BYE\n");
- end
+ private
- private
+ # Private method to ensure that a required field is present.
+ #
+ def ensure_present(info,key)
+ raise Exception.new("ERROR! Missing '#{key}'...") if info[key] == nil
+ end
- # Private method to ensure that a required field is present.
- #
- def ensure_present(info,key)
- raise Exception.new("ERROR! Missing '#{key}'...") if info[key] == nil
- end
-
- # Executes an external program to support the keytab function.
- #
- def kadmin_local(command)
- system("/usr/kerberos/sbin/kadmin.local -q '" + command + "'")
- end
+ # Executes an external program to support the keytab function.
+ #
+ def kadmin_local(command)
+ system("/usr/kerberos/sbin/kadmin.local -q '" + command + "'")
+ end
end
def entry_point(server)
- while(session = server.accept)
- child = fork do
- remote = session.peeraddr[2]
-
- puts "Connected to #{remote}" unless defined?(TESTING)
-
- # This is needed because we just forked a new process
- # which now needs its own connection to the database.
- database_connect
+ while(session = server.accept)
+ child = fork do
+ remote = session.peeraddr[2]
- begin
- browser = HostBrowser.new(session)
+ puts "Connected to #{remote}" unless defined?(TESTING)
- browser.begin_conversation
- case browser.get_mode
- when "AWAKEN": browser.create_keytab(remote,session.peeraddr[3])
- when "IDENTIFY": browser.write_host_info(browser.get_remote_info)
- end
+ # This is needed because we just forked a new process
+ # which now needs its own connection to the database.
+ database_connect
- browser.end_conversation
- rescue Exception => error
- session.write("ERROR #{error.message}\n")
- puts "ERROR #{error.message}" unless defined?(TESTING)
- end
+ begin
+ browser = HostBrowser.new(session)
- puts "Disconnected from #{remote}" unless defined?(TESTING)
+ browser.begin_conversation
+ case browser.get_mode
+ when "AWAKEN": browser.create_keytab(remote,session.peeraddr[3])
+ when "IDENTIFY": browser.write_host_info(browser.get_remote_info)
end
- Process.detach(child)
+ browser.end_conversation
+ rescue Exception => error
+ session.write("ERROR #{error.message}\n")
+ puts "ERROR #{error.message}" unless defined?(TESTING)
+ end
+
+ puts "Disconnected from #{remote}" unless defined?(TESTING)
end
+
+ Process.detach(child)
+ end
end
unless defined?(TESTING)
- # The main entry point.
- #
- unless ARGV[0] == "-n"
- daemonize
- # redirect output to the log
- STDOUT.reopen $logfile, 'a'
- STDERR.reopen STDOUT
- end
-
- server = TCPServer.new("",12120)
- entry_point(server)
+ # The main entry point.
+ #
+ unless ARGV[0] == "-n"
+ daemonize
+ # redirect output to the log
+ STDOUT.reopen $logfile, 'a'
+ STDERR.reopen STDOUT
+ end
+
+ server = TCPServer.new("",12120)
+ entry_point(server)
end
diff --git a/wui/src/host-browser/test-host-browser-identify.rb b/wui/src/host-browser/test-host-browser-identify.rb
index 7e672ce..e25497f 100755
--- a/wui/src/host-browser/test-host-browser-identify.rb
+++ b/wui/src/host-browser/test-host-browser-identify.rb
@@ -27,257 +27,259 @@ TESTING=true
require 'host-browser'
class TestHostBrowser < Test::Unit::TestCase
- def setup
- @session = flexmock('session')
- @session.should_receive(:peeraddr).at_least.once.returns { [nil,nil,nil,"192.168.2.255"] }
-
- @browser = HostBrowser.new(@session)
- @browser.logfile = './unit-test.log'
-
- # default host info
- @host_info = {}
- @host_info['UUID'] = 'node1'
- @host_info['IPADDR'] = '192.168.2.2'
- @host_info['HOSTNAME'] = 'prod.corp.com'
- @host_info['ARCH'] = 'x86_64'
- @host_info['MEMSIZE'] = '16384'
- @host_info['DISABLED'] = '0'
-
- @host_info['NUMCPUS'] = '2'
-
- @host_info['CPUINFO'] = Array.new
- @host_info['CPUINFO'][0] = {}
- @host_info['CPUINFO'][0]['CPUNUM'] = '0'
- @host_info['CPUINFO'][0]['CORENUM'] = '0'
- @host_info['CPUINFO'][0]['NUMCORES'] = '2'
- @host_info['CPUINFO'][0]['VENDOR'] = 'GenuineIntel'
- @host_info['CPUINFO'][0]['MODEL'] = '15'
- @host_info['CPUINFO'][0]['FAMILY'] = '6'
- @host_info['CPUINFO'][0]['CPUIDLVL'] = '10'
- @host_info['CPUINFO'][0]['SPEED'] = '3'
- @host_info['CPUINFO'][0]['CACHE'] = '4096 kb'
- @host_info['CPUINFO'][0]['FLAGS'] = 'fpu vme de pse tsc msr pae \
+ def setup
+ @connection = flexmock('connection')
+ @connection.should_receive(:peeraddr).at_least.once.returns { [nil,nil,nil,"192.168.2.255"] }
+
+ @browser = HostBrowser.new(@connection)
+ @browser.logfile = './unit-test.log'
+
+ # default host info
+ @host_info = {}
+ @host_info['UUID'] = 'node1'
+ @host_info['IPADDR'] = '192.168.2.2'
+ @host_info['HOSTNAME'] = 'prod.corp.com'
+ @host_info['ARCH'] = 'x86_64'
+ @host_info['MEMSIZE'] = '16384'
+ @host_info['DISABLED'] = '0'
+
+ @host_info['NUMCPUS'] = '2'
+
+ @host_info['CPUINFO'] = Array.new
+ @host_info['CPUINFO'][0] = {}
+ @host_info['CPUINFO'][0]['CPUNUM'] = '0'
+ @host_info['CPUINFO'][0]['CORENUM'] = '0'
+ @host_info['CPUINFO'][0]['NUMCORES'] = '2'
+ @host_info['CPUINFO'][0]['VENDOR'] = 'GenuineIntel'
+ @host_info['CPUINFO'][0]['MODEL'] = '15'
+ @host_info['CPUINFO'][0]['FAMILY'] = '6'
+ @host_info['CPUINFO'][0]['CPUIDLVL'] = '10'
+ @host_info['CPUINFO'][0]['SPEED'] = '3'
+ @host_info['CPUINFO'][0]['CACHE'] = '4096 kb'
+ @host_info['CPUINFO'][0]['FLAGS'] = 'fpu vme de pse tsc msr pae \
mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx \
fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs \
bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm'
- @host_info['CPUINFO'][1] = {}
- @host_info['CPUINFO'][1]['CPUNUM'] = '1'
- @host_info['CPUINFO'][1]['CORENUM'] = '1'
- @host_info['CPUINFO'][1]['NUMCORES'] = '2'
- @host_info['CPUINFO'][1]['VENDOR'] = 'GenuineIntel'
- @host_info['CPUINFO'][1]['MODEL'] = '15'
- @host_info['CPUINFO'][1]['FAMILY'] = '6'
- @host_info['CPUINFO'][1]['CPUIDLVL'] = '10'
- @host_info['CPUINFO'][1]['SPEED'] = '3'
- @host_info['CPUINFO'][1]['CACHE'] = '4096 kb'
- @host_info['CPUINFO'][1]['FLAGS'] = 'fpu vme de pse tsc msr pae \
+ @host_info['CPUINFO'][1] = {}
+ @host_info['CPUINFO'][1]['CPUNUM'] = '1'
+ @host_info['CPUINFO'][1]['CORENUM'] = '1'
+ @host_info['CPUINFO'][1]['NUMCORES'] = '2'
+ @host_info['CPUINFO'][1]['VENDOR'] = 'GenuineIntel'
+ @host_info['CPUINFO'][1]['MODEL'] = '15'
+ @host_info['CPUINFO'][1]['FAMILY'] = '6'
+ @host_info['CPUINFO'][1]['CPUIDLVL'] = '10'
+ @host_info['CPUINFO'][1]['SPEED'] = '3'
+ @host_info['CPUINFO'][1]['CACHE'] = '4096 kb'
+ @host_info['CPUINFO'][1]['FLAGS'] = 'fpu vme de pse tsc msr pae \
mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx \
fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs \
bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm'
- @host_info['NICINFO'] = Array.new
- @host_info['NICINFO'][0] = {}
- @host_info['NICINFO'][0]['MAC'] = '00:11:22:33:44:55'
- @host_info['NICINFO'][0]['BANDWIDTH'] = '100'
-
- @host_info['NICINFO'][1] = {}
- @host_info['NICINFO'][1]['MAC'] = '00:77:11:77:19:65'
- @host_info['NICINFO'][1]['BANDWIDTH'] = '100'
- end
-
- # Ensures that the server is satisfied if the remote system is
- # making a wakeup call.
- #
- def test_get_mode_with_awaken_request
- @session.should_receive(:write).with("MODE?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "IDENTIFY\n" }
-
- result = @browser.get_mode()
-
- assert_equal "IDENTIFY", result, "method did not return the right value"
- end
-
- # Ensures that, if an info field is missing a key, the server raises
- # an exception.
- #
- def test_get_info_with_missing_key
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "=value1\n" }
-
- assert_raise(Exception) { @browser.get_remote_info }
- end
-
- # Ensures that, if an info field is missing a value, the server raises
- # an exception.
- #
- def test_get_info_with_missing_value
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=\n" }
-
- assert_raise(Exception) { @browser.get_remote_info }
- end
-
- # Ensures that, if the server gets a poorly formed ending statement, it
- # raises an exception.
- #
- def test_get_info_with_invalid_end
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDIFNO\n" }
-
- assert_raise(Exception) { @browser.get_remote_info }
- end
-
- # Ensures that a well-formed transaction works as expected.
- #
- def test_get_info
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 4,info.keys.size, "Should contain four keys"
- assert info.include?("IPADDR")
- assert info.include?("HOSTNAME")
- assert info.include?("key1")
- assert info.include?("key2")
- end
-
- # Ensures that the server is fine when no UUID is present.
- #
- def test_write_host_info_with_missing_uuid
- @host_info['UUID'] = nil
-
- assert_nothing_raised { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if the hostname is missing, the server
- # raises an exception.
- #
- def test_write_host_info_with_missing_hostname
- @host_info['HOSTNAME'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if the architecture is missing, the server raises an
- # exception.
- #
- def test_write_host_info_with_missing_arch
- @host_info['ARCH'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if the memory size is missing, the server raises an
- # exception.
- #
- def test_write_host_info_info_with_missing_memsize
- @host_info['MEMSIZE'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if no cpu info was available, the server raises an
- # exception.
- #
- def test_write_host_info_with_missing_cpuinfo
- @host_info['CPUINFO'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if no NIC info was available, the server raises an
- # exception.
- #
- def test_write_host_info_with_missing_nicinfo
- @host_info['NICINFO'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures the browser can properly parse the CPU details.
- #
- def test_parse_cpu_info
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "CPU\n" }
- @session.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDCPU\n" }
- @session.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 3,info.keys.size, "Should contain four keys"
- assert info.include?("CPUINFO")
- end
-
- # Ensures the browser can properly parse the CPU details of two CPUs.
- #
- def test_parse_cpu_info_with_two_entries
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
-
- # CPU 0
- @session.should_receive(:readline).once().returns { "CPU\n" }
- @session.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDCPU\n" }
- @session.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
-
- # CPU 1
- @session.should_receive(:readline).once().returns { "CPU\n" }
- @session.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key3=value3\n" }
- @session.should_receive(:write).with("ACK key3\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key4=value4\n" }
- @session.should_receive(:write).with("ACK key4\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDCPU\n" }
- @session.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
-
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 3,info.keys.size, "Should contain four keys"
- assert info.include?('CPUINFO')
- assert_equal 2, info['CPUINFO'].size, "Should contain details for two CPUs"
- assert_not_nil info['CPUINFO'][0]['key1']
- assert_not_nil info['CPUINFO'][0]['key2']
- assert_not_nil info['CPUINFO'][1]['key3']
- assert_not_nil info['CPUINFO'][1]['key4']
- end
-
- # Ensures the browser can properly parse the details for a NIC.
- #
- def test_parse_nic_info
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "NIC\n" }
- @session.should_receive(:write).with("NICINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDNIC\n" }
- @session.should_receive(:write).with("ACK NIC\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 3,info.keys.size, "Should contain four keys"
- assert info.include?("NICINFO")
- end
+ @host_info['NICINFO'] = Array.new
+ @host_info['NICINFO'] << {
+ 'MAC' => '00:11:22:33:44:55',
+ 'BANDWIDTH' => '100',
+ 'IFACE_NAME' => 'eth0'}
+
+ @host_info['NICINFO'] << {
+ 'MAC' => '00:77:11:77:19:65',
+ 'BANDWIDTH' => '100',
+ 'IFACE_NAME' => 'eth01'}
+ end
+
+ # Ensures that the server is satisfied if the remote system is
+ # making a wakeup call.
+ #
+ def test_get_mode_with_awaken_request
+ @connection.should_receive(:write).with("MODE?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "IDENTIFY\n" }
+
+ result = @browser.get_mode()
+
+ assert_equal "IDENTIFY", result, "method did not return the right value"
+ end
+
+ # Ensures that, if an info field is missing a key, the server raises
+ # an exception.
+ #
+ def test_get_info_with_missing_key
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "=value1\n" }
+
+ assert_raise(Exception) { @browser.get_remote_info }
+ end
+
+ # Ensures that, if an info field is missing a value, the server raises
+ # an exception.
+ #
+ def test_get_info_with_missing_value
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=\n" }
+
+ assert_raise(Exception) { @browser.get_remote_info }
+ end
+
+ # Ensures that, if the server gets a poorly formed ending statement, it
+ # raises an exception.
+ #
+ def test_get_info_with_invalid_end
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDIFNO\n" }
+
+ assert_raise(Exception) { @browser.get_remote_info }
+ end
+
+ # Ensures that a well-formed transaction works as expected.
+ #
+ def test_get_info
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 4,info.keys.size, "Should contain four keys"
+ assert info.include?("IPADDR")
+ assert info.include?("HOSTNAME")
+ assert info.include?("key1")
+ assert info.include?("key2")
+ end
+
+ # Ensures that the server is fine when no UUID is present.
+ #
+ def test_write_host_info_with_missing_uuid
+ @host_info['UUID'] = nil
+
+ assert_nothing_raised { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if the hostname is missing, the server
+ # raises an exception.
+ #
+ def test_write_host_info_with_missing_hostname
+ @host_info['HOSTNAME'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if the architecture is missing, the server raises an
+ # exception.
+ #
+ def test_write_host_info_with_missing_arch
+ @host_info['ARCH'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if the memory size is missing, the server raises an
+ # exception.
+ #
+ def test_write_host_info_info_with_missing_memsize
+ @host_info['MEMSIZE'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if no cpu info was available, the server raises an
+ # exception.
+ #
+ def test_write_host_info_with_missing_cpuinfo
+ @host_info['CPUINFO'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if no NIC info was available, the server raises an
+ # exception.
+ #
+ def test_write_host_info_with_missing_nicinfo
+ @host_info['NICINFO'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures the browser can properly parse the CPU details.
+ #
+ def test_parse_cpu_info
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "CPU\n" }
+ @connection.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDCPU\n" }
+ @connection.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 3,info.keys.size, "Should contain four keys"
+ assert info.include?("CPUINFO")
+ end
+
+ # Ensures the browser can properly parse the CPU details of two CPUs.
+ #
+ def test_parse_cpu_info_with_two_entries
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+
+ # CPU 0
+ @connection.should_receive(:readline).once().returns { "CPU\n" }
+ @connection.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDCPU\n" }
+ @connection.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
+
+ # CPU 1
+ @connection.should_receive(:readline).once().returns { "CPU\n" }
+ @connection.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key3=value3\n" }
+ @connection.should_receive(:write).with("ACK key3\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key4=value4\n" }
+ @connection.should_receive(:write).with("ACK key4\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDCPU\n" }
+ @connection.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
+
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 3,info.keys.size, "Should contain four keys"
+ assert info.include?('CPUINFO')
+ assert_equal 2, info['CPUINFO'].size, "Should contain details for two CPUs"
+ assert_not_nil info['CPUINFO'][0]['key1']
+ assert_not_nil info['CPUINFO'][0]['key2']
+ assert_not_nil info['CPUINFO'][1]['key3']
+ assert_not_nil info['CPUINFO'][1]['key4']
+ end
+
+ # Ensures the browser can properly parse the details for a NIC.
+ #
+ def test_parse_nic_info
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "NIC\n" }
+ @connection.should_receive(:write).with("NICINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDNIC\n" }
+ @connection.should_receive(:write).with("ACK NIC\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 3,info.keys.size, "Should contain four keys"
+ assert info.include?("NICINFO")
+ end
end
diff --git a/wui/src/lib/managed_node_configuration.rb b/wui/src/lib/managed_node_configuration.rb
new file mode 100644
index 0000000..aa8c711
--- /dev/null
+++ b/wui/src/lib/managed_node_configuration.rb
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# +ManagedNodeConfiguration+ takes in the description for a managed node and,
+# from that, generates the configuration file that is consumed the next time
+# the managed node starts up.
+#
+
+require 'stringio'
+
+$: << File.join(File.dirname(__FILE__), "../dutils")
+$: << File.join(File.dirname(__FILE__), "../")
+
+class ManagedNodeConfiguration
+ NIC_ENTRY_PREFIX='/files/etc/sysconfig/network-scripts'
+
+ def self.generate(host)
+ result = StringIO.new
+
+ host.nics.each do |nic|
+ result.puts "rm #{NIC_ENTRY_PREFIX}/ifcfg-#{nic.iface_name}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{nic.iface_name}/DEVICE #{nic.iface_name}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{nic.iface_name}/IPADDR #{nic.ip_addr}" if nic.ip_addr
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{nic.iface_name}/BOOTPROTO dhcp" if nic.ip_addr == nil
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{nic.iface_name}/BRIDGE #{nic.bridge}" if nic.bridge
+ end
+
+ result.puts "save"
+
+ result.string
+ end
+end
+
diff --git a/wui/src/test/unit/managed_node_configuration_test.rb b/wui/src/test/unit/managed_node_configuration_test.rb
new file mode 100644
index 0000000..01b3fe4
--- /dev/null
+++ b/wui/src/test/unit/managed_node_configuration_test.rb
@@ -0,0 +1,87 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+$:.unshift File.join(File.dirname(__FILE__),'..','lib')
+
+# require File.dirname(__FILE__) + '/../test/test_helper'
+require 'test/unit'
+require 'managed_node_configuration'
+require 'dutils'
+
+# Performs unit tests on the +ManagedNodeConfiguration+ class.
+#
+class ManagedNodeConfigurationTest < Test::Unit::TestCase
+ def setup
+ @host = Host.new
+ end
+
+
+ # Ensures that network interfaces uses DHCP when no IP address is specified.
+ #
+ def test_generate_with_no_ip_address
+ @host.nics << Nic.new(:iface_name => 'eth0')
+
+ expected = <<HERE
+rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO dhcp
+save
+HERE
+
+ result = ManagedNodeConfiguration.generate @host
+
+ assert_equal expected, result
+ end
+
+ # Ensures that network interfaces use the IP address when it's provided.
+ #
+ def test_generate_with_ip_address
+ @host.nics << Nic.new(:iface_name => 'eth0', :ip_addr => '192.168.2.1')
+
+ expected = <<HERE
+rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/IPADDR 192.168.2.1
+save
+HERE
+
+ result = ManagedNodeConfiguration.generate @host
+
+ assert_equal expected, result
+ end
+
+ # Ensures the bridge is added to the configuration if one is defined.
+ #
+ def test_generate_with_bridge
+ @host.nics << Nic.new(:iface_name => 'eth0', :bridge => 'ovirtbr0')
+
+ expected = <<HERE
+rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO dhcp
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BRIDGE ovirtbr0
+save
+HERE
+
+ result = ManagedNodeConfiguration.generate @host
+
+ assert_equal expected, result
+ end
+
+end
--
1.5.5.1
More information about the ovirt-devel
mailing list