From 34fd31b7b1a7fc4bf16f09dddada1898fd2cd6c7 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Fri, 2 Jun 2017 14:56:49 +0200 Subject: [PATCH] agent: move config reloading into the agent --- command/agent/agent.go | 64 +++++++++++++++++++++++++++++++++++++ command/agent/command.go | 68 +++++----------------------------------- 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index 63b33c7484..f3c3852a3a 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -29,6 +29,8 @@ import ( "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/types" + "github.com/hashicorp/consul/watch" + multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/go-sockaddr/template" "github.com/hashicorp/go-uuid" "github.com/hashicorp/raft" @@ -2246,3 +2248,65 @@ func (a *Agent) getEndpoint(endpoint string) string { } return endpoint } + +func (a *Agent) ReloadConfig(newCfg *Config) (bool, error) { + var errs error + + // Bulk update the services and checks + a.PauseSync() + defer a.ResumeSync() + + // Snapshot the current state, and restore it afterwards + snap := a.snapshotCheckState() + defer a.restoreCheckState(snap) + + // First unload all checks, services, and metadata. This lets us begin the reload + // with a clean slate. + if err := a.unloadServices(); err != nil { + errs = multierror.Append(errs, fmt.Errorf("Failed unloading services: %s", err)) + return false, errs + } + if err := a.unloadChecks(); err != nil { + errs = multierror.Append(errs, fmt.Errorf("Failed unloading checks: %s", err)) + return false, errs + } + a.unloadMetadata() + + // Reload service/check definitions and metadata. + if err := a.loadServices(newCfg); err != nil { + errs = multierror.Append(errs, fmt.Errorf("Failed reloading services: %s", err)) + return false, errs + } + if err := a.loadChecks(newCfg); err != nil { + errs = multierror.Append(errs, fmt.Errorf("Failed reloading checks: %s", err)) + return false, errs + } + if err := a.loadMetadata(newCfg); err != nil { + errs = multierror.Append(errs, fmt.Errorf("Failed reloading metadata: %s", err)) + return false, errs + } + + // Get the new client listener addr + httpAddr, err := newCfg.ClientListener(a.config.Addresses.HTTP, a.config.Ports.HTTP) + if err != nil { + errs = multierror.Append(errs, fmt.Errorf("Failed to determine HTTP address: %v", err)) + } + + // Deregister the old watches + for _, wp := range a.config.WatchPlans { + wp.Stop() + } + + // Register the new watches + for _, wp := range newCfg.WatchPlans { + go func(wp *watch.Plan) { + wp.Handler = makeWatchHandler(a.LogOutput, wp.Exempt["handler"]) + wp.LogOutput = a.LogOutput + if err := wp.Run(httpAddr.String()); err != nil { + errs = multierror.Append(errs, fmt.Errorf("Error running watch: %v", err)) + } + }(wp) + } + + return true, errs +} diff --git a/command/agent/command.go b/command/agent/command.go index 2276bbc303..b750b28fa9 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -814,14 +814,14 @@ WAIT: func (cmd *Command) handleReload(agent *Agent, cfg *Config) (*Config, error) { cmd.UI.Output("Reloading configuration...") var errs error - newConf := cmd.readConfig() - if newConf == nil { + newCfg := cmd.readConfig() + if newCfg == nil { errs = multierror.Append(errs, fmt.Errorf("Failed to reload configs")) return cfg, errs } // Change the log level - minLevel := logutils.LogLevel(strings.ToUpper(newConf.LogLevel)) + minLevel := logutils.LogLevel(strings.ToUpper(newCfg.LogLevel)) if logger.ValidateLevelFilter(minLevel, cmd.logFilter) { cmd.logFilter.SetMinLevel(minLevel) } else { @@ -830,66 +830,14 @@ func (cmd *Command) handleReload(agent *Agent, cfg *Config) (*Config, error) { minLevel, cmd.logFilter.Levels)) // Keep the current log level - newConf.LogLevel = cfg.LogLevel + newCfg.LogLevel = cfg.LogLevel } - // Bulk update the services and checks - agent.PauseSync() - defer agent.ResumeSync() - - // Snapshot the current state, and restore it afterwards - snap := agent.snapshotCheckState() - defer agent.restoreCheckState(snap) - - // First unload all checks, services, and metadata. This lets us begin the reload - // with a clean slate. - if err := agent.unloadServices(); err != nil { - errs = multierror.Append(errs, fmt.Errorf("Failed unloading services: %s", err)) - return nil, errs + ok, errs := agent.ReloadConfig(newCfg) + if ok { + return newCfg, errs } - if err := agent.unloadChecks(); err != nil { - errs = multierror.Append(errs, fmt.Errorf("Failed unloading checks: %s", err)) - return nil, errs - } - agent.unloadMetadata() - - // Reload service/check definitions and metadata. - if err := agent.loadServices(newConf); err != nil { - errs = multierror.Append(errs, fmt.Errorf("Failed reloading services: %s", err)) - return nil, errs - } - if err := agent.loadChecks(newConf); err != nil { - errs = multierror.Append(errs, fmt.Errorf("Failed reloading checks: %s", err)) - return nil, errs - } - if err := agent.loadMetadata(newConf); err != nil { - errs = multierror.Append(errs, fmt.Errorf("Failed reloading metadata: %s", err)) - return nil, errs - } - - // Get the new client listener addr - httpAddr, err := newConf.ClientListener(cfg.Addresses.HTTP, cfg.Ports.HTTP) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("Failed to determine HTTP address: %v", err)) - } - - // Deregister the old watches - for _, wp := range cfg.WatchPlans { - wp.Stop() - } - - // Register the new watches - for _, wp := range newConf.WatchPlans { - go func(wp *watch.Plan) { - wp.Handler = makeWatchHandler(cmd.logOutput, wp.Exempt["handler"]) - wp.LogOutput = cmd.logOutput - if err := wp.Run(httpAddr.String()); err != nil { - errs = multierror.Append(errs, fmt.Errorf("Error running watch: %v", err)) - } - }(wp) - } - - return newConf, errs + return cfg, errs } func (cmd *Command) Synopsis() string {