Worker: test all discovered Manager URLs
Ping each discovered Manager URL to see whether it is reachable or not. If there are multiple usable URLs, it'll just pick the first.
This commit is contained in:
parent
d6a60c73d0
commit
ae892ff712
@ -4,6 +4,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -19,7 +20,9 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"git.blender.org/flamenco/internal/appinfo"
|
"git.blender.org/flamenco/internal/appinfo"
|
||||||
|
"git.blender.org/flamenco/internal/upnp_ssdp"
|
||||||
"git.blender.org/flamenco/internal/worker"
|
"git.blender.org/flamenco/internal/worker"
|
||||||
|
"git.blender.org/flamenco/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -58,6 +61,7 @@ func main() {
|
|||||||
configLogLevel()
|
configLogLevel()
|
||||||
|
|
||||||
configWrangler := worker.NewConfigWrangler()
|
configWrangler := worker.NewConfigWrangler()
|
||||||
|
maybeAutodiscoverManager(&configWrangler)
|
||||||
|
|
||||||
// Startup can take arbitrarily long, as it only ends when the Manager can be
|
// Startup can take arbitrarily long, as it only ends when the Manager can be
|
||||||
// reached and accepts our sign-on request. An offline Manager would cause the
|
// reached and accepts our sign-on request. An offline Manager would cause the
|
||||||
@ -180,3 +184,99 @@ func upstreamBufferOrDie(client worker.FlamencoClient, timeService clock.Clock)
|
|||||||
|
|
||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maybeAutodiscoverManager starts Manager auto-discovery if there is no Manager URL configured yet.
|
||||||
|
func maybeAutodiscoverManager(configWrangler *worker.FileConfigWrangler) {
|
||||||
|
cfg, err := configWrangler.WorkerConfig()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("unable to load configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.ManagerURL != "" {
|
||||||
|
// Manager URL is already known, don't bother with auto-discovery.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
discoverCtx, discoverCancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||||
|
defer discoverCancel()
|
||||||
|
|
||||||
|
foundManager, err := autodiscoverManager(discoverCtx)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("unable to discover manager")
|
||||||
|
}
|
||||||
|
|
||||||
|
configWrangler.SetManagerURL(foundManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
func autodiscoverManager(ctx context.Context) (string, error) {
|
||||||
|
c, err := upnp_ssdp.NewClient(log.Logger)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("unable to create UPnP/SSDP client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Msg("auto-discovering Manager via UPnP/SSDP")
|
||||||
|
|
||||||
|
urls, err := c.Run(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("unable to find Manager: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(urls) == 0 {
|
||||||
|
return "", errors.New("no Manager could be found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try out the URLs to see which one responds.
|
||||||
|
// TODO: parallelise this.
|
||||||
|
usableURLs := make([]string, 0)
|
||||||
|
for _, url := range urls {
|
||||||
|
if pingManager(ctx, url) {
|
||||||
|
usableURLs = append(usableURLs, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch len(usableURLs) {
|
||||||
|
case 0:
|
||||||
|
return "", fmt.Errorf("autodetected %d URLs, but none were usable", len(urls))
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
log.Info().Str("url", usableURLs[0]).Msg("found Manager")
|
||||||
|
return usableURLs[0], nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.Info().
|
||||||
|
Strs("urls", usableURLs).
|
||||||
|
Str("url", usableURLs[0]).
|
||||||
|
Msg("found multiple usable URLs, using the first one")
|
||||||
|
return usableURLs[0], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pingManager connects to a Manager and returns true if it responds.
|
||||||
|
func pingManager(ctx context.Context, url string) bool {
|
||||||
|
logger := log.With().Str("manager", url).Logger()
|
||||||
|
|
||||||
|
client, err := api.NewClientWithResponses(url)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warn().Err(err).Msg("unable to create API client with this URL")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.GetVersionWithResponse(ctx)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warn().Err(err).Msg("unable to get Flamenco version from Manager")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.JSON200 == nil {
|
||||||
|
logger.Warn().
|
||||||
|
Int("httpStatus", resp.StatusCode()).
|
||||||
|
Msg("unable to get Flamenco version, unexpected reply")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info().
|
||||||
|
Str("version", resp.JSON200.Version).
|
||||||
|
Str("name", resp.JSON200.Name).
|
||||||
|
Msg("found Flamenco Manager")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user