main.py 24.0 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.processes import sort_processes_key_list
31
from glances.logger import logger, LOG_FILENAME
N
Nicolas Hennion 已提交
32

N
Nicolas Hennion 已提交
33

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

37 38
    # Default stats' minimum refresh time is 2 seconds
    DEFAULT_REFRESH_TIME = 2
N
Nicolas Hennion 已提交
39
    # Set the default cache lifetime to 1 second (only for server)
A
Alessio Sergi 已提交
40
    cached_time = 1
N
Nicolas Hennion 已提交
41 42 43 44
    # 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 已提交
45 46
    # Web Server TCP port number (default is 61208)
    web_server_port = 61208
N
Nicolas Hennion 已提交
47 48 49 50
    # Default username/password for client/server mode
    username = "glances"
    password = ""

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

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

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

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

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

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

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

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

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

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

86 87 88 89 90
  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
91

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

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

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

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

A
Alessio Sergi 已提交
263 264 265 266 267 268
        return parser

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

269
        # Load the configuration file, if it exists
270 271
        # This function should be called after the parse_args
        # because the configration file path can be defined
A
Alessio Sergi 已提交
272 273
        self.config = Config(args.conf_file)

N
Nicolas Hennion 已提交
274 275 276 277
        # Debug mode
        if args.debug:
            from logging import DEBUG
            logger.setLevel(DEBUG)
278 279 280
        else:
            from warnings import simplefilter
            simplefilter("ignore")
N
Nicolas Hennion 已提交
281

282 283 284 285 286 287 288 289 290
        # 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))

291
        # Plugins disable/enable
292 293 294 295 296 297 298
        # 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
299 300 301
        if args.disable_plugin is not None:
            for p in args.disable_plugin.split(','):
                disable(args, p)
302 303 304
        if args.enable_plugin is not None:
            for p in args.enable_plugin.split(','):
                enable(args, p)
305

306 307 308 309 310
        # Exporters activation
        if args.export is not None:
            for p in args.export.split(','):
                setattr(args, 'export_' + p, True)

311
        # Client/server Port
312 313 314 315
        if args.port is None:
            if args.webserver:
                args.port = self.web_server_port
            else:
316
                args.port = self.server_port
N
nicolargo 已提交
317
        # Port in the -c URI #996
318 319
        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)))
320

321 322 323 324
        # Autodiscover
        if args.disable_autodiscover:
            logger.info("Auto discover mode is disabled")

325
        # In web server mode
A
Alessio Sergi 已提交
326
        if args.webserver:
327
            args.process_short_name = True
N
Nicolas Hennion 已提交
328 329

        # Server or client login/password
330 331 332 333 334
        if args.username_prompt:
            # Every username needs a password
            args.password_prompt = True
            # Prompt username
            if args.server:
N
nicolargo 已提交
335 336
                args.username = self.__get_username(
                    description='Define the Glances server username: ')
337
            elif args.webserver:
N
nicolargo 已提交
338 339
                args.username = self.__get_username(
                    description='Define the Glances webserver username: ')
340
            elif args.client:
N
nicolargo 已提交
341 342
                args.username = self.__get_username(
                    description='Enter the Glances server username: ')
343
        else:
344 345 346 347 348 349
            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
350

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

A
Alessio Sergi 已提交
375 376 377 378 379 380 381
        # 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

382 383 384 385
        # Manage light mode
        if args.enable_light:
            logger.info("Light mode is on")
            args.disable_left_sidebar = True
386 387 388 389
            disable(args, 'process')
            disable(args, 'alert')
            disable(args, 'amps')
            disable(args, 'docker')
390

391 392
        # Manage full quicklook option
        if args.full_quicklook:
393 394 395 396 397 398
            logger.info("Full quicklook mode")
            enable(args, 'quicklook')
            disable(args, 'cpu')
            disable(args, 'mem')
            disable(args, 'memswap')
            enable(args, 'load')
399 400 401 402

        # Manage disable_top option
        if args.disable_top:
            logger.info("Disable top menu")
403 404 405 406 407
            disable(args, 'quicklook')
            disable(args, 'cpu')
            disable(args, 'mem')
            disable(args, 'memswap')
            disable(args, 'load')
408

409 410 411 412
        # Init the generate_graph tag
        # Should be set to True to generate graphs
        args.generate_graph = False

413 414 415
        # Control parameter and exit if it is not OK
        self.args = args

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

428
        # Filter is only available in standalone mode
429
        if args.process_filter is not None and not self.is_standalone():
N
nicolargo 已提交
430 431
            logger.critical(
                "Process filter is only available in standalone mode")
432 433
            sys.exit(2)

434
        # Disable HDDTemp if sensors are disabled
435 436
        if getattr(args, 'disable_sensors', False):
            disable(args, 'hddtemp')
437 438
            logger.debug("Sensors and HDDTemp are disabled")

439 440 441 442 443 444 445
        # 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 已提交
446
        return args
N
Nicolas Hennion 已提交
447

N
Nicolas Hennion 已提交
448
    def is_standalone(self):
A
PEP 257  
Alessio Sergi 已提交
449
        """Return True if Glances is running in standalone mode."""
450 451 452 453
        return (not self.args.client and
                not self.args.browser and
                not self.args.server and
                not self.args.webserver)
N
Nicolas Hennion 已提交
454 455

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

459 460
    def is_client_browser(self):
        """Return True if Glances is running in client browser mode."""
461
        return self.args.browser and not self.args.server
N
Nicolas Hennion 已提交
462 463

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

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

471
    def get_config(self):
A
PEP 257  
Alessio Sergi 已提交
472
        """Return configuration file object."""
473
        return self.config
N
Nicolas Hennion 已提交
474 475

    def get_args(self):
A
PEP 257  
Alessio Sergi 已提交
476
        """Return the arguments."""
A
Alessio Sergi 已提交
477
        return self.args
478 479 480 481 482 483

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

    def __get_username(self, description=''):
484
        """Read an username from the command line."""
485 486
        return input(description)

487 488
    def __get_password(self, description='',
                       confirm=False, clear=False, username='glances'):
489 490 491 492 493 494 495 496
        """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)