Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hyper-v platform] Delete disks on deletion of VM #3616

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 73 additions & 5 deletions lisa/tools/hyperv.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
from dataclasses import dataclass
from enum import Enum
from typing import Dict, Optional
from typing import Dict, List, Optional

from assertpy import assert_that
from dataclasses_json import dataclass_json
Expand All @@ -14,6 +14,7 @@
from lisa.executable import Tool
from lisa.operating_system import Windows
from lisa.tools.powershell import PowerShell
from lisa.tools.rm import Rm
from lisa.tools.windows_feature import WindowsFeatureManagement
from lisa.util import LisaException
from lisa.util.process import Process
Expand All @@ -31,6 +32,25 @@ class VMSwitch:
type: HypervSwitchType = HypervSwitchType.EXTERNAL


class ControllerType(Enum):
IDE = 0
SCSI = 1


@dataclass
class VMDisk:
# The unique identifier of the virtual hard disk.
id: str = ""
# The file path of the virtual hard disk (VHDX) file.
path: str = ""
# The type of the controller (IDE or SCSI).
controller_type: ControllerType = ControllerType.IDE
# The number of the controller to which the virtual hard disk is attached.
controller_number: int = 0
# The location of the controller to which the virtual hard disk is attached.
controller_location: int = 0


class HyperV(Tool):
# 192.168.5.12
IP_REGEX = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
Expand All @@ -53,15 +73,63 @@ def exists_vm(self, name: str) -> bool:

return bool(output.strip() != "")

def get_vm_disks(self, name: str) -> List[VMDisk]:
vm_disks: List[VMDisk] = []
output = self.node.tools[PowerShell].run_cmdlet(
f"Get-VMHardDiskDrive -VMName {name} ",
force_run=True,
output_json=True,
)
if not output:
return []
# above command returns a list of disks if there are multiple disks.
# if there is only one disk, it returns a single disk but not a list.
# so convert the output to a list if it is not already a list
if not isinstance(output, list):
output = [output]
for disk in output:
vm_disks.append(
VMDisk(
id=disk["Id"],
path=disk["Path"],
controller_type=disk["ControllerType"],
controller_number=disk["ControllerNumber"],
controller_location=disk["ControllerLocation"],
)
)
return vm_disks

def delete_vm_disks(self, name: str) -> None:
# get vm disks
vm_disks = self.get_vm_disks(name)

# delete vm disks
for disk in vm_disks:
self.node.tools[PowerShell].run_cmdlet(
f"Remove-VMHardDiskDrive -VMName {name} "
f"-ControllerType {disk.controller_type} "
f"-ControllerNumber {disk.controller_number} "
f"-ControllerLocation {disk.controller_location}",
force_run=True,
)
self.node.tools[Rm].remove_file(
disk.path,
sudo=True,
)

def delete_vm_async(self, name: str) -> Optional[Process]:
# check if vm is present
# check if VM is present
if not self.exists_vm(name):
return None

# stop and delete vm
# stop the VM before deleting it
self.stop_vm(name=name)
powershell = self.node.tools[PowerShell]
return powershell.run_cmdlet_async(

# delete VM disks before deleting vm
self.delete_vm_disks(name)

# delete vm
return self.node.tools[PowerShell].run_cmdlet_async(
f"Remove-VM -Name {name} -Force",
force_run=True,
)
Expand Down
2 changes: 1 addition & 1 deletion lisa/tools/ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def is_file(self, path: PurePath, sudo: bool = False) -> bool:

def path_exists(self, path: str, sudo: bool = False) -> bool:
output = self.node.tools[PowerShell].run_cmdlet(
f"Test-Path {path}",
f"Test-Path '{path}'",
force_run=True,
sudo=sudo,
)
Expand Down
Loading