Squash []map[string]type for port_map and labels into map[string]type
This commit is contained in:
parent
275550dcd3
commit
cf4bb4cfd0
|
@ -37,12 +37,14 @@ type DockerDriverConfig struct {
|
|||
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
|
||||
PortMapRaw []map[string]int `mapstructure:"port_map"` //
|
||||
PortMap map[string]int `mapstructure:"-"` // 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
|
||||
DNSServers []string `mapstructure:"dns_servers"` // DNS Server for containers
|
||||
DNSSearchDomains []string `mapstructure:"dns_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
|
||||
LabelsRaw []map[string]string `mapstructure:"labels"` //
|
||||
Labels map[string]string `mapstructure:"-"` // Labels to set when the container starts up
|
||||
Auth []DockerDriverAuth `mapstructure:"auth"` // Authentication credentials for a private Docker registry
|
||||
}
|
||||
|
||||
|
@ -51,13 +53,9 @@ func (c *DockerDriverConfig) Validate() error {
|
|||
return fmt.Errorf("Docker Driver needs an image name")
|
||||
}
|
||||
|
||||
if len(c.PortMap) > 1 {
|
||||
return fmt.Errorf("Only one port_map block is allowed in the docker driver config")
|
||||
}
|
||||
c.PortMap = mapMergeStrInt(c.PortMapRaw...)
|
||||
c.Labels = mapMergeStrStr(c.LabelsRaw...)
|
||||
|
||||
if len(c.Labels) > 1 {
|
||||
return fmt.Errorf("Only one labels block is allowed in the docker driver config")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -239,7 +237,7 @@ func (d *DockerDriver) createContainer(ctx *ExecContext, task *structs.Task, dri
|
|||
// Setup port mapping and exposed ports
|
||||
if len(task.Resources.Networks) == 0 {
|
||||
d.logger.Println("[DEBUG] driver.docker: No network interfaces are available")
|
||||
if len(driverConfig.PortMap) == 1 && len(driverConfig.PortMap[0]) > 0 {
|
||||
if len(driverConfig.PortMap) > 0 {
|
||||
return c, fmt.Errorf("Trying to map ports but no network interface is available")
|
||||
}
|
||||
} else {
|
||||
|
@ -253,11 +251,8 @@ func (d *DockerDriver) createContainer(ctx *ExecContext, task *structs.Task, dri
|
|||
containerPortInt := port.Value
|
||||
|
||||
// If the user has mapped a port using port_map we'll change it here
|
||||
if len(driverConfig.PortMap) == 1 {
|
||||
mapped, ok := driverConfig.PortMap[0][port.Label]
|
||||
if ok {
|
||||
containerPortInt = mapped
|
||||
}
|
||||
if mapped, ok := driverConfig.PortMap[port.Label]; ok {
|
||||
containerPortInt = mapped
|
||||
}
|
||||
|
||||
hostPortStr := strconv.Itoa(port.Value)
|
||||
|
@ -277,11 +272,8 @@ func (d *DockerDriver) createContainer(ctx *ExecContext, task *structs.Task, dri
|
|||
containerPortInt := port.Value
|
||||
|
||||
// If the user has mapped a port using port_map we'll change it here
|
||||
if len(driverConfig.PortMap) == 1 {
|
||||
mapped, ok := driverConfig.PortMap[0][port.Label]
|
||||
if ok {
|
||||
containerPortInt = mapped
|
||||
}
|
||||
if mapped, ok := driverConfig.PortMap[port.Label]; ok {
|
||||
containerPortInt = mapped
|
||||
}
|
||||
|
||||
hostPortStr := strconv.Itoa(port.Value)
|
||||
|
@ -302,8 +294,8 @@ func (d *DockerDriver) createContainer(ctx *ExecContext, task *structs.Task, dri
|
|||
// TODO refactor the implementation in TaskEnvironmentVariables to match
|
||||
// the 0.2 ports world view. Docker seems to be the only place where
|
||||
// this is actually needed, but this is kinda hacky.
|
||||
if len(driverConfig.PortMap) == 1 {
|
||||
env.SetPorts(network.MapLabelToValues(driverConfig.PortMap[0]))
|
||||
if len(driverConfig.PortMap) > 0 {
|
||||
env.SetPorts(network.MapLabelToValues(driverConfig.PortMap))
|
||||
}
|
||||
hostConfig.PortBindings = publishedPorts
|
||||
config.ExposedPorts = exposedPorts
|
||||
|
@ -324,8 +316,8 @@ func (d *DockerDriver) createContainer(ctx *ExecContext, task *structs.Task, dri
|
|||
d.logger.Println("[DEBUG] driver.docker: ignoring command arguments because command is not specified")
|
||||
}
|
||||
|
||||
if len(driverConfig.Labels) == 1 {
|
||||
config.Labels = driverConfig.Labels[0]
|
||||
if len(driverConfig.Labels) > 0 {
|
||||
config.Labels = driverConfig.Labels
|
||||
d.logger.Printf("[DEBUG] driver.docker: applied labels on the container: %+v", config.Labels)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -92,7 +93,7 @@ func dockerSetup(t *testing.T, task *structs.Task) (*docker.Client, DriverHandle
|
|||
|
||||
client, err := docker.NewClientFromEnv()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
t.Fatalf("Failed to initialize client: %s\nStack\n%s", err, debug.Stack())
|
||||
}
|
||||
|
||||
driverCtx := testDockerDriverContext(task.Name)
|
||||
|
@ -102,11 +103,11 @@ func dockerSetup(t *testing.T, task *structs.Task) (*docker.Client, DriverHandle
|
|||
handle, err := driver.Start(ctx, task)
|
||||
if err != nil {
|
||||
ctx.AllocDir.Destroy()
|
||||
t.Fatalf("err: %v", err)
|
||||
t.Fatalf("Failed to start driver: %s\nStack\n%s", err, debug.Stack())
|
||||
}
|
||||
if handle == nil {
|
||||
ctx.AllocDir.Destroy()
|
||||
t.Fatalf("missing handle")
|
||||
t.Fatalf("handle is nil\nStack\n%s", debug.Stack())
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
|
|
|
@ -145,3 +145,23 @@ func TaskEnvironmentVariables(ctx *ExecContext, task *structs.Task) environment.
|
|||
|
||||
return env
|
||||
}
|
||||
|
||||
func mapMergeStrInt(maps ...map[string]int) map[string]int {
|
||||
out := map[string]int{}
|
||||
for _, in := range maps {
|
||||
for key, val := range in {
|
||||
out[key] = val
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func mapMergeStrStr(maps ...map[string]string) map[string]string {
|
||||
out := map[string]string{}
|
||||
for _, in := range maps {
|
||||
for key, val := range in {
|
||||
out[key] = val
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -99,3 +99,51 @@ func TestDriver_TaskEnvironmentVariables(t *testing.T) {
|
|||
t.Fatalf("TaskEnvironmentVariables(%#v, %#v) returned %#v; want %#v", ctx, task, act, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapMergeStrInt(t *testing.T) {
|
||||
a := map[string]int{
|
||||
"cakes": 5,
|
||||
"cookies": 3,
|
||||
}
|
||||
|
||||
b := map[string]int{
|
||||
"cakes": 3,
|
||||
"pies": 2,
|
||||
}
|
||||
|
||||
c := mapMergeStrInt(a, b)
|
||||
|
||||
d := map[string]int{
|
||||
"cakes": 3,
|
||||
"cookies": 3,
|
||||
"pies": 2,
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(c, d) {
|
||||
t.Errorf("\nExpected\n%+v\nGot\n%+v\n", d, c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapMergeStrStr(t *testing.T) {
|
||||
a := map[string]string{
|
||||
"cake": "chocolate",
|
||||
"cookie": "caramel",
|
||||
}
|
||||
|
||||
b := map[string]string{
|
||||
"cake": "strawberry",
|
||||
"pie": "apple",
|
||||
}
|
||||
|
||||
c := mapMergeStrStr(a, b)
|
||||
|
||||
d := map[string]string{
|
||||
"cake": "strawberry",
|
||||
"cookie": "caramel",
|
||||
"pie": "apple",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(c, d) {
|
||||
t.Errorf("\nExpected\n%+v\nGot\n%+v\n", d, c)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue