From fc7a161221b44fffcebba3bca2a6189efa7661b8 Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Fri, 11 Oct 2019 13:15:57 -0700 Subject: [PATCH] updated utils.check_cmd to accept the same parameters as other commands and be leveraged for node cmds --- daemon/core/nodes/base.py | 2 +- daemon/core/nodes/docker.py | 6 +++--- daemon/core/nodes/interface.py | 2 +- daemon/core/nodes/lxd.py | 6 +++--- daemon/core/nodes/network.py | 2 +- daemon/core/utils.py | 29 ++++++++++++++++------------- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/daemon/core/nodes/base.py b/daemon/core/nodes/base.py index 2b9e08eb..6a3bebf0 100644 --- a/daemon/core/nodes/base.py +++ b/daemon/core/nodes/base.py @@ -98,7 +98,7 @@ class NodeBase(object): :raises CoreCommandError: when a non-zero exit status occurs """ if self.server is None: - return utils.check_cmd(args, env=env, cwd=cwd) + return utils.check_cmd(args, env, cwd, wait) else: args = " ".join(args) return distributed.remote_cmd(self.server, args, env, cwd, wait) diff --git a/daemon/core/nodes/docker.py b/daemon/core/nodes/docker.py index 28a92607..1b8322ae 100644 --- a/daemon/core/nodes/docker.py +++ b/daemon/core/nodes/docker.py @@ -56,7 +56,7 @@ class DockerClient(object): cmd=cmd )) - def ns_cmd(self, cmd): + def ns_cmd(self, cmd, wait): if isinstance(cmd, list): cmd = " ".join(cmd) args = "nsenter -t {pid} -u -i -p -n {cmd}".format( @@ -64,7 +64,7 @@ class DockerClient(object): cmd=cmd ) logging.info("ns cmd: %s", args) - return utils.check_cmd(args) + return utils.check_cmd(args, wait=wait) def get_pid(self): args = "docker inspect -f '{{{{.State.Pid}}}}' {name}".format(name=self.name) @@ -147,7 +147,7 @@ class DockerNode(CoreNode): logging.debug("node down, not running network command: %s", args) return "" - return self.client.ns_cmd(args) + return self.client.ns_cmd(args, wait) def termcmdstring(self, sh="/bin/sh"): """ diff --git a/daemon/core/nodes/interface.py b/daemon/core/nodes/interface.py index 08f1d662..d749bbde 100644 --- a/daemon/core/nodes/interface.py +++ b/daemon/core/nodes/interface.py @@ -61,7 +61,7 @@ class CoreInterface(object): :raises CoreCommandError: when a non-zero exit status occurs """ if self.server is None: - return utils.check_cmd(args, env=env, cwd=cwd) + return utils.check_cmd(args, env, cwd, wait) else: args = " ".join(args) return distributed.remote_cmd(self.server, args, env, cwd, wait) diff --git a/daemon/core/nodes/lxd.py b/daemon/core/nodes/lxd.py index f16df715..df01f4ad 100644 --- a/daemon/core/nodes/lxd.py +++ b/daemon/core/nodes/lxd.py @@ -46,12 +46,12 @@ class LxdClient(object): def _cmd_args(self, cmd): return "lxc exec -nT {name} -- {cmd}".format(name=self.name, cmd=cmd) - def check_cmd(self, cmd): + def check_cmd(self, cmd, wait): if isinstance(cmd, list): cmd = " ".join(cmd) args = self._cmd_args(cmd) logging.info("lxc cmd output: %s", args) - return utils.check_cmd(args) + return utils.check_cmd(args, wait=wait) def _ns_args(self, cmd): return "nsenter -t {pid} -m -u -i -p -n {cmd}".format(pid=self.pid, cmd=cmd) @@ -144,7 +144,7 @@ class LxcNode(CoreNode): if not self.up: logging.debug("node down, not running network command: %s", args) return "" - return self.client.check_cmd(args) + return self.client.check_cmd(args, wait) def termcmdstring(self, sh="/bin/sh"): """ diff --git a/daemon/core/nodes/network.py b/daemon/core/nodes/network.py index b236b96b..7197c77f 100644 --- a/daemon/core/nodes/network.py +++ b/daemon/core/nodes/network.py @@ -322,7 +322,7 @@ class CoreNetwork(CoreNetworkBase): :raises CoreCommandError: when a non-zero exit status occurs """ logging.info("network node(%s) cmd", self.name) - output = utils.check_cmd(args, env=env, cwd=cwd) + output = utils.check_cmd(args, env, cwd, wait) args = " ".join(args) for server in self.session.servers: diff --git a/daemon/core/utils.py b/daemon/core/utils.py index ead65eeb..df59f9ea 100644 --- a/daemon/core/utils.py +++ b/daemon/core/utils.py @@ -11,8 +11,8 @@ import logging import logging.config import os import shlex -import subprocess import sys +from subprocess import PIPE, STDOUT, Popen from past.builtins import basestring @@ -203,33 +203,36 @@ def mute_detach(args, **kwargs): args = split_args(args) kwargs["preexec_fn"] = _detach_init kwargs["stdout"] = DEVNULL - kwargs["stderr"] = subprocess.STDOUT - return subprocess.Popen(args, **kwargs).pid + kwargs["stderr"] = STDOUT + return Popen(args, **kwargs).pid -def check_cmd(args, **kwargs): +def check_cmd(args, env=None, cwd=None, wait=True): """ Execute a command on the host and return a tuple containing the exit status and result string. stderr output is folded into the stdout result string. :param list[str]|str args: command arguments - :param dict kwargs: keyword arguments to pass to subprocess.Popen + :param dict env: environment to run command with + :param str cwd: directory to run command in + :param bool wait: True to wait for status, False otherwise :return: combined stdout and stderr :rtype: str :raises CoreCommandError: when there is a non-zero exit status or the file to execute is not found """ - kwargs["stdout"] = subprocess.PIPE - kwargs["stderr"] = subprocess.STDOUT args = split_args(args) logging.info("command: %s", args) try: - p = subprocess.Popen(args, **kwargs) - stdout, _ = p.communicate() - status = p.wait() - if status != 0: - raise CoreCommandError(status, args, stdout) - return stdout.decode("utf-8").strip() + p = Popen(args, stdout=PIPE, stderr=PIPE, env=env, cwd=cwd) + if wait: + stdout, stderr = p.communicate() + status = p.wait() + if status != 0: + raise CoreCommandError(status, args, stdout, stderr) + return stdout.decode("utf-8").strip() + else: + return "" except OSError: raise CoreCommandError(-1, args)