コード例 #1
0
ファイル: cmdutils.py プロジェクト: olegtikhonov/vdsm
def exec_cmd(cmd, env=None):
    """
    Execute cmd in an external process, collect its output and returncode

    :param cmd: an iterator of strings to be passed as exec(2)'s argv
    :param env: an optional dictionary to be placed as environment variables
                of the external process. If None, the environment of the
                calling process is used.
    :returns: a 3-tuple of the process's
              (returncode, stdout content, stderr content.)

    This is a bare-bones version of `commands.execCmd`. Unlike the latter, this
    function
    * uses Vdsm cpu pinning, and must not be used for long CPU-bound processes.
    * does not guarantee to kill underlying process if Popen.communicate()
      raises. Commands that access shared storage may not use this api.
    * does not hide passwords in logs if they are passed in cmd
    """
    logging.debug(command_log_line(cmd))

    p = subprocess.Popen(cmd,
                         close_fds=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         env=env)

    out, err = p.communicate()

    logging.debug(retcode_log_line(p.returncode, err=err))

    return p.returncode, out, err
コード例 #2
0
ファイル: v2v.py プロジェクト: minqf/vdsm
def _simple_exec_cmd(command,
                     env=None,
                     nice=None,
                     ioclass=None,
                     stdin=None,
                     stdout=None,
                     stderr=None):

    command = wrap_command(command,
                           with_ioclass=ioclass,
                           ioclassdata=None,
                           with_nice=nice,
                           with_setsid=False,
                           with_sudo=False,
                           reset_cpu_affinity=True)

    logging.debug(cmdutils.command_log_line(command, cwd=None))

    p = subprocess.Popen(command,
                         close_fds=True,
                         cwd=None,
                         env=env,
                         stdin=stdin,
                         stdout=stdout,
                         stderr=stderr)
    return p
コード例 #3
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_kill(self):
     p = subprocess.Popen(["sleep", "1"],
                          stdin=None,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     p.kill()
     list(cmdutils.receive(p))
     self.assertEqual(p.returncode, -signal.SIGKILL)
コード例 #4
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_no_output_error(self):
     p = subprocess.Popen(["false"],
                          stdin=None,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     received = list(cmdutils.receive(p))
     self.assertEqual(received, [])
     self.assertEqual(p.returncode, 1)
コード例 #5
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_stdout(self):
     p = subprocess.Popen(["echo", "output"],
                          stdin=None,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     received = list(cmdutils.receive(p))
     self.assertEqual(received, [(cmdutils.OUT, b"output\n")])
     self.assertEqual(p.returncode, 0)
コード例 #6
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_stderr(self):
     p = subprocess.Popen(["sh", "-c", "echo error >/dev/stderr"],
                          stdin=None,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     received = list(cmdutils.receive(p))
     self.assertEqual(received, [(cmdutils.ERR, b"error\n")])
     self.assertEqual(p.returncode, 0)
コード例 #7
0
ファイル: commands.py プロジェクト: ZhangNatural/vdsm
def execCmd(command,
            sudo=False,
            cwd=None,
            data=None,
            raw=False,
            printable=None,
            env=None,
            nice=None,
            ioclass=None,
            ioclassdata=None,
            setsid=False,
            execCmdLogger=logging.root,
            resetCpuAffinity=True):
    """
    Executes an external command, optionally via sudo.
    """

    command = cmdutils.wrap_command(command,
                                    with_ioclass=ioclass,
                                    ioclassdata=ioclassdata,
                                    with_nice=nice,
                                    with_setsid=setsid,
                                    with_sudo=sudo,
                                    reset_cpu_affinity=resetCpuAffinity)

    # Unsubscriptable objects (e.g. generators) need conversion
    if not callable(getattr(command, '__getitem__', None)):
        command = tuple(command)

    if not printable:
        printable = command

    execCmdLogger.debug(command_log_line(printable, cwd=cwd))

    p = subprocess.Popen(command,
                         close_fds=True,
                         cwd=cwd,
                         env=env,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

    with terminating(p):
        (out, err) = p.communicate(data)

    if out is None:
        # Prevent splitlines() from barfing later on
        out = b""

    execCmdLogger.debug(retcode_log_line(p.returncode, err=err))

    if not raw:
        out = out.splitlines(False)
        err = err.splitlines(False)

    return p.returncode, out, err
コード例 #8
0
 def test_without_affinity(self):
     args = [EXT_SLEEP, "3"]
     popen = subprocess.Popen(args, close_fds=True)
     stats = proc.pidstat(popen.pid)
     pid = int(stats.pid)
     # procName comes in the format of (procname)
     name = stats.comm
     self.assertEqual(pid, popen.pid)
     self.assertEqual(name, args[0])
     popen.kill()
     popen.wait()
コード例 #9
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_both_stdout_stderr(self):
     p = subprocess.Popen(
         ["sh", "-c", "echo output; echo error >/dev/stderr;"],
         stdin=None,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE)
     received = list(cmdutils.receive(p))
     self.assertEqual(sorted(received), sorted([
         (cmdutils.OUT, b"output\n"), (cmdutils.ERR, b"error\n")
     ]))
     self.assertEqual(p.returncode, 0)
コード例 #10
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_timeout_with_data(self):
     p = subprocess.Popen(["yes"],
                          stdin=None,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     try:
         with self.assertRaises(cmdutils.TimeoutExpired):
             for _ in cmdutils.receive(p, 0.5):
                 pass
     finally:
         p.kill()
         p.wait()
コード例 #11
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_no_fds(self):
     p = subprocess.Popen(["sleep", "1"],
                          stdin=None,
                          stdout=None,
                          stderr=None)
     try:
         with self.assertRaises(cmdutils.TimeoutExpired):
             for _ in cmdutils.receive(p, 0.5):
                 pass
     finally:
         p.kill()
         p.wait()
コード例 #12
0
ファイル: cmdutils_test.py プロジェクト: kkoojjyy/vdsm
 def test_fds_closed(self):
     cmd = ["python", "-c",
            "import os, time; os.close(1); os.close(2); time.sleep(1)"]
     p = subprocess.Popen(cmd, stdin=None, stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
     try:
         with self.assertRaises(cmdutils.TimeoutExpired):
             for _ in cmdutils.receive(p, 0.5):
                 pass
     finally:
         p.kill()
         p.wait()
コード例 #13
0
 def _child_processes(self):
     proc = subprocess.Popen(self.PGREP_CMD,
                             stdin=None,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
     out, err = proc.communicate()
     # EXIT STATUS
     # 0      One or more processes matched the criteria.
     # 1      No processes matched.
     if proc.returncode not in (0, 1):
         raise RuntimeError("Error running pgrep: [%d] %s" %
                            (proc.returncode, err))
     return frozenset(int(pid) for pid in out.splitlines())
コード例 #14
0
 def _start_process(self):
     """
     Starts a dd process performing direct I/O to path, reading the process
     stderr. When stderr has closed, _read_completed will be called.
     """
     cmd = [constants.EXT_DD, "if=%s" % self._path, "of=/dev/null",
            "bs=4096", "count=1", "iflag=direct"]
     cmd = cmdutils.wrap_command(cmd)
     self._proc = subprocess.Popen(
         cmd, stdin=None, stdout=None,
         stderr=subprocess.PIPE)
     self._reader = self._loop.create_dispatcher(
         asyncevent.BufferedReader, self._proc.stderr, self._read_completed)
コード例 #15
0
def checkSudo(cmd):
    try:
        p = subprocess.Popen(['sudo', '-l', '-n'] + cmd,
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
    except OSError as e:
        if e.errno == errno.ENOENT:
            raise SkipTest("Test requires SUDO executable (%s)" % e)
        else:
            raise

    out, err = p.communicate()

    if p.returncode != 0:
        raise SkipTest("Test requires SUDO configuration (%s)" % err.strip())
コード例 #16
0
 def test(self):
     sleepProcs = []
     try:
         for i in range(3):
             popen = subprocess.Popen([EXT_SLEEP, "3"])
             sleepProcs.append(popen)
         # There is no guarantee which process run first after forking a
         # child process, make sure all the children are runing before we
         # look for them.
         time.sleep(0.5)
         pids = proc.pgrep(EXT_SLEEP)
         for popen in sleepProcs:
             self.assertIn(popen.pid, pids)
     finally:
         for popen in sleepProcs:
             popen.kill()
             popen.wait()
コード例 #17
0
    def _start_process(self):
        """
        Start the underlying process.

        Raises:
            `RuntimeError` if invoked more then once
        """
        with self._lock:
            if self._state == ABORTED:
                raise exception.ActionStopped
            if self._state != CREATED:
                raise RuntimeError("Attempt to run an operation twice")
            log.debug(cmdutils.command_log_line(self._cmd, cwd=self._cwd))
            self._proc = subprocess.Popen(self._cmd,
                                          cwd=self._cwd,
                                          stdin=None,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE)
            self._state = RUNNING
コード例 #18
0
    def test_terminate(self, signo):
        # Start bash process printing its pid and sleeping.
        p = subprocess.Popen(
            ['./py-watch', '10', 'bash', '-c', 'echo $$; sleep 10'],
            stdout=subprocess.PIPE)

        # Wait until the underlying bash process prints its pid.
        for src, data in cmdutils.receive(p):
            if src == cmdutils.OUT:
                child_pid = int(data)
                break

        # Terminate py-watch, and check its exit code.
        p.send_signal(signo)
        assert p.wait() == 128 + signo

        # Check that the child process was terminated.
        with pytest.raises(OSError) as e:
            assert os.kill(child_pid, 0)
        assert e.value.errno == errno.ESRCH
コード例 #19
0
ファイル: pywatch_test.py プロジェクト: vjuranek/vdsm
    def test_terminate(self, signo):
        # Start bash process printing its pid and sleeping. The short sleep
        # before printing the pid avoids a race when we got the pid before
        # py-watch started to wait for the child.
        p = subprocess.Popen([
            sys.executable, 'py-watch', '10', 'bash', '-c',
            'sleep 0.5; echo $$; sleep 10'
        ],
                             stdout=subprocess.PIPE)

        # Wait until the underlying bash process prints its pid.
        for src, data in cmdutils.receive(p):
            if src == cmdutils.OUT:
                child_pid = int(data)
                break

        # Terminate py-watch, and check its exit code.
        p.send_signal(signo)
        assert p.wait() == 128 + signo

        # Check that the child process was terminated.
        with pytest.raises(OSError) as e:
            assert os.kill(child_pid, 0)
        assert e.value.errno == errno.ESRCH
コード例 #20
0
def netns_exec(netns_name, command):
    cmds = [_IP_BINARY.cmd, 'netns', 'exec', netns_name] + command
    return subprocess.Popen(cmds)