Skip to content

Commit 41706ad

Browse files
committed
mount API is not strictly equivalent to bind
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent ee33143 commit 41706ad

File tree

2 files changed

+62
-12
lines changed

2 files changed

+62
-12
lines changed

pkg/compose/create.go

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -858,24 +858,67 @@ MOUNTS:
858858
// `Mount` is preferred but does not offer option to created host path if missing
859859
// so `Bind` API is used here with raw volume string
860860
// see https://github.com/moby/moby/issues/43483
861-
for _, v := range service.Volumes {
862-
if v.Target == m.Target {
863-
switch {
864-
case string(m.Type) != v.Type:
865-
v.Source = m.Source
866-
fallthrough
867-
case !requireMountAPI(v.Bind):
868-
binds = append(binds, v.String())
869-
continue MOUNTS
870-
}
871-
}
861+
v := findVolumeByTarget(service.Volumes, m.Target)
862+
switch {
863+
case string(m.Type) != v.Type:
864+
v.Source = m.Source
865+
fallthrough
866+
case !requireMountAPI(v.Bind):
867+
vol := findVolumeByName(p.Volumes, m.Source)
868+
binds = append(binds, toBindString(vol.Name, v))
869+
continue MOUNTS
870+
}
871+
}
872+
if m.Type == mount.TypeVolume {
873+
v := findVolumeByTarget(service.Volumes, m.Target)
874+
vol := findVolumeByName(p.Volumes, m.Source)
875+
if vol.Driver == "local" && vol.DriverOpts["o"] == "bind" {
876+
// Looks like a volume, but actually a bind mount which requires the bind API
877+
binds = append(binds, toBindString(vol.Name, v))
878+
continue MOUNTS
872879
}
873880
}
874881
mounts = append(mounts, m)
875882
}
876883
return binds, mounts, nil
877884
}
878885

886+
func toBindString(name string, v *types.ServiceVolumeConfig) string {
887+
access := "rw"
888+
if v.ReadOnly {
889+
access = "ro"
890+
}
891+
options := []string{access}
892+
if v.Bind != nil && v.Bind.SELinux != "" {
893+
options = append(options, v.Bind.SELinux)
894+
}
895+
if v.Bind != nil && v.Bind.Propagation != "" {
896+
options = append(options, v.Bind.Propagation)
897+
}
898+
if v.Volume != nil && v.Volume.NoCopy {
899+
options = append(options, "nocopy")
900+
}
901+
return fmt.Sprintf("%s:%s:%s", name, v.Target, strings.Join(options, ","))
902+
}
903+
904+
func findVolumeByName(volumes types.Volumes, name string) *types.VolumeConfig {
905+
for _, vol := range volumes {
906+
if vol.Name == name {
907+
return &vol
908+
}
909+
}
910+
return nil
911+
}
912+
913+
func findVolumeByTarget(volumes []types.ServiceVolumeConfig, target string) *types.ServiceVolumeConfig {
914+
for _, v := range volumes {
915+
if v.Target == target {
916+
return &v
917+
}
918+
}
919+
return nil
920+
}
921+
879922
// requireMountAPI check if Bind declaration can be implemented by the plain old Bind API or uses any of the advanced
880923
// options which require use of Mount API
881924
func requireMountAPI(bind *types.ServiceVolumeBind) bool {

pkg/compose/down.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,15 @@ func (s *composeService) removeImage(ctx context.Context, image string, w progre
282282

283283
func (s *composeService) removeVolume(ctx context.Context, id string, w progress.Writer) error {
284284
resource := fmt.Sprintf("Volume %s", id)
285+
286+
_, err := s.apiClient().VolumeInspect(ctx, id)
287+
if errdefs.IsNotFound(err) {
288+
// Already gone
289+
return nil
290+
}
291+
285292
w.Event(progress.NewEvent(resource, progress.Working, "Removing"))
286-
err := s.apiClient().VolumeRemove(ctx, id, true)
293+
err = s.apiClient().VolumeRemove(ctx, id, true)
287294
if err == nil {
288295
w.Event(progress.NewEvent(resource, progress.Done, "Removed"))
289296
return nil

0 commit comments

Comments
 (0)