Core entrypoint for completion of an ostree-based install to a bootc one: - kernel argument handling - logically bound images We could also do other things here, such as write an aleph file or ensure the repo config is synchronized, but these two are the most important for now.
(
rootfs: &Dir,
sysroot: &ostree::Sysroot,
stateroot: Option<&str>,
)
| 272 | /// ensure the repo config is synchronized, but these two are the most important |
| 273 | /// for now. |
| 274 | pub(crate) async fn impl_completion( |
| 275 | rootfs: &Dir, |
| 276 | sysroot: &ostree::Sysroot, |
| 277 | stateroot: Option<&str>, |
| 278 | ) -> Result<()> { |
| 279 | // Log the completion operation to systemd journal |
| 280 | const COMPLETION_JOURNAL_ID: &str = "0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4"; |
| 281 | tracing::info!( |
| 282 | message_id = COMPLETION_JOURNAL_ID, |
| 283 | bootc.stateroot = stateroot.unwrap_or("default"), |
| 284 | "Starting bootc installation completion" |
| 285 | ); |
| 286 | |
| 287 | let deployment = &sysroot |
| 288 | .merge_deployment(stateroot) |
| 289 | .ok_or_else(|| anyhow::anyhow!("Failed to find deployment (stateroot={stateroot:?})"))?; |
| 290 | let sysroot_dir = crate::utils::sysroot_dir(&sysroot)?; |
| 291 | |
| 292 | // Create a subdir in /run |
| 293 | let rundir = "run/bootc-install"; |
| 294 | rootfs.create_dir_all(rundir)?; |
| 295 | let rundir = &rootfs.open_dir(rundir)?; |
| 296 | |
| 297 | // ostree-ext doesn't do kargs, so handle that now |
| 298 | reconcile_kargs(&sysroot, deployment)?; |
| 299 | |
| 300 | // ostree-ext doesn't do logically bound images |
| 301 | let bound_images = crate::boundimage::query_bound_images_for_deployment(sysroot, deployment)?; |
| 302 | |
| 303 | if !bound_images.is_empty() { |
| 304 | // Log bound images found |
| 305 | tracing::info!( |
| 306 | message_id = COMPLETION_JOURNAL_ID, |
| 307 | bootc.bound_images_count = bound_images.len(), |
| 308 | "Found {} bound images for completion", |
| 309 | bound_images.len() |
| 310 | ); |
| 311 | |
| 312 | // load the selinux policy from the target ostree deployment |
| 313 | let deployment_fd = deployment_fd(sysroot, deployment)?; |
| 314 | let sepolicy = crate::lsm::new_sepolicy_at(deployment_fd)?; |
| 315 | |
| 316 | // When we're run through ostree, we only lazily initialize the podman storage to avoid |
| 317 | // having a hard dependency on it. |
| 318 | let imgstorage = CStorage::create(&sysroot_dir, &rundir, sepolicy.as_ref())?; |
| 319 | crate::boundimage::pull_images_impl(&imgstorage, bound_images) |
| 320 | .await |
| 321 | .context("pulling bound images")?; |
| 322 | // Ensure the image storage is SELinux-labeled after all pulls are complete. |
| 323 | imgstorage.ensure_labeled()?; |
| 324 | } |
| 325 | |
| 326 | // Log completion success |
| 327 | tracing::info!( |
| 328 | message_id = COMPLETION_JOURNAL_ID, |
| 329 | bootc.stateroot = stateroot.unwrap_or("default"), |
| 330 | "Successfully completed bootc installation" |
| 331 | ); |
no test coverage detected