Merge "Append / to end of ansible_user_dir for rsync src" into feature/zuulv3
diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py
index 9a10e9d..94f169a 100755
--- a/tests/unit/test_v3.py
+++ b/tests/unit/test_v3.py
@@ -748,6 +748,48 @@
self.assertIn('appears multiple times', A.messages[0],
"A should have a syntax error reported")
+ def test_secret_not_found_error(self):
+ in_repo_conf = textwrap.dedent(
+ """
+ - job:
+ name: test
+ secrets: does-not-exist
+ """)
+
+ file_dict = {'.zuul.yaml': in_repo_conf}
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
+ files=file_dict)
+ A.addApproval('Code-Review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
+ self.waitUntilSettled()
+
+ self.assertEqual(A.data['status'], 'NEW')
+ self.assertEqual(A.reported, 1,
+ "A should report failure")
+ self.assertIn('secret "does-not-exist" was not found', A.messages[0],
+ "A should have a syntax error reported")
+
+ def test_nodeset_not_found_error(self):
+ in_repo_conf = textwrap.dedent(
+ """
+ - job:
+ name: test
+ nodeset: does-not-exist
+ """)
+
+ file_dict = {'.zuul.yaml': in_repo_conf}
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
+ files=file_dict)
+ A.addApproval('Code-Review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
+ self.waitUntilSettled()
+
+ self.assertEqual(A.data['status'], 'NEW')
+ self.assertEqual(A.reported, 1,
+ "A should report failure")
+ self.assertIn('nodeset "does-not-exist" was not found', A.messages[0],
+ "A should have a syntax error reported")
+
def test_multi_repo(self):
downstream_repo_conf = textwrap.dedent(
"""
diff --git a/zuul/ansible/callback/zuul_stream.py b/zuul/ansible/callback/zuul_stream.py
index 770a719..0a266df 100644
--- a/zuul/ansible/callback/zuul_stream.py
+++ b/zuul/ansible/callback/zuul_stream.py
@@ -294,11 +294,19 @@
if result._task.loop and 'results' in result_dict:
# items have their own events
pass
- elif (result_dict.get('msg') == 'MODULE FAILURE' and
- 'module_stdout' in result_dict):
- self._log_message(
- result, status='MODULE FAILURE',
- msg=result_dict['module_stdout'])
+ elif (result_dict.get('msg') == 'MODULE FAILURE'):
+ if 'module_stdout' in result_dict:
+ self._log_message(
+ result, status='MODULE FAILURE',
+ msg=result_dict['module_stdout'])
+ elif 'exception' in result_dict:
+ self._log_message(
+ result, status='MODULE FAILURE',
+ msg=result_dict['exception'])
+ elif 'module_stderr' in result_dict:
+ self._log_message(
+ result, status='MODULE FAILURE',
+ msg=result_dict['module_stderr'])
else:
self._log_message(
result=result, status='ERROR', result_dict=result_dict)
@@ -363,11 +371,19 @@
# items have their own events
pass
- elif (result_dict.get('msg') == 'MODULE FAILURE' and
- 'module_stdout' in result_dict):
- self._log_message(
- result, status='MODULE FAILURE',
- msg=result_dict['module_stdout'])
+ elif (result_dict.get('msg') == 'MODULE FAILURE'):
+ if 'module_stdout' in result_dict:
+ self._log_message(
+ result, status='MODULE FAILURE',
+ msg=result_dict['module_stdout'])
+ elif 'exception' in result_dict:
+ self._log_message(
+ result, status='MODULE FAILURE',
+ msg=result_dict['exception'])
+ elif 'module_stderr' in result_dict:
+ self._log_message(
+ result, status='MODULE FAILURE',
+ msg=result_dict['module_stderr'])
elif (len([key for key in result_dict.keys()
if not key.startswith('_ansible')]) == 1):
# this is a debug statement, handle it special
diff --git a/zuul/configloader.py b/zuul/configloader.py
index 62439c4..b70ea59 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -106,6 +106,24 @@
super(ProjectNotFoundError, self).__init__(message)
+class SecretNotFoundError(Exception):
+ def __init__(self, secret):
+ message = textwrap.dedent("""\
+ The secret "{secret}" was not found.
+ """)
+ message = textwrap.fill(message.format(secret=secret))
+ super(SecretNotFoundError, self).__init__(message)
+
+
+class NodesetNotFoundError(Exception):
+ def __init__(self, nodeset):
+ message = textwrap.dedent("""\
+ The nodeset "{nodeset}" was not found.
+ """)
+ message = textwrap.fill(message.format(nodeset=nodeset))
+ super(NodesetNotFoundError, self).__init__(message)
+
+
class PipelineNotPermittedError(Exception):
def __init__(self):
message = textwrap.dedent("""\
@@ -358,10 +376,6 @@
@staticmethod
def getSchema():
- node = {vs.Required('name'): str,
- vs.Required('label'): str,
- }
-
zuul_role = {vs.Required('zuul'): str,
'name': str}
@@ -391,7 +405,6 @@
'files': to_list(str),
'secrets': to_list(vs.Any(secret, str)),
'irrelevant-files': to_list(str),
- 'nodes': vs.Any([node], str),
# validation happens in NodeSetParser
'nodeset': vs.Any(dict, str),
'timeout': int,
@@ -489,13 +502,15 @@
# Secrets are part of the playbook context so we must establish
# them earlier than playbooks.
secrets = []
- for secret_config in conf.get('secrets', []):
+ for secret_config in as_list(conf.get('secrets', [])):
if isinstance(secret_config, str):
secret_name = secret_config
- secret = layout.secrets[secret_name]
+ secret = layout.secrets.get(secret_name)
else:
secret_name = secret_config['name']
- secret = layout.secrets[secret_config['secret']]
+ secret = layout.secrets.get(secret_config['secret'])
+ if secret is None:
+ raise SecretNotFoundError(secret_name)
if secret_name == 'zuul':
raise Exception("Secrets named 'zuul' are not allowed.")
if secret.source_context != job.source_context:
@@ -576,27 +591,15 @@
conf_nodeset = conf['nodeset']
if isinstance(conf_nodeset, str):
# This references an existing named nodeset in the layout.
- ns = layout.nodesets[conf_nodeset]
+ ns = layout.nodesets.get(conf_nodeset)
+ if ns is None:
+ raise NodesetNotFoundError(conf_nodeset)
else:
ns = NodeSetParser.fromYaml(conf_nodeset, anonymous=True)
if tenant.max_nodes_per_job != -1 and \
len(ns) > tenant.max_nodes_per_job:
raise MaxNodeError(job, tenant)
job.nodeset = ns
- elif 'nodes' in conf:
- conf_nodes = conf['nodes']
- if isinstance(conf_nodes, str):
- # This references an existing named nodeset in the layout.
- ns = layout.nodesets[conf_nodes]
- else:
- ns = model.NodeSet()
- for conf_node in conf_nodes:
- node = model.Node(conf_node['name'], conf_node['label'])
- ns.addNode(node)
- if tenant.max_nodes_per_job != -1 and \
- len(ns) > tenant.max_nodes_per_job:
- raise MaxNodeError(job, tenant)
- job.nodeset = ns
if 'required-projects' in conf:
new_projects = {}