aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar MarkKoz <[email protected]>2021-01-10 21:19:44 -0800
committerGravatar MarkKoz <[email protected]>2021-01-10 21:35:26 -0800
commitdab2a0ac4f9e5080865e77048c936ab279e5918d (patch)
treef56df32946f11ed0cde87d924e1653d233257efa
parentSupport overriding nsjail config values with additional arguments (diff)
Replace nsjpy alias with a Python script
The Python script uses the same underlying code Falcon uses to invoke nsjail. It allows for the omission of redundant shell code that set up cgroups and nsjail args. This is also a step towards removing dependence on shell scripts and thus resolving #73.
-rw-r--r--.github/workflows/lint-test-build-push.yaml1
-rw-r--r--Pipfile1
-rw-r--r--README.md6
-rw-r--r--scripts/.profile21
-rwxr-xr-xscripts/dev.sh3
-rw-r--r--snekbox/__main__.py28
6 files changed, 33 insertions, 27 deletions
diff --git a/.github/workflows/lint-test-build-push.yaml b/.github/workflows/lint-test-build-push.yaml
index 5aa2180..671e576 100644
--- a/.github/workflows/lint-test-build-push.yaml
+++ b/.github/workflows/lint-test-build-push.yaml
@@ -90,7 +90,6 @@ jobs:
--hostname pdsnk-dev
-e PYTHONDONTWRITEBYTECODE=1
-e PIPENV_PIPFILE='/snekbox/Pipfile'
- -e ENV="${PWD}/scripts/.profile"
--volume "${PWD}":"${PWD}"
--workdir "${PWD}"
--entrypoint /bin/bash
diff --git a/Pipfile b/Pipfile
index 5609128..2e86b25 100644
--- a/Pipfile
+++ b/Pipfile
@@ -41,6 +41,7 @@ testb = """
"""
report = "coverage report"
snekbox = "gunicorn -c config/gunicorn.conf.py snekbox.api.app"
+eval = "python -m snekbox"
devsh = "sh scripts/dev.sh"
protoc = "sh scripts/protoc.sh"
build = """
diff --git a/README.md b/README.md
index 453eb4c..eaa3eb6 100644
--- a/README.md
+++ b/README.md
@@ -153,13 +153,13 @@ pipenv run devsh [--build [--clean]] [bash_args ...]
#### 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:
+NsJail can be invoked in a more direction manner that does not require using a web server or its API. See `python -m snekbox --help`. Example usage:
```bash
-nsjpy "print('hello world!')"
+python -m snekbox 'print("hello world!")' --time_limit 0
```
-The alias can be found in `./scripts/.profile`, which is automatically added when the shell is launched in the container.
+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
diff --git a/scripts/.profile b/scripts/.profile
deleted file mode 100644
index 11c8d78..0000000
--- a/scripts/.profile
+++ /dev/null
@@ -1,21 +0,0 @@
-nsjpy() {
- local MEM_MAX=52428800
-
- # All arguments except the last are considered to be for NsJail, not Python.
- local nsj_args=""
- while [ "$#" -gt 1 ]; do
- nsj_args="${nsj_args:+${nsj_args} }$1"
- shift
- done
-
- # Set up cgroups and disable memory swapping.
- mkdir -p /sys/fs/cgroup/pids/NSJAIL
- mkdir -p /sys/fs/cgroup/memory/NSJAIL
- echo "${MEM_MAX}" > /sys/fs/cgroup/memory/NSJAIL/memory.limit_in_bytes
- echo "${MEM_MAX}" > /sys/fs/cgroup/memory/NSJAIL/memory.memsw.limit_in_bytes
-
- nsjail \
- --config "${NSJAIL_CFG:-/snekbox/config/snekbox.cfg}" \
- $nsj_args -- \
- /usr/local/bin/python -Squ -c "$@"
-}
diff --git a/scripts/dev.sh b/scripts/dev.sh
index 3f94874..efbd93a 100755
--- a/scripts/dev.sh
+++ b/scripts/dev.sh
@@ -44,7 +44,6 @@ docker run \
--ipc="none" \
-e PYTHONDONTWRITEBYTECODE=1 \
-e PIPENV_PIPFILE="/snekbox/Pipfile" \
- -e BASH_ENV="${PWD}/scripts/.profile" \
--volume "${PWD}":"${PWD}" \
--workdir "${PWD}"\
--entrypoint /bin/bash \
@@ -52,7 +51,7 @@ docker run \
>/dev/null \
# Execute the given command(s)
-docker exec -it snekbox_test /bin/bash --rcfile "${PWD}/scripts/.profile" "$@"
+docker exec -it snekbox_test /bin/bash "$@"
# Fix ownership of coverage file
# BusyBox doesn't support --reference for chown
diff --git a/snekbox/__main__.py b/snekbox/__main__.py
new file mode 100644
index 0000000..a63fd3c
--- /dev/null
+++ b/snekbox/__main__.py
@@ -0,0 +1,28 @@
+import argparse
+
+from snekbox.nsjail import NsJail
+
+
+def parse_args() -> argparse.Namespace:
+ """Parse the command-line arguments and return the populated namespace."""
+ parser = argparse.ArgumentParser(prog="snekbox", usage="%(prog)s code [nsjail_args ...]")
+ parser.add_argument("code", help="the Python code to evaluate")
+ parser.add_argument("nsjail_args", nargs="?", help="override configured NsJail options")
+
+ # nsjail_args is just a dummy for documentation purposes.
+ # Its actual value comes from all the unknown arguments.
+ # There doesn't seem to be a better solution with argparse.
+ args, unknown = parser.parse_known_args()
+ args.nsjail_args = unknown
+ return args
+
+
+def main() -> None:
+ """Evaluate Python code through NsJail."""
+ args = parse_args()
+ result = NsJail().python3(args.code, *args.nsjail_args)
+ print(result.stdout)
+
+
+if __name__ == "__main__":
+ main()