Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b6fb007
storage: remove guided schema
joseivanlopez Feb 5, 2025
4b8a45d
storage: generate model only if possible
joseivanlopez Feb 4, 2025
954b083
web: improve useAvailableDevices query
joseivanlopez Feb 5, 2025
0712819
web: improve query for getting the volumes
joseivanlopez Feb 6, 2025
b79c909
web: rename query
joseivanlopez Feb 7, 2025
3397c57
web: add useDASDSupported query
joseivanlopez Feb 7, 2025
a0762f9
web: wait for config mutation
joseivanlopez Feb 7, 2025
9cfc9c7
web: adapt proposal page layout according to the scenario
joseivanlopez Feb 7, 2025
390971b
web: fix tests
joseivanlopez Feb 11, 2025
b5417a9
web: remove unused component
joseivanlopez Feb 11, 2025
f040014
fix(storage): improve error message
joseivanlopez Feb 13, 2025
93f6e95
storage: generate model even for config with errors
joseivanlopez Feb 13, 2025
e93b6cb
fix(storage): set proposal issues as system issues
joseivanlopez Feb 13, 2025
b20812d
web: do not edit storage model if there are config errors
joseivanlopez Feb 13, 2025
a88edcd
web: disable delete for mandatory volumes
joseivanlopez Feb 13, 2025
c27e513
rust: remove unused mods
joseivanlopez Feb 13, 2025
17563ef
fix(web): improvements in custom policy page
joseivanlopez Feb 13, 2025
58e4a01
web: create separate component for unsupported model alert
joseivanlopez Feb 14, 2025
43e340c
web: improve ProposalPage code
joseivanlopez Feb 14, 2025
53df2e5
web: Adapt wording of some alerts and empty states
ancorgs Feb 14, 2025
5bfccf4
web: Wording fixes from review
ancorgs Feb 14, 2025
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
248 changes: 0 additions & 248 deletions rust/agama-lib/share/storage.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -594,254 +594,6 @@
}
}
}
},
"guided": {
"title": "Guided settings",
"$comment": "This guided section will be extracted to a separate schema. Only storage and legacyAutoyastStorage will be offered as valid schemas for the storage config.",
"type": "object",
"additionalProperties": false,
"properties": {
"target": {
"anyOf": [
{
"title": "Target for installing",
"description": "Indicates whether to install in a disk or a new LVM.",
"enum": ["disk", "newLvmVg"]
},
{
"title": "Target disk",
"description": "Indicates to install in a specific disk device.",
"type": "object",
"additionalProperties": false,
"required": ["disk"],
"properties": {
"disk": {
"title": "Device name",
"type": "string",
"examples": ["/dev/vda"]
}
}
},
{
"title": "New LVM",
"description": "Indicates to install in a new LVM created over some specific devices.",
"type": "object",
"additionalProperties": false,
"required": ["newLvmVg"],
"properties": {
"newLvmVg": {
"description": "List of devices in which to create the physical volumes.",
"type": "array",
"items": {
"title": "Device name",
"type": "string",
"examples": ["/dev/vda"]
}
}
}
}
]
},
"boot": {
"$ref": "#/$defs/boot"
},
"encryption": {
"title": "Encryption",
"description": "Indicates the options for encrypting the new partitions.",
"type": "object",
"additionalProperties": false,
"required": ["password"],
"properties": {
"password": {
"$ref": "#/$defs/encryptionPassword"
},
"method": {
"title": "Encryption method",
"description": "Method used to encrypt the devices.",
"enum": ["luks2", "tpm_fde"]
},
"pbkdFunction": {
"$ref": "#/$defs/encryptionPbkdFunction"
}
}
},
"space": {
"title": "Space policy",
"description": "Indicates how to find space for the new partitions.",
"type": "object",
"additionalProperties": false,
"properties": {
"policy": {
"enum": ["delete", "resize", "keep", "custom"]
},
"actions": {
"type": "array"
}
},
"if": {
"properties": {
"policy": { "const": "custom" }
}
},
"then": {
"required": ["policy", "actions"],
"properties": {
"actions": {
"title": "Custom actions",
"description": "Indicates what to do with specific devices.",
"type": "array",
"items": {
"anyOf": [
{
"title": "Force delete",
"description": "Indicates to delete a specific device.",
"type": "object",
"required": ["forceDelete"],
"additionalProperties": false,
"properties": {
"forceDelete": {
"description": "Name of the device to delete.",
"type": "string",
"examples": ["/dev/vda"]
}
}
},
{
"title": "Allow shinking",
"description": "Indicates whether a specific device can be shrunk if needed.",
"type": "object",
"required": ["resize"],
"additionalProperties": false,
"properties": {
"resize": {
"description": "Name of the shrinkable device.",
"type": "string",
"examples": ["/dev/vda"]
}
}
}
]
}
}
}
},
"else": {
"required": ["policy"],
"properties": {
"actions": {
"type": "array",
"maxItems": 0
}
}
}
},
"volumes": {
"title": "System volumes",
"description": "List of volumes (file systems) to create.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["mount"],
"properties": {
"mount": {
"title": "Mount properties",
"type": "object",
"additionalProperties": false,
"required": ["path"],
"properties": {
"path": {
"title": "Mount path",
"type": "string",
"examples": ["/dev/vda"]
},
"options": {
"title": "Mount options",
"description": "Options to add to the fourth field of fstab.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"filesystem": {
"$ref": "#/$defs/filesystemType"
},
"size": {
"$ref": "#/$defs/size"
},
"target": {
"title": "Volume target",
"description": "Options to indicate the location of a volume.",
"anyOf": [
{
"title": "Default target",
"description": "The volume is created in the target device for installing.",
"const": "default"
},
{
"title": "New partition",
"description": "The volume is created over a new partition in a specific disk.",
"type": "object",
"required": ["newPartition"],
"additionalProperties": false,
"properties": {
"newPartition": {
"description": "Name of a disk device.",
"type": "string",
"examples": ["/dev/vda"]
}
}
},
{
"title": "Dedicated LVM volume group",
"description": "The volume is created over a new dedicated LVM.",
"type": "object",
"additionalProperties": false,
"required": ["newVg"],
"properties": {
"newVg": {
"description": "Name of a disk device.",
"type": "string",
"examples": ["/dev/vda"]
}
}
},
{
"title": "Re-used existing device",
"description": "The volume is created over an existing device.",
"type": "object",
"additionalProperties": false,
"required": ["device"],
"properties": {
"device": {
"description": "Name of a device.",
"type": "string",
"examples": ["/dev/vda1"]
}
}
},
{
"title": "Re-used existing file system",
"description": "An existing file system is reused (without formatting).",
"type": "object",
"additionalProperties": false,
"required": ["filesystem"],
"properties": {
"filesystem": {
"description": "Name of a device containing the file system.",
"type": "string",
"examples": ["/dev/vda1"]
}
}
}
]
}
}
}
}
}
}
}
}
2 changes: 0 additions & 2 deletions rust/agama-lib/src/product/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@
// find current contact information at www.suse.com.

use std::collections::HashMap;
use std::str::FromStr;

use crate::dbus::{get_optional_property, get_property};
use crate::error::ServiceError;
use crate::software::model::RegistrationRequirement;
use crate::software::proxies::SoftwareProductProxy;
use serde::Serialize;
use zbus::Connection;
Expand Down
2 changes: 1 addition & 1 deletion service/lib/agama/dbus/interfaces/issues.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module Issues
#
# @return [Array<Array(String, String, Integer, Integer)>] The description, details, source
# and severity of each issue.
# Source: 1 for system, 2 for config and 3 for unknown.
# Source: 1 for system, 2 for config and 0 for unknown.
# Severity: 0 for warn and 1 for error.
def dbus_issues
issues.map do |issue|
Expand Down
10 changes: 8 additions & 2 deletions service/lib/agama/storage/config_checkers/boot.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2024] SUSE LLC
# Copyright (c) [2024-2025] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -55,7 +55,13 @@ def device_alias
def missing_alias_issue
return unless configure? && device_alias.nil?

error(_("There is no boot device alias"))
# Currently this situation only happens because the config solver was not able to find
# a device config containing a root volume. The message could become inaccurate if the
# solver logic changes.
error(
_("The boot device cannot be automatically selected because there is no root (/) " \
"file system")
)
end

# @return [Issue, nil]
Expand Down
33 changes: 28 additions & 5 deletions service/lib/agama/storage/proposal.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2022-2024] SUSE LLC
# Copyright (c) [2022-2025] SUSE LLC
#
# All Rights Reserved.
#
Expand All @@ -21,6 +21,7 @@

require "agama/issue"
require "agama/storage/actions_generator"
require "agama/storage/config_checker"
require "agama/storage/config_conversions"
require "agama/storage/config_solver"
require "agama/storage/proposal_settings"
Expand Down Expand Up @@ -93,10 +94,12 @@ def storage_json

# Config model according to the JSON schema.
#
# @return [Hash, nil] nil if there is no config.
# The config model is generated only if all the config features are supported by the model.
#
# @return [Hash, nil] nil if the config model cannot be generated.
def model_json
config = config(solved: true)
return unless config
return unless config && model_supported?(config)

ConfigConversions::ToModel.new(config).convert
end
Expand Down Expand Up @@ -282,6 +285,26 @@ def config(solved: false)
solved ? strategy.config : source_config
end

# Whether the config model supports all features of the given config.
#
# @param config [Storage::Config]
# @return [Boolean]
def model_supported?(config)
unsupported_configs = [
config.volume_groups,
config.md_raids,
config.btrfs_raids,
config.nfs_mounts
].flatten

encryptable_configs = [
config.drives,
config.partitions
].flatten

unsupported_configs.empty? && encryptable_configs.none?(&:encryption)
end

# Calculates a proposal from guided JSON settings.
#
# @param guided_json [Hash] e.g., { "target": { "disk": "/dev/vda" } }.
Expand Down Expand Up @@ -347,7 +370,7 @@ def storage_manager
def failed_issue
Issue.new(
_("Cannot accommodate the required file systems for installation"),
source: Issue::Source::CONFIG,
source: Issue::Source::SYSTEM,
severity: Issue::Severity::ERROR
)
end
Expand All @@ -359,7 +382,7 @@ def exception_issue(error)
Issue.new(
_("A problem ocurred while calculating the storage setup"),
details: error.message,
source: Issue::Source::CONFIG,
source: Issue::Source::SYSTEM,
severity: Issue::Severity::ERROR
)
end
Expand Down
4 changes: 2 additions & 2 deletions service/test/agama/storage/config_checker_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2024] SUSE LLC
# Copyright (c) [2025] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -288,7 +288,7 @@

issue = issues.first
expect(issue.error?).to eq(true)
expect(issue.description).to eq("There is no boot device alias")
expect(issue.description).to match(/there is no root \(\/\) file system/)
end
end

Expand Down
Loading