Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Nov 13, 2024
1 parent 2fcd9ab commit 75484a9
Show file tree
Hide file tree
Showing 38 changed files with 933 additions and 515 deletions.
14 changes: 14 additions & 0 deletions rust/agama-lib/share/storage.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"required": ["filesystem"],
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"index": { "$ref": "#/$defs/index" },
"alias": { "$ref": "#/$defs/alias" },
"encryption": { "$ref": "#/$defs/encryption" },
"filesystem": { "$ref": "#/$defs/filesystem" }
Expand All @@ -60,6 +61,7 @@
"additionalProperties": false,
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"index": { "$ref": "#/$defs/index" },
"alias": { "$ref": "#/$defs/alias" },
"ptableType": { "$ref": "#/$defs/ptableType" },
"partitions": {
Expand Down Expand Up @@ -117,6 +119,7 @@
"additionalProperties": false,
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"index": { "$ref": "#/$defs/index" },
"alias": { "$ref": "#/$defs/alias" },
"id": {
"title": "Partition id",
Expand All @@ -141,6 +144,7 @@
"required": ["delete", "search"],
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"index": { "$ref": "#/$defs/index" },
"delete": {
"description": "Delete the partition.",
"const": true
Expand All @@ -153,6 +157,7 @@
"required": ["deleteIfNeeded", "search"],
"properties": {
"search": { "$ref": "#/$defs/searchElement" },
"index": { "$ref": "#/$defs/index" },
"deleteIfNeeded": {
"description": "Delete the partition if needed to make space.",
"const": true
Expand All @@ -165,6 +170,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"index": { "$ref": "#/$defs/index" },
"name": {
"description": "Volume group name.",
"type": "string",
Expand Down Expand Up @@ -255,6 +261,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"index": { "$ref": "#/$defs/index" },
"name": {
"description": "Logical volume name.",
"type": "string",
Expand All @@ -272,6 +279,7 @@
"additionalProperties": false,
"required": ["pool"],
"properties": {
"index": { "$ref": "#/$defs/index" },
"pool": {
"description": "LVM thin pool.",
"const": true
Expand All @@ -293,6 +301,7 @@
"additionalProperties": false,
"required": ["usedPool"],
"properties": {
"index": { "$ref": "#/$defs/index" },
"name": {
"description": "Thin logical volume name.",
"type": "string",
Expand All @@ -310,6 +319,11 @@
"minimum": 1,
"maximum": 128
},
"index": {
"description": "Autogenerated index used for matching solved and unsolved configs.",
"type": "integer",
"minimum": 0
},
"searchElement": {
"anyOf": [
{ "$ref": "#/$defs/simpleSearchAll" },
Expand Down
14 changes: 14 additions & 0 deletions service/lib/agama/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,20 @@ def mandatory_paths
default_paths.select { |p| mandatory_path?(p) }
end

# Default policy to make space.
#
# @return [String]
def space_policy
data.dig("storage", "space_policy") || "keep"
end

# Whether LVM must be used by default.
#
# @return [Boolean]
def lvm?
data.dig("storage", "lvm") || false
end

private

def mandatory_path?(path)
Expand Down
2 changes: 1 addition & 1 deletion service/lib/agama/dbus/storage/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ def tree_path(tree_root)

# @return [Agama::Config]
def config
backend.config
backend.product_config
end

# @return [Agama::VolumeTemplatesBuilder]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def convert
# @return [Hash]
def conversions
{
index: drive_json[:index],
search: convert_search,
alias: drive_json[:alias],
encryption: convert_encryption,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def convert
# @return [Hash]
def conversions
{
index: logical_volume_json[:index],
alias: logical_volume_json[:alias],
encryption: convert_encryption,
filesystem: convert_filesystem,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def convert
# @return [Hash]
def conversions
{
index: partition_json[:index],
search: convert_search,
alias: partition_json[:alias],
encryption: convert_encryption,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def convert
# @return [Hash]
def conversions
{
index: volume_group_json[:index],
name: volume_group_json[:name],
extent_size: convert_extent_size,
physical_volumes_devices: convert_physical_volumes_devices,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def self.config_type
# @see Base#conversions
def conversions
{
index: config.index,
search: convert_search,
alias: config.alias,
encryption: convert_encryption,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def self.config_type
# @see Base#conversions
def conversions
{
index: config.index,
alias: config.alias,
encryption: convert_encryption,
filesystem: convert_filesystem,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def conversions
return convert_delete_if_needed if config.delete_if_needed?

{
index: config.index,
search: convert_search,
alias: config.alias,
encryption: convert_encryption,
Expand All @@ -63,6 +64,7 @@ def conversions
# @return [Hash]
def convert_delete
{
index: config.index,
search: convert_search,
delete: true
}
Expand All @@ -71,6 +73,7 @@ def convert_delete
# @return [Hash]
def convert_delete_if_needed
{
index: config.index,
search: convert_search,
size: convert_size,
deleteIfNeeded: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def self.config_type
# @see Base#conversions
def conversions
{
index: config.index,
name: config.name,
extentSize: config.extent_size&.to_i,
physicalVolumes: convert_physical_volumes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,30 @@
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "agama/storage/config_conversions"

module Agama
module Storage
# Reader for the initial storage config
class ConfigReader
# @param agama_config [Agama::Config]
def initialize(agama_config)
@agama_config = agama_config
# Reader for the initial JSON config.
class ConfigJSONReader
# @param product_config [Agama::Config]
def initialize(product_config)
@product_config = product_config
end

# Generates a storage config from the Agama control file.
# Generates a JSON config from the product config.
#
# @return [Storage::Config]
# @return [Hash]
def read
ConfigConversions::FromJSON.new(json, default_paths: default_paths).convert
json = product_config.lvm? ? json_for_lvm : json_for_disk

{ storage: json }
end

private

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

# Default filesystem paths from the Agama control file
#
# @return [Array<String>]
def default_paths
@default_paths ||= agama_config.default_paths
end
attr_reader :product_config

# Default policy to make space from the Agama control file
#
# @return [String]
def space_policy
@space_policy ||= agama_config.data.dig("storage", "space_policy")
end

# Whether the Agama control file specifies that LVM must be used by default
#
# @return [Boolean]
def lvm?
return @lvm unless @lvm.nil?

@lvm = !!agama_config.data.dig("storage", "lvm")
end

# JSON representation of the initial storage config
#
# @return [Hash]
def json
lvm? ? json_for_lvm : json_for_disk
end

# @see #json
#
# @see #read
# @return [Hash]
def json_for_disk
{
Expand All @@ -83,17 +52,16 @@ def json_for_disk
}
end

# @see #json
#
# @see #read
# @return [Hash]
def json_for_lvm
partition = partition_for_existing

drive = { alias: "target" }
drive[:partitions] = [partition] if partition

{
drives: [
{
alias: "target",
partitions: [partition_for_existing].compact
}
],
drives: [drive],
volumeGroups: [
{
name: "system",
Expand All @@ -104,17 +72,18 @@ def json_for_lvm
}
end

# JSON piece to generate default filesystems as partitions or logical volumes
# JSON piece to generate default filesystems as partitions or logical volumes.
#
# @return [Hash]
def volumes_generator
{ generate: "default" }
end

# JSON piece to specify what to do with existing partitions
# JSON piece to specify what to do with existing partitions.
#
# @return [Hash, nil] nil if no actions are to be performed
# @return [Hash, nil] nil if no actions are to be performed.
def partition_for_existing
space_policy = product_config.space_policy
return unless ["delete", "resize"].include?(space_policy)

partition = { search: "*" }
Expand Down
27 changes: 23 additions & 4 deletions service/lib/agama/storage/config_json_solver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def initialize(default_paths: [], mandatory_paths: [])
def solve(config_json)
@config_json = config_json

solve_indexes
solve_generate
end

Expand All @@ -87,6 +88,20 @@ def solve(config_json)
# @return [Hash]
attr_reader :config_json

def solve_indexes
drives = config_json[:drives] || []
assign_indexes(drives)
drives.each { |d| assign_indexes(d[:partitions] || []) }

volume_groups = config_json[:volumeGroups] || []
assign_indexes(volume_groups)
volume_groups.each { |d| assign_indexes(d[:logicalVolumes] || []) }
end

def assign_indexes(configs)
configs.each_with_index { |c, i| c[:index] = i }
end

def solve_generate
configs = configs_with_generate
return unless configs.any?
Expand All @@ -98,12 +113,16 @@ def solve_generate
# @param config [Hash] Drive or volume group config (e.g., { partitions: [...] }).
def expand_generate(config)
configs = volume_configs(config)
index = configs.index { |v| with_generate?(v) }
generate_config = configs.find { |c| with_generate?(c) }

return unless generate_config

current_index = configs.index(generate_config)
index = generate_config[:index] || current_index

return unless index
configs[current_index] = volumes_from_generate(generate_config)
.each { |c| c[:index] = index }

generate_config = configs[index]
configs[index] = volumes_from_generate(generate_config)
configs.flatten!
end

Expand Down
2 changes: 2 additions & 0 deletions service/lib/agama/storage/configs/drive.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

require "agama/storage/configs/search"
require "agama/storage/configs/with_alias"
require "agama/storage/configs/with_index"
require "agama/storage/configs/with_search"

module Agama
Expand All @@ -29,6 +30,7 @@ module Configs
# Section of the configuration representing a device that is expected to exist in the target
# system and that can be used as a regular disk.
class Drive
include WithIndex
include WithAlias
include WithSearch

Expand Down
2 changes: 2 additions & 0 deletions service/lib/agama/storage/configs/logical_volume.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@

require "agama/storage/configs/size"
require "agama/storage/configs/with_alias"
require "agama/storage/configs/with_index"

module Agama
module Storage
module Configs
# Section of the configuration representing a LVM logical volume.
class LogicalVolume
include WithIndex
include WithAlias

# @return [String, nil]
Expand Down
Loading

0 comments on commit 75484a9

Please sign in to comment.