ostree_ext/
sysroot.rs

1//! Helpers for interacting with sysroots.
2
3use std::ops::Deref;
4
5use anyhow::Result;
6
7/// A locked system root.
8#[derive(Debug)]
9pub struct SysrootLock {
10    /// The underlying sysroot value.
11    pub sysroot: ostree::Sysroot,
12    /// True if we didn't actually lock
13    unowned: bool,
14}
15
16impl Drop for SysrootLock {
17    fn drop(&mut self) {
18        if self.unowned {
19            return;
20        }
21        self.sysroot.unlock();
22    }
23}
24
25impl Deref for SysrootLock {
26    type Target = ostree::Sysroot;
27
28    fn deref(&self) -> &Self::Target {
29        &self.sysroot
30    }
31}
32
33impl SysrootLock {
34    /// Asynchronously acquire a sysroot lock.  If the lock cannot be acquired
35    /// immediately, a status message will be printed to standard output.
36    /// The lock will be unlocked when this object is dropped.
37    pub async fn new_from_sysroot(sysroot: &ostree::Sysroot) -> Result<Self> {
38        let mut printed = false;
39        loop {
40            if sysroot.try_lock()? {
41                return Ok(Self {
42                    sysroot: sysroot.clone(),
43                    unowned: false,
44                });
45            }
46            if !printed {
47                println!("Waiting for sysroot lock...");
48                printed = true;
49            }
50            tokio::time::sleep(std::time::Duration::from_secs(3)).await;
51        }
52    }
53
54    /// This function should only be used when you have locked the sysroot
55    /// externally (e.g. in C/C++ code).  This also does not unlock on drop.
56    pub fn from_assumed_locked(sysroot: &ostree::Sysroot) -> Self {
57        Self {
58            sysroot: sysroot.clone(),
59            unowned: true,
60        }
61    }
62}