fix: remove map ownerref writeback and delete maps via plan refs (#1105)

Signed-off-by: Andy Lee <andy.lee@suse.com>
This commit is contained in:
Andy Lee 2026-08-10 18:14:48 +08:00 committed by GitHub
parent 72282ae50e
commit ed2b6f2551
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 36 deletions

View File

@ -273,19 +273,6 @@ const startMigrationAction = async() => {
await plan.save(); await plan.save();
const planOwnerRef = {
apiVersion: FORKLIFT_API_VERSION,
kind: 'Plan',
name: plan.metadata.name,
uid: plan.metadata.uid,
blockOwnerDeletion: true,
};
networkMap.metadata.ownerReferences = [planOwnerRef];
await networkMap.save();
storageMap.metadata.ownerReferences = [planOwnerRef];
await storageMap.save();
// Kick off the first migration through the model so the Migration payload // Kick off the first migration through the model so the Migration payload
// lives in a single place (also reused by the dashboard start/restart action). // lives in a single place (also reused by the dashboard start/restart action).
await plan.startMigration(); await plan.startMigration();

View File

@ -68,29 +68,35 @@ export default defineComponent({
return (this.value || []).map((plan) => { return (this.value || []).map((plan) => {
const planName = plan?.metadata?.name || '-'; const planName = plan?.metadata?.name || '-';
const namespace = plan?.metadata?.namespace || ''; const namespace = plan?.metadata?.namespace || '';
const networkMapRef = this.getPlanMapRef(plan, 'network');
const storageMapRef = this.getPlanMapRef(plan, 'storage');
const migrations = existing[HCI.FORKLIFT_MIGRATION] const migrations = existing[HCI.FORKLIFT_MIGRATION]
.filter((resource) => this.ownedByPlan(resource, plan)) .filter((resource) => this.ownedByPlan(resource, plan))
.map((resource) => ({ .map((resource) => resource?.metadata?.name)
name: resource?.metadata?.name, .filter(Boolean);
namespace: resource?.metadata?.namespace || namespace,
}));
const matchedNetworkMap = existing[HCI.FORKLIFT_NETWORK_MAP].find((resource) => this.ownedByPlan(resource, plan)); const matchedNetworkMap = networkMapRef ? existing[HCI.FORKLIFT_NETWORK_MAP].find((resource) => resource?.metadata?.name === networkMapRef.name && resource?.metadata?.namespace === networkMapRef.namespace) : null;
const matchedStorageMap = existing[HCI.FORKLIFT_STORAGE_MAP].find((resource) => this.ownedByPlan(resource, plan)); const matchedStorageMap = storageMapRef ? existing[HCI.FORKLIFT_STORAGE_MAP].find((resource) => resource?.metadata?.name === storageMapRef.name && resource?.metadata?.namespace === storageMapRef.namespace) : null;
return { return {
planName, planName,
namespace, namespace,
migrations, migrations,
networkMap: matchedNetworkMap ? { networkMap: matchedNetworkMap ? {
namespace: matchedNetworkMap?.metadata?.namespace || namespace, namespace: matchedNetworkMap?.metadata?.namespace || networkMapRef?.namespace || namespace,
name: matchedNetworkMap?.metadata?.name, name: matchedNetworkMap?.metadata?.name,
} : null, } : (networkMapRef ? {
namespace: networkMapRef.namespace,
name: networkMapRef.name,
} : null),
storageMap: matchedStorageMap ? { storageMap: matchedStorageMap ? {
namespace: matchedStorageMap?.metadata?.namespace || namespace, namespace: matchedStorageMap?.metadata?.namespace || storageMapRef?.namespace || namespace,
name: matchedStorageMap?.metadata?.name, name: matchedStorageMap?.metadata?.name,
} : null, } : (storageMapRef ? {
namespace: storageMapRef.namespace,
name: storageMapRef.name,
} : null),
}; };
}); });
}, },
@ -113,6 +119,20 @@ export default defineComponent({
methods: { methods: {
resourceNames, resourceNames,
getPlanMapRef(plan, mapType) {
const ref = plan?.spec?.map?.[mapType];
const name = ref?.name;
if (!name) {
return null;
}
return {
name,
namespace: ref?.namespace || plan?.metadata?.namespace || '',
};
},
/** /**
* Determine whether a related resource (migration / network map / storage map) * Determine whether a related resource (migration / network map / storage map)
* is owned by the given plan by inspecting its `metadata.ownerReferences`. * is owned by the given plan by inspecting its `metadata.ownerReferences`.
@ -137,9 +157,8 @@ export default defineComponent({
const existing = this.existingRelatedResources; const existing = this.existingRelatedResources;
const targets = new Map(); const targets = new Map();
const addTarget = (type, resource) => { const addTarget = (type, name, namespace) => {
const name = resource?.metadata?.name; const ns = namespace || '';
const ns = resource?.metadata?.namespace;
if (!name) { if (!name) {
return; return;
@ -153,17 +172,20 @@ export default defineComponent({
}; };
for (const plan of this.value || []) { for (const plan of this.value || []) {
existing[HCI.FORKLIFT_NETWORK_MAP] const networkMapRef = this.getPlanMapRef(plan, 'network');
.filter((resource) => this.ownedByPlan(resource, plan)) const storageMapRef = this.getPlanMapRef(plan, 'storage');
.forEach((resource) => addTarget(HCI.FORKLIFT_NETWORK_MAP, resource));
existing[HCI.FORKLIFT_STORAGE_MAP] if (networkMapRef) {
.filter((resource) => this.ownedByPlan(resource, plan)) addTarget(HCI.FORKLIFT_NETWORK_MAP, networkMapRef.name, networkMapRef.namespace);
.forEach((resource) => addTarget(HCI.FORKLIFT_STORAGE_MAP, resource)); }
if (storageMapRef) {
addTarget(HCI.FORKLIFT_STORAGE_MAP, storageMapRef.name, storageMapRef.namespace);
}
existing[HCI.FORKLIFT_MIGRATION] existing[HCI.FORKLIFT_MIGRATION]
.filter((resource) => this.ownedByPlan(resource, plan)) .filter((resource) => this.ownedByPlan(resource, plan))
.forEach((resource) => addTarget(HCI.FORKLIFT_MIGRATION, resource)); .forEach((resource) => addTarget(HCI.FORKLIFT_MIGRATION, resource?.metadata?.name, resource?.metadata?.namespace));
} }
return [...targets.values()]; return [...targets.values()];
@ -256,11 +278,11 @@ export default defineComponent({
<div> {{ t('harvester.addons.vmMigration.labels.migration') }}:</div> <div> {{ t('harvester.addons.vmMigration.labels.migration') }}:</div>
<template v-if="summary.migrations.length"> <template v-if="summary.migrations.length">
<div <div
v-for="migration in summary.migrations" v-for="migrationName in summary.migrations"
:key="`${ migration.namespace }/${ migration.name }`" :key="migrationName"
> >
<div class="ml-20"> <div class="ml-20">
- {{ migration.name }} - {{ migrationName }}
</div> </div>
</div> </div>
</template> </template>