(
opts: SwitchOpts,
storage: &Storage,
booted_ostree: &BootedOstree<'_>,
)
| 1380 | /// Implementation of the `bootc switch` CLI command for ostree backend. |
| 1381 | #[context("Switching (ostree)")] |
| 1382 | async fn switch_ostree( |
| 1383 | opts: SwitchOpts, |
| 1384 | storage: &Storage, |
| 1385 | booted_ostree: &BootedOstree<'_>, |
| 1386 | ) -> Result<()> { |
| 1387 | let target = imgref_for_switch(&opts)?; |
| 1388 | let prog: ProgressWriter = opts.progress.try_into()?; |
| 1389 | let cancellable = gio::Cancellable::NONE; |
| 1390 | |
| 1391 | let repo = &booted_ostree.repo(); |
| 1392 | let (_, host) = crate::status::get_status(booted_ostree)?; |
| 1393 | |
| 1394 | let new_spec = { |
| 1395 | let mut new_spec = host.spec.clone(); |
| 1396 | new_spec.image = Some(target.clone()); |
| 1397 | new_spec |
| 1398 | }; |
| 1399 | |
| 1400 | if new_spec == host.spec { |
| 1401 | println!("Image specification is unchanged."); |
| 1402 | if opts.apply && host.status.staged.is_some() { |
| 1403 | crate::reboot::reboot()?; |
| 1404 | } |
| 1405 | return Ok(()); |
| 1406 | } |
| 1407 | |
| 1408 | // Log the switch operation to systemd journal |
| 1409 | const SWITCH_JOURNAL_ID: &str = "7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1"; |
| 1410 | let old_image = host |
| 1411 | .spec |
| 1412 | .image |
| 1413 | .as_ref() |
| 1414 | .map(|i| i.image.as_str()) |
| 1415 | .unwrap_or("none"); |
| 1416 | |
| 1417 | tracing::info!( |
| 1418 | message_id = SWITCH_JOURNAL_ID, |
| 1419 | bootc.old_image_reference = old_image, |
| 1420 | bootc.new_image_reference = &target.image, |
| 1421 | bootc.new_image_transport = &target.transport, |
| 1422 | "Switching from image {} to {}", |
| 1423 | old_image, |
| 1424 | target.image |
| 1425 | ); |
| 1426 | |
| 1427 | let new_spec = RequiredHostSpec::from_spec(&new_spec)?; |
| 1428 | |
| 1429 | // Determine whether to use unified storage path. |
| 1430 | // If explicitly requested via flag, use unified storage directly. |
| 1431 | // Otherwise, auto-detect based on whether the image exists in bootc storage. |
| 1432 | let use_unified = if opts.unified_storage_exp { |
| 1433 | true |
| 1434 | } else { |
| 1435 | crate::deploy::image_exists_in_unified_storage(storage, &target).await? |
| 1436 | }; |
| 1437 | |
| 1438 | let fetched = if use_unified { |
| 1439 | crate::deploy::pull_unified( |
no test coverage detected