o
    va                  
   @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ zddl	m
Z
 W n ey> Z zdaede W Y d	Z[nd	Z[ww d
add Zdd ZG dd deZd	S )a  
Hard disk SMART attributes plugin.
Depends on pySMART and smartmontools
Must execute as root
"usermod -a -G disk USERNAME" is not sufficient unfortunately
SmartCTL (/usr/sbin/smartctl) must be in system path for python2.

Regular PySMART is a python2 library.
We are using the pySMART.smartx updated library to support both python 2 and 3.

If we only have disk group access (no root):
$ smartctl -i /dev/sda
smartctl 6.6 2016-05-31 r4324 [x86_64-linux-4.15.0-30-generic] (local build)
Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org


Probable ATA device behind a SAT layer
Try an additional '-d ata' or '-d sat' argument.

This is not very hopeful: https://medium.com/opsops/why-smartctl-could-not-be-run-without-root-7ea0583b1323

So, here is what we are going to do:
Check for admin access.  If no admin access, disable SMART plugin.

If smartmontools is not installed, we should catch the error upstream in plugin initialization.
    )GlancesPlugin)logger)disable)is_admin)
DeviceListTz5Missing Python Lib ({}), HDD Smart plugin is disabledNFc                 C   s.   | j | j| j| j| j| j| j| j| j| j	d
S )N)
namenumflagsrawvalueworstZ	thresholdtypeupdatedwhen_failed)
r   r   r	   r
   r   r   Zthreshr   r   r   )attr r   ?/usr/lib/python3/dist-packages/glances/plugins/glances_smart.pyconvert_attribute_to_dict>   s   r   c                  C   s   g } zt  }W n ty% } ztd| da| W  Y d}~S d}~ww |jD ]N}| dd|j|j	i |j
D ];}|du rBq;t|}|dd}z|dusSJ W n tyo } ztd|| W Y d}~q;d}~ww || d |< q;q)| S )	aT  
    Get SMART attribute data
    :return: list of multi leveled dictionaries
             each dict has a key "DeviceName" with the identification of the device in smartctl
             also has keys of the SMART attribute id, with value of another dict of the attributes
             [
                {
                    "DeviceName": "/dev/sda blahblah",
                    "1":
                    {
                        "flags": "..",
                        "raw": "..",
                        etc,
                    }
                    ...
                }
             ]
    z2Smart plugin error - Can not grab device list ({})TN
DeviceNamez{} {}r   z/Smart plugin error - Skip the attribute {} ({}))r   	TypeErrorr   debugformatimport_error_tagZdevicesappendr   ZmodelZ
attributesr   pop	Exception)statsZdevlisteZdevZ	attributeZ
attribdictr   r   r   r   get_smart_dataM   s<   


r   c                       sN   e Zd ZdZddg f fdd	Zejejdd Zdd Z	dd	d
Z
  ZS )PluginzB
    Glances' HDD SMART plugin.

    stats is a list of dicts
    Nc                    s8   t  st|d td tt| j||d d| _dS )zInit the plugin.Zsmartz5Current user is not admin, HDD SMART plugin disabled.)argsconfigTN)r   r   r   r   superr    __init__Zdisplay_curse)selfr!   r"   Zstats_init_value	__class__r   r   r$      s
   


zPlugin.__init__c                 C   s<   |   }tr	| jS | jdkrt }n| jdkr	 || _| jS )z*Update SMART stats using the input method.ZlocalZsnmp)Zget_init_valuer   r   Zinput_methodr   )r%   r   r   r   r   update   s   

zPlugin.updatec                 C   s   dS )zReturn the key of the list.r   r   )r%   r   r   r   get_key   s   zPlugin.get_keyc                 C   s  g }t s| jr|  r|S |d }djd|d}|| |d | jD ]e}||   dj|d d| |d}|| | tdd	 | D t	d
D ]9}||   dj|| d d|d  
dd|d d}|| | d|| d }|| | qOq$|S )z2Return the dict to display in the curse interface.   z
{:{width}}zSMART disks)widthZTITLEr   Nc                 S   s   g | ]}|d kr|qS )r   r   ).0ir   r   r   
<listcomp>   s    z$Plugin.msg_curse.<locals>.<listcomp>)keyz {:{width}}r      _ z{:>8}r
   )r   r   Zis_disabledr   r   Zcurse_add_lineZcurse_new_linesortedkeysintreplace)r%   r!   Z	max_widthretZname_max_widthmsgZdevice_statZ
smart_statr   r   r   	msg_curse   s0   
"zPlugin.msg_curse)NN)__name__
__module____qualname____doc__r$   r   Z_check_decoratorZ_log_result_decoratorr(   r)   r9   __classcell__r   r   r&   r   r       s    r    )r=   Zglances.plugins.glances_pluginr   Zglances.loggerr   Zglances.mainr   Zglances.compatr   ZpySMARTr   ImportErrorr   r   Zwarningr   r   r   r    r   r   r   r   <module>   s    6