From 9193c52005369100422bc6ac2e76b05eb4314c7e Mon Sep 17 00:00:00 2001 From: Alexandre Alves Date: Wed, 11 Dec 2024 12:01:17 +0000 Subject: [PATCH 1/2] backport arch seedimage selector --- pkg/elemental/components/BuildMedia.vue | 109 ++++++++++++++++------ pkg/elemental/utils/feature-versioning.ts | 17 +++- 2 files changed, 95 insertions(+), 31 deletions(-) diff --git a/pkg/elemental/components/BuildMedia.vue b/pkg/elemental/components/BuildMedia.vue index d742bff..85c6108 100644 --- a/pkg/elemental/components/BuildMedia.vue +++ b/pkg/elemental/components/BuildMedia.vue @@ -9,6 +9,7 @@ import { getOperatorVersion, checkGatedFeatureCompatibility, BUILD_MEDIA_RAW_SUPPORT, + BUILD_MEDIA_ARCH_SUPPORT, CHANNEL_NO_LONGER_IN_SYNC, ALL_AREAS, ALL_MODES, @@ -28,6 +29,8 @@ export const MEDIA_TYPES = { } }; +const SPECIAL_DELIMITATOR = ':::::'; + export default { name: 'BuildMedia', components: { @@ -93,12 +96,25 @@ export default { const selectedFilterType = neu === MEDIA_TYPES.ISO.type ? MEDIA_TYPES.ISO.type : MEDIA_TYPES.RAW.filterType; this.filteredManagedOsVersions = this.managedOsVersions.filter(v => v.spec?.type === selectedFilterType) || []; - this.buildMediaOsVersions = this.filteredManagedOsVersions.map((f) => { - return { - label: `${ f.spec?.metadata?.displayName } ${ f.spec?.version } ${ this.supportChannelNoLongerInSync && typeof f.inSync === 'boolean' && !f.inSync ? '(deprecated)' : '' }`, - value: neu === MEDIA_TYPES.ISO.type ? f.spec?.metadata?.uri : f.spec?.metadata?.upgradeImage, - }; + const buildMediaOsVersions = []; + + this.filteredManagedOsVersions.forEach((osVersion) => { + if (this.supportBuildMediaArchitecture && osVersion.spec?.metadata?.platforms?.length) { + osVersion.spec?.metadata?.platforms.forEach((arch) => { + buildMediaOsVersions.push({ + label: `${ osVersion.spec?.metadata?.displayName } ${ osVersion.spec?.version } - ${arch}${ this.supportChannelNoLongerInSync && typeof osVersion.inSync === 'boolean' && !osVersion.inSync ? ' - (deprecated)' : '' }`, + value: `${neu === MEDIA_TYPES.ISO.type ? osVersion.spec?.metadata?.uri : osVersion.spec?.metadata?.upgradeImage}${SPECIAL_DELIMITATOR}${arch}`, + }); + }); + } else { + buildMediaOsVersions.push({ + label: `${ osVersion.spec?.metadata?.displayName } ${ osVersion.spec?.version } ${ this.supportChannelNoLongerInSync && typeof osVersion.inSync === 'boolean' && !osVersion.inSync ? '(deprecated)' : '' }`, + value: neu === MEDIA_TYPES.ISO.type ? osVersion.spec?.metadata?.uri : osVersion.spec?.metadata?.upgradeImage, + }); + } }); + + this.buildMediaOsVersions = buildMediaOsVersions; } } }, @@ -106,6 +122,9 @@ export default { supportChannelNoLongerInSync() { return checkGatedFeatureCompatibility(ALL_AREAS, ALL_MODES, CHANNEL_NO_LONGER_IN_SYNC, this.operatorVersion); }, + supportBuildMediaArchitecture() { + return checkGatedFeatureCompatibility(this.resource, this.mode, BUILD_MEDIA_ARCH_SUPPORT, this.operatorVersion); + }, isRawDiskImageBuildSupported() { const check = checkGatedFeatureCompatibility(this.resource, this.mode, BUILD_MEDIA_RAW_SUPPORT, this.operatorVersion); @@ -143,6 +162,12 @@ export default { return {}; }, + downloadUrl() { + return this.seedImageFound?.status?.downloadURL; + }, + checksumUrl() { + return this.seedImageFound?.status?.checksumURL; + }, isMediaBuilt() { if (this.seedImageFound && this.seedImageFound.status?.downloadURL) { this.buildBtnCallback(true); @@ -182,13 +207,21 @@ export default { const machineRegName = this.displayRegEndpoints ? this.registrationEndpointSelected.split('/')[1] : this.registrationEndpoint.split('/')[1]; const machineRegNamespace = this.displayRegEndpoints ? this.registrationEndpointSelected.split('/')[0] : this.registrationEndpoint.split('/')[0]; + let targetPlatform = ''; + let baseImage = this.buildMediaOsVersionSelected; + + if (this.supportBuildMediaArchitecture && this.buildMediaOsVersionSelected.includes(SPECIAL_DELIMITATOR)) { + targetPlatform = this.buildMediaOsVersionSelected.split(SPECIAL_DELIMITATOR)[1]; + baseImage = this.buildMediaOsVersionSelected.split(SPECIAL_DELIMITATOR)[0]; + } + const seedImageObject = { metadata: { name: `media-image-reg-${ machineRegName }-${ randomStr(8, CHARSET.ALPHA_LOWER ) }`, namespace: 'fleet-default' }, spec: { - baseImage: this.buildMediaOsVersionSelected, + baseImage, registrationRef: { name: machineRegName, namespace: machineRegNamespace @@ -201,6 +234,10 @@ export default { seedImageObject.spec.type = this.buildMediaTypeSelected; } + if (targetPlatform) { + seedImageObject.spec.targetPlatform = targetPlatform; + } + const seedImageModel = await this.$store.dispatch('management/create', seedImageObject); try { @@ -210,20 +247,6 @@ export default { this.mediaBuildTriggerError = e; btnCb(false); } - }, - downloadMedia(ev) { - ev.preventDefault(); - - if (this.isMediaBuilt) { - const downloadUrl = this.seedImageFound?.status?.downloadURL; - const link = document.createElement('a'); - - link.download = `elemental.${ this.buildMediaTypeSelected === MEDIA_TYPES.ISO.type ? MEDIA_TYPES.ISO.extension : MEDIA_TYPES.RAW.extension }`; - link.href = downloadUrl; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - } } }, }; @@ -235,7 +258,7 @@ export default {

{{ t('elemental.machineRegistration.edit.buildMediaTitle') }}

-
+
@@ -314,4 +350,19 @@ export default { font-size: 13px; color: var(--darker); } + +.download-group { + max-width: fit-content; + display: inline-flex; + flex-direction: column; + vertical-align: top; + + .checksum-btn { + cursor: pointer; + margin-top: 4px; + font-size: 12px; + text-align: center; + text-decoration: underline; + } +} diff --git a/pkg/elemental/utils/feature-versioning.ts b/pkg/elemental/utils/feature-versioning.ts index dc71c85..5d6cc66 100644 --- a/pkg/elemental/utils/feature-versioning.ts +++ b/pkg/elemental/utils/feature-versioning.ts @@ -1,6 +1,6 @@ import semver from 'semver'; -import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params'; +import { _CREATE, _EDIT, _VIEW, _DETAIL } from '@shell/config/query-params'; import { ELEMENTAL_SCHEMA_IDS } from '../config/elemental-types'; import { ELEMENTAL_TYPES } from '../types'; @@ -17,6 +17,7 @@ export const ALL_MODES:string = 'all-modes'; // features to be gated to specific operator versions export const MACH_REG_CONFIG_DEFAULTS:string = 'machine-reg-config-defaults'; export const BUILD_MEDIA_RAW_SUPPORT:string = 'build-media-raw-support'; +export const BUILD_MEDIA_ARCH_SUPPORT:string = 'build-media-arch-support'; export const DELETE_NO_LONGER_IN_SYNC_CHANNELS:string = 'delete-no-longer-in-sync-channels'; export const CHANNEL_NO_LONGER_IN_SYNC:string = 'channel-no-longer-in-sync'; @@ -39,9 +40,21 @@ const FEATURES_GATING:FeaturesGatingConfig[] = [ minOperatorVersion: '1.6.2', features: [BUILD_MEDIA_RAW_SUPPORT] }, + { + area: ELEMENTAL_TYPES.DASHBOARD, + mode: [_VIEW], + minOperatorVersion: '1.6.3', + features: [BUILD_MEDIA_ARCH_SUPPORT] + }, + { + area: ELEMENTAL_SCHEMA_IDS.MACHINE_REGISTRATIONS, + mode: [_VIEW], + minOperatorVersion: '1.6.3', + features: [BUILD_MEDIA_ARCH_SUPPORT] + }, { area: ELEMENTAL_SCHEMA_IDS.MANAGED_OS_VERSION_CHANNELS, - mode: [_CREATE, _EDIT], + mode: [_CREATE, _EDIT, _DETAIL, _VIEW], minOperatorVersion: '1.6.3', features: [DELETE_NO_LONGER_IN_SYNC_CHANNELS] }, From ba2107099448984e3dba62034089a920cd78dfbf Mon Sep 17 00:00:00 2001 From: Alexandre Alves Date: Wed, 11 Dec 2024 12:29:47 +0000 Subject: [PATCH 2/2] fix bug in managedosimage not backported from vue3 migration --- .../elemental.cattle.io.managedosimage.vue | 46 ++++++++++--------- pkg/elemental/utils/elemental-utils.js | 6 +-- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/pkg/elemental/edit/elemental.cattle.io.managedosimage.vue b/pkg/elemental/edit/elemental.cattle.io.managedosimage.vue index 8db9e3a..6869e55 100644 --- a/pkg/elemental/edit/elemental.cattle.io.managedosimage.vue +++ b/pkg/elemental/edit/elemental.cattle.io.managedosimage.vue @@ -15,8 +15,6 @@ import { filterForUsedElementalClustersOnManagedOs } from '../utils/elemental-utils'; -const STRING_SEPARATOR = '_***_'; - export default { name: 'ManagedOsImagesEditView', components: { @@ -68,29 +66,30 @@ export default { this.clusterTargets = targetsArray; } } + + // populate targetable clusters based on the usage of elemental clusters in other managedosimage's (discard those as valid options) + const targetableClusters = filterForUsedElementalClustersOnManagedOs(this.elementalClusters, this.osGroups, this.value.id); + + this.clusterTargetOptions = targetableClusters.map((cluster) => { + return { + label: cluster.name, + value: cluster.name + }; + }); }, data() { return { - elementalClusters: [], - osGroups: [], - osVersions: [], - osVersionChannels: [], - clusterTargets: [], - useManagedOsImages: true, - osVersionSelected: '' + elementalClusters: [], + osGroups: [], + osVersions: [], + osVersionChannels: [], + clusterTargets: [], + clusterTargetOptions: [], + useManagedOsImages: true, + osVersionSelected: '' }; }, computed: { - clusterTargetOptions() { - const targetableClusters = filterForUsedElementalClustersOnManagedOs(this.elementalClusters, this.osGroups); - - return targetableClusters.map((cluster) => { - return { - label: cluster.name, - value: cluster.name - }; - }); - }, managedOSVersionOptions() { const out = []; @@ -112,7 +111,7 @@ export default { versions.forEach((v) => { out.push({ label: v.name, - value: `${ channel.name }${ STRING_SEPARATOR }${ v.name }` + value: v.name }); }); } @@ -129,9 +128,11 @@ export default { this.value.spec.clusterTargets = ev.map((val) => { return { clusterName: val }; }); + this.clusterTargets = ev; }, handleManagedOSVersionNameChange(ev) { - this.value.spec.managedOSVersionName = ev.split(STRING_SEPARATOR)[1]; + this.value.spec.managedOSVersionName = ev; + this.osVersionSelected = ev; }, handleRadioBtnChange(val) { // if TRUE, this mean we are on option "use managed OS version" @@ -142,6 +143,8 @@ export default { delete this.value?.spec?.managedOSVersionName; this.osVersionSelected = ''; } + + this.useManagedOsImages = val; } }, }; @@ -177,6 +180,7 @@ export default { :placeholder="t('elemental.osimage.create.targetCluster.placeholder', null, true)" :mode="mode" :options="clusterTargetOptions" + option-key="value" :multiple="true" @input="handleClusterTargetChange($event)" /> diff --git a/pkg/elemental/utils/elemental-utils.js b/pkg/elemental/utils/elemental-utils.js index 53215a9..003b4d2 100644 --- a/pkg/elemental/utils/elemental-utils.js +++ b/pkg/elemental/utils/elemental-utils.js @@ -7,19 +7,19 @@ export function filterForElementalClusters(clusters) { cluster.spec?.rkeConfig?.machinePools[0].machineConfigRef.kind === KIND.MACHINE_INV_SELECTOR_TEMPLATES); } -export function filterForUsedElementalClustersOnManagedOs(elementalClusters, osGroups) { +export function filterForUsedElementalClustersOnManagedOs(elementalClusters, osGroups, id) { const out = [...elementalClusters]; + // filter out clusters that are in use by other ManagedOsVersion's osGroups.forEach((group) => { group.spec?.clusterTargets?.forEach((target) => { - if (elementalClusters.find(c => c.name === target.clusterName)) { + if (elementalClusters.find(c => c.name === target.clusterName && group.id !== id)) { const index = out.findIndex(c => c.name === target.clusterName); out.splice(index, 1); } }); }); - return out; }