blob: 24ef33c848616b950429ca9de50517757f4745f4 [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>
Derick Montaguead48a0c2020-10-30 08:48:09 -0500172
173 <b-btn type="submit" variant="primary">
174 {{ $t('pageFirmware.form.uploadAndRebootBmcOrHost') }}
175 </b-btn>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700176 </b-form>
177 </page-section>
178 </b-col>
179 </b-row>
180
181 <!-- Modals -->
182 <modal-upload @ok="uploadFirmware" />
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700183 <modal-reboot-backup-bmc
184 :current="bmcFirmwareCurrentVersion || '--'"
185 :backup="bmcFirmwareBackupVersion || '--'"
186 @ok="switchBmcFirmware"
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700187 />
188 </b-container>
189</template>
190
191<script>
192import { requiredIf } from 'vuelidate/lib/validators';
193import { mapGetters } from 'vuex';
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700194import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700195
196import PageSection from '@/components/Global/PageSection';
197import PageTitle from '@/components/Global/PageTitle';
198import Alert from '@/components/Global/Alert';
199import ModalUpload from './FirmwareModalUpload';
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700200import ModalRebootBackupBmc from './FirmwareModalRebootBackupBmc';
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700201
202import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
203import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
204import BVToastMixin from '@/components/Mixins/BVToastMixin';
205
206export default {
207 name: 'Firmware',
208 components: {
209 Alert,
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700210 IconSwitch,
211 ModalRebootBackupBmc,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700212 ModalUpload,
213 PageSection,
Derick Montague602e98a2020-10-21 16:20:00 -0500214 PageTitle,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700215 },
216 mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
Derick Montague602e98a2020-10-21 16:20:00 -0500217 beforeRouteLeave(to, from, next) {
218 this.hideLoader();
219 this.clearRebootTimeout();
220 next();
221 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700222 data() {
223 return {
224 isWorkstationSelected: true,
225 file: null,
226 tftpIpAddress: null,
227 tftpFileName: null,
Derick Montague602e98a2020-10-21 16:20:00 -0500228 timeoutId: null,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700229 };
230 },
231 computed: {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700232 ...mapGetters('firmware', [
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700233 'bmcFirmwareCurrentVersion',
234 'bmcFirmwareCurrentState',
235 'bmcFirmwareBackupVersion',
236 'bmcFirmwareBackupState',
237 'hostFirmwareCurrentVersion',
238 'hostFirmwareCurrentState',
239 'hostFirmwareBackupVersion',
Derick Montague602e98a2020-10-21 16:20:00 -0500240 'hostFirmwareBackupState',
241 ]),
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700242 },
243 watch: {
Derick Montague602e98a2020-10-21 16:20:00 -0500244 isWorkstationSelected: function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700245 this.$v.$reset();
246 this.file = null;
247 this.tftpIpAddress = null;
248 this.tftpFileName = null;
Derick Montague602e98a2020-10-21 16:20:00 -0500249 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700250 },
251 created() {
252 this.startLoader();
253 this.$store.dispatch('firmware/getUpdateServiceApplyTime');
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700254 this.$store
255 .dispatch('firmware/getFirmwareInformation')
256 .finally(() => this.endLoader());
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700257 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700258 validations() {
259 return {
260 file: {
Derick Montague602e98a2020-10-21 16:20:00 -0500261 required: requiredIf(function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700262 return this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500263 }),
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700264 },
265 tftpIpAddress: {
Derick Montague602e98a2020-10-21 16:20:00 -0500266 required: requiredIf(function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700267 return !this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500268 }),
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700269 },
270 tftpFileName: {
Derick Montague602e98a2020-10-21 16:20:00 -0500271 required: requiredIf(function () {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700272 return !this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500273 }),
274 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700275 };
276 },
277 methods: {
278 uploadFirmware() {
279 const startTime = this.$options.filters.formatTime(new Date());
280 this.setRebootTimeout(360000); //6 minute timeout
281 this.infoToast(
282 this.$t('pageFirmware.toast.infoUploadStartTimeMessage', { startTime }),
283 this.$t('pageFirmware.toast.infoUploadStartTimeTitle')
284 );
285 if (this.isWorkstationSelected) {
286 this.dispatchWorkstationUpload();
287 } else {
288 this.dispatchTftpUpload();
289 }
290 },
291 dispatchWorkstationUpload() {
292 this.$store
293 .dispatch('firmware/uploadFirmware', this.file)
Derick Montague602e98a2020-10-21 16:20:00 -0500294 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700295 this.infoToast(
296 success,
297 this.$t('pageFirmware.toast.successUploadTitle')
298 )
299 )
300 .catch(({ message }) => {
301 this.errorToast(message);
302 this.clearRebootTimeout();
303 });
304 },
305 dispatchTftpUpload() {
306 const data = {
307 address: this.tftpIpAddress,
Derick Montague602e98a2020-10-21 16:20:00 -0500308 filename: this.tftpFileName,
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700309 };
310 this.$store
311 .dispatch('firmware/uploadFirmwareTFTP', data)
Derick Montague602e98a2020-10-21 16:20:00 -0500312 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700313 this.infoToast(
314 success,
315 this.$t('pageFirmware.toast.successUploadTitle')
316 )
317 )
318 .catch(({ message }) => {
319 this.errorToast(message);
320 this.clearRebootTimeout();
321 });
322 },
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700323 switchBmcFirmware() {
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700324 this.setRebootTimeout();
325 this.$store
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700326 .dispatch('firmware/switchBmcFirmware')
Derick Montague602e98a2020-10-21 16:20:00 -0500327 .then((success) =>
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700328 this.infoToast(success, this.$t('global.status.success'))
329 )
330 .catch(({ message }) => {
331 this.errorToast(message);
332 this.clearRebootTimeout();
333 });
334 },
335 setRebootTimeout(timeoutMs = 60000) {
336 // Set a timeout to disable page interactions while
337 // an upload or BMC reboot is in progress
338 this.startLoader();
339 this.timeoutId = setTimeout(() => {
340 this.endLoader();
341 this.infoToast(
342 this.$t('pageFirmware.toast.infoRefreshApplicationMessage'),
343 this.$t('pageFirmware.toast.infoRefreshApplicationTitle')
344 );
345 }, timeoutMs);
346 },
347 clearRebootTimeout() {
348 if (this.timeoutId) {
349 clearTimeout(this.timeoutId);
350 this.endLoader();
351 }
352 },
353 onSubmitUpload() {
354 this.$v.$touch();
355 if (this.$v.$invalid) return;
356 this.$bvModal.show('modal-upload');
Derick Montague602e98a2020-10-21 16:20:00 -0500357 },
358 },
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700359};
360</script>
361
362<style lang="scss" scoped>
363.update-code {
364 border-left: none;
365 @include media-breakpoint-up(xl) {
366 border-left: 1px solid gray('300');
367 }
368}
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700369.card-footer {
Dixsie Wolmers30f11f82020-11-10 16:07:56 -0600370 height: 40px;
Yoshie Muranaka98bb24e2020-10-06 10:00:19 -0700371}
372.card-body {
373 padding: 0.75rem 1.25rem;
374}
Yoshie Muranaka92a0a4a2020-07-15 10:30:31 -0700375</style>