You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2021/06/24 23:09:15 UTC
[skywalking-infra-e2e] branch main updated: Upgrade docker-compose
framework (#22)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-infra-e2e.git
The following commit(s) were added to refs/heads/main by this push:
new c5d37eb Upgrade docker-compose framework (#22)
c5d37eb is described below
commit c5d37eb3c06aeb9f0ce03638dbfaf5644ac29df8
Author: mrproliu <74...@qq.com>
AuthorDate: Fri Jun 25 07:09:09 2021 +0800
Upgrade docker-compose framework (#22)
---
dist/LICENSE | 5 +-
go.mod | 5 +-
go.sum | 8 +-
internal/components/setup/compose.go | 152 +++++++++++------------------------
4 files changed, 56 insertions(+), 114 deletions(-)
diff --git a/dist/LICENSE b/dist/LICENSE
index e25fc62..018bc6e 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -225,12 +225,13 @@ The text of each license is the standard Apache 2.0 license.
cli-runtime v0.19.0: https://github.com/kubernetes/cli-runtime Apache 2.0
client-go v0.19.0 https://github.com/kubernetes/client-go Apache 2.0
kubectl v0.19.0: https://github.com/kubernetes/kubectl Apache 2.0
- docker v20.10.3: https://github.com/docker/docker Apache 2.0
+ docker v20.10.7: https://github.com/docker/docker Apache 2.0
utils v0.0.0-20201110183641-67b214c5f920: https://github.com/kubernetes/utils Apache 2.0
containerd v1.4.3: https://github.com/containerd/containerd Apache 2.0
go-connections v0.4.0: https://github.com/docker/go-connections Apache 2.0
go-units v0.4.0: https://github.com/docker/go-units Apache 2.0
image-spec v1.0.1: https://github.com/opencontainers/image-spec Apache 2.0
+ go-connections v0.4.0: https://github.com/opencontainers/image-spec Apache 2.0
========================================================================
MIT licenses
@@ -242,7 +243,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
logrus 1.7.0: https://github.com/sirupsen/logrus MIT
go-winio v0.4.16: https://github.com/Microsoft/go-winio MIT
aec v1.0.0: https://github.com/morikuni/aec MIT
- testcontainers-go v0.11.0: https://github.com/testcontainers/testcontainers-go MIT
+ testcontainers-go v0.11.1: https://github.com/testcontainers/testcontainers-go MIT
========================================================================
BSD licenses
diff --git a/go.mod b/go.mod
index c1c3c9d..ce51fdd 100644
--- a/go.mod
+++ b/go.mod
@@ -3,13 +3,14 @@ module github.com/apache/skywalking-infra-e2e
go 1.13
require (
- github.com/docker/docker v20.10.6+incompatible
+ github.com/docker/docker v20.10.7+incompatible
+ github.com/docker/go-connections v0.4.0
github.com/google/go-cmp v0.5.4
github.com/gorilla/mux v1.8.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/sirupsen/logrus v1.7.0
github.com/spf13/cobra v1.1.1
- github.com/testcontainers/testcontainers-go v0.11.0
+ github.com/testcontainers/testcontainers-go v0.11.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.20.7
k8s.io/apimachinery v0.20.7
diff --git a/go.sum b/go.sum
index ef890e0..6257f86 100644
--- a/go.sum
+++ b/go.sum
@@ -215,8 +215,8 @@ github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TT
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ=
-github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
+github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
@@ -642,8 +642,8 @@ github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
-github.com/testcontainers/testcontainers-go v0.11.0 h1:HO5YOx2DYBHqcg4MzVWPj3FuHAv7USWVu94vCSsgiaM=
-github.com/testcontainers/testcontainers-go v0.11.0/go.mod h1:HztBCODzuA+YpMXGK8amjO8j50jz2gcT0BOzSKUiYIs=
+github.com/testcontainers/testcontainers-go v0.11.1 h1:FiYsB83LSGbiawoV8TpAZGfcCUbtaeeg1SXqEKUxh08=
+github.com/testcontainers/testcontainers-go v0.11.1/go.mod h1:/V0UVq+1e7NWYoqTPog179clf0Qp9TOyp4EcXaEFQz8=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
diff --git a/internal/components/setup/compose.go b/internal/components/setup/compose.go
index 31b7aa7..07ec57c 100644
--- a/internal/components/setup/compose.go
+++ b/internal/components/setup/compose.go
@@ -21,12 +21,15 @@ package setup
import (
"context"
"fmt"
- "net"
"os"
"regexp"
- "syscall"
+ "strconv"
+ "strings"
"time"
+ "github.com/docker/go-connections/nat"
+ "github.com/testcontainers/testcontainers-go/wait"
+
"github.com/apache/skywalking-infra-e2e/internal/config"
"github.com/apache/skywalking-infra-e2e/internal/constant"
"github.com/apache/skywalking-infra-e2e/internal/logger"
@@ -57,13 +60,8 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error {
}
identifier := GetIdentity()
compose := testcontainers.NewLocalDockerCompose(composeFilePaths, identifier)
- execError := compose.WithCommand([]string{"up", "-d"}).Invoke()
- if execError.Error != nil {
- return execError.Error
- }
- // record time now
- timeNow := time.Now()
+ // bind wait port
timeout := e2eConfig.Setup.Timeout
var waitTimeout time.Duration
if timeout <= 0 {
@@ -71,16 +69,37 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error {
} else {
waitTimeout = time.Duration(timeout) * time.Second
}
- logger.Log.Debugf("wait timeout is %d seconds", int(waitTimeout.Seconds()))
-
- // find exported port and build env
+ serviceWithPorts := make(map[string][]int)
for service, content := range compose.Services {
serviceConfig := content.(map[interface{}]interface{})
ports := serviceConfig["ports"]
if ports == nil {
continue
}
+ serviceWithPorts[service] = []int{}
+
portList := ports.([]interface{})
+ for inx := range portList {
+ exportPort, err := getExpectPort(portList[inx])
+ if err != nil {
+ return err
+ }
+ serviceWithPorts[service] = append(serviceWithPorts[service], exportPort)
+
+ compose.WithExposedService(
+ service,
+ exportPort,
+ wait.NewHostPortStrategy(nat.Port(fmt.Sprintf("%d/tcp", exportPort))).WithStartupTimeout(waitTimeout))
+ }
+ }
+
+ execError := compose.WithCommand([]string{"up", "-d"}).Invoke()
+ if execError.Error != nil {
+ return execError.Error
+ }
+
+ // find exported port and build env
+ for service, portList := range serviceWithPorts {
container, err := findContainer(cli, fmt.Sprintf("%s_%s", identifier, getInstanceName(service)))
if err != nil {
return err
@@ -89,20 +108,10 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error {
for inx := range portList {
for _, containerPort := range containerPorts {
- if int(containerPort.PrivatePort) != portList[inx].(int) {
+ if int(containerPort.PrivatePort) != portList[inx] {
continue
}
- // calculate max wait time
- waitTimeout = NewTimeout(timeNow, waitTimeout)
- timeNow = time.Now()
-
- // wait port and export
- err := waitTCPPortStarted(context.Background(), cli, container, int(containerPort.PublicPort), int(containerPort.PrivatePort), waitTimeout)
- if err != nil {
- return fmt.Errorf("could wait port exported: %s:%d, %v", service, portList[inx], err)
- }
-
// expose env config to env
// format: <service_name>_<port>
envKey := fmt.Sprintf("%s_%d", service, containerPort.PrivatePort)
@@ -112,6 +121,7 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error {
return fmt.Errorf("could not set env for %s:%d, %v", service, portList[inx], err)
}
logger.Log.Infof("expose env : %s : %s", envKey, envValue)
+ break
}
}
}
@@ -119,6 +129,20 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error {
return nil
}
+func getExpectPort(portConfig interface{}) (int, error) {
+ switch conf := portConfig.(type) {
+ case int:
+ return conf, nil
+ case string:
+ portInfo := strings.Split(conf, ":")
+ if len(portInfo) > 1 {
+ return strconv.Atoi(portInfo[1])
+ }
+ return strconv.Atoi(portInfo[0])
+ }
+ return 0, fmt.Errorf("unknown port information: %v", portConfig)
+}
+
func findContainer(c *client.Client, instanceName string) (*types.Container, error) {
f := filters.NewArgs(filters.Arg("name", instanceName))
containerListOptions := types.ContainerListOptions{Filters: f}
@@ -133,90 +157,6 @@ func findContainer(c *client.Client, instanceName string) (*types.Container, err
return &containers[0], nil
}
-func waitTCPPortStarted(ctx context.Context, c *client.Client, container *types.Container, publicPort, interPort int, timeout time.Duration) error {
- // limit context to startupTimeout
- ctx, cancelContext := context.WithTimeout(ctx, timeout)
- defer cancelContext()
-
- var waitInterval = 100 * time.Millisecond
-
- // external check
- dialer := net.Dialer{}
- address := net.JoinHostPort("127.0.0.1", fmt.Sprintf("%d", publicPort))
- for {
- conn, err := dialer.DialContext(ctx, "tcp", address)
- if err != nil {
- if v, ok := err.(*net.OpError); ok {
- if v2, ok := (v.Err).(*os.SyscallError); ok {
- if isConnRefusedErr(v2.Err) {
- time.Sleep(waitInterval)
- continue
- }
- }
- }
- return err
- }
- conn.Close()
- break
- }
-
- // internal check
- command := buildInternalCheckCommand(interPort)
- for {
- if ctx.Err() != nil {
- return ctx.Err()
- }
- response, err := c.ContainerExecCreate(ctx, container.ID, types.ExecConfig{
- Cmd: []string{"/bin/sh", "-c", command},
- AttachStderr: true,
- AttachStdout: true,
- })
- if err != nil {
- return err
- }
-
- err = c.ContainerExecStart(ctx, response.ID, types.ExecStartCheck{
- Detach: false,
- })
- if err != nil {
- return err
- }
-
- var exitCode int
- for {
- execResp, err := c.ContainerExecInspect(ctx, response.ID)
- if err != nil {
- return err
- }
-
- if !execResp.Running {
- exitCode = execResp.ExitCode
- break
- }
-
- time.Sleep(waitInterval)
- }
-
- if exitCode == 0 {
- return nil
- }
- }
-}
-
-func buildInternalCheckCommand(internalPort int) string {
- command := `(
- nc -vz -w 1 localhost %d ||
- cat /proc/net/tcp | awk '{print $2}' | grep -i :%d ||
- </dev/tcp/localhost/%d
- )
- `
- return "true && " + fmt.Sprintf(command, internalPort, internalPort, internalPort)
-}
-
-func isConnRefusedErr(err error) bool {
- return err == syscall.ECONNREFUSED
-}
-
func getInstanceName(serviceName string) string {
match, err := regexp.MatchString(".*_[0-9]+", serviceName)
if err != nil {