Skip to content

Commit 9b2e75c

Browse files
allisonkarlitskayacgwalters
authored andcommitted
oci: add support for pulling decompressed tar
Check the media_type on the descriptor before attempting gzip decompression. If the media type indicates an uncompressed layer, then consume the stream directly. Add zstd support as well. Unfortunately the code is a bit awkward: split_async() is generic, so we need to make a separate call for each potential underlying AsyncBufRead impl. Signed-off-by: Allison Karlitskaya <[email protected]>
1 parent 7743d0d commit 9b2e75c

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ rhel9 = ['pre-6.15']
1818

1919
[dependencies]
2020
anyhow = { version = "1.0.97", default-features = false }
21-
async-compression = { version = "0.4.22", default-features = false, features = ["tokio", "gzip"] }
21+
async-compression = { version = "0.4.22", default-features = false, features = ["tokio", "zstd", "gzip"] }
2222
clap = { version = "4.5.32", default-features = false, features = ["std", "help", "usage", "derive"] }
2323
containers-image-proxy = "0.7.0"
2424
env_logger = "0.11.7"

src/oci/mod.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ pub mod tar;
44
use std::{collections::HashMap, io::Read, iter::zip, path::Path};
55

66
use anyhow::{bail, ensure, Context, Result};
7-
use async_compression::tokio::bufread::GzipDecoder;
7+
use async_compression::tokio::bufread::{GzipDecoder, ZstdDecoder};
88
use containers_image_proxy::{ImageProxy, ImageProxyConfig, OpenedImage};
99
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
10-
use oci_spec::image::{Descriptor, ImageConfiguration, ImageManifest};
10+
use oci_spec::image::{Descriptor, ImageConfiguration, ImageManifest, MediaType};
1111
use sha2::{Digest, Sha256};
1212

1313
use crate::{
@@ -101,9 +101,20 @@ impl<'repo> ImageOp<'repo> {
101101
let progress = bar.wrap_async_read(blob_reader);
102102
self.progress
103103
.println(format!("Fetching layer {}", hex::encode(layer_sha256)))?;
104-
let decoder = GzipDecoder::new(progress);
104+
105105
let mut splitstream = self.repo.create_stream(Some(*layer_sha256), None);
106-
split_async(decoder, &mut splitstream).await?;
106+
match descriptor.media_type() {
107+
MediaType::ImageLayer => {
108+
split_async(progress, &mut splitstream).await?;
109+
}
110+
MediaType::ImageLayerGzip => {
111+
split_async(GzipDecoder::new(progress), &mut splitstream).await?;
112+
}
113+
MediaType::ImageLayerZstd => {
114+
split_async(ZstdDecoder::new(progress), &mut splitstream).await?;
115+
}
116+
other => bail!("Unsupported layer media type {:?}", other),
117+
};
107118
let layer_id = self.repo.write_stream(splitstream, None)?;
108119
driver.await?;
109120
Ok(layer_id)

0 commit comments

Comments
 (0)