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
20 changes: 20 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 @@ -14,6 +14,7 @@ members = [
"agama-storage",
"agama-transfer",
"agama-utils",
"agama-users",
"suseconnect-agama",
"suseconnect-agama/suseconnect-agama-sys",
"xtask",
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 @@ -13,6 +13,7 @@ agama-network = { path = "../agama-network" }
agama-software = { path = "../agama-software" }
agama-storage = { path = "../agama-storage" }
agama-utils = { path = "../agama-utils" }
agama-users = { path = "../agama-users" }
thiserror = "2.0.12"
tokio = { version = "1.40.0", features = ["macros", "rt-multi-thread", "sync"] }
async-trait = "0.1.83"
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 @@ -32,6 +32,7 @@ pub use agama_l10n as l10n;
pub use agama_network as network;
pub use agama_software as software;
pub use agama_storage as storage;
pub use agama_users as users;

pub mod test_utils;

Expand Down
33 changes: 32 additions & 1 deletion rust/agama-manager/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

use crate::{bootloader, files, hardware, hostname, l10n, message, network, software, storage};
use crate::{
bootloader, files, hardware, hostname, l10n, message, network, software, storage, users,
};
use agama_utils::{
actor::{self, Actor, Handler, MessageHandler},
api::{
Expand Down Expand Up @@ -83,6 +85,8 @@ pub enum Error {
Hardware(#[from] hardware::Error),
#[error("Cannot dispatch this action in {current} stage (expected {expected}).")]
UnexpectedStage { current: Stage, expected: Stage },
#[error(transparent)]
Users(#[from] users::service::Error),
}

pub struct Starter {
Expand All @@ -99,6 +103,7 @@ pub struct Starter {
issues: Option<Handler<issue::Service>>,
progress: Option<Handler<progress::Service>>,
hardware: Option<hardware::Registry>,
users: Option<Handler<users::Service>>,
}

impl Starter {
Expand All @@ -121,6 +126,7 @@ impl Starter {
issues: None,
progress: None,
hardware: None,
users: None,
}
}

Expand Down Expand Up @@ -172,6 +178,11 @@ impl Starter {
self
}

pub fn with_users(mut self, users: Handler<users::Service>) -> Self {
self.users = Some(users);
self
}

/// Starts the service and returns a handler to communicate with it.
pub async fn start(self) -> Result<Handler<Service>, Error> {
let issues = match self.issues {
Expand Down Expand Up @@ -256,6 +267,15 @@ impl Starter {
None => hardware::Registry::new_from_system(),
};

let users = match self.users {
Some(users) => users,
None => {
users::Service::starter(self.events.clone(), issues.clone())
.start()
.await?
}
};

let mut service = Service {
questions: self.questions,
progress,
Expand All @@ -273,6 +293,7 @@ impl Starter {
config: Config::default(),
system: manager::SystemInfo::default(),
product: None,
users: users,
};

service.setup().await?;
Expand All @@ -297,6 +318,7 @@ pub struct Service {
product: Option<Arc<RwLock<ProductSpec>>>,
config: Config,
system: manager::SystemInfo,
users: Handler<users::Service>,
}

impl Service {
Expand Down Expand Up @@ -370,6 +392,10 @@ impl Service {
.call(l10n::message::SetConfig::new(config.l10n.clone()))
.await?;

self.users
.call(users::message::SetConfig::new(config.users.clone()))
.await?;

self.storage
.call(storage::message::SetConfig::new(
Arc::clone(product),
Expand Down Expand Up @@ -484,6 +510,7 @@ impl MessageHandler<message::GetSystem> for Service {
let storage = self.storage.call(storage::message::GetSystem).await?;
let network = self.network.get_system().await?;
let software = self.software.call(software::message::GetSystem).await?;

Ok(SystemInfo {
hostname,
l10n,
Expand Down Expand Up @@ -512,6 +539,7 @@ impl MessageHandler<message::GetExtendedConfig> for Service {
let questions = self.questions.call(question::message::GetConfig).await?;
let network = self.network.get_config().await?;
let storage = self.storage.call(storage::message::GetConfig).await?;
let users = self.users.call(users::message::GetConfig).await?;

Ok(Config {
bootloader,
Expand All @@ -522,6 +550,7 @@ impl MessageHandler<message::GetExtendedConfig> for Service {
software: Some(software),
storage,
files: None,
users: Some(users),
})
}
}
Expand Down Expand Up @@ -568,13 +597,15 @@ impl MessageHandler<message::GetProposal> for Service {
let software = self.software.call(software::message::GetProposal).await?;
let storage = self.storage.call(storage::message::GetProposal).await?;
let network = self.network.get_proposal().await?;
let users = self.users.call(users::message::GetProposal).await?;

Ok(Some(Proposal {
hostname,
l10n,
network,
software,
storage,
users,
}))
}
}
Expand Down
25 changes: 25 additions & 0 deletions rust/agama-users/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "agama-users"
version = "0.1.0"
rust-version.workspace = true
edition.workspace = true

[dependencies]
anyhow = "1.0.99"
thiserror = "2.0.16"
agama-locale-data = { path = "../agama-locale-data" }
agama-utils = { path = "../agama-utils" }
regex = "1.11.2"
tracing = "0.1.41"
gettext-rs = { version = "0.7.2", features = ["gettext-system"] }
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread", "sync"] }
tokio-stream = "0.1.17"
zbus = "5.11.0"
async-trait = "0.1.89"

[dev-dependencies]
test-context = "0.4.1"
tokio-test = "0.4.4"

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(ci)'] }
32 changes: 32 additions & 0 deletions rust/agama-users/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) [2025] 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 service;
pub use service::{Service, Starter};

pub mod message;

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

#[cfg(test)]
mod tests {
use super::*;
}
59 changes: 59 additions & 0 deletions rust/agama-users/src/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) [2025] 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.

use agama_utils::{
actor::Message,
api::{self},
};

#[derive(Clone)]
pub struct SetSystem<T> {
pub system: Option<T>,
}

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

pub struct GetConfig;

impl Message for GetConfig {
type Reply = api::users::Config;
}

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

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

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

pub struct GetProposal;

impl Message for GetProposal {
type Reply = Option<api::users::Config>;
}
39 changes: 39 additions & 0 deletions rust/agama-users/src/model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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.

use crate::service;

/// Abstract the users-related configuration from the underlying system.
pub trait ModelAdapter: Send + 'static {
/// Apply the changes to target system. It is expected to be called almost
/// at the end of the installation.
fn install(&self) -> Result<(), service::Error> {
Ok(())
}
}

/// [ModelAdapter] implementation for systemd-based systems.
pub struct Model {}

impl ModelAdapter for Model {
fn install(&self) -> Result<(), service::Error> {
Ok(())
}
}
Loading
Loading