multiSSH3 4.99__tar.gz → 5.4__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.
Potentially problematic release.
This version of multiSSH3 might be problematic. Click here for more details.
- {multissh3-4.99 → multissh3-5.4}/PKG-INFO +1 -1
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.egg-info/PKG-INFO +1 -1
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.py +115 -36
- {multissh3-4.99 → multissh3-5.4}/setup.py +1 -1
- {multissh3-4.99 → multissh3-5.4}/LICENSE +0 -0
- {multissh3-4.99 → multissh3-5.4}/README.md +0 -0
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.egg-info/SOURCES.txt +0 -0
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.egg-info/dependency_links.txt +0 -0
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.egg-info/entry_points.txt +0 -0
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.egg-info/requires.txt +0 -0
- {multissh3-4.99 → multissh3-5.4}/multiSSH3.egg-info/top_level.txt +0 -0
- {multissh3-4.99 → multissh3-5.4}/setup.cfg +0 -0
|
@@ -18,6 +18,7 @@ import glob
|
|
|
18
18
|
import shutil
|
|
19
19
|
import getpass
|
|
20
20
|
import uuid
|
|
21
|
+
import tempfile
|
|
21
22
|
|
|
22
23
|
try:
|
|
23
24
|
# Check if functiools.cache is available
|
|
@@ -30,7 +31,7 @@ except AttributeError:
|
|
|
30
31
|
# If neither is available, use a dummy decorator
|
|
31
32
|
def cache_decorator(func):
|
|
32
33
|
return func
|
|
33
|
-
version = '
|
|
34
|
+
version = '5.04'
|
|
34
35
|
VERSION = version
|
|
35
36
|
|
|
36
37
|
CONFIG_FILE = '/etc/multiSSH3.config.json'
|
|
@@ -94,7 +95,7 @@ __build_in_default_config = {
|
|
|
94
95
|
'DEFAULT_JSON_MODE': False,
|
|
95
96
|
'DEFAULT_PRINT_SUCCESS_HOSTS': False,
|
|
96
97
|
'DEFAULT_GREPPABLE_MODE': False,
|
|
97
|
-
'DEFAULT_SKIP_UNREACHABLE':
|
|
98
|
+
'DEFAULT_SKIP_UNREACHABLE': True,
|
|
98
99
|
'DEFAULT_SKIP_HOSTS': '',
|
|
99
100
|
'SSH_STRICT_HOST_KEY_CHECKING': False,
|
|
100
101
|
'ERROR_MESSAGES_TO_IGNORE': [
|
|
@@ -179,7 +180,7 @@ __DEBUG_MODE = __configs_from_file.get('__DEBUG_MODE', __build_in_default_config
|
|
|
179
180
|
|
|
180
181
|
|
|
181
182
|
|
|
182
|
-
__global_suppress_printout =
|
|
183
|
+
__global_suppress_printout = False
|
|
183
184
|
|
|
184
185
|
__mainReturnCode = 0
|
|
185
186
|
__failedHosts = set()
|
|
@@ -979,7 +980,14 @@ def get_hosts_to_display (hosts, max_num_hosts, hosts_to_display = None):
|
|
|
979
980
|
host.printedLines = 0
|
|
980
981
|
return new_hosts_to_display , {'running':len(running_hosts), 'failed':len(failed_hosts), 'finished':len(finished_hosts), 'waiting':len(waiting_hosts)}
|
|
981
982
|
|
|
982
|
-
|
|
983
|
+
# Error: integer division or modulo by zero, Reloading Configuration: min_char_len=40, min_line_len=1, single_window=False with window size (61, 186) and 1 hosts...
|
|
984
|
+
# Traceback (most recent call last):
|
|
985
|
+
# File "/usr/local/lib/python3.11/site-packages/multiSSH3.py", line 1030, in generate_display
|
|
986
|
+
# host_window_height = max_y // num_hosts_y
|
|
987
|
+
# ~~~~~~^^~~~~~~~~~~~~
|
|
988
|
+
# ZeroDivisionError: integer division or modulo by zero
|
|
989
|
+
|
|
990
|
+
def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_char_len = DEFAULT_CURSES_MINIMUM_CHAR_LEN, min_line_len = DEFAULT_CURSES_MINIMUM_LINE_LEN,single_window=DEFAULT_SINGLE_WINDOW, config_reason= 'New Configuration'):
|
|
983
991
|
try:
|
|
984
992
|
org_dim = stdscr.getmaxyx()
|
|
985
993
|
new_configured = True
|
|
@@ -995,9 +1003,9 @@ def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_c
|
|
|
995
1003
|
min_line_len_local = max_y-1
|
|
996
1004
|
# return True if the terminal is too small
|
|
997
1005
|
if max_x < 2 or max_y < 2:
|
|
998
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1006
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Terminal too small')
|
|
999
1007
|
if min_char_len_local < 1 or min_line_len_local < 1:
|
|
1000
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1008
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Minimum character or line length too small')
|
|
1001
1009
|
# We need to figure out how many hosts we can fit in the terminal
|
|
1002
1010
|
# We will need at least 2 lines per host, one for its name, one for its output
|
|
1003
1011
|
# Each line will be at least 61 characters long (60 for the output, 1 for the borders)
|
|
@@ -1005,14 +1013,14 @@ def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_c
|
|
|
1005
1013
|
max_num_hosts_y = max_y // (min_line_len_local + 1)
|
|
1006
1014
|
max_num_hosts = max_num_hosts_x * max_num_hosts_y
|
|
1007
1015
|
if max_num_hosts < 1:
|
|
1008
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1016
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Terminal too small to display any hosts')
|
|
1009
1017
|
hosts_to_display , host_stats = get_hosts_to_display(hosts, max_num_hosts)
|
|
1010
1018
|
if len(hosts_to_display) == 0:
|
|
1011
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1019
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'No hosts to display')
|
|
1012
1020
|
# Now we calculate the actual number of hosts we will display for x and y
|
|
1013
1021
|
optimal_len_x = max(min_char_len_local, 80)
|
|
1014
|
-
num_hosts_x = max(min(max_num_hosts_x, max_x // optimal_len_x),1)
|
|
1015
|
-
num_hosts_y = len(hosts_to_display) // num_hosts_x
|
|
1022
|
+
num_hosts_x = min(max(min(max_num_hosts_x, max_x // optimal_len_x),1),len(hosts_to_display))
|
|
1023
|
+
num_hosts_y = len(hosts_to_display) // num_hosts_x + (len(hosts_to_display) % num_hosts_x > 0)
|
|
1016
1024
|
while num_hosts_y > max_num_hosts_y:
|
|
1017
1025
|
num_hosts_x += 1
|
|
1018
1026
|
# round up for num_hosts_y
|
|
@@ -1024,12 +1032,12 @@ def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_c
|
|
|
1024
1032
|
num_hosts_x += 1
|
|
1025
1033
|
num_hosts_y = len(hosts_to_display) // num_hosts_x + (len(hosts_to_display) % num_hosts_x > 0)
|
|
1026
1034
|
break
|
|
1027
|
-
|
|
1035
|
+
num_hosts_y = max(num_hosts_y,1)
|
|
1028
1036
|
# We calculate the size of each window
|
|
1029
1037
|
host_window_height = max_y // num_hosts_y
|
|
1030
1038
|
host_window_width = max_x // num_hosts_x
|
|
1031
1039
|
if host_window_height < 1 or host_window_width < 1:
|
|
1032
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1040
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Host window too small')
|
|
1033
1041
|
|
|
1034
1042
|
old_stat = ''
|
|
1035
1043
|
old_bottom_stat = ''
|
|
@@ -1070,24 +1078,24 @@ def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_c
|
|
|
1070
1078
|
# with open('keylog.txt','a') as f:
|
|
1071
1079
|
# f.write(str(key)+'\n')
|
|
1072
1080
|
if key == 410: # 410 is the key code for resize
|
|
1073
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1081
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Terminal resize requested')
|
|
1074
1082
|
elif key == 95 and not __keyPressesIn[-1]: # 95 is the key code for _
|
|
1075
1083
|
# if last line is empty, we will reconfigure the wh to be smaller
|
|
1076
1084
|
if min_line_len != 1:
|
|
1077
|
-
return (lineToDisplay,curserPosition , min_char_len , max(min_line_len -1,1), single_window)
|
|
1085
|
+
return (lineToDisplay,curserPosition , min_char_len , max(min_line_len -1,1), single_window, 'Decrease line length')
|
|
1078
1086
|
elif key == 43 and not __keyPressesIn[-1]: # 43 is the key code for +
|
|
1079
1087
|
# if last line is empty, we will reconfigure the wh to be larger
|
|
1080
|
-
return (lineToDisplay,curserPosition , min_char_len , min_line_len +1, single_window)
|
|
1088
|
+
return (lineToDisplay,curserPosition , min_char_len , min_line_len +1, single_window, 'Increase line length')
|
|
1081
1089
|
elif key == 123 and not __keyPressesIn[-1]: # 123 is the key code for {
|
|
1082
1090
|
# if last line is empty, we will reconfigure the ww to be smaller
|
|
1083
1091
|
if min_char_len != 1:
|
|
1084
|
-
return (lineToDisplay,curserPosition , max(min_char_len -1,1), min_line_len, single_window)
|
|
1092
|
+
return (lineToDisplay,curserPosition , max(min_char_len -1,1), min_line_len, single_window, 'Decrease character length')
|
|
1085
1093
|
elif key == 124 and not __keyPressesIn[-1]: # 124 is the key code for |
|
|
1086
1094
|
# if last line is empty, we will toggle the single window mode
|
|
1087
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, not single_window)
|
|
1095
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, not single_window, 'Toggle single window mode')
|
|
1088
1096
|
elif key == 125 and not __keyPressesIn[-1]: # 125 is the key code for }
|
|
1089
1097
|
# if last line is empty, we will reconfigure the ww to be larger
|
|
1090
|
-
return (lineToDisplay,curserPosition , min_char_len +1, min_line_len, single_window)
|
|
1098
|
+
return (lineToDisplay,curserPosition , min_char_len +1, min_line_len, single_window, 'Increase character length')
|
|
1091
1099
|
# We handle positional keys
|
|
1092
1100
|
# if the key is up arrow, we will move the line to display up
|
|
1093
1101
|
elif key == 259: # 259 is the key code for up arrow
|
|
@@ -1146,7 +1154,7 @@ def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_c
|
|
|
1146
1154
|
curserPosition += 1
|
|
1147
1155
|
# reconfigure when the terminal size changes
|
|
1148
1156
|
if org_dim != stdscr.getmaxyx():
|
|
1149
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1157
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Terminal resize detected')
|
|
1150
1158
|
# We generate the aggregated stats if user did not input anything
|
|
1151
1159
|
if not __keyPressesIn[lineToDisplay]:
|
|
1152
1160
|
stats = '┍'+ f" Total: {len(hosts)} Running: {host_stats['running']} Failed: {host_stats['failed']} Finished: {host_stats['finished']} Waiting: {host_stats['waiting']} ww: {min_char_len} wh:{min_line_len} "[:max_x - 2].center(max_x - 2, "━")
|
|
@@ -1211,11 +1219,12 @@ def generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min_c
|
|
|
1211
1219
|
# print(str(e).strip())
|
|
1212
1220
|
# print(traceback.format_exc().strip())
|
|
1213
1221
|
if org_dim != stdscr.getmaxyx():
|
|
1214
|
-
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window)
|
|
1222
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, 'Terminal resize detected')
|
|
1215
1223
|
new_configured = False
|
|
1216
1224
|
last_refresh_time = time.perf_counter()
|
|
1217
1225
|
except Exception as e:
|
|
1218
|
-
|
|
1226
|
+
import traceback
|
|
1227
|
+
return (lineToDisplay,curserPosition , min_char_len, min_line_len, single_window, f'Error: {str(e)}',traceback.format_exc())
|
|
1219
1228
|
return None
|
|
1220
1229
|
|
|
1221
1230
|
def curses_print(stdscr, hosts, threads, min_char_len = DEFAULT_CURSES_MINIMUM_CHAR_LEN, min_line_len = DEFAULT_CURSES_MINIMUM_LINE_LEN,single_window = DEFAULT_SINGLE_WINDOW):
|
|
@@ -1254,7 +1263,12 @@ def curses_print(stdscr, hosts, threads, min_char_len = DEFAULT_CURSES_MINIMUM_C
|
|
|
1254
1263
|
curses.init_pair(18, curses.COLOR_BLACK, curses.COLOR_BLUE)
|
|
1255
1264
|
curses.init_pair(19, curses.COLOR_BLACK, curses.COLOR_MAGENTA)
|
|
1256
1265
|
curses.init_pair(20, curses.COLOR_BLACK, curses.COLOR_CYAN)
|
|
1257
|
-
|
|
1266
|
+
|
|
1267
|
+
# do not generate display if the output window have a size of zero
|
|
1268
|
+
if stdscr.getmaxyx()[0] < 2 or stdscr.getmaxyx()[1] < 2:
|
|
1269
|
+
return
|
|
1270
|
+
|
|
1271
|
+
params = (-1,0 , min_char_len, min_line_len, single_window,'new config')
|
|
1258
1272
|
while params:
|
|
1259
1273
|
params = generate_display(stdscr, hosts, *params)
|
|
1260
1274
|
if not params:
|
|
@@ -1264,8 +1278,19 @@ def curses_print(stdscr, hosts, threads, min_char_len = DEFAULT_CURSES_MINIMUM_C
|
|
|
1264
1278
|
break
|
|
1265
1279
|
# print the current configuration
|
|
1266
1280
|
stdscr.clear()
|
|
1267
|
-
|
|
1268
|
-
|
|
1281
|
+
try:
|
|
1282
|
+
stdscr.addstr(0, 0, f"{params[5]}, Reloading Configuration: min_char_len={params[2]}, min_line_len={params[3]}, single_window={params[4]} with window size {stdscr.getmaxyx()} and {len(hosts)} hosts...")
|
|
1283
|
+
if len(params) > 6:
|
|
1284
|
+
# traceback is available, print it
|
|
1285
|
+
i = 1
|
|
1286
|
+
for line in params[6].split('\n'):
|
|
1287
|
+
stdscr.addstr(i, 0, line)
|
|
1288
|
+
i += 1
|
|
1289
|
+
stdscr.refresh()
|
|
1290
|
+
except:
|
|
1291
|
+
pass
|
|
1292
|
+
params = params[:5]
|
|
1293
|
+
time.sleep(0.01)
|
|
1269
1294
|
#time.sleep(0.25)
|
|
1270
1295
|
|
|
1271
1296
|
|
|
@@ -1302,9 +1327,10 @@ def print_output(hosts,usejson = False,quiet = False,greppable = False):
|
|
|
1302
1327
|
outputs[hostPrintOut] = [host['name']]
|
|
1303
1328
|
else:
|
|
1304
1329
|
outputs[hostPrintOut].append(host['name'])
|
|
1305
|
-
rtnStr = ''
|
|
1330
|
+
rtnStr = '*'*80+'\n'
|
|
1306
1331
|
for output, hosts in outputs.items():
|
|
1307
1332
|
rtnStr += f"{','.join(hosts)}{output}\n"
|
|
1333
|
+
rtnStr += '*'*80+'\n'
|
|
1308
1334
|
if __keyPressesIn[-1]:
|
|
1309
1335
|
CMDsOut = [''.join(cmd).encode('unicode_escape').decode().replace('\\n', '↵') for cmd in __keyPressesIn if cmd]
|
|
1310
1336
|
rtnStr += 'User Inputs: '+ '\nUser Inputs: '.join(CMDsOut)
|
|
@@ -1416,13 +1442,45 @@ def processRunOnHosts(timeout, password, max_connections, hosts, returnUnfinishe
|
|
|
1416
1442
|
thread.join(timeout=3)
|
|
1417
1443
|
# update the unavailable hosts and global unavailable hosts
|
|
1418
1444
|
if willUpdateUnreachableHosts:
|
|
1445
|
+
unavailableHosts = set(unavailableHosts)
|
|
1419
1446
|
unavailableHosts.update([host.name for host in hosts if host.stderr and ('No route to host' in host.stderr[0].strip() or host.stderr[0].strip().startswith('Timeout!'))])
|
|
1447
|
+
# reachable hosts = all hosts - unreachable hosts
|
|
1448
|
+
reachableHosts = set([host.name for host in hosts]) - unavailableHosts
|
|
1420
1449
|
if __DEBUG_MODE:
|
|
1421
1450
|
print(f'Unreachable hosts: {unavailableHosts}')
|
|
1422
1451
|
__globalUnavailableHosts.update(unavailableHosts)
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1452
|
+
|
|
1453
|
+
# os.environ['__multiSSH3_UNAVAILABLE_HOSTS'] = ','.join(unavailableHosts)
|
|
1454
|
+
# create a temporary file to store the unavailable hosts
|
|
1455
|
+
try:
|
|
1456
|
+
# check for the old content, only update if the new content is different
|
|
1457
|
+
if not os.path.exists(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv')):
|
|
1458
|
+
with open(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv'),'w') as f:
|
|
1459
|
+
f.write(f',{int(time.time())}\n'.join(unavailableHosts) + f',{int(time.time())}\n')
|
|
1460
|
+
else:
|
|
1461
|
+
oldDic = {}
|
|
1462
|
+
try:
|
|
1463
|
+
with open(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv'),'r') as f:
|
|
1464
|
+
for line in f:
|
|
1465
|
+
line = line.strip()
|
|
1466
|
+
if line and ',' in line and len(line.split(',')) >= 2 and line.split(',')[0] and line.split(',')[1].isdigit():
|
|
1467
|
+
oldDic[line.split(',')[0]] = int(line.split(',')[1])
|
|
1468
|
+
except:
|
|
1469
|
+
pass
|
|
1470
|
+
# remove entries that are either available now or older than min(timeout,3600) seconds
|
|
1471
|
+
for key in list(oldDic.keys()):
|
|
1472
|
+
if key in reachableHosts or time.time() - oldDic[key] > min(timeout,3600):
|
|
1473
|
+
del oldDic[key]
|
|
1474
|
+
# add new entries
|
|
1475
|
+
for host in unavailableHosts:
|
|
1476
|
+
oldDic[host] = int(time.time())
|
|
1477
|
+
with open(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv.new'),'w') as f:
|
|
1478
|
+
for key, value in oldDic.items():
|
|
1479
|
+
f.write(f'{key},{value}\n')
|
|
1480
|
+
os.replace(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv.new'),os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv'))
|
|
1481
|
+
|
|
1482
|
+
except Exception as e:
|
|
1483
|
+
eprint(f'Error writing to temporary file: {e}')
|
|
1426
1484
|
|
|
1427
1485
|
# print the output, if the output of multiple hosts are the same, we aggragate them
|
|
1428
1486
|
if not called:
|
|
@@ -1555,10 +1613,30 @@ def run_command_on_hosts(hosts = DEFAULT_HOSTS,commands = None,oneonone = DEFAUL
|
|
|
1555
1613
|
global __DEBUG_MODE
|
|
1556
1614
|
_emo = False
|
|
1557
1615
|
_no_env = no_env
|
|
1558
|
-
if
|
|
1559
|
-
|
|
1616
|
+
if os.path.exists(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv')):
|
|
1617
|
+
if timeout <= 0:
|
|
1618
|
+
checkTime = DEFAULT_TIMEOUT
|
|
1619
|
+
else:
|
|
1620
|
+
checkTime = timeout
|
|
1621
|
+
if checkTime <= 0:
|
|
1622
|
+
checkTime = 60
|
|
1623
|
+
elif checkTime > 3600:
|
|
1624
|
+
checkTime = 3600
|
|
1625
|
+
try:
|
|
1626
|
+
if 0 < time.time() - os.path.getmtime(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv')) < checkTime:
|
|
1627
|
+
if not __global_suppress_printout:
|
|
1628
|
+
eprint(f"Reading unavailable hosts from the file {os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv')}")
|
|
1629
|
+
with open(os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv'),'r') as f:
|
|
1630
|
+
for line in f:
|
|
1631
|
+
line = line.strip()
|
|
1632
|
+
if line and ',' in line and len(line.split(',')) >= 2 and line.split(',')[0] and line.split(',')[1].isdigit():
|
|
1633
|
+
if int(line.split(',')[1]) > time.time() - checkTime:
|
|
1634
|
+
__globalUnavailableHosts.add(line.split(',')[0])
|
|
1635
|
+
except Exception as e:
|
|
1636
|
+
eprint(f"Warning: Unable to read the unavailable hosts from the file {os.path.join(tempfile.gettempdir(),'__multiSSH3_UNAVAILABLE_HOSTS.csv')}")
|
|
1637
|
+
eprint(str(e))
|
|
1560
1638
|
elif '__multiSSH3_UNAVAILABLE_HOSTS' in readEnvFromFile():
|
|
1561
|
-
__globalUnavailableHosts
|
|
1639
|
+
__globalUnavailableHosts.update(readEnvFromFile()['__multiSSH3_UNAVAILABLE_HOSTS'].split(','))
|
|
1562
1640
|
if not max_connections:
|
|
1563
1641
|
max_connections = 4 * os.cpu_count()
|
|
1564
1642
|
elif max_connections == 0:
|
|
@@ -1842,7 +1920,7 @@ def main():
|
|
|
1842
1920
|
parser.add_argument("-j","--json", action='store_true', help=F"Output in json format. (default: {DEFAULT_JSON_MODE})", default=DEFAULT_JSON_MODE)
|
|
1843
1921
|
parser.add_argument("--success_hosts", action='store_true', help=f"Output the hosts that succeeded in summary as wells. (default: {DEFAULT_PRINT_SUCCESS_HOSTS})", default=DEFAULT_PRINT_SUCCESS_HOSTS)
|
|
1844
1922
|
parser.add_argument("-g","--greppable", action='store_true', help=f"Output in greppable format. (default: {DEFAULT_GREPPABLE_MODE})", default=DEFAULT_GREPPABLE_MODE)
|
|
1845
|
-
parser.add_argument("-su","--skip_unreachable", action='store_true', help=f"Skip unreachable hosts
|
|
1923
|
+
parser.add_argument("-su","--skip_unreachable", action='store_true', help=f"Skip unreachable hosts. Note: Timedout Hosts are considered unreachable. Note: multiple command sequence will still auto skip unreachable hosts. (default: {DEFAULT_SKIP_UNREACHABLE})", default=DEFAULT_SKIP_UNREACHABLE)
|
|
1846
1924
|
parser.add_argument("-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)
|
|
1847
1925
|
parser.add_argument('--store_config_file', action='store_true', help=f'Store / generate the default config file from command line argument and current config at {CONFIG_FILE}')
|
|
1848
1926
|
parser.add_argument('--debug', action='store_true', help='Print debug information')
|
|
@@ -1940,15 +2018,16 @@ def main():
|
|
|
1940
2018
|
|
|
1941
2019
|
__ipmiiInterfaceIPPrefix = args.ipmi_interface_ip_prefix
|
|
1942
2020
|
|
|
1943
|
-
if
|
|
1944
|
-
__global_suppress_printout =
|
|
2021
|
+
if args.no_output:
|
|
2022
|
+
__global_suppress_printout = True
|
|
1945
2023
|
|
|
1946
2024
|
if not __global_suppress_printout:
|
|
1947
|
-
|
|
2025
|
+
cmdStr = getStrCommand(args.hosts,args.commands,oneonone=args.oneonone,timeout=args.timeout,password=args.password,
|
|
1948
2026
|
nowatch=args.nowatch,json=args.json,called=args.no_output,max_connections=args.max_connections,
|
|
1949
2027
|
files=args.file,file_sync=args.file_sync,ipmi=args.ipmi,interface_ip_prefix=args.interface_ip_prefix,scp=args.scp,gather_mode = args.gather_mode,username=args.username,
|
|
1950
2028
|
extraargs=args.extraargs,skipUnreachable=args.skip_unreachable,no_env=args.no_env,greppable=args.greppable,skip_hosts = args.skip_hosts,
|
|
1951
|
-
curses_min_char_len = args.window_width, curses_min_line_len = args.window_height,single_window=args.single_window,error_only=args.error_only,identity_file=args.key)
|
|
2029
|
+
curses_min_char_len = args.window_width, curses_min_line_len = args.window_height,single_window=args.single_window,error_only=args.error_only,identity_file=args.key)
|
|
2030
|
+
eprint('> ' + cmdStr)
|
|
1952
2031
|
if args.error_only:
|
|
1953
2032
|
__global_suppress_printout = True
|
|
1954
2033
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|