This is an automated email from the ASF dual-hosted git repository.
sureshanaparti pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.20 by this push:
new d72a05aa5ad Add special Icon to Shared FileSystem Instances (#10857)
d72a05aa5ad is described below
commit d72a05aa5adb29952a3eb7eeef0c95d535e09768
Author: Abhisar Sinha <[email protected]>
AuthorDate: Wed Jul 23 11:21:59 2025 +0530
Add special Icon to Shared FileSystem Instances (#10857)
* Use special icon for sharedfs instance and prefix for sharedfs volumes
* Give custom icon precedence over shared fs icon
* Fix sharedfsvm icon size
* Fix UT failure in StorageVmSharedFSLifeCycleTest
---
.../lifecycle/StorageVmSharedFSLifeCycle.java | 25 +++++++++++++++++-----
.../lifecycle/StorageVmSharedFSLifeCycleTest.java | 11 +++++++---
ui/src/components/view/InfoCard.vue | 7 +++++-
ui/src/components/view/ListView.vue | 7 +++++-
4 files changed, 40 insertions(+), 10 deletions(-)
diff --git
a/plugins/storage/sharedfs/storagevm/src/main/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycle.java
b/plugins/storage/sharedfs/storagevm/src/main/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycle.java
index 31159e7d3d9..ed26963cf81 100644
---
a/plugins/storage/sharedfs/storagevm/src/main/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycle.java
+++
b/plugins/storage/sharedfs/storagevm/src/main/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycle.java
@@ -140,13 +140,18 @@ public class StorageVmSharedFSLifeCycle implements
SharedFSLifeCycle {
return fsVmConfig;
}
- private String getStorageVmName(String fileShareName) {
+ private String getStorageVmPrefix(String fileShareName) {
String prefix = String.format("%s-%s", SharedFSVmNamePrefix,
fileShareName);
- String suffix = Long.toHexString(System.currentTimeMillis());
-
if (!NetUtils.verifyDomainNameLabel(prefix, true)) {
prefix = prefix.replaceAll("[^a-zA-Z0-9-]", "");
}
+ return prefix;
+ }
+
+ private String getStorageVmName(String fileShareName) {
+ String prefix = getStorageVmPrefix(fileShareName);
+ String suffix = Long.toHexString(System.currentTimeMillis());
+
int nameLength = prefix.length() + suffix.length() +
SharedFSVmNamePrefix.length();
if (nameLength > 63) {
int prefixLength = prefix.length() - (nameLength - 63);
@@ -236,8 +241,18 @@ public class StorageVmSharedFSLifeCycle implements
SharedFSLifeCycle {
Account owner =
accountMgr.getActiveAccountById(sharedFS.getAccountId());
UserVm vm = deploySharedFSVM(sharedFS.getDataCenterId(), owner,
List.of(networkId), sharedFS.getName(), sharedFS.getServiceOfferingId(),
diskOfferingId, sharedFS.getFsType(), size, minIops, maxIops);
- List<VolumeVO> volumes = volumeDao.findByInstanceAndType(vm.getId(),
Volume.Type.DATADISK);
- return new Pair<>(volumes.get(0).getId(), vm.getId());
+ List<VolumeVO> volumes = volumeDao.findByInstance(vm.getId());
+ VolumeVO dataVol = null;
+ for (VolumeVO vol : volumes) {
+ String volumeName = vol.getName();
+ String updatedVolumeName = SharedFSVmNamePrefix + "-" + volumeName;
+ vol.setName(updatedVolumeName);
+ volumeDao.update(vol.getId(), vol);
+ if (vol.getVolumeType() == Volume.Type.DATADISK) {
+ dataVol = vol;
+ }
+ }
+ return new Pair<>(dataVol.getId(), vm.getId());
}
@Override
diff --git
a/plugins/storage/sharedfs/storagevm/src/test/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycleTest.java
b/plugins/storage/sharedfs/storagevm/src/test/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycleTest.java
index 4393b0565f8..2cc909ce0d7 100644
---
a/plugins/storage/sharedfs/storagevm/src/test/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycleTest.java
+++
b/plugins/storage/sharedfs/storagevm/src/test/java/org/apache/cloudstack/storage/sharedfs/lifecycle/StorageVmSharedFSLifeCycleTest.java
@@ -260,9 +260,14 @@ public class StorageVmSharedFSLifeCycleTest {
anyMap(), isNull(), isNull(), isNull(), isNull(),
anyBoolean(), anyString(), isNull())).thenReturn(vm);
- VolumeVO volume = mock(VolumeVO.class);
- when(volume.getId()).thenReturn(s_volumeId);
- when(volumeDao.findByInstanceAndType(s_vmId,
Volume.Type.DATADISK)).thenReturn(List.of(volume));
+ VolumeVO rootVol = mock(VolumeVO.class);
+ when(rootVol.getVolumeType()).thenReturn(Volume.Type.ROOT);
+ when(rootVol.getName()).thenReturn("ROOT-1");
+ VolumeVO dataVol = mock(VolumeVO.class);
+ when(dataVol.getId()).thenReturn(s_volumeId);
+ when(dataVol.getName()).thenReturn("DATA-1");
+ when(dataVol.getVolumeType()).thenReturn(Volume.Type.DATADISK);
+ when(volumeDao.findByInstance(s_vmId)).thenReturn(List.of(rootVol,
dataVol));
Pair<Long, Long> result = lifeCycle.deploySharedFS(sharedFS,
s_networkId, s_diskOfferingId, s_size, s_minIops, s_maxIops);
Assert.assertEquals(Optional.ofNullable(result.first()),
Optional.ofNullable(s_volumeId));
diff --git a/ui/src/components/view/InfoCard.vue
b/ui/src/components/view/InfoCard.vue
index 2ad7b96602f..d467665ed5f 100644
--- a/ui/src/components/view/InfoCard.vue
+++ b/ui/src/components/view/InfoCard.vue
@@ -34,6 +34,9 @@
<span v-if="(resource.icon && resource.icon.base64image ||
images.template || images.iso || resourceIcon) && !['router', 'systemvm',
'volume'].includes($route.path.split('/')[1])">
<resource-icon :image="getImage(resource.icon &&
resource.icon.base64image || images.template || images.iso || resourceIcon)"
size="4x" style="margin-right: 5px"/>
</span>
+ <span v-else-if="resource.vmtype === 'sharedfsvm'">
+ <file-text-outlined style="font-size: 36px;" />
+ </span>
<span v-else>
<os-logo v-if="resource.ostypeid || resource.ostypename
|| ['guestoscategory'].includes($route.path.split('/')[1])"
:osId="resource.ostypeid" :osName="resource.ostypename || resource.name"
size="3x" @update-osname="setResourceOsType"/>
<render-icon v-else-if="typeof $route.meta.icon
==='string'" style="font-size: 36px" :icon="$route.meta.icon" />
@@ -876,6 +879,7 @@ import UploadResourceIcon from
'@/components/view/UploadResourceIcon'
import eventBus from '@/config/eventBus'
import ResourceIcon from '@/components/view/ResourceIcon'
import ResourceLabel from '@/components/widgets/ResourceLabel'
+import { FileTextOutlined } from '@ant-design/icons-vue'
export default {
name: 'InfoCard',
@@ -887,7 +891,8 @@ export default {
TooltipButton,
UploadResourceIcon,
ResourceIcon,
- ResourceLabel
+ ResourceLabel,
+ FileTextOutlined
},
props: {
resource: {
diff --git a/ui/src/components/view/ListView.vue
b/ui/src/components/view/ListView.vue
index 3d41e01bb1c..eca99dc0346 100644
--- a/ui/src/components/view/ListView.vue
+++ b/ui/src/components/view/ListView.vue
@@ -44,6 +44,9 @@
<span v-if="record.icon && record.icon.base64image">
<resource-icon :image="record.icon.base64image" size="2x"/>
</span>
+ <span v-else-if="record.vmtype === 'sharedfsvm'">
+ <file-text-outlined style="font-size: 18px;" />
+ </span>
<os-logo v-else :osId="record.ostypeid"
:osName="record.osdisplayname" size="xl" />
</span>
<span style="min-width: 120px" >
@@ -591,6 +594,7 @@ import { createPathBasedOnVmType } from '@/utils/plugins'
import { validateLinks } from '@/utils/links'
import cronstrue from 'cronstrue/i18n'
import moment from 'moment-timezone'
+import { FileTextOutlined } from '@ant-design/icons-vue'
export default {
name: 'ListView',
@@ -601,7 +605,8 @@ export default {
CopyLabel,
TooltipButton,
ResourceIcon,
- ResourceLabel
+ ResourceLabel,
+ FileTextOutlined
},
props: {
columns: {