docker driver: use toolbox exec

Older version of docker doesn't support the exec api Env and WorkingDir options.

Support these versions by doing the same we already do with the k8s driver: use
the `toolbox exec` command that will set the provided Env, change the cwd to the
WorkingDir and the exec the wanted command.
This commit is contained in:
Simone Gotti 2019-08-04 15:38:58 +02:00
parent b333b6f423
commit b3672bf927
3 changed files with 29 additions and 7 deletions

View File

@ -22,6 +22,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"runtime" "runtime"
"sort" "sort"
"strconv" "strconv"
@ -182,10 +183,11 @@ func (d *DockerDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.
} }
pod := &DockerPod{ pod := &DockerPod{
id: podConfig.ID, id: podConfig.ID,
client: d.client, client: d.client,
executorID: d.executorID, executorID: d.executorID,
containers: []*DockerContainer{}, containers: []*DockerContainer{},
initVolumeDir: podConfig.InitVolumeDir,
} }
count := 0 count := 0
@ -333,6 +335,7 @@ func (d *DockerDriver) GetPods(ctx context.Context, all bool) ([]Pod, error) {
client: d.client, client: d.client,
executorID: d.executorID, executorID: d.executorID,
containers: []*DockerContainer{}, containers: []*DockerContainer{},
// TODO(sgotti) initvolumeDir isn't set
} }
podsMap[podID] = pod podsMap[podID] = pod
} }
@ -397,6 +400,8 @@ type DockerPod struct {
labels map[string]string labels map[string]string
containers []*DockerContainer containers []*DockerContainer
executorID string executorID string
initVolumeDir string
} }
type DockerContainer struct { type DockerContainer struct {
@ -475,11 +480,20 @@ func (s *Stdin) Close() error {
func (dp *DockerPod) Exec(ctx context.Context, execConfig *ExecConfig) (ContainerExec, error) { func (dp *DockerPod) Exec(ctx context.Context, execConfig *ExecConfig) (ContainerExec, error) {
endCh := make(chan error) endCh := make(chan error)
// old docker versions doesn't support providing Env (before api 1.25) and
// WorkingDir (before api 1.35) in exec command.
// Use a toolbox command that will set them up and then exec the real command.
envj, err := json.Marshal(execConfig.Env)
if err != nil {
return nil, err
}
cmd := []string{filepath.Join(dp.initVolumeDir, "agola-toolbox"), "exec", "-e", string(envj), "-w", execConfig.WorkingDir, "--"}
cmd = append(cmd, execConfig.Cmd...)
dockerExecConfig := dockertypes.ExecConfig{ dockerExecConfig := dockertypes.ExecConfig{
Cmd: execConfig.Cmd, Cmd: cmd,
Env: makeEnvSlice(execConfig.Env),
Tty: execConfig.Tty, Tty: execConfig.Tty,
WorkingDir: execConfig.WorkingDir,
AttachStdin: execConfig.AttachStdin, AttachStdin: execConfig.AttachStdin,
AttachStdout: execConfig.Stdout != nil, AttachStdout: execConfig.Stdout != nil,
AttachStderr: execConfig.Stderr != nil, AttachStderr: execConfig.Stderr != nil,

View File

@ -96,6 +96,10 @@ func TestDockerPod(t *testing.T) {
ctx := context.Background() ctx := context.Background()
if err := d.Setup(ctx); err != nil {
t.Fatalf("unexpected err: %v", err)
}
t.Run("create a pod with one container", func(t *testing.T) { t.Run("create a pod with one container", func(t *testing.T) {
pod, err := d.NewPod(ctx, &PodConfig{ pod, err := d.NewPod(ctx, &PodConfig{
ID: uuid.NewV4().String(), ID: uuid.NewV4().String(),

View File

@ -48,6 +48,10 @@ func TestK8sPod(t *testing.T) {
ctx := context.Background() ctx := context.Background()
if err := d.Setup(ctx); err != nil {
t.Fatalf("unexpected err: %v", err)
}
t.Run("create a pod with one container", func(t *testing.T) { t.Run("create a pod with one container", func(t *testing.T) {
pod, err := d.NewPod(ctx, &PodConfig{ pod, err := d.NewPod(ctx, &PodConfig{
ID: uuid.NewV4().String(), ID: uuid.NewV4().String(),