summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/env/components/FirmwareSingleImage/FirmwareSingleImage.vue514
-rw-r--r--src/env/components/FirmwareSingleImage/FirmwareSingleImageModalRebootBackup.vue34
-rw-r--r--src/env/components/FirmwareSingleImage/FirmwareSingleImageModalSwitchToRunning.vue31
-rw-r--r--src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpdateFirmware.vue44
-rw-r--r--src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpload.vue21
-rw-r--r--src/env/store/FirmwareSingleImage/FirmwareSingleImageStore.js17
-rw-r--r--src/layouts/AppLayout.vue3
-rw-r--r--src/locales/en-US.json62
8 files changed, 392 insertions, 334 deletions
diff --git a/src/env/components/FirmwareSingleImage/FirmwareSingleImage.vue b/src/env/components/FirmwareSingleImage/FirmwareSingleImage.vue
index fe87e083..517e5fa1 100644
--- a/src/env/components/FirmwareSingleImage/FirmwareSingleImage.vue
+++ b/src/env/components/FirmwareSingleImage/FirmwareSingleImage.vue
@@ -1,219 +1,270 @@
<template>
<b-container fluid="xl">
- <page-title :description="$t('pageFirmware.pageDescriptionSingleImage')" />
- <!-- Operation in progress alert -->
- <alert v-if="isOperationInProgress" variant="info" class="mb-5">
- <p>
- {{ $t('pageFirmware.alert.operationInProgress') }}
- </p>
- </alert>
- <!-- Shutdown server warning alert -->
- <alert v-else-if="!isHostOff" variant="warning" class="mb-5">
- <p class="font-weight-bold mb-1">
- {{ $t('pageFirmware.alert.serverShutdownRequiredBeforeUpdate') }}
- </p>
- {{ $t('pageFirmware.alert.serverShutdownRequiredInfo') }}
- <template #action>
- <b-btn variant="link" class="text-nowrap" @click="onClickShutDown">
- {{ $t('pageFirmware.alert.shutDownServer') }}
- </b-btn>
- </template>
- </alert>
- <b-row class="mb-4">
- <!-- Firmware on system -->
- <b-col md="10" lg="12" xl="8" class="pr-xl-4">
- <page-section :section-title="$t('pageFirmware.firmwareOnSystem')">
+ <page-title />
+ <b-row>
+ <b-col xl="10">
+ <!-- Operation in progress alert -->
+ <alert v-if="isOperationInProgress" variant="info" class="mb-5">
+ <p>
+ {{ $t('pageFirmware.singleFileUpload.alert.operationInProgress') }}
+ </p>
+ </alert>
+ <!-- Power off server warning alert -->
+ <alert v-else-if="!isHostOff" variant="warning" class="mb-5">
+ <p class="mb-0">
+ {{
+ $t('pageFirmware.singleFileUpload.alert.serverMustBePoweredOffTo')
+ }}
+ </p>
+ <ul class="m-0">
+ <li>
+ {{
+ $t(
+ 'pageFirmware.singleFileUpload.alert.switchRunningAndBackupImages'
+ )
+ }}
+ </li>
+ <li>
+ {{ $t('pageFirmware.singleFileUpload.alert.updateFirmware') }}
+ </li>
+ </ul>
+ <template #action>
+ <b-link to="/control/server-power-operations">
+ {{
+ $t(
+ 'pageFirmware.singleFileUpload.alert.viewServerPowerOperations'
+ )
+ }}
+ </b-link>
+ </template>
+ </alert>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col xl="10">
+ <page-section>
<b-card-group deck>
- <!-- Current FW -->
- <b-card header-bg-variant="success">
+ <!-- Running image -->
+ <b-card>
<template #header>
- <dl class="mb-0">
- <dt>{{ $t('pageFirmware.current') }}</dt>
- <dd class="mb-0">{{ systemFirmwareVersion }}</dd>
- </dl>
+ <p class="font-weight-bold m-0">
+ {{ $t('pageFirmware.singleFileUpload.runningImage') }}
+ </p>
</template>
- <b-row>
- <b-col xs="6">
- <dl class="my-0">
- <dt>{{ $t('pageFirmware.bmcStatus') }}</dt>
- <dd>{{ $t('pageFirmware.running') }}</dd>
- </dl>
- </b-col>
- <b-col xs="6">
- <dl class="my-0">
- <dt>{{ $t('pageFirmware.hostStatus') }}</dt>
- <dd v-if="hostStatus === 'on'">
- {{ $t('global.status.on') }}
- </dd>
- <dd v-else-if="hostStatus === 'off'">
- {{ $t('global.status.off') }}
- </dd>
- <dd v-else>
- {{ $t('global.status.notAvailable') }}
- </dd>
- </dl>
- </b-col>
- </b-row>
+ <dl class="mb-0">
+ <dt>{{ $t('pageFirmware.singleFileUpload.bmcAndServer') }}</dt>
+ <dd class="mb-0">{{ systemFirmwareVersion }}</dd>
+ </dl>
</b-card>
- <!-- Backup FW -->
+ <!-- Backup image -->
<b-card>
<template #header>
- <dl class="mb-0">
- <dt>{{ $t('pageFirmware.backup') }}</dt>
- <dd class="mb-0">{{ backupFirmwareVersion }}</dd>
- </dl>
+ <p class="font-weight-bold m-0">
+ {{ $t('pageFirmware.singleFileUpload.backupImage') }}
+ </p>
</template>
- <b-row>
- <b-col xs="6">
- <dl class="my-0">
- <dt>{{ $t('pageFirmware.state') }}</dt>
- <dd>{{ backupFirmwareStatus }}</dd>
- </dl>
- </b-col>
- </b-row>
+ <dl>
+ <dt>
+ {{ $t('pageFirmware.singleFileUpload.bmcAndServer') }}
+ </dt>
+ <dd>
+ <status-icon v-if="showBackupImageStatus" status="danger" />
+ <span v-if="showBackupImageStatus" class="sr-only">
+ {{ backupFirmwareStatus }}
+ </span>
+ {{ backupFirmwareVersion }}
+ </dd>
+ </dl>
+ <b-btn
+ v-b-modal.modal-switch-to-running
+ data-test-id="firmware-button-switchToRunning"
+ variant="link"
+ size="sm"
+ class="py-0 px-1 mt-2"
+ :disabled="isPageDisabled || !isRebootFromBackupAvailable"
+ >
+ <icon-switch class="d-none d-sm-inline-block" />
+ {{ $t('pageFirmware.singleFileUpload.switchToRunning') }}
+ </b-btn>
</b-card>
</b-card-group>
</page-section>
-
- <!-- Change to backup image -->
- <page-section :section-title="$t('pageFirmware.changeToBackupImage')">
- <dl class="mb-5">
- <dt>
- {{ $t('pageFirmware.backupImage') }}
- </dt>
- <dd>{{ backupFirmwareVersion }}</dd>
- </dl>
- <b-btn
- v-b-modal.modal-reboot-backup
- type="button"
- variant="primary"
- :disabled="isPageDisabled || !isRebootFromBackupAvailable"
- >
- {{ $t('pageFirmware.changeAndRebootBmc') }}
- </b-btn>
- </page-section>
</b-col>
-
- <!-- Update code -->
- <b-col sm="8" xl="4" class="update-code pl-xl-4">
- <page-section :section-title="$t('pageFirmware.updateCode')">
- <b-form @submit.prevent="onSubmitUpload">
- <b-form-group
- :label="$t('pageFirmware.form.uploadLocation')"
- :disabled="isPageDisabled"
- >
- <b-form-radio v-model="isWorkstationSelected" :value="true">
- {{ $t('pageFirmware.form.workstation') }}
- </b-form-radio>
- <b-form-radio v-model="isWorkstationSelected" :value="false">
- {{ $t('pageFirmware.form.tftpServer') }}
- </b-form-radio>
- </b-form-group>
-
- <!-- Workstation Upload -->
- <template v-if="isWorkstationSelected">
+ </b-row>
+ <b-row>
+ <!-- Update firmware -->
+ <b-col sm="8" md="6" xl="4">
+ <page-section
+ :section-title="$t('pageFirmware.singleFileUpload.updateFirmware')"
+ >
+ <div class="form-background p-3">
+ <b-form @submit.prevent="onSubmitUpload">
<b-form-group
- :label="$t('pageFirmware.form.imageFile')"
- label-for="image-file"
+ :label="$t('pageFirmware.singleFileUpload.fileSource')"
+ :disabled="isPageDisabled"
>
- <b-form-text id="image-file-help-block">
- {{ $t('pageFirmware.form.onlyTarFilesAccepted') }}
- </b-form-text>
- <b-form-file
- id="image-file"
- v-model="file"
- accept=".tar"
- aria-describedby="image-file-help-block"
- :browse-text="$t('global.fileUpload.browseText')"
- :drop-placeholder="$t('global.fileUpload.dropPlaceholder')"
- :placeholder="$t('global.fileUpload.placeholder')"
- :disabled="isPageDisabled"
- :state="getValidationState($v.file)"
- @input="$v.file.$touch()"
- />
- <b-form-invalid-feedback role="alert">
- {{ $t('global.form.required') }}
- </b-form-invalid-feedback>
+ <b-form-radio v-model="isWorkstationSelected" :value="true">
+ {{ $t('pageFirmware.form.workstation') }}
+ </b-form-radio>
+ <b-form-radio v-model="isWorkstationSelected" :value="false">
+ {{ $t('pageFirmware.form.tftpServer') }}
+ </b-form-radio>
</b-form-group>
- </template>
- <!-- TFTP Server Upload -->
- <template v-else>
- <b-form-group
- :label="$t('pageFirmware.form.tftpServerAddress')"
- label-for="tftp-ip"
- >
- <b-form-text id="server-address-help-block">
- {{ $t('pageFirmware.form.tftpServerAddressHelper') }}
- </b-form-text>
- <b-form-input
- id="tftp-id"
- v-model="tftpIpAddress"
- type="text"
- :state="getValidationState($v.tftpIpAddress)"
- :disabled="isPageDisabled"
- aria-describedby="server-address-help-block"
- @input="$v.tftpIpAddress.$touch()"
- />
- <b-form-invalid-feedback role="alert">
- {{ $t('global.form.fieldRequired') }}
- </b-form-invalid-feedback>
- </b-form-group>
- <b-form-group
- :label="$t('pageFirmware.form.imageFileName')"
- label-for="tftp-file-name"
- >
- <b-form-input
- id="tftp-file-name"
- v-model="tftpFileName"
- type="text"
- :state="getValidationState($v.tftpFileName)"
- :disabled="isPageDisabled"
- @input="$v.tftpFileName.$touch()"
- />
- <b-form-invalid-feedback role="alert">
- {{ $t('global.form.fieldRequired') }}
- </b-form-invalid-feedback>
- </b-form-group>
- </template>
+ <!-- Workstation Upload -->
+ <template v-if="isWorkstationSelected">
+ <b-form-group
+ :label="$t('pageFirmware.form.imageFile')"
+ label-for="image-file"
+ >
+ <b-form-text id="image-file-help-block">
+ {{ $t('pageFirmware.form.onlyTarFilesAccepted') }}
+ </b-form-text>
+ <form-file
+ id="image-file"
+ accept=".tar"
+ :disabled="isPageDisabled"
+ :state="getValidationState($v.file)"
+ aria-describedby="image-file-help-block"
+ @input="onFileUpload($event)"
+ >
+ <template #invalid>
+ <b-form-invalid-feedback role="alert">
+ {{ $t('global.form.required') }}
+ </b-form-invalid-feedback>
+ </template>
+ </form-file>
+ </b-form-group>
+ </template>
- <!-- Info alert -->
- <alert variant="info" class="mt-4 mb-5">
- <p class="font-weight-bold mb-1">
- {{ $t('pageFirmware.alert.updateProcess') }}
- </p>
- <p>{{ $t('pageFirmware.alert.updateProcessInfoSingleImage') }}</p>
- </alert>
- <b-form-group>
- <b-btn type="submit" variant="primary" :disabled="isPageDisabled">
- {{ $t('pageFirmware.form.uploadAndRebootBmc') }}
+ <!-- TFTP Server Upload -->
+ <template v-else>
+ <b-form-group
+ :label="$t('pageFirmware.singleFileUpload.fileAddress')"
+ label-for="tftp-address"
+ >
+ <b-form-input
+ id="tftp-address"
+ v-model="tftpFileAddress"
+ type="text"
+ :state="getValidationState($v.tftpFileAddress)"
+ :disabled="isPageDisabled"
+ @input="$v.tftpFileAddress.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ {{ $t('global.form.fieldRequired') }}
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </template>
+ <b-btn
+ data-test-id="firmware-button-startUpdate"
+ type="submit"
+ variant="primary"
+ :disabled="isPageDisabled"
+ >
+ {{ $t('pageFirmware.singleFileUpload.startUpdate') }}
</b-btn>
- </b-form-group>
- </b-form>
+ <alert
+ v-if="!isHostOff"
+ variant="warning"
+ :small="true"
+ class="mt-4"
+ >
+ <p class="col-form-label">
+ {{
+ $t(
+ 'pageFirmware.singleFileUpload.alert.serverMustBePoweredOffToUpdateFirmware'
+ )
+ }}
+ </p>
+ </alert>
+ </b-form>
+ </div>
</page-section>
</b-col>
</b-row>
<!-- Modals -->
- <modal-upload @ok="uploadFirmware" />
- <modal-reboot-backup
- :current="systemFirmwareVersion"
+ <modal-update-firmware
+ :running="systemFirmwareVersion"
:backup="backupFirmwareVersion"
- @ok="rebootFromBackup"
+ @ok="updateFirmware"
/>
+ <modal-switch-to-running
+ :backup="backupFirmwareVersion"
+ @ok="switchToRunning"
+ />
+
+ <!-- Toasts -->
+ <b-toast id="switch-images" variant="info" solid :no-auto-hide="true">
+ <template #toast-title>
+ <status-icon status="info" class="toast-icon" />
+ <strong>{{
+ $t('pageFirmware.singleFileUpload.toast.rebootStarted')
+ }}</strong>
+ </template>
+ <p class="m-0">
+ {{ $t('pageFirmware.singleFileUpload.toast.rebootStartedMessage') }}
+ </p>
+ </b-toast>
+
+ <b-toast id="switch-images-2" variant="info" solid :no-auto-hide="true">
+ <template #toast-title>
+ <status-icon status="info" class="toast-icon" />
+ <strong>{{
+ $t('pageFirmware.singleFileUpload.toast.verifySwitch')
+ }}</strong>
+ </template>
+ <p>
+ {{ $t('pageFirmware.singleFileUpload.toast.verifySwitchMessage') }}
+ </p>
+ <b-link @click="onClickRefresh">{{ $t('global.action.refresh') }}</b-link>
+ </b-toast>
+
+ <b-toast id="update-firmware" variant="info" solid :no-auto-hide="true">
+ <template #toast-title>
+ <status-icon status="info" class="toast-icon" />
+ <strong>{{
+ $t('pageFirmware.singleFileUpload.toast.updateStarted')
+ }}</strong>
+ </template>
+ <p>
+ {{ $t('pageFirmware.singleFileUpload.toast.updateStartedMessage') }}
+ </p>
+ <p class="m-0">
+ {{ $t('pageFirmware.singleFileUpload.toast.startTime') }}
+ {{ $options.filters.formatTime(new Date()) }}
+ </p>
+ </b-toast>
+
+ <b-toast id="update-firmware-2" variant="info" solid :no-auto-hide="true">
+ <template #toast-title>
+ <status-icon status="info" class="toast-icon" />
+ <strong>{{
+ $t('pageFirmware.singleFileUpload.toast.verifyUpdate')
+ }}</strong>
+ </template>
+ <p>
+ {{ $t('pageFirmware.singleFileUpload.toast.verifyUpdateMessage') }}
+ </p>
+ <b-link @click="onClickRefresh">{{ $t('global.action.refresh') }}</b-link>
+ </b-toast>
</b-container>
</template>
<script>
import { requiredIf } from 'vuelidate/lib/validators';
import { mapGetters } from 'vuex';
+import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20';
import PageSection from '@/components/Global/PageSection';
import PageTitle from '@/components/Global/PageTitle';
import Alert from '@/components/Global/Alert';
-import ModalUpload from './FirmwareSingleImageModalUpload';
-import ModalRebootBackup from './FirmwareSingleImageModalRebootBackup';
+import FormFile from '@/components/Global/FormFile';
+import StatusIcon from '@/components/Global/StatusIcon';
+import ModalUpdateFirmware from './FirmwareSingleImageModalUpdateFirmware';
+import ModalSwitchToRunning from './FirmwareSingleImageModalSwitchToRunning';
import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
@@ -223,10 +274,13 @@ export default {
name: 'FirmwareSingleImage',
components: {
Alert,
- ModalRebootBackup,
- ModalUpload,
+ FormFile,
+ IconSwitch,
+ ModalSwitchToRunning,
+ ModalUpdateFirmware,
PageSection,
PageTitle,
+ StatusIcon,
},
mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
beforeRouteLeave(to, from, next) {
@@ -238,8 +292,7 @@ export default {
return {
isWorkstationSelected: true,
file: null,
- tftpIpAddress: null,
- tftpFileName: null,
+ tftpFileAddress: null,
timeoutId: null,
loading,
};
@@ -263,13 +316,18 @@ export default {
isPageDisabled() {
return !this.isHostOff || this.loading || this.isOperationInProgress;
},
+ showBackupImageStatus() {
+ return (
+ this.backupFirmwareStatus === 'Critical' ||
+ this.backupFirmwareStatus === 'Warning'
+ );
+ },
},
watch: {
isWorkstationSelected: function () {
this.$v.$reset();
this.file = null;
- this.tftpIpAddress = null;
- this.tftpFileName = null;
+ this.tftpFileAddress = null;
},
},
created() {
@@ -287,12 +345,7 @@ export default {
return this.isWorkstationSelected;
}),
},
- tftpIpAddress: {
- required: requiredIf(function () {
- return !this.isWorkstationSelected;
- }),
- },
- tftpFileName: {
+ tftpFileAddress: {
required: requiredIf(function () {
return !this.isWorkstationSelected;
}),
@@ -300,13 +353,9 @@ export default {
};
},
methods: {
- uploadFirmware() {
- const startTime = this.$options.filters.formatTime(new Date());
- this.setRebootTimeout(360000); //6 minute timeout
- this.infoToast(
- this.$t('pageFirmware.toast.infoUploadStartTimeMessage', { startTime }),
- this.$t('pageFirmware.toast.infoUploadStartTimeTitle')
- );
+ updateFirmware() {
+ this.setRebootTimeout(360000, 'update-firmware-2'); //6 minute timeout
+ this.$bvToast.show('update-firmware');
if (this.isWorkstationSelected) {
this.dispatchWorkstationUpload();
} else {
@@ -316,57 +365,41 @@ export default {
dispatchWorkstationUpload() {
this.$store
.dispatch('firmwareSingleImage/uploadFirmware', this.file)
- .then((success) =>
- this.infoToast(
- success,
- this.$t('pageFirmware.toast.successUploadTitle')
- )
- )
.catch(({ message }) => {
this.errorToast(message);
this.clearRebootTimeout();
});
},
dispatchTftpUpload() {
- const data = {
- address: this.tftpIpAddress,
- filename: this.tftpFileName,
- };
this.$store
- .dispatch('firmwareSingleImage/uploadFirmwareTFTP', data)
- .then((success) =>
- this.infoToast(
- success,
- this.$t('pageFirmware.toast.successUploadTitle')
- )
+ .dispatch(
+ 'firmwareSingleImage/uploadFirmwareTFTP',
+ this.tftpFileAddress
)
.catch(({ message }) => {
this.errorToast(message);
this.clearRebootTimeout();
});
},
- rebootFromBackup() {
- this.setRebootTimeout();
+ switchToRunning() {
+ this.setRebootTimeout(60000, 'switch-images-2');
this.$store
.dispatch('firmwareSingleImage/switchFirmwareAndReboot')
- .then((success) =>
- this.infoToast(success, this.$t('global.status.success'))
- )
+ .then(() => this.$bvToast.show('switch-images'))
.catch(({ message }) => {
this.errorToast(message);
this.clearRebootTimeout();
});
},
- setRebootTimeout(timeoutMs = 60000) {
- // Set a timeout to disable page interactions while
- // an upload or BMC reboot is in progress
+ setRebootTimeout(timeoutMs = 60000, toastId) {
+ // Set a timeout to disable page interactions
+ // during a BMC reboot
this.startLoader();
this.timeoutId = setTimeout(() => {
this.endLoader();
- this.infoToast(
- this.$t('pageFirmware.toast.infoRefreshApplicationMessage'),
- this.$t('pageFirmware.toast.infoRefreshApplicationTitle')
- );
+ if (toastId) {
+ this.$bvToast.show(toastId);
+ }
}, timeoutMs);
},
clearRebootTimeout() {
@@ -378,30 +411,15 @@ export default {
onSubmitUpload() {
this.$v.$touch();
if (this.$v.$invalid) return;
- this.$bvModal.show('modal-upload');
+ this.$bvModal.show('modal-update-firmware');
},
- onClickShutDown() {
- this.$bvModal
- .msgBoxConfirm(this.$t('pageFirmware.modal.serverShutdownMessage'), {
- title: this.$t('pageFirmware.modal.serverShutdownWillCauseOutage'),
- okTitle: this.$t('pageFirmware.modal.shutDownServer'),
- cancelTitle: this.$t('global.action.cancel'),
- okVariant: 'danger',
- })
- .then((shutdownConfirmed) => {
- if (shutdownConfirmed)
- this.$store.dispatch('controls/hostSoftPowerOff');
- });
+ onFileUpload(file) {
+ this.file = file;
+ this.$v.file.$touch();
+ },
+ onClickRefresh() {
+ this.$root.$emit('refresh-application');
},
},
};
</script>
-
-<style lang="scss" scoped>
-.update-code {
- border-left: none;
- @include media-breakpoint-up(xl) {
- border-left: 1px solid gray('300');
- }
-}
-</style>
diff --git a/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalRebootBackup.vue b/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalRebootBackup.vue
deleted file mode 100644
index f64065a8..00000000
--- a/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalRebootBackup.vue
+++ /dev/null
@@ -1,34 +0,0 @@
-<template>
- <b-modal
- id="modal-reboot-backup"
- :ok-title="$t('pageFirmware.modal.rebootFromBackup.primaryAction')"
- :cancel-title="$t('global.action.cancel')"
- :title="$t('pageFirmware.modal.rebootFromBackup.title')"
- @ok="$emit('ok')"
- >
- <p>
- {{ $t('pageFirmware.modal.rebootFromBackup.message1', { backup }) }}
- </p>
- <p>
- {{ $t('pageFirmware.modal.rebootFromBackup.message2', { current }) }}
- </p>
- <p class="font-weight-bold">
- {{ $t('pageFirmware.modal.rebootFromBackup.message3', { backup }) }}
- </p>
- </b-modal>
-</template>
-
-<script>
-export default {
- props: {
- current: {
- type: String,
- required: true,
- },
- backup: {
- type: String,
- required: true,
- },
- },
-};
-</script>
diff --git a/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalSwitchToRunning.vue b/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalSwitchToRunning.vue
new file mode 100644
index 00000000..56f505d0
--- /dev/null
+++ b/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalSwitchToRunning.vue
@@ -0,0 +1,31 @@
+<template>
+ <b-modal
+ id="modal-switch-to-running"
+ :ok-title="$t('pageFirmware.singleFileUpload.modal.switchImages')"
+ :cancel-title="$t('global.action.cancel')"
+ :title="$t('pageFirmware.singleFileUpload.modal.switchRunningImage')"
+ @ok="$emit('ok')"
+ >
+ <p>
+ {{ $t('pageFirmware.singleFileUpload.modal.switchRunningImageInfo') }}
+ </p>
+ <p class="m-0">
+ {{
+ $t('pageFirmware.singleFileUpload.modal.switchRunningImageInfo2', {
+ backup,
+ })
+ }}
+ </p>
+ </b-modal>
+</template>
+
+<script>
+export default {
+ props: {
+ backup: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
diff --git a/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpdateFirmware.vue b/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpdateFirmware.vue
new file mode 100644
index 00000000..51575253
--- /dev/null
+++ b/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpdateFirmware.vue
@@ -0,0 +1,44 @@
+<template>
+ <b-modal
+ id="modal-update-firmware"
+ :title="$t('pageFirmware.singleFileUpload.updateFirmware')"
+ :ok-title="$t('pageFirmware.singleFileUpload.startUpdate')"
+ :cancel-title="$t('global.action.cancel')"
+ @ok="$emit('ok')"
+ >
+ <p>
+ {{ $t('pageFirmware.singleFileUpload.modal.updateFirmwareInfo') }}
+ </p>
+ <p v-if="showMessage">
+ {{
+ $t('pageFirmware.singleFileUpload.modal.updateFirmwareInfo2', {
+ backup,
+ running,
+ })
+ }}
+ </p>
+ <p class="m-0">
+ {{ $t('pageFirmware.singleFileUpload.modal.updateFirmwareInfo3') }}
+ </p>
+ </b-modal>
+</template>
+
+<script>
+export default {
+ props: {
+ backup: {
+ type: String,
+ required: true,
+ },
+ running: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ showMessage() {
+ return this.backup !== this.running;
+ },
+ },
+};
+</script>
diff --git a/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpload.vue b/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpload.vue
deleted file mode 100644
index e544b9fd..00000000
--- a/src/env/components/FirmwareSingleImage/FirmwareSingleImageModalUpload.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-<template>
- <b-modal
- id="modal-upload"
- :title="$t('pageFirmware.modal.uploadAndRebootSingleImage.title')"
- :ok-title="
- $t('pageFirmware.modal.uploadAndRebootSingleImage.primaryAction')
- "
- :cancel-title="$t('global.action.cancel')"
- @ok="$emit('ok')"
- >
- <p>
- {{ $t('pageFirmware.modal.uploadAndRebootSingleImage.message1') }}
- </p>
- <p>
- {{ $t('pageFirmware.modal.uploadAndRebootSingleImage.message2') }}
- </p>
- <p class="font-weight-bold">
- {{ $t('pageFirmware.modal.uploadAndRebootSingleImage.message3') }}
- </p>
- </b-modal>
-</template>
diff --git a/src/env/store/FirmwareSingleImage/FirmwareSingleImageStore.js b/src/env/store/FirmwareSingleImage/FirmwareSingleImageStore.js
index ffc4bc4b..91bcb9fe 100644
--- a/src/env/store/FirmwareSingleImage/FirmwareSingleImageStore.js
+++ b/src/env/store/FirmwareSingleImage/FirmwareSingleImageStore.js
@@ -13,7 +13,7 @@ const FirmwareSingleImageStore = {
version: '--',
id: null,
location: null,
- status: '--',
+ status: null,
},
applyTime: null,
},
@@ -72,7 +72,7 @@ const FirmwareSingleImageStore = {
version: backupData.data?.Version,
id: backupData.data?.Id,
location: backupData.data?.['@odata.id'],
- status: backupData.data?.Status?.State,
+ status: backupData.data?.Status?.Health,
});
})
.catch((error) => console.log(error));
@@ -110,17 +110,15 @@ const FirmwareSingleImageStore = {
.post('/redfish/v1/UpdateService', image, {
headers: { 'Content-Type': 'application/octet-stream' },
})
- .then(() => dispatch('getSystemFirwareVersion'))
- .then(() => i18n.t('pageFirmware.toast.successUploadMessage'))
.catch((error) => {
console.log(error);
throw new Error(i18n.t('pageFirmware.toast.errorUploadAndReboot'));
});
},
- async uploadFirmwareTFTP({ state, dispatch }, { address, filename }) {
+ async uploadFirmwareTFTP({ state, dispatch }, fileAddress) {
const data = {
TransferProtocol: 'TFTP',
- ImageURI: `${address}/${filename}`,
+ ImageURI: fileAddress,
};
if (state.applyTime !== 'Immediate') {
// ApplyTime must be set to Immediate before making
@@ -132,8 +130,6 @@ const FirmwareSingleImageStore = {
'/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate',
data
)
- .then(() => dispatch('getSystemFirwareVersion'))
- .then(() => i18n.t('pageFirmware.toast.successUploadMessage'))
.catch((error) => {
console.log(error);
throw new Error(i18n.t('pageFirmware.toast.errorUploadAndReboot'));
@@ -150,10 +146,11 @@ const FirmwareSingleImageStore = {
};
return await api
.patch('/redfish/v1/Managers/bmc', data)
- .then(() => i18n.t('pageFirmware.toast.successRebootFromBackup'))
.catch((error) => {
console.log(error);
- throw new Error(i18n.t('pageFirmware.toast.errorRebootFromBackup'));
+ throw new Error(
+ i18n.t('pageFirmware.singleFileUpload.toast.errorSwitchImages')
+ );
});
},
},
diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue
index 228b25cd..c2023dfb 100644
--- a/src/layouts/AppLayout.vue
+++ b/src/layouts/AppLayout.vue
@@ -48,6 +48,9 @@ export default {
});
},
},
+ mounted() {
+ this.$root.$on('refresh-application', () => this.refresh());
+ },
methods: {
refresh() {
// Changing the component :key value will trigger
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index a4af7091..d3b6d754 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -13,6 +13,7 @@
"enable": "Enable",
"export": "Export",
"filter": "Filter",
+ "refresh": "Refresh",
"replace": "Replace",
"save": "Save",
"saveSettings": "Save settings",
@@ -261,29 +262,19 @@
},
"pageFirmware": {
"backup": "Backup:",
- "backupImage": "Backup image",
"bmcStatus": "BMC status",
- "changeAndRebootBmc": "Change image and reboot BMC",
- "changeToBackupImage": "Change to backup image",
"current": "Current:",
"firmwareOnBmc": "Firmware on BMC",
"firmwareOnHost": "Firmware on host",
- "firmwareOnSystem": "Firmware on system",
"hostStatus": "Host status",
"makeCurrentVersion": "Make current version",
"pageDescription": "Update firmware by uploading a BMC or Host image file from your workstation or TFTP server",
- "pageDescriptionSingleImage": "Update firmware by uploading a system image file from your workstation or TFTP server",
"running": "Running",
"state": "State",
"updateCode": "Update code",
"alert": {
- "operationInProgress": "Server power operation in progress.",
- "serverShutdownRequiredBeforeUpdate": "Server shutdown required before update",
- "serverShutdownRequiredInfo": "Shutdown will be orderly - OS will shutdown before the server shuts down.",
- "shutDownServer": "Shut down server",
"updateProcess": "Update process",
- "updateProcessInfo": "The new image will be uploaded and activated. After that, the BMC or host will reboot automatically to run from the new image.",
- "updateProcessInfoSingleImage": "The new image will be uploaded and activated. After that, the BMC will reboot automatically to run from the new image."
+ "updateProcessInfo": "The new image will be uploaded and activated. After that, the BMC or host will reboot automatically to run from the new image."
},
"form": {
"imageFile": "Image file",
@@ -299,9 +290,6 @@
},
"modal": {
"connectionToBmcWillBeLost": "Connection to BMC will be lost",
- "serverShutdownMessage": "There will be a server outage until the server is powered back on. Are you sure you want to shut down?",
- "serverShutdownWillCauseOutage": "Server shutdown will cause outage",
- "shutDownServer": "Shut down server",
"rebootFromBackup": {
"message1": "A BMC reboot is required before the system can run the backup image %{backup}. The reboot will cause a disconnection, and may require logging in again.",
"message2": "The current firmware image %{current} will be moved to backup. During the reboot, server cannot be powered back on.",
@@ -309,13 +297,6 @@
"primaryAction": "Reboot BMC from backup image",
"title": "@:pageFirmware.modal.connectionToBmcWillBeLost"
},
- "uploadAndRebootSingleImage": {
- "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.",
- "message2": "During the reboot, the server cannot be powered back on. The backup image will be permanently deleted.",
- "message3": "Are you sure you want to upload the new firmware image and reboot the BMC?",
- "primaryAction": "Upload and reboot BMC",
- "title": "@:pageFirmware.modal.connectionToBmcWillBeLost"
- },
"uploadAndRebootBmcOrHost": {
"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.",
"message2": "The backup image will be permanently deleted.",
@@ -334,6 +315,45 @@
"successRebootFromBackup": "Successfully started reboot from backup image.",
"successUploadMessage": "The upload was successful. During code update, the BMC will be not be responsive. Wait for the code update notification before making any changes.",
"successUploadTitle": "Code update started"
+ },
+ "singleFileUpload": {
+ "backupImage": "Backup image",
+ "bmcAndServer": "BMC and server:",
+ "fileAddress": "File address",
+ "fileSource": "File source",
+ "runningImage": "Running image",
+ "startUpdate": "Start update",
+ "switchToRunning": "Switch to running",
+ "updateFirmware": "Update firmware",
+ "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"
+ },
+ "modal": {
+ "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.",
+ "switchRunningImageInfo2": "Are you sure you want to switch to the backup image (%{backup})?",
+ "updateFirmwareInfo": "The BMC will reboot during the update process. The server cannot be powered on until the update is finished.",
+ "updateFirmwareInfo2": "The running image (%{running}) will be copied to backup and the backup image (%{backup}) will be permanently deleted.",
+ "updateFirmwareInfo3": "Are you sure you want to proceed with the update?"
+ },
+ "toast": {
+ "errorSwitchImages": "Error switching running and backup images.",
+ "rebootStarted": "Reboot started",
+ "rebootStartedMessage": "Successfully started reboot from backup image.",
+ "startTime": "Start time:",
+ "updateStarted": "Update started",
+ "updateStartedMessage": "Wait for the firmware update notification before making any changes.",
+ "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"
+ }
}
},
"pageHardwareStatus": {