def _watch_converge_task(self, api, nodelist):
        """
        run a converge task on a nodelist.

        returns (success_bool, failure_string)
        """

        if len(nodelist) == 0:
            return True, 'Nothing to converge'

        query = '"adventurator" in attrs.opencenter_agent_output_modules'
        adventurator = api._model_get_first_by_query('nodes', query)
        if adventurator is None:
            return False, 'could not find adventurator'

        dsl = [{'primitive': 'run_chef', 'ns': {}}]
        node_task = api._model_create(
            'tasks',
            {'action': 'adventurate',
             'node_id': adventurator['id'],
             'payload': {'nodes': nodelist,
                         'adventure_dsl': dsl}})

        # watch for task state
        while node_task['state'] not in ['timeout', 'cancelled', 'done']:
            time.sleep(5)
            node_task = api._model_get_by_id('tasks', node_task['id'])

        if node_task['state'] != 'done':
            return False, 'Task %s not completed' % node_task['id']

        if 'result_code' in node_task['result'] and \
                node_task['result']['result_code'] != 0:
            return False, node_task['id'] % 'Task %s was unsuccessful'

        return True, 'Node(s) converged successfully'

    # README(shep): not executed on the server, skipping from code coverage
dataset/ETHPy150Open rcbops/opencenter/opencenter/backends/chef-client/__init__.py/ChefClientBackend._watch_converge_task/swapped operands of `%`