diff options
-rw-r--r-- | libvirt/resource_libvirt_domain.go | 39 | ||||
-rw-r--r-- | libvirt/resource_libvirt_domain_test.go | 60 | ||||
-rw-r--r-- | website/docs/r/domain.html.markdown | 95 |
3 files changed, 193 insertions, 1 deletions
diff --git a/libvirt/resource_libvirt_domain.go b/libvirt/resource_libvirt_domain.go index a3b16792..81cc2d70 100644 --- a/libvirt/resource_libvirt_domain.go +++ b/libvirt/resource_libvirt_domain.go @@ -170,6 +170,27 @@ func resourceLibvirtDomain() *schema.Resource { Default: "/usr/bin/qemu-system-x86_64", Optional: true, }, + "kernel": &schema.Schema{ + Type: schema.TypeString, + Required: false, + Optional: true, + ForceNew: false, + }, + "initrd": &schema.Schema{ + Type: schema.TypeString, + Required: false, + Optional: true, + ForceNew: false, + }, + "cmdline": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Required: false, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeMap, + }, + }, }, } } @@ -267,6 +288,24 @@ func resourceLibvirtDomainCreate(d *schema.ResourceData, meta interface{}) error } } + if kernel, ok := d.GetOk("kernel"); ok { + domainDef.OS.Kernel = kernel.(string) + } + if initrd, ok := d.GetOk("initrd"); ok { + domainDef.OS.Initrd = initrd.(string) + } + + cmdlinesCount := d.Get("cmdline.#").(int) + cmdlineArgs := make([]string, 0) + for i := 0; i < cmdlinesCount; i++ { + cmdlineKey := fmt.Sprintf("cmdline.%d", i) + cmdlineMap := d.Get(cmdlineKey).(map[string]interface{}) + for k, v := range cmdlineMap { + cmdlineArgs = append(cmdlineArgs, fmt.Sprintf("%s=%v", k, v)) + } + } + domainDef.OS.KernelArgs = strings.Join(cmdlineArgs, " ") + if cpu, ok := d.GetOk("cpu"); ok { cpuMap := cpu.(map[string]interface{}) if cpuMode, ok := cpuMap["mode"]; ok { diff --git a/libvirt/resource_libvirt_domain_test.go b/libvirt/resource_libvirt_domain_test.go index 2c9f1b52..29e01095 100644 --- a/libvirt/resource_libvirt_domain_test.go +++ b/libvirt/resource_libvirt_domain_test.go @@ -235,6 +235,40 @@ func TestAccLibvirtDomainURLDisk(t *testing.T) { } +func TestAccLibvirtDomainKernelInitrdCmdline(t *testing.T) { + var domain libvirt.Domain + + var config = fmt.Sprintf(` + resource "libvirt_domain" "acceptance-test-domain" { + name = "terraform-test-domain" + kernel = "/boot/vmlinuz" + initrd = "/boot/initrd" + cmdline { + foo = 1 + bar = "bye" + } + cmdline { + foo = 2 + } + }`) + + 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), + testAccCheckLibvirtDomainKernelInitrdCmdline(&domain), + ), + }, + }, + }) + +} + func TestAccLibvirtDomain_NetworkInterface(t *testing.T) { var domain libvirt.Domain @@ -658,6 +692,32 @@ func testAccCheckLibvirtURLDisk(u *url.URL, domain *libvirt.Domain) resource.Tes } } +func testAccCheckLibvirtDomainKernelInitrdCmdline(domain *libvirt.Domain) resource.TestCheckFunc { + return func(s *terraform.State) error { + 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 domainDef.OS.Kernel != "/boot/vmlinuz" { + return fmt.Errorf("Kernel is not set correctly") + } + if domainDef.OS.Initrd != "/boot/initrd" { + return fmt.Errorf("Initrd is not set correctly") + } + if domainDef.OS.KernelArgs != "bar=bye foo=1 foo=2" { + return fmt.Errorf("Kernel args not set correctly") + } + return nil + } +} + func createNvramFile() (string, error) { // size of an accepted, valid, nvram backing store NVRAMDummyBuffer := make([]byte, 131072) diff --git a/website/docs/r/domain.html.markdown b/website/docs/r/domain.html.markdown index b047a6e7..a1e60fcb 100644 --- a/website/docs/r/domain.html.markdown +++ b/website/docs/r/domain.html.markdown @@ -59,6 +59,99 @@ The following arguments are supported: [below](#define-boot-device-order). * `emulator` - (Optional) The path of the emulator to use +### Kernel and boot arguments + +* `kernel` - (Optional) The path of the kernel to boot + +If you are using a qcow2 volume, you can pass the id of the volume (eg. `${libvirt_volume.kernel.id}`) +as they are local to the hypervisor. + +Given that you can define a volume from a remote http file, this means, you can also have remote kernels. + +```hcl +resource "libvirt_volume" "kernel" { + source = "http://download.opensuse.org/tumbleweed/repo/oss/boot/x86_64/loader/linux" + name = "kernel" + pool = "default" + format = "raw" +} + +resource "libvirt_domain" "domain-suse" { + name = "suse" + memory = "1024" + vcpu = 1 + + kernel = "${libvirt_volume.kernel.id}" + + // ... +} +``` + +* `kernel` - (Optional) The path of the initrd to boot. + +You can use it in the same way as the kernel. + +* `cmdlin` - (Optional) Arguments to the kernel + +resource "libvirt_domain" "domain-suse" { + name = "suse" + memory = "1024" + vcpu = 1 + + kernel = "${libvirt_volume.kernel.id}" + + cmdline { + arg1 = "value1" + arg2 = "value2" + } +} +``` + +Also note that the `cmd` block is actually a list of maps, so it is possible to +declare several of them by using either the literal list and map syntax as in +the following examples: + +```hcl +resource "libvirt_domain" "my_machine" { + //... + + cmdline { + arg1 = "value1" + } + cmdline { + arg2 = "value2" + } +} +``` + +```hcl +resource "libvirt_domain" "my_machine" { + ... + cmdline = [ + { + arg1 = "value1" + }, + { + arg2 = "value2" + } + ] +} +``` +The kernel supports passing the same option multiple times. If you need this, use separate cmdline blocks. + +```hcl +resource "libvirt_domain" "my_machine" { + //... + + cmdline { + arg1 = "value1" + } + cmdline { + arg1 = "value2" + } +} +``` + ### UEFI images Some extra arguments are also provided for using UEFI images: @@ -73,7 +166,7 @@ read-only. 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 +s * `template` - (Optional) path to the file used to override variables from the master NVRAM store. So you should typically use the firmware as this, |