From fe6882819a692cb90ee7a9a2c738d96a3de81a48 Mon Sep 17 00:00:00 2001 From: Eric Herrera Date: Thu, 7 Oct 2021 10:42:20 -0500 Subject: [PATCH] fix: Address more PR comments Address @felipemonotoya recommendations related to add versioning to safe_exec_remote functions. --- cms/envs/common.py | 22 +++++++++++++++++++ .../safe_exec/{helpers.py => remote_exec.py} | 21 +++++++++++++++--- common/lib/capa/capa/safe_exec/safe_exec.py | 7 +++--- lms/envs/common.py | 17 ++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) rename common/lib/capa/capa/safe_exec/{helpers.py => remote_exec.py} (78%) diff --git a/cms/envs/common.py b/cms/envs/common.py index 5036425d25..974e99370a 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -1000,6 +1000,28 @@ CODE_JAIL = { COURSES_WITH_UNSAFE_CODE = [] +# Cojail REST service +ENABLE_CODEJAIL_REST_SERVICE = False +# .. setting_name: CODE_JAIL_REST_SERVICE_REMOTE_EXEC +# .. setting_default: 'common.lib.capa.capa.safe_exec.remote_exec.send_safe_exec_request_v0' +# .. setting_description: Set the python package.module.function that is reponsible of +# calling the remote service in charge of jailed code execution +CODE_JAIL_REST_SERVICE_REMOTE_EXEC = 'common.lib.capa.capa.safe_exec.remote_exec.send_safe_exec_request_v0' +# .. setting_name: CODE_JAIL_REST_SERVICE_HOST +# .. setting_default: 'http://127.0.0.1:8550' +# .. setting_description: Set the codejail remote service host +CODE_JAIL_REST_SERVICE_HOST = 'http://127.0.0.1:8550' +# .. setting_name: CODE_JAIL_REST_SERVICE_CONNECT_TIMEOUT +# .. setting_default: 0.5 +# .. setting_description: Set the number of seconds CMS will wait to establish an internal +# connection to the codejail remote service. +CODE_JAIL_REST_SERVICE_CONNECT_TIMEOUT = 0.5 # time in seconds +# .. setting_name: CODE_JAIL_REST_SERVICE_READ_TIMEOUT +# .. setting_default: 3.5 +# .. setting_description: Set the number of seconds CMS will wait for a response from the +# codejail remote service endpoint. +CODE_JAIL_REST_SERVICE_READ_TIMEOUT = 3.5 # time in seconds + ############################ DJANGO_BUILTINS ################################ # Change DEBUG in your environment settings files, not here DEBUG = False diff --git a/common/lib/capa/capa/safe_exec/helpers.py b/common/lib/capa/capa/safe_exec/remote_exec.py similarity index 78% rename from common/lib/capa/capa/safe_exec/helpers.py rename to common/lib/capa/capa/safe_exec/remote_exec.py index 42d567f3ab..7f13e0fbd3 100644 --- a/common/lib/capa/capa/safe_exec/helpers.py +++ b/common/lib/capa/capa/safe_exec/remote_exec.py @@ -10,6 +10,7 @@ from codejail.safe_exec import SafeExecException from django.conf import settings from django.utils.translation import ugettext as _ from edx_toggles.toggles import SettingToggle +from importlib import import_module from requests.exceptions import RequestException, HTTPError from simplejson import JSONDecodeError @@ -33,22 +34,36 @@ def is_codejail_rest_service_enabled(): return ENABLE_CODEJAIL_REST_SERVICE.is_enabled() +def get_remote_exec(*args, **kwargs): + """Get remote exec function based on setting and executes it.""" + remote_exec_function_name = settings.CODE_JAIL_REST_SERVICE_REMOTE_EXEC + try: + mod_name, func_name = remote_exec_function_name.rsplit('.', 1) + remote_exec_module = import_module(mod_name) + remote_exec_function = getattr(remote_exec_module, func_name) + if not remote_exec_function: + remote_exec_function = send_safe_exec_request_v0 + except ModuleNotFoundError: + return send_safe_exec_request_v0(*args, **kwargs) + return remote_exec_function(*args, **kwargs) + + def get_codejail_rest_service_endpoint(): return f"{settings.CODE_JAIL_REST_SERVICE_HOST}/api/v0/code-exec" -def send_safe_exec_request(data, extra_files): +def send_safe_exec_request_v0(data): """ Sends a request to a codejail api service forwarding required code and files. Arguments: data: Dict containing code and other parameters required for jailed code execution. - extra_files: python_lib.zip file containing extra files - required by the codejail execution. + It also includes extra_files (python_lib.zip) required by the codejail execution. Returns: Response received from codejail api service """ globals_dict = data["globals_dict"] + extra_files = data.pop("extra_files") codejail_service_endpoint = get_codejail_rest_service_endpoint() payload = json.dumps(data) diff --git a/common/lib/capa/capa/safe_exec/safe_exec.py b/common/lib/capa/capa/safe_exec/safe_exec.py index 4b5d36c74d..e08e58d488 100644 --- a/common/lib/capa/capa/safe_exec/safe_exec.py +++ b/common/lib/capa/capa/safe_exec/safe_exec.py @@ -11,7 +11,7 @@ import six from six import text_type from . import lazymod -from .helpers import is_codejail_rest_service_enabled, send_safe_exec_request +from .remote_exec import is_codejail_rest_service_enabled, get_remote_exec # Establish the Python environment for Capa. # Capa assumes float-friendly division always. @@ -151,10 +151,11 @@ def safe_exec( "python_path": python_path, "limit_overrides_context": limit_overrides_context, "slug": slug, - "unsafely": unsafely + "unsafely": unsafely, + "extra_files": extra_files, } - emsg, exception = send_safe_exec_request(data, extra_files) + emsg, exception = get_remote_exec(data) else: # Decide which code executor to use. diff --git a/lms/envs/common.py b/lms/envs/common.py index 40c0343be0..22580a0d59 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1630,8 +1630,25 @@ CODE_JAIL = { COURSES_WITH_UNSAFE_CODE = [] # Cojail REST service +ENABLE_CODEJAIL_REST_SERVICE = False +# .. setting_name: CODE_JAIL_REST_SERVICE_REMOTE_EXEC +# .. setting_default: 'common.lib.capa.capa.safe_exec.remote_exec.send_safe_exec_request_v0' +# .. setting_description: Set the python package.module.function that is reponsible of +# calling the remote service in charge of jailed code execution +CODE_JAIL_REST_SERVICE_REMOTE_EXEC = 'common.lib.capa.capa.safe_exec.remote_exec.send_safe_exec_request_v0' +# .. setting_name: CODE_JAIL_REST_SERVICE_HOST +# .. setting_default: 'http://127.0.0.1:8550' +# .. setting_description: Set the codejail remote service host CODE_JAIL_REST_SERVICE_HOST = 'http://127.0.0.1:8550' +# .. setting_name: CODE_JAIL_REST_SERVICE_CONNECT_TIMEOUT +# .. setting_default: 0.5 +# .. setting_description: Set the number of seconds LMS will wait to establish an internal +# connection to the codejail remote service. CODE_JAIL_REST_SERVICE_CONNECT_TIMEOUT = 0.5 # time in seconds +# .. setting_name: CODE_JAIL_REST_SERVICE_READ_TIMEOUT +# .. setting_default: 3.5 +# .. setting_description: Set the number of seconds LMS will wait for a response from the +# codejail remote service endpoint. CODE_JAIL_REST_SERVICE_READ_TIMEOUT = 3.5 # time in seconds