Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package yast2-iscsi-client for 
openSUSE:Factory checked in at 2024-11-13 15:27:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-iscsi-client (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-iscsi-client.new.2017 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-iscsi-client"

Wed Nov 13 15:27:15 2024 rev:147 rq:1223768 version:5.0.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-iscsi-client/yast2-iscsi-client.changes    
2024-10-02 21:33:07.849748835 +0200
+++ 
/work/SRC/openSUSE:Factory/.yast2-iscsi-client.new.2017/yast2-iscsi-client.changes
  2024-11-13 15:27:20.782919264 +0100
@@ -1,0 +2,9 @@
+Thu Oct 31 11:46:26 UTC 2024 - Knut Anderssen <kanders...@suse.com>
+
+- Fixes for bsc#1231385
+   - Do not call iscsi_offload.sh script anymore using the iscsi 
+     ifaces created by autoLogOn directly and exposing them in the
+     UI instead of the offload card selection.
+- 5.0.4
+
+-------------------------------------------------------------------

Old:
----
  yast2-iscsi-client-5.0.3.tar.bz2

New:
----
  yast2-iscsi-client-5.0.4.tar.bz2

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

Other differences:
------------------
++++++ yast2-iscsi-client.spec ++++++
--- /var/tmp/diff_new_pack.whfg5o/_old  2024-11-13 15:27:22.562993616 +0100
+++ /var/tmp/diff_new_pack.whfg5o/_new  2024-11-13 15:27:22.574994118 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-iscsi-client
-Version:        5.0.3
+Version:        5.0.4
 Release:        0
 Summary:        YaST2 - iSCSI Client Configuration
 License:        GPL-2.0-only

++++++ yast2-iscsi-client-5.0.3.tar.bz2 -> yast2-iscsi-client-5.0.4.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/package/yast2-iscsi-client.changes 
new/yast2-iscsi-client-5.0.4/package/yast2-iscsi-client.changes
--- old/yast2-iscsi-client-5.0.3/package/yast2-iscsi-client.changes     
2024-10-01 16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/package/yast2-iscsi-client.changes     
2024-11-12 19:23:22.000000000 +0100
@@ -1,4 +1,13 @@
 -------------------------------------------------------------------
+Thu Oct 31 11:46:26 UTC 2024 - Knut Anderssen <kanders...@suse.com>
+
+- Fixes for bsc#1231385
+   - Do not call iscsi_offload.sh script anymore using the iscsi 
+     ifaces created by autoLogOn directly and exposing them in the
+     UI instead of the offload card selection.
+- 5.0.4
+
+-------------------------------------------------------------------
 Fri Sep 27 14:37:24 UTC 2024 - Knut Anderssen <kanders...@suse.com>
 
 - Fixes for bsc#1228084:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/package/yast2-iscsi-client.spec 
new/yast2-iscsi-client-5.0.4/package/yast2-iscsi-client.spec
--- old/yast2-iscsi-client-5.0.3/package/yast2-iscsi-client.spec        
2024-10-01 16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/package/yast2-iscsi-client.spec        
2024-11-12 19:23:22.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-iscsi-client
-Version:        5.0.3
+Version:        5.0.4
 Release:        0
 Summary:        YaST2 - iSCSI Client Configuration
 License:        GPL-2.0-only
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/src/clients/inst_iscsi-client.rb 
new/yast2-iscsi-client-5.0.4/src/clients/inst_iscsi-client.rb
--- old/yast2-iscsi-client-5.0.3/src/clients/inst_iscsi-client.rb       
2024-10-01 16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/src/clients/inst_iscsi-client.rb       
2024-11-12 19:23:22.000000000 +0100
@@ -69,12 +69,13 @@
       )
       # check initiator name, create if not exists
       IscsiClientLib.checkInitiatorName
-
-      IscsiClientLib.getiBFT
       IscsiClientLib.LoadOffloadModules
+      IscsiClientLib.getiBFT
 
       # try auto login to target
       auto_login = IscsiClientLib.autoLogOn
+      # force a read of ifaces
+      IscsiClientLib.read_ifaces if auto_login
       # force a read of sessions in case of auto_login (bsc#1228084)
       IscsiClientLib.readSessions if auto_login
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/src/include/iscsi-client/dialogs.rb 
new/yast2-iscsi-client-5.0.4/src/include/iscsi-client/dialogs.rb
--- old/yast2-iscsi-client-5.0.3/src/include/iscsi-client/dialogs.rb    
2024-10-01 16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/src/include/iscsi-client/dialogs.rb    
2024-11-12 19:23:22.000000000 +0100
@@ -83,19 +83,16 @@
           "widget"            => :custom,
           "custom_widget"     => HBox(
             MinWidth(
-              16,
+              72,
               HBox(
                 # name of iscsi client (/etc/iscsi/initiatorname.iscsi)
                 TextEntry(Id(:initiator_name), _("&Initiator Name")),
                 MinWidth(
-                  8,
+                  36,
                   ComboBox(
-                    Id(:offload_card),
+                    Id(:iface),
                     Opt(:notify),
-                    # prefer to not translate 'Offload' unless there is a well
-                    # known word for this technology (it's special hardware
-                    # shifting load from processor to card)
-                    _("Offload Car&d"),
+                    _("iSCSI I&face"),
                     []
                   )
                 )
@@ -113,10 +110,10 @@
             "symbol (string, map)"
           ),
           "handle"            => fun_ref(
-            method(:handleOffload),
+            method(:handleIface),
             "symbol (string, map)"
           ),
-          "help"              => Ops.get_string(@HELPS, "initiator_name", "")
+          "help"              => @HELPS["initiator_name"].to_s
         },
         # table of connected targets
         "connected_table"  => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/src/include/iscsi-client/helps.rb 
new/yast2-iscsi-client-5.0.4/src/include/iscsi-client/helps.rb
--- old/yast2-iscsi-client-5.0.3/src/include/iscsi-client/helps.rb      
2024-10-01 16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/src/include/iscsi-client/helps.rb      
2024-11-12 19:23:22.000000000 +0100
@@ -120,7 +120,10 @@
           ),
         "initiator_name" => _(
           "<p><b>Initiator Name</b> is a value from 
<tt>/etc/iscsi/initiatorname.iscsi</tt>. \nIn case you have iBFT, this value 
will be added from there and you are only able to change it in the BIOS 
setup.</p>"
-        ),
+        ) +
+          _(
+            "<p><b>iSCSI Iface</b> allows to select an specific iSCSI iface to 
be used for discovering targets.</p>"
+          ),
         "isns"           => _(
           "If you want to use <b>iSNS</b> (Internet  Storage  Name Service) 
for discovering targets instead of the default SendTargets method,\nfill in the 
IP address of the iSNS server and port. The default port should be 3205.\n"
         ),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/src/include/iscsi-client/widgets.rb 
new/yast2-iscsi-client-5.0.4/src/include/iscsi-client/widgets.rb
--- old/yast2-iscsi-client-5.0.3/src/include/iscsi-client/widgets.rb    
2024-10-01 16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/src/include/iscsi-client/widgets.rb    
2024-11-12 19:23:22.000000000 +0100
@@ -33,6 +33,8 @@
 
 module Yast
   module IscsiClientWidgetsInclude
+    include Logger
+
     def initialize_iscsi_client_widgets(_include_target)
       textdomain "iscsi-client"
       Yast.import "IP"
@@ -227,15 +229,10 @@
     def initInitName(_key)
       Builtins.y2milestone("initiatorname %1", IscsiClientLib.initiatorname)
       UI.ChangeWidget(:initiator_name, :Value, IscsiClientLib.initiatorname)
-      UI.ChangeWidget(:offload_card, :Items, IscsiClientLib.GetOffloadItems)
-      UI.ChangeWidget(:offload_card, :Value, IscsiClientLib.GetOffloadCard)
-      Builtins.y2milestone("OffloadCard %1", IscsiClientLib.GetOffloadCard)
-      if Ops.greater_than(
-        Builtins.size(
-          Ops.get_string(IscsiClientLib.getiBFT, "iSCSI_INITIATOR_NAME", "")
-        ),
-        0
-      )
+      UI.ChangeWidget(:iface, :Items, IscsiClientLib.iface_items)
+      UI.ChangeWidget(:iface, :Value, IscsiClientLib.selected_iface)
+      log.info "Selected Iface: #{IscsiClientLib.selected_iface}"
+      unless IscsiClientLib.getiBFT["iSCSI_INITIATOR_NAME"].to_s.empty?
         UI.ChangeWidget(:initiator_name, :Enabled, false)
         # Not sure if there is such a widget called :write
         UI.ChangeWidget(:write, :Enabled, false)
@@ -290,6 +287,10 @@
       end
     end
 
+    def iface_value
+      UI.QueryWidget(:iface, :Value).to_s
+    end
+
     def storeInitName(_key, event)
       event = deep_copy(event)
       if Convert.to_string(UI.QueryWidget(:initiator_name, :Value)) !=
@@ -304,34 +305,17 @@
         else
           Service.Restart("iscsid")
         end
-        Builtins.y2milestone(
-          "write initiatorname %1",
-          IscsiClientLib.initiatorname
-        )
-      end
-      if Convert.to_string(UI.QueryWidget(:offload_card, :Value)) !=
-          IscsiClientLib.GetOffloadCard
-        IscsiClientLib.SetOffloadCard(
-          Convert.to_string(UI.QueryWidget(:offload_card, :Value))
-        )
-        Builtins.y2milestone("OffloadCard %1", IscsiClientLib.GetOffloadCard)
+        log.info "write initiatorname #{IscsientLib.initiatorname}"
       end
+      IscsiClientLib.iface = iface_value if iface_value != 
IscsiClientLib.selected_iface
       nil
     end
 
-    def handleOffload(_key, event)
-      event = deep_copy(event)
-      if event["EventReason"] || "" == "ValueChanged" &&
-          event["ID"] || :none == :offload_card
-        if Convert.to_string(UI.QueryWidget(:offload_card, :Value)) !=
-            IscsiClientLib.GetOffloadCard
-          IscsiClientLib.SetOffloadCard(
-            Convert.to_string(UI.QueryWidget(:offload_card, :Value))
-          )
-          Builtins.y2milestone(
-            "handleOffload OffloadCard %1",
-            IscsiClientLib.GetOffloadCard
-          )
+    def handleIface(_key, event)
+      if event["EventReason"].to_s == "ValueChanged" && event["ID"] == :iface
+        if iface_value != IscsiClientLib.selected_iface
+          IscsiClientLib.iface = iface_value
+          log.info "handleIface iface: #{IscsiClientLib.selected_iface}"
         end
       end
       nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/src/modules/IscsiClientLib.rb 
new/yast2-iscsi-client-5.0.4/src/modules/IscsiClientLib.rb
--- old/yast2-iscsi-client-5.0.3/src/modules/IscsiClientLib.rb  2024-10-01 
16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/src/modules/IscsiClientLib.rb  2024-11-12 
19:23:22.000000000 +0100
@@ -43,6 +43,7 @@
     # if the binary is in /sbin or in /usr/sbin (usr-merge in openSUSE!)
     # (bsc#1196086, bsc#1196086)
     OFFLOAD_SCRIPT = "iscsi_offload".freeze
+    DISCOVERY_CMD = "iscsiadm -m discovery -P 1".freeze
 
     # Driver modules that depend on the iscsiuio service/socket
     #
@@ -57,6 +58,14 @@
 
     # Documentation for attributes that are initialized at #main
 
+    # @!attribute iface_file
+    #   Entries in the iscsi ifaces file which is initialized by 
#InitIfaceFile . Every network
+    #   interface that supports open-iscsi can have one o more iscsi ifaces 
associated with it.
+    #
+    #   Each entry associates the iscsi file name with the iscsi iface name 
which is usually the same.
+    #
+    #   @return [Hash{String => String}] ex. { 
"bnx2i.9c:dc:71:df:cf:29.ipv4.0" => "bnx2i.9c:dc:71:df:cf:29.ipv4.0"}
+    #
     # @!attribute sessions
     #   All connected nodes found via #readSessions
     #
@@ -107,7 +116,7 @@
       @discovered = []
       @targets = []
       @currentRecord = []
-      @iface_file = {}
+      @iface_file = nil
       @iface_eth = []
 
       # Content of the main configuration file (/etc/iscsi/iscsid.conf)
@@ -120,8 +129,10 @@
       @initiatorname = ""
       # map used for autoYaST
       @ay_settings = nil
-      # interface type for hardware offloading
+      # iscsi interface for hardware offloading
       @offload_card = "default"
+      # iscsi iface for discovering
+      @iface = "default"
 
       # Types of offload cards
       # [<id>, <label>, <matching_modules>, <load_modules>]
@@ -159,13 +170,10 @@
       #
       # Eg.
       # {
-      #   2 => [ ["eth4", "00:11:22:33:44:55:66", "eth4-bnx2i", "191.212.2.2"] 
],
-      #   6 => [
-      #          ["eth0", "00:...:33", "eth0-be2iscsi", "12.16.0.1"],
-      #          ["eth1", "00:...:11", "eth1-be2iscsi", "19.2.20.1"]
-      #        ]
+      #   2 => [ { "iface" => "eth4", "macaddr" =>  "00:11:22:33:44:55:66", 
"modules" => ["bnx2i"] } ],
+      #   6 => [ { "iface" => "eth0", "macaddr" => "00:....:33", "modules => 
"be2iscsi" }
+      #          { "iface" => "eth0", "macaddr" => "00:....:11", "modules => 
"be2iscsi" }]
       # }
-      #
       @offload_valid = nil
 
       # Very likely, these two instance variables should NOT be directly 
accessed everywhere in
@@ -252,14 +260,14 @@
       @offload_card
     end
 
-    def SetOffloadCard(new_card)
-      Builtins.y2milestone("SetOffloadCard:%1 cur:%2", new_card, @offload_card)
-      if new_card != @offload_card
-        @offload_card = new_card
-        CallConfigScript() if new_card != "default"
-      end
+    def selected_iface
+      @iface || "default"
+    end
 
-      nil
+    def iface=(iface)
+      return if @iface == iface
+      log.info "Changing the iface from #{iface} to #{@iface}"
+      @iface = iface
     end
 
     # Create and return complete iscsciadm command by adding the string
@@ -271,7 +279,7 @@
     #
     def GetAdmCmd(params, do_log = true)
       ret = "LC_ALL=POSIX iscsiadm #{params}"
-      Builtins.y2milestone("GetAdmCmd: #{ret}") if do_log
+      log.info("GetAdmCmd: #{ret}") if do_log
       ret
     end
 
@@ -426,14 +434,7 @@
     end
 
     def getNode
-      cmdline = GetAdmCmd(
-        Builtins.sformat(
-          "-S -m node -I %3 -T %1 -p %2",
-          Ops.get(@currentRecord, 1, "").shellescape,
-          Ops.get(@currentRecord, 0, "").shellescape,
-          Ops.get(@currentRecord, 2, "default").shellescape
-        )
-      )
+      cmdline = GetAdmCmd("-S -m node -I #{current_iface} -T #{current_target} 
-p #{current_portal}")
       cmd = SCR.Execute(path(".target.bash_output"), cmdline)
       return {} if Ops.get_integer(cmd, "exit", 0) != 0
       auth = {}
@@ -531,43 +532,39 @@
     #
     # @param data [Array<String>] output of the executed command, one array 
entry per line
     def ScanDiscovered(data)
-      data = deep_copy(data)
       ret = []
       target = ""
       portal = ""
       iface = ""
       dumped = true
-      Builtins.y2milestone("Got data: %1", data)
+      log.info "Got data: #{data}"
 
       # Each entry starts with Target:, the other two values are optional
       # (except the first entry) and, if missing, are inherited from previous
       # entry. Therefore: Dump whatever is cached on Target: entry and once
       # again at the end. Example input in the test case.
 
-      Builtins.foreach(data) do |row|
-        row = Builtins.substring(row, Builtins.findfirstnotof(row, "\t "), 999)
-        if Builtins.search(row, "Target:") != nil
+      data.each do |r|
+        row = r.strip
+        if row.include? "Target:"
           if !dumped
             # don't add Scope:Link IPv6 address
             ret << "#{portal} #{target} #{iface}" if 
!portal.start_with?("[fe80:")
           end
-          target = Ops.get(Builtins.splitstring(row, " "), 1, "")
+          target = row.split[1]
           dumped = false
-        elsif Builtins.search(row, "Portal:") != nil
-          if Builtins.search(row, "Current Portal:") != nil
-            portal = Ops.get(Builtins.splitstring(row, " "), 2, "")
-          elsif Builtins.search(row, "Persistent Portal:") != nil
+        elsif row.include? "Portal:"
+          if /(Current|Persistent) Portal:/.match?(row)
             # 'Persistent Portal' overwrites current (is used for login)
-            portal = Ops.get(Builtins.splitstring(row, " "), 2, "")
+            portal = row.split[2]
           else
             # read 'Portal' (from output of -m node)
-            portal = Ops.get(Builtins.splitstring(row, " "), 1, "")
+            portal = row.split[1]
           end
-          pos = Builtins.search(portal, ",")
-          portal = Builtins.substring(portal, 0, pos) if pos != nil
-        elsif Builtins.search(row, "Iface Name:") != nil
-          iface = Ops.get(Builtins.splitstring(row, " "), 2, "")
-          iface = Ops.get(@iface_file, iface, iface)
+          portal = portal.split(",")[0] if portal.include?(",")
+        elsif row.include? "Iface Name:"
+          iface = row.split[2]
+          iface = (@iface_file || {}).dig(iface, :name) || iface
           # don't add Scope:Link IPv6 address
           ret << "#{portal} #{target} #{iface}" if 
!portal.start_with?("[fe80:")
           dumped = true
@@ -578,21 +575,16 @@
         ret << "#{portal} #{target} #{iface}" if !portal.start_with?("[fe80:")
       end
 
-      Builtins.y2milestone("ScanDiscovered ret:%1", ret)
-      deep_copy(ret)
+      log.info "ScanDiscovered ret:#{ret}"
+      ret
     end
 
     # Read all discovered targets from the local nodes database, storing the 
result in the
     # {#discovered} attribute
     def getDiscovered
-      @discovered = []
       retcode = SCR.Execute(path(".target.bash_output"), GetAdmCmd("-m node -P 
1"))
-      if Builtins.size(Ops.get_string(retcode, "stderr", "")) == 0
-        @discovered = ScanDiscovered(
-          Builtins.splitstring(Ops.get_string(retcode, "stdout", ""), "\n")
-        )
-      end
-      deep_copy(@discovered)
+      @discovered =
+        retcode["stderr"].to_s.empty? ? 
ScanDiscovered(retcode["stdout"].to_s.split("\n")) : []
     end
 
     def start_services_initial
@@ -626,15 +618,10 @@
 
     # Get all connected targets storing the result in the #sessions attribute
     def readSessions
-      Builtins.y2milestone("reading current settings")
-      retcode = SCR.Execute(path(".target.bash_output"), GetAdmCmd("-m session 
-P 1"))
-      @sessions = ScanDiscovered(
-        Builtins.splitstring(Ops.get_string(retcode, "stdout", ""), "\n")
-      )
-      Builtins.y2milestone(
-        "Return list from iscsiadm -m session: %1",
-        @sessions
-      )
+      log.info "reading current settings"
+      ret = SCR.Execute(path(".target.bash_output"), GetAdmCmd("-m session -P 
1"))
+      @sessions = ScanDiscovered(ret.fetch("stdout", "").split("\n"))
+      log.info "Return list from iscsiadm -m session: #{@sessions}"
       true
     end
 
@@ -794,25 +781,13 @@
     #   {#sessions} gets refreshed in the latter case)
     def deleteRecord
       ret = true
-      Builtins.y2milestone("Delete record %1", @currentRecord)
+      log.info "Delete record #{@currentRecord}"
 
       retcode = SCR.Execute(
         path(".target.bash_output"),
-        GetAdmCmd(
-          Builtins.sformat(
-            "-m node -I %3 -T %1 -p %2 --logout",
-            Ops.get(@currentRecord, 1, "").shellescape,
-            Ops.get(@currentRecord, 0, "").shellescape,
-            Ops.get(@currentRecord, 2, "default").shellescape
-          )
-        )
-      )
-      if Ops.greater_than(
-        Builtins.size(Ops.get_string(retcode, "stderr", "")),
-        0
+        GetAdmCmd("-m node -I #{current_iface} -T #{current_target} -p 
#{current_portal} --logout")
       )
-        return false
-      end
+      return false unless retcode["stderr"].to_s.empty?
 
       readSessions
       ret
@@ -828,20 +803,13 @@
     #
     # @return [Boolean] whether the operation succeeded with no incidences
     def removeRecord
-      Builtins.y2milestone("Remove record %1", @currentRecord)
+      log.info "Remove record #{@currentRecord}"
 
       result = SCR.Execute(
         path(".target.bash_output"),
-        GetAdmCmd(
-          Builtins.sformat(
-            "-m node -T %1 -p %2 -I %3 --op=delete",
-            Ops.get(@currentRecord, 1, "").shellescape,
-            Ops.get(@currentRecord, 0, "").shellescape,
-            Ops.get(@currentRecord, 2, "").shellescape
-          )
-        )
+        GetAdmCmd("-m node -T #{current_target} -p #{current_portal} -I 
#{current_iface} --op=delete")
       )
-      Builtins.y2milestone(result.inspect)
+      log.info(result.inspect)
       result["exit"].zero?
     end
 
@@ -851,7 +819,7 @@
     #                   converted to a hash
     def getCurrentNodeValues
       ret = SCR.Execute(path(".target.bash_output"),
-        GetAdmCmd("-m node -I #{(@currentRecord[2] || "default").shellescape} 
-T #{(@currentRecord[1] || "").shellescape} -p #{(@currentRecord[0] || 
"").shellescape}"))
+        GetAdmCmd("-m node -I #{current_iface} -T #{current_target} -p 
#{current_portal}"))
       return {} if ret["exit"] != 0
 
       nodeInfoToMap(ret["stdout"] || "")
@@ -932,28 +900,24 @@
 
     # update authentication value
     def setValue(name, value)
-      rec = @currentRecord
-      Builtins.y2milestone("set %1  for record %2", name, rec)
+      log.info "set #{name} for record #{@currentRecord}"
 
-      log = !name.include?("password")
-      cmd = "-m node -I #{(rec[2] || "default").shellescape} -T #{(rec[1] || 
"").shellescape} -p #{(rec[0] || "").shellescape} --op=update 
--name=#{name.shellescape}"
+      login = !name.include?("password")
+      cmd = "-m node -I #{current_iface} -T #{current_target} -p 
#{current_portal} --op=update --name=#{name.shellescape}"
 
-      command = GetAdmCmd("#{cmd} --value=#{value.shellescape}", log)
-      if !log
+      command = GetAdmCmd("#{cmd} --value=#{value.shellescape}", login)
+      if !login
         value = "*****" if !value.empty?
-        Builtins.y2milestone("AdmCmd:LC_ALL=POSIX iscsiadm #{cmd} 
--value=#{value}")
+        log.info "AdmCmd:LC_ALL=POSIX iscsiadm #{cmd} --value=#{value}"
       end
 
       ret = true
       retcode = SCR.Execute(path(".target.bash_output"), command)
-      if Ops.greater_than(
-        Builtins.size(Ops.get_string(retcode, "stderr", "")),
-        0
-      )
-        Builtins.y2error("%1", Ops.get_string(retcode, "stderr", ""))
-        ret = false
+      unless retcode["stderr"].to_s.empty?
+        log.error retcode["stderr"]
+        return false
       end
-      Builtins.y2milestone("return value %1", ret)
+      log.info "return value #{ret}"
       ret
     end
 
@@ -995,11 +959,7 @@
 
     # check if given target is connected
     def connected(check_ip)
-      Builtins.y2internal(
-        "check connected status for %1 with IP check:%2",
-        @currentRecord,
-        check_ip
-      )
+      log.info "check connected status for #{@currentRecord} with IP 
check:#{check_ip}"
       !!find_session(check_ip)
     end
 
@@ -1008,73 +968,54 @@
     # @param check_ip [Boolean] whether the ip address must be considered in 
the comparison
     # @return [String, nil] corresponding entry from #sessions or nil if not 
found
     def find_session(check_ip)
-      Builtins.foreach(@sessions) do |row|
+      @sessions.find do |row|
         ip_ok = true
-        list_row = Builtins.splitstring(row, " ")
-        Builtins.y2milestone("Session row: %1", list_row)
+        list_row = row.split
+        log.info "Session row: #{list_row}"
         if check_ip
-          session_ip = Ops.get(
-            Builtins.splitstring(Ops.get(list_row, 0, ""), ","),
-            0, ""
-          )
-          current_ip = Ops.get(
-            Builtins.splitstring(Ops.get(@currentRecord, 0, ""), ","),
-            0, ""
-          )
+          session_ip = list_row[0].to_s.split(",")[0].to_s
+          current_ip = @currentRecord[0].to_s.split(",")[0].to_s
           ip_ok = ipEqual?(session_ip, current_ip)
         end
 
-        if Ops.get(list_row, 1, "") == Ops.get(@currentRecord, 1, "") &&
-            Ops.get(list_row, 2, "") == Ops.get(@currentRecord, 2, "") &&
-            ip_ok
-          return row
-        end
+        (list_row[1] == @currentRecord[1]) && (list_row[2] == 
@currentRecord[2]) && ip_ok
       end
-
-      nil
     end
 
     # change startup status (manual/onboot) for target
     def setStartupStatus(status)
-      Builtins.y2milestone(
-        "Set startup status for %1 to %2",
-        @currentRecord,
-        status
-      )
+      log.info "Set startup status for #{@currentRecord} to #{status}"
       ret = true
       retcode = SCR.Execute(
         path(".target.bash_output"),
         GetAdmCmd(
           Builtins.sformat(
             "-m node -I %3 -T %1 -p %2 --op=update --name=node.conn[0].startup 
--value=%4",
-            Ops.get(@currentRecord, 1, "").shellescape,
-            Ops.get(@currentRecord, 0, "").shellescape,
-            Ops.get(@currentRecord, 2, "default").shellescape,
+            current_target,
+            current_portal,
+            current_iface,
             status.shellescape
           )
         )
       )
-      if Ops.greater_than(
-        Builtins.size(Ops.get_string(retcode, "stderr", "")),
-        0
-      )
-        return false
-      else
+      if retcode["stderr"].to_s.empty?
         retcode = SCR.Execute(
           path(".target.bash_output"),
           GetAdmCmd(
             Builtins.sformat(
               "-m node -I %3 -T %1 -p %2 --op=update --name=node.startup 
--value=%4",
-              Ops.get(@currentRecord, 1, "").shellescape,
-              Ops.get(@currentRecord, 0, "").shellescape,
-              Ops.get(@currentRecord, 2, "default").shellescape,
+              current_target,
+              current_portal,
+              current_iface,
               status.shellescape
             )
           )
         )
+      else
+        ret = false
       end
 
-      Builtins.y2internal("retcode %1", retcode)
+      log.info "retcode #{retcode}"
       ret
     end
 
@@ -1105,11 +1046,7 @@
     #   "password_in".
     def loginIntoTarget(target)
       target = deep_copy(target)
-      @currentRecord = [
-        Ops.get_string(target, "portal", ""),
-        Ops.get_string(target, "target", ""),
-        Ops.get_string(target, "iface", "")
-      ]
+      @currentRecord = [target["portal"].to_s, target["target"].to_s, 
target["iface"].to_s]
 
       auth = Y2IscsiClient::Authentication.new_from_legacy(target)
       login_into_current(auth)
@@ -1144,14 +1081,7 @@
 
       output = SCR.Execute(
         path(".target.bash_output"),
-        GetAdmCmd(
-          Builtins.sformat(
-            "-m node -I %3 -T %1 -p %2 --login",
-            Ops.get(@currentRecord, 1, "").shellescape,
-            Ops.get(@currentRecord, 0, "").shellescape,
-            Ops.get(@currentRecord, 2, "").shellescape
-          )
-        )
+        GetAdmCmd("-m node -I #{current_iface} -T #{current_target} -p 
#{current_portal} --login")
       )
 
       Builtins.y2internal("output %1", output)
@@ -1279,213 +1209,130 @@
       portals = []
       ifaces = []
       ifacepar = ""
-      Builtins.foreach(Ops.get_list(@ay_settings, "targets", [])) do |target|
-        iface = Ops.get_string(target, "iface", "default")
+      @ay_settings.fetch("targets", []).each do |target|
+        iface = target.fetch("iface", "default")
         next if ifaces.include?(iface) # already added
 
         ifacepar << " " unless ifacepar.empty?
         ifacepar << "-I " << iface.shellescape
         ifaces << iface
       end
-      if Ops.greater_than(Builtins.size(Builtins.filter(ifaces) do |s|
-                                          s != "default"
-                                        end), 0)
-        CallConfigScript()
-      end
-      Builtins.foreach(Ops.get_list(@ay_settings, "targets", [])) do |target|
-        if !Builtins.contains(portals, Ops.get_string(target, "portal", ""))
-          SCR.Execute(
-            path(".target.bash"),
-            GetAdmCmd(
-              Builtins.sformat(
-                "-m discovery %1 -t st -p %2",
-                ifacepar,
-                Ops.get_string(target, "portal", "").shellescape
-              )
-            )
-          )
-          portals = Builtins.add(portals, Ops.get_string(target, "portal", ""))
-        end
-      end
-      Builtins.foreach(Ops.get_list(@ay_settings, "targets", [])) do |target|
-        Builtins.y2internal("login into target %1", target)
+
+      # rubocop:disable Style/CombinableLoops
+      @ay_settings.fetch("targets", []).each do |target|
+        next if portals.include? target["portal"]
+        SCR.Execute(
+          path(".target.bash"),
+          GetAdmCmd(%(-m discovery #{ifacepar} -t st -p 
#{target["portal"].shellescape}))
+        )
+        portals << target["portal"]
+        log.info "login into target #{target}"
         loginIntoTarget(target)
-        @currentRecord = [
-          Ops.get_string(target, "portal", ""),
-          Ops.get_string(target, "target", ""),
-          Ops.get_string(target, "iface", "")
-        ]
-        setStartupStatus(Ops.get_string(target, "startup", "manual"))
+        @currentRecord = [target["portal"], target["target"], target["iface"]]
+        setStartupStatus(target.fetch("startup", "manual"))
       end
+      # rubocop:enable Style/CombinableLoops
       true
     end
 
     def Overview
       overview = _("Configuration summary...")
-      if Ops.greater_than(Builtins.size(@ay_settings), 0)
+      unless (@ay_settings || {}).empty?
         overview = ""
-        if Ops.greater_than(
-          Builtins.size(Ops.get_string(@ay_settings, "initiatorname", "")),
-          0
-        )
-          overview = Ops.add(
-            Ops.add(
-              Ops.add(overview, "<p><b>Initiatorname: </b>"),
-              Ops.get_string(@ay_settings, "initiatorname", "")
-            ),
-            "</p>"
-          )
-        end
-        if Ops.greater_than(
-          Builtins.size(Ops.get_list(@ay_settings, "targets", [])),
-          0
-        )
-          Builtins.foreach(Ops.get_list(@ay_settings, "targets", [])) do 
|target|
-            overview = Ops.add(
-              Ops.add(
-                Ops.add(
-                  Ops.add(
-                    Ops.add(
-                      Ops.add(
-                        Ops.add(
-                          Ops.add(
-                            Ops.add(overview, "<p>"),
-                            Ops.get_string(target, "portal", "")
-                          ),
-                          ", "
-                        ),
-                        Ops.get_string(target, "target", "")
-                      ),
-                      ", "
-                    ),
-                    Ops.get_string(target, "iface", "")
-                  ),
-                  ", "
-                ),
-                Ops.get_string(target, "startup", "")
-              ),
-              "</p>"
-            )
+        initiatorname = @ay_settings.fetch("initiatorname", "")
+        targets = @ay_settings.fetch("targets", [])
+        unless initiatorname.empty?
+          overview << "<p><b>Initiatorname: </b>#{initiatorname}</p>"
+        end
+        unless targets.empty?
+          targets.each do |t|
+            overview << "<p>#{t["portal"]}, #{t["target"]}, #{t["iface"]}, 
#{t["startup"]}</p>"
           end
         end
       end
       overview
     end
 
-    def InitOffloadCard
+    def InitIface
       ret = "default"
       retcode = SCR.Execute(path(".target.bash_output"), GetAdmCmd("-m node -P 
1"))
       ifaces = []
       if retcode["stderr"].empty?
         ScanDiscovered(retcode["stdout"].split("\n")).each do |s|
-          sl = Builtins.splitstring(s, "  ")
-          iface_name = sl[2] || ""
+          iface_name = s.split[2].to_s
           next if iface_name.empty? || ifaces.include?(iface_name)
 
           ifaces << iface_name
         end
       end
-      Builtins.y2milestone("InitOffloadCard ifaces:%1", ifaces)
+      log.info "InitIface ifaces:#{ifaces}"
       if ifaces.size > 1
         ret = "all"
-      elsif @iface_eth.include?(ifaces.first)
-        ret = ifaces.first || "default"
+      elsif (@iface_file || {}).keys.include?(ifaces.first)
+        ret = ifaces.first
       end
-      Builtins.y2milestone("InitOffloadCard ret:%1", ret)
-      ret
+      log.info "InitIface ret:#{ret}"
+      @iface = ret
+    end
+
+    def iface_value(content, field)
+      content.find { |l| l.include? field }.to_s.gsub(/[[:space:]]/, 
"").split("=")[1]
+    end
+
+    def read_ifaces
+      InitIfaceFile()
+      InitIface()
     end
 
     def InitIfaceFile
       @iface_file = {}
-      files = Convert.convert(
-        SCR.Read(path(".target.dir"), "/etc/iscsi/ifaces"),
-        :from => "any",
-        :to   => "list <string>"
-      )
-      Builtins.y2milestone("InitIfaceFile files:%1", files)
-      if files == nil || Builtins.size(files) == 0
+      files = SCR.Read(path(".target.dir"), "/etc/iscsi/ifaces") || []
+      log.info "InitIfaceFile files: #{files}"
+      if files.empty?
         cmd = GetAdmCmd("-m iface")
         res = SCR.Execute(path(".target.bash_output"), cmd)
-        Builtins.y2milestone("InitIfaceFile cmd:#{cmd}\nres:#{res.inspect}", 
cmd)
-        files = SCR.Read(path(".target.dir"), "/etc/iscsi/ifaces")
-        Builtins.y2milestone("InitIfaceFile files:%1", files)
-      end
-      Builtins.foreach(files) do |file|
-        ls = Builtins.splitstring(
-          Convert.to_string(
-            SCR.Read(
-              path(".target.string"),
-              Ops.add("/etc/iscsi/ifaces/", file)
-            )
-          ),
-          "\n"
-        )
-        Builtins.y2milestone("InitIfaceFile file:%1", file)
-        Builtins.y2milestone("InitIfaceFile ls:%1", ls)
-        ls = Builtins.filter(ls) do |l|
-          Builtins.search(l, "iface.iscsi_ifacename") != nil
-        end
-        Builtins.y2milestone("InitIfaceFile ls:%1", ls)
-        if Ops.greater_than(Builtins.size(ls), 0)
-          Ops.set(
-            @iface_file,
-            Ops.get(
-              Builtins.splitstring(
-                Builtins.deletechars(Ops.get(ls, 0, ""), " "),
-                "="
-              ),
-              1,
-              ""
-            ),
-            file
-          )
-        end
+        log.info "InitIfaceFile cmd: #{cmd}\nres: #{res.inspect}"
+        files = SCR.Read(path(".target.dir"), "/etc/iscsi/ifaces") || []
+        log.info "InitIfaceFile files: #{files}"
+      end
+      files.each do |file|
+        ls = SCR.Read(path(".target.string"), 
"/etc/iscsi/ifaces/#{file}").split("\n")
+        log.info "InitIfaceFile file: #{file}\nInitIfaceFile ls: #{ls}"
+        ls.reject! { |l| l.start_with?(/\s*#/) }
+        iface_name = ls.find { |l| l.include? "iface.iscsi_ifacename" }.to_s
+        log.info "InitIfaceFile ls: #{iface_name}"
+        next if iface_name.empty?
+        name = iface_name.gsub(/[[:space:]]/, "").split("=")[1]
+        dev_name = iface_value(ls, "iface.net_ifacename")
+        transport = iface_value(ls, "iface.transport")
+        hwaddress = iface_value(ls, "iface.hwaddress")
+        ipaddress = iface_value(ls, "iface.ipaddress")
+        @iface_file[name] = { :name => name, :dev => dev_name, :transport => 
transport, :hwaddress => hwaddress, :ip => ipaddress }
       end
-      Builtins.y2milestone("InitIfaceFile iface_file:%1", @iface_file)
+      log.info "InitIfaceFile iface_file: #{@iface_file}"
 
       nil
     end
 
-    def GetOffloadItems
-      init = false
-      if @offload_valid.nil?
-        init = true
-        InitIfaceFile()
-        InitOffloadValid()
-      end
+    def default_item
+      Item(Id(@offload[0][0]), @offload[0][1], @iface == @offload[0][0])
+    end
 
-      entries = {}
-      @offload_valid.each do |i, cards|
-        cards.each do |card|
-          next if card[0].nil? || card[0].empty?
+    def all_item
+      Item(Id(@offload[1][0]), @offload[1][1], @iface == @offload[1][0])
+    end
 
-          entries[card[2]] = card_label(card, @offload[i][1])
-        end
+    def iface_items
+      if @iface_file.nil?
+        InitIfaceFile()
+        InitIface()
       end
-      Builtins.y2milestone("GetOffloadItems entries:%1", entries)
 
-      @iface_eth = Builtins.sort(Builtins.maplist(entries) { |e, _val| e })
-      Builtins.y2milestone("GetOffloadItems eth:%1", @iface_eth)
-      if init
-        @offload_card = InitOffloadCard()
-        Builtins.y2milestone("GetOffloadItems offload_card:%1", @offload_card)
-      end
-      ret = [
-        # Entry for "default"
-        Item(Id(@offload[0][0]), @offload[0][1], @offload_card == 
@offload[0][0])
-      ]
-      if @offload_valid.any?
-        # Entry for "all"
-        ret << Item(
-          Id(@offload[1][0]), @offload[1][1], @offload_card == @offload[1][0]
-        )
-      end
-      # Entries for the valid cards
-      ret.concat(
-        @iface_eth.map { |e| Item(Id(e), entries[e], @offload_card == e) }
-      )
-      Builtins.y2milestone("GetOffloadItems ret:%1", ret)
-      deep_copy(ret)
+      items = [default_item]
+      items << all_item if @iface_file.any?
+
+      @iface_file.each { |n, e| items << Item(Id(n), iface_label(e), @iface == 
n) }
+      items
     end
 
     # Modules to use for all the cards detected in the system and that support 
hardware
@@ -1496,85 +1343,56 @@
     #
     # @return [Array<String>]
     def GetOffloadModules
-      GetOffloadItems() if @offload_valid == nil
+      InitOffloadValid() if @offload_valid == nil
       modules = []
-      Builtins.foreach(@offload_valid) do |i, _l|
-        modules = Convert.convert(
-          Builtins.union(modules, Ops.get_list(@offload, [i, 3], [])),
-          :from => "list",
-          :to   => "list <string>"
-        )
-      end
-      Builtins.y2milestone("GetOffloadModules %1", modules)
-      deep_copy(modules)
+      @offload_valid.each { |i, _| modules.concat(@offload[i][3]) }
+      log.info "GetOffloadModules #{modules}"
+      modules.uniq
     end
 
     def LoadOffloadModules
       mods = GetOffloadModules()
-      Builtins.foreach(mods) do |s|
-        Builtins.y2milestone("Loading module %1", s)
+      mods.each do |s|
+        log.info "Loading module #{s}"
         ModuleLoading.Load(s, "", "", "", false, true)
       end
-      deep_copy(mods)
+      mods
     end
 
+    # It returns a list of iscsi ifaces corresponding to the current offload 
card selection, "default" will return
+    # an array with the current offload card while all will return an array 
with all the offlocad valid ifaces
+    #
+    # @return [Array<String>] List os iscsi ifaces for the current offload 
card selection, ex. ["eth2-bnx2i"]
     def GetDiscIfaces
-      ret = []
-      if GetOffloadCard() == "all"
-        tl = Builtins.maplist(GetOffloadItems()) do |t|
-          Ops.get_string(Builtins.argsof(t), [0, 0], "")
-        end
-        Builtins.y2milestone("GetDiscIfaces:%1", tl)
-        ret = Builtins.filter(tl) { |s| s != "all" }
-      else
-        ret = [GetOffloadCard()]
-      end
-      Builtins.y2milestone("GetDiscIfaces:%1", ret)
-      deep_copy(ret)
-    end
-
-    def CallConfigScript
-      sl = Builtins.filter(GetDiscIfaces()) { |s| s != "default" }
-      Builtins.y2milestone("CallConfigScript list:%1", sl)
-      Builtins.foreach(sl) do |s|
-        hw = []
-        hw = Ops.get(Builtins.maplist(Builtins.filter(@offload_valid) do |_i, 
eth|
-          Builtins.contains(
-            Builtins.flatten(
-              Convert.convert(eth, :from => "list", :to => "list <list>")
-            ),
-            s
-          )
-        end) { |_i, e| e }, 0, [])
-        Builtins.y2milestone("CallConfigScript hw:%1", hw)
-        hw = Builtins.find(
-          Convert.convert(hw, :from => "list", :to => "list <list>")
-        ) { |l| Ops.get_string(l, 2, "") == s }
-        Builtins.y2milestone("CallConfigScript hw:%1", hw)
-        if hw != nil
-          cmd = "#{OFFLOAD_SCRIPT} #{Ops.get_string(hw, 0, "").shellescape}"
-          Builtins.y2milestone("CallConfigScript cmd:%1", cmd)
-          output = SCR.Execute(path(".target.bash_output"), cmd)
-          Builtins.y2milestone("CallConfigScript %1", output)
-        end
-      end
-
-      nil
-    end
-
+      ifaces = (@iface == "all") ? @iface_file.keys : [@iface]
+      log.info "GetDiscIfaces:#{ifaces}"
+      ifaces
+    end
+
+    # Obtains the parameters for calling iscsiadm in discovery mode depending 
on the current
+    # iSNS configuration as well as the parameters given
+    #
+    # ex.
+    #   GetDiscoveryCmd("192.168.0.100", "3260") =>
+    #     ["iscsiadm", "-m", "discovery", "-P", "1", "-t", "st", "-p", 
"192.168.0.100:3260"]
+    #
+    # @param ip [String] Portal IP address
+    # @param port [String] Portal port number
+    # @param use_fw [Boolean] whether the target should be fw or not
+    # @param only_new [Boolean] whether a new record should be created
     # @return [Array<String>]
     def GetDiscoveryCmd(ip, port, use_fw: false, only_new: false)
-      Builtins.y2milestone("GetDiscoveryCmd ip:%1 port:%2 fw:%3 only new:%4",
-        ip, port, use_fw, only_new)
-      command = ["iscsiadm", "-m", "discovery", "-P", "1"]
+      log.info "GetDiscoveryCmd ip:#{ip} port:#{port} fw:#{use_fw} only 
new:#{only_new}"
+
+      command = DISCOVERY_CMD.split
       isns_info = useISNS
       if isns_info["use"]
         command << "-t" << "isns"
       else
         ifs = GetDiscIfaces()
-        Builtins.y2milestone("ifs=%1", ifs)
+        log.info "ifs=#{ifs}"
         ifs = ifs.each_with_object([]) { |s, res| res << "-I" << s }
-        Builtins.y2milestone("ifs=%1", ifs)
+        log.info "ifs=#{ifs}"
         tgt = "st"
         tgt = "fw" if use_fw
         command << "-t" << tgt
@@ -1584,7 +1402,7 @@
       command << "-p" << "#{ip}:#{port}"
       command << "-o" << "new" if only_new
 
-      Builtins.y2milestone("GetDiscoveryCmd %1", command)
+      log.info "GetDiscoveryCmd #{command}"
       command
     end
 
@@ -1609,8 +1427,6 @@
     publish :variable => :currentRecord, :type => "list <string>"
     publish :variable => :initiatorname, :type => "string"
     publish :variable => :ay_settings, :type => "map"
-    publish :function => :GetOffloadCard, :type => "string ()"
-    publish :function => :SetOffloadCard, :type => "void (string)"
     publish :function => :GetAdmCmd, :type => "string (string)"
     publish :function => :hidePassword, :type => "map <string, any> (map 
<string, any>)"
     publish :function => :getiBFT, :type => "map <string, any> ()"
@@ -1641,7 +1457,7 @@
     publish :function => :autoyastPrepare, :type => "boolean ()"
     publish :function => :autoyastWrite, :type => "boolean ()"
     publish :function => :Overview, :type => "string ()"
-    publish :function => :GetOffloadItems, :type => "list <term> ()"
+    publish :function => :iface_items, :type => "list <term> ()"
     publish :function => :GetOffloadModules, :type => "list <string> ()"
     publish :function => :LoadOffloadModules, :type => "list <string> ()"
     publish :function => :getCurrentNodeValues, :type => "map <string, any> ()"
@@ -1649,36 +1465,30 @@
 
   private
 
-    def InitOffloadValid
-      @offload_valid = potential_offload_cards
-      card_names = @offload_valid.values.flatten(1).map(&:first)
-      offload_res = configure_offload_engines(card_names)
+    def current_target
+      @currentRecord[1].to_s.shellescape
+    end
 
-      # Filter only those cards for which we have a hwaddr value in offload_res
-      @offload_valid.values.each do |cards|
-        cards.select! do |card|
-          card_res = offload_res[card[0]]
-          card_res["exit"].zero? && card_res["hwaddr"]
-        end
-      end
-      Builtins.y2milestone("GetOffloadItems offload_res:%1", offload_res)
-      Builtins.y2milestone("GetOffloadItems offload_valid:%1", @offload_valid)
+    def current_portal
+      @currentRecord[0].to_s.shellescape
+    end
 
-      # Sync the MAC with the hwaddr value from offload_res
-      @offload_valid.values.each do |cards|
-        cards.each do |card|
-          dev_name = card[0]
-          card[1] = offload_res[dev_name]["hwaddr"]
-        end
-      end
-      Builtins.y2milestone("GetOffloadItems offload_valid:%1", @offload_valid)
+    def current_iface
+      @currentRecord.fetch(2, "default").shellescape
+    end
 
-      @offload_valid.values.each do |cards|
-        cards.each do |card|
-          card << ip_addr(card[0])
-        end
-      end
-      Builtins.y2milestone("GetOffloadItems offload_valid:%1", @offload_valid)
+    def bring_up(card_names)
+      card_names.each { |n| Yast::Execute.locally!("ip", "link", "set", "dev", 
n, "up") }
+    end
+
+    def InitOffloadValid
+      read_ifaces if @iface_file.nil?
+
+      @offload_valid = potential_offload_cards
+      card_names = @offload_valid.values.flatten(1).map { |c| c["iface"] }.uniq
+      bring_up(card_names)
+      log.info "OffloadValid entries#{@offload_valid}"
+      nil
     end
 
     # List of modules for the given card description
@@ -1712,14 +1522,14 @@
     def potential_offload_cards
       # Store into hw_mods information about all the cards in the system
       cards = SCR.Read(path(".probe.netcard"))
-      hw_mods = cards.map do |c|
-        Builtins.y2milestone("GetOffloadItems card:%1", c)
+      hw_mods = cards.select { |c| c["iscsioffload"] }.map do |c|
+        log.info "GetOffloadItems card:#{c}"
         hw_mod = {
           "modules" => netcard_modules(c),
           "iface"   => c["dev_name"] || "",
-          "macaddr" => Ops.get_string(c, ["resource", "hwaddr", 0, "addr"], "")
+          "macaddr" => c.dig("resource", "hwaddr", 0, "addr") || ""
         }
-        Builtins.y2milestone("GetOffloadItems cinf:%1", hw_mod)
+        log.info "OffloadCards hw:#{hw_mod}"
         hw_mod
       end
 
@@ -1733,54 +1543,16 @@
           # Ignore this card unless it has some module in common with the 
offload entry
           next if (modules & hw["modules"]).empty?
 
-          Builtins.y2milestone("GetOffloadItems l:%1", offload_entry)
-          Builtins.y2milestone("GetOffloadItems valid:%1", hw)
+          log.info "GetOffloadItems l:#{offload_entry}"
+          log.info "GetOffloadItems valid:#{hw}"
           result[idx] ||= []
-          result[idx] << [
-            hw["iface"],
-            hw["macaddr"], # In fact, this is going to be overwritten at a 
later point
-            "#{hw["iface"]}-#{offload_entry[3].first}"
-          ]
+          result[idx] << hw
         end
       end
 
       result
     end
 
-    # Configures iSCSI offload engines for the given cards
-    #
-    # Tries to create an open-iscsi interface definition for each of the given 
cards.
-    #
-    # @param cards [Array<String>] list of interface names
-    # @return [Hash{String => Hash}] results of the operation, keys are the 
names of the interfaces
-    #   and values the corresponding result as a hash with three fields: 
"exit" (0 means the
-    #   definition was created), "hwaddr" and "ntype".
-    def configure_offload_engines(cards)
-      offload_res = {}
-
-      cards.each do |dev_name|
-        cmd = "#{OFFLOAD_SCRIPT} #{dev_name.shellescape} | grep ..:..:..:.." # 
grep for lines containing MAC address
-        Builtins.y2milestone("GetOffloadItems cmd:%1", cmd)
-        out = SCR.Execute(path(".target.bash_output"), cmd)
-        # Example for output if offload is supported on interface:
-        # cmd: iscsi_offload eth2
-        # out: $["exit":0, "stderr":"", "stdout":"00:00:c9:b1:bc:7f ip \n"]
-        cmd2 = "#{OFFLOAD_SCRIPT} #{dev_name.shellescape}"
-        result = SCR.Execute(path(".target.bash_output"), cmd2)
-        Builtins.y2milestone("GetOffloadItems iscsi_offload out:%1", result)
-
-        offload_res[dev_name] = {}
-        offload_res[dev_name]["exit"] = out["exit"]
-        next unless out["exit"].zero?
-
-        sl = Builtins.splitstring(out["stdout"], " \n")
-        offload_res[dev_name]["hwaddr"] = sl[0]
-        offload_res[dev_name]["ntype"] = sl[1]
-      end
-
-      offload_res
-    end
-
     # Current IP address of the given network interface
     def ip_addr(dev_name)
       stdout = Yast::Execute.on_target!("ip", "addr", "show", dev_name,
@@ -1788,8 +1560,6 @@
         stderr:             :capture,
         allowed_exitstatus: 0..127,
         env:                { "LC_ALL" => "POSIX" })[0]
-      log.info "IP Address config for #{dev_name}: #{stdout}"
-
       # Search for lines containing "inet", means IPv4 address.
       # Regarding the IPv6 support there are no changes needed here because
       # the IP address is not used farther.
@@ -1806,6 +1576,10 @@
       ipaddr
     end
 
+    def iface_label(data)
+      [data[:name], data[:ip]].compact.join(" - ")
+    end
+
     def card_label(card, type_label)
       dev_name = card[0]
       hwaddr = card[1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/test/data/chroot1/etc/iscsi/ifaces/bnx2i.ab:cd:de:fa:cf:29.ipv4.0
 
new/yast2-iscsi-client-5.0.4/test/data/chroot1/etc/iscsi/ifaces/bnx2i.ab:cd:de:fa:cf:29.ipv4.0
--- 
old/yast2-iscsi-client-5.0.3/test/data/chroot1/etc/iscsi/ifaces/bnx2i.ab:cd:de:fa:cf:29.ipv4.0
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/yast2-iscsi-client-5.0.4/test/data/chroot1/etc/iscsi/ifaces/bnx2i.ab:cd:de:fa:cf:29.ipv4.0
      2024-11-12 19:23:22.000000000 +0100
@@ -0,0 +1,26 @@
+# BEGIN RECORD 2.1.9
+iface.iscsi_ifacename = bnx2i.ab:cd:de:fa:cf:29.ipv4.0
+iface.net_ifacename = eth0
+iface.ipaddress = 192.168.100.29
+iface.prefix_len = 0
+iface.hwaddress = ab:cd:de:fa:cf:29
+iface.transport_name = bnx2i
+iface.initiatorname = 
iqn.2015-02.com.hpe:oneview-93044906-8f80-4d1a-9ddb-5f4a70cb47b4
+iface.vlan_id = 0
+iface.vlan_priority = 0
+iface.iface_num = 0
+iface.mtu = 0
+iface.port = 0
+iface.subnet_mask = 255.255.255.0
+iface.tos = 0
+iface.ttl = 0
+iface.tcp_wsf = 0
+iface.tcp_timer_scale = 0
+iface.def_task_mgmt_timeout = 0
+iface.erl = 0
+iface.max_receive_data_len = 0
+iface.first_burst_len = 0
+iface.max_outstanding_r2t = 0
+iface.max_burst_len = 0
+# END RECORD
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-iscsi-client-5.0.3/test/iscsi_client_lib_test.rb 
new/yast2-iscsi-client-5.0.4/test/iscsi_client_lib_test.rb
--- old/yast2-iscsi-client-5.0.3/test/iscsi_client_lib_test.rb  2024-10-01 
16:21:47.000000000 +0200
+++ new/yast2-iscsi-client-5.0.4/test/iscsi_client_lib_test.rb  2024-11-12 
19:23:22.000000000 +0100
@@ -690,14 +690,14 @@
                   "\tPortal: 192.168.20.20:3260,2",
                   "\t\tIface Name: default",
                   "\tPortal: 192.168.10.20:3260,1",
-                  "\t\tIface Name: default"]
+                  "\t\tIface Name: bnx2i.9c:dc:71:df:cf:29.ipv4.0"]
         )).to eq(
           [
             "[2620:113:80c0:8080:e051:f9ea:73c7:9171]:3260 
iqn.2013-10.de.suse:test_file2 default",
             "10.120.66.182:3260 iqn.2013-10.de.suse:test_file2 default",
             "[2620:113:80c0:8080:a00:27ff:fe1b:a7fe]:3260 
iqn.2013-10.de.suse:test_file2 default",
             "192.168.20.20:3260 iqn.2018-06.de.suse.zeus:01 default",
-            "192.168.10.20:3260 iqn.2018-06.de.suse.zeus:01 default"
+            "192.168.10.20:3260 iqn.2018-06.de.suse.zeus:01 
bnx2i.9c:dc:71:df:cf:29.ipv4.0"
           ]
         )
       end
@@ -805,7 +805,7 @@
     end
   end
 
-  describe ".GetOffloadItems" do
+  describe ".InitIfaceFile" do
     around(:each) do |example|
       # The directory /etc/iscsi/ifaces/ is always scanned to look for 
interface definitions,
       # let's chroot the YaST agents so we can use an /etc directory with 
mocked content
@@ -813,13 +813,54 @@
       change_scr_root(root, &example)
     end
 
-    before do
-      # The agent .probe.netcard is used to inspect the network cards in the 
system, this
-      # intercepts that call and mocks the result based on the scenario we 
want to simulate
-      allow(Yast::SCR).to receive(:Read).and_call_original
-      allow(Yast::SCR).to receive(:Read).with(Yast::Path.new(".probe.netcard"))
-        .and_return probe_netcard
+    it "reads the existent iface files" do
+      expect(Yast::SCR).to receive(:Read).with(Yast.path(".target.dir"), 
"/etc/iscsi/ifaces").twice
+      subject.send(:InitIfaceFile)
+    end
+
+    context "there is no iface files" do
+      it "tries to generate them calling iscsiadm -m iface" do
+        expect(Yast::SCR).to receive(:Read).with(Yast.path(".target.dir"), 
"/etc/iscsi/ifaces").and_return([])
+        path = Yast::Path.new(".target.bash_output")
+        cmd = "LC_ALL=POSIX iscsiadm -m iface"
+        expect(Yast::SCR).to receive(:Execute).with(path, cmd)
+        allow(Yast::SCR).to receive(:Read).with(Yast.path(".target.dir"), 
"/etc/iscsi/ifaces").and_return([])
+        subject.send(:InitIfaceFile)
+      end
+    end
+
+    context "there are iface files" do
+      it "does not call iscsiadm -m iface" do
+        path = Yast::Path.new(".target.bash_output")
+        cmd = "LC_ALL=POSIX iscsiadm -m iface"
+        expect(Yast::SCR).to_not receive(:Execute).with(path, cmd)
+        subject.send(:InitIfaceFile)
+      end
+
+      it "populates the ifaces_file variable with the read data" do
+        iface_file = subject.instance_variable_get(:@iface_file)
+        expect(iface_file).to be_nil
+        subject.send(:InitIfaceFile)
+        iface_file = subject.instance_variable_get(:@iface_file)
+        iface, data = iface_file.first
+        expect(iface).to eq("bnx2i.ab:cd:de:fa:cf:29.ipv4.0")
+        expect(data[:name]).to eq("bnx2i.ab:cd:de:fa:cf:29.ipv4.0")
+        expect(data[:hwaddress]).to eq("ab:cd:de:fa:cf:29")
+        expect(data[:ip]).to eq("192.168.100.29")
+        expect(data[:transport]).to eq("bnx2i")
+      end
+    end
+  end
+
+  describe ".iface_items" do
+    around(:each) do |example|
+      # The directory /etc/iscsi/ifaces/ is always scanned to look for 
interface definitions,
+      # let's chroot the YaST agents so we can use an /etc directory with 
mocked content
+      root = File.join(File.dirname(__FILE__), "data", "chroot1")
+      change_scr_root(root, &example)
+    end
 
+    before do
       # iscsiadm is always called, mock it to find no active ISCSI interfaces 
by default
       mock_iscsiadm_mode([])
     end
@@ -843,7 +884,7 @@
 
     RSpec.shared_examples "returns UI items" do
       it "returns an array of UI items" do
-        items = subject.GetOffloadItems
+        items = subject.iface_items
         expect(items).to be_an(Array)
         expect(items).to all be_a(Yast::Term)
         expect(items.map(&:value)).to all eq(:item)
@@ -852,132 +893,54 @@
 
     RSpec.shared_examples "only default" do
       it "provides 'default' as the only item" do
-        items = subject.GetOffloadItems
+        items = subject.iface_items
         expect(items.size).to eq 1
         expect(ui_item_label(items.first)).to eq "default (Software)"
         expect(ui_item_id(items.first)).to eq "default"
       end
     end
 
-    context "with no network cards in the system" do
-      let(:probe_netcard) { [] }
+    context "with no iscsi ifaces in the system" do
+      before do
+        allow(Yast::SCR).to receive(:Read).with(Yast.path(".target.dir"), 
"/etc/iscsi/ifaces")
+        mock_bash_out(/iscsiadm -m iface/, { "exit" => 0, "stdout" => "", 
"stderr" => "" })
+      end
 
       include_examples "returns UI items"
       include_examples "only default"
     end
 
-    context "with network cards not expected to support offloading" do
-      let(:probe_netcard) do
-        [
-          probed_card("enp0s1", "r8152", "12:34:56:78:90:ab"),
-          probed_card("enp5s6", "tg3", "23:45:67:89:0a:bc")
-        ]
-      end
-
+    context "with iscsi ifaces in the system" do
       include_examples "returns UI items"
-      include_examples "only default"
-    end
 
-    context "with several network cards that could support offloading" do
-      let(:probe_netcard) do
-        [
-          probed_card("p6p1_1", "qede",  "12:34:56:78:90:ab"),
-          probed_card("em1",    "bnx2x", "23:45:67:89:0a:bc"),
-          probed_card("p6p2_1", "qede",  "34:56:78:90:ab:cd"),
-          probed_card("em2",    "bnx2x", "45:67:89:0a:bc:de"),
-          probed_card("em3",    "bnx2x", "56:78:90:ab:cd:ef")
-        ]
-      end
-
-      context "if none of the cards support offloading" do
-        before do
-          mock_iscsi_offload("em1", false)
-          mock_iscsi_offload("em2", false)
-          mock_iscsi_offload("em3", false)
-          mock_iscsi_offload("p6p1_1", false)
-          mock_iscsi_offload("p6p2_1", false)
-        end
+      it "includes 'default', 'all' and an entry for each offload card" do
+        items = subject.iface_items
 
-        include_examples "returns UI items"
+        labels = items.map { |i| ui_item_label(i) }
+        expect(labels).to contain_exactly(
+          "default (Software)", "all", "bnx2i.ab:cd:de:fa:cf:29.ipv4.0 - 
192.168.100.29"
+        )
 
-        # NOTE: this is likely an unwanted behavior caused because
-        # @offload_valid == {2=>[], 7=>[]}
-        # which should be considered as an empty list but it's not
-        it "includes only 'default' and 'all'" do
-          labels = subject.GetOffloadItems.map { |i| ui_item_label(i) }
-          expect(labels).to contain_exactly("default (Software)", "all")
-        end
+        ids = items.map { |i| ui_item_id(i) }
+        expect(ids).to contain_exactly("default", "all", 
"bnx2i.ab:cd:de:fa:cf:29.ipv4.0")
       end
+    end
 
-      context "if some cards indeed support offloading" do
-        before do
-          mock_iscsi_offload("em1",    true, "23:45:67:89:0a:bc")
-          mock_iscsi_offload("em2",    false)
-          mock_iscsi_offload("em3",    true, "56:78:90:ab:cd:ef")
-          mock_iscsi_offload("p6p1_1", false)
-          mock_iscsi_offload("p6p2_1", true, "34:56:78:90:ab:cd")
-
-          mock_ip_addr("em1")
-          mock_ip_addr("em3")
-          mock_ip_addr("p6p2_1")
-        end
-
-        include_examples "returns UI items"
-
-        it "includes 'default', 'all' and an entry for each offload card" do
-          items = subject.GetOffloadItems
-
-          labels = items.map { |i| ui_item_label(i) }
-          expect(labels).to contain_exactly(
-            "default (Software)", "all", "em1 - 23:45:67:89:0a:bc - 
bnx2/bnx2i/bnx2x",
-            "em3 - 56:78:90:ab:cd:ef - bnx2/bnx2i/bnx2x", "p6p2_1 - 
34:56:78:90:ab:cd - qede/qedi"
-          )
-
-          ids = items.map { |i| ui_item_id(i) }
-          expect(ids).to contain_exactly("default", "all", "em1-bnx2i", 
"em3-bnx2i", "p6p2_1-qedi")
-        end
-
-        context "and ip is not found" do
-          # NOTE: testing the state of internal variables should be out of the 
scope of unit tests,
-          # but we want to prove a point here (see next context right below)
-          it "sets the IPs in @offload_valid to 'unknown'" do
-            subject.GetOffloadItems
-            cards = 
subject.instance_variable_get("@offload_valid").values.flatten(1)
-            expect(cards.map(&:last)).to eq ["unknown", "unknown", "unknown"]
-          end
-        end
-
-        context "and ip is found" do
-          before do
-            mock_ip_addr("em1",    "192.10.9.8/24")
-            mock_ip_addr("em3",    "")
-            mock_ip_addr("p6p2_1", "10.11.12.13/24")
-          end
-
-          it "sets the IPs in @offload_valid to 'unknown'" do
-            subject.GetOffloadItems
-            cards = 
subject.instance_variable_get("@offload_valid").values.flatten(1)
-            expect(cards.map(&:last)).to eq ["192.10.9.8", "unknown", 
"10.11.12.13"]
-          end
-        end
-
-        context "and no active card is reported by iscsiadm " do
-          before { mock_iscsiadm_mode([]) }
+    context "and no iscsi iface is reported by iscsiadm " do
+      before { mock_iscsiadm_mode([]) }
 
-          it "pre-selects the item 'default'" do
-            selected = subject.GetOffloadItems.find { |i| i.params[2] }
-            expect(ui_item_id(selected)).to eq "default"
-          end
-        end
+      it "pre-selects the item 'default'" do
+        selected = subject.iface_items.find { |i| i.params[2] }
+        expect(ui_item_id(selected)).to eq "default"
+      end
+    end
 
-        context "and one card is already associated to the first target" do
-          before { mock_iscsiadm_mode(["em3-bnx2i"]) }
+    context "and one card is already associated to the first target" do
+      before { mock_iscsiadm_mode(["bnx2i.ab:cd:de:fa:cf:29.ipv4.0"]) }
 
-          it "selects by default the current offload card" do
-            selected = subject.GetOffloadItems.find { |i| i.params[2] }
-            expect(ui_item_id(selected)).to eq "em3-bnx2i"
-          end
-        end
+      it "selects by default the current iface" do
+        selected = subject.iface_items.find { |i| i.params[2] }
+        expect(ui_item_id(selected)).to eq "bnx2i.ab:cd:de:fa:cf:29.ipv4.0"
       end
     end
   end

Reply via email to