From e3d84c79b2c306aba05abf8829251685d51f0e8f Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Mon, 24 Nov 2014 21:02:43 +0100 Subject: [PATCH] Add static server list --- conf/glances-test.conf | 5 ++ glances/core/glances_autodiscover.py | 1 + glances/core/glances_client.py | 5 +- glances/core/glances_client_browser.py | 29 +++++---- glances/core/glances_main.py | 2 +- glances/core/glances_processes.py | 0 glances/core/glances_staticlist.py | 86 ++++++++++++++++++++++++++ glances/outputs/glances_curses.py | 23 +++++-- 8 files changed, 133 insertions(+), 18 deletions(-) mode change 100755 => 100644 glances/core/glances_processes.py create mode 100644 glances/core/glances_staticlist.py diff --git a/conf/glances-test.conf b/conf/glances-test.conf index 9ca9175a..256b3947 100644 --- a/conf/glances-test.conf +++ b/conf/glances-test.conf @@ -130,3 +130,8 @@ list_1_regex=.*python.* list_2_description=Famous Xeyes list_2_regex=.*xeyes.* list_2_countmin=1 + +[serverlist] +# Define the static server list +server_1_name=localhost +server_1_port=61234 diff --git a/glances/core/glances_autodiscover.py b/glances/core/glances_autodiscover.py index 04e194ac..0795a0ab 100644 --- a/glances/core/glances_autodiscover.py +++ b/glances/core/glances_autodiscover.py @@ -65,6 +65,7 @@ class AutoDiscovered(object): 'port': port, # TCP port 'username': 'glances', # Default username 'password': '', # Default password + 'status': 'UNKNOWN', # Server status: 'UNKNOWN', 'OFFLINE', 'ONLINE', 'PROTECTED' } self._server_list.append(new_server) logger.debug("Updated servers list (%s servers): %s" % diff --git a/glances/core/glances_client.py b/glances/core/glances_client.py index c7f228ec..a844a710 100644 --- a/glances/core/glances_client.py +++ b/glances/core/glances_client.py @@ -115,7 +115,10 @@ class GlancesClient(object): logger.error("Connection to Glances server failed (%s)" % err) self.set_mode('snmp') fallbackmsg = _("Trying fallback to SNMP...") - print(fallbackmsg) + if not return_to_browser: + print(fallbackmsg) + else: + logger.info(fallbackmsg) except ProtocolError as err: # Others errors if str(err).find(" 401 ") > 0: diff --git a/glances/core/glances_client_browser.py b/glances/core/glances_client_browser.py index 03bd7fd9..714a97fe 100644 --- a/glances/core/glances_client_browser.py +++ b/glances/core/glances_client_browser.py @@ -33,7 +33,7 @@ from glances.core.glances_globals import logger from glances.outputs.glances_curses import GlancesCursesBrowser from glances.core.glances_client import GlancesClientTransport, GlancesClient from glances.core.glances_autodiscover import GlancesAutoDiscoverServer -#from glances.core.glances_staticlist import GlancesStaticServer +from glances.core.glances_staticlist import GlancesStaticServer class GlancesClientBrowser(object): @@ -45,8 +45,8 @@ class GlancesClientBrowser(object): self.args = args self.config = config - # TODO: Init the static server list (if defined) - # self.static_server = GlancesStaticServer() + # Init the static server list (if defined) + self.static_server = GlancesStaticServer(config=self.config) # Start the autodiscover mode (Zeroconf listener) if not self.args.disable_autodiscover: @@ -60,15 +60,16 @@ class GlancesClientBrowser(object): def get_servers_list(self): """ Return the current server list (list of dict) - TODO: should return the merge of static + autodiscover servers list + Merge of static + autodiscover servers list """ + ret = [] + if self.args.browser: + ret = self.static_server.get_servers_list() if self.autodiscover_server is not None: - return self.autodiscover_server.get_servers_list() - else: - return [] - else: - return [] + ret = self.autodiscover_server.get_servers_list() + self.static_server.get_servers_list() + + return ret def serve_forever(self): """Main client loop.""" @@ -106,14 +107,20 @@ class GlancesClientBrowser(object): s.getMem())['percent'] # OS (Human Readable name) v['hr_name'] = json.loads(s.getSystem())['hr_name'] + # Status + v['status'] = 'ONLINE' except (socket.error, Fault, KeyError) as e: - logger.warning( + logger.debug( "Error while grabbing stats form {0}: {1}".format(uri, e)) + v['status'] = 'OFFLINE' except ProtocolError as e: if str(e).find(" 401 ") > 0: # Error 401 (Authentication failed) # Password is not the good one... v['password'] = None + v['status'] = 'PROTECTED' + else: + v['status'] = 'OFFLINE' logger.debug( "Can not grab stats from {0}: {1}".format(uri, e)) # List can change size during iteration... @@ -163,7 +170,7 @@ class GlancesClientBrowser(object): logger.debug("Disconnect Glances client from the %s server" % self.get_servers_list()[self.screen.get_active()]['key']) - + # Return to the browser (no server selected) self.screen.set_active(None) diff --git a/glances/core/glances_main.py b/glances/core/glances_main.py index 79ba84d9..d52d44f3 100644 --- a/glances/core/glances_main.py +++ b/glances/core/glances_main.py @@ -82,7 +82,7 @@ class GlancesMain(object): dest='disable_log', help=_('disable log module')) parser.add_argument('--disable-bold', action='store_false', default=True, dest='disable_bold', help=_('disable bold mode in the terminal')) - parser.add_argument('--enable-process-extended', action='store_false', default=False, + parser.add_argument('--enable-process-extended', action='store_true', default=False, dest='enable_process_extended', help=_('enable extended stats on top process')) parser.add_argument('--enable-history', action='store_true', default=False, dest='enable_history', help=_('enable the history mode')) diff --git a/glances/core/glances_processes.py b/glances/core/glances_processes.py old mode 100755 new mode 100644 diff --git a/glances/core/glances_staticlist.py b/glances/core/glances_staticlist.py new file mode 100644 index 00000000..9d06f9f9 --- /dev/null +++ b/glances/core/glances_staticlist.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2014 Nicolargo +# +# Glances is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Glances is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +"""Manage the Glances server static list """ + +# Import Glances libs +from glances.core.glances_globals import logger + + +class GlancesStaticServer(object): + + """Manage the static servers list for the client browser""" + + _section = "serverlist" + + def __init__(self, config=None, args=None): + # server_dict is a list of dict (JSON compliant) + # [ {'key': 'zeroconf name', ip': '172.1.2.3', 'port': 61209, 'cpu': 3, 'mem': 34 ...} ... ] + # Load the configuration file + self._server_list = self.load(config) + + def load(self, config): + """Load the server list from the configuration file""" + + server_list = [] + + if config is None: + logger.warning("No configuration file available. Can not load server list.") + elif not config.has_section(self._section): + logger.warning("No [%s] section in the configuration file. Can not load server list." % self._section) + else: + for i in range(1, 256): + new_server = {} + postfix = 'server_%s_' % str(i) + # Read the server name (mandatory) + new_server['name'] = config.get_raw_option(self._section, '%sname' % postfix) + if new_server['name'] is not None: + # Read other optionnal information + for s in ['alias', 'port', 'password']: + new_server[s] = config.get_raw_option(self._section, '%s%s' % (postfix, s)) + + # Manage optionnal information + if new_server['alias'] is None: + new_server['alias'] = new_server['name'] + if new_server['port'] is None: + new_server['port'] = 61209 + if new_server['password'] is None: + new_server['password'] = '' + new_server['username'] = 'glances' + new_server['ip'] = new_server['name'] + new_server['key'] = new_server['name'] + ':' + new_server['port'] + new_server['status'] = 'UNKNOWN' + + # Add the server to the list + logger.debug("Add server %s to the static list" % new_server['name']) + server_list.append(new_server) + + # Server list loaded + logger.info("%s server(s) loaded from the configuration file" % len(server_list)) + logger.debug("Static server list: %s" % server_list) + + return server_list + + def get_servers_list(self): + """Return the current server list (dict of dict)""" + return self._server_list + + def set_server(self, server_pos, key, value): + """Set the key to the value for the server_pos (position in the list)""" + self._server_list[server_pos][key] = value diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 0843b53d..71708e05 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -437,7 +437,8 @@ class _GlancesCurses(object): max_processes_displayed = 0 if glances_processes.get_max_processes() is None or \ glances_processes.get_max_processes() != max_processes_displayed: - logger.debug("Set number of displayed processes to %s" % max_processes_displayed) + logger.debug("Set number of displayed processes to %s" % + max_processes_displayed) glances_processes.set_max_processes(max_processes_displayed) stats_processlist = stats.get_plugin( @@ -635,7 +636,8 @@ class _GlancesCurses(object): textbox.edit() self.set_cursor(0) if textbox.gather() != '': - logger.debug("User enters the following process filter patern: %s" % textbox.gather()) + logger.debug( + "User enters the following process filter patern: %s" % textbox.gather()) return textbox.gather()[:-1] else: logger.debug("User clears the process filter patern") @@ -720,7 +722,8 @@ class _GlancesCurses(object): # occupy several bytes offset = len(m['msg'].decode("utf-8")) except AttributeError: - # Python 3: strings are strings and bytes are bytes, all is good + # Python 3: strings are strings and bytes are bytes, all is + # good offset = len(m['msg']) x = x + offset @@ -836,6 +839,14 @@ class GlancesCursesBrowser(_GlancesCurses): # Init the father class _GlancesCurses.__init__(self, args=args) + _colors_list = { + 'UNKNOWN': self.no_color, + 'ONLINE': self.default_color2, + 'OFFLINE': self.ifCRITICAL_color2, + 'PROTECTED': self.ifWARNING_color2, + } + self.colors_list = dict(self.colors_list.items() + _colors_list.items()) + # First time scan tag # Used to display a specific message when the browser is started self.first_scan = True @@ -925,7 +936,8 @@ class GlancesCursesBrowser(_GlancesCurses): # Getkey pressedkey = self.__catch_key(servers_list) # Is it an exit or select server key ? - exitkey = (pressedkey == ord('\x1b') or pressedkey == ord('q') or pressedkey == 10) + exitkey = ( + pressedkey == ord('\x1b') or pressedkey == ord('q') or pressedkey == 10) if not exitkey and pressedkey > -1: # Redraw display self.flush(servers_list) @@ -990,6 +1002,7 @@ class GlancesCursesBrowser(_GlancesCurses): ['load_min5', _('LOAD'), 6], ['cpu_percent', _('CPU%'), 5], ['mem_percent', _('MEM%'), 5], + ['status', _('STATUS'), 8], ['ip', _('IP'), 15], ['port', _('PORT'), 5], ['hr_name', _('OS'), 16], @@ -1047,7 +1060,7 @@ class GlancesCursesBrowser(_GlancesCurses): self.term_window.addnstr(y, xc, "%s" % server_stat[c[0]], screen_x - xc, - self.colors_list['DEFAULT']) + self.colors_list[v['status']]) xc += c[2] + self.space_between_column cpt += 1 # Next line, next server...