1
0
Fork 0
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:
Anusha Ragunathan 2016-12-09 09:12:08 -08:00 committed by GitHub
commit 9d884986f5
2 changed files with 23 additions and 11 deletions

View file

@ -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
}

View file

@ -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())
}