Speedup network verification

Instead of sending test packets from each node one by one, sending them from group of nodes.
Number of nodes may be increased in future.

Closes-Bug: #1378500
Change-Id: Ia970692de1778b15d2401b4758d47bc1343c02b7
Blueprint: 200-nodes-support
This commit is contained in:
Łukasz Oleś 2014-12-03 16:27:11 +01:00
parent 3f1ece0318
commit f595715750
4 changed files with 75 additions and 19 deletions

View File

@ -84,7 +84,8 @@ module Astute
conf[:max_nodes_per_remove_call] = 10 # how many nodes to remove in one call
conf[:nodes_remove_interval] = 10 # sleeps for ## sec between remove calls
conf[:max_nodes_net_validation] = 10 # how many nodes will send in parallel test packets
# during network verification
conf[:dhcp_repeat] = 3 # Dhcp discover will be sended 3 times
conf[:iops] = 120 # Default IOPS master node IOPS performance

View File

@ -36,10 +36,30 @@ module Astute
# TODO Everything breakes if agent not found. We have to handle that
net_probe = MClient.new(ctx, "net_probe", uids)
start_frame_listeners(ctx, net_probe, nodes)
versioning = Versioning.new(ctx)
old_version, new_version = versioning.split_on_version(uids, '6.1.0')
old_uids = old_version.map { |node| node['uid'].to_i }
new_uids = new_version.map { |node| node['uid'].to_i }
old_nodes = nodes.select { |node| old_uids.include? node['uid'] }
new_nodes = nodes.select { |node| new_uids.include? node['uid'] }
if old_uids.present?
start_frame_listeners_60(ctx, net_probe, old_nodes)
end
if new_uids.present?
start_frame_listeners(ctx, net_probe, new_nodes)
end
ctx.reporter.report({'progress' => 30})
send_probing_frames(ctx, net_probe, nodes)
if old_uids.present?
send_probing_frames_60(ctx, net_probe, old_nodes)
end
if new_uids.present?
send_probing_frames(ctx, net_probe, new_nodes)
end
ctx.reporter.report({'progress' => 60})
net_probe.discover(:nodes => uids)
@ -96,6 +116,38 @@ module Astute
private
def self.start_frame_listeners(ctx, net_probe, nodes)
data_to_send = {}
nodes.each do |node|
data_to_send[node['uid'].to_s] = make_interfaces_to_send(node['networks'])
end
uids = nodes.map { |node| node['uid'].to_s }
Astute.logger.debug(
"#{ctx.task_id}: Network checker listen: nodes: #{uids} data: #{data_to_send.inspect}")
net_probe.discover(:nodes => uids)
net_probe.start_frame_listeners(:interfaces => data_to_send.to_json)
end
def self.send_probing_frames(ctx, net_probe, nodes)
nodes.each_slice(Astute.config[:max_nodes_net_validation]) do |nodes_part|
data_to_send = {}
nodes_part.each do |node|
data_to_send[node['uid'].to_s] = make_interfaces_to_send(node['networks'])
end
uids = nodes_part.map { |node| node['uid'].to_s }
Astute.logger.debug(
"#{ctx.task_id}: Network checker send: nodes: #{uids} data: #{data_to_send.inspect}")
net_probe.discover(:nodes => uids)
net_probe.send_probing_frames(:interfaces => data_to_send.to_json)
end
end
def self.start_frame_listeners_60(ctx, net_probe, nodes)
nodes.each do |node|
data_to_send = make_interfaces_to_send(node['networks'])
@ -107,7 +159,7 @@ module Astute
end
end
def self.send_probing_frames(ctx, net_probe, nodes)
def self.send_probing_frames_60(ctx, net_probe, nodes)
nodes.each do |node|
data_to_send = make_interfaces_to_send(node['networks'])

View File

@ -85,7 +85,7 @@ module MCollective
validate :interfaces, String
config = {
"action" => "listen",
"interfaces" => JSON.parse(request[:interfaces]),
"interfaces" => JSON.parse(request[:interfaces])[get_uid],
"dump_file" => "/var/tmp/net-probe-dump",
"ready_address" => "127.0.0.1",
"ready_port" => 31338,
@ -147,7 +147,7 @@ module MCollective
def send_probing_frames
validate :interfaces, String
config = { "action" => "generate", "uid" => get_uid,
"interfaces" => JSON.parse(request[:interfaces]) }
"interfaces" => JSON.parse(request[:interfaces])[get_uid]}
if request.data.key?('config')
config.merge!(JSON.parse(request[:config]))
end

View File

@ -26,7 +26,7 @@ describe Astute::Network do
def make_nodes(*uids)
uids.map do |uid|
{
'uid' => uid.to_s,
'uid' => uid,
'networks' => [
{
'iface' => 'eth0',
@ -67,21 +67,24 @@ describe Astute::Network do
rpcclient = mock_rpcclient(nodes)
rpcclient.expects(:get_probing_info).once.returns([mc_res1, mc_res2])
nodes.each do |node|
rpcclient.expects(:discover).with(:nodes => [node['uid']]).at_least_once
uids = nodes.map { |node| node['uid'].to_s }
data_to_send = {}
node['networks'].each{ |net| data_to_send[net['iface']] = net['vlans'].join(",") }
rpcclient.expects(:start_frame_listeners).
with(:interfaces => data_to_send.to_json).
returns([mc_valid_res]*2)
data_to_send = {}
nodes[0]['networks'].each{ |net| data_to_send[net['iface']] = net['vlans'].join(",") }
data_to_send = { '1' => data_to_send, '2' => data_to_send}
rpcclient.expects(:send_probing_frames).
with(:interfaces => data_to_send.to_json).
returns([mc_valid_res]*2)
end
rpcclient.expects(:start_frame_listeners).
with(:interfaces => data_to_send.to_json).
returns([mc_valid_res]*2)
rpcclient.expects(:send_probing_frames).
with(:interfaces => data_to_send.to_json).
returns([mc_valid_res]*2)
rpcclient.expects(:discover).with(:nodes => uids)
Astute::MClient.any_instance.stubs(:rpcclient).returns(rpcclient)
res = [[], [{"version"=>"6.1.0", "uid"=>"2"}, {"version"=>"6.1.0", "uid"=>"1"}]]
Astute::Versioning.any_instance.stubs(:split_on_version).returns(res)
res = Astute::Network.check_network(Astute::Context.new('task_uuid', reporter), nodes)
expected = {"nodes" => [{"networks" => [{"iface"=>"eth0", "vlans"=>[100]}], "uid"=>"1"},
@ -97,7 +100,7 @@ describe Astute::Network do
it "returns all vlans passed if only one node provided" do
nodes = make_nodes(1)
res = Astute::Network.check_network(Astute::Context.new('task_uuid', reporter), nodes)
expected = {"nodes" => [{"uid"=>"1", "networks" => [{"iface"=>"eth0", "vlans"=>[100, 101]}]}]}
expected = {"nodes" => [{"uid"=>1, "networks" => [{"iface"=>"eth0", "vlans"=>[100, 101]}]}]}
res.should eql(expected)
end
end