Skip to content

Commit

Permalink
Add bootloader section to agama config (jsc#AGM-54)
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Dec 19, 2024
1 parent 6749f1c commit 5492568
Show file tree
Hide file tree
Showing 23 changed files with 619 additions and 1 deletion.
9 changes: 9 additions & 0 deletions doc/dbus/bus/org.opensuse.Agama.Storage1.bus.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@
</method>
<property type="b" name="DeprecatedSystem" access="read"/>
</interface>
<interface name="org.opensuse.Agama.Storage1.Bootloader">
<method name="SetConfig">
<arg name="serialized_config" direction="in" type="s"/>
<arg name="result" direction="out" type="u"/>
</method>
<method name="GetConfig">
<arg name="serialized_config" direction="out" type="s"/>
</method>
</interface>
<interface name="org.opensuse.Agama.Storage1.DASD.Manager">
<method name="Probe">
</method>
Expand Down
10 changes: 10 additions & 0 deletions rust/agama-lib/share/profile.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@
}
}
},
"bootloader": {
"title": "Bootloader settings",
"type": "object",
"properties": {
"stopOnBootMenu": {
"title": "Specify if bootloader should stop on menu during boot.",
"type": "boolean"
}
}
},
"software": {
"title": "Software settings",
"type": "object",
Expand Down
28 changes: 28 additions & 0 deletions rust/agama-lib/src/bootloader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) [2024] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

//! Implements support for handling the storage settings
pub mod client;
// pub mod http_client;
pub mod http_client;
pub mod model;
pub mod proxies;
pub mod store;
57 changes: 57 additions & 0 deletions rust/agama-lib/src/bootloader/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) [2024] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

//! Implements a client to access Agama's D-Bus API related to Bootloader management.
use zbus::Connection;

use crate::{
bootloader::{model::BootloaderSettings, proxies::BootloaderProxy},
error::ServiceError,
};

/// Client to connect to Agama's D-Bus API for Bootloader management.
#[derive(Clone)]
pub struct BootloaderClient<'a> {
bootloader_proxy: BootloaderProxy<'a>,
}

impl<'a> BootloaderClient<'a> {
pub async fn new(connection: Connection) -> Result<BootloaderClient<'a>, ServiceError> {
let bootloader_proxy = BootloaderProxy::new(&connection).await?;

Ok(Self { bootloader_proxy })
}

pub async fn get_config(&self) -> Result<BootloaderSettings, ServiceError> {
let serialized_string = self.bootloader_proxy.get_config().await?;
let settings = serde_json::from_str(serialized_string.as_str())?;
Ok(settings)
}

pub async fn set_config(&self, config: &BootloaderSettings) -> Result<(), ServiceError> {
// ignore return value as currently it does not fail and who knows what future brings
// but it should not be part of result and instead transformed to ServiceError
self.bootloader_proxy
.set_config(serde_json::to_string(config)?.as_str())
.await?;
Ok(())
}
}
43 changes: 43 additions & 0 deletions rust/agama-lib/src/bootloader/http_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) [2024] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

//! Implements a client to access Agama's HTTP API related to Bootloader management.
use crate::base_http_client::BaseHTTPClient;
use crate::bootloader::model::BootloaderSettings;
use crate::ServiceError;

pub struct BootloaderHTTPClient {
client: BaseHTTPClient,
}

impl BootloaderHTTPClient {
pub fn new(base: BaseHTTPClient) -> Self {
Self { client: base }
}

pub async fn get_config(&self) -> Result<BootloaderSettings, ServiceError> {
self.client.get("/bootloader/config").await
}

pub async fn set_config(&self, config: &BootloaderSettings) -> Result<(), ServiceError> {
self.client.put_void("/bootloader/config", config).await
}
}
30 changes: 30 additions & 0 deletions rust/agama-lib/src/bootloader/model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) [2024] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

//! Implements a data model for Bootloader configuration.
use serde::{Deserialize, Serialize};

/// Represents a Bootloader
#[derive(Clone, Debug, Serialize, Deserialize, Default, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct BootloaderSettings {
pub stop_on_boot_menu: bool,
}
35 changes: 35 additions & 0 deletions rust/agama-lib/src/bootloader/proxies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! # D-Bus interface proxy for: `org.opensuse.Agama.Storage1.Bootloader`
//!
//! This code was generated by `zbus-xmlgen` `5.0.1` from D-Bus introspection data.
//! Source: `org.opensuse.Agama.Storage1.bus.xml`.
//!
//! You may prefer to adapt it, instead of using it verbatim.
//!
//! More information can be found in the [Writing a client proxy] section of the zbus
//! documentation.
//!
//! This type implements the [D-Bus standard interfaces], (`org.freedesktop.DBus.*`) for which the
//! following zbus API can be used:
//!
//! * [`zbus::fdo::IntrospectableProxy`]
//! * [`zbus::fdo::ObjectManagerProxy`]
//! * [`zbus::fdo::PropertiesProxy`]
//!
//! Consequently `zbus-xmlgen` did not generate code for the above interfaces.
//!
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
use zbus::proxy;
#[proxy(
default_service = "org.opensuse.Agama.Storage1",
default_path = "/org/opensuse/Agama/Storage1",
interface = "org.opensuse.Agama.Storage1.Bootloader",
assume_defaults = true
)]
pub trait Bootloader {
/// GetConfig method
fn get_config(&self) -> zbus::Result<String>;

/// SetConfig method
fn set_config(&self, serialized_config: &str) -> zbus::Result<u32>;
}
49 changes: 49 additions & 0 deletions rust/agama-lib/src/bootloader/store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) [2024] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

//! Implements the store for the storage settings.
use crate::base_http_client::BaseHTTPClient;
use crate::error::ServiceError;

use super::http_client::BootloaderHTTPClient;
use super::model::BootloaderSettings;

/// Loads and stores the storage settings from/to the HTTP service.
pub struct BootloaderStore {
bootloader_client: BootloaderHTTPClient,
}

impl BootloaderStore {
pub fn new(client: BaseHTTPClient) -> Result<Self, ServiceError> {
Ok(Self {
bootloader_client: BootloaderHTTPClient::new(client),
})
}

pub async fn load(&self) -> Result<BootloaderSettings, ServiceError> {
self.bootloader_client.get_config().await
}

pub async fn store(&self, settings: &BootloaderSettings) -> Result<(), ServiceError> {
self.bootloader_client.set_config(settings).await?;
Ok(())
}
}
3 changes: 3 additions & 0 deletions rust/agama-lib/src/install_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//! Configuration settings handling
//!
//! This module implements the mechanisms to load and store the installation settings.
use crate::bootloader::model::BootloaderSettings;
use crate::{
localization::LocalizationSettings, network::NetworkSettings, product::ProductSettings,
scripts::ScriptsConfig, software::SoftwareSettings, users::UserSettings,
Expand All @@ -39,6 +40,8 @@ use std::path::Path;
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InstallSettings {
#[serde(default)]
pub bootloader: Option<BootloaderSettings>,
#[serde(default, flatten)]
pub user: Option<UserSettings>,
#[serde(default)]
Expand Down
1 change: 1 addition & 0 deletions rust/agama-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
pub mod auth;
pub mod base_http_client;
pub mod bootloader;
pub mod error;
pub mod install_settings;
pub mod jobs;
Expand Down
7 changes: 7 additions & 0 deletions rust/agama-lib/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
// TODO: quickly explain difference between FooSettings and FooStore, with an example

use crate::base_http_client::BaseHTTPClient;
use crate::bootloader::store::BootloaderStore;
use crate::error::ServiceError;
use crate::install_settings::InstallSettings;
use crate::manager::{InstallationPhase, ManagerHTTPClient};
Expand All @@ -38,6 +39,7 @@ use crate::{
///
/// This struct uses the default connection built by [connection function](super::connection).
pub struct Store {
bootloader: BootloaderStore,
users: UsersStore,
network: NetworkStore,
product: ProductStore,
Expand All @@ -52,6 +54,7 @@ pub struct Store {
impl Store {
pub async fn new(http_client: BaseHTTPClient) -> Result<Store, ServiceError> {
Ok(Self {
bootloader: BootloaderStore::new(http_client.clone())?,
localization: LocalizationStore::new(http_client.clone())?,
users: UsersStore::new(http_client.clone())?,
network: NetworkStore::new(http_client.clone()).await?,
Expand All @@ -67,6 +70,7 @@ impl Store {
/// Loads the installation settings from the HTTP interface.
pub async fn load(&self) -> Result<InstallSettings, ServiceError> {
let mut settings = InstallSettings {
bootloader: Some(self.bootloader.load().await?),
network: Some(self.network.load().await?),
software: Some(self.software.load().await?),
user: Some(self.users.load().await?),
Expand Down Expand Up @@ -121,6 +125,9 @@ impl Store {
if settings.storage.is_some() || settings.storage_autoyast.is_some() {
self.storage.store(&settings.into()).await?
}
if let Some(bootloader) = &settings.bootloader {
self.bootloader.store(bootloader).await?;
}

Ok(())
}
Expand Down
21 changes: 21 additions & 0 deletions rust/agama-server/src/bootloader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) [2024] SUSE LLC
//
// All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, contact SUSE LLC.
//
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

pub mod web;
Loading

0 comments on commit 5492568

Please sign in to comment.