@@ -13,7 +13,7 @@ use std::fs::File;
1313use std:: os:: unix:: io:: AsRawFd ;
1414use std:: os:: unix:: prelude:: { FromRawFd , RawFd } ;
1515use std:: pin:: Pin ;
16- use std:: process:: Stdio ;
16+ use std:: process:: { ExitStatus , Stdio } ;
1717use std:: sync:: { Arc , Mutex } ;
1818use 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.
7171pub 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
7777impl 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