Skip to content

Commit

Permalink
deploy: Add a spinner
Browse files Browse the repository at this point in the history
First, this operation was absolutely not asynchronous
and we need to spawn it in a helper thread on general
principle. Doing that is unfortunately VERY hacky
because we need to clone a lot of things and especially
there's an ergonomics hit here since `Deployment` is
incorrectly `!Send`.

But the main motivation is this operation can be slow sometimes,
so let's show progress output so the admin knows we're not blocked.

Closes: containers#842
Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Oct 27, 2024
1 parent 7f64565 commit 3638b41
Showing 1 changed file with 45 additions and 22 deletions.
67 changes: 45 additions & 22 deletions lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ use ostree_ext::oci_spec::image::{Descriptor, Digest};
use ostree_ext::ostree::Deployment;
use ostree_ext::ostree::{self, Sysroot};
use ostree_ext::sysroot::SysrootLock;
use ostree_ext::tokio_util::spawn_blocking_cancellable_flatten;

use crate::spec::ImageReference;
use crate::spec::{BootOrder, HostSpec};
use crate::status::labels_of_config;
use crate::store::Storage;
use crate::utils::async_task_with_spinner;

// TODO use https://github.com/ostreedev/ostree-rs-ext/pull/493/commits/afc1837ff383681b947de30c0cefc70080a4f87a
const BASE_IMAGE_PREFIX: &str = "ostree/container/baseimage/bootc";
Expand Down Expand Up @@ -375,8 +377,6 @@ async fn deploy(
image: &ImageState,
origin: &glib::KeyFile,
) -> Result<Deployment> {
let stateroot = Some(stateroot);
let mut opts = ostree::SysrootDeployTreeOpts::default();
// Compute the kernel argument overrides. In practice today this API is always expecting
// a merge deployment. The kargs code also always looks at the booted root (which
// is a distinct minor issue, but not super important as right now the install path
Expand All @@ -386,26 +386,49 @@ async fn deploy(
} else {
None
};
// Because the C API expects a Vec<&str>, we need to generate a new Vec<>
// that borrows.
let override_kargs = override_kargs
.as_deref()
.map(|v| v.iter().map(|s| s.as_str()).collect::<Vec<_>>());
if let Some(kargs) = override_kargs.as_deref() {
opts.override_kernel_argv = Some(&kargs);
}
// Copy to move into thread
let cancellable = gio::Cancellable::NONE;
return sysroot
.stage_tree_with_options(
stateroot,
image.ostree_commit.as_str(),
Some(origin),
merge_deployment,
&opts,
cancellable,
)
.map_err(Into::into);
// Clone all the things to move to worker thread
let sysroot_clone = sysroot.sysroot.clone();
// ostree::Deployment is incorrently !Send 😢 so convert it to an integer
let merge_deployment = merge_deployment.map(|d| d.index() as usize);
let stateroot = stateroot.to_string();
let ostree_commit = image.ostree_commit.to_string();
// GKeyFile also isn't Send! So we serialize that as a string...
let origin_data = origin.to_data();
let r = async_task_with_spinner(
"Deploying",
spawn_blocking_cancellable_flatten(move |cancellable| -> Result<_> {
let sysroot = sysroot_clone;
let stateroot = Some(stateroot);
let mut opts = ostree::SysrootDeployTreeOpts::default();

// Because the C API expects a Vec<&str>, we need to generate a new Vec<>
// that borrows.
let override_kargs = override_kargs
.as_deref()
.map(|v| v.iter().map(|s| s.as_str()).collect::<Vec<_>>());
if let Some(kargs) = override_kargs.as_deref() {
opts.override_kernel_argv = Some(&kargs);
}
let deployments = sysroot.deployments();
let merge_deployment = merge_deployment.map(|m| &deployments[m]);
let origin = glib::KeyFile::new();
origin.load_from_data(&origin_data, glib::KeyFileFlags::NONE)?;
let d = sysroot.stage_tree_with_options(
stateroot.as_deref(),
&ostree_commit,
Some(&origin),
merge_deployment,
&opts,
Some(cancellable),
)?;
Ok(d.index())
}),
)
.await?;
// SAFETY: We must have a staged deployment
let staged = sysroot.staged_deployment().unwrap();
assert_eq!(staged.index(), r);
Ok(staged)
}

#[context("Generating origin")]
Expand Down

0 comments on commit 3638b41

Please sign in to comment.