mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
feature(oci): use local index as resolution cache when appropriate, fixes #289
This commit is contained in:
parent
146bda0810
commit
f8d17e7473
@ -50,7 +50,7 @@ async fn main() -> Result<()> {
|
||||
let (context, _) = OciProgressContext::create();
|
||||
let service = OciPackerService::new(None, &cache_dir, platform).await?;
|
||||
let packed = service
|
||||
.request(image.clone(), OciPackedFormat::Tar, false, context)
|
||||
.request(image.clone(), OciPackedFormat::Tar, false, true, context)
|
||||
.await?;
|
||||
let annotations = packed
|
||||
.manifest
|
||||
|
@ -38,6 +38,7 @@ impl ImagePullCommand {
|
||||
ImagePullImageFormat::Tar => OciImageFormat::Tar.into(),
|
||||
},
|
||||
overwrite_cache: self.overwrite_cache,
|
||||
update: true,
|
||||
})
|
||||
.await?;
|
||||
let reply = pull_interactive_progress(response.into_inner()).await?;
|
||||
|
@ -34,6 +34,8 @@ pub struct ZoneLaunchCommand {
|
||||
image_format: LaunchImageFormat,
|
||||
#[arg(long, help = "Overwrite image cache on pull")]
|
||||
pull_overwrite_cache: bool,
|
||||
#[arg(long, help = "Update image on pull")]
|
||||
pull_update: bool,
|
||||
#[arg(short, long, help = "Name of the zone")]
|
||||
name: Option<String>,
|
||||
#[arg(short, long, default_value_t = 1, help = "vCPUs available to the zone")]
|
||||
@ -181,6 +183,7 @@ impl ZoneLaunchCommand {
|
||||
image: image.to_string(),
|
||||
format: format.into(),
|
||||
overwrite_cache: self.pull_overwrite_cache,
|
||||
update: self.pull_update,
|
||||
})
|
||||
.await?;
|
||||
let reply = pull_interactive_progress(response.into_inner()).await?;
|
||||
|
@ -448,7 +448,7 @@ impl ControlService for DaemonControlService {
|
||||
|
||||
let output = try_stream! {
|
||||
let mut task = tokio::task::spawn(async move {
|
||||
our_packer.request(name, format, request.overwrite_cache, context).await
|
||||
our_packer.request(name, format, request.overwrite_cache, request.update, context).await
|
||||
});
|
||||
let abort_handle = task.abort_handle();
|
||||
let _task_cancel_guard = scopeguard::guard(abort_handle, |handle| {
|
||||
|
@ -184,6 +184,7 @@ message PullImageRequest {
|
||||
string image = 1;
|
||||
krata.v1.common.OciImageFormat format = 2;
|
||||
bool overwrite_cache = 3;
|
||||
bool update = 4;
|
||||
}
|
||||
|
||||
message PullImageReply {
|
||||
|
@ -37,7 +37,13 @@ async fn main() -> Result<()> {
|
||||
});
|
||||
let service = OciPackerService::new(seed, &cache_dir, OciPlatform::current()).await?;
|
||||
let packed = service
|
||||
.request(image.clone(), OciPackedFormat::Squashfs, false, context)
|
||||
.request(
|
||||
image.clone(),
|
||||
OciPackedFormat::Squashfs,
|
||||
false,
|
||||
true,
|
||||
context,
|
||||
)
|
||||
.await?;
|
||||
println!(
|
||||
"generated squashfs of {} to {}",
|
||||
|
@ -4,6 +4,7 @@ use crate::{
|
||||
schema::OciSchema,
|
||||
};
|
||||
|
||||
use crate::fetch::OciResolvedImage;
|
||||
use anyhow::Result;
|
||||
use log::{debug, error};
|
||||
use oci_spec::image::{
|
||||
@ -50,6 +51,51 @@ impl OciPackerCache {
|
||||
Ok(index.manifests().clone())
|
||||
}
|
||||
|
||||
pub async fn resolve(
|
||||
&self,
|
||||
name: ImageName,
|
||||
format: OciPackedFormat,
|
||||
) -> Result<Option<OciResolvedImage>> {
|
||||
if name.reference.as_deref() == Some("latest") {
|
||||
return Ok(None);
|
||||
}
|
||||
let name_str = name.to_string();
|
||||
let index = self.index.read().await;
|
||||
let mut descriptor: Option<Descriptor> = None;
|
||||
for manifest in index.manifests() {
|
||||
let Some(name) = manifest
|
||||
.annotations()
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.get(ANNOTATION_IMAGE_NAME)
|
||||
.cloned()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if name == name_str {
|
||||
descriptor = Some(manifest.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let Some(descriptor) = descriptor else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
debug!("resolve hit name={} digest={}", name, descriptor.digest());
|
||||
|
||||
self.recall(name, descriptor.digest().as_ref(), format)
|
||||
.await
|
||||
.map(|image| {
|
||||
image.map(|i| OciResolvedImage {
|
||||
name: i.name,
|
||||
digest: i.digest,
|
||||
descriptor: i.descriptor,
|
||||
manifest: i.manifest,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn recall(
|
||||
&self,
|
||||
name: ImageName,
|
||||
|
@ -75,13 +75,23 @@ impl OciPackerService {
|
||||
name: ImageName,
|
||||
format: OciPackedFormat,
|
||||
overwrite: bool,
|
||||
pull: bool,
|
||||
progress_context: OciProgressContext,
|
||||
) -> Result<OciPackedImage> {
|
||||
let progress = OciProgress::new();
|
||||
let progress = OciBoundProgress::new(progress_context.clone(), progress);
|
||||
let mut resolved = None;
|
||||
if !pull && !overwrite {
|
||||
resolved = self.cache.resolve(name.clone(), format).await?;
|
||||
}
|
||||
let fetcher =
|
||||
OciImageFetcher::new(self.seed.clone(), self.platform.clone(), progress.clone());
|
||||
let resolved = fetcher.resolve(name.clone()).await?;
|
||||
let resolved = if let Some(resolved) = resolved {
|
||||
resolved
|
||||
} else {
|
||||
fetcher.resolve(name.clone()).await?
|
||||
};
|
||||
|
||||
let key = OciPackerTaskKey {
|
||||
digest: resolved.digest.clone(),
|
||||
format,
|
||||
|
@ -138,7 +138,7 @@ impl VfsNode {
|
||||
header.set_mode(self.mode);
|
||||
|
||||
if let Some(link_name) = self.link_name.as_ref() {
|
||||
header.set_link_name(&PathBuf::from(link_name))?;
|
||||
header.set_link_name(PathBuf::from(link_name))?;
|
||||
}
|
||||
header.set_size(self.size);
|
||||
Ok(header)
|
||||
|
Loading…
Reference in New Issue
Block a user