Skip to content
Merged
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
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 18 additions & 7 deletions rust/agama-lib/share/profile.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1024,18 +1024,15 @@
"title": "Question class",
"description": "Each question has a \"class\" which works as an identifier.",
"type": "string",
"examples": ["storage.activate_multipath"]
"examples": [
"storage.activate_multipath"
]
},
"text": {
"title": "Question text",
"description": "Question full text",
"type": "string"
},
"answer": {
"title": "Question answer",
"description": "Answer to use for the question.",
"type": "string"
},
"password": {
"title": "Password provided as response to a password-based question",
"type": "string"
Expand All @@ -1044,7 +1041,21 @@
"title": "Additional data for matching questions",
"description": "Additional data for matching questions and answers",
"type": "object",
"examples": [{ "device": "/dev/sda" }]
"examples": [
{
"device": "/dev/sda"
}
]
},
"action": {
"title": "Predefined question action",
"description": "Action to use for the question.",
"type": "string"
},
"value": {
"title": "Predefined question value",
"description": "Value to use for the question.",
"type": "string"
}
}
},
Expand Down
1 change: 1 addition & 0 deletions rust/agama-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async-trait = "0.1.83"
zbus = { version = "5", default-features = false, features = ["tokio"] }
merge-struct = "0.1.0"
serde_json = "1.0.140"
tracing = "0.1.41"

[dev-dependencies]
tokio-test = "0.4.4"
Expand Down
86 changes: 58 additions & 28 deletions rust/agama-manager/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,17 @@ impl Service {
/// If a default product is set, it asks the other services to initialize their configurations.
pub async fn setup(&mut self) -> Result<(), Error> {
self.read_registries().await?;

if let Some(product) = self.products.default_product() {
let product = Arc::new(RwLock::new(product.clone()));
_ = self.software.cast(software::message::SetConfig::new(
Arc::clone(&product),
None,
));
self.product = Some(product);
} else {
self.notify_no_product()
}

self.update_issues();
Ok(())
}

Expand Down Expand Up @@ -173,15 +174,36 @@ impl Service {
Ok(())
}

fn notify_no_product(&self) {
let issue = Issue::new(
"no_product",
"No product has been selected.",
IssueSeverity::Error,
);
_ = self
.issues
.cast(issue::message::Set::new(Scope::Manager, vec![issue]));
fn set_product_from_config(&mut self, config: &Config) {
let product_id = config
.software
.as_ref()
.and_then(|s| s.product.as_ref())
.and_then(|p| p.id.as_ref());

if let Some(id) = product_id {
if let Some(product_spec) = self.products.find(&id) {
let product = RwLock::new(product_spec.clone());
self.product = Some(Arc::new(product));
} else {
tracing::warn!("Unknown product '{id}'");
}
}
}

fn update_issues(&self) {
if self.product.is_some() {
_ = self.issues.cast(issue::message::Clear::new(Scope::Manager));
} else {
let issue = Issue::new(
"no_product",
"No product has been selected.",
IssueSeverity::Error,
);
_ = self
.issues
.cast(issue::message::Set::new(Scope::Manager, vec![issue]));
}
}
}

Expand Down Expand Up @@ -248,22 +270,8 @@ impl MessageHandler<message::GetConfig> for Service {
#[async_trait]
impl MessageHandler<message::SetConfig> for Service {
/// Sets the user configuration with the given values.
/// Sets the config.
async fn handle(&mut self, message: message::SetConfig) -> Result<(), Error> {
let product_id = message
.config
.software
.as_ref()
.and_then(|s| s.product.as_ref())
.and_then(|p| p.id.as_ref());

if let Some(id) = product_id {
if let Some(product_spec) = self.products.find(&id) {
let product = RwLock::new(product_spec.clone());
self.product = Some(Arc::new(product));
_ = self.issues.cast(issue::message::Clear::new(Scope::Manager));
}
}
self.set_product_from_config(&message.config);

self.config = message.config.clone();
let config = message.config;
Expand All @@ -279,8 +287,6 @@ impl MessageHandler<message::SetConfig> for Service {
config.software.clone(),
))
.await?;
} else {
self.notify_no_product();
}

self.l10n
Expand All @@ -291,6 +297,7 @@ impl MessageHandler<message::SetConfig> for Service {
.call(storage::message::SetConfig::new(config.storage.clone()))
.await?;

self.update_issues();
Ok(())
}
}
Expand All @@ -303,6 +310,7 @@ impl MessageHandler<message::UpdateConfig> for Service {
/// config, then it keeps the values from the current config.
async fn handle(&mut self, message: message::UpdateConfig) -> Result<(), Error> {
let config = merge(&self.config, &message.config).map_err(|_| Error::MergeConfig)?;
self.set_product_from_config(&config);

if let Some(l10n) = &config.l10n {
self.l10n
Expand All @@ -322,7 +330,19 @@ impl MessageHandler<message::UpdateConfig> for Service {
.await?;
}

if let Some(product) = &self.product {
if let Some(software) = &config.software {
self.software
.call(software::message::SetConfig::with(
Arc::clone(&product),
software.clone(),
))
.await?;
}
}

self.config = config;
self.update_issues();
Ok(())
}
}
Expand Down Expand Up @@ -390,3 +410,13 @@ impl MessageHandler<message::SetStorageModel> for Service {
.await?)
}
}

// FIXME: write a macro to forward a message.
#[async_trait]
impl MessageHandler<software::message::SetResolvables> for Service {
/// It sets the software resolvables.
async fn handle(&mut self, message: software::message::SetResolvables) -> Result<(), Error> {
self.software.call(message).await?;
Ok(())
}
}
29 changes: 27 additions & 2 deletions rust/agama-server/src/server/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use crate::server::config_schema;
use agama_lib::error::ServiceError;
use agama_manager::{self as manager, message};
use agama_software::Resolvable;
use agama_utils::{
actor::Handler,
api::{
Expand All @@ -33,9 +34,9 @@ use agama_utils::{
question,
};
use axum::{
extract::State,
extract::{Path, State},
response::{IntoResponse, Response},
routing::{get, post},
routing::{get, post, put},
Json, Router,
};
use hyper::StatusCode;
Expand Down Expand Up @@ -109,6 +110,7 @@ pub async fn server_service(
"/private/storage_model",
get(get_storage_model).put(set_storage_model),
)
.route("/private/resolvables/:id", put(set_resolvables))
.with_state(state))
}

Expand Down Expand Up @@ -378,6 +380,29 @@ async fn set_storage_model(
Ok(())
}

#[utoipa::path(
put,
path = "/resolvables/:id",
context_path = "/api/v2",
responses(
(status = 200, description = "The resolvables list was updated.")
)
)]
async fn set_resolvables(
State(state): State<ServerState>,
Path(id): Path<String>,
Json(resolvables): Json<Vec<Resolvable>>,
) -> ServerResult<()> {
state
.manager
.call(agama_software::message::SetResolvables::new(
id,
resolvables,
))
.await?;
Ok(())
}

fn to_option_response<T: Serialize>(value: Option<T>) -> Response {
match value {
Some(inner) => Json(inner).into_response(),
Expand Down
40 changes: 0 additions & 40 deletions rust/agama-software/src/event.rs

This file was deleted.

5 changes: 1 addition & 4 deletions rust/agama-software/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@ pub mod service;
pub use service::Service;

mod model;
pub use model::{Model, ModelAdapter};

mod event;
pub use event::Event;
pub use model::{Model, ModelAdapter, Resolvable, ResolvableType};

pub mod message;
mod zypp_server;
25 changes: 25 additions & 0 deletions rust/agama-software/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ use agama_utils::{
use std::sync::Arc;
use tokio::sync::RwLock;

use crate::Resolvable;

#[derive(Clone)]
pub struct GetSystem;

Expand Down Expand Up @@ -66,6 +68,13 @@ impl<T> SetConfig<T> {
pub fn new(product: Arc<RwLock<ProductSpec>>, config: Option<T>) -> Self {
Self { config, product }
}

pub fn with(product: Arc<RwLock<ProductSpec>>, config: T) -> Self {
Self {
config: Some(config),
product,
}
}
}

pub struct GetProposal;
Expand All @@ -91,3 +100,19 @@ pub struct Finish;
impl Message for Finish {
type Reply = ();
}

// Sets a resolvables list
pub struct SetResolvables {
pub id: String,
pub resolvables: Vec<Resolvable>,
}

impl SetResolvables {
pub fn new(id: String, resolvables: Vec<Resolvable>) -> Self {
Self { id, resolvables }
}
}

impl Message for SetResolvables {
type Reply = ();
}
Loading
Loading