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