Merge pull request #437 from hashicorp/f-docker-labels

Support labels for docker containers
This commit is contained in:
Chris Bednarski 2015-11-17 16:10:36 -08:00
commit c275b3f06d
3 changed files with 89 additions and 19 deletions

View file

@ -35,15 +35,16 @@ type DockerAuthConfig struct {
type DockerDriverConfig struct {
DockerAuthConfig
ImageName string `mapstructure:"image"` // Container's Image Name
Command string `mapstructure:"command"` // The Command/Entrypoint to run when the container starts up
Args string `mapstructure:"args"` // The arguments to the Command/Entrypoint
NetworkMode string `mapstructure:"network_mode"` // The network mode of the container - host, net and none
PortMap []map[string]int `mapstructure:"port_map"` // A map of host port labels and the ports exposed on the container
Privileged bool `mapstructure:"privileged"` // Flag to run the container in priviledged mode
DNS string `mapstructure:"dns_server"` // DNS Server for containers
SearchDomains string `mapstructure:"search_domains"` // DNS Search domains for containers
Hostname string `mapstructure:"hostname"` // Hostname for containers
ImageName string `mapstructure:"image"` // Container's Image Name
Command string `mapstructure:"command"` // The Command/Entrypoint to run when the container starts up
Args string `mapstructure:"args"` // The arguments to the Command/Entrypoint
NetworkMode string `mapstructure:"network_mode"` // The network mode of the container - host, net and none
PortMap []map[string]int `mapstructure:"port_map"` // A map of host port labels and the ports exposed on the container
Privileged bool `mapstructure:"privileged"` // Flag to run the container in priviledged mode
DNS string `mapstructure:"dns_server"` // DNS Server for containers
SearchDomains string `mapstructure:"search_domains"` // DNS Search domains for containers
Hostname string `mapstructure:"hostname"` // Hostname for containers
Labels []map[string]string `mapstructure:"labels"` // Labels to set when the container starts up
}
func (c *DockerDriverConfig) Validate() error {
@ -54,6 +55,10 @@ func (c *DockerDriverConfig) Validate() error {
if len(c.PortMap) > 1 {
return fmt.Errorf("Only one port_map block is allowed in the docker driver config")
}
if len(c.Labels) > 1 {
return fmt.Errorf("Only one labels block is allowed in the docker driver config")
}
return nil
}
@ -323,6 +328,11 @@ func (d *DockerDriver) createContainer(ctx *ExecContext, task *structs.Task, dri
d.logger.Println("[DEBUG] driver.docker: ignoring args because command not specified")
}
if len(driverConfig.Labels) == 1 {
config.Labels = driverConfig.Labels[0]
d.logger.Println("[DEBUG] driver.docker: applied labels on the container")
}
config.Env = env.List()
return docker.CreateContainerOptions{
Name: fmt.Sprintf("%s-%s", task.Name, ctx.AllocID),

View file

@ -1,10 +1,12 @@
package driver
import (
"encoding/json"
"fmt"
"io/ioutil"
"path/filepath"
"reflect"
"strings"
"testing"
"time"
@ -433,3 +435,58 @@ func TestDockerHostNet(t *testing.T) {
}
defer handle.Kill()
}
func TestDockerLabels(t *testing.T) {
if !dockerIsConnected(t) {
t.SkipNow()
}
task := taskTemplate()
task.Config["labels"] = []map[string]string{
map[string]string{
"label1": "value1",
"label2": "value2",
},
}
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)
handle, err := d.Start(ctx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
client, err := docker.NewClientFromEnv()
if err != nil {
t.Fatalf("err: %v", err)
}
// don't know if is queriable in a clean way
parts := strings.SplitN(handle.ID(), ":", 2)
var pid dockerPID
err = json.Unmarshal([]byte(parts[1]), &pid)
if err != nil {
t.Fatalf("err: %v", err)
}
container, err := client.InspectContainer(pid.ContainerID)
if err != nil {
t.Fatalf("err: %v", err)
}
if want, got := 2, len(container.Config.Labels); want != got {
t.Errorf("Wrong labels count for docker job. Expect: %d, got: %d", want, got)
}
if want, got := "value1", container.Config.Labels["label1"]; want != got {
t.Errorf("Wrong label value docker job. Expect: %s, got: %s", want, got)
}
defer handle.Kill()
}

View file

@ -32,29 +32,32 @@ The `docker` driver supports the following configuration in the job specificatio
network mode is not supported right now and is reported as an invalid
option.
* `privileged` - (optional) Privileged mode gives the container full access to
* `privileged` - (Optional) Privileged mode gives the container full access to
the host. Valid options are `"true"` and `"false"` (defaults to `"false"`).
Tasks with `privileged` set can only run on Nomad Agents with
`docker.privileged.enabled = "true"`.
* `dns-servers` - (optional) A comma separated list of DNS servers for the container
* `dns-servers` - (Optional) A comma separated list of DNS servers for the container
to use (e.g. "8.8.8.8,8.8.4.4"). *Docker API v1.10 and above only*
* `search-domains` - (optional) A comma separated list of DNS search domains for the
* `search-domains` - (Optional) A comma separated list of DNS search domains for the
container to use.
* `hostname` - (optional) The hostname to assign to the container. When launching more
than one of a task (using `count`) with this option set, every container the task
starts will have the same hostname.
* `labels` - (Optional) A key/value map of labels to set to the containers on start.
**Authentication**
Registry authentication can be set per task with the following authentication
parameters. These options can provide access to private repositories that
Registry authentication can be set per task with the following authentication
parameters. These options can provide access to private repositories that
utilize the docker remote api (e.g. dockerhub, quay.io)
- `auth.username` - (optional) The account username
- `auth.password` - (optional) The account password
- `auth.email` - (optional) The account email
- `auth.server-address` - (optional) The server domain/ip without the protocol
- `auth.username` - (Optional) The account username
- `auth.password` - (Optional) The account password
- `auth.email` - (Optional) The account email
- `auth.server-address` - (Optional) The server domain/ip without the protocol
### Port Mapping