Skip to content

Commit 147f16c

Browse files
Merge pull request bootc-dev#1525 from cgwalters/store-no-deref
Some more refactoring of storage
2 parents f345357 + a99294f commit 147f16c

File tree

12 files changed

+143
-108
lines changed

12 files changed

+143
-108
lines changed

crates/lib/src/bootc_kargs.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ pub(crate) fn get_kargs(
116116
fetched: &ImageState,
117117
) -> Result<Vec<String>> {
118118
let cancellable = gio::Cancellable::NONE;
119-
let repo = &sysroot.repo();
119+
let ostree = sysroot.get_ostree()?;
120+
let repo = &ostree.repo();
120121
let mut kargs = vec![];
121122
let sys_arch = std::env::consts::ARCH;
122123

@@ -129,7 +130,7 @@ pub(crate) fn get_kargs(
129130
};
130131

131132
// Get the kargs in kargs.d of the merge
132-
let merge_root = &crate::utils::deployment_fd(sysroot, merge_deployment)?;
133+
let merge_root = &crate::utils::deployment_fd(ostree, merge_deployment)?;
133134
let existing_kargs = get_kargs_in_root(merge_root, sys_arch)?;
134135

135136
// Get the kargs in kargs.d of the pending image

crates/lib/src/boundimage.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use fn_error_context::context;
1313
use ostree_ext::containers_image_proxy;
1414
use ostree_ext::ostree::Deployment;
1515

16-
use crate::imgstorage::PullMode;
16+
use crate::podstorage::{CStorage, PullMode};
1717
use crate::store::Storage;
1818

1919
/// The path in a root for bound images; this directory should only contain
@@ -39,7 +39,7 @@ pub(crate) struct ResolvedBoundImage {
3939

4040
/// Given a deployment, pull all container images it references.
4141
pub(crate) async fn pull_bound_images(sysroot: &Storage, deployment: &Deployment) -> Result<()> {
42-
let bound_images = query_bound_images_for_deployment(sysroot, deployment)?;
42+
let bound_images = query_bound_images_for_deployment(sysroot.get_ostree()?, deployment)?;
4343
pull_images(sysroot, bound_images).await
4444
}
4545

@@ -158,7 +158,7 @@ pub(crate) async fn pull_images(
158158

159159
#[context("Pulling bound images")]
160160
pub(crate) async fn pull_images_impl(
161-
imgstore: &crate::imgstorage::Storage,
161+
imgstore: &CStorage,
162162
bound_images: Vec<crate::boundimage::BoundImage>,
163163
) -> Result<()> {
164164
let n = bound_images.len();

crates/lib/src/cli.rs

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use ostree_ext::container as ostree_container;
2424
use ostree_ext::container_utils::ostree_booted;
2525
use ostree_ext::keyfileext::KeyFileExt;
2626
use ostree_ext::ostree;
27+
use ostree_ext::sysroot::SysrootLock;
2728
use schemars::schema_for;
2829
use serde::{Deserialize, Serialize};
2930

@@ -778,13 +779,9 @@ fn has_soft_reboot_capability(deployment: Option<&crate::spec::BootEntry>) -> bo
778779

779780
/// Prepare a soft reboot for the given deployment
780781
#[context("Preparing soft reboot")]
781-
fn prepare_soft_reboot(
782-
sysroot: &crate::store::Storage,
783-
deployment: &ostree::Deployment,
784-
) -> Result<()> {
782+
fn prepare_soft_reboot(sysroot: &SysrootLock, deployment: &ostree::Deployment) -> Result<()> {
785783
let cancellable = ostree::gio::Cancellable::NONE;
786784
sysroot
787-
.sysroot
788785
.deployment_set_soft_reboot(deployment, false, cancellable)
789786
.context("Failed to prepare soft-reboot")?;
790787
Ok(())
@@ -829,7 +826,7 @@ where
829826
/// Handle soft reboot for staged deployments (used by upgrade and switch)
830827
#[context("Handling staged soft reboot")]
831828
fn handle_staged_soft_reboot(
832-
sysroot: &crate::store::Storage,
829+
sysroot: &SysrootLock,
833830
soft_reboot_mode: Option<SoftRebootMode>,
834831
host: &crate::spec::Host,
835832
) -> Result<()> {
@@ -843,7 +840,7 @@ fn handle_staged_soft_reboot(
843840

844841
/// Perform a soft reboot for a staged deployment
845842
#[context("Soft reboot staged deployment")]
846-
fn soft_reboot_staged(sysroot: &crate::store::Storage) -> Result<()> {
843+
fn soft_reboot_staged(sysroot: &SysrootLock) -> Result<()> {
847844
println!("Staged deployment is soft-reboot capable, preparing for soft-reboot...");
848845

849846
let deployments_list = sysroot.deployments();
@@ -858,7 +855,7 @@ fn soft_reboot_staged(sysroot: &crate::store::Storage) -> Result<()> {
858855

859856
/// Perform a soft reboot for a rollback deployment
860857
#[context("Soft reboot rollback deployment")]
861-
fn soft_reboot_rollback(sysroot: &crate::store::Storage) -> Result<()> {
858+
fn soft_reboot_rollback(sysroot: &SysrootLock) -> Result<()> {
862859
println!("Rollback deployment is soft-reboot capable, preparing for soft-reboot...");
863860

864861
let deployments_list = sysroot.deployments();
@@ -910,9 +907,9 @@ fn prepare_for_write() -> Result<()> {
910907
#[context("Upgrading")]
911908
async fn upgrade(opts: UpgradeOpts) -> Result<()> {
912909
let sysroot = &get_storage().await?;
913-
let repo = &sysroot.repo();
914-
let (booted_deployment, _deployments, host) =
915-
crate::status::get_status_require_booted(sysroot)?;
910+
let ostree = sysroot.get_ostree()?;
911+
let repo = &ostree.repo();
912+
let (booted_deployment, _deployments, host) = crate::status::get_status_require_booted(ostree)?;
916913
let imgref = host.spec.image.as_ref();
917914
let prog: ProgressWriter = opts.progress.try_into()?;
918915

@@ -988,7 +985,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
988985
.unwrap_or_default();
989986
if staged_unchanged {
990987
println!("Staged update present, not changed.");
991-
handle_staged_soft_reboot(sysroot, opts.soft_reboot, &host)?;
988+
handle_staged_soft_reboot(ostree, opts.soft_reboot, &host)?;
992989
if opts.apply {
993990
crate::reboot::reboot()?;
994991
}
@@ -1013,8 +1010,8 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
10131010
if opts.soft_reboot.is_some() {
10141011
// At this point we have new staged deployment and the host definition has changed.
10151012
// We need the updated host status before we check if we can prepare the soft-reboot.
1016-
let updated_host = crate::status::get_status(sysroot, Some(&booted_deployment))?.1;
1017-
handle_staged_soft_reboot(sysroot, opts.soft_reboot, &updated_host)?;
1013+
let updated_host = crate::status::get_status(ostree, Some(&booted_deployment))?.1;
1014+
handle_staged_soft_reboot(ostree, opts.soft_reboot, &updated_host)?;
10181015
}
10191016

10201017
if opts.apply {
@@ -1058,9 +1055,9 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
10581055
let cancellable = gio::Cancellable::NONE;
10591056

10601057
let sysroot = &get_storage().await?;
1061-
let repo = &sysroot.repo();
1062-
let (booted_deployment, _deployments, host) =
1063-
crate::status::get_status_require_booted(sysroot)?;
1058+
let ostree = sysroot.get_ostree()?;
1059+
let repo = &ostree.repo();
1060+
let (booted_deployment, _deployments, host) = crate::status::get_status_require_booted(ostree)?;
10641061

10651062
let new_spec = {
10661063
let mut new_spec = host.spec.clone();
@@ -1095,8 +1092,8 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
10951092
if opts.soft_reboot.is_some() {
10961093
// At this point we have staged the deployment and the host definition has changed.
10971094
// We need the updated host status before we check if we can prepare the soft-reboot.
1098-
let updated_host = crate::status::get_status(sysroot, Some(&booted_deployment))?.1;
1099-
handle_staged_soft_reboot(sysroot, opts.soft_reboot, &updated_host)?;
1095+
let updated_host = crate::status::get_status(ostree, Some(&booted_deployment))?.1;
1096+
handle_staged_soft_reboot(ostree, opts.soft_reboot, &updated_host)?;
11001097
}
11011098

11021099
if opts.apply {
@@ -1110,17 +1107,18 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
11101107
#[context("Rollback")]
11111108
async fn rollback(opts: RollbackOpts) -> Result<()> {
11121109
let sysroot = &get_storage().await?;
1110+
let ostree = sysroot.get_ostree()?;
11131111
crate::deploy::rollback(sysroot).await?;
11141112

11151113
if opts.soft_reboot.is_some() {
11161114
// Get status of rollback deployment to check soft-reboot capability
1117-
let host = crate::status::get_status_require_booted(sysroot)?.2;
1115+
let host = crate::status::get_status_require_booted(ostree)?.2;
11181116

11191117
handle_soft_reboot(
11201118
opts.soft_reboot,
11211119
host.status.rollback.as_ref(),
11221120
"rollback",
1123-
|| soft_reboot_rollback(sysroot),
1121+
|| soft_reboot_rollback(ostree),
11241122
)?;
11251123
}
11261124

@@ -1135,10 +1133,10 @@ async fn rollback(opts: RollbackOpts) -> Result<()> {
11351133
#[context("Editing spec")]
11361134
async fn edit(opts: EditOpts) -> Result<()> {
11371135
let sysroot = &get_storage().await?;
1138-
let repo = &sysroot.repo();
1136+
let ostree = sysroot.get_ostree()?;
1137+
let repo = &ostree.repo();
11391138

1140-
let (booted_deployment, _deployments, host) =
1141-
crate::status::get_status_require_booted(sysroot)?;
1139+
let (booted_deployment, _deployments, host) = crate::status::get_status_require_booted(ostree)?;
11421140
let new_host: Host = if let Some(filename) = opts.filename {
11431141
let mut r = std::io::BufReader::new(std::fs::File::open(filename)?);
11441142
serde_yaml::from_reader(&mut r)?

crates/lib/src/deploy.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,11 @@ async fn handle_layer_progress_print(
304304
/// Gather all bound images in all deployments, then prune the image store,
305305
/// using the gathered images as the roots (that will not be GC'd).
306306
pub(crate) async fn prune_container_store(sysroot: &Storage) -> Result<()> {
307-
let deployments = sysroot.deployments();
307+
let ostree = sysroot.get_ostree()?;
308+
let deployments = ostree.deployments();
308309
let mut all_bound_images = Vec::new();
309310
for deployment in deployments {
310-
let bound = crate::boundimage::query_bound_images_for_deployment(sysroot, &deployment)?;
311+
let bound = crate::boundimage::query_bound_images_for_deployment(ostree, &deployment)?;
311312
all_bound_images.extend(bound.into_iter());
312313
}
313314
// Convert to a hashset of just the image names
@@ -463,11 +464,11 @@ pub(crate) async fn cleanup(sysroot: &Storage) -> Result<()> {
463464
let bound_prune = prune_container_store(sysroot);
464465

465466
// We create clones (just atomic reference bumps) here to move to the thread.
466-
let repo = sysroot.repo();
467-
let sysroot = sysroot.sysroot.clone();
467+
let ostree = sysroot.get_ostree_cloned()?;
468+
let repo = ostree.repo();
468469
let repo_prune =
469470
ostree_ext::tokio_util::spawn_blocking_cancellable_flatten(move |cancellable| {
470-
let locked_sysroot = &SysrootLock::from_assumed_locked(&sysroot);
471+
let locked_sysroot = &SysrootLock::from_assumed_locked(&ostree);
471472
let cancellable = Some(cancellable);
472473
let repo = &repo;
473474
let txn = repo.auto_transaction(cancellable)?;
@@ -488,7 +489,7 @@ pub(crate) async fn cleanup(sysroot: &Storage) -> Result<()> {
488489

489490
// Then, for each deployment which is derived (e.g. has configmaps) we synthesize
490491
// a base ref to ensure that it's not GC'd.
491-
for (i, deployment) in sysroot.deployments().into_iter().enumerate() {
492+
for (i, deployment) in ostree.deployments().into_iter().enumerate() {
492493
let commit = deployment.csum();
493494
if let Some(base) = get_base_commit(repo, &commit)? {
494495
repo.transaction_set_refspec(&format!("{BASE_IMAGE_PREFIX}/{i}"), Some(&base));
@@ -543,7 +544,7 @@ async fn deploy(
543544
None
544545
};
545546
// Clone all the things to move to worker thread
546-
let sysroot_clone = sysroot.sysroot.clone();
547+
let ostree = sysroot.get_ostree_cloned()?;
547548
// ostree::Deployment is incorrectly !Send 😢 so convert it to an integer
548549
let merge_deployment = merge_deployment.map(|d| d.index() as usize);
549550
let stateroot = stateroot.to_string();
@@ -553,7 +554,7 @@ async fn deploy(
553554
let r = async_task_with_spinner(
554555
"Deploying",
555556
spawn_blocking_cancellable_flatten(move |cancellable| -> Result<_> {
556-
let sysroot = sysroot_clone;
557+
let ostree = ostree;
557558
let stateroot = Some(stateroot);
558559
let mut opts = ostree::SysrootDeployTreeOpts::default();
559560

@@ -565,11 +566,11 @@ async fn deploy(
565566
if let Some(kargs) = override_kargs.as_deref() {
566567
opts.override_kernel_argv = Some(&kargs);
567568
}
568-
let deployments = sysroot.deployments();
569+
let deployments = ostree.deployments();
569570
let merge_deployment = merge_deployment.map(|m| &deployments[m]);
570571
let origin = glib::KeyFile::new();
571572
origin.load_from_data(&origin_data, glib::KeyFileFlags::NONE)?;
572-
let d = sysroot.stage_tree_with_options(
573+
let d = ostree.stage_tree_with_options(
573574
stateroot.as_deref(),
574575
&ostree_commit,
575576
Some(&origin),
@@ -582,7 +583,8 @@ async fn deploy(
582583
)
583584
.await?;
584585
// SAFETY: We must have a staged deployment
585-
let staged = sysroot.staged_deployment().unwrap();
586+
let ostree = sysroot.get_ostree()?;
587+
let staged = ostree.staged_deployment().unwrap();
586588
assert_eq!(staged.index(), r);
587589
Ok(staged)
588590
}
@@ -608,6 +610,7 @@ pub(crate) async fn stage(
608610
spec: &RequiredHostSpec<'_>,
609611
prog: ProgressWriter,
610612
) -> Result<()> {
613+
let ostree = sysroot.get_ostree()?;
611614
let mut subtask = SubTaskStep {
612615
subtask: "merging".into(),
613616
description: "Merging Image".into(),
@@ -629,7 +632,7 @@ pub(crate) async fn stage(
629632
.collect(),
630633
})
631634
.await;
632-
let merge_deployment = sysroot.merge_deployment(Some(stateroot));
635+
let merge_deployment = ostree.merge_deployment(Some(stateroot));
633636

634637
subtask.completed = true;
635638
subtasks.push(subtask.clone());
@@ -740,15 +743,17 @@ pub(crate) async fn stage(
740743
/// Implementation of rollback functionality
741744
pub(crate) async fn rollback(sysroot: &Storage) -> Result<()> {
742745
const ROLLBACK_JOURNAL_ID: &str = "26f3b1eb24464d12aa5e7b544a6b5468";
743-
let repo = &sysroot.repo();
744-
let (booted_deployment, deployments, host) = crate::status::get_status_require_booted(sysroot)?;
746+
let ostree = sysroot.get_ostree()?;
747+
let (booted_deployment, deployments, host) = crate::status::get_status_require_booted(ostree)?;
745748

746749
let new_spec = {
747750
let mut new_spec = host.spec.clone();
748751
new_spec.boot_order = new_spec.boot_order.swap();
749752
new_spec
750753
};
751754

755+
let repo = &ostree.repo();
756+
752757
// Just to be sure
753758
host.spec.verify_transition(&new_spec)?;
754759

@@ -788,7 +793,7 @@ pub(crate) async fn rollback(sysroot: &Storage) -> Result<()> {
788793
.chain(deployments.other)
789794
.collect::<Vec<_>>();
790795
tracing::debug!("Writing new deployments: {new_deployments:?}");
791-
sysroot.write_deployments(&new_deployments, gio::Cancellable::NONE)?;
796+
ostree.write_deployments(&new_deployments, gio::Cancellable::NONE)?;
792797
if reverting {
793798
println!("Next boot: current deployment");
794799
} else {

crates/lib/src/fsck.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ static CHECK_RESOLVCONF: FsckCheck =
106106
/// But at the current time fsck is an experimental feature that we should only be running
107107
/// in our CI.
108108
fn check_resolvconf(storage: &Storage) -> FsckResult {
109+
let ostree = storage.get_ostree()?;
109110
// For now we only check the booted deployment.
110-
if storage.booted_deployment().is_none() {
111+
if ostree.booted_deployment().is_none() {
111112
return fsck_ok();
112113
}
113114
// Read usr/etc/resolv.conf directly.
@@ -240,7 +241,8 @@ fn check_fsverity(storage: &Storage) -> Pin<Box<dyn Future<Output = FsckResult>
240241
}
241242

242243
async fn check_fsverity_inner(storage: &Storage) -> FsckResult {
243-
let repo = &storage.repo();
244+
let ostree = storage.get_ostree()?;
245+
let repo = &ostree.repo();
244246
let verity_state = ostree_ext::fsverity::is_verity_enabled(repo)?;
245247
tracing::debug!(
246248
"verity: expected={:?} found={:?}",
@@ -249,7 +251,7 @@ async fn check_fsverity_inner(storage: &Storage) -> FsckResult {
249251
);
250252

251253
let verity_found_state =
252-
verity_state_of_all_objects(&storage.repo(), verity_state.desired == Tristate::Enabled)
254+
verity_state_of_all_objects(&ostree.repo(), verity_state.desired == Tristate::Enabled)
253255
.await?;
254256
let Some((missing, rest)) = collect_until(
255257
verity_found_state.missing.iter(),

crates/lib/src/image.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use serde::Serialize;
1414
use crate::{
1515
boundimage::query_bound_images,
1616
cli::{ImageListFormat, ImageListType},
17-
imgstorage::ensure_floating_c_storage_initialized,
17+
podstorage::{ensure_floating_c_storage_initialized, CStorage},
1818
};
1919

2020
/// The name of the image we push to containers-storage if nothing is specified.
@@ -42,7 +42,8 @@ struct ImageOutput {
4242

4343
#[context("Listing host images")]
4444
fn list_host_images(sysroot: &crate::store::Storage) -> Result<Vec<ImageOutput>> {
45-
let repo = sysroot.repo();
45+
let ostree = sysroot.get_ostree()?;
46+
let repo = ostree.repo();
4647
let images = ostree_ext::container::store::list_images(&repo).context("Querying images")?;
4748

4849
Ok(images
@@ -129,8 +130,8 @@ pub(crate) async fn list_entrypoint(
129130
pub(crate) async fn push_entrypoint(source: Option<&str>, target: Option<&str>) -> Result<()> {
130131
let transport = Transport::ContainerStorage;
131132
let sysroot = crate::cli::get_storage().await?;
132-
133-
let repo = &sysroot.repo();
133+
let ostree = sysroot.get_ostree()?;
134+
let repo = &ostree.repo();
134135

135136
// If the target isn't specified, push to containers-storage + our default image
136137
let target = if let Some(target) = target {
@@ -150,7 +151,7 @@ pub(crate) async fn push_entrypoint(source: Option<&str>, target: Option<&str>)
150151
let source = if let Some(source) = source {
151152
ImageReference::try_from(source).context("Parsing source image")?
152153
} else {
153-
let status = crate::status::get_status_require_booted(&sysroot)?;
154+
let status = crate::status::get_status_require_booted(&ostree)?;
154155
// SAFETY: We know it's booted
155156
let booted = status.2.status.booted.unwrap();
156157
let booted_image = booted.image.unwrap().image;
@@ -171,7 +172,7 @@ pub(crate) async fn push_entrypoint(source: Option<&str>, target: Option<&str>)
171172
/// Thin wrapper for invoking `podman image <X>` but set up for our internal
172173
/// image store (as distinct from /var/lib/containers default).
173174
pub(crate) async fn imgcmd_entrypoint(
174-
storage: &crate::imgstorage::Storage,
175+
storage: &CStorage,
175176
arg: &str,
176177
args: &[std::ffi::OsString],
177178
) -> std::result::Result<(), anyhow::Error> {

0 commit comments

Comments
 (0)