summaryrefslogtreecommitdiff
path: root/api/server
diff options
context:
space:
mode:
authorDrew Erny <derny@mirantis.com>2022-08-03 11:04:14 -0500
committerDrew Erny <derny@mirantis.com>2022-10-12 11:31:00 -0500
commit3246db3755698455740c812c6477f43e74924fa7 (patch)
treeb6d6036d60b05b938770beea3a2bffb908f21f4c /api/server
parent02ee154558b1edd0a95e114f1f8b50caac1a5886 (diff)
downloaddocker-3246db3755698455740c812c6477f43e74924fa7.tar.gz
fix force remove for cluster volumes
Signed-off-by: Drew Erny <derny@mirantis.com>
Diffstat (limited to 'api/server')
-rw-r--r--api/server/router/volume/volume_routes.go15
-rw-r--r--api/server/router/volume/volume_routes_test.go12
2 files changed, 20 insertions, 7 deletions
diff --git a/api/server/router/volume/volume_routes.go b/api/server/router/volume/volume_routes.go
index 7f1adfaa78..7a0fa42c26 100644
--- a/api/server/router/volume/volume_routes.go
+++ b/api/server/router/volume/volume_routes.go
@@ -162,11 +162,16 @@ func (v *volumeRouter) deleteVolumes(ctx context.Context, w http.ResponseWriter,
version := httputils.VersionFromContext(ctx)
err := v.backend.Remove(ctx, vars["name"], opts.WithPurgeOnError(force))
- if err != nil {
- if errdefs.IsNotFound(err) && versions.GreaterThanOrEqualTo(version, clusterVolumesVersion) && v.cluster.IsManager() {
- err := v.cluster.RemoveVolume(vars["name"], force)
- if err != nil {
- return err
+ // when a removal is forced, if the volume does not exist, no error will be
+ // returned. this means that to ensure forcing works on swarm volumes as
+ // well, we should always also force remove against the cluster.
+ if err != nil || force {
+ if versions.GreaterThanOrEqualTo(version, clusterVolumesVersion) && v.cluster.IsManager() {
+ if errdefs.IsNotFound(err) || force {
+ err := v.cluster.RemoveVolume(vars["name"], force)
+ if err != nil {
+ return err
+ }
}
} else {
return err
diff --git a/api/server/router/volume/volume_routes_test.go b/api/server/router/volume/volume_routes_test.go
index c80ff189a4..9bc50f3392 100644
--- a/api/server/router/volume/volume_routes_test.go
+++ b/api/server/router/volume/volume_routes_test.go
@@ -574,6 +574,7 @@ func TestVolumeRemoveSwarmForce(t *testing.T) {
assert.NilError(t, err)
assert.Equal(t, len(b.volumes), 0)
+ assert.Equal(t, len(c.volumes), 0)
}
type fakeVolumeBackend struct {
@@ -616,9 +617,16 @@ func (b *fakeVolumeBackend) Create(_ context.Context, name, driverName string, _
return v, nil
}
-func (b *fakeVolumeBackend) Remove(_ context.Context, name string, _ ...opts.RemoveOption) error {
+func (b *fakeVolumeBackend) Remove(_ context.Context, name string, o ...opts.RemoveOption) error {
+ removeOpts := &opts.RemoveConfig{}
+ for _, opt := range o {
+ opt(removeOpts)
+ }
+
if v, ok := b.volumes[name]; !ok {
- return errdefs.NotFound(fmt.Errorf("volume %s not found", name))
+ if !removeOpts.PurgeOnError {
+ return errdefs.NotFound(fmt.Errorf("volume %s not found", name))
+ }
} else if v.Name == "inuse" {
return errdefs.Conflict(fmt.Errorf("volume in use"))
}