Skip to content

Commit

Permalink
Merge pull request #12852 from torchiaf/12640-virt-page-4
Browse files Browse the repository at this point in the history
Virtualization Management, show warning message if there are no compatible Harvester versions
  • Loading branch information
torchiaf authored Dec 12, 2024
2 parents e115aa9 + e1abadb commit 6e34696
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 31 deletions.
4 changes: 4 additions & 0 deletions pkg/harvester-manager/l10n/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ harvesterManager:
warning: "The Harvester UI Extension repository is missing"
prompt: "Please click on Update button to add the Harvester repository and install the latest Harvester UI Extension, if any"
prompt-standard-user: Please contact your system administrator to install the latest Harvester UI Extension, if any
missingVersion:
warning: "Could not find a compatible version"
prompt: "Please update Rancher to get the latest compatible version of the Harvester UI extension"
prompt-standard-user: Please contact your system administrator
error:
warning: "Warning, Harvester UI extension automatic installation failed"
prompt: "Please refresh the page and try again or install the Harvester UI extension manually"
Expand Down
62 changes: 35 additions & 27 deletions pkg/harvester-manager/list/harvesterhci.io.management.cluster.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
waitForUIExtension,
waitForUIPackage,
} from '@shell/utils/uiplugins';
import { isRancherPrime } from '@shell/config/version';
import { isRancherPrime, getVersionData } from '@shell/config/version';
const HARVESTER_REPO = isRancherPrime() ? HARVESTER_RANCHER_REPO : HARVESTER_COMMUNITY_REPO;
Expand Down Expand Up @@ -78,8 +78,11 @@ export default {
realSchema: this.$store.getters['management/schemaFor'](CAPI.RANCHER_CLUSTER),
hciClusters: [],
mgmtClusters: [],
rancherVersion: getVersionData()?.Version || '',
kubeVersion: this.$store.getters['management/byId'](MANAGEMENT.CLUSTER, 'local')?.kubernetesVersionBase || '',
harvesterRepository: null,
harvesterLatestVersion: null,
harvesterInstallVersion: true,
harvesterUpdateVersion: null,
harvesterRepositoryError: false,
harvesterExtensionInstallError: false,
harvesterExtensionUpdateError: false,
Expand All @@ -104,7 +107,7 @@ export default {
await refreshHelmRepository(this.$store, HARVESTER_REPO.spec.gitRepo, HARVESTER_REPO.spec.gitBranch);
if (this.harvester.extension) {
await this.setHarvesterLatestVersion();
await this.setHarvesterUpdateVersion();
}
}
}
Expand All @@ -116,15 +119,15 @@ export default {
harvester() {
const extension = this.uiplugins?.find((c) => c.name === HARVESTER_CHART.name);
const missingRepository = !!extension && !this.harvesterRepository;
const isLatestVersionAvailable = !!this.harvesterLatestVersion;
const action = async(btnCb) => {
const action = `${ !extension ? 'install' : 'update' }HarvesterExtension`;
await this[action](btnCb);
};
const hasErrors = this.harvesterRepositoryError ||
const hasErrors = !this.harvesterInstallVersion ||
this.harvesterRepositoryError ||
this.harvesterExtensionInstallError ||
this.harvesterExtensionUpdateError;
Expand All @@ -134,11 +137,13 @@ export default {
].reduce((acc, label) => {
let action = '';
if (hasErrors) {
if (!this.harvesterInstallVersion) {
action = 'missingVersion';
} else if (hasErrors) {
action = 'error';
} else if (missingRepository) {
action = 'missingRepo';
} else if (isLatestVersionAvailable) {
} else if (!!this.harvesterUpdateVersion) {
action = 'update';
} else if (!extension) {
action = 'install';
Expand All @@ -159,9 +164,8 @@ export default {
return {
extension,
missingRepository,
isLatestVersionAvailable,
toInstall: !extension,
toUpdate: missingRepository || isLatestVersionAvailable,
toUpdate: missingRepository || !!this.harvesterUpdateVersion,
action,
panelLabel,
hasErrors,
Expand Down Expand Up @@ -214,12 +218,12 @@ export default {
}
},
async setHarvesterLatestVersion() {
async setHarvesterUpdateVersion() {
try {
const version = await getLatestExtensionVersion(this.$store, HARVESTER_CHART.name);
const version = await getLatestExtensionVersion(this.$store, HARVESTER_CHART.name, this.rancherVersion, this.kubeVersion);
if (semver.gt(version, this.harvester.extension.version)) {
this.harvesterLatestVersion = version;
this.harvesterUpdateVersion = version;
}
} catch (error) {
this.harvesterExtensionUpdateError = true;
Expand All @@ -238,17 +242,20 @@ export default {
*/
await refreshHelmRepository(this.$store, HARVESTER_REPO.spec.gitRepo, HARVESTER_REPO.spec.gitBranch);
const version = await getLatestExtensionVersion(this.$store, HARVESTER_CHART.name);
this.harvesterInstallVersion = await getLatestExtensionVersion(this.$store, HARVESTER_CHART.name, this.rancherVersion, this.kubeVersion);
await installHelmChart(harvesterRepo, { ...HARVESTER_CHART, version }, {}, UI_PLUGIN_NAMESPACE, 'install');
if (!this.harvesterInstallVersion) {
btnCb(false);
return;
}
await installHelmChart(harvesterRepo, { ...HARVESTER_CHART, version: this.harvesterInstallVersion }, {}, UI_PLUGIN_NAMESPACE, 'install');
const extension = await waitForUIExtension(this.$store, HARVESTER_CHART.name);
installed = await waitForUIPackage(this.$store, extension);
} catch (error) {
this.harvesterExtensionInstallError = true;
btnCb(false);
}
this.harvesterExtensionInstallError = !installed;
Expand All @@ -264,23 +271,24 @@ export default {
let updated = false;
try {
let harvesterRepository = this.harvesterRepository;
if (this.harvester.missingRepository) {
harvesterRepository = await ensureHelmRepository(this.$store, HARVESTER_REPO.spec.gitRepo, HARVESTER_REPO.metadata.name, HARVESTER_REPO.spec.gitBranch);
this.harvesterRepository = await ensureHelmRepository(this.$store, HARVESTER_REPO.spec.gitRepo, HARVESTER_REPO.metadata.name, HARVESTER_REPO.spec.gitBranch);
await this.setHarvesterLatestVersion();
await this.setHarvesterUpdateVersion();
}
await installHelmChart(harvesterRepository, { ...HARVESTER_CHART, version: this.harvesterLatestVersion }, {}, UI_PLUGIN_NAMESPACE, 'upgrade');
if (!this.harvesterUpdateVersion) {
btnCb(true);
return;
}
await installHelmChart(this.harvesterRepository, { ...HARVESTER_CHART, version: this.harvesterUpdateVersion }, {}, UI_PLUGIN_NAMESPACE, 'upgrade');
const extension = await waitForUIExtension(this.$store, HARVESTER_CHART.name);
updated = await waitForUIPackage(this.$store, { ...extension, version: this.harvesterLatestVersion });
updated = await waitForUIPackage(this.$store, { ...extension, version: this.harvesterUpdateVersion });
} catch (error) {
this.harvesterExtensionUpdateError = true;
btnCb(false);
}
this.harvesterExtensionUpdateError = !updated;
Expand Down Expand Up @@ -422,7 +430,7 @@ export default {
/>
</div>
</div>
<template v-if="isAdmin">
<template v-if="isAdmin && harvesterInstallVersion">
<div
v-if="harvester.hasErrors"
class="extension-info"
Expand Down
22 changes: 18 additions & 4 deletions shell/utils/uiplugins.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
import { CATALOG } from '@shell/config/types';
import { UI_PLUGIN_BASE_URL } from '@shell/config/uiplugins';
import { UI_PLUGIN_BASE_URL, isSupportedChartVersion } from '@shell/config/uiplugins';

const MAX_RETRIES = 10;
const RETRY_WAIT = 2500;
Expand All @@ -13,15 +13,29 @@ export type HelmChart = any;
*
* @param store Vue store
* @param chartName The chartName
* @param rancherVersion Rancher version
* @param kubeVersion K8s version
* @param opt Store options
* @returns The latest compatible version of the extension
* @returns The latest compatible version of the extension; return null If there are no compatible versions.
*/
export async function getLatestExtensionVersion(store: any, chartName: string, opt = { reset: true, force: true }) {
export async function getLatestExtensionVersion(
store: any,
chartName: string,
rancherVersion: string,
kubeVersion: string,
opt = { reset: true, force: true },
) {
await store.dispatch('catalog/load', opt);

const chart = store.getters['catalog/chart']({ chartName });

return chart?.versions?.[0]?.version;
const versions = chart?.versions || [];

const compatibleVersions = versions.filter((version: any) => isSupportedChartVersion({
version, rancherVersion, kubeVersion
}));

return compatibleVersions[0]?.version;
}

/**
Expand Down

0 comments on commit 6e34696

Please sign in to comment.