Add Rust progress task wrapper

The manual `std::mem::drop()` bits are ugly; while we can do
function pointers from Rust to C++, let's just add the obvious
high level wrapper in Rust that accepts a `FnOnce()`.

Note in one instance we directly pass a function pointer which
is quite clean.
This commit is contained in:
Colin Walters 2021-03-13 14:19:21 +00:00
parent 531907af90
commit 6eb3caf9a9
3 changed files with 34 additions and 21 deletions

View File

@ -433,6 +433,7 @@ mod passwd;
use passwd::*;
mod console_progress;
pub(crate) use self::console_progress::*;
mod progress;
mod scripts;
pub(crate) use self::scripts::*;
mod rpmutils;

View File

@ -9,6 +9,7 @@
use crate::ffi::LiveApplyState;
use crate::isolation;
use crate::progress::progress_task;
use crate::{cxxrsutil::*, variant_utils};
use anyhow::{anyhow, Context, Result};
use fn_error_context::context;
@ -468,34 +469,30 @@ pub(crate) fn transaction_apply_live(
// Gather the current diff of /etc - we need to avoid changing
// any files which are locally modified.
let task = crate::ffi::progress_begin_task("Computing /etc diff to preserve");
let config_diff = {
let config_diff = progress_task("Computing /etc diff to preserve", || -> Result<_> {
let usretc = &rootfs_dfd.sub_dir("usr/etc")?;
let etc = &rootfs_dfd.sub_dir("etc")?;
crate::dirdiff::diff(usretc, etc)?
};
crate::dirdiff::diff(usretc, etc)
})?;
println!("Computed /etc diff: {}", &config_diff);
std::mem::drop(task);
// The heart of things: updating the overlayfs on /usr
let task = crate::ffi::progress_begin_task("Updating /usr");
apply_diff(repo, &diff, &target_commit, &openat::Dir::open("/usr")?)?;
std::mem::drop(task);
progress_task("Updating /usr", || -> Result<_> {
apply_diff(repo, &diff, &target_commit, &openat::Dir::open("/usr")?)
})?;
// The other important bits are /etc and /var
let task = crate::ffi::progress_begin_task("Updating /etc");
update_etc(
repo,
&diff,
&config_diff,
&sepolicy,
&target_commit,
&openat::Dir::open("/etc")?,
)?;
std::mem::drop(task);
let task = crate::ffi::progress_begin_task("Running systemd-tmpfiles for /run and /var");
rerun_tmpfiles()?;
std::mem::drop(task);
progress_task("Updating /etc", || -> Result<_> {
update_etc(
repo,
&diff,
&config_diff,
&sepolicy,
&target_commit,
&openat::Dir::open("/etc")?,
)
})?;
progress_task("Running systemd-tmpfiles for /run and /var", rerun_tmpfiles)?;
// Success! Update the recorded state.
state.commit = target_commit.to_string();

15
rust/src/progress.rs Normal file
View File

@ -0,0 +1,15 @@
//! Rust convenience APIs over our rpmostree-output.h
//! progress/output APIs.
// SPDX-License-Identifier: Apache-2.0 OR MIT
/// Call the provided function, while displaying a "task progress"
/// message.
pub(crate) fn progress_task<F, T>(msg: &str, f: F) -> T
where
F: FnOnce() -> T,
{
// Drop will end the task
let _task = crate::ffi::progress_begin_task(msg);
f()
}