diff --git a/plugins/providers/hyperv/action/configure.rb b/plugins/providers/hyperv/action/configure.rb index 30831ac12..839e227ee 100644 --- a/plugins/providers/hyperv/action/configure.rb +++ b/plugins/providers/hyperv/action/configure.rb @@ -34,6 +34,57 @@ module VagrantPlugins end end end + + + # TODO: Should be controllers as we want to be able to have several lines. + #if !env[:machine].provider_config.controllers.empty? + # puts "hej: controller not empty" + # #env[:ui].detail("Controllers set") + # #controller.each do [key, value] + # # puts "key: #{id} value: #{value}" + # # if [type].include?(key) + # # puts "key matches type" + # # end + # #end + # + # env[:machine].provider_config.controller.each do |key, value| + # env[:ui].output("#{key} is #{value}") + # end + # + # #env[:machine].provider.driver.set_vm_integration_services( + # # env[:machine].provider_config.vm_integration_services) + #end + + disks_to_create = [] + env[:machine].provider_config.controllers.each { |controller| + #puts "configure.rb: controller: #{controller}" + + next_is_size = false + disk_name = '' + controller[:disks].each { |i| + #puts "configure.rb: i: #{i} disk_name: #{disk_name}" + if !next_is_size + if File.file?(i) + create_disk = false + filename_for_disk = i + next_is_size = false + + @logger.error("Attaching disks is not implemented yet") + else + create_disk = true + disk_name = i + next_is_size = true + #puts "configure.rb: disk_name set to: #{disk_name}" + end + else + #puts "configure.rb: Adding disk to create. name: #{disk_name}" + disks_to_create << { name: "\"#{disk_name}\"", size: i} + end + } + } + #puts "configure.rb: disks_to_create:#{disks_to_create}" + disks_to_create_json = disks_to_create.to_json + puts "configure.rb: json: #{disks_to_create_json}" # If we already configured previously don't prompt for switch sentinel = env[:machine].data_dir.join("action_configure") @@ -71,6 +122,7 @@ module VagrantPlugins "AutoStopAction" => env[:machine].provider_config.auto_stop_action, "EnableCheckpoints" => env[:machine].provider_config.enable_checkpoints, "VirtualizationExtensions" => !!env[:machine].provider_config.enable_virtualization_extensions, + "DisksToCreate" => disks_to_create_json } options.delete_if{|_,v| v.nil? } diff --git a/plugins/providers/hyperv/action/import.rb b/plugins/providers/hyperv/action/import.rb index 3710f3ab2..3d37a2729 100644 --- a/plugins/providers/hyperv/action/import.rb +++ b/plugins/providers/hyperv/action/import.rb @@ -17,7 +17,7 @@ module VagrantPlugins def call(env) vm_dir = env[:machine].box.directory.join("Virtual Machines") hd_dir = env[:machine].box.directory.join("Virtual Hard Disks") - disks_config = env[:machine].provider_config.disks_config + controller = env[:machine].provider_config.controller if !vm_dir.directory? || !hd_dir.directory? @logger.error("Required virtual machine directory not found!") raise Errors::BoxInvalid, name: env[:machine].name @@ -69,7 +69,7 @@ module VagrantPlugins "SourcePath" => Vagrant::Util::Platform.wsl_to_windows_path(image_path).gsub("/", "\\"), "VMName" => env[:machine].provider_config.vmname, } - options[:DisksConfig] = add_abs_path(disks_config, env[:machine].data_dir).to_json.to_s.gsub('"', '"""') if disks_config + #options[:DisksConfig] = add_abs_path(controller, env[:machine].data_dir).to_json.to_s.gsub('"', '"""') if controller env[:ui].detail("Creating and registering the VM...") diff --git a/plugins/providers/hyperv/config.rb b/plugins/providers/hyperv/config.rb index 38039a732..9468fc217 100644 --- a/plugins/providers/hyperv/config.rb +++ b/plugins/providers/hyperv/config.rb @@ -46,9 +46,9 @@ module VagrantPlugins attr_accessor :enable_virtualization_extensions # @return [Hash] Options for VMServiceIntegration attr_accessor :vm_integration_services - # @return [Hash] Config of disks and controllers - attr_accessor :disks_config - + # @return [Array] Config of disks and controllers + attr_accessor :controllers + def initialize @ip_address_timeout = UNSET_VALUE @memory = UNSET_VALUE @@ -64,7 +64,12 @@ module VagrantPlugins @enable_virtualization_extensions = UNSET_VALUE @enable_checkpoints = UNSET_VALUE @vm_integration_services = {} - @disks_config = UNSET_VALUE + @controllers = [] + end + + def controller(controller={}) + #puts "hej: controller called in config.rb" + @controllers << controller end def finalize! @@ -93,7 +98,6 @@ module VagrantPlugins else @enable_checkpoints = !!@enable_checkpoints end - @disks_config = nil if @disks_config == UNSET_VALUE end def validate(machine) @@ -125,6 +129,55 @@ module VagrantPlugins allowed_actions: ALLOWED_AUTO_STOP_ACTIONS.join(", ")) end + # This can happen when creating new on up. + controllers.delete_if &:empty? + + controllers.each { |controller| + #puts "controller: #{controller}" + + if ![:ide, :scsi].include?(controller[:type]) + errors << I18n.t("vagrant_hyperv.config.invalid_controller_type", + type: controller[:type]) + end + + if [:ide].include?(controller[:type]) + errors << I18n.t("vagrant_hyperv.config.invalid_controller_type_ide_not_implemeented_yet", + type: controller[:type]) + end + + if !controller[:disks].is_a?(Array) + errors << I18n.t("vagrant_hyperv.config.invalid_controller_disks_is_not_an_array", + disks: controller[:disks]) + next + end + + next_is_size = false + controller[:disks].each { |i| + if !next_is_size + if i.is_a?(String) + if File.file?(i) + next_is_size = false + + # TODO: This part not implemented yet. + errors << I18n.t("vagrant_hyperv.config.invalid_controller_disks_attaching_disks_not_implemented_yet", + element: i) + else + next_is_size = true + end + else + errors << I18n.t("vagrant_hyperv.config.invalid_controller_disks_element_is_not_a_string", + element: i) + end + else + #puts "next_is_size: true" + if !i.is_a?(Integer) + errors << I18n.t("vagrant_hyperv.config.invalid_controller_disks_element_is_not_an_integer", + element: i) + end + end + } + } + {"Hyper-V" => errors} end end diff --git a/plugins/providers/hyperv/driver.rb b/plugins/providers/hyperv/driver.rb index e200a8224..e1ea3a381 100644 --- a/plugins/providers/hyperv/driver.rb +++ b/plugins/providers/hyperv/driver.rb @@ -241,7 +241,8 @@ module VagrantPlugins notify: [:stdout, :stderr, :stdin], module_path: mod_path } - + + #puts "execute_powershell: options: #{ps_options}" Vagrant::Util::PowerShell.execute(path, *ps_options, **opts, &block) end end diff --git a/plugins/providers/hyperv/scripts/configure_vm.ps1 b/plugins/providers/hyperv/scripts/configure_vm.ps1 index 262c40a57..ee405e692 100644 --- a/plugins/providers/hyperv/scripts/configure_vm.ps1 +++ b/plugins/providers/hyperv/scripts/configure_vm.ps1 @@ -20,7 +20,7 @@ param( [parameter (Mandatory=$false)] [switch] $EnableCheckpoints, [parameter (Mandatory=$false)] - [string] $DisksConfig=$null + [string] $DisksToCreate=$null ) $ErrorActionPreference = "Stop" @@ -95,3 +95,49 @@ try { Write-ErrorMessage "Failed to ${CheckpointAction} checkpoints on VM: ${PSItem}" exit 1 } + + +#controller - path (for existent) +# path, +# sizeMB, name (for new) +function AddDisks($vm, $controller) { + #get controller + + $contNumber = ($vm | Add-VMScsiController -PassThru).ControllerNumber + foreach($disk in $controller) { + #get vhd + $vhd = $null + if($disk.Path) { + if (Test-Path -Path $disk.Path) { + $vhd = Resolve-Path -Path $disk.Path + } + } + else { + $vhd = "$($disk.Name).vhdx" + Add-Content "c:/ps_debug.log" -value "vhd: $vhd" + if (!(Test-Path -Path $vhd)) { + New-VHD -Path $vhd -SizeBytes ([UInt64]$disk.Size * 1MB) -Dynamic + } + } + if (!(Test-Path -Path $vhd)) { + Write-Error "There is error in virtual disk (VHD) configuration" + break + } + + $driveParam = @{ + ControllerNumber = $contNumber + Path = $vhd + ControllerType = "SCSI" + } + Add-Content "c:/ps_debug.log" -value "$vm | Add-VMHardDiskDrive @driveParam" + Add-Content "c:/ps_debug.log" -value "vhd: $vhd" + $vm | Add-VMHardDiskDrive @driveParam + } +} + +if ($DisksToCreate) { + Add-Content "c:/ps_debug.log" -value "DisksToCreate: $DisksToCreate" + $ParsedDisksToCreate = $DisksToCreate | ConvertFrom-Json + Add-Content "c:/ps_debug.log" -value "ParsedDisksToCreate: $ParsedDisksToCreate" + $ParsedDisksToCreate | ForEach-Object { AddDisks -vm $VM -controller $_ } +} \ No newline at end of file diff --git a/plugins/providers/hyperv/scripts/import_vm.ps1 b/plugins/providers/hyperv/scripts/import_vm.ps1 index b422824a0..538544553 100644 --- a/plugins/providers/hyperv/scripts/import_vm.ps1 +++ b/plugins/providers/hyperv/scripts/import_vm.ps1 @@ -14,7 +14,7 @@ param( [parameter (Mandatory=$false)] [string] $VMName=$null, [parameter (Mandatory=$false)] - [string] $DisksConfig=$null + [string] $DisksConfig=$null ) $ErrorActionPreference = "Stop" @@ -37,45 +37,3 @@ try { Write-ErrorMessage "${PSItem}" exit 1 } - - -#controller - path (for existent) -# path, -# sizeGB, name (for new) -function AddDisks($vm, $controller) { - #get controller - - $contNumber = ($vm | Add-VMScsiController -PassThru).ControllerNumber - foreach($disk in $controller) { - #get vhd - $vhd = $null - if($disk.Path) { - if (Test-Path -Path $disk.Path) { - $vhd = Resolve-Path -Path $disk.Path - } - } - else { - $vhd = $disk.Name - if (!(Test-Path -Path $vhd)) { - New-VHD -Path $vhd -SizeBytes ([UInt64]$disk.Size * 1GB) -Dynamic - } - } - if (!(Test-Path -Path $vhd)) { - Write-Error "There is error in virtual disk (VHD) configuration" - break - } - - $driveParam = @{ - ControllerNumber = $contNumber - Path = $vhd - ControllerType = "SCSI" - } - $vm | Add-VMHardDiskDrive @driveParam - } -} - -if ($DisksConfig) { - $ParsedDisksConfig = $DisksConfig | ConvertFrom-Json - $ParsedDisksConfig | ForEach-Object { AddDisks -vm $VMName -controller $_ } -} - diff --git a/website/source/docs/hyperv/configuration.html.md b/website/source/docs/hyperv/configuration.html.md index 178fadf10..b16006122 100644 --- a/website/source/docs/hyperv/configuration.html.md +++ b/website/source/docs/hyperv/configuration.html.md @@ -32,6 +32,7 @@ you may set. A complete reference is shown below: * `shutdown` (boolean) * `time_synchronization` (boolean) * `vss` (boolean) +* `controller` (hash) Config of disks and controllers. ## VM Integration Services