Beispiel #1
0
    def _wait_for_child_process(self,
                                timeout=CHILD_PROCESS_TIMEOUT,
                                sleep=CHILD_PROCESS_SLEEP):
        def child_is_running():
            child_pid = utils.get_root_helper_child_pid(self.pid,
                                                        self.cmd,
                                                        run_as_root=True)
            if utils.pid_invoked_with_cmdline(child_pid, self.cmd):
                return True

        try:
            common_utils.wait_until_true(child_is_running, timeout)
        except common_utils.WaitTimeout:
            # If there is an error, the stderr and stdout pipes usually have
            # information returned by the command executed. If not, timeout
            # the pipe communication quickly.
            stdout = stderr = ''
            try:
                stdout, stderr = self.communicate(timeout=0.5)
            except subprocess.TimeoutExpired:
                pass
            msg = ("Process %(cmd)s hasn't been spawned in %(seconds)d "
                   "seconds. Return code: %(ret_code)s, stdout: %(stdout)s, "
                   "sdterr: %(stderr)s" % {
                       'cmd': self.cmd,
                       'seconds': timeout,
                       'ret_code': self.returncode,
                       'stdout': stdout,
                       'stderr': stderr
                   })
            raise RuntimeError(msg)

        self.child_pid = utils.get_root_helper_child_pid(self.pid,
                                                         self.cmd,
                                                         run_as_root=True)
Beispiel #2
0
    def _test_get_root_helper_child_pid(self,
                                        expected=_marker,
                                        run_as_root=False,
                                        pids=None,
                                        cmds=None):
        def _find_child_pids(x):
            if not pids:
                return []
            pids.pop(0)
            return pids

        mock_pid = object()
        pid_invoked_with_cmdline = {}
        if cmds:
            pid_invoked_with_cmdline['side_effect'] = cmds
        else:
            pid_invoked_with_cmdline['return_value'] = False
        with mock.patch.object(utils, 'find_child_pids',
                               side_effect=_find_child_pids), \
                mock.patch.object(utils, 'pid_invoked_with_cmdline',
                                  **pid_invoked_with_cmdline):
            actual = utils.get_root_helper_child_pid(mock_pid, mock.ANY,
                                                     run_as_root)
        if expected is _marker:
            expected = str(mock_pid)
        self.assertEqual(expected, actual)
Beispiel #3
0
 def pid(self):
     if self._process:
         if not self._pid:
             self._pid = utils.get_root_helper_child_pid(
                 self._process.pid,
                 self.cmd_without_namespace,
                 run_as_root=self.run_as_root)
         return self._pid
Beispiel #4
0
 def pid(self):
     if self._process:
         if not self._pid:
             self._pid = utils.get_root_helper_child_pid(
                 self._process.pid,
                 self.cmd_without_namespace,
                 run_as_root=self.run_as_root)
         return self._pid
Beispiel #5
0
    def test_async_process_respawns(self):
        proc = async_process.AsyncProcess(["tail", "-f", self.test_file_path], respawn_interval=0)
        proc.start()

        # Ensure that the same output is read twice
        self._check_stdout(proc)
        pid = utils.get_root_helper_child_pid(proc._process.pid, proc.root_helper)
        proc._kill_process(pid)
        self._check_stdout(proc)
        proc.stop()
Beispiel #6
0
    def _wait_for_child_process(self, timeout=CHILD_PROCESS_TIMEOUT, sleep=CHILD_PROCESS_SLEEP):
        def child_is_running():
            child_pid = utils.get_root_helper_child_pid(self.pid, run_as_root=True)
            if utils.pid_invoked_with_cmdline(child_pid, self.cmd):
                return True

        utils.wait_until_true(
            child_is_running,
            timeout,
            exception=RuntimeError("Process %s hasn't been spawned " "in %d seconds" % (self.cmd, timeout)),
        )
        self.child_pid = utils.get_root_helper_child_pid(self.pid, run_as_root=True)
Beispiel #7
0
    def test_async_process_respawns(self):
        proc = async_process.AsyncProcess(['tail', '-f', self.test_file_path],
                                          respawn_interval=0)
        proc.start()

        # Ensure that the same output is read twice
        self._check_stdout(proc)
        pid = utils.get_root_helper_child_pid(proc._process.pid,
                                              proc.run_as_root)
        proc._kill_process(pid)
        self._check_stdout(proc)
        proc.stop()
Beispiel #8
0
 def test_killed_monitor_respawns(self):
     self.monitor.respawn_interval = 0
     old_pid = self.monitor._process.pid
     output1 = self.collect_initial_output()
     pid = utils.get_root_helper_child_pid(old_pid, self.root_helper)
     self.monitor._kill_process(pid)
     self.monitor._reset_queues()
     while (self.monitor._process.pid == old_pid):
         eventlet.sleep(0.01)
     output2 = self.collect_initial_output()
     # Initial output should appear twice
     self.assertEqual(output1, output2)
Beispiel #9
0
 def test_killed_monitor_respawns(self):
     self.monitor.respawn_interval = 0
     old_pid = self.monitor._process.pid
     output1 = self.collect_initial_output()
     pid = utils.get_root_helper_child_pid(old_pid, run_as_root=True)
     self.monitor._kill_process(pid)
     self.monitor._reset_queues()
     while (self.monitor._process.pid == old_pid):
         eventlet.sleep(0.01)
     output2 = self.collect_initial_output()
     # Initial output should appear twice
     self.assertEqual(output1, output2)
Beispiel #10
0
    def _test_get_root_helper_child_pid(self, expected=_marker, run_as_root=False, pids=None):
        def _find_child_pids(x):
            if not pids:
                return []
            pids.pop(0)
            return pids

        mock_pid = object()
        with mock.patch.object(utils, "find_child_pids", side_effect=_find_child_pids):
            actual = utils.get_root_helper_child_pid(mock_pid, run_as_root)
        if expected is _marker:
            expected = str(mock_pid)
        self.assertEqual(expected, actual)
Beispiel #11
0
    def _test_get_root_helper_child_pid(self, expected=_marker,
                                        run_as_root=False, pids=None):
        def _find_child_pids(x):
            if not pids:
                return []
            pids.pop(0)
            return pids

        mock_pid = object()
        with mock.patch.object(utils, 'find_child_pids',
                               side_effect=_find_child_pids):
            actual = utils.get_root_helper_child_pid(mock_pid, run_as_root)
        if expected is _marker:
            expected = str(mock_pid)
        self.assertEqual(expected, actual)
Beispiel #12
0
    def _wait_for_child_process(self, timeout=CHILD_PROCESS_TIMEOUT,
                                sleep=CHILD_PROCESS_SLEEP):
        def child_is_running():
            child_pid = utils.get_root_helper_child_pid(
                self.pid, run_as_root=self.run_as_root)
            if pid_invoked_with_cmdline(child_pid, self.cmd):
                return True

        wait_until_true(
            child_is_running,
            timeout,
            exception=RuntimeError("Process %s hasn't been spawned "
                                   "in %d seconds" % (self.cmd, timeout)))
        self.child_pid = utils.get_root_helper_child_pid(
            self.pid, run_as_root=self.run_as_root)
Beispiel #13
0
    def test_get_root_helper_child_pid_returns_first_child(self):
        """Test that the first child, not lowest child pid is returned.

        Test creates following process tree:
          sudo +
               |
               +--rootwrap +
                           |
                           +--bash+
                                  |
                                  +--sleep 100

        and tests that pid of `bash' command is returned.
        """

        def wait_for_sleep_is_spawned(parent_pid):
            proc_tree = utils.execute(
                ['pstree', parent_pid], check_exit_code=False)
            processes = [command.strip() for command in proc_tree.split('---')
                         if command]
            if processes:
                return 'sleep' == processes[-1]

        cmd = ['bash', '-c', '(sleep 100)']
        proc = async_process.AsyncProcess(cmd, run_as_root=True)
        proc.start()

        # root helpers spawn their child processes asynchronously, and we
        # don't want to use proc.start(block=True) as that uses
        # get_root_helper_child_pid (The method under test) internally.
        sudo_pid = proc._process.pid
        common_utils.wait_until_true(
            functools.partial(
                wait_for_sleep_is_spawned,
                sudo_pid),
            sleep=0.1)

        child_pid = utils.get_root_helper_child_pid(
            sudo_pid, cmd, run_as_root=True)
        self.assertIsNotNone(
            child_pid,
            "get_root_helper_child_pid is expected to return the pid of the "
            "bash process")
        self._addcleanup_sleep_process(child_pid)
        with open('/proc/%s/cmdline' % child_pid, 'r') as f_proc_cmdline:
            cmdline = f_proc_cmdline.readline().split('\0')[0]
        self.assertIn('bash', cmdline)
Beispiel #14
0
    def test_get_root_helper_child_pid_returns_first_child(self):
        """Test that the first child, not lowest child pid is returned.

        Test creates following process tree:
          sudo +
               |
               +--rootwrap +
                           |
                           +--bash+
                                  |
                                  +--sleep 100

        and tests that pid of `bash' command is returned.
        """
        def wait_for_sleep_is_spawned(parent_pid):
            proc_tree = utils.execute(['pstree', parent_pid],
                                      check_exit_code=False)
            processes = [
                command.strip() for command in proc_tree.split('---')
                if command
            ]
            if processes:
                return 'sleep' == processes[-1]

        cmd = ['bash', '-c', '(sleep 100)']
        proc = async_process.AsyncProcess(cmd, run_as_root=True)
        proc.start()

        # root helpers spawn their child processes asynchronously, and we
        # don't want to use proc.start(block=True) as that uses
        # get_root_helper_child_pid (The method under test) internally.
        sudo_pid = proc._process.pid
        common_utils.wait_until_true(functools.partial(
            wait_for_sleep_is_spawned, sudo_pid),
                                     sleep=0.1)

        child_pid = utils.get_root_helper_child_pid(sudo_pid,
                                                    cmd,
                                                    run_as_root=True)
        self.assertIsNotNone(
            child_pid,
            "get_root_helper_child_pid is expected to return the pid of the "
            "bash process")
        self._addcleanup_sleep_process(child_pid)
        with open('/proc/%s/cmdline' % child_pid, 'r') as f_proc_cmdline:
            cmdline = f_proc_cmdline.readline().split('\0')[0]
        self.assertIn('bash', cmdline)
Beispiel #15
0
    def _kill(self, respawning=False):
        """Kill the process and the associated watcher greenthreads.

        :param respawning: Optional, whether respawn will be subsequently
               attempted.
        """
        # Halt the greenthreads
        self._kill_event.send()

        pid = utils.get_root_helper_child_pid(self._process.pid,
                                              run_as_root=self.run_as_root)
        if pid:
            self._kill_process(pid)

        if not respawning:
            # Clear the kill event to ensure the process can be
            # explicitly started again.
            self._kill_event = None
Beispiel #16
0
    def _kill(self, respawning=False):
        """Kill the process and the associated watcher greenthreads.

        :param respawning: Optional, whether respawn will be subsequently
               attempted.
        """
        # Halt the greenthreads
        self._kill_event.send()

        pid = utils.get_root_helper_child_pid(
            self._process.pid, self.root_helper)
        if pid:
            self._kill_process(pid)

        if not respawning:
            # Clear the kill event to ensure the process can be
            # explicitly started again.
            self._kill_event = None
Beispiel #17
0
    def _test_get_root_helper_child_pid(self, expected=_marker, run_as_root=False, pids=None, cmds=None):
        def _find_child_pids(x):
            if not pids:
                return []
            pids.pop(0)
            return pids

        mock_pid = object()
        pid_invoked_with_cmdline = {}
        if cmds:
            pid_invoked_with_cmdline["side_effect"] = cmds
        else:
            pid_invoked_with_cmdline["return_value"] = False
        with mock.patch.object(utils, "find_child_pids", side_effect=_find_child_pids), mock.patch.object(
            utils, "pid_invoked_with_cmdline", **pid_invoked_with_cmdline
        ):
            actual = utils.get_root_helper_child_pid(mock_pid, mock.ANY, run_as_root)
        if expected is _marker:
            expected = str(mock_pid)
        self.assertEqual(expected, actual)
 def pid(self):
     if self._process:
         return utils.get_root_helper_child_pid(
             self._process.pid, run_as_root=self.run_as_root)
Beispiel #19
0
 def pid(self):
     if self._process:
         return utils.get_root_helper_child_pid(
             self._process.pid,
             run_as_root=self.run_as_root)
Beispiel #20
0
 def child_is_running():
     child_pid = utils.get_root_helper_child_pid(self.pid,
                                                 run_as_root=True)
     if utils.pid_invoked_with_cmdline(child_pid, self.cmd):
         return True
Beispiel #21
0
 def child_is_running():
     child_pid = utils.get_root_helper_child_pid(
         self.pid, self.cmd, run_as_root=True)
     if utils.pid_invoked_with_cmdline(child_pid, self.cmd):
         return True