package client import ( "context" "errors" "time" "github.com/docker/docker/client" "github.com/rs/zerolog/log" ) const ( WaitConnectionFailed time.Duration = 5 * time.Second DockerSwarmHostURL string = "tcp://127.0.0.1:4523" DockerHostURL string = "unix:///var/run/docker.sock" ClientConnectionAttempts int = 4 ) var ErrSwarmClientError = errors.New("unable to connect to the swarm") func GetSwarmClient() (*client.Client, error) { return initClientWithRetry(DockerSwarmHostURL, ClientConnectionAttempts) } func GetHostClient() (*client.Client, error) { return initClientWithRetry(DockerHostURL, ClientConnectionAttempts) } func initClient(url string) (*client.Client, error) { cli, err := client.NewClientWithOpts( client.WithHost(url), client.WithAPIVersionNegotiation(), ) if err != nil { return cli, err } return cli, nil } func initClientWithRetry(url string, attempt int) (*client.Client, error) { var i int for { if i == attempt { return nil, ErrSwarmClientError } cli, err := initClient(url) if err != nil { return nil, err } if _, err := cli.Ping(context.TODO()); err != nil { log.Error().Str("url", url).Msg("unable to connect to the swarm, retrying...") time.Sleep(WaitConnectionFailed) i++ continue } return cli, nil } }