-
Notifications
You must be signed in to change notification settings - Fork 0
/
wrapper.go
117 lines (95 loc) · 2.68 KB
/
wrapper.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package dockertestwrapper
import (
"net/url"
"strconv"
"strings"
"github.com/ory/dockertest/v3"
)
// DefaultContainerExpiresAfterSeconds tells docker the hard limit in seconds when the container should be purged
const (
DefaultContainerExpiresAfterSeconds uint = 1800
UnassignedPort int = -1
)
// AfterInitActionFunc is a function type which will be executed after container initialization
type AfterInitActionFunc func(hostname string, port int) error
// WrapperParams contains all parameters needed to start a new custom container
type WrapperParams struct {
ImageName string
ImageTag string
ContainerPort string
EnvVariables []string
Volumes []string
Command []string
AfterInitActionFunc AfterInitActionFunc
}
// WrapperInstance holds all the information of the running container
type WrapperInstance struct {
Hostname string
Port int
Pool *dockertest.Pool
Resource *dockertest.Resource
}
// InitContainer starts a new container with the given parameters
func InitContainer(params WrapperParams) (instance *WrapperInstance, err error) {
instance = &WrapperInstance{}
instance.Pool, err = dockertest.NewPool("")
if err != nil {
return nil, err
}
runOpts := dockertest.RunOptions{
Repository: params.ImageName,
Tag: params.ImageTag,
Env: params.EnvVariables,
Cmd: params.Command,
Mounts: params.Volumes,
}
instance.Resource, err = instance.Pool.RunWithOptions(&runOpts)
if err != nil {
return nil, err
}
if err := instance.Resource.Expire(DefaultContainerExpiresAfterSeconds); err != nil {
return nil, err
}
if err := instance.determineHostname(); err != nil {
return nil, err
}
if err := instance.determinePort(params.ContainerPort); err != nil {
return nil, err
}
err = instance.Pool.Retry(func() error {
return params.AfterInitActionFunc(instance.Hostname, instance.Port)
})
if err != nil {
return nil, err
}
return instance, nil
}
// PurgeContainer purges the running container
func (w WrapperInstance) PurgeContainer() error {
return w.Pool.Purge(w.Resource)
}
func (w *WrapperInstance) determineHostname() error {
if strings.HasPrefix(w.Pool.Client.Endpoint(), "unix://") {
w.Hostname = "localhost"
return nil
}
endpoint := w.Pool.Client.Endpoint()
endpointUrl, err := url.Parse(endpoint)
if err != nil {
return err
}
w.Hostname = endpointUrl.Hostname()
return nil
}
func (w *WrapperInstance) determinePort(containerPort string) (err error) {
if len(containerPort) == 0 {
w.Port = UnassignedPort
return
}
stringPort := w.Resource.GetPort(containerPort)
w.Port, err = strconv.Atoi(stringPort)
if err != nil {
return err
}
return nil
}