Merge "Re-assembling bond"

This commit is contained in:
Jenkins 2015-11-20 14:14:15 +00:00 committed by Gerrit Code Review
commit 7db9175477
3 changed files with 164 additions and 33 deletions

View File

@ -85,6 +85,7 @@ class Puppet::Provider::InterfaceToolset < Puppet::Provider
end
def self.interface_up(iface, force=false)
debug("Setting #{iface} up")
cmd = ['link', 'set', 'up', 'dev', iface]
cmd.insert(0, '--force') if force
begin
@ -98,6 +99,7 @@ class Puppet::Provider::InterfaceToolset < Puppet::Provider
end
def self.interface_down(iface, force=false)
debug("Setting #{iface} down")
cmd = ['link', 'set', 'down', 'dev', iface]
cmd.insert(0, '--force') if force
begin
@ -226,4 +228,4 @@ class Puppet::Provider::InterfaceToolset < Puppet::Provider
end
# vim: set ts=2 sw=2 et :
# vim: set ts=2 sw=2 et :

View File

@ -98,19 +98,21 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
end
if @property_flush.has_key? :bond_properties
# change bond_properties
need_reassemble = [:mode, :lacp_rate]
#todo(sv): inplement re-assembling only if it need
#todo(sv): re-set only delta between reality and requested
runtime_bond_state = !self.class.get_iface_state(@resource[:bond]).nil?
runtime_slave_ports = self.class.get_sys_class("#{bond_prop_dir}/bonding/slaves", true)
debug("Disassemble bond '#{@resource[:bond]}'")
runtime_slave_ports.each do |eth|
debug("Remove interface '#{eth}' from bond '#{@resource[:bond]}'")
# for most bond options we should disassemble bond before re-configuration. In the kernel module documentation
# says, that bond interface should be downed, but it's not enouth.
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "-#{eth}")
bond_is_up = !self.class.get_iface_state(@resource[:bond]).nil?
# Reassemble bond if we change bond mode
need_reassembling = true if self.class.get_sys_class("#{bond_prop_dir}/bonding/#{'mode'}") != @property_flush[:bond_properties][:mode]
if need_reassembling
self.class.interface_down(@resource[:bond])
bond_is_up = false
runtime_slave_ports = self.class.get_sys_class("#{bond_prop_dir}/bonding/slaves", true)
debug("Disassemble bond '#{@resource[:bond]}'")
runtime_slave_ports.each do |eth|
debug("Remove interface '#{eth}' from bond '#{@resource[:bond]}'")
# for most bond options we should disassemble bond before re-configuration. In the kernel module documentation
# says, that bond interface should be downed, but it's not enouth.
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "-#{eth}")
end
end
self.class.interface_down(@resource[:bond])
# setup primary bond_properties
primary_bond_properties = [:mode, :xmit_hash_policy]
debug("Set primary bond properties [#{primary_bond_properties.join(',')}] for bond '#{@resource[:bond]}'")
@ -122,7 +124,11 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
if ['', 'nil', 'undef'].include? should_pprop
debug("Skip undefined property '#{pprop}'='#{should_pprop}' for bond '#{@resource[:bond]}'")
elsif curr_pprop != should_pprop
debug("Setting #{pprop} '#{should_pprop}' for bond '#{@resource[:bond]}'")
if bond_is_up
self.class.interface_down(@resource[:bond])
bond_is_up = false
end
debug("Setting #{pprop} '#/{should_pprop}' for bond '#{@resource[:bond]}'")
self.class.set_sys_class("#{bond_prop_dir}/bonding/#{pprop}", should_pprop)
sleep(1)
else
@ -140,6 +146,10 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
val_should_be = val.to_s
val_actual = self.class.get_sys_class("#{bond_prop_dir}/bonding/#{prop}")
if val_actual != val_should_be
if bond_is_up
self.class.interface_down(@resource[:bond])
bond_is_up = false
end
debug("Setting property '#{prop}' to '#{val_should_be}' for bond '#{@resource[:bond]}'")
self.class.set_sys_class("#{bond_prop_dir}/bonding/#{prop}", val_should_be)
else
@ -149,13 +159,15 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
debug("Unsupported property '#{prop}' for bond '#{@resource[:bond]}'")
end
end
# re-assemble bond after configuration
self.class.interface_up(@resource[:bond]) if runtime_bond_state
debug("Re-assemble bond '#{@resource[:bond]}'")
runtime_slave_ports.each do |eth|
debug("Add interface '#{eth}' to bond '#{@resource[:bond]}'")
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "+#{eth}")
if need_reassembling
# re-assemble bond after configuration
debug("Re-assemble bond '#{@resource[:bond]}'")
runtime_slave_ports.each do |eth|
debug("Add interface '#{eth}' to bond '#{@resource[:bond]}'")
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "+#{eth}")
end
end
self.class.interface_up(@resource[:bond]) if !bond_is_up
end
if @property_flush.has_key? :bridge
# get actual bridge-list. We should do it here,
@ -166,11 +178,14 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
debug("Actual-port-bridge-mapping: '#{port_bridges_hash}'") # it should removed from LNX
#
# remove interface from old bridge
runtime_bond_state = !self.class.get_iface_state(@resource[:bond]).nil?
self.class.interface_down(@resource[:bond], true)
bond_is_up = !self.class.get_iface_state(@resource[:bond]).nil?
if ! port_bridges_hash[@resource[:bond]].nil?
br_name = port_bridges_hash[@resource[:bond]][:bridge]
if br_name != @resource[:bond]
if bond_is_up
self.class.interface_down(@resource[:bond], true)
bond_is_up = false
end
# do not remove bridge-based interface from his bridge
case port_bridges_hash[@resource[:bond]][:br_type]
when :ovs
@ -195,11 +210,11 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
#pass
end
end
self.class.interface_up(@resource[:bond]) if runtime_bond_state
self.class.interface_up(@resource[:bond]) if !bond_is_up
debug("Change bridge")
end
if @property_flush[:onboot]
self.class.interface_up(@resource[:bond])
self.class.interface_up(@resource[:bond]) if self.class.get_iface_state(@resource[:bond]).nil?
end
if !['', 'absent'].include? @property_flush[:mtu].to_s
self.class.set_mtu(@resource[:bond], @property_flush[:mtu])

View File

@ -29,6 +29,7 @@ describe Puppet::Type.type(:l2_bond).provider(:lnx) do
end
it "Just create bond, which unify two NICs" do
provider.class.stubs(:set_sys_class).with('/sys/class/net/bonding_masters', '+bond1').returns(true)
provider.create
#provider.flush
end
@ -38,11 +39,11 @@ describe Puppet::Type.type(:l2_bond).provider(:lnx) do
provider.class.stubs(:get_sys_class).with("/sys/class/net/bond1/bonding/slaves", true).returns([])
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/slaves', '+eth1').returns(true)
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/slaves', '+eth2').returns(true)
provider.class.stubs(:set_interface_down).with('bond1').returns(true)
provider.class.stubs(:set_interface_down).with('bond1', true).returns(true)
provider.class.stubs(:set_interface_down).with('eth1').returns(true)
provider.class.stubs(:set_interface_down).with('eth2').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/mode').returns('802.3ad')
provider.class.stubs(:interface_down).with('bond1').returns(true)
provider.class.stubs(:interface_down).with('bond1', true).returns(true)
provider.class.stubs(:interface_down).with('eth1').returns(true)
provider.class.stubs(:interface_down).with('eth2').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/mode').returns('balance-rr')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/mode', '802.3ad').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/xmit_hash_policy').returns('layer2')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/xmit_hash_policy', 'layer2+3').returns(true)
@ -54,9 +55,9 @@ describe Puppet::Type.type(:l2_bond).provider(:lnx) do
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/updelay', '111').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/downdelay').returns('0')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/downdelay', '222').returns(true)
provider.class.stubs(:set_interface_up).with('bond1').returns(true)
provider.class.stubs(:set_interface_up).with('eth1').returns(true)
provider.class.stubs(:set_interface_up).with('eth2').returns(true)
provider.class.stubs(:interface_up).with('bond1').returns(true)
provider.class.stubs(:interface_up).with('eth1').returns(true)
provider.class.stubs(:interface_up).with('eth2').returns(true)
provider.create
#leave here as template for future
#provider.expects(:warn).with { |arg| arg =~ /lnx\s+don't\s+allow\s+change\s+bond\s+slaves/ }
@ -70,4 +71,117 @@ describe Puppet::Type.type(:l2_bond).provider(:lnx) do
end
end
end
require 'spec_helper'
describe Puppet::Type.type(:l2_bond).provider(:lnx) do
let(:resource) {
Puppet::Type.type(:l2_bond).new(
:provider => :lnx,
:name => 'bond2',
:slaves => ['eth12', 'eth22'],
:bond_properties => {
'mode' => '802.3ad',
'lacp_rate' => 'fast',
'xmit_hash_policy' => 'layer2+3',
'updelay' => '111',
'downdelay' => '222',
'ad_select' => '2',
},
)
}
let(:provider) { resource.provider }
let(:instance) { provider.class.instances }
describe "lnx bond" do
before(:each) do
puppet_debug_override()
end
it "Do not re-assemble bond if mode is not changed" do
provider.class.stubs(:set_sys_class).with('/sys/class/net/bonding_masters', '+bond2').returns(true)
provider.create
provider.class.stubs(:get_sys_class).with("/sys/class/net/bond2/bonding/slaves", true).returns(['eth12', 'eth22'])
provider.class.expects(:set_sys_class).with('/sys/class/net/bond2/bonding/slaves', '-eth12').never
provider.class.expects(:set_sys_class).with('/sys/class/net/bond2/bonding/slaves', '-eth22').never
provider.class.stubs(:interface_down).with('bond2', true).returns(true)
provider.class.stubs(:interface_down).with('bond2').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond2/bonding/mode').returns('802.3ad')
provider.class.expects(:set_sys_class).with('/sys/class/net/bond2/bonding/mode', '802.3ad').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond2/bonding/xmit_hash_policy').returns('layer2')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond2/bonding/xmit_hash_policy', 'layer2+3').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond2/bonding/lacp_rate').returns('slow')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond2/bonding/lacp_rate', 'fast').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond2/bonding/ad_select').returns('stable')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond2/bonding/ad_select', '2').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond2/bonding/updelay').returns('0')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond2/bonding/updelay', '111').returns(true)
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond2/bonding/downdelay').returns('0')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond2/bonding/downdelay', '222').returns(true)
provider.class.expects(:set_sys_class).with('/sys/class/net/bond2/bonding/slaves', '+eth12').never
provider.class.expects(:set_sys_class).with('/sys/class/net/bond2/bonding/slaves', '+eth22').never
provider.class.stubs(:interface_up).with('bond2').returns(true)
provider.class.stubs(:interface_up).with('bond2', true).returns(true)
provider.flush
end
end
end
describe Puppet::Type.type(:l2_bond).provider(:lnx) do
let(:resource) {
Puppet::Type.type(:l2_bond).new(
:provider => :lnx,
:name => 'bond3',
:slaves => ['eth31', 'eth32'],
:bond_properties => {
'mode' => '802.3ad',
'lacp_rate' => 'fast',
'xmit_hash_policy' => 'layer2+3',
'updelay' => '111',
'downdelay' => '222',
'ad_select' => '2',
},
)
}
let(:provider) { resource.provider }
let(:instance) { provider.class.instances }
describe "lnx bond" do
before(:each) do
puppet_debug_override()
end
it "Do not down/up bond if nothing changed" do
provider.class.stubs(:set_sys_class).with('/sys/class/net/bonding_masters', '+bond3').returns(true)
provider.class.stubs(:get_iface_state).with('bond3').returns(true)
provider.create
provider.class.stubs(:get_sys_class).with("/sys/class/net/bond3/bonding/slaves", true).returns(['eth31', 'eth32'])
provider.class.expects(:set_sys_class).with('/sys/class/net/bond3/bonding/slaves', '-eth31').never
provider.class.expects(:set_sys_class).with('/sys/class/net/bond3/bonding/slaves', '-eth32').never
provider.class.stubs(:interface_down).with('bond3', true).never
provider.class.stubs(:interface_down).with('bond3').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond3/bonding/mode').returns('802.3ad')
provider.class.expects(:set_sys_class).with('/sys/class/net/bond3/bonding/mode', '802.3ad').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond3/bonding/xmit_hash_policy').returns('layer2+3')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond3/bonding/xmit_hash_policy', 'layer2+3').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond3/bonding/lacp_rate').returns('fast')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond3/bonding/lacp_rate', 'fast').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond3/bonding/ad_select').returns('2')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond3/bonding/ad_select', '2').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond3/bonding/updelay').returns('111')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond3/bonding/updelay', '111').never
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond3/bonding/downdelay').returns('222')
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond3/bonding/downdelay', '222').never
provider.class.expects(:set_sys_class).with('/sys/class/net/bond3/bonding/slaves', '+eth31').never
provider.class.expects(:set_sys_class).with('/sys/class/net/bond3/bonding/slaves', '+eth32').never
provider.class.stubs(:interface_up).with('bond3').never
provider.class.stubs(:interface_up).with('bond3', true).never
provider.flush
end
end
end