main.py 23.7 KB
Newer Older
N
Nicolas Hennion 已提交
1 2
# -*- coding: utf-8 -*-
#
3
# This file is part of Glances.
N
Nicolas Hennion 已提交
4
#
N
nicolargo 已提交
5
# Copyright (C) 2021 Nicolargo <nicolas@nicolargo.com>
N
Nicolas Hennion 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18
#
# 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 <http://www.gnu.org/licenses/>.
A
PEP 257  
Alessio Sergi 已提交
19 20

"""Glances main class."""
N
Nicolas Hennion 已提交
21

N
Nicolas Hennion 已提交
22
import argparse
23
import sys
24
import tempfile
N
Nicolas Hennion 已提交
25

A
Alessio Sergi 已提交
26
from glances import __version__, psutil_version
27
from glances.compat import input, disable, enable
28
from glances.config import Config
29
from glances.globals import WINDOWS
30
from glances.logger import logger, LOG_FILENAME
N
Nicolas Hennion 已提交
31

N
Nicolas Hennion 已提交
32

33
class GlancesMain(object):
A
PEP 257  
Alessio Sergi 已提交
34
    """Main class to manage Glances instance."""
N
Nicolas Hennion 已提交
35

36 37
    # Default stats' minimum refresh time is 2 seconds
    DEFAULT_REFRESH_TIME = 2
N
Nicolas Hennion 已提交
38
    # Set the default cache lifetime to 1 second (only for server)
A
Alessio Sergi 已提交
39
    cached_time = 1
N
Nicolas Hennion 已提交
40 41 42 43
    # By default, Glances is ran in standalone mode (no client/server)
    client_tag = False
    # Server TCP port number (default is 61209)
    server_port = 61209
N
Nicolas Hennion 已提交
44 45
    # Web Server TCP port number (default is 61208)
    web_server_port = 61208
N
Nicolas Hennion 已提交
46 47 48 49
    # Default username/password for client/server mode
    username = "glances"
    password = ""

50 51 52 53 54 55
    # Examples of use
    example_of_use = """
Examples of use:
  Monitor local machine (standalone mode):
    $ glances

56 57 58
  Display all Glances modules (plugins and exporters) and exit:
    $ glances --module-list

A
RESTful  
Alessio Sergi 已提交
59
  Monitor local machine with the Web interface and start RESTful server:
60 61 62
    $ glances -w
    Glances web server started on http://0.0.0.0:61208/

A
RESTful  
Alessio Sergi 已提交
63
  Only start RESTful API (without the WebUI):
64 65 66
    $ glances -w --disable-webui
    Glances API available on http://0.0.0.0:61208/api/

67
  Monitor local machine and export stats to a CSV file (standalone mode):
68
    $ glances --export csv --export-csv-file /tmp/glances.csv
69

N
nicolargo 已提交
70
  Monitor local machine and export stats to a InfluxDB server with 5s refresh rate (standalone mode):
71
    $ glances -t 5 --export influxdb
72

M
Michael J. Cohen 已提交
73
  Start a Glances XML-RPC server (server mode):
74 75
    $ glances -s

M
Michael J. Cohen 已提交
76
  Connect Glances to a Glances XML-RPC server (client mode):
77 78 79
    $ glances -c <ip_server>

  Connect Glances to a Glances server and export stats to a StatsD server (client mode):
80
    $ glances -c <ip_server> --export statsd
81 82 83

  Start the client browser (browser mode):
    $ glances --browser
84

85 86 87 88 89
  Display stats to stdout (one stat per line):
    $ glances --stdout now,cpu.user,mem.used,load

  Display CSV stats to stdout (all stats in one line):
    $ glances --stdout-csv now,cpu.user,mem.used,load
90

91
  Disable some plugins (comma separated list):
92
    $ glances --disable-plugin network,ports
93 94 95

  Enable some plugins (comma separated list):
    $ glances --enable-plugin sensors
96
"""
N
Nicolargo 已提交
97

N
Nicolas Hennion 已提交
98
    def __init__(self):
A
Alessio Sergi 已提交
99
        """Manage the command line arguments."""
100
        # Read the command line arguments
A
Alessio Sergi 已提交
101 102 103 104
        self.args = self.parse_args()

    def init_args(self):
        """Init all the command line arguments."""
105
        version = 'Glances v{} with PsUtil v{}\nLog file: {}'.format(__version__, psutil_version, LOG_FILENAME)
106
        parser = argparse.ArgumentParser(
A
Alessio Sergi 已提交
107
            prog='glances',
N
Nicolargo 已提交
108 109 110
            conflict_handler='resolve',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog=self.example_of_use)
111
        parser.add_argument(
112
            '-V', '--version', action='version', version=version)
N
Nicolas Hennion 已提交
113
        parser.add_argument('-d', '--debug', action='store_true', default=False,
A
Alessio Sergi 已提交
114
                            dest='debug', help='enable debug mode')
A
Alessio Sergi 已提交
115
        parser.add_argument('-C', '--config', dest='conf_file',
A
Alessio Sergi 已提交
116
                            help='path to the configuration file')
117
        # Disable plugin
N
nicolargo 已提交
118 119 120 121
        parser.add_argument('--modules-list', '--module-list',
                            action='store_true', default=False,
                            dest='modules_list',
                            help='display modules (plugins & exports) list and exit')
122
        parser.add_argument('--disable-plugin', '--disable-plugins', dest='disable_plugin',
123
                            help='disable plugin (comma separed list)')
124 125
        parser.add_argument('--enable-plugin', '--enable-plugins', dest='enable_plugin',
                            help='enable plugin (comma separed list)')
N
nicolargo 已提交
126 127
        parser.add_argument('--disable-process', action='store_true', default=False,
                            dest='disable_process', help='disable process module')
128
        # Enable or disable option
129 130
        parser.add_argument('--disable-webui', action='store_true', default=False,
                            dest='disable_webui', help='disable the Web Interface')
131 132 133
        parser.add_argument('--light', '--enable-light', action='store_true',
                            default=False, dest='enable_light',
                            help='light mode for Curses UI (disable all but top menu)')
N
nicolargo 已提交
134 135 136 137
        parser.add_argument('-0', '--disable-irix', action='store_true', default=False,
                            dest='disable_irix', help='task\'s cpu usage will be divided by the total number of CPUs')
        parser.add_argument('-1', '--percpu', action='store_true', default=False,
                            dest='percpu', help='start Glances in per CPU mode')
138
        parser.add_argument('-2', '--disable-left-sidebar', action='store_true',
A
Alessio Sergi 已提交
139
                            default=False, dest='disable_left_sidebar',
140
                            help='disable network, disk I/O, FS and sensors modules')
N
nicolargo 已提交
141 142 143 144 145 146 147
        parser.add_argument('-3', '--disable-quicklook', action='store_true', default=False,
                            dest='disable_quicklook', help='disable quick look module')
        parser.add_argument('-4', '--full-quicklook', action='store_true', default=False,
                            dest='full_quicklook', help='disable all but quick look and load')
        parser.add_argument('-5', '--disable-top', action='store_true',
                            default=False, dest='disable_top',
                            help='disable top menu (QL, CPU, MEM, SWAP and LOAD)')
148 149
        parser.add_argument('-6', '--meangpu', action='store_true', default=False,
                            dest='meangpu', help='start Glances in mean GPU mode')
N
Nicolargo 已提交
150 151
        parser.add_argument('--disable-history', action='store_true', default=False,
                            dest='disable_history', help='disable stats history')
152
        parser.add_argument('--disable-bold', action='store_true', default=False,
A
Alessio Sergi 已提交
153
                            dest='disable_bold', help='disable bold mode in the terminal')
154
        parser.add_argument('--disable-bg', action='store_true', default=False,
155
                            dest='disable_bg', help='disable background colors in the terminal')
156 157
        parser.add_argument('--enable-irq', action='store_true', default=False,
                            dest='enable_irq', help='enable IRQ module'),
N
Nicolargo 已提交
158
        parser.add_argument('--enable-process-extended', action='store_true', default=False,
A
Alessio Sergi 已提交
159
                            dest='enable_process_extended', help='enable extended stats on top process')
160
        # Export modules feature
161 162 163 164 165 166
        parser.add_argument('--export', dest='export',
                            help='enable export module (comma separed list)')
        parser.add_argument('--export-csv-file',
                            default='./glances.csv',
                            dest='export_csv_file',
                            help='file path for CSV exporter')
167 168
        parser.add_argument('--export-csv-overwrite', action='store_true', default=False,
                            dest='export_csv_overwrite', help='overwrite existing CSV file')
169 170 171 172
        parser.add_argument('--export-json-file',
                            default='./glances.json',
                            dest='export_json_file',
                            help='file path for JSON exporter')
N
nicolargo 已提交
173
        parser.add_argument('--export-graph-path',
174
                            default=tempfile.gettempdir(),
N
nicolargo 已提交
175 176
                            dest='export_graph_path',
                            help='Folder for Graph exporter')
N
Nicolargo 已提交
177 178
        # Client/Server option
        parser.add_argument('-c', '--client', dest='client',
A
Alessio Sergi 已提交
179
                            help='connect to a Glances server by IPv4/IPv6 address or hostname')
N
Nicolargo 已提交
180
        parser.add_argument('-s', '--server', action='store_true', default=False,
A
Alessio Sergi 已提交
181
                            dest='server', help='run Glances in server mode')
182
        parser.add_argument('--browser', action='store_true', default=False,
A
Alessio Sergi 已提交
183
                            dest='browser', help='start the client browser (list of servers)')
184
        parser.add_argument('--disable-autodiscover', action='store_true', default=False,
A
Alessio Sergi 已提交
185
                            dest='disable_autodiscover', help='disable autodiscover feature')
186
        parser.add_argument('-p', '--port', default=None, type=int, dest='port',
187
                            help='define the client/server TCP port [default: {}]'.format(self.server_port))
N
Nicolargo 已提交
188
        parser.add_argument('-B', '--bind', default='0.0.0.0', dest='bind_address',
A
Alessio Sergi 已提交
189
                            help='bind server to the given IPv4/IPv6 address or hostname')
190 191
        parser.add_argument('--username', action='store_true', default=False, dest='username_prompt',
                            help='define a client/server username')
A
Alessio Sergi 已提交
192
        parser.add_argument('--password', action='store_true', default=False, dest='password_prompt',
A
Alessio Sergi 已提交
193
                            help='define a client/server password')
194 195
        parser.add_argument('-u', dest='username_used',
                            help='use the given client/server username')
196
        parser.add_argument('--snmp-community', default='public', dest='snmp_community',
A
Alessio Sergi 已提交
197
                            help='SNMP community')
A
Alessio Sergi 已提交
198
        parser.add_argument('--snmp-port', default=161, type=int,
A
Alessio Sergi 已提交
199
                            dest='snmp_port', help='SNMP port')
N
Nicolargo 已提交
200
        parser.add_argument('--snmp-version', default='2c', dest='snmp_version',
A
Alessio Sergi 已提交
201
                            help='SNMP version (1, 2c or 3)')
N
Nicolargo 已提交
202
        parser.add_argument('--snmp-user', default='private', dest='snmp_user',
A
Alessio Sergi 已提交
203
                            help='SNMP username (only for SNMPv3)')
N
Nicolargo 已提交
204
        parser.add_argument('--snmp-auth', default='password', dest='snmp_auth',
A
Alessio Sergi 已提交
205
                            help='SNMP authentication key (only for SNMPv3)')
206
        parser.add_argument('--snmp-force', action='store_true', default=False,
A
Alessio Sergi 已提交
207
                            dest='snmp_force', help='force SNMP mode')
208
        parser.add_argument('-t', '--time', default=self.DEFAULT_REFRESH_TIME, type=float,
N
nicolargo 已提交
209 210
                            dest='time', help='set minumum refresh rate in seconds [default: {} sec]'.format(
                                self.DEFAULT_REFRESH_TIME))
A
Alessio Sergi 已提交
211
        parser.add_argument('-w', '--webserver', action='store_true', default=False,
A
Alessio Sergi 已提交
212
                            dest='webserver', help='run Glances in web server mode (bottle needed)')
213
        parser.add_argument('--cached-time', default=self.cached_time, type=int,
N
nicolargo 已提交
214 215
                            dest='cached_time', help='set the server cache time [default: {} sec]'.format(
                                self.cached_time))
N
nicolargo 已提交
216 217
        parser.add_argument('--open-web-browser', action='store_true', default=False,
                            dest='open_web_browser', help='try to open the Web UI in the default Web browser')
218
        # Display options
N
nicolargo 已提交
219 220
        parser.add_argument('-q', '--quiet', default=False, action='store_true',
                            dest='quiet', help='do not display the curses interface')
N
Nicolargo 已提交
221
        parser.add_argument('-f', '--process-filter', default=None, type=str,
A
Alessio Sergi 已提交
222
                            dest='process_filter', help='set the process filter pattern (regular expression)')
223
        parser.add_argument('--process-short-name', action='store_true', default=True,
A
Alessio Sergi 已提交
224
                            dest='process_short_name', help='force short name for processes name')
225 226
        parser.add_argument('--process-long-name', action='store_false', default=False,
                            dest='process_short_name', help='force long name for processes name')
227
        parser.add_argument('--stdout', default=None,
228 229 230
                            dest='stdout', help='display stats to stdout, one stat per line (comma separated list of plugins/plugins.attribute)')
        parser.add_argument('--stdout-csv', default=None,
                            dest='stdout_csv', help='display stats to stdout, csv format (comma separated list of plugins/plugins.attribute)')
231 232
        parser.add_argument('--issue', default=None, action='store_true',
                            dest='stdout_issue', help='test all plugins and exit (please copy/paste the output if you open an issue)')
N
nicolargo 已提交
233 234
        parser.add_argument('--api-doc', default=None, action='store_true',
                            dest='stdout_apidoc', help='display fields descriptions')
A
Alessio Sergi 已提交
235
        if not WINDOWS:
236
            parser.add_argument('--hide-kernel-threads', action='store_true', default=False,
237
                                dest='no_kernel_threads', help='hide kernel threads in process list (not available on Windows)')
N
Nicolargo 已提交
238
        parser.add_argument('-b', '--byte', action='store_true', default=False,
A
Alessio Sergi 已提交
239
                            dest='byte', help='display network rate in byte per second')
240 241
        parser.add_argument('--diskio-show-ramfs', action='store_true', default=False,
                            dest='diskio_show_ramfs', help='show RAM Fs in the DiskIO plugin')
242 243
        parser.add_argument('--diskio-iops', action='store_true', default=False,
                            dest='diskio_iops', help='show IO per second in the DiskIO plugin')
N
nicolargo 已提交
244 245
        parser.add_argument('--fahrenheit', action='store_true', default=False,
                            dest='fahrenheit', help='display temperature in Fahrenheit (default is Celsius)')
A
Alessio Sergi 已提交
246
        parser.add_argument('--fs-free-space', action='store_true', default=False,
A
Alessio Sergi 已提交
247
                            dest='fs_free_space', help='display FS free space instead of used')
248
        parser.add_argument('--sparkline', action='store_true', default=False,
N
nicolargo 已提交
249
                            dest='sparkline', help='display sparklines instead of bar in the curses interface')
N
Nicolargo 已提交
250
        parser.add_argument('--theme-white', action='store_true', default=False,
A
Alessio Sergi 已提交
251
                            dest='theme_white', help='optimize display colors for white background')
252 253 254
        # Globals options
        parser.add_argument('--disable-check-update', action='store_true', default=False,
                            dest='disable_check_update', help='disable online Glances version ckeck')
255 256 257
        parser.add_argument('--strftime', dest='strftime_format', default='',
                            help='strftime format string for displaying current date in standalone mode')

A
Alessio Sergi 已提交
258 259 260 261 262 263
        return parser

    def parse_args(self):
        """Parse command line arguments."""
        args = self.init_args().parse_args()

264
        # Load the configuration file, if it exists
265 266
        # This function should be called after the parse_args
        # because the configration file path can be defined
A
Alessio Sergi 已提交
267 268
        self.config = Config(args.conf_file)

N
Nicolas Hennion 已提交
269 270 271 272
        # Debug mode
        if args.debug:
            from logging import DEBUG
            logger.setLevel(DEBUG)
273 274 275
        else:
            from warnings import simplefilter
            simplefilter("ignore")
N
Nicolas Hennion 已提交
276

277 278 279 280 281 282 283 284 285
        # Plugins refresh rate
        if self.config.has_section('global'):
            global_refresh = self.config.get_float_value('global',
                                                         'refresh',
                                                         default=self.DEFAULT_REFRESH_TIME)
        if args.time == self.DEFAULT_REFRESH_TIME:
            args.time = global_refresh
        logger.debug('Global refresh rate is set to {} seconds'.format(args.time))

286
        # Plugins disable/enable
287 288 289 290 291 292 293
        # Allow users to disable plugins from the glances.conf (issue #1378)
        for s in self.config.sections():
            if self.config.has_section(s) \
               and (self.config.get_bool_value(s, 'disable', False)):
                disable(args, s)
                logger.debug('{} disabled by the configuration file'.format(s))
        # The configuration key can be overwrite from the command line
294 295 296
        if args.disable_plugin is not None:
            for p in args.disable_plugin.split(','):
                disable(args, p)
297 298 299
        if args.enable_plugin is not None:
            for p in args.enable_plugin.split(','):
                enable(args, p)
300

301 302 303 304 305
        # Exporters activation
        if args.export is not None:
            for p in args.export.split(','):
                setattr(args, 'export_' + p, True)

306
        # Client/server Port
307 308 309 310
        if args.port is None:
            if args.webserver:
                args.port = self.web_server_port
            else:
311
                args.port = self.server_port
N
nicolargo 已提交
312
        # Port in the -c URI #996
313 314
        if args.client is not None:
            args.client, args.port = (x if x else y for (x, y) in zip(args.client.partition(':')[::2], (args.client, args.port)))
315

316 317 318 319
        # Autodiscover
        if args.disable_autodiscover:
            logger.info("Auto discover mode is disabled")

320
        # In web server mode
A
Alessio Sergi 已提交
321
        if args.webserver:
322
            args.process_short_name = True
N
Nicolas Hennion 已提交
323 324

        # Server or client login/password
325 326 327 328 329
        if args.username_prompt:
            # Every username needs a password
            args.password_prompt = True
            # Prompt username
            if args.server:
N
nicolargo 已提交
330 331
                args.username = self.__get_username(
                    description='Define the Glances server username: ')
332
            elif args.webserver:
N
nicolargo 已提交
333 334
                args.username = self.__get_username(
                    description='Define the Glances webserver username: ')
335
            elif args.client:
N
nicolargo 已提交
336 337
                args.username = self.__get_username(
                    description='Enter the Glances server username: ')
338
        else:
339 340 341 342 343 344
            if args.username_used:
                # A username has been set using the -u option ?
                args.username = args.username_used
            else:
                # Default user name is 'glances'
                args.username = self.username
345

346
        if args.password_prompt or args.username_used:
N
Nicolargo 已提交
347
            # Interactive or file password
A
Alessio Sergi 已提交
348
            if args.server:
N
Nicolas Hennion 已提交
349
                args.password = self.__get_password(
N
nicolargo 已提交
350 351
                    description='Define the Glances server password ({} username): '.format(
                        args.username),
352 353
                    confirm=True,
                    username=args.username)
354 355
            elif args.webserver:
                args.password = self.__get_password(
N
nicolargo 已提交
356 357
                    description='Define the Glances webserver password ({} username): '.format(
                        args.username),
358 359
                    confirm=True,
                    username=args.username)
A
Alessio Sergi 已提交
360
            elif args.client:
N
Nicolas Hennion 已提交
361
                args.password = self.__get_password(
N
nicolargo 已提交
362 363
                    description='Enter the Glances server password ({} username): '.format(
                        args.username),
364 365
                    clear=True,
                    username=args.username)
N
Nicolas Hennion 已提交
366 367 368 369
        else:
            # Default is no password
            args.password = self.password

A
Alessio Sergi 已提交
370 371 372 373 374 375 376
        # By default help is hidden
        args.help_tag = False

        # Display Rx and Tx, not the sum for the network
        args.network_sum = False
        args.network_cumul = False

377 378 379 380
        # Manage light mode
        if args.enable_light:
            logger.info("Light mode is on")
            args.disable_left_sidebar = True
381 382 383 384
            disable(args, 'process')
            disable(args, 'alert')
            disable(args, 'amps')
            disable(args, 'docker')
385

386 387
        # Manage full quicklook option
        if args.full_quicklook:
388 389 390 391 392 393
            logger.info("Full quicklook mode")
            enable(args, 'quicklook')
            disable(args, 'cpu')
            disable(args, 'mem')
            disable(args, 'memswap')
            enable(args, 'load')
394 395 396 397

        # Manage disable_top option
        if args.disable_top:
            logger.info("Disable top menu")
398 399 400 401 402
            disable(args, 'quicklook')
            disable(args, 'cpu')
            disable(args, 'mem')
            disable(args, 'memswap')
            disable(args, 'load')
403

404 405 406 407
        # Init the generate_graph tag
        # Should be set to True to generate graphs
        args.generate_graph = False

408 409 410
        # Control parameter and exit if it is not OK
        self.args = args

411
        # Export is only available in standalone or client mode (issue #614)
412
        export_tag = self.args.export is not None and any(self.args.export)
413 414 415
        if WINDOWS and export_tag:
            # On Windows, export is possible but only in quiet mode
            # See issue #1038
416
            logger.info("On Windows OS, export disable the Web interface")
417 418
            self.args.quiet = True
            self.args.webserver = False
419 420
        elif not (self.is_standalone() or self.is_client()) and export_tag:
            logger.critical("Export is only available in standalone or client mode")
421 422
            sys.exit(2)

423
        # Filter is only available in standalone mode
424
        if args.process_filter is not None and not self.is_standalone():
N
nicolargo 已提交
425 426
            logger.critical(
                "Process filter is only available in standalone mode")
427 428
            sys.exit(2)

429
        # Disable HDDTemp if sensors are disabled
430 431
        if getattr(args, 'disable_sensors', False):
            disable(args, 'hddtemp')
432 433
            logger.debug("Sensors and HDDTemp are disabled")

434 435 436 437 438 439 440
        # Let the plugins known the Glances mode
        self.args.is_standalone = self.is_standalone()
        self.args.is_client = self.is_client()
        self.args.is_client_browser = self.is_client_browser()
        self.args.is_server = self.is_server()
        self.args.is_webserver = self.is_webserver()

N
Nicolas Hennion 已提交
441
        return args
N
Nicolas Hennion 已提交
442

N
Nicolas Hennion 已提交
443
    def is_standalone(self):
A
PEP 257  
Alessio Sergi 已提交
444
        """Return True if Glances is running in standalone mode."""
445 446 447 448
        return (not self.args.client and
                not self.args.browser and
                not self.args.server and
                not self.args.webserver)
N
Nicolas Hennion 已提交
449 450

    def is_client(self):
A
PEP 257  
Alessio Sergi 已提交
451
        """Return True if Glances is running in client mode."""
452
        return (self.args.client or self.args.browser) and not self.args.server
453

454 455
    def is_client_browser(self):
        """Return True if Glances is running in client browser mode."""
456
        return self.args.browser and not self.args.server
N
Nicolas Hennion 已提交
457 458

    def is_server(self):
A
PEP 257  
Alessio Sergi 已提交
459
        """Return True if Glances is running in server mode."""
460
        return not self.args.client and self.args.server
N
Nicolas Hennion 已提交
461

462
    def is_webserver(self):
A
PEP 257  
Alessio Sergi 已提交
463
        """Return True if Glances is running in Web server mode."""
464
        return not self.args.client and self.args.webserver
N
Nicolas Hennion 已提交
465

466
    def get_config(self):
A
PEP 257  
Alessio Sergi 已提交
467
        """Return configuration file object."""
468
        return self.config
N
Nicolas Hennion 已提交
469 470

    def get_args(self):
A
PEP 257  
Alessio Sergi 已提交
471
        """Return the arguments."""
A
Alessio Sergi 已提交
472
        return self.args
473 474 475 476 477 478

    def get_mode(self):
        """Return the mode."""
        return self.mode

    def __get_username(self, description=''):
479
        """Read an username from the command line."""
480 481
        return input(description)

482 483
    def __get_password(self, description='',
                       confirm=False, clear=False, username='glances'):
484 485 486 487 488 489 490 491
        """Read a password from the command line.

        - if confirm = True, with confirmation
        - if clear = True, plain (clear password)
        """
        from glances.password import GlancesPassword
        password = GlancesPassword(username=username)
        return password.get_password(description, confirm, clear)