This command will let Compose and external tooling know about which parameters should be passed to the Compose plugin Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
6.7 KiB
About
The Compose application model defines service
as an abstraction for a computing unit managing (a subset of)
application needs, which can interact with other service by relying on network(s). Docker Compose is designed
to use the Docker Engine ("Moby") API to manage services as containers, but the abstraction could also cover
many other runtimes, typically cloud services or services natively provided by host.
The Compose extensibility model has been designed to extend the service
support to runtimes accessible through
third-party tooling.
Architecture
Compose extensibility relies on the provider
attribute to select the actual binary responsible for managing
the resource(s) needed to run a service.
database:
provider:
type: awesomecloud
options:
type: mysql
size: 256
name: myAwesomeCloudDB
provider.type
tells Compose the binary to run, which can be either:
- Another Docker CLI plugin (typically,
model
to rundocker-model
) - An executable in user's
PATH
If provider.type
doesn't resolve into any of those, Compose will report an error and interrupt the up
command.
To be a valid Compose extension, provider command MUST accept a compose
command (which can be hidden)
with subcommands up
and down
.
Up lifecycle
To execute an application's up
lifecycle, Compose executes the provider's compose up
command, passing
the project name, service name, and additional options. The provider.options
are translated
into command line flags. For example:
awesomecloud compose --project-name <NAME> up --type=mysql --size=256 "database"
Note:
project-name
should be used by the provider to tag resources set for project, so that later execution withdown
subcommand releases all allocated resources set for the project.
Communication with Compose
Providers can interact with Compose using stdout
as a channel, sending JSON line delimited messages.
JSON messages MUST include a type
and a message
attribute.
{ "type": "info", "message": "preparing mysql ..." }
type
can be either:
info
: Reports status updates to the user. Compose will render message as the service state in the progress UIerror
: Let's the user know something went wrong with details about the error. Compose will render the message as the reason for the service failure.setenv
: Let's the plugin tell Compose how dependent services can access the created resource. See next section for further details.debug
: Those messages could help debugging the provider, but are not rendered to the user by default. They are rendered when Compose is started with--verbose
flag.
sequenceDiagram
Shell->>Compose: docker compose up
Compose->>Provider: compose up --project-name=xx --foo=bar "database"
Provider--)Compose: json { "info": "pulling 25%" }
Compose-)Shell: pulling 25%
Provider--)Compose: json { "info": "pulling 50%" }
Compose-)Shell: pulling 50%
Provider--)Compose: json { "info": "pulling 75%" }
Compose-)Shell: pulling 75%
Provider--)Compose: json { "setenv": "URL=http://cloud.com/abcd:1234" }
Compose-)Compose: set DATABASE_URL
Provider-)Compose: EOF (command complete) exit 0
Compose-)Shell: service started
Connection to a service managed by a provider
A service in the Compose application can declare dependency on a service managed by an external provider:
services:
app:
image: myapp
depends_on:
- database
database:
provider:
type: awesomecloud
When the provider command sends a setenv
JSON message, Compose injects the specified variable into any dependent service,
automatically prefixing it with the service name. For example, if awesomecloud compose up
returns:
{"type": "setenv", "message": "URL=https://awesomecloud.com/db:1234"}
Then the app
service, which depends on the service managed by the provider, will receive a DATABASE_URL
environment variable injected
into its runtime environment.
Note: The
compose up
provider command MUST be idempotent. If resource is already running, the command MUST set the same environment variables to ensure consistent configuration of dependent services.
Down lifecycle
down
lifecycle is equivalent to up
with the <provider> compose --project-name <NAME> down <SERVICE>
command.
The provider is responsible for releasing all resources associated with the service.
Provide metadata about options
Compose extensions MAY optionally implement a metadata
subcommand to provide information about the parameters accepted by the up
and down
commands.
The metadata
subcommand takes no parameters and returns a JSON structure on the stdout
channel that describes the parameters accepted by both the up
and down
commands, including whether each parameter is mandatory or optional.
awesomecloud compose metadata
The expected JSON output format is:
{
"description": "Manage services on AwesomeCloud",
"up": {
"parameters": [
{
"name": "type",
"description": "Database type (mysql, postgres, etc.)",
"required": true,
"type": "string"
},
{
"name": "size",
"description": "Database size in GB",
"required": false,
"type": "integer",
"default": "10"
},
{
"name": "name",
"description": "Name of the database to be created",
"required": true,
"type": "string"
}
]
},
"down": {
"parameters": [
{
"name": "name",
"description": "Name of the database to be removed",
"required": true,
"type": "string"
}
]
}
}
The top elements are:
description
: Human-readable description of the providerup
: Object describing the parameters accepted by theup
commanddown
: Object describing the parameters accepted by thedown
command
And for each command parameter, you should include the following properties:
name
: The parameter name (without--
prefix)description
: Human-readable description of the parameterrequired
: Boolean indicating if the parameter is mandatorytype
: Parameter type (string
,integer
,boolean
, etc.)default
: Default value (optional, only for non-required parameters)enum
: List of possible values supported by the parameter separated by,
(optional, only for parameters with a limited set of values)
This metadata allows Compose and other tools to understand the provider's interface and provide better user experience, such as validation, auto-completion, and documentation generation.
Examples
See example for illustration on implementing this API in a command line