Skip to content

Commit 01e749d

Browse files
yoshiemuranakarfrandse
authored andcommitted
Add two file firmware update
Adds the ability to upload separate Host and BMC firmware images through the GUI. By default, the two file firmware update page will be shown. Changes to the .env configurations will enable the single file upload page. The IBM env is configured to allow single file firmware update. Two file upload features: - File upload through local workstation or tftp server - Reboot from backup BMC image - Does not have ability to reboot from backup host image - Does not implement checks in GUI for host status, which is the same as what we have in phosphor-webui Signed-off-by: Yoshie Muranaka <[email protected]> Change-Id: Ibf2a2d9ffc3952dd5a5454c723350c61d9f91c3e
1 parent dd7d4ad commit 01e749d

File tree

9 files changed

+267
-196
lines changed

9 files changed

+267
-196
lines changed

src/env/components/FirmwareSingleImage/FirmwareSingleImage.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<b-container fluid="xl">
3-
<page-title :description="$t('pageFirmware.pageDescription')" />
3+
<page-title :description="$t('pageFirmware.pageDescriptionSingleImage')" />
44
<!-- Operation in progress alert -->
55
<alert v-if="isOperationInProgress" variant="info" class="mb-5">
66
<p>
@@ -183,7 +183,7 @@
183183
<p class="font-weight-bold mb-1">
184184
{{ $t('pageFirmware.alert.updateProcess') }}
185185
</p>
186-
<p>{{ $t('pageFirmware.alert.updateProcessInfo') }}</p>
186+
<p>{{ $t('pageFirmware.alert.updateProcessInfoSingleImage') }}</p>
187187
</alert>
188188
<b-form-group>
189189
<b-btn type="submit" variant="primary" :disabled="isPageDisabled">
@@ -271,7 +271,7 @@ export default {
271271
this.$store.dispatch('firmwareSingleImage/getUpdateServiceApplyTime');
272272
Promise.all([
273273
this.$store.dispatch('global/getHostStatus'),
274-
this.$store.dispatch('firmwareSingleImage/getSystemFirwareVersion')
274+
this.$store.dispatch('firmwareSingleImage/getFirmwareInformation')
275275
]).finally(() => this.endLoader());
276276
},
277277
beforeRouteLeave(to, from, next) {
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
<template>
22
<b-modal
33
id="modal-upload"
4-
:title="$t('pageFirmware.modal.uploadAndReboot.title')"
5-
:ok-title="$t('pageFirmware.modal.uploadAndReboot.primaryAction')"
4+
:title="$t('pageFirmware.modal.uploadAndRebootSingleImage.title')"
5+
:ok-title="
6+
$t('pageFirmware.modal.uploadAndRebootSingleImage.primaryAction')
7+
"
68
@ok="$emit('ok')"
79
>
810
<p>
9-
{{ $t('pageFirmware.modal.uploadAndReboot.message1') }}
11+
{{ $t('pageFirmware.modal.uploadAndRebootSingleImage.message1') }}
1012
</p>
1113
<p>
12-
{{ $t('pageFirmware.modal.uploadAndReboot.message2') }}
14+
{{ $t('pageFirmware.modal.uploadAndRebootSingleImage.message2') }}
1315
</p>
1416
<p class="font-weight-bold">
15-
{{ $t('pageFirmware.modal.uploadAndReboot.message3') }}
17+
{{ $t('pageFirmware.modal.uploadAndRebootSingleImage.message3') }}
1618
</p>
1719
</b-modal>
1820
</template>

src/env/store/FirmwareSingleImage/FirmwareSingleImageStore.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ const FirmwareSingleImageStore = {
2222
backupFirmwareVersion: state => state.backupFirmware.version,
2323
backupFirmwareStatus: state => state.backupFirmware.status,
2424
isRebootFromBackupAvailable: state =>
25-
state.backupFirmware.id ? true : false
25+
state.backupFirmware.id ? true : false,
26+
bmcFirmwareCurrentVersion: state => state.activeFirmware.version //this getter is needed for the Overview page
2627
},
2728
mutations: {
2829
setActiveFirmware: (state, { version, id, location }) => {
@@ -39,7 +40,7 @@ const FirmwareSingleImageStore = {
3940
setApplyTime: (state, applyTime) => (state.applyTime = applyTime)
4041
},
4142
actions: {
42-
async getSystemFirwareVersion({ commit }) {
43+
async getFirmwareInformation({ commit }) {
4344
return await api
4445
.get('/redfish/v1/Managers/bmc')
4546
.then(({ data: { Links } }) => {

src/locales/en-US.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,13 @@
199199
"changeAndRebootBmc": "Change image and reboot BMC",
200200
"changeToBackupImage": "Change to backup image",
201201
"current": "Current:",
202+
"firmwareOnBmc": "Firmware on BMC",
203+
"firmwareOnHost": "Firmware on host",
202204
"firmwareOnSystem": "Firmware on system",
203205
"hostStatus": "Host status",
204-
"pageDescription": "Update firmware by uploading a system image file from your workstation or TFTP server",
206+
"makeCurrentVersion": "Make current version",
207+
"pageDescription": "Update firmware by uploading a BMC or Host image file from your workstation or TFTP server",
208+
"pageDescriptionSingleImage": "Update firmware by uploading a system image file from your workstation or TFTP server",
205209
"running": "Running",
206210
"state": "State",
207211
"updateCode": "Update code",
@@ -211,7 +215,8 @@
211215
"serverShutdownRequiredInfo": "Shutdown will be orderly - OS will shutdown before the server shuts down.",
212216
"shutDownServer": "Shut down server",
213217
"updateProcess": "Update process",
214-
"updateProcessInfo": "The new image will be uploaded and activated. After that, the BMC will reboot automatically to run from the new image."
218+
"updateProcessInfo": "The new image will be uploaded and activated. After that, the BMC or host will reboot automatically to run from the new image.",
219+
"updateProcessInfoSingleImage": "The new image will be uploaded and activated. After that, the BMC will reboot automatically to run from the new image."
215220
},
216221
"form": {
217222
"imageFile": "Image file",
@@ -221,6 +226,7 @@
221226
"tftpServerAddress": "TFTP server address",
222227
"tftpServerAddressHelper": "IP address or FQDN",
223228
"uploadAndRebootBmc": "Upload and reboot BMC",
229+
"uploadAndRebootBmcOrHost": "Upload and reboot BMC or host",
224230
"uploadLocation": "Upload location",
225231
"workstation": "Workstation"
226232
},
@@ -236,12 +242,19 @@
236242
"primaryAction": "Reboot BMC from backup image",
237243
"title": "@:pageFirmware.modal.connectionToBmcWillBeLost"
238244
},
239-
"uploadAndReboot": {
245+
"uploadAndRebootSingleImage": {
240246
"message1": "A BMC reboot is required before the system can run the new firmware image. The reboot will cause a disconnection, and may require logging in again.",
241247
"message2": "During the reboot, the server cannot be powered back on. The backup image will be permanently deleted.",
242248
"message3": "Are you sure you want to upload the new firmware image and reboot the BMC?",
243249
"primaryAction": "Upload and reboot BMC",
244250
"title": "@:pageFirmware.modal.connectionToBmcWillBeLost"
251+
},
252+
"uploadAndRebootBmcOrHost": {
253+
"message1": "A BMC or host reboot is required before the system can run the new firmware image. The reboot will cause a disconnection, and may require logging in again.",
254+
"message2": "The backup image will be permanently deleted.",
255+
"message3": "Are you sure you want to upload the new firmware image and reboot the BMC or host?",
256+
"primaryAction": "Upload and reboot BMC or host",
257+
"title": "Connection to BMC or host will be lost"
245258
}
246259
},
247260
"toast": {

src/store/modules/Configuration/FirmwareStore.js

Lines changed: 105 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,126 @@
11
import api from '@/store/api';
22
import i18n from '@/i18n';
33

4+
/**
5+
* Get backup firmware image from SoftwareImages
6+
* The backup is whichever image is not the current
7+
* or "ActiveSoftwareImage"
8+
* @param {Array} list
9+
* @param {String} currentLocation
10+
*/
11+
function getBackupFirmwareLocation(list, currentLocation) {
12+
return list
13+
.map(item => item['@odata.id'])
14+
.find(location => {
15+
const id = location.split('/').pop();
16+
const currentId = currentLocation.split('/').pop();
17+
return id !== currentId;
18+
});
19+
}
20+
421
const FirmwareStore = {
522
namespaced: true,
623
state: {
7-
activeFirmware: {
8-
version: '--',
9-
id: null,
10-
location: null
24+
bmcFirmware: {
25+
currentVersion: null,
26+
currentState: null,
27+
currentLocation: null,
28+
backupVersion: null,
29+
backupState: null,
30+
backupLocation: null
1131
},
12-
backupFirmware: {
13-
version: '--',
14-
id: null,
15-
location: null,
16-
status: '--'
32+
hostFirmware: {
33+
currentVersion: null,
34+
currentState: null,
35+
currentLocation: null,
36+
backupVersion: null,
37+
backupState: null,
38+
backupLocation: null
1739
},
1840
applyTime: null
1941
},
2042
getters: {
21-
systemFirmwareVersion: state => state.activeFirmware.version,
22-
backupFirmwareVersion: state => state.backupFirmware.version,
23-
backupFirmwareStatus: state => state.backupFirmware.status,
24-
isRebootFromBackupAvailable: state =>
25-
state.backupFirmware.id ? true : false
43+
bmcFirmwareCurrentVersion: state => state.bmcFirmware.currentVersion,
44+
bmcFirmwareCurrentState: state => state.bmcFirmware.currentState,
45+
bmcFirmwareBackupVersion: state => state.bmcFirmware.backupVersion,
46+
bmcFirmwareBackupState: state => state.bmcFirmware.backupState,
47+
hostFirmwareCurrentVersion: state => state.hostFirmware.currentVersion,
48+
hostFirmwareCurrentState: state => state.hostFirmware.currentState,
49+
hostFirmwareBackupVersion: state => state.hostFirmware.backupVersion,
50+
hostFirmwareBackupState: state => state.hostFirmware.backupState
2651
},
2752
mutations: {
28-
setActiveFirmware: (state, { version, id, location }) => {
29-
state.activeFirmware.version = version;
30-
state.activeFirmware.id = id;
31-
state.activeFirmware.location = location;
53+
setBmcFirmwareCurrent: (state, { version, location, status }) => {
54+
state.bmcFirmware.currentVersion = version;
55+
state.bmcFirmware.currentState = status;
56+
state.bmcFirmware.currentLocation = location;
57+
},
58+
setBmcFirmwareBackup: (state, { version, location, status }) => {
59+
state.bmcFirmware.backupVersion = version;
60+
state.bmcFirmware.backupState = status;
61+
state.bmcFirmware.backupLocation = location;
3262
},
33-
setBackupFirmware: (state, { version, id, location, status }) => {
34-
state.backupFirmware.version = version;
35-
state.backupFirmware.id = id;
36-
state.backupFirmware.location = location;
37-
state.backupFirmware.status = status;
63+
setHostFirmwareCurrent: (state, { version, location, status }) => {
64+
state.hostFirmware.currentVersion = version;
65+
state.hostFirmware.currentState = status;
66+
state.hostFirmware.currentLocation = location;
67+
},
68+
setHostFirmwareBackup: (state, { version, location, status }) => {
69+
state.hostFirmware.backupVersion = version;
70+
state.hostFirmware.backupState = status;
71+
state.hostFirmware.backupLocation = location;
3872
},
3973
setApplyTime: (state, applyTime) => (state.applyTime = applyTime)
4074
},
4175
actions: {
42-
async getSystemFirwareVersion({ commit }) {
76+
async getFirmwareInformation({ dispatch }) {
77+
return await api.all([
78+
dispatch('getBmcFirmware'),
79+
dispatch('getHostFirmware')
80+
]);
81+
},
82+
async getBmcFirmware({ commit }) {
4383
return await api
4484
.get('/redfish/v1/Managers/bmc')
4585
.then(({ data: { Links } }) => {
4686
const currentLocation = Links.ActiveSoftwareImage['@odata.id'];
4787
// Check SoftwareImages list for not ActiveSoftwareImage id
48-
const backupLocation = Links.SoftwareImages.map(
49-
item => item['@odata.id']
50-
).find(location => {
51-
const id = location.split('/').pop();
52-
const currentId = currentLocation.split('/').pop();
53-
return id !== currentId;
88+
const backupLocation = getBackupFirmwareLocation(
89+
Links.SoftwareImages,
90+
currentLocation
91+
);
92+
return { currentLocation, backupLocation };
93+
})
94+
.then(async ({ currentLocation, backupLocation }) => {
95+
const currentData = await api.get(currentLocation);
96+
let backupData = {};
97+
98+
if (backupLocation) {
99+
backupData = await api.get(backupLocation);
100+
}
101+
102+
commit('setBmcFirmwareCurrent', {
103+
version: currentData?.data?.Version,
104+
location: currentData?.data?.['@odata.id'],
105+
status: currentData?.data?.Status?.State
106+
});
107+
commit('setBmcFirmwareBackup', {
108+
version: backupData.data?.Version,
109+
location: backupData.data?.['@odata.id'],
110+
status: backupData.data?.Status?.State
54111
});
112+
})
113+
.catch(error => console.log(error));
114+
},
115+
async getHostFirmware({ commit }) {
116+
return await api
117+
.get('/redfish/v1/Systems/system/Bios')
118+
.then(({ data: { Links } }) => {
119+
const currentLocation = Links.ActiveSoftwareImage['@odata.id'];
120+
const backupLocation = getBackupFirmwareLocation(
121+
Links.SoftwareImages,
122+
currentLocation
123+
);
55124
return { currentLocation, backupLocation };
56125
})
57126
.then(async ({ currentLocation, backupLocation }) => {
@@ -62,14 +131,13 @@ const FirmwareStore = {
62131
backupData = await api.get(backupLocation);
63132
}
64133

65-
commit('setActiveFirmware', {
134+
commit('setHostFirmwareCurrent', {
66135
version: currentData?.data?.Version,
67-
id: currentData?.data?.Id,
68-
location: currentData?.data?.['@odata.id']
136+
location: currentData?.data?.['@odata.id'],
137+
status: currentData?.data?.Status?.State
69138
});
70-
commit('setBackupFirmware', {
139+
commit('setHostFirmwareBackup', {
71140
version: backupData.data?.Version,
72-
id: backupData.data?.Id,
73141
location: backupData.data?.['@odata.id'],
74142
status: backupData.data?.Status?.State
75143
});
@@ -138,8 +206,8 @@ const FirmwareStore = {
138206
throw new Error(i18n.t('pageFirmware.toast.errorUploadAndReboot'));
139207
});
140208
},
141-
async switchFirmwareAndReboot({ state }) {
142-
const backupLoaction = state.backupFirmware.location;
209+
async swtichBmcFirmware({ state }) {
210+
const backupLoaction = state.bmcFirmware.backupLoaction;
143211
const data = {
144212
Links: {
145213
ActiveSoftwareImage: {

0 commit comments

Comments
 (0)