diff --git a/rust/agama-lib/Cargo.toml b/rust/agama-lib/Cargo.toml index 8bab6d10a4..c53bbacf2c 100644 --- a/rust/agama-lib/Cargo.toml +++ b/rust/agama-lib/Cargo.toml @@ -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" diff --git a/rust/agama-lib/src/install_settings.rs b/rust/agama-lib/src/install_settings.rs index d292db79df..9b4411c649 100644 --- a/rust/agama-lib/src/install_settings.rs +++ b/rust/agama-lib/src/install_settings.rs @@ -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; @@ -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 @@ -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, ] } @@ -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 { match s { "users" => Ok(Self::Users), @@ -81,6 +88,9 @@ pub struct InstallSettings { #[serde(default)] #[settings(nested)] pub storage: Option, + #[serde(default, rename = "legacyAutoyastStorage")] + #[settings(ignored)] + pub storage_autoyast: Option>, #[serde(default)] #[settings(nested)] pub network: Option, @@ -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); } diff --git a/rust/agama-lib/src/software/store.rs b/rust/agama-lib/src/software/store.rs index 5bb5ee21c4..3c72d952c2 100644 --- a/rust/agama-lib/src/software/store.rs +++ b/rust/agama-lib/src/software/store.rs @@ -1,4 +1,4 @@ -//! Implements the store for the storage settings. +//! Implements the store for the software settings. use std::collections::HashMap; diff --git a/rust/agama-lib/src/storage.rs b/rust/agama-lib/src/storage.rs index 66940a3599..2df50cbae1 100644 --- a/rust/agama-lib/src/storage.rs +++ b/rust/agama-lib/src/storage.rs @@ -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, diff --git a/rust/agama-lib/src/storage/autoyast.rs b/rust/agama-lib/src/storage/autoyast.rs new file mode 100644 index 0000000000..4aefc745c8 --- /dev/null +++ b/rust/agama-lib/src/storage/autoyast.rs @@ -0,0 +1,2 @@ +//! Implements support for handling the storage AutoYaST settings +pub mod store; diff --git a/rust/agama-lib/src/storage/autoyast/store.rs b/rust/agama-lib/src/storage/autoyast/store.rs new file mode 100644 index 0000000000..0b8d860e05 --- /dev/null +++ b/rust/agama-lib/src/storage/autoyast/store.rs @@ -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, 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(()) + } +} diff --git a/rust/agama-lib/src/storage/client.rs b/rust/agama-lib/src/storage/client.rs index 3f7c95d451..00ee681442 100644 --- a/rust/agama-lib/src/storage/client.rs +++ b/rust/agama-lib/src/storage/client.rs @@ -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 { + Ok(self.calculator_proxy.calculate_autoyast(settings).await?) + } + /// Calculates a new proposal with the given settings. pub async fn calculate(&self, settings: &StorageSettings) -> Result { let mut dbus_settings: HashMap<&str, zbus::zvariant::Value<'_>> = HashMap::new(); diff --git a/rust/agama-lib/src/storage/proxies.rs b/rust/agama-lib/src/storage/proxies.rs index f028528583..c64f87d02a 100644 --- a/rust/agama-lib/src/storage/proxies.rs +++ b/rust/agama-lib/src/storage/proxies.rs @@ -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; + /// Calculate AutoYaST proposal + fn calculate_autoyast(&self, settings: &str) -> zbus::Result; + /// DefaultVolume method fn default_volume( &self, @@ -53,9 +56,9 @@ trait ProposalCalculator { #[dbus_proxy(property)] fn product_mount_points(&self) -> zbus::Result>; - /// Result property - #[dbus_proxy(property)] - fn result(&self) -> zbus::Result; + /// Proposal result + fn result(&self) + -> zbus::Result>; } #[dbus_proxy( diff --git a/rust/agama-lib/src/store.rs b/rust/agama-lib/src/store.rs index 9ff30b8ea6..9a258fba4f 100644 --- a/rust/agama-lib/src/store.rs +++ b/rust/agama-lib/src/store.rs @@ -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; @@ -21,6 +22,7 @@ pub struct Store<'a> { product: ProductStore<'a>, software: SoftwareStore<'a>, storage: StorageStore<'a>, + storage_autoyast: StorageAutoyastStore<'a>, localization: LocalizationStore<'a>, } @@ -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>) -> Result { let scopes = match only { Some(scopes) => scopes, @@ -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?); } @@ -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(()) } }