diff options
Diffstat (limited to '')
| -rw-r--r-- | README.md | 135 | 
1 files changed, 41 insertions, 94 deletions
| @@ -25,7 +25,7 @@ result <- |             |<----------|           | <----------+  ``` -The code is executed in a Python process that is launched through [NsJail], which is responsible for sandboxing the Python process. See [`snekbox.cfg`] for the NsJail configuration. +The code is executed in a Python process that is launched through [NsJail], which is responsible for sandboxing the Python process.  The output returned by snekbox is truncated at around 1 MB. @@ -47,120 +47,62 @@ To run it in the background, use the `-d` option. See the documentation on [`doc  The above command will make the API accessible on the host via `http://localhost:8060/`. Currently, there's only one endpoint: `http://localhost:8060/eval`. -## Third-party Packages - -By default, the Python interpreter has no access to any packages besides the -standard library. Even snekbox's own dependencies like Falcon and Gunicorn are -not exposed. - -To expose third-party Python packages during evaluation, install them to a custom user site: - -```sh -docker exec snekbox /bin/sh -c 'PYTHONUSERBASE=/snekbox/user_base pip install numpy' -``` - -In the above command, `snekbox` is the name of the running container. The name may be different and can be checked with `docker ps`. - -The packages will be installed to the user site within `/snekbox/user_base`. To persist the installed packages, a volume for the directory can be created with Docker. For an example, see [`docker-compose.yml`]. - -If `pip`, `setuptools`, or `wheel` are dependencies or need to be exposed, then use the `--ignore-installed` option with pip. However, note that this will also re-install packages present in the custom user site, effectively making caching it futile. Current limitations of pip don't allow it to ignore packages extant outside the installation destination. - -## Development Environment - -### Initial Setup - -A Python 3.9 interpreter and the [pipenv] package are required. Once those requirements are satisfied, install the project's dependencies: - -``` -pipenv sync --dev -``` - -Follow that up with setting up the pre-commit hook: - -``` -pipenv run precommit -``` - -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 -``` - -### Running snekbox +## Configuration -The Docker image can be built with: +Configuration files can be edited directly. However, this requires rebuilding the image. Alternatively, a Docker volume or bind mounts can be used to override the configuration files at their default locations. -``` -pipenv run build -``` +### NsJail -Use Docker Compose to start snekbox: +The main features of the default configuration are: -``` -docker-compose up -``` +* Time limit +* Memory limit +* Process count limit +* No networking +* Restricted, read-only filesystem -### Running Tests +NsJail is configured through [`snekbox.cfg`]. It contains the exact values for the items listed above. The configuration format is defined by a [protobuf file][7] which can be referred to for documentation. The command-line options of NsJail can also serve as documentation since they closely follow the config file format. -Tests are run through coverage.py using unittest. Before tests can run, the dev venv Docker image has to be built: +### Gunicorn -``` -pipenv run builddev -``` +[Gunicorn settings] can be found in [`gunicorn.conf.py`]. In the default configuration, the worker count and the bind address are likely the only things of any interest. Since it uses the default synchronous workers, the [worker count] effectively determines how many concurrent code evaluations can be performed. -Alternatively, the following command will build the image and then run the tests: +### Environment Variables -``` -pipenv run testb -``` +All environment variables have defaults and are therefore not required to be set. -If the image doesn't need to be built, the tests can be run with: +Name | Description +---- | ----------- +`DEBUG` | Enable debug logging if set to a non-empty value. +`GIT_SHA` | [Sentry release] identifier. Set in CI. +`NSJAIL_CFG` | Path to the NsJail configuration file. +`NSJAIL_PATH` | Path to the NsJail binary. +`SNEKBOX_SENTRY_DSN` | [Data Source Name] for Sentry. Sentry is disabled if left unset. -``` -pipenv run test -``` - -### Coverage +Note: relative paths are relative to the root of the repository. -To see a coverage report, run +## Third-party Packages -``` -pipenv run report -``` +By default, the Python interpreter has no access to any packages besides the +standard library. Even snekbox's own dependencies like Falcon and Gunicorn are +not exposed. -Alternatively, a report can be generated as HTML: +To expose third-party Python packages during evaluation, install them to a custom user site: +```sh +docker exec snekbox /bin/sh -c 'PYTHONUSERBASE=/snekbox/user_base pip install numpy'  ``` -pipenv run coverage html -``` - -The HTML will output to `./htmlcov/` by default - - -### The `devsh` Helper Script - -This script starts a `bash` 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]] [bash_args ...] -``` +In the above command, `snekbox` is the name of the running container. The name may be different and can be checked with `docker ps`. -* `--build` Build the venv Docker image -* `--clean` Clean up dangling Docker images (only works if `--build` precedes it) -* `bash_args` Arguments to pass to `/bin/bash` (for example `-c "echo hello"`). An interactive shell is launched if no arguments are given +The packages will be installed to the user site within `/snekbox/user_base`. To persist the installed packages, a volume for the directory can be created with Docker. For an example, see [`docker-compose.yml`]. -#### Invoking NsJail +If `pip`, `setuptools`, or `wheel` are dependencies or need to be exposed, then use the `--ignore-installed` option with pip. However, note that this will also re-install packages present in the custom user site, effectively making caching it futile. Current limitations of pip don't allow it to ignore packages extant outside the installation destination. -NsJail can be invoked in a more direct manner that does not require using a web server or its API. See `python -m snekbox --help`. Example usage: +## Development Environment -```bash -python -m snekbox 'print("hello world!")' --time_limit 0 -``` +See [DEVELOPING.md](DEVELOPING.md). -With this command, NsJail uses the same configuration normally used through the web API. It also has an alias, `pipenv run eval`.  [1]: https://github.com/python-discord/snekbox/workflows/Lint,%20Test,%20Build,%20Push/badge.svg?branch=master  [2]: https://github.com/python-discord/snekbox/actions?query=workflow%3A%22Lint%2C+Test%2C+Build%2C+Push%22+branch%3Amaster @@ -168,6 +110,8 @@ With this command, NsJail uses the same configuration normally used through the  [4]: https://coveralls.io/github/python-discord/snekbox?branch=master  [5]: https://raw.githubusercontent.com/python-discord/branding/master/logos/badge/badge_github.svg  [6]: https://discord.gg/python +[7]: https://github.com/google/nsjail/blob/master/config.proto +[`gunicorn.conf.py`]: config/gunicorn.conf.py  [`snekbox.cfg`]: config/snekbox.cfg  [`snekapi.py`]: snekbox/api/snekapi.py  [`resources`]: snekbox/api/resources @@ -176,5 +120,8 @@ With this command, NsJail uses the same configuration normally used through the  [nsjail]: https://github.com/google/nsjail  [falcon]: https://falconframework.org/  [gunicorn]: https://gunicorn.org/ +[gunicorn settings]: https://docs.gunicorn.org/en/latest/settings.html +[worker count]: https://docs.gunicorn.org/en/latest/design.html#how-many-workers +[sentry release]: https://docs.sentry.io/platforms/python/configuration/releases/ +[data source name]: https://docs.sentry.io/product/sentry-basics/dsn-explainer/  [GitHub Container Registry]: https://github.com/orgs/python-discord/packages/container/package/snekbox -[pipenv]: https://docs.pipenv.org/en/latest/ | 
