From c0c8c29cc84a5c7b3b05456f66395b8ee46b522c Mon Sep 17 00:00:00 2001 From: Haider Agha Date: Thu, 19 Jan 2023 22:44:08 -0500 Subject: [PATCH 1/2] adding hyperv gen to az vm repair create --- src/vm-repair/HISTORY.rst | 4 ++ src/vm-repair/azext_vm_repair/custom.py | 10 ++--- src/vm-repair/azext_vm_repair/repair_utils.py | 15 ++++--- .../scripts/win-enable-nested-hyperv.ps1 | 44 +++++++++++++++---- src/vm-repair/setup.py | 2 +- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/vm-repair/HISTORY.rst b/src/vm-repair/HISTORY.rst index c36adb128a5..cb745e2dbc9 100644 --- a/src/vm-repair/HISTORY.rst +++ b/src/vm-repair/HISTORY.rst @@ -2,6 +2,10 @@ Release History =============== +0.5.0 +++++++ +Support for hosting repair vm in existing resource group and fixing existing resource group logic + 0.4.10 ++++++ Support for hosting repair vm in existing resource group and fixing existing resource group logic diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index 2bfc03a8325..15f500c14ef 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -59,7 +59,7 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern source_vm_instance_view = get_vm(cmd, resource_group_name, vm_name, 'instanceView') is_linux = _is_linux_os(source_vm) - is_gen2 = _is_gen2(source_vm_instance_view) + vm_hypervgen = _is_gen2(source_vm_instance_view) target_disk_name = source_vm.storage_profile.os_disk.name is_managed = _uses_managed_disk(source_vm) @@ -120,7 +120,7 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern if hyperV_generation: copy_disk_command += ' --hyper-v-generation {hyperV}'.format(hyperV=hyperV_generation) elif is_linux and hyperV_generation_linux == 'V2': - logger.info('The disk did not contian the info of gen2 , but the machine is created from gen2 image') + logger.info('The disk did not contain the information of gen2 , but the machine is created from gen2 image') copy_disk_command += ' --hyper-v-generation {hyperV}'.format(hyperV=hyperV_generation_linux) # Set availability zone for vm when available if source_vm.zones: @@ -209,7 +209,7 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern logger.info("Running Script win-enable-nested-hyperv.ps1 to install HyperV") run_hyperv_command = "az vm repair run -g {g} -n {name} --run-id win-enable-nested-hyperv --parameters gen={gen}" \ - .format(g=repair_group_name, name=repair_vm_name, gen=is_gen2) + .format(g=repair_group_name, name=repair_vm_name, gen=vm_hypervgen) ret_enable_nested = _call_az_command(run_hyperv_command) logger.debug("az vm repair run hyperv command returned: %s", ret_enable_nested) @@ -222,8 +222,8 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern # invoking hyperv script again logger.info("Running win-enable-nested-hyperv.ps1 again to create nested VM") - run_hyperv_command = "az vm repair run -g {g} -n {name} --run-id win-enable-nested-hyperv" \ - .format(g=repair_group_name, name=repair_vm_name) + run_hyperv_command = "az vm repair run -g {g} -n {name} --run-id win-enable-nested-hyperv --parameters gen={gen}" \ + .format(g=repair_group_name, name=repair_vm_name, gen=vm_hypervgen) ret_enable_nested_again = _call_az_command(run_hyperv_command) logger.debug("stderr: %s", ret_enable_nested_again) diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index d0fb25eae48..4492d705647 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -370,17 +370,20 @@ def _check_linux_hyperV_gen(source_vm): disk_id = source_vm.storage_profile.os_disk.managed_disk.id show_disk_command = 'az disk show --id {i} --query [hyperVgeneration] -o json' \ .format(i=disk_id) - hyperVGen = loads(_call_az_command(show_disk_command)) - if hyperVGen != 'V2': + disk_hyperVGen = loads(_call_az_command(show_disk_command)) + + if disk_hyperVGen != 'V2': logger.info('Checking if source VM is gen2') # if image is created from Marketplace gen2 image , the disk will not have the mark for gen2 fetch_hypervgen_command = 'az vm get-instance-view --ids {id} --query "[instanceView.hyperVGeneration]" -o json'.format(id=source_vm.id) hyperVGen_list = loads(_call_az_command(fetch_hypervgen_command)) - hyperVGen = hyperVGen_list[0] - if hyperVGen != 'V2': - hyperVGen = 'V1' + vm_hyperVGen = hyperVGen_list[0] + if vm_hyperVGen != 'V2': + vm_hyperVGen = 'V1' + + return vm_hyperVGen - return hyperVGen + return disk_hyperVGen def _secret_tag_check(resource_group_name, copy_disk_name, secreturl): diff --git a/src/vm-repair/azext_vm_repair/scripts/win-enable-nested-hyperv.ps1 b/src/vm-repair/azext_vm_repair/scripts/win-enable-nested-hyperv.ps1 index ae66cc50ab9..d3688188bcc 100644 --- a/src/vm-repair/azext_vm_repair/scripts/win-enable-nested-hyperv.ps1 +++ b/src/vm-repair/azext_vm_repair/scripts/win-enable-nested-hyperv.ps1 @@ -1,4 +1,8 @@ -Write-Output 'Running Script Enable-NestedHyperV' +Param([Parameter(Mandatory=$false)][string]$gen) + +. .\src\windows\common\setup\init.ps1 + +Log-Info 'Running Script Enable-NestedHyperV' $scriptStartTime = get-date -f yyyyMMddHHmmss $scriptPath = split-path -path $MyInvocation.MyCommand.Path -parent @@ -23,7 +27,7 @@ $rsatDhcp = $features | where Name -eq 'RSAT-DHCP' if ($hyperv.Installed -and $hypervTools.Installed -and $hypervPowerShell.Installed) { - Write-Output 'START: Creating nested guest VM' | out-file -FilePath $logFile -Append + Log-Info 'START: Creating nested guest VM' | out-file -FilePath $logFile -Append # Sets "Do not start Server Manager automatically at logon" $return = New-ItemProperty -Path HKLM:\Software\Microsoft\ServerManager -Name DoNotOpenServerManagerAtLogon -PropertyType DWORD -Value 1 -force -ErrorAction SilentlyContinue $return = New-ItemProperty -Path HKLM:\Software\Microsoft\ServerManager\Oobe -Name DoNotOpenInitialConfigurationTasksAtLogon -PropertyType DWORD -Value 1 -force -ErrorAction SilentlyContinue @@ -36,7 +40,7 @@ if ($hyperv.Installed -and $hypervTools.Installed -and $hypervPowerShell.Install if (!$switch) { $switch = New-VMSwitch -Name Internal -SwitchType Internal -ErrorAction Stop - #Log-Info 'New VMSwitch Successfully created' | out-file -FilePath $logFile -Append + Log-Info 'New VMSwitch Successfully created' | out-file -FilePath $logFile -Append } $adapter = Get-NetAdapter -Name 'vEthernet (Internal)' -ErrorAction Stop @@ -44,21 +48,21 @@ if ($hyperv.Installed -and $hypervTools.Installed -and $hypervPowerShell.Install if (!$ip) { $return = New-NetIPAddress -IPAddress 192.168.0.1 -PrefixLength 24 -InterfaceIndex $adapter.ifIndex -ErrorAction Stop - #Log-Info 'New NetIPAddress Successfully created' | out-file -FilePath $logFile -Append + Log-Info 'New NetIPAddress Successfully created' | out-file -FilePath $logFile -Append } $nat = Get-NetNat -Name InternalNAT -ErrorAction SilentlyContinue | select -first 1 if (!$nat) { $return = New-NetNat -Name InternalNAT -InternalIPInterfaceAddressPrefix 192.168.0.0/24 -ErrorAction Stop - #Log-Info 'New NetNat Successfully created' | out-file -FilePath $logFile -Append + Log-Info 'New NetNat Successfully created' | out-file -FilePath $logFile -Append } # Configure DHCP server service so nested guest can get an IP from DHCP and will use 168.63.129.16 for DNS and 192.168.0.1 as default gateway if ($dhcp.Installed -eq $false -or $rsatDhcp.Installed -eq $false) { $return = Install-WindowsFeature -Name DHCP -IncludeManagementTools -ErrorAction Stop - #Log-Info 'New NetIPAddress Successfully created' | out-file -FilePath $logFile -Append + Log-Info 'New NetIPAddress Successfully created' | out-file -FilePath $logFile -Append } $scope = Get-DhcpServerv4Scope -ErrorAction SilentlyContinue | where Name -eq Scope1 | select -first 1 if (!$scope) @@ -68,11 +72,29 @@ if ($hyperv.Installed -and $hypervTools.Installed -and $hypervPowerShell.Install $return = Set-DhcpServerv4OptionValue -DnsServer 168.63.129.16 -Router 192.168.0.1 -ErrorAction Stop # Create the nested guest VM - $return = new-vm -name $nestedGuestVmName -MemoryStartupBytes 4GB -NoVHD -BootDevice IDE -Generation 1 -ErrorAction Stop + if (!$gen) { + Log-Info 'Creating Gen1 VM with 4GB memory' | Out-File -FilePath $logFile -Append + $return = New-VM -Name $nestedGuestVmName -MemoryStartupBytes 4GB -NoVHD -BootDevice IDE -Generation 1 -ErrorAction Stop + } + else { + Log-Info "Creating Gen$($gen) VM with 4GB memory" | Out-File -FilePath $logFile -Append + $return = New-VM -Name $nestedGuestVmName -MemoryStartupBytes 4GB -NoVHD -Generation $gen -ErrorAction Stop + } $return = set-vm -name $nestedGuestVmName -ProcessorCount 2 -CheckpointType Disabled -ErrorAction Stop $disk = get-disk -ErrorAction Stop | where {$_.FriendlyName -eq 'Msft Virtual Disk'} $return = $disk | set-disk -IsOffline $true -ErrorAction Stop - $return = $disk | Add-VMHardDiskDrive -VMName $nestedGuestVmName -ErrorAction Stop + + if (!$gen) { + Log-Info "Gen1: Adding hard drive to IDE controller" | Out-File -FilePath $logFile -Append + $return = $disk | Add-VMHardDiskDrive -VMName $nestedGuestVmName -ErrorAction Stop + } + else { + Log-Info "Gen$($gen): Adding hard drive to SCSI controller" | Out-File -FilePath $logFile -Append + $return = $disk | Add-VMHardDiskDrive -VMName $nestedGuestVmName -ControllerType SCSI -ControllerNumber 0 -ErrorAction Stop + Log-Info "Gen$($gen): Modifying firmware boot order (we do not need to network boot)" | Out-File -FilePath $logFile -Append + $return = Set-VMFirmware $nestedGuestVmName -FirstBootDevice ((Get-VMFirmware $nestedGuestVmName).BootOrder | Where-Object { $_.BootType -eq "Drive" })[0] + } + $return = $switch | Connect-VMNetworkAdapter -VMName $nestedGuestVmName -ErrorAction Stop $return = start-vm -Name $nestedGuestVmName -ErrorAction Stop $nestedGuestVmState = (get-vm -Name $nestedGuestVmName -ErrorAction Stop).State @@ -86,7 +108,9 @@ if ($hyperv.Installed -and $hypervTools.Installed -and $hypervPowerShell.Install } catch { throw $_ + return $STATUS_ERROR } + # Returns the nested guest VM status to the calling script - "Running" if all went well. return $nestedGuestVmState } @@ -99,10 +123,12 @@ else } catch { throw $_ + return $STATUS_ERROR } "END: Installing Hyper-V" | out-file -FilePath $logFile -Append + $return.ExitCode write-host $return.ExitCode - return + return $STATUS_SUCCESS } $scriptEndTime = get-date -f yyyyMMddHHmmss diff --git a/src/vm-repair/setup.py b/src/vm-repair/setup.py index ebb2d999cd5..bf7412d189b 100644 --- a/src/vm-repair/setup.py +++ b/src/vm-repair/setup.py @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "0.4.10" +VERSION = "0.5.0" CLASSIFIERS = [ 'Development Status :: 4 - Beta', From 44194b7622546d804eee2dbef3a8a524047b9e2f Mon Sep 17 00:00:00 2001 From: Haider Agha Date: Thu, 19 Jan 2023 23:34:41 -0500 Subject: [PATCH 2/2] stylefix --- src/vm-repair/azext_vm_repair/repair_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index 4492d705647..3aedf016570 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -380,7 +380,7 @@ def _check_linux_hyperV_gen(source_vm): vm_hyperVGen = hyperVGen_list[0] if vm_hyperVGen != 'V2': vm_hyperVGen = 'V1' - + return vm_hyperVGen return disk_hyperVGen