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

VirtualHardDisk: New resource proposal #277

Open
bbonaby opened this issue Sep 19, 2023 · 3 comments · May be fixed by #279
Open

VirtualHardDisk: New resource proposal #277

bbonaby opened this issue Sep 19, 2023 · 3 comments · May be fixed by #279
Assignees
Labels
enhancement The issue is an enhancement request. in progress The issue is being actively worked on by someone. resource proposal The issue is proposing a new resource in the resource module.

Comments

@bbonaby
Copy link
Contributor

bbonaby commented Sep 19, 2023

Resource proposal

Currently there is no way to create a standalone virtual disk in PowerShell on Windows client machines outside of using the New-VHD cmdlet. The problem with New-VHD is that its needs the Hyper-V feature enabled in Windows. For machines without this feature enabled like freshly installed Windows client boxes, this feature isn't enabled by default and enabling it would require a reboot. We should be able to create a virtual disk just like using the legacy disk management tool using DSC without this requirement.

Another way to create a virtual disk in PowerShell is to use the New-VirtualDisk cmdlet. However, this attempts to create a virtual disk in a storage pool and a requirement for storage pools is that two or more separate disks other than the disk Windows is installed on needs to be available. Another issue is that the disks in question have to have their 'Can-pool' flag set to true, which isn't always the case, and a destructive operation may be required to achieve this.

I suggest we create a DSC that utilizes a generic way that does not utilize these methods. Here are some requirements I believe the initial Vhd resource should have:

  1. Create a virtual disk with the following user input:
    a. The full path to the virtual hard disk file
    b. The disk format of the virtual disk [vhd or vhdx]
    c. The disk type of the virtual disk [fixed or dynamic]
    d. The disk size for the virtual hard disk
  2. Attach the virtual disk:
    a. Attaching the has the same parameters as 'a' through 'd' above.
    b. Windows client now has a new win32 flag that will allow a virtual disk attached with the AttachVirtualDisk api to be reattached at boot time. see ATTACH_VIRTUAL_DISK_FLAG_AT_BOOT

I believe utilizing the win32 api's CreateVirtualDisk and AttachVirtualDisk is simple for this job. We can have a new virtual disk powershell function and an Add function to attach them. Inside both we would just use imported C# using the add-type cmdlet. The C# code would just have the win32 imported functions, structs and enums needed to achieve this. I've prototyped this in this forked branch

The Purpose of the resource would be to ensure that a virtual disk with parameters from 'a' to 'd' is created. We don't need to add a detach methods because that can be done via DSC_MountImage. The difference here is that the virtual disk is created and mounted at the same time, with the added benefit of allowing for the auto attach capability.

example of how the resource would work:

<#
    .DESCRIPTION
        This configuration will create a dynamically sized virtual hard disk that has a max size of 80Gb and will format a
        RefS volume named 'new volume 2' that uses the drive letter F, onto the newly created virtual hard disk. If the
        folder path in the FilePath property does not exist, it will be created.
#>
Configuration VirtualHardDisk_CreateDynamicallyExpandingVirtualDisk
{
    Import-DSCResource -ModuleName StorageDsc

    Node localhost
    {
          # Create new virtual disk
          VirtualHardDisk newVhd2
          {
            FilePath = 'C:\myVhds\virtDisk2.vhdx'
            DiskSize = 80Gb
            DiskFormat = 'Vhdx'
            DiskType = 'Dynamic'
            Ensure = 'Present'
          }

          # Create new volume onto the new virtual disk
          Disk Volume1
          {
            DiskId = 'C:\myVhds\virtDisk2.vhdx'
            DiskIdType = 'Location'
            DriveLetter = 'F'
            FSLabel = 'new volume 2'
            FSFormat = 'ReFS'
            Size = 20Gb
            DependsOn = '[VirtualHardDisk]newVhd2'
          }
    }
}


#pseudocode
function Get-TargetResource
{
       1. Use Get-DiskImage to get the disk
       2. If disk doesn't exist and Ensure set to 'Present', then we make Ensure set to 'Absent'
       3. If disk does exist then we make Ensure set to 'Present' if it isn't already
       4. return the image path, attach statue, size of disk, disk number and ensure state
}

function Test-TargetResource
{
	1. Get current state via Get-targetResource
	2. Check Ensure parameter
	3. if Ensure set to Present 
	    3.a. Check if virtual hard disk exists via current state from step 1
            3.b. if it does we return true
            3.c. if it does not we return false
     	4. if Ensure set to Absent
	    4.a. Check if virtual hard disk is attached. This is retrieved from step 1 where we get the state. 
            4.b. if it is attached we return false
            4.c. if it is not  attached or doesn't exist we return true
}

function Set-TargetResource
{
	1.Get current state via Get-targetResource
	2. Check Ensure parameter
	3. if Ensure set to Present 
	    3.a. we check if virtual hard disk exists via current state from step 1
            3.b. if the disk does exist we then check if it is not attached to the system.
                3.b.a if its attached we do nothing
                3.b.b if its not attached we attach it to the system
            3.c If the disk does not exist
                3.c.a We create the folder in the file path the user expects the virtual hard disk file to be created in. (if it doesn't exist)
                3.c.b if the folder now exists we create the virtual hard disk using the win32 apis
     	4. if Ensure set to Absent
	    4.a. we check if virtual hard disk is attached. This is retrieved from step 1 where we get the state. 
            4.b. if it is attached we detach it from the system
            4.c. if it is not  attached we do nothing
}

Proposed properties

Property Type qualifier Data type Description Default value Allowed values
FilePath Key String Specifies the full path to the virtual hard disk file that will be created or attached. This must include the extension, and the extension must match the disk format. None None
DiskSize Write Uint64 Specifies the size of virtual disk None None
DiskFormat Write String Specifies the disk format the virtual disk file should use. Vhdx Vhd, Vhdx
DiskType Write String Specifies the disk type the virtual disk should use. Dyanmic Fixed, Dyanmic
Ensure Key String Determines whether the virtual hard disk should be created and attached or should not be attached Present Present, Absent

Special considerations or limitations

Something to consider is that if the virtual disk file is dismounted from the system and moved to a different location. The DSC would likely create a new one. This is the nature of the virtual disk being a file that is portable.

@bbonaby
Copy link
Contributor Author

bbonaby commented Sep 19, 2023

FYI @PlagueHO

@PlagueHO PlagueHO added enhancement The issue is an enhancement request. in progress The issue is being actively worked on by someone. labels Sep 20, 2023
@PlagueHO
Copy link
Member

Thanks @bbonaby - love it!

We should probably combine the folder and filename parameters together because they would both need to be considered the key for the resource (otherwise you wouldn't be able to create two virtual disks in the same folder). Also, good to be explicit about the file extension and assume that if it is not included then the resource won't add it.

We should also add an Ensure parameter to enable detachment and removal of a VHD if it shouldn't exist - e.g. See example here: https://github.com/dsccommunity/StorageDsc/wiki/MountImage

@johlju johlju added the resource proposal The issue is proposing a new resource in the resource module. label Sep 23, 2023
@bbonaby
Copy link
Contributor Author

bbonaby commented Oct 19, 2023

updated the issue to reflect whats in the PR now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement The issue is an enhancement request. in progress The issue is being actively worked on by someone. resource proposal The issue is proposing a new resource in the resource module.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants