Compare commits

..
17 Commits
Author SHA1 Message Date
mergify[bot]andAndy Lee a6c60de2cb bump to 1.5.0 (#263) (#264)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit af43ebbf6f)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-23 17:13:34 +08:00
mergify[bot]andAndy Lee 843b388ede update RadioGroup update value action (#255) (#260)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 74300f24b3)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-17 15:29:06 +08:00
mergify[bot]andAndy Lee f2e8cce29f fix unable to detach PCI & USB device in VM edit page (#247) (#249)
* fix unable to detach PCI & USB device in VM edit page

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor based on comment

Signed-off-by: Andy Lee <andy.lee@suse.com>

* using set from shell/utils/object

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 2993ddb82c)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-16 16:13:12 +08:00
mergify[bot]andAndy Lee 31682dd165 bump to 1.5.0-rc5 (#245) (#246)
(cherry picked from commit a5d4604dce)
Signed-off-by: Andy Lee <andy.lee@suse.com>

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-16 14:44:54 +08:00
mergify[bot]andAndy Lee 9fac43d5e5 pass showYaml prop to prevent double generate secret (#243) (#244)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit daa6d6942b)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-15 16:08:09 +08:00
mergify[bot]andAndy Lee cd6ea6e402 Add logic to block import harvester version lower than 1.3.0 (#241) (#242)
* add logic to block import harvester version lower than 1.3.0

Signed-off-by: Andy Lee <andy.lee@suse.com>

* refactor console.error message

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit eb92642b3b)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-10 16:24:22 +08:00
mergify[bot]andAndy Lee 3bfe57dc54 filter golden image volume in hot plug volume modal (#239) (#240)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 78234b9e1e)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-10 13:27:23 +08:00
mergify[bot]andAndy Lee 089573f193 bump to 1.5.0-rc4 (#235) (#238)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 3dc6dda1ca)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-09 14:19:19 +08:00
mergify[bot]andAndy Lee 5d0c4f0c5a hide usb device tab in v1.3.x (#236) (#237)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit fca05d8489)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-09 14:04:30 +08:00
mergify[bot]andAndy Lee 57bb1e8562 Fix undefined error in VM edit as yaml page (#233) (#234)
* fix undefined error whenclick save in  edit as yaml

Signed-off-by: Andy Lee <andy.lee@suse.com>

* fix VM isEqual logic and fix undefined error

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 238c660796)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-07 15:33:36 +08:00
mergify[bot]andAndy Lee 30ff129691 fix secret name is different when edit as yaml (#230) (#232)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 19bea97106)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-07 10:56:49 +08:00
mergify[bot]andJack Yu 9175f16bfc chore: use default imag repo name (#212) (#231)
Signed-off-by: Jack Yu <jack.yu@suse.com>
(cherry picked from commit de4edbbf3b)

Co-authored-by: Jack Yu <jack.yu@suse.com>
2025-04-07 10:41:41 +08:00
mergify[bot]andAndy Lee 7c5e0f93d1 Bump ui-ext to 1.5.0-rc3 (#228) (#229)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 9256391627)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-04-02 16:03:13 +08:00
mergify[bot]andAndy Lee 8a7d3dffbe Fix error banner position in all dialogs (#226) (#227)
* fix error banner position in all dialogs

Signed-off-by: Andy Lee <andy.lee@suse.com>

* update HarvesterImageDownloader.vue

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 25439aee65)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-03-31 17:02:06 +08:00
b7810c5970 change longhorn v2 access mode to RWX (#223) (#225)
(cherry picked from commit f2fe1f5bd6)

Co-authored-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Yiya Chen <yiya.chen@suse.com>
2025-03-28 15:16:45 +08:00
mergify[bot]andAndy Lee 72dedd46d1 update to take VM snapshot logic (#222) (#224)
(cherry picked from commit f8d5aa1a21)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-03-28 15:13:46 +08:00
mergify[bot]andAndy Lee 24f716ab20 use harvester translation key forhost page CPU and memory (#220) (#221)
Signed-off-by: Andy Lee <andy.lee@suse.com>
(cherry picked from commit 38cf667830)

Co-authored-by: Andy Lee <andy.lee@suse.com>
2025-03-27 15:05:41 +08:00
38 changed files with 177 additions and 138 deletions
@@ -32,5 +32,4 @@ jobs:
with:
registry_target: docker.io
registry_user: rancher
repository_name: harvester-ui-catalog
secrets: inherit
+2 -13
View File
@@ -6,9 +6,6 @@ on:
registry_target:
required: true
type: string
repository_name:
required: true
type: string
registry_user:
required: true
type: string
@@ -69,13 +66,5 @@ jobs:
- name: Build and push UI image
run: |
publish="yarn publish-pkgs -c -r ${{ inputs.registry_target }} -o ${{ inputs.registry_user }}"
$publish
REPO_NAME=$(echo "${{ github.repository }}" | cut -d'/' -f2)
IMAGE_VERSION=$(cat package.json | jq .version | sed 's/"//g')
FULL_IMAGE_NAME=$(echo ${{ inputs.registry_target }}/${{ inputs.registry_user }}/ui-extension-$REPO_NAME:$IMAGE_VERSION)
IMAGE_ID=$(docker inspect --format='{{.Id}}' $FULL_IMAGE_NAME)
docker tag $IMAGE_ID ${{ inputs.registry_target }}/${{ inputs.registry_user }}/${{ inputs.repository_name }}:$IMAGE_VERSION
docker push ${{ inputs.registry_target }}/${{ inputs.registry_user }}/${{ inputs.repository_name }}:$IMAGE_VERSION
publish="yarn publish-pkgs -cp -r ${{ inputs.registry_target }} -o ${{ inputs.registry_user }}"
$publish
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "harvester-ui-extension",
"version": "1.5.0-rc2",
"version": "1.5.0",
"private": false,
"engines": {
"node": ">=20.0.0"
@@ -59,7 +59,7 @@ export default {
name="model"
:options="[true,false]"
:labels="[t('generic.enabled'), t('generic.disabled')]"
@input="update"
@update:value="update"
/>
<LabeledInput
@@ -138,6 +138,8 @@ export default {
<Banner
v-for="(error, i) in errors"
:key="i"
:label="error"
color="error"
/>
</div>
</template>
@@ -166,6 +166,8 @@ export default {
<Banner
v-for="(error, i) in errors"
:key="i"
:label="error"
color="error"
/>
</div>
</template>
+6 -7
View File
@@ -106,6 +106,12 @@ export default {
:label="t('harvester.modal.cloneVM.name')"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
:label="err"
color="error"
/>
</template>
<template #actions>
@@ -125,13 +131,6 @@ export default {
@click="create"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</div>
</template>
</Card>
@@ -57,6 +57,10 @@ export default {
if (!!pvc.metadata?.annotations?.[HCI_ANNOTATIONS.IMAGE_ID]) {
return false;
}
// we won't show golden image volume in the hot plug volume modal
if (pvc.isGoldenImageVolume) {
return false;
}
return !pvc.attachVM;
})
@@ -137,6 +141,12 @@ export default {
class="mt-20"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
:label="err"
color="error"
/>
</template>
<template #actions>
@@ -156,11 +166,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
@@ -103,6 +103,12 @@ export default {
:label="t('generic.name')"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -121,13 +127,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</div>
</template>
</Card>
@@ -120,6 +120,12 @@ export default {
v-model:value="description"
:label="t('harvester.modal.createTemplate.description')"
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -138,11 +144,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
@@ -128,6 +128,12 @@ export default {
<Banner color="warning">
<span>{{ t('harvester.modal.ejectCDROM.warnTip') }}</span>
</Banner>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -147,13 +153,6 @@ export default {
@click="remove"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</div>
</template>
</Card>
@@ -187,6 +187,12 @@ export default {
class="mt-20"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -205,11 +211,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
@@ -122,16 +122,15 @@ export default {
</Banner>
{{ t('harvester.modal.downloadImage.startMessage') }}
<br /><br />
</template>
<template #actions>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
>
{{ err }}
</Banner>
:label="err"
/>
</template>
<template #actions>
<div class="actions">
<div class="buttons">
<button
@@ -161,6 +161,12 @@ export default {
:placeholder="t('harvester.modal.migration.fields.nodeName.placeholder')"
:options="nodeNameList"
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template
@@ -181,12 +187,6 @@ export default {
@click="apply"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
</Card>
</template>
@@ -96,6 +96,12 @@ export default {
:suffix="GIBIBYTE"
class="mb-20"
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -109,12 +115,6 @@ export default {
</button>
<AsyncButton @click="save" />
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</div>
</template>
</Card>
@@ -136,6 +136,12 @@ export default {
:options="backupOption"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -154,11 +160,6 @@ export default {
@click="saveRestore"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
@@ -90,6 +90,12 @@ export default {
v-clean-html="t('harvester.virtualMachine.unplug.title', { name: diskName })"
class="text-default-text"
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -111,13 +117,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</div>
</template>
</Card>
@@ -132,6 +132,12 @@ export default {
:label="t('generic.name')"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -150,11 +156,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
@@ -107,6 +107,12 @@ export default {
:placeholder="t('harvester.harvesterVlanConfigMigrateDialog.targetClusterNetwork.placeholder')"
:options="clusterNetworks"
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -125,11 +131,6 @@ export default {
@click="apply"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
+6 -6
View File
@@ -70,16 +70,16 @@ export default {
v-clean-html="t('harvester.modal.restart.tip')"
class="pl-10 pr-10"
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
<div class="bottom">
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
<div class="buttons">
<button
class="btn role-secondary mr-10"
@@ -145,6 +145,12 @@ export default {
class="mt-20"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -162,10 +168,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
+6 -6
View File
@@ -79,6 +79,12 @@ export default {
:label="t('harvester.modal.snapshot.name')"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -96,12 +102,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</div>
</template>
</Card>
+6 -4
View File
@@ -98,6 +98,12 @@ export default {
:label="t('harvester.modal.volumeClone.name')"
required
/>
<Banner
v-for="(err, i) in errors"
:key="i"
color="error"
:label="err"
/>
</template>
<template #actions>
@@ -115,10 +121,6 @@ export default {
@click="save"
/>
</div>
<Banner
v-for="(err, i) in errors"
:key="i"
/>
</div>
</template>
</Card>
@@ -233,7 +233,7 @@ export default {
:disabled="isEdit || isView"
:mode="mode"
row
@input="onTypeChange"
@update:value="onTypeChange"
/>
</div>
<div class="row mb-30">
@@ -307,10 +307,10 @@ export default {
const storageClassName = this.value.spec.storageClassName;
const storageClass = this.storageClasses.find((sc) => sc.name === storageClassName);
let readWriteOnce = this.value.isLvm || this.value.isLonghornV2;
let readWriteOnce = this.value.isLvm || (!this.value.thirdPartyStorageFeatureEnabled && this.value.isLonghornV2);
if (storageClass) {
readWriteOnce = storageClass.provisioner === LVM_DRIVER || storageClass.parameters?.dataEngine === DATA_ENGINE_V2;
readWriteOnce = storageClass.provisioner === LVM_DRIVER || (!this.value.thirdPartyStorageFeatureEnabled && storageClass.parameters?.dataEngine === DATA_ENGINE_V2);
}
return readWriteOnce ? ['ReadWriteOnce'] : ['ReadWriteMany'];
@@ -97,7 +97,7 @@ export default {
});
const devices = [
...this.otherDevices(this.value.domain.devices.hostDevices || []),
...this.otherDevices(this.value?.domain?.devices?.hostDevices || []),
...formatted,
];
@@ -121,7 +121,9 @@ export default {
return inUse;
}
vm.hostDevices.forEach((device) => {
const hostDevices = vm?.hostDevices || [];
hostDevices.forEach((device) => {
inUse[device.name] = { usedBy: [vm.metadata.name] };
});
@@ -80,7 +80,7 @@ export default {
});
const devices = [
...this.otherDevices(this.value.domain.devices.hostDevices || []),
...this.otherDevices(this.value?.domain?.devices?.hostDevices || []),
...formatted,
];
@@ -121,7 +121,9 @@ export default {
return inUse;
}
vm.hostDevices.forEach((device) => {
const hostDevices = vm?.hostDevices || [];
hostDevices.forEach((device) => {
inUse[device.name] = { usedBy: [vm.metadata.name] };
});
@@ -111,7 +111,7 @@ export default {
return false;
}
if (pvc.metadata?.annotations?.[HCI_ANNOTATIONS.GOLDEN_IMAGE] === 'true') {
if (pvc.isGoldenImageVolume) {
return false;
}
@@ -201,10 +201,10 @@ export default {
const storageClass = this.storageClasses.find((sc) => sc.name === storageClassName);
let readWriteOnce = this.value.pvc?.isLvm || this.value.pvc?.isLonghornV2;
let readWriteOnce = this.value.pvc?.isLvm || (!this.thirdPartyStorageClassEnabled && this.value.pvc?.isLonghornV2);
if (storageClass) {
readWriteOnce = storageClass.provisioner === LVM_DRIVER || storageClass.parameters?.dataEngine === DATA_ENGINE_V2;
readWriteOnce = storageClass.provisioner === LVM_DRIVER || (!this.thirdPartyStorageClassEnabled && storageClass.parameters?.dataEngine === DATA_ENGINE_V2);
}
return readWriteOnce ? 'ReadWriteOnce' : 'ReadWriteMany';
@@ -2,6 +2,7 @@
import { isEqual } from 'lodash';
import { mapGetters } from 'vuex';
import Tabbed from '@shell/components/Tabbed';
import { clone, set } from '@shell/utils/object';
import Tab from '@shell/components/Tabbed/Tab';
import { Checkbox } from '@components/Form/Checkbox';
import CruResource from '@shell/components/CruResource';
@@ -15,9 +16,7 @@ import PodAffinity from '@shell/components/form/PodAffinity';
import VGpuDevices from './VirtualMachineVGpuDevices/index';
import UsbDevices from './VirtualMachineUSBDevices/index';
import KeyValue from '@shell/components/form/KeyValue';
import { clear } from '@shell/utils/array';
import { clone } from '@shell/utils/object';
import { saferDump } from '@shell/utils/create-yaml';
import { exceptionToErrorsArray } from '@shell/utils/error';
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
@@ -212,7 +211,10 @@ export default {
}
return false;
}
},
usbPassthroughEnabled() {
return this.$store.getters['harvester-common/getFeatureEnabled']('usbPassthrough');
},
},
watch: {
@@ -409,13 +411,26 @@ export default {
}
const cloneDeepNewVM = clone(this.value);
// new VM
delete cloneDeepNewVM?.metadata;
delete cloneDeepNewVM?.__clone;
// old VM
delete this.cloneVM?.metadata;
delete this.cloneVM?.__clone;
// add empty hostDevices to old VM as CRD does not have it.
const devicesObj = this.cloneVM?.spec?.template?.spec?.domain?.devices;
if (devicesObj && devicesObj.hostDevices === undefined) {
set(devicesObj, 'hostDevices', []);
}
const oldVM = JSON.parse(JSON.stringify(this.cloneVM));
const newVM = JSON.parse(JSON.stringify(cloneDeepNewVM));
// we won't show restart dialog in yaml page as we don't have a way to detect change in yaml editor.
// only check VM is changed in form page.
if (isEqual(oldVM, newVM)) {
return;
}
@@ -424,7 +439,11 @@ export default {
this.isOpen = true;
this.$nextTick(() => {
this.$refs.restartDialog.resolve = resolve;
if (this?.$refs?.restartDialog) {
this.$refs.restartDialog.resolve = resolve;
} else {
return resolve();
}
});
});
},
@@ -474,6 +493,7 @@ export default {
},
generateYaml() {
this.showYaml = this?.$refs?.vmCruResource?.showYaml || false;
this.parseVM();
const out = saferDump(this.value);
@@ -487,6 +507,7 @@ export default {
<CruResource
v-if="spec"
id="vm"
ref="vmCruResource"
:done-route="doneRoute"
:resource="value"
:cancel-event="true"
@@ -674,7 +695,7 @@ export default {
</Tab>
<Tab
v-if="enabledPCI"
v-if="enabledPCI && usbPassthroughEnabled"
:label="t('harvester.tab.usbDevices')"
name="usbDevices"
:weight="-7"
@@ -65,7 +65,7 @@ export default {
:labels="[t('generic.disabled'),t('generic.enabled')]"
:options="[false, true]"
:disabled="disabled"
@input="onToggle"
@update:value="onToggle"
/>
</div>
</div>
+2 -2
View File
@@ -101,14 +101,14 @@ export default {
const metricCol = [
{
name: 'cpu',
labelKey: 'node.detail.glance.consumptionGauge.cpu',
labelKey: 'harvester.dashboard.hardwareResourceGauge.cpu',
value: 'id',
formatter: 'HarvesterCPUUsed',
formatterOpts: { showUsed: true },
},
{
name: 'memory',
labelKey: 'node.detail.glance.consumptionGauge.memory',
labelKey: 'harvester.dashboard.hardwareResourceGauge.memory',
value: 'id',
formatter: 'HarvesterMemoryUsed',
formatterOpts: { showUsed: true },
@@ -6,10 +6,8 @@ import {
} from '@shell/config/types';
import { STATE, AGE, NAME, NAMESPACE } from '@shell/config/table-headers';
import HarvesterVolumeState from '../formatters/HarvesterVolumeState';
import { allSettled } from '../utils/promise';
import { HCI, VOLUME_SNAPSHOT } from '../types';
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
const schema = {
id: HCI.VOLUME,
@@ -72,7 +70,7 @@ export default {
},
filterRows() {
// we only show the non golden image PVCs in the list
return this.rows.filter((pvc) => pvc?.metadata?.annotations?.[HCI_ANNOTATIONS.GOLDEN_IMAGE] !== 'true');
return this.rows.filter((pvc) => !pvc?.isGoldenImageVolume);
},
headers() {
return [
+4 -3
View File
@@ -140,6 +140,7 @@ export default {
return {
OS,
isClone,
showYaml: false,
spec: null,
osType: 'linux',
sshKey: [],
@@ -269,7 +270,7 @@ export default {
needNewSecret() {
// When creating a template it is always necessary to create a new secret.
return this.resourceType === HCI.VM_VERSION || this.isCreate;
return this.showYaml ? false : this.resourceType === HCI.VM_VERSION || this.isCreate;
},
defaultTerminationSetting() {
@@ -669,7 +670,7 @@ export default {
}
});
if (!this.secretName || this.needNewSecret) {
if (this.needNewSecret || !this.secretName) {
this.secretName = this.generateSecretName(this.secretNamePrefix);
}
@@ -871,7 +872,7 @@ export default {
}
}
if (out.length === 0 && !!this.spec.template.spec.accessCredentials) {
if (out.length === 0 && !!this.spec.template.spec.accessCredentials === false) {
delete this.spec.template.spec.accessCredentials;
} else {
this.spec.template.spec.accessCredentials = out;
@@ -344,6 +344,10 @@ export default class HciPv extends HarvesterResource {
return this.dataEngine === DATA_ENGINE_V2;
}
get isGoldenImageVolume() {
return this?.metadata?.annotations?.[HCI_ANNOTATIONS.GOLDEN_IMAGE] === 'true';
}
get thirdPartyStorageFeatureEnabled() {
return this.$rootGetters['harvester-common/getFeatureEnabled']('thirdPartyStorage');
}
@@ -158,7 +158,7 @@ export default class VirtVm extends HarvesterResource {
},
{
action: 'takeVMSnapshot',
enabled: !!this.actions?.backup && !this.longhornV2Volumes.length,
enabled: (!!this.actions?.snapshot || !!this.action?.backup) && !this.longhornV2Volumes.length,
icon: 'icon icon-snapshot',
label: this.t('harvester.action.vmSnapshot')
},
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "harvester",
"description": "Rancher UI Extension for Harvester",
"version": "1.5.0-rc2",
"version": "1.5.0",
"private": false,
"rancher": {
"annotations": {
+10
View File
@@ -35,7 +35,17 @@ function latestMinorVersion(v) {
}
export const featureEnabled = (featureKey, serverVersion) => {
const minSupportedVersion = '1.3.0';
const version = getVersion(serverVersion);
if (semver.lt(version.replace('v', ''), minSupportedVersion)) {
// eslint-disable-next-line no-console
console.error(`Harvester UI extension only supports Harvester cluster version >= ${ minSupportedVersion }. Current version: ${ version }`);
return false;
}
let releasedFeatures = RELEASE_FEATURES[version];
if (!releasedFeatures) {