Refactor CLI: birdc-style help, collapsed nouns, ReloadConfig, bug fixes
maglevc - Rewrite '?' handler (birdc-style): show full command paths from current position to every leaf, right-aligned help column, dynamic slot values displayed as an indented block when cursor is at a slot position. - Collapse show frontends/frontend, backends/backend, healthchecks/healthcheck into single plural-noun nodes with an optional <name> slot. Allows 'sh ba' (list all) and 'sh ba nginx0' (show one) without ambiguity. - Add 'config reload' command. - Fix tabwriter ANSI alignment: continuation lines in transition output now carry the same label() byte overhead as the header line. - Fix broken Walk for 'set frontend' command: setFrontendPoolName and setWeightValue were fixed-word nodes that couldn't capture user input; mark them as slot nodes with dynNone. - Add tree_test.go covering expandPaths, cycle detection, prefix matching, and the full weight-command walk. gRPC / proto - Add ReloadConfig RPC: checks config then applies it to the running checker, returning ok/parse_error/semantic_error/reload_error. - Add logging to CheckConfig (config-check-start/config-check-done at INFO level). maglevd - SIGHUP handler now calls maglevServer.TriggerReload(), sharing the same code path as the gRPC ReloadConfig RPC. docs - Collapse show command documentation to use [<name>] optional syntax. - Remove developer-facing 'Command tree and parser' section. - Document 'config reload'.
This commit is contained in:
@@ -204,12 +204,57 @@ func (s *Server) WatchEvents(req *WatchRequest, stream Maglev_WatchEventsServer)
|
||||
// CheckConfig reads and validates the configuration file, returning a
|
||||
// structured result that distinguishes YAML parse errors from semantic errors.
|
||||
func (s *Server) CheckConfig(_ context.Context, _ *CheckConfigRequest) (*CheckConfigResponse, error) {
|
||||
slog.Info("config-check-start", "path", s.configPath)
|
||||
_, result := config.Check(s.configPath)
|
||||
return &CheckConfigResponse{
|
||||
resp := &CheckConfigResponse{
|
||||
Ok: result.OK(),
|
||||
ParseError: result.ParseError,
|
||||
SemanticError: result.SemanticError,
|
||||
}, nil
|
||||
}
|
||||
if result.OK() {
|
||||
slog.Info("config-check-done", "result", "ok")
|
||||
} else if result.ParseError != "" {
|
||||
slog.Info("config-check-done", "result", "failed", "type", "parse", "err", result.ParseError)
|
||||
} else {
|
||||
slog.Info("config-check-done", "result", "failed", "type", "semantic", "err", result.SemanticError)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ReloadConfig checks the configuration file and, if valid, applies it to the
|
||||
// running checker. This is the same code path used by SIGHUP.
|
||||
func (s *Server) ReloadConfig(_ context.Context, _ *ReloadConfigRequest) (*ReloadConfigResponse, error) {
|
||||
return s.doReloadConfig(), nil
|
||||
}
|
||||
|
||||
// TriggerReload performs a config check and reload. Intended for use by the
|
||||
// SIGHUP handler so that signals and gRPC share the same code path.
|
||||
func (s *Server) TriggerReload() {
|
||||
s.doReloadConfig()
|
||||
}
|
||||
|
||||
func (s *Server) doReloadConfig() *ReloadConfigResponse {
|
||||
slog.Info("config-reload-start")
|
||||
newCfg, result := config.Check(s.configPath)
|
||||
if !result.OK() {
|
||||
if result.ParseError != "" {
|
||||
slog.Error("config-check-failed", "type", "parse", "err", result.ParseError)
|
||||
} else {
|
||||
slog.Error("config-check-failed", "type", "semantic", "err", result.SemanticError)
|
||||
}
|
||||
return &ReloadConfigResponse{
|
||||
ParseError: result.ParseError,
|
||||
SemanticError: result.SemanticError,
|
||||
}
|
||||
}
|
||||
if err := s.checker.Reload(s.ctx, newCfg); err != nil {
|
||||
slog.Error("checker-reload-error", "err", err)
|
||||
return &ReloadConfigResponse{
|
||||
ReloadError: err.Error(),
|
||||
}
|
||||
}
|
||||
slog.Info("config-reload-done", "frontends", len(newCfg.Frontends))
|
||||
return &ReloadConfigResponse{Ok: true}
|
||||
}
|
||||
|
||||
// ---- conversion helpers ----------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user