Skip to content

Commit 618e00b

Browse files
author
Eugenio Grosso
committed
flasharray: fix delete() failing on snapshots due to invalid rename
ProviderAdapter.delete() is called for both volumes and snapshots; the adapter treated every target as a volume and applied the same rename-with-timestamp + destroy sequence. For snapshots this breaks twice: * FlashArray snapshots live at /volume-snapshots, not /volumes, so the PATCH request was going to the wrong endpoint. * The computed rename name (<volume>.<suffix>-<timestamp>) contains a literal "." character, which violates the array name rules: Volume name must be between 1 and 63 characters (alphanumeric, _ and -), begin and end with a letter or number, and include at least one letter, _, or -. Every CloudStack-side snapshot delete therefore failed with a 400 from the array, leaving orphan snapshots on both sides. Branch early when the data object is a snapshot: issue a single PATCH to /volume-snapshots with { destroyed: true } on the original name. No rename; the suffix the array assigns (e.g. ".1") already encodes the ordering and we cannot safely append anything to it. The 24h recycle bin still applies, so operators can recover a snapshot from the array within the retention window.
1 parent 139ca0c commit 618e00b

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

  • plugins/storage/volume/flasharray/src/main/java/org/apache/cloudstack/storage/datastore/adapter/flasharray

plugins/storage/volume/flasharray/src/main/java/org/apache/cloudstack/storage/datastore/adapter/flasharray/FlashArrayAdapter.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,30 @@ public void detach(ProviderAdapterContext context, ProviderAdapterDataObject dat
200200

201201
@Override
202202
public void delete(ProviderAdapterContext context, ProviderAdapterDataObject dataObject) {
203+
String fullName = normalizeName(pod, dataObject.getExternalName());
204+
205+
// Snapshots live under /volume-snapshots and have the reserved form
206+
// <volume>.<suffix>: the FlashArray rejects renames to any name that
207+
// includes '.' or is not pure alphanumeric+'_'+'-', so we cannot
208+
// tag them with a timestamp on the way out. Just mark them destroyed.
209+
if (dataObject.getType() == ProviderAdapterDataObject.Type.SNAPSHOT) {
210+
try {
211+
FlashArrayVolume destroy = new FlashArrayVolume();
212+
destroy.setDestroyed(true);
213+
PATCH("/volume-snapshots?names=" + fullName, destroy, new TypeReference<FlashArrayList<FlashArrayVolume>>() {
214+
});
215+
} catch (CloudRuntimeException e) {
216+
if (e.toString().contains("No such volume or snapshot")
217+
|| e.toString().contains("Volume does not exist")) {
218+
return;
219+
}
220+
throw e;
221+
}
222+
return;
223+
}
224+
203225
// first make sure we are disconnected
204226
removeVlunsAll(context, pod, dataObject.getExternalName());
205-
String fullName = normalizeName(pod, dataObject.getExternalName());
206227

207228
// Rename then destroy: FlashArray keeps destroyed volumes in a recycle
208229
// bin (default 24h) from which they can be recovered. Renaming with a

0 commit comments

Comments
 (0)