diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index fe2a82e47..296d7dc23 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -70,4 +70,5 @@ and we will add you. **All** contributors belong here. 💯 * [Chioma Onyekpere](https://github.com/Simpcyclassy) * [Hrittik Roy](https://github.com/hrittikhere) * [Tanmay Chaudhry](https://github.com/tchaudhry91) -* [Kevin Barbour](https://github.com/kevinbarbour) \ No newline at end of file +* [Rich Baird](https://github.com/richbai90) +* [Kevin Barbour](https://github.com/kevinbarbour) diff --git a/pkg/cnab/docker.go b/pkg/cnab/docker.go index 68aba1f74..d02eed2df 100644 --- a/pkg/cnab/docker.go +++ b/pkg/cnab/docker.go @@ -3,6 +3,9 @@ package cnab import ( "encoding/json" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/mount" + "github.com/docker/go-connections/nat" "github.com/pkg/errors" ) @@ -29,6 +32,19 @@ var DockerExtension = RequiredExtension{ type Docker struct { // Privileged represents whether or not the Docker container should run as --privileged Privileged bool `json:"privileged,omitempty"` + // Mounts represent mounts to be attached to the host machine with all configurable options. + Mounts []mount.Mount `json:"mounts,omitempty"` + // Network represents the network type applied to the container "host,bridged,etc" + Network string `json:"network,omitempty"` + // CapAdd represents the capabilities available to the container kernel + CapAdd []string `json:"capadd,omitempty"` + // CapDrop represents capabilities to exclude from the container kernel + CapDrop []string `json:"capdrop,omitempty"` + // Ports to bind between the host and the container + PortBindings []nat.PortMap `json:"portBindings,omitempty"` + // Restart policy to be used for the container + // This may be useful in some rare cases + RestartPolicy container.RestartPolicy `json:"restartPolicy"` } // DockerExtensionReader is a Reader for the DockerExtension, diff --git a/pkg/cnab/provider/driver.go b/pkg/cnab/provider/driver.go index 5d9a2f14e..df4bcc86c 100644 --- a/pkg/cnab/provider/driver.go +++ b/pkg/cnab/provider/driver.go @@ -78,6 +78,34 @@ func (r *Runtime) dockerDriverWithHostAccess(config cnab.Docker) (driver.Driver, }) } + if config.CapAdd != nil { + d.AddConfigurationOptions(func(cfg *container.Config, hostCfg *container.HostConfig) error { + hostCfg.CapAdd = config.CapAdd + return nil + }) + } + + if config.CapDrop != nil { + d.AddConfigurationOptions(func(cfg *container.Config, hostCfg *container.HostConfig) error { + hostCfg.CapDrop = config.CapDrop + return nil + }) + } + + if config.Mounts != nil { + d.AddConfigurationOptions(func(cfg *container.Config, hostCfg *container.HostConfig) error { + hostCfg.Mounts = config.Mounts + return nil + }) + } + + if config.Network != "" { + d.AddConfigurationOptions(func(cfg *container.Config, hostCfg *container.HostConfig) error { + hostCfg.NetworkMode = container.NetworkMode(config.Network) + return nil + }) + } + // Mount the docker socket d.AddConfigurationOptions(r.mountDockerSocket) diff --git a/pkg/cnab/schema/io-cnab-docker.schema.json b/pkg/cnab/schema/io-cnab-docker.schema.json index 662369203..e05909e31 100644 --- a/pkg/cnab/schema/io-cnab-docker.schema.json +++ b/pkg/cnab/schema/io-cnab-docker.schema.json @@ -1,11 +1,165 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "privileged": { - "description": "Option to set the --privileged flag when running the Docker container", - "type": "boolean" + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "privileged": { + "description": "Option to set the --privileged flag when running the Docker container", + "type": "boolean" + }, + "mounts": { + "description": "Specify mount configurations as parseable by the --mount flag", + "type": "array", + "items": { + "type": "object", + "description": "Options general to all mount configurations", + "properties": { + "Type": { + "type": "string", + "description": "Sets the mount type (bind/volume/tmpfs/npipe)" + }, + "Source": { + "type": "string", + "description": "The source of the mount on the host machine, or empty when using tmpfs" + }, + "Target": { + "type": "string", + "description": "The target of the mount on the container" + }, + "ReadOnly": { + "type": "boolean", + "description": "Specify that the mount has readonly access" + }, + "Consistency": { + "type": "string", + "description": "Specify the concsistency type for the mount" + }, + "BindOptions": { + "type": "object", + "properties": { + "Propagation": { + "type": "string", + "description": "Specify the propagation behavior for the mount" + }, + "NonRecursive": { + "type": "boolean", + "description": "Specify whether or not the mount should be recursive" + } + } + }, + "VolumeOptions": { + "type": "object", + "description": "Options specific to the volume mount type", + "properties": { + "NoCopy": { + "type": "boolean", + "description": "Specify" + }, + "Labels": { + "type": "object", + "description": "A map of volume labels in the form of :", + "patternProperties": { + "[a-zA-Z_0-9-]+": { + "type": "string" + } + } + }, + "DriverConfig": { + "type": "object", + "description": "Driver configuration options", + "properties": { + "Name": { + "type": "string", + "description": "The name of the driver to use" + }, + "Options": { + "type": "object", + "description": "A map of driver configuration options to use in the form of {option: value}", + "patternProperties": { + "[a-zA-Z_0-9-]+": { + "type": "string" + } + } + } + } + } + } + }, + "TmpfsOptions": { + "type": "object", + "description": "Options specific to the tmpfs mount type", + "properties": { + "SizeBytes": { + "type": "integer", + "description": "Specify the size of the filesystem in bytes" + }, + "Mode": { + "type": "integer", + "description": "Specify the filemode for the fs" + } + } + } + } + } + }, + "network": { + "type": "string", + "description": "Specify the network type to use when launching the container" + }, + "capadd": { + "type": "array", + "description": "A list of capabilities to add", + "items": { + "type": "string" + } + }, + "capdrop": { + "type": "array", + "description": "A llist of capabilities to drop", + "items": { + "type": "string" + }, + "examples": [] + }, + "portBindings": { + "type": "array", + "description": "A list of ports to bind between the host and the container", + "items": { + "type": "object", + "properties": { + "patternProperties": { + "[0-9]+": { + "type": "array", + "description": "The port on the container to bind", + "items": { + "type": "object", + "properties": { + "HostIp": { + "type": "The ip to bind the port to on the host" + }, + "HostPort": { + "type": "string", + "description": "The port on the host to map the container port to" + } + } + } + } + } + } + } + }, + "restartPolicy": { + "type": "object", + "description": "The restart policy for the container", + "properties": { + "Name": { + "type": "string", + "description": "The name of the restart policy" + }, + "MaximumRetryCount": { + "type": "integer", + "description": "The maximum retry count" + } + } + } } - }, - "additionalProperties": false -} +} \ No newline at end of file