From 8b4824b87687ee88896365234dac7e2bc7d626de Mon Sep 17 00:00:00 2001 From: marioevz Date: Fri, 15 Jul 2022 21:34:31 +0000 Subject: [PATCH] libhive, libdocker: Add client multiple port check --- internal/libdocker/container.go | 32 ++++++++++++++++++++++++-------- internal/libhive/api.go | 19 ++++++++++++------- internal/libhive/dockerface.go | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/internal/libdocker/container.go b/internal/libdocker/container.go index 849bd7bae4..9fd47942bd 100644 --- a/internal/libdocker/container.go +++ b/internal/libdocker/container.go @@ -117,7 +117,7 @@ func (b *ContainerBackend) CreateContainer(ctx context.Context, imageName string // StartContainer starts a docker container. func (b *ContainerBackend) StartContainer(ctx context.Context, containerID string, opt libhive.ContainerOptions) (*libhive.ContainerInfo, error) { - if opt.CheckLive != 0 && b.proxy == nil { + if opt.CheckLive != nil && b.proxy == nil { panic("attempt to start container with CheckLive, but proxy is not running") } @@ -158,18 +158,34 @@ func (b *ContainerBackend) StartContainer(ctx context.Context, containerID strin info.IP = container.NetworkSettings.IPAddress info.MAC = container.NetworkSettings.MacAddress - // Set up the port check if requested. + // Set up ports check if requested. hasStarted := make(chan struct{}) - if opt.CheckLive != 0 { + if opt.CheckLive != nil && len(opt.CheckLive) > 0 && opt.CheckLive[0] != 0 { + var ( + wg sync.WaitGroup + errors = make(chan error, len(opt.CheckLive)) + ) ctx, cancel := context.WithCancel(ctx) defer cancel() - addr := &net.TCPAddr{IP: net.ParseIP(info.IP), Port: int(opt.CheckLive)} - go func() { - err := b.proxy.CheckLive(ctx, addr) - if err == nil { + for _, port := range opt.CheckLive { + wg.Add(1) + addr := &net.TCPAddr{IP: net.ParseIP(info.IP), Port: int(port)} + go func(wg *sync.WaitGroup) { + defer wg.Done() + if err := b.proxy.CheckLive(ctx, addr); err != nil { + errors <- err + } + }(&wg) + } + go func(wg *sync.WaitGroup) { + wg.Wait() + select { + case err := <-errors: + logger.Error("error checking live ports", err) + default: close(hasStarted) } - }() + }(&wg) } else { close(hasStarted) } diff --git a/internal/libhive/api.go b/internal/libhive/api.go index 27223957bf..0f0eebe482 100644 --- a/internal/libhive/api.go +++ b/internal/libhive/api.go @@ -265,15 +265,20 @@ func (api *simAPI) startClient(w http.ResponseWriter, r *http.Request) { } // by default: check the eth1 port - options.CheckLive = 8545 + options.CheckLive = []uint16{ + 8545, + } if portStr := env["HIVE_CHECK_LIVE_PORT"]; portStr != "" { - v, err := strconv.ParseUint(portStr, 10, 16) - if err != nil { - log15.Error("API: could not parse check-live port", "error", err) - serveError(w, err, http.StatusBadRequest) - return + options.CheckLive = make([]uint16, 0) + for _, pStr := range strings.Split(portStr, ",") { + v, err := strconv.ParseUint(pStr, 10, 16) + if err != nil { + log15.Error("API: could not parse check-live port", "error", err) + serveError(w, err, http.StatusBadRequest) + return + } + options.CheckLive = append(options.CheckLive, uint16(v)) } - options.CheckLive = uint16(v) } // Start it! diff --git a/internal/libhive/dockerface.go b/internal/libhive/dockerface.go index 5b21d2de28..db00d2f5b5 100644 --- a/internal/libhive/dockerface.go +++ b/internal/libhive/dockerface.go @@ -51,7 +51,7 @@ type ContainerOptions struct { Files map[string]*multipart.FileHeader // This requests checking for the given TCP port to be opened by the container. - CheckLive uint16 + CheckLive []uint16 // Output: if LogFile is set, container stdin and stderr is redirected to the // given log file. If Output is set, stdout is redirected to the writer. These