summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/providers/libvirt/r/domain.html.markdown24
-rw-r--r--libvirt/domain_def.go6
-rw-r--r--libvirt/provider_test.go2
-rw-r--r--libvirt/resource_libvirt_domain.go67
-rw-r--r--libvirt/resource_libvirt_domain_test.go74
-rw-r--r--vendor.yml2
6 files changed, 165 insertions, 10 deletions
diff --git a/docs/providers/libvirt/r/domain.html.markdown b/docs/providers/libvirt/r/domain.html.markdown
index 995420da..b9a5500e 100644
--- a/docs/providers/libvirt/r/domain.html.markdown
+++ b/docs/providers/libvirt/r/domain.html.markdown
@@ -43,7 +43,29 @@ The following arguments are supported:
The following extra argument is provided for CoreOS images:
-* `coreos_ignition` - (Optional) The name of a CoreOS Ignition file.
+* `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.
+
+An example where a Terraform ignition provider object is used:
+```
+# Systemd unit resource containing the unit definition
+resource "ignition_systemd_unit" "example" {
+ name = "example.service"
+ content = "[Service]\nType=oneshot\nExecStart=/usr/bin/echo Hello World\n\n[Install]\nWantedBy=multi-user.target"
+}
+
+# Ignition config include the previous defined systemd unit resource
+resource "ignition_config" "example" {
+ systemd = [
+ "${ignition_systemd_unit.example.id}",
+ ]
+}
+
+resource "libvirt_domain" "my_machine" {
+ coreos_ignition = "${ignition_config.example.rendered}"
+ ...
+}
+```
Note that to make use of Ignition files with CoreOS the host must be running
QEMU v2.6 or greater.
diff --git a/libvirt/domain_def.go b/libvirt/domain_def.go
index e6952d79..46dadaaf 100644
--- a/libvirt/domain_def.go
+++ b/libvirt/domain_def.go
@@ -57,8 +57,9 @@ type defDomain struct {
}
type defMetadata struct {
- XMLName xml.Name `xml:"http://github.com/dmacvicar/terraform-provider-libvirt/ user_data"`
- Xml string `xml:",cdata"`
+ 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 {
@@ -143,3 +144,4 @@ func newDomainDef() defDomain {
return domainDef
}
+
diff --git a/libvirt/provider_test.go b/libvirt/provider_test.go
index 662b1185..c130f86b 100644
--- a/libvirt/provider_test.go
+++ b/libvirt/provider_test.go
@@ -6,6 +6,7 @@ import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
+ ignition "github.com/hashicorp/terraform/builtin/providers/ignition"
)
var testAccProviders map[string]terraform.ResourceProvider
@@ -15,6 +16,7 @@ func init() {
testAccProvider = Provider().(*schema.Provider)
testAccProviders = map[string]terraform.ResourceProvider{
"libvirt": testAccProvider,
+ "ignition": ignition.Provider(),
}
}
diff --git a/libvirt/resource_libvirt_domain.go b/libvirt/resource_libvirt_domain.go
index 26a121ff..00bbaf19 100644
--- a/libvirt/resource_libvirt_domain.go
+++ b/libvirt/resource_libvirt_domain.go
@@ -1,6 +1,7 @@
package libvirt
import (
+ "encoding/json"
"encoding/xml"
"fmt"
"log"
@@ -9,6 +10,8 @@ import (
"strings"
"time"
+ "crypto/sha256"
+ "encoding/hex"
"github.com/davecgh/go-spew/spew"
libvirt "github.com/dmacvicar/libvirt-go"
"github.com/hashicorp/terraform/helper/schema"
@@ -20,6 +23,11 @@ func init() {
spew.Config.Indent = "\t"
}
+func hash(s string) string {
+ sha := sha256.Sum256([]byte(s))
+ return hex.EncodeToString(sha[:])
+}
+
func resourceLibvirtDomain() *schema.Resource {
return &schema.Resource{
Create: resourceLibvirtDomainCreate,
@@ -145,12 +153,38 @@ func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error
}
if ignition, ok := d.GetOk("coreos_ignition"); ok {
- ignitionFile := ignition.(string)
- if _, err := os.Stat(ignitionFile); os.IsNotExist(err) {
- return fmt.Errorf("Could not find ignition file '%s'", ignitionFile)
+ 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
- ign_str := fmt.Sprintf("name=opt/com.coreos/config,file=%s", ignitionFile)
+ 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)
+ }
fw_cfg = append(fw_cfg, defCmd{"-fw_cfg"})
fw_cfg = append(fw_cfg, defCmd{ign_str})
domainDef.CmdLine.Cmd = fw_cfg
@@ -197,12 +231,14 @@ func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error
if consoleCount, ok := d.GetOk("console.#"); ok {
var consoles []defConsole
- for i :=0; i < consoleCount.(int); i++ {
+ for i := 0; i < consoleCount.(int); i++ {
console := defConsole{}
consolePrefix := fmt.Sprintf("console.%d", i)
console.Type = d.Get(consolePrefix + ".type").(string)
- console.Source.Path = d.Get(consolePrefix + ".source_path").(string)
console.Target.Port = d.Get(consolePrefix + ".target_port").(string)
+ if source_path, ok := d.GetOk(consolePrefix + ".source_path"); ok {
+ console.Source.Path = source_path.(string)
+ }
if target_type, ok := d.GetOk(consolePrefix + ".target_type"); ok {
console.Target.Type = target_type.(string)
}
@@ -756,6 +792,25 @@ func resourceLibvirtDomainDelete(d *schema.ResourceData, meta interface{}) error
}
defer domain.Free()
+ xmlDesc, err := domain.GetXMLDesc(0)
+ if err != nil {
+ return fmt.Errorf("Error retrieving libvirt domain XML description: %s", err)
+ }
+
+ domainDef := newDomainDef()
+ err = xml.Unmarshal([]byte(xmlDesc), &domainDef)
+ if err != nil {
+ 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 73feefe5..6749283c 100644
--- a/libvirt/resource_libvirt_domain_test.go
+++ b/libvirt/resource_libvirt_domain_test.go
@@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
//"gopkg.in/alexzorin/libvirt-go.v2"
+ "encoding/xml"
libvirt "github.com/dmacvicar/libvirt-go"
)
@@ -208,6 +209,44 @@ func TestAccLibvirtDomain_NetworkInterface(t *testing.T) {
})
}
+func TestAccLibvirtDomain_IgnitionObject(t *testing.T) {
+ var domain libvirt.VirDomain
+
+ 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_domain" "acceptance-test-domain" {
+ name = "terraform-test-domain"
+ coreos_ignition = "${ignition_config.acceptance-test-config.rendered}"
+ }
+ `)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckLibvirtDomainDestroy,
+ Steps: []resource.TestStep{
+ resource.TestStep{
+ Config: config,
+ ExpectNonEmptyPlan: true,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckLibvirtDomainExists("libvirt_domain.acceptance-test-domain", &domain),
+ testAccCheckIgnitionFileNameExists(&domain),
+ ),
+ },
+ },
+ })
+}
+
func testAccCheckLibvirtDomainDestroy(s *terraform.State) error {
virtConn := testAccProvider.Meta().(*Client).libvirt
@@ -263,3 +302,38 @@ func testAccCheckLibvirtDomainExists(n string, domain *libvirt.VirDomain) resour
return nil
}
}
+
+func testAccCheckIgnitionFileNameExists(domain *libvirt.VirDomain) 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"]
+ }
+
+ xmlDesc, err := domain.GetXMLDesc(0)
+ if err != nil {
+ return fmt.Errorf("Error retrieving libvirt domain XML description: %s", err)
+ }
+
+ 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)
+ }
+ return nil
+ }
+}
diff --git a/vendor.yml b/vendor.yml
index bdbfadde..ba42a8d1 100644
--- a/vendor.yml
+++ b/vendor.yml
@@ -23,7 +23,7 @@ vendors:
- path: github.com/hashicorp/logutils
rev: 0dc08b1671f34c4250ce212759ebd880f743d883
- path: github.com/hashicorp/terraform
- rev: v0.8.0
+ rev: v0.8.5
- path: github.com/hooklift/assert
rev: c7786599453421cddf9aa8a3a7b537f567d1ac1b
- path: github.com/hooklift/iso9660