cmd: Add --force flag to reload command (close #4005)

Can be useful if user wants to reload manual certificates, for example.
This commit is contained in:
Matthew Holt 2021-02-01 18:14:03 -07:00
parent c986110678
commit 2772ede43c
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
2 changed files with 14 additions and 3 deletions

View File

@ -282,7 +282,7 @@ func cmdRun(fl Flags) (int, error) {
func cmdStop(fl Flags) (int, error) { func cmdStop(fl Flags) (int, error) {
stopCmdAddrFlag := fl.String("address") stopCmdAddrFlag := fl.String("address")
err := apiRequest(stopCmdAddrFlag, http.MethodPost, "/stop", nil) err := apiRequest(stopCmdAddrFlag, http.MethodPost, "/stop", nil, nil)
if err != nil { if err != nil {
caddy.Log().Warn("failed using API to stop instance", zap.Error(err)) caddy.Log().Warn("failed using API to stop instance", zap.Error(err))
return caddy.ExitCodeFailedStartup, err return caddy.ExitCodeFailedStartup, err
@ -295,6 +295,7 @@ func cmdReload(fl Flags) (int, error) {
reloadCmdConfigFlag := fl.String("config") reloadCmdConfigFlag := fl.String("config")
reloadCmdConfigAdapterFlag := fl.String("adapter") reloadCmdConfigAdapterFlag := fl.String("adapter")
reloadCmdAddrFlag := fl.String("address") reloadCmdAddrFlag := fl.String("address")
reloadCmdForceFlag := fl.Bool("force")
if err := NotifyReloading(); err != nil { if err := NotifyReloading(); err != nil {
caddy.Log().Error("unable to notify reloading to service manager", zap.Error(err)) caddy.Log().Error("unable to notify reloading to service manager", zap.Error(err))
@ -328,7 +329,13 @@ func cmdReload(fl Flags) (int, error) {
adminAddr = tmpStruct.Admin.Listen adminAddr = tmpStruct.Admin.Listen
} }
err = apiRequest(adminAddr, http.MethodPost, "/load", bytes.NewReader(config)) // optionally force a config reload
headers := make(http.Header)
if reloadCmdForceFlag {
headers.Set("Cache-Control", "must-revalidate")
}
err = apiRequest(adminAddr, http.MethodPost, "/load", headers, bytes.NewReader(config))
if err != nil { if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("sending configuration to instance: %v", err) return caddy.ExitCodeFailedStartup, fmt.Errorf("sending configuration to instance: %v", err)
} }
@ -827,7 +834,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
// apiRequest makes an API request to the endpoint adminAddr with the // apiRequest makes an API request to the endpoint adminAddr with the
// given HTTP method and request URI. If body is non-nil, it will be // given HTTP method and request URI. If body is non-nil, it will be
// assumed to be Content-Type application/json. // assumed to be Content-Type application/json.
func apiRequest(adminAddr, method, uri string, body io.Reader) error { func apiRequest(adminAddr, method, uri string, headers http.Header, body io.Reader) error {
// parse the admin address // parse the admin address
if adminAddr == "" { if adminAddr == "" {
adminAddr = caddy.DefaultAdminListen adminAddr = caddy.DefaultAdminListen
@ -867,6 +874,9 @@ func apiRequest(adminAddr, method, uri string, body io.Reader) error {
if body != nil { if body != nil {
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
} }
for k, v := range headers {
req.Header[k] = v
}
// make an HTTP client that dials our network type, since admin // make an HTTP client that dials our network type, since admin
// endpoints aren't always TCP, which is what the default transport // endpoints aren't always TCP, which is what the default transport

View File

@ -178,6 +178,7 @@ config file; otherwise the default is assumed.`,
fs.String("config", "", "Configuration file (required)") fs.String("config", "", "Configuration file (required)")
fs.String("adapter", "", "Name of config adapter to apply") fs.String("adapter", "", "Name of config adapter to apply")
fs.String("address", "", "Address of the administration listener, if different from config") fs.String("address", "", "Address of the administration listener, if different from config")
fs.Bool("force", false, "Force config reload, even if it is the same")
return fs return fs
}(), }(),
}) })