forked from orbitalci/orbital
/
docker.go
102 lines (98 loc) · 3.1 KB
/
docker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package testutil
import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
"testing"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
)
// DockerCreateExec creates a docker container by running the docker client via the os/exec package. It will return a cleanup function that will
// kill the container.
func DockerCreateExec(t *testing.T, ctx context.Context, imageName string, ports []string, mounts ...string) (cleanup func(), err error) {
portsString := " -p " + strings.Join(ports, " -p ")
mountsStrings := " -v " + strings.Join(mounts, " -v ")
command := fmt.Sprintf("docker run --rm --init -d %s %s %s", portsString, mountsStrings, imageName)
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd := exec.CommandContext(ctx, "/bin/bash", "-c", command)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
t.Log(stderr.String())
t.Fatal(err)
}
time.Sleep(2 * time.Second)
t.Log(stdout.String())
id := strings.TrimSpace(stdout.String())
cleanup = func() {
cmd := exec.Command("/bin/bash", "-c", "docker kill "+id)
if err := cmd.Run(); err != nil {
t.Fatal(err)
}
}
return cleanup, nil
}
// i used all the damn functions that docker is using
// WHY
func DockerCreate(t *testing.T, ctx context.Context, imageName string, ports []string, mounts ...string) (isRunning bool, cleanup func()) {
cli, err := client.NewEnvClient()
if err != nil {
t.Fatal("couldn't create docker cli, err: ", err.Error())
}
exposedPorts, bindings, err := nat.ParsePortSpecs(ports)
if err != nil {
t.Error(err)
return false, nil
}
out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
if err != nil {
t.Fatal("couldn't pull image, err: ", err.Error())
}
defer out.Close()
containerConfig := &container.Config{
Image: imageName,
ExposedPorts: exposedPorts,
AttachStderr: true,
AttachStdout: true,
AttachStdin: true,
Tty: true,
}
binds := append([]string{"/var/run/docker.sock:/var/run/docker.sock"}, mounts...)
init := true
hostConfig := &container.HostConfig{
//TODO: have it be overridable via env variable
Binds: binds,
PortBindings: bindings,
AutoRemove: true,
//Binds: []string{ homeDirectory + ":/.ocelot", "/var/run/docker.sock:/var/run/docker.sock"},
NetworkMode: "host",
Init: &init,
}
resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, nil, "")
if err != nil {
t.Error("could not create container, error: ", err.Error(), "\nwarnings: ", strings.Join(resp.Warnings, "\n - "))
return
}
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
t.Error("couldnt create container, error: ", err.Error())
return
}
//containerLog, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{
// ShowStdout: true,
// ShowStderr: true,
// Follow: true,
//})
//if err != nil {
// t.Error("couldn't get container log, error: ", err.Error())
// return
//}
cleanup = func() { cli.ContainerKill(ctx, resp.ID, "SIGKILL") }
isRunning = true
return
}