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
|
// CreateFromContext creates a plugin from the given pluginDir which contains
|
||||||
// both the rootfs and the config.json and a repoName with optional tag.
|
// 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 {
|
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()
|
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)
|
pluginDir := filepath.Join(pm.libRoot, pluginID)
|
||||||
if err := os.MkdirAll(pluginDir, 0755); err != nil {
|
if err := os.MkdirAll(pluginDir, 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case an error happens, remove the created directory.
|
// 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 {
|
if err := os.RemoveAll(pluginDir); err != nil {
|
||||||
logrus.Warnf("unable to remove %q from failed plugin creation: %v", pluginDir, err)
|
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
|
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 {
|
if err := chrootarchive.Untar(tarCtx, pluginDir, nil); err != nil {
|
||||||
return err
|
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 {
|
if err := p.InitPlugin(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,13 @@ func (ps *Store) Add(p *v2.Plugin) error {
|
||||||
if v, exist := ps.plugins[p.GetID()]; exist {
|
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())
|
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 {
|
if _, exist := ps.nameToID[p.Name()]; exist {
|
||||||
return fmt.Errorf("plugin %q already exists", p.Name())
|
return fmt.Errorf("plugin %q already exists", p.Name())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue