From 5824ab066c958d4fc7a1c9e09f5c7d7397b797f1 Mon Sep 17 00:00:00 2001 From: jaronnie Date: Wed, 3 Apr 2024 16:53:25 +0800 Subject: [PATCH] feat(codapi): support go sandbox --- .gitignore | 1 + configs/boxes.json | 12 ++++++ configs/commands/go.json | 12 ++++++ configs/config.json | 2 +- docs/add-sandbox.md | 91 ++++++++++++++++++++++++++++++++++++++++ images/go/Dockerfile | 6 +++ 6 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 configs/commands/go.json create mode 100644 images/go/Dockerfile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/configs/boxes.json b/configs/boxes.json index ed0eb66..46f6ace 100644 --- a/configs/boxes.json +++ b/configs/boxes.json @@ -1,5 +1,17 @@ { "alpine": { "image": "codapi/alpine" + }, + "go": { + "image": "codapi/go", + "runtime": "runc", + "cpu": 2, + "memory": 512, + "network": "none", + "writable": true, + "volume": "%s:/sandbox:rw", + "cap_drop": ["all"], + "ulimit": ["nofile=96"], + "nproc": 64 } } diff --git a/configs/commands/go.json b/configs/commands/go.json new file mode 100644 index 0000000..8fb45cc --- /dev/null +++ b/configs/commands/go.json @@ -0,0 +1,12 @@ +{ + "run": { + "engine": "docker", + "entry": "main.go", + "steps": [ + { + "box": "go", + "command": ["go", "run", "main.go"] + } + ] + } +} diff --git a/configs/config.json b/configs/config.json index 7416ac3..7f030de 100644 --- a/configs/config.json +++ b/configs/config.json @@ -15,7 +15,7 @@ "step": { "user": "sandbox", "action": "run", - "timeout": 5, + "timeout": 30, "noutput": 4096 } } diff --git a/docs/add-sandbox.md b/docs/add-sandbox.md index 9811037..e3f9b4d 100644 --- a/docs/add-sandbox.md +++ b/docs/add-sandbox.md @@ -123,3 +123,94 @@ Which produces the following output: "stderr": "" } ``` + +## Go + +First, let's create a Docker image capable of running Go: + +```sh +cd /opt/codapi +mkdir images/go +touch images/go/Dockerfile +``` + +Fill the `Dockerfile`: + +```Dockerfile +FROM golang:1.22.1-alpine3.19 + +RUN adduser --home /sandbox --disabled-password sandbox +USER sandbox +WORKDIR /sandbox +``` + +Build the image: + +```sh +docker build --file images/go/Dockerfile --tag codapi/go:latest images/go/ +``` + +And register the image as a Codapi _box_ in `configs/boxes.json`: + +```json +{ + // ... + "go": { + "image": "codapi/go", + "runtime": "runc", + "cpu": 2, + "memory": 512, + "network": "none", + "writable": true, + "volume": "%s:/sandbox:rw", + "cap_drop": ["all"], + "ulimit": ["nofile=96"], + "nproc": 64 + } +} +``` + +Finally, let's configure what happens when the client executes the `run` command in the `go` sandbox. To do this, we create `configs/commands/go.json`: + +```json +{ + "run": { + "engine": "docker", + "entry": "main.go", + "steps": [ + { + "box": "go", + "command": ["go", "run", "main.go"] + } + ] + } +} +``` + +This is essentially what it says: + +> When the client executes the `run` command in the `go` sandbox, save their code to the `main.go` file, then run it in the `go` box (Docker container) using the `go run main.go` shell command. + +To apply the changed configuration, restart Codapi (as root): + +```sh +systemctl restart codapi.service +``` + +And try running some go code: + +```sh +curl -H "content-type: application/json" -d '{"sandbox":"go","version":"","command":"run","files":{"":"package main\nimport (\n \"fmt\"\n)\n\nfunc main() {\n fmt.Println(\"hello\")\n}"}}' http://localhost:1313/v1/exec +``` + +Which produces the following output: + +```json +{ + "id": "go_run_f9592410", + "ok": true, + "duration": 10839, + "stdout": "hello", + "stderr": "" +} +``` \ No newline at end of file diff --git a/images/go/Dockerfile b/images/go/Dockerfile new file mode 100644 index 0000000..2fee9ee --- /dev/null +++ b/images/go/Dockerfile @@ -0,0 +1,6 @@ +FROM golang:1.22.1-alpine3.19 + +RUN adduser --home /sandbox --disabled-password sandbox +USER sandbox +WORKDIR /sandbox +