diff options
author | 2021-02-03 12:12:20 -0800 | |
---|---|---|
committer | 2021-02-04 16:19:45 -0800 | |
commit | d274d25c2da31fd6cf5b8a86f81d9d79c4545e8c (patch) | |
tree | 95fee110c8c7071c875e7db9bda22a068d9830e6 | |
parent | Categorise and sort scripts in Pipfile (diff) |
Replace dev.sh with Docker Compose
Managing development containers through Docker Compose is convenient.
However, it isn't quite flexible enough to facilitate both development
and normal use. It's not really worth accommodating the latter since
the container gets pushed to a registry and that's the intended way to
run the service. Anyone that is checking out the repository and
therefore has access to the compose file is likely a developer, not a
user.
-rw-r--r-- | DEVELOPING.md | 46 | ||||
-rw-r--r-- | Pipfile | 18 | ||||
-rw-r--r-- | docker-compose.yml | 15 | ||||
-rwxr-xr-x | scripts/dev.sh | 65 |
4 files changed, 38 insertions, 106 deletions
diff --git a/DEVELOPING.md b/DEVELOPING.md index 934369c..4e47b84 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -22,33 +22,27 @@ pipenv run lint ## Running snekbox -The Docker image can be built with: - -``` -pipenv run build -``` - -Use Docker Compose to start snekbox: +Use Docker Compose to start snekbox in development mode. The optional `--build` argument can be passed to force the image to be rebuilt. ``` docker-compose up ``` -## Running Tests +The container has all development dependencies. The repository on the host is mounted within the container; changes made to local files will also affect the container. + +Note that the compose file depends on the environment variable `PWD` being set to the current working directory. It needs it to create the aforementioned bind mount. Unix shells normally have this set already. If for some reason it is not set, it needs to be manually set. A convenient way to set it is to define it in a `.env` file which Docker Compose will automatically read. -Tests are run through coverage.py using unittest. Before tests can run, the dev venv Docker image has to be built: +To build a normal container that can be used in production, run ``` -pipenv run builddev +pipenv run build ``` -Alternatively, the following command will build the image and then run the tests: +Refer to the [README] for how to run the container normally. -``` -pipenv run testb -``` +## Running Tests -If the image doesn't need to be built, the tests can be run with: +Tests are run through coverage.py using unittest. To run the tests within a development container, run ``` pipenv run test @@ -62,7 +56,7 @@ To see a coverage report, run pipenv run report ``` -Alternatively, a report can be generated as HTML: +Alternatively, a report can be generated as HTML with ``` pipenv run coverage html @@ -70,20 +64,21 @@ pipenv run coverage html The HTML will output to `./htmlcov/` by default +## Launching a Shell in the Container -## 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 +A bash shell can be launched in the development container using ``` -pipenv run devsh [--build [--clean]] [bash_args ...] +pipenv run devsh ``` -* `--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 +This creates a new container which will get deleted once the shell session ends. + +It's possible to run a command directly; it supports the same arguments that `bash` supports. + +```bash +pipenv run devsh -c 'echo hello' +``` ### Invoking NsJail @@ -96,3 +91,4 @@ python -m snekbox 'print("hello world!")' --time_limit 0 With this command, NsJail uses the same configuration normally used through the web API. It also has an alias, `pipenv run eval`. [pipenv]: https://docs.pipenv.org/en/latest/ +[readme]: README.md @@ -39,24 +39,14 @@ precommit = "pre-commit install" # Testing report = "coverage report" -test = "sh scripts/dev.sh -c 'pipenv run coverage run -m unittest'" -testb = """ - sh scripts/dev.sh \ - --build \ - --clean \ - -c 'pipenv run coverage run -m unittest' +test = """ + docker-compose run --entrypoint /bin/bash --rm snekbox -c \ + 'coverage run -m unittest' """ # Docker build = "docker build -t ghcr.io/python-discord/snekbox:latest ." -builddev = """ - docker build \ - -t ghcr.io/python-discord/snekbox-venv:dev \ - --target venv \ - --build-arg DEV=1 \ - . -""" -devsh = "sh scripts/dev.sh" +devsh = "docker-compose run --entrypoint /bin/bash --rm snekbox" # Other protoc = "sh scripts/protoc.sh" diff --git a/docker-compose.yml b/docker-compose.yml index a7747a6..d073dd1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,17 +2,28 @@ version: "3.7" services: snekbox: - container_name: snekbox + container_name: snekbox_dev + hostname: snekbox_dev privileged: true - image: ghcr.io/python-discord/snekbox:latest + image: ghcr.io/python-discord/snekbox:dev ports: - 8060:8060 init: true ipc: none + working_dir: $PWD + environment: + DEBUG: 1 + PIPENV_PIPFILE: /snekbox/Pipfile + PYTHONDONTWRITEBYTECODE: 1 build: context: . dockerfile: Dockerfile + args: + DEV: 1 + cache_from: + - ghcr.io/python-discord/snekbox:latest volumes: + - $PWD:$PWD - user-base:/snekbox/user_base volumes: diff --git a/scripts/dev.sh b/scripts/dev.sh deleted file mode 100755 index efbd93a..0000000 --- a/scripts/dev.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env sh - -# Sets up a development environment and runs a shell in a docker container. -# Usage: dev.sh [--build [--clean]] [bash_args ...] - -if [ "$1" = "--build" ]; then - shift - printf "Building ghcr.io/python-discord/snekbox-venv:dev..." - - docker build \ - -t ghcr.io/python-discord/snekbox-venv:dev \ - -f Dockerfile \ - --build-arg DEV=1 \ - --target venv \ - -q \ - . \ - >/dev/null \ - && printf " done!\n" || exit "$?" - - if [ "$1" = "--clean" ]; then - shift - dangling_imgs=$(docker images -f "dangling=true" -q) - - if [ -n "${dangling_imgs}" ]; then - printf "Removing dangling images..." - - # shellcheck disable=SC2086 - docker rmi $dangling_imgs >/dev/null \ - && printf " done!\n" || exit "$?" - fi - fi -fi - -# Keep the container up in the background so it doesn't have to be restarted -# for the ownership fix. -# The volume is mounted to same the path in the container as the source -# directory on the host to ensure coverage can find the source files. -docker run \ - --tty \ - --detach \ - --name snekbox_test \ - --privileged \ - --hostname pdsnk-dev \ - --ipc="none" \ - -e PYTHONDONTWRITEBYTECODE=1 \ - -e PIPENV_PIPFILE="/snekbox/Pipfile" \ - --volume "${PWD}":"${PWD}" \ - --workdir "${PWD}"\ - --entrypoint /bin/bash \ - ghcr.io/python-discord/snekbox-venv:dev \ - >/dev/null \ - -# Execute the given command(s) -docker exec -it snekbox_test /bin/bash "$@" - -# Fix ownership of coverage file -# BusyBox doesn't support --reference for chown -docker exec \ - -it \ - -e CWD="${PWD}" \ - snekbox_test \ - /bin/bash \ - -c 'chown "$(stat -c "%u:%g" "${CWD}")" "${CWD}/.coverage"' - -docker rm -f snekbox_test >/dev/null # Stop and remove the container |