impr: explicit versioned boxes
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user