Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion rust/agama-lib/share/storage.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,9 @@
{ "$ref": "#/$defs/advancedLogicalVolumesGenerator" },
{ "$ref": "#/$defs/logicalVolume" },
{ "$ref": "#/$defs/thinPoolLogicalVolume" },
{ "$ref": "#/$defs/thinLogicalVolume" }
{ "$ref": "#/$defs/thinLogicalVolume" },
{ "$ref": "#/$defs/logicalVolumeToDelete" },
{ "$ref": "#/$defs/logicalVolumeToDeleteIfNeeded" }
]
},
"advancedLogicalVolumesGenerator": {
Expand Down Expand Up @@ -366,6 +368,31 @@
"filesystem": { "$ref": "#/$defs/filesystem" }
}
},
"logicalVolumeToDelete": {
"type": "object",
"additionalProperties": false,
"required": ["delete", "search"],
"properties": {
"search": { "$ref": "#/$defs/deleteLogicalVolumeSearch" },
"delete": {
"description": "Delete the logical volume.",
"const": true
}
}
},
"logicalVolumeToDeleteIfNeeded": {
"type": "object",
"additionalProperties": false,
"required": ["deleteIfNeeded", "search"],
"properties": {
"search": { "$ref": "#/$defs/deleteLogicalVolumeSearch" },
"deleteIfNeeded": {
"description": "Delete the logical volume if needed to make space.",
"const": true
},
"size": { "$ref": "#/$defs/size" }
}
},
"logicalVolumeStripes": {
"description": "Number of stripes.",
"type": "integer",
Expand Down Expand Up @@ -587,6 +614,23 @@
"ifNotFound": { "$ref": "#/$defs/searchCreatableActions" }
}
},
"deleteLogicalVolumeSearch": {
"anyOf": [
{ "$ref": "#/$defs/searchAll" },
{ "$ref": "#/$defs/searchName" },
{ "$ref": "#/$defs/deleteLogicalVolumeAdvancedSearch" }
]
},
"deleteLogicalVolumeAdvancedSearch": {
"type": "object",
"additionalProperties": false,
"properties": {
"condition": { "$ref": "#/$defs/logicalVolumeSearchCondition" },
"sort": { "$ref": "#/$defs/logicalVolumeSearchSort" },
"max": { "$ref": "#/$defs/searchMax" },
"ifNotFound": { "$ref": "#/$defs/searchActions" }
}
},
"logicalVolumeSearchCondition": {
"anyOf": [
{ "$ref": "#/$defs/searchConditionName" },
Expand Down
5 changes: 5 additions & 0 deletions rust/share/system.storage.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"type": "array",
"items": { "type": "integer" }
},
"availableVolumeGroups": {
"description": "SIDs of the available LVM volume groups",
"type": "array",
"items": { "type": "integer" }
},
"candidateDrives": {
"description": "SIDs of the drives that are candidate for installation",
"type": "array",
Expand Down
27 changes: 17 additions & 10 deletions service/lib/agama/dbus/storage/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module Agama
module DBus
module Storage
# D-Bus object to manage storage installation
class Manager < BaseObject
class Manager < BaseObject # rubocop:disable Metrics/ClassLength
extend Yast::I18n
include Yast::I18n
include WithIssues
Expand Down Expand Up @@ -384,15 +384,16 @@ def serialize_system
return serialize_nil unless manager.probed?

json = {
devices: devices_json(:probed),
availableDrives: available_drives,
availableMdRaids: available_md_raids,
candidateDrives: candidate_drives,
candidateMdRaids: candidate_md_raids,
issues: system_issues_json,
productMountPoints: product_mount_points,
encryptionMethods: encryption_methods,
volumeTemplates: volume_templates
devices: devices_json(:probed),
availableDrives: available_drives,
availableMdRaids: available_md_raids,
availableVolumeGroups: available_volume_groups,
candidateDrives: candidate_drives,
candidateMdRaids: candidate_md_raids,
issues: system_issues_json,
productMountPoints: product_mount_points,
encryptionMethods: encryption_methods,
volumeTemplates: volume_templates
}
JSON.pretty_generate(json)
end
Expand Down Expand Up @@ -510,6 +511,12 @@ def candidate_md_raids
proposal.storage_system.candidate_md_raids.map(&:sid)
end

# @see Storage::System#available_volume_groups
# @return [Array<Integer>]
def available_volume_groups
proposal.storage_system.available_volume_groups.map(&:sid)
end

# Meaningful mount points for the current product.
#
# @return [Array<String>]
Expand Down
33 changes: 30 additions & 3 deletions service/lib/agama/storage/config.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2024-2025] SUSE LLC
# Copyright (c) [2024-2026] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -112,6 +112,11 @@ def partitionable(device_alias)
supporting_partitions.find { |d| d.alias?(device_alias) }
end

# @return [Array<Configs::Partition, Configs::LogicalVolume>]
def volumes
partitions + logical_volumes
end

# @return [Array<Configs::Partition>]
def partitions
supporting_partitions.flat_map(&:partitions)
Expand All @@ -131,7 +136,7 @@ def filesystems
#
# @return [Array<#search>]
def supporting_search
drives + md_raids + partitions
drives + md_raids + partitions + volume_groups + logical_volumes
end

# Configs with configurable encryption.
Expand Down Expand Up @@ -166,7 +171,7 @@ def supporting_partitions
#
# @return [#delete?]
def supporting_delete
partitions
partitions + logical_volumes
end

# Config objects that could act as physical volume
Expand Down Expand Up @@ -223,6 +228,20 @@ def valid_partitions
partitions.reject { |p| skipped?(p) }
end

# Volume group configs, excluding skipped ones.
#
# @return [Array<Configs::VolumeGroup>]
def valid_volume_groups
volume_groups.reject { |d| skipped?(d) }
end

# Logical volume configs, excluding skipped ones.
#
# @return [Array<Configs::LogicalVolume>]
def valid_logical_volumes
logical_volumes.reject { |d| skipped?(d) }
end

# Configs directly using a device with the given alias.
#
# @note Devices using the given alias as a target device (e.g., for creating physical volumes)
Expand All @@ -242,6 +261,14 @@ def target_users(device_alias)
[boot_target_user(device_alias), vg_target_users(device_alias)].flatten.compact
end

# Finds the config assigned to the given device.
#
# @param device [Y2Storage::BlkDevice]
# @return [#search]
def find_device(device)
supporting_search.find { |c| c.found_device == device }
end

private

# MD RAIDs using the given alias as member device.
Expand Down
15 changes: 13 additions & 2 deletions service/lib/agama/storage/config_checkers/logical_volume.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2024-2025] SUSE LLC
# Copyright (c) [2024-2026] SUSE LLC
#
# All Rights Reserved.
#
Expand All @@ -20,8 +20,10 @@
# find current contact information at www.suse.com.

require "agama/storage/config_checkers/base"
require "agama/storage/config_checkers/with_alias"
require "agama/storage/config_checkers/with_encryption"
require "agama/storage/config_checkers/with_filesystem"
require "agama/storage/config_checkers/with_search"
require "yast/i18n"

module Agama
Expand All @@ -30,18 +32,22 @@ module ConfigCheckers
# Class for checking a logical volume config.
class LogicalVolume < Base
include Yast::I18n
include WithAlias
include WithEncryption
include WithFilesystem
include WithSearch

# @param config [Configs::LogicalVolume]
# @param volume_group_config [Configs::VolumeGroup]
# @param storage_config [Storage::Config]
# @param product_config [Agama::Config]
def initialize(config, volume_group_config, product_config)
def initialize(config, volume_group_config, storage_config, product_config)
super()

textdomain "agama"
@config = config
@volume_group_config = volume_group_config
@storage_config = storage_config
@product_config = product_config
end

Expand All @@ -50,6 +56,8 @@ def initialize(config, volume_group_config, product_config)
# @return [Array<Issue>]
def issues
[
alias_issues,
search_issues,
filesystem_issues,
encryption_issues,
missing_thin_pool_issue
Expand All @@ -64,6 +72,9 @@ def issues
# @return [Configs::VolumeGroup]
attr_reader :volume_group_config

# @return [Storage::Config]
attr_reader :storage_config

# @return [Agama::Config]
attr_reader :product_config

Expand Down
Loading
Loading