Validate virtual environment while running a job/inventory update

Currently we only check the custom virtual environment path when
it's created. However, to tackle with the case when the venv might
have been changed/deleted afterward, we need to validate it at
run-time too.

Signed-off-by: Vismay Golwala <vgolwala@redhat.com>
This commit is contained in:
Vismay Golwala
2019-03-28 13:02:05 -04:00
committed by Ryan Petrello
parent 6d5897f371
commit 5d570a017a
3 changed files with 19 additions and 7 deletions

BIN
awx-dev Normal file

Binary file not shown.

View File

@@ -65,7 +65,7 @@ from awx.main.utils import (get_ssh_version, update_scm_url,
ignore_inventory_computed_fields, ignore_inventory_computed_fields,
ignore_inventory_group_removal, extract_ansible_vars, schedule_task_manager, ignore_inventory_group_removal, extract_ansible_vars, schedule_task_manager,
get_awx_version) get_awx_version)
from awx.main.utils.common import _get_ansible_version from awx.main.utils.common import _get_ansible_version, get_custom_venv_choices
from awx.main.utils.safe_yaml import safe_dump, sanitize_jinja from awx.main.utils.safe_yaml import safe_dump, sanitize_jinja
from awx.main.utils.reload import stop_local_services from awx.main.utils.reload import stop_local_services
from awx.main.utils.pglock import advisory_lock from awx.main.utils.pglock import advisory_lock
@@ -93,6 +93,12 @@ Try upgrading OpenSSH or providing your private key in an different format. \
logger = logging.getLogger('awx.main.tasks') logger = logging.getLogger('awx.main.tasks')
class InvalidVirtualenvError(Exception):
def __init__(self, message):
self.message = message
def dispatch_startup(): def dispatch_startup():
startup_logger = logging.getLogger('awx.main.tasks') startup_logger = logging.getLogger('awx.main.tasks')
startup_logger.info("Syncing Schedules") startup_logger.info("Syncing Schedules")
@@ -892,10 +898,13 @@ class BaseTask(object):
env['PATH'] = os.path.join(venv_path, "bin") + ":" + env['PATH'] env['PATH'] = os.path.join(venv_path, "bin") + ":" + env['PATH']
venv_libdir = os.path.join(venv_path, "lib") venv_libdir = os.path.join(venv_path, "lib")
if not isolated and not os.path.exists(venv_libdir): if not isolated and (
raise RuntimeError( not os.path.exists(venv_libdir) or
'a valid Python virtualenv does not exist at {}'.format(venv_path) os.path.join(venv_path, '') not in get_custom_venv_choices()
) ):
raise InvalidVirtualenvError(_(
'Invalid virtual environment selected: {}'.format(venv_path)
))
isolated_manager.set_pythonpath(venv_libdir, env) isolated_manager.set_pythonpath(venv_libdir, env)
@@ -1252,6 +1261,9 @@ class BaseTask(object):
status = 'failed' status = 'failed'
extra_update_fields['job_explanation'] = self.instance.job_explanation extra_update_fields['job_explanation'] = self.instance.job_explanation
except InvalidVirtualenvError as e:
extra_update_fields['job_explanation'] = e.message
logger.error('{} {}'.format(self.instance.log_format, e.message))
except Exception: except Exception:
# this could catch programming or file system errors # this could catch programming or file system errors
extra_update_fields['result_traceback'] = traceback.format_exc() extra_update_fields['result_traceback'] = traceback.format_exc()

View File

@@ -525,10 +525,10 @@ class TestGenericRun():
job.project.custom_virtualenv = '/venv/missing' job.project.custom_virtualenv = '/venv/missing'
task = tasks.RunJob() task = tasks.RunJob()
with pytest.raises(RuntimeError) as e: with pytest.raises(tasks.InvalidVirtualenvError) as e:
task.build_env(job, private_data_dir) task.build_env(job, private_data_dir)
assert 'a valid Python virtualenv does not exist at /venv/missing' == str(e.value) assert 'Invalid virtual environment selected: /venv/missing' == str(e.value)
class TestAdhocRun(TestJobExecution): class TestAdhocRun(TestJobExecution):