-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic nested hyperv on kvm test case
1. Start L1 Windows VM (w2022,2019,2016,win10) 2. Start L2 BIOS/UEFI VM via booting up fedora image Signed-off-by: xuemin <[email protected]>
- Loading branch information
1 parent
5d1600b
commit 6f7fb53
Showing
5 changed files
with
787 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
####################################################################### | ||
# | ||
# Initialize, or provision Windows Server as follows: | ||
# - The Hyper-V feature is installed. | ||
# - The required Hyper-V vSwitche is created, e.g. Internal switch. | ||
####################################################################### | ||
|
||
Write-Host "Info: Start to build up enviroment for Hyper-V" | ||
|
||
$internalSwitchName = "Internal" | ||
$externalSwitchName = "External" | ||
|
||
function TestCommandExists ([String]$command){ | ||
try { | ||
if(Get-Command $command -ErrorAction SilentlyContinue){ | ||
Write-Host "Info: $command exists"; | ||
return $true | ||
} | ||
} | ||
Catch { | ||
Write-Host "Info: $command does not exist"; | ||
return $false | ||
} | ||
} | ||
|
||
function InstallHyperVPowershell(){ | ||
# Need to restart windows to take effect, restart action will be out of this script | ||
if (TestCommandExists Get-WindowsFeature) { | ||
$powershellFeature = Get-WindowsFeature -Name "Hyper-v-powershell" | ||
if (-not $powershellFeature.Installed){ | ||
Install-windowsFeature -Name Hyper-v-powershell | ||
if (-not $?){ | ||
Throw "Error: Unable to install Hyper-v module" | ||
} | ||
else{ | ||
Write-Host "Info: Have executed Install-windowsfeature successfully"; | ||
} | ||
} | ||
} | ||
} | ||
|
||
function CreateExternalSwitch() | ||
{ | ||
# | ||
# We will only create an external switch if: | ||
# - The host only has a single physical NIC, and an external switch | ||
# does not already exist. | ||
# - The host has multiple physical NICs, but only one is connected, | ||
# and an external switch does not already exist. | ||
# | ||
|
||
Write-Host "Info: Checking for External vSwitch named '${externalSwitchName}'" | ||
$externalSwitch = Get-VMSwitch -Name "${externalSwitchName}" -ErrorAction SilentlyContinue | ||
if ($externalSwitch){ | ||
# A vSwitch named external already exists | ||
Write-Host -f Yellow "Warning: The external vSwitch '${externalSwitchName}' already exists" | ||
return | ||
} | ||
|
||
$adapters = Get-NetAdapter | ||
$numPotentialNICs = 0 | ||
$potentialNIC = $null | ||
|
||
foreach ($nic in $adapters){ | ||
# Make sure NIC is connected (MediaConnectState = 1) | ||
# and the NIC is up (InterfaceOperationalStatus = 1) | ||
|
||
if ($nic.InterfaceOperationalStatus -eq 1 -and $nic.MediaConnectState -eq 1){ | ||
$numPotentialNICs += 1 | ||
$potentialNIC = $nic.InterfaceDescription | ||
Write-Host "Info: Potential NIC for external vSwitch = '${potentialNIC}'" | ||
} | ||
} | ||
|
||
if ($numPotentialNICs -eq 0){ | ||
Write-Host -f Yellow "Warning: No potential NICs found to create an External vSwitch" | ||
Write-Host -f Yellow " You will need to manually create the external vSwitch" | ||
exit 1 | ||
} | ||
elseif ($numPotentialNICs -gt 1){ | ||
Write-Host -f Yellow "Warning: There are more than one physical NICs that could be used" | ||
Write-Host -f Yellow " with an external vSwitch. You will need to manually" | ||
Write-Host -f Yellow " create the external vSwitch" | ||
exit 1 | ||
} | ||
|
||
# | ||
# Create an External NIC using the one potential physical NIC | ||
# | ||
New-VMSwitch -Name "${externalSwitchName}" -NetAdapterInterfaceDescription "${potentialNIC}" | ||
if (-not $?){ | ||
Write-Host "Error: Unable to create external vSwitch using NIC '${potentialNIC}'" | ||
exit 1 | ||
} | ||
Write-Host "Info: External vSwitch '${externalSwitchName}' was created, using NIC" | ||
Write-Host " ${potentialNIC}" | ||
} | ||
|
||
function CreateInternalSwitch(){ | ||
# | ||
# See if an internal switch named 'Internal' already exists. | ||
# If not, create it | ||
# | ||
Write-Host "Info: Checking for Internal vSwitch named '${internalSwitchName}'" | ||
$internalSwitch = Get-VMSwitch -Name "${internalSwitchName}" -ErrorAction SilentlyContinue | ||
if (-not $internalSwitch){ | ||
New-VMSwitch -Name "${internalSwitchName}" -SwitchType Internal | ||
if (-not $?){ | ||
Throw "Error: Unable to create Internal switch" | ||
} | ||
|
||
Get-NetAdapter -Name "${internalSwitchName}" | New-NetIPAddress -AddressFamily ipv4 -IPAddress 192.168.0.1 -PrefixLength 24 | ||
Write-Host "Info: Internal vSwitch '${internalSwitchName}' was created with IP range 192.168.0.1/24" | ||
} | ||
else{ | ||
Write-Host -f Yellow "Warning: The Internal vSwitch '${internalSwitchName}' already exists" | ||
} | ||
} | ||
|
||
function InstallRolesAndFeatures(){ | ||
if ( TestCommandExists Get-WindowsFeature){ | ||
$hypervFeature = Get-WindowsFeature -Name "Hyper-V" | ||
if (-not $hypervFeature.Installed){ | ||
$feature = Install-WindowsFeature -Name "Hyper-V" -IncludeAllSubfeature -IncludeManagementTools | ||
if (-not $feature.Success){ | ||
Throw "Error: Unable to install the Hyper-V roles" | ||
}else{ | ||
Write-Host "Info: Have executed Install-WindowsFeature successfully" | ||
} | ||
} | ||
} | ||
else{ | ||
# For windows 10 and 11 | ||
$hypervFeature = Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All | ||
if (-not $hypervFeature.Enalbed){ | ||
$feature=Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All -NoRestart | ||
if (-not $feature.Online){ | ||
Throw "Error: Unable to enable the Hyper-V roles }" | ||
} | ||
else{ | ||
Write-Host "Info: Have executed Enable-WindowsOptionalFeature successfully" | ||
} | ||
} | ||
} | ||
} | ||
|
||
####################################################################### | ||
# | ||
# Main script body | ||
# | ||
####################################################################### | ||
|
||
try { | ||
# Install any roles and features | ||
Write-Host "Info: Start to install for Hyper-V Powershell" | ||
InstallHyperVPowershell | ||
|
||
Write-Host "Info: Start to install Hyper-V role" | ||
InstallRolesAndFeatures | ||
#CreateExternalSwitch | ||
#CreateInternalSwitch | ||
} | ||
catch { | ||
$msg = $_.Exception.Message | ||
Write-Host -f Red "Error: Unable to provision the host" | ||
Write-Host -f Red "${msg}" | ||
exit 1 | ||
} | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
param([String] $vhdx_path='C:\fedora.vhdx') | ||
# Main script to get vhdx and start gen1/gen2 vm. | ||
|
||
$PrivateSwitchName = "Private" | ||
|
||
function CreatePrivateSwitches(){ | ||
# | ||
# See if an Private switch named 'Private' already exists. | ||
# If not, create it | ||
# | ||
Write-Host "Info : Checking for Private vSwitch named '${PrivateSwitchName}'" | ||
$privateSwitch = Get-VMSwitch -Name "${privateSwitchName}" -ErrorAction SilentlyContinue | ||
if (-not $privateSwitch){ | ||
New-VMSwitch -Name "${privateSwitchName}" -SwitchType Private | ||
if (-not $?){ | ||
Throw "Error: Unable to create Private switch" | ||
} | ||
Write-Host "Info: Private vSwitch '${privateSwitchName}' is created" | ||
} | ||
else{ | ||
Write-Host -f Yellow "Warning: the vSwitch '$privateSwitchName}' already exists" | ||
} | ||
} | ||
|
||
# Create internal switch if does not exist | ||
CreatePrivateSwitches | ||
|
||
$vhdx_name=[System.IO.Path]::GetFileNameWithoutExtension($vhdx_path) | ||
$vhdx_folder=[System.IO.Path]::GetDirectoryName($vhdx_path) | ||
|
||
# $vm_name_gen1="fedora-gen1" | ||
# $vm_name_gen2="fedora-gen2" | ||
$vm_name_gen1= $vhdx_name +"-gen1" | ||
$vm_name_gen2= $vhdx_name +"-gen2" | ||
|
||
# $vm_gen1_vhdx="C:\fedora-gen1.vhdx" | ||
# $vm_gen2_vhdx="C:\fedora-gen2.vhdx" | ||
$vm_vhdx_gen1=$vhdx_folder+$vm_name_gen1+".vhdx" | ||
$vm_vhdx_gen2=$vhdx_folder+$vm_name_gen2+".vhdx" | ||
|
||
# Remove old vm if have | ||
powershell C:\nested-hyperv-on-kvm\hyperv_sets.ps1 -action del -vm_name $vm_name_gen1 | ||
powershell C:\nested-hyperv-on-kvm\hyperv_sets.ps1 -action del -vm_name $vm_name_gen2 | ||
start-sleep 2 | ||
|
||
if (-not (Test-Path $vhdx_path)){ | ||
write-host "Error: the vhdx file $vhdx_path does not exist." | ||
exit 1 | ||
} | ||
|
||
start-sleep 2 | ||
Copy-Item $vhdx_path $vm_vhdx_gen1 | ||
start-sleep 2 | ||
Copy-Item $vhdx_path $vm_vhdx_gen2 | ||
start-sleep 2 | ||
Remove-Item $vhdx_path | ||
|
||
#Start new gen1 vm | ||
powershell C:\nested-hyperv-on-kvm\hyperv_sets.ps1 -action clone -vm_name $vm_name_gen1 -vhd_path $vhdx_folder | ||
if ($? -eq $false) { | ||
write-host "Error: fail to start vm $vm_name_gen1" | ||
exit 1 | ||
} | ||
start-sleep 2 | ||
powershell C:\nested-hyperv-on-kvm\hyperv_sets.ps1 -action clone -vm_name $vm_name_gen2 -vhd_path $vhdx_folder -gen2 | ||
if ($? -eq $false) { | ||
write-host "Error: fail to start vm $vm_name_gen2" | ||
exit 1 | ||
} | ||
exit 0 |
Oops, something went wrong.