diff --git a/internal/config/config.go b/internal/config/config.go index 5323886..1e77f4a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -59,8 +59,7 @@ type Box struct { Runtime string `json:"runtime"` Host - Versions []string `json:"versions"` - Files []string `json:"files"` + Files []string `json:"files"` } // A Host describes container Host attributes. diff --git a/internal/engine/docker.go b/internal/engine/docker.go index 5214067..32abb12 100644 --- a/internal/engine/docker.go +++ b/internal/engine/docker.go @@ -9,7 +9,6 @@ import ( "os" "os/exec" "path/filepath" - "slices" "strconv" "strings" "time" @@ -98,8 +97,7 @@ func (e *Docker) Exec(req Request) Execution { // execStep executes a step using the docker container. func (e *Docker) execStep(step *config.Step, req Request, dir string, files Files) Execution { - box := e.cfg.Boxes[step.Box] - err := e.validateVersion(box, step, req) + box, err := e.getBox(step, req) if err != nil { 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 { - // If the version is set in the step config, use it. - // If the version isn't set in the request, use the latest one. - // Otherwise, check that the version in the request is supported - // according to the box config. - if step.Version == "" && req.Version != "" && !slices.Contains(box.Versions, req.Version) { - err := fmt.Errorf("box %s does not support version %s", step.Box, req.Version) - return err +// getBox selects an appropriate box for the step (if any). +func (e *Docker) getBox(step *config.Step, req Request) (*config.Box, error) { + if step.Action == actionExec { + // exec steps use existing instances + // and do not spin up new boxes + return nil, nil } - 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. @@ -273,17 +288,7 @@ func dockerRunArgs(box *config.Box, step *config.Step, req Request, dir string) for _, lim := range box.Ulimit { args = append(args, "--ulimit", lim) } - - 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) - } + args = append(args, box.Image) return args } diff --git a/internal/engine/docker_test.go b/internal/engine/docker_test.go index cb69ff9..883f25a 100644 --- a/internal/engine/docker_test.go +++ b/internal/engine/docker_test.go @@ -28,10 +28,9 @@ var dockerCfg = &config.Config{ Volume: "%s:/sandbox:ro", NProc: 64, }, - Versions: []string{"dev"}, }, - "postgresql": { - Image: "codapi/postgresql", + "go:dev": { + Image: "codapi/go:dev", Runtime: "runc", Host: config.Host{ CPU: 1, Memory: 64, Network: "none", @@ -47,7 +46,15 @@ var dockerCfg = &config.Config{ Volume: "%s:/sandbox:ro", 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{ @@ -200,7 +207,7 @@ func TestDockerRun(t *testing.T) { t.Error("OK: expected true") } 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) { @@ -219,7 +226,7 @@ func TestDockerRun(t *testing.T) { if out.OK { t.Error("OK: expected false") } - want := "box python does not support version 42" + want := "unknown box python:42" if out.Stderr != want { t.Errorf("Stderr: unexpected value: %s", out.Stderr) }