1
0
mirror of https://github.com/containers/bootc.git synced 2026-02-06 00:45:22 +01:00

Merge pull request #1536 from cgwalters/ostree-lock-spinner-async

ostree: Use indicatif + async for lock wait
This commit is contained in:
John Eckersberg
2025-08-20 14:08:40 -04:00
committed by GitHub
2 changed files with 40 additions and 13 deletions

View File

@@ -4,6 +4,8 @@ use std::ops::Deref;
use anyhow::Result;
use crate::utils::async_task_with_spinner;
/// A locked system root.
#[derive(Debug)]
pub struct SysrootLock {
@@ -35,20 +37,17 @@ impl SysrootLock {
/// immediately, a status message will be printed to standard output.
/// The lock will be unlocked when this object is dropped.
pub async fn new_from_sysroot(sysroot: &ostree::Sysroot) -> Result<Self> {
let mut printed = false;
loop {
if sysroot.try_lock()? {
return Ok(Self {
sysroot: sysroot.clone(),
unowned: false,
});
}
if !printed {
eprintln!("Waiting for sysroot lock...");
printed = true;
}
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
if sysroot.try_lock()? {
return Ok(Self {
sysroot: sysroot.clone(),
unowned: false,
});
}
async_task_with_spinner("Waiting for sysroot lock...", sysroot.lock_future()).await?;
Ok(Self {
sysroot: sysroot.clone(),
unowned: false,
})
}
/// This function should only be used when you have locked the sysroot

View File

@@ -1 +1,29 @@
use std::{future::Future, time::Duration};
/// Call an async task function, and write a message to stdout
/// with an automatic spinner to show that we're not blocked.
/// Note that generally the called function should not output
/// anything to stdout as this will interfere with the spinner.
pub(crate) async fn async_task_with_spinner<F, T>(msg: &str, f: F) -> T
where
F: Future<Output = T>,
{
let pb = indicatif::ProgressBar::new_spinner();
let style = indicatif::ProgressStyle::default_bar();
pb.set_style(style.template("{spinner} {msg}").unwrap());
pb.set_message(msg.to_string());
pb.enable_steady_tick(Duration::from_millis(150));
let r = f.await;
pb.finish_and_clear();
r
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_spinner() {
async_task_with_spinner("Testing...", tokio::time::sleep(Duration::from_secs(5))).await
}
}