@@ -10,7 +10,7 @@ use containerd_client::services::v1::{GetContainerRequest, GetImageRequest, Read
1010use containerd_client:: tonic:: transport:: Channel ;
1111use containerd_client:: { tonic, with_namespace} ;
1212use futures:: TryStreamExt ;
13- use oci_spec:: image:: { Arch , ImageManifest } ;
13+ use oci_spec:: image:: { Arch , ImageManifest , MediaType , Platform } ;
1414use tokio:: runtime:: Runtime ;
1515use tonic:: Request ;
1616
@@ -116,39 +116,57 @@ impl Client {
116116 // load module will query the containerd store to find an image that has an OS of type 'wasm'
117117 // If found it continues to parse the manifest and return the layers that contains the WASM modules
118118 // and possibly other configuration layers.
119- pub fn load_modules ( & self , containerd_id : impl ToString ) -> Result < Vec < oci:: WasmLayer > > {
119+ pub fn load_modules (
120+ & self ,
121+ containerd_id : impl ToString ,
122+ ) -> Result < ( Vec < oci:: WasmLayer > , Platform ) > {
120123 let image_name = self . get_image ( containerd_id. to_string ( ) ) ?;
121124 let digest = self . get_image_content_sha ( image_name) ?;
122125 let manifest = self . read_content ( digest) ?;
123126 let manifest = manifest. as_slice ( ) ;
124127 let manifest = ImageManifest :: from_reader ( manifest) ?;
125128
126- let arch = manifest
127- . config ( )
128- . platform ( )
129- . as_ref ( )
130- . ok_or_else ( || ShimError :: Containerd ( "failed to extract platform" . to_string ( ) ) ) ?
131- . architecture ( ) ;
129+ let image_config_descriptor = manifest. config ( ) ;
130+ let image_config = self . read_content ( image_config_descriptor. digest ( ) ) ?;
131+ let image_config = image_config. as_slice ( ) ;
132132
133- match arch {
134- Arch :: Wasm => {
135- log:: info!( "found manifest with WASM OCI image format." ) ;
136- }
137- _ => {
138- log:: info!( "manifest is not in WASM OCI image format" ) ;
139- return Ok ( [ ] . to_vec ( ) ) ;
140- }
141- }
133+ // the only part we care about here is the platform values
134+ let platform: Platform = serde_json:: from_slice ( image_config) ?;
135+ let Arch :: Wasm = platform. architecture ( ) else {
136+ log:: info!( "manifest is not in WASM OCI image format" ) ;
137+ return Ok ( ( vec ! [ ] , platform) ) ;
138+ } ;
139+ log:: info!( "found manifest with WASM OCI image format." ) ;
142140
143- manifest
141+ let layers = manifest
144142 . layers ( )
145143 . iter ( )
144+ . filter ( |x| !is_image_layer_type ( x. media_type ( ) ) )
146145 . map ( |config| {
147146 self . read_content ( config. digest ( ) ) . map ( |module| WasmLayer {
148147 config : config. clone ( ) ,
149148 layer : module,
150149 } )
151150 } )
152- . collect :: < Result < Vec < _ > > > ( )
151+ . collect :: < Result < Vec < _ > > > ( ) ?;
152+ Ok ( ( layers, platform) )
153+ }
154+ }
155+
156+ fn is_image_layer_type ( media_type : & MediaType ) -> bool {
157+ match media_type {
158+ MediaType :: ImageLayer
159+ | MediaType :: ImageLayerGzip
160+ | MediaType :: ImageLayerNonDistributable
161+ | MediaType :: ImageLayerNonDistributableGzip
162+ | MediaType :: ImageLayerNonDistributableZstd
163+ | MediaType :: ImageLayerZstd => true ,
164+ MediaType :: Other ( s)
165+ if s. as_str ( )
166+ . starts_with ( "application/vnd.docker.image.rootfs." ) =>
167+ {
168+ true
169+ }
170+ _ => false ,
153171 }
154172}
0 commit comments