Test Failed
Push — master ( ae3125...7a2ee5 )
by Nicolas
02:38
created

glances.main.GlancesMain.init_glances()   C

Complexity

Conditions 10

Size

Total Lines 58
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 27
nop 2
dl 0
loc 58
rs 5.9999
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like glances.main.GlancesMain.init_glances() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#
2
# This file is part of Glances.
3
#
4
# SPDX-FileCopyrightText: 2024 Nicolas Hennion <[email protected]>
5
#
6
# SPDX-License-Identifier: LGPL-3.0-only
7
#
8
9
"""Glances main class."""
10
11
import argparse
12
import sys
13
import tempfile
14
from logging import DEBUG
15
from warnings import simplefilter
16
17
from glances import __apiversion__, __version__, psutil_version
18
from glances.config import Config
19
from glances.globals import WINDOWS, disable, enable
20
from glances.logger import LOG_FILENAME, logger
21
from glances.processes import sort_processes_stats_list
22
23
24
class GlancesMain:
25
    """Main class to manage Glances instance."""
26
27
    # Default stats' minimum refresh time is 2 seconds
28
    DEFAULT_REFRESH_TIME = 2
29
    # Set the default cache lifetime to 1 second (only for server)
30
    cached_time = 1
31
    # By default, Glances is ran in standalone mode (no client/server)
32
    client_tag = False
33
    # Server TCP port number (default is 61209)
34
    server_port = 61209
35
    # Web Server TCP port number (default is 61208)
36
    web_server_port = 61208
37
    # Default username/password for client/server mode
38
    username = "glances"
39
    password = ""
40
41
    # Examples of use
42
    example_of_use = """
43
Examples of use:
44
  Monitor local machine (standalone mode):
45
    $ glances
46
47
  Display all Glances modules (plugins and exporters) and exit:
48
    $ glances --module-list
49
50
  Monitor local machine with the Web interface and start RESTful server:
51
    $ glances -w
52
    Glances web server started on http://0.0.0.0:61208/
53
54
  Only start RESTful API (without the WebUI):
55
    $ glances -w --disable-webui
56
    Glances API available on http://0.0.0.0:61208/api/
57
58
  Monitor local machine and export stats to a CSV file (standalone mode):
59
    $ glances --export csv --export-csv-file /tmp/glances.csv
60
61
  Monitor local machine and export stats to a InfluxDB server with 5s refresh rate (standalone mode):
62
    $ glances -t 5 --export influxdb
63
64
  Start a Glances XML-RPC server (server mode):
65
    $ glances -s
66
67
  Connect Glances to a Glances XML-RPC server (client mode):
68
    $ glances -c <ip_server>
69
70
  Connect Glances to a Glances server and export stats to a StatsD server (client mode):
71
    $ glances -c <ip_server> --export statsd
72
73
  Start TUI Central Glances Browser:
74
    $ glances --browser
75
76
  Start WebUI Central Glances Browser:
77
    $ glances --browser -w
78
79
  Display stats to stdout (one stat per line, possible to go inside stats using plugin.attribute):
80
    $ glances --stdout now,cpu.user,mem.used,load
81
82
  Display JSON stats to stdout (one stats per line):
83
    $ glances --stdout-json now,cpu,mem,load
84
85
  Display CSV stats to stdout (all stats in one line):
86
    $ glances --stdout-csv now,cpu.user,mem.used,load
87
88
  Enable some plugins disabled by default (comma-separated list):
89
    $ glances --enable-plugin sensors
90
91
  Disable some plugins (comma-separated list):
92
    $ glances --disable-plugin network,ports
93
94
  Disable all plugins except some (comma-separated list):
95
    $ glances --disable-plugin all --enable-plugin cpu,mem,load
96
97
"""
98
99
    def __init__(self, args_begin_at=1):
100
        """Manage the command line arguments."""
101
        self.init_glances(args_begin_at)
102
103
    def init_glances(self, args_begin_at):
104
        """Main method to init Glances."""
105
        # Read the command line arguments or parse the one given in parameter (parser)
106
        self.args = self.parse_args(args_begin_at)
107
108
        # Load the configuration file, if it exists
109
        # This function should be called after the parse_args
110
        # because the configuration file path can be defined
111
        self.config = Config(self.args.conf_file)
112
113
        # Init Glances debug mode
114
        self.init_debug(self.args)
115
116
        # Plugins Glances refresh rate
117
        self.init_refresh_rate(self.args)
118
119
        # Manage Plugins disable/enable option
120
        self.init_plugins(self.args)
121
122
        # Init Glances client/server mode
123
        self.init_client_server(self.args)
124
125
        # Init UI mode
126
        self.init_ui_mode(self.args)
127
128
        # Init the generate_graph tag
129
        # Should be set to True to generate graphs
130
        self.args.generate_graph = False
131
132
        # Export is only available in standalone or client mode (issue #614)
133
        export_tag = self.args.export is not None and any(self.args.export)
134
        if WINDOWS and export_tag:
135
            # On Windows, export is possible but only in quiet mode
136
            # See issue #1038
137
            logger.info("On Windows OS, export disable the Web interface")
138
            self.args.quiet = True
139
            self.args.webserver = False
140
        elif not (self.is_standalone() or self.is_client()) and export_tag:
141
            logger.critical("Export is only available in standalone or client mode")
142
            sys.exit(2)
143
144
        # Filter is only available in standalone mode
145
        if not self.args.process_filter and not self.is_standalone():
146
            logger.debug("Process filter is only available in standalone mode")
147
148
        # Cursor option is only available in standalone mode
149
        if not self.args.disable_cursor and not self.is_standalone():
150
            logger.debug("Cursor is only available in standalone mode")
151
152
        # Let the plugins known the Glances mode
153
        self.args.is_standalone = self.is_standalone()
154
        self.args.is_client = self.is_client()
155
        self.args.is_client_browser = self.is_client_browser()
156
        self.args.is_server = self.is_server()
157
        self.args.is_webserver = self.is_webserver()
158
159
        # Check mode compatibility
160
        self.check_mode_compatibility()
161
162
    def version_msg(self):
163
        """Return the version message."""
164
        version = f'Glances version:\t{__version__}\n'
165
        version += f'Glances API version:\t{__apiversion__}\n'
166
        version += f'PsUtil version:\t\t{psutil_version}\n'
167
        version += f'Log file:\t\t{LOG_FILENAME}\n'
168
        return version
169
170
    def init_args(self):
171
        """Init all the command line arguments."""
172
        parser = argparse.ArgumentParser(
173
            prog='glances',
174
            conflict_handler='resolve',
175
            formatter_class=argparse.RawDescriptionHelpFormatter,
176
            epilog=self.example_of_use,
177
        )
178
        parser.add_argument('-V', '--version', action='version', version=self.version_msg())
179
        parser.add_argument('-d', '--debug', action='store_true', default=False, dest='debug', help='enable debug mode')
180
        parser.add_argument('-C', '--config', dest='conf_file', help='path to the configuration file')
181
        parser.add_argument('-P', '--plugins', dest='plugin_dir', help='path to additional plugin directory')
182
        # Disable plugin
183
        parser.add_argument(
184
            '--modules-list',
185
            '--module-list',
186
            action='store_true',
187
            default=False,
188
            dest='modules_list',
189
            help='display modules (plugins & exports) list and exit',
190
        )
191
        parser.add_argument(
192
            '--disable-plugin',
193
            '--disable-plugins',
194
            '--disable',
195
            dest='disable_plugin',
196
            help='disable plugin (comma-separated list or all). If all is used, \
197
                then you need to configure --enable-plugin.',
198
        )
199
        parser.add_argument(
200
            '--enable-plugin',
201
            '--enable-plugins',
202
            '--enable',
203
            dest='enable_plugin',
204
            help='enable plugin (comma-separated list)',
205
        )
206
        parser.add_argument(
207
            '--disable-process',
208
            action='store_true',
209
            default=False,
210
            dest='disable_process',
211
            help='disable process module',
212
        )
213
        # Enable or disable option
214
        parser.add_argument(
215
            '--disable-webui',
216
            action='store_true',
217
            default=False,
218
            dest='disable_webui',
219
            help='disable the Web Interface',
220
        )
221
        parser.add_argument(
222
            '--light',
223
            '--enable-light',
224
            action='store_true',
225
            default=False,
226
            dest='enable_light',
227
            help='light mode for Curses UI (disable all but the top menu)',
228
        )
229
        parser.add_argument(
230
            '-0',
231
            '--disable-irix',
232
            action='store_true',
233
            default=False,
234
            dest='disable_irix',
235
            help='task\'s cpu usage will be divided by the total number of CPUs',
236
        )
237
        parser.add_argument(
238
            '-1',
239
            '--percpu',
240
            '--per-cpu',
241
            action='store_true',
242
            default=False,
243
            dest='percpu',
244
            help='start Glances in per CPU mode',
245
        )
246
        parser.add_argument(
247
            '-2',
248
            '--disable-left-sidebar',
249
            action='store_true',
250
            default=False,
251
            dest='disable_left_sidebar',
252
            help='disable network, disk I/O, FS and sensors modules',
253
        )
254
        parser.add_argument(
255
            '-3',
256
            '--disable-quicklook',
257
            action='store_true',
258
            default=False,
259
            dest='disable_quicklook',
260
            help='disable quick look module',
261
        )
262
        parser.add_argument(
263
            '-4',
264
            '--full-quicklook',
265
            action='store_true',
266
            default=False,
267
            dest='full_quicklook',
268
            help='disable all but quick look and load',
269
        )
270
        parser.add_argument(
271
            '-5',
272
            '--disable-top',
273
            action='store_true',
274
            default=False,
275
            dest='disable_top',
276
            help='disable top menu (QL, CPU, MEM, SWAP and LOAD)',
277
        )
278
        parser.add_argument(
279
            '-6', '--meangpu', action='store_true', default=False, dest='meangpu', help='start Glances in mean GPU mode'
280
        )
281
        parser.add_argument(
282
            '--disable-history',
283
            action='store_true',
284
            default=False,
285
            dest='disable_history',
286
            help='disable stats history',
287
        )
288
        parser.add_argument(
289
            '--disable-bold',
290
            action='store_true',
291
            default=False,
292
            dest='disable_bold',
293
            help='disable bold mode in the terminal',
294
        )
295
        parser.add_argument(
296
            '--disable-bg',
297
            action='store_true',
298
            default=False,
299
            dest='disable_bg',
300
            help='disable background colors in the terminal',
301
        )
302
        parser.add_argument(
303
            '--enable-irq', action='store_true', default=False, dest='enable_irq', help='enable IRQ module'
304
        )
305
        parser.add_argument(
306
            '--enable-process-extended',
307
            action='store_true',
308
            default=False,
309
            dest='enable_process_extended',
310
            help='enable extended stats on top process',
311
        )
312
        parser.add_argument(
313
            '--disable-separator',
314
            action='store_false',
315
            default=True,
316
            dest='enable_separator',
317
            help='disable separator in the UI (between top and others modules)',
318
        )
319
        parser.add_argument(
320
            '--disable-cursor',
321
            action='store_true',
322
            default=False,
323
            dest='disable_cursor',
324
            help='disable cursor (process selection) in the UI',
325
        )
326
        # Sort processes list
327
        parser.add_argument(
328
            '--sort-processes',
329
            dest='sort_processes_key',
330
            choices=sort_processes_stats_list,
331
            help='Sort processes by: {}'.format(', '.join(sort_processes_stats_list)),
332
        )
333
        # Display processes list by program name and not by thread
334
        parser.add_argument(
335
            '--programs',
336
            '--program',
337
            action='store_true',
338
            default=False,
339
            dest='programs',
340
            help='Accumulate processes by program',
341
        )
342
        # Export modules feature
343
        parser.add_argument('--export', dest='export', help='enable export module (comma-separated list)')
344
        parser.add_argument(
345
            '--export-csv-file', default='./glances.csv', dest='export_csv_file', help='file path for CSV exporter'
346
        )
347
        parser.add_argument(
348
            '--export-csv-overwrite',
349
            action='store_true',
350
            default=False,
351
            dest='export_csv_overwrite',
352
            help='overwrite existing CSV file',
353
        )
354
        parser.add_argument(
355
            '--export-json-file', default='./glances.json', dest='export_json_file', help='file path for JSON exporter'
356
        )
357
        parser.add_argument(
358
            '--export-graph-path',
359
            default=tempfile.gettempdir(),
360
            dest='export_graph_path',
361
            help='Folder for Graph exporter',
362
        )
363
        parser.add_argument(
364
            '--export-process-filter',
365
            default=None,
366
            type=str,
367
            dest='export_process_filter',
368
            help='set the export process filter (comman separated list of regular expression)',
369
        )
370
        # Client/Server option
371
        parser.add_argument(
372
            '-c', '--client', dest='client', help='connect to a Glances server by IPv4/IPv6 address or hostname'
373
        )
374
        parser.add_argument(
375
            '-s', '--server', action='store_true', default=False, dest='server', help='run Glances in server mode'
376
        )
377
        parser.add_argument(
378
            '--browser',
379
            action='store_true',
380
            default=False,
381
            dest='browser',
382
            help='start TUI Central Glances Browser (use --browser -w to start WebUI Central Glances Browser)',
383
        )
384
        parser.add_argument(
385
            '--disable-autodiscover',
386
            action='store_true',
387
            default=False,
388
            dest='disable_autodiscover',
389
            help='disable autodiscover feature',
390
        )
391
        parser.add_argument(
392
            '-p',
393
            '--port',
394
            default=None,
395
            type=int,
396
            dest='port',
397
            help=f'define the client/server TCP port [default: {self.server_port}]',
398
        )
399
        parser.add_argument(
400
            '-B',
401
            '--bind',
402
            default='0.0.0.0',
403
            dest='bind_address',
404
            help='bind server to the given IPv4/IPv6 address or hostname',
405
        )
406
        parser.add_argument(
407
            '--username',
408
            action='store_true',
409
            default=False,
410
            dest='username_prompt',
411
            help='define a client/server username',
412
        )
413
        parser.add_argument(
414
            '--password',
415
            action='store_true',
416
            default=False,
417
            dest='password_prompt',
418
            help='define a client/server password',
419
        )
420
        parser.add_argument('-u', dest='username_used', help='use the given client/server username')
421
        parser.add_argument('--snmp-community', default='public', dest='snmp_community', help='SNMP community')
422
        parser.add_argument('--snmp-port', default=161, type=int, dest='snmp_port', help='SNMP port')
423
        parser.add_argument('--snmp-version', default='2c', dest='snmp_version', help='SNMP version (1, 2c or 3)')
424
        parser.add_argument('--snmp-user', default='private', dest='snmp_user', help='SNMP username (only for SNMPv3)')
425
        parser.add_argument(
426
            '--snmp-auth', default='password', dest='snmp_auth', help='SNMP authentication key (only for SNMPv3)'
427
        )
428
        parser.add_argument(
429
            '--snmp-force', action='store_true', default=False, dest='snmp_force', help='force SNMP mode'
430
        )
431
        parser.add_argument(
432
            '-t',
433
            '--time',
434
            default=self.DEFAULT_REFRESH_TIME,
435
            type=float,
436
            dest='time',
437
            help=f'set minimum refresh rate in seconds [default: {self.DEFAULT_REFRESH_TIME} sec]',
438
        )
439
        parser.add_argument(
440
            '-w',
441
            '--webserver',
442
            action='store_true',
443
            default=False,
444
            dest='webserver',
445
            help='run Glances in web server mode (FastAPI, Uvicorn, Jinja2 libs needed)',
446
        )
447
        parser.add_argument(
448
            '--cached-time',
449
            default=self.cached_time,
450
            type=int,
451
            dest='cached_time',
452
            help=f'set the server cache time [default: {self.cached_time} sec]',
453
        )
454
        parser.add_argument(
455
            '--stop-after',
456
            default=None,
457
            type=int,
458
            dest='stop_after',
459
            help='stop Glances after n refresh',
460
        )
461
        parser.add_argument(
462
            '--open-web-browser',
463
            action='store_true',
464
            default=False,
465
            dest='open_web_browser',
466
            help='try to open the Web UI in the default Web browser',
467
        )
468
        # Display options
469
        parser.add_argument(
470
            '-q',
471
            '--quiet',
472
            default=False,
473
            action='store_true',
474
            dest='quiet',
475
            help='do not display the curses interface',
476
        )
477
        parser.add_argument(
478
            '-f',
479
            '--process-filter',
480
            default=None,
481
            type=str,
482
            dest='process_filter',
483
            help='set the process filter pattern (regular expression)',
484
        )
485
        parser.add_argument(
486
            '--process-short-name',
487
            action='store_true',
488
            default=True,
489
            dest='process_short_name',
490
            help='force short name for processes name',
491
        )
492
        parser.add_argument(
493
            '--process-long-name',
494
            action='store_false',
495
            default=False,
496
            dest='process_short_name',
497
            help='force long name for processes name',
498
        )
499
        parser.add_argument(
500
            '--stdout',
501
            default=None,
502
            dest='stdout',
503
            help='display stats to stdout, one stat per line (comma-separated list of plugins/plugins.attribute)',
504
        )
505
        parser.add_argument(
506
            '--stdout-json',
507
            default=None,
508
            dest='stdout_json',
509
            help='display stats to stdout, JSON format (comma-separated list of plugins/plugins.attribute)',
510
        )
511
        parser.add_argument(
512
            '--stdout-csv',
513
            default=None,
514
            dest='stdout_csv',
515
            help='display stats to stdout, CSV format (comma-separated list of plugins/plugins.attribute)',
516
        )
517
        parser.add_argument(
518
            '--issue',
519
            default=None,
520
            action='store_true',
521
            dest='stdout_issue',
522
            help='test all plugins and exit (please copy/paste the output if you open an issue)',
523
        )
524
        parser.add_argument(
525
            '--trace-malloc',
526
            default=False,
527
            action='store_true',
528
            dest='trace_malloc',
529
            help='trace memory allocation and display it at the end of the process (python 3.4 or higher needed)',
530
        )
531
        parser.add_argument(
532
            '--memory-leak',
533
            default=False,
534
            action='store_true',
535
            dest='memory_leak',
536
            help='test memory leak (python 3.4 or higher needed)',
537
        )
538
        parser.add_argument(
539
            '--api-doc', default=None, action='store_true', dest='stdout_apidoc', help='display fields descriptions'
540
        )
541
        if not WINDOWS:
542
            parser.add_argument(
543
                '--hide-kernel-threads',
544
                action='store_true',
545
                default=False,
546
                dest='no_kernel_threads',
547
                help='hide kernel threads in the process list (not available on Windows)',
548
            )
549
        parser.add_argument(
550
            '-b',
551
            '--byte',
552
            action='store_true',
553
            default=False,
554
            dest='byte',
555
            help='display network rate in bytes per second',
556
        )
557
        parser.add_argument(
558
            '--diskio-show-ramfs',
559
            action='store_true',
560
            default=False,
561
            dest='diskio_show_ramfs',
562
            help='show RAM Fs in the DiskIO plugin',
563
        )
564
        parser.add_argument(
565
            '--diskio-iops',
566
            action='store_true',
567
            default=False,
568
            dest='diskio_iops',
569
            help='show IO per second in the DiskIO plugin',
570
        )
571
        parser.add_argument(
572
            '--fahrenheit',
573
            action='store_true',
574
            default=False,
575
            dest='fahrenheit',
576
            help='display temperature in Fahrenheit (default is Celsius)',
577
        )
578
        parser.add_argument(
579
            '--fs-free-space',
580
            action='store_true',
581
            default=False,
582
            dest='fs_free_space',
583
            help='display FS free space instead of used',
584
        )
585
        parser.add_argument(
586
            '--sparkline',
587
            action='store_true',
588
            default=False,
589
            dest='sparkline',
590
            help='display sparklines instead of bar in the curses interface',
591
        )
592
        parser.add_argument(
593
            '--disable-unicode',
594
            action='store_true',
595
            default=False,
596
            dest='disable_unicode',
597
            help='disable unicode characters in the curses interface',
598
        )
599
        parser.add_argument(
600
            '--hide-public-info',
601
            action='store_true',
602
            default=False,
603
            help='hide public information (like public IP)',
604
        )
605
        # Globals options
606
        parser.add_argument(
607
            '--disable-check-update',
608
            action='store_true',
609
            default=False,
610
            dest='disable_check_update',
611
            help='disable online Glances version ckeck',
612
        )
613
        parser.add_argument(
614
            '--strftime',
615
            dest='strftime_format',
616
            default='',
617
            help='strftime format string for displaying current date in standalone mode',
618
        )
619
620
        return parser
621
622
    def init_debug(self, args):
623
        """Init Glances debug mode."""
624
        if args.debug:
625
            logger.setLevel(DEBUG)
626
        else:
627
            simplefilter("ignore")
628
629
    def init_refresh_rate(self, args):
630
        """Init Glances refresh rate"""
631
        if self.config.has_section('global'):
632
            global_refresh = self.config.get_float_value('global', 'refresh', default=self.DEFAULT_REFRESH_TIME)
633
        else:
634
            global_refresh = self.DEFAULT_REFRESH_TIME
635
636
        # The configuration key can be overwrite from the command line (-t <time>)
637
        if args.time == self.DEFAULT_REFRESH_TIME:
638
            args.time = global_refresh
639
640
        logger.debug(f'Global refresh rate is set to {args.time} seconds')
641
642
    def init_plugins(self, args):
643
        """Init Glances plugins"""
644
        # Allow users to disable plugins from the glances.conf (issue #1378)
645
        for s in self.config.sections():
646
            if self.config.has_section(s) and (self.config.get_bool_value(s, 'disable', False)):
647
                disable(args, s)
648
                logger.debug(f'{s} disabled by the configuration file')
649
        # The configuration key can be overwrite from the command line
650
        if args and args.disable_plugin and 'all' in args.disable_plugin.split(','):
651
            if not args.enable_plugin:
652
                logger.critical("'all' key in --disable-plugin needs to be used with --enable-plugin")
653
                sys.exit(2)
654
            else:
655
                logger.info(
656
                    "'all' key in --disable-plugin, only plugins defined with --enable-plugin will be available"
657
                )
658
        if args.disable_plugin is not None:
659
            for p in args.disable_plugin.split(','):
660
                disable(args, p)
661
        if args.enable_plugin is not None:
662
            for p in args.enable_plugin.split(','):
663
                enable(args, p)
664
665
        # Exporters activation
666
        if args.export is not None:
667
            for p in args.export.split(','):
668
                setattr(args, 'export_' + p, True)
669
670
        # By default help is hidden
671
        args.help_tag = False
672
673
        # Display Rx and Tx, not the sum for the network
674
        args.network_sum = False
675
        args.network_cumul = False
676
677
        # Processlist is updated in processcount
678
        if getattr(args, 'enable_processlist', False) or getattr(args, 'enable_programlist', False):
679
            enable(args, 'processcount')
680
681
        # Set a default export_process_filter (with all process) when using the stdout mode
682
        if getattr(args, 'stdout', True) and args.process_filter is None:
683
            setattr(args, 'export_process_filter', '.*')
684
685
    def init_client_server(self, args):
686
        """Init Glances client/server mode."""
687
688
        # Client/server Port
689
        if args.port is None:
690
            if args.webserver:
691
                args.port = self.web_server_port
692
            else:
693
                args.port = self.server_port
694
        # Port in the -c URI #996
695
        if args.client is not None:
696
            args.client, args.port = (
697
                x if x else y for (x, y) in zip(args.client.partition(':')[::2], (args.client, args.port))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable x does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable y does not seem to be defined.
Loading history...
698
            )
699
700
        # Client autodiscover mode
701
        if args.disable_autodiscover:
702
            logger.info("Auto discover mode is disabled")
703
704
        # Server or client login/password
705
        if args.username_prompt:
706
            # Every username needs a password
707
            args.password_prompt = True
708
            # Prompt username
709
            if args.server:
710
                args.username = self.__get_username(description='Define the Glances server username: ')
711
            elif args.webserver:
712
                args.username = self.__get_username(description='Define the Glances webserver username: ')
713
            elif args.client:
714
                args.username = self.__get_username(description='Enter the Glances server username: ')
715
        else:
716
            if args.username_used:
717
                # A username has been set using the -u option ?
718
                args.username = args.username_used
719
            else:
720
                # Default user name is 'glances'
721
                args.username = self.username
722
723
        if args.password_prompt or args.username_used:
724
            # Interactive or file password
725
            if args.server:
726
                args.password = self.__get_password(
727
                    description=f'Define the Glances server password ({args.username} username): ',
728
                    confirm=True,
729
                    username=args.username,
730
                )
731
            elif args.webserver:
732
                args.password = self.__get_password(
733
                    description=f'Define the Glances webserver password ({args.username} username): ',
734
                    confirm=True,
735
                    username=args.username,
736
                )
737
            elif args.client:
738
                args.password = self.__get_password(
739
                    description=f'Enter the Glances server password ({args.username} username): ',
740
                    clear=True,
741
                    username=args.username,
742
                )
743
        else:
744
            # Default is no password
745
            args.password = self.password
746
747
    def init_ui_mode(self, args):
748
        # Manage light mode
749
        if getattr(args, 'enable_light', False):
750
            logger.info("Light mode is on")
751
            args.disable_left_sidebar = True
752
            disable(args, 'process')
753
            disable(args, 'alert')
754
            disable(args, 'amps')
755
            disable(args, 'containers')
756
            disable(args, 'vms')
757
758
        # Manage full quicklook option
759
        if getattr(args, 'full_quicklook', False):
760
            logger.info("Full quicklook mode")
761
            enable(args, 'quicklook')
762
            disable(args, 'cpu')
763
            disable(args, 'mem')
764
            disable(args, 'memswap')
765
            enable(args, 'load')
766
767
        # Manage disable_top option
768
        if getattr(args, 'disable_top', False):
769
            logger.info("Disable top menu")
770
            disable(args, 'quicklook')
771
            disable(args, 'cpu')
772
            disable(args, 'mem')
773
            disable(args, 'memswap')
774
            disable(args, 'load')
775
776
        # Memory leak
777
        if getattr(args, 'memory_leak', False):
778
            logger.info('Memory leak detection enabled')
779
            args.quiet = True
780
            if not args.stop_after:
781
                args.stop_after = 60
782
            args.time = 1
783
            args.disable_history = True
784
785
        # Unicode => No separator
786
        if args.disable_unicode:
787
            args.enable_separator = False
788
789
    def parse_args(self, args_begin_at):
790
        """Parse command line arguments.
791
        Glances args start at position args_begin_at.
792
        """
793
        return self.init_args().parse_args(sys.argv[args_begin_at:])
794
795
    def check_mode_compatibility(self):
796
        """Check mode compatibility"""
797
        # Server and Web server are not compatible
798
        if self.args.is_server and self.args.is_webserver:
799
            logger.critical("Server and Web server modes should not be used together")
800
            sys.exit(2)
801
802
        # Trace malloc option
803
        if getattr(self.args, 'trace_malloc', True) and not self.is_standalone():
804
            logger.critical("Option --trace-malloc is only available in the terminal mode")
805
            sys.exit(2)
806
807
        # Memory leak option
808
        if getattr(self.args, 'memory_leak', True) and not self.is_standalone():
809
            logger.critical("Option --memory-leak is only available in the terminal mode")
810
            sys.exit(2)
811
812
    def is_standalone(self):
813
        """Return True if Glances is running in standalone mode."""
814
        return not self.args.client and not self.args.browser and not self.args.server and not self.args.webserver
815
816
    def is_client(self):
817
        """Return True if Glances is running in client mode."""
818
        return (self.args.client or self.args.browser) and not self.args.server and not self.args.webserver
819
820
    def is_client_browser(self):
821
        """Return True if Glances is running in client browser mode."""
822
        return self.args.browser and not self.args.server and not self.args.webserver
823
824
    def is_server(self):
825
        """Return True if Glances is running in server mode."""
826
        return not self.args.client and self.args.server
827
828
    def is_webserver(self):
829
        """Return True if Glances is running in Web server mode."""
830
        return not self.args.client and self.args.webserver
831
832
    def get_config(self):
833
        """Return configuration file object."""
834
        return self.config
835
836
    def get_args(self):
837
        """Return the arguments."""
838
        return self.args
839
840
    def get_mode(self):
841
        """Return the mode."""
842
        return self.mode
843
844
    def __get_username(self, description=''):
845
        """Read an username from the command line."""
846
        return input(description)
847
848
    def __get_password(self, description='', confirm=False, clear=False, username='glances'):
849
        """Read a password from the command line.
850
851
        - if confirm = True, with confirmation
852
        - if clear = True, plain (clear password)
853
        """
854
        from glances.password import GlancesPassword
855
856
        password = GlancesPassword(username=username, config=self.get_config())
857
        return password.get_password(description, confirm, clear)
858