aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Castelli <flavio@castelli.name>2017-05-26 12:23:43 +0200
committerGitHub <noreply@github.com>2017-05-26 12:23:43 +0200
commit686015805f14b93e7ef4d6d5a5655ab2b8154b79 (patch)
treede2acf4cfdbed6636a2c854bea452f6ff33a8aae
parent72fefb6fc13e75d850a6c67d572191e829ae2143 (diff)
parentf130f9848e61924bded600602a91822cf76e0959 (diff)
downloadterraform-provider-libvirt-686015805f14b93e7ef4d6d5a5655ab2b8154b79.tar
terraform-provider-libvirt-686015805f14b93e7ef4d6d5a5655ab2b8154b79.tar.gz
Merge pull request #107 from eamonnotoole/remote-ignition-temp-file-upstream
Write Ignition file as a volume in a libvirt storage pool
-rw-r--r--docs/providers/libvirt/r/coreos_ignition.html.markdown38
-rw-r--r--docs/providers/libvirt/r/domain.html.markdown14
-rw-r--r--libvirt/coreos_ignition_def.go202
-rw-r--r--libvirt/domain_def.go1
-rw-r--r--libvirt/provider.go1
-rw-r--r--libvirt/resource_libvirt_coreos_ignition.go95
-rw-r--r--libvirt/resource_libvirt_coreos_ignition_test.go113
-rw-r--r--libvirt/resource_libvirt_domain.go50
-rw-r--r--libvirt/resource_libvirt_domain_test.go49
9 files changed, 490 insertions, 73 deletions
diff --git a/docs/providers/libvirt/r/coreos_ignition.html.markdown b/docs/providers/libvirt/r/coreos_ignition.html.markdown
new file mode 100644
index 00000000..ae95e77b
--- /dev/null
+++ b/docs/providers/libvirt/r/coreos_ignition.html.markdown
@@ -0,0 +1,38 @@
+---
+layout: "libvirt"
+page_title: "Libvirt: libvirt_ignition"
+sidebar_current: "docs-libvirt-ignition"
+description: |-
+ Manages a CoreOS Ignition file to supply to a domain
+---
+
+# libvirt\_ignition
+
+Manages a [CoreOS Ignition](https://coreos.com/ignition/docs/latest/supported-platforms.html)
+file written as a volume to a libvirt storage pool that can be used to customize a CoreOS Domain during 1st
+boot.
+
+## Example Usage
+
+```
+resource "libvirt_ignition" "ignition" {
+ name = "example.ign"
+ content = <file-name or ignition object>
+}
+
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `name` - (Required) A unique name for the resource, required by libvirt.
+* `pool` - (Optional) The pool where the resource will be created.
+ If not given, the `default` pool will be used.
+* `content` - (Required) This points to the source of the Ignition configuration
+ information that will be used to create the Ignition file in the libvirt
+ storage pool. The `content` can be
+ * The name of file that contains Ignition configuration data, or its contents
+ * A rendered Terraform Ignition object
+
+Any change of the above fields will cause a new resource to be created.
diff --git a/docs/providers/libvirt/r/domain.html.markdown b/docs/providers/libvirt/r/domain.html.markdown
index af3d7247..a779a69b 100644
--- a/docs/providers/libvirt/r/domain.html.markdown
+++ b/docs/providers/libvirt/r/domain.html.markdown
@@ -41,10 +41,9 @@ The following arguments are supported:
cloud-init won't cause the domain to be recreated, however the change will
have effect on the next reboot.
-The following extra argument is provided for CoreOS images:
-
-* `coreos_ignition` - (Optional) This can be set to the name of an existing ignition
-file or alternatively can be set to the rendered value of a Terraform ignition provider object.
+There is an optional `coreos_ignition` parameter:
+* `coreos_ignition` (Optional) The `libvirt_ignition` resource that is to be used by
+ the CoreOS domain.
An example where a Terraform ignition provider object is used:
```
@@ -61,8 +60,13 @@ resource "ignition_config" "example" {
]
}
+resource "libvirt_ignition" "ignition" {
+ name = "ignition"
+ content = "${ignition_config.example.rendered}"
+}
+
resource "libvirt_domain" "my_machine" {
- coreos_ignition = "${ignition_config.example.rendered}"
+ coreos_ignition = "${libvirt_ignition.ignition.id}"
...
}
```
diff --git a/libvirt/coreos_ignition_def.go b/libvirt/coreos_ignition_def.go
new file mode 100644
index 00000000..216075f2
--- /dev/null
+++ b/libvirt/coreos_ignition_def.go
@@ -0,0 +1,202 @@
+package libvirt
+
+import (
+ "encoding/xml"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "strings"
+
+ libvirt "github.com/dmacvicar/libvirt-go"
+ "github.com/mitchellh/packer/common/uuid"
+)
+
+type defIgnition struct {
+ Name string
+ PoolName string
+ Content string
+}
+
+// Creates a new cloudinit with the defaults
+// the provider uses
+func newIgnitionDef() defIgnition {
+ ign := defIgnition{}
+
+ return ign
+}
+
+// Create a ISO file based on the contents of the CloudInit instance and
+// uploads it to the libVirt pool
+// Returns a string holding terraform's internal ID of this resource
+func (ign *defIgnition) CreateAndUpload(virConn *libvirt.VirConnection) (string, error) {
+ pool, err := virConn.LookupStoragePoolByName(ign.PoolName)
+ if err != nil {
+ return "", fmt.Errorf("can't find storage pool '%s'", ign.PoolName)
+ }
+ defer pool.Free()
+
+ PoolSync.AcquireLock(ign.PoolName)
+ defer PoolSync.ReleaseLock(ign.PoolName)
+
+ // Refresh the pool of the volume so that libvirt knows it is
+ // not longer in use.
+ WaitForSuccess("Error refreshing pool for volume", func() error {
+ return pool.Refresh(0)
+ })
+
+ volumeDef := newDefVolume()
+ volumeDef.Name = ign.Name
+
+ ignFile, err := ign.createFile()
+ if err != nil {
+ return "", err
+ }
+ defer func() {
+ // Remove the tmp ignition file
+ if err = os.Remove(ignFile); err != nil {
+ log.Printf("Error while removing tmp Ignition file: %s", err)
+ }
+ }()
+
+ img, err := newImage(ignFile)
+ if err != nil {
+ return "", err
+ }
+
+ size, err := img.Size()
+ if err != nil {
+ return "", err
+ }
+
+ volumeDef.Capacity.Unit = "B"
+ volumeDef.Capacity.Amount = size
+ volumeDef.Target.Format.Type = "raw"
+
+ volumeDefXml, err := xml.Marshal(volumeDef)
+ if err != nil {
+ return "", fmt.Errorf("Error serializing libvirt volume: %s", err)
+ }
+
+ // create the volume
+ volume, err := pool.StorageVolCreateXML(string(volumeDefXml), 0)
+ if err != nil {
+ return "", fmt.Errorf("Error creating libvirt volume for Ignition %s: %s", ign.Name, err)
+ }
+ defer volume.Free()
+
+ // upload ignition file
+ stream, err := libvirt.NewVirStream(virConn, 0)
+ if err != nil {
+ return "", err
+ }
+ defer stream.Close()
+
+ volume.Upload(stream, 0, uint64(volumeDef.Capacity.Amount), 0)
+ err = img.WriteToStream(stream)
+ if err != nil {
+ return "", err
+ }
+
+ key, err := volume.GetKey()
+ if err != nil {
+ return "", fmt.Errorf("Error retrieving volume key: %s", err)
+ }
+
+ return ign.buildTerraformKey(key), nil
+}
+
+// create a unique ID for terraform use
+// The ID is made by the volume ID (the internal one used by libvirt)
+// joined by the ";" with a UUID
+func (ign *defIgnition) buildTerraformKey(volumeKey string) string {
+ return fmt.Sprintf("%s;%s", volumeKey, uuid.TimeOrderedUUID())
+}
+
+func getIgnitionVolumeKeyFromTerraformID(id string) (string, error) {
+ s := strings.SplitN(id, ";", 2)
+ if len(s) != 2 {
+ return "", fmt.Errorf("%s is not a valid key", id)
+ }
+ return s[0], nil
+}
+
+
+// Dumps the Ignition object - either generated by Terraform or supplied as a file -
+// to a temporary ignition file
+func (ign *defIgnition) createFile() (string, error) {
+ log.Print("Creating Ignition temporary file")
+ tempFile, err := ioutil.TempFile("", ign.Name)
+ if err != nil {
+ return "", fmt.Errorf("Cannot create tmp file for Ignition: %s",
+ err)
+ }
+ defer tempFile.Close()
+
+ var file bool
+ file = true
+ if _, err := os.Stat(ign.Content); err != nil {
+ var js map[string]interface{}
+ if err_conf := json.Unmarshal([]byte(ign.Content), &js); err_conf != nil {
+ return "", fmt.Errorf("coreos_ignition 'content' is neither a file "+
+ "nor a valid json object %s", ign.Content)
+ }
+ file = false
+ }
+
+ if !file {
+ if _, err := tempFile.WriteString(ign.Content); err != nil {
+ return "", fmt.Errorf("Cannot write Ignition object to temporary "+
+ "ignition file")
+ }
+ } else if file {
+ ignFile, err := os.Open(ign.Content)
+ if err != nil {
+ return "", fmt.Errorf("Error opening supplied Ignition file %s", ign.Content)
+ }
+ defer ignFile.Close()
+ _, err = io.Copy(tempFile, ignFile)
+ if err != nil {
+ return "", fmt.Errorf("Error copying supplied Igition file to temporary file: %s", ign.Content)
+ }
+ }
+ return tempFile.Name(), nil
+}
+
+// Creates a new defIgnition object from provided id
+func newIgnitionDefFromRemoteVol(virConn *libvirt.VirConnection, id string) (defIgnition, error) {
+ ign := defIgnition{}
+
+ key, err := getIgnitionVolumeKeyFromTerraformID(id)
+ if err != nil {
+ return ign, err
+ }
+
+ volume, err := virConn.LookupStorageVolByKey(key)
+ if err != nil {
+ return ign, fmt.Errorf("Can't retrieve volume %s", key)
+ }
+ defer volume.Free()
+
+ ign.Name, err = volume.GetName()
+ if err != nil {
+ return ign, fmt.Errorf("Error retrieving volume name: %s", err)
+ }
+
+ volPool, err := volume.LookupPoolByVolume()
+ if err != nil {
+ return ign, fmt.Errorf("Error retrieving pool for volume: %s", err)
+ }
+ defer volPool.Free()
+
+ ign.PoolName, err = volPool.GetName()
+ if err != nil {
+ return ign, fmt.Errorf("Error retrieving pool name: %s", err)
+ }
+
+
+ return ign, nil
+}
+
diff --git a/libvirt/domain_def.go b/libvirt/domain_def.go
index 65425fd7..3ac2bedb 100644
--- a/libvirt/domain_def.go
+++ b/libvirt/domain_def.go
@@ -63,7 +63,6 @@ type defGraphics struct {
type defMetadata struct {
XMLName xml.Name `xml:"http://github.com/dmacvicar/terraform-provider-libvirt/ user_data"`
Xml string `xml:",cdata"`
- IgnitionFile string `xml:",ignition_file,omitempty"`
}
type defOs struct {
diff --git a/libvirt/provider.go b/libvirt/provider.go
index b0f86054..08a00435 100644
--- a/libvirt/provider.go
+++ b/libvirt/provider.go
@@ -21,6 +21,7 @@ func Provider() terraform.ResourceProvider {
"libvirt_volume": resourceLibvirtVolume(),
"libvirt_network": resourceLibvirtNetwork(),
"libvirt_cloudinit": resourceCloudInit(),
+ "libvirt_ignition": resourceIgnition(),
},
ConfigureFunc: providerConfigure,
diff --git a/libvirt/resource_libvirt_coreos_ignition.go b/libvirt/resource_libvirt_coreos_ignition.go
new file mode 100644
index 00000000..5bacc674
--- /dev/null
+++ b/libvirt/resource_libvirt_coreos_ignition.go
@@ -0,0 +1,95 @@
+package libvirt
+
+import (
+ "fmt"
+ "log"
+ "github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceIgnition() *schema.Resource {
+ return &schema.Resource{
+ Create: resourceIgnitionCreate,
+ Read: resourceIgnitionRead,
+ Delete: resourceIgnitionDelete,
+ Schema: map[string]*schema.Schema{
+ "name": &schema.Schema{
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ },
+ "pool": &schema.Schema{
+ Type: schema.TypeString,
+ Optional: true,
+ Default: "default",
+ ForceNew: true,
+ },
+ "content": &schema.Schema{
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ },
+ },
+ }
+}
+
+func resourceIgnitionCreate(d *schema.ResourceData, meta interface{}) error {
+ log.Printf("[DEBUG] creating ignition file")
+ virConn := meta.(*Client).libvirt
+ if virConn == nil {
+ return fmt.Errorf("The libvirt connection was nil.")
+ }
+
+ ignition := newIgnitionDef()
+
+ ignition.Name = d.Get("name").(string)
+ ignition.PoolName = d.Get("pool").(string)
+ ignition.Content = d.Get("content").(string)
+
+ log.Printf("[INFO] ignition: %+v", ignition)
+
+ key, err := ignition.CreateAndUpload(virConn)
+ if err != nil {
+ return err
+ }
+ d.SetId(key)
+
+ // make sure we record the id even if the rest of this gets interrupted
+ d.Partial(true) // make sure we record the id even if the rest of this gets interrupted
+ d.Set("id", key)
+ d.SetPartial("id")
+ // TODO: at this point we have collected more things than the ID, so let's save as many things as we can
+ d.Partial(false)
+
+ return resourceIgnitionRead(d, meta)
+}
+
+func resourceIgnitionRead(d *schema.ResourceData, meta interface{}) error {
+ virConn := meta.(*Client).libvirt
+ if virConn == nil {
+ return fmt.Errorf("The libvirt connection was nil.")
+ }
+
+ ign, err := newIgnitionDefFromRemoteVol(virConn, d.Id())
+ d.Set("pool", ign.PoolName)
+ d.Set("name", ign.Name)
+
+ if err != nil {
+ return fmt.Errorf("Error while retrieving remote volume: %s", err)
+ }
+
+ return nil
+}
+
+func resourceIgnitionDelete(d *schema.ResourceData, meta interface{}) error {
+ virConn := meta.(*Client).libvirt
+ if virConn == nil {
+ return fmt.Errorf("The libvirt connection was nil.")
+ }
+
+ key, err := getIgnitionVolumeKeyFromTerraformID(d.Id())
+ if err != nil {
+ return err
+ }
+
+ return RemoveVolume(virConn, key)
+}
diff --git a/libvirt/resource_libvirt_coreos_ignition_test.go b/libvirt/resource_libvirt_coreos_ignition_test.go
new file mode 100644
index 00000000..cbd5fe0e
--- /dev/null
+++ b/libvirt/resource_libvirt_coreos_ignition_test.go
@@ -0,0 +1,113 @@
+package libvirt
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform/helper/resource"
+ "github.com/hashicorp/terraform/terraform"
+ libvirt "github.com/dmacvicar/libvirt-go"
+)
+
+func TestAccLibvirtIgnition_Basic(t *testing.T) {
+ var volume libvirt.VirStorageVol
+ var config = fmt.Sprintf(`
+ resource "ignition_systemd_unit" "acceptance-test-systemd" {
+ name = "example.service"
+ content = "[Service]\nType=oneshot\nExecStart=/usr/bin/echo Hello World\n\n[Install]\nWantedBy=multi-user.target"
+ }
+
+ resource "ignition_config" "acceptance-test-config" {
+ systemd = [
+ "${ignition_systemd_unit.acceptance-test-systemd.id}",
+ ]
+ }
+
+ resource "libvirt_ignition" "ignition" {
+ name = "ignition"
+ content = "${ignition_config.acceptance-test-config.rendered}"
+ }
+ `)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckLibvirtIgnitionDestroy,
+ Steps: []resource.TestStep{
+ {
+ Config: config,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckIgnitionVolumeExists("libvirt_ignition.ignition", &volume),
+ resource.TestCheckResourceAttr(
+ "libvirt_ignition.ignition", "name", "ignition"),
+ resource.TestCheckResourceAttr(
+ "libvirt_ignition.ignition", "pool", "default"),
+ ),
+ },
+ },
+ })
+}
+
+func testAccCheckIgnitionVolumeExists(n string, volume *libvirt.VirStorageVol) resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ virConn := testAccProvider.Meta().(*Client).libvirt
+
+ rs, ok := s.RootModule().Resources[n]
+ if !ok {
+ return fmt.Errorf("Not found: %s", n)
+ }
+
+ if rs.Primary.ID == "" {
+ return fmt.Errorf("No libvirt ignition key ID is set")
+ }
+
+ ignKey, err := getIgnitionVolumeKeyFromTerraformID(rs.Primary.ID)
+ if err != nil {
+ return err
+ }
+
+ retrievedVol, err := virConn.LookupStorageVolByKey(ignKey)
+ if err != nil {
+ return err
+ }
+ fmt.Printf("The ID is %s", rs.Primary.ID)
+
+ realId, err := retrievedVol.GetKey()
+ if err != nil {
+ return err
+ }
+
+ if realId != ignKey {
+ return fmt.Errorf("Resource ID and volume key does not match")
+ }
+
+ *volume = retrievedVol
+ return nil
+ }
+}
+
+func testAccCheckLibvirtIgnitionDestroy(s *terraform.State) error {
+ virtConn := testAccProvider.Meta().(*Client).libvirt
+
+ for _, rs := range s.RootModule().Resources {
+ if rs.Type != "libvirt_ignition" {
+ continue
+ }
+
+ // Try to find the Ignition Volume
+
+ ignKey, errKey := getIgnitionVolumeKeyFromTerraformID(rs.Primary.ID)
+ if errKey != nil {
+ return errKey
+ }
+
+ _, err := virtConn.LookupStorageVolByKey(ignKey)
+ if err == nil {
+ return fmt.Errorf(
+ "Error waiting for IgnitionVolume (%s) to be destroyed: %s",
+ ignKey, err)
+ }
+ }
+
+ return nil
+} \ No newline at end of file
diff --git a/libvirt/resource_libvirt_domain.go b/libvirt/resource_libvirt_domain.go
index 1ac3cc86..170946c1 100644
--- a/libvirt/resource_libvirt_domain.go
+++ b/libvirt/resource_libvirt_domain.go
@@ -1,10 +1,9 @@
package libvirt
import (
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
"encoding/xml"
+ "encoding/hex"
+ "crypto/sha256"
"fmt"
"log"
"net"
@@ -83,9 +82,8 @@ func resourceLibvirtDomain() *schema.Resource {
},
"coreos_ignition": &schema.Schema{
Type: schema.TypeString,
- Required: false,
Optional: true,
- ForceNew: false,
+ ForceNew: true,
Default: "",
},
"disk": &schema.Schema{
@@ -153,38 +151,12 @@ func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error
}
if ignition, ok := d.GetOk("coreos_ignition"); ok {
- var file bool
- file = true
- ignitionString := ignition.(string)
- if _, err := os.Stat(ignitionString); err != nil {
- var js map[string]interface{}
- if err_conf := json.Unmarshal([]byte(ignitionString), &js); err_conf != nil {
- return fmt.Errorf("coreos_ignition parameter is neither a file "+
- "nor a valid json object %s", ignition)
- }
- log.Printf("[DEBUG] about to set file to false")
- file = false
- }
- log.Printf("[DEBUG] file %s", file)
var fw_cfg []defCmd
- var ign_str string
- if !file {
- ignitionHash := hash(ignitionString)
- tempFileName := fmt.Sprint("/tmp/", ignitionHash, ".ign")
- tempFile, err := os.Create(tempFileName)
- defer tempFile.Close()
- if err != nil {
- return fmt.Errorf("Cannot create temporary ignition file %s", tempFileName)
- }
- if _, err := tempFile.WriteString(ignitionString); err != nil {
- return fmt.Errorf("Cannot write Ignition object to temporary "+
- "ignition file %s", tempFileName)
- }
- domainDef.Metadata.TerraformLibvirt.IgnitionFile = tempFileName
- ign_str = fmt.Sprintf("name=opt/com.coreos/config,file=%s", tempFileName)
- } else if file {
- ign_str = fmt.Sprintf("name=opt/com.coreos/config,file=%s", ignitionString)
+ ignitionKey, err := getIgnitionVolumeKeyFromTerraformID(ignition.(string))
+ if err != nil {
+ return err
}
+ ign_str := fmt.Sprintf("name=opt/com.coreos/config,file=%s", ignitionKey)
fw_cfg = append(fw_cfg, defCmd{"-fw_cfg"})
fw_cfg = append(fw_cfg, defCmd{ign_str})
domainDef.CmdLine.Cmd = fw_cfg
@@ -828,14 +800,6 @@ func resourceLibvirtDomainDelete(d *schema.ResourceData, meta interface{}) error
return fmt.Errorf("Error reading libvirt domain XML description: %s", err)
}
- if ignitionFile := domainDef.Metadata.TerraformLibvirt.IgnitionFile; ignitionFile != "" {
- log.Printf("[DEBUG] deleting ignition file")
- err = os.Remove(ignitionFile)
- if err != nil && !os.IsNotExist(err) {
- return fmt.Errorf("Error removing Ignition file %s: %s", ignitionFile, err)
- }
- }
-
state, err := domain.GetState()
if err != nil {
return fmt.Errorf("Couldn't get info about domain: %s", err)
diff --git a/libvirt/resource_libvirt_domain_test.go b/libvirt/resource_libvirt_domain_test.go
index 44606e16..4e584c5a 100644
--- a/libvirt/resource_libvirt_domain_test.go
+++ b/libvirt/resource_libvirt_domain_test.go
@@ -1,11 +1,11 @@
package libvirt
import (
- "encoding/xml"
"fmt"
"log"
"testing"
+ "encoding/xml"
libvirt "github.com/dmacvicar/libvirt-go"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
@@ -281,6 +281,7 @@ func TestAccLibvirtDomain_Graphics(t *testing.T) {
func TestAccLibvirtDomain_IgnitionObject(t *testing.T) {
var domain libvirt.VirDomain
+ var volume libvirt.VirStorageVol
var config = fmt.Sprintf(`
resource "ignition_systemd_unit" "acceptance-test-systemd" {
@@ -294,9 +295,14 @@ func TestAccLibvirtDomain_IgnitionObject(t *testing.T) {
]
}
+ resource "libvirt_ignition" "ignition" {
+ name = "ignition"
+ content = "${ignition_config.acceptance-test-config.rendered}"
+ }
+
resource "libvirt_domain" "acceptance-test-domain" {
name = "terraform-test-domain"
- coreos_ignition = "${ignition_config.acceptance-test-config.rendered}"
+ coreos_ignition = "${libvirt_ignition.ignition.id}"
}
`)
@@ -305,12 +311,12 @@ func TestAccLibvirtDomain_IgnitionObject(t *testing.T) {
Providers: testAccProviders,
CheckDestroy: testAccCheckLibvirtDomainDestroy,
Steps: []resource.TestStep{
- resource.TestStep{
- Config: config,
- ExpectNonEmptyPlan: true,
+ {
+ Config: config,
Check: resource.ComposeTestCheckFunc(
testAccCheckLibvirtDomainExists("libvirt_domain.acceptance-test-domain", &domain),
- testAccCheckIgnitionFileNameExists(&domain),
+ testAccCheckIgnitionVolumeExists("libvirt_ignition.ignition", &volume),
+ testAccCheckIgnitionXML(&domain, &volume),
),
},
},
@@ -373,36 +379,31 @@ func testAccCheckLibvirtDomainExists(n string, domain *libvirt.VirDomain) resour
}
}
-func testAccCheckIgnitionFileNameExists(domain *libvirt.VirDomain) resource.TestCheckFunc {
+func testAccCheckIgnitionXML(domain *libvirt.VirDomain, volume *libvirt.VirStorageVol) resource.TestCheckFunc {
return func(s *terraform.State) error {
- var ignStr string
- for _, rs := range s.RootModule().Resources {
- if rs.Type != "libvirt_domain" {
- continue
- }
- ignStr = rs.Primary.Attributes["coreos_ignition"]
- }
-
+ var cmdLine []defCmd
xmlDesc, err := domain.GetXMLDesc(0)
if err != nil {
return fmt.Errorf("Error retrieving libvirt domain XML description: %s", err)
}
+ ignitionKey, err := volume.GetKey()
+ if err != nil {
+ return err
+ }
+ ignStr := fmt.Sprintf("name=opt/com.coreos/config,file=%s", ignitionKey)
+
domainDef := newDomainDef()
err = xml.Unmarshal([]byte(xmlDesc), &domainDef)
if err != nil {
return fmt.Errorf("Error reading libvirt domain XML description: %s", err)
}
- ignitionFile := domainDef.Metadata.TerraformLibvirt.IgnitionFile
- if ignitionFile == "" {
- return fmt.Errorf("No ignition file meta-data")
- }
-
- hashStr := hash(ignStr)
- hashFile := fmt.Sprint("/tmp/", hashStr, ".ign")
- if ignitionFile != hashFile {
- return fmt.Errorf("Igntion file metadata incorrect %s %s", ignitionFile, hashFile)
+ cmdLine = domainDef.CmdLine.Cmd
+ for i, cmd := range cmdLine {
+ if i == 1 && cmd.Value != ignStr {
+ return fmt.Errorf("libvirt domain fw_cfg XML is incorrect %s", cmd.Value)
+ }
}
return nil
}