-
Notifications
You must be signed in to change notification settings - Fork 1
/
docker.go
142 lines (118 loc) · 3.33 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
package docker
import (
"context"
"fmt"
"io"
"os"
"time"
"github.com/arielizuardi/envase/provider"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
)
const (
// DefaultDockerLibraryURL host
DefaultDockerLibraryURL = `docker.io/library/`
)
type dockerImageProvider struct {
Ctx context.Context
DockerClient *client.Client
ImageName string
Host string
ContainerPort string
ExposedPort string
ContainerName string
ContainerID string
EnvConfig []string
}
func (i *dockerImageProvider) Has() (bool, error) {
images, err := i.DockerClient.ImageList(i.Ctx, types.ImageListOptions{})
if err != nil {
return false, err
}
for _, image := range images {
for _, t := range image.RepoTags {
if t == i.ImageName {
fmt.Printf(">>> Found image [%v]\n", i.ImageName)
return true, nil
}
}
}
return false, nil
}
func (i *dockerImageProvider) Pull() error {
fmt.Printf(`>>> Pulling image [%v] ...`+"\n", i.ImageName)
imageURL := DefaultDockerLibraryURL + i.ImageName
out, err := i.DockerClient.ImagePull(i.Ctx, imageURL, types.ImagePullOptions{})
if err != nil {
return err
}
io.Copy(os.Stdout, out)
fmt.Printf(`>>> Finished pulling image [%v]`+"\n", i.ImageName)
return nil
}
func (i *dockerImageProvider) Status() (bool, bool, string, error) {
imageCreated := false
imageRunning := false
containers, err := i.DockerClient.ContainerList(i.Ctx, types.ContainerListOptions{All: true})
if err != nil {
return imageCreated, imageRunning, i.ContainerID, err
}
for _, container := range containers {
if container.Image == i.ImageName {
imageCreated = true
if container.State == `running` {
imageRunning = true
}
i.ContainerID = container.ID
}
}
return imageCreated, imageRunning, i.ContainerID, nil
}
func (i *dockerImageProvider) Create() (string, error) {
exposedPorts, portBindings, err := nat.ParsePortSpecs([]string{i.Host + `:` + i.ExposedPort + `:` + i.ContainerPort + `/tcp`})
if err != nil {
return ``, err
}
containerCreated, err := i.DockerClient.ContainerCreate(
i.Ctx,
&container.Config{
Image: i.ImageName,
ExposedPorts: exposedPorts,
Env: i.EnvConfig,
},
&container.HostConfig{
PortBindings: portBindings,
},
nil,
i.ContainerName,
)
if err != nil {
return ``, err
}
return containerCreated.ID, nil
}
func (i *dockerImageProvider) Start(containerID string) error {
return i.DockerClient.ContainerStart(i.Ctx, containerID, types.ContainerStartOptions{})
}
func (i *dockerImageProvider) Stop(containerID string) error {
dur := time.Duration(30) * time.Second
if err := i.DockerClient.ContainerStop(i.Ctx, containerID, &dur); err != nil {
return err
}
return nil
}
// NewDockerImageProvider returns new instance of docker image provider
func NewDockerImageProvider(ctx context.Context, dockerClient *client.Client, imageName string, host string, containerPort string, exposedPort string, containerName string, envConfig []string) provider.ImageProvider {
return &dockerImageProvider{
Ctx: ctx,
DockerClient: dockerClient,
ImageName: imageName,
Host: host,
ContainerPort: containerPort,
ExposedPort: exposedPort,
ContainerName: containerName,
EnvConfig: envConfig,
}
}