forked from thecodeteam/libstorage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch replaces PR thecodeteam#557 and introduces support for type-isolated Go plug-ins. The 'api/types/v1' package represents an initial version of the libStorage type system transformed into interfaces for use by independent, separate module files.
- Loading branch information
Showing
16 changed files
with
1,050 additions
and
1,501 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// +build go1.8,linux,mods | ||
|
||
package mods | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
"plugin" | ||
"strconv" | ||
"sync" | ||
|
||
"github.com/akutz/gotil" | ||
|
||
"github.com/codedellemc/libstorage/api/registry" | ||
"github.com/codedellemc/libstorage/api/types" | ||
) | ||
|
||
var ( | ||
loadedMods = map[string]bool{} | ||
loadedModsLock = sync.Mutex{} | ||
) | ||
|
||
// LoadModules loads the shared objects present on the file system | ||
// as libStorage plug-ins. | ||
func LoadModules( | ||
ctx types.Context, | ||
pathConfig *types.PathConfig) error { | ||
|
||
disabled, _ := strconv.ParseBool( | ||
os.Getenv("LIBSTORAGE_PLUGINS_DISABLED")) | ||
if disabled { | ||
ctx.Debug("plugin support disabled") | ||
return nil | ||
} | ||
|
||
loadedModsLock.Lock() | ||
defer loadedModsLock.Unlock() | ||
|
||
if !gotil.FileExists(pathConfig.Mod) { | ||
return fmt.Errorf("error: invalid mod dir: %v", pathConfig.Mod) | ||
} | ||
|
||
modFilePathMatches, err := filepath.Glob(path.Join(pathConfig.Mod, "/*.so")) | ||
if err != nil { | ||
// since the only possible error is ErrBadPattern then make sure | ||
// it panics the program since it should never be an invalid pattern | ||
panic(err) | ||
} | ||
|
||
for _, modFilePath := range modFilePathMatches { | ||
ctx.WithField( | ||
"path", modFilePath).Debug( | ||
"loading module") | ||
|
||
if loaded, ok := loadedMods[modFilePath]; ok && loaded { | ||
ctx.WithField( | ||
"path", modFilePath).Debug( | ||
"already loaded") | ||
continue | ||
} | ||
|
||
p, err := plugin.Open(modFilePath) | ||
if err != nil { | ||
ctx.WithError(err).WithField( | ||
"path", modFilePath).Error( | ||
"error opening module") | ||
continue | ||
} | ||
|
||
if err := loadPluginTypes(ctx, p); err != nil { | ||
continue | ||
} | ||
|
||
loadedMods[modFilePath] = true | ||
ctx.WithField( | ||
"path", modFilePath).Info( | ||
"loaded module") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func loadPluginTypes(ctx types.Context, p *plugin.Plugin) error { | ||
// lookup the plug-in's Types symbol; it's the type map used to | ||
// register the plug-in's modules | ||
tmapObj, err := p.Lookup("Types") | ||
if err != nil { | ||
ctx.WithError(err).Error("error looking up type map") | ||
return err | ||
} | ||
|
||
// assert that the Types symbol is a *map[string]func() interface{} | ||
tmapPtr, tmapOk := tmapObj.(*map[string]func() interface{}) | ||
if !tmapOk { | ||
err := fmt.Errorf("invalid type map: %T", tmapObj) | ||
ctx.Error(err) | ||
return err | ||
} | ||
|
||
// assert that the type map pointer is not nil | ||
if tmapPtr == nil { | ||
err := fmt.Errorf("nil type map: type=%[1]T val=%[1]v", tmapPtr) | ||
ctx.Error(err) | ||
return err | ||
} | ||
|
||
// dereference the type map pointer | ||
tmap := *tmapPtr | ||
|
||
// register the plug-in's modules | ||
for k, v := range tmap { | ||
registry.RegisterModType(k, v) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// +build !go1.8 !linux !mods | ||
|
||
package mods | ||
|
||
import ( | ||
"github.com/codedellemc/libstorage/api/types" | ||
) | ||
|
||
// LoadModules loads the shared objects present on the file system | ||
// as libStorage plug-ins. | ||
func LoadModules( | ||
ctx types.Context, | ||
pathConfig *types.PathConfig) { | ||
|
||
// Do nothing | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package v1 | ||
|
||
// AuthToken is a JSON Web Token. | ||
// | ||
// All fields related to times are stored as UTC epochs in seconds. | ||
type AuthToken interface { | ||
|
||
// GetSubject is the intended principal of the token. | ||
GetSubject() string | ||
|
||
// GetExpires is the time at which the token expires. | ||
GetExpires() int64 | ||
|
||
// GetNotBefore is the the time at which the token becomes valid. | ||
GetNotBefore() int64 | ||
|
||
// GetIssuedAt is the time at which the token was issued. | ||
GetIssuedAt() int64 | ||
|
||
// GetEncoded is the encoded JWT string. | ||
GetEncoded() string | ||
} | ||
|
||
// AuthConfig is the auth configuration. | ||
type AuthConfig interface { | ||
|
||
// GetDisabled is a flag indicating whether the auth configuration is | ||
// disabled. | ||
GetDisabled() bool | ||
|
||
// GetAllow is a list of allowed tokens. | ||
GetAllow() []string | ||
|
||
// GetDeny is a list of denied tokens. | ||
GetDeny() []string | ||
|
||
// GetKey is the signing key. | ||
GetKey() []byte | ||
|
||
// GetAlg is the cryptographic algorithm used to sign and verify the token. | ||
GetAlg() string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package v1 | ||
|
||
// Config is the interface that enables retrieving configuration information. | ||
// The variations of the Get function, the Set, IsSet, and Scope functions | ||
// all take an interface{} as their first parameter. However, the param must be | ||
// either a string or a fmt.Stringer, otherwise the function will panic. | ||
type Config interface { | ||
|
||
// GetString returns the value associated with the key as a string | ||
GetString(k interface{}) string | ||
|
||
// GetBool returns the value associated with the key as a bool | ||
GetBool(k interface{}) bool | ||
|
||
// GetStringSlice returns the value associated with the key as a string | ||
// slice. | ||
GetStringSlice(k interface{}) []string | ||
|
||
// GetInt returns the value associated with the key as an int | ||
GetInt(k interface{}) int | ||
|
||
// Get returns the value associated with the key | ||
Get(k interface{}) interface{} | ||
|
||
// Set sets an override value | ||
Set(k interface{}, v interface{}) | ||
|
||
// IsSet returns a flag indicating whether or not a key is set. | ||
IsSet(k interface{}) bool | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package v1 | ||
|
||
import "context" | ||
|
||
// Context is an extension of the Go Context. | ||
type Context interface { | ||
context.Context | ||
} | ||
|
||
// ContextLoggerFieldAware is used by types that will be logged by the | ||
// Context logger. The key/value pair returned by the type is then emitted | ||
// as part of the Context's log entry. | ||
type ContextLoggerFieldAware interface { | ||
|
||
// ContextLoggerField is the fields that is logged as part of a Context's | ||
// log entry. | ||
ContextLoggerField() (string, interface{}) | ||
} | ||
|
||
// ContextLoggerFieldsAware is used by types that will be logged by the | ||
// Context logger. The fields returned by the type are then emitted as part of | ||
// the Context's log entry. | ||
type ContextLoggerFieldsAware interface { | ||
|
||
// ContextLoggerFields are the fields that are logged as part of a | ||
// Context's log entry. | ||
ContextLoggerFields() map[string]interface{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package v1 | ||
|
||
// Driver the interface for types that are drivers. | ||
type Driver interface { | ||
|
||
// Do does the operation specified by the opID. | ||
Do( | ||
ctx interface{}, | ||
opID uint64, | ||
args ...interface{}) (result interface{}, err error) | ||
|
||
// Init initializes the driver instance. | ||
Init(ctx, config interface{}) error | ||
|
||
// Name returns the name of the driver. | ||
Name() string | ||
|
||
// Supports returns a mask of the operations supported by the driver. | ||
Supports() uint64 | ||
} | ||
|
||
const ( | ||
// DtStorage indicates the storage driver type. | ||
DtStorage uint8 = 1 << iota | ||
|
||
// DtIntegration indicates the integration driver type. | ||
DtIntegration | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package v1 | ||
|
||
import "errors" | ||
|
||
// ErrInvalidContext indicates an invalid object was provided as | ||
// the argument to a Context parameter. | ||
var ErrInvalidContext = errors.New("invalid context type") | ||
|
||
// ErrInvalidConfig indicates an invalid object was provided as | ||
// the argument to a Config parameter. | ||
var ErrInvalidConfig = errors.New("invalid config type") | ||
|
||
// ErrInvalidOp indicates an invalid operation ID. | ||
var ErrInvalidOp = errors.New("invalid op") | ||
|
||
// ErrInvalidArgsLen indicates the operation received an incorrect | ||
// number of arguments. | ||
var ErrInvalidArgsLen = errors.New("invalid args len") | ||
|
||
// ErrInvalidArgs indicates the operation received one or more | ||
// invalid arguments. | ||
var ErrInvalidArgs = errors.New("invalid args") |
Oops, something went wrong.