Feature/require only one healthy server frostfs #12
3 changed files with 44 additions and 19 deletions
|
@ -4,6 +4,9 @@ This document outlines major changes between releases.
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
- Using multiple servers require only one healthy (TrueCloudLab#12)
|
||||||
|
|
||||||
## [0.26.0] - 2022-12-28
|
## [0.26.0] - 2022-12-28
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -527,37 +527,61 @@ func (a *App) startServices() {
|
||||||
func (a *App) initServers(ctx context.Context) {
|
func (a *App) initServers(ctx context.Context) {
|
||||||
serversInfo := fetchServers(a.cfg)
|
serversInfo := fetchServers(a.cfg)
|
||||||
|
|
||||||
a.servers = make([]Server, len(serversInfo))
|
a.servers = make([]Server, 0, len(serversInfo))
|
||||||
for i, serverInfo := range serversInfo {
|
for _, serverInfo := range serversInfo {
|
||||||
a.log.Info("added server",
|
fields := []zap.Field{
|
||||||
zap.String("address", serverInfo.Address), zap.Bool("tls enabled", serverInfo.TLS.Enabled),
|
zap.String("address", serverInfo.Address), zap.Bool("tls enabled", serverInfo.TLS.Enabled),
|
||||||
zap.String("tls cert", serverInfo.TLS.CertFile), zap.String("tls key", serverInfo.TLS.KeyFile))
|
zap.String("tls cert", serverInfo.TLS.CertFile), zap.String("tls key", serverInfo.TLS.KeyFile),
|
||||||
a.servers[i] = newServer(ctx, serverInfo, a.log)
|
}
|
||||||
|
srv, err := newServer(ctx, serverInfo)
|
||||||
|
if err != nil {
|
||||||
|
a.log.Warn("failed to add server", append(fields, zap.Error(err))...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
a.servers = append(a.servers, srv)
|
||||||
|
a.log.Info("add server", fields...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(a.servers) == 0 {
|
||||||
|
a.log.Fatal("no healthy servers")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) updateServers() error {
|
func (a *App) updateServers() error {
|
||||||
serversInfo := fetchServers(a.cfg)
|
serversInfo := fetchServers(a.cfg)
|
||||||
|
|
||||||
if len(serversInfo) != len(a.servers) {
|
var found bool
|
||||||
return fmt.Errorf("invalid servers configuration: amount mismatch: old '%d', new '%d", len(a.servers), len(serversInfo))
|
for _, serverInfo := range serversInfo {
|
||||||
}
|
index := a.serverIndex(serverInfo.Address)
|
||||||
|
if index == -1 {
|
||||||
for i, serverInfo := range serversInfo {
|
continue
|
||||||
if serverInfo.Address != a.servers[i].Address() {
|
|
||||||
return fmt.Errorf("invalid servers configuration: addresses mismatch: old '%s', new '%s", a.servers[i].Address(), serverInfo.Address)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if serverInfo.TLS.Enabled {
|
if serverInfo.TLS.Enabled {
|
||||||
if err := a.servers[i].UpdateCert(serverInfo.TLS.CertFile, serverInfo.TLS.KeyFile); err != nil {
|
if err := a.servers[index].UpdateCert(serverInfo.TLS.CertFile, serverInfo.TLS.KeyFile); err != nil {
|
||||||
return fmt.Errorf("failed to update tls certs: %w", err)
|
return fmt.Errorf("failed to update tls certs: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
return fmt.Errorf("invalid servers configuration: no known server found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) serverIndex(address string) int {
|
||||||
|
for i := range a.servers {
|
||||||
|
if a.servers[i].Address() == address {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) stopServices() {
|
func (a *App) stopServices() {
|
||||||
ctx, cancel := shutdownContext()
|
ctx, cancel := shutdownContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
|
@ -7,8 +7,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -57,11 +55,11 @@ func (s *server) UpdateCert(certFile, keyFile string) error {
|
||||||
return s.tlsProvider.UpdateCert(certFile, keyFile)
|
return s.tlsProvider.UpdateCert(certFile, keyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer(ctx context.Context, serverInfo ServerInfo, logger *zap.Logger) *server {
|
func newServer(ctx context.Context, serverInfo ServerInfo) (*server, error) {
|
||||||
var lic net.ListenConfig
|
var lic net.ListenConfig
|
||||||
ln, err := lic.Listen(ctx, "tcp", serverInfo.Address)
|
ln, err := lic.Listen(ctx, "tcp", serverInfo.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("could not prepare listener", zap.String("address", serverInfo.Address), zap.Error(err))
|
return nil, fmt.Errorf("could not prepare listener: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsProvider := &certProvider{
|
tlsProvider := &certProvider{
|
||||||
|
@ -70,7 +68,7 @@ func newServer(ctx context.Context, serverInfo ServerInfo, logger *zap.Logger) *
|
||||||
|
|
||||||
if serverInfo.TLS.Enabled {
|
if serverInfo.TLS.Enabled {
|
||||||
if err = tlsProvider.UpdateCert(serverInfo.TLS.CertFile, serverInfo.TLS.KeyFile); err != nil {
|
if err = tlsProvider.UpdateCert(serverInfo.TLS.CertFile, serverInfo.TLS.KeyFile); err != nil {
|
||||||
logger.Fatal("failed to update cert", zap.Error(err))
|
return nil, fmt.Errorf("failed to update cert: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ln = tls.NewListener(ln, &tls.Config{
|
ln = tls.NewListener(ln, &tls.Config{
|
||||||
|
@ -82,7 +80,7 @@ func newServer(ctx context.Context, serverInfo ServerInfo, logger *zap.Logger) *
|
||||||
address: serverInfo.Address,
|
address: serverInfo.Address,
|
||||||
listener: ln,
|
listener: ln,
|
||||||
tlsProvider: tlsProvider,
|
tlsProvider: tlsProvider,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *certProvider) GetCertificate(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
func (p *certProvider) GetCertificate(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
|
Loading…
Reference in a new issue