glances.main.GlancesMain.init_plugins()   F
last analyzed

Complexity

Conditions 19

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 30
nop 2
dl 0
loc 45
rs 0.5999
c 0
b 0
f 0

How to fix   Complexity   

Complexity

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