Merge branch 'paulbellamy-docker-extra-hosts'

This commit is contained in:
James Nugent 2016-01-15 03:05:25 +00:00
commit 5834e65db9
4 changed files with 166 additions and 80 deletions

View File

@ -119,16 +119,91 @@ func resourceDockerContainer() *schema.Resource {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Elem: getVolumesElem(), Elem: &schema.Resource{
Set: resourceDockerVolumesHash, Schema: map[string]*schema.Schema{
"from_container": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"container_path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"host_path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"read_only": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
},
},
Set: resourceDockerVolumesHash,
}, },
"ports": &schema.Schema{ "ports": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Elem: getPortsElem(), Elem: &schema.Resource{
Set: resourceDockerPortsHash, Schema: map[string]*schema.Schema{
"internal": &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},
"external": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"ip": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"protocol": &schema.Schema{
Type: schema.TypeString,
Default: "tcp",
Optional: true,
ForceNew: true,
},
},
},
Set: resourceDockerPortsHash,
},
"host": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"host": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
},
Set: resourceDockerHostsHash,
}, },
"env": &schema.Schema{ "env": &schema.Schema{
@ -256,67 +331,6 @@ func resourceDockerContainer() *schema.Resource {
} }
} }
func getVolumesElem() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"from_container": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"container_path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"host_path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"read_only": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
},
}
}
func getPortsElem() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"internal": &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},
"external": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"ip": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"protocol": &schema.Schema{
Type: schema.TypeString,
Default: "tcp",
Optional: true,
ForceNew: true,
},
},
}
}
func resourceDockerPortsHash(v interface{}) int { func resourceDockerPortsHash(v interface{}) int {
var buf bytes.Buffer var buf bytes.Buffer
m := v.(map[string]interface{}) m := v.(map[string]interface{})
@ -338,6 +352,21 @@ func resourceDockerPortsHash(v interface{}) int {
return hashcode.String(buf.String()) return hashcode.String(buf.String())
} }
func resourceDockerHostsHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
if v, ok := m["ip"]; ok {
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
}
if v, ok := m["host"]; ok {
buf.WriteString(fmt.Sprintf("%v-", v.(string)))
}
return hashcode.String(buf.String())
}
func resourceDockerVolumesHash(v interface{}) int { func resourceDockerVolumesHash(v interface{}) int {
var buf bytes.Buffer var buf bytes.Buffer
m := v.(map[string]interface{}) m := v.(map[string]interface{})

View File

@ -67,6 +67,11 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err
createOpts.Config.ExposedPorts = exposedPorts createOpts.Config.ExposedPorts = exposedPorts
} }
extraHosts := []string{}
if v, ok := d.GetOk("host"); ok {
extraHosts = extraHostsSetToDockerExtraHosts(v.(*schema.Set))
}
volumes := map[string]struct{}{} volumes := map[string]struct{}{}
binds := []string{} binds := []string{}
volumesFrom := []string{} volumesFrom := []string{}
@ -100,7 +105,9 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err
if len(portBindings) != 0 { if len(portBindings) != 0 {
hostConfig.PortBindings = portBindings hostConfig.PortBindings = portBindings
} }
if len(extraHosts) != 0 {
hostConfig.ExtraHosts = extraHosts
}
if len(binds) != 0 { if len(binds) != 0 {
hostConfig.Binds = binds hostConfig.Binds = binds
} }
@ -324,6 +331,19 @@ func portSetToDockerPorts(ports *schema.Set) (map[dc.Port]struct{}, map[dc.Port]
return retExposedPorts, retPortBindings return retExposedPorts, retPortBindings
} }
func extraHostsSetToDockerExtraHosts(extraHosts *schema.Set) []string {
retExtraHosts := []string{}
for _, hostInt := range extraHosts.List() {
host := hostInt.(map[string]interface{})
ip := host["ip"].(string)
hostname := host["host"].(string)
retExtraHosts = append(retExtraHosts, hostname+":"+ip)
}
return retExtraHosts
}
func volumeSetToDockerVolumes(volumes *schema.Set) (map[string]struct{}, []string, []string, error) { func volumeSetToDockerVolumes(volumes *schema.Set) (map[string]struct{}, []string, []string, error) {
retVolumeMap := map[string]struct{}{} retVolumeMap := map[string]struct{}{}
retHostConfigBinds := []string{} retHostConfigBinds := []string{}

View File

@ -72,6 +72,18 @@ func TestAccDockerContainer_customized(t *testing.T) {
return fmt.Errorf("Container does not have the correct max-file log option: %v", c.HostConfig.LogConfig.Config["max-file"]) return fmt.Errorf("Container does not have the correct max-file log option: %v", c.HostConfig.LogConfig.Config["max-file"])
} }
if len(c.HostConfig.ExtraHosts) != 2 {
return fmt.Errorf("Container does not have correct number of extra host entries, got %d", len(c.HostConfig.ExtraHosts))
}
if c.HostConfig.ExtraHosts[0] != "testhost2:10.0.2.0" {
return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[0])
}
if c.HostConfig.ExtraHosts[1] != "testhost:10.0.1.0" {
return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[1])
}
return nil return nil
} }
@ -132,6 +144,7 @@ resource "docker_container" "foo" {
image = "${docker_image.foo.latest}" image = "${docker_image.foo.latest}"
} }
` `
const testAccDockerContainerCustomizedConfig = ` const testAccDockerContainerCustomizedConfig = `
resource "docker_image" "foo" { resource "docker_image" "foo" {
name = "nginx:latest" name = "nginx:latest"
@ -140,21 +153,31 @@ resource "docker_image" "foo" {
resource "docker_container" "foo" { resource "docker_container" "foo" {
name = "tf-test" name = "tf-test"
image = "${docker_image.foo.latest}" image = "${docker_image.foo.latest}"
entrypoint = ["/bin/bash", "-c", "ping localhost"] entrypoint = ["/bin/bash", "-c", "ping localhost"]
restart = "on-failure" restart = "on-failure"
max_retry_count = 5 max_retry_count = 5
memory = 512 memory = 512
memory_swap = 2048 memory_swap = 2048
cpu_shares = 32 cpu_shares = 32
labels { labels {
env = "prod" env = "prod"
role = "test" role = "test"
} }
log_driver = "json-file" log_driver = "json-file"
log_opts = { log_opts = {
max-size = "10m" max-size = "10m"
max-file = 20 max-file = 20
} }
network_mode = "bridge" network_mode = "bridge"
host {
host = "testhost"
ip = "10.0.1.0"
}
host {
host = "testhost2"
ip = "10.0.2.0"
}
} }
` `

View File

@ -57,6 +57,7 @@ The following arguments are supported:
kept running. If false, then as long as the container exists, Terraform kept running. If false, then as long as the container exists, Terraform
assumes it is successful. assumes it is successful.
* `ports` - (Optional) See [Ports](#ports) below for details. * `ports` - (Optional) See [Ports](#ports) below for details.
* `host_entry` - (Optional) See [Extra Hosts](#extra_hosts) below for details.
* `privileged` - (Optional, bool) Run container in privileged mode. * `privileged` - (Optional, bool) Run container in privileged mode.
* `publish_all_ports` - (Optional, bool) Publish all ports of the container. * `publish_all_ports` - (Optional, bool) Publish all ports of the container.
* `volumes` - (Optional) See [Volumes](#volumes) below for details. * `volumes` - (Optional) See [Volumes](#volumes) below for details.
@ -84,6 +85,19 @@ the following:
* `protocol` - (Optional, string) Protocol that can be used over this port, * `protocol` - (Optional, string) Protocol that can be used over this port,
defaults to TCP. defaults to TCP.
<a id="extra_hosts"></a>
## Extra Hosts
`host_entry` is a block within the configuration that can be repeated to specify
the extra host mappings for the container. Each `host_entry` block supports
the following:
* `host` - (Required, int) Hostname to add.
* `ip` - (Required, int) IP address this hostname should resolve to..
This is equivalent to using the `--add-host` option when using the `run`
command of the Docker CLI.
<a id="volumes"></a> <a id="volumes"></a>
## Volumes ## Volumes