Commit 9d48ad3f by Ned Batchelder

Updates to use the latest refactoring with edx-platform

* Python 2.x is called "python" again

* Provide "configure_python" so that edx-platform can get convenient
  configuration.
parent c62051af
......@@ -3,8 +3,12 @@ Integrate with application settings files.
"""
from __future__ import absolute_import
import os.path
from . import jail
from . import limits
from .util import sibling_sandbox_venv
def configure_from_settings(settings):
......@@ -57,12 +61,29 @@ def legacy_configure_from_settings(settings):
"user": "sandbox",
"limits": {"CPU": 1},
}
The virtualenv used depends on the 'python_bin' setting:
* If 'python_bin' is specified, it is the sandbox virtualenv to use.
* If 'python_bin' is specified as None, then code will run unsafely.
* If 'python_bin' isn't specified, then a virtualenv alongside the current
one, with a suffix of '-sandbox' will be used.
"""
python_bin = None
if 'python_bin' in settings.CODE_JAIL:
python_bin = settings.CODE_JAIL['python_bin']
else:
venv = sibling_sandbox_venv()
if venv:
python_bin = os.path.join(venv, "bin/python")
python_bin = settings.CODE_JAIL.get('python_bin')
if python_bin:
user = settings.CODE_JAIL['user']
jail.configure("python", python_bin, user=user)
requested_limits = settings.CODE_JAIL.get('limits', {})
for name, value in requested_limits.items():
limits.set_limit(name, value)
......@@ -34,7 +34,7 @@ other = Language(
)
python2 = Language(
name='python2',
name='python',
argv=[
'-E', # Ignore the environment variables PYTHON*
'-B', # Don't write .pyc files.
......
......@@ -5,9 +5,10 @@ import os.path
import shutil
import sys
from .exceptions import SafeExecException
from .jail import get_codejail, is_configured
from .util import temp_directory, change_directory, json_safe
from . import languages
from .exceptions import JailError, SafeExecException
from .jail import configure, get_codejail, is_configured
from .util import temp_directory, change_directory, json_safe, sibling_sandbox_venv
log = logging.getLogger("codejail")
......@@ -94,10 +95,20 @@ def not_safe_exec(
globals_dict.update(json_safe(g_dict))
if ALWAYS_BE_UNSAFE: # pragma: no cover
# Make safe_exec actually call not_safe_exec, but log that we're doing so.
def configure_python():
"""If "python" isn't configured, configure it to point to a sibling venv.
Raises JailError if it couldn't find a virtualenv to use.
"""
if not is_configured("python"):
venv = sibling_sandbox_venv()
if not venv:
raise JailError("Couldn't find sandbox virtualenv")
configure("python", os.path.join(venv, "bin/python"), user="sandbox", lang=languages.python2)
def safe_exec(*args, **kwargs): # pylint: disable=E0102
def fake_safe_exec(*args, **kwargs): # pylint: disable=E0102
"""An actually-unsafe safe_exec, that warns it's being used."""
# Because it would be bad if this function were used in production,
......@@ -107,3 +118,8 @@ if ALWAYS_BE_UNSAFE: # pragma: no cover
log.warning("Using codejail/safe_exec.py:not_safe_exec for %s", slug)
return not_safe_exec(*args, **kwargs)
if ALWAYS_BE_UNSAFE: # pragma: no cover
# Make safe_exec actually call not_safe_exec, but log that we're doing so.
safe_exec = fake_safe_exec
......@@ -7,8 +7,8 @@ import os.path
import sys
from unittest import TestCase
from codejail import jail
from codejail import languages
from codejail import jail, languages
from codejail.util import sibling_sandbox_venv
SAME = object()
......@@ -53,24 +53,15 @@ class JailMixin(TestCase):
super(JailMixin, self).setUp()
if not jail.is_configured("python"):
if not self._codejail_venv:
self._codejail_venv = self._autoconfigure_codejail_venv()
self._codejail_venv = sibling_sandbox_venv()
if not self._codejail_venv:
self.fail("No virtualenv found for codejail")
if not self._codejail_user:
# User explicitly requested no su user via environment variable
self._codejail_user = None
bin_path = os.path.join(self._codejail_venv, 'bin/python2')
bin_path = os.path.join(self._codejail_venv, 'bin/python')
jail.configure("python", bin_path, user=self._codejail_user, lang=languages.python2)
def _autoconfigure_codejail_venv(self):
"""
For the purposes of tests, look for a sandbox alongside the currently
running python.
"""
codejail_venv = '{}-sandbox'.format(sys.prefix)
if os.path.isdir(codejail_venv):
return codejail_venv
else:
self.fail("No virtualenv found for codejail")
class Python3Mixin(object):
"""
......
......@@ -3,6 +3,7 @@
import contextlib
import os
import shutil
import sys
import tempfile
try:
......@@ -67,3 +68,19 @@ def json_safe(input_dict):
else:
json_dict[key] = value
return json.loads(json.dumps(json_dict))
def sibling_sandbox_venv():
"""
Find a virtualenv next to ours, with a "-sandbox" suffix.
Returns the virtualenv directory name, or None if one couldn't be found.
"""
sandbox_venv = '{}-sandbox'.format(sys.prefix)
if os.path.isdir(sandbox_venv):
python_bin = os.path.join(sandbox_venv, "bin/python")
if os.path.exists(python_bin):
return sandbox_venv
return None
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment