-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker.go
151 lines (118 loc) · 2.79 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
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
package gockertest
import (
"bytes"
"errors"
"fmt"
"os/exec"
"strings"
)
// Cli is struct
type Cli struct {
// ID is container id
ID string
}
// Arguments is arguments for docker commands
type Arguments struct {
// Ports is `-p` option
Ports map[int]int
// Envs is `-e` option
Envs map[string]string
// Name is `--name` option
Name string
// Network is `--net` option
Network string
// RequireLogin is required login
RequireLogin bool
// Login is login info
Login Login
// Foreground is add `--rm` option instead of `-d`
Foreground bool
}
// Login is struct for login registry
type Login struct {
User string
Password string
Registry string
}
// Run is run images
func Run(image string, args Arguments) *Cli {
if args.RequireLogin {
out, err := run("docker", "login", "-u", args.Login.User, "-p", args.Login.Password, args.Login.Registry)
if err != nil {
panic(err)
}
fmt.Printf("login.result:%+v\n", out)
}
if len(args.Ports) == 0 {
panic(fmt.Errorf("ports.required"))
}
// update image
out, err := run("docker", "pull", image)
if err != nil {
panic(err)
}
fmt.Printf("update.result:%+v\n", out)
// ports mapping
ports := make([]string, 0, len(args.Ports))
for k, v := range args.Ports {
ports = append(ports, fmt.Sprintf("%d:%d", k, v))
}
// environment variables
envs := make([]string, 0, len(args.Envs))
for k, v := range args.Envs {
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
}
// build arguments for [docker] command
cmdArgs := make([]string, 0, len(ports)+1)
cmdArgs = append(cmdArgs, "run")
if args.Foreground {
cmdArgs = append(cmdArgs, "--rm")
} else {
cmdArgs = append(cmdArgs, "-d")
}
for _, p := range ports {
cmdArgs = append(cmdArgs, "-p")
cmdArgs = append(cmdArgs, p)
}
for _, e := range envs {
cmdArgs = append(cmdArgs, "-e")
cmdArgs = append(cmdArgs, e)
}
if args.Name != "" {
cmdArgs = append(cmdArgs, "--name", args.Name)
}
if args.Network != "" {
cmdArgs = append(cmdArgs, "--net", args.Network)
}
cmdArgs = append(cmdArgs, image)
fmt.Printf("cmdArgs:%+v\n", cmdArgs)
// run container
continerID, err := run("docker", cmdArgs...)
if err != nil {
panic(err)
}
fmt.Printf("start.container.id:%s\n", continerID)
return &Cli{
ID: continerID,
}
}
// Cleanup is cleanup image
func (cli *Cli) Cleanup() {
fmt.Printf("cleanup.container.id:%s\n", cli.ID)
run("docker", "rm", "-f", cli.ID)
}
func run(name string, args ...string) (out string, err error) {
cmd := exec.Command(name, args...)
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}
cmd.Stdout = stdout
cmd.Stderr = stderr
if err = cmd.Run(); err != nil {
return
}
if cmd.ProcessState.Success() {
return strings.TrimSpace(stdout.String()), nil
}
err = errors.New("command execution failed " + stderr.String())
return
}