Browse Source

Merge pull request #44360 from neersighted/backport_44224

[22.06 backport] Fix force-remove for cluster volumes
Sebastiaan van Stijn 2 năm trước cách đây
mục cha
commit
cbaf1808cb

+ 10 - 5
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

+ 10 - 2
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"))
 	}