Skip to content

Commit bac2231

Browse files
authored
Merge pull request #748 from cgwalters/create-imgstore-as-needed
Open/create imagestore as needed
2 parents ee11428 + bffb3bb commit bac2231

File tree

10 files changed

+65
-18
lines changed

10 files changed

+65
-18
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ tini = "1.3.0"
5050
[dev-dependencies]
5151
indoc = "2.0.5"
5252
similar-asserts = { version = "1.5.0" }
53+
static_assertions = "1.1.0"
5354

5455
[features]
5556
default = ["install"]

lib/src/boundimage.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,18 @@ fn parse_container_file(file_contents: &tini::Ini) -> Result<BoundImage> {
145145
#[context("Pulling bound images")]
146146
pub(crate) async fn pull_images(sysroot: &Storage, bound_images: Vec<BoundImage>) -> Result<()> {
147147
tracing::debug!("Pulling bound images: {}", bound_images.len());
148+
// Only initialize the image storage if we have images to pull
149+
let imgstore = if !bound_images.is_empty() {
150+
sysroot.get_ensure_imgstore()?
151+
} else {
152+
return Ok(());
153+
};
148154
//TODO: do this in parallel
149155
for bound_image in bound_images {
150156
let image = &bound_image.image;
151157
let desc = format!("Updating bound image: {image}");
152158
crate::utils::async_task_with_spinner(&desc, async move {
153-
sysroot
154-
.imgstore
159+
imgstore
155160
.pull(&bound_image.image, PullMode::IfNotExists)
156161
.await
157162
})

lib/src/cli.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -839,22 +839,26 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
839839
}
840840
ImageOpts::PullFromDefaultStorage { image } => {
841841
let sysroot = get_storage().await?;
842-
sysroot.imgstore.pull_from_host_storage(&image).await
842+
sysroot
843+
.get_ensure_imgstore()?
844+
.pull_from_host_storage(&image)
845+
.await
843846
}
844847
ImageOpts::Cmd(opt) => {
845-
let sysroot = get_storage().await?;
848+
let storage = get_storage().await?;
849+
let imgstore = storage.get_ensure_imgstore()?;
846850
match opt {
847851
ImageCmdOpts::List { args } => {
848-
crate::image::imgcmd_entrypoint(&sysroot.imgstore, "list", &args).await
852+
crate::image::imgcmd_entrypoint(imgstore, "list", &args).await
849853
}
850854
ImageCmdOpts::Build { args } => {
851-
crate::image::imgcmd_entrypoint(&sysroot.imgstore, "build", &args).await
855+
crate::image::imgcmd_entrypoint(imgstore, "build", &args).await
852856
}
853857
ImageCmdOpts::Pull { args } => {
854-
crate::image::imgcmd_entrypoint(&sysroot.imgstore, "pull", &args).await
858+
crate::image::imgcmd_entrypoint(imgstore, "pull", &args).await
855859
}
856860
ImageCmdOpts::Push { args } => {
857-
crate::image::imgcmd_entrypoint(&sysroot.imgstore, "push", &args).await
861+
crate::image::imgcmd_entrypoint(imgstore, "push", &args).await
858862
}
859863
}
860864
}

lib/src/deploy.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,10 @@ pub(crate) async fn prune_container_store(sysroot: &Storage) -> Result<()> {
280280
}
281281
// Convert to a hashset of just the image names
282282
let image_names = HashSet::from_iter(all_bound_images.iter().map(|img| img.image.as_str()));
283-
let pruned = sysroot.imgstore.prune_except_roots(&image_names).await?;
283+
let pruned = sysroot
284+
.get_ensure_imgstore()?
285+
.prune_except_roots(&image_names)
286+
.await?;
284287
tracing::debug!("Pruned images: {}", pruned.len());
285288
Ok(())
286289
}

lib/src/image.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(crate) async fn list_entrypoint() -> Result<()> {
2525
println!();
2626

2727
println!("# Logically bound images");
28-
let mut listcmd = sysroot.imgstore.new_image_cmd()?;
28+
let mut listcmd = sysroot.get_ensure_imgstore()?.new_image_cmd()?;
2929
listcmd.arg("list");
3030
listcmd.run()?;
3131

lib/src/imgstorage.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ pub(crate) struct Storage {
4949
#[allow(dead_code)]
5050
/// Our runtime state
5151
run: Dir,
52+
/// Disallow using this across multiple threads concurrently; while we
53+
/// have internal locking in podman, in the future we may change how
54+
/// things work here. And we don't have a use case right now for
55+
/// concurrent operations.
56+
_unsync: std::cell::Cell<()>,
5257
}
5358

5459
#[derive(Debug, PartialEq, Eq)]
@@ -160,12 +165,14 @@ impl Storage {
160165
sysroot
161166
.rename(&tmp, sysroot, subpath)
162167
.context("Renaming tmpdir")?;
168+
tracing::debug!("Created image store");
163169
}
164170
Self::open(sysroot, run)
165171
}
166172

167173
#[context("Opening imgstorage")]
168174
pub(crate) fn open(sysroot: &Dir, run: &Dir) -> Result<Self> {
175+
tracing::trace!("Opening container image store");
169176
Self::init_globals()?;
170177
let storage_root = sysroot
171178
.open_dir(SUBPATH)
@@ -178,6 +185,7 @@ impl Storage {
178185
sysroot: sysroot.try_clone()?,
179186
storage_root,
180187
run,
188+
_unsync: Default::default(),
181189
})
182190
}
183191

@@ -292,3 +300,9 @@ impl Storage {
292300
Ok(())
293301
}
294302
}
303+
304+
#[cfg(test)]
305+
mod tests {
306+
use super::*;
307+
static_assertions::assert_not_impl_any!(Storage: Sync);
308+
}

lib/src/install.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,10 +1289,13 @@ async fn install_with_sysroot(
12891289
tracing::debug!("Installed bootloader");
12901290

12911291
tracing::debug!("Perfoming post-deployment operations");
1292+
// Note that we *always* initialize this container storage, even
1293+
// if there are no bound images today.
1294+
let imgstore = sysroot.get_ensure_imgstore()?;
12921295
// Now copy each bound image from the host's container storage into the target.
12931296
for image in bound_images {
12941297
let image = image.image.as_str();
1295-
sysroot.imgstore.pull_from_host_storage(image).await?;
1298+
imgstore.pull_from_host_storage(image).await?;
12961299
}
12971300

12981301
Ok(())

lib/src/status.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fn boot_entry_from_deployment(
136136
let store = deployment.store()?;
137137
let store = store.as_ref().unwrap_or(&sysroot.store);
138138
let spec = Some(store.spec());
139-
let status = store.imagestatus(sysroot, deployment, image)?;
139+
let status = store.imagestatus(&*sysroot, deployment, image)?;
140140

141141
(spec, status)
142142
} else {

lib/src/store/mod.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::OnceCell;
12
use std::env;
23
use std::ops::Deref;
34

@@ -16,8 +17,8 @@ mod ostree_container;
1617

1718
pub(crate) struct Storage {
1819
pub sysroot: SysrootLock,
19-
#[allow(dead_code)]
20-
pub imgstore: crate::imgstorage::Storage,
20+
run: Dir,
21+
imgstore: OnceCell<crate::imgstorage::Storage>,
2122
pub store: Box<dyn ContainerImageStoreImpl>,
2223
}
2324

@@ -52,6 +53,7 @@ impl Deref for Storage {
5253

5354
impl Storage {
5455
pub fn new(sysroot: SysrootLock, run: &Dir) -> Result<Self> {
56+
let run = run.try_clone()?;
5557
let store = match env::var("BOOTC_STORAGE") {
5658
Ok(val) => crate::spec::Store::from_str(&val, true).unwrap_or_else(|_| {
5759
let default = crate::spec::Store::default();
@@ -61,17 +63,25 @@ impl Storage {
6163
Err(_) => crate::spec::Store::default(),
6264
};
6365

64-
let sysroot_dir = Dir::reopen_dir(&crate::utils::sysroot_fd(&sysroot))?;
65-
let imgstore = crate::imgstorage::Storage::open(&sysroot_dir, run)?;
66-
6766
let store = load(store);
6867

6968
Ok(Self {
7069
sysroot,
70+
run,
7171
store,
72-
imgstore,
72+
imgstore: Default::default(),
7373
})
7474
}
75+
76+
/// Access the image storage; will automatically initialize it if necessary.
77+
pub(crate) fn get_ensure_imgstore(&self) -> Result<&crate::imgstorage::Storage> {
78+
if let Some(imgstore) = self.imgstore.get() {
79+
return Ok(imgstore);
80+
}
81+
let sysroot_dir = Dir::reopen_dir(&crate::utils::sysroot_fd(&self.sysroot))?;
82+
let imgstore = crate::imgstorage::Storage::create(&sysroot_dir, &self.run)?;
83+
Ok(self.imgstore.get_or_init(|| imgstore))
84+
}
7585
}
7686

7787
impl ContainerImageStore for ostree::Deployment {

0 commit comments

Comments
 (0)