@@ -39,7 +39,6 @@ import (
39
39
"github.com/docker/docker/api/types/blkiodev"
40
40
"github.com/docker/docker/api/types/container"
41
41
"github.com/docker/docker/api/types/filters"
42
- "github.com/docker/docker/api/types/image"
43
42
"github.com/docker/docker/api/types/mount"
44
43
"github.com/docker/docker/api/types/network"
45
44
"github.com/docker/docker/api/types/strslice"
@@ -828,7 +827,6 @@ func getDependentServiceFromMode(mode string) string {
828
827
return ""
829
828
}
830
829
831
- //nolint:gocyclo
832
830
func (s * composeService ) buildContainerVolumes (
833
831
ctx context.Context ,
834
832
p types.Project ,
@@ -838,13 +836,7 @@ func (s *composeService) buildContainerVolumes(
838
836
var mounts []mount.Mount
839
837
var binds []string
840
838
841
- img := api .GetImageNameOrDefault (service , p .Name )
842
- imgInspect , err := s .apiClient ().ImageInspect (ctx , img )
843
- if err != nil {
844
- return nil , nil , err
845
- }
846
-
847
- mountOptions , err := buildContainerMountOptions (p , service , imgInspect , inherit )
839
+ mountOptions , err := s .buildContainerMountOptions (ctx , p , service , inherit )
848
840
if err != nil {
849
841
return nil , nil , err
850
842
}
@@ -857,11 +849,10 @@ func (s *composeService) buildContainerVolumes(
857
849
// see https://github.com/moby/moby/issues/43483
858
850
v := findVolumeByTarget (service .Volumes , m .Target )
859
851
if v != nil {
860
- switch {
861
- case v .Type != types .VolumeTypeBind :
852
+ if v .Type != types .VolumeTypeBind {
862
853
v .Source = m .Source
863
- fallthrough
864
- case ! requireMountAPI (v .Bind ):
854
+ }
855
+ if ! bindRequiresMountAPI (v .Bind ) {
865
856
source := m .Source
866
857
if vol := findVolumeByName (p .Volumes , m .Source ); vol != nil {
867
858
source = m .Source
@@ -874,8 +865,8 @@ func (s *composeService) buildContainerVolumes(
874
865
v := findVolumeByTarget (service .Volumes , m .Target )
875
866
vol := findVolumeByName (p .Volumes , m .Source )
876
867
if v != nil && vol != nil {
877
- if _ , ok := vol . DriverOpts [ "device" ]; ok && vol . Driver == "local" && vol . DriverOpts [ "o" ] == "bind" {
878
- // Looks like a volume, but actually a bind mount which requires the bind API
868
+ // Prefer the bind API if no advanced option is used, to preserve backward compatibility
869
+ if ! volumeRequiresMountAPI ( v . Volume ) {
879
870
binds = append (binds , toBindString (vol .Name , v ))
880
871
continue
881
872
}
@@ -930,9 +921,9 @@ func findVolumeByTarget(volumes []types.ServiceVolumeConfig, target string) *typ
930
921
return nil
931
922
}
932
923
933
- // requireMountAPI check if Bind declaration can be implemented by the plain old Bind API or uses any of the advanced
924
+ // bindRequiresMountAPI check if Bind declaration can be implemented by the plain old Bind API or uses any of the advanced
934
925
// options which require use of Mount API
935
- func requireMountAPI (bind * types.ServiceVolumeBind ) bool {
926
+ func bindRequiresMountAPI (bind * types.ServiceVolumeBind ) bool {
936
927
switch {
937
928
case bind == nil :
938
929
return false
@@ -947,7 +938,24 @@ func requireMountAPI(bind *types.ServiceVolumeBind) bool {
947
938
}
948
939
}
949
940
950
- func buildContainerMountOptions (p types.Project , s types.ServiceConfig , img image.InspectResponse , inherit * container.Summary ) ([]mount.Mount , error ) {
941
+ // volumeRequiresMountAPI check if Volume declaration can be implemented by the plain old Bind API or uses any of the advanced
942
+ // options which require use of Mount API
943
+ func volumeRequiresMountAPI (vol * types.ServiceVolumeVolume ) bool {
944
+ switch {
945
+ case vol == nil :
946
+ return false
947
+ case len (vol .Labels ) > 0 :
948
+ return true
949
+ case vol .Subpath != "" :
950
+ return true
951
+ case vol .NoCopy :
952
+ return true
953
+ default :
954
+ return false
955
+ }
956
+ }
957
+
958
+ func (s * composeService ) buildContainerMountOptions (ctx context.Context , p types.Project , service types.ServiceConfig , inherit * container.Summary ) ([]mount.Mount , error ) {
951
959
mounts := map [string ]mount.Mount {}
952
960
if inherit != nil {
953
961
for _ , m := range inherit .Mounts {
@@ -959,6 +967,11 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img imag
959
967
src = m .Name
960
968
}
961
969
970
+ img , err := s .apiClient ().ImageInspect (ctx , api .GetImageNameOrDefault (service , p .Name ))
971
+ if err != nil {
972
+ return nil , err
973
+ }
974
+
962
975
if img .Config != nil {
963
976
if _ , ok := img .Config .Volumes [m .Destination ]; ok {
964
977
// inherit previous container's anonymous volume
@@ -971,7 +984,7 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img imag
971
984
}
972
985
}
973
986
volumes := []types.ServiceVolumeConfig {}
974
- for _ , v := range s .Volumes {
987
+ for _ , v := range service .Volumes {
975
988
if v .Target != m .Destination || v .Source != "" {
976
989
volumes = append (volumes , v )
977
990
continue
@@ -984,11 +997,11 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img imag
984
997
ReadOnly : ! m .RW ,
985
998
}
986
999
}
987
- s .Volumes = volumes
1000
+ service .Volumes = volumes
988
1001
}
989
1002
}
990
1003
991
- mounts , err := fillBindMounts (p , s , mounts )
1004
+ mounts , err := fillBindMounts (p , service , mounts )
992
1005
if err != nil {
993
1006
return nil , err
994
1007
}
0 commit comments