Пример #1
0
def execCmd(command, sudo=False, cwd=None, data=None, raw=False,
            printable=None, env=None, sync=True, nice=None, ioclass=None,
            ioclassdata=None, setsid=False, execCmdLogger=logging.root,
            deathSignal=0, childUmask=None):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    if ioclass is not None:
        command = cmdutils.ionice(command, ioclass=ioclass,
                                  ioclassdata=ioclassdata)

    if nice is not None:
        command = cmdutils.nice(command, nice=nice)

    if setsid:
        command = cmdutils.setsid(command)

    if sudo:
        command = cmdutils.sudo(command)

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

    if not printable:
        printable = command

    execCmdLogger.debug("%s (cwd %s)", _list2cmdline(printable), cwd)

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal, childUmask=childUmask)
    if not sync:
        p = AsyncProc(p)
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

    execCmdLogger.debug("%s: <err> = %r; <rc> = %d",
                        "SUCCESS" if p.returncode == 0 else "FAILED",
                        err, p.returncode)

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

    return p.returncode, out, err
Пример #2
0
def execCmd(command, sudo=False, cwd=None, data=None, raw=False,
            printable=None, env=None, sync=True, nice=None, ioclass=None,
            ioclassdata=None, setsid=False, execCmdLogger=logging.root,
            deathSignal=0, childUmask=None):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    if ioclass is not None:
        command = cmdutils.ionice(command, ioclass=ioclass,
                                  ioclassdata=ioclassdata)

    if nice is not None:
        command = cmdutils.nice(command, nice=nice)

    if setsid:
        command = cmdutils.setsid(command)

    if sudo:
        command = cmdutils.sudo(command)

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

    if not printable:
        printable = command

    execCmdLogger.debug("%s (cwd %s)", _list2cmdline(printable), cwd)

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal, childUmask=childUmask)
    if not sync:
        p = AsyncProc(p)
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

    execCmdLogger.debug("%s: <err> = %r; <rc> = %d",
                        "SUCCESS" if p.returncode == 0 else "FAILED",
                        err, p.returncode)

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

    return p.returncode, out, err
Пример #3
0
def execCmd(command, cwd=None, data=None, raw=False,
            env=None, sync=True, deathSignal=0, childUmask=None):
    """
    Executes an external command,
    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    cmdline = repr(subprocess.list2cmdline(command))
    logger.info("%s (cwd %s)", cmdline, cwd)

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal, childUmask=childUmask)

    (out, err) = p.communicate(data)

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

    logger.debug("%s: <err> = %s; <rc> = %d",
                        {True: "SUCCESS", False: "FAILED"}[p.returncode == 0],
                 repr(err), p.returncode)

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

    return (p.returncode, out, err)
Пример #4
0
def execCmd(command, sudo=False, cwd=None, data=None, raw=False, logErr=True,
            printable=None, env=None, sync=True, nice=None, ioclass=None,
            ioclassdata=None, setsid=False, execCmdLogger=logging.root,
            deathSignal=0, childUmask=None):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """
    if ioclass is not None:
        cmd = command
        command = [ioniceCmdPath.cmd, '-c', str(ioclass)]
        if ioclassdata is not None:
            command.extend(("-n", str(ioclassdata)))

        command = command + cmd

    if nice is not None:
        command = [niceCmdPath.cmd, '-n', str(nice)] + command

    if setsid:
        command = [setsidCmdPath.cmd] + command

    if sudo:
        command = [sudoCmdPath.cmd, SUDO_NON_INTERACTIVE_FLAG] + command

    if not printable:
        printable = command

    cmdline = repr(subprocess.list2cmdline(printable))
    execCmdLogger.debug("%s (cwd %s)", cmdline, cwd)

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal, childUmask=childUmask)
    p = AsyncProc(p)
    if not sync:
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

    execCmdLogger.debug("%s: <err> = %s; <rc> = %d",
                        {True: "SUCCESS", False: "FAILED"}[p.returncode == 0],
                        repr(err), p.returncode)

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

    return (p.returncode, out, err)
Пример #5
0
 def testEcho(self):
     data = "Hello"
     p = CPopen([EXT_ECHO, "-n", data])
     out, err = p.communicate()
     self.assertTrue(p.returncode == 0,
                     "Process failed: %s" % os.strerror(p.returncode))
     self.assertEquals(out, data)
Пример #6
0
 def testCat(self):
     path = "/etc/passwd"
     p = CPopen(["cat", path])
     out, err = p.communicate()
     self.assertTrue(p.returncode == 0,
                     "Process failed: %s" % os.strerror(p.returncode))
     with open(path, "r") as f:
         self.assertEquals(out, f.read())
Пример #7
0
    def testStdin(self):
        data = "Hello World"
        p = CPopen(["cat"])
        out, err = p.communicate(data)
        self.assertTrue(p.returncode == 0,
                        "Process failed: %s" % os.strerror(p.returncode))

        self.assertEquals(out, data)
Пример #8
0
 def testCwd(self):
     cwd = "/proc"
     p = CPopen(["python", "-c", "import os; print os.getcwd()"],
                cwd=cwd)
     out, err = p.communicate()
     self.assertTrue(p.returncode == 0,
                     "Process failed: %s" % os.strerror(p.returncode))
     self.assertEquals(out.strip(), cwd)
Пример #9
0
def execCmd(command, sudo=False, cwd=None, data=None, raw=False, logErr=True,
            printable=None, env=None, sync=True, nice=None, ioclass=None,
            ioclassdata=None, setsid=False, execCmdLogger=logging.root,
            deathSignal=0):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: don't define a deathSignal when sync=False
    """
    if ioclass is not None:
        cmd = command
        command = [constants.EXT_IONICE, '-c', str(ioclass)]
        if ioclassdata is not None:
            command.extend(("-n", str(ioclassdata)))

        command = command + cmd

    if nice is not None:
        command = [constants.EXT_NICE, '-n', str(nice)] + command

    if setsid:
        command = [constants.EXT_SETSID] + command

    if sudo:
        command = [constants.EXT_SUDO, SUDO_NON_INTERACTIVE_FLAG] + command

    if not printable:
        printable = command

    cmdline = repr(subprocess.list2cmdline(printable))
    execCmdLogger.debug("%s (cwd %s)", cmdline, cwd)

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal)
    p = AsyncProc(p)
    if not sync:
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

    execCmdLogger.debug("%s: <err> = %s; <rc> = %d",
                        {True: "SUCCESS", False: "FAILED"}[p.returncode == 0],
                        repr(err), p.returncode)

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

    return (p.returncode, out, err)
Пример #10
0
 def testCloseOnExecStdin(self):
     # Unset close-on-exec on stdin fd
     data = "data"
     with tempfile.NamedTemporaryFile() as f:
         f.write(data)
         f.flush()
         set_close_on_exec(f.fileno())
         p = CPopen(["cat", f.name], stdin=f.fileno(), stdout=PIPE)
         out, err = p.communicate()
         self.assertEqual(out, data)
Пример #11
0
    def testUnicodeArg(self):
        data = u'hello'
        cmd = [EXT_ECHO, "-n", data]

        p = CPopen(cmd)
        out, err = p.communicate()
        p2 = subprocess.Popen(cmd, stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out2, err2 = p2.communicate()
        self.assertEquals(out, out2)
Пример #12
0
 def testPipeline(self):
     # echo -n 'it works!' | cat
     data = "it works!"
     p2 = CPopen(["cat"], stdin=PIPE, stdout=PIPE)
     try:
         p1 = CPopen(["echo", "-n", data], stdin=PIPE, stdout=p2.stdin)
         p1.wait()
     finally:
         out, err = p2.communicate()
     self.assertEqual(data, out)
Пример #13
0
def execCmd(command, sudo=False, cwd=None, data=None, raw=False,
            printable=None, env=None, sync=True, nice=None, ioclass=None,
            ioclassdata=None, setsid=False, execCmdLogger=logging.root,
            deathSignal=0, childUmask=None, resetCpuAffinity=True):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    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(cmdutils.command_log_line(printable, cwd=cwd))

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal, childUmask=childUmask)
    if not sync:
        p = AsyncProc(p)
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

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

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

    return p.returncode, out, err
Пример #14
0
    def testNonASCIIUnicodeArg(self):
        data = u'\u05e9\u05dc\u05d5\u05dd'
        # If the default encoding is not utf-8 the test *should* fail as non
        # ascii conversion shouldn't work
        if sys.getfilesystemencoding() != "UTF-8":
            raise SkipTest("The default encoding isn't unicode")

        cmd = [EXT_ECHO, "-n", data]

        p = CPopen(cmd)
        out, err = p.communicate()
        p2 = subprocess.Popen(cmd, stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out2, err2 = p2.communicate()
        self.assertEquals(out, out2)
Пример #15
0
 def testEnvUnicodeKey(self):
     p = CPopen(["printenv"], env={u"\u05d0": "value"})
     out, err = p.communicate()
     self.assertEqual(out, "\xd7\x90=value\n")
Пример #16
0
 def testEnvUnicodeValue(self):
     p = CPopen(["printenv"], env={"key": u"\u05d0"})
     out, err = p.communicate()
     self.assertEqual(out, "key=\xd7\x90\n")
Пример #17
0
def execCmd(command,
            sudo=False,
            cwd=None,
            data=None,
            raw=False,
            printable=None,
            env=None,
            sync=True,
            nice=None,
            ioclass=None,
            ioclassdata=None,
            setsid=False,
            execCmdLogger=logging.root,
            deathSignal=0,
            childUmask=None,
            resetCpuAffinity=True):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    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(cmdutils.command_log_line(printable, cwd=cwd))

    p = CPopen(command,
               close_fds=True,
               cwd=cwd,
               env=env,
               deathSignal=deathSignal,
               childUmask=childUmask)
    if not sync:
        p = AsyncProc(p)
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

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

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

    return p.returncode, out, err
Пример #18
0
 def testUmaskChange(self):
     p = CPopen(['sh', '-c', 'umask'], childUmask=0o007)
     out, err = p.communicate()
     self.assertEquals(out.splitlines()[0].strip(), '0007')
Пример #19
0
def execCmd(command,
            sudo=False,
            cwd=None,
            data=None,
            raw=False,
            printable=None,
            env=None,
            sync=True,
            nice=None,
            ioclass=None,
            ioclassdata=None,
            setsid=False,
            execCmdLogger=logging.root,
            deathSignal=0,
            childUmask=None,
            resetCpuAffinity=True):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    if ioclass is not None:
        command = cmdutils.ionice(command,
                                  ioclass=ioclass,
                                  ioclassdata=ioclassdata)

    if nice is not None:
        command = cmdutils.nice(command, nice=nice)

    if setsid:
        command = cmdutils.setsid(command)

    if sudo:
        command = cmdutils.sudo(command)

    # warning: the order of commands matters. If we add taskset
    # after sudo, we'll need to configure sudoers to allow both
    # 'sudo <command>' and 'sudo taskset <command>', which is
    # impractical. On the other hand, using 'taskset sudo <command>'
    # is much simpler and delivers the same end result.

    if resetCpuAffinity and _USING_CPU_AFFINITY:
        # only VDSM itself should be bound
        command = cmdutils.taskset(command, _ANY_CPU)

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

    if not printable:
        printable = command

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

    p = CPopen(command,
               close_fds=True,
               cwd=cwd,
               env=env,
               deathSignal=deathSignal,
               childUmask=childUmask)
    if not sync:
        p = AsyncProc(p)
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

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

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

    return p.returncode, out, err
Пример #20
0
 def testEnv(self):
     p = CPopen(["printenv"], env={"key": "value"})
     out, err = p.communicate()
     self.assertEqual(out, "key=value\n")
Пример #21
0
def execCmd(command,
            sudo=False,
            cwd=None,
            data=None,
            raw=False,
            logErr=True,
            printable=None,
            env=None,
            sync=True,
            nice=None,
            ioclass=None,
            ioclassdata=None,
            setsid=False,
            execCmdLogger=logging.root,
            deathSignal=0,
            childUmask=None):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """
    if ioclass is not None:
        cmd = command
        command = [ioniceCmdPath.cmd, '-c', str(ioclass)]
        if ioclassdata is not None:
            command.extend(("-n", str(ioclassdata)))

        command = command + cmd

    if nice is not None:
        command = [niceCmdPath.cmd, '-n', str(nice)] + command

    if setsid:
        command = [setsidCmdPath.cmd] + command

    if sudo:
        command = [sudoCmdPath.cmd, SUDO_NON_INTERACTIVE_FLAG] + command

    if not printable:
        printable = command

    cmdline = repr(subprocess.list2cmdline(printable))
    execCmdLogger.debug("%s (cwd %s)", cmdline, cwd)

    p = CPopen(command,
               close_fds=True,
               cwd=cwd,
               env=env,
               deathSignal=deathSignal,
               childUmask=childUmask)
    p = AsyncProc(p)
    if not sync:
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

    execCmdLogger.debug("%s: <err> = %s; <rc> = %d", {
        True: "SUCCESS",
        False: "FAILED"
    }[p.returncode == 0], repr(err), p.returncode)

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

    return (p.returncode, out, err)
Пример #22
0
def execCmd(command, sudo=False, cwd=None, data=None, raw=False,
            printable=None, env=None, sync=True, nice=None, ioclass=None,
            ioclassdata=None, setsid=False, execCmdLogger=logging.root,
            deathSignal=0, childUmask=None, resetCpuAffinity=True):
    """
    Executes an external command, optionally via sudo.

    IMPORTANT NOTE: the new process would receive `deathSignal` when the
    controlling thread dies, which may not be what you intended: if you create
    a temporary thread, spawn a sync=False sub-process, and have the thread
    finish, the new subprocess would die immediately.
    """

    if ioclass is not None:
        command = cmdutils.ionice(command, ioclass=ioclass,
                                  ioclassdata=ioclassdata)

    if nice is not None:
        command = cmdutils.nice(command, nice=nice)

    if setsid:
        command = cmdutils.setsid(command)

    if sudo:
        command = cmdutils.sudo(command)

    # warning: the order of commands matters. If we add taskset
    # after sudo, we'll need to configure sudoers to allow both
    # 'sudo <command>' and 'sudo taskset <command>', which is
    # impractical. On the other hand, using 'taskset sudo <command>'
    # is much simpler and delivers the same end result.

    if resetCpuAffinity and _USING_CPU_AFFINITY:
        # only VDSM itself should be bound
        command = cmdutils.taskset(command, _ANY_CPU)

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

    if not printable:
        printable = command

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

    p = CPopen(command, close_fds=True, cwd=cwd, env=env,
               deathSignal=deathSignal, childUmask=childUmask)
    if not sync:
        p = AsyncProc(p)
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

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

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

    return p.returncode, out, err
Пример #23
0
def execCmd(command,
            sudo=False,
            cwd=None,
            data=None,
            raw=False,
            logErr=True,
            printable=None,
            env=None,
            sync=True,
            nice=None,
            ioclass=None,
            ioclassdata=None,
            setsid=False,
            execCmdLogger=logging.root):
    """
    Executes an external command, optionally via sudo.
    """
    if ioclass is not None:
        cmd = command
        command = [constants.EXT_IONICE, '-c', str(ioclass)]
        if ioclassdata is not None:
            command.extend(("-n", str(ioclassdata)))

        command = command + cmd

    if nice is not None:
        command = [constants.EXT_NICE, '-n', str(nice)] + command

    if setsid:
        command = [constants.EXT_SETSID] + command

    if sudo:
        command = [constants.EXT_SUDO, SUDO_NON_INTERACTIVE_FLAG] + command

    if not printable:
        printable = command

    cmdline = repr(subprocess.list2cmdline(printable))
    execCmdLogger.debug("%s (cwd %s)", cmdline, cwd)

    p = BetterPopen(command, close_fds=True, cwd=cwd, env=env)
    p = AsyncProc(p)
    if not sync:
        if data is not None:
            p.stdin.write(data)
            p.stdin.flush()

        return p

    (out, err) = p.communicate(data)

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

    execCmdLogger.debug("%s: <err> = %s; <rc> = %d", {
        True: "SUCCESS",
        False: "FAILED"
    }[p.returncode == 0], repr(err), p.returncode)

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

    return (p.returncode, out, err)