Skip to content

Commit

Permalink
virtual machine resource: fix input devices (#107)
Browse files Browse the repository at this point in the history
Fix type conversion for input device blocks in virtual machine resource.
Fix virtual machine resource deletion.

related-to: harvester/harvester#6647

Signed-off-by: Moritz Röhrich <[email protected]>
  • Loading branch information
m-ildefons authored Nov 14, 2024
1 parent 422cad3 commit 72e76eb
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 21 deletions.
26 changes: 17 additions & 9 deletions internal/provider/virtualmachine/resource_virtualmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package virtualmachine

import (
"context"
"fmt"
"strings"
"time"

Expand Down Expand Up @@ -177,17 +176,26 @@ func resourceVirtualMachineDelete(ctx context.Context, d *schema.ResourceData, m
return diag.FromErr(err)
}

ctxDeadline, _ := ctx.Deadline()
events, err := c.HarvesterClient.
KubevirtV1().
VirtualMachines(namespace).
Watch(ctx, util.WatchOptions(name, time.Until(ctxDeadline)))
stateConf := &resource.StateChangeConf{
Pending: []string{
constants.StateCommonReady,
constants.StateCommonFailed,
constants.StateCommonUnknown,
constants.StateVirtualMachineRunning,
constants.StateVirtualMachineStarting,
constants.StateVirtualMachineStopping,
constants.StateVirtualMachineStopped,
},
Target: []string{constants.StateCommonRemoved},
Refresh: resourceVirtualMachineRefresh(ctx, d, meta, namespace, name, ""),
Timeout: d.Timeout(schema.TimeoutDelete),
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForStateContext(ctx)
if err != nil {
return diag.FromErr(err)
}
if !util.HasDeleted(events) {
return diag.FromErr(fmt.Errorf("timeout waiting for virtualmachine %s to be deleted", d.Id()))
}
d.SetId("")
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ func (c *Constructor) Setup() util.Processors {
Parser: func(i interface{}) error {
r := i.(map[string]interface{})
inputName := r[constants.FieldInputName].(string)
inputType := r[constants.FieldInputType].(kubevirtv1.InputType)
inputBus := r[constants.FieldInputBus].(kubevirtv1.InputBus)
inputType := kubevirtv1.InputType(r[constants.FieldInputType].(string))
inputBus := kubevirtv1.InputBus(r[constants.FieldInputBus].(string))
vmBuilder.Input(inputName, inputType, inputBus)
return nil
},
Expand Down
9 changes: 5 additions & 4 deletions internal/tests/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (

testAccResourceStateRemoved = "removed"
testAccResourceStateExist = "exist"
testAccResourceStateError = "error"
)

func init() {
Expand Down Expand Up @@ -54,9 +55,9 @@ func getStateChangeConf(refresh resource.StateRefreshFunc) *resource.StateChange
Pending: []string{testAccResourceStateExist},
Target: []string{testAccResourceStateRemoved},
Refresh: refresh,
Timeout: 1 * time.Minute,
Delay: 1 * time.Second,
MinTimeout: 3 * time.Second,
Timeout: 2 * time.Minute,
Delay: 10 * time.Second,
MinTimeout: 30 * time.Second,
}
}

Expand All @@ -67,7 +68,7 @@ func getResourceStateRefreshFunc(getResourceFunc func() (interface{}, error)) re
if apierrors.IsNotFound(err) {
return obj, testAccResourceStateRemoved, nil
}
return nil, "", err
return nil, testAccResourceStateError, err
}
return obj, testAccResourceStateExist, nil
}
Expand Down
60 changes: 54 additions & 6 deletions internal/tests/resource_virtualmachine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"testing"

"github.com/google/uuid"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -16,9 +18,7 @@ import (
)

const (
testAccVirtualMachineName = "test-acc-foo"
testAccVirtualMachineResourceName = constants.ResourceTypeVirtualMachine + "." + testAccVirtualMachineName
testAccVirtualMachineDescription = "Terraform Harvester vm acceptance test"
testAccVirtualMachineDescription = "Terraform Harvester vm acceptance test"

testAccVirtualMachineMemory = "1Gi"
testAccVirtualMachineMemoryUpdate = "2Gi"
Expand Down Expand Up @@ -47,20 +47,35 @@ resource %s "%s" {
container_image_name = "kubevirt/fedora-cloud-container-disk-demo:v0.35.0"
}
}
`
testAccInputBlockTemplate = `
input {
name = "%s"
type = "%s"
bus = "%s"
}
`
)

func addInputBlockConfig(name, inputType, bus, vmConfig string) string {
inputBlock := fmt.Sprintf(testAccInputBlockTemplate, name, inputType, bus)
return vmConfig[:(len(vmConfig)-3)] + inputBlock + vmConfig[(len(vmConfig)-3):]
}

func buildVirtualMachineConfig(name, description, memory string) string {
return fmt.Sprintf(testAccVirtualMachineConfigTemplate, constants.ResourceTypeVirtualMachine, name,
return fmt.Sprintf(testAccVirtualMachineConfigTemplate,
constants.ResourceTypeVirtualMachine, name,
constants.FieldCommonName, name,
constants.FieldCommonDescription, description,
constants.FieldVirtualMachineMemory, memory)
}

func TestAccVirtualMachine_basic(t *testing.T) {
var (
vm *kubevirtv1.VirtualMachine
ctx = context.Background()
testAccVirtualMachineName = "test-acc-basic-" + uuid.New().String()[:6]
testAccVirtualMachineResourceName = constants.ResourceTypeVirtualMachine + "." + testAccVirtualMachineName
vm *kubevirtv1.VirtualMachine
ctx = context.Background()
)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down Expand Up @@ -89,6 +104,39 @@ func TestAccVirtualMachine_basic(t *testing.T) {
})
}

func TestAccVirtualMachine_input(t *testing.T) {
var (
testAccVirtualMachineName = "test-acc-input-" + uuid.New().String()[:6]
testAccVirtualMachineResourceName = constants.ResourceTypeVirtualMachine + "." + testAccVirtualMachineName
vm *kubevirtv1.VirtualMachine
ctx = context.Background()
)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckVirtualMachineDestroy(ctx),
Steps: []resource.TestStep{
{
Config: addInputBlockConfig(
"tablet", "tablet", "usb",
buildVirtualMachineConfig(
testAccVirtualMachineName,
testAccVirtualMachineDescription,
testAccVirtualMachineMemoryUpdate,
),
),
Check: resource.ComposeTestCheckFunc(
testAccVirtualMachineExists(ctx, testAccVirtualMachineResourceName, vm),
resource.TestCheckResourceAttr(testAccVirtualMachineResourceName, constants.FieldVirtualMachineInput+".#", "1"),
resource.TestCheckResourceAttr(testAccVirtualMachineResourceName, constants.FieldVirtualMachineInput+".0.name", "tablet"),
resource.TestCheckResourceAttr(testAccVirtualMachineResourceName, constants.FieldVirtualMachineInput+".0.type", "tablet"),
resource.TestCheckResourceAttr(testAccVirtualMachineResourceName, constants.FieldVirtualMachineInput+".0.bus", "usb"),
),
},
},
})
}

func testAccVirtualMachineExists(ctx context.Context, n string, vm *kubevirtv1.VirtualMachine) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down

0 comments on commit 72e76eb

Please sign in to comment.