blob: 54a2bb154e9e69124cbd3ea371cba2fc7642be32 [file] [log] [blame]
Yoshie Muranaka0b980db2020-10-06 09:24:14 -07001<template>
2 <b-container fluid="xl">
Yoshie Muranaka6f712842021-02-04 11:23:03 -08003 <page-title />
Yoshie Muranakafc387aa2021-02-11 08:27:36 -08004 <b-row v-if="isServerPowerOffRequired">
Yoshie Muranaka6f712842021-02-04 11:23:03 -08005 <b-col xl="10">
6 <!-- Operation in progress alert -->
7 <alert v-if="isOperationInProgress" variant="info" class="mb-5">
8 <p>
9 {{ $t('pageFirmware.singleFileUpload.alert.operationInProgress') }}
10 </p>
11 </alert>
12 <!-- Power off server warning alert -->
13 <alert v-else-if="!isHostOff" variant="warning" class="mb-5">
14 <p class="mb-0">
15 {{
16 $t('pageFirmware.singleFileUpload.alert.serverMustBePoweredOffTo')
17 }}
18 </p>
19 <ul class="m-0">
20 <li>
21 {{
22 $t(
23 'pageFirmware.singleFileUpload.alert.switchRunningAndBackupImages'
24 )
25 }}
26 </li>
27 <li>
28 {{ $t('pageFirmware.singleFileUpload.alert.updateFirmware') }}
29 </li>
30 </ul>
31 <template #action>
32 <b-link to="/control/server-power-operations">
33 {{
34 $t(
35 'pageFirmware.singleFileUpload.alert.viewServerPowerOperations'
36 )
37 }}
38 </b-link>
39 </template>
40 </alert>
41 </b-col>
42 </b-row>
43 <b-row>
44 <b-col xl="10">
45 <page-section>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -070046 <b-card-group deck>
Yoshie Muranaka6f712842021-02-04 11:23:03 -080047 <!-- Running image -->
Yoshie Muranaka0b980db2020-10-06 09:24:14 -070048 <b-card>
Derick Montague602e98a2020-10-21 16:20:00 -050049 <template #header>
Yoshie Muranaka6f712842021-02-04 11:23:03 -080050 <p class="font-weight-bold m-0">
51 {{ $t('pageFirmware.singleFileUpload.runningImage') }}
52 </p>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -070053 </template>
Yoshie Muranaka6f712842021-02-04 11:23:03 -080054 <dl class="mb-0">
55 <dt>{{ $t('pageFirmware.singleFileUpload.bmcAndServer') }}</dt>
56 <dd class="mb-0">{{ systemFirmwareVersion }}</dd>
57 </dl>
58 </b-card>
59
60 <!-- Backup image -->
61 <b-card>
62 <template #header>
63 <p class="font-weight-bold m-0">
64 {{ $t('pageFirmware.singleFileUpload.backupImage') }}
65 </p>
66 </template>
67 <dl>
68 <dt>
69 {{ $t('pageFirmware.singleFileUpload.bmcAndServer') }}
70 </dt>
71 <dd>
72 <status-icon v-if="showBackupImageStatus" status="danger" />
73 <span v-if="showBackupImageStatus" class="sr-only">
74 {{ backupFirmwareStatus }}
75 </span>
76 {{ backupFirmwareVersion }}
77 </dd>
78 </dl>
79 <b-btn
80 v-b-modal.modal-switch-to-running
81 data-test-id="firmware-button-switchToRunning"
82 variant="link"
83 size="sm"
84 class="py-0 px-1 mt-2"
85 :disabled="isPageDisabled || !isRebootFromBackupAvailable"
86 >
87 <icon-switch class="d-none d-sm-inline-block" />
88 {{ $t('pageFirmware.singleFileUpload.switchToRunning') }}
89 </b-btn>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -070090 </b-card>
91 </b-card-group>
92 </page-section>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -070093 </b-col>
Yoshie Muranaka6f712842021-02-04 11:23:03 -080094 </b-row>
95 <b-row>
96 <!-- Update firmware -->
97 <b-col sm="8" md="6" xl="4">
98 <page-section
99 :section-title="$t('pageFirmware.singleFileUpload.updateFirmware')"
100 >
101 <div class="form-background p-3">
102 <b-form @submit.prevent="onSubmitUpload">
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700103 <b-form-group
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800104 :label="$t('pageFirmware.singleFileUpload.fileSource')"
105 :disabled="isPageDisabled"
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700106 >
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800107 <b-form-radio v-model="isWorkstationSelected" :value="true">
108 {{ $t('pageFirmware.form.workstation') }}
109 </b-form-radio>
110 <b-form-radio v-model="isWorkstationSelected" :value="false">
111 {{ $t('pageFirmware.form.tftpServer') }}
112 </b-form-radio>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700113 </b-form-group>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700114
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800115 <!-- Workstation Upload -->
116 <template v-if="isWorkstationSelected">
117 <b-form-group
118 :label="$t('pageFirmware.form.imageFile')"
119 label-for="image-file"
120 >
121 <b-form-text id="image-file-help-block">
122 {{ $t('pageFirmware.form.onlyTarFilesAccepted') }}
123 </b-form-text>
124 <form-file
125 id="image-file"
126 accept=".tar"
127 :disabled="isPageDisabled"
128 :state="getValidationState($v.file)"
129 aria-describedby="image-file-help-block"
130 @input="onFileUpload($event)"
131 >
132 <template #invalid>
133 <b-form-invalid-feedback role="alert">
134 {{ $t('global.form.required') }}
135 </b-form-invalid-feedback>
136 </template>
137 </form-file>
138 </b-form-group>
139 </template>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700140
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800141 <!-- TFTP Server Upload -->
142 <template v-else>
143 <b-form-group
144 :label="$t('pageFirmware.singleFileUpload.fileAddress')"
145 label-for="tftp-address"
146 >
147 <b-form-input
148 id="tftp-address"
149 v-model="tftpFileAddress"
150 type="text"
151 :state="getValidationState($v.tftpFileAddress)"
152 :disabled="isPageDisabled"
153 @input="$v.tftpFileAddress.$touch()"
154 />
155 <b-form-invalid-feedback role="alert">
156 {{ $t('global.form.fieldRequired') }}
157 </b-form-invalid-feedback>
158 </b-form-group>
159 </template>
160 <b-btn
161 data-test-id="firmware-button-startUpdate"
162 type="submit"
163 variant="primary"
164 :disabled="isPageDisabled"
165 >
166 {{ $t('pageFirmware.singleFileUpload.startUpdate') }}
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700167 </b-btn>
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800168 <alert
Yoshie Muranakafc387aa2021-02-11 08:27:36 -0800169 v-if="isServerPowerOffRequired && !isHostOff"
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800170 variant="warning"
171 :small="true"
172 class="mt-4"
173 >
174 <p class="col-form-label">
175 {{
176 $t(
177 'pageFirmware.singleFileUpload.alert.serverMustBePoweredOffToUpdateFirmware'
178 )
179 }}
180 </p>
181 </alert>
182 </b-form>
183 </div>
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700184 </page-section>
185 </b-col>
186 </b-row>
187
188 <!-- Modals -->
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800189 <modal-update-firmware
190 :running="systemFirmwareVersion"
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700191 :backup="backupFirmwareVersion"
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800192 @ok="updateFirmware"
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700193 />
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800194 <modal-switch-to-running
195 :backup="backupFirmwareVersion"
196 @ok="switchToRunning"
197 />
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700198 </b-container>
199</template>
200
201<script>
202import { requiredIf } from 'vuelidate/lib/validators';
203import { mapGetters } from 'vuex';
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800204import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20';
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700205
206import PageSection from '@/components/Global/PageSection';
207import PageTitle from '@/components/Global/PageTitle';
208import Alert from '@/components/Global/Alert';
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800209import FormFile from '@/components/Global/FormFile';
210import StatusIcon from '@/components/Global/StatusIcon';
211import ModalUpdateFirmware from './FirmwareSingleImageModalUpdateFirmware';
212import ModalSwitchToRunning from './FirmwareSingleImageModalSwitchToRunning';
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700213
214import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
Yoshie Muranakad73f4962020-12-09 08:52:23 -0800215import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700216import BVToastMixin from '@/components/Mixins/BVToastMixin';
217
218export default {
219 name: 'FirmwareSingleImage',
220 components: {
221 Alert,
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800222 FormFile,
223 IconSwitch,
224 ModalSwitchToRunning,
225 ModalUpdateFirmware,
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700226 PageSection,
Derick Montague602e98a2020-10-21 16:20:00 -0500227 PageTitle,
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800228 StatusIcon,
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700229 },
230 mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
Derick Montagueefbd4012020-11-03 14:10:45 -0600231 beforeRouteLeave(to, from, next) {
232 this.hideLoader();
Derick Montagueefbd4012020-11-03 14:10:45 -0600233 next();
234 },
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700235 data() {
236 return {
237 isWorkstationSelected: true,
238 file: null,
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800239 tftpFileAddress: null,
Derick Montague602e98a2020-10-21 16:20:00 -0500240 timeoutId: null,
Yoshie Muranakad73f4962020-12-09 08:52:23 -0800241 loading,
Yoshie Muranakafc387aa2021-02-11 08:27:36 -0800242 isServerPowerOffRequired:
243 process.env.VUE_APP_SERVER_OFF_REQUIRED === 'true',
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700244 };
245 },
246 computed: {
247 hostStatus() {
248 return this.$store.getters['global/hostStatus'];
249 },
250 isHostOff() {
251 return this.hostStatus === 'off' ? true : false;
252 },
253 isOperationInProgress() {
254 return this.$store.getters['controls/isOperationInProgress'];
255 },
256 ...mapGetters('firmwareSingleImage', [
257 'backupFirmwareStatus',
258 'backupFirmwareVersion',
259 'isRebootFromBackupAvailable',
Derick Montague602e98a2020-10-21 16:20:00 -0500260 'systemFirmwareVersion',
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700261 ]),
262 isPageDisabled() {
Yoshie Muranakafc387aa2021-02-11 08:27:36 -0800263 if (this.isServerPowerOffRequired) {
264 return !this.isHostOff || this.loading || this.isOperationInProgress;
265 }
266 return this.loading || this.isOperationInProgress;
Derick Montague602e98a2020-10-21 16:20:00 -0500267 },
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800268 showBackupImageStatus() {
269 return (
270 this.backupFirmwareStatus === 'Critical' ||
271 this.backupFirmwareStatus === 'Warning'
272 );
273 },
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700274 },
275 watch: {
Derick Montague602e98a2020-10-21 16:20:00 -0500276 isWorkstationSelected: function () {
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700277 this.$v.$reset();
278 this.file = null;
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800279 this.tftpFileAddress = null;
Derick Montague602e98a2020-10-21 16:20:00 -0500280 },
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700281 },
282 created() {
283 this.startLoader();
284 this.$store.dispatch('firmwareSingleImage/getUpdateServiceApplyTime');
285 Promise.all([
286 this.$store.dispatch('global/getHostStatus'),
Derick Montague602e98a2020-10-21 16:20:00 -0500287 this.$store.dispatch('firmwareSingleImage/getFirmwareInformation'),
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700288 ]).finally(() => this.endLoader());
289 },
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700290 validations() {
291 return {
292 file: {
Derick Montague602e98a2020-10-21 16:20:00 -0500293 required: requiredIf(function () {
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700294 return this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500295 }),
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700296 },
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800297 tftpFileAddress: {
Derick Montague602e98a2020-10-21 16:20:00 -0500298 required: requiredIf(function () {
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700299 return !this.isWorkstationSelected;
Derick Montague602e98a2020-10-21 16:20:00 -0500300 }),
301 },
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700302 };
303 },
304 methods: {
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800305 updateFirmware() {
Yoshie Muranakaf92e2962021-02-09 12:41:53 -0800306 this.setRebootTimeout(360000, () => {
307 this.infoToast(
308 this.$t('pageFirmware.singleFileUpload.toast.verifyUpdateMessage'),
309 {
310 title: this.$t('pageFirmware.singleFileUpload.toast.verifyUpdate'),
311 refreshAction: true,
312 }
313 );
314 });
315 this.infoToast(
316 this.$t('pageFirmware.singleFileUpload.toast.updateStartedMessage'),
317 {
318 title: this.$t('pageFirmware.singleFileUpload.toast.updateStarted'),
319 timestamp: true,
320 }
321 );
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700322 if (this.isWorkstationSelected) {
323 this.dispatchWorkstationUpload();
324 } else {
325 this.dispatchTftpUpload();
326 }
327 },
328 dispatchWorkstationUpload() {
329 this.$store
330 .dispatch('firmwareSingleImage/uploadFirmware', this.file)
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700331 .catch(({ message }) => {
332 this.errorToast(message);
333 this.clearRebootTimeout();
334 });
335 },
336 dispatchTftpUpload() {
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700337 this.$store
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800338 .dispatch(
339 'firmwareSingleImage/uploadFirmwareTFTP',
340 this.tftpFileAddress
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700341 )
342 .catch(({ message }) => {
343 this.errorToast(message);
344 this.clearRebootTimeout();
345 });
346 },
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800347 switchToRunning() {
Yoshie Muranakaf92e2962021-02-09 12:41:53 -0800348 this.setRebootTimeout(60000, () => {
349 this.infoToast(
350 this.$t('pageFirmware.singleFileUpload.toast.verifySwitchMessage'),
351 {
352 title: this.$t('pageFirmware.singleFileUpload.toast.verifySwitch'),
353 refreshAction: true,
354 }
355 );
356 });
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700357 this.$store
358 .dispatch('firmwareSingleImage/switchFirmwareAndReboot')
Yoshie Muranakaf92e2962021-02-09 12:41:53 -0800359 .then(() =>
360 this.infoToast(
361 this.$t('pageFirmware.singleFileUpload.toast.rebootStartedMessage'),
362 {
363 title: this.$t(
364 'pageFirmware.singleFileUpload.toast.rebootStarted'
365 ),
366 }
367 )
368 )
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700369 .catch(({ message }) => {
370 this.errorToast(message);
371 this.clearRebootTimeout();
372 });
373 },
Yoshie Muranakaf92e2962021-02-09 12:41:53 -0800374 setRebootTimeout(timeoutMs = 60000, callback) {
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800375 // Set a timeout to disable page interactions
376 // during a BMC reboot
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700377 this.startLoader();
378 this.timeoutId = setTimeout(() => {
379 this.endLoader();
Yoshie Muranakaf92e2962021-02-09 12:41:53 -0800380 if (callback) callback();
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700381 }, timeoutMs);
382 },
383 clearRebootTimeout() {
384 if (this.timeoutId) {
385 clearTimeout(this.timeoutId);
386 this.endLoader();
387 }
388 },
389 onSubmitUpload() {
390 this.$v.$touch();
391 if (this.$v.$invalid) return;
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800392 this.$bvModal.show('modal-update-firmware');
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700393 },
Yoshie Muranaka6f712842021-02-04 11:23:03 -0800394 onFileUpload(file) {
395 this.file = file;
396 this.$v.file.$touch();
397 },
Derick Montague602e98a2020-10-21 16:20:00 -0500398 },
Yoshie Muranaka0b980db2020-10-06 09:24:14 -0700399};
400</script>