Signed-off-by: Victor Vieux <victorvieux@gmail.com>
| ... | ... |
@@ -16,7 +16,8 @@ type Backend interface {
|
| 16 | 16 |
Inspect(name string) (enginetypes.Plugin, error) |
| 17 | 17 |
Remove(name string, config *enginetypes.PluginRmConfig) error |
| 18 | 18 |
Set(name string, args []string) error |
| 19 |
- Pull(name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig) (enginetypes.PluginPrivileges, error) |
|
| 19 |
+ Privileges(name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig) (enginetypes.PluginPrivileges, error) |
|
| 20 |
+ Pull(name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig, privileges enginetypes.PluginPrivileges) error |
|
| 20 | 21 |
Push(name string, metaHeaders http.Header, authConfig *enginetypes.AuthConfig) error |
| 21 | 22 |
CreateFromContext(ctx context.Context, tarCtx io.Reader, options *enginetypes.PluginCreateOptions) error |
| 22 | 23 |
} |
| ... | ... |
@@ -25,7 +25,8 @@ func (r *pluginRouter) Routes() []router.Route {
|
| 25 | 25 |
func (r *pluginRouter) initRoutes() {
|
| 26 | 26 |
r.routes = []router.Route{
|
| 27 | 27 |
router.NewGetRoute("/plugins", r.listPlugins),
|
| 28 |
- router.NewGetRoute("/plugins/{name:.*}", r.inspectPlugin),
|
|
| 28 |
+ router.NewGetRoute("/plugins/{name:.*}/json", r.inspectPlugin),
|
|
| 29 |
+ router.NewGetRoute("/plugins/privileges", r.getPrivileges),
|
|
| 29 | 30 |
router.NewDeleteRoute("/plugins/{name:.*}", r.removePlugin),
|
| 30 | 31 |
router.NewPostRoute("/plugins/{name:.*}/enable", r.enablePlugin), // PATCH?
|
| 31 | 32 |
router.NewPostRoute("/plugins/{name:.*}/disable", r.disablePlugin),
|
| ... | ... |
@@ -12,20 +12,17 @@ import ( |
| 12 | 12 |
"golang.org/x/net/context" |
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 |
-func (pr *pluginRouter) pullPlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
| 16 |
- if err := httputils.ParseForm(r); err != nil {
|
|
| 17 |
- return err |
|
| 18 |
- } |
|
| 15 |
+func parseHeaders(headers http.Header) (map[string][]string, *types.AuthConfig) {
|
|
| 19 | 16 |
|
| 20 | 17 |
metaHeaders := map[string][]string{}
|
| 21 |
- for k, v := range r.Header {
|
|
| 18 |
+ for k, v := range headers {
|
|
| 22 | 19 |
if strings.HasPrefix(k, "X-Meta-") {
|
| 23 | 20 |
metaHeaders[k] = v |
| 24 | 21 |
} |
| 25 | 22 |
} |
| 26 | 23 |
|
| 27 | 24 |
// Get X-Registry-Auth |
| 28 |
- authEncoded := r.Header.Get("X-Registry-Auth")
|
|
| 25 |
+ authEncoded := headers.Get("X-Registry-Auth")
|
|
| 29 | 26 |
authConfig := &types.AuthConfig{}
|
| 30 | 27 |
if authEncoded != "" {
|
| 31 | 28 |
authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) |
| ... | ... |
@@ -34,13 +31,42 @@ func (pr *pluginRouter) pullPlugin(ctx context.Context, w http.ResponseWriter, r |
| 34 | 34 |
} |
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 |
- privileges, err := pr.backend.Pull(r.FormValue("name"), metaHeaders, authConfig)
|
|
| 37 |
+ return metaHeaders, authConfig |
|
| 38 |
+} |
|
| 39 |
+ |
|
| 40 |
+func (pr *pluginRouter) getPrivileges(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
| 41 |
+ if err := httputils.ParseForm(r); err != nil {
|
|
| 42 |
+ return err |
|
| 43 |
+ } |
|
| 44 |
+ |
|
| 45 |
+ metaHeaders, authConfig := parseHeaders(r.Header) |
|
| 46 |
+ |
|
| 47 |
+ privileges, err := pr.backend.Privileges(r.FormValue("name"), metaHeaders, authConfig)
|
|
| 38 | 48 |
if err != nil {
|
| 39 | 49 |
return err |
| 40 | 50 |
} |
| 41 | 51 |
return httputils.WriteJSON(w, http.StatusOK, privileges) |
| 42 | 52 |
} |
| 43 | 53 |
|
| 54 |
+func (pr *pluginRouter) pullPlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
| 55 |
+ if err := httputils.ParseForm(r); err != nil {
|
|
| 56 |
+ return err |
|
| 57 |
+ } |
|
| 58 |
+ |
|
| 59 |
+ var privileges types.PluginPrivileges |
|
| 60 |
+ if err := json.NewDecoder(r.Body).Decode(&privileges); err != nil {
|
|
| 61 |
+ return err |
|
| 62 |
+ } |
|
| 63 |
+ |
|
| 64 |
+ metaHeaders, authConfig := parseHeaders(r.Header) |
|
| 65 |
+ |
|
| 66 |
+ if err := pr.backend.Pull(r.FormValue("name"), metaHeaders, authConfig, privileges); err != nil {
|
|
| 67 |
+ return err |
|
| 68 |
+ } |
|
| 69 |
+ w.WriteHeader(http.StatusCreated) |
|
| 70 |
+ return nil |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 44 | 73 |
func (pr *pluginRouter) createPlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 45 | 74 |
if err := httputils.ParseForm(r); err != nil {
|
| 46 | 75 |
return err |
| ... | ... |
@@ -52,6 +78,7 @@ func (pr *pluginRouter) createPlugin(ctx context.Context, w http.ResponseWriter, |
| 52 | 52 |
if err := pr.backend.CreateFromContext(ctx, r.Body, options); err != nil {
|
| 53 | 53 |
return err |
| 54 | 54 |
} |
| 55 |
+ //TODO: send progress bar |
|
| 55 | 56 |
w.WriteHeader(http.StatusNoContent) |
| 56 | 57 |
return nil |
| 57 | 58 |
} |
| ... | ... |
@@ -92,22 +119,8 @@ func (pr *pluginRouter) pushPlugin(ctx context.Context, w http.ResponseWriter, r |
| 92 | 92 |
return err |
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 |
- metaHeaders := map[string][]string{}
|
|
| 96 |
- for k, v := range r.Header {
|
|
| 97 |
- if strings.HasPrefix(k, "X-Meta-") {
|
|
| 98 |
- metaHeaders[k] = v |
|
| 99 |
- } |
|
| 100 |
- } |
|
| 95 |
+ metaHeaders, authConfig := parseHeaders(r.Header) |
|
| 101 | 96 |
|
| 102 |
- // Get X-Registry-Auth |
|
| 103 |
- authEncoded := r.Header.Get("X-Registry-Auth")
|
|
| 104 |
- authConfig := &types.AuthConfig{}
|
|
| 105 |
- if authEncoded != "" {
|
|
| 106 |
- authJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded)) |
|
| 107 |
- if err := json.NewDecoder(authJSON).Decode(authConfig); err != nil {
|
|
| 108 |
- authConfig = &types.AuthConfig{}
|
|
| 109 |
- } |
|
| 110 |
- } |
|
| 111 | 97 |
return pr.backend.Push(vars["name"], metaHeaders, authConfig) |
| 112 | 98 |
} |
| 113 | 99 |
|
| ... | ... |
@@ -11,7 +11,7 @@ import ( |
| 11 | 11 |
|
| 12 | 12 |
// PluginInspectWithRaw inspects an existing plugin |
| 13 | 13 |
func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
|
| 14 |
- resp, err := cli.get(ctx, "/plugins/"+name, nil, nil) |
|
| 14 |
+ resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil) |
|
| 15 | 15 |
if err != nil {
|
| 16 | 16 |
return nil, nil, err |
| 17 | 17 |
} |
| ... | ... |
@@ -14,27 +14,21 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types |
| 14 | 14 |
// FIXME(vdemeester) name is a ref, we might want to parse/validate it here. |
| 15 | 15 |
query := url.Values{}
|
| 16 | 16 |
query.Set("name", name)
|
| 17 |
- resp, err := cli.tryPluginPull(ctx, query, options.RegistryAuth) |
|
| 17 |
+ resp, err := cli.tryPluginPrivileges(ctx, query, options.RegistryAuth) |
|
| 18 | 18 |
if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil {
|
| 19 | 19 |
newAuthHeader, privilegeErr := options.PrivilegeFunc() |
| 20 | 20 |
if privilegeErr != nil {
|
| 21 | 21 |
ensureReaderClosed(resp) |
| 22 | 22 |
return privilegeErr |
| 23 | 23 |
} |
| 24 |
- resp, err = cli.tryPluginPull(ctx, query, newAuthHeader) |
|
| 24 |
+ options.RegistryAuth = newAuthHeader |
|
| 25 |
+ resp, err = cli.tryPluginPrivileges(ctx, query, options.RegistryAuth) |
|
| 25 | 26 |
} |
| 26 | 27 |
if err != nil {
|
| 27 | 28 |
ensureReaderClosed(resp) |
| 28 | 29 |
return err |
| 29 | 30 |
} |
| 30 | 31 |
|
| 31 |
- defer func() {
|
|
| 32 |
- if err != nil {
|
|
| 33 |
- delResp, _ := cli.delete(ctx, "/plugins/"+name, nil, nil) |
|
| 34 |
- ensureReaderClosed(delResp) |
|
| 35 |
- } |
|
| 36 |
- }() |
|
| 37 |
- |
|
| 38 | 32 |
var privileges types.PluginPrivileges |
| 39 | 33 |
if err := json.NewDecoder(resp.body).Decode(&privileges); err != nil {
|
| 40 | 34 |
ensureReaderClosed(resp) |
| ... | ... |
@@ -52,6 +46,18 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types |
| 52 | 52 |
} |
| 53 | 53 |
} |
| 54 | 54 |
|
| 55 |
+ _, err = cli.tryPluginPull(ctx, query, privileges, options.RegistryAuth) |
|
| 56 |
+ if err != nil {
|
|
| 57 |
+ return err |
|
| 58 |
+ } |
|
| 59 |
+ |
|
| 60 |
+ defer func() {
|
|
| 61 |
+ if err != nil {
|
|
| 62 |
+ delResp, _ := cli.delete(ctx, "/plugins/"+name, nil, nil) |
|
| 63 |
+ ensureReaderClosed(delResp) |
|
| 64 |
+ } |
|
| 65 |
+ }() |
|
| 66 |
+ |
|
| 55 | 67 |
if len(options.Args) > 0 {
|
| 56 | 68 |
if err := cli.PluginSet(ctx, name, options.Args); err != nil {
|
| 57 | 69 |
return err |
| ... | ... |
@@ -65,7 +71,12 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types |
| 65 | 65 |
return cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})
|
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 |
-func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
|
| 68 |
+func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {
|
|
| 69 |
+ headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
|
| 70 |
+ return cli.get(ctx, "/plugins/privileges", query, headers) |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) {
|
|
| 69 | 74 |
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
|
| 70 |
- return cli.post(ctx, "/plugins/pull", query, nil, headers) |
|
| 75 |
+ return cli.post(ctx, "/plugins/pull", query, privileges, headers) |
|
| 71 | 76 |
} |
| ... | ... |
@@ -5,12 +5,14 @@ package plugin |
| 5 | 5 |
import ( |
| 6 | 6 |
"bytes" |
| 7 | 7 |
"encoding/json" |
| 8 |
+ "errors" |
|
| 8 | 9 |
"fmt" |
| 9 | 10 |
"io" |
| 10 | 11 |
"io/ioutil" |
| 11 | 12 |
"net/http" |
| 12 | 13 |
"os" |
| 13 | 14 |
"path/filepath" |
| 15 |
+ "reflect" |
|
| 14 | 16 |
"regexp" |
| 15 | 17 |
|
| 16 | 18 |
"github.com/Sirupsen/logrus" |
| ... | ... |
@@ -87,59 +89,139 @@ func (pm *Manager) Inspect(refOrID string) (tp types.Plugin, err error) {
|
| 87 | 87 |
return tp, fmt.Errorf("no plugin name or ID associated with %q", refOrID)
|
| 88 | 88 |
} |
| 89 | 89 |
|
| 90 |
-func (pm *Manager) pull(ref reference.Named, metaHeader http.Header, authConfig *types.AuthConfig, pluginID string) (types.PluginPrivileges, error) {
|
|
| 90 |
+func (pm *Manager) pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (reference.Named, distribution.PullData, error) {
|
|
| 91 |
+ ref, err := distribution.GetRef(name) |
|
| 92 |
+ if err != nil {
|
|
| 93 |
+ logrus.Debugf("error in distribution.GetRef: %v", err)
|
|
| 94 |
+ return nil, nil, err |
|
| 95 |
+ } |
|
| 96 |
+ name = ref.String() |
|
| 97 |
+ |
|
| 98 |
+ if p, _ := pm.pluginStore.GetByName(name); p != nil {
|
|
| 99 |
+ logrus.Debug("plugin already exists")
|
|
| 100 |
+ return nil, nil, fmt.Errorf("%s exists", name)
|
|
| 101 |
+ } |
|
| 102 |
+ |
|
| 91 | 103 |
pd, err := distribution.Pull(ref, pm.registryService, metaHeader, authConfig) |
| 92 | 104 |
if err != nil {
|
| 93 | 105 |
logrus.Debugf("error in distribution.Pull(): %v", err)
|
| 94 |
- return nil, err |
|
| 106 |
+ return nil, nil, err |
|
| 95 | 107 |
} |
| 108 |
+ return ref, pd, nil |
|
| 109 |
+} |
|
| 96 | 110 |
|
| 97 |
- if err := distribution.WritePullData(pd, filepath.Join(pm.libRoot, pluginID), true); err != nil {
|
|
| 98 |
- logrus.Debugf("error in distribution.WritePullData(): %v", err)
|
|
| 111 |
+func computePrivileges(pd distribution.PullData) (types.PluginPrivileges, error) {
|
|
| 112 |
+ config, err := pd.Config() |
|
| 113 |
+ if err != nil {
|
|
| 99 | 114 |
return nil, err |
| 100 | 115 |
} |
| 101 | 116 |
|
| 102 |
- tag := distribution.GetTag(ref) |
|
| 103 |
- p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, pm.libRoot, tag) |
|
| 104 |
- if err := p.InitPlugin(); err != nil {
|
|
| 117 |
+ var c types.PluginConfig |
|
| 118 |
+ if err := json.Unmarshal(config, &c); err != nil {
|
|
| 105 | 119 |
return nil, err |
| 106 | 120 |
} |
| 107 |
- pm.pluginStore.Add(p) |
|
| 108 | 121 |
|
| 109 |
- pm.pluginEventLogger(pluginID, ref.String(), "pull") |
|
| 110 |
- return p.ComputePrivileges(), nil |
|
| 122 |
+ var privileges types.PluginPrivileges |
|
| 123 |
+ if c.Network.Type != "null" && c.Network.Type != "bridge" {
|
|
| 124 |
+ privileges = append(privileges, types.PluginPrivilege{
|
|
| 125 |
+ Name: "network", |
|
| 126 |
+ Description: "permissions to access a network", |
|
| 127 |
+ Value: []string{c.Network.Type},
|
|
| 128 |
+ }) |
|
| 129 |
+ } |
|
| 130 |
+ for _, mount := range c.Mounts {
|
|
| 131 |
+ if mount.Source != nil {
|
|
| 132 |
+ privileges = append(privileges, types.PluginPrivilege{
|
|
| 133 |
+ Name: "mount", |
|
| 134 |
+ Description: "host path to mount", |
|
| 135 |
+ Value: []string{*mount.Source},
|
|
| 136 |
+ }) |
|
| 137 |
+ } |
|
| 138 |
+ } |
|
| 139 |
+ for _, device := range c.Linux.Devices {
|
|
| 140 |
+ if device.Path != nil {
|
|
| 141 |
+ privileges = append(privileges, types.PluginPrivilege{
|
|
| 142 |
+ Name: "device", |
|
| 143 |
+ Description: "host device to access", |
|
| 144 |
+ Value: []string{*device.Path},
|
|
| 145 |
+ }) |
|
| 146 |
+ } |
|
| 147 |
+ } |
|
| 148 |
+ if c.Linux.DeviceCreation {
|
|
| 149 |
+ privileges = append(privileges, types.PluginPrivilege{
|
|
| 150 |
+ Name: "device-creation", |
|
| 151 |
+ Description: "allow creating devices inside plugin", |
|
| 152 |
+ Value: []string{"true"},
|
|
| 153 |
+ }) |
|
| 154 |
+ } |
|
| 155 |
+ if len(c.Linux.Capabilities) > 0 {
|
|
| 156 |
+ privileges = append(privileges, types.PluginPrivilege{
|
|
| 157 |
+ Name: "capabilities", |
|
| 158 |
+ Description: "list of additional capabilities required", |
|
| 159 |
+ Value: c.Linux.Capabilities, |
|
| 160 |
+ }) |
|
| 161 |
+ } |
|
| 162 |
+ |
|
| 163 |
+ return privileges, nil |
|
| 111 | 164 |
} |
| 112 | 165 |
|
| 113 |
-// Pull pulls a plugin and computes the privileges required to install it. |
|
| 114 |
-func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
|
|
| 115 |
- ref, err := distribution.GetRef(name) |
|
| 166 |
+// Privileges pulls a plugin config and computes the privileges required to install it. |
|
| 167 |
+func (pm *Manager) Privileges(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
|
|
| 168 |
+ _, pd, err := pm.pull(name, metaHeader, authConfig) |
|
| 116 | 169 |
if err != nil {
|
| 117 |
- logrus.Debugf("error in distribution.GetRef: %v", err)
|
|
| 118 | 170 |
return nil, err |
| 119 | 171 |
} |
| 120 |
- name = ref.String() |
|
| 172 |
+ return computePrivileges(pd) |
|
| 173 |
+} |
|
| 121 | 174 |
|
| 122 |
- if p, _ := pm.pluginStore.GetByName(name); p != nil {
|
|
| 123 |
- logrus.Debug("plugin already exists")
|
|
| 124 |
- return nil, fmt.Errorf("%s exists", name)
|
|
| 175 |
+// Pull pulls a plugin, check if the correct privileges are provided and install the plugin. |
|
| 176 |
+func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges) (err error) {
|
|
| 177 |
+ ref, pd, err := pm.pull(name, metaHeader, authConfig) |
|
| 178 |
+ if err != nil {
|
|
| 179 |
+ return err |
|
| 180 |
+ } |
|
| 181 |
+ |
|
| 182 |
+ requiredPrivileges, err := computePrivileges(pd) |
|
| 183 |
+ if err != nil {
|
|
| 184 |
+ return err |
|
| 185 |
+ } |
|
| 186 |
+ |
|
| 187 |
+ if !reflect.DeepEqual(privileges, requiredPrivileges) {
|
|
| 188 |
+ return errors.New("incorrect privileges")
|
|
| 125 | 189 |
} |
| 126 | 190 |
|
| 127 | 191 |
pluginID := stringid.GenerateNonCryptoID() |
| 128 | 192 |
pluginDir := filepath.Join(pm.libRoot, pluginID) |
| 129 | 193 |
if err := os.MkdirAll(pluginDir, 0755); err != nil {
|
| 130 | 194 |
logrus.Debugf("error in MkdirAll: %v", err)
|
| 131 |
- return nil, err |
|
| 195 |
+ return err |
|
| 132 | 196 |
} |
| 133 | 197 |
|
| 134 |
- priv, err := pm.pull(ref, metaHeader, authConfig, pluginID) |
|
| 135 |
- if err != nil {
|
|
| 136 |
- if err := os.RemoveAll(pluginDir); err != nil {
|
|
| 137 |
- logrus.Warnf("unable to remove %q from failed plugin pull: %v", pluginDir, err)
|
|
| 198 |
+ defer func() {
|
|
| 199 |
+ if err != nil {
|
|
| 200 |
+ if delErr := os.RemoveAll(pluginDir); delErr != nil {
|
|
| 201 |
+ logrus.Warnf("unable to remove %q from failed plugin pull: %v", pluginDir, delErr)
|
|
| 202 |
+ } |
|
| 138 | 203 |
} |
| 139 |
- return nil, err |
|
| 204 |
+ }() |
|
| 205 |
+ |
|
| 206 |
+ err = distribution.WritePullData(pd, filepath.Join(pm.libRoot, pluginID), true) |
|
| 207 |
+ if err != nil {
|
|
| 208 |
+ logrus.Debugf("error in distribution.WritePullData(): %v", err)
|
|
| 209 |
+ return err |
|
| 210 |
+ } |
|
| 211 |
+ |
|
| 212 |
+ tag := distribution.GetTag(ref) |
|
| 213 |
+ p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, pm.libRoot, tag) |
|
| 214 |
+ err = p.InitPlugin() |
|
| 215 |
+ if err != nil {
|
|
| 216 |
+ return err |
|
| 140 | 217 |
} |
| 218 |
+ pm.pluginStore.Add(p) |
|
| 141 | 219 |
|
| 142 |
- return priv, nil |
|
| 220 |
+ pm.pluginEventLogger(pluginID, ref.String(), "pull") |
|
| 221 |
+ |
|
| 222 |
+ return nil |
|
| 143 | 223 |
} |
| 144 | 224 |
|
| 145 | 225 |
// List displays the list of plugins and associated metadata. |
| ... | ... |
@@ -28,11 +28,16 @@ func (pm *Manager) Inspect(name string) (tp types.Plugin, err error) {
|
| 28 | 28 |
return tp, errNotSupported |
| 29 | 29 |
} |
| 30 | 30 |
|
| 31 |
-// Pull pulls a plugin and computes the privileges required to install it. |
|
| 32 |
-func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
|
|
| 31 |
+// Privileges pulls a plugin config and computes the privileges required to install it. |
|
| 32 |
+func (pm *Manager) Privileges(name string, metaHeaders http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
|
|
| 33 | 33 |
return nil, errNotSupported |
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 |
+// Pull pulls a plugin, check if the correct privileges are provided and install the plugin. |
|
| 37 |
+func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges) error {
|
|
| 38 |
+ return errNotSupported |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 36 | 41 |
// List displays the list of plugins and associated metadata. |
| 37 | 42 |
func (pm *Manager) List() ([]types.Plugin, error) {
|
| 38 | 43 |
return nil, errNotSupported |
| ... | ... |
@@ -216,53 +216,6 @@ next: |
| 216 | 216 |
return p.writeSettings() |
| 217 | 217 |
} |
| 218 | 218 |
|
| 219 |
-// ComputePrivileges takes the config file and computes the list of access necessary |
|
| 220 |
-// for the plugin on the host. |
|
| 221 |
-func (p *Plugin) ComputePrivileges() types.PluginPrivileges {
|
|
| 222 |
- c := p.PluginObj.Config |
|
| 223 |
- var privileges types.PluginPrivileges |
|
| 224 |
- if c.Network.Type != "null" && c.Network.Type != "bridge" {
|
|
| 225 |
- privileges = append(privileges, types.PluginPrivilege{
|
|
| 226 |
- Name: "network", |
|
| 227 |
- Description: "permissions to access a network", |
|
| 228 |
- Value: []string{c.Network.Type},
|
|
| 229 |
- }) |
|
| 230 |
- } |
|
| 231 |
- for _, mount := range c.Mounts {
|
|
| 232 |
- if mount.Source != nil {
|
|
| 233 |
- privileges = append(privileges, types.PluginPrivilege{
|
|
| 234 |
- Name: "mount", |
|
| 235 |
- Description: "host path to mount", |
|
| 236 |
- Value: []string{*mount.Source},
|
|
| 237 |
- }) |
|
| 238 |
- } |
|
| 239 |
- } |
|
| 240 |
- for _, device := range c.Linux.Devices {
|
|
| 241 |
- if device.Path != nil {
|
|
| 242 |
- privileges = append(privileges, types.PluginPrivilege{
|
|
| 243 |
- Name: "device", |
|
| 244 |
- Description: "host device to access", |
|
| 245 |
- Value: []string{*device.Path},
|
|
| 246 |
- }) |
|
| 247 |
- } |
|
| 248 |
- } |
|
| 249 |
- if c.Linux.DeviceCreation {
|
|
| 250 |
- privileges = append(privileges, types.PluginPrivilege{
|
|
| 251 |
- Name: "device-creation", |
|
| 252 |
- Description: "allow creating devices inside plugin", |
|
| 253 |
- Value: []string{"true"},
|
|
| 254 |
- }) |
|
| 255 |
- } |
|
| 256 |
- if len(c.Linux.Capabilities) > 0 {
|
|
| 257 |
- privileges = append(privileges, types.PluginPrivilege{
|
|
| 258 |
- Name: "capabilities", |
|
| 259 |
- Description: "list of additional capabilities required", |
|
| 260 |
- Value: c.Linux.Capabilities, |
|
| 261 |
- }) |
|
| 262 |
- } |
|
| 263 |
- return privileges |
|
| 264 |
-} |
|
| 265 |
- |
|
| 266 | 219 |
// IsEnabled returns the active state of the plugin. |
| 267 | 220 |
func (p *Plugin) IsEnabled() bool {
|
| 268 | 221 |
p.RLock() |