diff options
author | 2019-08-04 21:46:30 -0700 | |
---|---|---|
committer | 2019-08-04 22:18:57 -0700 | |
commit | cba3defa572398190e5675cd7cdeb7cb55aab391 (patch) | |
tree | 8736b0681d6e8b343bd73076eb172f038c97cbb0 /README.md | |
parent | Pin pydocstyle to unbreak flake8-docstrings (diff) |
Rewrite README and clean up Pipfile scripts
* Make the report script do the normal coverage report instead of HTML
* Remove Docker image push scripts
* Add image build script for the venv image
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 142 |
1 files changed, 79 insertions, 63 deletions
@@ -2,9 +2,9 @@ # snekbox -Python sandbox runners for executing code in isolation aka snekbox +Python sandbox runners for executing code in isolation aka snekbox. -The user sends a piece of python code to a snekbox, the snekbox executes the code and sends the result back to the users. +A client sends Python code to a snekbox, the snekbox executes the code, and finally the results of the execution are returned to the client. ``` +-------------+ +-----------+ @@ -22,91 +22,107 @@ result <- | |<----------| | <----------+ ``` +## Details -## Dependencies +The framework for the HTTP REST API is [Falcon](https://falconframework.org/) and the WSGI being used is [Gunicorn](https://gunicorn.org/). -| dep | version (or greater) | -|----------------|:---------------------| -| python | 3.6.5 | -| pip | 10.0.1 | -| pipenv | 2018.05.18 | -| docker | 18.03.1-ce | -| docker-compose | 1.21.2 | -| nsjail | 2.5 | -| flask | 1.0.2 | -| gunicorn | 19.9 | +The code is executed in a Python process that is launched through [NsJail](https://github.com/google/nsjail), which is responsible for sandboxing the Python process. NsJail is configured as follows: -_________________________________________ -## Setup local test +* Root directory is mounted as read-only +* Time limit of 2 seconds +* Maximum of 1 PID +* Maximum memory of 52428800 bytes +* Loopback interface is down +* procfs is disabled -install python packages +The Python process is configured as follows: -```bash -apt-get install -y libprotobuf-dev #needed by nsjail -pipenv sync --dev +* Isolated mode + * Neither the script's directory nor the user's site packages are in `sys.path` + * All `PYTHON*` environment variables are ignored + + +## Development Environment + +### Initial Setup + +A Python 3.7 interpreter and the pipenv package are required. Once those requirements are satisfied, install the project's dependencies: + +``` +pipenv --sync ``` -## NSJail +Follow that up with setting up the pre-commit hook: -Copy the appropriate binary to an appropriate path +``` +pipenv run precommit +``` -```bash -cp binaries/nsjail2.6-ubuntu-x86_64 /usr/bin/nsjail -chmod +x /usr/bin/nsjail +Now Flake8 will run and lint staged changes whenever an attempt to commit the changes is made. Flake8 can still be invoked manually: + +``` +pipenv run lint ``` -give nsjail a test run +### Running snekbox -```bash -# This is a workaround because nsjail can't create the directories automatically -sudo mkdir -p /sys/fs/cgroup/pids/NSJAIL \ - && mkdir -p /sys/fs/cgroup/memory/NSJAIL +The Docker images can be built with: -nsjail -Mo \ ---rlimit_as 700 \ ---chroot / \ --E LANG=en_US.UTF-8 \ --R/usr -R/lib -R/lib64 \ ---user nobody \ ---group nogroup \ ---time_limit 2 \ ---disable_proc \ ---iface_no_lo \ ---cgroup_pids_max=1 \ ---cgroup_mem_max=52428800 \ ---quiet -- \ -python3.6 -ISq -c "print('test')" +``` +pipenv run buildbase +pipenv run buildvenv +pipenv run build ``` -> if it fails, try without the `--cgroup_pids_max=1` and `--cgroup_mem_max=52428800` +Use Docker Compose to start snekbox: -## Development environment +``` +docker-compose up +``` -Start the webserver with docker: +### Running Tests -```bash -docker-compose up -d +Tests are ran through coverage.py using unittest: + +``` +pipenv run test ``` -Run locally with pipenv: -```bash -pipenv run snekbox # for debugging +To see a coverage report, run + +``` +pipenv run report ``` -Visit: `http://localhost:8060` -________________________________________ -## Unit testing and lint -```bash -pipenv run lint -pipenv run test +Alternatively, a report can be generated as HTML: + +``` +pipenv run coverage html +``` + +The HTML will output to `./htmlcov/` by default + + +### The `devsh` Helper Script + +This script starts an `ash` shell inside the venv Docker container and attaches to it. Unlike the production image, the venv image that is built by this script contains dev dependencies too. The project directory is mounted inside the container so any filesystem changes made inside the container affect the actual local project. + +#### Usage + +``` +pipenv run devsh [--build [--clean]] [ash_args ...] ``` -________________________________________ -## Build the containers +* `--build` build the venv Docker image +* `--clean` clean up dangling Docker images (only works if `--build` precedes it) +* `ash_args` arguments to pass to `/bin/ash` (for example `-c "echo hello"`). An interactive shell is launched if no arguments are given + +#### Invoking NsJail + +A shell alias named `nsjpy` is included and is basically `nsjail python -c <args>` but NsJail is configured as it would be if snekbox invoked it (such as the time and memory limits). It provides an easy way to run Python code inside NsJail without the need to run snekbox with its webserver and send HTTP requests. Example usage: ```bash -# Build -pipenv run buildbox -# Push -pipenv run pushbox +nsjpy "print('hello world!')" ``` + +The alias can be found in `./scripts/.profile`, which is automatically added when the shell is launched in the container. |