Skip to content

Commit 9a7c672

Browse files
authored
Merge pull request #1 from cgwalters/check-skopeo
Handle case where skopeo exits unexpectedly
2 parents eed699f + c2362e1 commit 9a7c672

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

src/imageproxy.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::fs::File;
1313
use std::os::unix::io::AsRawFd;
1414
use std::os::unix::prelude::{FromRawFd, RawFd};
1515
use std::pin::Pin;
16-
use std::process::Stdio;
16+
use std::process::{ExitStatus, Stdio};
1717
use std::sync::{Arc, Mutex};
1818
use tokio::io::{AsyncBufRead, AsyncReadExt};
1919

@@ -69,9 +69,9 @@ type JoinFuture<T> = Pin<Box<dyn Future<Output = Result<Result<T>>>>>;
6969

7070
/// Manage a child process proxy to fetch container images.
7171
pub struct ImageProxy {
72-
proc: tokio::process::Child,
7372
sockfd: Arc<Mutex<File>>,
7473
stderr: JoinFuture<String>,
74+
procwait: Pin<Box<dyn Future<Output = Result<ExitStatus>>>>,
7575
}
7676

7777
impl std::fmt::Debug for ImageProxy {
@@ -130,12 +130,22 @@ impl ImageProxy {
130130
.map_err(anyhow::Error::msg)
131131
.boxed();
132132

133+
let mut procwait = Box::pin(async move { proc.wait().map_err(anyhow::Error::msg).await });
134+
133135
let sockfd = Arc::new(Mutex::new(mysock));
134136

135137
// Verify semantic version
136-
let (protover, _) =
137-
Self::impl_request_raw::<String>(Arc::clone(&sockfd), Request::new_bare("Initialize"))
138-
.await?;
138+
let protoreq =
139+
Self::impl_request_raw::<String>(Arc::clone(&sockfd), Request::new_bare("Initialize"));
140+
let protover = tokio::select! {
141+
r = protoreq => {
142+
r?.0
143+
}
144+
r = &mut procwait => {
145+
let errmsg = stderr.await??;
146+
return Err(anyhow!("skopeo exited unexpectedly (no support for `experimental-image-proxy`?): {}\n{}", r?, errmsg));
147+
}
148+
};
139149
let protover = semver::Version::parse(protover.as_str())?;
140150
let supported = &*SUPPORTED_PROTO_VERSION;
141151
if !supported.matches(&protover) {
@@ -147,9 +157,9 @@ impl ImageProxy {
147157
}
148158

149159
let r = Self {
150-
proc,
151160
stderr,
152161
sockfd,
162+
procwait,
153163
};
154164
Ok(r)
155165
}
@@ -276,14 +286,14 @@ impl ImageProxy {
276286
}
277287

278288
/// Close the connection and wait for the child process to exit successfully.
279-
pub async fn finalize(mut self) -> Result<()> {
289+
pub async fn finalize(self) -> Result<()> {
280290
let req = Request::new_bare("Shutdown");
281291
let sendbuf = serde_json::to_vec(&req)?;
282292
// SAFETY: Only panics if a worker thread already panic'd
283293
let sockfd = Arc::try_unwrap(self.sockfd).unwrap().into_inner().unwrap();
284294
nixsocket::send(sockfd.as_raw_fd(), &sendbuf, nixsocket::MsgFlags::empty())?;
285295
drop(sendbuf);
286-
let status = self.proc.wait().await?;
296+
let status = self.procwait.await?;
287297
if !status.success() {
288298
if let Some(stderr) = self.stderr.await.map(|v| v.ok()).ok().flatten() {
289299
anyhow::bail!("proxy failed: {}\n{}", status, stderr)

0 commit comments

Comments
 (0)