コード例 #1
0
    def handle(self, *args, **options):
        hostname = options.get('hostname')
        if not hostname:
            raise CommandError("--hostname is a required argument")

        try:
            path = tempfile.mkdtemp(prefix='awx_isolated_ssh',
                                    dir=settings.AWX_PROOT_BASE_PATH)
            args = [
                'ansible', 'all', '-i', '{},'.format(hostname), '-u',
                settings.AWX_ISOLATED_USERNAME, '-T5', '-m', 'shell', '-a',
                'ansible-runner --version', '-vvv'
            ]
            if all([
                    getattr(settings, 'AWX_ISOLATED_KEY_GENERATION', False) is
                    True,
                    getattr(settings, 'AWX_ISOLATED_PRIVATE_KEY', None)
            ]):
                ssh_key_path = os.path.join(path, '.isolated')
                ssh_auth_sock = os.path.join(path, 'ssh_auth.sock')
                run.open_fifo_write(ssh_key_path,
                                    settings.AWX_ISOLATED_PRIVATE_KEY)
                args = run.wrap_args_with_ssh_agent(args, ssh_key_path,
                                                    ssh_auth_sock)
            try:
                print(' '.join(args))
                subprocess.check_call(args)
            except subprocess.CalledProcessError as e:
                sys.exit(e.returncode)
        finally:
            shutil.rmtree(path)
コード例 #2
0
ファイル: isolated_manager.py プロジェクト: w3bservice/awx
 def run_pexpect(cls, pexpect_args, *args, **kw):
     isolated_ssh_path = None
     try:
         if all([
             getattr(settings, 'AWX_ISOLATED_KEY_GENERATION', False) is True,
             getattr(settings, 'AWX_ISOLATED_PRIVATE_KEY', None)
         ]):
             isolated_ssh_path = tempfile.mkdtemp(prefix='awx_isolated', dir=settings.AWX_PROOT_BASE_PATH)
             os.chmod(isolated_ssh_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
             isolated_key = os.path.join(isolated_ssh_path, '.isolated')
             ssh_sock = os.path.join(isolated_ssh_path, '.isolated_ssh_auth.sock')
             run.open_fifo_write(isolated_key, settings.AWX_ISOLATED_PRIVATE_KEY)
             pexpect_args = run.wrap_args_with_ssh_agent(pexpect_args, isolated_key, ssh_sock, silence_ssh_add=True)
         return run.run_pexpect(pexpect_args, *args, **kw)
     finally:
         if isolated_ssh_path:
             shutil.rmtree(isolated_ssh_path)
コード例 #3
0
ファイル: isolated_manager.py プロジェクト: Chewy-Inc/awx
    def dispatch(self):
        '''
        Compile the playbook, its environment, and metadata into a series
        of files, and ship to a remote host for isolated execution.
        '''
        self.started_at = time.time()
        secrets = {
            'env': self.isolated_env,
            'passwords': self.expect_passwords,
            'ssh_key_data': None,
            'idle_timeout': self.idle_timeout,
            'job_timeout': self.job_timeout,
            'pexpect_timeout': self.pexpect_timeout
        }

        # if an ssh private key fifo exists, read its contents and delete it
        if self.ssh_key_path:
            buff = StringIO.StringIO()
            with open(self.ssh_key_path, 'r') as fifo:
                for line in fifo:
                    buff.write(line)
            secrets['ssh_key_data'] = buff.getvalue()
            os.remove(self.ssh_key_path)

        # write the entire secret payload to a named pipe
        # the run_isolated.yml playbook will use a lookup to read this data
        # into a variable, and will replicate the data into a named pipe on the
        # isolated instance
        secrets_path = os.path.join(self.private_data_dir, 'env')
        run.open_fifo_write(secrets_path,
                            base64.b64encode(json.dumps(secrets)))

        self.build_isolated_job_data()

        extra_vars = {
            'src': self.private_data_dir,
            'dest': settings.AWX_PROOT_BASE_PATH,
        }
        if self.proot_temp_dir:
            extra_vars['proot_temp_dir'] = self.proot_temp_dir

        # Run ansible-playbook to launch a job on the isolated host.  This:
        #
        # - sets up a temporary directory for proot/bwrap (if necessary)
        # - copies encrypted job data from the controlling host to the isolated host (with rsync)
        # - writes the encryption secret to a named pipe on the isolated host
        # - launches the isolated playbook runner via `awx-expect start <job-id>`
        args = self._build_args('run_isolated.yml', '%s,' % self.host,
                                extra_vars)
        if self.instance.verbosity:
            args.append('-%s' % ('v' * min(5, self.instance.verbosity)))
        buff = StringIO.StringIO()
        logger.debug(
            'Starting job {} on isolated host with `run_isolated.yml` playbook.'
            .format(self.instance.id))
        status, rc = IsolatedManager.run_pexpect(
            args,
            self.awx_playbook_path(),
            self.management_env,
            buff,
            idle_timeout=self.idle_timeout,
            job_timeout=settings.AWX_ISOLATED_LAUNCH_TIMEOUT,
            pexpect_timeout=5)
        output = buff.getvalue().encode('utf-8')
        playbook_logger.info('Isolated job {} dispatch:\n{}'.format(
            self.instance.id, output))
        if status != 'successful':
            self.stdout_handle.write(output)
        return status, rc