diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..17d6464 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use_nix \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/language-request.md b/.github/ISSUE_TEMPLATE/language-request.md new file mode 100644 index 0000000..5ae2661 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/language-request.md @@ -0,0 +1,10 @@ +--- +name: Language Request +about: Template for requesting language support +title: Add [insert language name here] +labels: package +assignees: '' + +--- + +Provide links to different compilers/interpreters that could be used to implement this language, and discuss pros/cons of each. diff --git a/.github/PULL_REQUEST_TEMPLATE/package.md b/.github/PULL_REQUEST_TEMPLATE/package.md new file mode 100644 index 0000000..6cd3c98 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/package.md @@ -0,0 +1,10 @@ +Checklist: +* [ ] The package builds locally with `./piston build-pkg [package] [version]` +* [ ] The package installs with `./piston ppman install [package]=[version]` +* [ ] The package runs the test code with `./piston run [package] -l [version] packages/[package]/[version]/test.*` +* [ ] Package files are placed in the correct directory +* [ ] No old package versions are removed +* [ ] All source files are deleted in the `build.sh` script +* [ ] `metadata.json`'s `language` and `version` fields match the directory path +* [ ] Any extensions the language may use are set as aliases +* [ ] Any alternative names the language is referred to are set as aliases. diff --git a/.github/workflows/package-pr.yaml b/.github/workflows/package-pr.yaml index b3027ec..bb264a3 100644 --- a/.github/workflows/package-pr.yaml +++ b/.github/workflows/package-pr.yaml @@ -55,7 +55,9 @@ jobs: run: | PACKAGES=$(jq '.[]' -r ${HOME}/files.json | awk -F/ '{ print $2 "-" $3 }' | sort -u) echo "Packages: $PACKAGES" - docker run -v "${{ github.workspace }}:/piston" docker.pkg.github.com/engineer-man/piston/repo-builder:latest --no-server $PACKAGES + docker pull docker.pkg.github.com/engineer-man/piston/repo-builder:latest + docker build -t repo-builder repo + docker run -v "${{ github.workspace }}:/piston" repo-builder --no-server $PACKAGES ls -la packages - name: Upload package as artifact @@ -89,7 +91,9 @@ jobs: run: | ls -la docker run -v $(pwd)'/repo:/piston/repo' -v $(pwd)'/packages:/piston/packages' -d --name repo docker.pkg.github.com/engineer-man/piston/repo-builder --no-build - docker run --network container:repo -v $(pwd)'/data:/piston' -e PISTON_LOG_LEVEL=DEBUG -e 'PISTON_REPO_URL=http://localhost:8000/index' -d --name api docker.pkg.github.com/engineer-man/piston/api + docker pull docker.pkg.github.com/engineer-man/piston/api + docker build -t piston-api api + docker run --network container:repo -v $(pwd)'/data:/piston' -e PISTON_LOG_LEVEL=DEBUG -e 'PISTON_REPO_URL=http://localhost:8000/index' -d --name api piston-api echo Waiting for API to start.. docker run --network container:api appropriate/curl -s --retry 10 --retry-connrefused http://localhost:2000/api/v2/runtimes diff --git a/.github/workflows/package-push.yaml b/.github/workflows/package-push.yaml index ad33f3e..bbb44af 100644 --- a/.github/workflows/package-push.yaml +++ b/.github/workflows/package-push.yaml @@ -33,7 +33,9 @@ jobs: run: | PACKAGES=$(jq '.[]' -r ${HOME}/files.json | awk -F/ '{ print $2 "-" $3 }' | sort -u) echo "Packages: $PACKAGES" - docker run -v "${{ github.workspace }}:/piston" docker.pkg.github.com/engineer-man/piston/repo-builder:latest --no-server $PACKAGES + docker pull docker.pkg.github.com/engineer-man/piston/repo-builder:latest + docker build -t repo-builder repo + docker run -v "${{ github.workspace }}:/piston" repo-builder --no-server $PACKAGES ls -la packages - name: Upload Packages @@ -73,4 +75,4 @@ jobs: file: index tag: pkgs overwrite: true - file_glob: true \ No newline at end of file + file_glob: true diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..e651ad5 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,8 @@ +version: 2 +mkdocs: + configuration: mkdocs.yml + +python: + version: 3.7 + install: + - requirements: docs/requirements.txt diff --git a/api/Dockerfile b/api/Dockerfile index 668c54a..ec0d2a8 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -13,7 +13,7 @@ RUN apt-get update && \ libncurses6 libncurses5 libedit-dev libseccomp-dev rename procps python3 \ libreadline-dev libblas-dev liblapack-dev libpcre3-dev libarpack2-dev \ libfftw3-dev libglpk-dev libqhull-dev libqrupdate-dev libsuitesparse-dev \ - libsundials-dev && \ + libsundials-dev libpcre2-dev && \ rm -rf /var/lib/apt/lists/* RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen diff --git a/api/src/job.js b/api/src/job.js index d213bbc..683cda6 100644 --- a/api/src/job.js +++ b/api/src/job.js @@ -59,6 +59,13 @@ class Job { for (const file of this.files) { let file_path = path.join(this.dir, file.name); + const rel = path.relative(this.dir, file_path); + + if(rel.startsWith("..")) + throw Error(`File path "${file.name}" tries to escape parent directory: ${rel}`) + + await fs.mkdir(path.dirname(file_path), {recursive: true, mode: 0o700}) + await fs.chown(path.dirname(file_path), this.uid, this.gid); await fs.write_file(file_path, file.content); await fs.chown(file_path, this.uid, this.gid); @@ -155,7 +162,7 @@ class Job { proc.on('exit', (code, signal) => { exit_cleanup(); - resolve({ stdout, stderr, code, signal, output }); + resolve({stdout, stderr, code, signal, output }); }); proc.on('error', err => { @@ -332,10 +339,8 @@ class Job { async cleanup() { logger.info(`Cleaning up job uuid=${this.uuid}`); - await Promise.all([ - this.cleanup_processes(), - this.cleanup_filesystem(), - ]); + await this.cleanup_processes(); + await this.cleanup_filesystem(); } } diff --git a/cli/package-lock.json b/cli/package-lock.json index 76a2cc6..f7c2771 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "axios": "^0.21.1", + "axios": "^0.21.2", "chalk": "^4.1.0", "minimatch": "^3.0.4", "nocamel": "^1.0.2", @@ -38,11 +38,11 @@ } }, "node_modules/axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", + "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", "dependencies": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "node_modules/balanced-match": { @@ -116,11 +116,22 @@ } }, "node_modules/follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", + "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, "node_modules/get-caller-file": { @@ -318,11 +329,11 @@ } }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.2.tgz", + "integrity": "sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "balanced-match": { @@ -387,9 +398,9 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==" + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", + "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==" }, "get-caller-file": { "version": "2.0.5", diff --git a/cli/package.json b/cli/package.json index 90e3e12..ef1103e 100644 --- a/cli/package.json +++ b/cli/package.json @@ -5,7 +5,7 @@ "main": "index.js", "license": "MIT", "dependencies": { - "axios": "^0.21.1", + "axios": "^0.21.2", "chalk": "^4.1.0", "minimatch": "^3.0.4", "nocamel": "^1.0.2", diff --git a/docs/api-v2.md b/docs/api-v2.md new file mode 100644 index 0000000..111b514 --- /dev/null +++ b/docs/api-v2.md @@ -0,0 +1,234 @@ +# API + +Piston exposes an API for managing packages and executing user-defined code. + +The API is broken in to 2 main sections - packages and jobs. + +The API is exposed from the container, by default on port 2000, at `/api/v2/`. + +All inputs are validated, and if an error occurs, a 4xx or 5xx status code is returned. +In this case, a JSON payload is sent back containing the error message as `message` + +## Runtimes + +### `GET /api/v2/runtimes` + +Returns a list of available languages, including the version, runtime and aliases. + +#### Response + +- `[].language`: Name of the language +- `[].version`: Version of the runtime +- `[].aliases`: List of alternative names that can be used for the language +- `[].runtime` (_optional_): Name of the runtime used to run the langage, only provided if alternative runtimes exist for the language + +#### Example + +``` +GET /api/v2/runtimes +``` + +```json +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "language": "bash", + "version": "5.1.0", + "aliases": ["sh"] + }, + { + "language": "javascript", + "version": "15.10.0", + "aliases": ["node-javascript", "node-js", "javascript", "js"], + "runtime": "node" + } +] +``` + +## Execute + +### `POST /api/v2/execute` + +Runs the given code, using the given runtime and arguments, returning the result. + +#### Request + +- `language`: Name or alias of a language listed in [runtimes](#runtimes) +- `version`: SemVer version selector of a language listed in [runtimes](#runtimes) +- `files`: An array of files which should be uploaded into the job context +- `files[].name` (_optional_): Name of file to be written, if none a random name is picked +- `files[].content`: Content of file to be written +- `stdin` (_optional_): Text to pass into stdin of the program. Defaults to blank string. +- `args` (_optional_): Arguments to pass to the program. Defaults to none +- `run_timeout` (_optional_): The maximum allowed time in milliseconds for the compile stage to finish before bailing out. Must be a number, less than or equal to the configured maximum timeout. +- `compile_timeout` (_optional_): The maximum allowed time in milliseconds for the run stage to finish before bailing out. Must be a number, less than or equal to the configured maximum timeout. Defaults to maximum. +- `compile_memory_limit` (_optional_): The maximum amount of memory the compile stage is allowed to use in bytes. Must be a number, less than or equal to the configured maximum. Defaults to maximum, or `-1` (no limit) if none is configured. +- `run_memory_limit` (_optional_): The maximum amount of memory the run stage is allowed to use in bytes. Must be a number, less than or equal to the configured maximum. Defaults to maximum, or `-1` (no limit) if none is configured. + +#### Response + +- `language`: Name (not alias) of the runtime used +- `version`: Version of the used runtime +- `run`: Results from the run stage +- `run.stdout`: stdout from run stage process +- `run.stderr`: stderr from run stage process +- `run.output`: stdout and stderr combined in order of data from run stage process +- `run.code`: Exit code from run process, or null if signal is not null +- `run.signal`: Signal from run process, or null if code is not null +- `compile` (_optional_): Results from the compile stage, only provided if the runtime has a compile stage +- `compile.stdout`: stdout from compile stage process +- `compile.stderr`: stderr from compile stage process +- `compile.output`: stdout and stderr combined in order of data from compile stage process +- `compile.code`: Exit code from compile process, or null if signal is not null +- `compile.signal`: Signal from compile process, or null if code is not null + +#### Example + +```json +POST /api/v2/execute +Content-Type: application/json + +{ + "language": "js", + "version": "15.10.0", + "files": [ + { + "name": "my_cool_code.js", + "content": "console.log(process.argv)" + } + ], + "stdin": "", + "args": ["1", "2", "3"], + "compile_timeout": 10000, + "run_timeout": 3000, + "compile_memory_limit": -1, + "run_memory_limit": -1 +} +``` + +```json +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "run": { + "stdout": "[\n '/piston/packages/node/15.10.0/bin/node',\n '/piston/jobs/e87afa0d-6c2a-40b8-a824-ffb9c5c6cb64/my_cool_code.js',\n '1',\n '2',\n '3'\n]\n", + "stderr": "", + "code": 0, + "signal": null, + "output": "[\n '/piston/packages/node/15.10.0/bin/node',\n '/piston/jobs/e87afa0d-6c2a-40b8-a824-ffb9c5c6cb64/my_cool_code.js',\n '1',\n '2',\n '3'\n]\n" + }, + "language": "javascript", + "version": "15.10.0" +} +``` + +## Packages + +### `GET /api/v2/packages` + +Returns a list of all possible packages, and whether their installation status. + +#### Response + +- `[].language`: Name of the contained runtime +- `[].language_version`: Version of the contained runtime +- `[].installed`: Status on the package being installed + +#### Example + +``` +GET /api/v2/packages +``` + +```json +HTTP/1.1 200 OK +Content-Type: application/json + +[ + { + "language": "node", + "language_version": "15.10.0", + "installed": true + }, + { + "language": "bash", + "language_version": "5.1.0", + "installed": true + } +] +``` + +### `POST /api/v2/packages` + +Install the given package. + +#### Request + +- `language`: Name of package from [package list](#get-apiv2packages) +- `version`: SemVer version selector for package from [package list](#get-apiv2packages) + +#### Response + +- `language`: Name of package installed +- `version`: Version of package installed + +#### Example + +```json +POST /api/v2/packages +Content-Type: application/json + +{ + "language": "bash", + "version": "5.x" +} +``` + +```json +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "language": "bash", + "version": "5.1.0" +} +``` + +### `DELETE /api/v2/packages` + +Uninstall the given package. + +#### Request + +- `language`: Name of package from [package list](#get-apiv2packages) +- `version`: SemVer version selector for package from [package list](#get-apiv2packages) + +#### Response + +- `language`: Name of package uninstalled +- `version`: Version of package uninstalled + +#### Example + +```json +DELETE /api/v2/packages +Content-Type: application/json + +{ + "language": "bash", + "version": "5.x" +} +``` + +```json +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "language": "bash", + "version": "5.1.0" +} +``` diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..1388e9d --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,147 @@ +# Configuration + +Piston provides many different configuration options to tweak Piston to meet your needs. + +Configuration is specified through environment variables, prefixed with `PISTON_`. + +## Log Level + +```yaml +key: PISTON_LOG_LEVEL +default: INFO +``` + +Level of log output to provide. + +One of `DEBUG`, `INFO`, `WARN`, `ERROR` or `NONE` + +## Bind Address + +```yaml +key: PISTON_BIND_ADDRESS +default: 0.0.0.0:2000 +``` + +Port and IP address to bind the Piston API to. + + +!!! warning + Changing this value is not recommended. + + This changes the bind address inside the container, and thus serves no purpose when running in a container + +## Data Directory + +```yaml +key: PISTON_DATA_DIRECTORY +default: /piston +``` + +Absolute path to piston related data, including packages and job contexts. + + +!!! warning + Changing this value is not recommended. + + Some packages require absolute paths on disk at build time. + Due to this, some packages may break when changing this parameter. + +## Runner GID/UID range + +```yaml +key: + - PISTON_RUNNER_UID_MIN + - PISTON_RUNNER_UID_MAX + - PISTON_RUNNER_GID_MIN + - PISTON_RUNNER_GID_MAX +default: + - 1001 + - 1500 + - 1001 + - 1500 +``` + +UID and GID ranges to use when executing jobs. + + +!!! warning + Changing this value is not recommended. + + The piston container creates 500 users and groups by default, and reserves user/group 1000 for running the API. + Any processes run by these users will be killed when cleaning up a job. + +## Disable Networking + +```yaml +key: PISTON_DISABLE_NETWORKING +default: true +``` + +Disallows access to `socket` syscalls, effectively disabling networking for jobs run by piston. + +## Max Process Count + +```yaml +key: PISTON_MAX_PROCESS_COUNT +default: 64 +``` + +Maximum number of processess allowed to to have open for a job. + +Resists against exhausting the process table, causing a full system lockup. + +## Output Max Side + +```yaml +key: PISTON_OUTPUT_MAX_SIZE +default: 1024 +``` + +Maximum size of stdio buffers for each job. + +Resist against run-away output which could lead to memory exhaustion. + +## Max Open Files + +```yaml +key: PISTON_MAX_OPEN_FILES +default: 64 +``` + +Maximum number of open files at a given time by a job. + +Resists against writing many smaller files to exhaust inodes. + +## Max File Size + +```yaml +key: PISTON_MAX_FILE_SIZE +default: 10000000 #10MB +``` + +Maximum size for a singular file written to disk. + +Resists against large file writes to exhaust disk space. + +## Compile/Run memory limits + +```yaml +key: + - PISTON_COMPILE_MEMORY_LIMIT + - PISTON_RUN_MEMORY_LIMIT +default: -1 +``` + +Maximum memory allowed by a stage in bytes. +Use -1 for unlimited memory usage. + +Useful for running memory-limited contests. + +## Repository URL + +```yaml +key: PISTON_REPO_URL +default: https://github.com/engineer-man/piston/releases/download/pkgs/index +``` + +URL for repository index, where packages will be downloaded from. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..a8e5891 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,3 @@ +# Piston + +These docs are a WIP diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..53dbf05 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +mkdocs==1.1.2 \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..148ba91 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,15 @@ +site_name: Piston +nav: + - Home: index.md + - Configuration: configuration.md + - API: api-v2.md + +theme: + name: readthedocs + highlightjs: true + hljs_languages: + - yaml + - json + +markdown_extensions: + - admonition diff --git a/packages/cow/1.0.0/build.sh b/packages/cow/1.0.0/build.sh index 3bf5938..4753cae 100755 --- a/packages/cow/1.0.0/build.sh +++ b/packages/cow/1.0.0/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Grab the latest cow source from github -git clone -q https://github.com/BigZaphod/COW.git cow +git clone -q https://github.com/Hydrazer/COW.git cow # Generate the cow binary into bin mkdir -p bin diff --git a/packages/go/1.16.2/run b/packages/go/1.16.2/run index da31af3..65c9a4f 100644 --- a/packages/go/1.16.2/run +++ b/packages/go/1.16.2/run @@ -1,6 +1,7 @@ #!/usr/bin/env bash mv $1 $1.go -filename=$1.go +#filename=$1.go +filename=*.go shift GOCACHE=$PWD go run $filename "$@" diff --git a/packages/julia/1.6.1/build.sh b/packages/julia/1.6.1/build.sh new file mode 100755 index 0000000..b2772ae --- /dev/null +++ b/packages/julia/1.6.1/build.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Install location +PREFIX=$(realpath $(dirname $0)) + +mkdir -p build +cd build + +# Download and extract Julia source +curl -L "https://github.com/JuliaLang/julia/releases/download/v1.6.1/julia-1.6.1.tar.gz" -o julia.tar.gz +tar xzf julia.tar.gz --strip-components=1 + +# Build +echo "JULIA_CPU_TARGET=generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1) +prefix=$PREFIX" > Make.user +make -j$(nproc) +make install -j$(nproc) + +# Cleanup +cd .. +rm -rf build diff --git a/packages/julia/1.6.1/environment b/packages/julia/1.6.1/environment new file mode 100644 index 0000000..e7d0c97 --- /dev/null +++ b/packages/julia/1.6.1/environment @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# Add Julia binary to path +export PATH=$PWD/bin:$PATH diff --git a/packages/julia/1.6.1/metadata.json b/packages/julia/1.6.1/metadata.json new file mode 100644 index 0000000..be2fdea --- /dev/null +++ b/packages/julia/1.6.1/metadata.json @@ -0,0 +1,5 @@ +{ + "language": "julia", + "version": "1.6.1", + "aliases": ["jl"] +} diff --git a/packages/julia/1.6.1/run b/packages/julia/1.6.1/run new file mode 100755 index 0000000..6badf1c --- /dev/null +++ b/packages/julia/1.6.1/run @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# Run without startup or history file +julia --startup-file=no --history-file=no "$@" diff --git a/packages/julia/1.6.1/test.jl b/packages/julia/1.6.1/test.jl new file mode 100644 index 0000000..dc98a27 --- /dev/null +++ b/packages/julia/1.6.1/test.jl @@ -0,0 +1 @@ +println("OK") diff --git a/packages/mono/6.12.0/build.sh b/packages/mono/6.12.0/build.sh index 2cecc07..7bb4b63 100755 --- a/packages/mono/6.12.0/build.sh +++ b/packages/mono/6.12.0/build.sh @@ -2,19 +2,31 @@ PREFIX=$(realpath $(dirname $0)) -mkdir -p build/mono +mkdir -p build/mono build/mono-basic cd build curl "https://download.mono-project.com/sources/mono/mono-6.12.0.122.tar.xz" -o mono.tar.xz +curl -L "https://github.com/mono/mono-basic/archive/refs/tags/4.7.tar.gz" -o mono-basic.tar.gz tar xf mono.tar.xz --strip-components=1 -C mono +tar xf mono-basic.tar.gz --strip-components=1 -C mono-basic +# Compiling Mono cd mono ./configure --prefix "$PREFIX" -make -j$(nproc) +make -j$(nproc) make install -j$(nproc) +export PATH="$PREFIX/bin:$PATH" # To be able to use mono commands + +# Compiling mono-basic +cd ../mono-basic +./configure --prefix="$PREFIX" + +make -j$(nproc) PLATFORM="linux" # Avoids conflict with the $PLATFORM variable we have +make install -j$(nproc) PLATFORM="linux" + +# Remove redundant files cd ../../ rm -rf build - diff --git a/packages/mono/6.12.0/compile b/packages/mono/6.12.0/compile index 8728714..e3ae230 100644 --- a/packages/mono/6.12.0/compile +++ b/packages/mono/6.12.0/compile @@ -1,4 +1,23 @@ #!/bin/bash -rename 's/$/\.cs/' "$@" # Add .cs extension -csc -out:out *.cs +check_errors () { + grep -q 'error [A-Z]\+[0-9]\+:' check.txt && cat check.txt 1>&2 || cat check.txt + rm check.txt +} + +case "${PISTON_LANGUAGE}" in + csharp) + rename 's/$/\.cs/' "$@" # Add .cs extension + csc -out:out *.cs > check.txt + check_errors + ;; + basic) + rename 's/$/\.vb/' "$@" # Add .vb extension + vbnc -out:out *.vb > check.txt + check_errors + ;; + *) + echo "How did you get here? (${PISTON_LANGUAGE})" + exit 1 + ;; +esac diff --git a/packages/mono/6.12.0/environment b/packages/mono/6.12.0/environment index bd0ff98..977a5e8 100644 --- a/packages/mono/6.12.0/environment +++ b/packages/mono/6.12.0/environment @@ -1 +1 @@ -export PATH=$PWD/bin:$PATH \ No newline at end of file +export PATH=$PWD/bin:$PATH diff --git a/packages/mono/6.12.0/metadata.json b/packages/mono/6.12.0/metadata.json index a053884..4d09ae7 100644 --- a/packages/mono/6.12.0/metadata.json +++ b/packages/mono/6.12.0/metadata.json @@ -5,6 +5,10 @@ { "language": "csharp", "aliases": ["mono", "mono-csharp", "mono-c#", "mono-cs", "c#", "cs"] + }, + { + "language": "basic", + "aliases": ["vb", "mono-vb", "mono-basic", "visual-basic", "visual basic"] } ] } diff --git a/packages/mono/6.12.0/test.vb b/packages/mono/6.12.0/test.vb new file mode 100644 index 0000000..291042e --- /dev/null +++ b/packages/mono/6.12.0/test.vb @@ -0,0 +1,9 @@ +Imports System + +Module Module1 + + Sub Main() + Console.WriteLine("OK") + End Sub + +End Module diff --git a/packages/node/16.3.0/build.sh b/packages/node/16.3.0/build.sh new file mode 100755 index 0000000..bbc19db --- /dev/null +++ b/packages/node/16.3.0/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +curl "https://nodejs.org/dist/v16.3.0/node-v16.3.0-linux-x64.tar.xz" -o node.tar.xz +tar xf node.tar.xz --strip-components=1 +rm node.tar.xz diff --git a/packages/node/16.3.0/environment b/packages/node/16.3.0/environment new file mode 100644 index 0000000..977a5e8 --- /dev/null +++ b/packages/node/16.3.0/environment @@ -0,0 +1 @@ +export PATH=$PWD/bin:$PATH diff --git a/packages/node/16.3.0/metadata.json b/packages/node/16.3.0/metadata.json new file mode 100644 index 0000000..ccd146a --- /dev/null +++ b/packages/node/16.3.0/metadata.json @@ -0,0 +1,10 @@ +{ + "language": "node", + "version": "16.3.0", + "provides": [ + { + "language": "javascript", + "aliases": ["node-javascript", "node-js", "javascript", "js"] + } + ] +} diff --git a/packages/node/16.3.0/run b/packages/node/16.3.0/run new file mode 100644 index 0000000..6d1fdee --- /dev/null +++ b/packages/node/16.3.0/run @@ -0,0 +1,3 @@ +#!/bin/bash + +node "$@" \ No newline at end of file diff --git a/packages/node/16.3.0/test.js b/packages/node/16.3.0/test.js new file mode 100644 index 0000000..56ed4a0 --- /dev/null +++ b/packages/node/16.3.0/test.js @@ -0,0 +1 @@ +console.log("OK") \ No newline at end of file diff --git a/packages/pwsh/7.1.4/build.sh b/packages/pwsh/7.1.4/build.sh new file mode 100755 index 0000000..3f4b070 --- /dev/null +++ b/packages/pwsh/7.1.4/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash +curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.1.4/powershell-7.1.4-linux-x64.tar.gz -o powershell.tar.gz +tar zxf powershell.tar.gz +rm powershell.tar.gz + +chmod +x pwsh diff --git a/packages/pwsh/7.1.4/environment b/packages/pwsh/7.1.4/environment new file mode 100644 index 0000000..42644cd --- /dev/null +++ b/packages/pwsh/7.1.4/environment @@ -0,0 +1 @@ +export PATH=$PWD:$PATH diff --git a/packages/pwsh/7.1.4/metadata.json b/packages/pwsh/7.1.4/metadata.json new file mode 100644 index 0000000..da90f76 --- /dev/null +++ b/packages/pwsh/7.1.4/metadata.json @@ -0,0 +1,10 @@ +{ + "language": "pwsh", + "version": "7.1.4", + "provides": [ + { + "language": "powershell", + "aliases": ["ps", "pwsh", "ps1"] + } + ] +} diff --git a/packages/pwsh/7.1.4/run b/packages/pwsh/7.1.4/run new file mode 100644 index 0000000..02a0be7 --- /dev/null +++ b/packages/pwsh/7.1.4/run @@ -0,0 +1,3 @@ +#!/bin/bash + +pwsh "$@" diff --git a/packages/pwsh/7.1.4/test.ps1 b/packages/pwsh/7.1.4/test.ps1 new file mode 100644 index 0000000..f0a4be3 --- /dev/null +++ b/packages/pwsh/7.1.4/test.ps1 @@ -0,0 +1 @@ +echo "OK" diff --git a/packages/rscript/4.1.1/build.sh b/packages/rscript/4.1.1/build.sh new file mode 100755 index 0000000..9837c22 --- /dev/null +++ b/packages/rscript/4.1.1/build.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +PREFIX=$(realpath $(dirname $0)) + +mkdir build +cd build + +curl https://cloud.r-project.org/src/base/R-4/R-4.1.1.tar.gz -o R.tar.gz +tar xzf R.tar.gz --strip-components 1 + +./configure --prefix="$PREFIX" --with-x=no +make -j$(nproc) +make install -j$(nproc) + +cd ../ +rm -rf build diff --git a/packages/rscript/4.1.1/environment b/packages/rscript/4.1.1/environment new file mode 100644 index 0000000..977a5e8 --- /dev/null +++ b/packages/rscript/4.1.1/environment @@ -0,0 +1 @@ +export PATH=$PWD/bin:$PATH diff --git a/packages/rscript/4.1.1/metadata.json b/packages/rscript/4.1.1/metadata.json new file mode 100644 index 0000000..db16a76 --- /dev/null +++ b/packages/rscript/4.1.1/metadata.json @@ -0,0 +1,5 @@ +{ + "language": "rscript", + "version": "4.1.1", + "aliases": ["r"] +} diff --git a/packages/rscript/4.1.1/run b/packages/rscript/4.1.1/run new file mode 100644 index 0000000..d122eb8 --- /dev/null +++ b/packages/rscript/4.1.1/run @@ -0,0 +1,2 @@ +#/bin/bash +Rscript "$@" diff --git a/packages/rscript/4.1.1/test.r b/packages/rscript/4.1.1/test.r new file mode 100644 index 0000000..9273f27 --- /dev/null +++ b/packages/rscript/4.1.1/test.r @@ -0,0 +1 @@ +cat('OK') diff --git a/packages/vlang/0.1.13/run b/packages/vlang/0.1.13/run index 18b6c05..c999cca 100644 --- a/packages/vlang/0.1.13/run +++ b/packages/vlang/0.1.13/run @@ -6,8 +6,9 @@ export TMPDIR="$PWD" # Put instructions to run the runtime -rename 's/$/\.v/' "$@" # Add .v extension +filename=$1 + +rename 's/$/\.v/' $filename # Add .v extension -filename=$1.v shift -v run $filename "$@" \ No newline at end of file +v run $filename.v "$@" diff --git a/piston b/piston index 7e3a469..28e18db 100755 --- a/piston +++ b/piston @@ -23,22 +23,23 @@ case $1 in echo " start Starts piston" echo " stop Stops piston" echo " restart Restarts piston" + echo " bash Opens a bash shell for the piston_api container" echo echo " update Fetches and applies latest updates" echo echo " Passthrough to piston cli tool" - echo + echo echo "Development Commands:" - + if [ $PISTON_ENV == dev ]; then - + echo " clean-pkgs Clean any package build artifacts on disk" echo " clean-repo Remove all packages from local repo" echo " build-pkg Build a package" echo " rebuild Build and restart the docker container" else - + echo " Switch to developement environment for more info" echo " > piston select dev" @@ -52,6 +53,7 @@ case $1 in restart) docker_compose restart ;; start) docker_compose up -d ;; stop) docker_compose down ;; + bash) docker_compose exec api /bin/bash ;; rebuild) docker_compose build && docker_compose up -d ;; @@ -77,4 +79,4 @@ case $1 in cd ../ node cli/index.js "$@" ;; -esac \ No newline at end of file +esac diff --git a/readme.md b/readme.md index 1a0f846..f43f70a 100644 --- a/readme.md +++ b/readme.md @@ -33,7 +33,8 @@ Supported LanguagesPrinciplesSecurity • - License + License • + Documentation --- @@ -65,6 +66,9 @@ The following are approved and endorsed extensions/utilities to the core Piston - [I Run Code](https://github.com/engineer-man/piston-bot), a Discord bot used in 4100+ servers to handle arbitrary code evaluation in Discord. To get this bot in your own server, go here: https://emkc.org/run. - [Piston CLI](https://github.com/Shivansh-007/piston-cli), a universal shell supporting code highlighting, files, and interpretation without the need to download a language. +- [Node Piston Client](https://github.com/dthree/node-piston), a Node.js wrapper for accessing the Piston API. +- [Piston4J](https://github.com/the-codeboy/Piston4J), a Java wrapper for accessing the Piston API. +- [Pyston](https://github.com/ffaanngg/pyston), a Python wrapper for accessing the Piston API.
@@ -84,7 +88,9 @@ POST https://emkc.org/api/v2/piston/execute > Important Note: The Piston API is rate limited to 5 requests per second. If you have a need for more requests than that > and it's for a good cause, please reach out to me (EngineerMan#0001) on [Discord](https://discord.gg/engineerman) -> so we can discuss potentially getting you an unlimited key. +> so we can discuss potentially getting you an unlimited key. What is and isn't a good cause is up to me, but, in general +> if your project is a) open source, b) helping people at no cost to them, and c) not likely to use tons of resources +> thereby impairing another's ability to enjoy Piston, you'll likely be granted a key.
@@ -96,7 +102,7 @@ POST https://emkc.org/api/v2/piston/execute - Docker - Docker Compose -- Node JS +- Node JS (>= 13, preferably >= 15) ### After system dependencies are installed, clone this repository: @@ -135,6 +141,22 @@ docker run \ ghcr.io/engineer-man/piston ``` +## Piston for testing packages locally + +### Host System Package Dependencies + +- Same as [All In One](#All-In-One) + +### Installation + +```sh +# Build the Docker containers +./piston start + +# For more help +./piston help +``` +
# Usage @@ -326,6 +348,7 @@ Content-Type: application/json `perl`, `php`, `ponylang`, +`powershell`, `prolog`, `pure`, `pyth`, @@ -333,11 +356,13 @@ Content-Type: application/json `python2`, `raku`, `rockstar`, +`rscript`, `ruby`, `rust`, `scala`, `swift`, `typescript`, +`basic`, `vlang`, `yeethon`, `zig`, diff --git a/repo/Dockerfile b/repo/Dockerfile index 106fef4..56ca59d 100644 --- a/repo/Dockerfile +++ b/repo/Dockerfile @@ -8,7 +8,8 @@ RUN apt-get update && apt-get install -y unzip autoconf build-essential libssl-d util-linux pciutils usbutils coreutils binutils findutils grep libncurses5-dev \ libncursesw5-dev python3-pip libgmp-dev libmpfr-dev python2 libffi-dev gfortran\ libreadline-dev libblas-dev liblapack-dev libpcre3-dev libarpack2-dev libfftw3-dev \ - libglpk-dev libqhull-dev libqrupdate-dev libsuitesparse-dev libsundials-dev && \ + libglpk-dev libqhull-dev libqrupdate-dev libsuitesparse-dev libsundials-dev \ + libbz2-dev liblzma-dev libpcre2-dev && \ ln -sf /bin/bash /bin/sh && \ rm -rf /var/lib/apt/lists/* && \ update-alternatives --install /usr/bin/python python /usr/bin/python3.7 2 @@ -17,4 +18,3 @@ ADD entrypoint.sh mkindex.sh / ENTRYPOINT ["bash","/entrypoint.sh"] CMD ["--no-build"] - diff --git a/shell.nix b/shell.nix index 47b2d12..339bead 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,5 @@ { pkgs ? import {} }: pkgs.mkShell { # nativeBuildInputs is usually what you want -- tools you need to run - nativeBuildInputs = with pkgs; [ nodejs-15_x jq ]; + nativeBuildInputs = with pkgs; [ nodejs-15_x jq mkdocs ]; }