From 5a0603ed72cead424a34b3bc5af3a5b1629ac187 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Tue, 31 Dec 2019 16:56:19 -0700 Subject: Config auto-save; run --resume flag; update environ output (close #2903) Config auto-saving is on by default and can be disabled. The --environ flag (or environ subcommand) now print more useful information from Caddy and the runtime, including some nifty paths. --- caddy.go | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'caddy.go') diff --git a/caddy.go b/caddy.go index f50598e..fefe50b 100644 --- a/caddy.go +++ b/caddy.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "io" + "io/ioutil" "log" "net/http" "path" @@ -30,6 +31,7 @@ import ( "time" "github.com/mholt/certmagic" + "go.uber.org/zap" ) // Config is the top (or beginning) of the Caddy configuration structure. @@ -148,13 +150,6 @@ func changeConfig(method, path string, input []byte, forceReload bool) error { } } - // remove any @id fields from the JSON, which would cause - // loading to break since the field wouldn't be recognized - // (an alternate way to do this would be to delete them from - // rawCfg as they are indexed, then iterate the index we made - // and add them back after encoding as JSON) - newCfg = RemoveMetaFields(newCfg) - // load this new config; if it fails, we need to revert to // our old representation of caddy's actual config err = unsyncedDecodeAndRun(newCfg) @@ -232,15 +227,19 @@ func indexConfigObjects(ptr interface{}, configPath string, index map[string]str return nil } -// unsyncedDecodeAndRun decodes cfgJSON and runs -// it as the new config, replacing any other -// current config. It does not update the raw -// config state, as this is a lower-level function; -// most callers will want to use Load instead. -// A write lock on currentCfgMu is required! +// unsyncedDecodeAndRun removes any meta fields (like @id tags) +// from cfgJSON, decodes the result into a *Config, and runs +// it as the new config, replacing any other current config. +// It does NOT update the raw config state, as this is a +// lower-level function; most callers will want to use Load +// instead. A write lock on currentCfgMu is required! func unsyncedDecodeAndRun(cfgJSON []byte) error { + // remove any @id fields from the JSON, which would cause + // loading to break since the field wouldn't be recognized + strippedCfgJSON := RemoveMetaFields(cfgJSON) + var newCfg *Config - err := strictUnmarshalJSON(cfgJSON, &newCfg) + err := strictUnmarshalJSON(strippedCfgJSON, &newCfg) if err != nil { return err } @@ -258,6 +257,22 @@ func unsyncedDecodeAndRun(cfgJSON []byte) error { // Stop, Cleanup each old app unsyncedStop(oldCfg) + // autosave a non-nil config, if not disabled + if newCfg != nil && + (newCfg.Admin == nil || + newCfg.Admin.Config == nil || + newCfg.Admin.Config.Persist == nil || + *newCfg.Admin.Config.Persist) { + err := ioutil.WriteFile(ConfigAutosavePath, cfgJSON, 0600) + if err == nil { + Log().Info("autosaved config", zap.String("file", ConfigAutosavePath)) + } else { + Log().Error("unable to autosave config", + zap.String("file", ConfigAutosavePath), + zap.Error(err)) + } + } + return nil } -- cgit v1.2.3