From d2a33ecbb54bbd8c07e03decce22a849303ed53b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 25 Mar 2019 14:43:14 +0100 Subject: [PATCH] B #3029: Avoid running nic_query in network pre script. Make use of pre_action detection in other drivers. Co-authored-by: Daniel Clavijo Coca --- src/vnm_mad/remotes/ebtables/Ebtables.rb | 41 +++--- src/vnm_mad/remotes/ebtables/pre | 2 +- src/vnm_mad/remotes/lib/nic.rb | 15 ++- src/vnm_mad/remotes/lib/vm.rb | 134 ++++++++++---------- src/vnm_mad/remotes/lib/vnm_driver.rb | 7 + src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb | 14 +- src/vnm_mad/remotes/ovswitch/pre | 2 +- src/vnm_mad/remotes/ovswitch_vxlan/pre | 2 +- 8 files changed, 117 insertions(+), 100 deletions(-) diff --git a/src/vnm_mad/remotes/ebtables/Ebtables.rb b/src/vnm_mad/remotes/ebtables/Ebtables.rb index 7a184569ca9..f9443f924e6 100644 --- a/src/vnm_mad/remotes/ebtables/Ebtables.rb +++ b/src/vnm_mad/remotes/ebtables/Ebtables.rb @@ -34,35 +34,36 @@ def ebtables(rule) # Activates ebtables rules # - def activate(pre_action=false) - if pre_action + def activate + if VNMMAD.pre_action? super() - else - lock + return 0 + end - process do |nic| - tap = nic[:tap] - if tap - iface_mac = nic[:mac] + lock - mac = iface_mac.split(':') - mac[-1] = '00' + process do |nic| + tap = nic[:tap] + if tap + iface_mac = nic[:mac] - net_mac = mac.join(':') + mac = iface_mac.split(':') + mac[-1] = '00' - in_rule="FORWARD -s ! #{net_mac}/ff:ff:ff:ff:ff:00 " << - "-o #{tap} -j DROP" - out_rule="FORWARD -s ! #{iface_mac} -i #{tap} -j DROP" + net_mac = mac.join(':') - ebtables(in_rule) if nic[:filter_mac_spoofing] =~ /yes/i - ebtables(out_rule) - end - end + in_rule="FORWARD -s ! #{net_mac}/ff:ff:ff:ff:ff:00 " << + "-o #{tap} -j DROP" + out_rule="FORWARD -s ! #{iface_mac} -i #{tap} -j DROP" - unlock + ebtables(in_rule) if nic[:filter_mac_spoofing] =~ /yes/i + ebtables(out_rule) + end end - return 0 + unlock + + 0 end def deactivate diff --git a/src/vnm_mad/remotes/ebtables/pre b/src/vnm_mad/remotes/ebtables/pre index b65174c3843..dff731119be 100755 --- a/src/vnm_mad/remotes/ebtables/pre +++ b/src/vnm_mad/remotes/ebtables/pre @@ -26,4 +26,4 @@ deploy_id = ARGV[0] xpath_filter = EbtablesVLAN::XPATH_FILTER onevlan = EbtablesVLAN.from_base64(template64, xpath_filter, deploy_id) -onevlan.activate(pre_action=true) +onevlan.activate diff --git a/src/vnm_mad/remotes/lib/nic.rb b/src/vnm_mad/remotes/lib/nic.rb index edc9e84f641..ac7b8d787d2 100644 --- a/src/vnm_mad/remotes/lib/nic.rb +++ b/src/vnm_mad/remotes/lib/nic.rb @@ -14,6 +14,8 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +require 'open3' + module VNMMAD module VNMNetwork @@ -110,12 +112,17 @@ def get_info(vm) end if deploy_id && vm.vm_info[:dumpxml].nil? - cmd = "lxc config show #{deploy_id} 2>/dev/null" + cmd = "lxc config show #{deploy_id}" + + config, e, s = Open3.capture3(cmd) - config = YAML.safe_load(`#{cmd}`) - config = YAML.safe_load(`sudo #{cmd}`) if config.nil? + if s.exitstatus != 0 && e.include?('cannot create'\ + 'user data directory') + cmd.prepend('sudo') + config, _e, _s = Open3.capture3(cmd) + end - vm.vm_info[:dumpxml] = config + vm.vm_info[:dumpxml] = YAML.safe_load(config) vm.vm_info.each_key do |k| vm.vm_info[k] = nil if vm.vm_info[k].to_s.strip.empty? diff --git a/src/vnm_mad/remotes/lib/vm.rb b/src/vnm_mad/remotes/lib/vm.rb index 4a32ea5978b..de3586857ee 100644 --- a/src/vnm_mad/remotes/lib/vm.rb +++ b/src/vnm_mad/remotes/lib/vm.rb @@ -16,100 +16,104 @@ module VNMMAD -module VNMNetwork + module VNMNetwork - ############################################################################ - # This class represents the VM abstraction. It provides basic methods - # to interact with its network interfaces. - ############################################################################ - class VM - attr_accessor :nics, :vm_info, :deploy_id, :vm_root + ######################################################################## + # This class represents the VM abstraction. It provides basic methods + # to interact with its network interfaces. + ######################################################################## + class VM + attr_accessor :nics, :vm_info, :deploy_id, :vm_root - # Creates a new VM object, and bootstrap the NICs array - # @param vm_root [REXML] XML document representing the VM - # @param xpath_filer [String] to get the VM NICs - # @param deploy_id [String] refers to the VM in the hypervisor - def initialize(vm_root, xpath_filter, deploy_id) - @vm_root = vm_root - @deploy_id = deploy_id + # Creates a new VM object, and bootstrap the NICs array + # @param vm_root [REXML] XML document representing the VM + # @param xpath_filer [String] to get the VM NICs + # @param deploy_id [String] refers to the VM in the hypervisor + def initialize(vm_root, xpath_filter, deploy_id) + @vm_root = vm_root + @deploy_id = deploy_id - @vm_info = Hash.new + @vm_info = {} - @deploy_id = nil if deploy_id == "-" + @deploy_id = nil if deploy_id == '-' - nics = VNMNetwork::Nics.new(hypervisor) + nics = VNMNetwork::Nics.new(hypervisor) - @vm_root.elements.each(xpath_filter) do |nic_element| - nic = nics.new_nic + @vm_root.elements.each(xpath_filter) do |nic_element| + nic = nics.new_nic - nic_build_hash(nic_element,nic) + nic_build_hash(nic_element, nic) - nic.get_info(self) - nic.get_tap(self) + if !VNMMAD.pre_action? + nic.get_info(self) + nic.get_tap(self) + end + + nics << nic + end - nics << nic + @nics = nics end - @nics = nics - end + # Iterator on each NIC of the VM + def each_nic(block) + return if @nics.nil? - # Iterator on each NIC of the VM - def each_nic(block) - if @nics != nil @nics.each do |the_nic| block.call(the_nic) end end - end - # Access an XML Element of the VM - # @param element [String] element name - # @return [String] value of the element or nil if not found - def [](element) - if @vm_root - val = @vm_root.elements[element] - return val.text if !val.nil? && val.text - end + # Access an XML Element of the VM + # @param element [String] element name + # @return [String] value of the element or nil if not found + def [](element) + if @vm_root + val = @vm_root.elements[element] + return val.text if !val.nil? && val.text + end - nil - end + nil + end - # Gets the Hypervisor VM_MAD from the Template - # @return [String] name of the hypervisor driver - def hypervisor - xpath = 'HISTORY_RECORDS/HISTORY/VM_MAD' - @vm_root.root.elements[xpath].text - end + # Gets the Hypervisor VM_MAD from the Template + # @return [String] name of the hypervisor driver + def hypervisor + xpath = 'HISTORY_RECORDS/HISTORY/VM_MAD' + @vm_root.root.elements[xpath].text + end - private + private - # Method to build the associated Hash from a NIC - # @param nic_element [REXML] for the NIC - # @param nic [Nic] class representation - def nic_build_hash(nic_element,nic) - nic_element.elements.each('*') do |nic_attribute| - key = nic_attribute.name.downcase.to_sym + # Method to build the associated Hash from a NIC + # @param nic_element [REXML] for the NIC + # @param nic [Nic] class representation + def nic_build_hash(nic_element, nic) + nic_element.elements.each('*') do |nic_attribute| + key = nic_attribute.name.downcase.to_sym - if nic_attribute.has_elements? - data = {} - nic_build_hash(nic_attribute,data) - else - data = nic_attribute.text - end + if nic_attribute.has_elements? + data = {} + nic_build_hash(nic_attribute, data) + else + data = nic_attribute.text + end - if nic[key] - if nic[key].instance_of?(Array) - nic[key] << data + if nic[key] + if nic[key].instance_of?(Array) + nic[key] << data + else + nic[key] = [nic[key], data] + end else - nic[key] = [nic[key], data] + nic[key] = data end - else - nic[key] = data end end + end + end -end end diff --git a/src/vnm_mad/remotes/lib/vnm_driver.rb b/src/vnm_mad/remotes/lib/vnm_driver.rb index 3b071604693..a0f9d3c2a9e 100644 --- a/src/vnm_mad/remotes/lib/vnm_driver.rb +++ b/src/vnm_mad/remotes/lib/vnm_driver.rb @@ -188,5 +188,12 @@ def self.parse_options(string) options end + + # Returns true if the driver is executing action pre + def self.pre_action? + File.basename($PROGRAM_NAME) == 'pre' + end + end + end diff --git a/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb b/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb index 1bd32f253e5..b0f42a2282b 100644 --- a/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb +++ b/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb @@ -34,7 +34,7 @@ def initialize(vm, xpath_filter = nil, deploy_id = nil) end end - def activate(pre_action=false) + def activate lock @bridges = get_bridges @@ -65,13 +65,11 @@ def activate(pre_action=false) # In net/pre action, we just need to ensure the bridge is # created so the libvirt/QEMU can add VM interfaces into that. # Any other driver actions are done in net/post action. - if pre_action - next - else - STDERR.puts "No tap device found for nic #{@nic[:nic_id]}" - unlock - exit 1 - end + next if VNMMAD.pre_action? + + STDERR.puts "No tap device found for nic #{@nic[:nic_id]}" + unlock + exit 1 end # Apply VLAN diff --git a/src/vnm_mad/remotes/ovswitch/pre b/src/vnm_mad/remotes/ovswitch/pre index fcb00cf73c8..a78b6953c27 100755 --- a/src/vnm_mad/remotes/ovswitch/pre +++ b/src/vnm_mad/remotes/ovswitch/pre @@ -27,4 +27,4 @@ xpath_filter = OpenvSwitchVLAN::XPATH_FILTER ovs = OpenvSwitchVLAN.from_base64(template64, xpath_filter, deploy_id) -ovs.activate(pre_action=true) +ovs.activate diff --git a/src/vnm_mad/remotes/ovswitch_vxlan/pre b/src/vnm_mad/remotes/ovswitch_vxlan/pre index b5a22c5cf4b..6f5748590b4 100755 --- a/src/vnm_mad/remotes/ovswitch_vxlan/pre +++ b/src/vnm_mad/remotes/ovswitch_vxlan/pre @@ -27,4 +27,4 @@ xpath_filter = OpenvSwitchVXLAN::XPATH_FILTER ovs = OpenvSwitchVXLAN.from_base64(template64, xpath_filter, deploy_id) -ovs.activate(pre_action=true) +ovs.activate