Skip to content

Commit

Permalink
Merge pull request #21 from mkuehlke/add-limit-option
Browse files Browse the repository at this point in the history
Add option to limit view to certain units
  • Loading branch information
rgwood authored May 25, 2024
2 parents 1ae829e + 23900c2 commit 56742c4
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 14 deletions.
9 changes: 5 additions & 4 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ use crate::{
pub struct App {
pub scope: Scope,
pub home: Arc<Mutex<Home>>,
pub limit_units: Vec<String>,
pub should_quit: bool,
pub should_suspend: bool,
}

impl App {
pub fn new(scope: Scope) -> Result<Self> {
let home = Home::new(scope);
pub fn new(scope: Scope, limit_units: Vec<String>) -> Result<Self> {
let home = Home::new(scope, &limit_units);
let home = Arc::new(Mutex::new(home));
Ok(Self { scope, home, should_quit: false, should_suspend: false })
Ok(Self { scope, home, limit_units, should_quit: false, should_suspend: false })
}

pub async fn run(&mut self) -> Result<()> {
Expand Down Expand Up @@ -57,7 +58,7 @@ impl App {

self.home.lock().await.init(action_tx.clone())?;

let units = get_all_services(self.scope)
let units = get_all_services(self.scope, &self.limit_units)
.await
.context("Unable to get services. Check that systemd is running and try running this tool with sudo.")?;
self.home.lock().await.set_units(units);
Expand Down
9 changes: 6 additions & 3 deletions src/components/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub enum Mode {
#[derive(Default)]
pub struct Home {
pub scope: Scope,
pub limit_units: Vec<String>,
pub logger: Logger,
pub show_logger: bool,
pub all_units: IndexMap<UnitId, UnitWithStatus>,
Expand Down Expand Up @@ -145,8 +146,9 @@ impl<T> StatefulList<T> {
}

impl Home {
pub fn new(scope: Scope) -> Self {
Self { scope, ..Default::default() }
pub fn new(scope: Scope, limit_units: &[String]) -> Self {
let limit_units = limit_units.to_vec();
Self { scope, limit_units, ..Default::default() }
}

pub fn set_units(&mut self, units: Vec<UnitWithStatus>) {
Expand Down Expand Up @@ -649,8 +651,9 @@ impl Component for Home {
Action::RefreshServices => {
let tx = self.action_tx.clone().unwrap();
let scope = self.scope;
let limit_units = self.limit_units.to_vec();
tokio::spawn(async move {
let units = systemd::get_all_services(scope)
let units = systemd::get_all_services(scope, &limit_units)
.await
.expect("Failed to get services. Check that systemd is running and try running this tool with sudo.");
tx.send(Action::SetServices(units)).unwrap();
Expand Down
5 changes: 4 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ struct Args {
/// Enable performance tracing (in Chromium Event JSON format)
#[clap(short, long)]
trace: bool,
/// Limit view to only these unit files
#[clap(short, long, default_value="*.service", num_args=1..)]
limit_units: Vec<String>,
}

#[derive(Parser, Debug, ValueEnum, Clone)]
Expand Down Expand Up @@ -52,7 +55,7 @@ async fn main() -> Result<()> {
},
};

let mut app = App::new(scope)?;
let mut app = App::new(scope, args.limit_units)?;
app.run().await?;

Ok(())
Expand Down
13 changes: 7 additions & 6 deletions src/systemd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub enum Scope {
}

// this takes like 5-10 ms on 13th gen Intel i7 (scope=all)
pub async fn get_all_services(scope: Scope) -> Result<Vec<UnitWithStatus>> {
pub async fn get_all_services(scope: Scope, services: &[String]) -> Result<Vec<UnitWithStatus>> {
let start = std::time::Instant::now();

let mut units = vec![];
Expand All @@ -106,15 +106,16 @@ pub async fn get_all_services(scope: Scope) -> Result<Vec<UnitWithStatus>> {

match scope {
Scope::Global => {
let system_units = get_services(UnitScope::Global).await?;
let system_units = get_services(UnitScope::Global, services).await?;
units.extend(system_units);
},
Scope::User => {
let user_units = get_services(UnitScope::User).await?;
let user_units = get_services(UnitScope::User, services).await?;
units.extend(user_units);
},
Scope::All => {
let (system_units, user_units) = tokio::join!(get_services(UnitScope::Global), get_services(UnitScope::User));
let (system_units, user_units) =
tokio::join!(get_services(UnitScope::Global, services), get_services(UnitScope::User, services));
units.extend(system_units?);

// Should always be able to get user units, but it may fail when running as root
Expand All @@ -136,10 +137,10 @@ pub async fn get_all_services(scope: Scope) -> Result<Vec<UnitWithStatus>> {
Ok(units)
}

async fn get_services(scope: UnitScope) -> Result<Vec<UnitWithStatus>, anyhow::Error> {
async fn get_services(scope: UnitScope, services: &[String]) -> Result<Vec<UnitWithStatus>, anyhow::Error> {
let connection = get_connection(scope).await?;
let manager_proxy = ManagerProxy::new(&connection).await?;
let units = manager_proxy.list_units_by_patterns(vec![], vec!["*.service".into()]).await?;
let units = manager_proxy.list_units_by_patterns(vec![], services.to_vec()).await?;
let units: Vec<_> = units.into_iter().map(|u| to_unit_status(u, scope)).collect();
Ok(units)
}
Expand Down

0 comments on commit 56742c4

Please sign in to comment.