import os
import subprocess
from subprocess import PIPE
from base_utils.common.constantsbase import ConstantsBase
from gspylib.common.ErrorCode import ErrorCode
from base_utils.common.fast_popen import FastPopen
from base_utils.security.sensitive_mask import SensitiveMask
class CmdExecutor(object):
"""
command executor.
"""
def __init__(self):
pass
@staticmethod
def execCommandLocally(cmd):
"""
functino: exec only on local node
input: cmd
output: NA
"""
proc = FastPopen(cmd, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True)
stdout, stderr = proc.communicate()
output = stdout + stderr
status = proc.returncode
if status != 0 and "[GAUSS-5" in str(output):
raise Exception(str(output))
elif status != 0:
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"]
% SensitiveMask.mask_pwd(str(cmd))
+ " Error: \n%s" % str(output))
@staticmethod
def execCommandWithMode(cmd,
g_ssh_tool,
local_mode=False,
mpprc_file='',
host_list=None,
parallelism=True):
"""
function: check the mode, if local mode, exec only on local node,
else exec on all nodes
input: cmd, decript, g_sshTool, localMode, mpprcFile
output: NA
"""
if not host_list:
host_list = []
if local_mode:
CmdExecutor.execCommandLocally(cmd)
else:
g_ssh_tool.executeCommand(cmd,
ConstantsBase.SUCCESS,
host_list,
mpprc_file,
parallelism=parallelism)
@staticmethod
def execCommandWithSubprocess(cmd, ignore_std_error=False):
"""
Simply call the command, and get the standard output and standard error.
:param cmd: The command string.
:param ignore_std_error: Whether need to ignore the standard error message.
Sometimes adding standard error
output results in unexpected errors.
:type cmd: str
:type ignore_std_error: bool
:return: Return the command execute result.
:rtype: (int, str, str | None)
"""
if ignore_std_error:
process = subprocess.Popen(
cmd,
universal_newlines=True,
stdout=subprocess.PIPE,
shell=True,
)
else:
process = subprocess.Popen(
cmd,
universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
)
try:
output, error = process.communicate()
except IOError:
process.kill()
output, error = "", ""
except Exception:
process.kill()
output, error = process.communicate()
ret_code = process.poll()
return ret_code, output, error