]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
d92186f24c4bbd7c348a9c98a5b9cac0a6b20f88
[ceph-ci.git] /
1 import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
2 import { I18n } from '@ngx-translate/i18n-polyfill';
3 import * as _ from 'lodash';
4 import {
5   OsdService,
6   SmartAttribute,
7   SmartDataV1,
8   SmartError
9 } from '../../../../shared/api/osd.service';
10 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
11
12 @Component({
13   selector: 'cd-osd-smart-list',
14   templateUrl: './osd-smart-list.component.html',
15   styleUrls: ['./osd-smart-list.component.scss']
16 })
17 export class OsdSmartListComponent implements OnInit, OnChanges {
18   @Input()
19   osdId: number;
20   loading = false;
21   incompatible = false;
22
23   data: {
24     [deviceId: string]: {
25       info: { [key: string]: number | string | boolean };
26       smart: {
27         revision: number;
28         table: SmartAttribute[];
29       };
30     };
31   } = {};
32
33   columns: CdTableColumn[];
34
35   constructor(private i18n: I18n, private osdService: OsdService) {}
36
37   private isSmartError(data: SmartDataV1 | SmartError): data is SmartError {
38     return (data as SmartError).error !== undefined;
39   }
40
41   private updateData(osdId: number) {
42     this.loading = true;
43     this.osdService.getSmartData(osdId).subscribe((data) => {
44       const result = {};
45       _.each(data, (smartData, deviceId) => {
46         if (this.isSmartError(smartData)) {
47           let userMessage = '';
48           if (smartData.smartctl_error_code === -22) {
49             userMessage = this.i18n(
50               `Smartctl has received an unknown argument (error code
51                 {{smartData.smartctl_error_code}}). You may be using an
52                 incompatible version of smartmontools. Version >= 7.0 of
53                 smartmontools is required to succesfully retrieve data.`,
54               { code: smartData.smartctl_error_code }
55             );
56           } else {
57             userMessage = this.i18n('An error with error code {{code}} occurred.', {
58               code: smartData.smartctl_error_code
59             });
60           }
61           result[deviceId] = {
62             error: smartData.error,
63             smartctl_error_code: smartData.smartctl_error_code,
64             smartctl_output: smartData.smartctl_output,
65             userMessage: userMessage,
66             device: smartData.dev,
67             identifier: smartData.nvme_vendor
68           };
69           return;
70         }
71
72         // Prepare S.M.A.R.T data
73         if (smartData.json_format_version[0] === 1) {
74           // Version 1.x
75           const excludes = [
76             'ata_smart_attributes',
77             'ata_smart_selective_self_test_log',
78             'ata_smart_data'
79           ];
80           const info = _.pickBy(smartData, (_value, key) => !excludes.includes(key));
81           // Build result
82           result[deviceId] = {
83             info: info,
84             smart: {
85               attributes: smartData.ata_smart_attributes,
86               data: smartData.ata_smart_data
87             },
88             device: info.device.name,
89             identifier: info.serial_number
90           };
91         } else {
92           this.incompatible = true;
93         }
94       });
95       this.data = result;
96       this.loading = false;
97     });
98   }
99
100   ngOnInit() {
101     this.columns = [
102       { prop: 'id', name: this.i18n('ID') },
103       { prop: 'name', name: this.i18n('Name') },
104       { prop: 'raw.value', name: this.i18n('Raw') },
105       { prop: 'thresh', name: this.i18n('Threshold') },
106       { prop: 'value', name: this.i18n('Value') },
107       { prop: 'when_failed', name: this.i18n('When Failed') },
108       { prop: 'worst', name: this.i18n('Worst') }
109     ];
110   }
111
112   ngOnChanges(changes: SimpleChanges): void {
113     this.data = {}; // Clear previous data
114     this.updateData(changes.osdId.currentValue);
115   }
116 }