|
@ -5,6 +5,7 @@ import ( |
|
|
"encoding/json" |
|
|
"encoding/json" |
|
|
"fmt" |
|
|
"fmt" |
|
|
"log" |
|
|
"log" |
|
|
|
|
|
"runtime/debug" |
|
|
"strings" |
|
|
"strings" |
|
|
"sync" |
|
|
"sync" |
|
|
"time" |
|
|
"time" |
|
@ -12,6 +13,28 @@ import ( |
|
|
"github.com/mholt/certmagic" |
|
|
"github.com/mholt/certmagic" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// Config represents a Caddy configuration.
|
|
|
|
|
|
type Config struct { |
|
|
|
|
|
Admin *AdminConfig `json:"admin,omitempty"` |
|
|
|
|
|
|
|
|
|
|
|
StorageRaw json.RawMessage `json:"storage,omitempty"` |
|
|
|
|
|
storage certmagic.Storage |
|
|
|
|
|
|
|
|
|
|
|
AppsRaw map[string]json.RawMessage `json:"apps,omitempty"` |
|
|
|
|
|
|
|
|
|
|
|
// apps stores the decoded Apps values,
|
|
|
|
|
|
// keyed by module name.
|
|
|
|
|
|
apps map[string]App |
|
|
|
|
|
|
|
|
|
|
|
cancelFunc context.CancelFunc |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// App is a thing that Caddy runs.
|
|
|
|
|
|
type App interface { |
|
|
|
|
|
Start() error |
|
|
|
|
|
Stop() error |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Run runs Caddy with the given config.
|
|
|
// Run runs Caddy with the given config.
|
|
|
func Run(newCfg *Config) error { |
|
|
func Run(newCfg *Config) error { |
|
|
currentCfgMu.Lock() |
|
|
currentCfgMu.Lock() |
|
@ -69,7 +92,7 @@ func Run(newCfg *Config) error { |
|
|
return err |
|
|
return err |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Load, Provision, Validate
|
|
|
// Load, Provision, Validate each app and their submodules
|
|
|
err = func() error { |
|
|
err = func() error { |
|
|
for modName, rawMsg := range newCfg.AppsRaw { |
|
|
for modName, rawMsg := range newCfg.AppsRaw { |
|
|
val, err := ctx.LoadModule(modName, rawMsg) |
|
|
val, err := ctx.LoadModule(modName, rawMsg) |
|
@ -112,7 +135,7 @@ func Run(newCfg *Config) error { |
|
|
oldCfg := currentCfg |
|
|
oldCfg := currentCfg |
|
|
currentCfg = newCfg |
|
|
currentCfg = newCfg |
|
|
|
|
|
|
|
|
// Stop, Cleanup
|
|
|
// Stop, Cleanup each old app
|
|
|
if oldCfg != nil { |
|
|
if oldCfg != nil { |
|
|
for name, a := range oldCfg.apps { |
|
|
for name, a := range oldCfg.apps { |
|
|
err := a.Stop() |
|
|
err := a.Stop() |
|
@ -121,35 +144,13 @@ func Run(newCfg *Config) error { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// clean up old modules
|
|
|
// clean up all old modules
|
|
|
oldCfg.cancelFunc() |
|
|
oldCfg.cancelFunc() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return nil |
|
|
return nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// App is a thing that Caddy runs.
|
|
|
|
|
|
type App interface { |
|
|
|
|
|
Start() error |
|
|
|
|
|
Stop() error |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Config represents a Caddy configuration.
|
|
|
|
|
|
type Config struct { |
|
|
|
|
|
Admin *AdminConfig `json:"admin,omitempty"` |
|
|
|
|
|
|
|
|
|
|
|
StorageRaw json.RawMessage `json:"storage,omitempty"` |
|
|
|
|
|
storage certmagic.Storage |
|
|
|
|
|
|
|
|
|
|
|
AppsRaw map[string]json.RawMessage `json:"apps,omitempty"` |
|
|
|
|
|
|
|
|
|
|
|
// apps stores the decoded Apps values,
|
|
|
|
|
|
// keyed by module name.
|
|
|
|
|
|
apps map[string]App |
|
|
|
|
|
|
|
|
|
|
|
cancelFunc context.CancelFunc |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Duration is a JSON-string-unmarshable duration type.
|
|
|
// Duration is a JSON-string-unmarshable duration type.
|
|
|
type Duration time.Duration |
|
|
type Duration time.Duration |
|
|
|
|
|
|
|
@ -163,6 +164,29 @@ func (d *Duration) UnmarshalJSON(b []byte) error { |
|
|
return nil |
|
|
return nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GoModule returns the build info of this Caddy
|
|
|
|
|
|
// build from debug.BuildInfo (requires Go modules).
|
|
|
|
|
|
// If no version information is available, a non-nil
|
|
|
|
|
|
// value will still be returned, but with an
|
|
|
|
|
|
// unknown version.
|
|
|
|
|
|
func GoModule() *debug.Module { |
|
|
|
|
|
bi, ok := debug.ReadBuildInfo() |
|
|
|
|
|
if ok { |
|
|
|
|
|
// The recommended way to build Caddy involves
|
|
|
|
|
|
// creating a separate main module, which
|
|
|
|
|
|
// TODO: track related Go issue: https://github.com/golang/go/issues/29228
|
|
|
|
|
|
for _, mod := range bi.Deps { |
|
|
|
|
|
if mod.Path == goModule { |
|
|
|
|
|
return mod |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return &debug.Module{Version: "unknown"} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// goModule is the name of this Go module.
|
|
|
|
|
|
const goModule = "github.com/mholt/caddy" |
|
|
|
|
|
|
|
|
// CtxKey is a value type for use with context.WithValue.
|
|
|
// CtxKey is a value type for use with context.WithValue.
|
|
|
type CtxKey string |
|
|
type CtxKey string |
|
|
|
|
|
|
|
|