finishSettingUp should be run after all apps have successfully started.
(ctx Context, cfg *Config)
| 592 | |
| 593 | // finishSettingUp should be run after all apps have successfully started. |
| 594 | func finishSettingUp(ctx Context, cfg *Config) error { |
| 595 | // establish this server's identity (only after apps are loaded |
| 596 | // so that cert management of this endpoint doesn't prevent user's |
| 597 | // servers from starting which likely also use HTTP/HTTPS ports; |
| 598 | // but before remote management which may depend on these creds) |
| 599 | err := manageIdentity(ctx, cfg) |
| 600 | if err != nil { |
| 601 | return fmt.Errorf("provisioning remote admin endpoint: %v", err) |
| 602 | } |
| 603 | |
| 604 | // replace any remote admin endpoint |
| 605 | err = replaceRemoteAdminServer(ctx, cfg) |
| 606 | if err != nil { |
| 607 | return fmt.Errorf("provisioning remote admin endpoint: %v", err) |
| 608 | } |
| 609 | |
| 610 | // if dynamic config is requested, set that up and run it |
| 611 | if cfg != nil && cfg.Admin != nil && cfg.Admin.Config != nil && cfg.Admin.Config.LoadRaw != nil { |
| 612 | val, err := ctx.LoadModule(cfg.Admin.Config, "LoadRaw") |
| 613 | if err != nil { |
| 614 | return fmt.Errorf("loading config loader module: %s", err) |
| 615 | } |
| 616 | |
| 617 | logger := Log().Named("config_loader").With( |
| 618 | zap.String("module", val.(Module).CaddyModule().ID.Name()), |
| 619 | zap.Int("load_delay", int(cfg.Admin.Config.LoadDelay))) |
| 620 | |
| 621 | runLoadedConfig := func(config []byte) error { |
| 622 | logger.Info("applying dynamically-loaded config") |
| 623 | err := changeConfig(http.MethodPost, "/"+rawConfigKey, config, "", false) |
| 624 | if errors.Is(err, errSameConfig) { |
| 625 | return err |
| 626 | } |
| 627 | if err != nil { |
| 628 | logger.Error("failed to run dynamically-loaded config", zap.Error(err)) |
| 629 | return err |
| 630 | } |
| 631 | logger.Info("successfully applied dynamically-loaded config") |
| 632 | return nil |
| 633 | } |
| 634 | |
| 635 | if cfg.Admin.Config.LoadDelay > 0 { |
| 636 | go func() { |
| 637 | // the loop is here to iterate ONLY if there is an error, a no-op config load, |
| 638 | // or an unchanged config; in which case we simply wait the delay and try again |
| 639 | for { |
| 640 | timer := time.NewTimer(time.Duration(cfg.Admin.Config.LoadDelay)) |
| 641 | select { |
| 642 | case <-timer.C: |
| 643 | loadedConfig, err := val.(ConfigLoader).LoadConfig(ctx) |
| 644 | if err != nil { |
| 645 | logger.Error("failed loading dynamic config; will retry", zap.Error(err)) |
| 646 | continue |
| 647 | } |
| 648 | if loadedConfig == nil { |
| 649 | logger.Info("dynamically-loaded config was nil; will retry") |
| 650 | continue |
| 651 | } |
no test coverage detected