Skip to content

Commit 3313741

Browse files
feat: simplify HTTP API (#2795)
Simplify the HTTP API by removing endpoints for each scope (e.g., */config/storage*) resulting in a smaller API for dealing with the config: ~~~ GET /extended_config GET PUT PATCH /config ~~~ With this new API, the way for resetting a specific scope consists on putting the whole current config without including the scope to remove. In the future, the schema for patching could be extended. For example, it could provide a way for resetting some scopes without giving the current config.
2 parents 556725d + 4e379c5 commit 3313741

File tree

10 files changed

+70
-353
lines changed

10 files changed

+70
-353
lines changed

doc/http_api.md

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ The API is designed around 3 main concepts: *system*, *config* and *proposal*.
2020
The *config* contains elements that can modify the *system*, the *proposal* or both. For example, the *dasd* config changes the *system*, and the *storage* config changes the *proposal*. In other cases like *network*, the config can affect to both *system* and *proposal*.
2121

2222
~~~
23+
GET /status
2324
GET /system
2425
GET /extended_config
25-
GET /extended_config/{scope}
2626
GET PUT PATCH /config
27-
GET PUT PATCH /config/{scope}
2827
GET POST PATCH /questions
2928
GET /proposal
30-
GET /status
3129
GET /issues
3230
POST /action
3331
~~~
3432

33+
### GET /status
34+
35+
Reports the status of the installation. It contains the installation state (*configuring*, *installing*, *finished*) and the active progresses.
36+
3537
### GET /system
3638

3739
Returns a JSON with the info of the system (storage devices, network connections, current localization, etc).
@@ -47,39 +49,51 @@ There is a distinction between *extended config* and *config*:
4749

4850
For example, if only the *locale* was configured by the user, then the *config* has no *keymap* property. Nevertheless, the *extended config* would have a *keymap* with the value from the default *extended config*.
4951

50-
The scope can be indicated to retrieve only a part of the config, for example *GET /extended_config/l10n*.
52+
### GET PUT /config
5153

52-
### GET PUT PATCH /config
54+
Reads or replaces the *config*. In case of patching, the given config is merged into the current *extended config*.
5355

54-
Reads, replaces or modifies the explicitly set *config*. In case of patching, the given config is merged into the current *extended config*.
56+
### PATCH /config
5557

56-
The scope can be indicated to manage only part of the config, for example *PUT /config/l10n*.
58+
Applies changes in the *config*. There is an own patch document:
5759

58-
### POST /action
60+
~~~json
61+
{
62+
"update": {
63+
"l10n": {
64+
"keymap": "es"
65+
}
66+
}
67+
}
68+
~~~
5969

60-
Allows performing actions that cannot be done as side effect of applying a config. For example, start the installation, reload the system, etc. The *actions schema* defines the possible actions, parameters, etc.
70+
The given config from the *update* key is merged into current *extended config*.
6171

62-
### GET /status
72+
The patch document could be extended in the future with more options, for example for resetting some parts of the config.
6373

64-
Reports the status of the installation. It contains the installation state (*configuring*, *installing*, *finished*) and the active progresses.
74+
See https://datatracker.ietf.org/doc/html/rfc5789#section-2
75+
76+
### POST /action
77+
78+
Allows performing actions that cannot be done as side effect of applying a config. For example, start the installation, reload the system, etc. The *actions schema* defines the possible actions, parameters, etc.
6579

66-
### Example: reload the system
80+
#### Example: reload the system
6781

6882
In some cases, clients need to request a system reload. For example, if you create a RAID device using the terminal, then you need to reload the system in order to see the new device. In the future, reloading the system could be automatically done (e.g., by listening udisk D-Bus). For now, reloading has to be manually requested.
6983

7084
~~~
71-
POST /action { "reloadSystem": { scope: "storage" } }
85+
POST /action { "reloadSystem": "storage" }
7286
~~~
7387

74-
### Example: change the system localization
88+
#### Example: change the system localization
7589

7690
Sometimes we need to directly modify the system without changing the config. For example, switching the locale of the running system (UI language).
7791

7892
~~~
7993
POST /action { "configureL10n": { language: "es_ES" } }
8094
~~~
8195

82-
### Example: start installation
96+
#### Example: start installation
8397

8498
The installation can be started by calling the proper action.
8599

rust/agama-manager/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ pub use start::start;
2424
pub mod service;
2525
pub use service::Service;
2626

27-
mod scope;
28-
pub use scope::{ConfigScope, Scope};
29-
3027
mod system_info;
3128
pub use system_info::SystemInfo;
3229

rust/agama-manager/src/message.rs

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
// To contact SUSE LLC about this file by physical or electronic mail, you may
1919
// find current contact information at www.suse.com.
2020

21-
use crate::{
22-
l10n, proposal::Proposal, scope::ConfigScope, scope::Scope, service, system_info::SystemInfo,
23-
};
21+
use crate::{l10n, proposal::Proposal, service, system_info::SystemInfo};
2422
use agama_lib::{install_settings::InstallSettings, issue::Issue};
2523
use agama_utils::{actor::Message, progress::Progress};
2624
use serde::{Deserialize, Serialize};
@@ -61,22 +59,6 @@ impl Message for GetExtendedConfig {
6159
type Reply = InstallSettings;
6260
}
6361

64-
/// Gets a scope from the full config.
65-
#[derive(Debug)]
66-
pub struct GetExtendedConfigScope {
67-
pub scope: Scope,
68-
}
69-
70-
impl GetExtendedConfigScope {
71-
pub fn new(scope: Scope) -> Self {
72-
Self { scope }
73-
}
74-
}
75-
76-
impl Message for GetExtendedConfigScope {
77-
type Reply = Option<ConfigScope>;
78-
}
79-
8062
/// Gets the current config set by the user.
8163
#[derive(Debug)]
8264
pub struct GetConfig;
@@ -117,54 +99,6 @@ impl Message for UpdateConfig {
11799
type Reply = ();
118100
}
119101

120-
/// Gets a scope from the config.
121-
#[derive(Debug)]
122-
pub struct GetConfigScope {
123-
pub scope: Scope,
124-
}
125-
126-
impl GetConfigScope {
127-
pub fn new(scope: Scope) -> Self {
128-
Self { scope }
129-
}
130-
}
131-
132-
impl Message for GetConfigScope {
133-
type Reply = Option<ConfigScope>;
134-
}
135-
136-
/// Sets a config scope
137-
#[derive(Debug)]
138-
pub struct SetConfigScope {
139-
pub config: ConfigScope,
140-
}
141-
142-
impl SetConfigScope {
143-
pub fn new(config: ConfigScope) -> Self {
144-
Self { config }
145-
}
146-
}
147-
148-
impl Message for SetConfigScope {
149-
type Reply = ();
150-
}
151-
152-
/// Updates a config scope
153-
#[derive(Debug)]
154-
pub struct UpdateConfigScope {
155-
pub config: ConfigScope,
156-
}
157-
158-
impl UpdateConfigScope {
159-
pub fn new(config: ConfigScope) -> Self {
160-
Self { config }
161-
}
162-
}
163-
164-
impl Message for UpdateConfigScope {
165-
type Reply = ();
166-
}
167-
168102
/// Gets the proposal.
169103
#[derive(Debug)]
170104
pub struct GetProposal;

rust/agama-manager/src/scope.rs

Lines changed: 0 additions & 45 deletions
This file was deleted.

rust/agama-manager/src/service.rs

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use crate::{
2222
l10n,
2323
message::{self, Action},
2424
proposal::Proposal,
25-
scope::{ConfigScope, Scope},
2625
system_info::SystemInfo,
2726
};
2827
use agama_lib::install_settings::InstallSettings;
@@ -147,23 +146,6 @@ impl MessageHandler<message::GetExtendedConfig> for Service {
147146
}
148147
}
149148

150-
#[async_trait]
151-
impl MessageHandler<message::GetExtendedConfigScope> for Service {
152-
/// It returns the configuration for the given scope.
153-
async fn handle(
154-
&mut self,
155-
message: message::GetExtendedConfigScope,
156-
) -> Result<Option<ConfigScope>, Error> {
157-
let option = match message.scope {
158-
Scope::L10n => {
159-
let l10n_config = self.l10n.call(l10n::message::GetConfig).await?;
160-
Some(ConfigScope::L10n(l10n_config))
161-
}
162-
};
163-
Ok(option)
164-
}
165-
}
166-
167149
#[async_trait]
168150
impl MessageHandler<message::GetConfig> for Service {
169151
/// Gets the current configuration set by the user.
@@ -205,63 +187,6 @@ impl MessageHandler<message::UpdateConfig> for Service {
205187
}
206188
}
207189

208-
#[async_trait]
209-
impl MessageHandler<message::GetConfigScope> for Service {
210-
/// It returns the configuration set by the user for the given scope.
211-
async fn handle(
212-
&mut self,
213-
message: message::GetConfigScope,
214-
) -> Result<Option<ConfigScope>, Error> {
215-
// FIXME: implement this logic at InstallSettings level: self.get_config().by_scope(...)
216-
// It would allow us to drop this method.
217-
let option = match message.scope {
218-
Scope::L10n => self
219-
.config
220-
.localization
221-
.clone()
222-
.map(|c| ConfigScope::L10n(c)),
223-
};
224-
Ok(option)
225-
}
226-
}
227-
228-
#[async_trait]
229-
impl MessageHandler<message::SetConfigScope> for Service {
230-
/// Sets the user configuration within the given scope.
231-
///
232-
/// It replaces the current configuration with the given one and calculates a
233-
/// new proposal. Only the configuration in the given scope is affected.
234-
async fn handle(&mut self, message: message::SetConfigScope) -> Result<(), Error> {
235-
match message.config {
236-
ConfigScope::L10n(l10n_config) => {
237-
self.l10n
238-
.call(l10n::message::SetConfig::new(l10n_config.clone()))
239-
.await?;
240-
self.config.localization = Some(l10n_config);
241-
}
242-
}
243-
Ok(())
244-
}
245-
}
246-
247-
#[async_trait]
248-
impl MessageHandler<message::UpdateConfigScope> for Service {
249-
/// Patches the user configuration within the given scope.
250-
///
251-
/// It merges the current configuration with the given one.
252-
async fn handle(&mut self, message: message::UpdateConfigScope) -> Result<(), Error> {
253-
match message.config {
254-
ConfigScope::L10n(l10n_config) => {
255-
let base_config = self.config.localization.clone().unwrap_or_default();
256-
let config = merge(&base_config, &l10n_config).map_err(|_| Error::MergeConfig)?;
257-
self.handle(message::SetConfigScope::new(ConfigScope::L10n(config)))
258-
.await?;
259-
}
260-
}
261-
Ok(())
262-
}
263-
}
264-
265190
#[async_trait]
266191
impl MessageHandler<message::GetProposal> for Service {
267192
/// It returns the current proposal, if any.

rust/agama-server/src/server/types.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020

2121
//! This module defines some ancillary types for the HTTP API.
2222
23-
use std::collections::HashMap;
24-
23+
use agama_lib::install_settings::InstallSettings;
2524
use agama_utils::issue;
26-
use serde::Serialize;
25+
use serde::{Deserialize, Serialize};
26+
use std::collections::HashMap;
2727

28-
#[derive(Serialize, utoipa::ToSchema)]
28+
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
2929
/// Holds the installation issues for each scope.
3030
pub struct IssuesMap {
3131
/// iSCSI issues.
@@ -60,3 +60,10 @@ impl From<HashMap<String, Vec<issue::Issue>>> for IssuesMap {
6060
}
6161
}
6262
}
63+
64+
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
65+
/// Patch for the config.
66+
pub struct ConfigPatch {
67+
/// Update for the current config.
68+
pub update: Option<InstallSettings>,
69+
}

0 commit comments

Comments
 (0)