Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package yast2-storage-ng for openSUSE:Factory checked in at 2024-09-22 11:05:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-storage-ng (Old) and /work/SRC/openSUSE:Factory/.yast2-storage-ng.new.29891 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-storage-ng" Sun Sep 22 11:05:52 2024 rev:163 rq:1202231 version:5.0.18 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-storage-ng/yast2-storage-ng.changes 2024-08-27 19:38:34.838560960 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-storage-ng.new.29891/yast2-storage-ng.changes 2024-09-22 11:06:05.784791139 +0200 @@ -1,0 +2,7 @@ +Fri Sep 20 13:06:00 UTC 2024 - Ancor Gonzalez Sosa <an...@suse.com> + +- Extend the API to resize partitions during a proposal (required + by gh#openSUSE/agama#1599). +- 5.0.18 + +------------------------------------------------------------------- Old: ---- yast2-storage-ng-5.0.17.tar.bz2 New: ---- yast2-storage-ng-5.0.18.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-storage-ng.spec ++++++ --- /var/tmp/diff_new_pack.ywyuRT/_old 2024-09-22 11:06:06.244810140 +0200 +++ /var/tmp/diff_new_pack.ywyuRT/_new 2024-09-22 11:06:06.244810140 +0200 @@ -17,7 +17,7 @@ Name: yast2-storage-ng -Version: 5.0.17 +Version: 5.0.18 Release: 0 Summary: YaST2 - Storage Configuration License: GPL-2.0-only OR GPL-3.0-only ++++++ yast2-storage-ng-5.0.17.tar.bz2 -> yast2-storage-ng-5.0.18.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/package/yast2-storage-ng.changes new/yast2-storage-ng-5.0.18/package/yast2-storage-ng.changes --- old/yast2-storage-ng-5.0.17/package/yast2-storage-ng.changes 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/package/yast2-storage-ng.changes 2024-09-20 15:57:19.000000000 +0200 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Fri Sep 20 13:06:00 UTC 2024 - Ancor Gonzalez Sosa <an...@suse.com> + +- Extend the API to resize partitions during a proposal (required + by gh#openSUSE/agama#1599). +- 5.0.18 + +------------------------------------------------------------------- Mon Aug 26 14:47:40 UTC 2024 - José Iván López González <jlo...@suse.com> - AutoYaST: small fix to ensure symbol for the drive type when diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/package/yast2-storage-ng.spec new/yast2-storage-ng-5.0.18/package/yast2-storage-ng.spec --- old/yast2-storage-ng-5.0.17/package/yast2-storage-ng.spec 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/package/yast2-storage-ng.spec 2024-09-20 15:57:19.000000000 +0200 @@ -16,7 +16,7 @@ # Name: yast2-storage-ng -Version: 5.0.17 +Version: 5.0.18 Release: 0 Summary: YaST2 - Storage Configuration License: GPL-2.0-only OR GPL-3.0-only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/free_disk_space.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/free_disk_space.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/free_disk_space.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/free_disk_space.rb 2024-09-20 15:57:19.000000000 +0200 @@ -95,6 +95,10 @@ # Whether the region belongs to a partition that is going to be reused # + # This only makes sense in the case of DASD devices with an implicit partition table, + # partitions are never deleted there, but 'reused' (nothing to do with the 'reuse' flag of + # planned devices). + # # @return [Boolean] def reused_partition? return false if growing? @@ -141,6 +145,26 @@ @require_end_alignment ||= disk.as_not_empty { disk.partition_table.require_end_alignment? } end + # Finds the remaining free space within the scope of the disk chunk defined by + # this (possibly outdated) FreeDiskSpace object + # + # @raise [NoDiskSpaceError] if there is no free space in the devicegraph at the region + # defined by the current FreeDiskSpace object + # + # @param devicegraph [Devicegraph] + # @return [FreeDiskSpace] free space within the area of the original FreeDiskSpace object + def updated_free_space(devicegraph) + disk = devicegraph.blk_devices.detect { |d| d.name == disk_name } + spaces = disk.as_not_empty { disk.free_spaces }.select do |space| + space.region.start >= region.start && + space.region.start < region.end + end + raise NoDiskSpaceError, "Exhausted free space" if spaces.empty? + + spaces.first + end + + # @return [String] def to_s "#<FreeDiskSpace disk_name=#{disk_name}, size=#{disk_size}, start_offset=#{start_offset}>" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/partition.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/partition.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/partition.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/partition.rb 2024-09-20 15:57:19.000000000 +0200 @@ -281,6 +281,25 @@ !disk.nil? && type.is?(:primary) && id.is?(:windows_system) end + # Whether the given disk space is located right after this partition + # + # @param disk_space [FreeDiskSpace] + # @return [Boolean] + def subsequent_slot?(disk_space) + return false if disk_space.disk != partition_table.partitionable + return false unless disk_space.region.start > region.end + + # The simplest case can be easily evaluated + return true if disk_space.region.start == (region.end + 1) + + # But if the end of the partition is not properly aligned, we may need to look closer + # FIXME: this can likely be both simpler and more efficient. But since it's used + # only for missaligned partitions is not a priority + slots = partition_table.partitions + partition_table.unused_partition_slots + break_points = slots.flat_map { |s| [s.region.start, s.region.end] } + break_points.none? { |p| p > region.end && p < disk_space.region.start } + end + protected # Values for volume specification matching diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/assigned_space.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/assigned_space.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/assigned_space.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/assigned_space.rb 2024-09-20 15:57:19.000000000 +0200 @@ -161,6 +161,15 @@ end end + # Space that can be sustracted from the start of the region without invalidating this + # valid assignation + # + # @return [DiskSize] + def disposable_size + # FIXME: This is more based on trial and error than on a real rationale + usable_extra_size - align_grain + end + # Space consumed by the EBR of one logical partition in a given disk # See https://en.wikipedia.org/wiki/Extended_boot_record # @@ -208,6 +217,14 @@ @disk_size ||= @disk_space.disk_size end + # Recalculates the information about the available space, in case it has been modified + def update_disk_space + @region = nil + @disk_size = nil + @space_start = nil + @disk_space = @disk_space.updated_free_space(devicegraph) + end + protected # Checks whether the disk space is inside an extended partition @@ -324,6 +341,11 @@ end end + # @return [Devicegraph] devicegraph in which the space is defined + def devicegraph + disk_space.disk.devicegraph + end + def partitions_sorted_by_attr(*attrs, nils_first: false, descending: false) partitions.each_with_index.sort do |one, other| compare(one, other, attrs, nils_first, descending) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/can_be_resized.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/can_be_resized.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/can_be_resized.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/can_be_resized.rb 2024-09-20 15:57:19.000000000 +0200 @@ -44,6 +44,15 @@ max_size <= device_to_reuse(devicegraph).size end + # Limit the max size to ensure the device does not grow more than a give margin + # + # @param max_grow [DiskSize] max margin to grow the device + # @param devicegraph [Devicegraph] + def limit_grow(max_grow, devicegraph) + limit = device_to_reuse(devicegraph).size + max_grow + self.max_size = [max_size, limit].min + end + protected # Implements reuse_device! hook diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/has_size.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/has_size.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/has_size.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/has_size.rb 2024-09-20 15:57:19.000000000 +0200 @@ -200,7 +200,7 @@ devices.map(&:weight).reduce(0, :+) end - # Checks if there are eough space at all + # Checks if there are enough space at all # @raise RuntimeError if there is not enough space def check_size(devices, space_size) needed_size = DiskSize.sum(devices.map(&:min)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/partition.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/partition.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/planned/partition.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/planned/partition.rb 2024-09-20 15:57:19.000000000 +0200 @@ -87,6 +87,19 @@ @primary = false end + # Whether this corresponds to a reused partition that is located right before the given + # assigned space + # + # @param assigned_space [AssignedSpace] + # @return [Boolean] + def subsequent_slot?(assigned_space) + devicegraph = assigned_space.disk_space.disk.devicegraph + dev = device_to_reuse(devicegraph) + return false unless dev + + dev.subsequent_slot?(assigned_space.disk_space) + end + def self.to_string_attrs [ :mount_point, :reuse_name, :reuse_sid, :min_size, :max_size, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/partition_creator.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/partition_creator.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/partition_creator.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/partition_creator.rb 2024-09-20 15:57:19.000000000 +0200 @@ -104,7 +104,7 @@ devices_map = {} planned_partitions.each_with_index do |part, idx| - space = free_space_within(initial_free_space) + space = initial_free_space.updated_free_space(devicegraph) primary = planned_partitions.size - idx > num_logical partition = create_partition(part, space, primary) part.format!(partition) @@ -117,22 +117,6 @@ devices_map end - # Finds the remaining free space within the scope of the disk chunk - # defined by a (probably outdated) FreeDiskSpace object - # - # @param initial_free_space [FreeDiskSpace] the original disk chunk, the - # returned free space will be within this area - def free_space_within(initial_free_space) - disk = devicegraph.blk_devices.detect { |d| d.name == initial_free_space.disk_name } - spaces = disk.as_not_empty { disk.free_spaces }.select do |space| - space.region.start >= initial_free_space.region.start && - space.region.start < initial_free_space.region.end - end - raise NoDiskSpaceError, "Exhausted free space" if spaces.empty? - - spaces.first - end - # Create a real partition for the specified planned partition within the # specified slot of free space. # @@ -150,7 +134,7 @@ create_primary_partition(planned_partition, free_space) elsif !ptable.has_extended? create_extended_partition(free_space) - free_space = free_space_within(free_space) + free_space = free_space.updated_free_space(devicegraph) create_logical_partition(planned_partition, free_space) else create_logical_partition(planned_partition, free_space) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/space_maker.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/space_maker.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/space_maker.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/space_maker.rb 2024-09-20 15:57:19.000000000 +0200 @@ -361,14 +361,17 @@ def execute_shrink(action, devicegraph, planned_partitions, disk_name) log.info "SpaceMaker#execute_shrink - #{action}" - if action.shrink_size.nil? + if action.target_size.nil? + part = devicegraph.find_device(action.sid) if planned_partitions - part = devicegraph.find_device(action.sid) - action.shrink_size = resizing_size(part, planned_partitions, disk_name) + resizing = resizing_size(part, planned_partitions, disk_name) + action.target_size = resizing > part.size ? DiskSize.zero : part.size - resizing else - action.shrink_size = DiskSize.Unlimited + # Mandatory resize + action.target_size = part.size end end + action.shrink(devicegraph) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/space_maker_actions/bigger_resize_strategy.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/space_maker_actions/bigger_resize_strategy.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/space_maker_actions/bigger_resize_strategy.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/space_maker_actions/bigger_resize_strategy.rb 2024-09-20 15:57:19.000000000 +0200 @@ -35,34 +35,29 @@ @to_delete_mandatory = [] @to_delete_optional = [] @to_wipe = [] - @to_resize = [] + @to_shrink_mandatory = [] + @to_shrink_optional = [] end # @param disk [Disk] see {List} def add_mandatory_actions(disk) return unless disk.partition_table? - devices = partitions(disk).select { |p| configured?(p, :force_delete) } - to_delete_mandatory.concat(devices) + add_mandatory_delete(disk) + add_mandatory_shrink(disk) end # @param disk [Disk] see {List} def add_optional_actions(disk, _lvm_helper) add_wipe(disk) - add_resize(disk) + add_optional_shrink(disk) add_optional_delete(disk) end # @return [Action, nil] nil if there are no more actions in the list def next source = source_for_next - dev = send(source).first - return unless dev - - return Shrink.new(dev) if source == :to_resize - return Wipe.new(dev) if source == :to_wipe - - Delete.new(dev, related_partitions: false) + send(source).first end # @param deleted_sids [Array<Integer>] see {List} @@ -70,7 +65,8 @@ send(source_for_next).shift cleanup(to_delete_mandatory, deleted_sids) cleanup(to_delete_optional, deleted_sids) - cleanup(to_resize, deleted_sids) + cleanup(to_shrink_mandatory, deleted_sids) + cleanup(to_shrink_optional, deleted_sids) end private @@ -78,16 +74,19 @@ # @return [ProposalSpaceSettings] proposal settings for making space attr_reader :settings - # @return [Array<BlkDevice>] list of devices to be deleted (mandatory) + # @return [Array<Base>] list of mandatory delete actions attr_reader :to_delete_mandatory - # @return [Array<BlkDevice>] list of devices to be deleted (optionally) + # @return [Array<Base>] list of optional delete actions attr_reader :to_delete_optional - # @return [Array<Partition>] list of partitions to be shrunk - attr_reader :to_resize + # @return [Array<Base>] list of mandatory shrink actions + attr_reader :to_shrink_mandatory + + # @return [Array<Base>] list of optional shrink actions + attr_reader :to_shrink_optional - # @return [Array<BlkDevice>] list of disks to be emptied if needed + # @return [Array<Base>] list of actions to wipe disks if needed attr_reader :to_wipe # @see #add_optional_actions @@ -95,32 +94,60 @@ def add_wipe(disk) return if disk.partition_table? - to_wipe << disk + to_wipe << Wipe.new(disk) end # @see #add_optional_actions # @param disk [Disk] - def add_resize(disk) + def add_optional_shrink(disk) return unless disk.partition_table? - partitions = partitions(disk).select { |p| configured?(p, :resize) } - return if partitions.empty? + actions = optional_shrinks(disk) + return if actions.empty? - @to_resize = (to_resize + partitions).sort { |a, b| preferred_resize(a, b) } + @to_shrink_optional = (to_shrink_optional + actions).sort do |a, b| + preferred_resize(a, b, disk.devicegraph) + end end - # Compares two partitions to decide which one should be resized first - # - # @param part1 [Partition] - # @param part2 [Partition] - def preferred_resize(part1, part2) - result = part2.recoverable_size <=> part1.recoverable_size + # @see #add_optional_shrink + # @param disk [Disk] + def optional_shrinks(disk) + partitions(disk).map do |part| + resize = resize_actions.find { |a| a.device == part.name } + next unless resize + next if resize.min_size && resize.min_size > part.size + next if resize.max_size && resize.max_size < part.size + + resize_to_shrink(part, resize) + end.compact + end + + # Compares two shrinking operations to decide which one should be executed first + # + # @param resize1 [Shrink] + # @param resize2 [Shrink] + def preferred_resize(resize1, resize2, devicegraph) + part1 = devicegraph.find_device(resize1.sid) + part2 = devicegraph.find_device(resize2.sid) + result = recoverable_size(part2, resize2) <=> recoverable_size(part1, resize1) return result unless result.zero? # Just to ensure stable sorting between different executions in case of draw part1.name <=> part2.name end + # Max space that can be recovered from the given partition, having into account the + # restrictions imposed by the its Resize action + # + # @see #preferred_resize + def recoverable_size(partition, resize) + min = resize.min_size + return partition.recoverable_size if min.nil? || min > partition.size + + [partition.recoverable_size, partition.size - min].min + end + # @see #add_optional_actions # # @param disk [Disk] @@ -128,7 +155,9 @@ return unless disk.partition_table? partitions = partitions(disk).select { |p| configured?(p, :delete) } - to_delete_optional.concat(partitions.sort { |a, b| preferred_delete(a, b) }) + partitions.sort! { |a, b| preferred_delete(a, b) } + actions = partitions.map { |p| Delete.new(p, related_partitions: false) } + to_delete_optional.concat(actions) end # Compares two partitions to decide which one should be deleted first @@ -136,10 +165,36 @@ # @param part1 [Partition] # @param part2 [Partition] def preferred_delete(part1, part2) - # Mimic order from the auto strategy. We might consider other approaches in the future. + # FIXME: Currently this mimics the order from the auto strategy. + # We might consider other approaches in the future, like deleting partitions that are + # next to another partition that needs to grow. That circumstance is maybe not so easy + # to evaluate at the start and needs to be reconsidered after every action. part2.region.start <=> part1.region.start end + # @see #add_optional_actions + # @param disk [Disk] + def add_mandatory_shrink(disk) + shrink_actions = partitions(disk).map do |part| + resize = resize_actions.find { |a| a.device == part.name } + next unless resize + next unless resize.max_size + next if part.size <= resize.max_size + + resize_to_shrink(part, resize) + end.compact + + to_shrink_mandatory.concat(shrink_actions) + end + + # @see #add_mandatory_actions + # @param disk [Disk] + def add_mandatory_delete(disk) + devices = partitions(disk).select { |p| configured?(p, :force_delete) } + actions = devices.map { |d| Delete.new(d, related_partitions: false) } + to_delete_mandatory.concat(actions) + end + # Whether the given action is configured for the given device at the proposal settings # # @see ProposalSpaceSettings#actions @@ -148,12 +203,17 @@ # @param action [Symbol] :force_delete, :delete or :resize # @return [Boolean] def configured?(device, action) - settings.actions[device.name]&.to_sym == action + case action + when :force_delete + delete_actions.select(&:mandatory).any? { |a| a.device == device.name } + when :delete + delete_actions.reject(&:mandatory).any? { |a| a.device == device.name } + end end # Removes devices with the given sids from a collection # - # @param collection [Array<BlkDevice>] + # @param collection [Array<Action>] # @param deleted_sids [Array<Integer>] def cleanup(collection, deleted_sids) collection.delete_if { |d| deleted_sids.include?(d.sid) } @@ -167,8 +227,10 @@ :to_delete_mandatory elsif to_wipe.any? :to_wipe - elsif to_resize.any? - :to_resize + elsif to_shrink_mandatory.any? + :to_shrink_mandatory + elsif to_shrink_optional.any? + :to_shrink_optional else :to_delete_optional end @@ -178,6 +240,24 @@ def partitions(disk) disk.partitions.reject { |part| part.type.is?(:extended) } end + + # Trivial conversion + def resize_to_shrink(partition, resize) + Shrink.new(partition).tap do |shrink| + shrink.min_size = resize.min_size + shrink.max_size = resize.max_size + end + end + + # All delete actions from the settings + def delete_actions + settings.actions.select { |a| a.is?(:delete) } + end + + # All resize actions from the settings + def resize_actions + settings.actions.select { |a| a.is?(:resize) } + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/space_maker_actions/shrink.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/space_maker_actions/shrink.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal/space_maker_actions/shrink.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal/space_maker_actions/shrink.rb 2024-09-20 15:57:19.000000000 +0200 @@ -26,12 +26,25 @@ # # @see Base class Shrink < Base - # @return [DiskSize] size of the space to substract ideally - attr_accessor :shrink_size + # Minimal size of the device set by the configuration, regardless of the ResizeInfo + # + # If set to nil, there is no artificial limit + # @return [DiskSize, nil] + attr_accessor :min_size + + # Max size of the device set by the configuration, regardless of the ResizeInfo + # + # If set to nil, there is no artificial limit + # @return [DiskSize, nil] + attr_accessor :max_size + + # Ideal final size of the device to satisfy the SpaceMaker algorithm + # @return [DiskSize] + attr_accessor :target_size # Reduces the size of the target partition # - # If possible, it reduces the size of the partition by {#shrink_size}. + # If possible, it reduces the size of the partition to {#adjusted_target_size}. # Otherwise, it reduces the size as much as possible. # # This method does not take alignment into account. @@ -48,9 +61,21 @@ # @param partition [Partition] def shrink_partition(partition) - target = shrink_size.unlimited? ? DiskSize.zero : partition.size - shrink_size # Explicitly avoid alignment to keep current behavior (to be reconsidered) - partition.resize(target, align_type: nil) + partition.resize(adjusted_target_size, align_type: nil) + end + + # Real target size taking into account the max and min limits + # + # @return [DiskSize] + def adjusted_target_size + if min_size && min_size > target_size + min_size + elsif max_size && max_size < target_size + max_size + else + target_size + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal_space_settings.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal_space_settings.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/proposal_space_settings.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/proposal_space_settings.rb 2024-09-20 15:57:19.000000000 +0200 @@ -19,6 +19,7 @@ require "yast" require "y2storage/equal_by_instance_variables" +require "y2storage/space_actions" module Y2Storage # Class to encapsulate all the GuidedProposal settings related to the process of making space @@ -84,27 +85,20 @@ # What to do with existing partitions if they are involved in the process of making space. # - # Keys are device names (like in BlkDevice#name, no alternative names) that correspond to a - # partition. - # - # The value for each key specifies what to do with the corresponding partition if the storage - # proposal needs to process the corresponding disk. If the device is not explicitly mentioned, - # nothing will be done. Possible values are :resize, :delete and :force_delete. - # # Entries for devices that are not involved in the proposal are ignored. For example, if all # the volumes are configured to be placed at /dev/sda but there is an entry like - # `{"/dev/sdb1" => :force_delete}`, the corresponding /dev/sdb1 partition will NOT be deleted - # because there is no reason for the proposal to process the disk /dev/sdb. + # Delete<device: "/dev/sdb1", mandatory: true>, the corresponding /dev/sdb1 partition will NOT + # be deleted because there is no reason for the proposal to process the disk /dev/sdb. # # Device names corresponding to extended partitions are also ignored. The storage proposal only # considers actions for primary and logical partitions. # - # @return [Hash{String => Symbol}] + # @return [Array<SpaceActions::Base>] attr_accessor :actions def initialize @strategy = :auto - @actions = {} + @actions = [] end # Whether the settings disable deletion of a given type of partitions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions/base.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions/base.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions/base.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions/base.rb 2024-09-20 15:57:19.000000000 +0200 @@ -0,0 +1,46 @@ +# Copyright (c) [2024] 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/equal_by_instance_variables" + +module Y2Storage + module SpaceActions + # Base class for representing the actions of the bigger_resize SpaceMaker strategy + class Base + include EqualByInstanceVariables + attr_reader :device + + # Constructor + def initialize(device) + @device = device + end + + # Checks whether this is a concrete kind(s) of action + # @return [Boolean] + def is?(*types) + (types.map(&:to_sym) & types_for_is).any? + end + + # @see #is? + def types_for_is + [] + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions/delete.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions/delete.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions/delete.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions/delete.rb 2024-09-20 15:57:19.000000000 +0200 @@ -0,0 +1,42 @@ +# Copyright (c) [2024] 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/space_actions/base" + +module Y2Storage + module SpaceActions + # Delete action to configure the bigger_resize SpaceMaker strategy + class Delete < Base + # Whether the delete action must always be executed (if the involved disk is processed) + # @return [Boolean] + attr_reader :mandatory + + # Constructor + def initialize(device, mandatory: false) + super(device) + @mandatory = mandatory + end + + # @see #is? + def types_for_is + [:delete] + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions/resize.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions/resize.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions/resize.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions/resize.rb 2024-09-20 15:57:19.000000000 +0200 @@ -0,0 +1,53 @@ +# Copyright (c) [2024] 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/space_actions/base" + +module Y2Storage + module SpaceActions + # Resize action to configure the bigger_resize SpaceMaker strategy + class Resize < Base + # Min size the device should have. + # + # Nil is equivalent to the initial size of the device (no shrinking, only growing). + # + # @return [DiskSize, nil] + attr_reader :min_size + + # Max size the device should have. + # + # Nil is equivalent to the initial size of the device (no growing, only shrinking). + # + # @return [DiskSize, nil] + attr_reader :max_size + + # Constructor + def initialize(device, min_size: DiskSize.zero, max_size: nil) + super(device) + @min_size = min_size + @max_size = max_size + end + + # @see #is? + def types_for_is + [:resize] + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions.rb new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions.rb --- old/yast2-storage-ng-5.0.17/src/lib/y2storage/space_actions.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-storage-ng-5.0.18/src/lib/y2storage/space_actions.rb 2024-09-20 15:57:19.000000000 +0200 @@ -0,0 +1,27 @@ +# Copyright (c) [2024] 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 Y2Storage + # Namespace for the objects representing the actions of the bigger_resize SpaceMaker strategy + module SpaceActions + end +end + +require "y2storage/space_actions/delete" +require "y2storage/space_actions/resize" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/partition_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/partition_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/partition_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/partition_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -446,6 +446,55 @@ end end + describe "#subsequent_slot?" do + let(:disk) { fake_devicegraph.find_by_name(disk_name) } + let(:region) { disk.partition_table.unused_partition_slots[slot].region } + let(:slot) { 0 } + let(:space) { Y2Storage::FreeDiskSpace.new(disk, region) } + subject(:partition) { fake_devicegraph.find_by_name(part_name) } + + context "when the space starts at the sector right after the partition" do + let(:scenario) { "spaces_5_5_10" } + let(:part_name) { "/dev/sda1" } + let(:disk_name) { "/dev/sda" } + + it "returns true" do + expect(partition.subsequent_slot?(space)).to eq true + end + end + + context "when the space is right after a partition with missaligned end" do + let(:scenario) { "alignment" } + let(:part_name) { "/dev/sdb1" } + let(:disk_name) { "/dev/sdb" } + + it "returns true" do + expect(partition.subsequent_slot?(space)).to eq true + end + end + + context "when the space is not adyacent to the partition" do + let(:scenario) { "spaces_5_5_10" } + let(:part_name) { "/dev/sda1" } + let(:disk_name) { "/dev/sda" } + let(:slot) { 1 } + + it "returns false" do + expect(partition.subsequent_slot?(space)).to eq false + end + end + + context "when the space starts at an appropriate sector but is in another disk" do + let(:scenario) { "alignment" } + let(:part_name) { "/dev/sdb1" } + let(:disk_name) { "/dev/sdc" } + + it "returns false" do + expect(partition.subsequent_slot?(space)).to eq false + end + end + end + # Only basic cases are tested here. More exhaustive tests can be found in tests # for Y2Storage::MatchVolumeSpec describe "#match_volume?" do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/planned/assigned_space_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/planned/assigned_space_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/planned/assigned_space_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/planned/assigned_space_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -179,4 +179,25 @@ end end end + + describe "#update_disk_space" do + before { fake_scenario("mixed_disks") } + let(:disk) { fake_devicegraph.find_by_name("/dev/sda") } + subject(:assigned) { described_class.new(disk.free_spaces.first, []) } + + it "refreshes all the information related to the available space" do + expect(assigned.region.start).to eq 209717248 + expect(assigned.disk_size).to eq 2.GiB + + disk.partition_table.create_partition( + "/dev/sda3", + Y2Storage::Region.create(assigned.region.start, 1048576, 512), + Y2Storage::PartitionType::PRIMARY + ) + assigned.update_disk_space + + expect(assigned.region.start).to eq(209717248 + 1048576) + expect(assigned.disk_size).to eq 1.5.GiB + end + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/planned/can_be_resized_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/planned/can_be_resized_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/planned/can_be_resized_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/planned/can_be_resized_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -172,4 +172,18 @@ end end end + + describe "#limit_grow" do + before { planned.max_size = 70.GiB } + + it "limits the max size if the sum of the new limit and the original size is smaller" do + planned.limit_grow(5.GiB, devicegraph) + expect(planned.max_size).to eq 55.GiB + end + + it "leaves the max size untouched if the sum of original size and limit is bigger" do + planned.limit_grow(50.GiB, devicegraph) + expect(planned.max_size).to eq 70.GiB + end + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/planned/partition_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/planned/partition_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/planned/partition_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/planned/partition_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -111,4 +111,53 @@ end end end + + describe "#subsequent_slot?" do + let(:assigned_space) { Y2Storage::Planned::AssignedSpace.new(space, []) } + let(:space) do + instance_double( + "Y2Storage::FreeDiskSpace", + disk: disk, + disk_size: 500.GiB, + align_grain: 1.MiB, + require_end_alignment?: false + ) + end + + let(:disk) { instance_double("Y2Storage::Disk", devicegraph: devicegraph) } + let(:devicegraph) { instance_double("Y2Storage::Devicegraph") } + + context "when the plan is to create a new partition" do + it "returns false" do + expect(partition.subsequent_slot?(assigned_space)).to eq false + end + end + + context "when the plan is to reuse an existing partition" do + let(:real_partition) { instance_double("Y2Storage::Partition", sid: 123) } + + before do + partition.assign_reuse(real_partition) + + allow(devicegraph).to receive(:find_device).and_return real_partition + allow(real_partition).to receive(:subsequent_slot?).with(space).and_return subsequent + end + + context "if the reused partition is next to the region of the assigned space" do + let(:subsequent) { true } + + it "returns true" do + expect(partition.subsequent_slot?(assigned_space)).to eq true + end + end + + context "if the reused partition is not adjacent to the region of the assigned space" do + let(:subsequent) { false } + + it "returns false" do + expect(partition.subsequent_slot?(assigned_space)).to eq false + end + end + end + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/proposal/space_maker_bigger_resize_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/proposal/space_maker_bigger_resize_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/proposal/space_maker_bigger_resize_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/proposal/space_maker_bigger_resize_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -39,8 +39,10 @@ settings.space_settings.actions = settings_actions settings end - let(:settings_actions) { {} } + let(:settings_actions) { [] } let(:analyzer) { Y2Storage::DiskAnalyzer.new(fake_devicegraph) } + let(:delete) { Y2Storage::SpaceActions::Delete } + let(:resize) { Y2Storage::SpaceActions::Resize } subject(:maker) { described_class.new(analyzer, settings) } @@ -48,7 +50,7 @@ let(:scenario) { "complex-lvm-encrypt" } context "if no device is set as :force_delete " do - let(:settings_actions) { { "/dev/sda1" => :delete, "/dev/sda2" => :delete } } + let(:settings_actions) { [delete.new("/dev/sda1"), delete.new("/dev/sda2")] } it "does not delete any partition" do result = maker.prepare_devicegraph(fake_devicegraph) @@ -56,9 +58,9 @@ end end - # :force_delete for disks should be ignored, actions only make sense for partitions and LVs + # Mandatory delete for disks should be ignored, actions only make sense for partitions and LVs context "if :force_delete is specified for a disk that contains partitions" do - let(:settings_actions) { { "/dev/sda" => :force_delete } } + let(:settings_actions) { [delete.new("/dev/sda", mandatory: true)] } it "does not delete any partition" do result = maker.prepare_devicegraph(fake_devicegraph) @@ -68,6 +70,9 @@ context "if :force_delete is specified for several partitions" do let(:settings_actions) { { "/dev/sda2" => :force_delete, "/dev/sde1" => :force_delete } } + let(:settings_actions) do + [delete.new("/dev/sda2", mandatory: true), delete.new("/dev/sde1", mandatory: true)] + end it "does not delete partitions out of SpaceMaker#candidate_devices" do result = maker.prepare_devicegraph(fake_devicegraph) @@ -80,11 +85,14 @@ end end - # :force_delete for disks should be ignored, actions only make sense for partitions and LVs + # Mandatory delete for disks should be ignored, actions only make sense for partitions and LVs context "if :force_delete is specified for a directly formatted disk (no partition table)" do let(:scenario) { "multipath-formatted.xml" } - let(:settings_actions) { { "/dev/mapper/0QEMU_QEMU_HARDDISK_mpath1" => :force_delete } } + let(:settings_actions) do + [delete.new("/dev/mapper/0QEMU_QEMU_HARDDISK_mpath1", mandatory: true)] + end + before do settings.candidate_devices = ["/dev/mapper/0QEMU_QEMU_HARDDISK_mpath1"] settings.root_device = "/dev/mapper/0QEMU_QEMU_HARDDISK_mpath1" @@ -104,7 +112,7 @@ context "when deleting a btrfs partition that is part of a multidevice btrfs" do let(:scenario) { "btrfs-multidevice-over-partitions.xml" } - let(:settings_actions) { { "/dev/sda1" => :force_delete } } + let(:settings_actions) { [delete.new("/dev/sda1", mandatory: true)] } it "deletes the partitions explicitly mentioned in the settings" do result = maker.prepare_devicegraph(fake_devicegraph) @@ -119,7 +127,7 @@ context "when deleting a partition that is part of a raid" do let(:scenario) { "raid0-over-partitions.xml" } - let(:settings_actions) { { "/dev/sda1" => :force_delete } } + let(:settings_actions) { [delete.new("/dev/sda1", mandatory: true)] } it "deletes the partitions explicitly mentioned in the settings" do result = maker.prepare_devicegraph(fake_devicegraph) @@ -134,7 +142,7 @@ context "when deleting a partition that is part of a lvm volume group" do let(:scenario) { "lvm-over-partitions.xml" } - let(:settings_actions) { { "/dev/sda1" => :force_delete } } + let(:settings_actions) { [delete.new("/dev/sda1", mandatory: true)] } it "deletes the partitions explicitly mentioned in the settings" do result = maker.prepare_devicegraph(fake_devicegraph) @@ -146,6 +154,31 @@ expect(result.partitions.map(&:name)).to include "/dev/sda2", "/dev/sda3", "/dev/sdb2" end end + + context "if there is a resize action with a max that is smaller than the partition size" do + using Y2Storage::Refinements::SizeCasts + + let(:scenario) { "irst-windows-linux-gpt" } + let(:settings_actions) do + [resize.new("/dev/sda2"), resize.new("/dev/sda3", max_size: 200.GiB)] + end + + let(:resize_info) do + instance_double("ResizeInfo", resize_ok?: true, min_size: 100.GiB, max_size: 800.GiB) + end + + before do + allow_any_instance_of(Y2Storage::Partition) + .to receive(:detect_resize_info).and_return(resize_info) + end + + it "resizes the partition to the specified max if possible" do + result = maker.prepare_devicegraph(fake_devicegraph) + expect(result.partitions).to include( + an_object_having_attributes(filesystem_label: "other", size: 200.GiB) + ) + end + end end describe "#provide_space" do @@ -254,10 +287,10 @@ context "if resizing some partitions and deleting others is allowed" do let(:settings_actions) do - { - "/dev/sda2" => :resize, "/dev/sda3" => :resize, - "/dev/sda5" => :delete, "/dev/sda6" => :delete - } + [ + resize.new("/dev/sda2"), resize.new("/dev/sda3"), + delete.new("/dev/sda5"), delete.new("/dev/sda6") + ] end context "and resizing one partition is enough" do @@ -285,7 +318,7 @@ end end - context "and resizing one partition is not enough" do + context "and resizing one partition is not enough because more space is needed" do let(:volumes) { [vol1, vol2] } it "resizes subsequent partitions" do @@ -311,6 +344,39 @@ end end + context "and resizing one partition is not enough because the action is limited" do + let(:volumes) { [vol1] } + + let(:settings_actions) do + [ + resize.new("/dev/sda2", min_size: 250.GiB), resize.new("/dev/sda3"), + delete.new("/dev/sda5"), delete.new("/dev/sda6") + ] + end + + it "resizes the more 'productive' partition taking restrictions into account" do + result = maker.provide_space(fake_devicegraph, volumes, lvm_helper) + expect(result[:devicegraph].partitions).to include( + an_object_having_attributes(filesystem_label: "windows", size: 360.GiB), + an_object_having_attributes(filesystem_label: "other", size: 110.GiB) + ) + end + + it "does not delete any partition" do + result = maker.provide_space(fake_devicegraph, volumes, lvm_helper) + expect(result[:devicegraph].partitions.map(&:name)).to contain_exactly( + "/dev/sda1", "/dev/sda2", "/dev/sda3", "/dev/sda4", "/dev/sda5" + ) + end + + it "suggests a distribution using the freed space" do + result = maker.provide_space(fake_devicegraph, volumes, lvm_helper) + distribution = result[:partitions_distribution] + expect(distribution.spaces.size).to eq 1 + expect(distribution.spaces.first.partitions).to eq volumes + end + end + context "and resizing all the allowed partitions is not enough" do let(:volumes) { [vol1, vol2, vol3] } @@ -335,6 +401,24 @@ expect(distribution.spaces.size).to eq 3 expect(distribution.spaces.flat_map(&:partitions)).to contain_exactly(*volumes) end + + context "if resize operations are limited" do + let(:settings_actions) do + [ + resize.new("/dev/sda2", min_size: 150.GiB), + resize.new("/dev/sda3", min_size: 110.GiB), + delete.new("/dev/sda5"), delete.new("/dev/sda6") + ] + end + + it "resizes all allowed partitions their specified limits" do + result = maker.provide_space(fake_devicegraph, volumes, lvm_helper) + expect(result[:devicegraph].partitions).to include( + an_object_having_attributes(filesystem_label: "windows", size: 150.GiB), + an_object_having_attributes(filesystem_label: "other", size: 110.GiB) + ) + end + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/proposal_agama_advanced_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/proposal_agama_advanced_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/proposal_agama_advanced_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/proposal_agama_advanced_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -42,6 +42,9 @@ { "mount_point" => "swap", "fs_type" => "swap", "min_size" => "1 GiB", "max_size" => "2 GiB" } end + let(:delete) { Y2Storage::SpaceActions::Delete } + let(:resize) { Y2Storage::SpaceActions::Resize } + let(:scenario) { "mixed_disks" } before do @@ -70,7 +73,7 @@ before do settings.candidate_devices = ["/dev/sdb"] settings.root_device = "/dev/sda" - settings.space_settings.actions = { "/dev/sda1" => :resize, "/dev/sda2" => :resize } + settings.space_settings.actions = [resize.new("/dev/sda1"), resize.new("/dev/sda2")] allow(storage_arch).to receive(:efiboot?).and_return(true) end @@ -127,7 +130,7 @@ it "tries to use the formatted disk before trying an optional delete" do sda1_sid = fake_devicegraph.find_by_name("/dev/sda1").sid - settings.space_settings.actions = { "/dev/sda1" => :delete } + settings.space_settings.actions = [delete.new("/dev/sda1")] proposal.propose expect(proposal.failed?).to eq false @@ -141,7 +144,7 @@ it "tries to use the formatted disk before trying an optional resize" do orig_sda1 = fake_devicegraph.find_by_name("/dev/sda1") - settings.space_settings.actions = { "/dev/sda1" => :resize } + settings.space_settings.actions = [resize.new("/dev/sda1")] proposal.propose expect(proposal.failed?).to eq false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/proposal_agama_basis_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/proposal_agama_basis_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/proposal_agama_basis_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/proposal_agama_basis_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -252,11 +252,11 @@ before do settings.space_settings.strategy = :bigger_resize - settings.space_settings.actions = { - "/dev/sda1" => :resize, - "/dev/sdb1" => :resize, - "/dev/sdc1" => :resize - } + settings.space_settings.actions = [ + Y2Storage::SpaceActions::Resize.new("/dev/sda1"), + Y2Storage::SpaceActions::Resize.new("/dev/sdb1"), + Y2Storage::SpaceActions::Resize.new("/dev/sdc1") + ] end include_examples "resize volume combinations" @@ -275,11 +275,11 @@ before do settings.space_settings.strategy = :bigger_resize - settings.space_settings.actions = { - "/dev/sda1" => :force_delete, - "/dev/sdb1" => :force_delete, - "/dev/sdc1" => :force_delete - } + settings.space_settings.actions = [ + Y2Storage::SpaceActions::Delete.new("/dev/sda1", mandatory: true), + Y2Storage::SpaceActions::Delete.new("/dev/sdb1", mandatory: true), + Y2Storage::SpaceActions::Delete.new("/dev/sdc1", mandatory: true) + ] end include_examples "delete volume combinations" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-5.0.17/test/y2storage/proposal_agama_reuse_test.rb new/yast2-storage-ng-5.0.18/test/y2storage/proposal_agama_reuse_test.rb --- old/yast2-storage-ng-5.0.17/test/y2storage/proposal_agama_reuse_test.rb 2024-08-26 17:03:52.000000000 +0200 +++ new/yast2-storage-ng-5.0.18/test/y2storage/proposal_agama_reuse_test.rb 2024-09-20 15:57:19.000000000 +0200 @@ -34,7 +34,7 @@ let(:settings_format) { :ng } let(:separate_home) { true } let(:control_file_content) { { "partitioning" => { "volumes" => volumes } } } - let(:space_actions) { {} } + let(:space_actions) { [] } let(:scenario) { "lvm-two-vgs" } let(:resize_info) do @@ -57,6 +57,9 @@ { "mount_point" => "swap", "fs_type" => "swap", "min_size" => "2 GiB", "max_size" => "6 GiB" } end + let(:delete) { Y2Storage::SpaceActions::Delete } + let(:resize) { Y2Storage::SpaceActions::Resize } + before do # Speed-up things by avoiding calls to hwinfo allow_any_instance_of(Y2Storage::Disk).to receive(:hwinfo).and_return(Y2Storage::HWInfoDisk.new) @@ -82,7 +85,9 @@ srv.reformat = reformat end - let(:space_actions) { { "/dev/sda1" => :delete, "/dev/sda2" => :delete, "/dev/sda8" => :delete } } + let(:space_actions) do + [delete.new("/dev/sda1"), delete.new("/dev/sda2"), delete.new("/dev/sda8")] + end let(:original_sda8) { fake_devicegraph.find_by_name("/dev/sda8") } context "keeping its filesystem" do @@ -129,7 +134,7 @@ srv.reformat = reformat end - let(:space_actions) { { "/dev/sda1" => :delete, "/dev/sda4" => :delete } } + let(:space_actions) { [delete.new("/dev/sda1"), delete.new("/dev/sda4")] } let(:original_sda4) { fake_devicegraph.find_by_name("/dev/sda4") } context "keeping its filesystem" do @@ -178,7 +183,9 @@ srv.reformat = reformat end - let(:space_actions) { { "/dev/sda1" => :delete, "/dev/sda2" => :delete, "/dev/sda5" => :delete } } + let(:space_actions) do + [delete.new("/dev/sda1"), delete.new("/dev/sda2"), delete.new("/dev/sda5")] + end let(:original_sda5) { fake_devicegraph.find_by_name("/dev/sda5") } context "keeping its filesystem" do @@ -316,7 +323,7 @@ srv.reuse_name = "/dev/md1" end - let(:space_actions) { { "/dev/sda2" => :delete, "/dev/sdb2" => :delete } } + let(:space_actions) { [delete.new("/dev/sda2"), delete.new("/dev/sdb2")] } let(:original_sda2) { fake_devicegraph.find_by_name("/dev/sda2") } let(:original_sdb2) { fake_devicegraph.find_by_name("/dev/sdb2") } @@ -345,7 +352,7 @@ srv.reuse_name = "/dev/md0" end - let(:space_actions) { { "/dev/sda1" => :delete, "/dev/sdb1" => :delete } } + let(:space_actions) { [delete.new("/dev/sda1"), delete.new("/dev/sdb1")] } let(:original_sda1) { fake_devicegraph.find_by_name("/dev/sda1") } let(:original_sdb1) { fake_devicegraph.find_by_name("/dev/sdb1") } @@ -383,7 +390,7 @@ srv.reformat = false end - let(:space_actions) { { "/dev/sda2" => :delete, "/dev/sdb2" => :delete } } + let(:space_actions) { [delete.new("/dev/sda2"), delete.new("/dev/sdb2")] } let(:original_sda2) { fake_devicegraph.find_by_name("/dev/sda2") } let(:original_sdb2) { fake_devicegraph.find_by_name("/dev/sdb2") } @@ -413,7 +420,7 @@ srv.reformat = false end - let(:space_actions) { { "/dev/sda2" => :delete, "/dev/sdb2" => :delete } } + let(:space_actions) { [delete.new("/dev/sda2"), delete.new("/dev/sdb2")] } let(:original_sda2) { fake_devicegraph.find_by_name("/dev/sda2") } let(:original_sdb2) { fake_devicegraph.find_by_name("/dev/sdb2") } @@ -477,10 +484,10 @@ end let(:space_actions) do - { - "/dev/sda1" => :delete, "/dev/sda2" => :delete, "/dev/sda3" => :delete, - "/dev/sdb1" => :delete, "/dev/sdb2" => :delete - } + [ + delete.new("/dev/sda1"), delete.new("/dev/sda2"), delete.new("/dev/sda3"), + delete.new("/dev/sdb1"), delete.new("/dev/sdb2") + ] end let(:original_sdb1) { fake_devicegraph.find_by_name("/dev/sdb1") }