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