blob: 48c29ebc46f1d3fcde8be21e8e89b8b67c342f37 [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">
102 <b-form-group
103 :label="$t('pageFirmware.form.imageFile')"
104 label-for="image-file"
105 >
106 <b-form-text id="image-file-help-block">
107 {{ $t('pageFirmware.form.onlyTarFilesAccepted') }}
108 </b-form-text>
109 <b-form-file
110 id="image-file"
111 v-model="file"
112 accept=".tar"
113 aria-describedby="image-file-help-block"
Yoshie Muranakacd933e32020-08-16 22:09:26 -0700114 :browse-text="$t('global.fileUpload.browseText')"
115 :drop-placeholder="$t('global.fileUpload.dropPlaceholder')"
116 :placeholder="$t('global.fileUpload.placeholder')"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700117 :state="getValidationState($v.file)"
118 @input="$v.file.$touch()"
119 />
120 <b-form-invalid-feedback role="alert">
121 {{ $t('global.form.required') }}
122 </b-form-invalid-feedback>
123 </b-form-group>
124 </template>
125
126 <!-- TFTP Server Upload -->
127 <template v-else>
128 <b-form-group
SurenNeware64c20a52020-10-07 20:30:34 +0530129 :label="$t('pageFirmware.form.tftpServerAddress')"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700130 label-for="tftp-ip"
131 >
SurenNeware64c20a52020-10-07 20:30:34 +0530132 <b-form-text id="server-address-help-block">
133 {{ $t('pageFirmware.form.tftpServerAddressHelper') }}
134 </b-form-text>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700135 <b-form-input
136 id="tftp-id"
137 v-model="tftpIpAddress"
138 type="text"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700139 :state="getValidationState($v.tftpIpAddress)"
140 :disabled="isPageDisabled"
SurenNeware64c20a52020-10-07 20:30:34 +0530141 aria-describedby="server-address-help-block"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700142 @input="$v.tftpIpAddress.$touch()"
143 />
144 <b-form-invalid-feedback role="alert">
145 {{ $t('global.form.fieldRequired') }}
146 </b-form-invalid-feedback>
147 </b-form-group>
148 <b-form-group
149 :label="$t('pageFirmware.form.imageFileName')"
150 label-for="tftp-file-name"
151 >
152 <b-form-input
153 id="tftp-file-name"
154 v-model="tftpFileName"
155 type="text"
156 :state="getValidationState($v.tftpFileName)"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700157 @input="$v.tftpFileName.$touch()"
158 />
159 <b-form-invalid-feedback role="alert">
160 {{ $t('global.form.fieldRequired') }}
161 </b-form-invalid-feedback>
162 </b-form-group>
163 </template>
164
165 <!-- Info alert -->
166 <alert variant="info" class="mt-4 mb-5">
167 <p class="font-weight-bold mb-1">
168 {{ $t('pageFirmware.alert.updateProcess') }}
169 </p>
170 <p>{{ $t('pageFirmware.alert.updateProcessInfo') }}</p>
171 </alert>
172 <b-form-group>
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700173 <b-btn type="submit" variant="primary">
174 {{ $t('pageFirmware.form.uploadAndRebootBmcOrHost') }}
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700175 </b-btn>
176 </b-form-group>
177 </b-form>
178 </page-section>
179 </b-col>
180 </b-row>
181
182 <!-- Modals -->
183 <modal-upload @ok="uploadFirmware" />
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700184 <modal-reboot-backup-bmc
185 :current="bmcFirmwareCurrentVersion || '--'"
186 :backup="bmcFirmwareBackupVersion || '--'"
187 @ok="switchBmcFirmware"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700188 />
189 </b-container>
190</template>
191
192<script>
193import { requiredIf } from 'vuelidate/lib/validators';
194import { mapGetters } from 'vuex';
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700195import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700196
197import PageSection from '@/components/Global/PageSection';
198import PageTitle from '@/components/Global/PageTitle';
199import Alert from '@/components/Global/Alert';
200import ModalUpload from './FirmwareModalUpload';
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700201import ModalRebootBackupBmc from './FirmwareModalRebootBackupBmc';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700202
203import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
204import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
205import BVToastMixin from '@/components/Mixins/BVToastMixin';
206
207export default {
208 name: 'Firmware',
209 components: {
210 Alert,
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700211 IconSwitch,
212 ModalRebootBackupBmc,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700213 ModalUpload,
214 PageSection,
Derick Montague602e98a2020-10-21 16:20:00 -0500215 PageTitle,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700216 },
217 mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
Derick Montague602e98a2020-10-21 16:20:00 -0500218 beforeRouteLeave(to, from, next) {
219 this.hideLoader();
220 this.clearRebootTimeout();
221 next();
222 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700223 data() {
224 return {
225 isWorkstationSelected: true,
226 file: null,
227 tftpIpAddress: null,
228 tftpFileName: null,
Derick Montague602e98a2020-10-21 16:20:00 -0500229 timeoutId: null,
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: {
279 uploadFirmware() {
280 const startTime = this.$options.filters.formatTime(new Date());
281 this.setRebootTimeout(360000); //6 minute timeout
282 this.infoToast(
283 this.$t('pageFirmware.toast.infoUploadStartTimeMessage', { startTime }),
284 this.$t('pageFirmware.toast.infoUploadStartTimeTitle')
285 );
286 if (this.isWorkstationSelected) {
287 this.dispatchWorkstationUpload();
288 } else {
289 this.dispatchTftpUpload();
290 }
291 },
292 dispatchWorkstationUpload() {
293 this.$store
294 .dispatch('firmware/uploadFirmware', this.file)
Derick Montague602e98a2020-10-21 16:20:00 -0500295 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700296 this.infoToast(
297 success,
298 this.$t('pageFirmware.toast.successUploadTitle')
299 )
300 )
301 .catch(({ message }) => {
302 this.errorToast(message);
303 this.clearRebootTimeout();
304 });
305 },
306 dispatchTftpUpload() {
307 const data = {
308 address: this.tftpIpAddress,
Derick Montague602e98a2020-10-21 16:20:00 -0500309 filename: this.tftpFileName,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700310 };
311 this.$store
312 .dispatch('firmware/uploadFirmwareTFTP', data)
Derick Montague602e98a2020-10-21 16:20:00 -0500313 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700314 this.infoToast(
315 success,
316 this.$t('pageFirmware.toast.successUploadTitle')
317 )
318 )
319 .catch(({ message }) => {
320 this.errorToast(message);
321 this.clearRebootTimeout();
322 });
323 },
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700324 switchBmcFirmware() {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700325 this.setRebootTimeout();
326 this.$store
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700327 .dispatch('firmware/switchBmcFirmware')
Derick Montague602e98a2020-10-21 16:20:00 -0500328 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700329 this.infoToast(success, this.$t('global.status.success'))
330 )
331 .catch(({ message }) => {
332 this.errorToast(message);
333 this.clearRebootTimeout();
334 });
335 },
336 setRebootTimeout(timeoutMs = 60000) {
337 // Set a timeout to disable page interactions while
338 // an upload or BMC reboot is in progress
339 this.startLoader();
340 this.timeoutId = setTimeout(() => {
341 this.endLoader();
342 this.infoToast(
343 this.$t('pageFirmware.toast.infoRefreshApplicationMessage'),
344 this.$t('pageFirmware.toast.infoRefreshApplicationTitle')
345 );
346 }, timeoutMs);
347 },
348 clearRebootTimeout() {
349 if (this.timeoutId) {
350 clearTimeout(this.timeoutId);
351 this.endLoader();
352 }
353 },
354 onSubmitUpload() {
355 this.$v.$touch();
356 if (this.$v.$invalid) return;
357 this.$bvModal.show('modal-upload');
Derick Montague602e98a2020-10-21 16:20:00 -0500358 },
359 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700360};
361</script>
362
363<style lang="scss" scoped>
364.update-code {
365 border-left: none;
366 @include media-breakpoint-up(xl) {
367 border-left: 1px solid gray('300');
368 }
369}
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700370.card-footer {
371 height: 41px;
372}
373.card-body {
374 padding: 0.75rem 1.25rem;
375}
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700376</style>