Skip to content

Commit f45afae

Browse files
committed
WIP
1 parent 8c16f55 commit f45afae

File tree

7 files changed

+120
-25
lines changed

7 files changed

+120
-25
lines changed

internal/services/icinga2/docker.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/docker/docker/api/types/container"
99
"github.com/docker/docker/api/types/network"
1010
"github.com/docker/docker/client"
11+
"github.com/docker/go-connections/nat"
1112
"github.com/icinga/icinga-testing/services"
1213
"github.com/icinga/icinga-testing/utils"
1314
"go.uber.org/zap"
@@ -16,6 +17,8 @@ import (
1617
"time"
1718
)
1819

20+
const PORT = "5665"
21+
1922
type dockerCreator struct {
2023
logger *zap.Logger
2124
dockerClient *client.Client
@@ -59,10 +62,15 @@ func (i *dockerCreator) CreateIcinga2(name string) services.Icinga2Base {
5962
panic(err)
6063
}
6164

65+
port := utils.NewPortDecision(i.dockerClient, PORT)
66+
6267
cont, err := i.dockerClient.ContainerCreate(context.Background(), &container.Config{
68+
ExposedPorts: nat.PortSet{
69+
nat.Port(fmt.Sprintf("%s/tcp", PORT)): struct{}{},
70+
},
6371
Image: dockerImage,
6472
Env: []string{"ICINGA_MASTER=1"},
65-
}, nil, &network.NetworkingConfig{
73+
}, &container.HostConfig{PortBindings: port.Map()}, &network.NetworkingConfig{
6674
EndpointsConfig: map[string]*network.EndpointSettings{
6775
networkName: {
6876
NetworkID: i.dockerNetworkId,
@@ -91,8 +99,8 @@ func (i *dockerCreator) CreateIcinga2(name string) services.Icinga2Base {
9199

92100
n := &dockerInstance{
93101
info: info{
94-
host: utils.MustString(utils.DockerContainerAddress(context.Background(), i.dockerClient, cont.ID)),
95-
port: "5665",
102+
host: port.Address(context.Background(), i.dockerClient, cont.ID),
103+
port: port.Port(),
96104
},
97105
icinga2Docker: i,
98106
logger: logger,

internal/services/icingadb/docker_binary.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func (i *dockerBinaryCreator) CreateIcingaDb(
6868

6969
services.MysqlDatabase{MysqlDatabaseBase: mysql}.ImportIcingaDbSchema()
7070

71-
configFile, err := ioutil.TempFile("", "icingadb.yml")
71+
configFile, err := ioutil.TempFile(filepath.Dir(i.binaryPath), "icingadb.yml")
7272
if err != nil {
7373
panic(err)
7474
}
@@ -118,7 +118,7 @@ func (i *dockerBinaryCreator) CreateIcingaDb(
118118
},
119119
}, nil, containerName)
120120
if err != nil {
121-
inst.logger.Fatal("failed to create icingadb container")
121+
inst.logger.Fatal("failed to create icingadb container", zap.Error(err))
122122
}
123123
inst.containerId = cont.ID
124124
inst.logger = inst.logger.With(zap.String("container-id", cont.ID))
@@ -136,7 +136,7 @@ func (i *dockerBinaryCreator) CreateIcingaDb(
136136

137137
err = i.dockerClient.ContainerStart(context.Background(), cont.ID, types.ContainerStartOptions{})
138138
if err != nil {
139-
inst.logger.Fatal("failed to start container")
139+
inst.logger.Fatal("failed to start container", zap.Error(err))
140140
}
141141
inst.logger.Debug("started container")
142142

internal/services/mysql/docker.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"time"
1212
)
1313

14+
const PORT = "3306"
15+
1416
type dockerCreator struct {
1517
*rootConnection
1618
logger *zap.Logger
@@ -38,13 +40,14 @@ func NewDockerCreator(logger *zap.Logger, dockerClient *client.Client, container
3840
panic(err)
3941
}
4042

43+
port := utils.NewPortDecision(dockerClient, PORT)
44+
4145
rootPassword := utils.RandomString(16)
4246
cont, err := dockerClient.ContainerCreate(context.Background(), &container.Config{
43-
ExposedPorts: nil,
44-
Env: []string{"MYSQL_ROOT_PASSWORD=" + rootPassword},
45-
Cmd: nil,
46-
Image: dockerImage,
47-
}, nil, &network.NetworkingConfig{
47+
Env: []string{"MYSQL_ROOT_PASSWORD=" + rootPassword},
48+
Cmd: nil,
49+
Image: dockerImage,
50+
}, &container.HostConfig{PortBindings: port.Map()}, &network.NetworkingConfig{
4851
EndpointsConfig: map[string]*network.EndpointSettings{
4952
networkName: {
5053
Aliases: []string{"mysql"},
@@ -73,14 +76,14 @@ func NewDockerCreator(logger *zap.Logger, dockerClient *client.Client, container
7376
}
7477
logger.Debug("started mysql container")
7578

76-
containerAddress := utils.MustString(utils.DockerContainerAddress(context.Background(), dockerClient, cont.ID))
77-
7879
d := &dockerCreator{
79-
rootConnection: newRootConnection(containerAddress, "3306", "root", rootPassword),
80-
logger: logger,
81-
client: dockerClient,
82-
containerId: cont.ID,
83-
containerName: containerName,
80+
rootConnection: newRootConnection(
81+
port.Address(context.Background(), dockerClient, cont.ID), port.Port(), "root", rootPassword,
82+
),
83+
logger: logger,
84+
client: dockerClient,
85+
containerId: cont.ID,
86+
containerName: containerName,
8487
}
8588

8689
for attempt := 1; ; attempt++ {

internal/services/redis/docker.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"time"
1616
)
1717

18+
const PORT = "6379"
19+
1820
type dockerCreator struct {
1921
logger *zap.Logger
2022
dockerClient *client.Client
@@ -55,9 +57,11 @@ func (r *dockerCreator) CreateRedisServer() services.RedisServerBase {
5557
panic(err)
5658
}
5759

60+
port := utils.NewPortDecision(r.dockerClient, PORT)
61+
5862
cont, err := r.dockerClient.ContainerCreate(context.Background(), &container.Config{
5963
Image: dockerImage,
60-
}, nil, &network.NetworkingConfig{
64+
}, &container.HostConfig{PortBindings: port.Map()}, &network.NetworkingConfig{
6165
EndpointsConfig: map[string]*network.EndpointSettings{
6266
networkName: {
6367
NetworkID: r.dockerNetworkId,
@@ -82,14 +86,14 @@ func (r *dockerCreator) CreateRedisServer() services.RedisServerBase {
8286

8387
err = r.dockerClient.ContainerStart(context.Background(), cont.ID, types.ContainerStartOptions{})
8488
if err != nil {
85-
logger.Fatal("failed to start container")
89+
logger.Fatal("failed to start container", zap.Error(err))
8690
}
8791
logger.Debug("started container")
8892

8993
s := &dockerServer{
9094
info: info{
91-
host: utils.MustString(utils.DockerContainerAddress(context.Background(), r.dockerClient, cont.ID)),
92-
port: "6379",
95+
host: port.Address(context.Background(), r.dockerClient, cont.ID),
96+
port: port.Port(),
9397
},
9498
redisDocker: r,
9599
logger: logger,

it.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func NewIT() *IT {
7070
})
7171
}
7272

73-
if n, err := it.dockerClient.NetworkCreate(context.Background(), it.prefix, types.NetworkCreate{}); err != nil {
73+
if n, err := it.dockerClient.NetworkCreate(context.Background(), it.prefix, types.NetworkCreate{Labels: map[string]string{"icinga": "testing"}}); err != nil {
7474
it.logger.Fatal("failed to create docker network", zap.String("network-name", it.prefix), zap.Error(err))
7575
} else {
7676
it.logger.Debug("created docker network", zap.String("network-name", it.prefix), zap.String("network-id", n.ID))

utils/docker.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"io"
1212
)
1313

14-
func DockerContainerAddress(ctx context.Context, client *client.Client, id string) (string, error) {
15-
info, err := client.ContainerInspect(ctx, id)
14+
func DockerContainerAddress(ctx context.Context, _client *client.Client, id string) (string, error) {
15+
info, err := _client.ContainerInspect(ctx, id)
1616
if err != nil {
1717
return "", err
1818
}

utils/port.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package utils
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/docker/docker/client"
7+
"github.com/docker/go-connections/nat"
8+
"net"
9+
"strconv"
10+
)
11+
12+
type PortDecision struct {
13+
dockerHost string
14+
exposed string
15+
port string
16+
remote bool
17+
}
18+
19+
func NewPortDecision(c *client.Client, port string) *PortDecision {
20+
url, err := client.ParseHostURL(c.DaemonHost())
21+
if err != nil {
22+
panic(err)
23+
}
24+
p := &PortDecision{port: port}
25+
if url.Scheme != "unix" {
26+
portNumber, err := GetFreePort()
27+
if err != nil {
28+
panic(err)
29+
}
30+
p.dockerHost = url.Hostname()
31+
p.exposed = strconv.Itoa(portNumber)
32+
p.remote = true
33+
} else {
34+
p.exposed = port
35+
}
36+
37+
return p
38+
}
39+
40+
func (p *PortDecision) Address(ctx context.Context, c *client.Client, id string) string {
41+
if p.remote {
42+
return p.dockerHost
43+
}
44+
45+
return MustString(DockerContainerAddress(ctx, c, id))
46+
}
47+
48+
func (p *PortDecision) Map() nat.PortMap {
49+
if p.remote {
50+
return nat.PortMap{
51+
nat.Port(fmt.Sprintf("%s/tcp", p.port)): []nat.PortBinding{
52+
{
53+
HostIP: "0.0.0.0",
54+
HostPort: p.exposed,
55+
},
56+
},
57+
}
58+
}
59+
60+
return nil
61+
}
62+
63+
func (p *PortDecision) Port() string {
64+
return p.exposed
65+
}
66+
67+
func GetFreePort() (int, error) {
68+
addr, err := net.ResolveTCPAddr("tcp", ":0")
69+
if err != nil {
70+
return 0, err
71+
}
72+
73+
l, err := net.ListenTCP("tcp", addr)
74+
if err != nil {
75+
return 0, err
76+
}
77+
defer l.Close()
78+
79+
return l.Addr().(*net.TCPAddr).Port, nil
80+
}

0 commit comments

Comments
 (0)