From 64626ebac7529a4cc471781ed45f0782d1b0c79f Mon Sep 17 00:00:00 2001
From: roly
Date: Thu, 9 Jan 2025 19:49:05 +0800
Subject: [PATCH] Support luxshare oem firmware update
---
src/components/Global/LinkButton.vue | 57 ++
src/components/Global/UploadFile.vue | 146 ++++
src/locales/en-US.json | 84 +-
src/store/modules/Operations/FirmwareStore.js | 220 ++++-
src/utilities/bus.js | 2 +
src/views/Operations/Firmware/Firmware.vue | 104 ++-
.../Operations/Firmware/FirmwareCardsBmc.vue | 27 +
.../Operations/Firmware/FirmwareCardsFPGA.vue | 40 +
.../Firmware/FirmwareCardsFcbCPLD.vue | 40 +
.../Operations/Firmware/FirmwareCardsMe.vue | 40 +
.../Firmware/FirmwareModalUpdateFirmware.vue | 29 +
.../Firmware/FirmwareUpdateStatus.vue | 822 ++++++++++++++++++
12 files changed, 1590 insertions(+), 21 deletions(-)
create mode 100755 src/components/Global/LinkButton.vue
create mode 100755 src/components/Global/UploadFile.vue
create mode 100755 src/utilities/bus.js
create mode 100755 src/views/Operations/Firmware/FirmwareCardsFPGA.vue
create mode 100755 src/views/Operations/Firmware/FirmwareCardsFcbCPLD.vue
create mode 100755 src/views/Operations/Firmware/FirmwareCardsMe.vue
create mode 100755 src/views/Operations/Firmware/FirmwareUpdateStatus.vue
diff --git a/src/components/Global/LinkButton.vue b/src/components/Global/LinkButton.vue
new file mode 100755
index 0000000..2a2022b
--- /dev/null
+++ b/src/components/Global/LinkButton.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Global/UploadFile.vue b/src/components/Global/UploadFile.vue
new file mode 100755
index 0000000..3e492bd
--- /dev/null
+++ b/src/components/Global/UploadFile.vue
@@ -0,0 +1,146 @@
+
+
+
+
+ {{ $t('pageFirmware.form.updateFirmware.startUpload') }}
+
+
+
+ {{ fileErrorTips }}
+
+
+
+
+
+
+
+
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 93ad806..0a67945 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -331,6 +331,12 @@
}
},
"pageFirmware": {
+ "primaryImage": "Primary",
+ "secondaryImage": "Secondary",
+ "both": "Both (Not recommended)",
+ "sectionTitleMeCards": "ME Firmware",
+ "sectionTitleFcbCPLDCards": "Fan Board CPLD",
+ "sectionTitleFPGACards": "FPGA",
"cardActionSwitchToRunning": "Switch to running",
"cardBodyVersion": "Version",
"cardBodyReleaseDate": "Release Date",
@@ -340,19 +346,41 @@
"cardTitleFBCpld": "Fan Board CPLD",
"sectionTitleBmcCards": "BMC",
"sectionTitleBmcCardsCombined": "BMC and server",
- "sectionTitleHostCards": "Host",
+ "sectionTitleHostCards": "BIOS",
"sectionTitleUpdateFirmware": "Update firmware",
"sectionTitleCPLDCards": "CPLD",
+ "sectionTitleUpdateFirmwareStatus": "Update firmware status",
"alert": {
"operationInProgress": "Server power operation in progress.",
"serverMustBePoweredOffTo": "Server must be powered off to:",
"serverMustBePoweredOffToUpdateFirmware": "Server must be powered off to update firmware",
"switchRunningAndBackupImages": "Switch running and backup images",
"updateFirmware": "Update firmware",
- "viewServerPowerOperations": "View server power operations"
+ "viewServerPowerOperations": "View server power operations",
+ "boxupdateFirmware": "Box Update firmware",
+ "updateTask": "Background Update Task"
},
"form": {
+ "invalidFiletype": "Invalid file type",
+ "updateOptions": {
+ "keep": "Keep all configurations update",
+ "clear": "Non keep configuration update",
+ "partialKeep": "Keep partial configuration update",
+ "factoryReset": "Factory reset"
+ },
"updateFirmware": {
+ "updateTimeout": "Update timeout",
+ "UploadedFirmware": "Uploaded %{type}",
+ "updateBmcRestFail": "BMC reset failed",
+ "updateSecondaryInfo": "Secondary BMC is now updating, please wait",
+ "updateFinished": "%{type} %{version} Updated",
+ "ok": "Ok",
+ "version": "Version",
+ "biosKeepConfig": "Keep Configuration",
+ "biosNonKeepConfig": "Non Keep Configuration",
+ "options": "Options",
+ "startUpload": "Upload image",
+ "updateAll": "Update all",
"fileAddress": "File address",
"fileSource": "File source",
"imageFile": "Image file",
@@ -362,6 +390,11 @@
}
},
"modal": {
+ "updateAllConfirm": "Are you sure you want to update all?",
+ "deleteConfirm": "Are you sure you want to delete the %{firmware} firmware?",
+ "updateFirmwareInfoOemBmc": "The primary(secondary) BMC firmware will be updated as you choose. In some scenarios, the BMC will reboot. Please confirm whether to update BMC firmware immediately?",
+ "updateSuccessOem": "update task is queued and will be activated when host DC power cycle by BMC (IPMI command or Redfish I/F)",
+ "updateFirmwareInfoOem": "The new image will be async activated. After that, the host will reboot automatically to run from the new image.",
"switchImages": "Switch images",
"switchRunningImage": "Switch running image",
"switchRunningImageInfo": "A BMC reboot is required to run the backup image. The application might be unresponsive during this time.",
@@ -372,16 +405,61 @@
"updateFirmwareInfoDefault": "The new image will be uploaded and activated. After that, the BMC or host will reboot automatically to run from the new image."
},
"toast": {
+ "errorUpdateAsyncAndSync": "BMC and other firmware cannot be updated simultaneously.",
+ "errorUpdateInPost": "The unit is in POST stage, can not flash BMC. Please wait a moment and try again.",
+ "errorUpdateInPeerNodeUpdating": "The peer node is upgrading components. Shared components do not allow dual nodes to be upgraded at the same time. Please try again later.",
+ "bmcUpdateTips": "BMC updates can cause other firmware to be lost.",
+ "errorUpdateFirmwareSign": "The firmware update failed or the signature was invalid.",
+ "errorInPostStatus": "BMC firmware can not update in BIOS POST status",
+ "uploadStarted": "Upload started",
+ "uploadStartedMessage": "Wait for the firmware upload notification before making any changes.",
+ "timeoutUpload": "Update timeout",
+ "timeoutUploadMessage": "Upload firmware image timeout",
+ "uploadSuccess": "Upload success",
+ "uploadSuccessMessage": "The firmware upload successfully",
+ "uploadFailed": "Upload failed",
+ "uploadFailedMessage": "The firmware upload failed",
+ "errorVerifyFirmware": "Failed to verify the signature image",
+ "errorUploadFirmware": "Failed to extract or verify the image",
"errorSwitchImages": "Error switching running and backup images.",
"errorUpdateFirmware": "Error starting firmware update.",
"rebootStarted": "Reboot started",
"rebootStartedMessage": "Successfully started reboot from backup image.",
"updateStarted": "Update started",
"updateStartedMessage": "Wait for the firmware update notification before making any changes.",
+ "updateSuccess": "Update success",
+ "updateSuccessMessage": "Successfully update the firmware, Please wait for the image refresh",
+ "updateFailed": "Update failed",
+ "updateFailedMessage": "Failed in update the firmware.",
"verifySwitch": "Verify switch",
"verifySwitchMessage": "Refresh the application to verify the running and backup images switched.",
"verifyUpdate": "Verify update",
- "verifyUpdateMessage": "Refresh the application to verify firmware updated successfully"
+ "verifyUpdateMessage": "Refresh the application to verify firmware updated successfully",
+ "errorGetUpdateStatus": "Failed to retrieve firmware update status.",
+ "deleteSuccess": "Deletion successful.",
+ "firmwareDeleted": "Firmware %{firmware} has been deleted.",
+ "deleteFailed": "Failed to delete firmware %{firmware}.",
+ "bmcUpdatingTips": "The page functionality is temporarily unavailable during the BMC firmware update.",
+ "bmcUpdateCompleteTips": "BMC upgrade completed. Please refresh the page after a moment. Note that the IP address may change in some cases.",
+ "validateFirmwareFailed": "Failed to validate the %{firmware} firmware image.",
+ "firmwareIdMismatch": "The %{firmware} firmware does not match"
+ },
+ "table": {
+ "updateComplete": "Update completed",
+ "updateFailed": "Update failed",
+ "updating": "Updating",
+ "waitUpdate": "Wait for update",
+ "emptyMessage": "No firmware available",
+ "update": "update",
+ "delete": "delete",
+ "noupdate": "No update",
+ "name": "Unit name",
+ "status": "Update Status",
+ "time": "Estimated time",
+ "progress": "Progress",
+ "firmwareName": "Name",
+ "firmwareStatus": "Status",
+ "firmwareVersion": "Version"
}
},
"pageInventory": {
diff --git a/src/store/modules/Operations/FirmwareStore.js b/src/store/modules/Operations/FirmwareStore.js
index 001eaf6..39b71e8 100644
--- a/src/store/modules/Operations/FirmwareStore.js
+++ b/src/store/modules/Operations/FirmwareStore.js
@@ -1,20 +1,57 @@
import api from '@/store/api';
import i18n from '@/i18n';
+import { bus } from '@/utilities/bus';
+const FIRMWARE_PURPOSE = {
+ BMC: 'xyz.openbmc_project.Software.Version.VersionPurpose.BMC',
+ CPLD: 'xyz.openbmc_project.Software.Version.VersionPurpose.CPLD',
+ FPGA: 'xyz.openbmc_project.Software.Version.VersionPurpose.FPGA',
+ BIOS: 'xyz.openbmc_project.Software.Version.VersionPurpose.Host',
+ PSU: 'xyz.openbmc_project.Software.Version.VersionPurpose.PSU',
+ HSBP: 'xyz.openbmc_project.Software.Version.VersionPurpose.HSBP',
+ FCB: 'xyz.openbmc_project.Software.Version.VersionPurpose.FCB',
+};
const FirmwareStore = {
namespaced: true,
state: {
bmcFirmware: [],
hostFirmware: [],
+ uploadFirmwareType: null,
+ uploadFirmwareState: null,
+ uploadFirmwareId: null,
+ firmwareFunctionData: [],
+ meFirmware: [],
cpldFirmware: [],
- fbcpldFirmware: [],
+ fcbCpldFirmware: [],
+ fpgaFirmware: [],
bmcActiveFirmwareId: null,
hostActiveFirmwareId: null,
applyTime: null,
httpPushUri: null,
tftpAvailable: false,
+ firmwareStatus: null,
+ isFirmwareProgress: false,
+ isNeedCycle: false,
+ bmcIsUpdating: false,
+ bmcIsUpdatingfCurrentPartition: false,
},
getters: {
+ uploadFirmwareId: (state) => state.uploadFirmwareId,
+ uploadFirmwareState: (state) => state.uploadFirmwareState,
+ uploadFirmwareType: (state) => state.uploadFirmwareType,
+ priorityFirmware: (state) => {
+ return state.firmwareFunctionData.find(
+ (firmware) => firmware.Purpose === FIRMWARE_PURPOSE.BMC
+ );
+ },
+ meFirmware: (state) => {
+ return state.meFirmware.find((firmware) => firmware.id === 'me');
+ },
+ fpgaFirmware: (state) => {
+ return state.fpgaFirmware.find(
+ (firmware) => firmware.id === 'fpga_active'
+ );
+ },
isTftpUploadAvailable: (state) => state.tftpAvailable,
isSingleFileUploadEnabled: (state) => state.hostFirmware.length === 0,
activeBmcFirmware: (state) => {
@@ -29,7 +66,9 @@ const FirmwareStore = {
},
backupBmcFirmware: (state) => {
return state.bmcFirmware.find(
- (firmware) => firmware.id !== state.bmcActiveFirmwareId
+ (firmware) =>
+ firmware.id !== state.bmcActiveFirmwareId &&
+ firmware.state === 'Enabled'
);
},
backupHostFirmware: (state) => {
@@ -42,28 +81,53 @@ const FirmwareStore = {
(firmware) => firmware.id === 'cpld_active'
);
},
- fbcpldFirmware: (state) => {
- return state.fbcpldFirmware.find(
- (firmware) => firmware.id === 'fb_cpld_active'
+ fcbCpldFirmware: (state) => {
+ return state.fcbCpldFirmware.find(
+ (firmware) => firmware.id === 'fcb_cpld_active'
);
},
+ allFirmwareStatus: (state) => state.firmwareStatus,
+ isFirmwareProgress: (state) => state.isFirmwareProgress,
+ isNeedCycle: (state) => state.isNeedCycle,
+ bmcIsUpdating: (state) => state.bmcIsUpdating,
+ bmcIsUpdatingfCurrentPartition: (state) =>
+ state.bmcIsUpdatingfCurrentPartition,
},
mutations: {
+ setFirmwareFunctionData: (state, firmware) =>
+ (state.firmwareFunctionData = firmware),
+ setMeFirmware: (state, firmware) => (state.meFirmware = firmware),
+ setFPGAFirmware: (state, firmware) => (state.fpgaFirmware = firmware),
setActiveBmcFirmwareId: (state, id) => (state.bmcActiveFirmwareId = id),
setActiveHostFirmwareId: (state, id) => (state.hostActiveFirmwareId = id),
setBmcFirmware: (state, firmware) => (state.bmcFirmware = firmware),
setHostFirmware: (state, firmware) => (state.hostFirmware = firmware),
setCPLDFirmware: (state, firmware) => (state.cpldFirmware = firmware),
- setFBCPLDFirmware: (state, firmware) => (state.fbcpldFirmware = firmware),
+ setFcbCpldFirmware: (state, firmware) => (state.fcbCpldFirmware = firmware),
setApplyTime: (state, applyTime) => (state.applyTime = applyTime),
setHttpPushUri: (state, httpPushUri) => (state.httpPushUri = httpPushUri),
setTftpUploadAvailable: (state, tftpAvailable) =>
(state.tftpAvailable = tftpAvailable),
+ setFirmwareUpdateStatus: (state, status) => (state.firmwareStatus = status),
+ setIsFirmwareProgress: (state, isProgress) =>
+ (state.isFirmwareProgress = isProgress),
+ setIsNeedCycle: (state, isNeedCycle) => (state.isNeedCycle = isNeedCycle),
+ setBmcIsUpdating: (state, bmcIsUpdating) =>
+ (state.bmcIsUpdating = bmcIsUpdating),
+ setBmcIsUpdatingfCurrentPartition: (state, bool) => {
+ state.bmcIsUpdatingfCurrentPartition = bool;
+ },
+ setBmcUpdateProgress: (state, progress) => {
+ const bmcFirmware = state.firmwareStatus.find((it) => it.BMC);
+ bmcFirmware.BMC.UpdateProgress = progress;
+ bmcFirmware.BMC.UpdateStatus = progress === 100 ? 'Updated' : 'Updating';
+ },
},
actions: {
async getFirmwareInformation({ dispatch }) {
dispatch('getActiveHostFirmware');
dispatch('getActiveBmcFirmware');
+ dispatch('getFirmwareFunctionData');
return await dispatch('getFirmwareInventory');
},
getActiveBmcFirmware({ commit }) {
@@ -94,10 +158,12 @@ const FirmwareStore = {
await api
.all(inventoryList)
.then((response) => {
+ const meFirmware = [];
+ const fpgaFirmware = [];
const bmcFirmware = [];
const hostFirmware = [];
const cpldFirmware = [];
- const fbcpldFirmware = [];
+ const fcbCpldFirmware = [];
response.forEach(({ data }) => {
const firmwareType = data?.RelatedItem?.[0]?.['@odata.id']
.split('/')
@@ -108,24 +174,29 @@ const FirmwareStore = {
location: data?.['@odata.id'],
status: data?.Status?.Health,
reldate: data?.ReleaseDate,
+ state: data?.Status?.State,
};
if (firmwareType === 'bmc') {
bmcFirmware.push(item);
} else if (firmwareType === 'Bios') {
hostFirmware.push(item);
}
-
if (item.id === 'cpld_active') {
cpldFirmware.push(item);
- }
- if (item.id === 'fb_cpld_active') {
- fbcpldFirmware.push(item);
+ } else if (item.id === 'fpga_active') {
+ fpgaFirmware.push(item);
+ } else if (item.id === 'me') {
+ meFirmware.push(item);
+ } else if (item.id === 'fcb_cpld_active') {
+ fcbCpldFirmware.push(item);
}
});
commit('setBmcFirmware', bmcFirmware);
commit('setHostFirmware', hostFirmware);
commit('setCPLDFirmware', cpldFirmware);
- commit('setFBCPLDFirmware', fbcpldFirmware);
+ commit('setFcbCpldFirmware', fcbCpldFirmware);
+ commit('setFPGAFirmware', fpgaFirmware);
+ commit('setMeFirmware', meFirmware);
})
.catch((error) => {
console.log(error);
@@ -214,6 +285,131 @@ const FirmwareStore = {
throw new Error(i18n.t('pageFirmware.toast.errorSwitchImages'));
});
},
+ // ======================== firmware OEM ========================
+ getFirmwareFunctionData({ commit }) {
+ return api
+ .get('/xyz/openbmc_project/software/functional')
+ .then((response) =>
+ api.all(response.data.data.endpoints.map((bmcurl) => api.get(bmcurl)))
+ )
+ .then((bmcResult) => {
+ const bmcStateData = bmcResult.map((datas) => datas.data.data);
+ commit('setFirmwareFunctionData', bmcStateData);
+ })
+ .catch((error) => {
+ console.log(error);
+ });
+ },
+ // ----------------- firmware update ----------
+ async uploadFirmwareOEM({ commit }, image) {
+ console.log('image', image);
+ const data = new FormData();
+ data.append('fwimage', image);
+ commit('setIsFirmwareProgress', true);
+ return await api
+ .post(
+ '/redfish/v1/UpdateService/Actions/Oem/Luxshare/FirmwareFile',
+ data
+ )
+ .then((response) => {
+ console.log('upload success', response);
+ return response;
+ })
+ .catch((error) => {
+ console.log('upload error', error);
+ throw new Error(i18n.t('pageFirmware.toast.errorUploadFirmware'));
+ })
+ .finally(() => commit('setIsFirmwareProgress', false));
+ },
+ async getAllUpdateStatus({ commit }) {
+ return await api
+ .get('/redfish/v1/UpdateService/Actions/Oem/Luxshare/FirmwareStatus')
+ .then((response) => {
+ // if (state.bmcIsUpdating) return;
+ commit('setFirmwareUpdateStatus', response.data.Oem.Luxshare);
+ const isNeedCycle = response.data.Oem.Luxshare.find((firmware) => {
+ const entries = Object.entries(firmware);
+ return (
+ entries[0][1].UpdateStatus === 'Queued' ||
+ (entries[0][0] === 'Retimer' &&
+ entries[0][1].UpdateStatus === 'Updated')
+ );
+ });
+ commit('setIsNeedCycle', !!isNeedCycle);
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageFirmware.toast.errorGetUpdateStatus'));
+ });
+ },
+ async startUpdate({ commit }, updateConfigs) {
+ commit('setIsFirmwareProgress', true);
+ return await api
+ .post(
+ '/redfish/v1/UpdateService/Actions/Oem/Luxshare/FirmwareUpdate',
+ updateConfigs
+ )
+ .finally(() => commit('setIsFirmwareProgress', false));
+ },
+ async deleteFirmware(_, target) {
+ console.log('target', target);
+ return await api.delete(
+ '/redfish/v1/UpdateService/Actions/Oem/Luxshare/FirmwareUpdate',
+ {
+ data: {
+ Target: target,
+ },
+ }
+ );
+ },
+ async pollingBmcUpdateStatus() {
+ const timeout = 3000;
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ reject();
+ }, timeout);
+ api
+ .get('/redfish/v1/UpdateService/Actions/Oem/Luxshare/FirmwareStatus')
+ .then((res) => {
+ const progress = res.data.Oem.Luxshare?.[0]?.BMC?.UpdateProgress;
+ resolve(progress);
+ })
+ .catch((error) => {
+ reject(error);
+ });
+ });
+ },
+ getBmcUpdateStatus({ state, commit, dispatch }) {
+ dispatch('pollingBmcUpdateStatus')
+ .then((progress) => {
+ const bmcFirmware = state.firmwareStatus.find((it) => it.BMC);
+ if (bmcFirmware.BMC.UpdateProgress === 100) {
+ return;
+ } else if (
+ progress !== undefined &&
+ progress > bmcFirmware.BMC.UpdateProgress
+ ) {
+ commit('setBmcUpdateProgress', progress);
+ }
+ if (progress === 100) {
+ bus.$emit('bmcUpdateComplete');
+ localStorage.setItem('loggingStatus', 'logout');
+ commit('authentication/logout', null, { root: true });
+ } else {
+ setTimeout(() => {
+ dispatch('getBmcUpdateStatus');
+ }, 3000);
+ }
+ })
+ .catch(() => {
+ const bmcFirmware = state.firmwareStatus.find((it) => it.BMC);
+ if (bmcFirmware.BMC.UpdateProgress === 100) return;
+ setTimeout(() => {
+ dispatch('getBmcUpdateStatus');
+ }, 3000);
+ });
+ },
+ // ======================== END ========================
},
};
diff --git a/src/utilities/bus.js b/src/utilities/bus.js
new file mode 100755
index 0000000..68259ae
--- /dev/null
+++ b/src/utilities/bus.js
@@ -0,0 +1,2 @@
+import Vue from 'vue';
+export const bus = new Vue();
diff --git a/src/views/Operations/Firmware/Firmware.vue b/src/views/Operations/Firmware/Firmware.vue
index 25fe0bb..106da18 100644
--- a/src/views/Operations/Firmware/Firmware.vue
+++ b/src/views/Operations/Firmware/Firmware.vue
@@ -13,15 +13,37 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -34,17 +56,29 @@
+
+
+
+
+
+
+
diff --git a/src/views/Operations/Firmware/FirmwareCardsBmc.vue b/src/views/Operations/Firmware/FirmwareCardsBmc.vue
index 8765f77..37c9cf8 100644
--- a/src/views/Operations/Firmware/FirmwareCardsBmc.vue
+++ b/src/views/Operations/Firmware/FirmwareCardsBmc.vue
@@ -10,6 +10,8 @@
+ - {{ priorityFirmware }}
+
- {{ $t('pageFirmware.cardBodyVersion') }}
- {{ runningVersion }}
@@ -28,6 +30,8 @@
+ - {{ backupFirmware }}
+
- {{ $t('pageFirmware.cardBodyVersion') }}
-
@@ -82,6 +86,26 @@ export default {
};
},
computed: {
+ priorityFirmware() {
+ const pri = this.$store.getters['firmware/priorityFirmware'];
+ if (pri?.Priority === 0) {
+ return this.$t('pageFirmware.primaryImage');
+ }
+ if (pri?.Priority === 1) {
+ return this.$t('pageFirmware.secondaryImage');
+ }
+ return '';
+ },
+ backupFirmware() {
+ const pri = this.$store.getters['firmware/priorityFirmware'];
+ if (pri?.Priority === 0) {
+ return this.$t('pageFirmware.secondaryImage');
+ }
+ if (pri?.Priority === 1) {
+ return this.$t('pageFirmware.primaryImage');
+ }
+ return '';
+ },
isSingleFileUploadEnabled() {
return this.$store.getters['firmware/isSingleFileUploadEnabled'];
},
@@ -114,6 +138,9 @@ export default {
this.backupStatus === 'Critical' || this.backupStatus === 'Warning'
);
},
+ backupReleaseDate() {
+ return this.backup?.reldate || '--';
+ },
},
methods: {
switchToRunning() {
diff --git a/src/views/Operations/Firmware/FirmwareCardsFPGA.vue b/src/views/Operations/Firmware/FirmwareCardsFPGA.vue
new file mode 100755
index 0000000..f1f5ddd
--- /dev/null
+++ b/src/views/Operations/Firmware/FirmwareCardsFPGA.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+ {{ $t('pageFirmware.cardTitleRunning') }}
+
+
+
+ - {{ $t('pageFirmware.cardBodyVersion') }}
+ - {{ runningVersion }}
+
+
+
+
+
+
+
+
+
diff --git a/src/views/Operations/Firmware/FirmwareCardsFcbCPLD.vue b/src/views/Operations/Firmware/FirmwareCardsFcbCPLD.vue
new file mode 100755
index 0000000..79294d5
--- /dev/null
+++ b/src/views/Operations/Firmware/FirmwareCardsFcbCPLD.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+ {{ $t('pageFirmware.cardTitleRunning') }}
+
+
+
+ - {{ $t('pageFirmware.cardBodyVersion') }}
+ - {{ runningVersion }}
+
+
+
+
+
+
+
+
+
diff --git a/src/views/Operations/Firmware/FirmwareCardsMe.vue b/src/views/Operations/Firmware/FirmwareCardsMe.vue
new file mode 100755
index 0000000..8828463
--- /dev/null
+++ b/src/views/Operations/Firmware/FirmwareCardsMe.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+ {{ $t('pageFirmware.cardTitleRunning') }}
+
+
+
+ - {{ $t('pageFirmware.cardBodyVersion') }}
+ - {{ runningVersion }}
+
+
+
+
+
+
+
+
+
diff --git a/src/views/Operations/Firmware/FirmwareModalUpdateFirmware.vue b/src/views/Operations/Firmware/FirmwareModalUpdateFirmware.vue
index 1835521..79ee979 100644
--- a/src/views/Operations/Firmware/FirmwareModalUpdateFirmware.vue
+++ b/src/views/Operations/Firmware/FirmwareModalUpdateFirmware.vue
@@ -6,6 +6,9 @@
:cancel-title="$t('global.action.cancel')"
@ok="$emit('ok')"
>
+
+ {{ $t('pageFirmware.toast.bmcUpdateTips') }}
+
{{ $t('pageFirmware.modal.updateFirmwareInfo') }}
@@ -21,6 +24,22 @@
{{ $t('pageFirmware.modal.updateFirmwareInfo3') }}
+
+ {{ $t('pageFirmware.modal.updateFirmwareInfoOem') }}
+
+
+ {{ $t('pageFirmware.modal.updateFirmwareInfoOemBmc') }}
+
{{ $t('pageFirmware.modal.updateFirmwareInfoDefault') }}
@@ -29,6 +48,16 @@
+
--
2.25.1