mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #28949 from yongtang/28717-docker-plugin-create
Use GetByName to check for collision before create any context in plugin creation
This commit is contained in:
commit
9d884986f5
2 changed files with 23 additions and 11 deletions
|
@ -311,15 +311,29 @@ func (pm *Manager) Set(name string, args []string) error {
|
|||
// CreateFromContext creates a plugin from the given pluginDir which contains
|
||||
// both the rootfs and the config.json and a repoName with optional tag.
|
||||
func (pm *Manager) CreateFromContext(ctx context.Context, tarCtx io.Reader, options *types.PluginCreateOptions) error {
|
||||
repoName := options.RepoName
|
||||
ref, err := distribution.GetRef(repoName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := ref.Name()
|
||||
tag := distribution.GetTag(ref)
|
||||
pluginID := stringid.GenerateNonCryptoID()
|
||||
|
||||
p := v2.NewPlugin(name, pluginID, pm.runRoot, pm.libRoot, tag)
|
||||
|
||||
if v, _ := pm.pluginStore.GetByName(p.Name()); v != nil {
|
||||
return fmt.Errorf("plugin %q already exists", p.Name())
|
||||
}
|
||||
|
||||
pluginDir := filepath.Join(pm.libRoot, pluginID)
|
||||
if err := os.MkdirAll(pluginDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// In case an error happens, remove the created directory.
|
||||
if err := pm.createFromContext(ctx, pluginID, pluginDir, tarCtx, options); err != nil {
|
||||
if err := pm.createFromContext(ctx, tarCtx, pluginDir, repoName, p); err != nil {
|
||||
if err := os.RemoveAll(pluginDir); err != nil {
|
||||
logrus.Warnf("unable to remove %q from failed plugin creation: %v", pluginDir, err)
|
||||
}
|
||||
|
@ -329,20 +343,11 @@ func (pm *Manager) CreateFromContext(ctx context.Context, tarCtx io.Reader, opti
|
|||
return nil
|
||||
}
|
||||
|
||||
func (pm *Manager) createFromContext(ctx context.Context, pluginID, pluginDir string, tarCtx io.Reader, options *types.PluginCreateOptions) error {
|
||||
func (pm *Manager) createFromContext(ctx context.Context, tarCtx io.Reader, pluginDir, repoName string, p *v2.Plugin) error {
|
||||
if err := chrootarchive.Untar(tarCtx, pluginDir, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repoName := options.RepoName
|
||||
ref, err := distribution.GetRef(repoName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := ref.Name()
|
||||
tag := distribution.GetTag(ref)
|
||||
|
||||
p := v2.NewPlugin(name, pluginID, pm.runRoot, pm.libRoot, tag)
|
||||
if err := p.InitPlugin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -113,6 +113,13 @@ func (ps *Store) Add(p *v2.Plugin) error {
|
|||
if v, exist := ps.plugins[p.GetID()]; exist {
|
||||
return fmt.Errorf("plugin %q has the same ID %s as %q", p.Name(), p.GetID(), v.Name())
|
||||
}
|
||||
// Since both Pull() and CreateFromContext() calls GetByName() before any plugin
|
||||
// to search for collision (to fail fast), it is unlikely the following check
|
||||
// will return an error.
|
||||
// However, in case two CreateFromContext() are called at the same time,
|
||||
// there is still a remote possibility that a collision might happen.
|
||||
// For that reason we still perform the collision check below as it is protected
|
||||
// by ps.Lock() and ps.Unlock() above.
|
||||
if _, exist := ps.nameToID[p.Name()]; exist {
|
||||
return fmt.Errorf("plugin %q already exists", p.Name())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue