multiSSH3 6.18__tar.gz → 6.20__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.
- {multissh3-6.18 → multissh3-6.20}/PKG-INFO +1 -1
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.egg-info/PKG-INFO +1 -1
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.py +216 -164
- {multissh3-6.18 → multissh3-6.20}/README.md +0 -0
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.egg-info/SOURCES.txt +0 -0
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.egg-info/dependency_links.txt +0 -0
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.egg-info/entry_points.txt +0 -0
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.egg-info/requires.txt +0 -0
- {multissh3-6.18 → multissh3-6.20}/multiSSH3.egg-info/top_level.txt +0 -0
- {multissh3-6.18 → multissh3-6.20}/setup.cfg +0 -0
- {multissh3-6.18 → multissh3-6.20}/setup.py +0 -0
- {multissh3-6.18 → multissh3-6.20}/test/test.py +0 -0
- {multissh3-6.18 → multissh3-6.20}/test/testCurses.py +0 -0
- {multissh3-6.18 → multissh3-6.20}/test/testCursesOld.py +0 -0
- {multissh3-6.18 → multissh3-6.20}/test/testPerfCompact.py +0 -0
- {multissh3-6.18 → multissh3-6.20}/test/testPerfExpand.py +0 -0
|
@@ -30,15 +30,15 @@ import threading
|
|
|
30
30
|
import time
|
|
31
31
|
import typing
|
|
32
32
|
import uuid
|
|
33
|
-
from collections import Counter, defaultdict, deque
|
|
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.
|
|
38
|
+
version = '6.20'
|
|
39
39
|
VERSION = version
|
|
40
40
|
__version__ = version
|
|
41
|
-
COMMIT_DATE = '2026-04-
|
|
41
|
+
COMMIT_DATE = '2026-04-16'
|
|
42
42
|
# TODO: Add terminal TUI
|
|
43
43
|
|
|
44
44
|
CONFIG_FILE_CHAIN = ['./multiSSH3.config.json',
|
|
@@ -70,10 +70,22 @@ DEFAULT_REPEAT = 1
|
|
|
70
70
|
DEFAULT_INTERVAL = 0
|
|
71
71
|
DEFAULT_IPMI = False
|
|
72
72
|
DEFAULT_IPMI_INTERFACE_IP_PREFIX = ''
|
|
73
|
+
DEFAULT_IPMI_USERNAME = 'admin'
|
|
74
|
+
DEFAULT_IPMI_PASSWORD = 'admin'
|
|
75
|
+
DEFAULT_IPMI_ARGS=''
|
|
76
|
+
DEFAULT_IPMI_METHOD = 'ipmitool'
|
|
77
|
+
DEFAULT_IPMI_RETRY_LOCKOUT_TIME = -1
|
|
78
|
+
def get_default_ipmi_definition():
|
|
79
|
+
return {'interface_ip_prefix': DEFAULT_IPMI_INTERFACE_IP_PREFIX,
|
|
80
|
+
'username': DEFAULT_IPMI_USERNAME,
|
|
81
|
+
'password': DEFAULT_IPMI_PASSWORD,
|
|
82
|
+
'args': DEFAULT_IPMI_ARGS,
|
|
83
|
+
'ipmi_method': DEFAULT_IPMI_METHOD,
|
|
84
|
+
'hostname_keyword': '',
|
|
85
|
+
'retry_lockout_time': DEFAULT_IPMI_RETRY_LOCKOUT_TIME,
|
|
86
|
+
}
|
|
87
|
+
DEFAULT_IPMI_DEFINITIONS = [get_default_ipmi_definition()]
|
|
73
88
|
DEFAULT_INTERFACE_IP_PREFIX = None
|
|
74
|
-
DEFAULT_IPMI_USERNAME = 'ADMIN'
|
|
75
|
-
DEFAULT_IPMI_PASSWORD = ''
|
|
76
|
-
DEAFULT_IPMI_ARGS=''
|
|
77
89
|
DEFAULT_NO_WATCH = False
|
|
78
90
|
DEFAULT_WINDOW_WIDTH = 40
|
|
79
91
|
DEFAULT_WINDOW_HEIGHT = 1
|
|
@@ -367,8 +379,6 @@ __wildCharacters = ['*','?','x']
|
|
|
367
379
|
_no_env = DEFAULT_NO_ENV
|
|
368
380
|
_env_files = DEFAULT_ENV_FILES
|
|
369
381
|
__globalUnavailableHosts = dict()
|
|
370
|
-
__ipmiiInterfaceIPPrefix = DEFAULT_IPMI_INTERFACE_IP_PREFIX
|
|
371
|
-
__ipmi_args = DEAFULT_IPMI_ARGS
|
|
372
382
|
__keyPressesIn = [[]]
|
|
373
383
|
_emo = False
|
|
374
384
|
__curses_global_color_pairs = {(-1,-1):1}
|
|
@@ -405,7 +415,7 @@ if __resource_lib_available:
|
|
|
405
415
|
resource.setrlimit(resource.RLIMIT_NOFILE, (__system_nofile_limit, __system_nofile_limit))
|
|
406
416
|
__max_connections_nofile_limit_supported = int((__system_nofile_limit - 10) / 3)
|
|
407
417
|
_binPaths = {}
|
|
408
|
-
_binCalled = set(['sshpass', 'ssh', 'scp', 'ipmitool','rsync','sh','ssh-copy-id'])
|
|
418
|
+
_binCalled = set(['sshpass', 'ssh', 'scp', 'ipmitool','rsync','sh','ssh-copy-id','redfishtool'])
|
|
409
419
|
def check_path(program_name):
|
|
410
420
|
global __configs_from_file
|
|
411
421
|
global _binPaths
|
|
@@ -1789,7 +1799,7 @@ def __handle_writing_stream(stream,stop_event,host):
|
|
|
1789
1799
|
# host.stdout.append(' $ ' + ''.join(__keyPressesIn[-1]).encode().decode().replace('\n', '↵'))
|
|
1790
1800
|
return sentInputPos
|
|
1791
1801
|
|
|
1792
|
-
def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,
|
|
1802
|
+
def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7 + len(DEFAULT_IPMI_DEFINITIONS),ipmi_definitions_list = ...):
|
|
1793
1803
|
'''
|
|
1794
1804
|
Run the command on the host. Will format the commands accordingly. Main execution function.
|
|
1795
1805
|
|
|
@@ -1804,45 +1814,67 @@ def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,ipmi_args =
|
|
|
1804
1814
|
'''
|
|
1805
1815
|
global _emo
|
|
1806
1816
|
global __ERROR_MESSAGES_TO_IGNORE_REGEX
|
|
1807
|
-
global __ipmiiInterfaceIPPrefix
|
|
1808
1817
|
global _binPaths
|
|
1809
1818
|
global __DEBUG_MODE
|
|
1810
|
-
global DEFAULT_IPMI_USERNAME
|
|
1811
|
-
global DEFAULT_IPMI_PASSWORD
|
|
1812
1819
|
global DEFAULT_USERNAME
|
|
1813
1820
|
global DEFAULT_PASSWORD
|
|
1814
1821
|
global SSH_STRICT_HOST_KEY_CHECKING
|
|
1815
|
-
global __ipmi_args
|
|
1816
|
-
global DEAFULT_IPMI_ARGS
|
|
1817
1822
|
if retry_limit < 0:
|
|
1818
1823
|
host.output.append('Error: Retry limit reached!')
|
|
1819
1824
|
host.stderr.append('Error: Retry limit reached!')
|
|
1820
1825
|
host.returncode = 1
|
|
1821
1826
|
return
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1827
|
+
ipmi_definition = {}
|
|
1828
|
+
username = None
|
|
1829
|
+
sshLocalExtraArgs = []
|
|
1830
|
+
ip_prefix = None
|
|
1825
1831
|
try:
|
|
1826
|
-
localExtraArgs = []
|
|
1827
|
-
|
|
1828
1832
|
if not SSH_STRICT_HOST_KEY_CHECKING:
|
|
1829
|
-
|
|
1833
|
+
sshLocalExtraArgs = ['-o StrictHostKeyChecking=no','-o UserKnownHostsFile=/dev/null']
|
|
1830
1834
|
if host.identity_file:
|
|
1831
|
-
|
|
1832
|
-
rsyncLocalExtraArgs = ['--rsh','ssh ' + ' '.join(
|
|
1833
|
-
host.username = None
|
|
1835
|
+
sshLocalExtraArgs += ['-i',host.identity_file]
|
|
1836
|
+
rsyncLocalExtraArgs = ['--rsh','ssh ' + ' '.join(sshLocalExtraArgs)]
|
|
1834
1837
|
host.address = host.name
|
|
1835
1838
|
if '@' in host.name:
|
|
1836
|
-
|
|
1839
|
+
username, host.address = host.name.rsplit('@',1)
|
|
1840
|
+
if host.ipmi:
|
|
1841
|
+
if ipmi_definitions_list is ...:
|
|
1842
|
+
ipmi_definitions_list = [ipmi_definition for ipmi_definition in DEFAULT_IPMI_DEFINITIONS if not ipmi_definition.get('hostname_keyword') or str(ipmi_definition.get('hostname_keyword')).strip() in host.name]
|
|
1843
|
+
if not ipmi_definitions_list:
|
|
1844
|
+
host.output.append('Error: Exhausted all matching ipmi definitions!')
|
|
1845
|
+
host.stderr.append('Error: Exhausted all matching ipmi definitions!')
|
|
1846
|
+
host.returncode = 1
|
|
1847
|
+
return
|
|
1848
|
+
ipmi_definition = dict(ChainMap(ipmi_definitions_list.pop(0),get_default_ipmi_definition()))
|
|
1849
|
+
if ipmi_definition.get('ipmi_method') == 'ssh_ipmitool':
|
|
1850
|
+
if not host.command:
|
|
1851
|
+
host.command = 'ipmitool power status'
|
|
1852
|
+
else:
|
|
1853
|
+
host.command = 'ipmitool '+host.command if not host.command.startswith('ipmitool ') else host.command
|
|
1854
|
+
if username:
|
|
1855
|
+
host.output.append(f'Warning:-u SSH_USERNAME {username} is provided in the host name! Using the username from the ipmi definition if provided: {ipmi_definition.get("username")}')
|
|
1856
|
+
if __DEBUG_MODE:
|
|
1857
|
+
host.stderr.append(f'Warning:-u SSH_USERNAME {username} is provided in the host name! Using the username from the ipmi definition if provided: {ipmi_definition.get("username")}')
|
|
1858
|
+
username = ipmi_definition.get('username',username)
|
|
1859
|
+
if passwds:
|
|
1860
|
+
host.output.append(f'Warning: -p SSH_PASSWORD {passwds} is provided! Using the password from the ipmi definition if provided: {ipmi_definition.get("password")}')
|
|
1861
|
+
if __DEBUG_MODE:
|
|
1862
|
+
host.stderr.append(f'Warning: -p SSH_PASSWORD {passwds} is provided! Using the password from the ipmi definition if provided: {ipmi_definition.get("password")}')
|
|
1863
|
+
passwds = ipmi_definition.get('password',passwds)
|
|
1864
|
+
if ipmi_definition.get('interface_ip_prefix') and ipmi_definition.get('interface_ip_prefix') == DEFAULT_IPMI_INTERFACE_IP_PREFIX:
|
|
1865
|
+
host.output.append('Warning: ipmi_interface_ip_prefix that is the same as the DEFAULT_IPMI_INTERFACE_IP_PREFIX is ignored in ssh_ipmitool mode.')
|
|
1866
|
+
if __DEBUG_MODE:
|
|
1867
|
+
host.stderr.append('Warning: ipmi_interface_ip_prefix that is the same as the DEFAULT_IPMI_INTERFACE_IP_PREFIX is ignored in ssh_ipmitool mode.')
|
|
1868
|
+
else:
|
|
1869
|
+
ip_prefix = ipmi_definition.get('interface_ip_prefix')
|
|
1837
1870
|
host.command = replace_magic_strings(host.command,['#HOST#','#HOSTNAME#'],host.address,case_sensitive=False)
|
|
1838
|
-
if
|
|
1839
|
-
host.command = replace_magic_strings(host.command,['#USER#','#USERNAME#'],
|
|
1871
|
+
if username:
|
|
1872
|
+
host.command = replace_magic_strings(host.command,['#USER#','#USERNAME#'],username,case_sensitive=False)
|
|
1840
1873
|
else:
|
|
1841
1874
|
current_user = getpass.getuser()
|
|
1842
1875
|
host.command = replace_magic_strings(host.command,['#USER#','#USERNAME#'],current_user,case_sensitive=False)
|
|
1843
1876
|
host.command = replace_magic_strings(host.command,['#ID#'],str(id(host)),case_sensitive=False)
|
|
1844
1877
|
host.command = replace_magic_strings(host.command,['#I#'],str(host.i),case_sensitive=False)
|
|
1845
|
-
host.command = replace_magic_strings(host.command,['#PASSWD#','#PASSWORD#'],passwds,case_sensitive=False)
|
|
1846
1878
|
host.command = replace_magic_strings(host.command,['#UUID#'],str(host.uuid),case_sensitive=False)
|
|
1847
1879
|
host.command = replace_magic_strings(host.command,['#IP#'],str(host.ip),case_sensitive=False)
|
|
1848
1880
|
formatedCMD = []
|
|
@@ -1852,63 +1884,65 @@ def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,ipmi_args =
|
|
|
1852
1884
|
extraargs = [str(arg) for arg in host.extraargs]
|
|
1853
1885
|
else:
|
|
1854
1886
|
extraargs = []
|
|
1855
|
-
if
|
|
1856
|
-
|
|
1857
|
-
if
|
|
1887
|
+
if not ip_prefix:
|
|
1888
|
+
ip_prefix = host.interface_ip_prefix
|
|
1889
|
+
if ip_prefix:
|
|
1858
1890
|
try:
|
|
1859
1891
|
hostOctets = host.ip.split('.')
|
|
1860
|
-
prefixOctets =
|
|
1892
|
+
prefixOctets = ip_prefix.split('.')
|
|
1861
1893
|
host.address = '.'.join(prefixOctets[:3]+hostOctets[min(3,len(prefixOctets)):])
|
|
1862
|
-
host.resolvedName = host.username + '@' if host.username else ''
|
|
1863
|
-
host.resolvedName += host.address
|
|
1864
1894
|
except Exception:
|
|
1865
|
-
host.
|
|
1895
|
+
host.output.append(f'Warning: Failed to resolve the IP address for the host {host.name}. Unable to resolve ip_prefix {ip_prefix}!')
|
|
1896
|
+
if __DEBUG_MODE:
|
|
1897
|
+
host.stderr.append(f'Warning: Failed to resolve the IP address for the host {host.name}. Unable to resolve ip_prefix {ip_prefix}!')
|
|
1898
|
+
if username:
|
|
1899
|
+
host.resolvedName = username + '@' + host.address
|
|
1866
1900
|
else:
|
|
1867
|
-
host.resolvedName = host.
|
|
1901
|
+
host.resolvedName = host.address
|
|
1868
1902
|
if host.resolvedName:
|
|
1869
1903
|
host.command = replace_magic_strings(host.command,['#RESOLVEDNAME#','#RESOLVED#'],host.resolvedName,case_sensitive=False)
|
|
1870
|
-
|
|
1871
|
-
|
|
1904
|
+
if __DEBUG_MODE:
|
|
1905
|
+
host.stderr.append(f'Resolved name: {host.resolvedName}')
|
|
1906
|
+
if host.ipmi and ipmi_definition.get('ipmi_method') != 'ssh_ipmitool':
|
|
1907
|
+
#{interface_ip_prefix,username,password,args,ipmi_method,hostname_keyword,retry_lockout_time}
|
|
1908
|
+
if ipmi_definition.get('ipmi_method') == 'ipmitool':
|
|
1909
|
+
if 'ipmitool' not in _binPaths:
|
|
1910
|
+
host.output.append('Ipmitool not found on the local machine! Trying ipmitool on the remote machine...')
|
|
1911
|
+
if __DEBUG_MODE:
|
|
1912
|
+
host.stderr.append('Ipmitool not found on the local machine! Trying ipmitool on the remote machine...')
|
|
1913
|
+
if ipmi_definition.get('interface_ip_prefix') == DEFAULT_IPMI_INTERFACE_IP_PREFIX:
|
|
1914
|
+
ipmi_definition['interface_ip_prefix'] = DEFAULT_INTERFACE_IP_PREFIX
|
|
1915
|
+
ipmi_definition['username'] = username
|
|
1916
|
+
ipmi_definition['password'] = passwds
|
|
1917
|
+
ipmi_definition['ipmi_method'] = 'ssh_ipmitool'
|
|
1918
|
+
ipmi_definitions_list.insert(0,ipmi_definition)
|
|
1919
|
+
return run_command(host,sem,timeout,passwds,retry_limit=retry_limit - 1,ipmi_definitions_list=ipmi_definitions_list)
|
|
1872
1920
|
if host.command.startswith('ipmitool '):
|
|
1873
1921
|
host.command = host.command.replace('ipmitool ','')
|
|
1874
1922
|
elif host.command.startswith(_binPaths['ipmitool']):
|
|
1875
1923
|
host.command = host.command.replace(_binPaths['ipmitool'],'')
|
|
1876
|
-
if not host.username or host.username == DEFAULT_USERNAME:
|
|
1877
|
-
if DEFAULT_IPMI_USERNAME:
|
|
1878
|
-
host.username = DEFAULT_IPMI_USERNAME
|
|
1879
|
-
elif DEFAULT_USERNAME:
|
|
1880
|
-
host.username = DEFAULT_USERNAME
|
|
1881
|
-
else:
|
|
1882
|
-
host.username = 'ADMIN'
|
|
1883
|
-
if not passwds or passwds == DEFAULT_PASSWORD:
|
|
1884
|
-
if DEFAULT_IPMI_PASSWORD:
|
|
1885
|
-
passwds = DEFAULT_IPMI_PASSWORD
|
|
1886
|
-
elif DEFAULT_PASSWORD:
|
|
1887
|
-
passwds = DEFAULT_PASSWORD
|
|
1888
|
-
else:
|
|
1889
|
-
host.output.append('Warning: Password not provided for ipmi! Using a default password `admin`.')
|
|
1890
|
-
passwds = 'admin'
|
|
1891
1924
|
if not host.command:
|
|
1892
1925
|
host.command = 'power status'
|
|
1926
|
+
ipmi_args = ipmi_definition.get('args','')
|
|
1893
1927
|
if 'sh' in _binPaths:
|
|
1894
|
-
formatedCMD = [_binPaths['sh'],'-c',f'ipmitool -H {host.address} -U {
|
|
1928
|
+
formatedCMD = [_binPaths['sh'],'-c',f'ipmitool -H {host.address} -U {ipmi_definition.get("username",username)} -P {ipmi_definition.get("password",passwds)} {ipmi_args} {host.command}']
|
|
1895
1929
|
else:
|
|
1896
|
-
formatedCMD = [_binPaths['ipmitool'],f'-H {host.address}',f'-U {
|
|
1897
|
-
elif '
|
|
1898
|
-
host.
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
host.interface_ip_prefix = None
|
|
1930
|
+
formatedCMD = [_binPaths['ipmitool'],f'-H {host.address}',f'-U {ipmi_definition.get("username",username)}',f'-P {ipmi_definition.get("password",passwds)}'] + [f'-{s}' for s in ipmi_args.split('-') if s] + [host.command]
|
|
1931
|
+
elif ipmi_definition.get('ipmi_method') == 'redfish':
|
|
1932
|
+
if host.command.startswith('redfishtool '):
|
|
1933
|
+
host.command = host.command.replace('redfishtool ','')
|
|
1934
|
+
elif host.command.startswith(_binPaths['redfishtool']):
|
|
1935
|
+
host.command = host.command.replace(_binPaths['redfishtool'],'')
|
|
1903
1936
|
if not host.command:
|
|
1904
|
-
host.command = '
|
|
1937
|
+
host.command = 'Systems'
|
|
1938
|
+
ipmi_args = ipmi_definition.get('args','')
|
|
1939
|
+
if 'sh' in _binPaths:
|
|
1940
|
+
formatedCMD = [_binPaths['sh'],'-c',f'redfishtool -S Always -a -r {host.address} -u {ipmi_definition.get("username",username)} -p {ipmi_definition.get("password",passwds)} {ipmi_args} {host.command}']
|
|
1905
1941
|
else:
|
|
1906
|
-
|
|
1907
|
-
run_command(host,sem,timeout,prePasword,retry_limit=retry_limit - 1,ipmi_args=ipmi_args)
|
|
1908
|
-
return
|
|
1942
|
+
formatedCMD = [_binPaths['redfishtool'],'-S', 'Always','-a','-r',host.address,'-u',ipmi_definition.get("username",username),'-p',ipmi_definition.get("password",passwds)] + [f'-{s}' for s in ipmi_args.split('-') if s] + [host.command]
|
|
1909
1943
|
else:
|
|
1910
|
-
host.output.append('
|
|
1911
|
-
host.stderr.append('
|
|
1944
|
+
host.output.append(f'IPMI method {ipmi_definition.get("ipmi_method","None")} not supported!')
|
|
1945
|
+
host.stderr.append(f'IPMI method {ipmi_definition.get("ipmi_method","None")} not supported!')
|
|
1912
1946
|
host.returncode = 1
|
|
1913
1947
|
return
|
|
1914
1948
|
elif host.shell:
|
|
@@ -1923,7 +1957,7 @@ def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,ipmi_args =
|
|
|
1923
1957
|
host.stderr.append('shell not found on the local machine! Using ssh localhost instead...')
|
|
1924
1958
|
host.shell = False
|
|
1925
1959
|
host.name = 'localhost'
|
|
1926
|
-
run_command(host,sem,timeout,
|
|
1960
|
+
run_command(host,sem,timeout,passwds,retry_limit=retry_limit - 1,ipmi_definitions_list=ipmi_definitions_list)
|
|
1927
1961
|
else:
|
|
1928
1962
|
if host.files:
|
|
1929
1963
|
if host.scp:
|
|
@@ -1956,11 +1990,11 @@ def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,ipmi_args =
|
|
|
1956
1990
|
else:
|
|
1957
1991
|
fileArgs = host.files + [f'{host.resolvedName}:{host.command}']
|
|
1958
1992
|
if useScp:
|
|
1959
|
-
formatedCMD = [_binPaths['scp'],'-rp'] +
|
|
1993
|
+
formatedCMD = [_binPaths['scp'],'-rp'] + sshLocalExtraArgs + extraargs +['--']+fileArgs
|
|
1960
1994
|
else:
|
|
1961
1995
|
formatedCMD = [_binPaths['rsync'],'-ahlX','--partial','--inplace', '--info=name'] + rsyncLocalExtraArgs + extraargs +['--']+fileArgs
|
|
1962
1996
|
else:
|
|
1963
|
-
formatedCMD = [_binPaths['ssh']] +
|
|
1997
|
+
formatedCMD = [_binPaths['ssh']] + sshLocalExtraArgs + extraargs +['--']+ [host.resolvedName, host.command]
|
|
1964
1998
|
if passwds and 'sshpass' in _binPaths:
|
|
1965
1999
|
formatedCMD = [_binPaths['sshpass'], '-p', passwds] + formatedCMD
|
|
1966
2000
|
elif passwds:
|
|
@@ -2077,7 +2111,7 @@ def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,ipmi_args =
|
|
|
2077
2111
|
host.output.append("Warning: Too many open files. retrying...")
|
|
2078
2112
|
# Handle the error, e.g., clean up, retry logic, or exit
|
|
2079
2113
|
time.sleep(0.1)
|
|
2080
|
-
run_command(host,sem,timeout,
|
|
2114
|
+
run_command(host,sem,timeout,passwds,retry_limit=retry_limit - 1,ipmi_definitions_list=ipmi_definitions_list)
|
|
2081
2115
|
else:
|
|
2082
2116
|
# Re-raise the exception if it's not the specific one
|
|
2083
2117
|
raise
|
|
@@ -2088,39 +2122,47 @@ def run_command(host, sem, timeout=60,passwds=None, retry_limit = 7,ipmi_args =
|
|
|
2088
2122
|
host.stderr.extend(traceback.format_exc().split('\n'))
|
|
2089
2123
|
host.output.extend(traceback.format_exc().split('\n'))
|
|
2090
2124
|
host.returncode = -1
|
|
2091
|
-
# If using ipmi, we will try again using
|
|
2092
|
-
if host.ipmi and host.returncode != 0
|
|
2125
|
+
# If using ipmi, we will try again using next ipmi definition if ipmi connection is not successful
|
|
2126
|
+
if host.ipmi and host.returncode != 0:
|
|
2093
2127
|
host.returncode = None
|
|
2094
|
-
host.
|
|
2095
|
-
if
|
|
2096
|
-
|
|
2097
|
-
host.output.append(f'IPMI connection failed with arg {ipmi_args}! Trying DEFAULT_IPMI_ARGS:{DEAFULT_IPMI_ARGS}')
|
|
2098
|
-
if __DEBUG_MODE:
|
|
2099
|
-
host.stderr.append(f'IPMI connection failed with arg {ipmi_args}! Trying DEFAULT_IPMI_ARGS:{DEAFULT_IPMI_ARGS}')
|
|
2100
|
-
ipmi_args = DEAFULT_IPMI_ARGS
|
|
2101
|
-
else:
|
|
2102
|
-
host.output.append(f'IPMI connection failed with arg {ipmi_args}! Trying without args...')
|
|
2103
|
-
if __DEBUG_MODE:
|
|
2104
|
-
host.stderr.append(f'IPMI connection failed with arg {ipmi_args}! Trying without args...')
|
|
2105
|
-
ipmi_args = ''
|
|
2128
|
+
host.output.append('IPMI connection failed! Trying next ipmi definition...')
|
|
2129
|
+
if __DEBUG_MODE:
|
|
2130
|
+
host.stderr.append('IPMI connection failed! Trying next ipmi definition...')
|
|
2106
2131
|
else:
|
|
2107
|
-
host.
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2132
|
+
host.stdout = []
|
|
2133
|
+
host.stderr = []
|
|
2134
|
+
if ipmi_definition.get('retry_lockout_time'):
|
|
2135
|
+
try:
|
|
2136
|
+
sleep_seconds = int(ipmi_definition.get('retry_lockout_time'))
|
|
2137
|
+
if sleep_seconds >= 0:
|
|
2138
|
+
host.output.append(f'Sleeping for {sleep_seconds} seconds...')
|
|
2139
|
+
if __DEBUG_MODE:
|
|
2140
|
+
host.stderr.append(f'Sleeping for {sleep_seconds} seconds...')
|
|
2141
|
+
time.sleep(sleep_seconds)
|
|
2142
|
+
except Exception as e:
|
|
2143
|
+
host.output.append(f'Error: Failed to sleep for {ipmi_definition.get("retry_lockout_time")} seconds! {e}')
|
|
2144
|
+
if __DEBUG_MODE:
|
|
2145
|
+
host.stderr.append(f'Error: Failed to sleep for {ipmi_definition.get("retry_lockout_time")} seconds! {e}')
|
|
2146
|
+
time.sleep(DEFAULT_IPMI_RETRY_LOCKOUT_TIME)
|
|
2147
|
+
if ipmi_definition.get('ipmi_method') == 'ipmitool':
|
|
2148
|
+
if ipmi_definition.get('interface_ip_prefix') == DEFAULT_IPMI_INTERFACE_IP_PREFIX:
|
|
2149
|
+
ipmi_definition['interface_ip_prefix'] = DEFAULT_INTERFACE_IP_PREFIX
|
|
2150
|
+
ipmi_definition['username'] = username
|
|
2151
|
+
ipmi_definition['password'] = passwds
|
|
2152
|
+
ipmi_definition['ipmi_method'] = 'ssh_ipmitool'
|
|
2153
|
+
ipmi_definitions_list.append(ipmi_definition)
|
|
2154
|
+
run_command(host,sem,timeout,passwds,retry_limit=retry_limit - 1,ipmi_definitions_list=ipmi_definitions_list)
|
|
2114
2155
|
# If transfering files, we will try again using scp if rsync connection is not successful
|
|
2115
2156
|
elif host.files and not host.scp and not useScp and host.returncode != 0 and host.stderr:
|
|
2116
2157
|
host.returncode = None
|
|
2117
|
-
host.stderr = []
|
|
2118
|
-
host.stdout = []
|
|
2119
2158
|
host.output.append('Rsync connection failed! Trying SCP connection...')
|
|
2120
2159
|
if __DEBUG_MODE:
|
|
2121
2160
|
host.stderr.append('Rsync connection failed! Trying SCP connection...')
|
|
2161
|
+
else:
|
|
2162
|
+
host.stdout = []
|
|
2163
|
+
host.stderr = []
|
|
2122
2164
|
host.scp = True
|
|
2123
|
-
run_command(host,sem,timeout,
|
|
2165
|
+
run_command(host,sem,timeout,passwds,retry_limit=retry_limit - 1,ipmi_definitions_list=ipmi_definitions_list)
|
|
2124
2166
|
|
|
2125
2167
|
#%% ------------ Start Threading Block ----------------
|
|
2126
2168
|
def start_run_on_hosts(hosts, timeout=60,password=None,max_connections=4 * os.cpu_count()):
|
|
@@ -3378,16 +3420,35 @@ def formHostStr(host) -> str:
|
|
|
3378
3420
|
return ','.join(compact_hostnames(host))
|
|
3379
3421
|
|
|
3380
3422
|
@cache_decorator
|
|
3381
|
-
def __formCommandArgStr(
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3423
|
+
def __formCommandArgStr(shortend = False, **kwargs) -> str:
|
|
3424
|
+
oneonone = kwargs.get('oneonone', DEFAULT_ONE_ON_ONE)
|
|
3425
|
+
timeout = kwargs.get('timeout', DEFAULT_TIMEOUT)
|
|
3426
|
+
password = kwargs.get('password', DEFAULT_PASSWORD)
|
|
3427
|
+
no_watch = kwargs.get('no_watch', DEFAULT_NO_WATCH)
|
|
3428
|
+
json = kwargs.get('json', DEFAULT_JSON_MODE)
|
|
3429
|
+
max_connections = kwargs.get('max_connections', DEFAULT_MAX_CONNECTIONS)
|
|
3430
|
+
file = kwargs.get('file', None)
|
|
3431
|
+
ipmi = kwargs.get('ipmi', DEFAULT_IPMI)
|
|
3432
|
+
interface_ip_prefix = kwargs.get('interface_ip_prefix', DEFAULT_INTERFACE_IP_PREFIX)
|
|
3433
|
+
scp = kwargs.get('scp', DEFAULT_SCP)
|
|
3434
|
+
gather_mode = kwargs.get('gather_mode', False)
|
|
3435
|
+
username = kwargs.get('username', DEFAULT_USERNAME)
|
|
3436
|
+
extraargs = kwargs.get('extraargs', DEFAULT_EXTRA_ARGS)
|
|
3437
|
+
skip_unreachable = kwargs.get('skip_unreachable', DEFAULT_SKIP_UNREACHABLE)
|
|
3438
|
+
no_env = kwargs.get('no_env', DEFAULT_NO_ENV)
|
|
3439
|
+
greppable = kwargs.get('greppable', DEFAULT_GREPPABLE_MODE)
|
|
3440
|
+
skip_hosts = kwargs.get('skip_hosts', DEFAULT_SKIP_HOSTS)
|
|
3441
|
+
file_sync = kwargs.get('file_sync', False)
|
|
3442
|
+
error_only = kwargs.get('error_only', DEFAULT_ERROR_ONLY)
|
|
3443
|
+
identity_file = kwargs.get('identity_file', DEFAULT_IDENTITY_FILE)
|
|
3444
|
+
copy_id = kwargs.get('copy_id', False)
|
|
3445
|
+
unavailable_host_expiry = kwargs.get('unavailable_host_expiry', DEFAULT_UNAVAILABLE_HOST_EXPIRY)
|
|
3446
|
+
no_history = kwargs.get('no_history', DEFAULT_NO_HISTORY)
|
|
3447
|
+
history_file = kwargs.get('history_file', DEFAULT_HISTORY_FILE)
|
|
3448
|
+
env_file = kwargs.get('env_file', '')
|
|
3449
|
+
env_files = kwargs.get('env_files', DEFAULT_ENV_FILES)
|
|
3450
|
+
repeat = kwargs.get('repeat', DEFAULT_REPEAT)
|
|
3451
|
+
interval = kwargs.get('interval', DEFAULT_INTERVAL)
|
|
3391
3452
|
argsList = []
|
|
3392
3453
|
if oneonone:
|
|
3393
3454
|
argsList.append('--oneonone' if not shortend else '-11')
|
|
@@ -3449,37 +3510,22 @@ def __formCommandArgStr(oneonone = DEFAULT_ONE_ON_ONE, timeout = DEFAULT_TIMEOUT
|
|
|
3449
3510
|
argsList.append('--file_sync' if not shortend else '-fs')
|
|
3450
3511
|
return ' '.join(argsList)
|
|
3451
3512
|
|
|
3452
|
-
def getStrCommand(hosts = DEFAULT_HOSTS,commands = None,
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
single_window = DEFAULT_SINGLE_WINDOW,file_sync = False,error_only = DEFAULT_ERROR_ONLY, identity_file = DEFAULT_IDENTITY_FILE,
|
|
3459
|
-
copy_id = False, unavailable_host_expiry = DEFAULT_UNAVAILABLE_HOST_EXPIRY,no_history = DEFAULT_NO_HISTORY,
|
|
3460
|
-
history_file = DEFAULT_HISTORY_FILE, env_file = '', env_files = [],
|
|
3461
|
-
repeat = DEFAULT_REPEAT,interval = DEFAULT_INTERVAL,
|
|
3462
|
-
shortend = False,tabSeperated = False,**kwargs) -> str:
|
|
3463
|
-
_ = called
|
|
3464
|
-
_ = return_unfinished
|
|
3465
|
-
_ = will_update_unreachable_hosts
|
|
3466
|
-
_ = no_start
|
|
3467
|
-
_ = window_width
|
|
3468
|
-
_ = window_height
|
|
3469
|
-
_ = single_window
|
|
3513
|
+
def getStrCommand(hosts = DEFAULT_HOSTS,commands = None,shortend = False,tabSeperated = False,**kwargs) -> str:
|
|
3514
|
+
# Allow explicit kwargs to override base parameters when forwarding dicts.
|
|
3515
|
+
hosts = kwargs.get('hosts', hosts)
|
|
3516
|
+
commands = kwargs.get('commands', commands)
|
|
3517
|
+
shortend = kwargs.get('shortend', shortend)
|
|
3518
|
+
tabSeperated = kwargs.get('tabSeperated', tabSeperated)
|
|
3470
3519
|
hosts = hosts if isinstance(hosts,str) else frozenset(hosts)
|
|
3471
3520
|
hostStr = formHostStr(hosts)
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
history_file = history_file, env_file = env_file, env_files = env_files,
|
|
3481
|
-
repeat = repeat,interval = interval,
|
|
3482
|
-
shortend = shortend)
|
|
3521
|
+
commandArgKwargs = dict(kwargs)
|
|
3522
|
+
commandArgKwargs.pop('hosts', None)
|
|
3523
|
+
commandArgKwargs.pop('commands', None)
|
|
3524
|
+
commandArgKwargs.pop('shortend', None)
|
|
3525
|
+
commandArgKwargs.pop('tabSeperated', None)
|
|
3526
|
+
if commandArgKwargs.get('file'):
|
|
3527
|
+
commandArgKwargs['file'] = frozenset(commandArgKwargs['file'])
|
|
3528
|
+
argsStr = __formCommandArgStr(shortend = shortend, **commandArgKwargs)
|
|
3483
3529
|
commands = [command.replace('"', '\\"').replace('\n', '\\n').replace('\t', '\\t') for command in format_commands(commands)]
|
|
3484
3530
|
commandStr = '"' + '" "'.join(commands) + '"' if commands else ''
|
|
3485
3531
|
filePath = os.path.abspath(__file__)
|
|
@@ -3503,15 +3549,11 @@ def record_command_history(kwargs):
|
|
|
3503
3549
|
global __global_suppress_printout
|
|
3504
3550
|
global __DEBUG_MODE
|
|
3505
3551
|
try:
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
for name in sig.parameters
|
|
3512
|
-
if name in kwargs
|
|
3513
|
-
}
|
|
3514
|
-
strCommand = getStrCommand(**wanted,shortend=True,tabSeperated=True)
|
|
3552
|
+
historyKwargs = dict(kwargs)
|
|
3553
|
+
historyKwargs['shortend'] = True
|
|
3554
|
+
historyKwargs['tabSeperated'] = True
|
|
3555
|
+
history_file = os.path.expanduser(historyKwargs.get('history_file', DEFAULT_HISTORY_FILE))
|
|
3556
|
+
strCommand = getStrCommand(**historyKwargs)
|
|
3515
3557
|
with open(history_file, 'a') as f:
|
|
3516
3558
|
# it follows <timestamp>\t<strCommand>\n
|
|
3517
3559
|
f.write(f'{int(time.time())}\t{strCommand}\n')
|
|
@@ -3867,10 +3909,13 @@ def generate_default_config(args):
|
|
|
3867
3909
|
'DEFAULT_INTERVAL': args.interval,
|
|
3868
3910
|
'DEFAULT_IPMI': args.ipmi,
|
|
3869
3911
|
'DEFAULT_IPMI_INTERFACE_IP_PREFIX': args.ipmi_interface_ip_prefix,
|
|
3870
|
-
'DEFAULT_INTERFACE_IP_PREFIX': args.interface_ip_prefix,
|
|
3871
3912
|
'DEFAULT_IPMI_USERNAME': args.ipmi_username,
|
|
3872
3913
|
'DEFAULT_IPMI_PASSWORD': args.ipmi_password,
|
|
3873
3914
|
'DEAFULT_IPMI_ARGS': args.ipmi_args,
|
|
3915
|
+
'DEFAULT_IPMI_METHOD': args.ipmi_method,
|
|
3916
|
+
'DEFAULT_IPMI_RETRY_LOCKOUT_TIME': args.ipmi_retry_lockout_time,
|
|
3917
|
+
'DEFAULT_INTERFACE_IP_PREFIX': args.interface_ip_prefix,
|
|
3918
|
+
'DEFAULT_IPMI_DEFINITIONS': DEFAULT_IPMI_DEFINITIONS,
|
|
3874
3919
|
'DEFAULT_NO_WATCH': args.no_watch,
|
|
3875
3920
|
'DEFAULT_WINDOW_WIDTH': args.window_width,
|
|
3876
3921
|
'DEFAULT_WINDOW_HEIGHT': args.window_height,
|
|
@@ -3891,10 +3936,7 @@ def generate_default_config(args):
|
|
|
3891
3936
|
'DEFAULT_HOST_FILE': args.host_file,
|
|
3892
3937
|
'DEFAULT_ENCODING': args.encoding,
|
|
3893
3938
|
'DEFAULT_DIFF_DISPLAY_THRESHOLD': args.diff_display_threshold,
|
|
3894
|
-
'SSH_STRICT_HOST_KEY_CHECKING': SSH_STRICT_HOST_KEY_CHECKING,
|
|
3895
|
-
'ERROR_MESSAGES_TO_IGNORE': ERROR_MESSAGES_TO_IGNORE,
|
|
3896
3939
|
'FORCE_TRUECOLOR': args.force_truecolor,
|
|
3897
|
-
'POSSIBLE_SSH_KEY_FILES': POSSIBLE_SSH_KEY_FILES,
|
|
3898
3940
|
}
|
|
3899
3941
|
|
|
3900
3942
|
def write_default_config(args,CONFIG_FILE = None, force = False):
|
|
@@ -3951,11 +3993,11 @@ def get_parser():
|
|
|
3951
3993
|
)
|
|
3952
3994
|
parser.add_argument('hosts', metavar='hosts', type=str, nargs='?', help=f'Hosts to run the command on, use "," to seperate hosts. (default: {DEFAULT_HOSTS})',default=DEFAULT_HOSTS)
|
|
3953
3995
|
parser.add_argument('commands', metavar='commands', type=str, nargs='*',default=None,help='the command to run on the hosts / the destination of the files #HOST# or #HOSTNAME# will be replaced with the host name.')
|
|
3954
|
-
parser.add_argument('-u','--username', type=str,help=f'The general username to use to connect to the hosts. Will get overwrote by individual username@host if specified. (default: {DEFAULT_USERNAME})',default=DEFAULT_USERNAME)
|
|
3955
|
-
parser.add_argument('-p', '--password', type=str,help=f'The password to use to connect to the hosts, (default: {DEFAULT_PASSWORD})',default=DEFAULT_PASSWORD)
|
|
3996
|
+
parser.add_argument('-u','--username', type=str,help=f'The general username to use to connect to the hosts via ssh. Will get overwrote by individual username@host if specified. (default: {DEFAULT_USERNAME})',default=DEFAULT_USERNAME)
|
|
3997
|
+
parser.add_argument('-p', '--password', type=str,help=f'The password to use to connect to the hosts via ssh, (default: {DEFAULT_PASSWORD})',default=DEFAULT_PASSWORD)
|
|
3956
3998
|
parser.add_argument('-k','--identity_file','--key','--identity',nargs='?', type=str,help=f'The identity file to use to connect to the hosts. Implies --use_key. Specify a folder for program to search for a key. Use option without value to use {DEFAULT_SSH_KEY_SEARCH_PATH} (default: {DEFAULT_IDENTITY_FILE})',const=DEFAULT_SSH_KEY_SEARCH_PATH,default=DEFAULT_IDENTITY_FILE)
|
|
3957
3999
|
parser.add_argument('-uk','--use_key', action='store_true', help=f'Attempt to use public key file to connect to the hosts. (default: {DEFAULT_USE_KEY})', default=DEFAULT_USE_KEY)
|
|
3958
|
-
parser.add_argument('-ea','--extraargs',type=str,help=f'Extra arguments to pass to the ssh / rsync / scp command. Put in one string for multiple arguments.Use "=" ! Ex. -ea="--delete" (default: {DEFAULT_EXTRA_ARGS})',default=DEFAULT_EXTRA_ARGS)
|
|
4000
|
+
parser.add_argument('-ea','--extraargs',type=str,help=f'Extra arguments to pass to the ssh / rsync / scp command. (Use -ia for ipmi arguments) Put in one string for multiple arguments.Use "=" ! Ex. -ea="--delete" (default: {DEFAULT_EXTRA_ARGS})',default=DEFAULT_EXTRA_ARGS)
|
|
3959
4001
|
parser.add_argument("-11",'--oneonone', action='store_true', help=f"Run one corresponding command on each host. (default: {DEFAULT_ONE_ON_ONE})", default=DEFAULT_ONE_ON_ONE)
|
|
3960
4002
|
parser.add_argument("-f","--file", action='append', help="The file to be copied to the hosts. Use -f multiple times to copy multiple files")
|
|
3961
4003
|
parser.add_argument('-s','-fs','--file_sync',nargs='?', action='append', help=f'Operate in file sync mode, sync path in <COMMANDS> from this machine to <HOSTS>. Treat --file <FILE> and <COMMANDS> both as source and source and destination will be the same in this mode. Infer destination from source path. (default: {DEFAULT_FILE_SYNC})',const=True, default=[DEFAULT_FILE_SYNC])
|
|
@@ -3971,7 +4013,9 @@ def get_parser():
|
|
|
3971
4013
|
parser.add_argument("-pre","--interface_ip_prefix", type=str, help=f"The prefix of the for the interfaces (default: {DEFAULT_INTERFACE_IP_PREFIX})", default=DEFAULT_INTERFACE_IP_PREFIX)
|
|
3972
4014
|
parser.add_argument('-iu','--ipmi_username', type=str,help=f'The username to use to connect to the hosts via ipmi. (default: {DEFAULT_IPMI_USERNAME})',default=DEFAULT_IPMI_USERNAME)
|
|
3973
4015
|
parser.add_argument('-ip','--ipmi_password', type=str,help=f'The password to use to connect to the hosts via ipmi. (default: {DEFAULT_IPMI_PASSWORD})',default=DEFAULT_IPMI_PASSWORD)
|
|
3974
|
-
parser.add_argument('-ia','--ipmi_args',type=str,help=f'The arguments passed to ipmitool to use to connect to the hosts via ipmi. (default: {
|
|
4016
|
+
parser.add_argument('-ia','--ipmi_args',type=str,help=f'The arguments passed to ipmitool to use to connect to the hosts via ipmi. (default: {DEFAULT_IPMI_ARGS})',default=DEFAULT_IPMI_ARGS)
|
|
4017
|
+
parser.add_argument('-im','--ipmi_method', type=str,help=f'The method to use to connect to the hosts via ipmi. (default: {DEFAULT_IPMI_METHOD})',default=DEFAULT_IPMI_METHOD)
|
|
4018
|
+
parser.add_argument('-irlt','--ipmi_retry_lockout_time', type=int,help=f'The time in seconds to retry the lockout of the hosts via ipmi. (default: {DEFAULT_IPMI_RETRY_LOCKOUT_TIME})',default=DEFAULT_IPMI_RETRY_LOCKOUT_TIME)
|
|
3975
4019
|
parser.add_argument('-S',"-q","-nw","--no_watch", action='store_true', help=f"Quiet mode, no curses watch, only print the output. (default: {DEFAULT_NO_WATCH})", default=DEFAULT_NO_WATCH)
|
|
3976
4020
|
parser.add_argument("-ww",'--window_width', type=int, help=f"The minimum character length of the curses window. (default: {DEFAULT_WINDOW_WIDTH})", default=DEFAULT_WINDOW_WIDTH)
|
|
3977
4021
|
parser.add_argument("-wh",'--window_height', type=int, help=f"The minimum line height of the curses window. (default: {DEFAULT_WINDOW_HEIGHT})", default=DEFAULT_WINDOW_HEIGHT)
|
|
@@ -4008,8 +4052,6 @@ def get_parser():
|
|
|
4008
4052
|
return parser
|
|
4009
4053
|
|
|
4010
4054
|
def process_args(args = None):
|
|
4011
|
-
global DEFAULT_IPMI_USERNAME
|
|
4012
|
-
global DEFAULT_IPMI_PASSWORD
|
|
4013
4055
|
global __configs_from_file
|
|
4014
4056
|
cfp = parser = argparse.ArgumentParser(add_help=False)
|
|
4015
4057
|
cfp.add_argument('--config_file', type=str,nargs='?',const='multiSSH3.config.json',default=None)
|
|
@@ -4067,7 +4109,27 @@ def process_args(args = None):
|
|
|
4067
4109
|
if args.unavailable_host_expiry <= 0:
|
|
4068
4110
|
eprint(f"Warning: The unavailable host expiry time {args.unavailable_host_expiry} is less than 0, setting it to 10 seconds.")
|
|
4069
4111
|
args.unavailable_host_expiry = 10
|
|
4070
|
-
|
|
4112
|
+
default_ipmi_definition = get_default_ipmi_definition()
|
|
4113
|
+
while DEFAULT_IPMI_DEFINITIONS:
|
|
4114
|
+
last_definition = DEFAULT_IPMI_DEFINITIONS.pop()
|
|
4115
|
+
if last_definition != default_ipmi_definition:
|
|
4116
|
+
DEFAULT_IPMI_DEFINITIONS.append(last_definition)
|
|
4117
|
+
break
|
|
4118
|
+
fields = [
|
|
4119
|
+
('interface_ip_prefix', args.ipmi_interface_ip_prefix),
|
|
4120
|
+
('username', args.ipmi_username),
|
|
4121
|
+
('password', args.ipmi_password),
|
|
4122
|
+
('args', args.ipmi_args),
|
|
4123
|
+
('ipmi_method', args.ipmi_method),
|
|
4124
|
+
('retry_lockout_time', args.ipmi_retry_lockout_time),
|
|
4125
|
+
]
|
|
4126
|
+
modified = any(val != default_ipmi_definition[key] for key, val in fields)
|
|
4127
|
+
for key, val in fields:
|
|
4128
|
+
default_ipmi_definition[key] = val
|
|
4129
|
+
if modified:
|
|
4130
|
+
DEFAULT_IPMI_DEFINITIONS.insert(0, default_ipmi_definition)
|
|
4131
|
+
else:
|
|
4132
|
+
DEFAULT_IPMI_DEFINITIONS.append(default_ipmi_definition)
|
|
4071
4133
|
return args
|
|
4072
4134
|
|
|
4073
4135
|
def process_config_file(args):
|
|
@@ -4150,19 +4212,14 @@ def process_control_master_config(args):
|
|
|
4150
4212
|
|
|
4151
4213
|
def set_global_with_args(args):
|
|
4152
4214
|
global _emo
|
|
4153
|
-
global __ipmiiInterfaceIPPrefix
|
|
4154
4215
|
global _env_files
|
|
4155
4216
|
global __DEBUG_MODE
|
|
4156
4217
|
global _encoding
|
|
4157
4218
|
global __returnZero
|
|
4158
|
-
global DEFAULT_IPMI_USERNAME
|
|
4159
|
-
global DEFAULT_IPMI_PASSWORD
|
|
4160
4219
|
global DEFAULT_DIFF_DISPLAY_THRESHOLD
|
|
4161
4220
|
global FORCE_TRUECOLOR
|
|
4162
4221
|
global DEFAULT_HOST_FILE
|
|
4163
|
-
global __ipmi_args
|
|
4164
4222
|
_emo = False
|
|
4165
|
-
__ipmiiInterfaceIPPrefix = args.ipmi_interface_ip_prefix
|
|
4166
4223
|
if args.env_file:
|
|
4167
4224
|
_env_files = [args.env_file]
|
|
4168
4225
|
else:
|
|
@@ -4171,15 +4228,10 @@ def set_global_with_args(args):
|
|
|
4171
4228
|
_encoding = args.encoding
|
|
4172
4229
|
if args.return_zero:
|
|
4173
4230
|
__returnZero = True
|
|
4174
|
-
if args.ipmi_username:
|
|
4175
|
-
DEFAULT_IPMI_USERNAME = args.ipmi_username
|
|
4176
|
-
if args.ipmi_password:
|
|
4177
|
-
DEFAULT_IPMI_PASSWORD = args.ipmi_password
|
|
4178
4231
|
DEFAULT_DIFF_DISPLAY_THRESHOLD = args.diff_display_threshold
|
|
4179
4232
|
FORCE_TRUECOLOR = args.force_truecolor
|
|
4180
4233
|
if args.host_file:
|
|
4181
4234
|
DEFAULT_HOST_FILE = args.host_file
|
|
4182
|
-
__ipmi_args = args.ipmi_args
|
|
4183
4235
|
|
|
4184
4236
|
#%% ------------ Wrapper Block ----------------
|
|
4185
4237
|
def main(args = None):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|