Skip to content

Commit c573bc1

Browse files
authored
Merge pull request dmacvicar#571 from zeenix/pool-resource
Add storage pool resource
2 parents 709e1db + 476095b commit c573bc1

File tree

7 files changed

+650
-1
lines changed

7 files changed

+650
-1
lines changed

examples/ubuntu/ubuntu-example.tf

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ provider "libvirt" {
33
uri = "qemu:///system"
44
}
55

6+
resource "libvirt_pool" "ubuntu" {
7+
name = "ubuntu"
8+
type = "dir"
9+
path = "/tmp/terraform-provider-libvirt-pool-ubuntu"
10+
}
11+
612
# We fetch the latest ubuntu release image from their mirrors
713
resource "libvirt_volume" "ubuntu-qcow2" {
814
name = "ubuntu-qcow2"
9-
pool = "default"
15+
pool = "${libvirt_pool.ubuntu.name}"
1016
source = "https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img"
1117
format = "qcow2"
1218
}
@@ -27,6 +33,7 @@ resource "libvirt_cloudinit_disk" "commoninit" {
2733
name = "commoninit.iso"
2834
user_data = "${data.template_file.user_data.rendered}"
2935
network_config = "${data.template_file.network_config.rendered}"
36+
pool = "${libvirt_pool.ubuntu.name}"
3037
}
3138

3239
# Create the machine

libvirt/helpers_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@ func getResourceFromTerraformState(resourceName string, state *terraform.State)
7171

7272
// ** resource specifics helpers **
7373

74+
// getPoolFromTerraformState lookup pool by name and return the libvirt pool from a terraform state
75+
func getPoolFromTerraformState(name string, state *terraform.State, virConn libvirt.Connect) (*libvirt.StoragePool, error) {
76+
rs, err := getResourceFromTerraformState(name, state)
77+
if err != nil {
78+
return nil, err
79+
}
80+
81+
pool, err := virConn.LookupStoragePoolByUUIDString(rs.Primary.ID)
82+
if err != nil {
83+
return nil, err
84+
}
85+
log.Printf("[DEBUG]:The ID is %s", rs.Primary.ID)
86+
return pool, nil
87+
}
88+
7489
// getVolumeFromTerraformState lookup volume by name and return the libvirt volume from a terraform state
7590
func getVolumeFromTerraformState(name string, state *terraform.State, virConn libvirt.Connect) (*libvirt.StorageVol, error) {
7691
rs, err := getResourceFromTerraformState(name, state)

libvirt/pool.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package libvirt
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"time"
7+
8+
"github.com/hashicorp/terraform/helper/resource"
9+
libvirt "github.com/libvirt/libvirt-go"
10+
)
11+
12+
const (
13+
poolExistsID = "EXISTS"
14+
poolNotExistsID = "NOT-EXISTS"
15+
)
16+
17+
// poolExists returns "EXISTS" or "NOT-EXISTS" depending on the current pool existence
18+
func poolExists(virConn *libvirt.Connect, uuid string) resource.StateRefreshFunc {
19+
return func() (interface{}, string, error) {
20+
pool, err := virConn.LookupStoragePoolByUUIDString(uuid)
21+
if err != nil {
22+
if err.(libvirt.Error).Code == libvirt.ERR_NO_STORAGE_POOL {
23+
log.Printf("Pool %s does not exist", uuid)
24+
return virConn, "NOT-EXISTS", nil
25+
}
26+
log.Printf("Pool %s: error: %s", uuid, err.(libvirt.Error).Message)
27+
}
28+
if pool != nil {
29+
defer pool.Free()
30+
}
31+
return virConn, poolExistsID, err
32+
}
33+
}
34+
35+
// poolWaitForExists waits for a storage pool to be up and timeout after 5 minutes.
36+
func poolWaitForExists(virConn *libvirt.Connect, uuid string) error {
37+
log.Printf("Waiting for pool %s to be active...", uuid)
38+
stateConf := &resource.StateChangeConf{
39+
Pending: []string{poolNotExistsID},
40+
Target: []string{poolExistsID},
41+
Refresh: poolExists(virConn, uuid),
42+
Timeout: 1 * time.Minute,
43+
Delay: 5 * time.Second,
44+
MinTimeout: 3 * time.Second,
45+
}
46+
47+
if _, err := stateConf.WaitForState(); err != nil {
48+
log.Printf("%s", err)
49+
return fmt.Errorf("unexpected error during pool creation operation. The operation did not complete successfully")
50+
}
51+
return nil
52+
}
53+
54+
// poolWaitDeleted waits for a storage pool to be removed
55+
func poolWaitDeleted(virConn *libvirt.Connect, uuid string) error {
56+
log.Printf("Waiting for pool %s to be deleted...", uuid)
57+
stateConf := &resource.StateChangeConf{
58+
Pending: []string{poolExistsID},
59+
Target: []string{poolNotExistsID},
60+
Refresh: poolExists(virConn, uuid),
61+
Timeout: 1 * time.Minute,
62+
Delay: 5 * time.Second,
63+
MinTimeout: 3 * time.Second,
64+
}
65+
66+
if _, err := stateConf.WaitForState(); err != nil {
67+
log.Printf("%s", err)
68+
return fmt.Errorf("unexpected error during pool destroy operation. The pool was not deleted")
69+
}
70+
return nil
71+
}
72+
73+
// deletePool deletes the pool identified by `uuid` from libvirt
74+
func deletePool(client *Client, uuid string) error {
75+
virConn := client.libvirt
76+
if virConn == nil {
77+
return fmt.Errorf(LibVirtConIsNil)
78+
}
79+
80+
pool, err := virConn.LookupStoragePoolByUUIDString(uuid)
81+
if err != nil {
82+
return fmt.Errorf("error retrieving storage pool info: %s", err)
83+
}
84+
85+
poolName, err := pool.GetName()
86+
if err != nil {
87+
return fmt.Errorf("error retrieving storage pool name: %s", err)
88+
}
89+
client.poolMutexKV.Lock(poolName)
90+
defer client.poolMutexKV.Unlock(poolName)
91+
92+
info, err := pool.GetInfo()
93+
if err != nil {
94+
return fmt.Errorf("error retrieving storage pool info: %s", err)
95+
}
96+
97+
if info.State != libvirt.STORAGE_POOL_INACTIVE {
98+
err := pool.Destroy()
99+
if err != nil {
100+
return fmt.Errorf("error deleting storage pool: %s", err)
101+
}
102+
}
103+
104+
err = pool.Delete(0)
105+
if err != nil {
106+
return fmt.Errorf("error deleting storage pool: %s", err)
107+
}
108+
109+
err = pool.Undefine()
110+
if err != nil {
111+
return fmt.Errorf("error deleting storage pool: %s", err)
112+
}
113+
114+
return poolWaitDeleted(client.libvirt, uuid)
115+
}

libvirt/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func Provider() terraform.ResourceProvider {
2323
"libvirt_domain": resourceLibvirtDomain(),
2424
"libvirt_volume": resourceLibvirtVolume(),
2525
"libvirt_network": resourceLibvirtNetwork(),
26+
"libvirt_pool": resourceLibvirtPool(),
2627
"libvirt_cloudinit_disk": resourceCloudInitDisk(),
2728
"libvirt_ignition": resourceIgnition(),
2829
},

0 commit comments

Comments
 (0)