mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #29191 from anusha-ragunathan/plugin_races
Make v2/Plugin accesses safe.
This commit is contained in:
commit
9d898b872e
7 changed files with 133 additions and 74 deletions
|
@ -37,7 +37,11 @@ func (pm *Manager) Disable(name string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := pm.disable(p); err != nil {
|
pm.mu.RLock()
|
||||||
|
c := pm.cMap[p]
|
||||||
|
pm.mu.RUnlock()
|
||||||
|
|
||||||
|
if err := pm.disable(p, c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pm.pluginEventLogger(p.GetID(), name, "disable")
|
pm.pluginEventLogger(p.GetID(), name, "disable")
|
||||||
|
@ -46,14 +50,13 @@ func (pm *Manager) Disable(name string) error {
|
||||||
|
|
||||||
// Enable activates a plugin, which implies that they are ready to be used by containers.
|
// Enable activates a plugin, which implies that they are ready to be used by containers.
|
||||||
func (pm *Manager) Enable(name string, config *types.PluginEnableConfig) error {
|
func (pm *Manager) Enable(name string, config *types.PluginEnableConfig) error {
|
||||||
|
|
||||||
p, err := pm.pluginStore.GetByName(name)
|
p, err := pm.pluginStore.GetByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.TimeoutInSecs = config.Timeout
|
c := &controller{timeoutInSecs: config.Timeout}
|
||||||
if err := pm.enable(p, false); err != nil {
|
if err := pm.enable(p, c, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pm.pluginEventLogger(p.GetID(), name, "enable")
|
pm.pluginEventLogger(p.GetID(), name, "enable")
|
||||||
|
@ -267,25 +270,25 @@ func (pm *Manager) Push(name string, metaHeader http.Header, authConfig *types.A
|
||||||
// Remove deletes plugin's root directory.
|
// Remove deletes plugin's root directory.
|
||||||
func (pm *Manager) Remove(name string, config *types.PluginRmConfig) error {
|
func (pm *Manager) Remove(name string, config *types.PluginRmConfig) error {
|
||||||
p, err := pm.pluginStore.GetByName(name)
|
p, err := pm.pluginStore.GetByName(name)
|
||||||
|
pm.mu.RLock()
|
||||||
|
c := pm.cMap[p]
|
||||||
|
pm.mu.RUnlock()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.ForceRemove {
|
if !config.ForceRemove {
|
||||||
p.RLock()
|
if p.GetRefCount() > 0 {
|
||||||
if p.RefCount > 0 {
|
|
||||||
p.RUnlock()
|
|
||||||
return fmt.Errorf("plugin %s is in use", p.Name())
|
return fmt.Errorf("plugin %s is in use", p.Name())
|
||||||
}
|
}
|
||||||
p.RUnlock()
|
|
||||||
|
|
||||||
if p.IsEnabled() {
|
if p.IsEnabled() {
|
||||||
return fmt.Errorf("plugin %s is enabled", p.Name())
|
return fmt.Errorf("plugin %s is enabled", p.Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.IsEnabled() {
|
if p.IsEnabled() {
|
||||||
if err := pm.disable(p); err != nil {
|
if err := pm.disable(p, c); err != nil {
|
||||||
logrus.Errorf("failed to disable plugin '%s': %s", p.Name(), err)
|
logrus.Errorf("failed to disable plugin '%s': %s", p.Name(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pm *Manager) restorePlugin(p *v2.Plugin) error {
|
func (pm *Manager) restorePlugin(p *v2.Plugin) error {
|
||||||
p.RuntimeSourcePath = filepath.Join(pm.runRoot, p.GetID())
|
p.Restore(pm.runRoot)
|
||||||
if p.IsEnabled() {
|
if p.IsEnabled() {
|
||||||
return pm.restore(p)
|
return pm.restore(p)
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,15 @@ type Manager struct {
|
||||||
registryService registry.Service
|
registryService registry.Service
|
||||||
liveRestore bool
|
liveRestore bool
|
||||||
pluginEventLogger eventLogger
|
pluginEventLogger eventLogger
|
||||||
|
mu sync.RWMutex // protects cMap
|
||||||
|
cMap map[*v2.Plugin]*controller
|
||||||
|
}
|
||||||
|
|
||||||
|
// controller represents the manager's control on a plugin.
|
||||||
|
type controller struct {
|
||||||
|
restart bool
|
||||||
|
exitChan chan bool
|
||||||
|
timeoutInSecs int
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetManager returns the singleton plugin Manager
|
// GetManager returns the singleton plugin Manager
|
||||||
|
@ -67,7 +76,8 @@ func Init(root string, ps *store.Store, remote libcontainerd.Remote, rs registry
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := manager.init(); err != nil {
|
manager.cMap = make(map[*v2.Plugin]*controller)
|
||||||
|
if err := manager.reload(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -83,22 +93,27 @@ func (pm *Manager) StateChanged(id string, e libcontainerd.StateInfo) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.RLock()
|
|
||||||
if p.ExitChan != nil {
|
pm.mu.RLock()
|
||||||
close(p.ExitChan)
|
c := pm.cMap[p]
|
||||||
|
|
||||||
|
if c.exitChan != nil {
|
||||||
|
close(c.exitChan)
|
||||||
}
|
}
|
||||||
restart := p.Restart
|
restart := c.restart
|
||||||
p.RUnlock()
|
pm.mu.RUnlock()
|
||||||
|
|
||||||
p.RemoveFromDisk()
|
p.RemoveFromDisk()
|
||||||
if restart {
|
if restart {
|
||||||
pm.enable(p, true)
|
pm.enable(p, c, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) init() error {
|
// reload is used on daemon restarts to load the manager's state
|
||||||
|
func (pm *Manager) reload() error {
|
||||||
dt, err := os.Open(filepath.Join(pm.libRoot, "plugins.json"))
|
dt, err := os.Open(filepath.Join(pm.libRoot, "plugins.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
@ -117,6 +132,8 @@ func (pm *Manager) init() error {
|
||||||
var group sync.WaitGroup
|
var group sync.WaitGroup
|
||||||
group.Add(len(plugins))
|
group.Add(len(plugins))
|
||||||
for _, p := range plugins {
|
for _, p := range plugins {
|
||||||
|
c := &controller{}
|
||||||
|
pm.cMap[p] = c
|
||||||
go func(p *v2.Plugin) {
|
go func(p *v2.Plugin) {
|
||||||
defer group.Done()
|
defer group.Done()
|
||||||
if err := pm.restorePlugin(p); err != nil {
|
if err := pm.restorePlugin(p); err != nil {
|
||||||
|
@ -129,7 +146,7 @@ func (pm *Manager) init() error {
|
||||||
|
|
||||||
if requiresManualRestore {
|
if requiresManualRestore {
|
||||||
// if liveRestore is not enabled, the plugin will be stopped now so we should enable it
|
// if liveRestore is not enabled, the plugin will be stopped now so we should enable it
|
||||||
if err := pm.enable(p, true); err != nil {
|
if err := pm.enable(p, c, true); err != nil {
|
||||||
logrus.Errorf("failed to enable plugin '%s': %s", p.Name(), err)
|
logrus.Errorf("failed to enable plugin '%s': %s", p.Name(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pm *Manager) enable(p *v2.Plugin, force bool) error {
|
func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
|
||||||
if p.IsEnabled() && !force {
|
if p.IsEnabled() && !force {
|
||||||
return fmt.Errorf("plugin %s is already enabled", p.Name())
|
return fmt.Errorf("plugin %s is already enabled", p.Name())
|
||||||
}
|
}
|
||||||
|
@ -24,23 +24,26 @@ func (pm *Manager) enable(p *v2.Plugin, force bool) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.Lock()
|
|
||||||
p.Restart = true
|
c.restart = true
|
||||||
p.ExitChan = make(chan bool)
|
c.exitChan = make(chan bool)
|
||||||
p.Unlock()
|
|
||||||
|
pm.mu.Lock()
|
||||||
|
pm.cMap[p] = c
|
||||||
|
pm.mu.Unlock()
|
||||||
|
|
||||||
if err := pm.containerdClient.Create(p.GetID(), "", "", specs.Spec(*spec), attachToLog(p.GetID())); err != nil {
|
if err := pm.containerdClient.Create(p.GetID(), "", "", specs.Spec(*spec), attachToLog(p.GetID())); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.PClient, err = plugins.NewClientWithTimeout("unix://"+filepath.Join(p.RuntimeSourcePath, p.GetSocket()), nil, p.TimeoutInSecs)
|
client, err := plugins.NewClientWithTimeout("unix://"+filepath.Join(p.GetRuntimeSourcePath(), p.GetSocket()), nil, c.timeoutInSecs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.Lock()
|
c.restart = false
|
||||||
p.Restart = false
|
shutdownPlugin(p, c, pm.containerdClient)
|
||||||
p.Unlock()
|
|
||||||
shutdownPlugin(p, pm.containerdClient)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.SetPClient(client)
|
||||||
pm.pluginStore.SetState(p, true)
|
pm.pluginStore.SetState(p, true)
|
||||||
pm.pluginStore.CallHandler(p)
|
pm.pluginStore.CallHandler(p)
|
||||||
|
|
||||||
|
@ -51,7 +54,7 @@ func (pm *Manager) restore(p *v2.Plugin) error {
|
||||||
return pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID()))
|
return pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func shutdownPlugin(p *v2.Plugin, containerdClient libcontainerd.Client) {
|
func shutdownPlugin(p *v2.Plugin, c *controller, containerdClient libcontainerd.Client) {
|
||||||
pluginID := p.GetID()
|
pluginID := p.GetID()
|
||||||
|
|
||||||
err := containerdClient.Signal(pluginID, int(syscall.SIGTERM))
|
err := containerdClient.Signal(pluginID, int(syscall.SIGTERM))
|
||||||
|
@ -59,7 +62,7 @@ func shutdownPlugin(p *v2.Plugin, containerdClient libcontainerd.Client) {
|
||||||
logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
|
logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
|
||||||
} else {
|
} else {
|
||||||
select {
|
select {
|
||||||
case <-p.ExitChan:
|
case <-c.exitChan:
|
||||||
logrus.Debug("Clean shutdown of plugin")
|
logrus.Debug("Clean shutdown of plugin")
|
||||||
case <-time.After(time.Second * 10):
|
case <-time.After(time.Second * 10):
|
||||||
logrus.Debug("Force shutdown plugin")
|
logrus.Debug("Force shutdown plugin")
|
||||||
|
@ -70,15 +73,13 @@ func shutdownPlugin(p *v2.Plugin, containerdClient libcontainerd.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) disable(p *v2.Plugin) error {
|
func (pm *Manager) disable(p *v2.Plugin, c *controller) error {
|
||||||
if !p.IsEnabled() {
|
if !p.IsEnabled() {
|
||||||
return fmt.Errorf("plugin %s is already disabled", p.Name())
|
return fmt.Errorf("plugin %s is already disabled", p.Name())
|
||||||
}
|
}
|
||||||
p.Lock()
|
|
||||||
p.Restart = false
|
|
||||||
p.Unlock()
|
|
||||||
|
|
||||||
shutdownPlugin(p, pm.containerdClient)
|
c.restart = false
|
||||||
|
shutdownPlugin(p, c, pm.containerdClient)
|
||||||
pm.pluginStore.SetState(p, false)
|
pm.pluginStore.SetState(p, false)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -87,15 +88,17 @@ func (pm *Manager) disable(p *v2.Plugin) error {
|
||||||
func (pm *Manager) Shutdown() {
|
func (pm *Manager) Shutdown() {
|
||||||
plugins := pm.pluginStore.GetAll()
|
plugins := pm.pluginStore.GetAll()
|
||||||
for _, p := range plugins {
|
for _, p := range plugins {
|
||||||
|
pm.mu.RLock()
|
||||||
|
c := pm.cMap[p]
|
||||||
|
pm.mu.RUnlock()
|
||||||
|
|
||||||
if pm.liveRestore && p.IsEnabled() {
|
if pm.liveRestore && p.IsEnabled() {
|
||||||
logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
|
logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if pm.containerdClient != nil && p.IsEnabled() {
|
if pm.containerdClient != nil && p.IsEnabled() {
|
||||||
p.Lock()
|
c.restart = false
|
||||||
p.Restart = false
|
shutdownPlugin(p, c, pm.containerdClient)
|
||||||
p.Unlock()
|
|
||||||
shutdownPlugin(p, pm.containerdClient)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pm *Manager) enable(p *v2.Plugin, force bool) error {
|
func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
|
||||||
return fmt.Errorf("Not implemented")
|
return fmt.Errorf("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ func (pm *Manager) initSpec(p *v2.Plugin) (*specs.Spec, error) {
|
||||||
return nil, fmt.Errorf("Not implemented")
|
return nil, fmt.Errorf("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) disable(p *v2.Plugin) error {
|
func (pm *Manager) disable(p *v2.Plugin, c *controller) error {
|
||||||
return fmt.Errorf("Not implemented")
|
return fmt.Errorf("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pm *Manager) enable(p *v2.Plugin, force bool) error {
|
func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
|
||||||
return fmt.Errorf("Not implemented")
|
return fmt.Errorf("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ func (pm *Manager) initSpec(p *v2.Plugin) (*specs.Spec, error) {
|
||||||
return nil, fmt.Errorf("Not implemented")
|
return nil, fmt.Errorf("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *Manager) disable(p *v2.Plugin) error {
|
func (pm *Manager) disable(p *v2.Plugin, c *controller) error {
|
||||||
return fmt.Errorf("Not implemented")
|
return fmt.Errorf("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,9 +174,7 @@ func (ps *Store) Get(name, capability string, mode int) (plugingetter.CompatPlug
|
||||||
}
|
}
|
||||||
p, err = ps.GetByName(fullName)
|
p, err = ps.GetByName(fullName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
p.Lock()
|
p.SetRefCount(mode + p.GetRefCount())
|
||||||
p.RefCount += mode
|
|
||||||
p.Unlock()
|
|
||||||
if p.IsEnabled() {
|
if p.IsEnabled() {
|
||||||
return p.FilterByCap(capability)
|
return p.FilterByCap(capability)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,12 @@ import (
|
||||||
|
|
||||||
// Plugin represents an individual plugin.
|
// Plugin represents an individual plugin.
|
||||||
type Plugin struct {
|
type Plugin struct {
|
||||||
sync.RWMutex
|
mu sync.RWMutex
|
||||||
PluginObj types.Plugin `json:"plugin"`
|
PluginObj types.Plugin `json:"plugin"`
|
||||||
PClient *plugins.Client `json:"-"`
|
pClient *plugins.Client
|
||||||
RuntimeSourcePath string `json:"-"`
|
runtimeSourcePath string
|
||||||
RefCount int `json:"-"`
|
refCount int
|
||||||
Restart bool `json:"-"`
|
libRoot string
|
||||||
ExitChan chan bool `json:"-"`
|
|
||||||
LibRoot string `json:"-"`
|
|
||||||
TimeoutInSecs int `json:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPluginRuntimeDestination = "/run/docker/plugins"
|
const defaultPluginRuntimeDestination = "/run/docker/plugins"
|
||||||
|
@ -47,14 +44,39 @@ func newPluginObj(name, id, tag string) types.Plugin {
|
||||||
func NewPlugin(name, id, runRoot, libRoot, tag string) *Plugin {
|
func NewPlugin(name, id, runRoot, libRoot, tag string) *Plugin {
|
||||||
return &Plugin{
|
return &Plugin{
|
||||||
PluginObj: newPluginObj(name, id, tag),
|
PluginObj: newPluginObj(name, id, tag),
|
||||||
RuntimeSourcePath: filepath.Join(runRoot, id),
|
runtimeSourcePath: filepath.Join(runRoot, id),
|
||||||
LibRoot: libRoot,
|
libRoot: libRoot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore restores the plugin
|
||||||
|
func (p *Plugin) Restore(runRoot string) {
|
||||||
|
p.runtimeSourcePath = filepath.Join(runRoot, p.GetID())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRuntimeSourcePath gets the Source (host) path of the plugin socket
|
||||||
|
// This path gets bind mounted into the plugin.
|
||||||
|
func (p *Plugin) GetRuntimeSourcePath() string {
|
||||||
|
p.mu.RLock()
|
||||||
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
|
return p.runtimeSourcePath
|
||||||
|
}
|
||||||
|
|
||||||
// Client returns the plugin client.
|
// Client returns the plugin client.
|
||||||
func (p *Plugin) Client() *plugins.Client {
|
func (p *Plugin) Client() *plugins.Client {
|
||||||
return p.PClient
|
p.mu.RLock()
|
||||||
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
|
return p.pClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPClient set the plugin client.
|
||||||
|
func (p *Plugin) SetPClient(client *plugins.Client) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
p.pClient = client
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsV1 returns true for V1 plugins and false otherwise.
|
// IsV1 returns true for V1 plugins and false otherwise.
|
||||||
|
@ -85,12 +107,12 @@ func (p *Plugin) FilterByCap(capability string) (*Plugin, error) {
|
||||||
|
|
||||||
// RemoveFromDisk deletes the plugin's runtime files from disk.
|
// RemoveFromDisk deletes the plugin's runtime files from disk.
|
||||||
func (p *Plugin) RemoveFromDisk() error {
|
func (p *Plugin) RemoveFromDisk() error {
|
||||||
return os.RemoveAll(p.RuntimeSourcePath)
|
return os.RemoveAll(p.runtimeSourcePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitPlugin populates the plugin object from the plugin config file.
|
// InitPlugin populates the plugin object from the plugin config file.
|
||||||
func (p *Plugin) InitPlugin() error {
|
func (p *Plugin) InitPlugin() error {
|
||||||
dt, err := os.Open(filepath.Join(p.LibRoot, p.PluginObj.ID, "config.json"))
|
dt, err := os.Open(filepath.Join(p.libRoot, p.PluginObj.ID, "config.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -118,7 +140,7 @@ func (p *Plugin) InitPlugin() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Plugin) writeSettings() error {
|
func (p *Plugin) writeSettings() error {
|
||||||
f, err := os.Create(filepath.Join(p.LibRoot, p.PluginObj.ID, "plugin-settings.json"))
|
f, err := os.Create(filepath.Join(p.libRoot, p.PluginObj.ID, "plugin-settings.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -129,8 +151,8 @@ func (p *Plugin) writeSettings() error {
|
||||||
|
|
||||||
// Set is used to pass arguments to the plugin.
|
// Set is used to pass arguments to the plugin.
|
||||||
func (p *Plugin) Set(args []string) error {
|
func (p *Plugin) Set(args []string) error {
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
if p.PluginObj.Enabled {
|
if p.PluginObj.Enabled {
|
||||||
return fmt.Errorf("cannot set on an active plugin, disable plugin before setting")
|
return fmt.Errorf("cannot set on an active plugin, disable plugin before setting")
|
||||||
|
@ -218,36 +240,52 @@ next:
|
||||||
|
|
||||||
// IsEnabled returns the active state of the plugin.
|
// IsEnabled returns the active state of the plugin.
|
||||||
func (p *Plugin) IsEnabled() bool {
|
func (p *Plugin) IsEnabled() bool {
|
||||||
p.RLock()
|
p.mu.RLock()
|
||||||
defer p.RUnlock()
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
return p.PluginObj.Enabled
|
return p.PluginObj.Enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the plugin's ID.
|
// GetID returns the plugin's ID.
|
||||||
func (p *Plugin) GetID() string {
|
func (p *Plugin) GetID() string {
|
||||||
p.RLock()
|
p.mu.RLock()
|
||||||
defer p.RUnlock()
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
return p.PluginObj.ID
|
return p.PluginObj.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSocket returns the plugin socket.
|
// GetSocket returns the plugin socket.
|
||||||
func (p *Plugin) GetSocket() string {
|
func (p *Plugin) GetSocket() string {
|
||||||
p.RLock()
|
p.mu.RLock()
|
||||||
defer p.RUnlock()
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
return p.PluginObj.Config.Interface.Socket
|
return p.PluginObj.Config.Interface.Socket
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTypes returns the interface types of a plugin.
|
// GetTypes returns the interface types of a plugin.
|
||||||
func (p *Plugin) GetTypes() []types.PluginInterfaceType {
|
func (p *Plugin) GetTypes() []types.PluginInterfaceType {
|
||||||
p.RLock()
|
p.mu.RLock()
|
||||||
defer p.RUnlock()
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
return p.PluginObj.Config.Interface.Types
|
return p.PluginObj.Config.Interface.Types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRefCount returns the reference count.
|
||||||
|
func (p *Plugin) GetRefCount() int {
|
||||||
|
p.mu.RLock()
|
||||||
|
defer p.mu.RUnlock()
|
||||||
|
|
||||||
|
return p.refCount
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRefCount sets the reference count.
|
||||||
|
func (p *Plugin) SetRefCount(count int) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
p.refCount = count
|
||||||
|
}
|
||||||
|
|
||||||
// InitSpec creates an OCI spec from the plugin's config.
|
// InitSpec creates an OCI spec from the plugin's config.
|
||||||
func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
|
func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
|
||||||
rootfs := filepath.Join(libRoot, p.PluginObj.ID, "rootfs")
|
rootfs := filepath.Join(libRoot, p.PluginObj.ID, "rootfs")
|
||||||
|
@ -262,7 +300,7 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mounts := append(p.PluginObj.Config.Mounts, types.PluginMount{
|
mounts := append(p.PluginObj.Config.Mounts, types.PluginMount{
|
||||||
Source: &p.RuntimeSourcePath,
|
Source: &p.runtimeSourcePath,
|
||||||
Destination: defaultPluginRuntimeDestination,
|
Destination: defaultPluginRuntimeDestination,
|
||||||
Type: "bind",
|
Type: "bind",
|
||||||
Options: []string{"rbind", "rshared"},
|
Options: []string{"rbind", "rshared"},
|
||||||
|
|
Loading…
Reference in a new issue