/
run.go
159 lines (120 loc) · 4.37 KB
/
run.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package docker
import (
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/shell"
"github.com/gruntwork-io/terratest/modules/testing"
"github.com/stretchr/testify/require"
)
// RunOptions defines options that can be passed to the 'docker run' command.
type RunOptions struct {
// Override the default COMMAND of the Docker image
Command []string
// If set to true, pass the --detach flag to 'docker run' to run the container in the background
Detach bool
// Override the default ENTRYPOINT of the Docker image
Entrypoint string
// Set environment variables
EnvironmentVariables []string
// If set to true, pass the --init flag to 'docker run' to run an init inside the container that forwards signals
// and reaps processes
Init bool
// Assign a name to the container
Name string
// If set to true, pass the --privileged flag to 'docker run' to give extended privileges to the container
Privileged bool
// If set to true, pass the --rm flag to 'docker run' to automatically remove the container when it exits
Remove bool
// If set to true, pass the -tty flag to 'docker run' to allocate a pseudo-TTY
Tty bool
// Username or UID
User string
// Bind mount these volume(s) when running the container
Volumes []string
// Custom CLI options that will be passed as-is to the 'docker run' command. This is an "escape hatch" that allows
// Terratest to not have to support every single command-line option offered by the 'docker run' command, and
// solely focus on the most important ones.
OtherOptions []string
// Set a logger that should be used. See the logger package for more info.
Logger *logger.Logger
}
// Run runs the 'docker run' command on the given image with the given options and return stdout/stderr. This method
// fails the test if there are any errors.
func Run(t testing.TestingT, image string, options *RunOptions) string {
out, err := RunE(t, image, options)
require.NoError(t, err)
return out
}
// RunE runs the 'docker run' command on the given image with the given options and return stdout/stderr, or any error.
func RunE(t testing.TestingT, image string, options *RunOptions) (string, error) {
options.Logger.Logf(t, "Running 'docker run' on image '%s'", image)
args, err := formatDockerRunArgs(image, options)
if err != nil {
return "", err
}
cmd := shell.Command{
Command: "docker",
Args: args,
Logger: options.Logger,
}
return shell.RunCommandAndGetOutputE(t, cmd)
}
// RunAndGetID runs the 'docker run' command on the given image with the given options and returns the container ID
// that is returned in stdout. This method fails the test if there are any errors.
func RunAndGetID(t testing.TestingT, image string, options *RunOptions) string {
out, err := RunAndGetIDE(t, image, options)
require.NoError(t, err)
return out
}
// RunAndGetIDE runs the 'docker run' command on the given image with the given options and returns the container ID
// that is returned in stdout, or any error.
func RunAndGetIDE(t testing.TestingT, image string, options *RunOptions) (string, error) {
options.Logger.Logf(t, "Running 'docker run' on image '%s', returning stdout", image)
args, err := formatDockerRunArgs(image, options)
if err != nil {
return "", err
}
cmd := shell.Command{
Command: "docker",
Args: args,
Logger: options.Logger,
}
return shell.RunCommandAndGetStdOutE(t, cmd)
}
// formatDockerRunArgs formats the arguments for the 'docker run' command.
func formatDockerRunArgs(image string, options *RunOptions) ([]string, error) {
args := []string{"run"}
if options.Detach {
args = append(args, "--detach")
}
if options.Entrypoint != "" {
args = append(args, "--entrypoint", options.Entrypoint)
}
for _, envVar := range options.EnvironmentVariables {
args = append(args, "--env", envVar)
}
if options.Init {
args = append(args, "--init")
}
if options.Name != "" {
args = append(args, "--name", options.Name)
}
if options.Privileged {
args = append(args, "--privileged")
}
if options.Remove {
args = append(args, "--rm")
}
if options.Tty {
args = append(args, "--tty")
}
if options.User != "" {
args = append(args, "--user", options.User)
}
for _, volume := range options.Volumes {
args = append(args, "--volume", volume)
}
args = append(args, options.OtherOptions...)
args = append(args, image)
args = append(args, options.Command...)
return args, nil
}