Skip to content

Commit

Permalink
Merge pull request #134 from microsoft/user/pgayam/cherrypick-remove-iso
Browse files Browse the repository at this point in the history
[Cherry pick] Clean up seed ISO image attached to Arc VMs
  • Loading branch information
msftpgayam authored Oct 25, 2024
2 parents 7c456ef + 39d4a6a commit 96ab495
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pkg/virtualization/core/service/dvddrive.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,8 @@ func (vmms *VirtualSystemManagementService) RemoveDvdDrive(dvd *drive.DvdDrive)
err = vmms.RemoveVirtualSystemResource(dvd.CIM_ResourceAllocationSettingData, -1)
return
}

func (vmms *VirtualSystemManagementService) RemoveDvdDisk(dvddisk *disk.LogicalDisk) (err error) {
err = vmms.RemoveVirtualSystemResource(dvddisk.CIM_ResourceAllocationSettingData, -1)
return
}
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,67 @@ func TestAddRemoveIsoDiskGen1(t *testing.T) {
}
}

func TestAddRemoveIsoDiskByPath(t *testing.T) {
vmms, err := GetVirtualSystemManagementService(whost)
if err != nil {
t.Fatalf("Failed [%+v]", err)
}
vm, err := vmms.GetVirtualMachineByName("test")
if err != nil {
t.Fatalf("Failed [%+v]", err)
}
defer vm.Close()
t.Logf("Found [%s] VMs", vm.Name())

// make sure there is a controller
err = vmms.AddSCSIController(vm)
if err != nil {
t.Fatalf("Failed [%+v]", err)
}

path := "c:\\test\\tmp.iso"

// create an iso file
err = generateIso(path)
if err != nil {
t.Fatalf("Failed [%+v]", err)
}

isodisk, dvddrive, err := vmms.AddISODisk(vm, path)
if err != nil {
t.Fatalf("Failed [%+v]", err)
}
defer isodisk.Close()
defer dvddrive.Close()

// remove the iso disk
vmdvddrive, vmdvddisk, err := vm.GetDvdDriveAndLogicalDiskByIsoPath(path)
if err != nil {
t.Fatalf("Failed [%+v]", err)
}
t.Logf("Obtained ISO disk [%s] from [%s]", path, "test")
defer vmdvddisk.Close()
defer vmdvddrive.Close()

// Remove logical disk
err = vmms.RemoveDvdDisk(vmdvddisk)
if err != nil {
t.Fatalf("Failed to remove DVD disk [%+v]", err)
}

// Remove DVD drive
err = vmms.RemoveDvdDrive(vmdvddrive)
if err != nil {
t.Fatalf("Failed to remove DVD drive [%+v]", err)
}

// Remove the ISO file
err = os.Remove(path)
if err != nil {
t.Fatalf("Failed [%+v]", err)
}
}

func generateIso(path string) error {
writer, err := iso9660.NewWriter()
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions pkg/virtualization/core/storage/drive/dvddrive.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ func NewDvdDrive(instance *wmi.WmiInstance) (*DvdDrive, error) {
}
return &DvdDrive{wmivm}, nil
}

func GetRelatedStorageAllocationSettingData(instance *wmi.WmiInstance) (value *wmi.WmiInstance, err error) {
return instance.GetRelated("Msvm_StorageAllocationSettingData")
}
29 changes: 29 additions & 0 deletions pkg/virtualization/core/storage/drive/dvddrivecollection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package drive

import (
wmi "github.com/microsoft/wmi/pkg/wmiinstance"
)

type DvdDriveCollection []*DvdDrive

func NewDvdDriveCollection(instances []*wmi.WmiInstance) (col DvdDriveCollection, err error) {
for _, inst := range instances {
na, err1 := NewDvdDrive(inst)
if err1 != nil {
err = err1
return
}
col = append(col, na)
}
return
}

func (dvdcol *DvdDriveCollection) Close() (err error) {
for _, value := range *dvdcol {
value.Close()
}
return nil
}
86 changes: 86 additions & 0 deletions pkg/virtualization/core/virtualsystem/virtualmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package virtualsystem

import (
"fmt"
"path/filepath"

//"log"
"time"
Expand Down Expand Up @@ -762,6 +763,91 @@ func (vm *VirtualMachine) GetVirtualHardDrives() (col resourceallocation.Resourc
return
}

func (vm *VirtualMachine) GetDvdDrives() (col drive.DvdDriveCollection, err error) {
settings, err := vm.GetVirtualSystemSettingData()
if err != nil {
return
}
defer settings.Close()
return settings.GetVirtualDvdDrives()
}

func (vm *VirtualMachine) GetDvdDriveAndLogicalDiskByIsoPath(isoPath string) (dvd *drive.DvdDrive, diskdvd *disk.LogicalDisk, err error) {
dvdCol, err := vm.GetDvdDrives()
if err != nil {
return
}
defer dvdCol.Close()

for _, inst := range dvdCol {
dvddisk, err1 := drive.GetRelatedStorageAllocationSettingData(inst.WmiInstance)
if err1 != nil {
// Missing related storage allocation data is benign
// It just means that DVD disk is not available
continue
}

dvdPathInterface, err1 := dvddisk.GetProperty("HostResource")
if err1 != nil {
err = fmt.Errorf("unable to read HostResource field from disk WMI %s", err1)
return
}
if dvdPathInterface == nil {
// Attached ISO path is not available, continue
continue
}

dvdPath := ""
for _, interfaceValue := range dvdPathInterface.([]interface{}) {
valuetmp, ok := interfaceValue.(string)
if !ok {
err = errors.Wrapf(errors.InvalidType, " string is Invalid. Expected %s", reflect.TypeOf(interfaceValue))
return
}

dvdPath = string(valuetmp)
}

if filepath.Clean(dvdPath) != filepath.Clean(isoPath) {
continue
}

// Clone the DVD drive instance for return
dvdclone, err1 := inst.Clone()
if err1 != nil {
err = err1
return
}

retdvd, err1 := drive.NewDvdDrive(dvdclone)
if err1 != nil {
err = err1
return
}

// Also clone the logical disk instance for return
dvddiskclone, err1 := dvddisk.Clone()
if err1 != nil {
err = err1
return
}

retdvddisk, err1 := disk.NewLogicalDisk(dvddiskclone)
if err1 != nil {
err = err1
return
}

dvd = retdvd
diskdvd = retdvddisk
return
}
err = errors.Wrapf(errors.NotFound,
"Dvd drive with path [%s] not found in Vm [%s]", isoPath, vm.Name())
dvd = nil
return
}

func (vm *VirtualMachine) GetVirtualHardDiskByLocation(controllerNumber, controllerLocation int) (vhd *disk.VirtualHardDisk, err error) {
col, err := vm.GetVirtualHardDisks()
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,24 @@ func TestGetVirtualHardDisks(t *testing.T) {
defer vhds.Close()
t.Logf("Virtual Hard Disks Found [%d]", len(vhds))
}

func TestGetVirtualDvdDrives(t *testing.T) {
vm, err := GetVirtualMachineByVMName(whost, "test")
if err != nil {
t.Fatal("Failed " + err.Error())
}
defer vm.Close()

setting, err := vm.GetVirtualSystemSettingData()
if err != nil {
t.Fatal("Failed " + err.Error())
}
defer setting.Close()

dvds, err := setting.GetVirtualDvdDrives()
if err != nil {
t.Fatal("Failed " + err.Error())
}
defer dvds.Close()
t.Logf("DVD drives Found [%d]", len(dvds))
}
16 changes: 16 additions & 0 deletions pkg/virtualization/core/virtualsystem/virtualsystemsettingdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/microsoft/wmi/pkg/virtualization/core/pcie"
"github.com/microsoft/wmi/pkg/virtualization/core/processor"
"github.com/microsoft/wmi/pkg/virtualization/core/storage/disk"
"github.com/microsoft/wmi/pkg/virtualization/core/storage/drive"
na "github.com/microsoft/wmi/pkg/virtualization/network/virtualnetworkadapter"
wmi "github.com/microsoft/wmi/pkg/wmiinstance"
v2 "github.com/microsoft/wmi/server2019/root/virtualization/v2"
Expand Down Expand Up @@ -251,6 +252,21 @@ func (vm *VirtualSystemSettingData) GetVirtualHardDisks() (col disk.VirtualHardD
return
}

func (vm *VirtualSystemSettingData) GetVirtualDvdDrives() (col drive.DvdDriveCollection, err error) {
resourceType := fmt.Sprintf("%d", int32(v2.ResourceAllocationSettingData_ResourceType_DVD_drive))
query := query.NewWmiQuery("Cim_ResourceAllocationSettingData", "ResourceType", resourceType)
rasdcollection, err := instance.GetWmiInstancesFromHost(vm.GetWmiHost(), string(constant.Virtualization), query)
if err != nil {
return
}

col, err = drive.NewDvdDriveCollection(rasdcollection)
if err != nil {
rasdcollection.Close()
}
return
}

func (vm *VirtualSystemSettingData) getResourceAllocationSettingData(rtype v2.ResourceAllocationSettingData_ResourceType) (col wmi.WmiInstanceCollection, err error) {
resourceType := fmt.Sprintf("%d", int32(rtype))
query := query.NewWmiQuery("Cim_ResourceAllocationSettingData", "ResourceType", resourceType)
Expand Down

0 comments on commit 96ab495

Please sign in to comment.