@@ -2830,7 +2830,11 @@ func (s *store) Version() ([][2]string, error) {
2830
2830
return [][2 ]string {}, nil
2831
2831
}
2832
2832
2833
- func (s * store ) mount (id string , options drivers.MountOpts ) (string , error ) {
2833
+ func (s * store ) MountImage (id string , mountOpts []string , mountLabel string ) (string , error ) {
2834
+ if err := validateMountOptions (mountOpts ); err != nil {
2835
+ return "" , err
2836
+ }
2837
+
2834
2838
// We need to make sure the home mount is present when the Mount is done, which happens by possibly reinitializing the graph driver
2835
2839
// in startUsingGraphDriver().
2836
2840
if err := s .startUsingGraphDriver (); err != nil {
@@ -2842,57 +2846,61 @@ func (s *store) mount(id string, options drivers.MountOpts) (string, error) {
2842
2846
if err != nil {
2843
2847
return "" , err
2844
2848
}
2845
- if options .UidMaps != nil || options .GidMaps != nil {
2846
- options .DisableShifting = ! s .canUseShifting (options .UidMaps , options .GidMaps )
2847
- }
2849
+ var imageHomeStore roImageStore
2848
2850
2849
- // function used to have a scope for rlstore.StopWriting()
2850
- tryMount := func () (string , error ) {
2851
- if err := rlstore .startWriting (); err != nil {
2851
+ if err := rlstore .startWriting (); err != nil {
2852
+ return "" , err
2853
+ }
2854
+ defer rlstore .stopWriting ()
2855
+ for _ , s := range lstores {
2856
+ if err := s .startReading (); err != nil {
2852
2857
return "" , err
2853
2858
}
2854
- defer rlstore .stopWriting ()
2855
- if rlstore .Exists (id ) {
2856
- return rlstore .Mount (id , options )
2857
- }
2858
- return "" , nil
2859
+ defer s .stopReading ()
2859
2860
}
2860
- mountPoint , err := tryMount ()
2861
- if mountPoint != "" || err != nil {
2862
- return mountPoint , err
2861
+ if err := s .imageStore .startWriting (); err != nil {
2862
+ return "" , err
2863
2863
}
2864
+ defer s .imageStore .stopWriting ()
2864
2865
2865
- // check if the layer is in a read-only store, and return a better error message
2866
- for _ , store := range lstores {
2867
- if err := store .startReading (); err != nil {
2868
- return "" , err
2869
- }
2870
- exists := store .Exists (id )
2871
- store .stopReading ()
2872
- if exists {
2873
- return "" , fmt .Errorf ("mounting read/only store images is not allowed: %w" , ErrStoreIsReadOnly )
2866
+ cimage , err := s .imageStore .Get (id )
2867
+ if err == nil {
2868
+ imageHomeStore = s .imageStore
2869
+ } else {
2870
+ for _ , s := range s .roImageStores {
2871
+ if err := s .startReading (); err != nil {
2872
+ return "" , err
2873
+ }
2874
+ defer s .stopReading ()
2875
+ cimage , err = s .Get (id )
2876
+ if err == nil {
2877
+ imageHomeStore = s
2878
+ break
2879
+ }
2874
2880
}
2875
2881
}
2882
+ if cimage == nil {
2883
+ return "" , fmt .Errorf ("locating image with ID %q: %w" , id , ErrImageUnknown )
2884
+ }
2876
2885
2877
- return "" , ErrLayerUnknown
2878
- }
2879
-
2880
- func (s * store ) MountImage (id string , mountOpts []string , mountLabel string ) (string , error ) {
2881
- // Append ReadOnly option to mountOptions
2882
- img , err := s .Image (id )
2886
+ idmappingsOpts := types.IDMappingOptions {
2887
+ HostUIDMapping : true ,
2888
+ HostGIDMapping : true ,
2889
+ }
2890
+ ilayer , err := s .imageTopLayerForMapping (cimage , imageHomeStore , rlstore , lstores , idmappingsOpts )
2883
2891
if err != nil {
2884
2892
return "" , err
2885
2893
}
2886
2894
2887
- if err := validateMountOptions ( mountOpts ); err != nil {
2888
- return "" , err
2895
+ if len ( ilayer . UIDMap ) > 0 || len ( ilayer . GIDMap ) > 0 {
2896
+ return "" , fmt . Errorf ( "cannot create an image with canonical UID/GID mappings in a read-only store" )
2889
2897
}
2898
+
2890
2899
options := drivers.MountOpts {
2891
2900
MountLabel : mountLabel ,
2892
2901
Options : append (mountOpts , "ro" ),
2893
2902
}
2894
-
2895
- return s .mount (img .TopLayer , options )
2903
+ return rlstore .Mount (ilayer .ID , options )
2896
2904
}
2897
2905
2898
2906
func (s * store ) Mount (id , mountLabel string ) (string , error ) {
@@ -2914,7 +2922,43 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
2914
2922
}
2915
2923
}
2916
2924
}
2917
- return s .mount (id , options )
2925
+
2926
+ // We need to make sure the home mount is present when the Mount is done, which happens by possibly reinitializing the graph driver
2927
+ // in startUsingGraphDriver().
2928
+ if err := s .startUsingGraphDriver (); err != nil {
2929
+ return "" , err
2930
+ }
2931
+ defer s .stopUsingGraphDriver ()
2932
+
2933
+ rlstore , lstores , err := s .bothLayerStoreKindsLocked ()
2934
+ if err != nil {
2935
+ return "" , err
2936
+ }
2937
+ if options .UidMaps != nil || options .GidMaps != nil {
2938
+ options .DisableShifting = ! s .canUseShifting (options .UidMaps , options .GidMaps )
2939
+ }
2940
+
2941
+ if err := rlstore .startWriting (); err != nil {
2942
+ return "" , err
2943
+ }
2944
+ defer rlstore .stopWriting ()
2945
+ if rlstore .Exists (id ) {
2946
+ return rlstore .Mount (id , options )
2947
+ }
2948
+
2949
+ // check if the layer is in a read-only store, and return a better error message
2950
+ for _ , store := range lstores {
2951
+ if err := store .startReading (); err != nil {
2952
+ return "" , err
2953
+ }
2954
+ exists := store .Exists (id )
2955
+ store .stopReading ()
2956
+ if exists {
2957
+ return "" , fmt .Errorf ("mounting read/only store images is not allowed: %w" , ErrStoreIsReadOnly )
2958
+ }
2959
+ }
2960
+
2961
+ return "" , ErrLayerUnknown
2918
2962
}
2919
2963
2920
2964
func (s * store ) Mounted (id string ) (int , error ) {
@@ -2938,7 +2982,23 @@ func (s *store) UnmountImage(id string, force bool) (bool, error) {
2938
2982
if err != nil {
2939
2983
return false , err
2940
2984
}
2941
- return s .Unmount (img .TopLayer , force )
2985
+
2986
+ return writeToLayerStore (s , func (lstore rwLayerStore ) (bool , error ) {
2987
+ for _ , layerID := range img .MappedTopLayers {
2988
+ l , err := lstore .Get (layerID )
2989
+ if err != nil {
2990
+ if err == ErrLayerUnknown {
2991
+ continue
2992
+ }
2993
+ return false , err
2994
+ }
2995
+ // check if the layer with the canonical mapping is in the mapped top layers
2996
+ if len (l .UIDMap ) == 0 && len (l .GIDMap ) == 0 {
2997
+ return lstore .unmount (l .ID , force , false )
2998
+ }
2999
+ }
3000
+ return lstore .unmount (img .TopLayer , force , false )
3001
+ })
2942
3002
}
2943
3003
2944
3004
func (s * store ) Unmount (id string , force bool ) (bool , error ) {
0 commit comments