Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
479b7cb
service: Add Storage1.Devices D-Bus interface
joseivanlopez May 28, 2024
4266d42
WIP: [Service] Backend implementation of AutoYaST proposal
ancorgs May 28, 2024
92e1ade
service: Add Storage1.Devices D-Bus interface
joseivanlopez May 28, 2024
3463678
service: D-Bus interface for calculating autoyast proposal
joseivanlopez May 28, 2024
1d84aee
rust: Allow ignoring settings
joseivanlopez May 29, 2024
11288fe
rust: Process 'legacy_autoyast_storage' section
joseivanlopez May 29, 2024
ec56fe9
WIP: [Service] Refactor AutoYaST proposal
ancorgs May 29, 2024
f7ec414
Merge branch 'legacy-autoyast-support' of github.com:joseivanlopez/ag…
ancorgs May 29, 2024
882c98d
Merge branch 'master' into legacy-autoyast-support
joseivanlopez May 29, 2024
110d8e2
[Service] Fix some method invocations
ancorgs May 31, 2024
b77be22
[Service] Delete file submitted by mistake
ancorgs May 31, 2024
f4879ab
[Service] Small code fixes
ancorgs May 31, 2024
9155591
rust: Fix settings merge
joseivanlopez Jun 3, 2024
4bee24e
service: Do not export autoyast proposal
joseivanlopez Jun 3, 2024
b3e20ac
service: Remove references to dropped file
joseivanlopez Jun 3, 2024
7e0ef5d
web: Avoid error if there is no proposal
joseivanlopez Jun 3, 2024
0fc11b2
WIP: [Service] Handle AutoYaST issues at storage proposal
ancorgs Jun 3, 2024
9f52e7a
service: Add missing documentation
joseivanlopez Jun 4, 2024
8979df1
service: Remove obsolete method
joseivanlopez Jun 4, 2024
6f225ca
service: Add unit tests
joseivanlopez Jun 4, 2024
3d9b7ae
service: Remove unused API from storage client
joseivanlopez Jun 4, 2024
55169e6
service: Fix tests
joseivanlopez Jun 4, 2024
2d64072
WIP: [Service] Improvements in the storage proposal
ancorgs Jun 4, 2024
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
7 changes: 6 additions & 1 deletion rust/agama-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum SettingKind {
Collection,
/// The value is another FooSettings, use `#[settings(nested)]`.
Nested,
Ignored,
}

/// Represents a setting and its configuration
Expand Down Expand Up @@ -176,7 +177,7 @@ fn expand_merge_fn(settings: &SettingFieldsList) -> TokenStream2 {
let arms = settings.all().iter().map(|s| {
let field_name = &s.ident;
match s.kind {
SettingKind::Scalar => quote! {
SettingKind::Scalar | SettingKind::Ignored => quote! {
if let Some(value) = &other.#field_name {
self.#field_name = Some(value.clone())
}
Expand Down Expand Up @@ -274,6 +275,10 @@ fn parse_setting_fields(fields: Vec<&syn::Field>) -> SettingFieldsList {
setting.kind = SettingKind::Nested;
}

if meta.path.is_ident("ignored") {
setting.kind = SettingKind::Ignored;
}

if meta.path.is_ident("flatten") {
setting.flatten = true;
}
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jsonschema = { version = "0.16.1", default-features = false }
log = "0.4"
reqwest = { version = "0.12.4", features = ["json", "cookies"] }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.94"
serde_json = { version = "1.0.94", features = ["raw_value"] }
serde_repr = "0.1.18"
tempfile = "3.4.0"
thiserror = "1.0.39"
Expand Down
17 changes: 14 additions & 3 deletions rust/agama-lib/src/install_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
};
use agama_settings::Settings;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue;
use std::default::Default;
use std::str::FromStr;

Expand All @@ -22,6 +23,8 @@ pub enum Scope {
Software,
/// Storage settings
Storage,
/// Storage AutoYaST settings (for backward compatibility with AutoYaST profiles)
StorageAutoyast,
/// Network settings
Network,
/// Product settings
Expand All @@ -34,13 +37,14 @@ impl Scope {
/// Returns known scopes
///
// TODO: we can rely on strum so we do not forget to add them
pub fn all() -> [Scope; 6] {
pub fn all() -> [Scope; 7] {
[
Scope::Localization,
Scope::Network,
Scope::Product,
Scope::Software,
Scope::Storage,
Scope::StorageAutoyast,
Scope::Users,
]
}
Expand All @@ -49,6 +53,9 @@ impl Scope {
impl FromStr for Scope {
type Err = &'static str;

// Do not generate the StorageAutoyast scope. Note that storage AutoYaST settings will only be
// temporary availble for importing an AutoYaST profile. But CLI should not allow modifying the
// storate AutoYaST settings.
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"users" => Ok(Self::Users),
Expand Down Expand Up @@ -81,6 +88,9 @@ pub struct InstallSettings {
#[serde(default)]
#[settings(nested)]
pub storage: Option<StorageSettings>,
#[serde(default, rename = "legacyAutoyastStorage")]
#[settings(ignored)]
pub storage_autoyast: Option<Box<RawValue>>,
#[serde(default)]
#[settings(nested)]
pub network: Option<NetworkSettings>,
Expand All @@ -95,11 +105,12 @@ impl InstallSettings {
if self.user.is_some() {
scopes.push(Scope::Users);
}

if self.storage.is_some() {
scopes.push(Scope::Storage);
}

if self.storage_autoyast.is_some() {
scopes.push(Scope::StorageAutoyast);
}
if self.software.is_some() {
scopes.push(Scope::Software);
}
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-lib/src/software/store.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implements the store for the storage settings.
//! Implements the store for the software settings.

use std::collections::HashMap;

Expand Down
2 changes: 2 additions & 0 deletions rust/agama-lib/src/storage.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Implements support for handling the storage settings

mod autoyast;
pub mod client;
pub mod model;
pub mod proxies;
mod settings;
mod store;

pub use autoyast::store::StorageAutoyastStore;
pub use client::{
iscsi::{ISCSIAuth, ISCSIClient, ISCSIInitiator, ISCSINode},
StorageClient,
Expand Down
2 changes: 2 additions & 0 deletions rust/agama-lib/src/storage/autoyast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//! Implements support for handling the storage AutoYaST settings
pub mod store;
26 changes: 26 additions & 0 deletions rust/agama-lib/src/storage/autoyast/store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Implements the store for the storage AutoYaST settings.

use crate::error::ServiceError;
use crate::storage::StorageClient;
use zbus::Connection;

/// Stores the storage AutoYaST settings to the D-Bus service.
///
/// NOTE: The AutoYaST settings are not loaded from D-Bus because they cannot be modified. The only
/// way of using the storage AutoYaST settings is by loading a json config file.
pub struct StorageAutoyastStore<'a> {
storage_client: StorageClient<'a>,
}

impl<'a> StorageAutoyastStore<'a> {
pub async fn new(connection: Connection) -> Result<StorageAutoyastStore<'a>, ServiceError> {
Ok(Self {
storage_client: StorageClient::new(connection).await?,
})
}

pub async fn store(&self, settings: &str) -> Result<(), ServiceError> {
self.storage_client.calculate_autoyast(settings).await?;
Ok(())
}
}
4 changes: 4 additions & 0 deletions rust/agama-lib/src/storage/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ impl<'a> StorageClient<'a> {
Ok(self.calculator_proxy.calculate(settings.into()).await?)
}

pub async fn calculate_autoyast(&self, settings: &str) -> Result<u32, ServiceError> {
Ok(self.calculator_proxy.calculate_autoyast(settings).await?)
}

/// Calculates a new proposal with the given settings.
pub async fn calculate(&self, settings: &StorageSettings) -> Result<u32, ServiceError> {
let mut dbus_settings: HashMap<&str, zbus::zvariant::Value<'_>> = HashMap::new();
Expand Down
11 changes: 7 additions & 4 deletions rust/agama-lib/src/storage/proxies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ trait Storage1 {
default_path = "/org/opensuse/Agama/Storage1"
)]
trait ProposalCalculator {
/// Calculate method
/// Calculate guided proposal
fn calculate(
&self,
settings: std::collections::HashMap<&str, zbus::zvariant::Value<'_>>,
) -> zbus::Result<u32>;

/// Calculate AutoYaST proposal
fn calculate_autoyast(&self, settings: &str) -> zbus::Result<u32>;

/// DefaultVolume method
fn default_volume(
&self,
Expand All @@ -53,9 +56,9 @@ trait ProposalCalculator {
#[dbus_proxy(property)]
fn product_mount_points(&self) -> zbus::Result<Vec<String>>;

/// Result property
#[dbus_proxy(property)]
fn result(&self) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
/// Proposal result
fn result(&self)
-> zbus::Result<std::collections::HashMap<String, zbus::zvariant::OwnedValue>>;
}

#[dbus_proxy(
Expand Down
20 changes: 17 additions & 3 deletions rust/agama-lib/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::error::ServiceError;
use crate::install_settings::{InstallSettings, Scope};
use crate::{
localization::LocalizationStore, network::NetworkStore, product::ProductStore,
software::SoftwareStore, storage::StorageStore, users::UsersStore,
software::SoftwareStore, storage::StorageAutoyastStore, storage::StorageStore,
users::UsersStore,
};
use zbus::Connection;

Expand All @@ -21,6 +22,7 @@ pub struct Store<'a> {
product: ProductStore<'a>,
software: SoftwareStore<'a>,
storage: StorageStore<'a>,
storage_autoyast: StorageAutoyastStore<'a>,
localization: LocalizationStore<'a>,
}

Expand All @@ -35,11 +37,16 @@ impl<'a> Store<'a> {
network: NetworkStore::new(http_client).await?,
product: ProductStore::new(connection.clone()).await?,
software: SoftwareStore::new(connection.clone()).await?,
storage: StorageStore::new(connection).await?,
storage: StorageStore::new(connection.clone()).await?,
storage_autoyast: StorageAutoyastStore::new(connection).await?,
})
}

/// Loads the installation settings from the D-Bus service
/// Loads the installation settings from the D-Bus service.
///
/// NOTE: The storage AutoYaST settings cannot be loaded because they cannot be modified. The
/// ability of using the storage AutoYaST settings from a json config file is temporary and it
/// will be removed in the future.
pub async fn load(&self, only: Option<Vec<Scope>>) -> Result<InstallSettings, ServiceError> {
let scopes = match only {
Some(scopes) => scopes,
Expand All @@ -50,6 +57,7 @@ impl<'a> Store<'a> {
if scopes.contains(&Scope::Network) {
settings.network = Some(self.network.load().await?);
}

if scopes.contains(&Scope::Storage) {
settings.storage = Some(self.storage.load().await?);
}
Expand Down Expand Up @@ -97,6 +105,12 @@ impl<'a> Store<'a> {
if let Some(storage) = &settings.storage {
self.storage.store(storage).await?;
}
if let Some(storage_autoyast) = &settings.storage_autoyast {
// Storage scope has precedence.
if settings.storage.is_none() {
self.storage_autoyast.store(storage_autoyast.get()).await?;
}
}
Ok(())
}
}
52 changes: 1 addition & 51 deletions service/lib/agama/dbus/clients/storage.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2022-2023] SUSE LLC
# Copyright (c) [2022-2024] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -36,12 +36,6 @@ class Storage < Base
STORAGE_IFACE = "org.opensuse.Agama.Storage1"
private_constant :STORAGE_IFACE

PROPOSAL_CALCULATOR_IFACE = "org.opensuse.Agama.Storage1.Proposal.Calculator"
private_constant :PROPOSAL_CALCULATOR_IFACE

PROPOSAL_IFACE = "org.opensuse.Agama.Storage1.Proposal"
private_constant :PROPOSAL_IFACE

def service_name
@service_name ||= "org.opensuse.Agama.Storage1"
end
Expand All @@ -66,56 +60,12 @@ def finish
dbus_object.Finish
end

# Devices available for the installation
#
# @return [Array<String>] name of the devices
def available_devices
dbus_object[PROPOSAL_CALCULATOR_IFACE]["AvailableDevices"]
.map(&:first)
end

# Devices selected for the installation
#
# @return [Array<String>] name of the devices
def candidate_devices
return [] unless dbus_proposal

dbus_proposal[PROPOSAL_IFACE]["CandidateDevices"]
end

# Actions to perform in the storage devices
#
# @return [Array<String>]
def actions
return [] unless dbus_proposal

dbus_proposal[PROPOSAL_IFACE]["Actions"].map do |a|
a["Text"]
end
end

# Calculates the storage proposal with the given devices
#
# @param candidate_devices [Array<String>] name of the new candidate devices
def calculate(candidate_devices)
calculator_iface = dbus_object[PROPOSAL_CALCULATOR_IFACE]
calculator_iface.Calculate({ "CandidateDevices" => candidate_devices })
end

private

# @return [::DBus::Object]
def dbus_object
@dbus_object ||= service["/org/opensuse/Agama/Storage1"].tap(&:introspect)
end

# @return [::DBus::Object, nil]
def dbus_proposal
path = dbus_object["org.opensuse.Agama.Storage1.Proposal.Calculator"]["Result"]
return nil if path == "/"

service.object(path).tap(&:introspect)
end
end
end
end
Expand Down
Loading