mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Merge pull request #28148 from vieux/rename_plugin_manifest
rename plugin manifest
This commit is contained in:
		
						commit
						89cc35447d
					
				
					 12 changed files with 126 additions and 140 deletions
				
			
		| 
						 | 
				
			
			@ -1213,7 +1213,7 @@ definitions:
 | 
			
		|||
  Plugin:
 | 
			
		||||
    description: "A plugin for the Remote API"
 | 
			
		||||
    type: "object"
 | 
			
		||||
    required: [Config, Enabled, Manifest, Name, Tag]
 | 
			
		||||
    required: [Settings, Enabled, Config, Name, Tag]
 | 
			
		||||
    properties:
 | 
			
		||||
      Id:
 | 
			
		||||
        type: "string"
 | 
			
		||||
| 
						 | 
				
			
			@ -1227,7 +1227,7 @@ definitions:
 | 
			
		|||
        description: "True when the plugin is running. False when the plugin is not running, only installed."
 | 
			
		||||
        type: "boolean"
 | 
			
		||||
        x-nullable: false
 | 
			
		||||
      Config:
 | 
			
		||||
      Settings:
 | 
			
		||||
        description: "Settings that can be modified by users."
 | 
			
		||||
        type: "object"
 | 
			
		||||
        x-nullable: false
 | 
			
		||||
| 
						 | 
				
			
			@ -1249,12 +1249,11 @@ definitions:
 | 
			
		|||
            type: "array"
 | 
			
		||||
            items:
 | 
			
		||||
              $ref: "#/definitions/PluginDevice"
 | 
			
		||||
      Manifest:
 | 
			
		||||
        description: "The manifest of a plugin."
 | 
			
		||||
      Config:
 | 
			
		||||
        description: "The config of a plugin."
 | 
			
		||||
        type: "object"
 | 
			
		||||
        x-nullable: false
 | 
			
		||||
        required:
 | 
			
		||||
          - ManifestVersion
 | 
			
		||||
          - Description
 | 
			
		||||
          - Documentation
 | 
			
		||||
          - Interface
 | 
			
		||||
| 
						 | 
				
			
			@ -1267,9 +1266,6 @@ definitions:
 | 
			
		|||
          - Env
 | 
			
		||||
          - Args
 | 
			
		||||
        properties:
 | 
			
		||||
          ManifestVersion:
 | 
			
		||||
            type: "string"
 | 
			
		||||
            x-nullable: false
 | 
			
		||||
          Description:
 | 
			
		||||
            type: "string"
 | 
			
		||||
            x-nullable: false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,47 +18,26 @@ type Plugin struct {
 | 
			
		|||
	// Id
 | 
			
		||||
	ID string `json:"Id,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// manifest
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Manifest PluginManifest `json:"Manifest"`
 | 
			
		||||
 | 
			
		||||
	// name
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Name string `json:"Name"`
 | 
			
		||||
 | 
			
		||||
	// settings
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Settings PluginSettings `json:"Settings"`
 | 
			
		||||
 | 
			
		||||
	// tag
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Tag string `json:"Tag"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginConfig Settings that can be modified by users.
 | 
			
		||||
// PluginConfig The config of a plugin.
 | 
			
		||||
// swagger:model PluginConfig
 | 
			
		||||
type PluginConfig struct {
 | 
			
		||||
 | 
			
		||||
	// args
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Args []string `json:"Args"`
 | 
			
		||||
 | 
			
		||||
	// devices
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Devices []PluginDevice `json:"Devices"`
 | 
			
		||||
 | 
			
		||||
	// env
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Env []string `json:"Env"`
 | 
			
		||||
 | 
			
		||||
	// mounts
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Mounts []PluginMount `json:"Mounts"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginManifest The manifest of a plugin.
 | 
			
		||||
// swagger:model PluginManifest
 | 
			
		||||
type PluginManifest struct {
 | 
			
		||||
 | 
			
		||||
	// args
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Args PluginManifestArgs `json:"Args"`
 | 
			
		||||
	Args PluginConfigArgs `json:"Args"`
 | 
			
		||||
 | 
			
		||||
	// capabilities
 | 
			
		||||
	// Required: true
 | 
			
		||||
| 
						 | 
				
			
			@ -86,11 +65,7 @@ type PluginManifest struct {
 | 
			
		|||
 | 
			
		||||
	// interface
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Interface PluginManifestInterface `json:"Interface"`
 | 
			
		||||
 | 
			
		||||
	// manifest version
 | 
			
		||||
	// Required: true
 | 
			
		||||
	ManifestVersion string `json:"ManifestVersion"`
 | 
			
		||||
	Interface PluginConfigInterface `json:"Interface"`
 | 
			
		||||
 | 
			
		||||
	// mounts
 | 
			
		||||
	// Required: true
 | 
			
		||||
| 
						 | 
				
			
			@ -98,19 +73,19 @@ type PluginManifest struct {
 | 
			
		|||
 | 
			
		||||
	// network
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Network PluginManifestNetwork `json:"Network"`
 | 
			
		||||
	Network PluginConfigNetwork `json:"Network"`
 | 
			
		||||
 | 
			
		||||
	// user
 | 
			
		||||
	User PluginManifestUser `json:"User,omitempty"`
 | 
			
		||||
	User PluginConfigUser `json:"User,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// workdir
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Workdir string `json:"Workdir"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginManifestArgs plugin manifest args
 | 
			
		||||
// swagger:model PluginManifestArgs
 | 
			
		||||
type PluginManifestArgs struct {
 | 
			
		||||
// PluginConfigArgs plugin config args
 | 
			
		||||
// swagger:model PluginConfigArgs
 | 
			
		||||
type PluginConfigArgs struct {
 | 
			
		||||
 | 
			
		||||
	// description
 | 
			
		||||
	// Required: true
 | 
			
		||||
| 
						 | 
				
			
			@ -129,9 +104,9 @@ type PluginManifestArgs struct {
 | 
			
		|||
	Value []string `json:"Value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginManifestInterface The interface between Docker and the plugin
 | 
			
		||||
// swagger:model PluginManifestInterface
 | 
			
		||||
type PluginManifestInterface struct {
 | 
			
		||||
// PluginConfigInterface The interface between Docker and the plugin
 | 
			
		||||
// swagger:model PluginConfigInterface
 | 
			
		||||
type PluginConfigInterface struct {
 | 
			
		||||
 | 
			
		||||
	// socket
 | 
			
		||||
	// Required: true
 | 
			
		||||
| 
						 | 
				
			
			@ -142,18 +117,18 @@ type PluginManifestInterface struct {
 | 
			
		|||
	Types []PluginInterfaceType `json:"Types"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginManifestNetwork plugin manifest network
 | 
			
		||||
// swagger:model PluginManifestNetwork
 | 
			
		||||
type PluginManifestNetwork struct {
 | 
			
		||||
// PluginConfigNetwork plugin config network
 | 
			
		||||
// swagger:model PluginConfigNetwork
 | 
			
		||||
type PluginConfigNetwork struct {
 | 
			
		||||
 | 
			
		||||
	// type
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Type string `json:"Type"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginManifestUser plugin manifest user
 | 
			
		||||
// swagger:model PluginManifestUser
 | 
			
		||||
type PluginManifestUser struct {
 | 
			
		||||
// PluginConfigUser plugin config user
 | 
			
		||||
// swagger:model PluginConfigUser
 | 
			
		||||
type PluginConfigUser struct {
 | 
			
		||||
 | 
			
		||||
	// g ID
 | 
			
		||||
	GID uint32 `json:"GID,omitempty"`
 | 
			
		||||
| 
						 | 
				
			
			@ -161,3 +136,24 @@ type PluginManifestUser struct {
 | 
			
		|||
	// UID
 | 
			
		||||
	UID uint32 `json:"UID,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginSettings Settings that can be modified by users.
 | 
			
		||||
// swagger:model PluginSettings
 | 
			
		||||
type PluginSettings struct {
 | 
			
		||||
 | 
			
		||||
	// args
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Args []string `json:"Args"`
 | 
			
		||||
 | 
			
		||||
	// devices
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Devices []PluginDevice `json:"Devices"`
 | 
			
		||||
 | 
			
		||||
	// env
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Env []string `json:"Env"`
 | 
			
		||||
 | 
			
		||||
	// mounts
 | 
			
		||||
	// Required: true
 | 
			
		||||
	Mounts []PluginMount `json:"Mounts"`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,14 +24,14 @@ func validateTag(rawRepo string) error {
 | 
			
		|||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// validateManifest ensures that a valid manifest.json is available in the given path
 | 
			
		||||
func validateManifest(path string) error {
 | 
			
		||||
	dt, err := os.Open(filepath.Join(path, "manifest.json"))
 | 
			
		||||
// validateConfig ensures that a valid config.json is available in the given path
 | 
			
		||||
func validateConfig(path string) error {
 | 
			
		||||
	dt, err := os.Open(filepath.Join(path, "config.json"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m := types.PluginManifest{}
 | 
			
		||||
	m := types.PluginConfig{}
 | 
			
		||||
	err = json.NewDecoder(dt).Decode(&m)
 | 
			
		||||
	dt.Close()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,8 +64,8 @@ func newCreateCommand(dockerCli *command.DockerCli) *cobra.Command {
 | 
			
		|||
	options := pluginCreateOptions{}
 | 
			
		||||
 | 
			
		||||
	cmd := &cobra.Command{
 | 
			
		||||
		Use:   "create [OPTIONS] reponame[:tag] PATH-TO-ROOTFS (rootfs + manifest.json)",
 | 
			
		||||
		Short: "Create a plugin from a rootfs and manifest",
 | 
			
		||||
		Use:   "create [OPTIONS] reponame[:tag] PATH-TO-ROOTFS (rootfs + config.json)",
 | 
			
		||||
		Short: "Create a plugin from a rootfs and config",
 | 
			
		||||
		Args:  cli.RequiresMinArgs(2),
 | 
			
		||||
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
			
		||||
			options.repoName = args[0]
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ func runCreate(dockerCli *command.DockerCli, options pluginCreateOptions) error
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := validateManifest(options.context); err != nil {
 | 
			
		||||
	if err := validateConfig(options.context); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ func runList(dockerCli *command.DockerCli, opts listOptions) error {
 | 
			
		|||
	fmt.Fprintf(w, "\n")
 | 
			
		||||
 | 
			
		||||
	for _, p := range plugins {
 | 
			
		||||
		desc := strings.Replace(p.Manifest.Description, "\n", " ", -1)
 | 
			
		||||
		desc := strings.Replace(p.Config.Description, "\n", " ", -1)
 | 
			
		||||
		desc = strings.Replace(desc, "\r", " ", -1)
 | 
			
		||||
		if !opts.noTrunc {
 | 
			
		||||
			desc = stringutils.Ellipsis(desc, 45)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
aliases: [
 | 
			
		||||
"/engine/extend/"
 | 
			
		||||
]
 | 
			
		||||
title: "Plugin manifest"
 | 
			
		||||
title: "Plugin config"
 | 
			
		||||
description: "How develop and use a plugin with the managed plugin system"
 | 
			
		||||
keywords: "API, Usage, plugins, documentation, developer"
 | 
			
		||||
advisory: "experimental"
 | 
			
		||||
| 
						 | 
				
			
			@ -17,29 +17,25 @@ advisory: "experimental"
 | 
			
		|||
     will be rejected.
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
# Plugin Manifest Version 0 of Plugin V2
 | 
			
		||||
# Plugin Config Version 0 of Plugin V2
 | 
			
		||||
 | 
			
		||||
This document outlines the format of the V0 plugin manifest. The plugin
 | 
			
		||||
manifest described herein was introduced in the Docker daemon (experimental version) in the [v1.12.0
 | 
			
		||||
This document outlines the format of the V0 plugin config. The plugin
 | 
			
		||||
config described herein was introduced in the Docker daemon (experimental version) in the [v1.12.0
 | 
			
		||||
release](https://github.com/docker/docker/commit/f37117045c5398fd3dca8016ea8ca0cb47e7312b).
 | 
			
		||||
 | 
			
		||||
Plugin manifests describe the various constituents of a docker plugin. Plugin
 | 
			
		||||
manifests can be serialized to JSON format with the following media types:
 | 
			
		||||
Plugin configs describe the various constituents of a docker plugin. Plugin
 | 
			
		||||
configs can be serialized to JSON format with the following media types:
 | 
			
		||||
 | 
			
		||||
Manifest Type  | Media Type
 | 
			
		||||
Config Type  | Media Type
 | 
			
		||||
------------- | -------------
 | 
			
		||||
manifest  | "application/vnd.docker.plugin.v0+json"
 | 
			
		||||
config  | "application/vnd.docker.plugin.v0+json"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## *Manifest* Field Descriptions
 | 
			
		||||
## *Config* Field Descriptions
 | 
			
		||||
 | 
			
		||||
Manifest provides the base accessible fields for working with V0 plugin format
 | 
			
		||||
Config provides the base accessible fields for working with V0 plugin format
 | 
			
		||||
 in the registry.
 | 
			
		||||
 | 
			
		||||
- **`manifestVersion`** *string*
 | 
			
		||||
 | 
			
		||||
	version of the plugin manifest (This version uses V0)
 | 
			
		||||
 | 
			
		||||
- **`description`** *string*
 | 
			
		||||
 | 
			
		||||
	description of the plugin
 | 
			
		||||
| 
						 | 
				
			
			@ -169,13 +165,13 @@ Manifest provides the base accessible fields for working with V0 plugin format
 | 
			
		|||
	  values of the args.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Example Manifest
 | 
			
		||||
## Example Config
 | 
			
		||||
 | 
			
		||||
*Example showing the 'tiborvass/no-remove' plugin manifest.*
 | 
			
		||||
*Example showing the 'tiborvass/no-remove' plugin config.*
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
{
 | 
			
		||||
       	"manifestVersion": "v0",
 | 
			
		||||
       	"configVersion": "v0",
 | 
			
		||||
       	"description": "A test plugin for Docker",
 | 
			
		||||
       	"documentation": "https://docs.docker.com/engine/extend/plugins/",
 | 
			
		||||
       	"entrypoint": ["plugin-no-remove", "/data"],
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ a `plugins.json` with a single plugin installed.
 | 
			
		|||
{
 | 
			
		||||
  "cd851ce43a403": {
 | 
			
		||||
    "plugin": {
 | 
			
		||||
      "Manifest": {
 | 
			
		||||
      "Config": {
 | 
			
		||||
        "Args": {
 | 
			
		||||
          "Value": null,
 | 
			
		||||
          "Settable": null,
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +154,6 @@ a `plugins.json` with a single plugin installed.
 | 
			
		|||
        "Capabilities": [
 | 
			
		||||
          "CAP_SYS_ADMIN"
 | 
			
		||||
        ],
 | 
			
		||||
        "ManifestVersion": "v0",
 | 
			
		||||
        "Description": "sshFS plugin for Docker",
 | 
			
		||||
        "Documentation": "https://docs.docker.com/engine/extend/plugins/",
 | 
			
		||||
        "Interface": {
 | 
			
		||||
| 
						 | 
				
			
			@ -196,8 +195,8 @@ and two JSON files.
 | 
			
		|||
# ls -la /var/lib/docker/plugins/cd851ce43a403
 | 
			
		||||
total 12
 | 
			
		||||
drwx------ 19 root root 4096 Aug  8 17:56 rootfs
 | 
			
		||||
-rw-r--r--  1 root root   50 Aug  8 17:56 plugin-config.json
 | 
			
		||||
-rw-------  1 root root  347 Aug  8 17:56 manifest.json
 | 
			
		||||
-rw-r--r--  1 root root   50 Aug  8 17:56 plugin-settings.json
 | 
			
		||||
-rw-------  1 root root  347 Aug  8 17:56 config.json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### The rootfs directory
 | 
			
		||||
| 
						 | 
				
			
			@ -219,17 +218,16 @@ $ docker rm -vf "$id"
 | 
			
		|||
$ docker rmi rootfs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### The manifest.json and plugin-config.json files
 | 
			
		||||
#### The config.json and plugin-settings.json files
 | 
			
		||||
 | 
			
		||||
The `manifest.json` file describes the plugin. The `plugin-config.json` file
 | 
			
		||||
The `config.json` file describes the plugin. The `plugin-settings.json` file
 | 
			
		||||
contains runtime parameters and is only required if your plugin has runtime
 | 
			
		||||
parameters. [See the Plugins Manifest reference](manifest.md).
 | 
			
		||||
parameters. [See the Plugins Config reference](config.md).
 | 
			
		||||
 | 
			
		||||
Consider the following `manifest.json` file.
 | 
			
		||||
Consider the following `config.json` file.
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
	"manifestVersion": "v0",
 | 
			
		||||
	"description": "sshFS plugin for Docker",
 | 
			
		||||
	"documentation": "https://docs.docker.com/engine/extend/plugins/",
 | 
			
		||||
	"entrypoint": ["/go/bin/docker-volume-sshfs"],
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +248,7 @@ entrypoint and uses the `/run/docker/plugins/sshfs.sock` socket to communicate
 | 
			
		|||
with Docker Engine.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Consider the following `plugin-config.json` file.
 | 
			
		||||
Consider the following `plugin-settings.json` file.
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -264,8 +262,8 @@ Consider the following `plugin-config.json` file.
 | 
			
		|||
This plugin has no runtime parameters.
 | 
			
		||||
 | 
			
		||||
Each of these JSON files is included as part of `plugins.json`, as you can see
 | 
			
		||||
by looking back at the example above. After a plugin is installed, `manifest.json`
 | 
			
		||||
is read-only, but `plugin-config.json` is read-write, and includes all runtime
 | 
			
		||||
by looking back at the example above. After a plugin is installed, `config.json`
 | 
			
		||||
is read-only, but `plugin-settings.json` is read-write, and includes all runtime
 | 
			
		||||
configuration options for the plugin.
 | 
			
		||||
 | 
			
		||||
### Creating the plugin
 | 
			
		||||
| 
						 | 
				
			
			@ -279,9 +277,9 @@ Follow these steps to create a plugin:
 | 
			
		|||
   using `docker export`. See [The rootfs directory](#the-rootfs-directory) for
 | 
			
		||||
   an example of creating a `rootfs`.
 | 
			
		||||
 | 
			
		||||
3. Create a `manifest.json` file in `/var/lib/docker/plugins/$id/`.
 | 
			
		||||
3. Create a `config.json` file in `/var/lib/docker/plugins/$id/`.
 | 
			
		||||
 | 
			
		||||
4. Create a `plugin-config.json` file if needed.
 | 
			
		||||
4. Create a `plugin-settings.json` file if needed.
 | 
			
		||||
 | 
			
		||||
5. Create or add a section to `/var/lib/docker/plugins/plugins.json`. Use
 | 
			
		||||
   `<user>/<name>` as “Name” and `$id` as “Id”.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ advisory: "experimental"
 | 
			
		|||
```markdown
 | 
			
		||||
Usage:  docker plugin create [OPTIONS] reponame[:tag] PATH-TO-ROOTFS
 | 
			
		||||
 | 
			
		||||
create a plugin from the given PATH-TO-ROOTFS, which contains the plugin's root filesystem and the manifest file, manifest.json
 | 
			
		||||
create a plugin from the given PATH-TO-ROOTFS, which contains the plugin's root filesystem and the config file, config.json
 | 
			
		||||
 | 
			
		||||
Options:
 | 
			
		||||
      --compress   Compress the context using gzip 
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ Options:
 | 
			
		|||
```
 | 
			
		||||
 | 
			
		||||
Creates a plugin. Before creating the plugin, prepare the plugin's root filesystem as well as
 | 
			
		||||
the manifest.json (https://github.com/docker/docker/blob/master/docs/extend/manifest.md)
 | 
			
		||||
the config.json (https://github.com/docker/docker/blob/master/docs/extend/config.md)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The following example shows how to create a sample `plugin`.
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ The following example shows how to create a sample `plugin`.
 | 
			
		|||
 | 
			
		||||
$ ls -ls /home/pluginDir
 | 
			
		||||
 | 
			
		||||
4 -rw-r--r--  1 root root 431 Nov  7 01:40 manifest.json
 | 
			
		||||
4 -rw-r--r--  1 root root 431 Nov  7 01:40 config.json
 | 
			
		||||
0 drwxr-xr-x 19 root root 420 Nov  7 01:40 rootfs
 | 
			
		||||
 | 
			
		||||
$ docker plugin create plugin /home/pluginDir
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,12 +123,12 @@ func (s *DockerSuite) TestPluginSet(c *check.C) {
 | 
			
		|||
	out, _ := dockerCmd(c, "plugin", "install", "--grant-all-permissions", "--disable", pName)
 | 
			
		||||
	c.Assert(strings.TrimSpace(out), checker.Contains, pName)
 | 
			
		||||
 | 
			
		||||
	env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Config.Env}}", pName)
 | 
			
		||||
	env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", pName)
 | 
			
		||||
	c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=0]")
 | 
			
		||||
 | 
			
		||||
	dockerCmd(c, "plugin", "set", pName, "DEBUG=1")
 | 
			
		||||
 | 
			
		||||
	env, _ = dockerCmd(c, "plugin", "inspect", "-f", "{{.Config.Env}}", pName)
 | 
			
		||||
	env, _ = dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", pName)
 | 
			
		||||
	c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=1]")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +137,7 @@ func (s *DockerSuite) TestPluginInstallArgs(c *check.C) {
 | 
			
		|||
	out, _ := dockerCmd(c, "plugin", "install", "--grant-all-permissions", "--disable", pName, "DEBUG=1")
 | 
			
		||||
	c.Assert(strings.TrimSpace(out), checker.Contains, pName)
 | 
			
		||||
 | 
			
		||||
	env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Config.Env}}", pName)
 | 
			
		||||
	env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", pName)
 | 
			
		||||
	c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=1]")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ func (pm *Manager) Enable(name string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inspect examines a plugin manifest
 | 
			
		||||
// Inspect examines a plugin config
 | 
			
		||||
func (pm *Manager) Inspect(name string) (tp types.Plugin, err error) {
 | 
			
		||||
	p, err := pm.pluginStore.GetByName(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ func (pm *Manager) Push(name string, metaHeader http.Header, authConfig *types.A
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	dest := filepath.Join(pm.libRoot, p.GetID())
 | 
			
		||||
	config, err := ioutil.ReadFile(filepath.Join(dest, "manifest.json"))
 | 
			
		||||
	config, err := ioutil.ReadFile(filepath.Join(dest, "config.json"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +180,7 @@ func (pm *Manager) Set(name string, args []string) error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// CreateFromContext creates a plugin from the given pluginDir which contains
 | 
			
		||||
// both the rootfs and the manifest.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 {
 | 
			
		||||
	pluginID := stringid.GenerateNonCryptoID()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ import (
 | 
			
		|||
	"golang.org/x/net/context"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// PullData is the plugin manifest and the rootfs
 | 
			
		||||
// PullData is the plugin config and the rootfs
 | 
			
		||||
type PullData interface {
 | 
			
		||||
	Config() ([]byte, error)
 | 
			
		||||
	Layer() (io.ReadCloser, error)
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +183,7 @@ func WritePullData(pd PullData, dest string, extract bool) error {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if extract {
 | 
			
		||||
		if err := ioutil.WriteFile(filepath.Join(dest, "manifest.json"), config, 0600); err != nil {
 | 
			
		||||
		if err := ioutil.WriteFile(filepath.Join(dest, "config.json"), config, 0600); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,8 @@ func TestFilterByCapNeg(t *testing.T) {
 | 
			
		|||
	p := v2.NewPlugin("test", "1234567890", "/run/docker", "/var/lib/docker/plugins", "latest")
 | 
			
		||||
 | 
			
		||||
	iType := types.PluginInterfaceType{"volumedriver", "docker", "1.0"}
 | 
			
		||||
	i := types.PluginManifestInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
 | 
			
		||||
	p.PluginObj.Manifest.Interface = i
 | 
			
		||||
	i := types.PluginConfigInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
 | 
			
		||||
	p.PluginObj.Config.Interface = i
 | 
			
		||||
 | 
			
		||||
	_, err := p.FilterByCap("foobar")
 | 
			
		||||
	if err == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -24,8 +24,8 @@ func TestFilterByCapPos(t *testing.T) {
 | 
			
		|||
	p := v2.NewPlugin("test", "1234567890", "/run/docker", "/var/lib/docker/plugins", "latest")
 | 
			
		||||
 | 
			
		||||
	iType := types.PluginInterfaceType{"volumedriver", "docker", "1.0"}
 | 
			
		||||
	i := types.PluginManifestInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
 | 
			
		||||
	p.PluginObj.Manifest.Interface = i
 | 
			
		||||
	i := types.PluginConfigInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
 | 
			
		||||
	p.PluginObj.Config.Interface = i
 | 
			
		||||
 | 
			
		||||
	_, err := p.FilterByCap("volumedriver")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ func (p *Plugin) Name() string {
 | 
			
		|||
// FilterByCap query the plugin for a given capability.
 | 
			
		||||
func (p *Plugin) FilterByCap(capability string) (*Plugin, error) {
 | 
			
		||||
	capability = strings.ToLower(capability)
 | 
			
		||||
	for _, typ := range p.PluginObj.Manifest.Interface.Types {
 | 
			
		||||
	for _, typ := range p.PluginObj.Config.Interface.Types {
 | 
			
		||||
		if typ.Capability == capability && typ.Prefix == "docker" {
 | 
			
		||||
			return p, nil
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -86,39 +86,39 @@ func (p *Plugin) RemoveFromDisk() error {
 | 
			
		|||
	return os.RemoveAll(p.RuntimeSourcePath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InitPlugin populates the plugin object from the plugin manifest file.
 | 
			
		||||
// InitPlugin populates the plugin object from the plugin config file.
 | 
			
		||||
func (p *Plugin) InitPlugin() error {
 | 
			
		||||
	dt, err := os.Open(filepath.Join(p.LibRoot, p.PluginObj.ID, "manifest.json"))
 | 
			
		||||
	dt, err := os.Open(filepath.Join(p.LibRoot, p.PluginObj.ID, "config.json"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	err = json.NewDecoder(dt).Decode(&p.PluginObj.Manifest)
 | 
			
		||||
	err = json.NewDecoder(dt).Decode(&p.PluginObj.Config)
 | 
			
		||||
	dt.Close()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.PluginObj.Config.Mounts = make([]types.PluginMount, len(p.PluginObj.Manifest.Mounts))
 | 
			
		||||
	for i, mount := range p.PluginObj.Manifest.Mounts {
 | 
			
		||||
		p.PluginObj.Config.Mounts[i] = mount
 | 
			
		||||
	p.PluginObj.Settings.Mounts = make([]types.PluginMount, len(p.PluginObj.Config.Mounts))
 | 
			
		||||
	for i, mount := range p.PluginObj.Config.Mounts {
 | 
			
		||||
		p.PluginObj.Settings.Mounts[i] = mount
 | 
			
		||||
	}
 | 
			
		||||
	p.PluginObj.Config.Env = make([]string, 0, len(p.PluginObj.Manifest.Env))
 | 
			
		||||
	for _, env := range p.PluginObj.Manifest.Env {
 | 
			
		||||
	p.PluginObj.Settings.Env = make([]string, 0, len(p.PluginObj.Config.Env))
 | 
			
		||||
	for _, env := range p.PluginObj.Config.Env {
 | 
			
		||||
		if env.Value != nil {
 | 
			
		||||
			p.PluginObj.Config.Env = append(p.PluginObj.Config.Env, fmt.Sprintf("%s=%s", env.Name, *env.Value))
 | 
			
		||||
			p.PluginObj.Settings.Env = append(p.PluginObj.Settings.Env, fmt.Sprintf("%s=%s", env.Name, *env.Value))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	copy(p.PluginObj.Config.Args, p.PluginObj.Manifest.Args.Value)
 | 
			
		||||
	copy(p.PluginObj.Settings.Args, p.PluginObj.Config.Args.Value)
 | 
			
		||||
 | 
			
		||||
	return p.writeConfig()
 | 
			
		||||
	return p.writeSettings()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Plugin) writeConfig() error {
 | 
			
		||||
	f, err := os.Create(filepath.Join(p.LibRoot, p.PluginObj.ID, "plugin-config.json"))
 | 
			
		||||
func (p *Plugin) writeSettings() error {
 | 
			
		||||
	f, err := os.Create(filepath.Join(p.LibRoot, p.PluginObj.ID, "plugin-settings.json"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	err = json.NewEncoder(f).Encode(&p.PluginObj.Config)
 | 
			
		||||
	err = json.NewEncoder(f).Encode(&p.PluginObj.Settings)
 | 
			
		||||
	f.Close()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -139,9 +139,9 @@ func (p *Plugin) Set(args []string) error {
 | 
			
		|||
 | 
			
		||||
next:
 | 
			
		||||
	for _, s := range sets {
 | 
			
		||||
		// range over all the envs in the manifest
 | 
			
		||||
		for _, env := range p.PluginObj.Manifest.Env {
 | 
			
		||||
			// found the env in the manifest
 | 
			
		||||
		// range over all the envs in the config
 | 
			
		||||
		for _, env := range p.PluginObj.Config.Env {
 | 
			
		||||
			// found the env in the config
 | 
			
		||||
			if env.Name == s.name {
 | 
			
		||||
				// is it settable ?
 | 
			
		||||
				if ok, err := s.isSettable(allowedSettableFieldsEnv, env.Settable); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -149,8 +149,8 @@ next:
 | 
			
		|||
				} else if !ok {
 | 
			
		||||
					return fmt.Errorf("%q is not settable", s.prettyName())
 | 
			
		||||
				}
 | 
			
		||||
				// is it, so lets update the config in memory
 | 
			
		||||
				updateConfigEnv(&p.PluginObj.Config.Env, &s)
 | 
			
		||||
				// is it, so lets update the settings in memory
 | 
			
		||||
				updateConfigEnv(&p.PluginObj.Settings.Env, &s)
 | 
			
		||||
				continue next
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -160,14 +160,14 @@ next:
 | 
			
		|||
		return fmt.Errorf("setting %q not found in the plugin configuration", s.name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// update the config on disk
 | 
			
		||||
	return p.writeConfig()
 | 
			
		||||
	// update the settings on disk
 | 
			
		||||
	return p.writeSettings()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ComputePrivileges takes the manifest file and computes the list of access necessary
 | 
			
		||||
// ComputePrivileges takes the config file and computes the list of access necessary
 | 
			
		||||
// for the plugin on the host.
 | 
			
		||||
func (p *Plugin) ComputePrivileges() types.PluginPrivileges {
 | 
			
		||||
	m := p.PluginObj.Manifest
 | 
			
		||||
	m := p.PluginObj.Config
 | 
			
		||||
	var privileges types.PluginPrivileges
 | 
			
		||||
	if m.Network.Type != "null" && m.Network.Type != "bridge" {
 | 
			
		||||
		privileges = append(privileges, types.PluginPrivilege{
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +225,7 @@ func (p *Plugin) GetSocket() string {
 | 
			
		|||
	p.RLock()
 | 
			
		||||
	defer p.RUnlock()
 | 
			
		||||
 | 
			
		||||
	return p.PluginObj.Manifest.Interface.Socket
 | 
			
		||||
	return p.PluginObj.Config.Interface.Socket
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetTypes returns the interface types of a plugin.
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +233,7 @@ func (p *Plugin) GetTypes() []types.PluginInterfaceType {
 | 
			
		|||
	p.RLock()
 | 
			
		||||
	defer p.RUnlock()
 | 
			
		||||
 | 
			
		||||
	return p.PluginObj.Manifest.Interface.Types
 | 
			
		||||
	return p.PluginObj.Config.Interface.Types
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InitSpec creates an OCI spec from the plugin's config.
 | 
			
		||||
| 
						 | 
				
			
			@ -241,10 +241,10 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
 | 
			
		|||
	rootfs := filepath.Join(libRoot, p.PluginObj.ID, "rootfs")
 | 
			
		||||
	s.Root = specs.Root{
 | 
			
		||||
		Path:     rootfs,
 | 
			
		||||
		Readonly: false, // TODO: all plugins should be readonly? settable in manifest?
 | 
			
		||||
		Readonly: false, // TODO: all plugins should be readonly? settable in config?
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mounts := append(p.PluginObj.Config.Mounts, types.PluginMount{
 | 
			
		||||
	mounts := append(p.PluginObj.Settings.Mounts, types.PluginMount{
 | 
			
		||||
		Source:      &p.RuntimeSourcePath,
 | 
			
		||||
		Destination: defaultPluginRuntimeDestination,
 | 
			
		||||
		Type:        "bind",
 | 
			
		||||
| 
						 | 
				
			
			@ -274,12 +274,12 @@ func (p *Plugin) InitSpec(s specs.Spec, libRoot string) (*specs.Spec, error) {
 | 
			
		|||
		s.Mounts = append(s.Mounts, m)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	envs := make([]string, 1, len(p.PluginObj.Config.Env)+1)
 | 
			
		||||
	envs := make([]string, 1, len(p.PluginObj.Settings.Env)+1)
 | 
			
		||||
	envs[0] = "PATH=" + system.DefaultPathEnv
 | 
			
		||||
	envs = append(envs, p.PluginObj.Config.Env...)
 | 
			
		||||
	envs = append(envs, p.PluginObj.Settings.Env...)
 | 
			
		||||
 | 
			
		||||
	args := append(p.PluginObj.Manifest.Entrypoint, p.PluginObj.Config.Args...)
 | 
			
		||||
	cwd := p.PluginObj.Manifest.Workdir
 | 
			
		||||
	args := append(p.PluginObj.Config.Entrypoint, p.PluginObj.Settings.Args...)
 | 
			
		||||
	cwd := p.PluginObj.Config.Workdir
 | 
			
		||||
	if len(cwd) == 0 {
 | 
			
		||||
		cwd = "/"
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue