From 43027f4a3920f309a3bd5bc59ea6375b8e1000f5 Mon Sep 17 00:00:00 2001 From: Nicolargo Date: Tue, 2 Dec 2014 22:40:59 +0100 Subject: [PATCH] Upgrade status in the browser list --- conf/glances-test.conf | 7 +-- docs/glances-doc.rst | 6 +-- glances/core/glances_autodiscover.py | 1 + glances/core/glances_client.py | 2 + glances/core/glances_client_browser.py | 70 ++++++++++++++++++++------ glances/core/glances_staticlist.py | 5 ++ glances/outputs/glances_curses.py | 16 ++++-- 7 files changed, 81 insertions(+), 26 deletions(-) diff --git a/conf/glances-test.conf b/conf/glances-test.conf index 5e930388..719ac78f 100644 --- a/conf/glances-test.conf +++ b/conf/glances-test.conf @@ -135,10 +135,11 @@ list_2_countmin=1 # Define the static server list server_1_name=localhost server_1_alias=MonXPS -server_1_port=61234 +server_1_port=61209 server_2_name=localhost server_2_port=61235 -server_3_name=localhost -server_3_port=61236 +server_3_name=192.168.0.17 +server_3_alias=VMWin7 +server_3_port=61209 server_4_name=pasbon server_4_port=61237 diff --git a/docs/glances-doc.rst b/docs/glances-doc.rst index 5c740abd..fa0dc956 100644 --- a/docs/glances-doc.rst +++ b/docs/glances-doc.rst @@ -2,11 +2,11 @@ Glances ======= -This manual describes *Glances* version 2.1.2. +This manual describes *Glances* version 2.2. Copyright © 2012-2014 Nicolas Hennion -October 2014 +December 2014 .. contents:: Table of Contents @@ -67,7 +67,7 @@ and on the client: where ``@server`` is the IP address or hostname of the server. -Glances can centralize available Glances servers using the ``--browser`` option. The server list can be staticaly defined in the Glances configuration file (section [serverlist]). Glances can also detect and display all Glances servers available on you network (auto discover mode is based on the the Zeroconf protocol): +Glances can centralize available Glances servers using the ``--browser`` option. The server list can be staticaly defined in the Glances configuration file (section [serverlist]). Glances can also detect and display all Glances servers available on you network (auto discover mode is based on the the Zeroconf protocol only available on GNU/Linux and Mac OS X): .. code-block:: console diff --git a/glances/core/glances_autodiscover.py b/glances/core/glances_autodiscover.py index d269aff7..f95400d3 100644 --- a/glances/core/glances_autodiscover.py +++ b/glances/core/glances_autodiscover.py @@ -66,6 +66,7 @@ class AutoDiscovered(object): 'username': 'glances', # Default username 'password': '', # Default password 'status': 'UNKNOWN', # Server status: 'UNKNOWN', 'OFFLINE', 'ONLINE', 'PROTECTED' + 'type': 'DYNAMIC', # Server type: 'STATIC' or 'DYNAMIC' } 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 a844a710..45d9db7c 100644 --- a/glances/core/glances_client.py +++ b/glances/core/glances_client.py @@ -235,6 +235,8 @@ class GlancesClient(object): cs_status=cs_status, return_to_browser=return_to_browser) + return self.get_mode() + def end(self): """End of the client session.""" self.screen.end() diff --git a/glances/core/glances_client_browser.py b/glances/core/glances_client_browser.py index d195b6d1..bd34b794 100644 --- a/glances/core/glances_client_browser.py +++ b/glances/core/glances_client_browser.py @@ -76,19 +76,28 @@ class GlancesClientBrowser(object): while True: # No need to update the server list # It's done by the GlancesAutoDiscoverListener class (glances_autodiscover.py) + # Or define staticaly in the configuration file (module glances_staticlist.py) # For each server in the list, grab elementary stats (CPU, LOAD, MEM, OS...) # logger.debug(self.get_servers_list()) try: for v in self.get_servers_list(): - # !!! Perhaps, it will be better to store the ServerProxy instance in the get_servers_list + # Do not retreive stats for statics server + # Why ? Because for each offline servers, the timeout will be reached + # So ? The curse interface freezes + if (v['type'] == 'STATIC' and v['status'] in ['UNKNOWN', 'SNMP', 'OFFLINE']): + continue + + # Select the connection mode (with or without password) if v['password'] != "": uri = 'http://{0}:{1}@{2}:{3}'.format(v['username'], v['password'], v['ip'], v['port']) else: uri = 'http://{0}:{1}'.format(v['ip'], v['port']) - # Try to connect to the URI + + # Try to connect to the server t = GlancesClientTransport() t.set_timeout(3) + # Get common stats try: s = ServerProxy(uri, transport=t) @@ -96,9 +105,8 @@ class GlancesClientBrowser(object): logger.warning( "Client browser couldn't create socket {0}: {1}".format(uri, e)) else: + # Mandatory stats try: - # LOAD - v['load_min5'] = json.loads(s.getLoad())['min5'] # CPU% cpu_percent = 100 - json.loads(s.getCpu())['idle'] v['cpu_percent'] = '{0:.1f}'.format(cpu_percent) @@ -106,8 +114,6 @@ class GlancesClientBrowser(object): v['mem_percent'] = json.loads(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.debug( "Error while grabbing stats form {0}: {1}".format(uri, e)) @@ -122,6 +128,17 @@ class GlancesClientBrowser(object): v['status'] = 'OFFLINE' logger.debug( "Can not grab stats from {0}: {1}".format(uri, e)) + else: + # Status + v['status'] = 'ONLINE' + + # Optional stats (load is not available on Windows OS) + try: + # LOAD + v['load_min5'] = json.loads(s.getLoad())['min5'] + except Exception as e: + logger.warning( + "Error while grabbing stats form {0}: {1}".format(uri, e)) # List can change size during iteration... except RuntimeError: logger.debug( @@ -134,6 +151,11 @@ class GlancesClientBrowser(object): else: # Display the Glances client for the selected server logger.debug("Selected server: %s" % self.get_servers_list()[self.screen.get_active()]) + + # Connection can take time + # Display a popup + self.screen.display_popup(_("Connect to %s:%s" % (v['name'], v['port'])), duration=1) + # A password is needed to access to the server's stats if self.get_servers_list()[self.screen.get_active()]['password'] is None: from hashlib import sha256 @@ -141,15 +163,8 @@ class GlancesClientBrowser(object): clear_password = self.screen.display_popup(_("Password needed for %s: " % v['name']), is_input=True) # Hash with SHA256 encoded_password = sha256(clear_password).hexdigest() - # Static list then dynamic one - if self.screen.get_active() >= len(self.static_server.get_servers_list()): - self.autodiscover_server.set_server(self.screen.get_active() - len(self.static_server.get_servers_list()), - 'password', - encoded_password) - else: - self.static_server.set_server(self.screen.get_active(), - 'password', - encoded_password) + # Store the password for the selected server + self.set_in_selected('password', encoded_password) # Display the Glance client on the selected server logger.info("Connect Glances client to the %s server" % @@ -169,16 +184,39 @@ class GlancesClientBrowser(object): # Test if client and server are in the same major version if not client.login(return_to_browser=True): self.screen.display_popup(_("Sorry, can not connect to %s (see log file for additional information)" % v['name'])) + + # Set the ONLINE status for the selected server + self.set_in_selected('status', 'OFFLINE') else: # Start the client loop - client.serve_forever(return_to_browser=True) + # Return connection type: 'glances' or 'snmp' + connection_type = client.serve_forever(return_to_browser=True) logger.debug("Disconnect Glances client from the %s server" % self.get_servers_list()[self.screen.get_active()]['key']) + # Set the ONLINE status for the selected server + if connection_type == 'snmp': + self.set_in_selected('status', 'SNMP') + else: + self.set_in_selected('status', 'ONLINE') + # Return to the browser (no server selected) self.screen.set_active(None) + def set_in_selected(self, key, value): + """Set the (key, value) for the selected server in the list""" + # Static list then dynamic one + if self.screen.get_active() >= len(self.static_server.get_servers_list()): + self.autodiscover_server.set_server(self.screen.get_active() - len(self.static_server.get_servers_list()), + key, + value) + else: + self.static_server.set_server(self.screen.get_active(), + key, + value) + + def end(self): """End of the client browser session.""" self.screen.end() diff --git a/glances/core/glances_staticlist.py b/glances/core/glances_staticlist.py index 955d3a6f..bc95e38b 100644 --- a/glances/core/glances_staticlist.py +++ b/glances/core/glances_staticlist.py @@ -67,8 +67,13 @@ class GlancesStaticServer(object): logger.error("Can not get IP address for server %s (%s)" % (new_server['name'], e)) continue new_server['key'] = new_server['name'] + ':' + new_server['port'] + + # Default status is 'UNKNOWN' new_server['status'] = 'UNKNOWN' + # Server type is 'STATIC' + new_server['type'] = 'STATIC' + # Add the server to the list logger.debug("Add server %s to the static list" % new_server['name']) server_list.append(new_server) diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index a2b0dbee..72b89eac 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -845,6 +845,7 @@ class GlancesCursesBrowser(_GlancesCurses): _colors_list = { 'UNKNOWN': self.no_color, + 'SNMP': self.default_color2, 'ONLINE': self.default_color2, 'OFFLINE': self.ifCRITICAL_color2, 'PROTECTED': self.ifWARNING_color2, @@ -886,16 +887,20 @@ class GlancesCursesBrowser(_GlancesCurses): """Return the cursor position""" return self.cursor_position - def cursor_up(self): + def cursor_up(self, servers_list): """Set the cursor to position N-1 in the list""" if self.cursor_position > 0: self.cursor_position -= 1 + else: + self.cursor_position = len(servers_list) - 1 return self.cursor_position def cursor_down(self, servers_list): """Set the cursor to position N-1 in the list""" if self.cursor_position < len(servers_list) - 1: self.cursor_position += 1 + else: + self.cursor_position = 0 return self.cursor_position def __catch_key(self, servers_list): @@ -915,7 +920,7 @@ class GlancesCursesBrowser(_GlancesCurses): elif self.pressedkey == 259: # 'UP' > Up in the server list logger - self.cursor_up() + self.cursor_up(servers_list) elif self.pressedkey == 258: # 'DOWN' > Down in the server list self.cursor_down(servers_list) @@ -1046,8 +1051,11 @@ class GlancesCursesBrowser(_GlancesCurses): "Can not grab stats {0} from server (KeyError: {1})".format(c[0], e)) server_stat[c[0]] = '?' # Display alias instead of name - if c[0] == 'alias' and v[c[0]] is not None: - server_stat['name'] = v[c[0]] + try: + if c[0] == 'alias' and v[c[0]] is not None: + server_stat['name'] = v[c[0]] + except KeyError as e: + pass # Display line for server stats cpt = 0