blob: d9f337f4ae93fd17ca859a1cce01e7a0bab828c6 [file] [log] [blame]
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -07001<template>
2 <b-container fluid="xl">
3 <page-title :description="$t('pageFirmware.pageDescription')" />
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -07004 <b-row class="mb-4">
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -07005 <b-col md="10" lg="12" xl="8" class="pr-xl-4">
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -07006 <!-- Firmware on BMC -->
7 <page-section :section-title="$t('pageFirmware.firmwareOnBmc')">
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -07008 <b-card-group deck>
9 <!-- Current FW -->
10 <b-card header-bg-variant="success">
Derick Montague602e98a2020-10-21 16:20:00 -050011 <template #header>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070012 <dl class="mb-0">
13 <dt>{{ $t('pageFirmware.current') }}</dt>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070014 <dd class="mb-0">{{ bmcFirmwareCurrentVersion }}</dd>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070015 </dl>
16 </template>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070017 <dl class="my-0">
18 <dt>{{ $t('pageFirmware.state') }}:</dt>
19 <dd>{{ bmcFirmwareCurrentState }}</dd>
20 </dl>
Derick Montague602e98a2020-10-21 16:20:00 -050021 <template #footer></template>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070022 </b-card>
23
24 <!-- Backup FW -->
25 <b-card footer-class="p-0">
Derick Montague602e98a2020-10-21 16:20:00 -050026 <template #header>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070027 <dl class="mb-0">
28 <dt>{{ $t('pageFirmware.backup') }}</dt>
29 <dd class="mb-0">{{ bmcFirmwareBackupVersion }}</dd>
30 </dl>
31 </template>
32 <dl class="my-0">
33 <dt>{{ $t('pageFirmware.state') }}:</dt>
34 <dd>{{ bmcFirmwareBackupState }}</dd>
35 </dl>
Derick Montague602e98a2020-10-21 16:20:00 -050036 <template #footer>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070037 <b-btn
38 v-b-modal.modal-reboot-backup-bmc
39 :disabled="!bmcFirmwareBackupVersion"
40 variant="link"
41 size="sm"
42 >
43 <icon-switch class="d-none d-sm-inline-block" />
44 {{ $t('pageFirmware.makeCurrentVersion') }}</b-btn
45 >
46 </template>
47 </b-card>
48 </b-card-group>
49 </page-section>
50
51 <!-- Firmware on Host -->
52 <page-section :section-title="$t('pageFirmware.firmwareOnHost')">
53 <b-card-group deck>
54 <!-- Current FW -->
55 <b-card header-bg-variant="success">
Derick Montague602e98a2020-10-21 16:20:00 -050056 <template #header>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070057 <dl class="mb-0">
58 <dt>{{ $t('pageFirmware.current') }}</dt>
59 <dd class="mb-0">{{ hostFirmwareCurrentVersion }}</dd>
60 </dl>
61 </template>
62 <!-- State -->
63 <dl class="my-0">
64 <dt>{{ $t('pageFirmware.state') }}:</dt>
65 <dd>{{ hostFirmwareCurrentState }}</dd>
66 </dl>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070067 </b-card>
68
69 <!-- Backup FW -->
70 <b-card>
Derick Montague602e98a2020-10-21 16:20:00 -050071 <template #header>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070072 <dl class="mb-0">
73 <dt>{{ $t('pageFirmware.backup') }}</dt>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070074 <dd class="mb-0">{{ hostFirmwareBackupVersion }}</dd>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070075 </dl>
76 </template>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070077 <!-- State -->
78 <dl class="my-0">
79 <dt>{{ $t('pageFirmware.state') }}:</dt>
80 <dd>{{ hostFirmwareBackupState }}</dd>
81 </dl>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070082 </b-card>
83 </b-card-group>
84 </page-section>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070085 </b-col>
86
87 <!-- Update code -->
88 <b-col sm="8" xl="4" class="update-code pl-xl-4">
89 <page-section :section-title="$t('pageFirmware.updateCode')">
90 <b-form @submit.prevent="onSubmitUpload">
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -070091 <b-form-group :label="$t('pageFirmware.form.uploadLocation')">
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -070092 <b-form-radio v-model="isWorkstationSelected" :value="true">
93 {{ $t('pageFirmware.form.workstation') }}
94 </b-form-radio>
95 <b-form-radio v-model="isWorkstationSelected" :value="false">
96 {{ $t('pageFirmware.form.tftpServer') }}
97 </b-form-radio>
98 </b-form-group>
99
100 <!-- Workstation Upload -->
101 <template v-if="isWorkstationSelected">
SurenNeware978807d2020-09-03 18:35:21 +0530102 <b-form-group :label="$t('pageFirmware.form.imageFile')">
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700103 <b-form-text id="image-file-help-block">
104 {{ $t('pageFirmware.form.onlyTarFilesAccepted') }}
105 </b-form-text>
SurenNeware978807d2020-09-03 18:35:21 +0530106 <form-file
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700107 id="image-file"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700108 accept=".tar"
SurenNeware978807d2020-09-03 18:35:21 +0530109 :disabled="isPageDisabled"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700110 :state="getValidationState($v.file)"
SurenNeware978807d2020-09-03 18:35:21 +0530111 aria-describedby="image-file-help-block"
112 @input="onFileUpload($event)"
113 >
114 <template #invalid>
115 <b-form-invalid-feedback role="alert">
Yoshie Muranaka00f5b792020-12-07 07:28:50 -0800116 {{ $t('global.form.required') }}
SurenNeware978807d2020-09-03 18:35:21 +0530117 </b-form-invalid-feedback>
118 </template>
119 </form-file>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700120 </b-form-group>
121 </template>
122
123 <!-- TFTP Server Upload -->
124 <template v-else>
125 <b-form-group
SurenNeware64c20a52020-10-07 20:30:34 +0530126 :label="$t('pageFirmware.form.tftpServerAddress')"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700127 label-for="tftp-ip"
128 >
SurenNeware64c20a52020-10-07 20:30:34 +0530129 <b-form-text id="server-address-help-block">
130 {{ $t('pageFirmware.form.tftpServerAddressHelper') }}
131 </b-form-text>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700132 <b-form-input
133 id="tftp-id"
134 v-model="tftpIpAddress"
135 type="text"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700136 :state="getValidationState($v.tftpIpAddress)"
137 :disabled="isPageDisabled"
SurenNeware64c20a52020-10-07 20:30:34 +0530138 aria-describedby="server-address-help-block"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700139 @input="$v.tftpIpAddress.$touch()"
140 />
141 <b-form-invalid-feedback role="alert">
142 {{ $t('global.form.fieldRequired') }}
143 </b-form-invalid-feedback>
144 </b-form-group>
145 <b-form-group
146 :label="$t('pageFirmware.form.imageFileName')"
147 label-for="tftp-file-name"
148 >
149 <b-form-input
150 id="tftp-file-name"
151 v-model="tftpFileName"
152 type="text"
153 :state="getValidationState($v.tftpFileName)"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700154 @input="$v.tftpFileName.$touch()"
155 />
156 <b-form-invalid-feedback role="alert">
157 {{ $t('global.form.fieldRequired') }}
158 </b-form-invalid-feedback>
159 </b-form-group>
160 </template>
161
162 <!-- Info alert -->
163 <alert variant="info" class="mt-4 mb-5">
164 <p class="font-weight-bold mb-1">
165 {{ $t('pageFirmware.alert.updateProcess') }}
166 </p>
167 <p>{{ $t('pageFirmware.alert.updateProcessInfo') }}</p>
168 </alert>
Derick Montaguead48a0c2020-10-30 08:48:09 -0500169
170 <b-btn type="submit" variant="primary">
171 {{ $t('pageFirmware.form.uploadAndRebootBmcOrHost') }}
172 </b-btn>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700173 </b-form>
174 </page-section>
175 </b-col>
176 </b-row>
177
178 <!-- Modals -->
179 <modal-upload @ok="uploadFirmware" />
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700180 <modal-reboot-backup-bmc
181 :current="bmcFirmwareCurrentVersion || '--'"
182 :backup="bmcFirmwareBackupVersion || '--'"
183 @ok="switchBmcFirmware"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700184 />
185 </b-container>
186</template>
187
188<script>
189import { requiredIf } from 'vuelidate/lib/validators';
190import { mapGetters } from 'vuex';
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700191import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700192
193import PageSection from '@/components/Global/PageSection';
194import PageTitle from '@/components/Global/PageTitle';
195import Alert from '@/components/Global/Alert';
196import ModalUpload from './FirmwareModalUpload';
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700197import ModalRebootBackupBmc from './FirmwareModalRebootBackupBmc';
SurenNeware978807d2020-09-03 18:35:21 +0530198import FormFile from '@/components/Global/FormFile';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700199
200import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
SurenNewareba91c492020-10-27 14:18:54 +0530201import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700202import BVToastMixin from '@/components/Mixins/BVToastMixin';
203
204export default {
205 name: 'Firmware',
206 components: {
207 Alert,
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700208 IconSwitch,
209 ModalRebootBackupBmc,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700210 ModalUpload,
211 PageSection,
Derick Montague602e98a2020-10-21 16:20:00 -0500212 PageTitle,
SurenNeware978807d2020-09-03 18:35:21 +0530213 FormFile,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700214 },
215 mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
Derick Montague602e98a2020-10-21 16:20:00 -0500216 beforeRouteLeave(to, from, next) {
217 this.hideLoader();
218 this.clearRebootTimeout();
219 next();
220 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700221 data() {
222 return {
223 isWorkstationSelected: true,
224 file: null,
225 tftpIpAddress: null,
226 tftpFileName: null,
Derick Montague602e98a2020-10-21 16:20:00 -0500227 timeoutId: null,
SurenNeware978807d2020-09-03 18:35:21 +0530228 isPageDisabled: null,
SurenNewareba91c492020-10-27 14:18:54 +0530229 loading: loading,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700230 };
231 },
232 computed: {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700233 ...mapGetters('firmware', [
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700234 'bmcFirmwareCurrentVersion',
235 'bmcFirmwareCurrentState',
236 'bmcFirmwareBackupVersion',
237 'bmcFirmwareBackupState',
238 'hostFirmwareCurrentVersion',
239 'hostFirmwareCurrentState',
240 'hostFirmwareBackupVersion',
Derick Montague602e98a2020-10-21 16:20:00 -0500241 'hostFirmwareBackupState',
242 ]),
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700243 },
244 watch: {
Derick Montague602e98a2020-10-21 16:20:00 -0500245 isWorkstationSelected: function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700246 this.$v.$reset();
247 this.file = null;
248 this.tftpIpAddress = null;
249 this.tftpFileName = null;
Derick Montague602e98a2020-10-21 16:20:00 -0500250 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700251 },
252 created() {
253 this.startLoader();
254 this.$store.dispatch('firmware/getUpdateServiceApplyTime');
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700255 this.$store
256 .dispatch('firmware/getFirmwareInformation')
257 .finally(() => this.endLoader());
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700258 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700259 validations() {
260 return {
261 file: {
Derick Montague602e98a2020-10-21 16:20:00 -0500262 required: requiredIf(function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700263 return this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500264 }),
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700265 },
266 tftpIpAddress: {
Derick Montague602e98a2020-10-21 16:20:00 -0500267 required: requiredIf(function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700268 return !this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500269 }),
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700270 },
271 tftpFileName: {
Derick Montague602e98a2020-10-21 16:20:00 -0500272 required: requiredIf(function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700273 return !this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500274 }),
275 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700276 };
277 },
278 methods: {
SurenNeware978807d2020-09-03 18:35:21 +0530279 onFileUpload(file) {
280 this.file = file;
281 this.$v.file.$touch();
282 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700283 uploadFirmware() {
284 const startTime = this.$options.filters.formatTime(new Date());
285 this.setRebootTimeout(360000); //6 minute timeout
286 this.infoToast(
287 this.$t('pageFirmware.toast.infoUploadStartTimeMessage', { startTime }),
288 this.$t('pageFirmware.toast.infoUploadStartTimeTitle')
289 );
290 if (this.isWorkstationSelected) {
291 this.dispatchWorkstationUpload();
292 } else {
293 this.dispatchTftpUpload();
294 }
295 },
296 dispatchWorkstationUpload() {
297 this.$store
298 .dispatch('firmware/uploadFirmware', this.file)
Derick Montague602e98a2020-10-21 16:20:00 -0500299 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700300 this.infoToast(
301 success,
302 this.$t('pageFirmware.toast.successUploadTitle')
303 )
304 )
305 .catch(({ message }) => {
306 this.errorToast(message);
307 this.clearRebootTimeout();
308 });
309 },
310 dispatchTftpUpload() {
311 const data = {
312 address: this.tftpIpAddress,
Derick Montague602e98a2020-10-21 16:20:00 -0500313 filename: this.tftpFileName,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700314 };
315 this.$store
316 .dispatch('firmware/uploadFirmwareTFTP', data)
Derick Montague602e98a2020-10-21 16:20:00 -0500317 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700318 this.infoToast(
319 success,
320 this.$t('pageFirmware.toast.successUploadTitle')
321 )
322 )
323 .catch(({ message }) => {
324 this.errorToast(message);
325 this.clearRebootTimeout();
326 });
327 },
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700328 switchBmcFirmware() {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700329 this.setRebootTimeout();
330 this.$store
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700331 .dispatch('firmware/switchBmcFirmware')
Derick Montague602e98a2020-10-21 16:20:00 -0500332 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700333 this.infoToast(success, this.$t('global.status.success'))
334 )
335 .catch(({ message }) => {
336 this.errorToast(message);
337 this.clearRebootTimeout();
338 });
339 },
340 setRebootTimeout(timeoutMs = 60000) {
341 // Set a timeout to disable page interactions while
342 // an upload or BMC reboot is in progress
343 this.startLoader();
344 this.timeoutId = setTimeout(() => {
345 this.endLoader();
346 this.infoToast(
347 this.$t('pageFirmware.toast.infoRefreshApplicationMessage'),
348 this.$t('pageFirmware.toast.infoRefreshApplicationTitle')
349 );
350 }, timeoutMs);
351 },
352 clearRebootTimeout() {
353 if (this.timeoutId) {
354 clearTimeout(this.timeoutId);
355 this.endLoader();
356 }
357 },
358 onSubmitUpload() {
359 this.$v.$touch();
360 if (this.$v.$invalid) return;
361 this.$bvModal.show('modal-upload');
Derick Montague602e98a2020-10-21 16:20:00 -0500362 },
363 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700364};
365</script>
366
367<style lang="scss" scoped>
368.update-code {
369 border-left: none;
370 @include media-breakpoint-up(xl) {
371 border-left: 1px solid gray('300');
372 }
373}
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700374.card-footer {
Dixsie Wolmers30f11f82020-11-10 16:07:56 -0600375 height: 40px;
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700376}
377.card-body {
378 padding: 0.75rem 1.25rem;
379}
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700380</style>