provider/docker: Add `docker_volume` resource
This commit is contained in:
parent
ead4865b7f
commit
e887ac2523
|
@ -29,6 +29,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"docker_container": resourceDockerContainer(),
|
||||
"docker_image": resourceDockerImage(),
|
||||
"docker_network": resourceDockerNetwork(),
|
||||
"docker_volume": resourceDockerVolume(),
|
||||
},
|
||||
|
||||
ConfigureFunc: providerConfigure,
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
dc "github.com/fsouza/go-dockerclient"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceDockerVolume() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceDockerVolumeCreate,
|
||||
Read: resourceDockerVolumeRead,
|
||||
Delete: resourceDockerVolumeDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"driver": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"driver_opts": &schema.Schema{
|
||||
Type: schema.TypeMap,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"mountpoint": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceDockerVolumeCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*dc.Client)
|
||||
|
||||
createOpts := dc.CreateVolumeOptions{}
|
||||
if v, ok := d.GetOk("name"); ok {
|
||||
createOpts.Name = v.(string)
|
||||
}
|
||||
if v, ok := d.GetOk("driver"); ok {
|
||||
createOpts.Driver = v.(string)
|
||||
}
|
||||
if v, ok := d.GetOk("driver_opts"); ok {
|
||||
createOpts.DriverOpts = mapTypeMapValsToString(v.(map[string]interface{}))
|
||||
}
|
||||
|
||||
var err error
|
||||
var retVolume *dc.Volume
|
||||
if retVolume, err = client.CreateVolume(createOpts); err != nil {
|
||||
return fmt.Errorf("Unable to create volume: %s", err)
|
||||
}
|
||||
if retVolume == nil {
|
||||
return fmt.Errorf("Returned volume is nil")
|
||||
}
|
||||
|
||||
d.SetId(retVolume.Name)
|
||||
d.Set("name", retVolume.Name)
|
||||
d.Set("driver", retVolume.Driver)
|
||||
d.Set("mountpoint", retVolume.Mountpoint)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDockerVolumeRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*dc.Client)
|
||||
|
||||
var err error
|
||||
var retVolume *dc.Volume
|
||||
if retVolume, err = client.InspectVolume(d.Id()); err != nil && err != dc.ErrNoSuchVolume {
|
||||
return fmt.Errorf("Unable to inspect volume: %s", err)
|
||||
}
|
||||
if retVolume == nil {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
d.Set("name", retVolume.Name)
|
||||
d.Set("driver", retVolume.Driver)
|
||||
d.Set("mountpoint", retVolume.Mountpoint)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDockerVolumeDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*dc.Client)
|
||||
|
||||
if err := client.RemoveVolume(d.Id()); err != nil && err != dc.ErrNoSuchVolume {
|
||||
return fmt.Errorf("Error deleting volume %s: %s", d.Id(), err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
dc "github.com/fsouza/go-dockerclient"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccDockerVolume_basic(t *testing.T) {
|
||||
var v dc.Volume
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccDockerVolumeConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
checkDockerVolume("docker_volume.foo", &v),
|
||||
resource.TestCheckResourceAttr("docker_volume.foo", "id", "testAccDockerVolume_basic"),
|
||||
resource.TestCheckResourceAttr("docker_volume.foo", "name", "testAccDockerVolume_basic"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func checkDockerVolume(n string, volume *dc.Volume) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
client := testAccProvider.Meta().(*dc.Client)
|
||||
volumes, err := client.ListVolumes(dc.ListVolumesOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, v := range volumes {
|
||||
if v.Name == rs.Primary.ID {
|
||||
inspected, err := client.InspectVolume(v.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Volume could not be inspected: %s", err)
|
||||
}
|
||||
*volume = *inspected
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Volume not found: %s", rs.Primary.ID)
|
||||
}
|
||||
}
|
||||
|
||||
const testAccDockerVolumeConfig = `
|
||||
resource "docker_volume" "foo" {
|
||||
name = "testAccDockerVolume_basic"
|
||||
}
|
||||
`
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
layout: "docker"
|
||||
page_title: "Docker: docker_volume"
|
||||
sidebar_current: "docs-docker-resource-volume"
|
||||
description: |-
|
||||
Creates and destroys docker volumes.
|
||||
---
|
||||
|
||||
# docker\_volume
|
||||
|
||||
Creates and destroys a volume in Docker. This can be used alongside
|
||||
[docker\_container](/docs/providers/docker/r/container.html)
|
||||
to prepare volumes that can be shared across containers.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
# Creates a docker volume "shared_volume".
|
||||
resource "docker_volume" "shared_volume" {
|
||||
name = "shared_volume"
|
||||
}
|
||||
|
||||
# Reference the volume with ${docker_volume.shared_volume.name}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Optional, string) The name of the Docker volume (generated if not provided).
|
||||
* `driver` - (Optional, string) Driver type for the volume (defaults to local).
|
||||
* `driver_opts` - (Optional, map of strings) Options specific to the driver.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported in addition to the above configuration:
|
||||
|
||||
* `mountpoint` (string) - The mountpoint of the volume.
|
Loading…
Reference in New Issue