diff --git a/provider.go b/provider.go index 799fd9bd..b842d6b6 100644 --- a/provider.go +++ b/provider.go @@ -29,6 +29,7 @@ func Provider() terraform.ResourceProvider { "docker_container": resourceDockerContainer(), "docker_image": resourceDockerImage(), "docker_network": resourceDockerNetwork(), + "docker_volume": resourceDockerVolume(), }, ConfigureFunc: providerConfigure, diff --git a/resource_docker_volume.go b/resource_docker_volume.go new file mode 100644 index 00000000..33c22d58 --- /dev/null +++ b/resource_docker_volume.go @@ -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 +} diff --git a/resource_docker_volume_test.go b/resource_docker_volume_test.go new file mode 100644 index 00000000..38fec3c4 --- /dev/null +++ b/resource_docker_volume_test.go @@ -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" +} +`