Hello community,

here is the log from the commit of package yast2-network for openSUSE:Factory 
checked in at 2016-05-23 16:36:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-network (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-network.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-network"

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-network/yast2-network.changes      
2016-05-10 09:24:57.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-network.new/yast2-network.changes 
2016-05-23 16:36:10.000000000 +0200
@@ -1,0 +2,22 @@
+Tue May 17 16:04:49 UTC 2016 - [email protected]
+
+- bnc#971175
+  - /etc/hosts is correctly updated with static address, hostname
+    when static net configuration is done via linuxrc and hostname
+    is provided by AY profile
+- 3.1.151
+
+-------------------------------------------------------------------
+Fri May 13 10:19:39 UTC 2016 - [email protected]
+
+- fate#315995
+  - Added physical port id to device overview and bond slaves item
+    description if supported.
+  - Warn the user when two or more bonded interfaces share the
+    same physical port.
+  - Available interfaces for bonding in bond slaves tab are now
+    sorted and moving them up or down maintain the interface
+    selected.
+- 3.1.150
+
+-------------------------------------------------------------------

Old:
----
  yast2-network-3.1.149.tar.bz2

New:
----
  yast2-network-3.1.151.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-network.spec ++++++
--- /var/tmp/diff_new_pack.imYbXS/_old  2016-05-23 16:36:11.000000000 +0200
+++ /var/tmp/diff_new_pack.imYbXS/_new  2016-05-23 16:36:11.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-network
-Version:        3.1.149
+Version:        3.1.151
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build

++++++ yast2-network-3.1.149.tar.bz2 -> yast2-network-3.1.151.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/package/yast2-network.changes 
new/yast2-network-3.1.151/package/yast2-network.changes
--- old/yast2-network-3.1.149/package/yast2-network.changes     2016-05-04 
21:43:30.000000000 +0200
+++ new/yast2-network-3.1.151/package/yast2-network.changes     2016-05-17 
18:24:00.000000000 +0200
@@ -1,4 +1,26 @@
 -------------------------------------------------------------------
+Tue May 17 16:04:49 UTC 2016 - [email protected]
+
+- bnc#971175
+  - /etc/hosts is correctly updated with static address, hostname
+    when static net configuration is done via linuxrc and hostname
+    is provided by AY profile
+- 3.1.151
+
+-------------------------------------------------------------------
+Fri May 13 10:19:39 UTC 2016 - [email protected]
+
+- fate#315995
+  - Added physical port id to device overview and bond slaves item
+    description if supported.
+  - Warn the user when two or more bonded interfaces share the
+    same physical port.
+  - Available interfaces for bonding in bond slaves tab are now
+    sorted and moving them up or down maintain the interface
+    selected.
+- 3.1.150
+
+-------------------------------------------------------------------
 Mon May  2 11:35:45 UTC 2016 - [email protected]
 
 - bnc#977953
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/package/yast2-network.spec 
new/yast2-network-3.1.151/package/yast2-network.spec
--- old/yast2-network-3.1.149/package/yast2-network.spec        2016-05-04 
21:43:30.000000000 +0200
+++ new/yast2-network-3.1.151/package/yast2-network.spec        2016-05-17 
18:24:00.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-network
-Version:        3.1.149
+Version:        3.1.151
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/src/clients/save_network.rb 
new/yast2-network-3.1.151/src/clients/save_network.rb
--- old/yast2-network-3.1.149/src/clients/save_network.rb       2016-05-04 
21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/src/clients/save_network.rb       2016-05-17 
18:24:00.000000000 +0200
@@ -36,8 +36,6 @@
     include Logger
 
     def main
-      Yast.import "UI"
-
       textdomain "network"
 
       Yast.import "DNS"
@@ -86,6 +84,8 @@
     SYSCONFIG = "/etc/sysconfig/network/"
 
     def CopyConfiguredNetworkFiles
+      return if Mode.autoinst && !NetworkAutoYast.instance.keep_net_config?
+
       log.info(
         "Copy network configuration files from 1st stage into installed system"
       )
@@ -247,15 +247,28 @@
       nil
     end
 
+    # Creates target's default DNS configuration
+    #
+    # It uses DNS configuration as defined in AY profile (if any) or
+    # proposes a predefined default values.
+    def configure_dns
+      configured = false
+      configured = NetworkAutoYast.instance.configure_dns if Mode.autoinst
+      NetworkAutoconfiguration.instance.configure_dns if !configured
+
+      DNS.create_hostname_link
+    end
+
     # It does an automatic configuration of installed system
     #
     # Basically, it runs several proposals.
     def configure_target
       NetworkAutoconfiguration.instance.configure_virtuals
-      NetworkAutoconfiguration.instance.configure_dns
-      NetworkAutoconfiguration.instance.configure_hosts
 
-      DNS.create_hostname_link
+      configure_dns
+
+      # this depends on DNS configuration
+      NetworkAutoconfiguration.instance.configure_hosts
 
       set_network_service
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-network-3.1.149/src/include/network/lan/address.rb 
new/yast2-network-3.1.151/src/include/network/lan/address.rb
--- old/yast2-network-3.1.149/src/include/network/lan/address.rb        
2016-05-04 21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/src/include/network/lan/address.rb        
2016-05-17 18:24:00.000000000 +0200
@@ -28,6 +28,8 @@
 #
 module Yast
   module NetworkLanAddressInclude
+    include Yast::Logger
+
     def initialize_network_lan_address(include_target)
       Yast.import "UI"
 
@@ -226,8 +228,8 @@
           "help"          => Ops.get_string(@help, "etherdevice", "")
         },
         "BONDSLAVE"    => {
-          "widget"        => :custom,
-          "custom_widget" => Frame(
+          "widget"            => :custom,
+          "custom_widget"     => Frame(
             _("Bond Slaves and Order"),
             VBox(
               MultiSelectionBox(Id(:msbox_items), Opt(:notify), "", []),
@@ -237,18 +239,23 @@
               )
             )
           ),
-          "label"         => _("Bond &Slaves"),
+          "label"             => _("Bond &Slaves"),
           #        "opt": [`shrinkable],
-          "init"          => fun_ref(
+          "init"              => fun_ref(
             method(:InitSlave),
             "void (string)"
           ),
-          "handle"        => fun_ref(
+          "handle"            => fun_ref(
             method(:HandleSlave),
             "symbol (string, map)"
           ),
-          "store"         => fun_ref(method(:StoreSlave), "void (string, 
map)"),
-          "help"          => Ops.get_string(@help, "bondslave", "")
+          "validate_type"     => :function,
+          "validate_function" => fun_ref(
+            method(:validate_bond),
+            "boolean (string, map)"
+          ),
+          "store"             => fun_ref(method(:StoreSlave), "void (string, 
map)"),
+          "help"              => @help["bondslave"].to_s
         },
         "BONDOPTION"   => {
           "widget" => :combobox,
@@ -576,22 +583,14 @@
       nil
     end
 
+    # Given a device name returns the position in the bond slaves table
+    # or -1 if not present
+    #
+    # @param [String] slave name
+    # @return [Integer] index of the given slave in msbox_items table
     def getISlaveIndex(slave)
-      items = Convert.convert(
-        UI.QueryWidget(:msbox_items, :Items),
-        from: "any",
-        to:   "list <term>"
-      )
-      index = -1
-      pos = 0
-      Builtins.foreach(items) do |it|
-        if Ops.get_string(it, [0, 0], "") == slave
-          index = pos
-          raise Break
-        end
-        pos = Ops.add(pos, 1)
-      end
-      index
+      items = UI.QueryWidget(:msbox_items, :Items)
+      items.index { |i| i[0][0] == slave } || -1
     end
 
     def enableSlaveButtons
@@ -615,14 +614,14 @@
     # Default function to init the value of slave devices box for bonding.
     # @param [String] key      id of the widget
     def InitSlave(_key)
-      Ops.set(@settings, "SLAVES", LanItems.bond_slaves)
+      @settings["SLAVES"] =  LanItems.bond_slaves || []
       UI.ChangeWidget(
         :msbox_items,
         :SelectedItems,
-        Ops.get_list(@settings, "SLAVES", [])
+        @settings["SLAVES"]
       )
 
-      Ops.set(@settings, "BONDOPTION", LanItems.bond_option)
+      @settings["BONDOPTION"] = LanItems.bond_option
 
       items = CreateSlaveItems(
         LanItems.GetBondableInterfaces(LanItems.GetCurrentName),
@@ -630,95 +629,59 @@
       )
 
       # reorder the items
-      l2 = []
-      l1 = []
-      Builtins.foreach(
-        Convert.convert(items, from: "list", to: "list <term>")
-      ) do |t|
-        if Builtins.contains(
-          Ops.get_list(@settings, "SLAVES", []),
-          Ops.get_string(t, [0, 0], "")
-          )
-          l1 = Builtins.add(l1, t)
-        else
-          l2 = Builtins.add(l2, t)
-        end
-      end
+      l1, l2 = items.partition { |t| @settings["SLAVES"].include? t[0][0] }
 
-      items = []
-      Builtins.foreach(Ops.get_list(@settings, "SLAVES", [])) do |s|
-        Builtins.foreach(
-          Convert.convert(l1, from: "list", to: "list <term>")
-        ) do |t|
-          items = Builtins.add(items, t) if Ops.get_string(t, [0, 0], "") == s
-        end
-      end
+      items = l1 + l2.sort_by { |t| justify_dev_name(t[0][0]) }
 
-      items = Builtins.union(items, l2)
       UI.ChangeWidget(:msbox_items, :Items, items)
       enableSlaveButtons
 
       nil
     end
 
+    # A helper for sort devices by name. It justify at right with 0's numeric 
parts of given
+    # device name until 5 digits.
+    #
+    # ==== Examples
+    #
+    #   justify_dev_name("eth0") # => "eth00000"
+    #   justify_dev_name("eth111") # => "eth00111"
+    #   justify_dev_name("enp0s25") # => "enp00000s00025"
+    #
+    # @param name [String] device name
+    # @return [String] given name with numbers justified at right
+    def justify_dev_name(name)
+      splited_dev_name = name.scan(/\p{Alpha}+|\p{Digit}+/)
+      splited_dev_name.map! do |d|
+        if d.match(/\p{Digit}+/)
+          d.rjust(5, "0")
+        else
+          d
+        end
+      end.join
+    end
+
     def HandleSlave(_key, event)
-      event = deep_copy(event)
-      if Ops.get_string(event, "EventReason", "") == "SelectionChanged"
+      if event["EventReason"] == "SelectionChanged"
         enableSlaveButtons
-      elsif Ops.get_string(event, "EventReason", "") == "Activated" &&
-          Ops.get(event, "WidgetClass") == :PushButton
-        items = Convert.convert(
-          UI.QueryWidget(:msbox_items, :Items),
-          from: "any",
-          to:   "list <term>"
-        )
-        current = Builtins.tostring(UI.QueryWidget(:msbox_items, :CurrentItem))
+      elsif event["EventReason"] == "Activated" && event["WidgetClass"] == 
:PushButton
+        items = UI.QueryWidget(:msbox_items, :Items) || []
+        current = UI.QueryWidget(:msbox_items, :CurrentItem).to_s
         index = getISlaveIndex(current)
-        new_items = []
-        pos = 0
-        case Ops.get_symbol(event, "ID", :nil)
+        case event["ID"]
         when :up
-          while Ops.greater_than(index, Ops.add(pos, 1))
-            new_items = Builtins.add(new_items, Ops.get(items, pos))
-            pos = Ops.add(pos, 1)
-          end
-          new_items = Builtins.add(new_items, Ops.get(items, index))
-          new_items = Builtins.add(
-            new_items,
-            Ops.get(items, Ops.subtract(index, 1))
-          )
-          new_items = Convert.convert(
-            Builtins.union(new_items, Builtins.sublist(items, index)),
-            from: "list",
-            to:   "list <term>"
-          )
+          items[index], items[index - 1] = items[index - 1], items[index]
         when :down
-          while Ops.greater_than(index, pos)
-            new_items = Builtins.add(new_items, Ops.get(items, pos))
-            pos = Ops.add(pos, 1)
-          end
-          new_items = Builtins.add(
-            new_items,
-            Ops.get(items, Ops.add(index, 1))
-          )
-          new_items = Builtins.add(new_items, Ops.get(items, index))
-          new_items = Convert.convert(
-            Builtins.union(
-              new_items,
-              Builtins.sublist(items, Ops.add(index, 1))
-            ),
-            from: "list",
-            to:   "list <term>"
-          )
+          items[index], items[index + 1] = items[index + 1], items[index]
         else
-          Builtins.y2warning("unknown action")
+          log.warn("unknown action")
           return nil
         end
-        items = deep_copy(new_items)
         UI.ChangeWidget(:msbox_items, :Items, items)
+        UI.ChangeWidget(:msbox_items, :CurrentItem, current)
         enableSlaveButtons
       else
-        Builtins.y2debug("event:%1", event)
+        log.debug("event:#{event}")
       end
 
       nil
@@ -728,36 +691,70 @@
     # @param [String] key      id of the widget
     # @param [String] key id of the widget
     def StoreSlave(_key, _event)
-      configured_slaves = Ops.get_list(@settings, "SLAVES", [])
+      configured_slaves = @settings["SLAVES"] || []
 
-      Ops.set(
-        @settings,
-        "SLAVES",
-        Convert.convert(
-          UI.QueryWidget(:msbox_items, :SelectedItems),
-          from: "any",
-          to:   "list <string>"
-        )
-      )
-      Ops.set(@settings, "BONDOPTION", UI.QueryWidget(Id("BONDOPTION"), 
:Value))
+      @settings["SLAVES"] = get_selected_slaves
 
-      LanItems.bond_slaves = Ops.get_list(@settings, "SLAVES", [])
-      LanItems.bond_option = Ops.get_string(@settings, "BONDOPTION", "")
+      @settings["BONDOPTION"] = UI.QueryWidget(Id("BONDOPTION"), :Value).to_s
+
+      LanItems.bond_slaves = @settings["SLAVES"]
+      LanItems.bond_option = @settings["BONDOPTION"]
 
       # create list of "unconfigured" slaves
-      new_slaves = Builtins.filter(Ops.get_list(@settings, "SLAVES", [])) do 
|slave|
-        !Builtins.contains(configured_slaves, slave)
+      new_slaves = @settings["SLAVES"].select do |slave|
+        !configured_slaves.include? slave
       end
 
-      Lan.bond_autoconf_slaves = Convert.convert(
-        Builtins.toset(Builtins.merge(Lan.bond_autoconf_slaves, new_slaves)),
-        from: "list",
-        to:   "list <string>"
-      )
+      Lan.bond_autoconf_slaves = (Lan.bond_autoconf_slaves + 
new_slaves).uniq.sort
 
       nil
     end
 
+    # Validates created bonding. Currently just prevent the user to create a
+    # bond with more than one interface sharing the same physical port id
+    #
+    # @param [String] key the widget being validated
+    # @param [Hash] event the event being handled
+    # @return true if valid or user decision if not
+    def validate_bond(_key, _event)
+      physical_ports = repeated_physical_port_ids(get_selected_slaves)
+
+      physical_ports.empty? ? true : continue_with_duplicates?(physical_ports)
+    end
+
+    # FIXME: This method should be moved to a more generic class.
+    # Wrap given text breaking lines longer than given wrap size. It supports
+    # custom separator, max number of lines to split in and cut text to add
+    # as last line if cut was needed.
+    #
+    # @param [String] text to be wrapped
+    # @param [String] wrap size
+    # @param [Hash <String>] optional parameters as separator and prepend_text.
+    # @return [String] wrap text
+    def wrap_text(text, wrap = 78, separator: " ", prepend_text: "",
+                  n_lines: nil, cut_text: nil)
+      lines = []
+      message_line = prepend_text
+      text.split(/\s+/).each_with_index do |t, i|
+        if !message_line.empty? && "#{message_line}#{t}".size > wrap
+          lines << message_line
+          message_line = ""
+        end
+
+        message_line << separator if !message_line.empty? && i != 0
+        message_line << t
+      end
+
+      lines << message_line if !message_line.empty?
+
+      if n_lines && lines.size > n_lines
+        lines = lines[0..n_lines - 1]
+        lines << cut_text if cut_text
+      end
+
+      lines.join("\n")
+    end
+
     def initTunnel(_key)
       Builtins.y2internal("initTunnel %1", @settings)
       UI.ChangeWidget(
@@ -1600,5 +1597,52 @@
 
       deep_copy(ret)
     end
+
+  private
+
+    def get_selected_slaves
+      UI.QueryWidget(:msbox_items, :SelectedItems) || []
+    end
+
+    # Given a map of duplicated port ids with device names, aks the user if he
+    # would like to continue or not.
+    #
+    # @param [Hash{String => Array<String>}] hash of duplicated physical port 
ids
+    # mapping to an array of device names
+    # @return [Boolean] true if continue with duplicates, otherwise false
+    def continue_with_duplicates?(physical_ports)
+      message = physical_ports.map do |port, slave|
+        label =  "PhysicalPortID (#{port}): "
+        wrap_text(slave.join(", "), 76, prepend_text: label)
+      end.join("\n")
+
+      Popup.YesNoHeadline(
+        Label.WarningMsg,
+        # Translators: Warn the user about not desired effect
+        _("The interfaces selected share the same physical port and bonding " \
+          "them \nmay not have the desired effect of redundancy.\n\n%s\n\n" \
+          "Really continue?\n") % message
+      )
+    end
+
+    # Given a list of device names returns a hash of physical port ids mapping
+    # device names if at least two devices shared the same physical port id
+    #
+    # @param [Array<String] bonding slaves
+    # @return [Hash{String => Array<String>}] of duplicated physical port ids
+    def repeated_physical_port_ids(slaves)
+      physical_port_ids = {}
+
+      slaves.each do |slave|
+        if physical_port_id?(slave)
+          p = physical_port_ids[physical_port_id(slave)] ||= []
+          p << slave
+        end
+      end
+
+      physical_port_ids.select! { |_k, v| v.size > 1 }
+
+      physical_port_ids
+    end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-network-3.1.149/src/include/network/routines.rb 
new/yast2-network-3.1.151/src/include/network/routines.rb
--- old/yast2-network-3.1.149/src/include/network/routines.rb   2016-05-04 
21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/src/include/network/routines.rb   2016-05-17 
18:24:00.000000000 +0200
@@ -746,6 +746,25 @@
       ).to_i != 0
     end
 
+    # With NPAR and SR-IOV capabilities, one device could divide a ethernet
+    # port in various. If the driver module support it, we can check the phys
+    # port id via sysfs reading the /sys/class/net/$dev_name/phys_port_id
+    #
+    # @param [String] device name to check
+    # @return [String] physical port id if supported or a empty string if not
+    def physical_port_id(dev_name)
+      SCR.Read(
+        path(".target.string"),
+        "/sys/class/net/#{dev_name}/phys_port_id"
+      ).to_s.strip
+    end
+
+    # @return [boolean] true if the physical port id is not empty
+    # @see #physical_port_id
+    def physical_port_id?(dev_name)
+      !physical_port_id(dev_name).empty?
+    end
+
     # Checks if device is physically connected to a network
     #
     # It does neccessary steps which might be needed for proper initialization
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/src/include/network/widgets.rb 
new/yast2-network-3.1.151/src/include/network/widgets.rb
--- old/yast2-network-3.1.149/src/include/network/widgets.rb    2016-05-04 
21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/src/include/network/widgets.rb    2016-05-17 
18:24:00.000000000 +0200
@@ -574,6 +574,8 @@
         selected = false
         selected = enslavedIfaces.include?(dev_name) if enslavedIfaces
 
+        description << " (Port ID: #{physical_port_id(dev_name)})" if 
physical_port_id?(dev_name)
+
         items << Item(
           Id(dev_name),
           "#{dev_name} - #{description}",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-network-3.1.149/src/lib/network/network_autoyast.rb 
new/yast2-network-3.1.151/src/lib/network/network_autoyast.rb
--- old/yast2-network-3.1.149/src/lib/network/network_autoyast.rb       
2016-05-04 21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/src/lib/network/network_autoyast.rb       
2016-05-17 18:24:00.000000000 +0200
@@ -104,6 +104,37 @@
       NetworkService.EnableDisableNow
     end
 
+    # Initializates DNS setup according AY profile
+    #
+    # FIXME: it currently doesn't write DNS configuration. It is used for 
initialization
+    # of DNS setup according AY profile in 1st stage as part of network setup 
was moved
+    # here already and some parts of network configuration needs to know it. 
DNS write
+    # is still done in 2nd stage.
+    #
+    # @return [Boolean] true when configuration was present and loaded from 
the profile
+    def configure_dns
+      ay_dns_config = ay_networking_section["dns"]
+
+      return false if !ay_dns_config
+
+      DNS.Import(ay_dns_config)
+
+      log.info("NetworkAutoYast: DNS / Hostname configuration")
+      log.info("dhcp hostname: #{DNS.dhcp_hostname}")
+      log.info("write hostname: #{DNS.write_hostname}")
+
+      true
+    end
+
+    # Checks if the profile asks for keeping installation network configuration
+    def keep_net_config?
+      ret = ay_networking_section.fetch("keep_install_network", false)
+
+      log.info("NetworkAutoYast: keep installation network: #{ret}")
+
+      ret
+    end
+
   private
 
     # Merges two devices map into one.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/src/modules/LanItems.rb 
new/yast2-network-3.1.151/src/modules/LanItems.rb
--- old/yast2-network-3.1.149/src/modules/LanItems.rb   2016-05-04 
21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/src/modules/LanItems.rb   2016-05-17 
18:24:00.000000000 +0200
@@ -813,7 +813,7 @@
 
       result = []
 
-      Builtins.foreach(@Items) do |itemId, _attribs|
+      LanItems.Items.each do |itemId, _attribs|
         if @current != itemId && validator.call(master, itemId)
           result = Builtins.add(result, itemId)
         else
@@ -1407,9 +1407,11 @@
 
         mac_dev = HTML.Bold("MAC : ") + item_hwinfo["mac"].to_s + "<br>"
         bus_id  = HTML.Bold("BusID : ") + item_hwinfo["busid"].to_s + "<br>"
+        physical_port_id = HTML.Bold("PhysicalPortID : ") + 
physical_port_id(ifcfg_name) + "<br>"
 
         rich << " " << conn << "<br>" << mac_dev if 
IsNotEmpty(item_hwinfo["mac"])
         rich << bus_id if IsNotEmpty(item_hwinfo["busid"])
+        rich << physical_port_id if physical_port_id?(ifcfg_name)
         # display it only if we need it, don't duplicate "ifcfg_name" above
         if IsNotEmpty(item_hwinfo["dev_name"]) && ifcfg_name.empty?
           dev_name = _("Device Name: %s") %  item_hwinfo["dev_name"]
@@ -2284,7 +2286,7 @@
         SCR.Execute(path(".target.bash_output"), command1),
         from: "any",
         to:   "map <string, any>"
-      )
+    )
       if Ops.get_integer(output1, "exit", -1) == 0 &&
           Builtins.size(Ops.get_string(output1, "stderr", "")) == 0
         Builtins.y2milestone("Success : %1", output1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/test/address_test.rb 
new/yast2-network-3.1.151/test/address_test.rb
--- old/yast2-network-3.1.149/test/address_test.rb      1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-network-3.1.151/test/address_test.rb      2016-05-17 
18:24:00.000000000 +0200
@@ -0,0 +1,131 @@
+#!/usr/bin/env rspec
+
+require_relative "test_helper"
+
+Yast.import "UI"
+
+class DummyClass < Yast::Module
+  def initialize
+    Yast.include self, "network/lan/address.rb"
+  end
+end
+
+describe "NetworkLanAddressInclude" do
+  subject { DummyClass.new }
+
+  describe "#justify_dev_name" do
+
+    it "returns given device name justified by 0's at right" do
+      expect(subject.justify_dev_name("em5p1")).to eq("em00005p00001")
+    end
+
+  end
+
+  describe "wrap_text" do
+    subject(:routines) { DummyClass.new }
+    let(:devices) { ["eth0", "eth1", "eth2", "eth3", 
"a_very_long_device_name"] }
+    let(:more_devices) do
+      [
+        "enp5s0", "enp5s1", "enp5s2", "enp5s3",
+        "enp5s4", "enp5s5", "enp5s6", "enp5s7"
+      ]
+    end
+
+    context "given a text" do
+      it "returns same text if it does not exceed wrap size" do
+        text = "eth0, eth1, eth2, eth3, a_very_long_device_name"
+
+        expect(routines.wrap_text(devices.join(", "))).to eql(text)
+      end
+
+      context "given a line size" do
+        it "returns given text splitted in lines by given line size" do
+          text = "eth0, eth1, eth2,\n"     \
+                 "eth3,\n"                 \
+                 "a_very_long_device_name"
+
+          expect(routines.wrap_text(devices.join(", "), 16)).to eql(text)
+        end
+      end
+
+      context "given a number of lines and '...' as cut text" do
+        it "returns wrapped text until given line's number adding '...' as a 
new line" do
+          devices_s = (devices + more_devices).join(", ")
+          text = "eth0, eth1, eth2,\n"        \
+                 "eth3,\n"                    \
+                 "a_very_long_device_name,\n" \
+                 "..."
+
+          expect(routines.wrap_text(devices_s, 20, n_lines: 3, cut_text: 
"...")).to eql(text)
+        end
+      end
+
+    end
+  end
+
+  describe "#getISlaveIndex" do
+    let(:msbox_items) do
+      [
+        Yast::Term.new(:item, Yast::Term.new(:id, "eth0")),
+        Yast::Term.new(:item, Yast::Term.new(:id, "eth1")),
+        Yast::Term.new(:item, Yast::Term.new(:id, "eth1.5")),
+        Yast::Term.new(:item, Yast::Term.new(:id, "eth2"))
+      ]
+    end
+
+    before do
+      allow(Yast::UI).to receive(:QueryWidget).with(:msbox_items, 
:Items).and_return(msbox_items)
+    end
+
+    it "returns the index position of the given slave in the mbox_items table" 
do
+      expect(subject.getISlaveIndex("eth2")).to eql(3)
+      expect(subject.getISlaveIndex("eth1.5")).to eql(2)
+    end
+
+    it "returns -1 in case the slave is not in the msbox_items table" do
+      expect(subject.getISlaveIndex("eth4")).to eql(-1)
+    end
+  end
+
+  describe "#validate_bond" do
+    before do
+      allow(Yast::UI).to receive(:QueryWidget)
+        .with(:msbox_items, :SelectedItems)
+        .and_return(msbox_items)
+    end
+
+    context "when there is not more than one physical port id per interface" do
+      let(:msbox_items) { ["eth0", "eth1", "eth2", "eth3"] }
+
+      it "returns true" do
+        allow(subject).to 
receive(:physical_port_id?).with("eth0").and_return(false)
+        allow(subject).to 
receive(:physical_port_id?).with("eth1").and_return(false)
+        allow(subject).to 
receive(:physical_port_id?).with("eth2").and_return(true)
+        allow(subject).to 
receive(:physical_port_id?).with("eth3").and_return(true)
+        allow(subject).to 
receive(:physical_port_id).with("eth2").and_return("00010486fd348")
+        allow(subject).to 
receive(:physical_port_id).with("eth3").and_return("00010486fd34a")
+
+        expect(subject.validate_bond("key", "Event")).to eql(true)
+      end
+    end
+
+    context "when there is more than one physical port id per interface" do
+      let(:msbox_items) do
+        ["eth0", "eth1", "eth2", "eth3", "eth4", "eth5", "eth6", "eth7",
+         "enp0sp25", "enp0sp26", "enp0sp27", "enp0sp28", "enp0sp29"]
+      end
+
+      it "warns the user and request confirmation to continue" do
+        msbox_items.map do |i|
+          allow(subject).to 
receive(:physical_port_id?).with(i).and_return(true)
+          allow(subject).to 
receive(:physical_port_id).with(i).and_return("00010486fd348")
+        end
+
+        expect(Yast::Popup).to 
receive(:YesNoHeadline).and_return(:request_answer)
+
+        expect(subject.validate_bond("key", "Event")).to eql(:request_answer)
+      end
+    end
+  end
+
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/test/network_autoyast_test.rb 
new/yast2-network-3.1.151/test/network_autoyast_test.rb
--- old/yast2-network-3.1.149/test/network_autoyast_test.rb     2016-05-04 
21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/test/network_autoyast_test.rb     2016-05-17 
18:24:00.000000000 +0200
@@ -209,6 +209,47 @@
     end
   end
 
+  describe "#configure_dns" do
+    let(:network_autoyast) { Yast::NetworkAutoYast.instance }
+
+    it "imports DNS configuration when available in profile" do
+      Yast.import "DNS"
+
+      allow(network_autoyast)
+        .to receive(:ay_networking_section)
+        .and_return("dns" => { "dhcp_hostname" => false })
+
+      expect(Yast::DNS).to receive(:Import)
+
+      network_autoyast.configure_dns
+    end
+  end
+
+  describe "#keep_net_config?" do
+    let(:network_autoyast) { Yast::NetworkAutoYast.instance }
+
+    def keep_install_network_value(value)
+      allow(network_autoyast)
+        .to receive(:ay_networking_section)
+        .and_return(value)
+    end
+
+    it "succeedes when keep_install_network is set in AY profile" do
+      keep_install_network_value("keep_install_network" => true)
+      expect(network_autoyast.keep_net_config?).to be true
+    end
+
+    it "fails when keep_install_network is not set in AY profile" do
+      keep_install_network_value("keep_install_network" => false)
+      expect(network_autoyast.keep_net_config?).to be false
+    end
+
+    it "fails when keep_install_network is not present in AY profile" do
+      keep_install_network_value({})
+      expect(network_autoyast.keep_net_config?).to be false
+    end
+  end
+
   context "When AY profile contains old style name" do
     let(:ay_old_id) do
       {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.1.149/test/routines_test.rb 
new/yast2-network-3.1.151/test/routines_test.rb
--- old/yast2-network-3.1.149/test/routines_test.rb     2016-05-04 
21:43:31.000000000 +0200
+++ new/yast2-network-3.1.151/test/routines_test.rb     2016-05-17 
18:24:00.000000000 +0200
@@ -121,3 +121,38 @@
       .to match_array([Item(Id(0), "x", false), Item(Id(1), "y", true)])
   end
 end
+
+describe "physical_port_id" do
+  subject(:routines) { RoutinesTestClass.new }
+  let(:phys_port_id) { "physical_port_id" }
+
+  before do
+    allow(Yast::SCR).to receive(:Read)
+      .with(Yast::Path.new(".target.string"), 
"/sys/class/net/eth0/phys_port_id")
+      .and_return(phys_port_id)
+  end
+
+  context "when the module driver support it" do
+    it "returns ethernet physical port id" do
+      expect(routines.physical_port_id("eth0")).to eql("physical_port_id")
+    end
+  end
+
+  context "when the module driver doesn't support it" do
+    let(:phys_port_id) { nil }
+
+    it "returns an empty string" do
+      expect(routines.physical_port_id("eth0")).to be_empty
+    end
+  end
+end
+
+describe "#physical_port_id?" do
+  subject(:routines) { RoutinesTestClass.new }
+
+  it "returns true if physical port id is not empty" do
+    allow(routines).to receive(:physical_port_id).with("eth0") { 
"physical_port_id" }
+
+    expect(routines.physical_port_id?("eth0")).to eql(true)
+  end
+end


Reply via email to