summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandr Ilenko <AIlenko@IBS.RU>2022-09-15 18:16:54 +0300
committerAlexandr Ilenko <AIlenko@IBS.RU>2022-09-15 18:16:54 +0300
commit9a98353618d13ee4ae2a724cf3e58aca848d09e0 (patch)
treec28cf54285e0006a2eea089f88da175da703f1b2
parent413ec1e968858b145a0ee7d254da82bf0e6c257e (diff)
downloadwebui-vue-9a98353618d13ee4ae2a724cf3e58aca848d09e0.tar.xz
[SILABMC-248] Fix: add redfish transition state polling for VirtualMedia (store)
-rw-r--r--src/store/modules/Operations/VirtualMediaStore.js142
1 files changed, 138 insertions, 4 deletions
diff --git a/src/store/modules/Operations/VirtualMediaStore.js b/src/store/modules/Operations/VirtualMediaStore.js
index 5cd8f98c..b9eefa2b 100644
--- a/src/store/modules/Operations/VirtualMediaStore.js
+++ b/src/store/modules/Operations/VirtualMediaStore.js
@@ -19,6 +19,13 @@ const VirtualMediaStore = {
proxyDevices: [],
legacyDevices: [],
connections: [],
+ // VirtualMedia`s log shows some 90 secs timeout (nbd-client`s output)
+ // kernel log shows some ~90 secs timeout in ndb device driver
+ // Let`s use 2*60 secs. Experiments showed it is enough by the moment.
+ legacyDevicesTransitionStateInitialTimeout: 2 * 60,
+ legacyDevicesTransitionStateZeroTimeout: 0,
+ legacyDevicesTransitionStatePollInterval: 1,
+ legacyDevicesTransitionStateTimerId: null,
},
getters: {
proxyDevices: (state) => state.proxyDevices,
@@ -29,9 +36,26 @@ const VirtualMediaStore = {
(state.proxyDevices = deviceData),
setLegacyDevicesData: (state, deviceData) =>
(state.legacyDevices = deviceData),
+ setLegacyDevicesTransitionStateTimerId: (state, newTimerId) => {
+ if (state.legacyDevicesTransitionStateTimerId != null) {
+ clearTimeout(state.legacyDevicesTransitionStateTimerId);
+ }
+ state.legacyDevicesTransitionStateTimerId = newTimerId;
+ },
+ patchLegacyDevice: (state, devicePatch) => {
+ state.legacyDevices = state.legacyDevices.map((device) => {
+ if (device.id === devicePatch.id) {
+ device = {
+ ...device,
+ ...devicePatch,
+ };
+ }
+ return device;
+ });
+ },
},
actions: {
- async getData({ commit }) {
+ async getData({ commit, state }) {
const virtualMediaListEnabled =
process.env.VUE_APP_VIRTUAL_MEDIA_LIST_ENABLED === 'true'
? true
@@ -43,6 +67,7 @@ const VirtualMediaStore = {
file: null,
transferProtocolType: transferProtocolType.OEM,
isActive: false,
+ isConnected: undefined,
};
commit('setProxyDevicesData', [device]);
return;
@@ -56,12 +81,30 @@ const VirtualMediaStore = {
.then((devices) => api.all(devices.map((device) => api.get(device))))
.then((devices) => {
const deviceData = devices.map((device) => {
+ const id = device.data?.Id;
const isActive = device.data?.Inserted === true ? true : false;
+ const isConnected = device.data?.ConnectedVia !== undefined;
+ let serverUri = device.data?.Image;
+ let isRW = device.data?.WriteProtected === false ? true : false;
+ if (serverUri === undefined) {
+ const device = state.legacyDevices.find(
+ (device) => device.id === id
+ );
+ if (device !== undefined) {
+ serverUri = device.serverUri;
+ isRW = device.isRW;
+ } else {
+ serverUri = '';
+ }
+ }
return {
- id: device.data?.Id,
+ id: id,
transferProtocolType: device.data?.TransferProtocolType,
websocket: device.data?.Oem?.OpenBMC?.WebSocketEndpoint,
isActive: isActive,
+ isConnected: isConnected,
+ serverUri: serverUri,
+ isRW: isRW,
};
});
const proxyDevices = deviceData
@@ -75,12 +118,20 @@ const VirtualMediaStore = {
const legacyDevices = deviceData
.filter((d) => d.transferProtocolType !== transferProtocolType.OEM)
.map((device) => {
+ let newTimeout = state.legacyDevicesTransitionStateZeroTimeout;
+ if (device.isConnected && !device.isActive) {
+ this.dispatch(
+ 'virtualMedia/pollLegacyDevicesTransitionState',
+ device.id
+ );
+ // re-commit the state
+ newTimeout = state.legacyDevicesTransitionStateInitialTimeout;
+ }
return {
...device,
- serverUri: '',
username: '',
password: '',
- isRW: false,
+ legacyDeviceTransitionStateTimeout: newTimeout,
};
});
proxyDevices.sort((a, b) => a.id.localeCompare(b.id));
@@ -92,12 +143,92 @@ const VirtualMediaStore = {
console.log('Virtual Media:', error);
});
},
+ async getLegacyDeviceData({ commit, state }, id) {
+ const device = state.legacyDevices.find((device) => device.id === id);
+ let newTimeout = device.legacyDeviceTransitionStateTimeout - 1;
+ if (
+ device.legacyDeviceTransitionStateTimeout %
+ state.legacyDevicesTransitionStatePollInterval !=
+ 0
+ ) {
+ const devicePatch = {
+ id: id,
+ legacyDeviceTransitionStateTimeout: newTimeout,
+ };
+ commit('patchLegacyDevice', devicePatch);
+ return;
+ }
+ return await api
+ .get(`/redfish/v1/Managers/bmc/VirtualMedia/${id}`)
+ .then((response) => {
+ if (response.data?.Id !== id) {
+ console.log(
+ `VirtualMedia: Error: expected_id=${id}, actual_id=${response.data?.Id}`
+ );
+ }
+ const isActive = response.data?.Inserted === true ? true : false;
+ const isConnected = response.data?.ConnectedVia !== undefined;
+ if (!(isConnected && !isActive)) {
+ newTimeout = device.legacyDevicesTransitionStateZeroTimeout - 1;
+ }
+ const devicePatch = {
+ id: id,
+ isActive: isActive,
+ isConnected: isConnected,
+ legacyDeviceTransitionStateTimeout: newTimeout,
+ };
+ commit('patchLegacyDevice', devicePatch);
+ })
+ .catch((error) => {
+ console.log('Virtual Media:', error);
+ });
+ },
+ async pollLegacyDevicesTransitionState({ commit, state }, id = undefined) {
+ let needRescheduling = false;
+ if (id !== undefined) {
+ const devicePatch = {
+ id: id,
+ isConnected: true,
+ isActive: false,
+ legacyDeviceTransitionStateTimeout:
+ state.legacyDevicesTransitionStateInitialTimeout,
+ };
+ commit('patchLegacyDevice', devicePatch);
+ needRescheduling = true;
+ } else {
+ const devicesCount = state.legacyDevices
+ .filter((device) => {
+ return (
+ device.isConnected &&
+ !device.isActive &&
+ device.legacyDeviceTransitionStateTimeout >
+ state.legacyDevicesTransitionStateZeroTimeout
+ );
+ })
+ .map((device) => {
+ this.dispatch('virtualMedia/getLegacyDeviceData', device.id);
+ })
+ .reduce((previous) => previous + 1, 0);
+ needRescheduling = devicesCount > 0;
+ }
+ let newRescheduleTimerId = null;
+ if (needRescheduling) {
+ const pollTimeout = 1 * 1000;
+ newRescheduleTimerId = setTimeout(() => {
+ this.dispatch('virtualMedia/pollLegacyDevicesTransitionState');
+ }, pollTimeout);
+ }
+ commit('setLegacyDevicesTransitionStateTimerId', newRescheduleTimerId);
+ },
async mountImage(_, { id, data }) {
return await api
.post(
`/redfish/v1/Managers/bmc/VirtualMedia/${id}/Actions/VirtualMedia.InsertMedia`,
data
)
+ .then(() => {
+ this.dispatch('virtualMedia/pollLegacyDevicesTransitionState', id);
+ })
.catch((error) => {
console.log('Mount image:', error);
throw new Error();
@@ -108,6 +239,9 @@ const VirtualMediaStore = {
.post(
`/redfish/v1/Managers/bmc/VirtualMedia/${id}/Actions/VirtualMedia.EjectMedia`
)
+ .then(() => {
+ this.dispatch('virtualMedia/pollLegacyDevicesTransitionState', id);
+ })
.catch((error) => {
console.log('Unmount image:', error);
throw new Error();