all: sync with master

This commit is contained in:
Eugene Burkov
2024-12-05 16:00:18 +03:00
parent 54f3a5f990
commit 3f95db98d3
143 changed files with 3476 additions and 2959 deletions

View File

@@ -8,6 +8,7 @@ import (
"context"
"fmt"
"io/fs"
"log/slog"
"net/netip"
"os"
"slices"
@@ -19,18 +20,23 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/next/dnssvc"
"github.com/AdguardTeam/AdGuardHome/internal/next/websvc"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/timeutil"
"github.com/google/renameio/v2/maybe"
"gopkg.in/yaml.v3"
)
// Configuration Manager
// Manager handles full and partial changes in the configuration, persisting
// them to disk if necessary.
//
// TODO(a.garipov): Support missing configs and default values.
type Manager struct {
// baseLogger is used to create loggers for other entities.
baseLogger *slog.Logger
// logger is used for logging the operation of the configuration manager.
logger *slog.Logger
// updMu makes sure that at most one reconfiguration is performed at a time.
// updMu protects all fields below.
updMu *sync.RWMutex
@@ -57,12 +63,24 @@ func Validate(fileName string) (err error) {
return err
}
// Don't wrap the error, because it's informative enough as is.
return conf.validate()
err = conf.validate()
if err != nil {
return fmt.Errorf("validating config: %w", err)
}
return nil
}
// Config contains the configuration parameters for the configuration manager.
type Config struct {
// BaseLogger is used to create loggers for other entities. It must not be
// nil.
BaseLogger *slog.Logger
// Logger is used for logging the operation of the configuration manager.
// It must not be nil.
Logger *slog.Logger
// Frontend is the filesystem with the frontend files.
Frontend fs.FS
@@ -93,9 +111,11 @@ func New(ctx context.Context, c *Config) (m *Manager, err error) {
}
m = &Manager{
updMu: &sync.RWMutex{},
current: conf,
fileName: c.FileName,
baseLogger: c.BaseLogger,
logger: c.Logger,
updMu: &sync.RWMutex{},
current: conf,
fileName: c.FileName,
}
err = m.assemble(ctx, conf, c.Frontend, c.WebAddr, c.Start)
@@ -137,6 +157,7 @@ func (m *Manager) assemble(
start time.Time,
) (err error) {
dnsConf := &dnssvc.Config{
Logger: m.baseLogger.With(slogutil.KeyPrefix, "dnssvc"),
Addresses: conf.DNS.Addresses,
BootstrapServers: conf.DNS.BootstrapDNS,
UpstreamServers: conf.DNS.UpstreamDNS,
@@ -151,6 +172,7 @@ func (m *Manager) assemble(
}
webSvcConf := &websvc.Config{
Logger: m.baseLogger.With(slogutil.KeyPrefix, "websvc"),
Pprof: &websvc.PprofConfig{
Port: conf.HTTP.Pprof.Port,
Enabled: conf.HTTP.Pprof.Enabled,
@@ -176,18 +198,18 @@ func (m *Manager) assemble(
}
// write writes the current configuration to disk.
func (m *Manager) write() (err error) {
func (m *Manager) write(ctx context.Context) (err error) {
b, err := yaml.Marshal(m.current)
if err != nil {
return fmt.Errorf("encoding: %w", err)
}
err = aghos.WriteFile(m.fileName, b, aghos.DefaultPermFile)
err = maybe.WriteFile(m.fileName, b, aghos.DefaultPermFile)
if err != nil {
return fmt.Errorf("writing: %w", err)
}
log.Info("configmgr: written to %q", m.fileName)
m.logger.InfoContext(ctx, "config file written", "path", m.fileName)
return nil
}
@@ -216,7 +238,7 @@ func (m *Manager) UpdateDNS(ctx context.Context, c *dnssvc.Config) (err error) {
m.updateCurrentDNS(c)
return m.write()
return m.write(ctx)
}
// updateDNS recreates the DNS service. m.updMu is expected to be locked.
@@ -270,7 +292,7 @@ func (m *Manager) UpdateWeb(ctx context.Context, c *websvc.Config) (err error) {
m.updateCurrentWeb(c)
return m.write()
return m.write(ctx)
}
// updateWeb recreates the web service. m.upd is expected to be locked.