Completed
Push — master ( 1806d1...053f07 )
by Nicolas
01:42
created

_linux_os_release()   F

Complexity

Conditions 9

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 9
dl 0
loc 26
rs 3
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2015 Nicolargo <[email protected]>
6
#
7
# Glances is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU Lesser General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Glances is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Lesser General Public License for more details.
16
#
17
# You should have received a copy of the GNU Lesser General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
"""System plugin."""
21
22
import os
23
import platform
24
import re
25
from io import open
26
27
from glances.compat import iteritems
28
from glances.plugins.glances_plugin import GlancesPlugin
29
30
# SNMP OID
31
snmp_oid = {'default': {'hostname': '1.3.6.1.2.1.1.5.0',
32
                        'system_name': '1.3.6.1.2.1.1.1.0'},
33
            'netapp': {'hostname': '1.3.6.1.2.1.1.5.0',
34
                       'system_name': '1.3.6.1.2.1.1.1.0',
35
                       'platform': '1.3.6.1.4.1.789.1.1.5.0'}}
36
37
# SNMP to human read
38
# Dict (key: OS short name) of dict (reg exp OID to human)
39
# Windows:
40
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
41
snmp_to_human = {'windows': {'Windows Version 6.3': 'Windows 8.1 or Server 2012R2',
42
                             'Windows Version 6.2': 'Windows 8 or Server 2012',
43
                             'Windows Version 6.1': 'Windows 7 or Server 2008R2',
44
                             'Windows Version 6.0': 'Windows Vista or Server 2008',
45
                             'Windows Version 5.2': 'Windows XP 64bits or 2003 server',
46
                             'Windows Version 5.1': 'Windows XP',
47
                             'Windows Version 5.0': 'Windows 2000'}}
48
49
50
def _linux_os_release():
51
    """Try to determine the name of a Linux distribution.
52
53
    This function checks for the /etc/os-release file.
54
    It takes the name from the 'NAME' field and the version from 'VERSION_ID'.
55
    An empty string is returned if the above values cannot be determined.
56
    """
57
    pretty_name = ''
58
    ashtray = {}
59
    keys = ['NAME', 'VERSION_ID']
60
    try:
61
        with open(os.path.join('/etc', 'os-release')) as f:
62
            for line in f:
63
                for key in keys:
64
                    if line.startswith(key):
65
                        ashtray[key] = line.strip().split('=')[1][1:-1]
66
    except (OSError, IOError):
67
        return pretty_name
68
69
    if ashtray:
70
        if 'NAME' in ashtray:
71
            pretty_name = ashtray['NAME']
72
        if 'VERSION_ID' in ashtray:
73
            pretty_name += ' {0}'.format(ashtray['VERSION_ID'])
74
75
    return pretty_name
76
77
78
class Plugin(GlancesPlugin):
79
80
    """Glances' host/system plugin.
81
82
    stats is a dict
83
    """
84
85
    def __init__(self, args=None):
86
        """Init the plugin."""
87
        super(Plugin, self).__init__(args=args)
88
89
        # We want to display the stat in the curse interface
90
        self.display_curse = True
91
92
        # Init the stats
93
        self.reset()
94
95
    def reset(self):
96
        """Reset/init the stats."""
97
        self.stats = {}
98
99
    def update(self):
100
        """Update the host/system info using the input method.
101
102
        Return the stats (dict)
103
        """
104
        # Reset stats
105
        self.reset()
106
107
        if self.input_method == 'local':
108
            # Update stats using the standard system lib
109
            self.stats['os_name'] = platform.system()
110
            self.stats['hostname'] = platform.node()
111
            self.stats['platform'] = platform.architecture()[0]
112
            if self.stats['os_name'] == "Linux":
113
                linux_distro = platform.linux_distribution()
114
                if linux_distro[0] == '':
115
                    self.stats['linux_distro'] = _linux_os_release()
116
                else:
117
                    self.stats['linux_distro'] = ' '.join(linux_distro[:2])
118
                self.stats['os_version'] = platform.release()
119
            elif self.stats['os_name'].endswith('BSD'):
120
                self.stats['os_version'] = platform.release()
121
            elif self.stats['os_name'] == "Darwin":
122
                self.stats['os_version'] = platform.mac_ver()[0]
123
            elif self.stats['os_name'] == "Windows":
124
                os_version = platform.win32_ver()
125
                self.stats['os_version'] = ' '.join(os_version[::2])
126
                # if the python version is 32 bit perhaps the windows operating
127
                # system is 64bit
128
                if self.stats['platform'] == '32bit' and 'PROCESSOR_ARCHITEW6432' in os.environ:
129
                    self.stats['platform'] = '64bit'
130
            else:
131
                self.stats['os_version'] = ""
132
            # Add human readable name
133
            if self.stats['os_name'] == "Linux":
134
                self.stats['hr_name'] = self.stats['linux_distro']
135
            else:
136
                self.stats['hr_name'] = '{0} {1}'.format(
137
                    self.stats['os_name'], self.stats['os_version'])
138
            self.stats['hr_name'] += ' {0}'.format(self.stats['platform'])
139
140
        elif self.input_method == 'snmp':
141
            # Update stats using SNMP
142
            try:
143
                self.stats = self.get_stats_snmp(
144
                    snmp_oid=snmp_oid[self.short_system_name])
145
            except KeyError:
146
                self.stats = self.get_stats_snmp(snmp_oid=snmp_oid['default'])
147
            # Default behavor: display all the information
148
            self.stats['os_name'] = self.stats['system_name']
149
            # Windows OS tips
150
            if self.short_system_name == 'windows':
151
                for r, v in iteritems(snmp_to_human['windows']):
152
                    if re.search(r, self.stats['system_name']):
153
                        self.stats['os_name'] = v
154
                        break
155
            # Add human readable name
156
            self.stats['hr_name'] = self.stats['os_name']
157
158
        return self.stats
159
160
    def msg_curse(self, args=None):
161
        """Return the string to display in the curse interface."""
162
        # Init the return message
163
        ret = []
164
165
        # Build the string message
166
        if args.client:
167
            # Client mode
168
            if args.cs_status.lower() == "connected":
169
                msg = 'Connected to '
170
                ret.append(self.curse_add_line(msg, 'OK'))
171
            elif args.cs_status.lower() == "snmp":
172
                msg = 'SNMP from '
173
                ret.append(self.curse_add_line(msg, 'OK'))
174
            elif args.cs_status.lower() == "disconnected":
175
                msg = 'Disconnected from '
176
                ret.append(self.curse_add_line(msg, 'CRITICAL'))
177
178
        # Hostname is mandatory
179
        msg = self.stats['hostname']
180
        ret.append(self.curse_add_line(msg, "TITLE"))
181
        # System info
182
        if self.stats['os_name'] == "Linux" and self.stats['linux_distro']:
183
            msg = ' ({0} {1} / {2} {3})'.format(self.stats['linux_distro'],
184
                                                self.stats['platform'],
185
                                                self.stats['os_name'],
186
                                                self.stats['os_version'])
187
        else:
188
            try:
189
                msg = ' ({0} {1} {2})'.format(self.stats['os_name'],
190
                                              self.stats['os_version'],
191
                                              self.stats['platform'])
192
            except Exception:
193
                msg = ' ({0})'.format(self.stats['os_name'])
194
        ret.append(self.curse_add_line(msg, optional=True))
195
196
        # Return the message with decoration
197
        return ret
198