Skip to content

Commit 103ec81

Browse files
authored
Drop unmaintained users dependency (#13)
* Add CI and github config Mostly copied from operator-rs. Would be nice to have this managed by operator-templating, but that depends on stackabletech/operator-templating#80. * Import pre-commit and cargo deny config as well * pre-commit * Drop unmaintained users dependency It's unmaintained, has open vulnerabilities, and is redundant with sysinfo which we already use. * Update cargo-deny to v2.0.4 * Update dependencies * Update deny.toml from op-rs
1 parent 24c805d commit 103ec81

File tree

7 files changed

+107
-32
lines changed

7 files changed

+107
-32
lines changed

Cargo.lock

Lines changed: 2 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ hickory-resolver = "0.24.1"
1010
local-ip-address = "0.6.3"
1111
serde = { version = "1.0.210", features = ["derive"] }
1212
serde_json = "1.0.128"
13+
snafu = "0.8.5"
1314
stackable-operator = { git = "https://github.com/stackabletech/operator-rs", tag = "stackable-operator-0.83.0" }
14-
sysinfo = "0.32.0"
15+
sysinfo = { version = "0.32.0", features = ["serde"] }
1516
tracing = "0.1.40"
16-
users = "0.11.0"
1717

1818
[build-dependencies]
1919
built = { version = "0.7", features = ["chrono", "git2"] }

src/error.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use serde::Serialize;
2+
use snafu::Snafu;
3+
4+
/// Wrapped version of the errors returned by [`sysinfo`], since they are bare [`str`]s.
5+
#[derive(Debug, Snafu)]
6+
#[snafu(display("{msg}"))]
7+
pub struct SysinfoError {
8+
pub msg: &'static str,
9+
}
10+
11+
/// Wraps errors returned by a component to present them consistently for serialization.
12+
#[derive(Debug, Serialize)]
13+
#[serde(untagged)]
14+
pub enum ComponentResult<T> {
15+
Ok(T),
16+
Err {
17+
#[serde(rename = "$error")]
18+
inner: ComponentError,
19+
},
20+
}
21+
impl<T> ComponentResult<T> {
22+
#[track_caller]
23+
pub fn report_from_result<E: std::error::Error + 'static>(
24+
component: &str,
25+
result: Result<T, E>,
26+
) -> ComponentResult<T> {
27+
match result {
28+
Ok(x) => ComponentResult::Ok(x),
29+
Err(err) => {
30+
tracing::error!(
31+
error = &err as &dyn std::error::Error,
32+
"error reported by {component}, ignoring...",
33+
);
34+
err.source();
35+
ComponentResult::Err {
36+
inner: ComponentError {
37+
message: err.to_string(),
38+
causes: std::iter::successors(err.source(), |err| err.source())
39+
.map(|err| err.to_string())
40+
.collect(),
41+
},
42+
}
43+
}
44+
}
45+
}
46+
}
47+
#[derive(Debug, Serialize)]
48+
pub struct ComponentError {
49+
message: String,
50+
causes: Vec<String>,
51+
}

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod error;
12
mod system_information;
23

34
use clap::{crate_description, crate_version, Parser};

src/system_information/mod.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use serde::Serialize;
22

3+
use crate::error::ComponentResult;
4+
35
pub mod disk;
46
pub mod network;
57
pub mod os;
@@ -10,7 +12,7 @@ pub mod user;
1012
pub struct SystemInformation {
1113
pub resources: resources::Resources,
1214
pub os: os::OperatingSystem,
13-
pub current_user: user::User,
15+
pub current_user: ComponentResult<user::User>,
1416
pub disks: Vec<disk::Disk>,
1517
pub network: network::SystemNetworkInfo,
1618
// TODO:
@@ -34,10 +36,19 @@ impl SystemInformation {
3436
#[tracing::instrument(name = "SystemInformation::collect")]
3537
pub fn collect() -> Self {
3638
tracing::info!("Starting data collection");
39+
40+
// Please note that we use "new_all" to ensure that all list of
41+
// components, network interfaces, disks and users are already
42+
// filled!
43+
let sys = sysinfo::System::new_all();
44+
3745
let info = Self {
38-
resources: resources::Resources::collect(),
46+
resources: resources::Resources::collect(&sys),
3947
os: os::OperatingSystem::collect(),
40-
current_user: user::User::collect_current(),
48+
current_user: ComponentResult::report_from_result(
49+
"User::collect_current",
50+
user::User::collect_current(&sys),
51+
),
4152
disks: disk::Disk::collect_all(),
4253
network: network::SystemNetworkInfo::collect(),
4354
};

src/system_information/resources.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,11 @@ pub struct Resources {
2121
}
2222

2323
impl Resources {
24-
#[tracing::instrument(name = "Resources::collect")]
25-
pub fn collect() -> Self {
24+
#[tracing::instrument(name = "Resources::collect", skip(sys))]
25+
pub fn collect(sys: &System) -> Self {
2626
// This style of "declare-then-log-then-merge becomes a bit verbose,
2727
// but should help keep each log statement local to where that info is collected.
2828

29-
// Please note that we use "new_all" to ensure that all list of
30-
// components, network interfaces, disks and users are already
31-
// filled!
32-
let sys = System::new_all();
33-
3429
let cpu_count = sys.cpus().len();
3530
let physical_core_count = sys.physical_core_count();
3631
tracing::info!(

src/system_information/user.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,47 @@
11
use serde::Serialize;
2+
use snafu::{OptionExt, ResultExt, Snafu};
3+
use sysinfo::{Gid, Pid, Uid};
4+
5+
use crate::error::SysinfoError;
6+
7+
#[derive(Debug, Snafu)]
8+
pub enum Error {
9+
#[snafu(display("failed to get pid of the current process"))]
10+
GetCurrentPid { source: SysinfoError },
11+
#[snafu(display("current pid {pid} could not be resolved to a proess"))]
12+
ResolveCurrentProcess { pid: Pid },
13+
}
14+
type Result<T, E = Error> = std::result::Result<T, E>;
215

316
#[derive(Debug, Serialize)]
417
pub struct User {
518
pub name: Option<String>, // The name of the current user
6-
pub uid: u32, // The user ID (UID)
7-
pub gid: u32, // The group ID (GID)
19+
pub uid: Option<Uid>, // The user ID (UID)
20+
pub gid: Option<Gid>, // The group ID (GID)
821
}
922

1023
impl User {
11-
pub fn collect_current() -> Self {
12-
let uid = users::get_current_uid();
24+
#[tracing::instrument(name = "User::collect_current", skip(sys))]
25+
pub fn collect_current(sys: &sysinfo::System) -> Result<Self> {
26+
let pid = sysinfo::get_current_pid()
27+
.map_err(|msg| SysinfoError { msg })
28+
.context(GetCurrentPidSnafu)?;
29+
let current_process = sys
30+
.process(pid)
31+
.context(ResolveCurrentProcessSnafu { pid })?;
32+
let uid = current_process.user_id();
33+
let os_users = sysinfo::Users::new_with_refreshed_list();
1334
let user = Self {
14-
name: users::get_user_by_uid(uid).map(|user| user.name().to_string_lossy().to_string()),
15-
uid,
16-
gid: users::get_current_gid(),
35+
name: uid.and_then(|uid| Some(os_users.get_user_by_id(uid)?.name().to_string())),
36+
uid: uid.cloned(),
37+
gid: current_process.group_id(),
1738
};
18-
tracing::info!(user.name, user.uid, user.gid, "current user");
19-
user
39+
tracing::info!(
40+
user.name,
41+
user.uid = user.uid.as_ref().map(|uid| format!("{uid:?}")),
42+
user.gid = user.uid.as_ref().map(|gid| format!("{gid:?}")),
43+
"current user"
44+
);
45+
Ok(user)
2046
}
2147
}

0 commit comments

Comments
 (0)