Update for new API
This commit is contained in:
commit
c10a30b69a
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
263
api/main.go
263
api/main.go
|
@ -1,263 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os/exec"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Inbound struct {
|
|
||||||
Language string `json:"language"`
|
|
||||||
Source string `json:"source"`
|
|
||||||
Args []string `json:"args"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Problem struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Outbound struct {
|
|
||||||
Ran bool `json:"ran"`
|
|
||||||
Language string `json:"language"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
Output string `json:"output"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Language struct {
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var instance int
|
|
||||||
var languages []Language
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
port := "2000"
|
|
||||||
|
|
||||||
var err error
|
|
||||||
languages, err = UpdateVersions()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("could not get version info and therefore couldn't start")
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("starting api on port", port)
|
|
||||||
http.HandleFunc("/execute", Execute)
|
|
||||||
http.HandleFunc("/versions", Versions)
|
|
||||||
http.ListenAndServe(":"+port, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Execute(res http.ResponseWriter, req *http.Request) {
|
|
||||||
res.Header().Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
// get json
|
|
||||||
inbound := Inbound{}
|
|
||||||
message := json.NewDecoder(req.Body)
|
|
||||||
message.Decode(&inbound)
|
|
||||||
|
|
||||||
whitelist := []string{
|
|
||||||
"awk",
|
|
||||||
"bash",
|
|
||||||
"brainfuck", "bf",
|
|
||||||
"c",
|
|
||||||
"cpp", "c++",
|
|
||||||
"csharp", "cs", "c#",
|
|
||||||
"d",
|
|
||||||
"deno", "denojs", "denots",
|
|
||||||
"elixir", "exs",
|
|
||||||
"emacs", "elisp", "el",
|
|
||||||
"go",
|
|
||||||
"haskell", "hs",
|
|
||||||
"java",
|
|
||||||
"jelly",
|
|
||||||
"julia", "jl",
|
|
||||||
"kotlin",
|
|
||||||
"lua",
|
|
||||||
"nasm", "asm",
|
|
||||||
"nasm64", "asm64",
|
|
||||||
"nim",
|
|
||||||
"node", "javascript", "js",
|
|
||||||
"perl", "pl",
|
|
||||||
"php",
|
|
||||||
"python2",
|
|
||||||
"python3", "python",
|
|
||||||
"paradoc",
|
|
||||||
"ruby",
|
|
||||||
"rust",
|
|
||||||
"swift",
|
|
||||||
"typescript", "ts",
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the supplied language is supported
|
|
||||||
// now calls function and returns
|
|
||||||
for _, lang := range whitelist {
|
|
||||||
if lang == inbound.Language {
|
|
||||||
launch(inbound, res)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now only called when the language is not supported
|
|
||||||
problem := Problem{
|
|
||||||
Code: "unsupported_language",
|
|
||||||
Message: inbound.Language + " is not supported by Piston",
|
|
||||||
}
|
|
||||||
|
|
||||||
pres, _ := json.Marshal(problem)
|
|
||||||
|
|
||||||
res.Write(pres)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Versions(res http.ResponseWriter, req *http.Request) {
|
|
||||||
res.Header().Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
data, _ := json.Marshal(languages)
|
|
||||||
|
|
||||||
res.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func launch(request Inbound, res http.ResponseWriter) {
|
|
||||||
stamp := time.Now().UnixNano()
|
|
||||||
|
|
||||||
// write the code to temp dir
|
|
||||||
srcfile := fmt.Sprintf("/tmp/%d.code", stamp)
|
|
||||||
|
|
||||||
ioutil.WriteFile(srcfile, []byte(request.Source), 0644)
|
|
||||||
|
|
||||||
// set up the arguments to send to the execute command
|
|
||||||
cmd := exec.Command("../lxc/execute", request.Language, srcfile, strings.Join(request.Args, "\n"))
|
|
||||||
|
|
||||||
// capture out/err
|
|
||||||
var stdout, stderr bytes.Buffer
|
|
||||||
cmd.Stdout = &stdout
|
|
||||||
cmd.Stderr = &stderr
|
|
||||||
|
|
||||||
err := cmd.Run()
|
|
||||||
|
|
||||||
// get the executing version of the language
|
|
||||||
execlang := request.Language
|
|
||||||
|
|
||||||
switch execlang {
|
|
||||||
case "bf":
|
|
||||||
execlang = "brainfuck"
|
|
||||||
case "c++":
|
|
||||||
execlang = "cpp"
|
|
||||||
case "cs", "c#":
|
|
||||||
execlang = "csharp"
|
|
||||||
case "denojs", "denots":
|
|
||||||
execlang = "deno"
|
|
||||||
case "el", "elisp":
|
|
||||||
execlang = "emacs"
|
|
||||||
case "exs":
|
|
||||||
execlang = "elixir"
|
|
||||||
case "hs":
|
|
||||||
execlang = "haskell"
|
|
||||||
case "asm":
|
|
||||||
execlang = "nasm"
|
|
||||||
case "asm64":
|
|
||||||
execlang = "nasm64"
|
|
||||||
case "js", "javascript":
|
|
||||||
execlang = "node"
|
|
||||||
case "jl":
|
|
||||||
execlang = "julia"
|
|
||||||
case "python":
|
|
||||||
execlang = "python3"
|
|
||||||
case "ts":
|
|
||||||
execlang = "typescript"
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare response
|
|
||||||
outbound := Outbound{
|
|
||||||
Ran: err == nil,
|
|
||||||
Language: request.Language,
|
|
||||||
Version: "",
|
|
||||||
Output: strings.TrimSpace(stdout.String()),
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve the language version
|
|
||||||
for _, lang := range languages {
|
|
||||||
if lang.Name == execlang {
|
|
||||||
outbound.Version = lang.Version
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response, _ := json.Marshal(outbound)
|
|
||||||
|
|
||||||
res.Write(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateVersions() ([]Language, error) {
|
|
||||||
langs, err := GetVersions()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return langs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// get all the language and their current version
|
|
||||||
func GetVersions() ([]Language, error) {
|
|
||||||
var languages []Language
|
|
||||||
|
|
||||||
res, err := ExecVersionScript()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
info := strings.Split(res, "---")
|
|
||||||
|
|
||||||
for _, v := range info {
|
|
||||||
if len(v) < 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
name, version := GetVersion(v)
|
|
||||||
languages = append(languages, Language{
|
|
||||||
Name: name,
|
|
||||||
Version: version,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return languages, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// run the script that retrieves all the language versions
|
|
||||||
func ExecVersionScript() (string, error) {
|
|
||||||
cmd := exec.Command("../lxc/versions")
|
|
||||||
|
|
||||||
var stdout bytes.Buffer
|
|
||||||
cmd.Stdout = &stdout
|
|
||||||
cmd.Stderr = &stdout
|
|
||||||
|
|
||||||
err := cmd.Run()
|
|
||||||
|
|
||||||
return strings.ToLower(stdout.String()), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the language and its version
|
|
||||||
// most of the time it is easy to get the name and version
|
|
||||||
// but for some languages helper functions are used
|
|
||||||
func GetVersion(s string) (string, string) {
|
|
||||||
lines := strings.Split(s, "\n")
|
|
||||||
|
|
||||||
if lines[1] == "java" {
|
|
||||||
return "java", regexp.MustCompile("([0-9]+)").FindString(lines[2])
|
|
||||||
}
|
|
||||||
|
|
||||||
if lines[1] == "emacs" {
|
|
||||||
return "emacs", regexp.MustCompile("([0-9]+\\.[0-9]+)").FindString(lines[2])
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines[1], regexp.MustCompile("([0-9]+\\.[0-9]+\\.[0-9]+)").FindString(s)
|
|
||||||
}
|
|
|
@ -0,0 +1,903 @@
|
||||||
|
{
|
||||||
|
"name": "api",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-validator": "^6.9.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "1.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||||
|
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "~2.1.24",
|
||||||
|
"negotiator": "0.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/array-flatten": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "1.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||||
|
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.0",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"http-errors": "1.7.2",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"qs": "6.7.0",
|
||||||
|
"raw-body": "2.4.0",
|
||||||
|
"type-is": "~1.6.17"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "0.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||||
|
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "5.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/depd": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/destroy": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
|
},
|
||||||
|
"node_modules/ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||||
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "4.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||||
|
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "~1.3.7",
|
||||||
|
"array-flatten": "1.1.1",
|
||||||
|
"body-parser": "1.19.0",
|
||||||
|
"content-disposition": "0.5.3",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"cookie": "0.4.0",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"finalhandler": "~1.1.2",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"merge-descriptors": "1.0.1",
|
||||||
|
"methods": "~1.1.2",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"path-to-regexp": "0.1.7",
|
||||||
|
"proxy-addr": "~2.0.5",
|
||||||
|
"qs": "6.7.0",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"safe-buffer": "5.1.2",
|
||||||
|
"send": "0.17.1",
|
||||||
|
"serve-static": "1.14.1",
|
||||||
|
"setprototypeof": "1.1.1",
|
||||||
|
"statuses": "~1.5.0",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"utils-merge": "1.0.1",
|
||||||
|
"vary": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-validator": {
|
||||||
|
"version": "6.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.9.2.tgz",
|
||||||
|
"integrity": "sha512-Yqlsw2/uBobtBVkP+gnds8OMmVAEb3uTI4uXC93l0Ym5JGHgr8Vd4ws7oSo7GGYpWn5YCq4UePMEppKchURXrw==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.20",
|
||||||
|
"validator": "^13.5.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"statuses": "~1.5.0",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/forwarded": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-errors": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.1.1",
|
||||||
|
"statuses": ">= 1.5.0 < 2",
|
||||||
|
"toidentifier": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.4.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"node_modules/ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||||
|
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||||
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
|
},
|
||||||
|
"node_modules/methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||||
|
"bin": {
|
||||||
|
"mime": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.45.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||||
|
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||||
|
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.45.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/on-finished": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
|
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||||
|
},
|
||||||
|
"node_modules/proxy-addr": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "~0.1.2",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.0",
|
||||||
|
"http-errors": "1.7.2",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "0.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||||
|
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"destroy": "~1.0.4",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "~1.7.2",
|
||||||
|
"mime": "1.6.0",
|
||||||
|
"ms": "2.1.1",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"statuses": "~1.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/ms": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"send": "0.17.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||||
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
|
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/toidentifier": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "1.6.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||||
|
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "~2.1.24"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/utils-merge": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/validator": {
|
||||||
|
"version": "13.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz",
|
||||||
|
"integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||||
|
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "~2.1.24",
|
||||||
|
"negotiator": "0.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"array-flatten": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
|
},
|
||||||
|
"body-parser": {
|
||||||
|
"version": "1.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||||
|
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||||
|
"requires": {
|
||||||
|
"bytes": "3.1.0",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"http-errors": "1.7.2",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"qs": "6.7.0",
|
||||||
|
"raw-body": "2.4.0",
|
||||||
|
"type-is": "~1.6.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bytes": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||||
|
},
|
||||||
|
"content-disposition": {
|
||||||
|
"version": "0.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||||
|
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content-type": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||||
|
},
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||||
|
},
|
||||||
|
"cookie-signature": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"depd": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||||
|
},
|
||||||
|
"destroy": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
|
},
|
||||||
|
"ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
|
},
|
||||||
|
"encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
|
},
|
||||||
|
"escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||||
|
},
|
||||||
|
"etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||||
|
},
|
||||||
|
"express": {
|
||||||
|
"version": "4.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||||
|
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "~1.3.7",
|
||||||
|
"array-flatten": "1.1.1",
|
||||||
|
"body-parser": "1.19.0",
|
||||||
|
"content-disposition": "0.5.3",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"cookie": "0.4.0",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"finalhandler": "~1.1.2",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"merge-descriptors": "1.0.1",
|
||||||
|
"methods": "~1.1.2",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"path-to-regexp": "0.1.7",
|
||||||
|
"proxy-addr": "~2.0.5",
|
||||||
|
"qs": "6.7.0",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"safe-buffer": "5.1.2",
|
||||||
|
"send": "0.17.1",
|
||||||
|
"serve-static": "1.14.1",
|
||||||
|
"setprototypeof": "1.1.1",
|
||||||
|
"statuses": "~1.5.0",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"utils-merge": "1.0.1",
|
||||||
|
"vary": "~1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"express-validator": {
|
||||||
|
"version": "6.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.9.2.tgz",
|
||||||
|
"integrity": "sha512-Yqlsw2/uBobtBVkP+gnds8OMmVAEb3uTI4uXC93l0Ym5JGHgr8Vd4ws7oSo7GGYpWn5YCq4UePMEppKchURXrw==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.20",
|
||||||
|
"validator": "^13.5.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"finalhandler": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"statuses": "~1.5.0",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"forwarded": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||||
|
},
|
||||||
|
"fresh": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||||
|
},
|
||||||
|
"http-errors": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||||
|
"requires": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.1.1",
|
||||||
|
"statuses": ">= 1.5.0 < 2",
|
||||||
|
"toidentifier": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"iconv-lite": {
|
||||||
|
"version": "0.4.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
|
"requires": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||||
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||||
|
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||||
|
},
|
||||||
|
"media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||||
|
},
|
||||||
|
"merge-descriptors": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
|
},
|
||||||
|
"methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||||
|
},
|
||||||
|
"mime": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.45.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||||
|
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w=="
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||||
|
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "1.45.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
},
|
||||||
|
"negotiator": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||||
|
},
|
||||||
|
"on-finished": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
|
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||||
|
"requires": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||||
|
},
|
||||||
|
"path-to-regexp": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||||
|
},
|
||||||
|
"proxy-addr": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||||
|
"requires": {
|
||||||
|
"forwarded": "~0.1.2",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||||
|
},
|
||||||
|
"range-parser": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||||
|
},
|
||||||
|
"raw-body": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||||
|
"requires": {
|
||||||
|
"bytes": "3.1.0",
|
||||||
|
"http-errors": "1.7.2",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
},
|
||||||
|
"safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
|
},
|
||||||
|
"send": {
|
||||||
|
"version": "0.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||||
|
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"destroy": "~1.0.4",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "~1.7.2",
|
||||||
|
"mime": "1.6.0",
|
||||||
|
"ms": "2.1.1",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"statuses": "~1.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve-static": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||||
|
"requires": {
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"send": "0.17.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"setprototypeof": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||||
|
},
|
||||||
|
"statuses": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
|
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||||
|
},
|
||||||
|
"toidentifier": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||||
|
},
|
||||||
|
"type-is": {
|
||||||
|
"version": "1.6.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||||
|
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||||
|
"requires": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "~2.1.24"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||||
|
},
|
||||||
|
"utils-merge": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||||
|
},
|
||||||
|
"validator": {
|
||||||
|
"version": "13.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz",
|
||||||
|
"integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ=="
|
||||||
|
},
|
||||||
|
"vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "api",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-validator": "^6.9.2"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
const express = require('express');
|
||||||
|
const { execute } = require('../../shared/execute');
|
||||||
|
const { languages } = require('./languages');
|
||||||
|
const { checkSchema, validationResult } = require('express-validator');
|
||||||
|
|
||||||
|
const PORT = 2000;
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
'/execute',
|
||||||
|
checkSchema({
|
||||||
|
language: {
|
||||||
|
in: 'body',
|
||||||
|
notEmpty: {
|
||||||
|
errorMessage: 'No language supplied',
|
||||||
|
},
|
||||||
|
isString: {
|
||||||
|
errorMessage: 'Supplied language is not a string',
|
||||||
|
},
|
||||||
|
custom: {
|
||||||
|
options: value => value && languages.find(language => language.aliases.includes(value.toLowerCase())),
|
||||||
|
errorMessage: 'Supplied language is not supported by Piston',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
in: 'body',
|
||||||
|
notEmpty: {
|
||||||
|
errorMessage: 'No source supplied',
|
||||||
|
},
|
||||||
|
isString: {
|
||||||
|
errorMessage: 'Supplied source is not a string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
in: 'body',
|
||||||
|
optional: true,
|
||||||
|
isArray: {
|
||||||
|
errorMessage: 'Supplied args is not an array',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stdin: {
|
||||||
|
in: 'body',
|
||||||
|
optional: true,
|
||||||
|
isString: {
|
||||||
|
errorMessage: 'Supplied stdin is not a string',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
async (req, res) => {
|
||||||
|
const errors = validationResult(req).array();
|
||||||
|
|
||||||
|
if (errors.length === 0) {
|
||||||
|
const language = languages.find(language =>
|
||||||
|
language.aliases.includes(req.body.language.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
const { stdout, stderr, output, ran } = await execute(language, req.body.source, req.body.stdin, req.body.args);
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
ran,
|
||||||
|
language: language.name,
|
||||||
|
version: language.version,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
output,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.status(400).json({
|
||||||
|
message: errors[0].msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get('/versions', (_, res) => res.json(languages));
|
||||||
|
|
||||||
|
app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
|
|
@ -0,0 +1,39 @@
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
const languages = require('../../shared/languages.json');
|
||||||
|
|
||||||
|
{
|
||||||
|
const process = spawn(__dirname + '/../../lxc/versions');
|
||||||
|
|
||||||
|
let output = '';
|
||||||
|
process.stderr.on('data', chunk => output += chunk);
|
||||||
|
process.stdout.on('data', chunk => output += chunk);
|
||||||
|
|
||||||
|
process.on('exit', () => {
|
||||||
|
const sections = output.toLowerCase().split('---');
|
||||||
|
const versions = {};
|
||||||
|
|
||||||
|
for (const section of sections) {
|
||||||
|
const lines = section.trim().split('\n');
|
||||||
|
|
||||||
|
if (lines.length >= 2) {
|
||||||
|
const language = lines[0];
|
||||||
|
|
||||||
|
if (language === 'java') {
|
||||||
|
versions[language] = /\d+/.exec(lines[1])?.[0];
|
||||||
|
} else if (language === 'emacs') {
|
||||||
|
versions[language] = /\d+\.\d+/.exec(lines[1])?.[0];
|
||||||
|
} else {
|
||||||
|
versions[language] = /\d+\.\d+\.\d+/.exec(section)?.[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const language of languages) {
|
||||||
|
language.version = versions[language.name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
languages,
|
||||||
|
};
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
go run main.go $*
|
node src
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { execute } = require('../shared/execute');
|
||||||
|
const { readFileSync } = require('fs');
|
||||||
|
const languages = require('../shared/languages.json');
|
||||||
|
|
||||||
|
const [languageName, sourceFile, ...args] = process.argv.slice(2);
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
if (!languageName) {
|
||||||
|
console.error('Provide a language name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sourceFile) {
|
||||||
|
console.error('Provide a source file');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = readFileSync(sourceFile).toString();
|
||||||
|
|
||||||
|
const language = languages.find(language => language.aliases.includes(languageName.toLowerCase()));
|
||||||
|
|
||||||
|
if (!language) {
|
||||||
|
console.error(`${languageName} is not supported by Piston`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { output } = await execute(language, source, '', args);
|
||||||
|
|
||||||
|
console.log(output);
|
||||||
|
})();
|
130
lxc/execute
130
lxc/execute
|
@ -4,11 +4,7 @@ dir="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
|
||||||
touch $dir/lockfile
|
touch $dir/lockfile
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||||
echo "invalid args"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if [ -z "$2" ]; then
|
|
||||||
echo "invalid args"
|
echo "invalid args"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
@ -18,13 +14,15 @@ epoch=$(date +%s%N)
|
||||||
basepath="/var/lib/lxc/piston/rootfs"
|
basepath="/var/lib/lxc/piston/rootfs"
|
||||||
filepath="/tmp/$epoch/code.code"
|
filepath="/tmp/$epoch/code.code"
|
||||||
argpath="/tmp/$epoch/args.args"
|
argpath="/tmp/$epoch/args.args"
|
||||||
|
stdinpath="/tmp/$epoch/stdin.stdin"
|
||||||
arg=$(basename $argpath)
|
arg=$(basename $argpath)
|
||||||
|
|
||||||
# write arg file
|
# write arg file
|
||||||
mkdir -p $basepath/tmp/$epoch
|
mkdir -p $basepath/tmp/$epoch
|
||||||
chmod 777 $basepath/tmp/$epoch
|
chmod 777 $basepath/tmp/$epoch
|
||||||
cat $2 > $basepath$filepath
|
cat $2 > $basepath$filepath
|
||||||
echo "${@:3}" > $basepath$argpath
|
echo $3 > $basepath$stdinpath
|
||||||
|
echo -n "${@:4}" > $basepath$argpath
|
||||||
|
|
||||||
# process incrementor
|
# process incrementor
|
||||||
exec 200>$dir/lockfile
|
exec 200>$dir/lockfile
|
||||||
|
@ -40,116 +38,24 @@ else
|
||||||
fi
|
fi
|
||||||
exec 200>&-
|
exec 200>&-
|
||||||
|
|
||||||
bin=
|
|
||||||
case "$lang" in
|
|
||||||
"awk")
|
|
||||||
bin=awk
|
|
||||||
;;
|
|
||||||
"bash")
|
|
||||||
bin=bash
|
|
||||||
;;
|
|
||||||
"brainfuck" | "bf")
|
|
||||||
bin=brainfuck
|
|
||||||
;;
|
|
||||||
"c")
|
|
||||||
bin=c
|
|
||||||
;;
|
|
||||||
"cpp" | "c++")
|
|
||||||
bin=cpp
|
|
||||||
;;
|
|
||||||
"csharp" | "cs" | "c#")
|
|
||||||
bin=csharp
|
|
||||||
;;
|
|
||||||
"d")
|
|
||||||
bin=d
|
|
||||||
;;
|
|
||||||
"elixir" | "exs")
|
|
||||||
bin=elixir
|
|
||||||
;;
|
|
||||||
"go")
|
|
||||||
bin=go
|
|
||||||
;;
|
|
||||||
"haskell" | "hs")
|
|
||||||
bin=haskell
|
|
||||||
;;
|
|
||||||
"java")
|
|
||||||
bin=java
|
|
||||||
;;
|
|
||||||
"jelly")
|
|
||||||
bin=jelly
|
|
||||||
;;
|
|
||||||
"julia" | "jl")
|
|
||||||
bin=julia
|
|
||||||
;;
|
|
||||||
"kotlin")
|
|
||||||
bin=kotlin
|
|
||||||
;;
|
|
||||||
"lua")
|
|
||||||
bin=lua
|
|
||||||
;;
|
|
||||||
"nasm" | "asm")
|
|
||||||
bin=nasm
|
|
||||||
;;
|
|
||||||
"nasm64" | "asm64")
|
|
||||||
bin=nasm64
|
|
||||||
;;
|
|
||||||
"nim")
|
|
||||||
bin=nim
|
|
||||||
;;
|
|
||||||
"node" | "js" | "javascript")
|
|
||||||
bin=node
|
|
||||||
;;
|
|
||||||
"deno" | "denojs" | "denots")
|
|
||||||
bin=deno
|
|
||||||
;;
|
|
||||||
"paradoc")
|
|
||||||
bin=paradoc
|
|
||||||
;;
|
|
||||||
"perl")
|
|
||||||
bin=perl
|
|
||||||
;;
|
|
||||||
"php")
|
|
||||||
bin=php
|
|
||||||
;;
|
|
||||||
"python2")
|
|
||||||
bin=python2
|
|
||||||
;;
|
|
||||||
"python3" | "python")
|
|
||||||
bin=python3
|
|
||||||
;;
|
|
||||||
"ruby")
|
|
||||||
bin=ruby
|
|
||||||
;;
|
|
||||||
"rust")
|
|
||||||
bin=rust
|
|
||||||
;;
|
|
||||||
"swift")
|
|
||||||
bin=swift
|
|
||||||
;;
|
|
||||||
"emacs" | "elisp" | "el")
|
|
||||||
bin=emacs
|
|
||||||
;;
|
|
||||||
"bash")
|
|
||||||
bin=bash
|
|
||||||
;;
|
|
||||||
"typescript" | "ts")
|
|
||||||
bin=typescript
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "invalid language"
|
|
||||||
exit
|
|
||||||
esac
|
|
||||||
|
|
||||||
# runner
|
# runner
|
||||||
timeout -s KILL 10 \
|
timeout -s KILL 20 \
|
||||||
lxc-attach --clear-env -n piston -- \
|
lxc-attach --clear-env -n piston -- \
|
||||||
/bin/bash -l -c "bash /exec/$bin $newinc $epoch 2>&1 | head -c 65536"
|
/bin/bash -l -c "runuser runner$newinc /exec/$lang $newinc $epoch"
|
||||||
|
|
||||||
# process janitor
|
# process janitor
|
||||||
lxc-attach --clear-env -n piston -- \
|
lxc-attach --clear-env -n piston -- \
|
||||||
/bin/bash -l -c "\
|
/bin/bash -l -c "
|
||||||
for i in {1..100}; do pkill -u runner$newinc --signal SIGKILL; done ;\
|
for i in {1..100}
|
||||||
find /tmp -user runner$newinc -exec /bin/rm -rf {} \;\
|
do
|
||||||
" > /dev/null 2>&1 &
|
pkill -u runner$newinc --signal SIGKILL
|
||||||
|
done
|
||||||
|
|
||||||
|
find /tmp -user runner$newinc -delete
|
||||||
|
find /var/tmp -user runner$newinc -delete
|
||||||
|
find /var/lock -user runner$newinc -delete
|
||||||
|
find /dev/shm -user runner$newinc -delete
|
||||||
|
find /run/lock -user runner$newinc -delete
|
||||||
|
" > /dev/null 2>&1 &
|
||||||
|
|
||||||
rm -rf $basepath/tmp/$epoch
|
rm -rf $basepath/tmp/$epoch
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 2 sed "/___code___/Q" code.code > code.stdin
|
timeout -s KILL 3 xargs -a args.args -d '\n' awk -f code.code < stdin.stdin
|
||||||
timeout -s KILL 2 sed "1,/___code___/d" code.code > code.awk
|
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; timeout -s KILL 3 awk -f code.awk < code.stdin"
|
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 bash code.code"
|
xargs -a args.args -d '\n' timeout -s KILL 3 bash code.code < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 brainfuck code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' brainfuck code.code < stdin.stdin
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 10 gcc -std=c11 -o binary -x c code.code
|
gcc -std=c11 -o binary -x c code.code
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./binary"
|
timeout -s KILL 3 xargs -a args.args ./binary < stdin.stdin
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 10 g++ -std=c++17 -o binary -x c++ code.code
|
g++ -std=c++17 -o binary -x c++ code.code
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./binary"
|
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 10 mcs $(echo code.code | sed 's/\///') -nowarn:0219 -out:binary
|
mcs $(echo code.code | sed 's/\///') -nowarn:0219 -out:binary
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 mono binary"
|
timeout -s KILL 3 xargs -a args.args -d '\n' mono binary < stdin.stdin
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
cp code.code code.d
|
cp code.code code.d
|
||||||
timeout -s KILL 10 dmd code.d
|
timeout -s KILL 10 dmd code.d
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./code"
|
xtimeout -s KILL 3 args -a args.args -d '\n' ./code
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
cd /tmp/$2
|
#!/bin/bash
|
||||||
|
|
||||||
if [[ -z $(grep '[^[:space:]]' args.args) ]]; then
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; timeout -s KILL 3 deno run code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' deno run code.code < stdin.stdin
|
||||||
else
|
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 deno run code.code"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
cd /tmp/$2
|
#!/bin/bash
|
||||||
|
|
||||||
if [[ -z $(grep '[^[:space:]]' args.args) ]]; then
|
export LC_ALL="en_US.UTF-8"
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; timeout -s KILL 3 elixir code.code"
|
|
||||||
else
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args ; xargs -d '\n' timeout -s KILL 3 elixir code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' elixir code.code < stdin.stdin
|
||||||
fi
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
cd /tmp/$2
|
#!/bin/bash
|
||||||
|
|
||||||
if [[ -z $(grep '[^[:space:]]' args.args) ]]; then
|
cd /tmp/$2
|
||||||
runuser -l runner$1 -c "cd /tmp/$2 ; timeout -s KILL 3 emacs -Q --script code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' emacs -Q --script code.code < stdin.stdin
|
||||||
else
|
|
||||||
runuser -l runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 emacs -Q --script code.code"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
cp code.code interim.go
|
cp code.code interim.go
|
||||||
file="interim.go"
|
go build interim.go
|
||||||
timeout -s KILL 10 go build $file
|
timeout -s KILL 3 xargs -a args.args -d '\n' ./interim < stdin.stdin
|
||||||
file=${file%%.*}
|
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./$file"
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
mv code.code code.hs
|
cp code.code code.hs
|
||||||
timeout -s KILL 10 ghc -dynamic -o binary code.hs > /dev/null 2>&1
|
ghc -dynamic -o binary code.hs > /dev/null 2>&1
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./binary"
|
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
cp code.code interim.java
|
name=$(grep -Po "(?<=\n|\A)\s*(public\s+)?(class|interface)\s+\K([^\/\\\\\n\s{]+)" code.code)
|
||||||
name=$(grep -Po "(?<=\n|\A)\s*(public\s+)?(class|interface)\s+\K([^\n\s{]+)" interim.java)
|
cp code.code $name.java
|
||||||
mv interim.java $name.java
|
javac $name.java
|
||||||
timeout -s KILL 10 javac $name.java
|
timeout -s KILL 3 xargs -a args.args -d '\n' java $name < stdin.stdin
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 java $name"
|
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 jelly fu code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' jelly fu code.code < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 julia code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' julia code.code < stdin.stdin
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
cp code.code code.kt
|
cp code.code code.kt
|
||||||
timeout -s KILL 10 kotlinc code.kt -include-runtime -d code.jar
|
kotlinc code.kt -include-runtime -d code.jar
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 java -jar code.jar"
|
timeout -s KILL 3 xargs -a args.args -d '\n' java -jar code.jar < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 lua code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' lua code.code < stdin.stdin
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 10 nasm -f elf32 -o binary.o code.code
|
nasm -f elf32 -o binary.o code.code
|
||||||
timeout -s KILL 10 ld -m elf_i386 binary.o -o binary
|
ld -m elf_i386 binary.o -o binary
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./binary"
|
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 10 nasm -f elf64 -o binary.o code.code
|
nasm -f elf64 -o binary.o code.code
|
||||||
timeout -s KILL 10 ld -m elf_x86_64 binary.o -o binary
|
ld -m elf_x86_64 binary.o -o binary
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./binary"
|
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
cd /tmp/$2
|
|
||||||
timeout -s KILL 10 nim --hints:off c code.code
|
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./code"
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
cd /tmp/$2
|
#!/bin/bash
|
||||||
|
|
||||||
if [[ -z $(grep '[^[:space:]]' args.args) ]]; then
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; timeout -s KILL 3 node code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' node code.code < stdin.stdin
|
||||||
else
|
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 node code.code"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; timeout -s KILL 3 python3 -m paradoc code.code <<< args.args"
|
export PYTHONPATH=$PYTHONPATH:/opt/paradoc
|
||||||
|
timeout -s KILL 3 python3.8 -m paradoc code.code < args.args
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 perl code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' perl code.code < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 php code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' php code.code < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 python code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' python code.code < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 python3.8 code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' python3.8 code.code < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ruby code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' ruby code.code < stdin.stdin
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
timeout -s KILL 10 rustc -o binary code.code
|
rustc -o binary code.code
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 ./binary"
|
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 swift code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' swift code.code < stdin.stdin
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
cd /tmp/$2
|
cd /tmp/$2
|
||||||
mv code.code interim.ts
|
mv code.code interim.ts
|
||||||
timeout -s KILL 10 tsc interim.ts
|
tsc interim.ts
|
||||||
rm interim.ts
|
rm -f interim.ts
|
||||||
mv interim.js code.code
|
mv interim.js code.code
|
||||||
runuser runner$1 -c "cd /tmp/$2 ; cat args.args | xargs -d '\n' timeout -s KILL 3 node code.code"
|
timeout -s KILL 3 xargs -a args.args -d '\n' node code.code < stdin.stdin
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
mkdir -p /var/lib/lxc/piston/rootfs/exec
|
mkdir -p /var/lib/lxc/piston/rootfs/exec
|
||||||
rm -f /var/lib/lxc/piston/rootfs/exec/*
|
rm -f /var/lib/lxc/piston/rootfs/exec/*
|
||||||
cp -f executors/* /var/lib/lxc/piston/rootfs/exec
|
cp -f executors/* /var/lib/lxc/piston/rootfs/exec
|
||||||
chmod 700 /var/lib/lxc/piston/rootfs/exec/*
|
chmod 555 /var/lib/lxc/piston/rootfs/exec/*
|
||||||
chown -R root:root /var/lib/lxc/piston/rootfs/exec
|
chown -R root:root /var/lib/lxc/piston/rootfs/exec
|
||||||
|
|
||||||
lxc-start -n piston -d
|
lxc-start -n piston -d
|
||||||
|
|
108
lxc/test_all_lxc
108
lxc/test_all_lxc
|
@ -1,57 +1,57 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
cd tests
|
cd tests
|
||||||
|
|
||||||
echo 'testing awk'
|
echo -n 'testing awk = '
|
||||||
../execute awk test.awk
|
../../cli/execute awk awk.awk
|
||||||
echo 'testing c'
|
echo -n 'testing bash = '
|
||||||
../execute c test.c
|
../../cli/execute bash bash.sh
|
||||||
echo 'testing cpp'
|
echo -n 'testing c = '
|
||||||
../execute cpp test.cpp
|
../../cli/execute c c.c
|
||||||
echo 'testing cs'
|
echo -n 'testing cpp = '
|
||||||
../execute cs test.cs
|
../../cli/execute cpp cpp.cpp
|
||||||
echo 'testing d'
|
echo -n 'testing csharp = '
|
||||||
../execute d test.d
|
../../cli/execute csharp csharp.cs
|
||||||
echo 'testing deno ts'
|
echo -n 'testing d = '
|
||||||
../execute deno testdeno.ts
|
../../cli/execute d test.d
|
||||||
echo 'testing elisp'
|
echo -n 'testing deno = '
|
||||||
../execute elisp test.el
|
../../cli/execute deno deno.ts
|
||||||
echo 'testing elixir'
|
echo -n 'testing elixir = '
|
||||||
../execute exs test.exs
|
../../cli/execute elixir elixir.exs
|
||||||
echo 'testing go'
|
echo -n 'testing emacs = '
|
||||||
../execute go test.go
|
../../cli/execute emacs emacs.el
|
||||||
echo 'testing haskell'
|
echo -n 'testing go = '
|
||||||
../execute haskell test.hs
|
../../cli/execute go go.go
|
||||||
echo 'testing java'
|
echo -n 'testing haskell = '
|
||||||
../execute java test.java
|
../../cli/execute haskell haskell.hs
|
||||||
echo 'testing jl'
|
echo -n 'testing java = '
|
||||||
../execute jl test.jl
|
../../cli/execute java java.java
|
||||||
echo 'testing js'
|
echo -n 'testing jelly = '
|
||||||
../execute js test.js
|
../../cli/execute jelly jelly.jelly good
|
||||||
echo 'testing kotlin'
|
echo -n 'testing julia = '
|
||||||
../execute kotlin test.kt
|
../../cli/execute julia julia.jl
|
||||||
echo 'testing asm 32 bit'
|
echo -n 'testing kotlin = '
|
||||||
../execute asm test.nasm
|
../../cli/execute kotlin kotlin.kt
|
||||||
echo 'testing asm 64 bit'
|
echo -n 'testing nasm 32 bit = '
|
||||||
../execute asm64 test64.nasm
|
../../cli/execute nasm nasm.nasm
|
||||||
echo 'testing nim'
|
echo -n 'testing nasm 64 bit = '
|
||||||
../execute nim test.nim
|
../../cli/execute nasm64 nasm64.nasm
|
||||||
echo 'testing php'
|
echo -n 'testing node = '
|
||||||
../execute php test.php
|
../../cli/execute node node.js
|
||||||
echo 'testing perl'
|
echo -n 'testing paradoc = '
|
||||||
../execute perl test.pl
|
../../cli/execute bash paradoc.sh
|
||||||
echo 'testing ruby'
|
echo -n 'testing perl = '
|
||||||
../execute ruby test.rb
|
../../cli/execute perl perl.pl
|
||||||
echo 'testing rust'
|
echo -n 'testing php = '
|
||||||
../execute rust test.rs
|
../../cli/execute php php.php
|
||||||
echo 'testing bash'
|
echo -n 'testing python2 = '
|
||||||
../execute bash test.sh
|
../../cli/execute python2 python2.py
|
||||||
echo 'testing swift'
|
echo -n 'testing python3 = '
|
||||||
../execute swift test.swift
|
../../cli/execute python3 python3.py
|
||||||
echo 'testing typescript'
|
echo -n 'testing ruby = '
|
||||||
../execute typescript test.ts
|
../../cli/execute ruby ruby.rb
|
||||||
echo 'testing python2'
|
echo -n 'testing rust = '
|
||||||
../execute python2 test2.py
|
../../cli/execute rust rust.rs
|
||||||
echo 'testing python3'
|
echo -n 'testing swift = '
|
||||||
../execute python3 test3.py
|
../../cli/execute swift swift.swift
|
||||||
echo 'testing paradoc'
|
echo -n 'testing typescript = '
|
||||||
../execute python3 test_paradoc.py
|
../../cli/execute typescript typescript.ts
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{ print "good" }
|
|
@ -0,0 +1 @@
|
||||||
|
³
|
|
@ -0,0 +1,3 @@
|
||||||
|
fun main() {
|
||||||
|
println("good")
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
SECTION .data
|
||||||
|
good: db "good", 0x0
|
||||||
|
txtlen: equ $ - good
|
||||||
|
|
||||||
|
SECTION .text
|
||||||
|
GLOBAL _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
;sys_write
|
||||||
|
mov rax, 1
|
||||||
|
mov rdi, 1
|
||||||
|
mov rsi, good
|
||||||
|
mov rdx, txtlen
|
||||||
|
syscall
|
||||||
|
;sys_exit
|
||||||
|
mov rax, 60
|
||||||
|
mov rdi, 0
|
||||||
|
syscall
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# add paradoc module to python python
|
||||||
|
export PYTHONPATH=$PYTHONPATH:/opt/paradoc
|
||||||
|
# file for test code
|
||||||
|
test_code=/tmp/paradoc.test
|
||||||
|
# save test code to file
|
||||||
|
echo -n iP>$test_code
|
||||||
|
# pass param to paradoc module and have it print it
|
||||||
|
echo good | python3.8 -m paradoc $test_code
|
||||||
|
# clean test code
|
||||||
|
rm -f $test_code
|
|
@ -1,3 +0,0 @@
|
||||||
good
|
|
||||||
___code___
|
|
||||||
{ print }
|
|
|
@ -1,3 +0,0 @@
|
||||||
fun main(args: Array<String>) {
|
|
||||||
println("good")
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
SECTION .data
|
|
||||||
good: db "good", 0x0a, 0x0
|
|
||||||
txtlen: equ $ - good
|
|
||||||
|
|
||||||
SECTION .text
|
|
||||||
GLOBAL _start
|
|
||||||
|
|
||||||
_start:
|
|
||||||
;sys_write
|
|
||||||
mov rax, 1
|
|
||||||
mov rdi, 1
|
|
||||||
mov rsi, good
|
|
||||||
mov rdx, txtlen
|
|
||||||
syscall
|
|
||||||
;sys_exit
|
|
||||||
mov rax, 60
|
|
||||||
mov rdi, 0
|
|
||||||
syscall
|
|
|
@ -1,5 +0,0 @@
|
||||||
try:
|
|
||||||
import paradoc
|
|
||||||
print('good')
|
|
||||||
except:
|
|
||||||
pass
|
|
12
lxc/versions
12
lxc/versions
|
@ -14,11 +14,11 @@ echo '1.0.0'
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'c'
|
echo 'c'
|
||||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "gcc -v"
|
lxc-attach --clear-env -n piston -- /bin/bash -l -c "gcc --version"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'cpp'
|
echo 'cpp'
|
||||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "g++ -v"
|
lxc-attach --clear-env -n piston -- /bin/bash -l -c "g++ --version"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'csharp'
|
echo 'csharp'
|
||||||
|
@ -73,8 +73,8 @@ echo 'nasm'
|
||||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nasm -version"
|
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nasm -version"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'nim'
|
echo 'nasm64'
|
||||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nim -v | head -n1"
|
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nasm -version"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'node'
|
echo 'node'
|
||||||
|
@ -94,11 +94,11 @@ lxc-attach --clear-env -n piston -- /bin/bash -l -c "python -V"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'python3'
|
echo 'python3'
|
||||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python3 -V"
|
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python3.8 -V"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'paradoc'
|
echo 'paradoc'
|
||||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python3 -m paradoc --version"
|
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python3.8 -m paradoc --version"
|
||||||
echo '---'
|
echo '---'
|
||||||
|
|
||||||
echo 'ruby'
|
echo 'ruby'
|
||||||
|
|
547
readme.md
547
readme.md
|
@ -1,348 +1,220 @@
|
||||||
## Piston
|
<h1 align="center">
|
||||||
Piston is the underlying engine for running untrusted and possibly malicious
|
<a href="https://github.com/engineer-man/piston"><img src="https://emkc.org/images/icon_circle_24.png" alt="engineer-man piston"></a>
|
||||||
code that originates from EMKC contests and challenges. It's also used in the
|
Piston
|
||||||
Engineer Man Discord server via [I Run Code](https://github.com/engineer-man/piston-bot) bot as well as 1000+ other servers.
|
</h1>
|
||||||
|
|
||||||
|
<h3 align="center">A high performance general purpose code execution engine.</h3>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/ArmynC/ArminC-AutoExec/commits/master">
|
||||||
|
<img src="https://img.shields.io/github/last-commit/engineer-man/piston.svg?style=for-the-badge&logo=github&logoColor=white"
|
||||||
|
alt="GitHub last commit">
|
||||||
|
<a href="https://github.com/engineer-man/piston/issues">
|
||||||
|
<img src="https://img.shields.io/github/issues/engineer-man/piston.svg?style=for-the-badge&logo=github&logoColor=white"
|
||||||
|
alt="GitHub issues">
|
||||||
|
<a href="https://github.com/engineer-man/piston/pulls">
|
||||||
|
<img src="https://img.shields.io/github/issues-pr-raw/engineer-man/piston.svg?style=for-the-badge&logo=github&logoColor=white"
|
||||||
|
alt="GitHub pull requests">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<h4 align="center">
|
||||||
|
<a href="#About">About</a> •
|
||||||
|
<a href="#Public-API">Public API</a> •
|
||||||
|
<a href="#Getting-Started">Getting Started</a> •
|
||||||
|
<a href="#Usage">Usage</a> •
|
||||||
|
<a href="#Supported-Languages">Supported Languages</a> •
|
||||||
|
<a href="#Principle-of-Operation">Principles</a> •
|
||||||
|
<a href="#Security">Security</a> •
|
||||||
|
<a href="#License">License</a>
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
---
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# About
|
||||||
|
|
||||||
|
<h4>
|
||||||
|
Piston is a high performance general purpose code execution engine. It excels at running untrusted and
|
||||||
|
possibly malicious code without fear from any harmful effects.
|
||||||
|
</h4>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
It's used in numerous places including:
|
||||||
|
* [EMKC Challenges](https://emkc.org/challenges),
|
||||||
|
* [EMKC Weekly Contests](https://emkc.org/contests),
|
||||||
|
* [Engineer Man Discord Server](https://discord.gg/engineerman),
|
||||||
|
* [I Run Code (Discord Bot)](https://github.com/engineer-man/piston-bot) bot as well as 1300+ other servers
|
||||||
|
and 100+ direct integrations.
|
||||||
|
|
||||||
To get it in your own server, go here: https://emkc.org/run.
|
To get it in your own server, go here: https://emkc.org/run.
|
||||||
|
|
||||||
#### Use Public API (new)
|
<br>
|
||||||
Requires no installation and you can use it immediately. Reference the API Usage section below to learn
|
|
||||||
about the request format but rather than using the local URLs, use the following URLs:
|
|
||||||
- `GET` `https://emkc.org/api/v1/piston/versions`
|
|
||||||
- `POST` `https://emkc.org/api/v1/piston/execute`
|
|
||||||
|
|
||||||
Important Note: The Piston API is rate limited to 5 requests per second
|
# Public API
|
||||||
|
|
||||||
|
- Requires no installation and you can use it immediately.
|
||||||
|
- Reference the Versions/Execute sections below to learn about the request and response formats.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
When using the public Piston API, use the base URL:
|
||||||
|
|
||||||
#### Installation
|
|
||||||
```
|
```
|
||||||
# clone and enter repo
|
https://emkc.org/api/v1/piston
|
||||||
git clone https://github.com/engineer-man/piston
|
```
|
||||||
cd piston/lxc
|
|
||||||
|
|
||||||
# install dependencies
|
#### GET
|
||||||
|
```
|
||||||
|
https://emkc.org/api/v1/piston/versions
|
||||||
|
```
|
||||||
|
#### POST
|
||||||
|
```
|
||||||
|
https://emkc.org/api/v1/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.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# Getting Started
|
||||||
|
|
||||||
|
### Host System Package Dependencies
|
||||||
|
|
||||||
|
* NodeJS
|
||||||
|
* lxc
|
||||||
|
* libvirt
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
If your OS is not documented below, please open pull requests with the correct commands for your OS.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><span style="font-size:1.43em;">CentOS / RHEL</span></summary>
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
||||||
|
nvm install --lts
|
||||||
|
nvm use --lts
|
||||||
|
|
||||||
# centos:
|
|
||||||
yum install -y epel-release
|
yum install -y epel-release
|
||||||
yum install -y lxc lxc-templates debootstrap libvirt
|
yum install -y lxc lxc-templates debootstrap libvirt
|
||||||
systemctl start libvirtd
|
systemctl start libvirtd
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
# ubuntu server 18.04:
|
<details>
|
||||||
apt install lxc lxc-templates debootstrap libvirt0
|
<summary><span style="font-size:1.43em;">Ubuntu (18.04)</span></summary>
|
||||||
|
|
||||||
# arch:
|
```sh
|
||||||
sudo pacman -S lxc libvirt unzip
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
||||||
|
nvm install --lts
|
||||||
|
nvm use --lts
|
||||||
|
|
||||||
# everything else:
|
apt install -y lxc lxc-templates debootstrap libvirt0
|
||||||
# not documented, please open pull requests with commands for debian/arch/macos
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
# create and start container
|
<details>
|
||||||
lxc-create -t download -n piston -- --dist ubuntu --release bionic --arch amd64
|
<summary><span style="font-size:1.43em;">Arch Linux</span></summary>
|
||||||
./start
|
|
||||||
|
|
||||||
# open a shell to the container
|
```sh
|
||||||
./shell
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
||||||
|
nvm install --lts
|
||||||
|
nvm use --lts
|
||||||
|
|
||||||
# install all necessary piston dependencies
|
pacman -S lxc libvirt unzip
|
||||||
echo 'source /opt/.profile' >> /opt/.bashrc
|
```
|
||||||
echo 'export HOME=/opt' >> /opt/.profile
|
</details>
|
||||||
echo 'export TERM=linux' >> /opt/.profile
|
|
||||||
echo 'export PATH=$PATH:/opt/.local/bin' >> /opt/.profile
|
|
||||||
export HOME=/opt
|
|
||||||
export TERM=linux
|
|
||||||
sed -i 's/\/root/\/opt/' /etc/passwd
|
|
||||||
sed -i \
|
|
||||||
's/http:\/\/archive.ubuntu.com\/ubuntu/http:\/\/mirror.math.princeton.edu\/pub\/ubuntu/' \
|
|
||||||
/etc/apt/sources.list
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y \
|
|
||||||
nano wget build-essential pkg-config libxml2-dev \
|
|
||||||
libsqlite3-dev mono-complete curl cmake libpython2.7-dev \
|
|
||||||
ruby libtinfo-dev unzip
|
|
||||||
|
|
||||||
# install python2
|
#### After system dependencies are installed, clone this repository:
|
||||||
# final binary: /opt/python2/Python-2.7.17/python
|
|
||||||
# get version: /opt/python2/Python-2.7.17/python -V
|
|
||||||
cd /opt && mkdir python2 && cd python2
|
|
||||||
wget https://www.python.org/ftp/python/2.7.17/Python-2.7.17.tar.xz
|
|
||||||
unxz Python-2.7.17.tar.xz
|
|
||||||
tar -xf Python-2.7.17.tar
|
|
||||||
cd Python-2.7.17
|
|
||||||
./configure
|
|
||||||
# open Modules/Setup and uncomment zlib line
|
|
||||||
make
|
|
||||||
echo 'export PATH=$PATH:/opt/python2/Python-2.7.17' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install python3
|
```sh
|
||||||
# final binary: /opt/python3/Python-3.8.2/python
|
# clone and enter repo
|
||||||
# get version: /opt/python3/Python-3.8.2/python -V
|
git clone https://github.com/engineer-man/piston
|
||||||
cd /opt && mkdir python3 && cd python3
|
cd piston/lxc
|
||||||
wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz
|
|
||||||
unxz Python-3.8.2.tar.xz
|
|
||||||
tar -xf Python-3.8.2.tar
|
|
||||||
cd Python-3.8.2
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
ln -s python python3.8
|
|
||||||
echo 'export PATH=$PATH:/opt/python3/Python-3.8.2' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install paradoc
|
|
||||||
# this is not a binary, it is a python module
|
|
||||||
# therefore it cannot be run directly as it requires python3 to be installed
|
|
||||||
cd /opt && mkdir paradoc && cd paradoc
|
|
||||||
git clone https://github.com/betaveros/paradoc.git
|
|
||||||
echo 'export PYTHONPATH=$PYTHONPATH:/opt/paradoc/paradoc' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install node.js
|
|
||||||
# final binary: /opt/nodejs/node-v12.16.1-linux-x64/bin/node
|
|
||||||
# get version: /opt/nodejs/node-v12.16.1-linux-x64/bin/node -v
|
|
||||||
cd /opt && mkdir nodejs && cd nodejs
|
|
||||||
wget https://nodejs.org/dist/v12.16.1/node-v12.16.1-linux-x64.tar.xz
|
|
||||||
unxz node-v12.16.1-linux-x64.tar.xz
|
|
||||||
tar -xf node-v12.16.1-linux-x64.tar
|
|
||||||
echo 'export PATH=$PATH:/opt/nodejs/node-v12.16.1-linux-x64/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install typescript
|
|
||||||
# final binary: /opt/nodejs/node-v12.16.1-linux-x64/bin/tsc
|
|
||||||
# get version: /opt/nodejs/node-v12.16.1-linux-x64/bin/tsc -v
|
|
||||||
/opt/nodejs/node-v12.16.1-linux-x64/bin/npm i -g typescript
|
|
||||||
|
|
||||||
# install golang
|
|
||||||
# final binary: /opt/go/go/bin/go
|
|
||||||
# get version: /opt/go/go/bin/go version
|
|
||||||
cd /opt && mkdir go && cd go
|
|
||||||
wget https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz
|
|
||||||
tar -xzf go1.14.1.linux-amd64.tar.gz
|
|
||||||
echo 'export PATH=$PATH:/opt/go/go/bin' >> /opt/.profile
|
|
||||||
echo 'export GOROOT=/opt/go/go' >> /opt/.profile
|
|
||||||
echo 'export GOCACHE=/tmp' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install php
|
|
||||||
# final binary: /usr/local/bin/php
|
|
||||||
# get version: /usr/local/bin/php -v
|
|
||||||
cd /opt && mkdir php && cd php
|
|
||||||
wget https://www.php.net/distributions/php-7.4.4.tar.gz
|
|
||||||
tar -xzf php-7.4.4.tar.gz
|
|
||||||
cd php-7.4.4
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
# install rust
|
|
||||||
# final binary: /opt/.cargo/bin/rustc
|
|
||||||
# get version: /opt/.cargo/bin/rustc --version
|
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
||||||
echo 'export PATH=$PATH:/opt/.cargo/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install swift
|
|
||||||
# final binary: /opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin/swift
|
|
||||||
# get version: /opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin/swift --version
|
|
||||||
cd /opt && mkdir swift && cd swift
|
|
||||||
wget https://swift.org/builds/swift-5.1.5-release/ubuntu1804/swift-5.1.5-RELEASE/swift-5.1.5-RELEASE-ubuntu18.04.tar.gz
|
|
||||||
tar -xzf swift-5.1.5-RELEASE-ubuntu18.04.tar.gz
|
|
||||||
echo 'export PATH=$PATH:/opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install nasm
|
|
||||||
# final binary: /opt/nasm/nasm-2.14.02/nasm
|
|
||||||
# get version: /opt/nasm/nasm-2.14.02/nasm -v
|
|
||||||
cd /opt && mkdir nasm && cd nasm
|
|
||||||
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
|
|
||||||
tar -xzf nasm-2.14.02.tar.gz
|
|
||||||
cd nasm-2.14.02
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
echo 'export PATH=$PATH:/opt/nasm/nasm-2.14.02' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install java
|
|
||||||
# final binary: /opt/java/jdk-14/bin/java
|
|
||||||
# get version: /opt/java/jdk-14/bin/java -version
|
|
||||||
cd /opt && mkdir java && cd java
|
|
||||||
wget https://download.java.net/java/GA/jdk14/076bab302c7b4508975440c56f6cc26a/36/GPL/openjdk-14_linux-x64_bin.tar.gz
|
|
||||||
tar -xzf openjdk-14_linux-x64_bin.tar.gz
|
|
||||||
echo 'export PATH=$PATH:/opt/java/jdk-14/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install jelly
|
|
||||||
cd /opt && mkdir jelly && cd jelly
|
|
||||||
wget https://github.com/DennisMitchell/jellylanguage/archive/master.zip
|
|
||||||
unzip master.zip
|
|
||||||
cd jellylanguage-master
|
|
||||||
pip3.8 install .
|
|
||||||
|
|
||||||
# install julia
|
|
||||||
# final binary: /opt/julia/julia-1.5.0/bin/julia
|
|
||||||
# get version: /opt/julia/julia-1.5.0/bin/julia --version
|
|
||||||
cd /opt && mkdir julia && cd julia
|
|
||||||
wget https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.0-linux-x86_64.tar.gz
|
|
||||||
tar -xzf julia-1.5.0-linux-x86_64.tar.gz
|
|
||||||
echo 'export PATH=$PATH:/opt/julia/julia-1.5.0/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install kotlin
|
|
||||||
# final binary: /opt/kotlinc/bin/kotlinc
|
|
||||||
# get version: /opt/kotlinc/bin/kotlinc -version
|
|
||||||
cd /opt
|
|
||||||
wget https://github.com/JetBrains/kotlin/releases/download/v1.4.10/kotlin-compiler-1.4.10.zip
|
|
||||||
unzip kotlin-compiler-1.4.10.zip
|
|
||||||
rm kotlin-compiler-1.4.10.zip
|
|
||||||
echo 'export PATH=$PATH:/opt/kotlinc/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install elixir and erlang
|
|
||||||
# final binary: /opt/elixir/bin/elixir
|
|
||||||
# get version: /opt/elixir/bin/elixir --version
|
|
||||||
# erlang
|
|
||||||
cd /opt && mkdir erlang && cd erlang
|
|
||||||
wget http://erlang.org/download/otp_src_23.0.tar.gz
|
|
||||||
gunzip -c otp_src_23.0.tar.gz | tar xf -
|
|
||||||
cd otp_src_23.0 && ./configure
|
|
||||||
make
|
|
||||||
echo 'export PATH=$PATH:/opt/erlang/otp_src_23.0/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
# elixir
|
|
||||||
cd /opt && mkdir elixir && cd elixir
|
|
||||||
wget https://github.com/elixir-lang/elixir/releases/download/v1.10.3/Precompiled.zip
|
|
||||||
mkdir elixir-1.10.3 && unzip Precompiled.zip -d elixir-1.10.3/
|
|
||||||
echo 'export PATH=$PATH:/opt/elixir/elixir-1.10.3/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install emacs
|
|
||||||
# final binary: /opt/emacs/emacs-26.3/src/emacs
|
|
||||||
# get version: /opt/emacs/emacs-26.3/src/emacs --version
|
|
||||||
cd /opt && mkdir emacs && cd emacs
|
|
||||||
wget https://mirrors.ocf.berkeley.edu/gnu/emacs/emacs-26.3.tar.xz
|
|
||||||
tar -xf emacs-26.3.tar.xz
|
|
||||||
cd emacs-26.3
|
|
||||||
./configure --with-gnutls=no
|
|
||||||
make
|
|
||||||
echo 'export PATH=$PATH:/opt/emacs/emacs-26.3/src' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install lua
|
|
||||||
# final binary: /opt/lua/lua54/src/lua
|
|
||||||
# get version: /opt/lua/lua54/src/lua -v
|
|
||||||
cd /opt && mkdir lua && cd lua
|
|
||||||
wget https://sourceforge.net/projects/luabinaries/files/5.4.0/Docs%20and%20Sources/lua-5.4.0_Sources.tar.gz/download
|
|
||||||
tar -xzf download
|
|
||||||
cd lua54
|
|
||||||
make
|
|
||||||
echo 'export PATH=$PATH:/opt/lua/lua54/src' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install haskell
|
|
||||||
# final binary: /usr/bin/ghc
|
|
||||||
# get version: /usr/bin/ghc --version
|
|
||||||
apt install -y ghc
|
|
||||||
|
|
||||||
# install deno
|
|
||||||
# final binary: /opt/.deno/bin/deno
|
|
||||||
# get version: /opt/.deno/bin/deno --version
|
|
||||||
cd /opt && mkdir deno && cd deno
|
|
||||||
curl -fsSL https://deno.land/x/install/install.sh | sh
|
|
||||||
echo 'export DENO_INSTALL="/opt/.deno"' >> /opt/.profile
|
|
||||||
echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install nim
|
|
||||||
# final binary: /opt/nim/bin/nim
|
|
||||||
# get version: /opt/nim/bin/nim -v
|
|
||||||
cd /opt && mkdir nim && cd nim
|
|
||||||
wget https://nim-lang.org/download/nim-1.4.0-linux_x64.tar.xz
|
|
||||||
unxz nim-1.4.0-linux_x64.tar.xz
|
|
||||||
tar -xf nim-1.4.0-linux_x64.tar
|
|
||||||
cd nim-1.4.0
|
|
||||||
./install.sh /opt
|
|
||||||
echo 'export PATH=$PATH:/opt/nim/bin' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# install d
|
|
||||||
# final binary: /opt/d/dmd2/linux/bin64/dmd
|
|
||||||
# get version: /opt/d/dmd2/linux/bin64/dmd --version
|
|
||||||
cd /opt && mkdir d && cd d
|
|
||||||
wget http://downloads.dlang.org/releases/2.x/2.095.0/dmd.2.095.0.linux.tar.xz
|
|
||||||
unxz dmd.2.095.0.linux.tar.xz
|
|
||||||
tar -xf dmd.2.095.0.linux.tar
|
|
||||||
echo 'export PATH=$PATH:/opt/d/dmd2/linux/bin64' >> /opt/.profile
|
|
||||||
source /opt/.profile
|
|
||||||
|
|
||||||
# create runnable users and apply limits
|
|
||||||
for i in {1..150}; do
|
|
||||||
useradd -M runner$i
|
|
||||||
usermod -d /tmp runner$i
|
|
||||||
echo "runner$i soft nproc 64" >> /etc/security/limits.conf
|
|
||||||
echo "runner$i hard nproc 64" >> /etc/security/limits.conf
|
|
||||||
echo "runner$i soft nofile 2048" >> /etc/security/limits.conf
|
|
||||||
echo "runner$i hard nofile 2048" >> /etc/security/limits.conf
|
|
||||||
done
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
rm -rf /home/ubuntu
|
|
||||||
chmod 777 /tmp
|
|
||||||
|
|
||||||
# leave container
|
|
||||||
exit
|
|
||||||
|
|
||||||
# optionally run tests
|
|
||||||
cd ../tests
|
|
||||||
./test_all_lxc
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### CLI Usage
|
#### Installation (simple)
|
||||||
- `lxc/execute [language] [file path] [arg]...`
|
|
||||||
|
- Coming soon.
|
||||||
|
|
||||||
|
#### Installation (advanced)
|
||||||
|
|
||||||
|
- See `var/install.txt` for how to create a new LXC container and install all of the required
|
||||||
|
software.
|
||||||
|
|
||||||
|
#### CLI Usage
|
||||||
|
- `cli/execute [language] [file path] [args]`
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lxc/execute [language] [file path] [args]
|
||||||
|
```
|
||||||
|
|
||||||
|
### API
|
||||||
|
To use the API, it must first be started. Please note that if root is required to access
|
||||||
|
LXC then the API must also be running as root. To start the API, run the following:
|
||||||
|
|
||||||
#### API Usage
|
|
||||||
To use the API, it must first be started. To start the API, run the following:
|
|
||||||
```
|
```
|
||||||
cd api
|
cd api
|
||||||
./start
|
./start
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Base URLs
|
For your own local installation, the API is available at:
|
||||||
For your own local installation, use:
|
|
||||||
```
|
```
|
||||||
http://127.0.0.1:2000
|
http://127.0.0.1:2000
|
||||||
```
|
```
|
||||||
When using the public Piston API, use:
|
|
||||||
```
|
|
||||||
https://emkc.org/api/v1/piston
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Versions Endpoint
|
#### Versions Endpoint
|
||||||
`GET /versions`
|
`GET /versions`
|
||||||
This endpoint takes no input and returns a JSON array of the currently installed languages.
|
This endpoint will return the supported languages along with the current version and aliases. To execute
|
||||||
|
code for a particular language using the `/execute` endpoint, either the name or one of the aliases must
|
||||||
Truncated response sample:
|
be provided.
|
||||||
```json
|
```json
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "awk",
|
"name": "awk",
|
||||||
|
"aliases": ["awk"],
|
||||||
"version": "1.3.3"
|
"version": "1.3.3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "bash",
|
"name": "bash",
|
||||||
|
"aliases": ["bash"],
|
||||||
"version": "4.4.20"
|
"version": "4.4.20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "c",
|
"name": "c",
|
||||||
|
"aliases": ["c"],
|
||||||
"version": "7.5.0"
|
"version": "7.5.0"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Execution Endpoint
|
#### Execute Endpoint
|
||||||
`POST /execute`
|
`POST /execute`
|
||||||
This endpoint takes the following JSON payload and expects at least the language and source. If
|
This endpoint requests execution of some arbitrary code.
|
||||||
source is not provided, a blank file is passed as the source.
|
- `language` (**required**) The language to use for execution, must be a string and supported by Piston (see list below).
|
||||||
|
- `source` (**required**) The source code to execute, must be a string.
|
||||||
|
- `stdin` (*optional*) The text to pass as stdin to the program. Must be a string or left out of the request.
|
||||||
|
- `args` (*optional*) The arguments to pass to the program. Must be an array or left out of the request.
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"language": "js",
|
"language": "js",
|
||||||
"source": "console.log(process.argv)",
|
"source": "console.log(process.argv)",
|
||||||
|
"stdin": "",
|
||||||
"args": [
|
"args": [
|
||||||
"1",
|
"1",
|
||||||
"2",
|
"2",
|
||||||
|
@ -350,58 +222,76 @@ source is not provided, a blank file is passed as the source.
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
A typical response when everything succeeds will be similar to the following:
|
A typical response upon successful execution will contain the `language`, `version`, `output` which
|
||||||
|
is a combination of both `stdout` and `stderr` but in chronological order according to program output,
|
||||||
|
as well as separate `stdout` and `stderr`.
|
||||||
```json
|
```json
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"ran": true,
|
"ran": true,
|
||||||
"language": "js",
|
"language": "js",
|
||||||
"version": "12.13.0",
|
"version": "12.13.0",
|
||||||
"output": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]"
|
"output": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]",
|
||||||
|
"stdout": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]",
|
||||||
|
"stderr": ""
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
If an invalid language is supplied, a typical response will look like the following:
|
If a problem exists with the request, a `400` status code is returned and the reason in the `message` key.
|
||||||
```json
|
```json
|
||||||
|
HTTP/1.1 400 Bad Request
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"code": "unsupported_language",
|
"message": "Supplied language is not supported by Piston"
|
||||||
"message": "whatever is not supported by Piston"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Supported Languages
|
<br>
|
||||||
- awk
|
|
||||||
- bash
|
|
||||||
- c
|
|
||||||
- cpp
|
|
||||||
- csharp
|
|
||||||
- d
|
|
||||||
- deno
|
|
||||||
- elixir
|
|
||||||
- emacs
|
|
||||||
- go
|
|
||||||
- haskell
|
|
||||||
- java
|
|
||||||
- jelly
|
|
||||||
- julia
|
|
||||||
- kotlin
|
|
||||||
- nasm
|
|
||||||
- node
|
|
||||||
- perl
|
|
||||||
- php
|
|
||||||
- python2
|
|
||||||
- python3
|
|
||||||
- paradoc
|
|
||||||
- ruby
|
|
||||||
- rust
|
|
||||||
- swift
|
|
||||||
- typescript
|
|
||||||
|
|
||||||
#### Principle of Operation
|
# Supported Languages
|
||||||
Piston utilizes LXC as the primary mechanism for sandboxing. There is a small API written in Go which takes
|
`awk`,
|
||||||
|
`bash`,
|
||||||
|
`brainfuck`,
|
||||||
|
`c`,
|
||||||
|
`cpp`,
|
||||||
|
`csharp`,
|
||||||
|
`d`,
|
||||||
|
`deno`,
|
||||||
|
`elixir`,
|
||||||
|
`emacs`,
|
||||||
|
`elisp`,
|
||||||
|
`go`,
|
||||||
|
`haskell`,
|
||||||
|
`java`,
|
||||||
|
`jelly`,
|
||||||
|
`julia`,
|
||||||
|
`kotlin`,
|
||||||
|
`lua`,
|
||||||
|
`nasm`,
|
||||||
|
`node`,
|
||||||
|
`paradoc`,
|
||||||
|
`perl`,
|
||||||
|
`php`,
|
||||||
|
`python2`,
|
||||||
|
`python3`,
|
||||||
|
`ruby`,
|
||||||
|
`rust`,
|
||||||
|
`swift`,
|
||||||
|
`typescript`,
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# Principle of Operation
|
||||||
|
Piston utilizes LXC as the primary mechanism for sandboxing. There is a small API written in Node which takes
|
||||||
in execution requests and executes them in the container. High level, the API writes
|
in execution requests and executes them in the container. High level, the API writes
|
||||||
a temporary source and args file to `/tmp` and that gets mounted read-only along with the execution scripts into the container.
|
a temporary source and args file to `/tmp` and that gets mounted read-only along with the execution scripts into the container.
|
||||||
The source file is either ran or compiled and ran (in the case of languages like c, c++, c#, go, etc.).
|
The source file is either ran or compiled and ran (in the case of languages like c, c++, c#, go, etc.).
|
||||||
|
|
||||||
#### Security
|
<br>
|
||||||
|
|
||||||
|
# Security
|
||||||
LXC provides a great deal of security out of the box in that it's separate from the system.
|
LXC provides a great deal of security out of the box in that it's separate from the system.
|
||||||
Piston takes additional steps to make it resistant to
|
Piston takes additional steps to make it resistant to
|
||||||
various privilege escalation, denial-of-service, and resource saturation threats. These steps include:
|
various privilege escalation, denial-of-service, and resource saturation threats. These steps include:
|
||||||
|
@ -409,10 +299,13 @@ various privilege escalation, denial-of-service, and resource saturation threats
|
||||||
- Capping max processes at 64 (resists `:(){ :|: &}:;`, `while True: os.fork()`, etc.)
|
- Capping max processes at 64 (resists `:(){ :|: &}:;`, `while True: os.fork()`, etc.)
|
||||||
- Capping max files at 2048 (resists various file based attacks)
|
- Capping max files at 2048 (resists various file based attacks)
|
||||||
- Mounting all resources read-only (resists `sudo rm -rf --no-preserve-root /`)
|
- Mounting all resources read-only (resists `sudo rm -rf --no-preserve-root /`)
|
||||||
|
- Cleaning up all temp space after each execution (resists out of drive space attacks)
|
||||||
- Running as a variety of unprivileged users
|
- Running as a variety of unprivileged users
|
||||||
- Capping runtime execution at 3 seconds
|
- Capping runtime execution at 3 seconds
|
||||||
- Capping stdout to 65536 characters (resists yes/no bombs and runaway output)
|
- Capping stdout to 65536 characters (resists yes/no bombs and runaway output)
|
||||||
- SIGKILLing misbehaving code
|
- SIGKILLing misbehaving code
|
||||||
|
|
||||||
#### License
|
<br>
|
||||||
|
|
||||||
|
# License
|
||||||
Piston is licensed under the MIT license.
|
Piston is licensed under the MIT license.
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
const { writeFileSync, unlinkSync } = require('fs');
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
|
||||||
|
const OUTPUT_LIMIT = 65535;
|
||||||
|
|
||||||
|
function execute(language, source, stdin = '', args = []) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const stamp = new Date().getTime();
|
||||||
|
const sourceFile = `/tmp/${stamp}.code`;
|
||||||
|
|
||||||
|
writeFileSync(sourceFile, source);
|
||||||
|
|
||||||
|
const process = spawn(__dirname + '/../lxc/execute', [
|
||||||
|
language.name,
|
||||||
|
sourceFile,
|
||||||
|
stdin,
|
||||||
|
args.join('\n'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let stdout = '';
|
||||||
|
let stderr = '';
|
||||||
|
let output = '';
|
||||||
|
|
||||||
|
process.stderr.on('data', chunk => {
|
||||||
|
if (stderr.length >= OUTPUT_LIMIT) return;
|
||||||
|
|
||||||
|
stderr += chunk;
|
||||||
|
output += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
process.stdout.on('data', chunk => {
|
||||||
|
if (stdout.length >= OUTPUT_LIMIT) return;
|
||||||
|
|
||||||
|
stdout += chunk;
|
||||||
|
output += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', code => {
|
||||||
|
unlinkSync(sourceFile);
|
||||||
|
|
||||||
|
stderr = stderr.trim().substring(0, OUTPUT_LIMIT);
|
||||||
|
stdout = stdout.trim().substring(0, OUTPUT_LIMIT);
|
||||||
|
output = output.trim().substring(0, OUTPUT_LIMIT);
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
output,
|
||||||
|
ran: code === 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
execute,
|
||||||
|
};
|
|
@ -0,0 +1,209 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "nasm",
|
||||||
|
"aliases": [
|
||||||
|
"asm",
|
||||||
|
"nasm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nasm64",
|
||||||
|
"aliases": [
|
||||||
|
"asm64",
|
||||||
|
"nasm64"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "awk",
|
||||||
|
"aliases": [
|
||||||
|
"awk"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bash",
|
||||||
|
"aliases": [
|
||||||
|
"bash"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "brainfuck",
|
||||||
|
"aliases": [
|
||||||
|
"bf",
|
||||||
|
"brainfuck"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "c",
|
||||||
|
"aliases": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "csharp",
|
||||||
|
"aliases": [
|
||||||
|
"c#",
|
||||||
|
"cs",
|
||||||
|
"csharp"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpp",
|
||||||
|
"aliases": [
|
||||||
|
"c++",
|
||||||
|
"cpp",
|
||||||
|
"cc",
|
||||||
|
"cxx"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "d",
|
||||||
|
"aliases": [
|
||||||
|
"dlang",
|
||||||
|
"d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deno",
|
||||||
|
"aliases": [
|
||||||
|
"deno",
|
||||||
|
"denojs",
|
||||||
|
"denots"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ruby",
|
||||||
|
"aliases": [
|
||||||
|
"duby",
|
||||||
|
"rb",
|
||||||
|
"ruby"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "emacs",
|
||||||
|
"aliases": [
|
||||||
|
"el",
|
||||||
|
"elisp",
|
||||||
|
"emacs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "elixir",
|
||||||
|
"aliases": [
|
||||||
|
"elixir",
|
||||||
|
"exs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "haskell",
|
||||||
|
"aliases": [
|
||||||
|
"haskell",
|
||||||
|
"hs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "go",
|
||||||
|
"aliases": [
|
||||||
|
"go",
|
||||||
|
"golang"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java",
|
||||||
|
"aliases": [
|
||||||
|
"java"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"aliases": [
|
||||||
|
"javascript",
|
||||||
|
"js",
|
||||||
|
"node",
|
||||||
|
"node.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "jelly",
|
||||||
|
"aliases": [
|
||||||
|
"jelly"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "julia",
|
||||||
|
"aliases": [
|
||||||
|
"jl",
|
||||||
|
"julia"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kotlin",
|
||||||
|
"aliases": [
|
||||||
|
"kotlin",
|
||||||
|
"kt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lua",
|
||||||
|
"aliases": [
|
||||||
|
"lua"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "paradoc",
|
||||||
|
"aliases": [
|
||||||
|
"paradoc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "perl",
|
||||||
|
"aliases": [
|
||||||
|
"perl",
|
||||||
|
"pl"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "php",
|
||||||
|
"aliases": [
|
||||||
|
"php",
|
||||||
|
"php3",
|
||||||
|
"php4",
|
||||||
|
"php5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "python3",
|
||||||
|
"aliases": [
|
||||||
|
"py",
|
||||||
|
"py3",
|
||||||
|
"python",
|
||||||
|
"python3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "python2",
|
||||||
|
"aliases": [
|
||||||
|
"python2",
|
||||||
|
"py2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rust",
|
||||||
|
"aliases": [
|
||||||
|
"rs",
|
||||||
|
"rust"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "swift",
|
||||||
|
"aliases": [
|
||||||
|
"swift"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "typescript",
|
||||||
|
"aliases": [
|
||||||
|
"ts",
|
||||||
|
"typescript"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,262 @@
|
||||||
|
# create and start container
|
||||||
|
lxc-create -t download -n piston -- --dist ubuntu --release bionic --arch amd64
|
||||||
|
./start
|
||||||
|
|
||||||
|
# open a shell to the container
|
||||||
|
./shell
|
||||||
|
|
||||||
|
# install all necessary piston dependencies
|
||||||
|
echo 'source /opt/.profile' >> /opt/.bashrc
|
||||||
|
echo 'export HOME=/opt' >> /opt/.profile
|
||||||
|
echo 'export TERM=linux' >> /opt/.profile
|
||||||
|
echo 'export PATH=$PATH:/opt/.local/bin' >> /opt/.profile
|
||||||
|
export HOME=/opt
|
||||||
|
export TERM=linux
|
||||||
|
sed -i 's/\/root/\/opt/' /etc/passwd
|
||||||
|
sed -i \
|
||||||
|
's/http:\/\/archive.ubuntu.com\/ubuntu/http:\/\/mirror.math.princeton.edu\/pub\/ubuntu/' \
|
||||||
|
/etc/apt/sources.list
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y \
|
||||||
|
nano wget build-essential pkg-config libxml2-dev \
|
||||||
|
libsqlite3-dev mono-complete curl cmake libpython2.7-dev \
|
||||||
|
ruby libtinfo-dev unzip git openssl libssl-dev
|
||||||
|
|
||||||
|
# install python2
|
||||||
|
# final binary: /opt/python2/Python-2.7.17/python
|
||||||
|
# get version: /opt/python2/Python-2.7.17/python -V
|
||||||
|
cd /opt && mkdir python2 && cd python2
|
||||||
|
wget https://www.python.org/ftp/python/2.7.17/Python-2.7.17.tar.xz
|
||||||
|
unxz Python-2.7.17.tar.xz
|
||||||
|
tar -xf Python-2.7.17.tar
|
||||||
|
cd Python-2.7.17
|
||||||
|
./configure
|
||||||
|
# open Modules/Setup and uncomment zlib line
|
||||||
|
make
|
||||||
|
echo 'export PATH=$PATH:/opt/python2/Python-2.7.17' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install python3
|
||||||
|
# final binary: /opt/python3/Python-3.8.2/python
|
||||||
|
# get version: /opt/python3/Python-3.8.2/python -V
|
||||||
|
cd /opt && mkdir python3 && cd python3
|
||||||
|
wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz
|
||||||
|
unxz Python-3.8.2.tar.xz
|
||||||
|
tar -xf Python-3.8.2.tar
|
||||||
|
cd Python-3.8.2
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
ln -s python python3.8
|
||||||
|
echo 'export PATH=$PATH:/opt/python3/Python-3.8.2' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install paradoc
|
||||||
|
# this is not a binary, it is a python module
|
||||||
|
# therefore it cannot be run directly as it requires python3 to be installed
|
||||||
|
cd /opt && mkdir paradoc && cd paradoc
|
||||||
|
git clone https://github.com/betaveros/paradoc.git
|
||||||
|
|
||||||
|
# install node.js
|
||||||
|
# final binary: /opt/nodejs/node-v12.16.1-linux-x64/bin/node
|
||||||
|
# get version: /opt/nodejs/node-v12.16.1-linux-x64/bin/node -v
|
||||||
|
cd /opt && mkdir nodejs && cd nodejs
|
||||||
|
wget https://nodejs.org/dist/v12.16.1/node-v12.16.1-linux-x64.tar.xz
|
||||||
|
unxz node-v12.16.1-linux-x64.tar.xz
|
||||||
|
tar -xf node-v12.16.1-linux-x64.tar
|
||||||
|
echo 'export PATH=$PATH:/opt/nodejs/node-v12.16.1-linux-x64/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install typescript
|
||||||
|
# final binary: /opt/nodejs/node-v12.16.1-linux-x64/bin/tsc
|
||||||
|
# get version: /opt/nodejs/node-v12.16.1-linux-x64/bin/tsc -v
|
||||||
|
/opt/nodejs/node-v12.16.1-linux-x64/bin/npm i -g typescript
|
||||||
|
|
||||||
|
# install golang
|
||||||
|
# final binary: /opt/go/go/bin/go
|
||||||
|
# get version: /opt/go/go/bin/go version
|
||||||
|
cd /opt && mkdir go && cd go
|
||||||
|
wget https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz
|
||||||
|
tar -xzf go1.14.1.linux-amd64.tar.gz
|
||||||
|
echo 'export PATH=$PATH:/opt/go/go/bin' >> /opt/.profile
|
||||||
|
echo 'export GOROOT=/opt/go/go' >> /opt/.profile
|
||||||
|
echo 'export GOCACHE=/tmp' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install php
|
||||||
|
# final binary: /usr/local/bin/php
|
||||||
|
# get version: /usr/local/bin/php -v
|
||||||
|
cd /opt && mkdir php && cd php
|
||||||
|
wget https://www.php.net/distributions/php-7.4.4.tar.gz
|
||||||
|
tar -xzf php-7.4.4.tar.gz
|
||||||
|
cd php-7.4.4
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
# install rust
|
||||||
|
# final binary: /usr/local/bin/rustc
|
||||||
|
# get version: /usr/local/bin/rustc --version
|
||||||
|
cd /opt && mkdir rust && cd rust
|
||||||
|
wget https://static.rust-lang.org/dist/rust-1.49.0-x86_64-unknown-linux-gnu.tar.gz
|
||||||
|
tar -xzf rust-1.49.0-x86_64-unknown-linux-gnu.tar.gz
|
||||||
|
cd rust-1.49.0-x86_64-unknown-linux-gnu
|
||||||
|
./install.sh
|
||||||
|
|
||||||
|
# install swift
|
||||||
|
# final binary: /opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin/swift
|
||||||
|
# get version: /opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin/swift --version
|
||||||
|
cd /opt && mkdir swift && cd swift
|
||||||
|
wget https://swift.org/builds/swift-5.1.5-release/ubuntu1804/swift-5.1.5-RELEASE/swift-5.1.5-RELEASE-ubuntu18.04.tar.gz
|
||||||
|
tar -xzf swift-5.1.5-RELEASE-ubuntu18.04.tar.gz
|
||||||
|
echo 'export PATH=$PATH:/opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install nasm
|
||||||
|
# final binary: /opt/nasm/nasm-2.14.02/nasm
|
||||||
|
# get version: /opt/nasm/nasm-2.14.02/nasm -v
|
||||||
|
cd /opt && mkdir nasm && cd nasm
|
||||||
|
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
|
||||||
|
tar -xzf nasm-2.14.02.tar.gz
|
||||||
|
cd nasm-2.14.02
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
echo 'export PATH=$PATH:/opt/nasm/nasm-2.14.02' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install java
|
||||||
|
# final binary: /opt/java/jdk-14/bin/java
|
||||||
|
# get version: /opt/java/jdk-14/bin/java -version
|
||||||
|
cd /opt && mkdir java && cd java
|
||||||
|
wget https://download.java.net/java/GA/jdk14/076bab302c7b4508975440c56f6cc26a/36/GPL/openjdk-14_linux-x64_bin.tar.gz
|
||||||
|
tar -xzf openjdk-14_linux-x64_bin.tar.gz
|
||||||
|
echo 'export PATH=$PATH:/opt/java/jdk-14/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install jelly
|
||||||
|
cd /opt && mkdir jelly && cd jelly
|
||||||
|
wget https://github.com/DennisMitchell/jellylanguage/archive/master.zip
|
||||||
|
unzip master.zip
|
||||||
|
cd jellylanguage-master
|
||||||
|
python3.8 -m pip install .
|
||||||
|
sed -i 's/\/usr\/local\/bin\/python3.8/\/opt\/python3\/Python-3.8.2\/python3.8/' /usr/local/bin/jelly
|
||||||
|
|
||||||
|
# install julia
|
||||||
|
# final binary: /opt/julia/julia-1.5.0/bin/julia
|
||||||
|
# get version: /opt/julia/julia-1.5.0/bin/julia --version
|
||||||
|
cd /opt && mkdir julia && cd julia
|
||||||
|
wget https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.0-linux-x86_64.tar.gz
|
||||||
|
tar -xzf julia-1.5.0-linux-x86_64.tar.gz
|
||||||
|
echo 'export PATH=$PATH:/opt/julia/julia-1.5.0/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install kotlin
|
||||||
|
# final binary: /opt/kotlinc/bin/kotlinc
|
||||||
|
# get version: /opt/kotlinc/bin/kotlinc -version
|
||||||
|
cd /opt
|
||||||
|
wget https://github.com/JetBrains/kotlin/releases/download/v1.4.10/kotlin-compiler-1.4.10.zip
|
||||||
|
unzip kotlin-compiler-1.4.10.zip
|
||||||
|
rm kotlin-compiler-1.4.10.zip
|
||||||
|
echo 'export PATH=$PATH:/opt/kotlinc/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install elixir and erlang
|
||||||
|
# final binary: /opt/elixir/bin/elixir
|
||||||
|
# get version: /opt/elixir/bin/elixir --version
|
||||||
|
# erlang
|
||||||
|
cd /opt && mkdir erlang && cd erlang
|
||||||
|
wget http://erlang.org/download/otp_src_23.0.tar.gz
|
||||||
|
gunzip -c otp_src_23.0.tar.gz | tar xf -
|
||||||
|
cd otp_src_23.0 && ./configure
|
||||||
|
make
|
||||||
|
echo 'export PATH=$PATH:/opt/erlang/otp_src_23.0/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
# elixir
|
||||||
|
cd /opt && mkdir elixir && cd elixir
|
||||||
|
wget https://github.com/elixir-lang/elixir/releases/download/v1.10.3/Precompiled.zip
|
||||||
|
mkdir elixir-1.10.3 && unzip Precompiled.zip -d elixir-1.10.3/
|
||||||
|
echo 'export PATH=$PATH:/opt/elixir/elixir-1.10.3/bin' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install emacs
|
||||||
|
# final binary: /opt/emacs/emacs-26.3/src/emacs
|
||||||
|
# get version: /opt/emacs/emacs-26.3/src/emacs --version
|
||||||
|
cd /opt && mkdir emacs && cd emacs
|
||||||
|
wget https://mirrors.ocf.berkeley.edu/gnu/emacs/emacs-26.3.tar.xz
|
||||||
|
tar -xf emacs-26.3.tar.xz
|
||||||
|
rm emacs-26.3.tar.xz
|
||||||
|
cd emacs-26.3
|
||||||
|
./configure --with-gnutls=no
|
||||||
|
make
|
||||||
|
echo 'export PATH=$PATH:/opt/emacs/emacs-26.3/src' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install lua
|
||||||
|
# final binary: /opt/lua/lua54/src/lua
|
||||||
|
# get version: /opt/lua/lua54/src/lua -v
|
||||||
|
cd /opt && mkdir lua && cd lua
|
||||||
|
wget https://sourceforge.net/projects/luabinaries/files/5.4.0/Docs%20and%20Sources/lua-5.4.0_Sources.tar.gz/download
|
||||||
|
tar -xzf download
|
||||||
|
cd lua54
|
||||||
|
make
|
||||||
|
echo 'export PATH=$PATH:/opt/lua/lua54/src' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install haskell
|
||||||
|
# final binary: /usr/bin/ghc
|
||||||
|
# get version: /usr/bin/ghc --version
|
||||||
|
apt install -y ghc
|
||||||
|
|
||||||
|
# install deno
|
||||||
|
# final binary: /opt/.deno/bin/deno
|
||||||
|
# get version: /opt/.deno/bin/deno --version
|
||||||
|
cd /opt && mkdir deno && cd deno
|
||||||
|
curl -fsSL https://deno.land/x/install/install.sh | sh
|
||||||
|
echo 'export DENO_INSTALL="/opt/.deno"' >> /opt/.profile
|
||||||
|
echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install brainfuck
|
||||||
|
cd /opt && mkdir bf && cd bf
|
||||||
|
git clone https://github.com/texus/Brainfuck-interpreter
|
||||||
|
cd Brainfuck-interpreter
|
||||||
|
echo 'export PATH=$PATH:/opt/bf/Brainfuck-interpreter' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# install d
|
||||||
|
# final binary: /opt/d/dmd2/linux/bin64/dmd
|
||||||
|
# get version: /opt/d/dmd2/linux/bin64/dmd --version
|
||||||
|
cd /opt && mkdir d && cd d
|
||||||
|
wget http://downloads.dlang.org/releases/2.x/2.095.0/dmd.2.095.0.linux.tar.xz
|
||||||
|
unxz dmd.2.095.0.linux.tar.xz
|
||||||
|
tar -xf dmd.2.095.0.linux.tar
|
||||||
|
echo 'export PATH=$PATH:/opt/d/dmd2/linux/bin64' >> /opt/.profile
|
||||||
|
source /opt/.profile
|
||||||
|
|
||||||
|
# create runnable users and apply limits
|
||||||
|
for i in {1..150}; do
|
||||||
|
useradd -M runner$i
|
||||||
|
usermod -d /tmp runner$i
|
||||||
|
echo "runner$i soft nproc 64" >> /etc/security/limits.conf
|
||||||
|
echo "runner$i hard nproc 64" >> /etc/security/limits.conf
|
||||||
|
echo "runner$i soft nofile 2048" >> /etc/security/limits.conf
|
||||||
|
echo "runner$i hard nofile 2048" >> /etc/security/limits.conf
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove any lingering write access to others
|
||||||
|
cd /opt
|
||||||
|
chown -R root: *
|
||||||
|
chmod -R o-w *
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
rm -rf /home/ubuntu
|
||||||
|
chmod 777 /tmp
|
||||||
|
|
||||||
|
# disable cron
|
||||||
|
systemctl stop cron
|
||||||
|
systemctl disable cron
|
||||||
|
|
||||||
|
# leave container
|
||||||
|
exit
|
||||||
|
|
||||||
|
# optionally run tests
|
||||||
|
./test_all_lxc
|
|
@ -0,0 +1,24 @@
|
||||||
|
# make piston image
|
||||||
|
lxc-clone -KMP /mnt/piston_image piston piston
|
||||||
|
sed -i 's/\/mnt\/piston_image/\/var\/lib\/lxc/' piston/config
|
||||||
|
tar -czf piston.tar.gz piston/
|
||||||
|
|
||||||
|
# restore piston image
|
||||||
|
cd /var/lib/lxc
|
||||||
|
tar -xzf piston.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
# get piston image
|
||||||
|
cd /var/lib/lxc
|
||||||
|
wget whatever url
|
||||||
|
tar -xzf piston.tar.gz
|
||||||
|
sed -i "s/virtbr0/$(ip a | grep br0: | cut -d' ' -f2 | sed 's/://gi')/" piston/config
|
||||||
|
|
||||||
|
# start piston
|
||||||
|
cd /path/to/piston/lxc
|
||||||
|
./start
|
||||||
|
```
|
Loading…
Reference in New Issue