9
9
"""Containers plugin."""
10
10
11
11
from copy import deepcopy
12
+ from functools import partial , reduce
12
13
from typing import Any , Dict , List , Optional , Tuple
13
14
14
15
from glances .globals import iteritems , itervalues
@@ -290,17 +291,7 @@ def update_views(self) -> bool:
290
291
291
292
return True
292
293
293
- def msg_curse (self , args = None , max_width : Optional [int ] = None ) -> List [str ]:
294
- """Return the dict to display in the curse interface."""
295
- # Init the return message
296
- ret = []
297
-
298
- # Only process if stats exist (and non null) and display plugin enable...
299
- if not self .stats or len (self .stats ) == 0 or self .is_disabled ():
300
- return ret
301
-
302
- # Build the string message
303
- # Title
294
+ def build_title (self , ret ):
304
295
msg = '{}' .format ('CONTAINERS' )
305
296
ret .append (self .curse_add_line (msg , "TITLE" ))
306
297
msg = f' { len (self .stats )} '
@@ -311,97 +302,130 @@ def msg_curse(self, args=None, max_width: Optional[int] = None) -> List[str]:
311
302
msg = f' (served by { self .stats [0 ].get ("engine" , "" )} )'
312
303
ret .append (self .curse_add_line (msg ))
313
304
ret .append (self .curse_new_line ())
314
- # Header
315
- ret .append (self .curse_new_line ())
316
- # Get the maximum containers name
317
- # Max size is configurable. See feature request #1723.
318
- name_max_width = min (
319
- self .config .get_int_value ('containers' , 'max_name_size' , default = 20 ) if self .config is not None else 20 ,
320
- len (max (self .stats , key = lambda x : len (x ['name' ]))['name' ]),
321
- )
305
+ return ret
322
306
307
+ def maybe_add_engine_name_or_pod_line (self , ret ):
323
308
if self .views ['show_engine_name' ]:
324
- msg = ' {:{width}}' .format ('Engine' , width = 6 )
325
- ret .append (self .curse_add_line (msg ))
309
+ ret = self .add_msg_to_line (ret , ' {:{width}}' .format ('Engine' , width = 6 ))
326
310
if self .views ['show_pod_name' ]:
327
- msg = ' {:{width}}' .format ('Pod' , width = 12 )
328
- ret .append (self .curse_add_line (msg ))
311
+ ret = self .add_msg_to_line (ret , ' {:{width}}' .format ('Pod' , width = 12 ))
312
+
313
+ return ret
314
+
315
+ def maybe_add_engine_name_or_pod_name (self , ret , container ):
316
+ ret .append (self .curse_new_line ())
317
+ if self .views ['show_engine_name' ]:
318
+ ret .append (self .curse_add_line (' {:{width}}' .format (container ["engine" ], width = 6 )))
319
+ if self .views ['show_pod_name' ]:
320
+ ret .append (self .curse_add_line (' {:{width}}' .format (container .get ("pod_id" , "-" ), width = 12 )))
321
+
322
+ return ret
323
+
324
+ def build_container_name (self , name_max_width ):
325
+ def build_for_this_max_length (ret , container ):
326
+ ret .append (
327
+ self .curse_add_line (' {:{width}}' .format (container ['name' ][:name_max_width ], width = name_max_width ))
328
+ )
329
+
330
+ return ret
331
+
332
+ return build_for_this_max_length
333
+
334
+ def build_header (self , ret , name_max_width ):
335
+ ret .append (self .curse_new_line ())
336
+
337
+ ret = self .maybe_add_engine_name_or_pod_line (ret )
338
+
329
339
msg = ' {:{width}}' .format ('Name' , width = name_max_width )
330
340
ret .append (self .curse_add_line (msg , 'SORT' if self .sort_key == 'name' else 'DEFAULT' ))
331
- msg = '{:>10}' . format ( 'Status' )
332
- ret . append ( self . curse_add_line ( msg ))
333
- msg = '{:>10}' . format ( 'Uptime' )
334
- ret . append ( self . curse_add_line ( msg ))
341
+
342
+ msgs = [ '{:>10}' . format ( 'Status' ), '{:>10}' . format ( 'Uptime' )]
343
+ ret = reduce ( self . add_msg_to_line , msgs , ret )
344
+
335
345
msg = '{:>6}' .format ('CPU%' )
336
346
ret .append (self .curse_add_line (msg , 'SORT' if self .sort_key == 'cpu_percent' else 'DEFAULT' ))
337
347
msg = '{:>7}' .format ('MEM' )
338
348
ret .append (self .curse_add_line (msg , 'SORT' if self .sort_key == 'memory_usage' else 'DEFAULT' ))
339
- msg = '/{:<7}' .format ('MAX' )
340
- ret .append (self .curse_add_line (msg ))
341
- msg = '{:>7}' .format ('IOR/s' )
342
- ret .append (self .curse_add_line (msg ))
343
- msg = ' {:<7}' .format ('IOW/s' )
349
+
350
+ msgs = [
351
+ '/{:<7}' .format ('MAX' ),
352
+ '{:>7}' .format ('IOR/s' ),
353
+ ' {:<7}' .format ('IOW/s' ),
354
+ '{:>7}' .format ('Rx/s' ),
355
+ ' {:<7}' .format ('Tx/s' ),
356
+ ' {:8}' .format ('Command' ),
357
+ ]
358
+
359
+ return reduce (self .add_msg_to_line , msgs , ret )
360
+
361
+ def add_msg_to_line (self , ret , msg ):
344
362
ret .append (self .curse_add_line (msg ))
345
- msg = '{:>7}' .format ('Rx/s' )
363
+
364
+ return ret
365
+
366
+ def get_max_of_container_names (self ):
367
+ return min (
368
+ self .config .get_int_value ('containers' , 'max_name_size' , default = 20 ) if self .config is not None else 20 ,
369
+ len (max (self .stats , key = lambda x : len (x ['name' ]))['name' ]),
370
+ )
371
+
372
+ def build_status_name (self , ret , container ):
373
+ status = self .container_alert (container ['status' ])
374
+ msg = '{:>10}' .format (container ['status' ][0 :10 ])
375
+ ret .append (self .curse_add_line (msg , status ))
376
+
377
+ return ret
378
+
379
+ def build_uptime_line (self , ret , container ):
380
+ if container ['uptime' ]:
381
+ msg = '{:>10}' .format (container ['uptime' ])
382
+ else :
383
+ msg = '{:>10}' .format ('_' )
384
+
385
+ return self .add_msg_to_line (ret , msg )
386
+
387
+ def build_cpu_line (self , ret , container ):
388
+ try :
389
+ msg = '{:>6.1f}' .format (container ['cpu' ]['total' ])
390
+ except (KeyError , TypeError ):
391
+ msg = '{:>6}' .format ('_' )
392
+ ret .append (self .curse_add_line (msg , self .get_views (item = container ['name' ], key = 'cpu' , option = 'decoration' )))
393
+
394
+ return ret
395
+
396
+ def build_memory_line (self , ret , container ):
397
+ try :
398
+ msg = '{:>7}' .format (self .auto_unit (self .memory_usage_no_cache (container ['memory' ])))
399
+ except KeyError :
400
+ msg = '{:>7}' .format ('_' )
401
+ ret .append (self .curse_add_line (msg , self .get_views (item = container ['name' ], key = 'mem' , option = 'decoration' )))
402
+ try :
403
+ msg = '/{:<7}' .format (self .auto_unit (container ['memory' ]['limit' ]))
404
+ except (KeyError , TypeError ):
405
+ msg = '/{:<7}' .format ('_' )
346
406
ret .append (self .curse_add_line (msg ))
347
- msg = ' {:<7}' .format ('Tx/s' )
407
+
408
+ return ret
409
+
410
+ def build_io_line (self , ret , container ):
411
+ unit = 'B'
412
+ try :
413
+ value = self .auto_unit (int (container ['io_rx' ])) + unit
414
+ msg = f'{ value :>7} '
415
+ except (KeyError , TypeError ):
416
+ msg = '{:>7}' .format ('_' )
348
417
ret .append (self .curse_add_line (msg ))
349
- msg = ' {:8}' .format ('Command' )
418
+ try :
419
+ value = self .auto_unit (int (container ['io_wx' ])) + unit
420
+ msg = f' { value :<7} '
421
+ except (KeyError , TypeError ):
422
+ msg = ' {:<7}' .format ('_' )
350
423
ret .append (self .curse_add_line (msg ))
351
424
352
- # Data
353
- for container in self .stats :
354
- ret .append (self .curse_new_line ())
355
- if self .views ['show_engine_name' ]:
356
- ret .append (self .curse_add_line (' {:{width}}' .format (container ["engine" ], width = 6 )))
357
- if self .views ['show_pod_name' ]:
358
- ret .append (self .curse_add_line (' {:{width}}' .format (container .get ("pod_id" , "-" ), width = 12 )))
359
- # Name
360
- ret .append (
361
- self .curse_add_line (' {:{width}}' .format (container ['name' ][:name_max_width ], width = name_max_width ))
362
- )
363
- # Status
364
- status = self .container_alert (container ['status' ])
365
- msg = '{:>10}' .format (container ['status' ][0 :10 ])
366
- ret .append (self .curse_add_line (msg , status ))
367
- # Uptime
368
- if container ['uptime' ]:
369
- msg = '{:>10}' .format (container ['uptime' ])
370
- else :
371
- msg = '{:>10}' .format ('_' )
372
- ret .append (self .curse_add_line (msg ))
373
- # CPU
374
- try :
375
- msg = '{:>6.1f}' .format (container ['cpu' ]['total' ])
376
- except (KeyError , TypeError ):
377
- msg = '{:>6}' .format ('_' )
378
- ret .append (self .curse_add_line (msg , self .get_views (item = container ['name' ], key = 'cpu' , option = 'decoration' )))
379
- # MEM
380
- try :
381
- msg = '{:>7}' .format (self .auto_unit (self .memory_usage_no_cache (container ['memory' ])))
382
- except KeyError :
383
- msg = '{:>7}' .format ('_' )
384
- ret .append (self .curse_add_line (msg , self .get_views (item = container ['name' ], key = 'mem' , option = 'decoration' )))
385
- try :
386
- msg = '/{:<7}' .format (self .auto_unit (container ['memory' ]['limit' ]))
387
- except (KeyError , TypeError ):
388
- msg = '/{:<7}' .format ('_' )
389
- ret .append (self .curse_add_line (msg ))
390
- # IO R/W
391
- unit = 'B'
392
- try :
393
- value = self .auto_unit (int (container ['io_rx' ])) + unit
394
- msg = f'{ value :>7} '
395
- except (KeyError , TypeError ):
396
- msg = '{:>7}' .format ('_' )
397
- ret .append (self .curse_add_line (msg ))
398
- try :
399
- value = self .auto_unit (int (container ['io_wx' ])) + unit
400
- msg = f' { value :<7} '
401
- except (KeyError , TypeError ):
402
- msg = ' {:<7}' .format ('_' )
403
- ret .append (self .curse_add_line (msg ))
404
- # NET RX/TX
425
+ return ret
426
+
427
+ def build_net_line (self , args ):
428
+ def build_with_this_args (ret , container ):
405
429
if args .byte :
406
430
# Bytes per second (for dummy)
407
431
to_bit = 1
@@ -422,15 +446,68 @@ def msg_curse(self, args=None, max_width: Optional[int] = None) -> List[str]:
422
446
except (KeyError , TypeError ):
423
447
msg = ' {:<7}' .format ('_' )
424
448
ret .append (self .curse_add_line (msg ))
425
- # Command
426
- if container ['command' ] is not None :
427
- msg = ' {}' .format (container ['command' ])
428
- else :
429
- msg = ' {}' .format ('_' )
430
- ret .append (self .curse_add_line (msg , splittable = True ))
449
+
450
+ return ret
451
+
452
+ return build_with_this_args
453
+
454
+ def build_cmd_line (self , ret , container ):
455
+ if container ['command' ] is not None :
456
+ msg = ' {}' .format (container ['command' ])
457
+ else :
458
+ msg = ' {}' .format ('_' )
459
+ ret .append (self .curse_add_line (msg , splittable = True ))
431
460
432
461
return ret
433
462
463
+ def msg_curse (self , args = None , max_width : Optional [int ] = None ) -> List [str ]:
464
+ """Return the dict to display in the curse interface."""
465
+ # Init the return message
466
+ init = []
467
+
468
+ # Only process if stats exist (and non null) and display plugin enable...
469
+ conditions = [not self .stats , len (self .stats ) == 0 , self .is_disabled ()]
470
+ if any (conditions ):
471
+ return init
472
+
473
+ # Build the string message
474
+ # Get the maximum containers name
475
+ # Max size is configurable. See feature request #1723.
476
+ name_max_width = self .get_max_of_container_names ()
477
+
478
+ steps = [
479
+ self .build_title ,
480
+ partial (self .build_header , name_max_width = name_max_width ),
481
+ self .build_data_line (name_max_width , args ),
482
+ ]
483
+
484
+ return reduce (lambda ret , step : step (ret ), steps , init )
485
+
486
+ def build_data_line (self , name_max_width , args ):
487
+ def build_for_this_params (ret ):
488
+ build_data_with_params = self .build_container_data (name_max_width , args )
489
+ return reduce (build_data_with_params , self .stats , ret )
490
+
491
+ return build_for_this_params
492
+
493
+ def build_container_data (self , name_max_width , args ):
494
+ def build_with_this_params (ret , container ):
495
+ steps = [
496
+ self .maybe_add_engine_name_or_pod_name ,
497
+ self .build_container_name (name_max_width ),
498
+ self .build_status_name ,
499
+ self .build_uptime_line ,
500
+ self .build_cpu_line ,
501
+ self .build_memory_line ,
502
+ self .build_io_line ,
503
+ self .build_net_line (args ),
504
+ self .build_cmd_line ,
505
+ ]
506
+
507
+ return reduce (lambda ret , step : step (ret , container ), steps , ret )
508
+
509
+ return build_with_this_params
510
+
434
511
@staticmethod
435
512
def container_alert (status : str ) -> str :
436
513
"""Analyse the container status.
0 commit comments