-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Tommi2Day
committed
Sep 4, 2024
1 parent
788fd1a
commit d4be938
Showing
10 changed files
with
322 additions
and
219 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,159 +1,197 @@ | ||
package dblib | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net" | ||
"os" | ||
"time" | ||
|
||
"github.com/tommi2day/gomodules/common" | ||
"github.com/tommi2day/gomodules/netlib" | ||
"github.com/tommi2day/gomodules/test" | ||
|
||
"github.com/ory/dockertest/v3" | ||
"github.com/ory/dockertest/v3/docker" | ||
"github.com/tommi2day/gomodules/common" | ||
) | ||
|
||
"github.com/tommi2day/gomodules/test" | ||
const ( | ||
dblibDNSContainerTimeout = 10 | ||
dblibNetworkName = "dblib-dns" | ||
dblibNetworkPrefix = "172.24.0" | ||
dblibRepoTag = "9.20" | ||
dblibDNSPort = 9054 | ||
dblibTestAddr = racaddr | ||
) | ||
|
||
var ( | ||
dblibDNSContainerName string | ||
dblibDNSContainer *dockertest.Resource | ||
dblibDNSNetwork *dockertest.Network | ||
dblibDNSNetworkCreated = false | ||
dblibDNSServer = "127.0.0.1" | ||
) | ||
|
||
const dblibDNSContainerTimeout = 10 | ||
const dblibNetworkName = "dblib-dns" | ||
const dblibNetworkPrefix = "172.24.0" | ||
const dblibRepoTag = "9.20" | ||
|
||
var dblibDNSContainerName string | ||
var dblibDNSContainer *dockertest.Resource | ||
var dblibDNSNetwork *dockertest.Network | ||
var dblibNetworkCreated = false | ||
var dblibDNSServer = "" | ||
var dblibDNSPort = 0 | ||
|
||
// prepareDNSContainer create a Bind9 Docker Container | ||
func prepareDNSContainer() (container *dockertest.Resource, err error) { | ||
if os.Getenv("SKIP_DNS") != "" { | ||
err = fmt.Errorf("skipping DNS Container in CI environment") | ||
// prepareDBlibDNSContainer create a Bind9 Docker Container | ||
func prepareDBlibDNSContainer() (container *dockertest.Resource, err error) { | ||
if os.Getenv("SKIP_DB_DNS") != "" { | ||
return nil, fmt.Errorf("skipping DB DNS Container in CI environment") | ||
} | ||
|
||
dblibDNSContainerName = getContainerName() | ||
pool, err := common.GetDockerPool() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = setupNetwork(pool) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
container, err = buildAndRunContainer(pool) | ||
if err != nil { | ||
return | ||
} | ||
dblibDNSContainerName = os.Getenv("DNS_CONTAINER_NAME") | ||
if dblibDNSContainerName == "" { | ||
dblibDNSContainerName = "dblib-bind9" | ||
|
||
time.Sleep(10 * time.Second) | ||
|
||
err = validateContainerIP(container) | ||
if err != nil { | ||
return | ||
} | ||
var pool *dockertest.Pool | ||
pool, err = common.GetDockerPool() | ||
|
||
err = waitForDNSServer(pool) | ||
if err != nil { | ||
return | ||
} | ||
|
||
err = testDNSResolution() | ||
return | ||
} | ||
|
||
func getContainerName() string { | ||
name := os.Getenv("DBDNS_CONTAINER_NAME") | ||
if name == "" { | ||
name = "dblib-bind9" | ||
} | ||
return name | ||
} | ||
|
||
func setupNetwork(pool *dockertest.Pool) error { | ||
networks, err := pool.NetworksByName(dblibNetworkName) | ||
if err != nil || len(networks) == 0 { | ||
dblibDNSNetwork, err = pool.CreateNetwork(dblibNetworkName, func(options *docker.CreateNetworkOptions) { | ||
options.Name = dblibNetworkName | ||
options.CheckDuplicate = true | ||
options.IPAM = &docker.IPAMOptions{ | ||
Driver: "default", | ||
Config: []docker.IPAMConfig{{ | ||
Subnet: dblibNetworkPrefix + ".0/24", | ||
Gateway: dblibNetworkPrefix + ".1", | ||
}}, | ||
} | ||
options.EnableIPv6 = false | ||
// options.Internal = true | ||
}) | ||
if err != nil { | ||
err = fmt.Errorf("could not create Network: %s:%s", dblibNetworkName, err) | ||
return | ||
return createNetwork(pool) | ||
} | ||
dblibDNSNetwork = &networks[0] | ||
return nil | ||
} | ||
|
||
func createNetwork(pool *dockertest.Pool) error { | ||
var err error | ||
dblibDNSNetwork, err = pool.CreateNetwork(dblibNetworkName, func(options *docker.CreateNetworkOptions) { | ||
options.Name = dblibNetworkName | ||
options.CheckDuplicate = true | ||
options.IPAM = &docker.IPAMOptions{ | ||
Driver: "default", | ||
Config: []docker.IPAMConfig{{ | ||
Subnet: dblibNetworkPrefix + ".0/24", | ||
Gateway: dblibNetworkPrefix + ".1", | ||
}}, | ||
} | ||
dblibNetworkCreated = true | ||
} else { | ||
dblibDNSNetwork = &networks[0] | ||
options.EnableIPv6 = false | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("could not create Network: %s:%s", dblibNetworkName, err) | ||
} | ||
dblibDNSNetworkCreated = true | ||
return nil | ||
} | ||
|
||
func buildAndRunContainer(pool *dockertest.Pool) (*dockertest.Resource, error) { | ||
vendorImagePrefix := os.Getenv("VENDOR_IMAGE_PREFIX") | ||
|
||
fmt.Printf("Try to build and start docker container %s\n", dblibDNSContainerName) | ||
fmt.Printf("Try to build and start docker container %s\n", dblibDNSContainerName) | ||
buildArgs := []docker.BuildArg{ | ||
{ | ||
Name: "VENDOR_IMAGE_PREFIX", | ||
Value: vendorImagePrefix, | ||
}, | ||
{ | ||
Name: "BIND9_VERSION", | ||
Value: dblibRepoTag, | ||
}, | ||
{Name: "VENDOR_IMAGE_PREFIX", Value: vendorImagePrefix}, | ||
{Name: "BIND9_VERSION", Value: dblibRepoTag}, | ||
} | ||
container, err = pool.BuildAndRunWithBuildOptions( | ||
|
||
dockerContextDir := test.TestDir + "/docker/oracle-dns" | ||
return pool.BuildAndRunWithBuildOptions( | ||
&dockertest.BuildOptions{ | ||
BuildArgs: buildArgs, | ||
ContextDir: test.TestDir + "/docker/oracle-dns", | ||
ContextDir: dockerContextDir, | ||
Dockerfile: "Dockerfile", | ||
}, | ||
&dockertest.RunOptions{ | ||
Hostname: dblibDNSContainerName, | ||
Name: dblibDNSContainerName, | ||
Networks: []*dockertest.Network{dblibDNSNetwork}, | ||
ExposedPorts: []string{"53/tcp", "53/udp", "953/tcp"}, | ||
ExposedPorts: []string{"9054/tcp"}, | ||
// need fixed mapping here | ||
PortBindings: map[docker.Port][]docker.PortBinding{ | ||
"9054/tcp": { | ||
{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", dblibDNSPort)}, | ||
}, | ||
}, | ||
}, func(config *docker.HostConfig) { | ||
// set AutoRemove to true so that stopped container goes away by itself | ||
config.AutoRemove = true | ||
config.AutoRemove = false | ||
config.RestartPolicy = docker.RestartPolicy{Name: "no"} | ||
}) | ||
} | ||
|
||
if err != nil || container == nil { | ||
err = fmt.Errorf("error starting oracle-dns docker container: %v", err) | ||
return | ||
} | ||
// ip := container.Container.NetworkSettings.Networks[dblibNetworkName].IPAddress | ||
func validateContainerIP(container *dockertest.Resource) error { | ||
ip := container.GetIPInNetwork(dblibDNSNetwork) | ||
if ip != dblibNetworkPrefix+".2" { | ||
err = fmt.Errorf("internal ip not as expected: %s", ip) | ||
return | ||
} | ||
|
||
fmt.Printf("DB DNS Container IP: %s\n", ip) | ||
return nil | ||
} | ||
|
||
// func waitForDNSServer(pool *dockertest.Pool, container *dockertest.Resource) error { | ||
func waitForDNSServer(pool *dockertest.Pool) error { | ||
pool.MaxWait = dblibDNSContainerTimeout * time.Second | ||
dblibDNSServer, dblibDNSPort = common.GetContainerHostAndPort(container, "53/tcp") | ||
if dblibDNSPort == 0 || dblibDNSServer == "" { | ||
err = fmt.Errorf("could not get host/port of dns container") | ||
return | ||
} | ||
fmt.Printf("Wait to successfully connect to DNS to %s:%d (max %ds)...\n", dblibDNSServer, dblibDNSPort, dblibDNSContainerTimeout) | ||
start := time.Now() | ||
var c net.Conn | ||
if err = pool.Retry(func() error { | ||
c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", dblibDNSServer, dblibDNSPort)) | ||
err := pool.Retry(func() error { | ||
c, err := net.Dial("udp", fmt.Sprintf("%s:%d", dblibDNSServer, dblibDNSPort)) | ||
if err != nil { | ||
fmt.Printf("Err:%s\n", err) | ||
return err | ||
} | ||
return err | ||
}); err != nil { | ||
err = fmt.Errorf("could not connect to DNS Container: %d", err) | ||
return | ||
_ = c.Close() | ||
return nil | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("could not connect to DB DNS Container: %v", err) | ||
} | ||
_ = c.Close() | ||
|
||
// wait 10s to init container | ||
time.Sleep(10 * time.Second) | ||
elapsed := time.Since(start) | ||
fmt.Printf("DNS Container is available after %s\n", elapsed.Round(time.Millisecond)) | ||
if dblibDNSServer == "localhost" { | ||
dblibDNSServer = "127.0.0.1" | ||
} | ||
// fmt.Printf("DNS Container is available after %s\n", elapsed.Round(time.Millisecond)) | ||
// test dns | ||
fmt.Println("DB DNS Container is ready after ", elapsed.Round(time.Millisecond)) | ||
return nil | ||
} | ||
|
||
func testDNSResolution() error { | ||
dns := netlib.NewResolver(dblibDNSServer, dblibDNSPort, true) | ||
ips, e := dns.Resolver.LookupHost(context.Background(), racaddr) | ||
if e != nil || len(ips) == 0 { | ||
err = fmt.Errorf("could not resolve DNS for %s on %s:%d: %v", racaddr, dblibDNSServer, dblibDNSPort, e) | ||
return | ||
dns.IPv4Only = true | ||
s := "/udp" | ||
if dns.TCP { | ||
s = "/tcp" | ||
} | ||
fmt.Println("DNS Container is ready after ", elapsed.Round(time.Millisecond), ", host ", racaddr, "resolved to", ips[0]) | ||
err = nil | ||
return | ||
fmt.Printf("resolve on %s:%d%s\n", dns.Nameserver, dns.Port, s) | ||
ips, err := dns.LookupIP(dblibTestAddr) | ||
if err != nil || len(ips) == 0 { | ||
return fmt.Errorf("could not resolve DNS for %s: %v", dblibTestAddr, err) | ||
} | ||
fmt.Printf("Host %s resolved to %s\n", dblibTestAddr, ips[0]) | ||
return nil | ||
} | ||
|
||
func destroyDNSContainer(container *dockertest.Resource) { | ||
if container != nil { | ||
common.DestroyDockerContainer(container) | ||
} | ||
|
||
if dblibNetworkCreated && dblibDNSNetwork != nil { | ||
if dblibDNSNetworkCreated && dblibDNSNetwork != nil { | ||
_ = dblibDNSNetwork.Close() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.