summaryrefslogtreecommitdiff
path: root/modules.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-05-16 16:05:38 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-05-16 16:05:38 -0600
commit1f0c061ce30f218e63fcc17e0fdfc8b90d754ba5 (patch)
treeef148ac39ec520d14342ce48cec07f5efe0379f3 /modules.go
parentff5b4639d597203f8aec43e5eae8fe3774976d32 (diff)
Architectural shift to using context for config and module state
Diffstat (limited to 'modules.go')
-rw-r--r--modules.go95
1 files changed, 7 insertions, 88 deletions
diff --git a/modules.go b/modules.go
index b2c9b96..bba6b93 100644
--- a/modules.go
+++ b/modules.go
@@ -3,7 +3,6 @@ package caddy2
import (
"encoding/json"
"fmt"
- "reflect"
"sort"
"strings"
"sync"
@@ -32,9 +31,6 @@ func RegisterModule(mod Module) error {
if mod.Name == "caddy" {
return fmt.Errorf("modules cannot be named 'caddy'")
}
- if strings.HasPrefix(mod.Name, "caddy.") {
- return fmt.Errorf("modules cannot be namespaced in 'caddy'")
- }
modulesMu.Lock()
defer modulesMu.Unlock()
@@ -123,88 +119,6 @@ func Modules() []string {
return names
}
-// 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 LoadModule(name string, rawMsg json.RawMessage) (interface{}, error) {
- modulesMu.Lock()
- mod, ok := modules[name]
- modulesMu.Unlock()
- if !ok {
- return nil, fmt.Errorf("unknown module: %s", name)
- }
-
- if mod.New == nil {
- return nil, fmt.Errorf("module '%s' has no constructor", mod.Name)
- }
-
- val, err := mod.New()
- if err != nil {
- return nil, fmt.Errorf("initializing module '%s': %v", mod.Name, err)
- }
-
- // value must be a pointer for unmarshaling into concrete type
- if rv := reflect.ValueOf(val); rv.Kind() != reflect.Ptr {
- val = reflect.New(rv.Type()).Elem().Addr().Interface()
- }
-
- // fill in its config only if there is a config to fill in
- if len(rawMsg) > 0 {
- err = json.Unmarshal(rawMsg, &val)
- if err != nil {
- return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err)
- }
- }
-
- if prov, ok := val.(Provisioner); ok {
- err := prov.Provision()
- if err != nil {
- return nil, fmt.Errorf("provision %s: %v", mod.Name, err)
- }
- }
-
- if validator, ok := val.(Validator); ok {
- err := validator.Validate()
- if err != nil {
- return nil, fmt.Errorf("%s: invalid configuration: %v", mod.Name, err)
- }
- }
-
- moduleInstances[mod.Name] = append(moduleInstances[mod.Name], val)
-
- 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 LoadModuleInline(moduleNameKey, moduleScope string, raw json.RawMessage) (interface{}, error) {
- moduleName, err := getModuleNameInline(moduleNameKey, raw)
- if err != nil {
- return nil, err
- }
-
- val, err := LoadModule(moduleScope+"."+moduleName, raw)
- if err != nil {
- return nil, fmt.Errorf("loading module '%s': %v", moduleName, err)
- }
-
- return val, nil
-}
-
// getModuleNameInline loads the string value from raw of moduleNameKey,
// where raw must be a JSON encoding of a map.
func getModuleNameInline(moduleNameKey string, raw json.RawMessage) (string, error) {
@@ -228,14 +142,19 @@ func getModuleNameInline(moduleNameKey string, raw json.RawMessage) (string, err
// always be fast (imperceptible running time) and an error should
// be returned only if the value's configuration is invalid.
type Validator interface {
- Validate() error
+ Validate(Context) error
}
// Provisioner is implemented by modules which may need to perform
// some additional "setup" steps immediately after being loaded.
// This method will be called after Validate() (if implemented).
type Provisioner interface {
- Provision() error
+ Provision(Context) error
+}
+
+// TODO: different name...
+type CleanerUpper interface {
+ Cleanup() error
}
var (