mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 12:50:22 -07:00
More work on getting integration tests running for v2
This commit is contained in:
parent
6326daa34e
commit
02bc014bcd
27 changed files with 414 additions and 187 deletions
|
@ -31,7 +31,7 @@ from ansible import constants as C
|
|||
from ansible.errors import AnsibleError
|
||||
from ansible.executor.module_common import ModuleReplacer
|
||||
from ansible.parsing.utils.jsonify import jsonify
|
||||
from ansible.plugins import module_loader, shell_loader
|
||||
from ansible.plugins import shell_loader
|
||||
|
||||
from ansible.utils.debug import debug
|
||||
|
||||
|
@ -44,11 +44,12 @@ class ActionBase:
|
|||
action in use.
|
||||
'''
|
||||
|
||||
def __init__(self, task, connection, connection_info, loader):
|
||||
def __init__(self, task, connection, connection_info, loader, module_loader):
|
||||
self._task = task
|
||||
self._connection = connection
|
||||
self._connection_info = connection_info
|
||||
self._loader = loader
|
||||
self._module_loader = module_loader
|
||||
self._shell = self.get_shell()
|
||||
|
||||
def get_shell(self):
|
||||
|
@ -80,9 +81,9 @@ class ActionBase:
|
|||
|
||||
# Search module path(s) for named module.
|
||||
module_suffixes = getattr(self._connection, 'default_suffixes', None)
|
||||
module_path = module_loader.find_plugin(module_name, module_suffixes, transport=self._connection.get_transport())
|
||||
module_path = self._module_loader.find_plugin(module_name, module_suffixes, transport=self._connection.get_transport())
|
||||
if module_path is None:
|
||||
module_path2 = module_loader.find_plugin('ping', module_suffixes)
|
||||
module_path2 = self._module_loader.find_plugin('ping', module_suffixes)
|
||||
if module_path2 is not None:
|
||||
raise AnsibleError("The module %s was not found in configured module paths" % (module_name))
|
||||
else:
|
||||
|
@ -391,6 +392,10 @@ class ActionBase:
|
|||
data = json.loads(self._filter_leading_non_json_lines(res['stdout']))
|
||||
if 'parsed' in data and data['parsed'] == False:
|
||||
data['msg'] += res['stderr']
|
||||
# pre-split stdout into lines, if stdout is in the data and there
|
||||
# isn't already a stdout_lines value there
|
||||
if 'stdout' in data and 'stdout_lines' not in data:
|
||||
data['stdout_lines'] = data.get('stdout', '').splitlines()
|
||||
else:
|
||||
data = dict()
|
||||
|
||||
|
@ -424,7 +429,6 @@ class ActionBase:
|
|||
cmd, prompt, success_key = self._connection_info.make_sudo_cmd('/usr/bin/sudo', executable, cmd)
|
||||
|
||||
debug("executing the command through the connection")
|
||||
#rc, stdin, stdout, stderr = self._connection.exec_command(cmd, tmp, executable=executable, in_data=in_data, sudoable=sudoable)
|
||||
rc, stdin, stdout, stderr = self._connection.exec_command(cmd, tmp, executable=executable, in_data=in_data)
|
||||
debug("command execution done")
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.playbook.conditional import Conditional
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
|
@ -42,9 +43,10 @@ class ActionModule(ActionBase):
|
|||
# the built in evaluate function. The when has already been evaluated
|
||||
# by this point, and is not used again, so we don't care about mangling
|
||||
# that value now
|
||||
cond = Conditional(loader=self._loader)
|
||||
for that in thats:
|
||||
self._task.when = [ that ]
|
||||
test_result = self._task.evaluate_conditional(all_vars=task_vars)
|
||||
cond.when = [ that ]
|
||||
test_result = cond.evaluate_conditional(all_vars=task_vars)
|
||||
if not test_result:
|
||||
result = dict(
|
||||
failed = True,
|
||||
|
|
|
@ -63,12 +63,10 @@ class ActionModule(ActionBase):
|
|||
source = parts[0]
|
||||
args = ' '.join(parts[1:])
|
||||
|
||||
# FIXME: need to sort out all the _original_file stuff still
|
||||
#if '_original_file' in task_vars:
|
||||
# source = self._loader.path_dwim_relative(inject['_original_file'], 'files', source, self.runner.basedir)
|
||||
#else:
|
||||
# source = self._loader.path_dwim(self.runner.basedir, source)
|
||||
source = self._loader.path_dwim(source)
|
||||
if self._task._role is not None:
|
||||
source = self._loader.path_dwim_relative(self._task._role._role_path, 'files', source)
|
||||
else:
|
||||
source = self._loader.path_dwim(source)
|
||||
|
||||
# transfer the file to a remote tmp location
|
||||
tmp_src = self._shell.join_path(tmp, os.path.basename(source))
|
||||
|
|
|
@ -17,10 +17,17 @@
|
|||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.template import Templar
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
|
||||
TRANSFERS_FILES = False
|
||||
|
||||
def run(self, tmp=None, task_vars=dict()):
|
||||
return dict(changed=True, ansible_facts=self._task.args)
|
||||
templar = Templar(loader=self._loader, variables=task_vars)
|
||||
facts = dict()
|
||||
if self._task.args:
|
||||
for (k, v) in self._task.args.iteritems():
|
||||
k = templar.template(k)
|
||||
facts[k] = v
|
||||
return dict(changed=True, ansible_facts=facts)
|
||||
|
|
|
@ -46,23 +46,34 @@ class CallbackModule(CallbackBase):
|
|||
pass
|
||||
|
||||
def runner_on_failed(self, task, result, ignore_errors=False):
|
||||
self._display.display("fatal: [%s]: FAILED! => %s" % (result._host.get_name(), result._result), color='red')
|
||||
self._display.display("fatal: [%s]: FAILED! => %s" % (result._host.get_name(), json.dumps(result._result, ensure_ascii=False)), color='red')
|
||||
|
||||
def runner_on_ok(self, task, result):
|
||||
msg = "ok: [%s]" % result._host.get_name()
|
||||
|
||||
if result._result.get('changed', False):
|
||||
msg = "changed: [%s]" % result._host.get_name()
|
||||
color = 'yellow'
|
||||
else:
|
||||
msg = "ok: [%s]" % result._host.get_name()
|
||||
color = 'green'
|
||||
|
||||
if self._display._verbosity > 0 or 'verbose_always' in result._result:
|
||||
indent = None
|
||||
if 'verbose_always' in result._result:
|
||||
indent = 4
|
||||
del result._result['verbose_always']
|
||||
msg += " => %s" % result._result
|
||||
self._display.display(msg, color='green')
|
||||
msg += " => %s" % json.dumps(result._result, indent=indent, ensure_ascii=False)
|
||||
self._display.display(msg, color=color)
|
||||
|
||||
def runner_on_skipped(self, task, result):
|
||||
msg = "SKIPPED: [%s]" % result._host.get_name()
|
||||
msg = "skipping: [%s]" % result._host.get_name()
|
||||
if self._display._verbosity > 0 or 'verbose_always' in result._result:
|
||||
indent = None
|
||||
if 'verbose_always' in result._result:
|
||||
indent = 4
|
||||
del result._result['verbose_always']
|
||||
msg += " => %s" % result._result
|
||||
self._display.display(msg)
|
||||
msg += " => %s" % json.dumps(result._result, indent=indent, ensure_ascii=False)
|
||||
self._display.display(msg, color='cyan')
|
||||
|
||||
def runner_on_unreachable(self, task, result):
|
||||
self._display.display("fatal: [%s]: UNREACHABLE! => %s" % (result._host.get_name(), result._result), color='red')
|
||||
|
|
|
@ -117,7 +117,8 @@ class Connection(ConnectionBase):
|
|||
#vvv("PUT %s TO %s" % (in_path, out_path), host=self.host)
|
||||
self._display.vvv("%s PUT %s TO %s" % (self._host, in_path, out_path))
|
||||
if not os.path.exists(in_path):
|
||||
raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
||||
#raise AnsibleFileNotFound("file or module does not exist: %s" % in_path)
|
||||
raise AnsibleError("file or module does not exist: %s" % in_path)
|
||||
try:
|
||||
shutil.copyfile(in_path, out_path)
|
||||
except shutil.Error:
|
||||
|
|
|
@ -120,6 +120,7 @@
|
|||
import os
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.template import Templar
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
|
@ -167,22 +168,26 @@ class LookupModule(LookupBase):
|
|||
else:
|
||||
total_search = terms
|
||||
|
||||
templar = Templar(loader=self._loader, variables=variables)
|
||||
roledir = variables.get('roledir')
|
||||
for fn in total_search:
|
||||
# FIXME: the original file stuff needs to be fixed/implemented
|
||||
#if variables and '_original_file' in variables:
|
||||
# # check the templates and vars directories too,
|
||||
# # if they exist
|
||||
# for roledir in ('templates', 'vars'):
|
||||
# path = self._loader.path_dwim(os.path.join(self.basedir, '..', roledir), fn)
|
||||
# if os.path.exists(path):
|
||||
# return [path]
|
||||
fn = templar.template(fn)
|
||||
if os.path.isabs(fn) and os.path.exists(fn):
|
||||
return [fn]
|
||||
else:
|
||||
if roledir is not None:
|
||||
# check the templates and vars directories too,if they exist
|
||||
for subdir in ('templates', 'vars'):
|
||||
path = self._loader.path_dwim_relative(roledir, subdir, fn)
|
||||
if os.path.exists(path):
|
||||
return [path]
|
||||
|
||||
# if none of the above were found, just check the
|
||||
# current filename against the basedir (this will already
|
||||
# have ../files from runner, if it's a role task
|
||||
path = self._loader.path_dwim(fn)
|
||||
if os.path.exists(path):
|
||||
return [path]
|
||||
# if none of the above were found, just check the
|
||||
# current filename against the basedir (this will already
|
||||
# have ../files from runner, if it's a role task
|
||||
path = self._loader.path_dwim(fn)
|
||||
if os.path.exists(path):
|
||||
return [path]
|
||||
else:
|
||||
if skip:
|
||||
return []
|
||||
|
|
|
@ -20,5 +20,9 @@ from ansible.plugins.lookup import LookupBase
|
|||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, **kwargs):
|
||||
|
||||
if not isinstance(terms, list):
|
||||
terms = [ terms ]
|
||||
|
||||
return self._flatten(terms)
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ from re import compile as re_compile, IGNORECASE
|
|||
from ansible.errors import *
|
||||
from ansible.parsing.splitter import parse_kv
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.template import Templar
|
||||
|
||||
# shortcut format
|
||||
NUM = "(0?x?[0-9a-f]+)"
|
||||
|
@ -174,15 +175,18 @@ class LookupModule(LookupBase):
|
|||
if isinstance(terms, basestring):
|
||||
terms = [ terms ]
|
||||
|
||||
templar = Templar(loader=self._loader, variables=variables)
|
||||
|
||||
for term in terms:
|
||||
try:
|
||||
self.reset() # clear out things for this iteration
|
||||
|
||||
term = templar.template(term)
|
||||
try:
|
||||
if not self.parse_simple_args(term):
|
||||
self.parse_kv_args(parse_kv(term))
|
||||
except Exception, e:
|
||||
raise AnsibleError("unknown error parsing with_sequence arguments: %r" % term)
|
||||
raise AnsibleError("unknown error parsing with_sequence arguments: %r. Error was: %s" % (term, e))
|
||||
|
||||
self.sanity_check()
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class LookupModule(LookupBase):
|
|||
def __lookup_variabless(self, terms, variables):
|
||||
results = []
|
||||
for x in terms:
|
||||
intermediate = listify_lookup_plugin_terms(x, variables)
|
||||
intermediate = listify_lookup_plugin_terms(x, variables, loader=self._loader)
|
||||
results.append(intermediate)
|
||||
return results
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ from ansible.inventory.group import Group
|
|||
|
||||
from ansible.playbook.helpers import compile_block_list
|
||||
from ansible.playbook.role import ROLE_CACHE
|
||||
from ansible.plugins import module_loader
|
||||
from ansible.utils.debug import debug
|
||||
|
||||
|
||||
|
@ -103,7 +104,7 @@ class StrategyBase:
|
|||
self._cur_worker = 0
|
||||
|
||||
self._pending_results += 1
|
||||
main_q.put((host, task, self._loader.get_basedir(), task_vars, connection_info), block=False)
|
||||
main_q.put((host, task, self._loader.get_basedir(), task_vars, connection_info, module_loader), block=False)
|
||||
except (EOFError, IOError, AssertionError), e:
|
||||
# most likely an abort
|
||||
debug("got an error while queuing: %s" % e)
|
||||
|
@ -154,20 +155,20 @@ class StrategyBase:
|
|||
|
||||
elif result[0] == 'add_host':
|
||||
task_result = result[1]
|
||||
new_host_info = task_result._result.get('add_host', dict())
|
||||
new_host_info = task_result.get('add_host', dict())
|
||||
|
||||
self._add_host(new_host_info)
|
||||
|
||||
elif result[0] == 'add_group':
|
||||
task_result = result[1]
|
||||
host = task_result._host
|
||||
group_name = task_result._result.get('add_group')
|
||||
host = result[1]
|
||||
task_result = result[2]
|
||||
group_name = task_result.get('add_group')
|
||||
|
||||
self._add_group(host, group_name)
|
||||
|
||||
elif result[0] == 'notify_handler':
|
||||
handler_name = result[1]
|
||||
host = result[2]
|
||||
host = result[1]
|
||||
handler_name = result[2]
|
||||
if host not in self._notified_handlers[handler_name]:
|
||||
self._notified_handlers[handler_name].append(host)
|
||||
|
||||
|
|
|
@ -67,6 +67,11 @@ class StrategyModule(StrategyBase):
|
|||
# anything to do do for this host
|
||||
if host_name not in self._tqm._failed_hosts and host_name not in self._tqm._unreachable_hosts and iterator.get_next_task_for_host(host, peek=True):
|
||||
|
||||
# FIXME: check task tags, etc. here as we do in linear
|
||||
# FIXME: handle meta tasks here, which will require a tweak
|
||||
# to run_handlers so that only the handlers on this host
|
||||
# are flushed and not all
|
||||
|
||||
# set the flag so the outer loop knows we've still found
|
||||
# some work which needs to be done
|
||||
work_to_do = True
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.strategies import StrategyBase
|
||||
|
||||
from ansible.utils.debug import debug
|
||||
|
||||
class StrategyModule(StrategyBase):
|
||||
|
@ -80,12 +80,21 @@ class StrategyModule(StrategyBase):
|
|||
continue
|
||||
|
||||
work_to_do = True
|
||||
if not callback_sent:
|
||||
self._callback.playbook_on_task_start(task.get_name(), False)
|
||||
callback_sent = True
|
||||
if task.action == 'meta':
|
||||
# meta tasks store their args in the _raw_params field of args,
|
||||
# since they do not use k=v pairs, so get that
|
||||
meta_action = task.args.get('_raw_params')
|
||||
if meta_action == 'flush_handlers':
|
||||
self.run_handlers(iterator, connection_info)
|
||||
else:
|
||||
raise AnsibleError("invalid meta action requested: %s" % meta_action, obj=task._ds)
|
||||
else:
|
||||
if not callback_sent:
|
||||
self._callback.playbook_on_task_start(task.get_name(), False)
|
||||
callback_sent = True
|
||||
|
||||
self._blocked_hosts[host.get_name()] = True
|
||||
self._queue_task(host, task, task_vars, connection_info)
|
||||
self._blocked_hosts[host.get_name()] = True
|
||||
self._queue_task(host, task, task_vars, connection_info)
|
||||
|
||||
self._process_pending_results()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue