From a92cbc89d5b5be40dce89f4aa232b5e7eb8032b5 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Mon, 23 Jan 2017 14:56:49 -0800 Subject: [PATCH] Put Zuul vars in an ansible vars file This adds a vars file for use by ansible playbooks with all vars scoped under 'zuul'. The existing environment variables will be moved into this section in a later change. Currently, the only supplied variable is 'uuid' for use in a test. Also, add a test-specific vars entry (zuul._test) so that we can pass information such as the test chroot into playbooks used in our tests. This is used by a test to set a flag file inside of the test chroot to verify that the ansible playbook in a job actually ran and did something. Change-Id: Ie5d950d051accad4ec9dc90a9e1b01b3095a1e5c Co-Authored-By: Monty Taylor --- tests/base.py | 8 +++++++- .../ansible/git/common-config/playbooks/python27.yaml | 3 +-- tests/unit/test_v3.py | 7 +++++-- zuul/launcher/client.py | 5 +++++ zuul/launcher/server.py | 9 ++++++++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/base.py b/tests/base.py index 83354c9514..2d1dd7d50a 100755 --- a/tests/base.py +++ b/tests/base.py @@ -676,6 +676,7 @@ class RecordingLaunchServer(zuul.launcher.server.LaunchServer): """ def __init__(self, *args, **kw): self._run_ansible = kw.pop('_run_ansible', False) + self._test_root = kw.pop('_test_root', False) super(RecordingLaunchServer, self).__init__(*args, **kw) self.hold_jobs_in_build = False self.lock = threading.Lock() @@ -724,6 +725,9 @@ class RecordingLaunchServer(zuul.launcher.server.LaunchServer): job.build = build self.running_builds.append(build) self.job_builds[job.unique] = build + args = json.loads(job.arguments) + args['zuul']['_test'] = dict(test_root=self._test_root) + job.arguments = json.dumps(args) super(RecordingLaunchServer, self).launchJob(job) def stopJob(self, job): @@ -1252,7 +1256,9 @@ class ZuulTestCase(BaseTestCase): self._startMerger() self.launch_server = RecordingLaunchServer( - self.config, self.connections, _run_ansible=self.run_ansible) + self.config, self.connections, + _run_ansible=self.run_ansible, + _test_root=self.test_root) self.launch_server.start() self.history = self.launch_server.build_history self.builds = self.launch_server.running_builds diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/python27.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/python27.yaml index 227cc126a2..6b0af99358 100644 --- a/tests/fixtures/config/ansible/git/common-config/playbooks/python27.yaml +++ b/tests/fixtures/config/ansible/git/common-config/playbooks/python27.yaml @@ -1,6 +1,5 @@ -# TODO(jeblair): Perform an action inside of a test chroot - hosts: all tasks: - file: - path: /tmp/playbook.test + path: "{{zuul._test.test_root}}/{{zuul.uuid}}.flag" state: touch diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py index 96f24a1e6a..9034bf7d59 100644 --- a/tests/unit/test_v3.py +++ b/tests/unit/test_v3.py @@ -15,6 +15,7 @@ # under the License. import logging +import os import textwrap from tests.base import AnsibleZuulTestCase @@ -129,5 +130,7 @@ class TestAnsible(AnsibleZuulTestCase): A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) self.waitUntilSettled() - self.assertEqual(self.getJobFromHistory('python27').result, - 'SUCCESS') + build = self.getJobFromHistory('python27') + self.assertEqual(build.result, 'SUCCESS') + flag_path = os.path.join(self.test_root, build.uuid + '.flag') + self.assertTrue(os.path.exists(flag_path)) diff --git a/zuul/launcher/client.py b/zuul/launcher/client.py index 716e59bf74..f7bb73b2a9 100644 --- a/zuul/launcher/client.py +++ b/zuul/launcher/client.py @@ -300,6 +300,10 @@ class LaunchClient(object): [x.change for x in dependent_items])) dependent_items = dependent_items[:] dependent_items.reverse() + # TODOv3(jeblair): This ansible vars data structure will + # replace the environment variables below. + zuul_params = dict(uuid=uuid) + # Legacy environment variables params = dict(ZUUL_UUID=uuid, ZUUL_PROJECT=item.change.project.name) params['ZUUL_PIPELINE'] = pipeline.name @@ -382,6 +386,7 @@ class LaunchClient(object): for node in item.current_build_set.getJobNodeSet(job.name).getNodes(): nodes.append(dict(name=node.name, image=node.image)) params['nodes'] = nodes + params['zuul'] = zuul_params projects = set() for item in all_items: if item.change.project not in projects: diff --git a/zuul/launcher/server.py b/zuul/launcher/server.py index 58bfb07d78..213af76d69 100644 --- a/zuul/launcher/server.py +++ b/zuul/launcher/server.py @@ -24,6 +24,7 @@ import tempfile import threading import time import traceback +import yaml import gear @@ -75,6 +76,7 @@ class JobDir(object): os.makedirs(self.ansible_root) self.known_hosts = os.path.join(self.ansible_root, 'known_hosts') self.inventory = os.path.join(self.ansible_root, 'inventory') + self.vars = os.path.join(self.ansible_root, 'vars.yaml') self.playbook = None self.playbook_root = os.path.join(self.ansible_root, 'playbook') os.makedirs(self.playbook_root) @@ -444,6 +446,10 @@ class LaunchServer(object): for k, v in host_vars.items(): inventory.write('%s=%s' % (k, v)) inventory.write('\n') + with open(jobdir.vars, 'w') as vars_yaml: + zuul_vars = dict(zuul=args['zuul']) + vars_yaml.write( + yaml.safe_dump(zuul_vars, default_flow_style=False)) with open(jobdir.config, 'w') as config: config.write('[defaults]\n') config.write('hostfile = %s\n' % jobdir.inventory) @@ -499,7 +505,8 @@ class LaunchServer(object): else: verbose = '-v' - cmd = ['ansible-playbook', jobdir.playbook, verbose] + cmd = ['ansible-playbook', jobdir.playbook, + '-e@%s' % jobdir.vars, verbose] self.log.debug("Ansible command: %s" % (cmd,)) # TODOv3: verbose proc = subprocess.Popen(