mirror of
https://github.com/harvester/harvester-ui-extension.git
synced 2026-10-08 15:16:07 +08:00
Compare commits
37
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8a0885fe6 | ||
|
|
a0f21d5902 | ||
|
|
f0929100f0 | ||
|
|
78ca4bb663 | ||
|
|
eb917c9d18 | ||
|
|
8815c70361 | ||
|
|
eb4c0504c8 | ||
|
|
82e7b0da19 | ||
|
|
92f34fa64f | ||
|
|
6039f21320 | ||
|
|
3cbaf97399 | ||
|
|
bcde1744e1 | ||
|
|
e991c9bcc8 | ||
|
|
6e709bc00f | ||
|
|
20d40860ce | ||
|
|
1496c17f3d | ||
|
|
e99e4ef34f | ||
|
|
73e022172b | ||
|
|
7e86c9fae0 | ||
|
|
b4b49222c3 | ||
|
|
b937a2147b | ||
|
|
07f2b02a9d | ||
|
|
35b6949cdc | ||
|
|
c577f589e7 | ||
|
|
b1387820ed | ||
|
|
45f72749f5 | ||
|
|
a65b3f443e | ||
|
|
21d415b5f3 | ||
|
|
7493fe2dfc | ||
|
|
e71d12f67f | ||
|
|
d3b77e2e41 | ||
|
|
73126b953c | ||
|
|
937afd9c9a | ||
|
|
3658caf067 | ||
|
|
a067751cba | ||
|
|
94566b2b54 | ||
|
|
d47bf1d712 |
@@ -6,7 +6,6 @@ on:
|
|||||||
- main
|
- main
|
||||||
- 'release-harvester-v*'
|
- 'release-harvester-v*'
|
||||||
- '*-dev'
|
- '*-dev'
|
||||||
- new_review_page
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
@@ -29,4 +28,8 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
id-token: write
|
id-token: write
|
||||||
with:
|
with:
|
||||||
|
<<<<<<< HEAD
|
||||||
CI_BRANCH: ${{github.ref_name}}
|
CI_BRANCH: ${{github.ref_name}}
|
||||||
|
=======
|
||||||
|
CI_BRANCH: ${{ github.event_name == 'push' && github.ref_name || '' }}
|
||||||
|
>>>>>>> 719c33f (ci: fix CI_BRANCH ternary so PR builds skip upload gate (#1062))
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "harvester-ui-extension",
|
"name": "harvester-ui-extension",
|
||||||
"version": "1.10.0-dev",
|
"version": "1.9.0-rc3",
|
||||||
"private": false,
|
"private": false,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=24.0.0"
|
"node": ">=24.0.0"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const {
|
|||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
skipTlsVerify,
|
skipTlsVerify,
|
||||||
|
vddkInitImage,
|
||||||
testPassed,
|
testPassed,
|
||||||
testResult,
|
testResult,
|
||||||
testError,
|
testError,
|
||||||
@@ -97,6 +98,7 @@ watch(selectedProvider, (val) => {
|
|||||||
username.value = '';
|
username.value = '';
|
||||||
password.value = '';
|
password.value = '';
|
||||||
skipTlsVerify.value = false;
|
skipTlsVerify.value = false;
|
||||||
|
vddkInitImage.value = '';
|
||||||
createdProvider.value = null;
|
createdProvider.value = null;
|
||||||
createdSecret.value = null;
|
createdSecret.value = null;
|
||||||
} else {
|
} else {
|
||||||
@@ -107,6 +109,7 @@ watch(selectedProvider, (val) => {
|
|||||||
if (provider) {
|
if (provider) {
|
||||||
providerName.value = provider.metadata.name;
|
providerName.value = provider.metadata.name;
|
||||||
url.value = provider.spec?.url || '';
|
url.value = provider.spec?.url || '';
|
||||||
|
vddkInitImage.value = provider.spec?.settings?.vddkInitImage || '';
|
||||||
|
|
||||||
const secretRef = provider.spec?.secret;
|
const secretRef = provider.spec?.secret;
|
||||||
|
|
||||||
@@ -239,6 +242,18 @@ const testConnection = async(buttonCb) => {
|
|||||||
if (props.editMode && createdProvider.value) {
|
if (props.editMode && createdProvider.value) {
|
||||||
try {
|
try {
|
||||||
createdProvider.value.spec.url = url.value;
|
createdProvider.value.spec.url = url.value;
|
||||||
|
|
||||||
|
const vddkImage = vddkInitImage.value?.trim();
|
||||||
|
|
||||||
|
if (vddkImage) {
|
||||||
|
createdProvider.value.spec.settings = {
|
||||||
|
...(createdProvider.value.spec.settings || {}),
|
||||||
|
vddkInitImage: vddkImage,
|
||||||
|
};
|
||||||
|
} else if (createdProvider.value.spec.settings) {
|
||||||
|
delete createdProvider.value.spec.settings.vddkInitImage;
|
||||||
|
}
|
||||||
|
|
||||||
await createdProvider.value.save();
|
await createdProvider.value.save();
|
||||||
|
|
||||||
const secretRef = createdProvider.value.spec?.secret;
|
const secretRef = createdProvider.value.spec?.secret;
|
||||||
@@ -283,20 +298,28 @@ const testConnection = async(buttonCb) => {
|
|||||||
const namespace = FORKLIFT_NAMESPACE;
|
const namespace = FORKLIFT_NAMESPACE;
|
||||||
const secretName = `${ providerName.value }-creds-${ randomStr(4).toLowerCase() }`;
|
const secretName = `${ providerName.value }-creds-${ randomStr(4).toLowerCase() }`;
|
||||||
|
|
||||||
|
const spec = {
|
||||||
|
type: 'vsphere',
|
||||||
|
url: url.value,
|
||||||
|
secret: {
|
||||||
|
name: secretName,
|
||||||
|
namespace,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vddkImage = vddkInitImage.value?.trim();
|
||||||
|
|
||||||
|
if (vddkImage) {
|
||||||
|
spec.settings = { vddkInitImage: vddkImage };
|
||||||
|
}
|
||||||
|
|
||||||
const provider = await store.dispatch(`${ inStore }/create`, {
|
const provider = await store.dispatch(`${ inStore }/create`, {
|
||||||
type: HCI.FORKLIFT_PROVIDER,
|
type: HCI.FORKLIFT_PROVIDER,
|
||||||
metadata: {
|
metadata: {
|
||||||
name: providerName.value,
|
name: providerName.value,
|
||||||
namespace,
|
namespace,
|
||||||
},
|
},
|
||||||
spec: {
|
spec,
|
||||||
type: 'vsphere',
|
|
||||||
url: url.value,
|
|
||||||
secret: {
|
|
||||||
name: secretName,
|
|
||||||
namespace,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await provider.save();
|
await provider.save();
|
||||||
@@ -420,17 +443,28 @@ defineExpose({ testConnection, clickTestButton });
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="row">
|
||||||
<LabeledInput
|
<div class="col span-6">
|
||||||
v-model:value="url"
|
<LabeledInput
|
||||||
:label="t('harvester.addons.vmMigration.configureProvider.urlLabel')"
|
v-model:value="url"
|
||||||
:placeholder="t('harvester.addons.vmMigration.configureProvider.urlPlaceholder')"
|
:label="t('harvester.addons.vmMigration.configureProvider.urlLabel')"
|
||||||
:disabled="isExistingProvider && !editMode"
|
:placeholder="t('harvester.addons.vmMigration.configureProvider.urlPlaceholder')"
|
||||||
required
|
:disabled="isExistingProvider && !editMode"
|
||||||
/>
|
required
|
||||||
<p class="text-deemphasized mt-5">
|
/>
|
||||||
{{ t('harvester.addons.vmMigration.configureProvider.urlHint') }}
|
<p class="text-deemphasized mt-5">
|
||||||
</p>
|
{{ t('harvester.addons.vmMigration.configureProvider.urlHint') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col span-6">
|
||||||
|
<LabeledInput
|
||||||
|
v-model:value="vddkInitImage"
|
||||||
|
:label="t('harvester.addons.vmMigration.configureProvider.vddkImageLabel')"
|
||||||
|
:placeholder="t('harvester.addons.vmMigration.configureProvider.vddkImagePlaceholder')"
|
||||||
|
:tooltip="t('harvester.addons.vmMigration.configureProvider.vddkImageTooltip')"
|
||||||
|
:disabled="isExistingProvider && !editMode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ const storageMappings = ref([]);
|
|||||||
const planName = ref('');
|
const planName = ref('');
|
||||||
const targetNamespace = ref('');
|
const targetNamespace = ref('');
|
||||||
const namespaceOptions = ref([]);
|
const namespaceOptions = ref([]);
|
||||||
|
const existingProviderNames = ref([]);
|
||||||
|
const existingPlanNames = ref([]);
|
||||||
const errors = ref([]);
|
const errors = ref([]);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
|
||||||
@@ -44,6 +46,24 @@ targetNamespace.value = props.stepData.targetNamespace || '';
|
|||||||
|
|
||||||
const NS = FORKLIFT_NAMESPACE;
|
const NS = FORKLIFT_NAMESPACE;
|
||||||
|
|
||||||
|
const nameConflictError = computed(() => {
|
||||||
|
const name = (planName.value || '').trim();
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingProviderNames.value.includes(name)) {
|
||||||
|
return t('harvester.addons.vmMigration.reviewMigration.planNameProviderConflict', { name });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingPlanNames.value.includes(name)) {
|
||||||
|
return t('harvester.addons.vmMigration.reviewMigration.planNamePlanConflict', { name });
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
watch(planName, (val) => {
|
watch(planName, (val) => {
|
||||||
props.stepData.planName = val;
|
props.stepData.planName = val;
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
@@ -52,8 +72,8 @@ watch(targetNamespace, (val) => {
|
|||||||
props.stepData.targetNamespace = val;
|
props.stepData.targetNamespace = val;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch([planName, targetNamespace], ([name, namespace]) => {
|
watch([planName, targetNamespace, nameConflictError], () => {
|
||||||
emit('ready', !!name && !!namespace);
|
emit('ready', !!planName.value && !!targetNamespace.value && !nameConflictError.value);
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
const formatNetworkTarget = (target = '') => {
|
const formatNetworkTarget = (target = '') => {
|
||||||
@@ -282,6 +302,22 @@ const init = async() => {
|
|||||||
namespaceOptions.value = [];
|
namespaceOptions.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await store.dispatch(`${ inStore }/findAll`, { type: HCI.FORKLIFT_PROVIDER });
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
existingProviderNames.value = (store.getters[`${ inStore }/all`](HCI.FORKLIFT_PROVIDER) || [])
|
||||||
|
.map((p) => p.metadata?.name)
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await store.dispatch(`${ inStore }/findAll`, { type: HCI.FORKLIFT_PLAN });
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
existingPlanNames.value = (store.getters[`${ inStore }/all`](HCI.FORKLIFT_PLAN) || [])
|
||||||
|
.map((p) => p.metadata?.name)
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
if (props.mappingEntries) {
|
if (props.mappingEntries) {
|
||||||
networkMappings.value = (props.mappingEntries.networkEntries || []).map((entry) => ({
|
networkMappings.value = (props.mappingEntries.networkEntries || []).map((entry) => ({
|
||||||
source: entry.name || entry.id,
|
source: entry.name || entry.id,
|
||||||
@@ -313,6 +349,12 @@ defineExpose({ startMigration: startMigrationAction });
|
|||||||
<div
|
<div
|
||||||
class="review-migration-content"
|
class="review-migration-content"
|
||||||
>
|
>
|
||||||
|
<Banner
|
||||||
|
v-if="nameConflictError"
|
||||||
|
color="error"
|
||||||
|
:label="nameConflictError"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Migration Details Summary -->
|
<!-- Migration Details Summary -->
|
||||||
<div class="migration-details">
|
<div class="migration-details">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
|
|||||||
@@ -15,13 +15,6 @@ export const VOLUME_MODE = {
|
|||||||
FILE_SYSTEM: 'Filesystem'
|
FILE_SYSTEM: 'Filesystem'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ACCESS_MODE = {
|
|
||||||
READ_WRITE_MANY: 'ReadWriteMany',
|
|
||||||
READ_WRITE_ONCE: 'ReadWriteOnce',
|
|
||||||
READ_ONLY_MANY: 'ReadOnlyMany',
|
|
||||||
READ_WRITE_ONCE_POD: 'ReadWriteOncePod',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const NETWORK_PROTOCOL = {
|
export const NETWORK_PROTOCOL = {
|
||||||
IPv4: 'IPv4',
|
IPv4: 'IPv4',
|
||||||
IPv6: 'IPv6',
|
IPv6: 'IPv6',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { VOLUME_MODE, ACCESS_MODE } from '@pkg/harvester/config/types';
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
|
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
|
||||||
import ArrayList from '@shell/components/form/ArrayList';
|
import ArrayList from '@shell/components/form/ArrayList';
|
||||||
import { Checkbox } from '@components/Form/Checkbox';
|
import { Checkbox } from '@components/Form/Checkbox';
|
||||||
@@ -10,10 +10,6 @@ import { HCI_SETTING } from '../../config/settings';
|
|||||||
import { allHash } from '@shell/utils/promise';
|
import { allHash } from '@shell/utils/promise';
|
||||||
import { _EDIT, _CREATE } from '@shell/config/query-params';
|
import { _EDIT, _CREATE } from '@shell/config/query-params';
|
||||||
|
|
||||||
const {
|
|
||||||
READ_WRITE_ONCE, READ_ONLY_MANY, READ_WRITE_MANY, READ_WRITE_ONCE_POD
|
|
||||||
} = ACCESS_MODE;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CDISettings',
|
name: 'CDISettings',
|
||||||
|
|
||||||
@@ -94,10 +90,10 @@ export default {
|
|||||||
|
|
||||||
accessModeOptions() {
|
accessModeOptions() {
|
||||||
return [
|
return [
|
||||||
{ label: READ_WRITE_ONCE, value: READ_WRITE_ONCE },
|
{ label: 'ReadWriteOnce', value: 'ReadWriteOnce' },
|
||||||
{ label: READ_ONLY_MANY, value: READ_ONLY_MANY },
|
{ label: 'ReadOnlyMany', value: 'ReadOnlyMany' },
|
||||||
{ label: READ_WRITE_MANY, value: READ_WRITE_MANY },
|
{ label: 'ReadWriteMany', value: 'ReadWriteMany' },
|
||||||
{ label: READ_WRITE_ONCE_POD, value: READ_WRITE_ONCE_POD },
|
{ label: 'ReadWriteOncePod', value: 'ReadWriteOncePod' },
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,9 @@ import { HCI, VOLUME_SNAPSHOT } from '../types';
|
|||||||
import { LVM_DRIVER } from '../models/harvester/storage.k8s.io.storageclass';
|
import { LVM_DRIVER } from '../models/harvester/storage.k8s.io.storageclass';
|
||||||
import { DATA_ENGINE_V2 } from '../models/harvester/persistentvolumeclaim';
|
import { DATA_ENGINE_V2 } from '../models/harvester/persistentvolumeclaim';
|
||||||
import { GIBIBYTE } from '../utils/unit';
|
import { GIBIBYTE } from '../utils/unit';
|
||||||
import { VOLUME_MODE, ACCESS_MODE } from '@pkg/harvester/config/types';
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
import { isInternalStorageClass } from '../utils/storage-class';
|
import { isInternalStorageClass } from '../utils/storage-class';
|
||||||
|
|
||||||
const { READ_WRITE_MANY, READ_WRITE_ONCE, READ_ONLY_MANY } = ACCESS_MODE;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HarvesterVolume',
|
name: 'HarvesterVolume',
|
||||||
|
|
||||||
@@ -85,7 +83,7 @@ export default {
|
|||||||
if (this.mode === _CREATE) {
|
if (this.mode === _CREATE) {
|
||||||
// default volumeMode to Block
|
// default volumeMode to Block
|
||||||
this.value.spec.volumeMode = VOLUME_MODE.BLOCK;
|
this.value.spec.volumeMode = VOLUME_MODE.BLOCK;
|
||||||
this.value.spec.accessModes = [READ_WRITE_MANY];
|
this.value.spec.accessModes = ['ReadWriteMany'];
|
||||||
}
|
}
|
||||||
|
|
||||||
const storage = this.value?.spec?.resources?.requests?.storage || null;
|
const storage = this.value?.spec?.resources?.requests?.storage || null;
|
||||||
@@ -162,7 +160,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
accessModeOptions() {
|
accessModeOptions() {
|
||||||
return [READ_WRITE_ONCE, READ_WRITE_MANY, READ_ONLY_MANY];
|
return ['ReadWriteOnce', 'ReadWriteMany', 'ReadOnlyMany'];
|
||||||
},
|
},
|
||||||
|
|
||||||
imageOption() {
|
imageOption() {
|
||||||
@@ -357,7 +355,7 @@ export default {
|
|||||||
|
|
||||||
getAccessMode() {
|
getAccessMode() {
|
||||||
if (!this.longhornV2LVMSupport) {
|
if (!this.longhornV2LVMSupport) {
|
||||||
return [READ_WRITE_MANY];
|
return ['ReadWriteMany'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.value?.spec?.accessModes && this.value?.spec?.accessModes?.length > 0) {
|
if (this.value?.spec?.accessModes && this.value?.spec?.accessModes?.length > 0) {
|
||||||
@@ -373,7 +371,7 @@ export default {
|
|||||||
readWriteOnce = storageClass.provisioner === LVM_DRIVER || (!this.value.thirdPartyStorageFeatureEnabled && storageClass.parameters?.dataEngine === DATA_ENGINE_V2);
|
readWriteOnce = storageClass.provisioner === LVM_DRIVER || (!this.value.thirdPartyStorageFeatureEnabled && storageClass.parameters?.dataEngine === DATA_ENGINE_V2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return readWriteOnce ? [READ_WRITE_ONCE] : [READ_WRITE_MANY];
|
return readWriteOnce ? ['ReadWriteOnce'] : ['ReadWriteMany'];
|
||||||
},
|
},
|
||||||
buildDataVolumeObj() {
|
buildDataVolumeObj() {
|
||||||
const storage = {
|
const storage = {
|
||||||
|
|||||||
@@ -16,12 +16,10 @@ import { PLUGIN_DEVELOPER, DEV } from '@shell/store/prefs';
|
|||||||
import { VOLUME_HOTPLUG_ACTION, SOURCE_TYPE } from '../../../config/harvester-map';
|
import { VOLUME_HOTPLUG_ACTION, SOURCE_TYPE } from '../../../config/harvester-map';
|
||||||
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../../config/harvester';
|
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../../../config/harvester';
|
||||||
import { HCI } from '../../../types';
|
import { HCI } from '../../../types';
|
||||||
import { VOLUME_MODE, ACCESS_MODE } from '@pkg/harvester/config/types';
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
import { OFF } from '../../../models/kubevirt.io.virtualmachine';
|
import { OFF } from '../../../models/kubevirt.io.virtualmachine';
|
||||||
import { EMPTY_IMAGE } from '../../../utils/vm';
|
import { EMPTY_IMAGE } from '../../../utils/vm';
|
||||||
|
|
||||||
const { READ_WRITE_MANY } = ACCESS_MODE;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['update:value'],
|
emits: ['update:value'],
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ export default {
|
|||||||
|
|
||||||
customAccessMode: {
|
customAccessMode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: READ_WRITE_MANY
|
default: 'ReadWriteMany'
|
||||||
},
|
},
|
||||||
|
|
||||||
resourceType: {
|
resourceType: {
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import { LVM_DRIVER } from '../../../../models/harvester/storage.k8s.io.storagec
|
|||||||
import { DATA_ENGINE_V2 } from '../../../../models/harvester/persistentvolumeclaim';
|
import { DATA_ENGINE_V2 } from '../../../../models/harvester/persistentvolumeclaim';
|
||||||
import { GIBIBYTE } from '../../../../utils/unit';
|
import { GIBIBYTE } from '../../../../utils/unit';
|
||||||
import { isInternalStorageClass } from '../../../../utils/storage-class';
|
import { isInternalStorageClass } from '../../../../utils/storage-class';
|
||||||
import { VOLUME_MODE, ACCESS_MODE } from '@pkg/harvester/config/types';
|
import { VOLUME_MODE } from '@pkg/harvester/config/types';
|
||||||
|
|
||||||
const { READ_WRITE_MANY, READ_WRITE_ONCE } = ACCESS_MODE;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HarvesterEditVolume',
|
name: 'HarvesterEditVolume',
|
||||||
@@ -207,7 +205,7 @@ export default {
|
|||||||
|
|
||||||
getAccessMode(storageClassName) {
|
getAccessMode(storageClassName) {
|
||||||
if (!this.longhornV2LVMSupport) {
|
if (!this.longhornV2LVMSupport) {
|
||||||
return READ_WRITE_MANY;
|
return 'ReadWriteMany';
|
||||||
}
|
}
|
||||||
|
|
||||||
const storageClass = this.storageClasses.find((sc) => sc.name === storageClassName);
|
const storageClass = this.storageClasses.find((sc) => sc.name === storageClassName);
|
||||||
@@ -218,7 +216,7 @@ export default {
|
|||||||
readWriteOnce = storageClass.provisioner === LVM_DRIVER || (!this.thirdPartyStorageClassEnabled && storageClass.parameters?.dataEngine === DATA_ENGINE_V2);
|
readWriteOnce = storageClass.provisioner === LVM_DRIVER || (!this.thirdPartyStorageClassEnabled && storageClass.parameters?.dataEngine === DATA_ENGINE_V2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return readWriteOnce ? READ_WRITE_ONCE : READ_WRITE_MANY;
|
return readWriteOnce ? 'ReadWriteOnce' : 'ReadWriteMany';
|
||||||
},
|
},
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
|
|||||||
@@ -1898,6 +1898,9 @@ harvester:
|
|||||||
urlLabel: vCenter/ESXi URL
|
urlLabel: vCenter/ESXi URL
|
||||||
urlPlaceholder: "https://vcenter.example.com/sdk"
|
urlPlaceholder: "https://vcenter.example.com/sdk"
|
||||||
urlHint: Enter the full URL including https://
|
urlHint: Enter the full URL including https://
|
||||||
|
vddkImageLabel: VMware VDDK Image
|
||||||
|
vddkImagePlaceholder: "[your-private-registry]/vddk-image:latest"
|
||||||
|
vddkImageTooltip: Specify the VMware VDDK (Virtual Disk Development Kit) Image to accelerate and optimize VMware virtual machine migration.
|
||||||
skipSsl: Skip SSL certificate verification
|
skipSsl: Skip SSL certificate verification
|
||||||
skipSslHint: Not recommended for production environments
|
skipSslHint: Not recommended for production environments
|
||||||
testConnection:
|
testConnection:
|
||||||
@@ -1984,6 +1987,8 @@ harvester:
|
|||||||
description: Confirm your migration settings before starting the transfer of VMs to the target cluster.
|
description: Confirm your migration settings before starting the transfer of VMs to the target cluster.
|
||||||
planName: Name
|
planName: Name
|
||||||
planNamePlaceholder: "e.g. my-migration-plan"
|
planNamePlaceholder: "e.g. my-migration-plan"
|
||||||
|
planNameProviderConflict: 'The name “{name}” is already used by an existing provider. Please input a different plan name.'
|
||||||
|
planNamePlanConflict: 'The name “{name}” is already used by an existing migration plan. Please input a different plan name.'
|
||||||
migrationDetails: Migration Details
|
migrationDetails: Migration Details
|
||||||
migrationDetailsDescription: Name this plan and choose the namespace where migrated VMs will be created.
|
migrationDetailsDescription: Name this plan and choose the namespace where migrated VMs will be created.
|
||||||
totalVms: Total VMs
|
totalVms: Total VMs
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ import { HCI } from '../../types';
|
|||||||
import { parseVolumeClaimTemplates, EMPTY_IMAGE } from '../../utils/vm';
|
import { parseVolumeClaimTemplates, EMPTY_IMAGE } from '../../utils/vm';
|
||||||
import impl, { QGA_JSON, USB_TABLET } from './impl';
|
import impl, { QGA_JSON, USB_TABLET } from './impl';
|
||||||
import { GIBIBYTE } from '../../utils/unit';
|
import { GIBIBYTE } from '../../utils/unit';
|
||||||
import { VOLUME_MODE, ACCESS_MODE, FILESYSTEM_SOURCE_TYPE } from '@pkg/harvester/config/types';
|
import { VOLUME_MODE, FILESYSTEM_SOURCE_TYPE } from '@pkg/harvester/config/types';
|
||||||
|
|
||||||
const { READ_WRITE_MANY } = ACCESS_MODE;
|
|
||||||
|
|
||||||
const LONGHORN_V2_DATA_ENGINE = 'longhorn-system/v2-data-engine';
|
const LONGHORN_V2_DATA_ENGINE = 'longhorn-system/v2-data-engine';
|
||||||
|
|
||||||
@@ -278,7 +276,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
customAccessMode() {
|
customAccessMode() {
|
||||||
return this.storageClassSetting.accessModes || READ_WRITE_MANY;
|
return this.storageClassSetting.accessModes || 'ReadWriteMany';
|
||||||
},
|
},
|
||||||
|
|
||||||
isWindows() {
|
isWindows() {
|
||||||
@@ -506,7 +504,7 @@ export default {
|
|||||||
id: randomStr(5),
|
id: randomStr(5),
|
||||||
source: SOURCE_TYPE.IMAGE,
|
source: SOURCE_TYPE.IMAGE,
|
||||||
name: 'disk-0',
|
name: 'disk-0',
|
||||||
accessMode: READ_WRITE_MANY, // root disk only support LHv1 volume, should be RWX
|
accessMode: 'ReadWriteMany', // root disk only support LHv1 volume, should be RWX
|
||||||
bus,
|
bus,
|
||||||
volumeName: '',
|
volumeName: '',
|
||||||
size,
|
size,
|
||||||
@@ -572,7 +570,7 @@ export default {
|
|||||||
const pvcResource = allPVCs.find( (O) => O.id === `${ namespace }/${ volume?.persistentVolumeClaim?.claimName }`);
|
const pvcResource = allPVCs.find( (O) => O.id === `${ namespace }/${ volume?.persistentVolumeClaim?.claimName }`);
|
||||||
|
|
||||||
source = SOURCE_TYPE.ATTACH_VOLUME;
|
source = SOURCE_TYPE.ATTACH_VOLUME;
|
||||||
accessMode = pvcResource?.spec?.accessModes?.[0] || READ_WRITE_MANY;
|
accessMode = pvcResource?.spec?.accessModes?.[0] || 'ReadWriteMany';
|
||||||
size = pvcResource?.spec?.resources?.requests?.storage || '10Gi';
|
size = pvcResource?.spec?.resources?.requests?.storage || '10Gi';
|
||||||
storageClassName = pvcResource?.spec?.storageClassName;
|
storageClassName = pvcResource?.spec?.storageClassName;
|
||||||
volumeMode = pvcResource?.spec?.volumeMode || VOLUME_MODE.BLOCK;
|
volumeMode = pvcResource?.spec?.volumeMode || VOLUME_MODE.BLOCK;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "harvester",
|
"name": "harvester",
|
||||||
"description": "Rancher UI Extension for Harvester",
|
"description": "Rancher UI Extension for Harvester",
|
||||||
"version": "1.10.0-dev",
|
"version": "1.9.0-rc3",
|
||||||
"private": false,
|
"private": false,
|
||||||
"rancher": {
|
"rancher": {
|
||||||
"annotations": {
|
"annotations": {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ const stepData = reactive({
|
|||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
skipTlsVerify: false,
|
skipTlsVerify: false,
|
||||||
|
vddkInitImage: '',
|
||||||
testPassed: false,
|
testPassed: false,
|
||||||
testResult: null,
|
testResult: null,
|
||||||
testError: null,
|
testError: null,
|
||||||
@@ -193,6 +194,7 @@ const init = async() => {
|
|||||||
stepData.provider.selectedProvider = fetchedProvider.metadata.name;
|
stepData.provider.selectedProvider = fetchedProvider.metadata.name;
|
||||||
stepData.provider.providerName = fetchedProvider.metadata.name;
|
stepData.provider.providerName = fetchedProvider.metadata.name;
|
||||||
stepData.provider.url = fetchedProvider.spec?.url || '';
|
stepData.provider.url = fetchedProvider.spec?.url || '';
|
||||||
|
stepData.provider.vddkInitImage = fetchedProvider.spec?.settings?.vddkInitImage || '';
|
||||||
stepData.provider.createdProvider = fetchedProvider;
|
stepData.provider.createdProvider = fetchedProvider;
|
||||||
|
|
||||||
const secretRef = fetchedProvider.spec?.secret;
|
const secretRef = fetchedProvider.spec?.secret;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ const stepData = reactive({
|
|||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
skipTlsVerify: false,
|
skipTlsVerify: false,
|
||||||
|
vddkInitImage: '',
|
||||||
testPassed: false,
|
testPassed: false,
|
||||||
testResult: null,
|
testResult: null,
|
||||||
testError: null,
|
testError: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user