3232import org .apache .cloudstack .storage .datastore .db .StoragePoolDetailsDao ;
3333import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
3434import org .apache .cloudstack .storage .feign .client .SnapshotFeignClient ;
35+ import org .apache .cloudstack .storage .feign .model .CliSnapshotRestoreRequest ;
3536import org .apache .cloudstack .storage .feign .model .FlexVolSnapshot ;
36- import org .apache .cloudstack .storage .feign .model .SnapshotFileRestoreRequest ;
3737import org .apache .cloudstack .storage .feign .model .response .JobResponse ;
3838import org .apache .cloudstack .storage .feign .model .response .OntapResponse ;
3939import org .apache .cloudstack .storage .service .StorageStrategy ;
@@ -157,8 +157,10 @@ public StrategyPriority canHandle(VMSnapshot vmSnapshot) {
157157
158158 // For new snapshots, check if Disk-only and all volumes on ONTAP
159159 if (vmSnapshotVO .getType () != VMSnapshot .Type .Disk ) {
160- logger .error ("canHandle: ONTAP VM snapshot strategy cannot handle memory snapshots for VM [{}]" , vmSnapshot .getVmId ());
161- throw new CloudRuntimeException ("ONTAP VM snapshot strategy cannot handle memory snapshots for VM [" + vmSnapshot .getVmId () + "]" );
160+ // Memory snapshots are not supported by ONTAP strategy - return CANT_HANDLE
161+ // so other strategies can be tried or proper error handling can occur
162+ logger .debug ("canHandle: ONTAP VM snapshot strategy cannot handle memory snapshots for VM [{}]" , vmSnapshot .getVmId ());
163+ return StrategyPriority .CANT_HANDLE ;
162164 }
163165
164166 if (allVolumesOnOntapManagedStorage (vmSnapshot .getVmId ())) {
@@ -775,14 +777,14 @@ void deleteFlexVolSnapshots(List<VMSnapshotDetailsVO> flexVolDetails) {
775777 }
776778
777779 /**
778- * Reverts all volumes of a VM snapshot using ONTAP Snapshot File Restore.
780+ * Reverts all volumes of a VM snapshot using ONTAP CLI-based Snapshot File Restore.
779781 *
780782 * <p>Instead of restoring the entire FlexVolume to a snapshot (which would affect
781783 * other VMs/files on the same FlexVol), this method restores <b>only the individual
782- * files or LUNs</b> belonging to this VM using the dedicated ONTAP snapshot file
784+ * files or LUNs</b> belonging to this VM using the dedicated ONTAP CLI snapshot file
783785 * restore API:</p>
784786 *
785- * <p>{@code POST /api/storage/volumes/{ volume.uuid}/snapshots/{ snapshot.uuid}/files/{file.path}/ restore}</p>
787+ * <p>{@code POST /api/private/cli/ volume/ snapshot/ restore-file }</p>
786788 *
787789 * <p>For each persisted detail row (one per CloudStack volume):</p>
788790 * <ul>
@@ -806,31 +808,40 @@ void revertFlexVolSnapshots(List<VMSnapshotDetailsVO> flexVolDetails) {
806808 SnapshotFeignClient snapshotClient = storageStrategy .getSnapshotFeignClient ();
807809 String authHeader = storageStrategy .getAuthHeader ();
808810
809- // Prepare the file path for ONTAP API (ensure it starts with "/")
811+ // Get SVM name and FlexVolume name from pool details
812+ String svmName = poolDetails .get (Constants .SVM_NAME );
813+ String flexVolName = poolDetails .get (Constants .VOLUME_NAME );
814+
815+ if (svmName == null || svmName .isEmpty ()) {
816+ throw new CloudRuntimeException ("revertFlexVolSnapshots: SVM name not found in pool details for pool [" + detail .poolId + "]" );
817+ }
818+ if (flexVolName == null || flexVolName .isEmpty ()) {
819+ throw new CloudRuntimeException ("revertFlexVolSnapshots: FlexVolume name not found in pool details for pool [" + detail .poolId + "]" );
820+ }
821+
822+ // The path must start with "/" for the ONTAP CLI API
810823 String ontapFilePath = detail .volumePath .startsWith ("/" ) ? detail .volumePath : "/" + detail .volumePath ;
811824
812- logger .info ("revertFlexVolSnapshots: Restoring volume [{}] from FlexVol snapshot [{}] (uuid={}) on FlexVol [{}] (protocol={})" ,
813- ontapFilePath , detail .snapshotName , detail .snapshotUuid ,
814- detail .flexVolUuid , detail .protocol );
825+ logger .info ("revertFlexVolSnapshots: Restoring volume [{}] from FlexVol snapshot [{}] on FlexVol [{}] (protocol={})" ,
826+ ontapFilePath , detail .snapshotName , flexVolName , detail .protocol );
815827
816- // POST /api/storage/volumes/{vol}/snapshots/{snap}/files/{path}/ restore
817- // with body: { "destination_path": "<volumePath>" }
818- SnapshotFileRestoreRequest restoreRequest = new SnapshotFileRestoreRequest ( detail .volumePath );
828+ // Use CLI-based restore API: POST /api/private/cli/volume/snapshot/ restore-file
829+ CliSnapshotRestoreRequest restoreRequest = new CliSnapshotRestoreRequest (
830+ svmName , flexVolName , detail .snapshotName , ontapFilePath );
819831
820- JobResponse jobResponse = snapshotClient .restoreFileFromSnapshot (
821- authHeader , detail .flexVolUuid , detail .snapshotUuid , ontapFilePath , restoreRequest );
832+ JobResponse jobResponse = snapshotClient .restoreFileFromSnapshotCli (authHeader , restoreRequest );
822833
823834 if (jobResponse != null && jobResponse .getJob () != null ) {
824835 Boolean success = storageStrategy .jobPollForSuccess (jobResponse .getJob ().getUuid (), 60 , 2 );
825836 if (!success ) {
826837 throw new CloudRuntimeException ("Snapshot file restore failed for volume path [" +
827838 ontapFilePath + "] from snapshot [" + detail .snapshotName +
828- "] on FlexVol [" + detail . flexVolUuid + "]" );
839+ "] on FlexVol [" + flexVolName + "]" );
829840 }
830841 }
831842
832843 logger .info ("revertFlexVolSnapshots: Successfully restored volume [{}] from snapshot [{}] on FlexVol [{}]" ,
833- ontapFilePath , detail .snapshotName , detail . flexVolUuid );
844+ ontapFilePath , detail .snapshotName , flexVolName );
834845 }
835846 }
836847
0 commit comments