Arjun Roy
2009-Jul-10 16:48 UTC
[Ovirt-devel] [PATCH: server 0/3] Add host-register.rb (replaces host-browser.rb in part)
Removes node identification functionality from host-browser.rb and adds a new script, host-register.rb, that takes over that functionality. The chief difference is that host-browser used a simple TCP server setup to get data from the node, while host-register uses the qpid bus to do so. Specifically, it communicates with the matahari qmf agent added to the node in two related patchsets to node and node-image. At present, there is a bug in the ruby console api that affects host-register.rb. As a temporary workaround, managed connections have been disabled. There are two related patchsets for node and node-image that must be applied as well to test out the changes in this patchset. Arjun Roy (3): Removed host-browser identify node functionality and unit test. Added new host-register script to ovirt server. Temporarily set managed_connections to false for host-register till qpid ruby console api bug is fixed. conf/ovirt-host-register | 54 +++ installer/modules/ovirt/manifests/ovirt.pp | 6 + ovirt-server.spec.in | 5 + src/host-browser/host-browser.rb | 255 +--------------- src/host-browser/host-register.rb | 468 +++++++++++++++++++++++++++ src/test/unit/host_browser_identify_test.rb | 310 ------------------ 6 files changed, 534 insertions(+), 564 deletions(-) create mode 100644 conf/ovirt-host-register create mode 100644 src/host-browser/host-register.rb delete mode 100644 src/test/unit/host_browser_identify_test.rb
Arjun Roy
2009-Jul-10 16:48 UTC
[Ovirt-devel] [PATCH: server 1/3] Removed host-browser identify node functionality and unit test.
--- src/host-browser/host-browser.rb | 255 +---------------------- src/test/unit/host_browser_identify_test.rb | 310 --------------------------- 2 files changed, 1 insertions(+), 564 deletions(-) delete mode 100644 src/test/unit/host_browser_identify_test.rb diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb index 13b2ac4..d77b321 100755 --- a/src/host-browser/host-browser.rb +++ b/src/host-browser/host-browser.rb @@ -22,7 +22,6 @@ $: << File.join(File.dirname(__FILE__), "../dutils") $: << File.join(File.dirname(__FILE__), "../") require 'rubygems' -require 'libvirt' require 'dutils' require 'socket' @@ -35,9 +34,7 @@ include Socket::Constants $logfile = '/var/log/ovirt-server/host-browser.log' -# +HostBrowser+ communicates with the a managed node. It retrieves specific information -# about the node and then updates the list of active nodes for the Server. -# +# +HostBrowser+ provides kerberos related services to a managed node. class HostBrowser attr_accessor :logfile attr_accessor :keytab_dir @@ -78,245 +75,6 @@ class HostBrowser response end - # Requests node information from the remote system. - # - def get_remote_info - puts "#{prefix(@session)} Begin remote info collection" unless defined?(TESTING) - result = Hash.new - result['HOSTNAME'] = @session.peeraddr[2] - result['IPADDR'] = @session.peeraddr[3] - result['NICINFO'] = Array.new - - @session.write("INFO?\n") - - loop do - info = @session.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 - - cpu_info << cpu - when "NIC" - nic = get_nic_info - nic_info = result['NICINFO'] - - if(nic_info == nil) - nic_info = Array.new - result['NICINFO'] = nic_info - end - - nic_info << nic - else - - raise Exception.new("ERRINFO! Expected key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]+/ - - key, value = info.split("=") - - puts "#{prefix(@session)} ::Received - #{key}:#{value}" unless defined?(TESTING) - result[key] = value - - @session.write("ACK #{key}\n") - end - end - - return result - end - - # Extracts CPU details from the managed node. - # - def get_cpu_info - puts "Begin receiving CPU details" - - result = Hash.new - - @session.write("CPUINFO?\n") - - loop do - info = @session.readline.chomp - - break if info == "ENDCPU" - - raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]/ - - key, value = info.split("=") - - puts "#{prefix(@session)} ::Received - #{key}:#{value}" unless defined?(TESTING) - result[key] = value - - @session.write("ACK #{key}\n") - end - - @session.write("ACK CPU\n"); - - return result - end - - # Extracts NIC details from the managed node. - # - def get_nic_info - puts "Begin receiving NIC details" - - result = Hash.new - - @session.write("NICINFO?\n") - - loop do - info = @session.readline.chomp - - break if info == "ENDNIC" - - raise Exception.new("ERRINFO! Excepted key=value : #{info}\n") unless info =~ /[\w]+[\s]*=[\w]*/ - - key, value = info.split("=") - - puts "#{prefix(@session)} ::Received - #{key}:#{value}" unless defined?(TESTING) - result[key] = value - - @session.write("ACK #{key}\n") - end - - @session.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 - - 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 - - # 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.each do |cpu| - detail = Cpu.new( - "cpu_number" => cpu['CPUNUM'].to_i, - "core_number" => cpu['CORENUM]'].to_i, - "number_of_cores" => cpu['NUMCORES'].to_i, - "vendor" => cpu['VENDOR'], - "model" => cpu['MODEL'], - "family" => cpu['FAMILY'], - "cpuid_level" => cpu['CPUIDLVL'].to_i, - "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 - nics_to_delete = Array.new - - host.nics.each do |nic| - found = false - - nic_info.each do |detail| - # if we have a match, then update the database and remove - # the received data to avoid creating a dupe later - puts "Searching for existing record for: #{detail['MAC'].upcase}" - if detail['MAC'].upcase == nic.mac - puts "Updating details for: #{detail['IFACE_NAME']} [#{nic.mac}]}" - nic.bandwidth = detail['BANDWIDTH'].to_i - nic.interface_name = detail['IFACE_NAME'] - nic.save! - found = true - nic_info.delete(detail) - end - end - - # if the record wasn't found, then remove it from the database - unless found - puts "Marking NIC for removal: #{nic.interface_name} [#{nic.mac}]" - nics_to_delete << nic - end - end - - nics_to_delete.each { |nic| puts "Removing NIC: #{nic.interface_name} []#{nic.mac}]"; host.nics.delete(nic) } - - # iterate over any nics left and create new records for them. - nic_info.each do |nic| - puts "Creating a new nic: #{nic['IFACE_NAME']} [#{nic['MAC']}]" - detail = Nic.new( - 'mac' => nic['MAC'].upcase, - 'bandwidth' => nic['BANDWIDTH'].to_i, - 'interface_name' => nic['IFACE_NAME'], - 'usage_type' => 1) - - host.nics << detail - end - - host.save! - - return host - end - # Creates a keytab if one is needed, returning the filename. # def create_keytab(hostname, ipaddress, krb5_arg = nil) @@ -359,12 +117,6 @@ class HostBrowser 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 - # Executes an external program to support the keytab function. # def kadmin_local(command) @@ -379,17 +131,12 @@ def entry_point(server) 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 - begin browser = HostBrowser.new(session) 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 browser.end_conversation diff --git a/src/test/unit/host_browser_identify_test.rb b/src/test/unit/host_browser_identify_test.rb deleted file mode 100644 index 083b364..0000000 --- a/src/test/unit/host_browser_identify_test.rb +++ /dev/null @@ -1,310 +0,0 @@ -#!/usr/bin/ruby -Wall -# -# 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. - -$: << File.join(File.dirname(__FILE__), "../../dutils") -$: << File.join(File.dirname(__FILE__), "../../host-browser") - -require File.dirname(__FILE__) + '/../test_helper' - -require 'test/unit' -require 'flexmock/test_unit' -require 'dutils' - -TESTING=true - -require 'host-browser' - -# +HostBrowserIdentifyTest+ tests the host-browser server to ensure that it -# works correctly during the identify mode of operation. -# -class HostBrowserIdentifyTest < Test::Unit::TestCase - fixtures :boot_types - - 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 \ - 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'] << { - '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 5,info.keys.size, "Should contain five keys" - assert info.include?("IPADDR") - assert info.include?("HOSTNAME") - assert info.include?("NICINFO") - 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 that, if a NIC is present that was already submitted, it - # doesn't get re-entered. - # - def test_write_host_info_with_duplicate_nic - # Values taken from the nics.yml fixture - @host_info['NICINFO'] << { - 'MAC' => '00:11:22:33:44:55', - 'BANDWIDTH' => '100', - 'IFACE_NAME' => 'eth0' - } - - assert_nothing_raised { @browser.write_host_info(@host_info) } - assert_equal 3, Host.find_by_hostname('prod.corp.com').nics.size, 'Expected three NICs.' - 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 4,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 4,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 -- 1.6.2.5
Arjun Roy
2009-Jul-10 19:43 UTC
[Ovirt-devel] [PATCH: server 0/3] Add host-register.rb (replaces host-browser.rb in part)
Removes node identification functionality from host-browser.rb and adds a new script, host-register.rb, that takes over that functionality. The chief difference is that host-browser used a simple TCP server setup to get data from the node, while host-register uses the qpid bus to do so. Specifically, it communicates with the matahari qmf agent added to the node in two related patchsets to node and node-image. At present, there is a bug in the ruby console api that affects host-register.rb. As a temporary workaround, managed connections have been disabled. There are two related patchsets for node and node-image that must be applied as well to test out the changes in this patchset. This is the third version of this patchset, and hopefully all the kinks have been worked out by now. :) Arjun Roy (3): Removed host-browser identify node functionality and unit test. Added new host-register script to ovirt server. Temporarily setting managed connections to false till ruby qmf console bug fix is pushed. conf/ovirt-host-register | 54 +++ installer/modules/ovirt/manifests/ovirt.pp | 6 + ovirt-server.spec.in | 5 + src/host-browser/host-browser.rb | 255 +--------------- src/host-browser/host-register.rb | 468 +++++++++++++++++++++++++++ src/test/unit/host_browser_identify_test.rb | 310 ------------------ 6 files changed, 534 insertions(+), 564 deletions(-) create mode 100644 conf/ovirt-host-register create mode 100755 src/host-browser/host-register.rb delete mode 100644 src/test/unit/host_browser_identify_test.rb
Possibly Parallel Threads
- [PATCH: host-browser replacement 0/3] replacement of host-browser on ovirt-server
- [PATCH] Add support for tagged VLAN
- [PATCH] Fix dbomatic state changes.
- [PATCH server] Fixed db-omatic so it doesn't die due to an unhandled ActiveRecord::StaleObjectError exception.
- [PATCH node] Update autobuild and autotest scripts for new build structure