StorPool: fix of delete snapshot (#9855)

* StorPool: fix of delete snapshot

Mark the DB record as destroyed when a snapshot is deleted

* Addressed reviews

* addressed review

* addressed review
This commit is contained in:
slavkap 2024-11-04 13:52:02 +02:00 committed by GitHub
parent 019f2c60ce
commit be247334a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 26 deletions

View File

@ -138,6 +138,8 @@ public class StorPoolUtil {
public static final String SP_TIER = "SP_QOSCLASS"; public static final String SP_TIER = "SP_QOSCLASS";
public static final String OBJECT_DOES_NOT_EXIST = "objectDoesNotExist";
public static enum StorpoolRights { public static enum StorpoolRights {
RO("ro"), RW("rw"), DETACH("detach"); RO("ro"), RW("rw"), DETACH("detach");
@ -458,7 +460,7 @@ public class StorPoolUtil {
} }
private static boolean objectExists(SpApiError err) { private static boolean objectExists(SpApiError err) {
if (!err.getName().equals("objectDoesNotExist")) { if (!err.getName().equals(OBJECT_DOES_NOT_EXIST)) {
throw new CloudRuntimeException(err.getDescr()); throw new CloudRuntimeException(err.getDescr());
} }
return false; return false;

View File

@ -16,10 +16,19 @@
// under the License. // under the License.
package org.apache.cloudstack.storage.snapshot; package org.apache.cloudstack.storage.snapshot;
import java.util.ArrayList; import com.cloud.exception.InvalidParameterValueException;
import java.util.List; import com.cloud.hypervisor.kvm.storage.StorPoolStorageAdaptor;
import com.cloud.storage.DataStoreRole;
import javax.inject.Inject; import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.SnapshotDetailsDao;
import com.cloud.storage.dao.SnapshotDetailsVO;
import com.cloud.storage.dao.SnapshotZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@ -40,23 +49,13 @@ import org.apache.cloudstack.storage.datastore.util.StorPoolUtil;
import org.apache.cloudstack.storage.datastore.util.StorPoolUtil.SpApiResponse; import org.apache.cloudstack.storage.datastore.util.StorPoolUtil.SpApiResponse;
import org.apache.cloudstack.storage.datastore.util.StorPoolUtil.SpConnectionDesc; import org.apache.cloudstack.storage.datastore.util.StorPoolUtil.SpConnectionDesc;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.exception.InvalidParameterValueException; import javax.inject.Inject;
import com.cloud.hypervisor.kvm.storage.StorPoolStorageAdaptor; import java.util.ArrayList;
import com.cloud.storage.DataStoreRole; import java.util.List;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.SnapshotDetailsDao;
import com.cloud.storage.dao.SnapshotDetailsVO;
import com.cloud.storage.dao.SnapshotZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
@Component @Component
@ -117,10 +116,11 @@ public class StorPoolSnapshotStrategy implements SnapshotStrategy {
if (resp.getError() != null) { if (resp.getError() != null) {
final String err = String.format("Failed to clean-up Storpool snapshot %s. Error: %s", name, resp.getError()); final String err = String.format("Failed to clean-up Storpool snapshot %s. Error: %s", name, resp.getError());
StorPoolUtil.spLog(err); StorPoolUtil.spLog(err);
markSnapshotAsDestroyedIfAlreadyRemoved(snapshotId, resp); markSnapshotAsDestroyedIfAlreadyRemoved(snapshotId, resp.getError().getName().equals(StorPoolUtil.OBJECT_DOES_NOT_EXIST));
throw new CloudRuntimeException(err); throw new CloudRuntimeException(err);
} else { } else {
res = deleteSnapshotFromDbIfNeeded(snapshotVO, zoneId); res = deleteSnapshotFromDbIfNeeded(snapshotVO, zoneId);
markSnapshotAsDestroyedIfAlreadyRemoved(snapshotId,true);
StorPoolUtil.spLog("StorpoolSnapshotStrategy.deleteSnapshot: executed successfully=%s, snapshot uuid=%s, name=%s", res, snapshotVO.getUuid(), name); StorPoolUtil.spLog("StorpoolSnapshotStrategy.deleteSnapshot: executed successfully=%s, snapshot uuid=%s, name=%s", res, snapshotVO.getUuid(), name);
} }
} catch (Exception e) { } catch (Exception e) {
@ -129,15 +129,23 @@ public class StorPoolSnapshotStrategy implements SnapshotStrategy {
} }
} }
List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listBySnapshotIdAndState(snapshotId, State.Ready);
if (res || CollectionUtils.isEmpty(snapshots)) {
updateSnapshotToDestroyed(snapshotVO);
return true;
}
return res; return res;
} }
private void markSnapshotAsDestroyedIfAlreadyRemoved(Long snapshotId, SpApiResponse resp) { private void markSnapshotAsDestroyedIfAlreadyRemoved(Long snapshotId, boolean isSnapshotDeleted) {
if (resp.getError().getName().equals("objectDoesNotExist")) { if (!isSnapshotDeleted) {
SnapshotDataStoreVO snapshotOnPrimary = _snapshotStoreDao.findBySourceSnapshot(snapshotId, DataStoreRole.Primary); return;
if (snapshotOnPrimary != null) { }
snapshotOnPrimary.setState(State.Destroyed); List<SnapshotDataStoreVO> snapshotsOnStore = _snapshotStoreDao.listBySnapshotIdAndState(snapshotId, State.Ready);
_snapshotStoreDao.update(snapshotOnPrimary.getId(), snapshotOnPrimary); for (SnapshotDataStoreVO snapshot : snapshotsOnStore) {
if (snapshot.getInstallPath() != null && snapshot.getInstallPath().contains(StorPoolUtil.SP_DEV_PATH)) {
snapshot.setState(State.Destroyed);
_snapshotStoreDao.update(snapshot.getId(), snapshot);
} }
} }
} }