Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-d-installer for 
openSUSE:Factory checked in at 2023-02-28 12:48:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-d-installer (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-d-installer.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-d-installer"

Tue Feb 28 12:48:30 2023 rev:4 rq:1067904 version:0.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-d-installer/rubygem-d-installer.changes  
2023-02-16 16:56:53.234948920 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-d-installer.new.31432/rubygem-d-installer.changes
       2023-02-28 12:48:51.940567567 +0100
@@ -1,0 +2,5 @@
+Wed Feb 15 16:09:16 UTC 2023 - José Iván López González <[email protected]>
+
+- Add D-Bus API for iSCSI.
+
+-------------------------------------------------------------------

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

Other differences:
------------------
++++++ rubygem-d-installer.spec ++++++
--- /var/tmp/diff_new_pack.O7NLkw/_old  2023-02-28 12:48:52.540571464 +0100
+++ /var/tmp/diff_new_pack.O7NLkw/_new  2023-02-28 12:48:52.544571491 +0100
@@ -29,6 +29,8 @@
 %define mod_name d-installer
 %define mod_full_name %{mod_name}-%{version}
 # MANUAL
+# Override build.rpm, see also 
https://github.com/openSUSE/obs-build/blob/master/configs/
+%global rb_build_versions %{rb_default_ruby}
 BuildRequires:  dbus-1-common
 Requires:       dbus-1-common
 Requires:       snapper
@@ -36,6 +38,7 @@
 Requires:       yast2-country
 Requires:       yast2-hardware-detection
 Requires:       yast2-installation
+Requires:       yast2-iscsi-client >= 4.5.7
 Requires:       yast2-network
 Requires:       yast2-proxy
 Requires:       yast2-storage-ng

++++++ d-installer-0.7.gem ++++++
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/etc/d-installer.yaml new/etc/d-installer.yaml
--- old/etc/d-installer.yaml    2023-02-15 17:34:43.000000000 +0100
+++ new/etc/d-installer.yaml    2023-02-24 14:18:28.000000000 +0100
@@ -149,15 +149,16 @@
 ALP:
   software:
     installation_repositories:
-      - url: 
https://download.opensuse.org/repositories/SUSE:/ALP:/ToTest/images/repo/ALP-0.1-x86_64-Media1/
+      - url: https://download.opensuse.org/repositories/SUSE:/ALP/standard/
         archs: x86_64
-      - url: 
https://download.opensuse.org/repositories/SUSE:/ALP:/ToTest/images/repo/ALP-0.1-aarch64-Media1/
+      - url: https://download.opensuse.org/repositories/SUSE:/ALP/standard/
         archs: aarch64
     mandatory_patterns:
       - alp_base
       - alp_base_zypper
       - alp_cockpit
       - alp-container_runtime
+      - alt_defaults
     optional_patterns: null # no optional pattern shared
     mandatory_packages:
       - device-mapper # Apparently needed if devices at /dev/mapper are used 
at boot (eg. FDE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/dbus/storage/iscsi_node.rb 
new/lib/dinstaller/dbus/storage/iscsi_node.rb
--- old/lib/dinstaller/dbus/storage/iscsi_node.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/dinstaller/dbus/storage/iscsi_node.rb       2023-02-24 
14:18:28.000000000 +0100
@@ -0,0 +1,157 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+require "dbus"
+require "dinstaller/dbus/base_object"
+require "dinstaller/dbus/storage/with_iscsi_auth"
+
+module DInstaller
+  module DBus
+    module Storage
+      # Class representing an iSCSI node
+      class ISCSINode < BaseObject
+        include WithISCSIAuth
+
+        # @return [DInstaller::Storage::ISCSI::Manager]
+        attr_reader :iscsi_manager
+
+        # @return [DInstaller::Storage::ISCSI::Node]
+        attr_reader :iscsi_node
+
+        # Constructor
+        #
+        # @param iscsi_manager [DInstaller::Storage::Iscsi::Manager]
+        # @param iscsi_node [DInstaller::Storage::Iscsi::Node]
+        # @param path [DBus::ObjectPath] Path in which the object is exported
+        # @param logger [Logger, nil]
+        def initialize(iscsi_manager, iscsi_node, path, logger: nil)
+          super(path, logger: logger)
+
+          @iscsi_manager = iscsi_manager
+          @iscsi_node = iscsi_node
+        end
+
+        ISCSI_NODE_INTERFACE = "org.opensuse.DInstaller.Storage1.ISCSI.Node"
+        private_constant :ISCSI_NODE_INTERFACE
+
+        dbus_interface ISCSI_NODE_INTERFACE do
+          dbus_reader(:target, "s")
+          dbus_reader(:address, "s")
+          dbus_reader(:port, "u")
+          dbus_reader(:interface, "s")
+          dbus_reader(:connected, "b")
+          dbus_reader(:startup, "s")
+          dbus_method(:Login, "in options:a{sv}, out result:u") { |o| login(o) 
}
+          dbus_method(:Logout, "out result:u") { logout }
+        end
+
+        # Name of the iSCSI target
+        #
+        # @return [String]
+        def target
+          iscsi_node.target || ""
+        end
+
+        # IP address of the iSCSI target
+        #
+        # @return [String]
+        def address
+          iscsi_node.address || ""
+        end
+
+        # Port of the iSCSI target
+        #
+        # @return [Integer]
+        def port
+          iscsi_node.port || 0
+        end
+
+        # Interface of the iSCSI node
+        #
+        # @return [String]
+        def interface
+          iscsi_node.interface || ""
+        end
+
+        # Whether the node is connected
+        #
+        # @return [Boolean]
+        def connected
+          iscsi_node.connected?
+        end
+
+        # Startup status of the connection
+        #
+        # @return [String] Empty if the node is not connected
+        def startup
+          iscsi_node.startup || ""
+        end
+
+        # Sets the associated iSCSI node
+        #
+        # @note A properties changed signal is always emitted.
+        #
+        # @param value [DInstaller::Storage::ISCSI::Node]
+        def iscsi_node=(value)
+          @iscsi_node = value
+
+          properties = interfaces_and_properties[ISCSI_NODE_INTERFACE]
+          dbus_properties_changed(ISCSI_NODE_INTERFACE, properties, [])
+        end
+
+        # Creates an iSCSI session
+        #
+        # @param options [Hash<String, String>] Options from a D-Bus call:
+        #   @option Username [String] Username for authentication by target
+        #   @option Password [String] Password for authentication by target
+        #   @option ReverseUsername [String] Username for authentication by 
initiator
+        #   @option ReversePassword [String] Password for authentication by 
inititator
+        #   @option Startup [String] Valid values are "onboot", "manual", 
"automatic"
+        #
+        # @return [Integer] 0 on success, 1 on failure if the given startup 
value is not valid, and
+        #   2 on failure because any other reason.
+        def login(options = {})
+          auth = iscsi_auth(options)
+          startup = options["Startup"]
+
+          if startup && 
!DInstaller::Storage::ISCSI::Manager::STARTUP_OPTIONS.include?(startup)
+            logger.info("iSCSI login error: startup value #{startup} is not 
valid")
+            return 1
+          end
+
+          success = iscsi_manager.login(iscsi_node, auth, startup: startup)
+          return 0 if success
+
+          logger.info("iSCSI login error: fail to login iSCSI node #{path}")
+          2 # Error code
+        end
+
+        # Logouts the iSCSI session
+        #
+        # @return [Integer] 0 on success, 1 on failure
+        def logout
+          success = iscsi_manager.logout(iscsi_node)
+          success ? 0 : 1
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/dbus/storage/iscsi_nodes_tree.rb 
new/lib/dinstaller/dbus/storage/iscsi_nodes_tree.rb
--- old/lib/dinstaller/dbus/storage/iscsi_nodes_tree.rb 1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/dinstaller/dbus/storage/iscsi_nodes_tree.rb 2023-02-24 
14:18:28.000000000 +0100
@@ -0,0 +1,162 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+require "dinstaller/dbus/with_path_generator"
+require "dinstaller/dbus/storage/iscsi_node"
+
+module DInstaller
+  module DBus
+    module Storage
+      # Class representing the iSCSI nodes tree exported on D-Bus
+      class ISCSINodesTree
+        include WithPathGenerator
+
+        ROOT_PATH = "/org/opensuse/DInstaller/Storage1/iscsi_nodes"
+        path_generator ROOT_PATH
+
+        # Constructor
+        #
+        # @param service [::DBus::Service]
+        # @param iscsi_manager DInstaller::Storage::ISCSI::Manager]
+        # @param logger [Logger, nil]
+        def initialize(service, iscsi_manager, logger: nil)
+          @service = service
+          @iscsi_manager = iscsi_manager
+          @logger = logger
+        end
+
+        # Finds an iSCSI D-Bus node exported with the given path
+        #
+        # @param path [::DBus::ObjectPath]
+        def find(path)
+          dbus_nodes.find { |n| n.path == path }
+        end
+
+        # Updates the D-Bus tree according to the given iSCSI nodes
+        #
+        # New nodes are exported, existing nodes are updated and missing nodes 
are unexported.
+        #
+        # @param iscsi_nodes [Array<DInstaller::Storage::ISCSI::Node>]
+        def update(iscsi_nodes)
+          add_new_nodes(iscsi_nodes)
+          update_existing_nodes(iscsi_nodes)
+          delete_old_nodes(iscsi_nodes)
+        end
+
+      private
+
+        # @return [::DBus::Service]
+        attr_reader :service
+
+        # @return [DInstaller::Storage::ISCSI::Manager]
+        attr_reader :iscsi_manager
+
+        # @return [Logger]
+        attr_reader :logger
+
+        # Exports a new iSCSI D-Bus node for the given iSCSI nodes which do 
not have a D-Bus object
+        #
+        # @param iscsi_nodes [Array<DInstaller::Storage::ISCSI::Node>]
+        def add_new_nodes(iscsi_nodes)
+          new_iscsi_nodes = iscsi_nodes.select { |n| find_node(n).nil? }
+          new_iscsi_nodes.each { |n| add_node(n) }
+        end
+
+        # Updates the D-Bus iSCSI node for the given iSCSI nodes that already 
have a D-Bus object
+        #
+        # @param iscsi_nodes [Array<DInstaller::Storage::ISCSI::Node>]
+        def update_existing_nodes(iscsi_nodes)
+          existing_iscsi_nodes = iscsi_nodes.reject { |n| find_node(n).nil? }
+          existing_iscsi_nodes.each { |n| update_node(n) }
+        end
+
+        # Unexports the D-Bus iSCSI nodes that do not represent any of the 
given iSCSI nodes
+        #
+        # @param iscsi_nodes [Array<DInstaller::Storage::ISCSI::Node>]
+        def delete_old_nodes(iscsi_nodes)
+          current_iscsi_nodes = dbus_nodes.map(&:iscsi_node)
+          deleted_iscsi_nodes = current_iscsi_nodes.select do |current_node|
+            iscsi_nodes.none? { |n| same_iscsi_node?(n, current_node) }
+          end
+
+          deleted_iscsi_nodes.each { |n| delete_node(n) }
+        end
+
+        # Exports a D-Bus node for the given iSCSI node
+        #
+        # @param iscsi_node [DInstaller::Storage::ISCSI::Node]
+        def add_node(iscsi_node)
+          dbus_node = DBus::Storage::ISCSINode.new(
+            iscsi_manager, iscsi_node, next_path, logger: logger
+          )
+          service.export(dbus_node)
+          dbus_node.path
+        end
+
+        # Updates the D-Bus node associated to the given iSCSI node
+        #
+        # @param iscsi_node [DInstaller::Storage::ISCSI::Node]
+        def update_node(iscsi_node)
+          dbus_node = find_node(iscsi_node)
+          dbus_node.iscsi_node = iscsi_node
+        end
+
+        # Unexports the D-Bus node associated to the given iSCSI node
+        #
+        # @param iscsi_node [DInstaller::Storage::ISCSI::Node]
+        def delete_node(iscsi_node)
+          dbus_node = find_node(iscsi_node)
+          service.unexport(dbus_node)
+        end
+
+        # Returns the D-Bus node associated to the given iSCSI node
+        #
+        # @param iscsi_node [DInstaller::Storage::ISCSI::Node]
+        # @return [DInstaller::DBus::Storage::ISCSINode]
+        def find_node(iscsi_node)
+          dbus_nodes.find { |n| same_iscsi_node?(n.iscsi_node, iscsi_node) }
+        end
+
+        # All exported iSCSI D-Bus nodes
+        #
+        # @return [Array<DInstaller::DBus::Storage::ISCSINode>]
+        def dbus_nodes
+          root = service.get_node(ROOT_PATH, create: false)
+          return [] unless root
+
+          root.descendant_objects
+        end
+
+        # Whether the given iSCSI nodes can be considered the same iSCSI node
+        #
+        # @param iscsi_node1 [DInstaller::Storage::ISCSI::Node]
+        # @param iscsi_node2 [DInstaller::Storage::ISCSI::Node]
+        #
+        # @return [Boolean]
+        def same_iscsi_node?(iscsi_node1, iscsi_node2)
+          [:address, :port, :target, :interface].all? do |method|
+            iscsi_node1.public_send(method) == iscsi_node2.public_send(method)
+          end
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/dbus/storage/manager.rb 
new/lib/dinstaller/dbus/storage/manager.rb
--- old/lib/dinstaller/dbus/storage/manager.rb  2023-02-15 17:34:43.000000000 
+0100
+++ new/lib/dinstaller/dbus/storage/manager.rb  2023-02-24 14:18:28.000000000 
+0100
@@ -25,14 +25,18 @@
 require "dinstaller/dbus/interfaces/progress"
 require "dinstaller/dbus/interfaces/service_status"
 require "dinstaller/dbus/interfaces/validation"
+require "dinstaller/dbus/storage/proposal"
 require "dinstaller/dbus/storage/proposal_settings_converter"
 require "dinstaller/dbus/storage/volume_converter"
+require "dinstaller/dbus/storage/with_iscsi_auth"
+require "dinstaller/dbus/storage/iscsi_nodes_tree"
 
 module DInstaller
   module DBus
     module Storage
       # D-Bus object to manage storage installation
       class Manager < BaseObject
+        include WithISCSIAuth
         include WithServiceStatus
         include ::DBus::ObjectManager
         include DBus::Interfaces::Progress
@@ -52,17 +56,12 @@
           register_proposal_callbacks
           register_progress_callbacks
           register_service_status_callbacks
+          register_iscsi_callbacks
         end
 
         STORAGE_INTERFACE = "org.opensuse.DInstaller.Storage1"
         private_constant :STORAGE_INTERFACE
 
-        dbus_interface STORAGE_INTERFACE do
-          dbus_method(:Probe) { probe }
-          dbus_method(:Install) { install }
-          dbus_method(:Finish) { finish }
-        end
-
         def probe
           busy_while { backend.probe }
         end
@@ -75,22 +74,15 @@
           busy_while { backend.finish }
         end
 
+        dbus_interface STORAGE_INTERFACE do
+          dbus_method(:Probe) { probe }
+          dbus_method(:Install) { install }
+          dbus_method(:Finish) { finish }
+        end
+
         PROPOSAL_CALCULATOR_INTERFACE = 
"org.opensuse.DInstaller.Storage1.Proposal.Calculator"
         private_constant :PROPOSAL_CALCULATOR_INTERFACE
 
-        dbus_interface PROPOSAL_CALCULATOR_INTERFACE do
-          dbus_reader :available_devices, "a(ssa{sv})"
-
-          dbus_reader :volume_templates, "aa{sv}"
-
-          dbus_reader :result, "o"
-
-          # result: 0 success; 1 error
-          dbus_method :Calculate, "in settings:a{sv}, out result:u" do 
|settings|
-            busy_while { calculate_proposal(settings) }
-          end
-        end
-
         # List of disks available for installation
         #
         # Each device is represented by an array containing the name of the 
device and the label to
@@ -131,6 +123,82 @@
           success ? 0 : 1
         end
 
+        dbus_interface PROPOSAL_CALCULATOR_INTERFACE do
+          dbus_reader :available_devices, "a(ssa{sv})"
+
+          dbus_reader :volume_templates, "aa{sv}"
+
+          dbus_reader :result, "o"
+
+          # result: 0 success; 1 error
+          dbus_method :Calculate, "in settings:a{sv}, out result:u" do 
|settings|
+            busy_while { calculate_proposal(settings) }
+          end
+        end
+
+        ISCSI_INITIATOR_INTERFACE = 
"org.opensuse.DInstaller.Storage1.ISCSI.Initiator"
+        private_constant :ISCSI_INITIATOR_INTERFACE
+
+        # Gets the iSCSI initiator name
+        #
+        # @return [String]
+        def initiator_name
+          backend.iscsi.initiator.name || ""
+        end
+
+        # Sets the iSCSI initiator name
+        #
+        # @param value [String]
+        def initiator_name=(value)
+          backend.iscsi.initiator.name = value
+        end
+
+        # Performs an iSCSI discovery
+        #
+        # @param address [String] IP address of the iSCSI server
+        # @param port [Integer] Port of the iSCSI server
+        # @param options [Hash<String, String>] Options from a D-Bus call:
+        #   @option Username [String] Username for authentication by target
+        #   @option Password [String] Password for authentication by target
+        #   @option ReverseUsername [String] Username for authentication by 
initiator
+        #   @option ReversePassword [String] Username for authentication by 
inititator
+        #
+        # @return [Integer] 0 on success, 1 on failure
+        def iscsi_discover(address, port, options = {})
+          success = backend.iscsi.discover_send_targets(address, port, 
iscsi_auth(options))
+          success ? 0 : 1
+        end
+
+        # Deletes an iSCSI node from the database
+        #
+        # @param path [::DBus::ObjectPath]
+        # @return [Integer] 0 on success, 1 on failure if the given node is 
not exported, 2 on
+        #   failure because any other reason.
+        def iscsi_delete(path)
+          dbus_node = iscsi_nodes_tree.find(path)
+          if !dbus_node
+            logger.info("iSCSI delete error: iSCSI node #{path} is not 
exported")
+            return 1
+          end
+
+          success = backend.iscsi.delete(dbus_node.iscsi_node)
+          return 0 if success
+
+          logger.info("iSCSI delete error: fail to delete iSCSI node #{path}")
+          2 # Error code
+        end
+
+        dbus_interface ISCSI_INITIATOR_INTERFACE do
+          dbus_accessor :initiator_name, "s"
+
+          dbus_method :Discover,
+            "in address:s, in port:u, in options:a{sv}, out result:u" do 
|address, port, options|
+            busy_while { iscsi_discover(address, port, options) }
+          end
+
+          dbus_method(:Delete, "in node:o, out result:u") { |n| 
iscsi_delete(n) }
+        end
+
       private
 
         # @return [DInstaller::Storage::Manager]
@@ -152,6 +220,12 @@
           end
         end
 
+        def register_iscsi_callbacks
+          backend.iscsi.on_probe do
+            refresh_iscsi_nodes
+          end
+        end
+
         def properties_changed
           properties = interfaces_and_properties[PROPOSAL_CALCULATOR_INTERFACE]
           dbus_properties_changed(PROPOSAL_CALCULATOR_INTERFACE, properties, 
[])
@@ -162,6 +236,15 @@
           @dbus_proposal = DBus::Storage::Proposal.new(proposal, logger)
           @service.export(@dbus_proposal)
         end
+
+        def refresh_iscsi_nodes
+          nodes = backend.iscsi.nodes
+          iscsi_nodes_tree.update(nodes)
+        end
+
+        def iscsi_nodes_tree
+          @iscsi_nodes_tree ||= ISCSINodesTree.new(@service, backend.iscsi, 
logger: logger)
+        end
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/dbus/storage/with_iscsi_auth.rb 
new/lib/dinstaller/dbus/storage/with_iscsi_auth.rb
--- old/lib/dinstaller/dbus/storage/with_iscsi_auth.rb  1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/dinstaller/dbus/storage/with_iscsi_auth.rb  2023-02-24 
14:18:28.000000000 +0100
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+require "y2iscsi_client/authentication"
+
+module DInstaller
+  module DBus
+    module Storage
+      # Mixin for creating an iSCSI authentication object from D-Bus options
+      module WithISCSIAuth
+        # Creates an iSCSI authentication object
+        #
+        # @param dbus_options [Hash<String, String>] Options from a D-Bus call:
+        #   @option Username [String] Username for authentication by target
+        #   @option Password [String] Password for authentication by target
+        #   @option ReverseUsername [String] Username for authentication by 
initiator
+        #   @option ReversePassword [String] Username for authentication by 
inititator
+        #
+        # @return [Y2IscsiClient::Authentication]
+        def iscsi_auth(dbus_options)
+          Y2IscsiClient::Authentication.new.tap do |auth|
+            auth.username = dbus_options["Username"]
+            auth.password = dbus_options["Password"]
+            auth.username_in = dbus_options["ReverseUsername"]
+            auth.password_in = dbus_options["ReversePassword"]
+          end
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/dbus/with_path_generator.rb 
new/lib/dinstaller/dbus/with_path_generator.rb
--- old/lib/dinstaller/dbus/with_path_generator.rb      1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/dinstaller/dbus/with_path_generator.rb      2023-02-24 
14:18:28.000000000 +0100
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+require "dbus/object_path"
+require "pathname"
+
+module DInstaller
+  module DBus
+    # Mixin for creating D-Bus path of dynamically exported objects
+    #
+    # @example
+    #   class Test1
+    #     include WithPathGenerator
+    #     path_generator "/test1/objects"
+    #   end
+    #
+    #   class Test2
+    #     include WithPathGenerator
+    #     path_generator "/test2", "object"
+    #   end
+    #
+    #   test1.next_path #=> "/test1/objects/1"
+    #   test1.next_path #=> "/test1/objects/2"
+    #
+    #   test2.next_path #=> "/test2/object1"
+    #   test2.next_path #=> "/test2/object2"
+    module WithPathGenerator
+      # Generates the next based on the configuration of the path generator
+      #
+      # @return [::DBus::ObjectPath]
+      def next_path
+        self.class.next_path
+      end
+
+      def self.included(base)
+        base.extend ClassMethods
+      end
+
+      # Define class methods
+      module ClassMethods
+        def next_path
+          raise "path_generator not configured yet" unless @path_generator
+
+          @path_generator.next
+        end
+
+        # Configures the path generator
+        #
+        # @param base_path [String]
+        # @param base_name [String]
+        def path_generator(base_path, base_name = "")
+          @path_generator = PathGenerator.new(base_path, base_name)
+        end
+
+        # Class for generating an object path
+        class PathGenerator
+          def initialize(base_path, base_name)
+            @base_path = base_path
+            @base_name = base_name
+          end
+
+          def next
+            path = Pathname.new(@base_path).join(@base_name + next_id.to_s)
+            ::DBus::ObjectPath.new(path.to_s)
+          end
+
+        private
+
+          # Generates the next id
+          #
+          # @return [Integer]
+          def next_id
+            @last_id ||= 0
+            @last_id += 1
+          end
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/storage/iscsi/initiator.rb 
new/lib/dinstaller/storage/iscsi/initiator.rb
--- old/lib/dinstaller/storage/iscsi/initiator.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/dinstaller/storage/iscsi/initiator.rb       2023-02-24 
14:18:28.000000000 +0100
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+Yast.import "IscsiClientLib"
+
+module DInstaller
+  module Storage
+    module ISCSI
+      # Class representing an open-iscsi initiator
+      #
+      # This class is a wrapper for YaST code dealing with the iSCSI 
initiator. Note that the YaST
+      # code uses a singleton module, so different instances of this class 
always represent the very
+      # same iSCSI initiator configured by YaST.
+      class Initiator
+        # Initiator name
+        #
+        # @return [String]
+        def name
+          Yast::IscsiClientLib.initiatorname
+        end
+
+        # Sets the inititator name
+        #
+        # @param value [String]
+        def name=(value)
+          return if Yast::IscsiClientLib.initiatorname == value
+
+          Yast::IscsiClientLib.writeInitiatorName(value)
+        end
+
+        # Configured iSCSI offload card
+        #
+        # @return [String]
+        def offload_card
+          Yast::IscsiClientLib.GetOffloadCard()
+        end
+
+        # Sets the iSCSI offload card
+        #
+        # @param value [String]
+        def offload_card=(value)
+          Yast::IscsiClientLib.SetOffloadCard(value)
+        end
+
+        # Whether the initiator name was set via iBFT
+        #
+        # @return [Boolean]
+        def ibft_name?
+          !Yast::IscsiClientLib.getiBFT.fetch("iSCSI_INITIATOR_NAME", 
"").empty?
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/storage/iscsi/manager.rb 
new/lib/dinstaller/storage/iscsi/manager.rb
--- old/lib/dinstaller/storage/iscsi/manager.rb 1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/dinstaller/storage/iscsi/manager.rb 2023-02-24 14:18:28.000000000 
+0100
@@ -0,0 +1,243 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+require "yast"
+require "dinstaller/storage/iscsi/node"
+require "dinstaller/storage/iscsi/initiator"
+
+Yast.import "IscsiClientLib"
+
+module DInstaller
+  module Storage
+    module ISCSI
+      # Manager for iSCSI
+      class Manager
+        STARTUP_OPTIONS = ["onboot", "manual", "automatic"].freeze
+
+        # iSCSI initiator
+        #
+        # @return [Initiator]
+        attr_reader :initiator
+
+        # Discovered iSCSI nodes
+        #
+        # @return [Array<Node>]
+        attr_reader :nodes
+
+        # Constructor
+        #
+        # @param logger [Logger, nil]
+        def initialize(logger: nil)
+          @logger = logger || ::Logger.new($stdout)
+          @initiator = ISCSI::Initiator.new
+
+          @on_probe_callbacks = []
+        end
+
+        # Performs actions for activating iSCSI
+        def activate
+          logger.info "Activating iSCSI"
+
+          @activated = true
+
+          # Why we need to sleep every now and then? This was copied from 
yast2-iscsi-client.
+          sl = 0.5
+
+          Yast::IscsiClientLib.getiBFT
+          sleep(sl)
+
+          # Check initiator name, creating one if missing
+          return false unless Yast::IscsiClientLib.checkInitiatorName(silent: 
true)
+
+          sleep(sl)
+
+          Yast::IscsiClientLib.getConfig
+          Yast::IscsiClientLib.autoLogOn
+          sleep(sl)
+        end
+
+        # Probes iSCSI
+        #
+        # Callbacks are called at the end, see {#on_probe}.
+        def probe
+          logger.info "Probing iSCSI"
+
+          Yast::IscsiClientLib.readSessions
+          @nodes = Yast::IscsiClientLib.getDiscovered.map { |t| 
node_from(t.split) }
+
+          @on_probe_callbacks.each(&:call)
+        end
+
+        # Performs an iSCSI discovery
+        #
+        # Based on provided address and port, ie. assuming ISNS is not used. 
Since YaST do not offer
+        # UI to configure ISNS during installation, we are assuming it's not 
supported.
+        #
+        # @note iSCSI nodes are probed again, see {#probe_after}.
+        #
+        # @param host [String] IP address
+        # @param port [Integer]
+        # @param authentication [Y2IscsiClient::Authentication]
+        #
+        # @return [Boolean] Whether the action successes
+        def discover_send_targets(host, port, authentication)
+          ensure_activated
+
+          probe_after do
+            Yast::IscsiClientLib.discover(host, port, authentication, silent: 
true)
+          end
+        end
+
+        # Creates a new iSCSI session
+        #
+        # @note iSCSI nodes are probed again if needed, see {#probe_after}.
+        #
+        # @param node [Node]
+        # @param authentication [Y2IscsiClient::Authentication]
+        # @param startup [String, nil] Startup status
+        #
+        # @return [Boolean] Whether the action successes
+        def login(node, authentication, startup: nil)
+          startup ||= Yast::IscsiClientLib.default_startup_status
+
+          if !STARTUP_OPTIONS.include?(startup)
+            logger.info(
+              "Cannot create iSCSI session because startup status is not 
valid: #{startup}"
+            )
+            return false
+          end
+
+          ensure_activated
+
+          probe_after do
+            Yast::IscsiClientLib.currentRecord = record_from(node)
+            Yast::IscsiClientLib.login_into_current(authentication, silent: 
true) &&
+              Yast::IscsiClientLib.setStartupStatus(startup)
+          end
+        end
+
+        # Closes an iSCSI session
+        #
+        # @note iSCSI nodes are probed again, see {#probe_after}.
+        #
+        # @param node [Node]
+        # @return [Boolean] Whether the action successes
+        def logout(node)
+          ensure_activated
+
+          probe_after do
+            Yast::IscsiClientLib.currentRecord = record_from(node)
+            # Yes, this is the correct method name for logging out
+            Yast::IscsiClientLib.deleteRecord
+          end
+        end
+
+        # Deletes an iSCSI node from the database
+        #
+        # @note iSCSI nodes are probed again, see {#probe_after}.
+        #
+        # @param node [Node]
+        # @return [Boolean] Whether the action successes
+        def delete(node)
+          probe_after do
+            Yast::IscsiClientLib.currentRecord = record_from(node)
+            Yast::IscsiClientLib.removeRecord
+          end
+        end
+
+        # Registers a callback to be called when the nodes are probed
+        #
+        # @param block [Proc]
+        def on_probe(&block)
+          @on_probe_callbacks << block
+        end
+
+      private
+
+        # @return [Logger]
+        attr_reader :logger
+
+        # Calls activation if needed
+        def ensure_activated
+          activate unless activated?
+        end
+
+        # Whether activation has been already performed
+        #
+        # @return [Boolean]
+        def activated?
+          !!@activated
+        end
+
+        # Creates a node from the record provided by YaST
+        #
+        # @param record [Array] Contains portal, target and interface of the 
iSCSI node.
+        # @return [Node]
+        def node_from(record)
+          ISCSI::Node.new.tap do |node|
+            node.portal = record[0]
+            node.target = record[1]
+            node.interface = record[2] || "default"
+            node.connected = false
+
+            Yast::IscsiClientLib.currentRecord = record
+            node.ibtf = 
Yast::IscsiClientLib.iBFT?(Yast::IscsiClientLib.getCurrentNodeValues)
+
+            session_record = find_session_for(record)
+
+            if session_record
+              node.connected = true
+              # FIXME: the calculation of both startup and ibft imply 
executing getCurrentNodeValues
+              # (ie. calling iscsiadm)
+              Yast::IscsiClientLib.currentRecord = session_record
+              node.startup = Yast::IscsiClientLib.getStartupStatus
+            end
+          end
+        end
+
+        # Generates a YaST record from a node
+        #
+        # @param node [Node]
+        # @return [Array]
+        def record_from(node)
+          [node.portal, node.target, node.interface]
+        end
+
+        # Finds a session for the given iSCSI record
+        #
+        # @param record [Array] Contains portal, target and interface of the 
iSCSI node.
+        # @return [Array, nil] Record for the iSCSI session
+        def find_session_for(record)
+          Yast::IscsiClientLib.currentRecord = record
+          Yast::IscsiClientLib.find_session(true)&.split
+        end
+
+        # Calls the given block and performs iSCSI probing afterwards
+        #
+        # @note Returns the result of the block.
+        # @param block [Proc]
+        def probe_after(&block)
+          block.call.tap { probe }
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/storage/iscsi/node.rb 
new/lib/dinstaller/storage/iscsi/node.rb
--- old/lib/dinstaller/storage/iscsi/node.rb    1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/dinstaller/storage/iscsi/node.rb    2023-02-24 14:18:28.000000000 
+0100
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+module DInstaller
+  module Storage
+    module ISCSI
+      # Class to represent an Open-iscsi node
+      #
+      # Bear in mind Open-iscsi does not use the term node as defined by the 
iSCSI RFC, where a node
+      # is a single iSCSI initiator or target. Open-iscsi uses the term node 
to refer to a portal on
+      # a target
+      class Node
+        # Target IP address
+        #
+        # @return [String]
+        attr_accessor :address
+
+        # Target port
+        #
+        # @return [Integer]
+        attr_accessor :port
+
+        # Target name
+        #
+        # @return [String]
+        attr_accessor :target
+
+        # Target interface
+        #
+        # @return [String]
+        attr_accessor :interface
+
+        # Whether the node was initiated by iBTF
+        #
+        # @return [Boolean]
+        attr_accessor :ibtf
+
+        # Whether the node is connected (there is a session)
+        #
+        # @return [Boolean]
+        attr_accessor :connected
+
+        # Startup status
+        #
+        # @return [String]
+        attr_accessor :startup
+
+        def ibft?
+          !!ibtf
+        end
+
+        def connected?
+          !!connected
+        end
+
+        def portal
+          "#{address}:#{port}"
+        end
+
+        def portal=(value)
+          address, port = value.split(":")
+
+          @address = address
+          @port = port.to_i
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/storage/iscsi.rb 
new/lib/dinstaller/storage/iscsi.rb
--- old/lib/dinstaller/storage/iscsi.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/dinstaller/storage/iscsi.rb 2023-02-24 14:18:28.000000000 +0100
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+# Copyright (c) [2023] SUSE LLC
+#
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, contact SUSE LLC.
+#
+# To contact SUSE LLC about this file by physical or electronic mail, you may
+# find current contact information at www.suse.com.
+
+module DInstaller
+  module Storage
+    # Module for iSCSI
+    module ISCSI
+    end
+  end
+end
+
+require "dinstaller/storage/iscsi/initiator"
+require "dinstaller/storage/iscsi/node"
+require "dinstaller/storage/iscsi/manager"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/storage/manager.rb 
new/lib/dinstaller/storage/manager.rb
--- old/lib/dinstaller/storage/manager.rb       2023-02-15 17:34:43.000000000 
+0100
+++ new/lib/dinstaller/storage/manager.rb       2023-02-24 14:18:28.000000000 
+0100
@@ -28,6 +28,7 @@
 require "dinstaller/storage/proposal"
 require "dinstaller/storage/proposal_settings"
 require "dinstaller/storage/callbacks"
+require "dinstaller/storage/iscsi/manager"
 require "dinstaller/with_progress"
 require "dinstaller/security"
 require "dinstaller/dbus/clients/questions"
@@ -111,6 +112,13 @@
         @proposal ||= Proposal.new(logger, config)
       end
 
+      # iSCSI manager
+      #
+      # @return [Storage::ISCSI::Manager]
+      def iscsi
+        @iscsi ||= ISCSI::Manager.new(logger: logger)
+      end
+
       # Validates the storage configuration
       #
       # @return [Array<ValidationError>] List of validation errors
@@ -133,12 +141,14 @@
       def activate_devices
         callbacks = Callbacks::Activate.new(questions_client, logger)
 
+        iscsi.activate
         Y2Storage::StorageManager.instance.activate(callbacks)
       end
 
       # Probes the devices
       def probe_devices
         # TODO: probe callbacks
+        iscsi.probe
         Y2Storage::StorageManager.instance.probe
       end
 
@@ -188,8 +198,7 @@
       end
 
       def tpm_proposal?
-        settings = proposal.calculated_settings
-        settings.encrypt? && !settings.lvm
+        proposal.calculated_settings.encrypt?
       end
 
       def tpm_system?
@@ -201,7 +210,7 @@
 
         @tpm_present =
           begin
-            execute_fdectl("tpm-present")
+            Yast::Execute.on_target!("fdectl", "tpm-present")
             logger.info "FDE: TPMv2 detected"
             true
           rescue Cheetah::ExecutionFailed
@@ -215,9 +224,9 @@
       end
 
       def prepare_tpm_key
-        keyfile_path = File.join(Yast::Installation.destdir, "root", 
".root.keyfile")
-        execute_fdectl(
-          "add-secondary-key", "--keyfile", keyfile_path,
+        keyfile_path = File.join("root", ".root.keyfile")
+        Yast::Execute.on_target!(
+          "fdectl", "add-secondary-key", "--keyfile", keyfile_path,
           stdin:    "#{proposal.calculated_settings.encryption_password}\n",
           recorder: Yast::ReducedRecorder.new(skip: :stdin)
         )
@@ -228,16 +237,6 @@
       rescue Cheetah::ExecutionFailed
         false
       end
-
-      def execute_fdectl(*args)
-        # Some subcommands like "tpm-present" should not require a --device 
argument, but they
-        # currently do. Let's always us until the problem at fdectl is fully 
fixed.
-        Yast::Execute.locally!("fdectl", "--device", fdectl_device, *args)
-      end
-
-      def fdectl_device
-        Yast::Installation.destdir
-      end
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dinstaller/storage/proposal.rb 
new/lib/dinstaller/storage/proposal.rb
--- old/lib/dinstaller/storage/proposal.rb      2023-02-15 17:34:43.000000000 
+0100
+++ new/lib/dinstaller/storage/proposal.rb      2023-02-24 14:18:28.000000000 
+0100
@@ -21,7 +21,6 @@
 
 require "y2storage"
 require "y2storage/dialogs/guided_setup/helpers/disk"
-require "dinstaller/with_progress"
 require "dinstaller/validation_error"
 require "dinstaller/storage/actions"
 require "dinstaller/storage/proposal_settings"
@@ -42,8 +41,6 @@
     #   proposal.calculate(settings)  #=> true
     #   proposal.calculated_volumes   #=> [Volume, Volume]
     class Proposal
-      include WithProgress
-
       # Constructor
       #
       # @param logger [Logger]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2023-02-15 17:34:43.000000000 +0100
+++ new/metadata        2023-02-24 14:18:28.000000000 +0100
@@ -8,7 +8,7 @@
 autorequire:
 bindir: bin
 cert_chain: []
-date: 2023-02-15 00:00:00.000000000 Z
+date: 2023-02-24 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: packaging_rake_tasks
@@ -254,13 +254,17 @@
 - lib/dinstaller/dbus/software/proposal.rb
 - lib/dinstaller/dbus/software_service.rb
 - lib/dinstaller/dbus/storage.rb
+- lib/dinstaller/dbus/storage/iscsi_node.rb
+- lib/dinstaller/dbus/storage/iscsi_nodes_tree.rb
 - lib/dinstaller/dbus/storage/manager.rb
 - lib/dinstaller/dbus/storage/proposal.rb
 - lib/dinstaller/dbus/storage/proposal_settings_converter.rb
 - lib/dinstaller/dbus/storage/volume_converter.rb
+- lib/dinstaller/dbus/storage/with_iscsi_auth.rb
 - lib/dinstaller/dbus/storage_service.rb
 - lib/dinstaller/dbus/users.rb
 - lib/dinstaller/dbus/users_service.rb
+- lib/dinstaller/dbus/with_path_generator.rb
 - lib/dinstaller/dbus/with_service_status.rb
 - lib/dinstaller/dbus/y2dir/manager/modules/Package.rb
 - lib/dinstaller/dbus/y2dir/manager/modules/PackagesProposal.rb
@@ -295,6 +299,10 @@
 - lib/dinstaller/storage/callbacks/activate.rb
 - lib/dinstaller/storage/callbacks/activate_luks.rb
 - lib/dinstaller/storage/callbacks/activate_multipath.rb
+- lib/dinstaller/storage/iscsi.rb
+- lib/dinstaller/storage/iscsi/initiator.rb
+- lib/dinstaller/storage/iscsi/manager.rb
+- lib/dinstaller/storage/iscsi/node.rb
 - lib/dinstaller/storage/manager.rb
 - lib/dinstaller/storage/proposal.rb
 - lib/dinstaller/storage/proposal_settings.rb
@@ -332,7 +340,7 @@
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.3.26
+rubygems_version: 3.4.6
 signing_key:
 specification_version: 4
 summary: D-Installer Service

++++++ gem2rpm.yml ++++++
--- /var/tmp/diff_new_pack.O7NLkw/_old  2023-02-28 12:48:52.736572738 +0100
+++ /var/tmp/diff_new_pack.O7NLkw/_new  2023-02-28 12:48:52.740572764 +0100
@@ -1,6 +1,8 @@
 ---
 :sourceurl: "%{mod_full_name}.gem"
 :preamble: |-
+  # Override build.rpm, see also 
https://github.com/openSUSE/obs-build/blob/master/configs/
+  %global rb_build_versions %{rb_default_ruby}
   BuildRequires:  dbus-1-common
   Requires:       dbus-1-common
   Requires:       snapper
@@ -11,6 +13,7 @@
   Requires:       yast2-network
   Requires:       yast2-proxy
   Requires:       yast2-storage-ng
+  Requires:       yast2-iscsi-client >= 4.5.7
   Requires:       yast2-users
   # yast2 with ArchFilter
   Requires:       yast2 >= 4.5.20

Reply via email to