code: func (pm *Manager) createPlugin(name string, configDigest digest.Digest, blobsums []digest.Digest, rootFSDir string, privileges *types.PluginPrivileges, opts ...CreateOpt) (p *v2.Plugin, err error) {
  	if err := pm.config.Store.validateName(name); err != nil { // todo: this check is wrong. remove store
  		return nil, errdefs.InvalidParameter(err)
  	}
  
  	config, err := pm.setupNewPlugin(configDigest, blobsums, privileges)
  	if err != nil {
  		return nil, err
  	}
  
  	p = &v2.Plugin{
  		PluginObj: types.Plugin{
  			Name:   name,
  			ID:     stringid.GenerateRandomID(),
  			Config: config,
  		},
  		Config:   configDigest,
  		Blobsums: blobsums,
  	}
  	p.InitEmptySettings()
  	for _, o := range opts {
  		o(p)
  	}
  
  	pdir := filepath.Join(pm.config.Root, p.PluginObj.ID)
  	if err := os.MkdirAll(pdir, 0700); err != nil {
  		return nil, errors.Wrapf(err, "failed to mkdir %v", pdir)
  	}
  
  	defer func() {
  		if err != nil {
  			os.RemoveAll(pdir)
  		}
  	}()
  
  	if err := os.Rename(rootFSDir, filepath.Join(pdir, rootFSFileName)); err != nil {
  		return nil, errors.Wrap(err, "failed to rename rootfs")
  	}
  
  	if err := pm.save(p); err != nil {
  		return nil, err
  	}
  
  	pm.config.Store.Add(p) // todo: remove
  
  	return p, nil
  }
docs: // createPlugin creates a new plugin. take lock before calling.