-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CloudStack Volume support with ONTAP storage #13053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
4c8c8d9
bf838b3
b82fb40
1199d55
ebc3f00
28faca1
fe0f752
35f1011
a03a2c4
2e0efe8
a96eb9e
0f09c5f
2cc4b0c
033c23d
2822946
f7b837a
c585299
a492797
25353c2
973f5e2
686a892
edfcdde
73eb9f5
465fffe
3d6bd91
5815ebd
618f957
6c4b24e
1b0c7f7
54ddfa9
b23ac40
2c61e76
e99b98e
ef0354a
2f02d8a
1ae738b
890c2db
2d3b279
8a2c7fb
b26542f
856c5cc
7c2b229
763aa3b
eace4ee
f42552b
8894248
3f0019a
9b79f46
7a0d61e
7c3419e
d2b6a27
c5d5428
3f18c11
723561b
09968db
0a1a9c4
49df4c3
776b9a2
c04e223
186e59b
1020a2c
672d7a4
9c63c61
79730ed
ae96e9b
1b0bba9
7780a93
5bff41f
2abbed6
2340400
ce93705
e1a6465
9138e20
5f9e51c
142e0e6
aa74a5a
55447b7
fccaf83
ea40967
a41eb28
7d08878
4a62d40
a6e4b49
b58fd24
0f5370a
ddb119f
929d30f
a20b6cc
9748198
cddacd1
34e910c
c86d377
199c463
11c937d
a0234e4
cc9a6fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,6 +83,7 @@ | |
| import org.apache.cloudstack.storage.to.TemplateObjectTO; | ||
| import org.apache.cloudstack.storage.to.VolumeObjectTO; | ||
| import org.apache.commons.collections.CollectionUtils; | ||
| import org.apache.commons.lang3.ObjectUtils; | ||
| import org.apache.commons.lang3.StringUtils; | ||
| import org.apache.logging.log4j.Logger; | ||
| import org.apache.logging.log4j.LogManager; | ||
|
|
@@ -1340,6 +1341,11 @@ private void createManagedVolumeCopyTemplateAsync(VolumeInfo volumeInfo, Primary | |
| primaryDataStore.setDetails(details); | ||
|
|
||
| grantAccess(volumeInfo, destHost, primaryDataStore); | ||
| volumeInfo = volFactory.getVolume(volumeInfo.getId(), primaryDataStore); | ||
| // For Netapp ONTAP iscsiName or Lun path is available only after grantAccess | ||
| String managedStoreTarget = ObjectUtils.defaultIfNull(volumeInfo.get_iScsiName(), volumeInfo.getUuid()); | ||
| details.put(PrimaryDataStore.MANAGED_STORE_TARGET, managedStoreTarget); | ||
| primaryDataStore.setDetails(details); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this set be done inside There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @winterhazel No — these are different details. The map here is the in-memory transport details on PrimaryDataStoreImpl (serialized into PrimaryDataStoreTO for the agent's CopyCommand), not the DB-persisted storage pool details. org.apache.cloudstack.storage.driver.OntapPrimaryDatastoreDriver#grantAccess can only work on db details. |
||
|
|
||
| try { | ||
| motionSrv.copyAsync(srcTemplateInfo, destTemplateInfo, destHost, caller); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -106,6 +106,10 @@ protected Answer takeDiskOnlyVmSnapshotOfRunningVm(CreateDiskOnlyVmSnapshotComma | |
| return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, errorMsg, null); | ||
| } | ||
| return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, e.getMessage(), null); | ||
| } catch (Exception e) { | ||
| String errorMsg = String.format("Creation of disk-only VM snapshot for VM [%s] failed due to %s.", vmName, e.getMessage()); | ||
| logger.error(errorMsg, e); | ||
| return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, errorMsg, null); | ||
| } finally { | ||
| if (dm != null) { | ||
| try { | ||
|
|
@@ -146,21 +150,13 @@ protected Answer takeDiskOnlyVmSnapshotOfStoppedVm(CreateDiskOnlyVmSnapshotComma | |
| } | ||
| } catch (LibvirtException | QemuImgException e) { | ||
| logger.error("Exception while creating disk-only VM snapshot for VM [{}]. Deleting leftover deltas.", vmName, e); | ||
| for (VolumeObjectTO volumeObjectTO : volumeObjectTos) { | ||
| Pair<Long, String> volSizeAndNewPath = mapVolumeToSnapshotSizeAndNewVolumePath.get(volumeObjectTO.getUuid()); | ||
| PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) volumeObjectTO.getDataStore(); | ||
| KVMStoragePool kvmStoragePool = storagePoolMgr.getStoragePool(primaryDataStoreTO.getPoolType(), primaryDataStoreTO.getUuid()); | ||
|
|
||
| if (volSizeAndNewPath == null) { | ||
| continue; | ||
| } | ||
| try { | ||
| Files.deleteIfExists(Path.of(kvmStoragePool.getLocalPathFor(volSizeAndNewPath.second()))); | ||
| } catch (IOException ex) { | ||
| logger.warn("Tried to delete leftover snapshot at [{}] failed.", volSizeAndNewPath.second(), ex); | ||
| } | ||
| } | ||
| cleanupLeftoverDeltas(volumeObjectTos, mapVolumeToSnapshotSizeAndNewVolumePath, storagePoolMgr); | ||
| return new Answer(cmd, e); | ||
| } catch (Exception e) { | ||
| logger.error("Unexpected exception while creating disk-only VM snapshot for VM [{}]. Deleting leftover deltas.", vmName, e); | ||
| cleanupLeftoverDeltas(volumeObjectTos, mapVolumeToSnapshotSizeAndNewVolumePath, storagePoolMgr); | ||
| return new CreateDiskOnlyVmSnapshotAnswer(cmd, false, | ||
| String.format("Creation of disk-only VM snapshot for VM [%s] failed due to %s.", vmName, e.getMessage()), null); | ||
|
Comment on lines
+155
to
+159
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be unified with the catch block above?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @winterhazel, I added this logic separately after encountering failures in negative scenarios where the UI did not surface any error details. With this change, users are now notified of the failure reason when the exception falls outside the scope of the existing catch block. This is expected to improve overall user experience. Please let me know if you still feel this should be removed. |
||
| } | ||
|
|
||
| return new CreateDiskOnlyVmSnapshotAnswer(cmd, true, null, mapVolumeToSnapshotSizeAndNewVolumePath); | ||
|
|
@@ -192,6 +188,23 @@ protected Pair<String, Map<String, Pair<Long, String>>> createSnapshotXmlAndNewV | |
| return new Pair<>(snapshotXml, volumeObjectToNewPathMap); | ||
| } | ||
|
|
||
| protected void cleanupLeftoverDeltas(List<VolumeObjectTO> volumeObjectTos, Map<String, Pair<Long, String>> mapVolumeToSnapshotSizeAndNewVolumePath, KVMStoragePoolManager storagePoolMgr) { | ||
| for (VolumeObjectTO volumeObjectTO : volumeObjectTos) { | ||
| Pair<Long, String> volSizeAndNewPath = mapVolumeToSnapshotSizeAndNewVolumePath.get(volumeObjectTO.getUuid()); | ||
| PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) volumeObjectTO.getDataStore(); | ||
| KVMStoragePool kvmStoragePool = storagePoolMgr.getStoragePool(primaryDataStoreTO.getPoolType(), primaryDataStoreTO.getUuid()); | ||
|
|
||
| if (volSizeAndNewPath == null) { | ||
| continue; | ||
| } | ||
| try { | ||
| Files.deleteIfExists(Path.of(kvmStoragePool.getLocalPathFor(volSizeAndNewPath.second()))); | ||
| } catch (IOException ex) { | ||
| logger.warn("Tried to delete leftover snapshot at [{}] failed.", volSizeAndNewPath.second(), ex); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| protected long getFileSize(String path) { | ||
| return new File(path).length(); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This constant is declared in 3 places. Perhaps we could create a file in a single common dependency (maybe cloud-api) to declare the plugin names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@winterhazel I did not find any suitable place in cloud-api for keeping this constant, It would be helpful if you could point out some place to keep this constant.