This commit is contained in:
JohnEricson 2020-01-28 00:22:24 +01:00 committed by GitHub
commit b32222e104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 172 additions and 1 deletions

View File

@ -1,5 +1,6 @@
require "fileutils"
require "log4r"
require "json"
module VagrantPlugins
module HyperV
@ -60,6 +61,38 @@ module VagrantPlugins
env[:ui].output("Importing a Hyper-V instance")
dest_path = env[:machine].data_dir.join("Virtual Hard Disks").join(image_path.basename).to_s
if defined? env[:machine].provider_config.controllers
controllers = env[:machine].provider_config.controllers
disks_to_create = []
data_dir = env[:machine].data_dir
# This can happen when creating new on up.
controllers.delete_if &:empty?
controllers.each { |controller|
next_is_size = false
disk_name = ''
controller[:disks].each { |i|
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
disk_name = data_dir.join("#{disk_name}.vhdx").to_s.gsub("/", "\\")
next_is_size = true
end
else
disks_to_create << { name: disk_name, size: i}
end
}
}
disks_to_create_json = disks_to_create.to_json.to_s.gsub('"', '"""')
end
options = {
"VMConfigFile" => Vagrant::Util::Platform.wsl_to_windows_path(config_path).gsub("/", "\\"),
"DestinationPath" => Vagrant::Util::Platform.wsl_to_windows_path(dest_path).gsub("/", "\\"),
@ -67,6 +100,7 @@ module VagrantPlugins
"LinkedClone" => !!env[:machine].provider_config.linked_clone,
"SourcePath" => Vagrant::Util::Platform.wsl_to_windows_path(image_path).gsub("/", "\\"),
"VMName" => env[:machine].provider_config.vmname,
"DisksToCreate" => disks_to_create_json,
}

View File

@ -48,6 +48,8 @@ module VagrantPlugins
attr_accessor :enable_virtualization_extensions
# @return [Hash] Options for VMServiceIntegration
attr_accessor :vm_integration_services
# @return [Array] Config of disks and controllers
attr_accessor :controllers
def initialize
@ip_address_timeout = UNSET_VALUE
@ -65,6 +67,11 @@ module VagrantPlugins
@enable_automatic_checkpoints = UNSET_VALUE
@enable_checkpoints = UNSET_VALUE
@vm_integration_services = {}
@controllers = []
end
def controller(controller={})
@controllers << controller
end
def finalize!
@ -133,6 +140,52 @@ 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|
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")
end
if !controller[:disks].is_a?(Array)
errors << I18n.t("vagrant_hyperv.config.invalid_controller_disks_is_not_an_array",
received: controller[:disks].class)
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, element_class: i.class)
end
else
if !i.is_a?(Integer)
errors << I18n.t("vagrant_hyperv.config.invalid_controller_disks_element_is_not_an_integer",
element: i, element_class: i.class)
end
end
}
}
{"Hyper-V" => errors}
end
end

View File

@ -12,7 +12,9 @@ param(
[parameter (Mandatory=$false)]
[switch] $LinkedClone,
[parameter (Mandatory=$false)]
[string] $VMName=$null
[string] $VMName=$null,
[parameter (Mandatory=$false)]
[string] $DisksToCreate=$null
)
$ErrorActionPreference = "Stop"
@ -35,3 +37,45 @@ try {
Write-ErrorMessage "${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
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"
}
$vm | Add-VMHardDiskDrive @driveParam
}
}
if ($DisksToCreate) {
$ParsedDisksToCreate = $DisksToCreate | ConvertFrom-Json
$ParsedDisksToCreate | ForEach-Object { AddDisks -vm $VMName -controller $_ }
}

View File

@ -39,6 +39,25 @@ en:
The `differencing_disk` configuration option is deprecated and should
no longer be used. The `linked_clone` configuration option should
be used instead.
invalid_controller_type: |-
Invalid controller type provided for :type. Type receiver is
`%{type}` but `:ide` or `:scsi` was expected.
Received: %{type}
Allowed: :ide, :scsi
invalid_controller_type_ide_not_implemeented_yet: |-
Controller type IDE is not implemented yet.
invalid_controller_disks_is_not_an_array: |-
Invalid type provided for `disks` in controller. Type received
is `%{received}` but `Array` was expected.
invalid_controller_disks_attaching_disks_not_implemented_yet: |-
Attaching existing disks is not implemented yet.
invalid_controller_disks_element_is_not_a_string: |-
Invalid type provided for element `%{element}`. Type received is
`%{element_class}` but `String` was expected.
invalid_controller_disks_element_is_not_an_integer: |-
Invalid type provided for element `%{element}`. Type received is
`%{element_class}` but `Integer` was expected.
errors:
admin_required: |-
The Hyper-V provider requires that Vagrant be run with

View File

@ -33,6 +33,9 @@ you may set. A complete reference is shown below:
* `shutdown` (boolean)
* `time_synchronization` (boolean)
* `vss` (boolean)
* `controller` (hash) - Config of disks and controllers.
* `type` (:scsi) - Determines type of controller. Only supports SCSI right now. IDE is to be implemented.
* `disks` (array) - Disks to be created on the controller. First element is a string specifying name of disk, example d1. Second is size of disk in MB, example 10 * 1024 is 10 GB. Name of disk comes first and size after on every disk.
## VM Integration Services
@ -55,3 +58,21 @@ end
This example would enable the `GuestServiceInterface` (which Vagrant is aware) and `CustomVMSRV` (which
Vagrant is _not_ aware) VM integration services.
## Attaching extra controllers and disks
The `controller` configuration option is a simple hash that describes what kind of controller it is.
Such as `:scsi` or `:ide`. Right now only `:scsi` is supported. After this the disks that will be
created is specified in the `disks` array. This is an array where several disks to create can be
specified. First comes the name of the disk, for example d1, and after that followes the size of the
disk specified in MB, for example 10 * 1024 for a 10 GB disk. Repeat this for the number of disks you
want to attach on the controller. To attach existing vhd- or vhdx-files is not implemented yet.
```ruby
config.vm.provider "hyperv" do |h|
h.controller type: :scsi, disks: [ "d1", 10 * 1024 ]
end
```
This example would create a SCSI controller and also create a d1.vhdx file and attach it as a dynamic
disk that is 10 * 1024 MB big, in other words 10 GB.