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"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
const (
fixedDockerVersion = "1.38"
)
var (
dockerCtx context.Context
dockerCLI *client.Client
)
func setupContext() {
if dockerCtx == nil {
dockerCtx = context.Background()
}
}
func setupDockerCLI() (err error) {
os.Setenv("DOCKER_API_VERSION", "1.27")
if dockerCLI == nil {
dockerCLI, err = client.NewEnvClient()
}
return err
}
func listDockerContainers() {
log.Println("listing the docker containers...")
// setup the context and the docker cli connection
setupContext()
setupDockerCLI()
// get a list of all networks
networks, err := dockerCLI.NetworkList(context.Background(), types.NetworkListOptions{})
if err != nil {
panic(err)
}
// get a list of all containers
containers, err := dockerCLI.ContainerList(context.Background(), types.ContainerListOptions{})
if err != nil {
panic(err)
}
// find the container names of the companion containers by iterating over
// all containers adding the containers containing the string "companion" in
// their names to the list of companion containers
var companionContainerNames []string
for _, container := range containers {
if strings.Contains(container.Image, "companion") {
companionContainerNames = append(companionContainerNames, container.Names[0][1:])
}
}
fmt.Printf("%#v\n\n", companionContainerNames)
// find the IPs of the companion containers by iterating over all networks,
// then iterating over all containers in the network and then testing if the
// container is part of the previously generated companion-containers-list.
var companionContainerIPs []string
for _, network := range networks {
for _, container := range network.Containers {
for _, name := range companionContainerNames {
if container.Name == name {
companionContainerIPs = append(companionContainerIPs, container.IPv4Address)
}
}
}
}
fmt.Printf("%#v\n\n", companionContainerIPs)
// print all ips found
for _, rawip := range companionContainerIPs {
// if the ip starts with 172, it's the right one!
if strings.Compare(rawip[0:3], "172") == 0 {
// strip the "/16" or so suffix (this might break, see the todo
// below...)
// TODO: strip everything after the slash and the slash
ip := rawip[:len(rawip)-3]
fmt.Printf("ip: %s\n\n", ip)
// get the stats from the container
stats, err := getStats(ip, 8080)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s\n", stats)
}
}
}
// getStats makes an http request to the container with the given ip and port
// returning the result of the request to the /api/getStats endpoint
func getStats(containerName string, containerPort uint16) (string, error) {
// define the url where the request should go
url := fmt.Sprintf("http://%s:%d/api/getStats", containerName, containerPort)
log.Printf("url: %s", url)
// make the request
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("could not make the http get request: %v", err)
}
defer resp.Body.Close()
// read the response body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("could not read the request body: %v", err)
}
// returns the stats
return string(body), nil
}
|