feat(codapi): support go sandbox

This commit is contained in:
jaronnie 2024-04-03 16:53:25 +08:00
parent 530958f8ef
commit 5824ab066c
6 changed files with 123 additions and 1 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode

View File

@ -1,5 +1,17 @@
{ {
"alpine": { "alpine": {
"image": "codapi/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
} }
} }

12
configs/commands/go.json Normal file
View File

@ -0,0 +1,12 @@
{
"run": {
"engine": "docker",
"entry": "main.go",
"steps": [
{
"box": "go",
"command": ["go", "run", "main.go"]
}
]
}
}

View File

@ -15,7 +15,7 @@
"step": { "step": {
"user": "sandbox", "user": "sandbox",
"action": "run", "action": "run",
"timeout": 5, "timeout": 30,
"noutput": 4096 "noutput": 4096
} }
} }

View File

@ -123,3 +123,94 @@ Which produces the following output:
"stderr": "" "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": ""
}
```

6
images/go/Dockerfile Normal file
View File

@ -0,0 +1,6 @@
FROM golang:1.22.1-alpine3.19
RUN adduser --home /sandbox --disabled-password sandbox
USER sandbox
WORKDIR /sandbox