2022-07-12 09:59:19 +00:00
|
|
|
#!/usr/bin/python3.9
|
2021-09-10 12:44:40 +00:00
|
|
|
|
|
|
|
"""
|
2022-07-12 09:59:19 +00:00
|
|
|
Helper functions to use with `neofs-cli`, `neo-go` and other CLIs.
|
2021-09-10 12:44:40 +00:00
|
|
|
"""
|
2022-07-12 09:59:19 +00:00
|
|
|
import json
|
2021-09-10 12:44:40 +00:00
|
|
|
import subprocess
|
2022-07-05 07:18:37 +00:00
|
|
|
import sys
|
|
|
|
from contextlib import suppress
|
|
|
|
from datetime import datetime
|
|
|
|
from textwrap import shorten
|
2022-07-12 09:59:19 +00:00
|
|
|
from typing import Union
|
2021-09-10 12:44:40 +00:00
|
|
|
|
2022-07-05 07:18:37 +00:00
|
|
|
import allure
|
2022-06-09 13:08:11 +00:00
|
|
|
import pexpect
|
2021-09-10 12:44:40 +00:00
|
|
|
from robot.api import logger
|
|
|
|
|
|
|
|
ROBOT_AUTO_KEYWORDS = False
|
|
|
|
|
|
|
|
|
2022-07-12 09:59:19 +00:00
|
|
|
def _cmd_run(cmd: str, timeout: int = 30) -> str:
|
2021-09-10 12:44:40 +00:00
|
|
|
"""
|
|
|
|
Runs given shell command <cmd>, in case of success returns its stdout,
|
|
|
|
in case of failure returns error message.
|
|
|
|
"""
|
|
|
|
try:
|
2022-03-15 11:58:59 +00:00
|
|
|
logger.info(f"Executing command: {cmd}")
|
2022-07-12 09:59:19 +00:00
|
|
|
start_time = datetime.utcnow()
|
2021-09-10 12:44:40 +00:00
|
|
|
compl_proc = subprocess.run(cmd, check=True, universal_newlines=True,
|
2022-07-07 21:31:58 +00:00
|
|
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
|
|
timeout=timeout,
|
2022-06-09 13:08:11 +00:00
|
|
|
shell=True)
|
2021-09-10 12:44:40 +00:00
|
|
|
output = compl_proc.stdout
|
2022-07-05 07:18:37 +00:00
|
|
|
return_code = compl_proc.returncode
|
2022-07-12 09:59:19 +00:00
|
|
|
end_time = datetime.utcnow()
|
2021-09-10 12:44:40 +00:00
|
|
|
logger.info(f"Output: {output}")
|
2022-07-05 07:18:37 +00:00
|
|
|
_attach_allure_log(cmd, output, return_code, start_time, end_time)
|
|
|
|
|
2021-09-10 12:44:40 +00:00
|
|
|
return output
|
|
|
|
except subprocess.CalledProcessError as exc:
|
|
|
|
raise RuntimeError(f"Error:\nreturn code: {exc.returncode} "
|
2022-06-09 13:08:11 +00:00
|
|
|
f"\nOutput: {exc.output}") from exc
|
2022-07-07 21:31:58 +00:00
|
|
|
except OSError as exc:
|
|
|
|
raise RuntimeError(f"Output: {exc.strerror}") from exc
|
2022-02-07 11:41:34 +00:00
|
|
|
except Exception as exc:
|
|
|
|
return_code, _ = subprocess.getstatusoutput(cmd)
|
|
|
|
logger.info(f"Error:\nreturn code: {return_code}\nOutput: "
|
2022-06-09 13:08:11 +00:00
|
|
|
f"{exc.output.decode('utf-8') if type(exc.output) is bytes else exc.output}")
|
2022-02-07 11:41:34 +00:00
|
|
|
raise
|
2021-11-03 12:48:31 +00:00
|
|
|
|
2022-06-09 13:08:11 +00:00
|
|
|
|
2022-07-12 09:59:19 +00:00
|
|
|
def _run_with_passwd(cmd: str) -> str:
|
2022-02-07 11:41:34 +00:00
|
|
|
child = pexpect.spawn(cmd)
|
2022-07-05 07:18:37 +00:00
|
|
|
child.delaybeforesend = 1
|
2022-02-07 11:41:34 +00:00
|
|
|
child.expect(".*")
|
|
|
|
child.sendline('\r')
|
2022-07-05 07:18:37 +00:00
|
|
|
if sys.platform == "darwin":
|
|
|
|
child.expect(pexpect.EOF)
|
|
|
|
cmd = child.before
|
|
|
|
else:
|
|
|
|
child.wait()
|
|
|
|
cmd = child.read()
|
|
|
|
return cmd.decode()
|
|
|
|
|
|
|
|
|
2022-07-12 09:59:19 +00:00
|
|
|
def _configure_aws_cli(cmd: str, key_id: str, access_key: str, out_format: str = "json") -> str:
|
2022-07-05 07:18:37 +00:00
|
|
|
child = pexpect.spawn(cmd)
|
|
|
|
child.delaybeforesend = 1
|
|
|
|
|
|
|
|
child.expect("AWS Access Key ID.*")
|
|
|
|
child.sendline(key_id)
|
|
|
|
|
|
|
|
child.expect("AWS Secret Access Key.*")
|
|
|
|
child.sendline(access_key)
|
|
|
|
|
|
|
|
child.expect("Default region name.*")
|
|
|
|
child.sendline('')
|
|
|
|
|
|
|
|
child.expect("Default output format.*")
|
|
|
|
child.sendline(out_format)
|
|
|
|
|
2022-02-07 11:41:34 +00:00
|
|
|
child.wait()
|
|
|
|
cmd = child.read()
|
2022-07-05 07:18:37 +00:00
|
|
|
# child.expect(pexpect.EOF)
|
|
|
|
# cmd = child.before
|
2021-11-03 12:48:31 +00:00
|
|
|
return cmd.decode()
|
2022-07-05 07:18:37 +00:00
|
|
|
|
|
|
|
|
2022-07-12 09:59:19 +00:00
|
|
|
def _attach_allure_log(cmd: str, output: str, return_code: int, start_time: datetime,
|
|
|
|
end_time: datetime) -> None:
|
2022-07-05 07:18:37 +00:00
|
|
|
if 'allure' in sys.modules:
|
|
|
|
command_attachment = (
|
|
|
|
f"COMMAND: '{cmd}'\n"
|
|
|
|
f'OUTPUT:\n {output}\n'
|
|
|
|
f'RC: {return_code}\n'
|
|
|
|
f'Start / End / Elapsed\t {start_time.time()} / {end_time.time()} / {end_time - start_time}'
|
|
|
|
)
|
|
|
|
with allure.step(f'COMMAND: {shorten(cmd, width=60, placeholder="...")}'):
|
|
|
|
allure.attach(command_attachment, 'Command execution', allure.attachment_type.TEXT)
|
|
|
|
|
|
|
|
|
2022-07-12 09:59:19 +00:00
|
|
|
def log_command_execution(cmd: str, output: Union[str, dict]) -> None:
|
2022-07-05 07:18:37 +00:00
|
|
|
logger.info(f'{cmd}: {output}')
|
|
|
|
if 'allure' in sys.modules:
|
|
|
|
with suppress(Exception):
|
2022-07-12 09:59:19 +00:00
|
|
|
json_output = json.dumps(output, indent=4, sort_keys=True)
|
2022-07-05 07:18:37 +00:00
|
|
|
output = json_output
|
|
|
|
command_attachment = (
|
|
|
|
f"COMMAND: '{cmd}'\n"
|
|
|
|
f'OUTPUT:\n {output}\n'
|
|
|
|
)
|
|
|
|
with allure.step(f'COMMAND: {shorten(cmd, width=60, placeholder="...")}'):
|
|
|
|
allure.attach(command_attachment, 'Command execution', allure.attachment_type.TEXT)
|