Update Python runner to take git worktree path into account when
content_version is provided and when setting pack common libs/ dir path.
Also log a message when we fail to retrieve common libs path and remove
leading ":" from path (if any).
@@ -43,6 +43,7 @@ from st2common.constants.system import API_URL_ENV_VARIABLE_NAME
from st2common.constants.system import AUTH_TOKEN_ENV_VARIABLE_NAME
from st2common.util.api import get_full_public_api_url
from st2common.util.pack import get_pack_common_libs_path_for_pack_ref
+from st2common.content.utils import get_pack_base_path
from st2common.util.sandboxing import get_sandbox_path
from st2common.util.sandboxing import get_sandbox_python_path
from st2common.util.sandboxing import get_sandbox_python_binary_path
@@ -197,8 +198,10 @@ class PythonRunner(GitWorktreeActionRunner):
if self._enable_common_pack_libs:
try:
- pack_common_libs_path = get_pack_common_libs_path_for_pack_ref(pack_ref=pack)
- except Exception:
+ pack_common_libs_path = self._get_pack_common_libs_path(pack_ref=pack)
+ except Exception as e:
+ LOG.debug('Failed to retrieve pack common lib path: %s' % (str(e)))
+ print(e)
# There is no MongoDB connection available in Lambda and pack common lib
# functionality is not also mandatory for Lambda so we simply ignore those errors.
# Note: We should eventually refactor this code to make runner standalone and not
@@ -208,6 +211,10 @@ class PythonRunner(GitWorktreeActionRunner):
else:
pack_common_libs_path = None
+ # Remove leading : (if any)
+ if sandbox_python_path.startswith(':'):
+ sandbox_python_path = sandbox_python_path[1:]
+
if self._enable_common_pack_libs and pack_common_libs_path:
env['PYTHONPATH'] = pack_common_libs_path + ':' + sandbox_python_path
else:
@@ -258,6 +265,35 @@ class PythonRunner(GitWorktreeActionRunner):
LOG.debug('Returning.')
return self._get_output_values(exit_code, stdout, stderr, timed_out)
+ def _get_pack_common_libs_path(self, pack_ref):
+ """
+ Retrieve path to the pack common lib/ directory taking git work tree path into account
+ (if used).
+ """
+ worktree_path = self.git_worktree_path
+ pack_common_libs_path = get_pack_common_libs_path_for_pack_ref(pack_ref=pack_ref)
+
+ if not worktree_path:
+ return pack_common_libs_path
+
+ # Modify the path so it uses git worktree directory
+ pack_base_path = get_pack_base_path(pack_name=pack_ref)
+
+ new_pack_common_libs_path = pack_common_libs_path.replace(pack_base_path, '')
+
+ # Remove leading slash (if any)
+ if new_pack_common_libs_path.startswith('/'):
+ new_pack_common_libs_path = new_pack_common_libs_path[1:]
+
+ new_pack_common_libs_path = os.path.join(worktree_path, new_pack_common_libs_path)
+
+ # Check to prevent directory traversal
+ common_prefix = os.path.commonprefix([worktree_path, new_pack_common_libs_path])
+ if common_prefix != worktree_path:
+ raise ValueError('pack libs path is not located inside the pack directory')
+
+ return new_pack_common_libs_path
+
def _get_output_values(self, exit_code, stdout, stderr, timed_out):
"""
Return sanitized output values.
