Example #1
0
 def test_exitcode_nonzero(self):
     cmd = ['false']
     with pytest.raises(subprocess.CalledProcessError) as excinfo:
         popen_rt(cmd)
     err = excinfo.value
     assert err.returncode > 0
     assert err.cmd == cmd
     assert not err.output
Example #2
0
 def test_stdin(self, tmpdir):
     text = 'foo\nbar'
     infile = tmpdir.join('stdin')
     infile.write(text)
     out, err = popen_rt(['cat'], stdin=infile.open())
     assert out == text
     assert not err
Example #3
0
 def test_stderr(self):
     text = 'Lorem ipsum'
     out, err = popen_rt('echo -n %s >&2' % text,
                         shell=True,
                         stderr=subprocess.PIPE)
     assert not out
     assert err == text
Example #4
0
 def test_stream_merge(self):
     text_out = 'this is stdout'
     text_err = 'this is stderr'
     out, err = popen_rt('echo -n %s; echo -n %s >&2' %
                         (text_out, text_err),
                         shell=True)
     assert out == text_out + text_err
     assert not err
Example #5
0
 def test_stream_separate(self):
     text_out = 'this is stdout'
     text_err = 'this is stderr'
     out, err = popen_rt('echo -n %s; echo -n %s >&2' %
                         (text_out, text_err),
                         shell=True,
                         stderr=subprocess.PIPE)
     assert out == text_out
     assert err == text_err
Example #6
0
 def test_raise_stdout(self):
     with pytest.raises(exc.CheckbValueError):
         popen_rt(['false'], stdout=None)
Example #7
0
 def test_shell(self):
     popen_rt('true && true', shell=True)
Example #8
0
 def test_stdout(self):
     text = 'Lorem ipsum'
     out, err = popen_rt(['echo', '-n', text])
     assert out == text
     assert not err
Example #9
0
 def test_exitcode_zero(self):
     out, err = popen_rt(['true'])
     assert not out
     assert not err
Example #10
0
    def _run_playbook(self, test_playbook, ipaddr, playbook_vars):
        '''Run the ansible-playbook command to execute given playbook
        containing the task.

        :param str test_playbook: name of the playbook, relative to the task
            directory
        :param str ipaddr: IP address of the machine the task will be run on
        :param dict playbook_vars: vars dict created by
            :meth:`_create_playbook_vars`
        :return: stream output of the ansible-playbook command (stdout and
            stderr merged together)
        :rtype: str
        :raise CheckbPlaybookError: when the playbook is not syntactically
            correct
        '''
        ansible_dir = os.path.join(config.get_config()._data_dir, 'ansible')

        # dump variables for future use
        varsfile, allvarsfile = self._dump_playbook_vars(playbook_vars)

        # figure out the ansible-playbook command
        cmd = [
            'ansible-playbook',
            'runner.yml',
            '--inventory=%s,' % ipaddr,  # the ending comma is important
            '--extra-vars=@%s' % allvarsfile,
        ]

        # for local execution, run as root unless instructed otherwise
        if not self.run_remotely and playbook_vars['become_root']:
            cmd.append('--become')

        if self.run_remotely:
            if self.arg_data['ssh_privkey']:
                cmd.append('--private-key=%s' % self.arg_data['ssh_privkey'])
        else:
            cmd.append('--connection=local')

        if self.arg_data['debug']:
            cmd.append('-vv')

        log.debug('Running ansible playbook %s', ' '.join(cmd))
        try:
            # during playbook execution, handle system signals asking us to
            # quit
            signal.signal(signal.SIGINT, self._interrupt_handler)
            signal.signal(signal.SIGTERM, self._interrupt_handler)

            output, _ = os_utils.popen_rt(cmd, cwd=ansible_dir)
            return output
        except subprocess.CalledProcessError as e:
            log.error('ansible-playbook ended with %d return code',
                      e.returncode)
            log.debug(e.output)
            raise exc.CheckbError(e)
        except exc.CheckbInterruptError as e:
            log.error(
                'System interrupt %s detected. Pulling logs and '
                'stopping execution.', e)
            cmd_failsafe = cmd + ['--tags', 'failsafe']
            try:
                os_utils.popen_rt(cmd_failsafe, cwd=ansible_dir)
            except (subprocess.CalledProcessError,
                    exc.CheckbInterruptError) as e2:
                log.error(
                    'Error during failsafe pulling logs, ignoring and '
                    'raising the original error. The current error is: %s:%s',
                    e2.__class__.__name__, e2)
            raise e
        finally:
            # reset signal handling to default behavior
            signal.signal(signal.SIGINT, signal.SIG_DFL)
            signal.signal(signal.SIGTERM, signal.SIG_DFL)