aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ. Eduardo <j.eduardo@gmail.com>2017-07-31 22:16:24 +0200
committerFlavio Castelli <flavio@castelli.me>2017-08-01 09:11:49 +0200
commit968bf16201a9f13030f84765b027d7e45fdbef57 (patch)
tree2f581ce06f099681af4550c25593365428b06b21
parent78341e5971cac8f23e7c36321180a71ee6816131 (diff)
downloadterraform-provider-libvirt-968bf16201a9f13030f84765b027d7e45fdbef57.tar
terraform-provider-libvirt-968bf16201a9f13030f84765b027d7e45fdbef57.tar.gz
Added support for specifying NVRAM templates when using UEFI images.
-rw-r--r--examples/uefi/libvirt.tf38
-rw-r--r--libvirt/resource_libvirt_domain.go29
-rw-r--r--libvirt/resource_libvirt_domain_test.go96
-rwxr-xr-xtravis/setup-guest2
-rw-r--r--website/docs/r/domain.html.markdown53
5 files changed, 202 insertions, 16 deletions
diff --git a/examples/uefi/libvirt.tf b/examples/uefi/libvirt.tf
new file mode 100644
index 00000000..1419806f
--- /dev/null
+++ b/examples/uefi/libvirt.tf
@@ -0,0 +1,38 @@
+provider "libvirt" {
+ uri = "qemu:///system"
+}
+
+resource "libvirt_volume" "ubuntu-cloud-uefi" {
+ name = "ubuntu-cloud-uefi"
+ source = "https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-uefi1.img"
+}
+
+resource "libvirt_volume" "volume" {
+ name = "vm${count.index}"
+ base_volume_id = "${libvirt_volume.ubuntu-cloud-uefi.id}"
+ count = 1
+}
+
+resource "libvirt_domain" "domain" {
+ count = 2
+ name = "ubuntu-cloud-${count.index}"
+ memory = "512"
+ vcpu = 1
+ # This file is usually present as part of the ovmf firmware package in many
+ # Linux distributions.
+ firmware = "/usr/share/OVMF/OVMF_CODE.fd"
+ nvram {
+ # This is the file which will back the UEFI NVRAM content.
+ file = "/var/lib/libvirt/qemu/nvram/vm${count.index}_VARS.fd"
+ # This file needs to be provided by the user.
+ template = "/srv/provisioning/terraform/debian-stable-uefi_VARS.fd"
+ }
+ disk {
+ volume_id = "${element(libvirt_volume.volume.*.id, count.index)}"
+ }
+ graphics {
+ type = "spice"
+ listen_type = "address"
+ autoport = true
+ }
+
diff --git a/libvirt/resource_libvirt_domain.go b/libvirt/resource_libvirt_domain.go
index 66b6a122..844b6cf7 100644
--- a/libvirt/resource_libvirt_domain.go
+++ b/libvirt/resource_libvirt_domain.go
@@ -75,7 +75,7 @@ func resourceLibvirtDomain() *schema.Resource {
ForceNew: true,
},
"nvram": &schema.Schema{
- Type: schema.TypeString,
+ Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
@@ -244,21 +244,30 @@ func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error
if _, err := os.Stat(firmwareFile); os.IsNotExist(err) {
return fmt.Errorf("Could not find firmware file '%s'.", firmwareFile)
}
- domainDef.OS = &libvirtxml.DomainOS{
- Loader: &libvirtxml.DomainLoader{
- Path: firmwareFile,
- Readonly: "yes",
- Type: "pflash",
- },
+ domainDef.OS.Loader = &libvirtxml.DomainLoader{
+ Path: firmwareFile,
+ Readonly: "yes",
+ Type: "pflash",
+ Secure: "no",
}
if nvram, ok := d.GetOk("nvram"); ok {
- nvramFile := nvram.(string)
+ nvram_map := nvram.(map[string]interface{})
+
+ nvramFile := nvram_map["file"].(string)
if _, err := os.Stat(nvramFile); os.IsNotExist(err) {
return fmt.Errorf("Could not find nvram file '%s'.", nvramFile)
}
+ nvramTemplateFile := ""
+ if nvram_template, ok := nvram_map["template"]; ok {
+ nvramTemplateFile = nvram_template.(string)
+ if _, err := os.Stat(nvramTemplateFile); os.IsNotExist(err) {
+ return fmt.Errorf("Could not find nvram template file '%s'.", nvramTemplateFile)
+ }
+ }
domainDef.OS.NVRam = &libvirtxml.DomainNVRam{
- NVRam: nvramFile,
+ NVRam: nvramFile,
+ Template: nvramTemplateFile,
}
}
}
@@ -768,7 +777,7 @@ func resourceLibvirtDomainRead(d *schema.ResourceData, meta interface{}) error {
}
d.Set("name", domainDef.Name)
- d.Set("vpu", domainDef.VCPU)
+ d.Set("vcpu", domainDef.VCPU)
d.Set("memory", domainDef.Memory)
d.Set("firmware", domainDef.OS.Loader)
d.Set("nvram", domainDef.OS.NVRam)
diff --git a/libvirt/resource_libvirt_domain_test.go b/libvirt/resource_libvirt_domain_test.go
index 1410b639..e4d2f542 100644
--- a/libvirt/resource_libvirt_domain_test.go
+++ b/libvirt/resource_libvirt_domain_test.go
@@ -3,6 +3,7 @@ package libvirt
import (
"encoding/xml"
"fmt"
+ "io/ioutil"
"log"
"testing"
@@ -587,3 +588,98 @@ func testAccCheckLibvirtScsiDisk(n string, domain *libvirt.Domain) resource.Test
return nil
}
}
+
+func createNvramFile() (string, error) {
+ // size of an accepted, valid, nvram backing store
+ nvram_dummy_buffer := make([]byte, 131072)
+ file, err := ioutil.TempFile("/tmp", "nvram")
+ if err != nil {
+ return "", err
+ }
+ file.Chmod(0777)
+ _, err = file.Write(nvram_dummy_buffer)
+ if err != nil {
+ return "", err
+ }
+ if file.Close() != nil {
+ return "", err
+ }
+ return file.Name(), nil
+}
+
+func TestAccLibvirtDomain_FirmwareNoTemplate(t *testing.T) {
+ nvram_path, err := createNvramFile()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var domain libvirt.Domain
+ var config = fmt.Sprintf(`
+ resource "libvirt_domain" "acceptance-test-domain" {
+ name = "terraform-test-firmware-no-template"
+ firmware = "/usr/share/ovmf/OVMF.fd"
+ nvram {
+ file = "%s"
+ }
+ }`, nvram_path)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckLibvirtDomainDestroy,
+ Steps: []resource.TestStep{
+ resource.TestStep{
+ Config: config,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckLibvirtDomainExists("libvirt_domain.acceptance-test-domain", &domain),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "name", "terraform-test-firmware-no-template"),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "nvram.file", nvram_path),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "firmware", "/usr/share/ovmf/OVMF.fd"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccLibvirtDomain_FirmwareTemplate(t *testing.T) {
+ nvram_path, err := createNvramFile()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var domain libvirt.Domain
+ var config = fmt.Sprintf(`
+ resource "libvirt_domain" "acceptance-test-domain" {
+ name = "terraform-test-firmware-with-template"
+ firmware = "/usr/share/ovmf/OVMF.fd"
+ nvram {
+ file = "%s"
+ template = "/usr/share/qemu/OVMF.fd"
+ }
+ }`, nvram_path)
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ CheckDestroy: testAccCheckLibvirtDomainDestroy,
+ Steps: []resource.TestStep{
+ resource.TestStep{
+ Config: config,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckLibvirtDomainExists("libvirt_domain.acceptance-test-domain", &domain),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "name", "terraform-test-firmware-with-template"),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "nvram.file", nvram_path),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "nvram.template", "/usr/share/qemu/OVMF.fd"),
+ resource.TestCheckResourceAttr(
+ "libvirt_domain.acceptance-test-domain", "firmware", "/usr/share/ovmf/OVMF.fd"),
+ ),
+ },
+ },
+ })
+}
diff --git a/travis/setup-guest b/travis/setup-guest
index 43b87853..e5f982a5 100755
--- a/travis/setup-guest
+++ b/travis/setup-guest
@@ -13,7 +13,7 @@ while check_network ; [ $? -ne 0 ];do
done
apt-get -qq update
-apt-get install -y qemu libvirt-bin libvirt-dev golang-1.8
+apt-get install -y qemu libvirt-bin libvirt-dev golang-1.8 ovmf
echo -e "<pool type='dir'>\n<name>default</name>\n<target>\n<path>/pool-default</path>\n</target>\n</pool>" > pool.xml
mkdir /pool-default
chmod a+rwx /pool-default
diff --git a/website/docs/r/domain.html.markdown b/website/docs/r/domain.html.markdown
index 6c40cb10..bdb71077 100644
--- a/website/docs/r/domain.html.markdown
+++ b/website/docs/r/domain.html.markdown
@@ -59,11 +59,14 @@ Some extra arguments are also provided for using UEFI images:
environment. Users should usually specify one of the standard _Open Virtual Machine
Firmware_ (_OVMF_) images available for their distributions. The file will be opened
read-only.
-* `nvram` - (Optional) the _nvram_ variables file corresponding to the firmware. When provided,
-this file must be writable and specific to this domain, as it will be updated when running
-the domain. However, `libvirt` can manage this automatically (and this is the recommended solution)
-if a mapping for the firmware to a _variables file_ exists in `/etc/libvirt/qemu.conf:nvram`.
-In that case, `libvirt` will copy that variables file into a file specific for this domain.
+* `nvram` - (Optional) this block allows specifying the following attributes related to the _nvram_:
+ * `file` - path to the file backing the NVRAM store for non-volatile variables. When provided,
+ this file must be writable and specific to this domain, as it will be updated when running the
+ domain. However, `libvirt` can manage this automatically (and this is the recommended solution)
+ if a mapping for the firmware to a _variables file_ exists in `/etc/libvirt/qemu.conf:nvram`.
+ In that case, `libvirt` will copy that variables file into a file specific for this domain.
+ * `template` - (Optional) path to the file used to override variables from the master NVRAM
+ store.
So you should typically use the firmware as this,
@@ -88,6 +91,46 @@ nvram = [
]
```
+In case you need (or want) to specify the path for the NVRAM store, the domain definition should
+look like this:
+
+```hcl
+resource "libvirt_domain" "my_machine" {
+ name = "my_machine"
+ firmware = "/usr/share/qemu/ovmf-x86_64-code.bin"
+ nvram {
+ file = "/usr/local/share/qemu/custom-vars.bin"
+ }
+ memory = "2048"
+
+ disk {
+ volume_id = "${libvirt_volume.volume.id}"
+ }
+ ...
+}
+
+```
+
+Finally, if you want the initial values for the NVRAM to be overridden by custom initial values
+coming from a template, the domain definition should look like this:
+
+```hcl
+resource "libvirt_domain" "my_machine" {
+ name = "my_machine"
+ firmware = "/usr/share/qemu/ovmf-x86_64-code.bin"
+ nvram {
+ file = "/usr/local/share/qemu/custom-vars.bin"
+ template = "/usr/local/share/qemu/template-vars.bin"
+ }
+ memory = "2048"
+
+ disk {
+ volume_id = "${libvirt_volume.volume.id}"
+ }
+ ...
+}
+```
+
### Handling disks
The `disk` block supports: