scripts: print perftune.py error message when capture_output=True

We currently does not able to get any error message from subprocess when we specified capture_output=True on subprocess.run().
This is because CalledProcessError does not print stdout/stderr when it raised, and we don't catch the exception, we just let python to cause Traceback.
Result of that, we only able to know exit status and failed command but
not able to get stdout/stderr.

This is problematic especially working on perftune.py bug, since the
script should caused Traceback but we never able to see it.

To resolve this, add wrapper function "out()" for capture output, and
print stdout/stderr with error message inside the function.

Fixes #10390

Closes #10391
This commit is contained in:
Takuya ASADA
2022-04-18 19:19:38 +09:00
committed by Avi Kivity
parent 27093d32d1
commit acaf0bb88a
3 changed files with 17 additions and 3 deletions

View File

@@ -18,7 +18,7 @@ from scylla_util import *
from subprocess import run
def get_mode_cpuset(nic, mode):
mode_cpu_mask = run('/opt/scylladb/scripts/perftune.py --tune net --nic {} --mode {} --get-cpu-mask-quiet'.format(nic, mode), shell=True, check=True, capture_output=True, encoding='utf-8').stdout.strip()
mode_cpu_mask = out('/opt/scylladb/scripts/perftune.py --tune net --nic {} --mode {} --get-cpu-mask-quiet'.format(nic, mode))
return hex2list(mode_cpu_mask)
def get_cur_cpuset():
@@ -70,7 +70,7 @@ def create_perftune_conf(cfg):
mode = get_tune_mode(nic)
params += ' --mode {mode} --dump-options-file'.format(mode=mode)
yaml = run('/opt/scylladb/scripts/perftune.py ' + params, shell=True, check=True, capture_output=True, encoding='utf-8').stdout.strip()
yaml = out('/opt/scylladb/scripts/perftune.py ' + params)
with open('/etc/scylla.d/perftune.yaml', 'w') as f:
f.write(yaml)
os.chmod('/etc/scylla.d/perftune.yaml', 0o644)

View File

@@ -70,7 +70,7 @@ if __name__ == '__main__':
network_mode = args.mode if args.mode else cfg.get('NETWORK_MODE')
if args.setup_nic_and_disks:
res = run('{} --tune net --nic {} --get-cpu-mask'.format(perftune_base_command(), ifname), shell=True, check=True, capture_output=True, encoding='utf-8').stdout
res = out('{} --tune net --nic {} --get-cpu-mask'.format(perftune_base_command(), ifname))
# we need to extract CPU mask from output, since perftune.py may also print warning messages (#10082)
match = re.match('(.*)(0x[0-9a-f]+)', res, re.DOTALL)
try:

View File

@@ -21,6 +21,20 @@ from scylla_product import PRODUCT
from multiprocessing import cpu_count
def out(cmd, shell=True, timeout=None, encoding='utf-8'):
res = subprocess.run(cmd, capture_output=True, shell=shell, timeout=timeout, check=False, encoding=encoding)
if res.returncode != 0:
print(f'Command \'{cmd}\' returned non-zero exit status: {res.returncode}')
print('---------- stdout ----------')
print(res.stdout, end='')
print('------------------------------')
print('---------- stderr ----------')
print(res.stderr, end='')
print('------------------------------')
res.check_returncode()
return res.stdout.strip()
def scriptsdir_p():
p = Path(sys.argv[0]).resolve()
if p.parent.name == 'libexec':