Skip to content

Commit

Permalink
[Service] Make it possible to use non-auto sizes for volumes with adj…
Browse files Browse the repository at this point in the history
…ust_by_ram (#1111)

## Problem

In Agama a volume can have automatic sizes based on one or several of
the following reasons:

- Snapshots
- Fallbacks from other volumes (eg. "/" max size can exist or not based
on the existence of "/home")
- Size of the RAM

But the third one was not working because it was impossible to set the
sizes manually for volumes with the property `adjust_by_ram` in their
corresponding outline.

## Solution

This sets the new YaST setting `ignore_adjust_by_ram` if the user has
decided to manually enforce sizes. So now it's possible to honor the
automatic size or to use custom sizes instead.

Using the automatic size

| The table | The form |
|-|-|
|
![table-auto](https://github.com/openSUSE/agama/assets/3638289/4f7d2b6f-b728-4d47-aca4-8321301e822a)
|
![form-auto](https://github.com/openSUSE/agama/assets/3638289/eb072fd2-011f-4eb8-8c02-1a218053254b)
|

Forcing manual sizes

| The table | The form |
|-|-|
|
![table-man](https://github.com/openSUSE/agama/assets/3638289/a25510fa-b4fd-40f4-bc4c-c096995a6c57)
|
![form-man](https://github.com/openSUSE/agama/assets/3638289/59994396-3627-4dac-b18b-5aa63ce0dbcc)
|



To get some background on how this functionality compares to the
traditional YaST checkbox "Enlarge to RAM Size for Suspend", see the
dedicated section at the description of
#1081.

Additionally, this pull request enables `adjust_by_ram` for swap at the
Tumbleweed product, to raise awareness and get feedback.

## Testing

- Added a new unit test
- Tested manually (see screenshots above)

## Dependencies

Needs yast/yast-storage-ng#1376 at
yast2-storage-ng, which implies the corresponding rpm dependency has
been updated.
  • Loading branch information
ancorgs authored Mar 22, 2024
2 parents 03a6b6b + 7fd7f75 commit afa39b5
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 8 deletions.
8 changes: 5 additions & 3 deletions products.d/tumbleweed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,12 @@ storage:
- mount_path: "swap"
filesystem: swap
size:
auto: false
min: 1 GiB
max: 2 GiB
auto: true
outline:
auto_size:
base_min: 1 GiB
base_max: 2 GiB
adjust_by_ram: true
required: false
filesystems:
- swap
Expand Down
12 changes: 11 additions & 1 deletion service/lib/agama/storage/volume_conversion/from_y2storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def convert

# @param target [Agama::Storage::Volume]
def sizes_conversion(target)
target.auto_size = !spec.ignore_fallback_sizes? || !spec.ignore_snapshots_sizes?
target.auto_size = auto_size?

# The volume specification contains the min and max sizes for the volume. But the final
# range of sizes used by the Y2Storage proposal depends on the fallback sizes (if this
Expand All @@ -74,6 +74,16 @@ def sizes_conversion(target)
target.max_size = planned&.max || spec.max_size
end

# @see #sizes_conversion
#
# @return [Boolean]
def auto_size?
# The three ignore_xxx attributes (ignore_snapshots_sizes, ignore_fallback_sizes and
# ignore_adjust_by_ram) are always in sync and always initialized to the inverse of
# #auto_size
!spec.ignore_fallback_sizes?
end

# @param target [Agama::Storage::Volume]
def btrfs_conversion(target)
target.btrfs.snapshots = spec.snapshots?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def sizes_conversion(target)

target.ignore_fallback_sizes = !auto
target.ignore_snapshots_sizes = !auto
target.ignore_adjust_by_ram = !auto

# The range of sizes is defined by the volume outline in case of auto size (mix and max
# sizes cannot be configured if auto size is set).
Expand Down
2 changes: 1 addition & 1 deletion service/package/gem2rpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
Requires: yast2-iscsi-client >= 4.5.7
Requires: yast2-network
Requires: yast2-proxy
Requires: yast2-storage-ng >= 5.0.8
Requires: yast2-storage-ng >= 5.0.10
Requires: yast2-users
%ifarch s390 s390x
Requires: yast2-s390 >= 4.6.4
Expand Down
6 changes: 6 additions & 0 deletions service/package/rubygem-agama-yast.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Fri Mar 22 09:18:20 UTC 2024 - Ancor Gonzalez Sosa <[email protected]>

- Make it possible to use non-auto sizes for volumes with
adjust_by_ram (gh#openSUSE/agama#1111).

-------------------------------------------------------------------
Thu Mar 21 10:35:09 UTC 2024 - Ancor Gonzalez Sosa <[email protected]>

Expand Down
75 changes: 72 additions & 3 deletions service/test/agama/storage/proposal_volumes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@

describe Agama::Storage::Proposal do
include Agama::RSpec::StorageHelpers
before { mock_storage }
before do
allow(Yast::SCR).to receive(:Read).and_call_original
allow(Yast::SCR).to receive(:Read).with(path(".proc.meminfo"))
.and_return("memtotal" => 8388608)

mock_storage
end

subject(:proposal) { described_class.new(config, logger: logger) }

Expand All @@ -42,7 +48,7 @@

let(:cfg_volumes) { ["/", "swap"] }

let(:cfg_templates) { [root_template, other_template] }
let(:cfg_templates) { [root_template, swap_template, other_template] }
let(:root_template) do
{
"mount_path" => "/", "filesystem" => "btrfs", "size" => { "auto" => true },
Expand All @@ -55,6 +61,14 @@
}
}
end
let(:swap_template) do
{
"mount_path" => "swap", "filesystem" => "swap", "size" => { "auto" => true },
"outline" => {
"auto_size" => { "base_min" => "1 GiB", "base_max" => "2 GiB", "adjust_by_ram" => true }
}
}
end
let(:other_template) do
{
"mount_path" => "/two", "filesystem" => "xfs",
Expand Down Expand Up @@ -126,6 +140,7 @@ def expect_proposal_with_expects(*specs)
ignore_fallback_sizes: false, ignore_snapshots_sizes: false,
min_size: Y2Storage::DiskSize.GiB(10)
},
{ mount_point: "swap", proposed: false },
{ mount_point: "/two", proposed: false, fallback_for_min_size: "/" }
)
proposal.calculate(settings)
Expand Down Expand Up @@ -163,6 +178,7 @@ def expect_proposal_with_expects(*specs)
ignore_fallback_sizes: false, ignore_snapshots_sizes: false,
min_size: Y2Storage::DiskSize.GiB(10)
},
{ mount_point: "swap", proposed: false },
{ mount_point: "/two", proposed: true, fallback_for_min_size: "/" }
)
proposal.calculate(settings)
Expand Down Expand Up @@ -201,6 +217,7 @@ def expect_proposal_with_expects(*specs)
ignore_fallback_sizes: false, ignore_snapshots_sizes: false,
min_size: Y2Storage::DiskSize.GiB(10)
},
{ mount_point: "swap", proposed: false },
{ mount_point: "/two", proposed: false, fallback_for_min_size: "/" }
)
proposal.calculate(settings)
Expand All @@ -224,8 +241,50 @@ def expect_proposal_with_expects(*specs)
end
end

context "when auto size is used and it is affected by RAM size" do
let(:volumes) { [test_vol("/"), test_vol("swap")] }

describe "#calculate" do
before do
allow(Y2Storage::StorageManager.instance).to receive(:proposal=)
end

it "runs the Y2Storage proposal with the correct set of VolumeSpecification" do
expect_proposal_with_expects(
{ mount_point: "/", proposed: true },
{ mount_point: "/two", proposed: false },
{
mount_point: "swap", proposed: true, ignore_adjust_by_ram: false,
min_size: Y2Storage::DiskSize.GiB(1)
}
)
proposal.calculate(settings)
end
end

describe "#settings" do
it "returns settings with a set of volumes with adjusted sizes" do
proposal.calculate(settings)

expect(proposal.settings.volumes).to contain_exactly(
an_object_having_attributes(mount_path: "/", auto_size: true),
an_object_having_attributes(
mount_path: "swap",
auto_size?: true,
min_size: Y2Storage::DiskSize.GiB(8)
)
)
end
end
end

context "when fixed sizes are enforced" do
let(:volumes) { [test_vol("/", auto_size: false, min_size: "6 GiB")] }
let(:volumes) do
[
test_vol("/", auto_size: false, min_size: "6 GiB"),
test_vol("swap", auto_size: false, min_size: "1 GiB")
]
end

describe "#calculate" do
before do
Expand All @@ -239,6 +298,10 @@ def expect_proposal_with_expects(*specs)
ignore_fallback_sizes: true, ignore_snapshots_sizes: true,
min_size: Y2Storage::DiskSize.GiB(6)
},
{
mount_point: "swap", proposed: true, ignore_adjust_by_ram: true,
min_size: Y2Storage::DiskSize.GiB(1)
},
{ mount_point: "/two", proposed: false, fallback_for_min_size: "/" }
)
proposal.calculate(settings)
Expand All @@ -256,6 +319,12 @@ def expect_proposal_with_expects(*specs)
auto_size?: false,
min_size: Y2Storage::DiskSize.GiB(6),
outline: an_object_having_attributes(min_size_fallback_for: ["/two"])
),
an_object_having_attributes(
mount_path: "swap",
auto_size?: false,
min_size: Y2Storage::DiskSize.GiB(1),
outline: an_object_having_attributes(adjust_by_ram: true)
)
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
adjust_by_ram?: false,
ignore_fallback_sizes: true,
ignore_snapshots_sizes: true,
ignore_adjust_by_ram: true,
min_size: Y2Storage::DiskSize.GiB(5),
max_size: Y2Storage::DiskSize.GiB(20),
max_size_lvm: Y2Storage::DiskSize.GiB(20),
Expand All @@ -96,6 +97,7 @@
expect(spec).to have_attributes(
ignore_fallback_sizes: false,
ignore_snapshots_sizes: false,
ignore_adjust_by_ram: false,
min_size: Y2Storage::DiskSize.GiB(10),
max_size: Y2Storage::DiskSize.GiB(50),
max_size_lvm: Y2Storage::DiskSize.GiB(50)
Expand Down

0 comments on commit afa39b5

Please sign in to comment.