Skip to content

Commit 29e552e

Browse files
committed
Resolves: MTV-3641 | address feedback
Signed-off-by: Jeff Puzzo <jpuzzo@redhat.com>
1 parent 902b453 commit 29e552e

File tree

9 files changed

+24
-70
lines changed

9 files changed

+24
-70
lines changed

src/plans/create/steps/customization-scripts/ConfigMapSelect.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { type ComponentProps, type ForwardedRef, forwardRef, useMemo } from 'react';
22

33
import Select from '@components/common/Select';
4+
import type { IoK8sApiCoreV1ConfigMap } from '@forklift-ui/types';
45
import { type K8sResourceCommon, useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
56
import { SelectList, SelectOption } from '@patternfly/react-core';
67
import { getName } from '@utils/crds/common/selectors';
78
import { isEmpty } from '@utils/helpers';
89
import { useForkliftTranslation } from '@utils/i18n';
910

1011
import { CONFIG_MAP_GVK } from './constants';
11-
import type { K8sConfigMap } from './types';
1212
import { isScriptConfigMap } from './utils';
1313

1414
type ConfigMapSelectProps = Pick<ComponentProps<typeof Select>, 'status'> & {
1515
id: string;
1616
namespace: string;
17-
onSelect: (event: unknown, configMap: K8sConfigMap) => void;
17+
onSelect: (event: unknown, configMap: IoK8sApiCoreV1ConfigMap) => void;
1818
testId?: string;
1919
value: string;
2020
};
@@ -31,14 +31,14 @@ const ConfigMapSelect = (
3131
namespace,
3232
});
3333

34-
const scriptConfigMaps = useMemo((): K8sConfigMap[] => {
34+
const scriptConfigMaps = useMemo((): IoK8sApiCoreV1ConfigMap[] => {
3535
if (!allConfigMaps) {
3636
return [];
3737
}
3838

3939
return allConfigMaps.filter((cm) =>
40-
isScriptConfigMap((cm as K8sConfigMap).data),
41-
) as K8sConfigMap[];
40+
isScriptConfigMap((cm as IoK8sApiCoreV1ConfigMap).data),
41+
) as IoK8sApiCoreV1ConfigMap[];
4242
}, [allConfigMaps]);
4343

4444
const hasNoScriptConfigMaps = isEmpty(scriptConfigMaps);

src/plans/create/steps/customization-scripts/types.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
import type { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';
2-
31
import type { GuestType, ScriptType } from './constants';
42

5-
export type K8sConfigMap = K8sResourceCommon & {
6-
data?: Record<string, string>;
7-
};
8-
93
export type CustomScript = {
104
content: string;
115
guestType: GuestType;

src/plans/create/steps/customization-scripts/utils.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {
1111
import type { CustomScript } from './types';
1212

1313
/**
14-
* Builds a ConfigMap data key from a script definition.
15-
* Format: `{order}_{os}_{type}_{name}.{ext}`
16-
* Example: `10_linux_firstboot_setup_network.sh`
14+
* Builds a ConfigMap data key matching the backend regex patterns in customize.go.
15+
* Order is zero-padded so lexicographic sorting matches numeric order (e.g. `02_` before `10_`).
16+
* @see https://github.com/kubev2v/forklift/blob/main/pkg/virt-v2v/customize/customize.go
1717
*/
1818
export const buildConfigMapKey = (script: CustomScript): string => {
1919
const paddedOrder = String(script.order).padStart(2, '0');
@@ -23,19 +23,13 @@ export const buildConfigMapKey = (script: CustomScript): string => {
2323
return `${paddedOrder}_${osPrefix}_${script.scriptType}_${script.name}.${ext}`;
2424
};
2525

26-
/**
27-
* Converts an array of scripts to ConfigMap data entries.
28-
*/
2926
export const scriptsToConfigMapData = (scripts: CustomScript[]): Record<string, string> => {
3027
return scripts.reduce<Record<string, string>>((data, script) => {
3128
data[buildConfigMapKey(script)] = script.content;
3229
return data;
3330
}, {});
3431
};
3532

36-
/**
37-
* Calculates the next order number for a new script entry.
38-
*/
3933
export const getNextOrder = (scripts: CustomScript[]): number => {
4034
if (isEmpty(scripts)) {
4135
return ORDER_INCREMENT;
@@ -45,10 +39,6 @@ export const getNextOrder = (scripts: CustomScript[]): number => {
4539
return maxOrder + ORDER_INCREMENT;
4640
};
4741

48-
/**
49-
* Validates a script name for use in ConfigMap keys.
50-
* Must be lowercase alphanumeric with hyphens and underscores, starting with alphanumeric.
51-
*/
5242
export const validateScriptName = (value: string): string | undefined => {
5343
if (!value?.trim()) {
5444
return t('Script name is required.');
@@ -63,9 +53,6 @@ export const validateScriptName = (value: string): string | undefined => {
6353
return undefined;
6454
};
6555

66-
/**
67-
* Checks if a ConfigMap contains at least one key matching the customization script naming pattern.
68-
*/
6956
export const isScriptConfigMap = (data: Record<string, string> | undefined): boolean => {
7057
if (!data) {
7158
return false;

src/plans/create/types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import type { StorageMapping, TargetStorage } from 'src/storageMaps/utils/types'
44
import type { InventoryNetwork } from 'src/utils/hooks/useNetworks';
55
import type { InventoryStorage } from 'src/utils/hooks/useStorages';
66

7-
import type { HypervNetwork } from '@forklift-ui/types';
87
import type {
8+
HypervNetwork,
9+
IoK8sApiCoreV1ConfigMap,
910
OpenShiftNetworkAttachmentDefinition,
1011
OpenshiftVM,
1112
OpenstackNetwork,
@@ -30,7 +31,7 @@ import type {
3031
CustomScriptsFieldId,
3132
CustomScriptsType,
3233
} from './steps/customization-scripts/constants';
33-
import type { CustomScript, K8sConfigMap } from './steps/customization-scripts/types';
34+
import type { CustomScript } from './steps/customization-scripts/types';
3435
import type { GeneralFormFieldId } from './steps/general-information/constants';
3536
import type { HooksFormFieldId, MigrationHook } from './steps/migration-hooks/constants';
3637
import type { MigrationTypeFieldId, MigrationTypeValue } from './steps/migration-type/constants';
@@ -83,7 +84,7 @@ export type CreatePlanFormData = FieldValues & {
8384
[OtherSettingsFormFieldId.PreserveStaticIps]: boolean;
8485
[OtherSettingsFormFieldId.MigrateSharedDisks]: boolean;
8586
[CustomScriptsFieldId.ScriptsType]: CustomScriptsType;
86-
[CustomScriptsFieldId.ExistingConfigMap]: K8sConfigMap | undefined;
87+
[CustomScriptsFieldId.ExistingConfigMap]: IoK8sApiCoreV1ConfigMap | undefined;
8788
[CustomScriptsFieldId.Scripts]: CustomScript[];
8889
[HooksFormFieldId.PreMigration]: MigrationHook;
8990
[HooksFormFieldId.PostMigration]: MigrationHook;
@@ -122,7 +123,7 @@ export type CreatePlanParams = {
122123
migrateSharedDisks?: boolean;
123124
luks?: V1beta1PlanSpecVmsLuks;
124125
nbdeClevis?: boolean;
125-
customScriptsConfigMap?: K8sConfigMap;
126+
customScriptsConfigMap?: IoK8sApiCoreV1ConfigMap;
126127
preHook?: V1beta1Hook;
127128
postHook?: V1beta1Hook;
128129
targetPowerState: TargetPowerStateValue;

src/plans/create/utils/addOwnerRefs.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
import type {
2-
IoK8sApiCoreV1Secret,
3-
V1beta1Hook,
4-
V1beta1NetworkMap,
5-
V1beta1StorageMap,
6-
} from '@forklift-ui/types';
71
import {
82
type K8sModel,
93
k8sPatch,
@@ -12,18 +6,9 @@ import {
126
import { isEmpty } from '@utils/helpers';
137
import type { ObjectRef } from '@utils/helpers/getObjectRef';
148

15-
/**
16-
* Adds owner references to a resource
17-
* This establishes parent-child relationships between Kubernetes resources
18-
*/
199
export const addOwnerRefs = async (
2010
model: K8sModel,
21-
resource:
22-
| V1beta1NetworkMap
23-
| V1beta1StorageMap
24-
| IoK8sApiCoreV1Secret
25-
| V1beta1Hook
26-
| K8sResourceCommon,
11+
resource: K8sResourceCommon,
2712
newOwnerReferences: ObjectRef[],
2813
) => {
2914
const existingOwnerReferences = resource.metadata?.ownerReferences;

src/plans/create/utils/addPlanResourceOwnerRefs.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
HookModel,
3+
type IoK8sApiCoreV1ConfigMap,
34
type IoK8sApiCoreV1Secret,
45
NetworkMapModel,
56
SecretModel,
@@ -11,20 +12,15 @@ import {
1112
import { ConfigMapModel } from '@utils/analytics/constants';
1213
import type { ObjectRef } from '@utils/helpers/getObjectRef';
1314

14-
import type { K8sConfigMap } from '../steps/customization-scripts/types';
15-
1615
import { addOwnerRefs } from './addOwnerRefs';
1716

18-
/**
19-
* Adds owner references to all created resources for a created plan
20-
*/
2117
export const addPlanResourceOwnerRefs = async (
2218
resources: {
2319
networkMap: V1beta1NetworkMap;
2420
storageMap: V1beta1StorageMap;
2521
secret?: IoK8sApiCoreV1Secret;
2622
hooks: { preHook?: V1beta1Hook; postHook?: V1beta1Hook };
27-
scriptsConfigMap?: K8sConfigMap;
23+
scriptsConfigMap?: IoK8sApiCoreV1ConfigMap;
2824
},
2925
planRef: ObjectRef,
3026
) => {

src/plans/create/utils/createCustomScriptsConfigMap.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import type { IoK8sApiCoreV1ConfigMap } from '@forklift-ui/types';
12
import { k8sCreate } from '@openshift-console/dynamic-plugin-sdk';
23
import { ConfigMapModel } from '@utils/analytics/constants';
34

4-
import type { CustomScript, K8sConfigMap } from '../steps/customization-scripts/types';
5+
import type { CustomScript } from '../steps/customization-scripts/types';
56
import { scriptsToConfigMapData } from '../steps/customization-scripts/utils';
67

78
type CreateConfigMapParams = {
@@ -10,16 +11,12 @@ type CreateConfigMapParams = {
1011
scripts: CustomScript[];
1112
};
1213

13-
/**
14-
* Creates a ConfigMap containing customization scripts for guest conversion.
15-
* Keys follow the naming pattern: `{order}_{os}_{type}_{name}.{ext}`
16-
*/
1714
export const createCustomScriptsConfigMap = async ({
1815
planName,
1916
planProject,
2017
scripts,
21-
}: CreateConfigMapParams): Promise<K8sConfigMap> => {
22-
const configMap: K8sConfigMap = {
18+
}: CreateConfigMapParams): Promise<IoK8sApiCoreV1ConfigMap> => {
19+
const configMap: IoK8sApiCoreV1ConfigMap = {
2320
apiVersion: 'v1',
2421
data: scriptsToConfigMapData(scripts),
2522
kind: 'ConfigMap',

src/plans/create/utils/resolveScriptsConfigMap.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1+
import type { IoK8sApiCoreV1ConfigMap } from '@forklift-ui/types';
12
import { isEmpty } from '@utils/helpers';
23

34
import { CustomScriptsType } from '../steps/customization-scripts/constants';
4-
import type { K8sConfigMap } from '../steps/customization-scripts/types';
55
import type { CreatePlanFormData } from '../types';
66

77
import { createCustomScriptsConfigMap } from './createCustomScriptsConfigMap';
88

9-
/**
10-
* Resolves the scripts ConfigMap based on the user's selection:
11-
* - Existing mode: returns the selected ConfigMap as-is
12-
* - New mode: creates a new ConfigMap from the defined scripts
13-
* - No scripts: returns undefined
14-
*/
159
export const resolveScriptsConfigMap = async ({
1610
customScripts,
1711
customScriptsType,
@@ -25,7 +19,7 @@ export const resolveScriptsConfigMap = async ({
2519
| 'existingCustomScriptsConfigMap'
2620
| 'planName'
2721
| 'planProject'
28-
>): Promise<K8sConfigMap | undefined> => {
22+
>): Promise<IoK8sApiCoreV1ConfigMap | undefined> => {
2923
if (customScriptsType === CustomScriptsType.Existing) {
3024
return existingCustomScriptsConfigMap;
3125
}

src/plans/create/utils/submitMigrationPlan.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { createStorageMap } from 'src/storageMaps/create/utils/createStorageMap';
22

33
import type {
4+
IoK8sApiCoreV1ConfigMap,
45
IoK8sApiCoreV1Secret,
56
V1beta1NetworkMap,
67
V1beta1StorageMap,
78
} from '@forklift-ui/types';
89
import { CreationMethod, TELEMETRY_EVENTS } from '@utils/analytics/constants';
910
import { isEmpty } from '@utils/helpers';
1011

11-
import type { K8sConfigMap } from '../steps/customization-scripts/types';
1212
import { MigrationHookFieldId } from '../steps/migration-hooks/constants';
1313
import type { CreatePlanFormData } from '../types';
1414

@@ -68,7 +68,7 @@ export const submitMigrationPlan = async (
6868
Promise<V1beta1StorageMap>,
6969
Promise<IoK8sApiCoreV1Secret | undefined>,
7070
Promise<CreatedHooks>,
71-
Promise<K8sConfigMap | undefined>,
71+
Promise<IoK8sApiCoreV1ConfigMap | undefined>,
7272
] = [
7373
existingNetworkMap
7474
? copyNetworkMap(existingNetworkMap, planName, planProject)

0 commit comments

Comments
 (0)