Move tmpdir into work root

Ansible 2.4 changes the way the template module works. It now
processes the template and writes it into a temporary file in a newly
created temporary dir. After that it reuses the copy plugin to copy
this onto the node. This fails for untrusted jobs because the
temporary file is created outside of the work root which fails the
safe path validation of the copy plugin [1].

There are two issues with this behavior. First Ansible doesn't use the
configured local_tmp dir for this temporary file. This can be fixed by
setting the TMP variable.

Second our current local_tmp setting is outside of the work dir so
this needs to be moved into the work dir.

[1] Failed log:
TASK [gitlint : Ensure project has a fallback default config]
node | ERROR
node | {
node |   "msg": "Accessing files from outside the working dir /tmp/54614d6f189a48968648c4e68c05bdba/work is prohibited",
node |   "path": "/tmp/tmpssae4qfb/gitlint.j2"
node | }

Change-Id: Ie2c7518973fc81f51826fa16021b95590e08749e
This commit is contained in:
Tobias Henkel 2018-02-21 17:26:32 +01:00
parent cb4b10f517
commit 2bc13cdfaf
No known key found for this signature in database
GPG Key ID: 03750DEC158E5FA2
1 changed files with 9 additions and 2 deletions

View File

@ -310,6 +310,7 @@ class JobDir(object):
# <project> # <project>
# logs # logs
# job-output.txt # job-output.txt
# tmp
# results.json # results.json
self.keep = keep self.keep = keep
if root: if root:
@ -324,6 +325,12 @@ class JobDir(object):
os.makedirs(self.src_root) os.makedirs(self.src_root)
self.log_root = os.path.join(self.work_root, 'logs') self.log_root = os.path.join(self.work_root, 'logs')
os.makedirs(self.log_root) os.makedirs(self.log_root)
# Create local tmp directory
# NOTE(tobiash): This must live within the work root as it can be used
# by ansible for temporary files which are path checked in untrusted
# jobs.
self.local_tmp = os.path.join(self.work_root, 'tmp')
os.makedirs(self.local_tmp)
self.ansible_root = os.path.join(self.root, 'ansible') self.ansible_root = os.path.join(self.root, 'ansible')
os.makedirs(self.ansible_root) os.makedirs(self.ansible_root)
self.trusted_root = os.path.join(self.root, 'trusted') self.trusted_root = os.path.join(self.root, 'trusted')
@ -1261,8 +1268,7 @@ class AnsibleJob(object):
with open(jobdir_playbook.ansible_config, 'w') as config: with open(jobdir_playbook.ansible_config, 'w') as config:
config.write('[defaults]\n') config.write('[defaults]\n')
config.write('inventory = %s\n' % self.jobdir.inventory) config.write('inventory = %s\n' % self.jobdir.inventory)
config.write('local_tmp = %s/local_tmp\n' % config.write('local_tmp = %s\n' % self.jobdir.local_tmp)
self.jobdir.ansible_cache_root)
config.write('retry_files_enabled = False\n') config.write('retry_files_enabled = False\n')
config.write('gathering = smart\n') config.write('gathering = smart\n')
config.write('fact_caching = jsonfile\n') config.write('fact_caching = jsonfile\n')
@ -1345,6 +1351,7 @@ class AnsibleJob(object):
env_copy['ARA_LOG_CONFIG'] = self.jobdir.logging_json env_copy['ARA_LOG_CONFIG'] = self.jobdir.logging_json
env_copy['ZUUL_JOB_LOG_CONFIG'] = self.jobdir.logging_json env_copy['ZUUL_JOB_LOG_CONFIG'] = self.jobdir.logging_json
env_copy['ZUUL_JOBDIR'] = self.jobdir.root env_copy['ZUUL_JOBDIR'] = self.jobdir.root
env_copy['TMP'] = self.jobdir.local_tmp
pythonpath = env_copy.get('PYTHONPATH') pythonpath = env_copy.get('PYTHONPATH')
if pythonpath: if pythonpath:
pythonpath = [pythonpath] pythonpath = [pythonpath]