diff --git a/service/lib/agama/dbus/storage/manager.rb b/service/lib/agama/dbus/storage/manager.rb index 7f96b546b9..a341b3bd73 100644 --- a/service/lib/agama/dbus/storage/manager.rb +++ b/service/lib/agama/dbus/storage/manager.rb @@ -303,9 +303,6 @@ def calculate_guided_proposal(settings_dbus) # List of disks available for installation # - # Each device is represented by an array containing the name of the device and the label to - # represent that device in the UI when further information is needed. - # # @return [Array<::DBus::ObjectPath>] def available_devices proposal.available_devices.map { |d| system_devices_tree.path_for(d) } diff --git a/service/lib/agama/storage/config_conversions/to_model_conversions/space_policy.rb b/service/lib/agama/storage/config_conversions/to_model_conversions/space_policy.rb index 6b028b7614..fcd33bdae0 100644 --- a/service/lib/agama/storage/config_conversions/to_model_conversions/space_policy.rb +++ b/service/lib/agama/storage/config_conversions/to_model_conversions/space_policy.rb @@ -89,7 +89,7 @@ def shrink_all?(partition_config) # @return [Boolean] def search_all?(partition_config) !partition_config.search.nil? && - partition_config.search.always_match? && + !partition_config.search.condition? && partition_config.search.max.nil? end end diff --git a/service/lib/agama/storage/config_solver.rb b/service/lib/agama/storage/config_solver.rb index f2bec9ca13..fe76fa879c 100644 --- a/service/lib/agama/storage/config_solver.rb +++ b/service/lib/agama/storage/config_solver.rb @@ -20,7 +20,6 @@ # find current contact information at www.suse.com. require "agama/storage/config_solvers" -require "y2storage/disk_analyzer" module Agama module Storage @@ -34,13 +33,10 @@ module Storage # generated from a profile. class ConfigSolver # @param product_config [Agama::Config] configuration of the product to install - # @param devicegraph [Y2Storage::Devicegraph] initial layout of the system - # @param disk_analyzer [Y2Storage::DiskAnalyzer, nil] extra information about the initial - # layout of the system - def initialize(product_config, devicegraph, disk_analyzer: nil) + # @param storage_system [Storage::System] + def initialize(product_config, storage_system) @product_config = product_config - @devicegraph = devicegraph - @disk_analyzer = disk_analyzer || Y2Storage::DiskAnalyzer.new(devicegraph) + @storage_system = storage_system end # Solves the config according to the product and the system. @@ -52,10 +48,10 @@ def solve(config) ConfigSolvers::Boot.new(product_config).solve(config) ConfigSolvers::Encryption.new(product_config).solve(config) ConfigSolvers::Filesystem.new(product_config).solve(config) - ConfigSolvers::DrivesSearch.new(devicegraph, disk_analyzer).solve(config) - ConfigSolvers::MdRaidsSearch.new(devicegraph, disk_analyzer).solve(config) + ConfigSolvers::DrivesSearch.new(storage_system).solve(config) + ConfigSolvers::MdRaidsSearch.new(storage_system).solve(config) # Sizes must be solved once the searches are solved. - ConfigSolvers::Size.new(product_config, devicegraph).solve(config) + ConfigSolvers::Size.new(product_config).solve(config) end private @@ -63,11 +59,8 @@ def solve(config) # @return [Agama::Config] attr_reader :product_config - # @return [Y2Storage::Devicegraph] - attr_reader :devicegraph - - # @return [Y2Storage::DiskAnalyzer] - attr_reader :disk_analyzer + # @return [Storage::System] + attr_reader :storage_system end end end diff --git a/service/lib/agama/storage/config_solvers/base.rb b/service/lib/agama/storage/config_solvers/base.rb index e300aa9397..b084306c09 100644 --- a/service/lib/agama/storage/config_solvers/base.rb +++ b/service/lib/agama/storage/config_solvers/base.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -33,9 +33,11 @@ def initialize(product_config) # Solves a given config. # + # @note Derived classes must implement this method. + # # @param _config [Config] def solve(_config) - raise "#solve is not defined" + raise NotImplementedError end private diff --git a/service/lib/agama/storage/config_solvers/drives_search.rb b/service/lib/agama/storage/config_solvers/drives_search.rb index dcd456b209..0dac9c2862 100644 --- a/service/lib/agama/storage/config_solvers/drives_search.rb +++ b/service/lib/agama/storage/config_solvers/drives_search.rb @@ -31,12 +31,10 @@ class DrivesSearch < DevicesSearch include SearchMatchers include WithPartitionsSearch - # @param devicegraph [Y2Storage::Devicegraph] - # @param disk_analyzer [Y2Storage::DiskAnalyzer] - def initialize(devicegraph, disk_analyzer) + # @param storage_system [Storage::System] + def initialize(storage_system) super() - @devicegraph = devicegraph - @disk_analyzer = disk_analyzer + @storage_system = storage_system end # Solves the search of the drive configs and solves the searches of their partitions. @@ -46,18 +44,15 @@ def initialize(devicegraph, disk_analyzer) # @param config [Storage::Config] # @return [Storage::Config] def solve(config) - config.drives = super(config.drives, candidate_drives) + config.drives = super(config.drives, storage_system.candidate_drives) solve_partitions_search(config.drives) config end private - # @return [Y2Storage::Devicegraph] - attr_reader :devicegraph - - # @return [Y2Storage::DiskAnalyzer] - attr_reader :disk_analyzer + # @return [Storage::System] + attr_reader :storage_system # @see DevicesSearch#match_condition? # @param drive_config [Configs::Drive] @@ -67,14 +62,6 @@ def solve(config) def match_condition?(drive_config, drive) match_name?(drive_config, drive) && match_size?(drive_config, drive) end - - # Candidate drives for solving the search of drive configs. - # - # @return [Array] - def candidate_drives - drives = devicegraph.disk_devices + devicegraph.stray_blk_devices - drives.select { |d| disk_analyzer.candidate_device?(d) } - end end end end diff --git a/service/lib/agama/storage/config_solvers/md_raids_search.rb b/service/lib/agama/storage/config_solvers/md_raids_search.rb index 3bdc0ab60d..caf5571baf 100644 --- a/service/lib/agama/storage/config_solvers/md_raids_search.rb +++ b/service/lib/agama/storage/config_solvers/md_raids_search.rb @@ -31,12 +31,10 @@ class MdRaidsSearch < DevicesSearch include SearchMatchers include WithPartitionsSearch - # @param devicegraph [Y2Storage::Devicegraph] - # @param disk_analyzer [Y2Storage::DiskAnalyzer] - def initialize(devicegraph, disk_analyzer) + # @param storage_system [Storage::System] + def initialize(storage_system) super() - @devicegraph = devicegraph - @disk_analyzer = disk_analyzer + @storage_system = storage_system end # Solves the search of the MD RAID configs and solves the searches of their partitions. @@ -46,18 +44,15 @@ def initialize(devicegraph, disk_analyzer) # @param config [Storage::Config] # @return [Storage::Config] def solve(config) - config.md_raids = super(config.md_raids, candidate_md_raids) + config.md_raids = super(config.md_raids, storage_system.candidate_md_raids) solve_partitions_search(config.md_raids) config end private - # @return [Y2Storage::Devicegraph] - attr_reader :devicegraph - - # @return [Y2Storage::DiskAnalyzer] - attr_reader :disk_analyzer + # @return [Storage::System] + attr_reader :storage_system # @see DevicesSearch#match_condition? # @param md_raid_config [Configs::MdRaid] @@ -67,13 +62,6 @@ def solve(config) def match_condition?(md_raid_config, md_raid) match_name?(md_raid_config, md_raid) && match_size?(md_raid_config, md_raid) end - - # Candidate MD RAIDs for solving the search of the configs. - # - # @return [Array] def available_devices - disk_analyzer&.candidate_disks || [] + storage_system.candidate_drives end # Storage config according to the JSON schema from the current proposal. @@ -116,10 +117,7 @@ def solve_model(model_json) .new(model_json, product_config: product_config) .convert - ConfigSolver - .new(product_config, storage_manager.probed, disk_analyzer: disk_analyzer) - .solve(config) - + ConfigSolver.new(product_config, storage_system).solve(config) ConfigConversions::ToModel.new(config).convert end @@ -169,7 +167,7 @@ def calculate_from_model(model_json) def calculate_guided(settings) logger.info("Calculating proposal with guided strategy: #{settings.inspect}") reset - @strategy = ProposalStrategies::Guided.new(product_config, logger, settings) + @strategy = ProposalStrategies::Guided.new(product_config, storage_system, settings, logger) calculate end @@ -181,7 +179,7 @@ def calculate_agama(config) logger.info("Calculating proposal with agama strategy: #{config.inspect}") reset @source_config = config.copy - @strategy = ProposalStrategies::Agama.new(product_config, logger, config) + @strategy = ProposalStrategies::Agama.new(product_config, storage_system, config, logger) calculate end @@ -195,7 +193,8 @@ def calculate_autoyast(partitioning) reset # Ensures keys are strings. partitioning = JSON.parse(partitioning.to_json) - @strategy = ProposalStrategies::Autoyast.new(product_config, logger, partitioning) + @strategy = ProposalStrategies::Autoyast + .new(product_config, storage_system, partitioning, logger) calculate end @@ -336,18 +335,16 @@ def calculate success? end + # @return [Storage::System] + def storage_system + @storage_system ||= Storage::System.new + end + # @return [Y2Storage::Proposal::Base, nil] def proposal storage_manager.proposal end - # @return [Y2Storage::DiskAnalyzer, nil] nil if the system is not probed yet. - def disk_analyzer - return unless storage_manager.probed? - - storage_manager.probed_disk_analyzer - end - # @return [Y2Storage::StorageManager] def storage_manager Y2Storage::StorageManager.instance diff --git a/service/lib/agama/storage/proposal_strategies/agama.rb b/service/lib/agama/storage/proposal_strategies/agama.rb index ecf6e6c8ca..265aec5c30 100644 --- a/service/lib/agama/storage/proposal_strategies/agama.rb +++ b/service/lib/agama/storage/proposal_strategies/agama.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -34,12 +34,13 @@ class Agama < Base alias_method :settings, :config # @param product_config [Agama::Config] - # @param logger [Logger] + # @param storage_system [Storage::System] # @param config [Agama::Storage::Config] - def initialize(product_config, logger, config) + # @param logger [Logger] + def initialize(product_config, storage_system, config, logger) textdomain "agama" - super(product_config, logger) + super(product_config, storage_system, logger) @config = config end @@ -67,11 +68,12 @@ def issues # # @return [Y2Storage::AgamaProposal] def agama_proposal - Y2Storage::AgamaProposal.new(config, + Y2Storage::AgamaProposal.new( + config, + storage_system, product_config: product_config, - devicegraph: probed_devicegraph, - disk_analyzer: disk_analyzer, - issues_list: []) + issues_list: [] + ) end end end diff --git a/service/lib/agama/storage/proposal_strategies/autoyast.rb b/service/lib/agama/storage/proposal_strategies/autoyast.rb index 5ef1841ef7..3f8b3ff392 100644 --- a/service/lib/agama/storage/proposal_strategies/autoyast.rb +++ b/service/lib/agama/storage/proposal_strategies/autoyast.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -31,12 +31,13 @@ class Autoyast < Base include Yast::I18n # @param product_config [Config] Product config - # @param logger [Logger] + # @param storage_system [Storage::System] # @param partitioning [Array] - def initialize(product_config, logger, partitioning) + # @param logger [Logger] + def initialize(product_config, storage_system, partitioning, logger) textdomain "agama" - super(product_config, logger) + super(product_config, storage_system, logger) @partitioning = partitioning end @@ -52,8 +53,8 @@ def calculate proposal = Y2Storage::AutoinstProposal.new( partitioning: partitioning, proposal_settings: proposal_settings, - devicegraph: probed_devicegraph, - disk_analyzer: disk_analyzer, + devicegraph: storage_system.devicegraph, + disk_analyzer: storage_system.analyzer, issues_list: ay_issues ) proposal.propose diff --git a/service/lib/agama/storage/proposal_strategies/base.rb b/service/lib/agama/storage/proposal_strategies/base.rb index 3ed64e009a..19d881e410 100644 --- a/service/lib/agama/storage/proposal_strategies/base.rb +++ b/service/lib/agama/storage/proposal_strategies/base.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -29,9 +29,11 @@ module ProposalStrategies # Base class for the strategies used by the Agama proposal. class Base # @param product_config [Config] Product config + # @param storage_system [Storage::System] # @param logger [Logger] - def initialize(product_config, logger) + def initialize(product_config, storage_system, logger) @product_config = product_config + @storage_system = storage_system @logger = logger end @@ -60,32 +62,12 @@ def issues # @return [Config] attr_reader :product_config + # @return [Storage::System] + attr_reader :storage_system + # @return [Logger] attr_reader :logger - # @return [Y2Storage::DiskAnalyzer, nil] nil if the system is not probed yet. - def disk_analyzer - return nil unless storage_manager.probed? - - storage_manager.probed_disk_analyzer - end - - # Available devices for installation. - # - # @return [Array] - def available_devices - disk_analyzer&.candidate_disks || [] - end - - # Devicegraph representing the system - # - # @return [Y2Storage::Devicegraph, nil] nil if the system is not probed yet. - def probed_devicegraph - return nil unless storage_manager.probed? - - storage_manager.probed - end - # @return [Y2Storage::StorageManager] def storage_manager Y2Storage::StorageManager.instance diff --git a/service/lib/agama/storage/proposal_strategies/guided.rb b/service/lib/agama/storage/proposal_strategies/guided.rb index 48a8975f36..926b8ea90c 100644 --- a/service/lib/agama/storage/proposal_strategies/guided.rb +++ b/service/lib/agama/storage/proposal_strategies/guided.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -31,12 +31,13 @@ class Guided < Base include Yast::I18n # @param product_config [Config] Product config - # @param logger [Logger] + # @param storage_system [Storage::System] # @param input_settings [ProposalSettings] - def initialize(product_config, logger, input_settings) + # @param logger [Logger] + def initialize(product_config, storage_system, input_settings, logger) textdomain "agama" - super(product_config, logger) + super(product_config, storage_system, logger) @input_settings = input_settings end @@ -76,6 +77,13 @@ def issues # @return [ProposalSettings] attr_reader :input_settings + # Available devices for installation. + # + # @return [Array] + def available_devices + storage_system.analyzer&.candidate_disks || [] + end + # Selects the first available device as target device for installation. # # @param settings [ProposalSettings] @@ -113,8 +121,8 @@ def missing_target_device?(settings) def guided_proposal(settings) Y2Storage::MinGuidedProposal.new( settings: settings.to_y2storage(config: product_config), - devicegraph: probed_devicegraph, - disk_analyzer: disk_analyzer + devicegraph: storage_system.devicegraph, + disk_analyzer: storage_system.analyzer ) end diff --git a/service/lib/agama/storage/system.rb b/service/lib/agama/storage/system.rb new file mode 100644 index 0000000000..2088ff5169 --- /dev/null +++ b/service/lib/agama/storage/system.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +# Copyright (c) [2025] 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 "y2storage/storage_manager" +require "y2storage/disk_analyzer" + +module Agama + module Storage + # Helper class for asking about the system devices. + class System + # @param devicegraph [Y2Storage::Devicegraph, nil] Devicegraph representing the system. Probed + # is used by default. + def initialize(devicegraph = nil) + return unless devicegraph + + @devicegraph = devicegraph + @disk_analizer = Y2Storage::DiskAnalyzer.new(devicegraph) + end + + # Candidate drives for installation. + # + # @return [Array] + def candidate_drives + return [] unless devicegraph + + drives = devicegraph.disk_devices + devicegraph.stray_blk_devices + drives.select { |d| analyzer.candidate_device?(d) } + end + + # Candidate MD RAIDs for installation. + # + # @return [Array] List of found issues attr_reader :issues_list - # @note The storage config (first param) is modified in several ways: - # * The search configs are solved. - # * The sizes are solved (setting the size of the selected device, assigning fallbacks, etc). + # @note The storage config (first param) is modified while solving it, see + # {#calculate_proposal}. # # @param config [Agama::Storage::Config] - # @param product_config [Agama::Config] - # @param devicegraph [Devicegraph] Starting point. If nil, then probed devicegraph will be used. - # @param disk_analyzer [DiskAnalyzer] By default, the method will create a new one based on the - # initial devicegraph or will use the one from the StorageManager if starting from probed - # (i.e. 'devicegraph' argument is also missing). - # @param issues_list [Array, nil] Stores issues found during the process. + def initialize(config, storage_system, product_config: nil, issues_list: nil) + super(devicegraph: storage_system.devicegraph, disk_analyzer: storage_system.analyzer) @config = config + @storage_system = storage_system @product_config = product_config || Agama::Config.new @issues_list = issues_list || [] end private + # @return [Agama::Storage::System] + attr_reader :storage_system + # @return [Agama::Config] attr_reader :product_config @@ -93,7 +92,7 @@ def fatal_error? # @raise [NoDiskSpaceError] if there is no enough space to perform the installation def calculate_proposal Agama::Storage::ConfigSolver - .new(product_config, initial_devicegraph, disk_analyzer: disk_analyzer) + .new(product_config, storage_system) .solve(config) issues = Agama::Storage::ConfigChecker diff --git a/service/package/rubygem-agama-yast.changes b/service/package/rubygem-agama-yast.changes index de270f3344..5c2974e4f2 100644 --- a/service/package/rubygem-agama-yast.changes +++ b/service/package/rubygem-agama-yast.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri May 16 08:45:58 UTC 2025 - José Iván López González + +- Fix list of candidate drives and candidate MD RAIDs for + installation (gh#agama-project/agama#2362). + ------------------------------------------------------------------- Wed May 14 15:15:47 UTC 2025 - José Iván López González @@ -26,7 +32,7 @@ Wed May 7 10:24:14 UTC 2025 - Imobach Gonzalez Sosa Wed May 7 06:33:28 UTC 2025 - José Iván López González - Add support for creating and reusing MD RAID devices - (gh#agama-project/agama#2286). + (gh#agama-project/agama#2286, bsc#1241958). ------------------------------------------------------------------- Tue May 6 11:33:52 UTC 2025 - Imobach Gonzalez Sosa diff --git a/service/test/agama/storage/config_checkers/context.rb b/service/test/agama/storage/config_checkers/context.rb index 55eb56790f..a5726829ec 100644 --- a/service/test/agama/storage/config_checkers/context.rb +++ b/service/test/agama/storage/config_checkers/context.rb @@ -23,16 +23,17 @@ require "agama/config" require "agama/storage/config_conversions/from_json" require "agama/storage/config_solver" +require "agama/storage/system" require "y2storage" require "y2storage/encryption_method/tpm_fde" shared_context "checker" do # Solves the config. def solve_config - devicegraph = Y2Storage::StorageManager.instance.probed + storage_system = Agama::Storage::System.new Agama::Storage::ConfigSolver - .new(product_config, devicegraph) + .new(product_config, storage_system) .solve(config) end diff --git a/service/test/agama/storage/config_conversions/model_support_checker_test.rb b/service/test/agama/storage/config_conversions/model_support_checker_test.rb index 75668465e7..19bb585353 100644 --- a/service/test/agama/storage/config_conversions/model_support_checker_test.rb +++ b/service/test/agama/storage/config_conversions/model_support_checker_test.rb @@ -24,6 +24,9 @@ require "agama/storage/config_conversions/from_json" require "agama/storage/config_solver" require "agama/storage/model_support_checker" +require "agama/storage/system" +require "y2storage/blk_device" +require "y2storage/encryption_method" require "y2storage/refinements" using Y2Storage::Refinements::SizeCasts @@ -94,13 +97,13 @@ let(:product_config) { Agama::Config.new(product_data) } - let(:devicegraph) { Y2Storage::StorageManager.instance.probed } + let(:storage_system) { Agama::Storage::System.new } let(:config) do Agama::Storage::ConfigConversions::FromJSON .new(config_json) .convert - .tap { |c| Agama::Storage::ConfigSolver.new(product_config, devicegraph).solve(c) } + .tap { |c| Agama::Storage::ConfigSolver.new(product_config, storage_system).solve(c) } end before do @@ -109,6 +112,8 @@ allow(Y2Storage::EncryptionMethod::TPM_FDE) .to(receive(:possible?)) .and_return(true) + # Speed-up fallback search (and make sure it fails) + allow(Y2Storage::BlkDevice).to receive(:find_by_any_name) end subject { described_class.new(config) } diff --git a/service/test/agama/storage/config_conversions/to_model_test.rb b/service/test/agama/storage/config_conversions/to_model_test.rb index 93490272e2..d7cc5b2255 100644 --- a/service/test/agama/storage/config_conversions/to_model_test.rb +++ b/service/test/agama/storage/config_conversions/to_model_test.rb @@ -23,6 +23,9 @@ require_relative "../../../test_helper" require "agama/storage/config_conversions" require "agama/storage/config_solver" +require "agama/storage/system" +require "y2storage/blk_device" +require "y2storage/encryption_method" require "y2storage/refinements" using Y2Storage::Refinements::SizeCasts @@ -595,13 +598,15 @@ let(:product_config) { Agama::Config.new(product_data) } - let(:devicegraph) { Y2Storage::StorageManager.instance.probed } + let(:storage_system) { Agama::Storage::System.new } + + let(:devicegraph) { storage_system.devicegraph } let(:config) do Agama::Storage::ConfigConversions::FromJSON .new(config_json) .convert - .tap { |c| Agama::Storage::ConfigSolver.new(product_config, devicegraph).solve(c) } + .tap { |c| Agama::Storage::ConfigSolver.new(product_config, storage_system).solve(c) } end before do @@ -610,6 +615,8 @@ allow(Y2Storage::EncryptionMethod::TPM_FDE) .to(receive(:possible?)) .and_return(true) + # Speed-up fallback search (and make sure it fails) + allow(Y2Storage::BlkDevice).to receive(:find_by_any_name) end subject { described_class.new(config) } diff --git a/service/test/agama/storage/config_solver_test.rb b/service/test/agama/storage/config_solver_test.rb index a2a8fe53e2..5a3b374719 100644 --- a/service/test/agama/storage/config_solver_test.rb +++ b/service/test/agama/storage/config_solver_test.rb @@ -23,6 +23,7 @@ require "agama/config" require "agama/storage/config_conversions" require "agama/storage/config_solver" +require "agama/storage/system" require "y2storage" require "y2storage/refinements" @@ -99,7 +100,7 @@ .convert end - let(:devicegraph) { Y2Storage::StorageManager.instance.probed } + let(:storage_system) { Agama::Storage::System.new } before do mock_storage(devicegraph: scenario) @@ -109,7 +110,7 @@ .and_return(true) end - subject { described_class.new(product_config, devicegraph) } + subject { described_class.new(product_config, storage_system) } describe "#solve" do let(:scenario) { "empty-hd-50GiB.yaml" } diff --git a/service/test/agama/storage/config_solvers/drives_search_test.rb b/service/test/agama/storage/config_solvers/drives_search_test.rb index 677bbd31e6..984110694e 100644 --- a/service/test/agama/storage/config_solvers/drives_search_test.rb +++ b/service/test/agama/storage/config_solvers/drives_search_test.rb @@ -22,15 +22,15 @@ require_relative "../storage_helpers" require "agama/storage/config_conversions/from_json" require "agama/storage/config_solvers/drives_search" +require "agama/storage/system" require "y2storage" describe Agama::Storage::ConfigSolvers::DrivesSearch do include Agama::RSpec::StorageHelpers - subject { described_class.new(devicegraph, disk_analyzer) } + subject { described_class.new(storage_system) } - let(:devicegraph) { Y2Storage::StorageManager.instance.probed } - let(:disk_analyzer) { Y2Storage::StorageManager.instance.probed_disk_analyzer } + let(:storage_system) { Agama::Storage::System.new } before do mock_storage(devicegraph: scenario) @@ -71,7 +71,7 @@ context "and any of the devices is not a candidate device" do before do - allow(disk_analyzer).to receive(:candidate_device?) { |d| d.name != "/dev/vda" } + allow(storage_system.analyzer).to receive(:candidate_device?) { |d| d.name != "/dev/vda" } end it "sets the first unassigned candidate device to the drive config" do diff --git a/service/test/agama/storage/config_solvers/md_raids_search_test.rb b/service/test/agama/storage/config_solvers/md_raids_search_test.rb index 662a1e54a2..5659518404 100644 --- a/service/test/agama/storage/config_solvers/md_raids_search_test.rb +++ b/service/test/agama/storage/config_solvers/md_raids_search_test.rb @@ -22,15 +22,15 @@ require_relative "../storage_helpers" require "agama/storage/config_conversions/from_json" require "agama/storage/config_solvers/md_raids_search" +require "agama/storage/system" require "y2storage" describe Agama::Storage::ConfigSolvers::MdRaidsSearch do include Agama::RSpec::StorageHelpers - subject { described_class.new(devicegraph, disk_analyzer) } + subject { described_class.new(storage_system) } - let(:devicegraph) { Y2Storage::StorageManager.instance.probed } - let(:disk_analyzer) { Y2Storage::StorageManager.instance.probed_disk_analyzer } + let(:storage_system) { Agama::Storage::System.new } before do mock_storage(devicegraph: scenario) @@ -68,7 +68,7 @@ context "and any of the devices is not a candidate device" do before do - allow(disk_analyzer).to receive(:candidate_device?) { |d| d.name != "/dev/md0" } + allow(storage_system.analyzer).to receive(:candidate_device?) { |d| d.name != "/dev/md0" } end it "sets the first unassigned candidate device to the MD RAID config" do @@ -287,7 +287,7 @@ let(:size) { { equal: value } } context "and there is a MD RAID with equal size" do - let(:value) { devicegraph.find_by_name("/dev/md2").size } + let(:value) { storage_system.devicegraph.find_by_name("/dev/md2").size } include_examples "find device", "/dev/md2" end diff --git a/service/test/agama/storage/system_test.rb b/service/test/agama/storage/system_test.rb new file mode 100644 index 0000000000..fa626c5a89 --- /dev/null +++ b/service/test/agama/storage/system_test.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +# Copyright (c) [2025] 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_relative "./storage_helpers" +require "agama/storage/system" + +describe Agama::Storage::System do + include Agama::RSpec::StorageHelpers + + before { mock_storage(devicegraph: scenario) } + + let(:disk_analyzer) { Y2Storage::StorageManager.instance.probed_disk_analyzer } + + describe "#candidate_drives" do + let(:scenario) { "disks.yaml" } + + before do + allow(disk_analyzer).to receive(:candidate_device?) { |d| d.name != "/dev/vdb" } + end + + it "includes all drives suitable for installation" do + expect(subject.candidate_drives.map(&:name)).to contain_exactly("/dev/vda", "/dev/vdc") + end + + context "if there are MD RAIDs" do + let(:scenario) { "md_raids.yaml" } + + before do + allow(disk_analyzer).to receive(:candidate_device?).and_call_original + end + + it "does not include MD RAIDs" do + expect(subject.candidate_drives.map(&:name)).to contain_exactly("/dev/vda", "/dev/vdb") + end + end + end + + describe "#candidate_md_raids" do + let(:scenario) { "md_raids.yaml" } + + before do + allow(disk_analyzer).to receive(:candidate_device?) { |d| d.name != "/dev/md0" } + end + + it "includes all MD RAIDs suitable for installation" do + expect(subject.candidate_md_raids.map(&:name)).to contain_exactly("/dev/md1", "/dev/md2") + end + end +end diff --git a/service/test/y2storage/agama_proposal_lvm_test.rb b/service/test/y2storage/agama_proposal_lvm_test.rb index 0c7130eaf2..d6e4ca84ed 100644 --- a/service/test/y2storage/agama_proposal_lvm_test.rb +++ b/service/test/y2storage/agama_proposal_lvm_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -23,6 +23,7 @@ require "agama/config" require "agama/storage/config" require "agama/storage/config_conversions/from_json" +require "agama/storage/system" require "y2storage" require "y2storage/agama_proposal" @@ -31,9 +32,11 @@ include Agama::RSpec::StorageHelpers subject(:proposal) do - described_class.new(config, issues_list: issues_list) + described_class.new(config, storage_system, issues_list: issues_list) end + let(:storage_system) { Agama::Storage::System.new } + let(:config) { config_from_json } let(:config_from_json) do diff --git a/service/test/y2storage/agama_proposal_md_lvm.rb b/service/test/y2storage/agama_proposal_md_lvm_test.rb similarity index 98% rename from service/test/y2storage/agama_proposal_md_lvm.rb rename to service/test/y2storage/agama_proposal_md_lvm_test.rb index a6d892d7ca..ebf492eab4 100644 --- a/service/test/y2storage/agama_proposal_md_lvm.rb +++ b/service/test/y2storage/agama_proposal_md_lvm_test.rb @@ -23,6 +23,7 @@ require "agama/config" require "agama/storage/config" require "agama/storage/config_conversions/from_json" +require "agama/storage/system" require "y2storage" require "y2storage/agama_proposal" @@ -31,9 +32,11 @@ include Agama::RSpec::StorageHelpers subject(:proposal) do - described_class.new(config, issues_list: issues_list) + described_class.new(config, storage_system, issues_list: issues_list) end + let(:storage_system) { Agama::Storage::System.new } + let(:config) { config_from_json } let(:config_from_json) do diff --git a/service/test/y2storage/agama_proposal_md_test.rb b/service/test/y2storage/agama_proposal_md_test.rb index b18808f1a7..a67621e15b 100644 --- a/service/test/y2storage/agama_proposal_md_test.rb +++ b/service/test/y2storage/agama_proposal_md_test.rb @@ -23,6 +23,7 @@ require "agama/config" require "agama/storage/config" require "agama/storage/config_conversions/from_json" +require "agama/storage/system" require "y2storage" require "y2storage/agama_proposal" @@ -31,9 +32,11 @@ include Agama::RSpec::StorageHelpers subject(:proposal) do - described_class.new(config, issues_list: issues_list) + described_class.new(config, storage_system, issues_list: issues_list) end + let(:storage_system) { Agama::Storage::System.new } + let(:config) { config_from_json } let(:config_from_json) do diff --git a/service/test/y2storage/agama_proposal_search_test.rb b/service/test/y2storage/agama_proposal_search_test.rb index 4945e04526..f6c359b59b 100644 --- a/service/test/y2storage/agama_proposal_search_test.rb +++ b/service/test/y2storage/agama_proposal_search_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -23,6 +23,7 @@ require "agama/config" require "agama/storage/config" require "agama/storage/config_conversions" +require "agama/storage/system" require "y2storage" require "y2storage/agama_proposal" @@ -31,9 +32,11 @@ include Agama::RSpec::StorageHelpers subject(:proposal) do - described_class.new(config, issues_list: issues_list) + described_class.new(config, storage_system, issues_list: issues_list) end + let(:storage_system) { Agama::Storage::System.new } + let(:config) { config_from_json } let(:config_from_json) do diff --git a/service/test/y2storage/agama_proposal_test.rb b/service/test/y2storage/agama_proposal_test.rb index edff7343a2..67f092064f 100644 --- a/service/test/y2storage/agama_proposal_test.rb +++ b/service/test/y2storage/agama_proposal_test.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) [2024] SUSE LLC +# Copyright (c) [2024-2025] SUSE LLC # # All Rights Reserved. # @@ -23,6 +23,7 @@ require "agama/config" require "agama/storage/config" require "agama/storage/config_conversions" +require "agama/storage/system" require "y2storage" require "y2storage/agama_proposal" @@ -75,9 +76,16 @@ def partition_config(name: nil, filesystem: nil, size: nil) include Agama::RSpec::StorageHelpers subject(:proposal) do - described_class.new(config, product_config: product_config, issues_list: issues_list) + described_class.new( + config, + storage_system, + product_config: product_config, + issues_list: issues_list + ) end + let(:storage_system) { Agama::Storage::System.new } + let(:config) { config_json ? config_from_json : default_config } let(:config_from_json) do