Fix root container path for project updates in K8s

Modifies to_container_path to accept an optional
container_root parameter.

Normally this defaults to /runner, but in K8S
environments, project updates run from the
private_data_dir, e.g. /tmp/awx_1_123abc, not
/runner.

In that situation, we just pass in private_data_dir
as the container_root.

---------

Signed-off-by: Seth Foster <fosterbseth@gmail.com>
Co-authored-by: TVo <thavo@redhat.com>
This commit is contained in:
Seth Foster 2025-03-13 13:34:12 -04:00 committed by GitHub
parent 01fae57de2
commit e9f2a14ebd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 5 deletions

View File

@ -491,7 +491,7 @@ class CredentialType(CommonModelNameNotUnique):
def load_plugin(cls, ns, plugin):
ManagedCredentialType(namespace=ns, name=plugin.name, kind='external', inputs=plugin.inputs)
def inject_credential(self, credential, env, safe_env, args, private_data_dir):
def inject_credential(self, credential, env, safe_env, args, private_data_dir, container_root=None):
"""
Inject credential data into the environment variables and arguments
passed to `ansible-playbook`
@ -515,6 +515,9 @@ class CredentialType(CommonModelNameNotUnique):
:param private_data_dir: a temporary directory to store files generated
by `file` injectors (like config files or key
files)
:param container_root: root directory inside of container to mount the
private data directory to
"""
if not self.injectors:
if self.managed and credential.credential_type.namespace in dir(builtin_injectors):
@ -618,7 +621,7 @@ class CredentialType(CommonModelNameNotUnique):
extra_vars = build_extra_vars(self.injectors.get('extra_vars', {}))
if extra_vars:
path = build_extra_vars_file(extra_vars, private_data_dir)
container_path = to_container_path(path, private_data_dir)
container_path = to_container_path(path, private_data_dir, container_root=container_root)
args.extend(['-e', '@%s' % container_path])

View File

@ -520,9 +520,13 @@ class BaseTask(object):
credentials = self.build_credentials_list(self.instance)
container_root = None
if settings.IS_K8S and isinstance(self.instance, ProjectUpdate):
container_root = private_data_dir
for credential in credentials:
if credential:
credential.credential_type.inject_credential(credential, env, self.safe_cred_env, args, private_data_dir)
credential.credential_type.inject_credential(credential, env, self.safe_cred_env, args, private_data_dir, container_root=container_root)
self.runner_callback.safe_env.update(self.safe_cred_env)

View File

@ -79,7 +79,7 @@ def get_default_pod_spec():
CONTAINER_ROOT = '/runner'
def to_container_path(path, private_data_dir):
def to_container_path(path, private_data_dir, container_root=None):
"""Given a path inside of the host machine filesystem,
this returns the expected path which would be observed by the job running
inside of the EE container.
@ -87,9 +87,11 @@ def to_container_path(path, private_data_dir):
"""
if not os.path.isabs(private_data_dir):
raise RuntimeError('The private_data_dir path must be absolute')
if container_root is None:
container_root = CONTAINER_ROOT
# due to how tempfile.mkstemp works, we are probably passed a resolved path, but unresolved private_data_dir
resolved_path = Path(path).resolve()
resolved_pdd = Path(private_data_dir).resolve()
if resolved_pdd != resolved_path and resolved_pdd not in resolved_path.parents:
raise RuntimeError(f'Cannot convert path {resolved_path} unless it is a subdir of {resolved_pdd}')
return str(resolved_path).replace(str(resolved_pdd), CONTAINER_ROOT, 1)
return str(resolved_path).replace(str(resolved_pdd), container_root, 1)