Refactor the Cloud plugin, disable it by default in the default configuration file - Related to #2279

This commit is contained in:
nicolargo 2023-03-11 11:01:29 +01:00
parent a798d10ab1
commit d28a696fc1
9 changed files with 544 additions and 583 deletions

View File

@ -263,6 +263,11 @@ disable=False
#folder_3_path=/nonexisting
#folder_4_path=/root
[cloud]
# Documentation: https://glances.readthedocs.io/en/stable/aoa/cloud.html
# This plugin is disabled by default
disable=True
[raid]
# Documentation: https://glances.readthedocs.io/en/stable/aoa/raid.html
# This plugin is disabled by default

BIN
docs/_static/cloud.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

15
docs/aoa/cloud.rst Normal file
View File

@ -0,0 +1,15 @@
.. _cloud:
CLOUD
=====
This plugin diplays information about the cloud provider if your host is running on OpenStack.
The plugin use the standard OpenStack `metadata`_ service to retrieve the information.
This plugin is disable by default, please use the --enable-plugin cloud option
to enable it.
.. image:: ../_static/cloud.png
.. _metadata: https://docs.openstack.org/nova/latest/user/metadata.html

View File

@ -34,6 +34,7 @@ Legend:
fs
irq
folders
cloud
raid
smart
sensors

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "GLANCES" "1" "Jan 30, 2023" "3.4.0_beta1" "Glances"
.TH "GLANCES" "1" "Mar 11, 2023" "3.4.0_beta1" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS

View File

@ -16,12 +16,12 @@ export default {
return this.data.stats['cloud'];
},
provider() {
return this.stats['ami-id'] !== undefined ? 'AWS EC2' : null;
return this.stats['id'] !== undefined ? `${stats['platform']}` : null;
},
instance() {
const { stats } = this;
return this.stats['ami-id'] !== undefined
? `${stats['instance-type']} instance ${stats['instance-id']} (${stats['reggion']})`
return this.stats['id'] !== undefined
? `${stats['type']} instance ${stats['name']} (${stats['region']})`
: null;
}
}

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,8 @@
"""Cloud plugin.
Supported Cloud API:
- OpenStack meta data (class ThreadOpenStack, see below): AWS, OVH...
- OpenStack meta data (class ThreadOpenStack) - Vanilla OpenStack
- OpenStackEC2 meta data (class ThreadOpenStackEC2) - Amazon EC2 compatible
"""
import threading
@ -53,13 +54,16 @@ class Plugin(GlancesPlugin):
# Init thread to grab OpenStack stats asynchronously
self.OPENSTACK = ThreadOpenStack()
self.OPENSTACKEC2 = ThreadOpenStackEC2()
# Run the thread
self.OPENSTACK.start()
self.OPENSTACKEC2.start()
def exit(self):
"""Overwrite the exit method to close threads."""
self.OPENSTACK.stop()
self.OPENSTACKEC2.stop()
# Call the father class
super(Plugin, self).exit()
@ -80,12 +84,15 @@ class Plugin(GlancesPlugin):
# Update the stats
if self.input_method == 'local':
stats = self.OPENSTACK.stats
if not stats:
stats = self.OPENSTACKEC2.stats
# Example:
# Uncomment to test on physical computer
# stats = {'ami-id': 'ami-id',
# 'instance-id': 'instance-id',
# 'instance-type': 'instance-type',
# 'region': 'placement/availability-zone'}
# Uncomment to test on physical computer (only for test purpose)
# stats = {'id': 'ami-id',
# 'name': 'My VM',
# 'type': 'Gold',
# 'region': 'France',
# 'platform': 'OpenStack'}
# Update the stats
self.stats = stats
@ -101,13 +108,14 @@ class Plugin(GlancesPlugin):
return ret
# Generate the output
if 'instance-type' in self.stats and 'instance-id' in self.stats and 'region' in self.stats:
msg = 'Cloud '
ret.append(self.curse_add_line(msg, "TITLE"))
msg = '{} instance {} ({})'.format(
self.stats['instance-type'], self.stats['instance-id'], self.stats['region']
)
ret.append(self.curse_add_line(msg))
msg = self.stats.get('platform', 'Unknown')
ret.append(self.curse_add_line(msg, "TITLE"))
msg = ' {} instance {} ({})'.format(
self.stats.get('type', 'Unknown'),
self.stats.get('name', 'Unknown'),
self.stats.get('region', 'Unknown')
)
ret.append(self.curse_add_line(msg))
# Return the message with decoration
# logger.info(ret)
@ -121,13 +129,19 @@ class ThreadOpenStack(threading.Thread):
stats is a dict
"""
# The metadata service provides a way for instances to retrieve
# instance-specific data via a REST API. Instances access this
# service at 169.254.169.254 or at fe80::a9fe:a9fe.
# All types of metadata, be it user-, nova- or vendor-provided,
# can be accessed via this service.
# https://docs.openstack.org/nova/latest/user/metadata-service.html
OPENSTACK_API_URL = 'http://169.254.169.254/latest/meta-data'
OPENSTACK_PLATFORM = "OpenStack"
OPENSTACK_API_URL = 'http://169.254.169.254/openstack/latest/meta-data'
OPENSTACK_API_METADATA = {
'ami-id': 'ami-id',
'instance-id': 'instance-id',
'instance-type': 'instance-type',
'region': 'placement/availability-zone',
'id': 'project_id',
'name': 'name',
'type': 'meta/role',
'region': 'availability_zone',
}
def __init__(self):
@ -159,6 +173,9 @@ class ThreadOpenStack(threading.Thread):
else:
if r.ok:
self._stats[k] = to_ascii(r.content)
else:
# No break during the loop, so we can set the platform
self._stats['platform'] = self.OPENSTACK_PLATFORM
return True
@ -180,3 +197,26 @@ class ThreadOpenStack(threading.Thread):
def stopped(self):
"""Return True is the thread is stopped."""
return self._stopper.is_set()
class ThreadOpenStackEC2(ThreadOpenStack):
"""
Specific thread to grab OpenStack EC2 (Amazon cloud) stats.
stats is a dict
"""
# The metadata service provides a way for instances to retrieve
# instance-specific data via a REST API. Instances access this
# service at 169.254.169.254 or at fe80::a9fe:a9fe.
# All types of metadata, be it user-, nova- or vendor-provided,
# can be accessed via this service.
# https://docs.openstack.org/nova/latest/user/metadata-service.html
OPENSTACK_PLATFORM = "Amazon EC2"
OPENSTACK_API_URL = 'http://169.254.169.254/latest/meta-data'
OPENSTACK_API_METADATA = {
'id': 'ami-id',
'name': 'instance-id',
'type': 'instance-type',
'region': 'placement/availability-zone',
}