multiSSH3 6.20__tar.gz → 6.22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multiSSH3
3
- Version: 6.20
3
+ Version: 6.22
4
4
  Summary: Run commands on multiple hosts via SSH
5
5
  Home-page: https://github.com/yufei-pan/multiSSH3
6
6
  Author: Yufei Pan
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multiSSH3
3
- Version: 6.20
3
+ Version: 6.22
4
4
  Summary: Run commands on multiple hosts via SSH
5
5
  Home-page: https://github.com/yufei-pan/multiSSH3
6
6
  Author: Yufei Pan
@@ -29,16 +29,16 @@ import textwrap
29
29
  import threading
30
30
  import time
31
31
  import typing
32
- import uuid
32
+ from uuid import uuid4
33
33
  from collections import Counter, defaultdict, deque, ChainMap
34
34
  from itertools import count, product
35
35
  from pprint import pformat
36
36
 
37
37
 
38
- version = '6.20'
38
+ version = '6.22'
39
39
  VERSION = version
40
40
  __version__ = version
41
- COMMIT_DATE = '2026-04-16'
41
+ COMMIT_DATE = '2026-04-21'
42
42
  # TODO: Add terminal TUI
43
43
 
44
44
  CONFIG_FILE_CHAIN = ['./multiSSH3.config.json',
@@ -337,6 +337,7 @@ def _get_i():
337
337
 
338
338
  #%% ------------ Load Defaults ( Config ) File ----------------
339
339
  def load_config_file(config_file):
340
+ global __working_config_file
340
341
  '''
341
342
  Load the config file to global variables
342
343
 
@@ -351,6 +352,7 @@ def load_config_file(config_file):
351
352
  try:
352
353
  with open(config_file,'r') as f:
353
354
  config = json.load(f)
355
+ __working_config_file = config_file
354
356
  except Exception as e:
355
357
  eprint(f"Error: Cannot load config file {config_file!r}: {e}")
356
358
  return {}
@@ -358,6 +360,7 @@ def load_config_file(config_file):
358
360
 
359
361
  #%% Load Config Based Default Global variables
360
362
  __configs_from_file = {}
363
+ __working_config_file = './multiSSH3.config.json'
361
364
  for config_file in reversed(CONFIG_FILE_CHAIN.copy()):
362
365
  __configs_from_file.update(load_config_file(os.path.expanduser(config_file)))
363
366
  globals().update(__configs_from_file)
@@ -455,7 +458,7 @@ if __curses_available:
455
458
 
456
459
  #%% ------------ Host Object ----------------
457
460
  class Host:
458
- def __init__(self, name, command, files = None,ipmi = False,interface_ip_prefix = None,scp=False,extraargs=None,gatherMode=False,identity_file=None,shell=False,i = -1,uuid=uuid.uuid4(),ip = None):
461
+ def __init__(self, name, command, files = None,ipmi = False,interface_ip_prefix = None,scp=False,extraargs=None,gatherMode=False,identity_file=None,shell=False,i = -1,uuid=...,ip = None):
459
462
  self.name = name # the name of the host (hostname or IP address)
460
463
  self.command = command # the command to run on the host
461
464
  self.returncode = None # the return code of the command
@@ -475,7 +478,7 @@ class Host:
475
478
  self.resolvedName = None # the resolved IP address of the host
476
479
  # also store a globally unique integer i from 0
477
480
  self.i = i if i != -1 else _get_i()
478
- self.uuid = uuid
481
+ self.uuid = uuid if uuid is not ... else uuid4()
479
482
  self.identity_file = identity_file
480
483
  self.ip = ip if ip else getIP(name)
481
484
  self.current_color_pair = [-1, -1, 1]
@@ -4035,9 +4038,9 @@ def get_parser():
4035
4038
  su_group.add_argument('-a',"-nsu","--no_skip_unreachable",dest = 'skip_unreachable', action='store_false', help=f"Do not skip unreachable hosts. Note: Timedout Hosts are considered unreachable. Note: multiple command sequence will still auto skip unreachable hosts. (default: {not DEFAULT_SKIP_UNREACHABLE})", default=not DEFAULT_SKIP_UNREACHABLE)
4036
4039
  parser.add_argument('-uhe','--unavailable_host_expiry', type=int, help=f"Time in seconds to expire the unavailable hosts (default: {DEFAULT_UNAVAILABLE_HOST_EXPIRY})", default=DEFAULT_UNAVAILABLE_HOST_EXPIRY)
4037
4040
  parser.add_argument('-X',"-sh","--skip_hosts", type=str, help=f"Skip the hosts in the list. (default: {DEFAULT_SKIP_HOSTS if DEFAULT_SKIP_HOSTS else 'None'})", default=DEFAULT_SKIP_HOSTS)
4038
- parser.add_argument('--generate_config_file', action='store_true', help='Restore / generate using the build-in default configs with default config file chain and command line argument to write to --config_file / stdout')
4039
- parser.add_argument('--config_file', type=str,nargs='?', help='Additional config file to apply, Warning: will over write CLI options. When using with generate_config_file, will store the resulting config file at this location. Use without a path will use multiSSH3.config.json',const='multiSSH3.config.json',default=None)
4040
- parser.add_argument('--store_config_file',type = str,nargs='?',help='Refresh / store the specified config file with new params and command line args into the config file. Defaults to ./multiSSH3.config.json or --config_file if supplied.',const=...)
4041
+ parser.add_argument('--generate_config_file', action='store_true', help='Restore / generate using the build-in default configs with default config file chain and command line argument to write to --store_config_file / stdout')
4042
+ parser.add_argument('--config_file', type=str,nargs='?', help='Load additional config file to apply, Warning: will over write CLI options. Use without a path will use multiSSH3.config.json',const='multiSSH3.config.json',default=None)
4043
+ parser.add_argument('--store_config_file',type = str,nargs='?',help=f'Refresh / store the specified config file with new params and command line args into the config file. Defaults to the first config file found in search path: {__working_config_file}',const=...)
4041
4044
  parser.add_argument('--debug', action='store_true', help='Print debug information')
4042
4045
  parser.add_argument('-ci','--copy_id', action='store_true', help='Copy the ssh id to the hosts')
4043
4046
  parser.add_argument('-I','-nh','--no_history', action='store_true', help=f'Do not record the command to history. Default: {DEFAULT_NO_HISTORY}', default=DEFAULT_NO_HISTORY)
@@ -4055,10 +4058,9 @@ def process_args(args = None):
4055
4058
  global __configs_from_file
4056
4059
  cfp = parser = argparse.ArgumentParser(add_help=False)
4057
4060
  cfp.add_argument('--config_file', type=str,nargs='?',const='multiSSH3.config.json',default=None)
4058
- cfp.add_argument('--generate_config_file', action='store_true')
4059
4061
  try:
4060
4062
  cfpa, args = cfp.parse_known_args(args)
4061
- if cfpa.config_file and not cfpa.generate_config_file:
4063
+ if cfpa.config_file:
4062
4064
  if os.path.exists(cfpa.config_file):
4063
4065
  configs = load_config_file(os.path.expanduser(cfpa.config_file))
4064
4066
  globals().update(configs)
@@ -4084,7 +4086,6 @@ def process_args(args = None):
4084
4086
  args.commands += unknown
4085
4087
  try:
4086
4088
  args.config_file = cfpa.config_file
4087
- args.generate_config_file = cfpa.generate_config_file
4088
4089
  except Exception:
4089
4090
  pass
4090
4091
  if args.script:
@@ -4134,19 +4135,20 @@ def process_args(args = None):
4134
4135
 
4135
4136
  def process_config_file(args):
4136
4137
  global __configs_from_file
4138
+ global __working_config_file
4137
4139
  if args.generate_config_file or args.store_config_file:
4138
4140
  if args.store_config_file:
4139
4141
  if args.store_config_file is ...:
4140
- configFileToWriteTo = args.config_file if args.config_file else './multiSSH3.config.json'
4142
+ configFileToWriteTo = __working_config_file
4141
4143
  else:
4142
4144
  configFileToWriteTo = args.store_config_file
4143
4145
  else:
4144
- configFileToWriteTo = args.config_file
4145
- write_default_config(args,configFileToWriteTo,force=args.store_config_file)
4146
+ configFileToWriteTo = None
4147
+ write_default_config(args,configFileToWriteTo,force=args.generate_config_file)
4146
4148
  if not args.commands and not args.file:
4147
4149
  if configFileToWriteTo:
4148
4150
  with open(configFileToWriteTo,'r') as f:
4149
- eprint(f"Config file content: \n{f.read()}")
4151
+ eprint(f"Config file {configFileToWriteTo} content: \n{f.read()}")
4150
4152
  _exit_with_code(0)
4151
4153
  return args
4152
4154
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes