multiSSH3 5.35__tar.gz → 5.39__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-5.35 → multissh3-5.39}/PKG-INFO +21 -12
- {multissh3-5.35 → multissh3-5.39}/README.md +10 -10
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.egg-info/PKG-INFO +21 -12
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.py +34 -29
- {multissh3-5.35 → multissh3-5.39}/setup.py +1 -1
- {multissh3-5.35 → multissh3-5.39}/LICENSE +0 -0
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.egg-info/SOURCES.txt +0 -0
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.egg-info/dependency_links.txt +0 -0
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.egg-info/entry_points.txt +0 -0
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.egg-info/requires.txt +0 -0
- {multissh3-5.35 → multissh3-5.39}/multiSSH3.egg-info/top_level.txt +0 -0
- {multissh3-5.35 → multissh3-5.39}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: multiSSH3
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.39
|
|
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
|
|
@@ -13,6 +13,15 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: argparse
|
|
15
15
|
Requires-Dist: ipaddress
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: author-email
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
16
25
|
|
|
17
26
|
# multiSSH3
|
|
18
27
|
A script that is able to issue commands to multiple hosts while monitoring their progress.
|
|
@@ -43,6 +52,15 @@ mssh --store_config_file
|
|
|
43
52
|
|
|
44
53
|
You can modify the json file directly after generation and multissh will read from it for loading defaults.
|
|
45
54
|
|
|
55
|
+
```bash
|
|
56
|
+
mssh --ipmi_interface_ip_prefix 192 --store_config_file
|
|
57
|
+
```
|
|
58
|
+
will store
|
|
59
|
+
```json
|
|
60
|
+
"DEFAULT_IPMI_INTERFACE_IP_PREFIX": "192"
|
|
61
|
+
```
|
|
62
|
+
into the json file.
|
|
63
|
+
|
|
46
64
|
Note:
|
|
47
65
|
|
|
48
66
|
If you want to store password, it will be a plain text password in this config file. This will be better to supply it everytime as a CLI argument but you should really consider setting up priv-pub key setup.
|
|
@@ -53,15 +71,6 @@ On some systems, scp / rsync will require you use a priv-pub key to work
|
|
|
53
71
|
|
|
54
72
|
This option can also be used to store cli options into the config files. For example.
|
|
55
73
|
|
|
56
|
-
```bash
|
|
57
|
-
mssh --ipmi_interface_ip_prefix 192 --store_config_file
|
|
58
|
-
```
|
|
59
|
-
will store
|
|
60
|
-
```json
|
|
61
|
-
"DEFAULT_IPMI_INTERFACE_IP_PREFIX": "192"
|
|
62
|
-
```
|
|
63
|
-
into the json file.
|
|
64
|
-
|
|
65
74
|
By defualt reads bash env variables for hostname aliases. Also able to read
|
|
66
75
|
```bash
|
|
67
76
|
DEFAULT_ENV_FILE = '/etc/profile.d/hosts.sh'
|
|
@@ -77,7 +86,7 @@ us_east='100.100.0.1-3,us_east_prod_[1-5]'
|
|
|
77
86
|
us_central=""
|
|
78
87
|
us_west="100.101.0.1-2,us_west_prod_[a-c]_[1-3]"
|
|
79
88
|
us="$us_east,$us_central,$us_west"
|
|
80
|
-
asia="100.90.0-1
|
|
89
|
+
asia="100.90.0-1.1-9"
|
|
81
90
|
eu=''
|
|
82
91
|
rhel8="$asia,$us_east"
|
|
83
92
|
all="$us,$asia,$eu"
|
|
@@ -27,6 +27,15 @@ mssh --store_config_file
|
|
|
27
27
|
|
|
28
28
|
You can modify the json file directly after generation and multissh will read from it for loading defaults.
|
|
29
29
|
|
|
30
|
+
```bash
|
|
31
|
+
mssh --ipmi_interface_ip_prefix 192 --store_config_file
|
|
32
|
+
```
|
|
33
|
+
will store
|
|
34
|
+
```json
|
|
35
|
+
"DEFAULT_IPMI_INTERFACE_IP_PREFIX": "192"
|
|
36
|
+
```
|
|
37
|
+
into the json file.
|
|
38
|
+
|
|
30
39
|
Note:
|
|
31
40
|
|
|
32
41
|
If you want to store password, it will be a plain text password in this config file. This will be better to supply it everytime as a CLI argument but you should really consider setting up priv-pub key setup.
|
|
@@ -37,15 +46,6 @@ On some systems, scp / rsync will require you use a priv-pub key to work
|
|
|
37
46
|
|
|
38
47
|
This option can also be used to store cli options into the config files. For example.
|
|
39
48
|
|
|
40
|
-
```bash
|
|
41
|
-
mssh --ipmi_interface_ip_prefix 192 --store_config_file
|
|
42
|
-
```
|
|
43
|
-
will store
|
|
44
|
-
```json
|
|
45
|
-
"DEFAULT_IPMI_INTERFACE_IP_PREFIX": "192"
|
|
46
|
-
```
|
|
47
|
-
into the json file.
|
|
48
|
-
|
|
49
49
|
By defualt reads bash env variables for hostname aliases. Also able to read
|
|
50
50
|
```bash
|
|
51
51
|
DEFAULT_ENV_FILE = '/etc/profile.d/hosts.sh'
|
|
@@ -61,7 +61,7 @@ us_east='100.100.0.1-3,us_east_prod_[1-5]'
|
|
|
61
61
|
us_central=""
|
|
62
62
|
us_west="100.101.0.1-2,us_west_prod_[a-c]_[1-3]"
|
|
63
63
|
us="$us_east,$us_central,$us_west"
|
|
64
|
-
asia="100.90.0-1
|
|
64
|
+
asia="100.90.0-1.1-9"
|
|
65
65
|
eu=''
|
|
66
66
|
rhel8="$asia,$us_east"
|
|
67
67
|
all="$us,$asia,$eu"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: multiSSH3
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.39
|
|
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
|
|
@@ -13,6 +13,15 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: argparse
|
|
15
15
|
Requires-Dist: ipaddress
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: author-email
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
16
25
|
|
|
17
26
|
# multiSSH3
|
|
18
27
|
A script that is able to issue commands to multiple hosts while monitoring their progress.
|
|
@@ -43,6 +52,15 @@ mssh --store_config_file
|
|
|
43
52
|
|
|
44
53
|
You can modify the json file directly after generation and multissh will read from it for loading defaults.
|
|
45
54
|
|
|
55
|
+
```bash
|
|
56
|
+
mssh --ipmi_interface_ip_prefix 192 --store_config_file
|
|
57
|
+
```
|
|
58
|
+
will store
|
|
59
|
+
```json
|
|
60
|
+
"DEFAULT_IPMI_INTERFACE_IP_PREFIX": "192"
|
|
61
|
+
```
|
|
62
|
+
into the json file.
|
|
63
|
+
|
|
46
64
|
Note:
|
|
47
65
|
|
|
48
66
|
If you want to store password, it will be a plain text password in this config file. This will be better to supply it everytime as a CLI argument but you should really consider setting up priv-pub key setup.
|
|
@@ -53,15 +71,6 @@ On some systems, scp / rsync will require you use a priv-pub key to work
|
|
|
53
71
|
|
|
54
72
|
This option can also be used to store cli options into the config files. For example.
|
|
55
73
|
|
|
56
|
-
```bash
|
|
57
|
-
mssh --ipmi_interface_ip_prefix 192 --store_config_file
|
|
58
|
-
```
|
|
59
|
-
will store
|
|
60
|
-
```json
|
|
61
|
-
"DEFAULT_IPMI_INTERFACE_IP_PREFIX": "192"
|
|
62
|
-
```
|
|
63
|
-
into the json file.
|
|
64
|
-
|
|
65
74
|
By defualt reads bash env variables for hostname aliases. Also able to read
|
|
66
75
|
```bash
|
|
67
76
|
DEFAULT_ENV_FILE = '/etc/profile.d/hosts.sh'
|
|
@@ -77,7 +86,7 @@ us_east='100.100.0.1-3,us_east_prod_[1-5]'
|
|
|
77
86
|
us_central=""
|
|
78
87
|
us_west="100.101.0.1-2,us_west_prod_[a-c]_[1-3]"
|
|
79
88
|
us="$us_east,$us_central,$us_west"
|
|
80
|
-
asia="100.90.0-1
|
|
89
|
+
asia="100.90.0-1.1-9"
|
|
81
90
|
eu=''
|
|
82
91
|
rhel8="$asia,$us_east"
|
|
83
92
|
all="$us,$asia,$eu"
|
|
@@ -37,7 +37,7 @@ except AttributeError:
|
|
|
37
37
|
# If neither is available, use a dummy decorator
|
|
38
38
|
def cache_decorator(func):
|
|
39
39
|
return func
|
|
40
|
-
version = '5.
|
|
40
|
+
version = '5.39'
|
|
41
41
|
VERSION = version
|
|
42
42
|
|
|
43
43
|
CONFIG_FILE = '/etc/multiSSH3.config.json'
|
|
@@ -158,7 +158,7 @@ def _get_i():
|
|
|
158
158
|
|
|
159
159
|
# ------------ Host Object ----------------
|
|
160
160
|
class Host:
|
|
161
|
-
def __init__(self, name, command, files = None,ipmi = False,interface_ip_prefix = None,scp=False,extraargs=None,gatherMode=False,identity_file=None,
|
|
161
|
+
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 = _get_i(),uuid=uuid.uuid4(),ip = None):
|
|
162
162
|
self.name = name # the name of the host (hostname or IP address)
|
|
163
163
|
self.command = command # the command to run on the host
|
|
164
164
|
self.returncode = None # the return code of the command
|
|
@@ -170,7 +170,7 @@ class Host:
|
|
|
170
170
|
self.lastUpdateTime = time.time() # the last time the output was updated
|
|
171
171
|
self.files = files # the files to be copied to the host
|
|
172
172
|
self.ipmi = ipmi # whether to use ipmi to connect to the host
|
|
173
|
-
self.
|
|
173
|
+
self.shell = shell # whether to use shell to run the command
|
|
174
174
|
self.interface_ip_prefix = interface_ip_prefix # the prefix of the ip address of the interface to be used to connect to the host
|
|
175
175
|
self.scp = scp # whether to use scp to copy files to the host
|
|
176
176
|
self.gatherMode = gatherMode # whether the host is in gather mode
|
|
@@ -272,7 +272,7 @@ __build_in_default_config = {
|
|
|
272
272
|
'_scpPath': None,
|
|
273
273
|
'_ipmitoolPath': None,
|
|
274
274
|
'_rsyncPath': None,
|
|
275
|
-
'
|
|
275
|
+
'_shellPath': None,
|
|
276
276
|
'__ERROR_MESSAGES_TO_IGNORE_REGEX':None,
|
|
277
277
|
'__DEBUG_MODE': False,
|
|
278
278
|
}
|
|
@@ -390,7 +390,7 @@ def check_path(program_name):
|
|
|
390
390
|
return True
|
|
391
391
|
return False
|
|
392
392
|
|
|
393
|
-
[check_path(program) for program in ['sshpass', 'ssh', 'scp', 'ipmitool','rsync','
|
|
393
|
+
[check_path(program) for program in ['sshpass', 'ssh', 'scp', 'ipmitool','rsync','sh','ssh-copy-id']]
|
|
394
394
|
|
|
395
395
|
def find_ssh_key_file(searchPath = DEDAULT_SSH_KEY_SEARCH_PATH):
|
|
396
396
|
'''
|
|
@@ -472,6 +472,7 @@ def replace_magic_strings(string,keys,value,case_sensitive=False):
|
|
|
472
472
|
return string
|
|
473
473
|
|
|
474
474
|
def pretty_format_table(data):
|
|
475
|
+
version = 1.0
|
|
475
476
|
if not data:
|
|
476
477
|
return ''
|
|
477
478
|
if type(data) == str:
|
|
@@ -488,7 +489,6 @@ def pretty_format_table(data):
|
|
|
488
489
|
data = [[key] + list(value) for key, value in data.items()]
|
|
489
490
|
elif type(data) != list:
|
|
490
491
|
data = list(data)
|
|
491
|
-
# TODO : add support for list of dictionaries
|
|
492
492
|
# format the list into 2d list of list of strings
|
|
493
493
|
if isinstance(data[0], dict):
|
|
494
494
|
tempData = [data[0].keys()]
|
|
@@ -833,7 +833,7 @@ def __compact_hostnames(Hostnames):
|
|
|
833
833
|
rtnSet.add(''.join(hostnameList))
|
|
834
834
|
return frozenset(rtnSet)
|
|
835
835
|
|
|
836
|
-
def compact_hostnames(Hostnames):
|
|
836
|
+
def compact_hostnames(Hostnames,verify = True):
|
|
837
837
|
"""
|
|
838
838
|
Compact a list of hostnames.
|
|
839
839
|
Compact numeric numbers into ranges.
|
|
@@ -864,10 +864,11 @@ def compact_hostnames(Hostnames):
|
|
|
864
864
|
else:
|
|
865
865
|
hostSet = Hostnames
|
|
866
866
|
compact_hosts = __compact_hostnames(hostSet)
|
|
867
|
-
if
|
|
868
|
-
if
|
|
869
|
-
|
|
870
|
-
|
|
867
|
+
if verify:
|
|
868
|
+
if set(expand_hostnames(compact_hosts)) != set(expand_hostnames(hostSet)):
|
|
869
|
+
if not __global_suppress_printout:
|
|
870
|
+
eprint(f"Error compacting hostnames: {hostSet} -> {compact_hosts}")
|
|
871
|
+
compact_hosts = hostSet
|
|
871
872
|
return compact_hosts
|
|
872
873
|
|
|
873
874
|
# ------------ Expanding Hostnames ----------------
|
|
@@ -883,7 +884,6 @@ def __validate_expand_hostname(hostname):
|
|
|
883
884
|
list: A list of valid hostnames
|
|
884
885
|
'''
|
|
885
886
|
global _no_env
|
|
886
|
-
# maybe it is just defined in ./target_files/hosts.sh and exported to the environment
|
|
887
887
|
# we will try to get the valid host name from the environment
|
|
888
888
|
hostname = hostname.strip().strip('$')
|
|
889
889
|
if getIP(hostname,local=True):
|
|
@@ -1018,6 +1018,8 @@ def __expand_hostnames(hosts) -> dict:
|
|
|
1018
1018
|
dict: A dictionary of expanded hostnames with key: hostname, value: resolved IP address
|
|
1019
1019
|
'''
|
|
1020
1020
|
expandedhosts = {}
|
|
1021
|
+
if isinstance(hosts, str):
|
|
1022
|
+
hosts = [hosts]
|
|
1021
1023
|
for host in hosts:
|
|
1022
1024
|
host = host.strip()
|
|
1023
1025
|
if not host:
|
|
@@ -1220,12 +1222,12 @@ def run_command(host, sem, timeout=60,passwds=None):
|
|
|
1220
1222
|
host.username = 'admin'
|
|
1221
1223
|
if not host.command:
|
|
1222
1224
|
host.command = 'power status'
|
|
1223
|
-
if '
|
|
1225
|
+
if 'sh' in _binPaths:
|
|
1224
1226
|
if passwds:
|
|
1225
|
-
formatedCMD = [_binPaths['
|
|
1227
|
+
formatedCMD = [_binPaths['sh'],'-c',f'ipmitool -H {host.address} -U {host.username} -P {passwds} {" ".join(extraargs)} {host.command}']
|
|
1226
1228
|
else:
|
|
1227
1229
|
host.output.append('Warning: Password not provided for ipmi! Using a default password `admin`.')
|
|
1228
|
-
formatedCMD = [_binPaths['
|
|
1230
|
+
formatedCMD = [_binPaths['sh'],'-c',f'ipmitool -H {host.address} -U {host.username} -P admin {" ".join(extraargs)} {host.command}']
|
|
1229
1231
|
else:
|
|
1230
1232
|
if passwds:
|
|
1231
1233
|
formatedCMD = [_binPaths['ipmitool'],f'-H {host.address}',f'-U {host.username}',f'-P {passwds}'] + extraargs + [host.command]
|
|
@@ -1249,17 +1251,17 @@ def run_command(host, sem, timeout=60,passwds=None):
|
|
|
1249
1251
|
host.stderr.append('Ipmitool not found on the local machine! Please install ipmitool to use ipmi mode.')
|
|
1250
1252
|
host.returncode = 1
|
|
1251
1253
|
return
|
|
1252
|
-
elif host.
|
|
1253
|
-
if '
|
|
1254
|
-
host.output.append('Running command in
|
|
1254
|
+
elif host.shell:
|
|
1255
|
+
if 'sh' in _binPaths:
|
|
1256
|
+
host.output.append('Running command in shell mode, ignoring the hosts...')
|
|
1255
1257
|
if __DEBUG_MODE:
|
|
1256
|
-
host.stderr.append('Running command in
|
|
1257
|
-
formatedCMD = [_binPaths['
|
|
1258
|
+
host.stderr.append('Running command in shell mode, ignoring the hosts...')
|
|
1259
|
+
formatedCMD = [_binPaths['sh'],'-c',host.command]
|
|
1258
1260
|
else:
|
|
1259
|
-
host.output.append('
|
|
1261
|
+
host.output.append('shell not found on the local machine! Using ssh localhost instead...')
|
|
1260
1262
|
if __DEBUG_MODE:
|
|
1261
|
-
host.stderr.append('
|
|
1262
|
-
host.
|
|
1263
|
+
host.stderr.append('shell not found on the local machine! Using ssh localhost instead...')
|
|
1264
|
+
host.shell = False
|
|
1263
1265
|
host.name = 'localhost'
|
|
1264
1266
|
run_command(host,sem,timeout,passwds)
|
|
1265
1267
|
else:
|
|
@@ -1547,6 +1549,7 @@ def __get_curses_color_pair(fg, bg):
|
|
|
1547
1549
|
if __curses_current_color_pair_index >= curses.COLOR_PAIRS:
|
|
1548
1550
|
print("Warning: Maximum number of color pairs reached, wrapping around.")
|
|
1549
1551
|
__curses_current_color_pair_index = 1
|
|
1552
|
+
# TODO: avoid initializing the same fg and bg color
|
|
1550
1553
|
curses.init_pair(__curses_current_color_pair_index, fg, bg)
|
|
1551
1554
|
__curses_global_color_pairs[(fg, bg)] = __curses_current_color_pair_index
|
|
1552
1555
|
__curses_current_color_pair_index += 1
|
|
@@ -1725,8 +1728,8 @@ def _curses_add_string_to_window(window, line = '', y = 0, x = 0, number_of_char
|
|
|
1725
1728
|
# process centering
|
|
1726
1729
|
if centered:
|
|
1727
1730
|
fill_length = numChar - len(lead_str) - len(trail_str) - sum([len(segment) for segment in segments if not segment.startswith("\x1b[")])
|
|
1728
|
-
window.addnstr(y, x + charsWritten, fill_char * (fill_length // 2), numChar - charsWritten, boxAttr)
|
|
1729
|
-
charsWritten += min(fill_length // 2, numChar - charsWritten)
|
|
1731
|
+
window.addnstr(y, x + charsWritten, fill_char * (fill_length // 2 // len(fill_char)), numChar - charsWritten, boxAttr)
|
|
1732
|
+
charsWritten += min(len(fill_char * (fill_length // 2)), numChar - charsWritten)
|
|
1730
1733
|
# add the segments
|
|
1731
1734
|
for segment in segments:
|
|
1732
1735
|
if not segment:
|
|
@@ -1741,7 +1744,7 @@ def _curses_add_string_to_window(window, line = '', y = 0, x = 0, number_of_char
|
|
|
1741
1744
|
charsWritten += min(len(segment), numChar - charsWritten)
|
|
1742
1745
|
# if we have finished printing segments but we still have space, we will fill it with fill_char
|
|
1743
1746
|
if charsWritten + len(trail_str) < numChar:
|
|
1744
|
-
fillStr = fill_char * (numChar - charsWritten - len(trail_str))
|
|
1747
|
+
fillStr = fill_char * ((numChar - charsWritten - len(trail_str))//len(fill_char))
|
|
1745
1748
|
#fillStr = f'{color_pair_list}'
|
|
1746
1749
|
window.addnstr(y, x + charsWritten, fillStr + trail_str, numChar - charsWritten, boxAttr)
|
|
1747
1750
|
charsWritten += numChar - charsWritten
|
|
@@ -2000,6 +2003,8 @@ def __generate_display(stdscr, hosts, lineToDisplay = -1,curserPosition = 0, min
|
|
|
2000
2003
|
# we will only update the window if there is new output or the window is not fully printed
|
|
2001
2004
|
if new_configured or host.printedLines < len(host.output):
|
|
2002
2005
|
try:
|
|
2006
|
+
if new_configured:
|
|
2007
|
+
host.printedLines = 0
|
|
2003
2008
|
#host_window.clear()
|
|
2004
2009
|
# we will try to center the name of the host with ┼ at the beginning and end and ─ in between
|
|
2005
2010
|
#linePrintOut = f'┼{(host.name+":["+host.command+"]")[:host_window_width - 2].center(host_window_width - 1, "─")}'.replace('\n', ' ').replace('\r', ' ').strip()
|
|
@@ -2124,7 +2129,7 @@ def curses_print(stdscr, hosts, threads, min_char_len = DEFAULT_CURSES_MINIMUM_C
|
|
|
2124
2129
|
stdscr.refresh()
|
|
2125
2130
|
except:
|
|
2126
2131
|
pass
|
|
2127
|
-
params = params[:5]
|
|
2132
|
+
params = params[:5] + ('new config',)
|
|
2128
2133
|
time.sleep(0.01)
|
|
2129
2134
|
#time.sleep(0.25)
|
|
2130
2135
|
|
|
@@ -2317,7 +2322,7 @@ def __formCommandArgStr(oneonone = DEFAULT_ONE_ON_ONE, timeout = DEFAULT_TIMEOUT
|
|
|
2317
2322
|
if gather_mode: argsList.append('--gather_mode' if not shortend else '-gm')
|
|
2318
2323
|
if username and username != DEFAULT_USERNAME: argsList.append(f'--username="{username}"' if not shortend else f'-u="{username}"')
|
|
2319
2324
|
if extraargs and extraargs != DEFAULT_EXTRA_ARGS: argsList.append(f'--extraargs="{extraargs}"' if not shortend else f'-ea="{extraargs}"')
|
|
2320
|
-
if skipUnreachable: argsList.append('--
|
|
2325
|
+
if skipUnreachable: argsList.append('--skip_unreachable' if not shortend else '-su')
|
|
2321
2326
|
if no_env: argsList.append('--no_env')
|
|
2322
2327
|
if greppable: argsList.append('--greppable' if not shortend else '-g')
|
|
2323
2328
|
if error_only: argsList.append('--error_only' if not shortend else '-eo')
|
|
@@ -2504,7 +2509,7 @@ def run_command_on_hosts(hosts = DEFAULT_HOSTS,commands = None,oneonone = DEFAUL
|
|
|
2504
2509
|
command = f"{command}{host}"
|
|
2505
2510
|
if password and 'sshpass' in _binPaths:
|
|
2506
2511
|
command = f"{_binPaths['sshpass']} -p {password} {command}"
|
|
2507
|
-
hosts.append(Host(host, command,identity_file=identity_file,
|
|
2512
|
+
hosts.append(Host(host, command,identity_file=identity_file,shell=True,ip = targetHostDic[host]))
|
|
2508
2513
|
else:
|
|
2509
2514
|
eprint(f"> {command}")
|
|
2510
2515
|
os.system(command)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|