Skip to content

Commit

Permalink
Reserved storage size in the dashboard isn't useful
Browse files Browse the repository at this point in the history
... display allocated/scheduled storage instead.

Relates to: harvester/harvester#6362

Signed-off-by: Volker Theile <vtheile@suse.com>
  • Loading branch information
votdev committed Aug 21, 2024
1 parent b97bf06 commit 008d334
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ export default {
<HarvesterStorageUsed
:row="value"
:resource-name="t('harvester.host.detail.storage')"
:show-reserved="true"
:show-allocated="true"
/>
</div>
</div>
Expand Down
110 changes: 59 additions & 51 deletions pkg/harvester/formatters/HarvesterStorageUsed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,102 +23,110 @@ export default {
default: ''
},
showReserved: {
showAllocated: {
type: Boolean,
default: false,
},
},
data() {
return {};
async fetch() {
const inStore = this.$store.getters['currentProduct'].inStore;
this.longhornSettings = await this.$store.dispatch(`${ inStore }/findAll`, { type: LONGHORN.SETTINGS });
},
computed: {
usage() {
const inStore = this.$store.getters['currentProduct'].inStore;
const longhornNode = this.$store.getters[`${ inStore }/byId`](LONGHORN.NODES, `longhorn-system/${ this.row.id }`) || {};
data() {
const inStore = this.$store.getters['currentProduct'].inStore;
const longhornSettings = this.$store.getters[`${ inStore }/all`](LONGHORN.SETTINGS) || [];
return longhornNode?.used || 0;
},
return { longhornSettings };
},
reserved() {
computed: {
storageInfo() {
const out = {
used: 0,
scheduled: 0,
maximum: 0,
reserved: 0
};
const inStore = this.$store.getters['currentProduct'].inStore;
const longhornNode = this.$store.getters[`${ inStore }/byId`](LONGHORN.NODES, `longhorn-system/${ this.row.id }`);
let reserved = 0;
const node = this.$store.getters[`${ inStore }/byId`](LONGHORN.NODES, `longhorn-system/${ this.row.id }`) || {};
const disks = node?.spec?.disks || {};
const diskStatus = node?.status?.diskStatus || {};
const disks = longhornNode?.spec?.disks || {};
out.used += node?.spec?.allowScheduling ? node.used : 0;
Object.values(disks).map((disk) => {
if (disk.allowScheduling) {
reserved += disk.storageReserved;
}
Object.keys(disks).map((key) => {
out.scheduled += node?.spec?.allowScheduling ? (diskStatus[key]?.storageScheduled || 0) : 0;
out.reserved += disks[key]?.storageReserved || 0;
});
Object.values(diskStatus).map((diskStat) => {
out.maximum += diskStat?.storageMaximum || 0;
});
return reserved;
return out;
},
total() {
const inStore = this.$store.getters['currentProduct'].inStore;
const longhornNode = this.$store.getters[`${ inStore }/byId`](LONGHORN.NODES, `longhorn-system/${ this.row.id }`);
let out = 0;
const diskStatus = longhornNode?.status?.diskStatus || {};
totalAllocated() {
const setting = this.longhornSettings.find(s => s.id === 'longhorn-system/storage-over-provisioning-percentage');
const storageInfo = this.storageInfo;
Object.values(diskStatus).map((disk) => {
if (disk?.storageMaximum) {
out += disk.storageMaximum;
}
});
return out;
return ((storageInfo.maximum - storageInfo.reserved) * Number(setting?.value ?? 0)) / 100;
},
units() {
const exponent = exponentNeeded(this.total, 1024);
const storageInfo = this.storageInfo;
const exponent = exponentNeeded(storageInfo.maximum, 1024);
return `${ UNITS[exponent] }iB`;
},
used() {
let out = this.formatter(this.usage || 0);
const storageInfo = this.storageInfo;
let out = this.formatter(storageInfo.used);
if (!Number.parseFloat(out) > 0) {
out = this.formatter(this.usage || 0, { canRoundToZero: false });
out = this.formatter(storageInfo.used, { canRoundToZero: false });
}
return out;
},
formatReserved() {
let out = this.formatter(this.reserved || 0);
formatAllocated() {
const storageInfo = this.storageInfo;
let out = this.formatter(storageInfo.scheduled);
if (!Number.parseFloat(out) > 0) {
out = this.formatter(this.reserved || 0, { canRoundToZero: false });
out = this.formatter(storageInfo.scheduled, { canRoundToZero: false });
}
return out;
},
usedAmountTemplateValues() {
const storageInfo = this.storageInfo;
return {
used: this.used,
total: this.formatter(this.total || 0),
total: this.formatter(storageInfo.maximum),
unit: this.units,
};
},
reservedAmountTemplateValues() {
allocatedAmountTemplateValues() {
return {
used: this.formatReserved,
total: this.formatter(this.total || 0),
used: this.formatAllocated,
total: this.formatter(this.totalAllocated),
unit: this.units,
};
},
},
methods: {
formatter(value, format) {
const minExponent = exponentNeeded(this.total, 1024);
const storageInfo = this.storageInfo;
const minExponent = exponentNeeded(storageInfo.maximum, 1024);
const formatOptions = {
addSuffix: false,
increment: 1024,
Expand All @@ -137,21 +145,21 @@ export default {
<template>
<div>
<div
v-if="showReserved"
v-if="showAllocated"
>
<ConsumptionGauge
:capacity="total"
:used="reserved"
:capacity="totalAllocated"
:used="storageInfo.scheduled"
:units="units"
:number-formatter="formatter"
:resource-name="resourceName"
>
<template #title="{formattedPercentage}">
<span>
{{ t('clusterIndexPage.hardwareResourceGauge.reserved') }}
{{ t('clusterIndexPage.hardwareResourceGauge.allocated') }}
</span>
<span class="precent-data">
{{ t('node.detail.glance.consumptionGauge.amount', reservedAmountTemplateValues) }}
{{ t('node.detail.glance.consumptionGauge.amount', allocatedAmountTemplateValues) }}
<span class="ml-10 percentage">
/&nbsp;{{ formattedPercentage }}
</span>
Expand All @@ -160,13 +168,13 @@ export default {
</ConsumptionGauge>
</div>
<ConsumptionGauge
:capacity="total"
:used="usage"
:capacity="storageInfo.maximum"
:used="storageInfo.used"
:units="units"
:number-formatter="formatter"
:resource-name="showReserved ? '' : resourceName"
:resource-name="showAllocated ? '' : resourceName"
:class="{
'mt-10': showReserved,
'mt-10': showAllocated,
}"
>
<template #title="{formattedPercentage}">
Expand Down
97 changes: 46 additions & 51 deletions pkg/harvester/list/harvesterhci.io.dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,16 @@ export default {
const inStore = this.$store.getters['currentProduct'].inStore;
const hash = {
vms: this.fetchClusterResources(HCI.VM),
nodes: this.fetchClusterResources(NODE),
events: this.fetchClusterResources(EVENT),
metricNodes: this.fetchClusterResources(METRIC.NODE),
settings: this.fetchClusterResources(HCI.SETTING),
services: this.fetchClusterResources(SERVICE),
metric: this.fetchClusterResources(METRIC.NODE),
longhornNode: this.fetchClusterResources(LONGHORN.NODES) || [],
_pods: this.$store.dispatch('harvester/findAll', { type: POD }),
vms: this.fetchClusterResources(HCI.VM),
nodes: this.fetchClusterResources(NODE),
events: this.fetchClusterResources(EVENT),
metricNodes: this.fetchClusterResources(METRIC.NODE),
settings: this.fetchClusterResources(HCI.SETTING),
services: this.fetchClusterResources(SERVICE),
metric: this.fetchClusterResources(METRIC.NODE),
longhornNodes: this.fetchClusterResources(LONGHORN.NODES),
longhornSettings: this.fetchClusterResources(LONGHORN.SETTINGS),
_pods: this.$store.dispatch('harvester/findAll', { type: POD }),
};
(this.accessibleResources || []).map((a) => {
Expand All @@ -155,6 +156,10 @@ export default {
hash.addons = this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.ADD_ONS });
}
if (this.$store.getters[`${ inStore }/schemaFor`](LONGHORN.NODES)) {
this.hasLonghornSchema = true;
}
const res = await allHash(hash);
for ( const k in res ) {
Expand Down Expand Up @@ -226,6 +231,7 @@ export default {
showClusterMetrics: false,
showVmMetrics: false,
enabledMonitoringAddon: false,
hasLonghornSchema: false,
};
},
Expand Down Expand Up @@ -305,8 +311,7 @@ export default {
currentVersion() {
const inStore = this.$store.getters['currentProduct'].inStore;
const settings = this.$store.getters[`${ inStore }/all`](HCI.SETTING);
const setting = settings.find( S => S.id === 'server-version');
const setting = this.$store.getters[`${ inStore }/byId`](HCI.SETTING, 'server-version');
return setting?.value || setting?.default;
},
Expand Down Expand Up @@ -364,53 +369,42 @@ export default {
return out;
},
storageUsage() {
const inStore = this.$store.getters['currentProduct'].inStore;
const longhornNodes = this.$store.getters[`${ inStore }/all`](LONGHORN.NODES) || [];
return longhornNodes.filter(node => node.spec?.allowScheduling).reduce((total, node) => {
return total + node.used;
}, 0);
},
storageReservedTotal() {
let out = 0;
(this.longhornNode || []).filter(node => node.spec?.allowScheduling).forEach((node) => {
storageInfo() {
return this.longhornNodes.reduce((total, node) => {
const disks = node?.spec?.disks || {};
Object.values(disks).map((disk) => {
if (disk.allowScheduling) {
out += disk.storageReserved;
}
});
});
return out;
},
storageTotal() {
let out = 0;
(this.longhornNode || []).forEach((node) => {
const diskStatus = node?.status?.diskStatus || {};
Object.values(diskStatus).map((disk) => {
if (disk?.storageMaximum) {
out += disk.storageMaximum;
}
total.used += node?.spec?.allowScheduling ? node.used : 0;
Object.keys(disks).map((key) => {
total.scheduled += node?.spec?.allowScheduling ? (diskStatus[key]?.storageScheduled || 0) : 0;
total.reserved += disks[key]?.storageReserved || 0;
});
Object.values(diskStatus).map((diskStat) => {
total.maximum += diskStat?.storageMaximum || 0;
});
});
return out;
return total;
}, {
used: 0,
scheduled: 0,
maximum: 0,
reserved: 0
});
},
storageUsed() {
return this.createMemoryValues(this.storageTotal, this.storageUsage);
const storageInfo = this.storageInfo;
return this.createMemoryValues(storageInfo.maximum, storageInfo.used);
},
storageReserved() {
return this.createMemoryValues(this.storageTotal, this.storageReservedTotal);
storageAllocated() {
const setting = this.longhornSettings.find(s => s.id === 'longhorn-system/storage-over-provisioning-percentage');
const storageInfo = this.storageInfo;
const total = ((storageInfo.maximum - storageInfo.reserved) * Number(setting.value)) / 100;
return this.createMemoryValues(total, storageInfo.scheduled);
},
vmEvents() {
Expand Down Expand Up @@ -646,7 +640,7 @@ export default {
<div
class="hardware-resource-gauges"
:class="{
live: !storageTotal,
live: !hasLonghornSchema,
}"
>
<HardwareResourceGauge
Expand All @@ -660,10 +654,11 @@ export default {
:used="ramUsed"
/>
<HardwareResourceGauge
v-if="storageTotal"
v-if="hasLonghornSchema"
:name="t('harvester.dashboard.hardwareResourceGauge.storage')"
:used="storageUsed"
:reserved="storageReserved"
:reserved="storageAllocated"
:reserved-title="t('clusterIndexPage.hardwareResourceGauge.allocated')"
/>
</div>
</template>
Expand Down
2 changes: 1 addition & 1 deletion pkg/harvester/list/harvesterhci.io.host.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default {
labelKey: 'tableHeaders.storage',
value: 'id',
formatter: 'HarvesterStorageUsed',
formatterOpts: { showReserved: true },
formatterOpts: { showAllocated: true },
};
out.splice(-1, 0, storageHeader);
Expand Down
1 change: 1 addition & 0 deletions shell/assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,7 @@ clusterIndexPage:
ram: Memory
used: Used
reserved: Reserved
allocated: Allocated
units:
cores: |-
{count, plural,
Expand Down
Loading

0 comments on commit 008d334

Please sign in to comment.