@@ -54,6 +54,9 @@ pub enum Error {
5454 #[ error( "Expected digest algorithm sha256 but found {found}" ) ]
5555 /// Returned when a digest algorithm is not supported
5656 UnsupportedDigestAlgorithm { found : Box < str > } ,
57+ #[ error( "Cannot find the Image Index (index.json)" ) ]
58+ /// Returned when the OCI Image Index (index.json) is missing
59+ MissingImageIndex ,
5760 #[ error( "error" ) ]
5861 /// An unknown other error
5962 Other ( Box < str > ) ,
@@ -384,9 +387,7 @@ impl OciDir {
384387
385388 /// Returns `true` if the manifest is already present.
386389 pub fn has_manifest ( & self , desc : & oci_spec:: image:: Descriptor ) -> Result < bool > {
387- let Some ( index) = self . read_index ( ) ? else {
388- return Ok ( false ) ;
389- } ;
390+ let index = self . read_index ( ) ?;
390391 Ok ( index
391392 . manifests ( )
392393 . iter ( )
@@ -414,11 +415,11 @@ impl OciDir {
414415 }
415416
416417 /// Read the image index.
417- pub fn read_index ( & self ) -> Result < Option < ImageIndex > > {
418+ pub fn read_index ( & self ) -> Result < ImageIndex > {
418419 let r = if let Some ( index) = self . dir . open_optional ( "index.json" ) ?. map ( BufReader :: new) {
419- Some ( oci_image:: ImageIndex :: from_reader ( index) ?)
420+ oci_image:: ImageIndex :: from_reader ( index) ?
420421 } else {
421- None
422+ return Err ( Error :: MissingImageIndex ) ;
422423 } ;
423424 Ok ( r)
424425 }
@@ -442,21 +443,23 @@ impl OciDir {
442443 manifest. set_annotations ( Some ( annotations) ) ;
443444 }
444445
445- let index = self . read_index ( ) ?;
446- let index = if let Some ( mut index) = index {
447- let mut manifests = index. manifests ( ) . clone ( ) ;
448- if let Some ( tag) = tag {
449- manifests. retain ( |d| !Self :: descriptor_is_tagged ( d, tag) ) ;
446+ let index = match self . read_index ( ) {
447+ Ok ( mut index) => {
448+ let mut manifests = index. manifests ( ) . clone ( ) ;
449+ if let Some ( tag) = tag {
450+ manifests. retain ( |d| !Self :: descriptor_is_tagged ( d, tag) ) ;
451+ }
452+ manifests. push ( manifest. clone ( ) ) ;
453+ index. set_manifests ( manifests) ;
454+ index
450455 }
451- manifests. push ( manifest. clone ( ) ) ;
452- index. set_manifests ( manifests) ;
453- index
454- } else {
455- oci_image:: ImageIndexBuilder :: default ( )
456+ Err ( Error :: MissingImageIndex ) => oci_image:: ImageIndexBuilder :: default ( )
456457 . schema_version ( oci_image:: SCHEMA_VERSION )
457458 . manifests ( vec ! [ manifest. clone( ) ] )
458- . build ( )
459- . unwrap ( )
459+ . build ( ) ?,
460+ Err ( e) => {
461+ return Err ( e) ;
462+ }
460463 } ;
461464
462465 self . dir
@@ -519,14 +522,21 @@ impl OciDir {
519522
520523 /// Find the manifest with the provided tag
521524 pub fn find_manifest_with_tag ( & self , tag : & str ) -> Result < Option < oci_image:: ImageManifest > > {
522- let f = self . dir . open ( "index.json" ) ?;
523- let idx: oci_image:: ImageIndex = serde_json:: from_reader ( BufReader :: new ( f) ) ?;
524- for img in idx. manifests ( ) {
525- if Self :: descriptor_is_tagged ( img, tag) {
526- return self . read_json_blob ( img) . map ( Some ) ;
527- }
528- }
529- Ok ( None )
525+ let desc = self . find_manifest_descriptor_with_tag ( tag) ?;
526+ desc. map ( |img| self . read_json_blob ( & img) ) . transpose ( )
527+ }
528+
529+ /// Find the manifest descriptor with the provided tag
530+ pub fn find_manifest_descriptor_with_tag (
531+ & self ,
532+ tag : & str ,
533+ ) -> Result < Option < oci_image:: Descriptor > > {
534+ let idx = self . read_index ( ) ?;
535+ Ok ( idx
536+ . manifests ( )
537+ . iter ( )
538+ . find ( |desc| Self :: descriptor_is_tagged ( desc, tag) )
539+ . cloned ( ) )
530540 }
531541
532542 /// Verify a single manifest and all of its referenced objects.
@@ -567,9 +577,7 @@ impl OciDir {
567577 /// Verify consistency of the index, its manifests, the config and blobs (all the latter)
568578 /// by verifying their descriptor.
569579 pub fn fsck ( & self ) -> Result < u64 > {
570- let Some ( index) = self . read_index ( ) ? else {
571- return Ok ( 0 ) ;
572- } ;
580+ let index = self . read_index ( ) ?;
573581 let mut validated_blobs = HashSet :: new ( ) ;
574582 for manifest_descriptor in index. manifests ( ) {
575583 let expected_sha256 = sha256_of_descriptor ( manifest_descriptor) ?;
@@ -813,7 +821,7 @@ mod tests {
813821 "349438e5faf763e8875b43de4d7101540ef4d865190336c2cc549a11f33f8d7c"
814822 ) ;
815823 // Nothing referencing this blob yet
816- assert_eq ! ( w. fsck( ) . unwrap ( ) , 0 ) ;
824+ assert ! ( matches! ( w. fsck( ) . unwrap_err ( ) , Error :: MissingImageIndex ) ) ;
817825 assert ! ( w. has_blob( & root_layer_desc) . unwrap( ) ) ;
818826
819827 // Check that we don't find nonexistent blobs
@@ -834,7 +842,7 @@ mod tests {
834842 let config = w. write_config ( config) ?;
835843 manifest. set_config ( config) ;
836844 w. replace_with_single_manifest ( manifest. clone ( ) , oci_image:: Platform :: default ( ) ) ?;
837- assert_eq ! ( w. read_index( ) . unwrap( ) . unwrap ( ) . manifests( ) . len( ) , 1 ) ;
845+ assert_eq ! ( w. read_index( ) . unwrap( ) . manifests( ) . len( ) , 1 ) ;
838846 assert_eq ! ( w. fsck( ) . unwrap( ) , 3 ) ;
839847 // Also verify that corrupting a blob is found
840848 {
@@ -851,7 +859,7 @@ mod tests {
851859 assert_eq ! ( w. fsck( ) . unwrap( ) , 3 ) ;
852860 }
853861
854- let idx = w. read_index ( ) ?. unwrap ( ) ;
862+ let idx = w. read_index ( ) ?;
855863 let manifest_desc = idx. manifests ( ) . first ( ) . unwrap ( ) ;
856864 let read_manifest = w. read_json_blob ( manifest_desc) . unwrap ( ) ;
857865 assert_eq ! ( & read_manifest, & manifest) ;
@@ -860,7 +868,7 @@ mod tests {
860868 w. insert_manifest ( manifest, Some ( "latest" ) , oci_image:: Platform :: default ( ) ) ?;
861869 assert ! ( w. has_manifest( & desc) . unwrap( ) ) ;
862870 // There's more than one now
863- assert_eq ! ( w. read_index( ) . unwrap( ) . unwrap ( ) . manifests( ) . len( ) , 2 ) ;
871+ assert_eq ! ( w. read_index( ) . unwrap( ) . manifests( ) . len( ) , 2 ) ;
864872
865873 assert ! ( w. find_manifest_with_tag( "noent" ) . unwrap( ) . is_none( ) ) ;
866874 let found_via_tag = w. find_manifest_with_tag ( "latest" ) . unwrap ( ) . unwrap ( ) ;
@@ -880,7 +888,7 @@ mod tests {
880888 Some ( "latest" ) ,
881889 oci_image:: Platform :: default ( ) ,
882890 ) ?;
883- assert_eq ! ( w. read_index( ) . unwrap( ) . unwrap ( ) . manifests( ) . len( ) , 2 ) ;
891+ assert_eq ! ( w. read_index( ) . unwrap( ) . manifests( ) . len( ) , 2 ) ;
884892 assert_eq ! ( w. fsck( ) . unwrap( ) , 6 ) ;
885893 Ok ( ( ) )
886894 }
0 commit comments