Skip to content

Commit f30bd93

Browse files
committed
Add GetBlobRaw
This is needed for my "registry frontend for containers-storage" project, but should also be useful in general as we've discussed moving checksum verification into callers. Then there's no need for a driver etc. Signed-off-by: Colin Walters <[email protected]>
1 parent b5a74f7 commit f30bd93

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

src/imageproxy.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,7 @@ impl ImageProxy {
411411
});
412412
}
413413
let fdret = match (fdret, reply.pipeid) {
414-
(Some(fd), n) => {
415-
if n == 0 {
416-
return Err(Error::Other("got fd but no pipeid".into()));
417-
}
418-
Some((fd, n))
419-
}
414+
(Some(fd), n) => Some((fd, n)),
420415
(None, n) => {
421416
if n != 0 {
422417
return Err(Error::Other(format!("got no fd with pipeid {}", n).into()));
@@ -458,6 +453,7 @@ impl ImageProxy {
458453
#[instrument]
459454
async fn finish_pipe(&self, pipeid: u32) -> Result<()> {
460455
tracing::debug!("closing pipe");
456+
debug_assert!(pipeid > 0);
461457
let (r, fd) = self.impl_request("FinishPipe", [pipeid]).await?;
462458
if fd.is_some() {
463459
return Err(Error::Other("Unexpected fd in finish_pipe reply".into()));
@@ -496,6 +492,9 @@ impl ImageProxy {
496492

497493
async fn read_all_fd(&self, fd: Option<(OwnedFd, u32)>) -> Result<Vec<u8>> {
498494
let (fd, pipeid) = fd.ok_or_else(|| Error::Other("Missing fd from reply".into()))?;
495+
if pipeid == 0 {
496+
return Err(Error::Other("got fd but no pipeid".into()));
497+
}
499498
let fd = tokio::fs::File::from_std(std::fs::File::from(fd));
500499
let mut fd = tokio::io::BufReader::new(fd);
501500
let mut r = Vec::new();
@@ -570,12 +569,33 @@ impl ImageProxy {
570569
vec![img.0.into(), digest.to_string().into(), size.into()];
571570
let (_bloblen, fd) = self.impl_request::<i64, _, _>("GetBlob", args).await?;
572571
let (fd, pipeid) = fd.ok_or_else(|| Error::new_other("Missing fd from reply"))?;
572+
if pipeid == 0 {
573+
return Err(Error::Other("got fd but no pipeid".into()));
574+
}
573575
let fd = tokio::fs::File::from_std(std::fs::File::from(fd));
574576
let fd = tokio::io::BufReader::new(fd);
575577
let finish = Box::pin(self.finish_pipe(pipeid));
576578
Ok((fd, finish))
577579
}
578580

581+
/// Fetch a blob identified by e.g. `sha256:<digest>`; does not perform
582+
/// any verification that the blob matches the digest. The size of the
583+
/// blob and a pipe file descriptor are returned.
584+
#[instrument]
585+
pub async fn get_raw_blob(
586+
&self,
587+
img: &OpenedImage,
588+
digest: &Digest,
589+
) -> Result<(u64, tokio::fs::File)> {
590+
tracing::debug!("fetching blob");
591+
let args: Vec<serde_json::Value> = vec![img.0.into(), digest.to_string().into()];
592+
let (bloblen, fd) = self.impl_request::<u64, _, _>("GetRawBlob", args).await?;
593+
let (fd, pipeid) = fd.ok_or_else(|| Error::new_other("Missing fd from reply"))?;
594+
debug_assert_eq!(pipeid, 0);
595+
let fd = tokio::fs::File::from_std(std::fs::File::from(fd));
596+
Ok((bloblen, fd))
597+
}
598+
579599
/// Fetch a descriptor. The requested size and digest are verified (by the proxy process).
580600
#[instrument]
581601
pub async fn get_descriptor(

0 commit comments

Comments
 (0)