Repository: hashicorp/vagrant (Ruby)

Issue:
vagrant up with Hyper-V fails when box was packaged from a VM that has more resources than available on current Machine.
When I package a Hyper-V Box on a machine with lots of resources (e.g. 50GB memory, 20 CPUs), I am unable to launch the instance on another machine with fewer resources, even if local resources are specified in the vagrantfile.

It seems that Vagrant packages the Hyper-V *.vcmx file in the box and uses that to launch the VM instance on the new machine. Vagrant subsequently modifies the Hyper-V resources according to the vagrantfile. This works great on the original machine where it can get past step 1, but on the new machine with fewer resources it cant get past step 1 and fails to launch the VM. I think the appropriate way to handle this would be to edit the *.vcmx file with the resource constraints before launching it. 

Workaround for now is to just build the box with those resource constraints in mind.

### Vagrant version
2.2.14

### Host operating system
Windows10 20H2

### Guest operating system
Windows10 20H2

###Vagrantfile

Vagrant.configure("2") do |config|
  ...
  config.vm.provider "hyperv" do |hyperv|
    hyperv.memory = memory * 1024
    hyperv.maxmemory = max_memory * 1024
    hyperv.cpus = cpus
  end

end

### Error
INFO interface: error: An error occurred while executing a PowerShell script. This error
is shown below. Please read the error message and see if this is
a configuration error with your system. If it is not, then please
report a bug.

Script: import_vm.ps1
Error:

[
    "Memory virtual quantity above maximum.",
    "Cannot assign the specified number of processors for virtual machine \u0027Development Environment Version 1.2.9\u0027 is out of range. The range is 1 through 4. (Virtual machine ID 420E68AF-BEBC-4762-B68F-3B141F171582)"
]

### Expected behavior

Vagrant up launches a virtual machine with the Hyper-V provider with the resources specified in the vagrantfile.

### Actual behavior

Vagrant up fails with above error message

### Steps to reproduce

1. Package vagrant box from Hyper-V VM with 50GB RAM on system with 64GB RAM.
2. Transfer box to machine with 32GB RAM and specify in vagrantfile 16GB RAM to be used.





Fix (patch):
diff --git a/plugins/providers/hyperv/action/import.rb b/plugins/providers/hyperv/action/import.rb
index f901d1af9f9..716cc51dfec 100644
--- a/plugins/providers/hyperv/action/import.rb
+++ b/plugins/providers/hyperv/action/import.rb
@@ -70,9 +70,11 @@ def call(env)
             "LinkedClone" => !!env[:machine].provider_config.linked_clone,
             "SourcePath" => Vagrant::Util::Platform.wsl_to_windows_path(image_path).gsub("/", "\\"),
             "VMName" => env[:machine].provider_config.vmname,
+            "Memory" => env[:machine].provider_config.memory,
+            "MaxMemory" => env[:machine].provider_config.maxmemory,
+            "Processors" => env[:machine].provider_config.cpus,
           }
 
-
           env[:ui].detail("Creating and registering the VM...")
           server = env[:machine].provider.driver.import(options)
 
diff --git a/plugins/providers/hyperv/scripts/import_vm.ps1 b/plugins/providers/hyperv/scripts/import_vm.ps1
index db695f0ff11..dce979a9d64 100644
--- a/plugins/providers/hyperv/scripts/import_vm.ps1
+++ b/plugins/providers/hyperv/scripts/import_vm.ps1
@@ -15,6 +15,12 @@ param(
     [parameter (Mandatory=$false)]
     [switch] $LinkedClone,
     [parameter (Mandatory=$false)]
+    [int] $Memory = $null,
+    [parameter (Mandatory=$false)]
+    [int] $MaxMemory = $null,
+    [parameter (Mandatory=$false)]
+    [int] $Processors = $null,
+    [parameter (Mandatory=$false)]
     [string] $VMName=$null
 )
 
@@ -28,7 +34,8 @@ try {
     }
 
     $VM = New-VagrantVM -VMConfigFile $VMConfigFile -DestinationPath $DestinationPath `
-      -DataPath $DataPath -SourcePath $SourcePath -LinkedClone $linked -VMName $VMName
+      -DataPath $DataPath -SourcePath $SourcePath -LinkedClone $linked -Memory $Memory `
+      -MaxMemory $MaxMemory -CPUCount $Processors -VMName $VMName
 
     $Result = @{
         id = $VM.Id.Guid;
diff --git a/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 b/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1
index 927b676dacd..e3886efccef 100644
--- a/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1
+++ b/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1
@@ -33,6 +33,12 @@ function New-VagrantVM {
         [string] $SourcePath,
         [parameter (Mandatory=$false)]
         [bool] $LinkedClone = $false,
+        [parameter (Mandatory=$false)]
+        [int] $Memory = $null,
+        [parameter (Mandatory=$false)]
+        [int] $MaxMemory = $null,
+        [parameter (Mandatory=$false)]
+        [int] $CPUCount = $null,
         [parameter(Mandatory=$false)]
         [string] $VMName
     )
@@ -93,6 +99,12 @@ function New-VagrantVMVMCX {
         [string] $SourcePath,
         [parameter (Mandatory=$false)]
         [bool] $LinkedClone = $false,
+        [parameter (Mandatory=$false)]
+        [int] $Memory = $null,
+        [parameter (Mandatory=$false)]
+        [int] $MaxMemory = $null,
+        [parameter (Mandatory=$false)]
+        [int] $CPUCount = $null,
         [parameter(Mandatory=$false)]
         [string] $VMName
     )
@@ -127,6 +139,16 @@ function New-VagrantVMVMCX {
     # Disconnect adapters from switches
     Hyper-V\Get-VMNetworkAdapter -VM $VM | Hyper-V\Disconnect-VMNetworkAdapter
 
+    # If we have a memory value provided, set it here
+    if($Memory -ne $null) {
+        Set-VagrantVMMemory -VM $VM -Memory $Memory -MaxMemory $MaxMemory
+    }
+
+    # If we have a CPU count provided, set it here
+    if($CPUCount -ne $null) {
+        Set-VagrantVMCPUS -VM $VM -CPUCount $CPUCount
+    }
+
     # Verify new VM
     $Report = Hyper-V\Compare-VM -CompatibilityReport $VMConfig
     if($Report.Incompatibilities.Length -gt 0){