1import api from '@/store/api'; 2import i18n from '@/i18n'; 3 4const FirmwareStore = { 5 namespaced: true, 6 state: { 7 bmcFirmware: [], 8 hostFirmware: [], 9 bmcActiveFirmwareId: null, 10 hostActiveFirmwareId: null, 11 applyTime: null, 12 multipartHttpPushUri: null, 13 httpPushUri: null, 14 }, 15 getters: { 16 isSingleFileUploadEnabled: (state) => state.hostFirmware.length === 0, 17 activeBmcFirmware: (state) => { 18 return state.bmcFirmware.find( 19 (firmware) => firmware.id === state.bmcActiveFirmwareId, 20 ); 21 }, 22 activeHostFirmware: (state) => { 23 return state.hostFirmware.find( 24 (firmware) => firmware.id === state.hostActiveFirmwareId, 25 ); 26 }, 27 backupBmcFirmware: (state) => { 28 return state.bmcFirmware.find( 29 (firmware) => firmware.id !== state.bmcActiveFirmwareId, 30 ); 31 }, 32 backupHostFirmware: (state) => { 33 return state.hostFirmware.find( 34 (firmware) => firmware.id !== state.hostActiveFirmwareId, 35 ); 36 }, 37 }, 38 mutations: { 39 setActiveBmcFirmwareId: (state, id) => (state.bmcActiveFirmwareId = id), 40 setActiveHostFirmwareId: (state, id) => (state.hostActiveFirmwareId = id), 41 setBmcFirmware: (state, firmware) => (state.bmcFirmware = firmware), 42 setHostFirmware: (state, firmware) => (state.hostFirmware = firmware), 43 setApplyTime: (state, applyTime) => (state.applyTime = applyTime), 44 setHttpPushUri: (state, httpPushUri) => (state.httpPushUri = httpPushUri), 45 setMultipartHttpPushUri: (state, multipartHttpPushUri) => 46 (state.multipartHttpPushUri = multipartHttpPushUri), 47 }, 48 actions: { 49 async getFirmwareInformation({ dispatch }) { 50 dispatch('getActiveHostFirmware'); 51 dispatch('getActiveBmcFirmware'); 52 return await dispatch('getFirmwareInventory'); 53 }, 54 async getActiveBmcFirmware({ commit }) { 55 return api 56 .get(`${await this.dispatch('global/getBmcPath')}`) 57 .then(({ data: { Links } }) => { 58 const id = Links?.ActiveSoftwareImage['@odata.id'].split('/').pop(); 59 commit('setActiveBmcFirmwareId', id); 60 }) 61 .catch((error) => console.log(error)); 62 }, 63 async getActiveHostFirmware({ commit }) { 64 return api 65 .get(`${await this.dispatch('global/getSystemPath')}/Bios`) 66 .then(({ data: { Links } }) => { 67 const id = Links?.ActiveSoftwareImage['@odata.id'].split('/').pop(); 68 commit('setActiveHostFirmwareId', id); 69 }) 70 .catch((error) => console.log(error)); 71 }, 72 async getFirmwareInventory({ commit }) { 73 const inventoryList = await api 74 .get('/redfish/v1/UpdateService/FirmwareInventory') 75 .then(({ data: { Members = [] } = {} }) => 76 Members.map((item) => api.get(item['@odata.id'])), 77 ) 78 .catch((error) => console.log(error)); 79 await api 80 .all(inventoryList) 81 .then((response) => { 82 const bmcFirmware = []; 83 const hostFirmware = []; 84 response.forEach(({ data }) => { 85 const firmwareType = data?.RelatedItem?.[0]?.['@odata.id'] 86 .split('/') 87 .pop(); 88 const item = { 89 version: data?.Version, 90 id: data?.Id, 91 location: data?.['@odata.id'], 92 status: data?.Status?.Health, 93 }; 94 if (firmwareType === 'bmc') { 95 bmcFirmware.push(item); 96 } else if (firmwareType === 'Bios') { 97 hostFirmware.push(item); 98 } 99 }); 100 commit('setBmcFirmware', bmcFirmware); 101 commit('setHostFirmware', hostFirmware); 102 }) 103 .catch((error) => { 104 console.log(error); 105 }); 106 }, 107 getUpdateServiceSettings({ commit }) { 108 api 109 .get('/redfish/v1/UpdateService') 110 .then(({ data }) => { 111 const applyTime = 112 data.HttpPushUriOptions.HttpPushUriApplyTime.ApplyTime; 113 commit('setApplyTime', applyTime); 114 const httpPushUri = data.HttpPushUri; 115 commit('setHttpPushUri', httpPushUri); 116 const multipartHttpPushUri = data.MultipartHttpPushUri; 117 commit('setMultipartHttpPushUri', multipartHttpPushUri); 118 }) 119 .catch((error) => console.log(error)); 120 }, 121 async uploadFirmware({ state, dispatch }, params) { 122 if (state.multipartHttpPushUri != null) { 123 return dispatch('uploadFirmwareMultipartHttpPush', params); 124 } else if (state.httpPushUri != null) { 125 return dispatch('uploadFirmwareHttpPush', params); 126 } else { 127 console.log('Do not support firmware push update'); 128 } 129 }, 130 async uploadFirmwareHttpPush({ state }, { image }) { 131 return await api 132 .post(state.httpPushUri, image, { 133 headers: { 'Content-Type': 'application/octet-stream' }, 134 }) 135 .catch((error) => { 136 console.log(error); 137 throw new Error( 138 i18n.global.t('pageFirmware.toast.errorUpdateFirmware'), 139 ); 140 }); 141 }, 142 async uploadFirmwareMultipartHttpPush({ state }, { image, targets }) { 143 const formData = new FormData(); 144 formData.append('UpdateFile', image); 145 let params = {}; 146 if (targets != null && targets.length > 0) { 147 params.Targets = targets; 148 } else { 149 // TODO: Should be OK to leave Targets out, remove this clause 150 // when bmcweb is updated 151 params.Targets = [`${await this.dispatch('global/getBmcPath')}`]; 152 } 153 formData.append('UpdateParameters', JSON.stringify(params)); 154 return await api 155 .post(state.multipartHttpPushUri, formData, { 156 headers: { 'Content-Type': 'multipart/form-data' }, 157 }) 158 .catch((error) => { 159 console.log(error); 160 throw new Error( 161 i18n.global.t('pageFirmware.toast.errorUpdateFirmware'), 162 ); 163 }); 164 }, 165 async switchBmcFirmwareAndReboot({ getters }) { 166 const backupLocation = getters.backupBmcFirmware.location; 167 const data = { 168 Links: { 169 ActiveSoftwareImage: { 170 '@odata.id': backupLocation, 171 }, 172 }, 173 }; 174 return await api 175 .patch(`${await this.dispatch('global/getBmcPath')}`, data) 176 .catch((error) => { 177 console.log(error); 178 throw new Error( 179 i18n.global.t('pageFirmware.toast.errorSwitchImages'), 180 ); 181 }); 182 }, 183 }, 184}; 185 186export default FirmwareStore; 187