github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/plugin/backend.go (about)

     1  package plugin
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	"github.com/Sirupsen/logrus"
    13  	"github.com/docker/docker/api/types"
    14  	"github.com/docker/docker/pkg/archive"
    15  	"github.com/docker/docker/pkg/stringid"
    16  	"github.com/docker/docker/plugin/distribution"
    17  	"github.com/docker/docker/plugin/v2"
    18  )
    19  
    20  // Disable deactivates a plugin, which implies that they cannot be used by containers.
    21  func (pm *Manager) Disable(name string) error {
    22  	p, err := pm.pluginStore.GetByName(name)
    23  	if err != nil {
    24  		return err
    25  	}
    26  	if err := pm.disable(p); err != nil {
    27  		return err
    28  	}
    29  	pm.pluginEventLogger(p.GetID(), name, "disable")
    30  	return nil
    31  }
    32  
    33  // Enable activates a plugin, which implies that they are ready to be used by containers.
    34  func (pm *Manager) Enable(name string) error {
    35  	p, err := pm.pluginStore.GetByName(name)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	if err := pm.enable(p, false); err != nil {
    40  		return err
    41  	}
    42  	pm.pluginEventLogger(p.GetID(), name, "enable")
    43  	return nil
    44  }
    45  
    46  // Inspect examines a plugin manifest
    47  func (pm *Manager) Inspect(name string) (tp types.Plugin, err error) {
    48  	p, err := pm.pluginStore.GetByName(name)
    49  	if err != nil {
    50  		return tp, err
    51  	}
    52  	return p.PluginObj, nil
    53  }
    54  
    55  // Pull pulls a plugin and computes the privileges required to install it.
    56  func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
    57  	ref, err := distribution.GetRef(name)
    58  	if err != nil {
    59  		logrus.Debugf("error in distribution.GetRef: %v", err)
    60  		return nil, err
    61  	}
    62  	name = ref.String()
    63  
    64  	if p, _ := pm.pluginStore.GetByName(name); p != nil {
    65  		logrus.Debugf("plugin already exists")
    66  		return nil, fmt.Errorf("%s exists", name)
    67  	}
    68  
    69  	pluginID := stringid.GenerateNonCryptoID()
    70  
    71  	if err := os.MkdirAll(filepath.Join(pm.libRoot, pluginID), 0755); err != nil {
    72  		logrus.Debugf("error in MkdirAll: %v", err)
    73  		return nil, err
    74  	}
    75  
    76  	pd, err := distribution.Pull(ref, pm.registryService, metaHeader, authConfig)
    77  	if err != nil {
    78  		logrus.Debugf("error in distribution.Pull(): %v", err)
    79  		return nil, err
    80  	}
    81  
    82  	if err := distribution.WritePullData(pd, filepath.Join(pm.libRoot, pluginID), true); err != nil {
    83  		logrus.Debugf("error in distribution.WritePullData(): %v", err)
    84  		return nil, err
    85  	}
    86  
    87  	tag := distribution.GetTag(ref)
    88  	p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, tag)
    89  	if err := p.InitPlugin(pm.libRoot); err != nil {
    90  		return nil, err
    91  	}
    92  	pm.pluginStore.Add(p)
    93  
    94  	pm.pluginEventLogger(pluginID, name, "pull")
    95  	return p.ComputePrivileges(), nil
    96  }
    97  
    98  // List displays the list of plugins and associated metadata.
    99  func (pm *Manager) List() ([]types.Plugin, error) {
   100  	plugins := pm.pluginStore.GetAll()
   101  	out := make([]types.Plugin, 0, len(plugins))
   102  	for _, p := range plugins {
   103  		out = append(out, p.PluginObj)
   104  	}
   105  	return out, nil
   106  }
   107  
   108  // Push pushes a plugin to the store.
   109  func (pm *Manager) Push(name string, metaHeader http.Header, authConfig *types.AuthConfig) error {
   110  	p, err := pm.pluginStore.GetByName(name)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	dest := filepath.Join(pm.libRoot, p.GetID())
   115  	config, err := ioutil.ReadFile(filepath.Join(dest, "manifest.json"))
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	var dummy types.Plugin
   121  	err = json.Unmarshal(config, &dummy)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	rootfs, err := archive.Tar(filepath.Join(dest, "rootfs"), archive.Gzip)
   127  	if err != nil {
   128  		return err
   129  	}
   130  	defer rootfs.Close()
   131  
   132  	_, err = distribution.Push(name, pm.registryService, metaHeader, authConfig, ioutil.NopCloser(bytes.NewReader(config)), rootfs)
   133  	// XXX: Ignore returning digest for now.
   134  	// Since digest needs to be written to the ProgressWriter.
   135  	return err
   136  }
   137  
   138  // Remove deletes plugin's root directory.
   139  func (pm *Manager) Remove(name string, config *types.PluginRmConfig) error {
   140  	p, err := pm.pluginStore.GetByName(name)
   141  	if err != nil {
   142  		return err
   143  	}
   144  
   145  	if !config.ForceRemove {
   146  		p.RLock()
   147  		if p.RefCount > 0 {
   148  			p.RUnlock()
   149  			return fmt.Errorf("plugin %s is in use", p.Name())
   150  		}
   151  		p.RUnlock()
   152  
   153  		if p.IsEnabled() {
   154  			return fmt.Errorf("plugin %s is enabled", p.Name())
   155  		}
   156  	}
   157  
   158  	if p.IsEnabled() {
   159  		if err := pm.disable(p); err != nil {
   160  			logrus.Errorf("failed to disable plugin '%s': %s", p.Name(), err)
   161  		}
   162  	}
   163  
   164  	pm.pluginStore.Remove(p)
   165  	pm.pluginEventLogger(p.GetID(), name, "remove")
   166  	return nil
   167  }
   168  
   169  // Set sets plugin args
   170  func (pm *Manager) Set(name string, args []string) error {
   171  	p, err := pm.pluginStore.GetByName(name)
   172  	if err != nil {
   173  		return err
   174  	}
   175  	return p.Set(args)
   176  }