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