Add untested plugin support
This commit is contained in:
		
							parent
							
								
									9a6607494f
								
							
						
					
					
						commit
						209270a179
					
				@ -5,7 +5,9 @@ import "io"
 | 
			
		||||
import "fmt"
 | 
			
		||||
import "time"
 | 
			
		||||
import "io/fs"
 | 
			
		||||
import "plugin"
 | 
			
		||||
import "errors"
 | 
			
		||||
import "syscall"
 | 
			
		||||
import "context"
 | 
			
		||||
import "path/filepath"
 | 
			
		||||
import "html/template"
 | 
			
		||||
@ -103,6 +105,55 @@ func (this *Environment) Unload (name string) {
 | 
			
		||||
	delete(documents, name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LoadProviderPlugin loads a plugin given its file path. The file must:
 | 
			
		||||
//
 | 
			
		||||
//   - Be a shared library
 | 
			
		||||
//   - Be built with go -buildmode=plugin
 | 
			
		||||
//   - Be built with the same version of Go
 | 
			
		||||
//   - Be built with the same version of STEP
 | 
			
		||||
//   - Be owned by root
 | 
			
		||||
//
 | 
			
		||||
// Plugins cannot be unloaded from the current program once they are loaded.
 | 
			
		||||
// Sorgy :( its Go's fault.
 | 
			
		||||
func (this *Environment) LoadProviderPlugin (name string) (Provider, error) {
 | 
			
		||||
	return this.loadProviderPlugin(name, true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LoadProviderPluginUnsafe is like LoadProviderPlugin, but does not check to
 | 
			
		||||
// see that the file is owned by root, thereby making it easier to run a random
 | 
			
		||||
// plugin you just compiled. This should not be used otherwise.
 | 
			
		||||
func (this *Environment) LoadProviderPluginUnsafe (name string) (Provider, error) {
 | 
			
		||||
	return this.loadProviderPlugin(name, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Environment) loadProviderPlugin (name string, checkRoot bool) (Provider, error) {
 | 
			
		||||
	plugin, err := this.loadPlugin(name, checkRoot)
 | 
			
		||||
	if err != nil { return nil, err }
 | 
			
		||||
	providerSymbol, err := plugin.Lookup("Provider")
 | 
			
		||||
	if err != nil { return nil, err }
 | 
			
		||||
	providerFactory, ok := providerSymbol.(func () Provider)
 | 
			
		||||
	if !ok { return nil, ErrPluginBadSymbol }
 | 
			
		||||
	provider := providerFactory()
 | 
			
		||||
	this.Providers = append(this.Providers, provider)
 | 
			
		||||
	return provider, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Environment) loadPlugin (name string, checkRoot bool) (*plugin.Plugin, error) {
 | 
			
		||||
	name = filepath.Clean(name)
 | 
			
		||||
	if checkRoot {
 | 
			
		||||
		info, err := os.Stat(name)
 | 
			
		||||
		if err != nil { return nil, err }
 | 
			
		||||
		if info, ok := info.Sys().(*syscall.Stat_t); ok {
 | 
			
		||||
			if info.Uid != 0 {
 | 
			
		||||
				return nil, ErrPluginNotOwnedByRoot
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			return nil, ErrInsufficientSystem
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return plugin.Open(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Environment) parse (name string, modTime time.Time, input io.Reader) (*Document, error) {
 | 
			
		||||
	documents, done := this.documents.Borrow()
 | 
			
		||||
	defer done()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								error.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								error.go
									
									
									
									
									
								
							@ -2,10 +2,13 @@ package step
 | 
			
		||||
 | 
			
		||||
// Error enumerates errors common to this package.
 | 
			
		||||
type Error string; const (
 | 
			
		||||
	ErrCircularInheritance Error = "circular inheritance"
 | 
			
		||||
	ErrMetaMalformed       Error = "metadata is malformed"
 | 
			
		||||
	ErrMetaNeverClosed     Error = "metadata is never closed"
 | 
			
		||||
	ErrTypeMismatch        Error = "type mismatch"
 | 
			
		||||
	ErrCircularInheritance  Error = "circular inheritance"
 | 
			
		||||
	ErrMetaMalformed        Error = "metadata is malformed"
 | 
			
		||||
	ErrMetaNeverClosed      Error = "metadata is never closed"
 | 
			
		||||
	ErrTypeMismatch         Error = "type mismatch"
 | 
			
		||||
	ErrPluginBadSymbol      Error = "plugin has an incorrect symbol"
 | 
			
		||||
	ErrPluginNotOwnedByRoot Error = "plugin is not owned by the root user"
 | 
			
		||||
	ErrInsufficientSystem   Error = "the system cannot perform this action"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Error fulfills the error interface.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user