-
Notifications
You must be signed in to change notification settings - Fork 16
Codejail Tutor plugin - MVP #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
65993ed
0d94906
e3aa9f6
5efde16
f61cb35
eda975f
8b71349
4c01860
b885745
2b3cc68
011eb8d
f085ef2
5a772c6
02c0c79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| .*.swp | ||
| !.gitignore | ||
| TODO | ||
| __pycache__ | ||
| *.egg-info/ | ||
| /build/ | ||
| /dist/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| recursive-include tutorcodejail/patches * | ||
| recursive-include tutorcodejail/templates * |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import io | ||
| import os | ||
| from setuptools import setup, find_packages | ||
|
|
||
| HERE = os.path.abspath(os.path.dirname(__file__)) | ||
|
|
||
|
|
||
| def load_readme(): | ||
| with io.open(os.path.join(HERE, "README.rst"), "rt", encoding="utf8") as f: | ||
| return f.read() | ||
|
|
||
|
|
||
| def load_about(): | ||
| about = {} | ||
| with io.open( | ||
| os.path.join(HERE, "tutorcodejail", "__about__.py"), | ||
| "rt", | ||
| encoding="utf-8", | ||
| ) as f: | ||
| exec(f.read(), about) # pylint: disable=exec-used | ||
| return about | ||
|
|
||
|
|
||
| ABOUT = load_about() | ||
|
|
||
|
|
||
| setup( | ||
| name="tutor-contrib-codejail", | ||
| version=ABOUT["__version__"], | ||
| url="https://github.com/github/tutor-contrib-codejail", | ||
| project_urls={ | ||
| "Code": "https://github.com/edunext/tutor-contrib-codejail", | ||
| "Issue tracker": "https://github.com/edunext/tutor-contrib-codejail/issues", | ||
| }, | ||
| license="AGPLv3", | ||
| author="Eric Herrera", | ||
| description="codejail plugin for Tutor", | ||
| long_description=load_readme(), | ||
| packages=find_packages(exclude=["tests*"]), | ||
| include_package_data=True, | ||
| python_requires=">=3.5", | ||
| install_requires=["tutor-openedx"], | ||
| entry_points={ | ||
| "tutor.plugin.v0": [ | ||
| "codejail = tutorcodejail.plugin" | ||
| ] | ||
| }, | ||
| classifiers=[ | ||
| "Development Status :: 3 - Alpha", | ||
| "Intended Audience :: Developers", | ||
| "License :: OSI Approved :: GNU Affero General Public License v3", | ||
| "Operating System :: OS Independent", | ||
| "Programming Language :: Python", | ||
| "Programming Language :: Python :: 3.5", | ||
| "Programming Language :: Python :: 3.6", | ||
| "Programming Language :: Python :: 3.7", | ||
| "Programming Language :: Python :: 3.8", | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| ], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| __version__ = "12.0.0" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| "CODE_JAIL_REST_SERVICE_HOST": "http://{{ CODEJAIL_HOST }}:8550", | ||
| "CODE_JAIL_REST_SERVICE_CONNECT_TIMEOUT": 0.5, | ||
| "CODE_JAIL_REST_SERVICE_READ_TIMEOUT": 3.5 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| "ENABLE_CODEJAIL_REST_SERVICE": true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| "CODE_JAIL_REST_SERVICE_HOST": "http://{{ CODEJAIL_HOST }}:8550", | ||
| "CODE_JAIL_REST_SERVICE_CONNECT_TIMEOUT": 0.5, | ||
| "CODE_JAIL_REST_SERVICE_READ_TIMEOUT": 3.5 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| codejailservice: | ||
| command: flask run --host 0.0.0.0 --port 8550 | ||
| environment: | ||
| FLASK_ENV: development | ||
| FLASK_APP_SETTINGS: codejailservice.config.DevelopmentConfig | ||
| ports: | ||
| - "8550:8550" | ||
| restart: unless-stopped |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| codejail_apparmor-job: | ||
| image: ednxops/codejail_apparmor_loader:latest | ||
| privileged: true | ||
| volumes: | ||
| - ../plugins/codejail/apps/profiles/docker-edx-sandbox:/profiles/docker-edx-sandbox:ro | ||
| - /sys:/sys | ||
| - /etc/apparmor.d:/etc/apparmor.d |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #############Codejail service | ||
| codejailservice: | ||
| image: {{ CODEJAIL_DOCKER_IMAGE }} | ||
| environment: | ||
| FLASK_APP_SETTINGS: config.ProductionConfig | ||
| security_opt: | ||
| - apparmor:docker-edx-sandbox | ||
| volumes: | ||
| - ../plugins/codejail/apps/config/tutor.py:/openedx/codejailservice/codejailservice/tutor.py:ro | ||
| - ../../data/codejail:/openedx/data | ||
| restart: unless-stopped |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| from glob import glob | ||
| import os | ||
| import pkg_resources | ||
|
|
||
| from .__about__ import __version__ | ||
|
|
||
| templates = pkg_resources.resource_filename( | ||
| "tutorcodejail", "templates" | ||
| ) | ||
|
|
||
| config = { | ||
| "add": { | ||
| "SECRET_KEY": "{{ 24|random_string }}", | ||
| }, | ||
| "defaults": { | ||
| "VERSION": __version__, | ||
| "HOST": "codejailservice", | ||
| "DOCKER_IMAGE": f"docker.io/ednxops/codejailservice:{__version__}", | ||
| "SANDBOX_PYTHON_VERSION": "3.5.10", | ||
| }, | ||
| "set":{} | ||
| } | ||
|
|
||
| hooks = { | ||
| "build-image": { | ||
| "codejail": "{{ CODEJAIL_DOCKER_IMAGE }}", | ||
| "codejail_apparmor": f"docker.io/ednxops/codejail_apparmor:{__version__}" | ||
| }, | ||
| "remote-image": { | ||
| "codejail": "{{ CODEJAIL_DOCKER_IMAGE }}", | ||
| "codejail_apparmor": f"docker.io/ednxops/codejail_apparmor:{__version__}" | ||
| }, | ||
| "init": ["codejail_apparmor"] | ||
| } | ||
|
|
||
|
|
||
| def patches(): | ||
| all_patches = {} | ||
| patches_dir = pkg_resources.resource_filename( | ||
| "tutorcodejail", "patches" | ||
| ) | ||
| for path in glob(os.path.join(patches_dir, "*")): | ||
| with open(path) as patch_file: | ||
| name = os.path.basename(path) | ||
| content = patch_file.read() | ||
| all_patches[name] = content | ||
| return all_patches | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from base import BaseConfig | ||
|
|
||
| class DevConfig(BaseConfig): | ||
| pass | ||
|
|
||
| class ProductionConfig(BaseConfig): | ||
| pass |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| #include <tunables/global> | ||
|
|
||
| profile docker-edx-sandbox flags=(attach_disconnected,mediate_deleted) { | ||
| #include <abstractions/base> | ||
|
|
||
| network, | ||
| capability, | ||
| file, | ||
| umount, | ||
| signal (receive) peer=unconfined, | ||
| signal (receive) peer=cri-containerd.apparmor.d, | ||
| signal (send,receive) peer=docker-edx-sandbox, | ||
|
|
||
| deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir) | ||
| # deny write to files not in /proc/<number>/** or /proc/sys/** | ||
| deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9]*}/** w, | ||
| deny @{PROC}/sys/[^k]** w, # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel) | ||
| deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w, # deny everything except shm* in /proc/sys/kernel/ | ||
| deny @{PROC}/sysrq-trigger rwklx, | ||
| deny @{PROC}/mem rwklx, | ||
| deny @{PROC}/kmem rwklx, | ||
| deny @{PROC}/kcore rwklx, | ||
|
|
||
| deny mount, | ||
| deny /sys/[^f]*/** wklx, | ||
| deny /sys/f[^s]*/** wklx, | ||
| deny /sys/fs/[^c]*/** wklx, | ||
| deny /sys/fs/c[^g]*/** wklx, | ||
| deny /sys/fs/cg[^r]*/** wklx, | ||
| deny /sys/firmware/** rwklx, | ||
| deny /sys/kernel/security/** rwklx, | ||
|
|
||
| ptrace (trace,read) peer=docker-edx-sandbox, | ||
|
|
||
| /sandbox/venv/bin/python Cx -> child, | ||
| profile child flags=(attach_disconnected,mediate_deleted){ | ||
| #include <abstractions/base> | ||
|
|
||
| # | ||
| # Python abstractions adapted from https://gitlab.com/apparmor/apparmor/-/raw/master/profiles/apparmor.d/abstractions/python | ||
| # | ||
| /opt/pyenv/versions/{2.[4-7].*,3.[0-9].*}/lib/python{2.[4-7],3.[0-9]}/**.{pyc,so} mr, | ||
| /opt/pyenv/versions/{2.[4-7].*,3.[0-9].*}/lib/python{2.[4-7],3.[0-9]}/**.{egg,py,pth} r, | ||
| /opt/pyenv/versions/{2.[4-7].*,3.[0-9].*}/lib/python{2.[4-7],3.[0-9]}/{site,dist}-packages/ r, | ||
| /opt/pyenv/versions/3.[0-9].*/lib/python3.[0-9]/lib-dynload/*.so mr, | ||
|
|
||
| /opt/pyenv/versions/{2.[4-7].*,3.[0-9].*}/include/python{2.[4-7],3.[0-9]}*/pyconfig.h r, | ||
|
|
||
|
|
||
| # | ||
| # Whitelist particiclar shared objects from the system | ||
| # python installation | ||
| # | ||
| /sandbox/venv/** mr, | ||
| /opt/pyenv/versions/3.5.10/** mr, | ||
| /tmp/codejail-*/ rix, | ||
| /tmp/codejail-*/** wrix, | ||
|
|
||
| # | ||
| # Whitelist particular shared objects from the system | ||
| # python installation | ||
| # | ||
| /sandbox/venv/.config/ wrix, | ||
| /sandbox/venv/.cache/ wrix, | ||
| /sandbox/venv/.config/** wrix, | ||
| /sandbox/venv/.cache/** wrix, | ||
|
|
||
| # Matplot lib needs fonts to make graphs | ||
| /usr/share/fonts/ r, | ||
| /usr/share/fonts/** r, | ||
| /usr/local/share/fonts/ r, | ||
| /usr/local/share/fonts/** r, | ||
|
|
||
| # | ||
| # Allow access to selections from /proc | ||
| # | ||
| /proc/*/mounts r, | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| FROM docker.io/ubuntu:20.04 as minimal | ||
| MAINTAINER edunext.co <contact@edunext.co> | ||
|
|
||
| ENV DEBIAN_FRONTEND=noninteractive | ||
| RUN apt update && \ | ||
| apt install -y build-essential curl git language-pack-en | ||
| ENV LC_ALL en_US.UTF-8 | ||
|
|
||
| ###### Install python with pyenv in /opt/pyenv and create virtualenv in /openedx/venv | ||
| FROM minimal as python | ||
| # https://github.com/pyenv/pyenv/wiki/Common-build-problems#prerequisites | ||
| RUN apt update && \ | ||
| apt install -y libssl-dev zlib1g-dev libbz2-dev \ | ||
| libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ | ||
| xz-utils tk-dev libffi-dev liblzma-dev python-openssl git subversion | ||
| ENV PYENV_ROOT /opt/pyenv | ||
| RUN git clone https://github.com/pyenv/pyenv $PYENV_ROOT --branch v1.2.21 --depth 1 | ||
|
|
||
| ARG CODEJAILSERVICE_PYTHON_VERSION=3.8.6 | ||
| RUN $PYENV_ROOT/bin/pyenv install $CODEJAILSERVICE_PYTHON_VERSION | ||
|
|
||
| ARG SANDBOX_PYTHON_VERSION={{ CODEJAIL_SANDBOX_PYTHON_VERSION }} | ||
| RUN $PYENV_ROOT/bin/pyenv install $SANDBOX_PYTHON_VERSION | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the future, I think that all code below this line should be run as a different user (e.g: |
||
| RUN $PYENV_ROOT/versions/$CODEJAILSERVICE_PYTHON_VERSION/bin/python -m venv /openedx/venv | ||
| RUN $PYENV_ROOT/versions/$SANDBOX_PYTHON_VERSION/bin/python -m venv --copies /sandbox/venv | ||
|
|
||
| ###### Codejail service code | ||
| FROM minimal as code | ||
| RUN git clone https://github.com/eduNEXT/codejailservice.git --branch {{ CODEJAIL_VERSION }} --depth 1 /openedx/codejailservice | ||
| WORKDIR /openedx/codejailservice | ||
|
|
||
| ###### Install python requirements in virtualenv | ||
| FROM python as codejailservice-python-requirements | ||
|
|
||
| ENV PATH /openedx/venv/bin:${PATH} | ||
| ENV VIRTUAL_ENV /openedx/venv/ | ||
|
|
||
| COPY --from=code /openedx/codejailservice /openedx/codejailservice | ||
| WORKDIR /openedx/codejailservice | ||
| RUN pip3 install -r requirements/base.txt | ||
| RUN pip3 install ipdb | ||
|
|
||
| ###### Install python requirements in virtualenv | ||
| FROM python as sandbox-python-requirements | ||
|
|
||
| ENV PATH /sandbox/venv/bin:${PATH} | ||
| ENV VIRTUAL_ENV /sandbox/venv/ | ||
|
|
||
| WORKDIR /var/tmp | ||
| RUN mkdir -p common/lib/ | ||
|
|
||
| COPY --from={{ DOCKER_IMAGE_OPENEDX }} /openedx/edx-platform/common/lib/sandbox-packages common/lib/sandbox-packages | ||
| COPY --from={{ DOCKER_IMAGE_OPENEDX }} /openedx/edx-platform/common/lib/symmath common/lib/symmath | ||
| COPY --from={{ DOCKER_IMAGE_OPENEDX }} /openedx/edx-platform/requirements/edx-sandbox/py35.txt py35.txt | ||
| RUN pip3 install -r py35.txt | ||
|
|
||
| ##### Prod image | ||
| FROM minimal as production | ||
|
|
||
| # Install system requirements | ||
| RUN apt update && \ | ||
| apt install -y sudo | ||
|
|
||
| COPY --from=code /openedx/codejailservice /openedx/codejailservice | ||
| COPY --from=python /opt/pyenv /opt/pyenv | ||
| COPY --from=codejailservice-python-requirements /openedx/venv /openedx/venv | ||
| COPY --from=sandbox-python-requirements /sandbox/venv /sandbox/venv | ||
|
|
||
| # Setup sandbox | ||
| ENV SANDBOX_ENV=/sandbox/venv | ||
| RUN groupadd -r sandbox && useradd -m -r -g sandbox sandbox && chown -R sandbox:sandbox /sandbox | ||
|
|
||
| ENV PATH /openedx/venv/bin:${PATH} | ||
| ENV VIRTUAL_ENV /openedx/venv/ | ||
| WORKDIR /openedx/codejailservice | ||
|
|
||
| EXPOSE 8000 | ||
| CMD uwsgi \ | ||
| --http 0.0.0.0:8000 \ | ||
| --thunder-lock \ | ||
| --single-interpreter \ | ||
| --enable-threads \ | ||
| --processes=${UWSGI_WORKERS:-2} \ | ||
| --buffer-size=8192 \ | ||
| --max-requests=1000 \ | ||
| --wsgi-file /openedx/codejailservice/wsgi.py | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| FROM golang:latest as go_compiler | ||
|
|
||
| RUN mkdir /app | ||
| WORKDIR /app | ||
| ADD https://raw.githubusercontent.com/kubernetes/kubernetes/master/test/images/apparmor-loader/loader.go loader.go | ||
| RUN go mod init loader | ||
| RUN go get k8s.io/klog/v2 | ||
| RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -installsuffix cgo --ldflags '-w' -o loader . | ||
|
|
||
| FROM alpine:latest | ||
|
|
||
| RUN apk add apparmor libapparmor --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted && \ | ||
| apk add --no-cache musl\>1.1.20 --repository http://dl-cdn.alpinelinux.org/alpine/edge/main/ | ||
|
|
||
| COPY --from=go_compiler /app/loader /usr/bin/loader |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /usr/bin/loader -logtostderr -v=2 /profiles |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest moving this to the "defaults" section. Then, use it as
CODEJAIL_SANDBOX_PYTHON_VERSION. When possible, we should really try to avoid "set" entries. They are only required to override existing tutor settings.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done