backend.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // +build experimental
  2. package plugin
  3. import (
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "path/filepath"
  8. "github.com/Sirupsen/logrus"
  9. "github.com/docker/docker/pkg/archive"
  10. "github.com/docker/docker/pkg/stringid"
  11. "github.com/docker/docker/plugin/distribution"
  12. "github.com/docker/docker/reference"
  13. "github.com/docker/engine-api/types"
  14. )
  15. // Disable deactivates a plugin, which implies that they cannot be used by containers.
  16. func (pm *Manager) Disable(name string) error {
  17. p, err := pm.get(name)
  18. if err != nil {
  19. return err
  20. }
  21. if err := pm.disable(p); err != nil {
  22. return err
  23. }
  24. pm.pluginEventLogger(p.PluginObj.ID, name, "disable")
  25. return nil
  26. }
  27. // Enable activates a plugin, which implies that they are ready to be used by containers.
  28. func (pm *Manager) Enable(name string) error {
  29. p, err := pm.get(name)
  30. if err != nil {
  31. return err
  32. }
  33. if err := pm.enable(p); err != nil {
  34. return err
  35. }
  36. pm.pluginEventLogger(p.PluginObj.ID, name, "enable")
  37. return nil
  38. }
  39. // Inspect examines a plugin manifest
  40. func (pm *Manager) Inspect(name string) (tp types.Plugin, err error) {
  41. p, err := pm.get(name)
  42. if err != nil {
  43. return tp, err
  44. }
  45. return p.PluginObj, nil
  46. }
  47. // Pull pulls a plugin and computes the privileges required to install it.
  48. func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
  49. ref, err := reference.ParseNamed(name)
  50. if err != nil {
  51. logrus.Debugf("error in reference.ParseNamed: %v", err)
  52. return nil, err
  53. }
  54. name = ref.String()
  55. if p, _ := pm.get(name); p != nil {
  56. logrus.Debugf("plugin already exists")
  57. return nil, fmt.Errorf("%s exists", name)
  58. }
  59. pluginID := stringid.GenerateNonCryptoID()
  60. if err := os.MkdirAll(filepath.Join(pm.libRoot, pluginID), 0755); err != nil {
  61. logrus.Debugf("error in MkdirAll: %v", err)
  62. return nil, err
  63. }
  64. pd, err := distribution.Pull(name, pm.registryService, metaHeader, authConfig)
  65. if err != nil {
  66. logrus.Debugf("error in distribution.Pull(): %v", err)
  67. return nil, err
  68. }
  69. if err := distribution.WritePullData(pd, filepath.Join(pm.libRoot, pluginID), true); err != nil {
  70. logrus.Debugf("error in distribution.WritePullData(): %v", err)
  71. return nil, err
  72. }
  73. p := pm.newPlugin(ref, pluginID)
  74. if err := pm.initPlugin(p); err != nil {
  75. return nil, err
  76. }
  77. pm.Lock()
  78. pm.plugins[pluginID] = p
  79. pm.nameToID[name] = pluginID
  80. pm.save()
  81. pm.Unlock()
  82. pm.pluginEventLogger(pluginID, name, "pull")
  83. return computePrivileges(&p.PluginObj.Manifest), nil
  84. }
  85. // List displays the list of plugins and associated metadata.
  86. func (pm *Manager) List() ([]types.Plugin, error) {
  87. out := make([]types.Plugin, 0, len(pm.plugins))
  88. for _, p := range pm.plugins {
  89. out = append(out, p.PluginObj)
  90. }
  91. return out, nil
  92. }
  93. // Push pushes a plugin to the store.
  94. func (pm *Manager) Push(name string, metaHeader http.Header, authConfig *types.AuthConfig) error {
  95. p, err := pm.get(name)
  96. if err != nil {
  97. return err
  98. }
  99. dest := filepath.Join(pm.libRoot, p.PluginObj.ID)
  100. config, err := os.Open(filepath.Join(dest, "manifest.json"))
  101. if err != nil {
  102. return err
  103. }
  104. defer config.Close()
  105. rootfs, err := archive.Tar(filepath.Join(dest, "rootfs"), archive.Gzip)
  106. if err != nil {
  107. return err
  108. }
  109. _, err = distribution.Push(name, pm.registryService, metaHeader, authConfig, config, rootfs)
  110. // XXX: Ignore returning digest for now.
  111. // Since digest needs to be written to the ProgressWriter.
  112. return err
  113. }
  114. // Remove deletes plugin's root directory.
  115. func (pm *Manager) Remove(name string) error {
  116. p, err := pm.get(name)
  117. if err != nil {
  118. return err
  119. }
  120. if err := pm.remove(p); err != nil {
  121. return err
  122. }
  123. pm.pluginEventLogger(p.PluginObj.ID, name, "remove")
  124. return nil
  125. }
  126. // Set sets plugin args
  127. func (pm *Manager) Set(name string, args []string) error {
  128. p, err := pm.get(name)
  129. if err != nil {
  130. return err
  131. }
  132. return pm.set(p, args)
  133. }