|
|
@ -10,12 +10,30 @@ import ( |
|
|
|
"github.com/mholt/certmagic" |
|
|
|
) |
|
|
|
|
|
|
|
// Context is a type which defines the lifetime of modules that
|
|
|
|
// are loaded and provides access to the parent configuration
|
|
|
|
// that spawned the modules which are loaded. It should be used
|
|
|
|
// with care and only wrapped with derivation functions from
|
|
|
|
// the standard context package if you don't need the Caddy
|
|
|
|
// specific features. These contexts are cancelled when the
|
|
|
|
// lifetime of the modules loaded from it are over.
|
|
|
|
//
|
|
|
|
// Use NewContext() to get a valid value (but most modules will
|
|
|
|
// not actually need to do this).
|
|
|
|
type Context struct { |
|
|
|
context.Context |
|
|
|
moduleInstances map[string][]interface{} |
|
|
|
cfg *Config |
|
|
|
} |
|
|
|
|
|
|
|
// NewContext provides a new context derived from the given
|
|
|
|
// context ctx. Normally, you will not need to call this
|
|
|
|
// function unless you are loading modules which have a
|
|
|
|
// different lifespan than the ones for the context the
|
|
|
|
// module was provisioned with. Be sure to call the cancel
|
|
|
|
// func when the context is to be cleaned up so that
|
|
|
|
// modules which are loaded will be properly unloaded.
|
|
|
|
// See standard library context package's documentation.
|
|
|
|
func NewContext(ctx Context) (Context, context.CancelFunc) { |
|
|
|
newCtx := Context{moduleInstances: make(map[string][]interface{}), cfg: ctx.cfg} |
|
|
|
c, cancel := context.WithCancel(ctx.Context) |
|
|
@ -36,6 +54,14 @@ func NewContext(ctx Context) (Context, context.CancelFunc) { |
|
|
|
return newCtx, wrappedCancel |
|
|
|
} |
|
|
|
|
|
|
|
// LoadModule decodes rawMsg into a new instance of mod and
|
|
|
|
// returns the value. If mod.New() does not return a pointer
|
|
|
|
// value, it is converted to one so that it is unmarshaled
|
|
|
|
// into the underlying concrete type. If mod.New is nil, an
|
|
|
|
// error is returned. If the module implements Validator or
|
|
|
|
// Provisioner interfaces, those methods are invoked to
|
|
|
|
// ensure the module is fully configured and valid before
|
|
|
|
// being used.
|
|
|
|
func (ctx Context) LoadModule(name string, rawMsg json.RawMessage) (interface{}, error) { |
|
|
|
modulesMu.Lock() |
|
|
|
mod, ok := modules[name] |
|
|
@ -74,7 +100,7 @@ func (ctx Context) LoadModule(name string, rawMsg json.RawMessage) (interface{}, |
|
|
|
} |
|
|
|
|
|
|
|
if validator, ok := val.(Validator); ok { |
|
|
|
err := validator.Validate(ctx) |
|
|
|
err := validator.Validate() |
|
|
|
if err != nil { |
|
|
|
if cleanerUpper, ok := val.(CleanerUpper); ok { |
|
|
|
err2 := cleanerUpper.Cleanup() |
|
|
@ -91,6 +117,17 @@ func (ctx Context) LoadModule(name string, rawMsg json.RawMessage) (interface{}, |
|
|
|
return val, nil |
|
|
|
} |
|
|
|
|
|
|
|
// LoadModuleInline loads a module from a JSON raw message which decodes
|
|
|
|
// to a map[string]interface{}, where one of the keys is moduleNameKey
|
|
|
|
// and the corresponding value is the module name as a string, which
|
|
|
|
// can be found in the given scope.
|
|
|
|
//
|
|
|
|
// This allows modules to be decoded into their concrete types and
|
|
|
|
// used when their names cannot be the unique key in a map, such as
|
|
|
|
// when there are multiple instances in the map or it appears in an
|
|
|
|
// array (where there are no custom keys). In other words, the key
|
|
|
|
// containing the module name is treated special/separate from all
|
|
|
|
// the other keys.
|
|
|
|
func (ctx Context) LoadModuleInline(moduleNameKey, moduleScope string, raw json.RawMessage) (interface{}, error) { |
|
|
|
moduleName, err := getModuleNameInline(moduleNameKey, raw) |
|
|
|
if err != nil { |
|
|
|