-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
132 lines (113 loc) · 3.46 KB
/
main.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
package main
import (
"context"
"io"
"os"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
)
func main() {
ctx := context.Background()
// Get a Docker API client
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
panic(err)
}
// Download the Docker images we'll use
curlImage := "curlimages/curl"
httpBinImage := "mccutchen/go-httpbin"
images := []string{curlImage, httpBinImage}
for _, image := range images {
reader, err := apiClient.ImagePull(ctx, image, types.ImagePullOptions{})
if err != nil {
panic(err)
}
// Log the download
io.Copy(os.Stdout, reader)
}
// This is the "alias" for the httpbin container on
// our user-defined network.
httpBinDNSName := "httpbin"
// Config for httpbin
httpBinConfig := &container.Config{
Image: httpBinImage,
Tty: false,
}
// Config for Curl
curlConfig := &container.Config{
Image: "curlimages/curl:latest",
Cmd: []string{"curl", "http://" + httpBinDNSName + ":8080/get?foo=bar"},
Tty: false,
}
// Create a user defined network. Each of our containers
// will be attached to this network.
networkID := "kljensen-golang-docker-link"
networkCreate := types.NetworkCreate{
Attachable: true,
CheckDuplicate: true,
}
networkResult, err := apiClient.NetworkCreate(ctx, networkID, networkCreate)
if err != nil {
panic(err)
}
// Remove the network on panic or when `main` returns
defer apiClient.NetworkRemove(ctx, networkResult.ID)
// Create network config for the curl Docker container
curlNetworkConfig := &network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
// I don't think the "net" key matters here. I believe
// it could just as easily be "foo" or "blah".
"net": {
NetworkID: networkResult.ID,
},
},
}
// Create Docker config for the httpbin Docker container.
// Notice how it is given an alias.
httpBinNetworkConfig := &network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
"net": {
Aliases: []string{httpBinDNSName},
NetworkID: networkResult.ID,
},
},
}
// Create and start the httpbin container
httpBinResp, err := apiClient.ContainerCreate(ctx, httpBinConfig, nil, httpBinNetworkConfig, nil, "")
if err != nil {
panic(err)
}
if err := apiClient.ContainerStart(ctx, httpBinResp.ID, types.ContainerStartOptions{}); err != nil {
panic(err)
}
// Stop the httpbin container on panic or when `main` returns
timeout := 5 * time.Second
defer apiClient.ContainerStop(ctx, httpBinResp.ID, &timeout)
// Create and start the curl container
curlResp, err := apiClient.ContainerCreate(ctx, curlConfig, nil, curlNetworkConfig, nil, "")
if err != nil {
panic(err)
}
if err := apiClient.ContainerStart(ctx, curlResp.ID, types.ContainerStartOptions{}); err != nil {
panic(err)
}
// Wait for the curl request to end and its container to stop
statusCh, errCh := apiClient.ContainerWait(ctx, curlResp.ID, container.WaitConditionNotRunning)
select {
case err := <-errCh:
if err != nil {
panic(err)
}
case <-statusCh:
}
// Grab the curl logs and echo them to stdout
out, err := apiClient.ContainerLogs(ctx, curlResp.ID, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true})
if err != nil {
panic(err)
}
stdcopy.StdCopy(os.Stdout, os.Stderr, out)
}