Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
17463b5
Drop the unused agama_utils::service module
imobachgs Oct 10, 2025
09aea71
Add storage service
joseivanlopez Oct 16, 2025
154dc6e
Make dbus connection mandatory
joseivanlopez Oct 17, 2025
9ed773f
Add HTTP resource for the storage model
joseivanlopez Oct 20, 2025
e92d64a
Skeleton of the new D-Bus API of storage
joseivanlopez Oct 21, 2025
7f36d4a
Implement some methods of the new D-Bus API
joseivanlopez Oct 21, 2025
781c961
Rename progress
joseivanlopez Oct 22, 2025
d890b6f
Rename mixin
joseivanlopez Oct 22, 2025
ddd3124
Add new progress
joseivanlopez Oct 22, 2025
1410f79
Add progress to API methods
joseivanlopez Oct 22, 2025
15016ea
Implement Install and Finish API methods
joseivanlopez Oct 23, 2025
b05630d
Merge branch 'api-v2' into drop-unused-module
imobachgs Oct 24, 2025
e2c1366
First version of devicegraph_conversions
ancorgs Oct 17, 2025
dbf0503
service: First versions of D-Bus GetProposal and GetSystem
ancorgs Oct 22, 2025
c7ec8d9
Delete some dead code
ancorgs Oct 23, 2025
77d3f73
Delete some calls to deleted methods
ancorgs Oct 23, 2025
f8089dc
Implement SetLocale API method
joseivanlopez Oct 24, 2025
18925a4
Remove deprecated system
joseivanlopez Oct 24, 2025
9e5459e
Remove service status
joseivanlopez Oct 24, 2025
e8e7cf1
Emit signals
joseivanlopez Oct 24, 2025
ac87a60
Reorder manager code
joseivanlopez Oct 24, 2025
e16bc85
Move code to service starter
joseivanlopez Oct 24, 2025
97103b9
Add methods to dbus client
joseivanlopez Oct 24, 2025
8301745
Allow setting a specific progress
joseivanlopez Oct 27, 2025
734ed47
Add storage monitor
joseivanlopez Oct 27, 2025
5aa6373
Move dbus client
joseivanlopez Oct 28, 2025
56f1085
Use option to track null json
joseivanlopez Oct 28, 2025
fb445a3
Add storage messages
joseivanlopez Oct 28, 2025
b32d238
Adapt manager
joseivanlopez Oct 28, 2025
54b5099
Recover storage system info
joseivanlopez Oct 28, 2025
ba5c24e
Recover storage extended config
joseivanlopez Oct 28, 2025
8939347
Recover storage proposal
joseivanlopez Oct 28, 2025
854886f
Configure storage locale
joseivanlopez Oct 28, 2025
58515fd
service: Report both storage issues and storage probing issues
ancorgs Oct 27, 2025
b076228
Remove reference to deleted file
ancorgs Oct 27, 2025
4dd5528
Fix ambiguous mixin name
ancorgs Oct 28, 2025
6715b0e
Improve yardoc
ancorgs Oct 27, 2025
1550f3a
Please rubocop
ancorgs Oct 27, 2025
4662ac6
Remove unit tests for deprecated_system
ancorgs Oct 27, 2025
075ffee
Fix tests for DBus::Storage::Manager
ancorgs Oct 27, 2025
628bfc3
Fix tests for Agama::Storage::Manager
ancorgs Oct 28, 2025
1c19bb3
Fix tests for DBus::Clients::Storage
ancorgs Oct 28, 2025
bbcf2b8
Fix tests for Agama::Manager
ancorgs Oct 28, 2025
e2fba00
Return null in some cases for GetSystem and GetProposal
ancorgs Oct 28, 2025
d431574
Some fixes from code review
ancorgs Oct 29, 2025
5fce2a1
Small modification to Manager#reset_activation
ancorgs Oct 29, 2025
50d5879
Allow to reset config
joseivanlopez Oct 29, 2025
e4c32e6
Fix dbus service
joseivanlopez Oct 29, 2025
2ea9e8f
Set storage config
joseivanlopez Oct 29, 2025
b64ce44
Add storage actions
joseivanlopez Oct 30, 2025
d0ebbaf
Speed up tests
ancorgs Oct 30, 2025
3854894
Report storage issues
joseivanlopez Oct 30, 2025
fc0613f
Include system information in the SystemChanged signal
ancorgs Oct 30, 2025
e282c16
Include proposal information in the ProposalChanged signal
ancorgs Oct 29, 2025
5280dc4
Remove wrong signal declaration
ancorgs Oct 30, 2025
0f10897
Change from code review
ancorgs Oct 31, 2025
3aa33a7
Merge pull request #13 from ancorgs/storage-new-api-ags7
joseivanlopez Oct 31, 2025
022b0ba
Adapt signals
joseivanlopez Oct 31, 2025
330c427
Drop storage from issues monitor
joseivanlopez Oct 31, 2025
045ddc1
Check config schema
joseivanlopez Oct 31, 2025
5e798bb
Extend schema
joseivanlopez Oct 31, 2025
204c18f
Extract patch
joseivanlopez Oct 31, 2025
bdfd2b1
Fix example
joseivanlopez Oct 31, 2025
c83592f
Use serde Value instead of RawValue
joseivanlopez Nov 3, 2025
254dde0
Make questions config optional
joseivanlopez Nov 3, 2025
be86d5f
Remove unused mixins
joseivanlopez Nov 3, 2025
329467c
Changelogs
joseivanlopez Nov 3, 2025
034bece
Fix tests
joseivanlopez Nov 4, 2025
ef9f458
feat: storage service (#2816)
joseivanlopez Nov 4, 2025
73cf50a
Drop the unused agama_utils::service module (#2798)
imobachgs Nov 6, 2025
d9381bf
WIP: First version of the JSON schema for system/storage
ancorgs Nov 4, 2025
8cd2988
web: Types based on the storage system schema
ancorgs Nov 4, 2025
def09e7
Modularize system.storage.schema
ancorgs Nov 5, 2025
a3e1382
web: Update and relocate system.ts types definition
ancorgs Nov 5, 2025
9516fae
First version of the JSON schema for proposal/storage
ancorgs Nov 5, 2025
9ffd71e
web: Types based on the storage proposal schema
ancorgs Nov 5, 2025
f978ce3
Make encryptionMethod an enum in the schema for system/storage
ancorgs Nov 7, 2025
0b9ab30
First version of the JSON schemas for system/storage and proposal/sto…
ancorgs Nov 7, 2025
464354e
Merge branch 'api-v2' into merge-api-v2
imobachgs Nov 7, 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
17 changes: 17 additions & 0 deletions rust/Cargo.lock

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

1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [
"agama-network",
"agama-server",
"agama-software",
"agama-storage",
"agama-utils",
"xtask",
"zypp-agama",
Expand Down
10 changes: 8 additions & 2 deletions rust/agama-l10n/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,23 @@ impl Message for GetConfig {
}

pub struct SetConfig<T> {
pub config: T,
pub config: Option<T>,
}

impl<T: Send + 'static> Message for SetConfig<T> {
type Reply = ();
}

impl<T> SetConfig<T> {
pub fn new(config: T) -> Self {
pub fn new(config: Option<T>) -> Self {
Self { config }
}

pub fn with(config: T) -> Self {
Self {
config: Some(config),
}
}
}

pub struct GetProposal;
Expand Down
22 changes: 14 additions & 8 deletions rust/agama-l10n/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl Service {
details: None,
source: IssueSource::Config,
severity: IssueSeverity::Error,
kind: "unknown_locale".to_string(),
class: "unknown_locale".to_string(),
});
}

Expand All @@ -133,7 +133,7 @@ impl Service {
details: None,
source: IssueSource::Config,
severity: IssueSeverity::Error,
kind: "unknown_keymap".to_string(),
class: "unknown_keymap".to_string(),
});
}

Expand All @@ -143,7 +143,7 @@ impl Service {
details: None,
source: IssueSource::Config,
severity: IssueSeverity::Error,
kind: "unknown_timezone".to_string(),
class: "unknown_timezone".to_string(),
});
}

Expand Down Expand Up @@ -195,16 +195,22 @@ impl MessageHandler<message::SetConfig<api::l10n::Config>> for Service {
&mut self,
message: message::SetConfig<api::l10n::Config>,
) -> Result<(), Error> {
let config = Config::new_from(&self.system);
let merged = config.merge(&message.config)?;
if merged == self.config {
let base_config = Config::new_from(&self.system);

let config = if let Some(config) = &message.config {
base_config.merge(config)?
} else {
base_config
};

if config == self.config {
return Ok(());
}

self.config = merged;
self.config = config;
let issues = self.find_issues();
self.issues
.cast(issue::message::Update::new(Scope::L10n, issues))?;
.cast(issue::message::Set::new(Scope::L10n, issues))?;
self.events
.send(Event::ProposalChanged { scope: Scope::L10n })?;
Ok(())
Expand Down
50 changes: 37 additions & 13 deletions rust/agama-l10n/src/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,16 @@ mod tests {
use crate::model::{KeymapsDatabase, LocalesDatabase, ModelAdapter, TimezonesDatabase};
use crate::service::{self, Service};
use agama_locale_data::{KeymapId, LocaleId};
use agama_utils::actor::{self, Handler};
use agama_utils::api;
use agama_utils::api::event::{self, Event};
use agama_utils::api::l10n::{Keymap, LocaleEntry, TimezoneEntry};
use agama_utils::api::scope::Scope;
use agama_utils::issue;
use agama_utils::{
actor::{self, Handler},
api::{
self,
event::{self, Event},
l10n::{Keymap, LocaleEntry, TimezoneEntry},
scope::Scope,
},
issue, test,
};
use tokio::sync::broadcast;

pub struct TestModel {
Expand Down Expand Up @@ -145,7 +149,8 @@ mod tests {
async fn start_testing_service() -> (event::Receiver, Handler<Service>, Handler<issue::Service>)
{
let (events_tx, events_rx) = broadcast::channel::<Event>(16);
let issues = issue::start(events_tx.clone(), None).await.unwrap();
let dbus = test::dbus::connection().await.unwrap();
let issues = issue::start(events_tx.clone(), dbus).await.unwrap();

let model = build_adapter();
let service = Service::new(model, issues.clone(), events_tx);
Expand All @@ -167,7 +172,7 @@ mod tests {
timezone: Some("Atlantic/Canary".to_string()),
};
handler
.call(message::SetConfig::new(input_config.clone()))
.call(message::SetConfig::with(input_config.clone()))
.await?;

let updated = handler.call(message::GetConfig).await?;
Expand All @@ -190,7 +195,7 @@ mod tests {

// Use system info for missing values.
handler
.call(message::SetConfig::new(input_config.clone()))
.call(message::SetConfig::with(input_config.clone()))
.await?;

let updated = handler.call(message::GetConfig).await?;
Expand All @@ -206,6 +211,25 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn test_reset_config() -> Result<(), Box<dyn std::error::Error>> {
let (mut _events_rx, handler, _issues) = start_testing_service().await;

handler.call(message::SetConfig::new(None)).await?;

let config = handler.call(message::GetConfig).await?;
assert_eq!(
config,
api::l10n::Config {
locale: Some("en_US.UTF-8".to_string()),
keymap: Some("us".to_string()),
timezone: Some("Europe/Berlin".to_string()),
}
);

Ok(())
}

#[tokio::test]
async fn test_set_invalid_config() -> Result<(), Box<dyn std::error::Error>> {
let (_events_rx, handler, _issues) = start_testing_service().await;
Expand All @@ -216,7 +240,7 @@ mod tests {
};

let result = handler
.call(message::SetConfig::new(input_config.clone()))
.call(message::SetConfig::with(input_config.clone()))
.await;
assert!(matches!(result, Err(service::Error::InvalidLocale(_))));
Ok(())
Expand All @@ -228,7 +252,7 @@ mod tests {

let config = handler.call(message::GetConfig).await?;
assert_eq!(config.locale, Some("en_US.UTF-8".to_string()));
let message = message::SetConfig::new(config.clone());
let message = message::SetConfig::with(config.clone());
handler.call(message).await?;
// Wait until the action is dispatched.
let _ = handler.call(message::GetConfig).await?;
Expand All @@ -247,7 +271,7 @@ mod tests {
locale: Some("xx_XX.UTF-8".to_string()),
timezone: Some("Unknown/Unknown".to_string()),
};
let _ = handler.call(message::SetConfig::new(config)).await?;
let _ = handler.call(message::SetConfig::with(config)).await?;

let found_issues = issues.call(issue::message::Get).await?;
let l10n_issues = found_issues.get(&Scope::L10n).unwrap();
Expand Down Expand Up @@ -277,7 +301,7 @@ mod tests {
keymap: Some("es".to_string()),
timezone: Some("Atlantic/Canary".to_string()),
};
let message = message::SetConfig::new(input_config.clone());
let message = message::SetConfig::with(input_config.clone());
handler.call(message).await?;

let proposal = handler
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-lib/share/examples/profile_tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"localization": {
"keyboard": "es",
"language": "es_ES.UTF-8",
"keymap": "es_ES.UTF-8"
"timezone": "Europe/Berlin"
},
"software": {
"patterns": ["gnome"],
Expand Down
26 changes: 25 additions & 1 deletion rust/agama-lib/share/profile.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,33 @@
}
}
},
"localization": {
"l10n": {
"title": "Localization settings",
"type": "object",
"additionalProperties": false,
"properties": {
"locale": {
"title": "Locale ID",
"type": "string",
"examples": ["en_US.UTF-8", "en_US"]
},
"keymap": {
"title": "Keymap ID",
"type": "string",
"examples": ["us", "en", "es"]
},
"timezone": {
"title": "Time zone ID",
"type": "string",
"examples": ["Europe/Berlin"]
}
}
},
"localization": {
"deprecated": true,
"title": "Localization settings (old schema)",
"type": "object",
"additionalProperties": false,
"properties": {
"language": {
"title": "System language ID",
Expand Down
12 changes: 5 additions & 7 deletions rust/agama-lib/src/questions/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use std::time::Duration;

use agama_utils::api::{
config::Patch,
patch::{self, Patch},
question::{
Answer, AnswerRule, Config as QuestionsConfig, Policy, Question, QuestionSpec,
UpdateQuestion,
Expand All @@ -38,6 +38,8 @@ pub enum QuestionsHTTPClientError {
HTTP(#[from] BaseHTTPClientError),
#[error("Unknown question with ID {0}")]
UnknownQuestion(u32),
#[error(transparent)]
Patch(#[from] patch::Error),
}

pub struct HTTPClient {
Expand Down Expand Up @@ -99,9 +101,7 @@ impl HTTPClient {
..Default::default()
};

let patch = Patch {
update: Some(config),
};
let patch = Patch::with_update(&config)?;

_ = self.client.patch_void("/v2/config", &patch).await?;
Ok(())
Expand All @@ -120,9 +120,7 @@ impl HTTPClient {
..Default::default()
};

let patch = Patch {
update: Some(config),
};
let patch = Patch::with_update(&config)?;
self.client.patch_void("/v2/config", &patch).await?;
Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions rust/agama-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ edition.workspace = true
agama-utils = { path = "../agama-utils" }
agama-l10n = { path = "../agama-l10n" }
agama-software = { path = "../agama-software" }
agama-storage = { path = "../agama-storage" }
thiserror = "2.0.12"
tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread", "sync"] }
async-trait = "0.1.83"
zbus = { version = "5", default-features = false, features = ["tokio"] }
merge-struct = "0.1.0"
serde_json = "1.0.140"

[dev-dependencies]
tokio-test = "0.4.4"
Expand Down
1 change: 1 addition & 0 deletions rust/agama-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ pub mod message;

pub use agama_l10n as l10n;
pub use agama_software as software;
pub use agama_storage as storage;
23 changes: 23 additions & 0 deletions rust/agama-manager/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use agama_utils::{
actor::Message,
api::{Action, Config, IssueMap, Proposal, Status, SystemInfo},
};
use serde_json::Value;

/// Gets the installation status.
pub struct GetStatus;
Expand Down Expand Up @@ -118,3 +119,25 @@ impl RunAction {
impl Message for RunAction {
type Reply = ();
}

// Gets the storage model.
pub struct GetStorageModel;

impl Message for GetStorageModel {
type Reply = Option<Value>;
}

// Sets the storage model.
pub struct SetStorageModel {
pub model: Value,
}

impl SetStorageModel {
pub fn new(model: Value) -> Self {
Self { model }
}
}

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