summaryrefslogtreecommitdiffstats
path: root/glances/plugins/system/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'glances/plugins/system/__init__.py')
-rw-r--r--glances/plugins/system/__init__.py200
1 files changed, 200 insertions, 0 deletions
diff --git a/glances/plugins/system/__init__.py b/glances/plugins/system/__init__.py
index e69de29b..0b53bfd5 100644
--- a/glances/plugins/system/__init__.py
+++ b/glances/plugins/system/__init__.py
@@ -0,0 +1,200 @@
+# -*- coding: utf-8 -*-
+#
+# This file is part of Glances.
+#
+# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
+#
+# SPDX-License-Identifier: LGPL-3.0-only
+#
+
+"""System plugin."""
+
+import os
+import platform
+import re
+from io import open
+
+from glances.globals import iteritems
+from glances.plugins.plugin.model import GlancesPluginModel
+
+# SNMP OID
+snmp_oid = {
+ 'default': {'hostname': '1.3.6.1.2.1.1.5.0', 'system_name': '1.3.6.1.2.1.1.1.0'},
+ 'netapp': {
+ 'hostname': '1.3.6.1.2.1.1.5.0',
+ 'system_name': '1.3.6.1.2.1.1.1.0',
+ 'platform': '1.3.6.1.4.1.789.1.1.5.0',
+ },
+}
+
+# SNMP to human read
+# Dict (key: OS short name) of dict (reg exp OID to human)
+# Windows:
+# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
+snmp_to_human = {
+ 'windows': {
+ 'Windows Version 10.0': 'Windows 10 or Server 2016',
+ 'Windows Version 6.3': 'Windows 8.1 or Server 2012R2',
+ 'Windows Version 6.2': 'Windows 8 or Server 2012',
+ 'Windows Version 6.1': 'Windows 7 or Server 2008R2',
+ 'Windows Version 6.0': 'Windows Vista or Server 2008',
+ 'Windows Version 5.2': 'Windows XP 64bits or 2003 server',
+ 'Windows Version 5.1': 'Windows XP',
+ 'Windows Version 5.0': 'Windows 2000',
+ }
+}
+
+
+def _linux_os_release():
+ """Try to determine the name of a Linux distribution.
+
+ This function checks for the /etc/os-release file.
+ It takes the name from the 'NAME' field and the version from 'VERSION_ID'.
+ An empty string is returned if the above values cannot be determined.
+ """
+ pretty_name = ''
+ ashtray = {}
+ keys = ['NAME', 'VERSION_ID']
+ try:
+ with open(os.path.join('/etc', 'os-release')) as f:
+ for line in f:
+ for key in keys:
+ if line.startswith(key):
+ ashtray[key] = re.sub(r'^"|"$', '', line.strip().split('=')[1])
+ except (OSError, IOError):
+ return pretty_name
+
+ if ashtray:
+ if 'NAME' in ashtray:
+ pretty_name = ashtray['NAME']
+ if 'VERSION_ID' in ashtray:
+ pretty_name += ' {}'.format(ashtray['VERSION_ID'])
+
+ return pretty_name
+
+
+class PluginModel(GlancesPluginModel):
+
+ """Glances' host/system plugin.
+
+ stats is a dict
+ """
+
+ def __init__(self, args=None, config=None):
+ """Init the plugin."""
+ super(PluginModel, self).__init__(args=args, config=config)
+
+ # We want to display the stat in the curse interface
+ self.display_curse = True
+
+ # Set default rate to 60 seconds
+ if self.get_refresh():
+ self.set_refresh(60)
+
+ @GlancesPluginModel._check_decorator
+ @GlancesPluginModel._log_result_decorator
+ def update(self):
+ """Update the host/system info using the input method.
+
+ :return: the stats dict
+ """
+ # Init new stats
+ stats = self.get_init_value()
+
+ if self.input_method == 'local':
+ # Update stats using the standard system lib
+ stats['os_name'] = platform.system()
+ stats['hostname'] = platform.node()
+ stats['platform'] = platform.architecture()[0]
+ if stats['os_name'] == "Linux":
+ try:
+ linux_distro = platform.linux_distribution()
+ except AttributeError:
+ stats['linux_distro'] = _linux_os_release()
+ else:
+ if linux_distro[0] == '':
+ stats['linux_distro'] = _linux_os_release()
+ else:
+ stats['linux_distro'] = ' '.join(linux_distro[:2])
+ stats['os_version'] = platform.release()
+ elif stats['os_name'].endswith('BSD') or stats['os_name'] == 'SunOS':
+ stats['os_version'] = platform.release()
+ elif stats['os_name'] == "Darwin":
+ stats['os_version'] = platform.mac_ver()[0]
+ elif stats['os_name'] == "Windows":
+ os_version = platform.win32_ver()
+ stats['os_version'] = ' '.join(os_version[::2])
+ # if the python version is 32 bit perhaps the windows operating
+ # system is 64bit
+ if stats['platform'] == '32bit' and 'PROCESSOR_ARCHITEW6432' in os.environ:
+ stats['platform'] = '64bit'
+ else:
+ stats['os_version'] = ""
+ # Add human readable name
+ if stats['os_name'] == "Linux":
+ stats['hr_name'] = stats['linux_distro']
+ else:
+ stats['hr_name'] = '{} {}'.format(stats['os_name'], stats['os_version'])
+ stats['hr_name'] += ' {}'.format(stats['platform'])
+
+ elif self.input_method == 'snmp':
+ # Update stats using SNMP
+ try:
+ stats = self.get_stats_snmp(snmp_oid=snmp_oid[self.short_system_name])
+ except KeyError:
+ stats = self.get_stats_snmp(snmp_oid=snmp_oid['default'])
+ # Default behavior: display all the information
+ stats['os_name'] = stats['system_name']
+ # Windows OS tips
+ if self.short_system_name == 'windows':
+ for r, v in iteritems(snmp_to_human['windows']):
+ if re.search(r, stats['system_name']):
+ stats['os_name'] = v
+ break
+ # Add human readable name
+ stats['hr_name'] = stats['os_name']
+
+ # Update the stats
+ self.stats = stats
+
+ return self.stats
+
+ def msg_curse(self, args=None, max_width=None):
+ """Return the string to display in the curse interface."""
+ # Init the return message
+ ret = []
+
+ # Only process if stats exist and plugin not disabled
+ if not self.stats or self.is_disabled():
+ return ret
+
+ # Build the string message
+ if args.client:
+ # Client mode
+ if args.cs_status.lower() == "connected":
+ msg = 'Connected to '
+ ret.append(self.curse_add_line(msg, 'OK'))
+ elif args.cs_status.lower() == "snmp":
+ msg = 'SNMP from '
+ ret.append(self.curse_add_line(msg, 'OK'))
+ elif args.cs_status.lower() == "disconnected":
+ msg = 'Disconnected from '
+ ret.append(self.curse_add_line(msg, 'CRITICAL'))
+
+ # Hostname is mandatory
+ msg = self.stats['hostname']
+ ret.append(self.curse_add_line(msg, "TITLE"))
+ # System info
+ if self.stats['os_name'] == "Linux" and self.stats['linux_distro']:
+ msg = ' ({} {} / {} {})'.format(
+ self.stats['linux_distro'], self.stats['platform'], self.stats['os_name'], self.stats['os_version']
+ )
+ else:
+ try:
+ msg = ' ({} {} {})'.format(self.stats['os_name'], self.stats['os_version'], self.stats['platform'])
+ except Exception:
+ msg = ' ({})'.format(self.stats['os_name'])
+ ret.append(self.curse_add_line(msg, optional=True))
+
+ # Return the message with decoration
+ return ret