impr: explicit versioned boxes

This commit is contained in:
Anton
2023-12-21 16:46:31 +05:00
parent ade821ff61
commit 3fd59120f5
3 changed files with 42 additions and 31 deletions

View File

@@ -59,8 +59,7 @@ type Box struct {
Runtime string `json:"runtime"` Runtime string `json:"runtime"`
Host Host
Versions []string `json:"versions"` Files []string `json:"files"`
Files []string `json:"files"`
} }
// A Host describes container Host attributes. // A Host describes container Host attributes.

View File

@@ -9,7 +9,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"slices"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -98,8 +97,7 @@ func (e *Docker) Exec(req Request) Execution {
// execStep executes a step using the docker container. // execStep executes a step using the docker container.
func (e *Docker) execStep(step *config.Step, req Request, dir string, files Files) Execution { func (e *Docker) execStep(step *config.Step, req Request, dir string, files Files) Execution {
box := e.cfg.Boxes[step.Box] box, err := e.getBox(step, req)
err := e.validateVersion(box, step, req)
if err != nil { if err != nil {
return Fail(req.ID, err) return Fail(req.ID, err)
} }
@@ -123,16 +121,33 @@ func (e *Docker) execStep(step *config.Step, req Request, dir string, files File
} }
} }
func (e *Docker) validateVersion(box *config.Box, step *config.Step, req Request) error { // getBox selects an appropriate box for the step (if any).
// If the version is set in the step config, use it. func (e *Docker) getBox(step *config.Step, req Request) (*config.Box, error) {
// If the version isn't set in the request, use the latest one. if step.Action == actionExec {
// Otherwise, check that the version in the request is supported // exec steps use existing instances
// according to the box config. // and do not spin up new boxes
if step.Version == "" && req.Version != "" && !slices.Contains(box.Versions, req.Version) { return nil, nil
err := fmt.Errorf("box %s does not support version %s", step.Box, req.Version)
return err
} }
return nil var boxName string
// If the version is set in the step config, use it.
if step.Version != "" {
if step.Version == "latest" {
boxName = step.Box
} else {
boxName = step.Box + ":" + step.Version
}
} else if req.Version != "" {
// If the version is set in the request, use it.
boxName = step.Box + ":" + req.Version
} else {
// otherwise, use the latest version
boxName = step.Box
}
box, found := e.cfg.Boxes[boxName]
if !found {
return nil, fmt.Errorf("unknown box %s", boxName)
}
return box, nil
} }
// copyFiles copies box files to the temporary directory. // copyFiles copies box files to the temporary directory.
@@ -273,17 +288,7 @@ func dockerRunArgs(box *config.Box, step *config.Step, req Request, dir string)
for _, lim := range box.Ulimit { for _, lim := range box.Ulimit {
args = append(args, "--ulimit", lim) args = append(args, "--ulimit", lim)
} }
args = append(args, box.Image)
if step.Version != "" {
// if the version is set in the step config, use it
args = append(args, box.Image+":"+step.Version)
} else if req.Version != "" {
// if the version is set in the request, use it
args = append(args, box.Image+":"+req.Version)
} else {
// otherwise, use the latest version
args = append(args, box.Image)
}
return args return args
} }

View File

@@ -28,10 +28,9 @@ var dockerCfg = &config.Config{
Volume: "%s:/sandbox:ro", Volume: "%s:/sandbox:ro",
NProc: 64, NProc: 64,
}, },
Versions: []string{"dev"},
}, },
"postgresql": { "go:dev": {
Image: "codapi/postgresql", Image: "codapi/go:dev",
Runtime: "runc", Runtime: "runc",
Host: config.Host{ Host: config.Host{
CPU: 1, Memory: 64, Network: "none", CPU: 1, Memory: 64, Network: "none",
@@ -47,7 +46,15 @@ var dockerCfg = &config.Config{
Volume: "%s:/sandbox:ro", Volume: "%s:/sandbox:ro",
NProc: 64, NProc: 64,
}, },
Versions: []string{"dev"}, },
"python:dev": {
Image: "codapi/python:dev",
Runtime: "runc",
Host: config.Host{
CPU: 1, Memory: 64, Network: "none",
Volume: "%s:/sandbox:ro",
NProc: 64,
},
}, },
}, },
Commands: map[string]config.SandboxCommands{ Commands: map[string]config.SandboxCommands{
@@ -200,7 +207,7 @@ func TestDockerRun(t *testing.T) {
t.Error("OK: expected true") t.Error("OK: expected true")
} }
mem.MustHave(t, "codapi/go:dev") mem.MustHave(t, "codapi/go:dev")
mem.MustHave(t, "codapi/alpine:latest") mem.MustHave(t, "codapi/alpine")
}) })
t.Run("unsupported version", func(t *testing.T) { t.Run("unsupported version", func(t *testing.T) {
@@ -219,7 +226,7 @@ func TestDockerRun(t *testing.T) {
if out.OK { if out.OK {
t.Error("OK: expected false") t.Error("OK: expected false")
} }
want := "box python does not support version 42" want := "unknown box python:42"
if out.Stderr != want { if out.Stderr != want {
t.Errorf("Stderr: unexpected value: %s", out.Stderr) t.Errorf("Stderr: unexpected value: %s", out.Stderr)
} }