Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-agama-yast for 
openSUSE:Factory checked in at 2026-01-30 18:19:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-agama-yast (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-agama-yast.new.1995 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-agama-yast"

Fri Jan 30 18:19:38 2026 rev:35 rq:1329814 version:19.pre.devel1272.5cc4683a6

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-agama-yast/rubygem-agama-yast.changes    
2026-01-28 15:06:15.975802671 +0100
+++ 
/work/SRC/openSUSE:Factory/.rubygem-agama-yast.new.1995/rubygem-agama-yast.changes
  2026-01-30 18:20:00.447804908 +0100
@@ -1,0 +2,12 @@
+Thu Jan 29 09:55:38 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Retry requests to the web server if the connection failed
+  (gh#agama-project/agama#3096, related to bsc#1257067).
+
+-------------------------------------------------------------------
+Wed Jan 28 09:51:16 UTC 2026 - José Iván López González <[email protected]>
+
+- Configure storage and iSCSI only if needed
+  (gh#agama-project/agama#3064).
+
+-------------------------------------------------------------------

Old:
----
  agama-yast-19.pre.devel1189.efc3a4978.gem

New:
----
  agama-yast-19.pre.devel1272.5cc4683a6.gem

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

Other differences:
------------------
++++++ agama-yast.spec ++++++
--- /var/tmp/diff_new_pack.3udcGh/_old  2026-01-30 18:20:01.927866663 +0100
+++ /var/tmp/diff_new_pack.3udcGh/_new  2026-01-30 18:20:01.931866830 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           agama-yast
-Version:        19.pre.devel1189.efc3a4978
+Version:        19.pre.devel1272.5cc4683a6
 Release:        0
 %define mod_name agama-yast
 %define mod_full_name %{mod_name}-%{version}

++++++ rubygem-agama-yast.spec ++++++
--- /var/tmp/diff_new_pack.3udcGh/_old  2026-01-30 18:20:02.007870001 +0100
+++ /var/tmp/diff_new_pack.3udcGh/_new  2026-01-30 18:20:02.007870001 +0100
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-agama-yast
-Version:        19.pre.devel1189.efc3a4978
+Version:        19.pre.devel1272.5cc4683a6
 Release:        0
 %define mod_name agama-yast
 %define mod_full_name %{mod_name}-%{version}

++++++ agama-yast-19.pre.devel1189.efc3a4978.gem -> 
agama-yast-19.pre.devel1272.5cc4683a6.gem ++++++
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/dbus/storage/iscsi.rb 
new/lib/agama/dbus/storage/iscsi.rb
--- old/lib/agama/dbus/storage/iscsi.rb 1980-01-02 01:00:00.000000000 +0100
+++ new/lib/agama/dbus/storage/iscsi.rb 1980-01-02 01:00:00.000000000 +0100
@@ -87,9 +87,17 @@
         def configure(serialized_config)
           config_json = JSON.parse(serialized_config, symbolize_names: true)
 
+          # Do not configure if there is no config
+          return unless config_json
+
+          # Do not configure if there is nothing to change.
+          return if manager.configured?(config_json)
+
+          logger.info("Configuring iSCSI")
+
           start_progress(1, _("Configuring iSCSI"))
-          manager.configure(config_json)
-          emit_system_changed
+          system_changed = manager.configure(config_json)
+          emit_system_changed if system_changed
           finish_progress
         end
 
@@ -98,7 +106,10 @@
         # @param serialized_options [String] Serialized dicovery options.
         # @return [Number] 0 success; 1 failure.
         def discover(serialized_options)
+          logger.info("Discovering iSCSI targets")
+
           options = JSON.parse(serialized_options, symbolize_names: true)
+
           address = options[:address]
           port = options[:port]
           credentials = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/dbus/storage/manager.rb 
new/lib/agama/dbus/storage/manager.rb
--- old/lib/agama/dbus/storage/manager.rb       1980-01-02 01:00:00.000000000 
+0100
+++ new/lib/agama/dbus/storage/manager.rb       1980-01-02 01:00:00.000000000 
+0100
@@ -169,15 +169,23 @@
         #
         # @raise If the config is not valid.
         #
-        # @param serialized_product [String] Serialized product config.
+        # @param serialized_product_config [String] Serialized product config.
         # @param serialized_config [String] Serialized storage config.
-        def configure(serialized_product, serialized_config)
+        def configure(serialized_product_config, serialized_config)
+          product_config_json = JSON.parse(serialized_product_config)
+          config_json = JSON.parse(serialized_config, symbolize_names: true)
+
+          # Do not configure if there is nothing to change.
+          return if backend.configured?(product_config_json, config_json)
+
+          logger.info("Configuring storage")
+
           system_changed = false
-          new_product_config = 
Agama::Config.new(JSON.parse(serialized_product))
+          product_config = Agama::Config.new(product_config_json)
 
-          if product_config != new_product_config
+          if backend.product_config != product_config
             system_changed = true
-            backend.product_config = new_product_config
+            backend.update_product_config(product_config)
           end
 
           start_progress(3, ACTIVATING_STEP)
@@ -197,8 +205,6 @@
           emit_system_changed if system_changed
 
           next_progress_step(CONFIGURING_STEP)
-          config_json = JSON.parse(serialized_config, symbolize_names: true)
-
           calculate_proposal(config_json)
 
           finish_progress
@@ -307,12 +313,11 @@
 
         # Configures storage using the current config.
         #
-        # @note The proposal is not calculated if there is not a config yet.
+        # @note Skips if no proposal has been calculated yet.
         def configure_with_current
-          config_json = proposal.storage_json
-          return unless config_json
+          return unless proposal.storage_json
 
-          calculate_proposal(config_json)
+          calculate_proposal(backend.config_json)
         end
 
         # @see #configure
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/http/clients/base.rb 
new/lib/agama/http/clients/base.rb
--- old/lib/agama/http/clients/base.rb  1980-01-02 01:00:00.000000000 +0100
+++ new/lib/agama/http/clients/base.rb  1980-01-02 01:00:00.000000000 +0100
@@ -37,7 +37,9 @@
         # @param path [String] path relatived to `api`` endpoint.
         # @param data [#to_json] data to send in request
         def post(path, data)
-          response = Net::HTTP.post(uri(path), data.to_json, headers)
+          response = request_with_retry do
+            Net::HTTP.post(uri(path), data.to_json, headers)
+          end
           return response unless response.is_a?(Net::HTTPClientError)
 
           @logger.warn "server returned #{response.code} with body: 
#{response.body}"
@@ -47,7 +49,9 @@
         # @param path [String] path relatived to `api`` endpoint.
         # @return [Net::HTTPResponse, nil] Net::HTTPResponse if it is not an 
Net::HTTPClientError
         def get(path)
-          response = Net::HTTP.get(uri(path), headers)
+          response = request_with_retry do
+            Net::HTTP.get(uri(path), headers)
+          end
           return response unless response.is_a?(Net::HTTPClientError)
 
           @logger.warn "server returned #{response.code} with body: 
#{response.body}"
@@ -57,7 +61,9 @@
         # @param path [String] path relatived to `api`` endpoint.
         # @param data [#to_json] data to send in request
         def put(path, data)
-          response = Net::HTTP.put(uri(path), data.to_json, headers)
+          response = request_with_retry do
+            Net::HTTP.put(uri(path), data.to_json, headers)
+          end
           return unless response.is_a?(Net::HTTPClientError)
 
           @logger.warn "server returned #{response.code} with body: 
#{response.body}"
@@ -68,8 +74,10 @@
         # @param data [#to_json] data to send in request
         def patch(path, data)
           url = uri(path)
-          http = Net::HTTP.start(url.hostname, url.port, use_ssl: url.scheme 
== "https")
-          response = http.patch(url, data.to_json, headers)
+          response = request_with_retry do
+            http = Net::HTTP.start(url.hostname, url.port, use_ssl: url.scheme 
== "https")
+            http.patch(url, data.to_json, headers)
+          end
           return response unless response.is_a?(Net::HTTPClientError)
 
           @logger.warn "server returned #{response.code} with body: 
#{response.body}"
@@ -91,6 +99,29 @@
         def auth_token
           File.read("/run/agama/token")
         end
+
+        CONNECT_ATTEMPTS = 10
+
+        # Performs a request and retries if it fails.
+        #
+        # During initialization, it might happen that Agama's web server is 
not available.
+        # This method retries the block if the connection is not possible.
+        #
+        # @return [Object] value returned by the block
+        def request_with_retry(&block)
+          attempt = 1
+          begin
+            block.call
+          rescue Errno::ECONNREFUSED => e
+            @logger.warn "Failed to contact Agama's server with error #{e} " \
+                         "(attempt #{attempt} of #{CONNECT_ATTEMPTS})."
+            raise if attempt == CONNECT_ATTEMPTS
+
+            sleep 1
+            attempt += 1
+            retry
+          end
+        end
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/storage/iscsi/initiator.rb 
new/lib/agama/storage/iscsi/initiator.rb
--- old/lib/agama/storage/iscsi/initiator.rb    1980-01-02 01:00:00.000000000 
+0100
+++ new/lib/agama/storage/iscsi/initiator.rb    1980-01-02 01:00:00.000000000 
+0100
@@ -19,11 +19,15 @@
 # To contact SUSE LLC about this file by physical or electronic mail, you may
 # find current contact information at www.suse.com.
 
+require "yast2/equatable"
+
 module Agama
   module Storage
     module ISCSI
       # Class representing an open-iscsi initiator
       class Initiator
+        include Yast2::Equatable
+
         # Initiator name
         #
         # @return [String]
@@ -34,6 +38,8 @@
         # @return [Boolean]
         attr_accessor :ibft_name
         alias_method :ibft_name?, :ibft_name
+
+        eql_attr :name, :ibft_name
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/storage/iscsi/manager.rb 
new/lib/agama/storage/iscsi/manager.rb
--- old/lib/agama/storage/iscsi/manager.rb      1980-01-02 01:00:00.000000000 
+0100
+++ new/lib/agama/storage/iscsi/manager.rb      1980-01-02 01:00:00.000000000 
+0100
@@ -86,15 +86,31 @@
         # Applies the given iSCSI config.
         #
         # @param config_json [Hash{Symbol=>Object}] Config according to the 
JSON schema.
+        # @return [Boolean] Whether the iSCSI system was changed.
         def configure(config_json)
           probe unless probed?
           config = assign_config(config_json)
+
+          initiator = self.initiator
+          nodes = self.nodes
+
           probe_after do
             configure_initiator(config)
             discover_from_portals(config)
             disconnect_missing_targets(config)
             configure_targets(config)
           end
+
+          system_changed?(initiator, nodes)
+        end
+
+        # Whether the system is already configured for the given config.
+        #
+        # @param config_json [Hash]
+        # @return [Boolean]
+        def configured?(config_json)
+          config = ConfigImporter.new(config_json).import
+          initiator_configured?(config) && nodes_configured?(config)
         end
 
       private
@@ -147,12 +163,55 @@
           @nodes
         end
 
+        # Whether the initiator is already configured for the given config.
+        #
+        # @param config [Config]
+        # @return [Boolean]
+        def initiator_configured?(config)
+          return true unless config.initiator
+
+          initiator&.name == config.initiator
+        end
+
+        # Whether all the nodes are already configured for the given config.
+        #
+        # @param config [Config]
+        # @return [Boolean]
+        def nodes_configured?(config)
+          nodes.all? { |n| node_configured?(n, config) }
+        end
+
+        # Whether the node is already configured for the given config.
+        #
+        # @param node [Node]
+        # @param config [Config]
+        #
+        # @return [Boolean]
+        def node_configured?(node, config)
+          target_config = config.find_target(node.target)
+
+          if target_config
+            node.connected? &&
+              !credentials_changed?(target_config) &&
+              !startup_changed?(target_config)
+          else
+            !node.connected || node.locked?
+          end
+        end
+
+        # Whether the system has changed.
+        #
+        # @param initiator [Initiator]
+        # @param nodes [Array<Node>]
+        def system_changed?(initiator, nodes)
+          self.initiator != initiator || self.nodes != nodes
+        end
+
         # Configures the initiator.
         #
         # @param config [ISCSI::Config]
         def configure_initiator(config)
-          return unless initiator && config.initiator
-          return if initiator.name == config.initiator
+          return if initiator_configured?(config)
 
           adapter.update_initiator(initiator, name: config.initiator)
         end
@@ -165,6 +224,7 @@
             interfaces = config.interfaces(portal)
             adapter.discover_from_portal(portal, interfaces: interfaces)
           end
+          probe_nodes
         end
 
         # Disconnects the targets that are not configured, preventing to 
disconnect locked targets.
@@ -218,6 +278,7 @@
         #
         # @return [Boolean] Whether the node was connected.
         def connect_node(node, target_config)
+          logger.info("Connecting iSCSI node: #{node.inspect}")
           adapter.login(
             node,
             credentials: target_config.credentials || {},
@@ -230,6 +291,7 @@
         # @param node [Node]
         # @return [Boolean] Whether the node was disconnected.
         def disconnect_node(node)
+          logger.info("Disconnecting iSCSI node: #{node.inspect}")
           adapter.logout(node).tap do |success|
             # Unlock the node if it was correctly disconnected.
             @locked_targets&.delete(node.target) if success
@@ -253,6 +315,7 @@
         #
         # @return [Boolean] Whether the node was updated.
         def update_node(node, target_config)
+          logger.info("Updating iSCSI node: #{node.inspect}")
           adapter.update_node(node, startup: target_config.startup)
         end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/storage/iscsi/node.rb 
new/lib/agama/storage/iscsi/node.rb
--- old/lib/agama/storage/iscsi/node.rb 1980-01-02 01:00:00.000000000 +0100
+++ new/lib/agama/storage/iscsi/node.rb 1980-01-02 01:00:00.000000000 +0100
@@ -19,6 +19,8 @@
 # To contact SUSE LLC about this file by physical or electronic mail, you may
 # find current contact information at www.suse.com.
 
+require "yast2/equatable"
+
 module Agama
   module Storage
     module ISCSI
@@ -28,6 +30,8 @@
       # is a single iSCSI initiator or target. Open-iscsi uses the term node 
to refer to a portal on
       # a target
       class Node
+        include Yast2::Equatable
+
         # Target IP address
         #
         # @return [String]
@@ -68,6 +72,8 @@
         # @return [Boolean]
         attr_accessor :locked
 
+        eql_attr :address, :port, :target, :interface, :ibft, :connected, 
:startup, :locked
+
         def locked?
           !!locked
         end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/storage/manager.rb 
new/lib/agama/storage/manager.rb
--- old/lib/agama/storage/manager.rb    1980-01-02 01:00:00.000000000 +0100
+++ new/lib/agama/storage/manager.rb    1980-01-02 01:00:00.000000000 +0100
@@ -44,6 +44,9 @@
       # @return [Agama::Config]
       attr_reader :product_config
 
+      # @return [Hash, nil]
+      attr_reader :config_json
+
       # @return [Bootloader]
       attr_reader :bootloader
 
@@ -56,15 +59,15 @@
         @bootloader = Bootloader.new(logger)
         @issues = []
         @yast_no_bls_boot = ENV["YAST_NO_BLS_BOOT"]
-        self.product_config = Agama::Config.new
+        update_product_config(Agama::Config.new)
       end
 
       # Assigns a new product config.
       #
-      # @param config [Agama::Config]
-      def product_config=(config)
-        @product_config = config
-        proposal.product_config = config
+      # @param product_config [Agama::Config]
+      def update_product_config(product_config)
+        @product_config = product_config
+        proposal.product_config = product_config
         configure_no_bls_bootloader
       end
 
@@ -90,6 +93,16 @@
         Y2Storage::StorageManager.instance.probed?
       end
 
+      # Whether the current proposal was already calculated for the given 
product and config.
+      #
+      # @param product_config_json [Hash]
+      # @param config_json [Hash]
+      #
+      # @return [Boolean]
+      def configured?(product_config_json, config_json)
+        product_config.data == product_config_json && self.config_json == 
config_json
+      end
+
       # Probes the devices.
       def probe
         callbacks = Y2Storage::Callbacks::UserProbe.new
@@ -102,7 +115,7 @@
       #   the default config is applied.
       # @return [Boolean] Whether storage was successfully configured.
       def configure(config_json = nil)
-        logger.info("Configuring storage: #{config_json}")
+        @config_json = config_json
         result = Configurator.new(proposal).configure(config_json)
         update_issues
         result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/agama/storage/volume_templates_builder.rb 
new/lib/agama/storage/volume_templates_builder.rb
--- old/lib/agama/storage/volume_templates_builder.rb   1980-01-02 
01:00:00.000000000 +0100
+++ new/lib/agama/storage/volume_templates_builder.rb   1980-01-02 
01:00:00.000000000 +0100
@@ -152,8 +152,7 @@
         outline_data = fetch(data, "outline", {})
         VolumeOutline.new.tap do |outline|
           outline.required = fetch(outline_data, "required", false)
-          outline.filesystems = fetch(outline_data, "filesystems", [])
-          outline.filesystems.map! { |fs| fs_type(fs) }
+          outline.filesystems = fetch(outline_data, "filesystems", []).map { 
|f| fs_type(f) }
           outline.snapshots_configurable = fetch(outline_data, 
"snapshots_configurable", false)
 
           size = fetch(outline_data, "auto_size", {})
@@ -163,9 +162,9 @@
           outline.base_max_size = max if max
           outline.adjust_by_ram = fetch(size, :adjust_by_ram, false)
           outline.min_size_fallback_for = Array(fetch(size, :min_fallback_for))
-          outline.min_size_fallback_for.map! { |p| cleanpath(p) }
+            .map { |p| cleanpath(p) }
           outline.max_size_fallback_for = Array(fetch(size, :max_fallback_for))
-          outline.max_size_fallback_for.map! { |p| cleanpath(p) }
+            .map { |p| cleanpath(p) }
 
           assign_snapshots_increment(outline, fetch(size, 
:snapshots_increment))
         end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        1980-01-02 01:00:00.000000000 +0100
+++ new/metadata        1980-01-02 01:00:00.000000000 +0100
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: agama-yast
 version: !ruby/object:Gem::Version
-  version: 19.pre.devel1189.efc3a4978
+  version: 19.pre.devel1272.5cc4683a6
 platform: ruby
 authors:
 - YaST Team

++++++ po.tar.bz2 ++++++

Reply via email to