Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtualization Management, show warning message if there are no compatible Harvester versions #12852

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading